Update mrams driver.

This commit is contained in:
Serge Vakulenko
2015-09-29 19:43:33 -07:00
parent 09112b6b7a
commit 644b6c2112
5 changed files with 249 additions and 49 deletions

View File

@@ -156,24 +156,14 @@ options "SRAMC_SWAP_KBYTES=2048" # size of partition B
# mrams - SPI block device
controller spi1 # RAM disk: mrams
device mr0 at spi1
pins RA4, RA2, RB14, RB12, # chip select signals
RB10, RB11
options "MRAMS_CHIPS=6" # number of chips
pins RA4, RA2, RB14, RB12 # chip select signals
options "MRAMS_CHIPS=4" # number of chips
options "MRAMS_CHIPSIZE=512" # chip size in kbytes
options "MRAMS_MHZ=10" # speed 10 MHz
options "MRAMS_PORT=SPI1CON" # TODO: delete this option
signal "MRAMS_CS0" pin RA4 # TODO: delete
signal "MRAMS_CS1" pin RA2 # TODO: delete
signal "MRAMS_CS2" pin RB14 # TODO: delete
signal "MRAMS_CS3" pin RB12 # TODO: delete
signal "MRAMS_CS4" pin RB10 # TODO: delete
signal "MRAMS_CS5" pin RB11 # TODO: delete
signal "MRAMS_LED0" pin RF0 # optional LED indicators
signal "MRAMS_LED1" pin RF1
signal "MRAMS_LED2" pin RF2
signal "MRAMS_LED3" pin RF3
signal "MRAMS_LED4" pin RF4
signal "MRAMS_LED5" pin RF5
# spirams - SPI block device
controller spi1 # RAM disk: spirams

View File

@@ -0,0 +1,74 @@
#
# Fubarino SD board
# =================
# Console on USB.
# For details, see https://github.com/RetroBSD/retrobsd/wiki/Board-Fubarino-SD
#
# To build the kernel, use:
# cd sys/pic32/fubarino
# kconfig Config
# make clean
# make
#
# Format of this file is described on page:
# http://retrobsd.org/wiki/doku.php/doc/kconfig
#
architecture "pic32"
cpu "PIC32MX7" # Processor variant
board "FUBARINO" # Board type
ldscript "max32/bootloader.ld" # Linker script
# Standard system options
options "CPU_KHZ=80000" # Oscillator frequency of CPU core
options "BUS_KHZ=80000" # Frequency of peripheral bus
options "BUS_DIV=1" # Bus clock divisor 1/2/4/8
# LED
signal "LED_KERNEL" pin RE5 # kernel activity indicator
# Root filesystem at /dev/sd0a, swap at /dev/sd0b
config unix root on sd0a
swap on sd0b
# Console options
options "CONS_MAJOR=UARTUSB_MAJOR" # UARTUSB device
# Virtual UART on USB
device uartusb
options "USB_MAX_EP_NUMBER=3"
options "USB_NUM_STRING_DESCRIPTORS=3"
# UART ports
device uart2 # Pins RF4, RF5
# SPI ports
controller spi2 # SD card
controller spi3 # Pins RD1, RD2, RD3
# microSD card
device sd0 at spi2 pin RG9 # select pin
# General purpose I/O ports
# Flags define a mask of available pins
# The following pins excluded:
# RG6, RG7, RG8, RG9 - spi2, SD card
# RD1, RD2, RD3 - spi3
# RF4, RF5 - uart2
device gpio1 flags 0xffff # port B
device gpio2 flags 0xf000 # port C
device gpio3 flags 0x0ff1 # port D
device gpio4 flags 0x00ff # port E
device gpio5 flags 0x000b # port F
device gpio6 flags 0x000c # port G
# ADC driver
device adc
# PWM driver
device pwm
# mrams - SPI block device
device mr0 at spi3
pins RD4, RD5, RD6, RD7 # chip select signals
options "MRAMS_CHIPS=4" # number of chips
options "MRAMS_CHIPSIZE=512" # chip size in kbytes

View File

@@ -1,5 +1,5 @@
/*
* TODO: Modify this driver to be able to function without rdisk layer.
* Disk driver for serial MRAM chips connected via SPI port.
*/
#include <sys/param.h>
#include <sys/systm.h>
@@ -8,7 +8,8 @@
#include <sys/dk.h>
#include <sys/disk.h>
#include <sys/spi.h>
#include <sys/debug.h>
#include <sys/kconfig.h>
#include <machine/debug.h>
#include <machine/mrams.h>
#define MRAM_WREN 0x06
@@ -26,10 +27,12 @@
struct spiio mrams_io[MRAMS_CHIPS];
int mrams_size(int unit)
{
return MRAMS_CHIPS * MRAMS_CHIPSIZE;
}
int mrams_dkindex; /* disk index for statistics */
/*
* Size of RAM disk.
*/
#define MRAMS_TOTAL_KBYTES (MRAMS_CHIPS * MRAMS_CHIPSIZE)
#define MRBSIZE 1024
#define MRBLOG2 10
@@ -108,7 +111,7 @@ unsigned int mr_read_block(unsigned int chip, unsigned int address, unsigned int
return cs;
}
int mrams_read(int unit, unsigned int offset, char *data, unsigned int bcount)
int mrams_read(unsigned int offset, char *data, unsigned int bcount)
{
register unsigned int chip;
register unsigned int toread;
@@ -211,7 +214,7 @@ unsigned int mr_write_block(unsigned int chip, unsigned int address, unsigned in
return cs;
}
int mrams_write(int unit, unsigned int offset, char *data, unsigned bcount)
int mrams_write(unsigned int offset, char *data, unsigned bcount)
{
register unsigned int chip;
register unsigned int address;
@@ -240,27 +243,33 @@ int mrams_write(int unit, unsigned int offset, char *data, unsigned bcount)
return 1;
}
void mrams_preinit(int unit)
static unsigned *gpio_base(int cs)
{
int port = (cs >> 4) - 1;
struct gpioreg *base = port + (struct gpioreg*) &TRISA;
return (unsigned int*) base;
}
/*
* Initialize hardware.
*/
static int mrams_init(int spi_port, int cs0, int cs1, int cs2, int cs3)
{
struct spiio *io = &mrams_io[0];
struct buf *bp;
if (unit >= 1)
return;
/* Initialize hardware. */
if (spi_setup(io, MRAMS_PORT, (unsigned int *)&MRAMS_CS0_PORT, MRAMS_CS0_PIN) != 0)
return;
if (spi_setup(io, spi_port, gpio_base(cs0), cs0 & 15) != 0) {
printf("mr0: cannot open SPI%u port\n", spi_port);
return 0;
}
spi_brg(io, MRAMS_MHZ * 1000);
spi_set(io, PIC32_SPICON_CKE);
spi_select(io);
spi_transfer(io, MRAM_WREN);
spi_deselect(io);
#ifdef MRAMS_CS1_PORT
spi_setup(io+1, MRAMS_PORT, (unsigned int *)&MRAMS_CS1_PORT, MRAMS_CS1_PIN);
#if MRAMS_CHIPS >= 1
spi_setup(io+1, spi_port, gpio_base(cs1), cs1 & 15);
spi_brg(io+1, MRAMS_MHZ * 1000);
spi_set(io+1, PIC32_SPICON_CKE);
@@ -268,8 +277,8 @@ void mrams_preinit(int unit)
spi_transfer(io+1, MRAM_WREN);
spi_deselect(io+1);
#endif
#ifdef MRAMS_CS2_PORT
spi_setup(io+2, MRAMS_PORT, (unsigned int *)&MRAMS_CS2_PORT, MRAMS_CS2_PIN);
#if MRAMS_CHIPS >= 2
spi_setup(io+2, spi_port, gpio_base(cs2), cs2 & 15);
spi_brg(io+2, MRAMS_MHZ * 1000);
spi_set(io+2, PIC32_SPICON_CKE);
@@ -277,8 +286,8 @@ void mrams_preinit(int unit)
spi_transfer(io+2, MRAM_WREN);
spi_deselect(io+2);
#endif
#ifdef MRAMS_CS3_PORT
spi_setup(io+3, MRAMS_PORT, (unsigned int *)&MRAMS_CS3_PORT, MRAMS_CS3_PIN);
#if MRAMS_CHIPS >= 3
spi_setup(io+3, spi_port, gpio_base(cs3), cs3 & 15);
spi_brg(io+3, MRAMS_MHZ * 1000);
spi_set(io+3, PIC32_SPICON_CKE);
@@ -287,12 +296,137 @@ void mrams_preinit(int unit)
spi_deselect(io+3);
#endif
printf("mrams0: port %s, size %dKB, speed %d Mbit/sec\n",
spi_name(MRAMS_PORT), MRAMS_CHIPS * MRAMS_CHIPSIZE,
spi_get_brg(io) / 1000);
bp = prepartition_device("mrams0");
if (bp) {
mrams_write(0, 0, bp->b_addr, 512);
brelse(bp);
printf("mr0: size %dKB, speed %d Mbit/sec\n",
MRAMS_CHIPS * MRAMS_CHIPSIZE, spi_get_brg(io) / 1000);
return 1;
}
/*
* Open the disk.
*/
int mrams_open(dev_t dev, int flag, int mode)
{
return 0;
}
int mrams_close(dev_t dev, int flag, int mode)
{
return 0;
}
/*
* Return the size of the device in kbytes.
*/
daddr_t mrams_size(dev_t dev)
{
return MRAMS_TOTAL_KBYTES;
}
void mrams_strategy(struct buf *bp)
{
int offset = bp->b_blkno;
long nblk = btod(bp->b_bcount);
int s;
/*
* Determine the size of the transfer, and make sure it is
* within the boundaries of the partition.
*/
if (bp->b_blkno + nblk > MRAMS_TOTAL_KBYTES) {
/* if exactly at end of partition, return an EOF */
if (bp->b_blkno == MRAMS_TOTAL_KBYTES) {
bp->b_resid = bp->b_bcount;
biodone(bp);
return;
}
/* or truncate if part of it fits */
nblk = MRAMS_TOTAL_KBYTES - bp->b_blkno;
if (nblk <= 0) {
bp->b_error = EINVAL;
bp->b_flags |= B_ERROR;
biodone(bp);
return;
}
bp->b_bcount = nblk << DEV_BSHIFT;
}
led_control(LED_SWAP, 1);
s = splbio();
#ifdef UCB_METER
if (mrams_dkindex >= 0) {
dk_busy |= 1 << mrams_dkindex;
dk_xfer[mrams_dkindex]++;
dk_bytes[mrams_dkindex] += bp->b_bcount;
}
#endif
if (bp->b_flags & B_READ) {
mrams_read(offset, bp->b_addr, bp->b_bcount);
} else {
mrams_write(offset, bp->b_addr, bp->b_bcount);
}
biodone(bp);
led_control(LED_SWAP, 0);
#ifdef UCB_METER
if (mrams_dkindex >= 0)
dk_busy &= ~(1 << mrams_dkindex);
#endif
splx(s);
}
int mrams_ioctl(dev_t dev, u_int cmd, caddr_t addr, int flag)
{
int error = 0;
switch (cmd) {
case DIOCGETMEDIASIZE:
/* Get disk size in kbytes. */
*(int*) addr = MRAMS_TOTAL_KBYTES;
break;
default:
error = EINVAL;
break;
}
return error;
}
/*
* Test to see if device is present.
* Return true if found and initialized ok.
*/
static int
mrams_probe(config)
struct conf_device *config;
{
int cs0 = config->dev_pins[0];
int cs1 = config->dev_pins[1];
int cs2 = config->dev_pins[2];
int cs3 = config->dev_pins[3];
/* Only one device unit is supported. */
if (config->dev_unit != 0)
return 0;
printf("mr0: port SPI%d, pins cs0=R%c%d/cs1=R%c%d/cs2=R%c%d/cs3=R%c%d\n",
config->dev_ctlr,
gpio_portname(cs0), gpio_pinno(cs0),
gpio_portname(cs1), gpio_pinno(cs1),
gpio_portname(cs2), gpio_pinno(cs2),
gpio_portname(cs3), gpio_pinno(cs3));
if (mrams_init(config->dev_ctlr, cs0, cs1, cs2, cs3) != 0)
return 0;
#ifdef UCB_METER
dk_alloc(&mrams_dkindex, 1, "mr0");
#endif
return 1;
}
struct driver mrdriver = {
"mr", mrams_probe,
};

View File

@@ -1,9 +1,12 @@
#ifndef _MRAMS_H
#define _MRAMS_H
extern int mrams_size(int unit);
extern int mrams_read(int unit, unsigned int offset, char *data, unsigned int bcount);
extern int mrams_write (int unit, unsigned offset, char *data, unsigned bcount);
extern void mrams_preinit (int unit);
#ifdef KERNEL
extern int mrams_open(dev_t dev, int flag, int mode);
extern int mrams_close(dev_t dev, int flag, int mode);
extern daddr_t mrams_size(dev_t dev);
extern void mrams_strategy(struct buf *bp);
extern int mrams_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag);
#endif
#endif

View File

@@ -1,6 +1,5 @@
/*
* Driver for external SRAM-CPLD based Swap and Filesystem devices
* TODO: Modify this driver to be able to function without rdisk layer.
*
* This version is for 8MB RAMDISK v.1.1 and compatible
* Pito 7.4.2014 - PIC32MX PMP bus version