better sd(ram|card) drivers
This commit is contained in:
parent
c9fbaf61f8
commit
802d8118c5
@ -110,8 +110,8 @@ struct dkdriver sbusfpga_sd_dkdriver = {
|
||||
|
||||
static int sdcard_init(struct sbusfpga_sd_softc *sc);
|
||||
static int dma_init(struct sbusfpga_sd_softc *sc);
|
||||
static void sdcard_read(struct sbusfpga_sd_softc *sc, uint32_t block, uint32_t count, uint8_t* buf);
|
||||
static void sdcard_write(struct sbusfpga_sd_softc *sc, uint32_t block, uint32_t count, uint8_t* buf);
|
||||
static int sdcard_read(struct sbusfpga_sd_softc *sc, uint32_t block, uint32_t count, uint8_t* buf);
|
||||
static int sdcard_write(struct sbusfpga_sd_softc *sc, uint32_t block, uint32_t count, uint8_t* buf);
|
||||
|
||||
#if 0
|
||||
static int sbusfpga_sd_mmc_host_reset(sdmmc_chipset_handle_t);
|
||||
@ -291,10 +291,24 @@ sbusfpga_sd_attach(device_t parent, device_t self, void *aux)
|
||||
sc->sc_burst,
|
||||
sbsc->sc_burst);
|
||||
|
||||
if (!sdcard_init(sc)) {
|
||||
aprint_error_dev(self, "couldn't initialize sdcard\n");
|
||||
return;
|
||||
sc->max_rd_blk_len = 0;
|
||||
sc->max_size_in_blk = 0;
|
||||
/* check values from the PROM for proper initialization */
|
||||
if (prom_getpropint(node, "sdcard-good", 0) == 1) {
|
||||
aprint_normal_dev(self, "sdcard initialized by PROM\n");
|
||||
sc->max_rd_blk_len = prom_getpropint(node, "max_rd_blk_len", 0);
|
||||
sc->max_size_in_blk = prom_getpropint(node, "max_size_in_blk", 0);
|
||||
}
|
||||
/* if PROM initialization is not done [properly], try in the driver */
|
||||
if ((sc->max_rd_blk_len == 0) || (sc->max_size_in_blk == 0)) {
|
||||
if (!sdcard_init(sc)) {
|
||||
aprint_error_dev(self, "couldn't initialize sdcard\n");
|
||||
return;
|
||||
} else {
|
||||
aprint_normal_dev(self, "sdcard initialized by kernel\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!dma_init(sc)) {
|
||||
aprint_error_dev(self, "couldn't initialize DMA for sdcard\n");
|
||||
return;
|
||||
@ -342,7 +356,7 @@ sbusfpga_sd_open(dev_t dev, int flag, int fmt, struct lwp *l)
|
||||
device_printf(sd->dk.sc_dev, "%s:%d: sd == NULL! giving up\n", __PRETTY_FUNCTION__, __LINE__);
|
||||
return (ENXIO);
|
||||
} else {
|
||||
aprint_normal("%s:%d: open device, part is %d\n", __PRETTY_FUNCTION__, __LINE__, DISKPART(dev));
|
||||
aprint_normal("%s:%d: open device %d, part is %d\n", __PRETTY_FUNCTION__, __LINE__, DISKUNIT(dev), DISKPART(dev));
|
||||
}
|
||||
dksc = &sd->dk;
|
||||
|
||||
@ -421,7 +435,14 @@ static void sbusfpga_sd_set_geometry(struct sbusfpga_sd_softc *sc) {
|
||||
int
|
||||
sbusfpga_sd_size(dev_t dev) {
|
||||
struct sbusfpga_sd_softc *sc = device_lookup_private(&sbusfpga_sd_cd, DISKUNIT(dev));
|
||||
return sc->max_size_in_blk;
|
||||
if (sc == NULL)
|
||||
return -1;
|
||||
|
||||
if (!device_is_active(sc->dk.sc_dev)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return dk_size(&sc->dk, dev);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -431,7 +452,6 @@ sbusfpga_sd_minphys(struct buf *bp)
|
||||
bp->b_bcount = SBUSFPGA_SD_VAL_DMA_MAX_SZ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sbusfpga_sd_diskstart(device_t self, struct buf *bp)
|
||||
{
|
||||
@ -455,44 +475,9 @@ sbusfpga_sd_diskstart(device_t self, struct buf *bp)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
paddr_t pap;
|
||||
pmap_t pk = pmap_kernel();
|
||||
if (pmap_extract(pk, (vaddr_t)bp->b_data, &pap)) {
|
||||
aprint_normal_dev(sc->dk.sc_dev, "KVA %p mapped to PA 0x%08lx\n", bp->b_data, pap);
|
||||
if (bp->b_bcount > 4096) {
|
||||
u_int32_t np = (bp->b_bcount + 4095) / 4096;
|
||||
u_int32_t pn;
|
||||
for (pn = 1 ; pn < np ; pn ++) {
|
||||
paddr_t papn;
|
||||
if (pmap_extract(pk, (vaddr_t)bp->b_data + pn * 4096, &papn)) {
|
||||
if (papn != (pap + pn * 4096))
|
||||
break;
|
||||
} else break;
|
||||
}
|
||||
aprint_normal_dev(sc->dk.sc_dev, "And we have %u out %u consecutive PA pages\n", pn, np);
|
||||
}
|
||||
} else {
|
||||
aprint_normal_dev(sc->dk.sc_dev, "KVA %p not mapped\n", bp->b_data);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (bp->b_flags & B_READ) {
|
||||
unsigned char* data = bp->b_data;
|
||||
daddr_t blk = bp->b_rawblkno;
|
||||
/* struct partition *p = NULL; */
|
||||
|
||||
/* if (DISKPART(bp->b_dev) != RAW_PART) { */
|
||||
/* if ((err = bounds_check_with_label(&sc->dk.sc_dkdev, bp, 0)) <= 0) { */
|
||||
/* device_printf(sc->dk.sc_dev, "%s:%d: bounds_check_with_label -> %d\n", __PRETTY_FUNCTION__, __LINE__, err); */
|
||||
/* bp->b_resid = bp->b_bcount; */
|
||||
/* goto done; */
|
||||
/* } */
|
||||
/* p = &sc->dk.sc_dkdev.dk_label->d_partitions[DISKPART(bp->b_dev)]; */
|
||||
/* blk = bp->b_blkno + p->p_offset; */
|
||||
/* } */
|
||||
|
||||
while (bp->b_resid >= 512 && !err) {
|
||||
u_int32_t blkcnt = bp->b_resid / 512;
|
||||
@ -501,7 +486,7 @@ sbusfpga_sd_diskstart(device_t self, struct buf *bp)
|
||||
blkcnt = (SBUSFPGA_SD_VAL_DMA_MAX_SZ/512);
|
||||
|
||||
if (blk+blkcnt <= sc->max_size_in_blk) {
|
||||
sdcard_read(sc, blk, blkcnt, data);
|
||||
err = sdcard_read(sc, blk, blkcnt, data);
|
||||
} else {
|
||||
device_printf(sc->dk.sc_dev, "%s:%d: blk = %lld read out of range! giving up\n", __PRETTY_FUNCTION__, __LINE__, blk);
|
||||
err = EINVAL;
|
||||
@ -512,24 +497,8 @@ sbusfpga_sd_diskstart(device_t self, struct buf *bp)
|
||||
bp->b_resid -= 512 * blkcnt;
|
||||
}
|
||||
} else {
|
||||
/* aprint_normal_dev(sc->dk.sc_dev, "%s:%d: part %d\n", __PRETTY_FUNCTION__, __LINE__, DISKPART(bp->b_dev)); */
|
||||
/* aprint_normal_dev(sc->dk.sc_dev, "%s:%d: bp->b_bflags = 0x%08x\n", __PRETTY_FUNCTION__, __LINE__, bp->b_flags); */
|
||||
/* aprint_normal_dev(sc->dk.sc_dev, "%s:%d: bp->b_bufsize = %d\n", __PRETTY_FUNCTION__, __LINE__, bp->b_bufsize); */
|
||||
/* aprint_normal_dev(sc->dk.sc_dev, "%s:%d: bp->b_blkno = %lld\n", __PRETTY_FUNCTION__, __LINE__, bp->b_blkno); */
|
||||
/* aprint_normal_dev(sc->dk.sc_dev, "%s:%d: bp->b_rawblkno = %lld\n", __PRETTY_FUNCTION__, __LINE__, bp->b_rawblkno); */
|
||||
/* aprint_normal_dev(sc->dk.sc_dev, "%s:%d: bp->b_bcount = %d\n", __PRETTY_FUNCTION__, __LINE__, bp->b_bcount); */
|
||||
unsigned char* data = bp->b_data;
|
||||
daddr_t blk = bp->b_rawblkno;
|
||||
/* struct partition *p = NULL; */
|
||||
|
||||
/* if (DISKPART(bp->b_dev) != RAW_PART) { */
|
||||
/* if (bounds_check_with_label(&sc->dk.sc_dkdev, bp, 0) <= 0) { */
|
||||
/* bp->b_resid = bp->b_bcount; */
|
||||
/* goto done; */
|
||||
/* } */
|
||||
/* p = &sc->dk.sc_dkdev.dk_label->d_partitions[DISKPART(bp->b_dev)]; */
|
||||
/* blk = bp->b_blkno + p->p_offset; */
|
||||
/* } */
|
||||
|
||||
while (bp->b_resid >= 512 && !err) {
|
||||
u_int32_t blkcnt = bp->b_resid / 512;
|
||||
@ -538,7 +507,7 @@ sbusfpga_sd_diskstart(device_t self, struct buf *bp)
|
||||
blkcnt = (SBUSFPGA_SD_VAL_DMA_MAX_SZ/512);
|
||||
|
||||
if (blk+blkcnt <= sc->max_size_in_blk) {
|
||||
sdcard_write(sc, blk, blkcnt, data);
|
||||
err = sdcard_write(sc, blk, blkcnt, data);
|
||||
} else {
|
||||
device_printf(sc->dk.sc_dev, "%s:%d: blk = %lld write out of range! giving up\n", __PRETTY_FUNCTION__, __LINE__, blk);
|
||||
err = EINVAL;
|
||||
@ -550,9 +519,6 @@ sbusfpga_sd_diskstart(device_t self, struct buf *bp)
|
||||
}
|
||||
}
|
||||
|
||||
/* aprint_normal_dev(sc->dk.sc_dev, "%s:%d: bp->b_resid = %d\n", __PRETTY_FUNCTION__, __LINE__, bp->b_resid); */
|
||||
/* aprint_normal_dev(sc->dk.sc_dev, "%s:%d: bp->b_error = %d\n", __PRETTY_FUNCTION__, __LINE__, bp->b_error); */
|
||||
|
||||
done:
|
||||
biodone(bp);
|
||||
return err;
|
||||
@ -567,30 +533,6 @@ static int dma_init(struct sbusfpga_sd_softc *sc) {
|
||||
} else {
|
||||
aprint_normal_dev(sc->dk.sc_dev, "dmamap: %lu %lu %d (%p)\n", sc->sc_dmamap->dm_maxsegsz, sc->sc_dmamap->dm_mapsize, sc->sc_dmamap->dm_nsegs, sc->sc_dmatag->_dmamap_load);
|
||||
}
|
||||
|
||||
if (bus_dmamem_alloc(sc->sc_dmatag, SBUSFPGA_SD_VAL_DMA_MAX_SZ, 64, 64, &sc->sc_segs, 1, &sc->sc_rsegs, BUS_DMA_NOWAIT | BUS_DMA_STREAMING)) {
|
||||
aprint_error_dev(sc->dk.sc_dev, "cannot allocate DVMA memory");
|
||||
bus_dmamap_destroy(sc->sc_dmatag, sc->sc_dmamap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bus_dmamem_map(sc->sc_dmatag, &sc->sc_segs, 1, SBUSFPGA_SD_VAL_DMA_MAX_SZ, &sc->sc_dma_kva, BUS_DMA_NOWAIT)) {
|
||||
aprint_error_dev(sc->dk.sc_dev, "cannot allocate DVMA address");
|
||||
bus_dmamem_free(sc->sc_dmatag, &sc->sc_segs, 1);
|
||||
bus_dmamap_destroy(sc->sc_dmatag, sc->sc_dmamap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, sc->sc_dma_kva, SBUSFPGA_SD_VAL_DMA_MAX_SZ, /* kernel space */ NULL,
|
||||
BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_WRITE)) {
|
||||
aprint_error_dev(sc->dk.sc_dev, "cannot load dma map");
|
||||
bus_dmamem_unmap(sc->sc_dmatag, &sc->sc_dma_kva, SBUSFPGA_SD_VAL_DMA_MAX_SZ);
|
||||
bus_dmamem_free(sc->sc_dmatag, &sc->sc_segs, 1);
|
||||
bus_dmamap_destroy(sc->sc_dmatag, sc->sc_dmamap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
aprint_normal_dev(sc->dk.sc_dev, "DMA: SW -> kernel address is %p, dvma address is 0x%08llx\n", sc->sc_dma_kva, sc->sc_dmamap->dm_segs[0].ds_addr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1138,12 +1080,19 @@ device_printf(sc->dk.sc_dev, "rca is 0x%08x\n", rca);
|
||||
}
|
||||
|
||||
|
||||
static void sdcard_read(struct sbusfpga_sd_softc *sc, uint32_t block, uint32_t count, uint8_t* buf)
|
||||
static int sdcard_read(struct sbusfpga_sd_softc *sc, uint32_t block, uint32_t count, uint8_t* buf)
|
||||
{
|
||||
uint32_t counto = count;
|
||||
uint64_t ds_addr = sc->sc_dmamap->dm_segs[0].ds_addr;
|
||||
const uint32_t counto = count;
|
||||
uint64_t ds_addr;
|
||||
//device_printf(sc->dk.sc_dev, "%s:%d: block %u count %u buf %p ds_addr %llx\n", __PRETTY_FUNCTION__, __LINE__, block, count, buf, ds_addr);
|
||||
|
||||
if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, buf, counto * 512, /* kernel space */ NULL,
|
||||
BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_WRITE)) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
ds_addr = sc->sc_dmamap->dm_segs[0].ds_addr;
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, counto * 512, BUS_DMASYNC_PREWRITE);
|
||||
|
||||
while (count) {
|
||||
@ -1190,16 +1139,23 @@ static void sdcard_read(struct sbusfpga_sd_softc *sc, uint32_t block, uint32_t c
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, counto * 512, BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
memcpy(buf, sc->sc_dma_kva, counto * 512);
|
||||
bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sdcard_write(struct sbusfpga_sd_softc *sc, uint32_t block, uint32_t count, uint8_t* buf)
|
||||
static int sdcard_write(struct sbusfpga_sd_softc *sc, uint32_t block, uint32_t count, uint8_t* buf)
|
||||
{
|
||||
uint32_t counto = count;
|
||||
uint64_t ds_addr = sc->sc_dmamap->dm_segs[0].ds_addr;
|
||||
const uint32_t counto = count;
|
||||
uint64_t ds_addr;
|
||||
//device_printf(sc->dk.sc_dev, "%s: block %u count %u buf %p ds_addr %llx\n", __PRETTY_FUNCTION__, block, count, buf, ds_addr);
|
||||
|
||||
if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, buf, counto * 512, /* kernel space */ NULL,
|
||||
BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_READ)) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(sc->sc_dma_kva, buf, counto * 512);
|
||||
ds_addr = sc->sc_dmamap->dm_segs[0].ds_addr;
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, counto * 512, BUS_DMASYNC_PREREAD);
|
||||
|
||||
@ -1245,4 +1201,8 @@ static void sdcard_write(struct sbusfpga_sd_softc *sc, uint32_t block, uint32_t
|
||||
}
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, counto * 512, BUS_DMASYNC_POSTREAD);
|
||||
|
||||
bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -53,11 +53,8 @@ struct sbusfpga_sd_softc {
|
||||
/* DMA kernel structures */
|
||||
bus_dma_tag_t sc_dmatag;
|
||||
bus_dmamap_t sc_dmamap;
|
||||
bus_dma_segment_t sc_segs;
|
||||
int sc_rsegs;
|
||||
void * sc_dma_kva;
|
||||
|
||||
device_t sc_sdmmc_dev; /* us as a sdmmc bus device */
|
||||
//device_t sc_sdmmc_dev; /* us as a sdmmc bus device */
|
||||
};
|
||||
|
||||
#define SBUSFPGA_SD_VAL_DMA_MAX_SZ (64*1024)
|
||||
|
||||
@ -126,21 +126,6 @@ static void enable_irq(struct sbusfpga_sdram_softc *sc);
|
||||
static void reset_irq(struct sbusfpga_sdram_softc *sc);
|
||||
#endif
|
||||
|
||||
struct sbusfpga_sdram_rwpg {
|
||||
u_int32_t pgdata[512];
|
||||
u_int32_t checksum[8];
|
||||
u_int32_t checksumbis[8];
|
||||
u_int32_t pgnum;
|
||||
u_int32_t last_blk;
|
||||
u_int32_t last_dma;
|
||||
u_int32_t dma_wrdone;
|
||||
};
|
||||
#define SBUSFPGA_READ_PG _IOWR('X', 0, struct sbusfpga_sdram_rwpg)
|
||||
#define SBUSFPGA_WRITE_PG _IOWR('X', 1, struct sbusfpga_sdram_rwpg)
|
||||
|
||||
static inline void exchange_with_mem_checksum_read(struct sbusfpga_sdram_softc *sc, uint32_t* data);
|
||||
static inline void exchange_with_mem_checksum_write(struct sbusfpga_sdram_softc *sc, uint32_t* data);
|
||||
|
||||
int
|
||||
sbusfpga_sdram_open(dev_t dev, int flag, int fmt, struct lwp *l)
|
||||
{
|
||||
@ -152,7 +137,7 @@ sbusfpga_sdram_open(dev_t dev, int flag, int fmt, struct lwp *l)
|
||||
aprint_error("%s:%d: sd == NULL! giving up\n", __PRETTY_FUNCTION__, __LINE__);
|
||||
return (ENXIO);
|
||||
} else {
|
||||
aprint_normal("%s:%d: open device, part is %d\n", __PRETTY_FUNCTION__, __LINE__, DISKPART(dev));
|
||||
aprint_normal("%s:%d: open device %d, part is %d\n", __PRETTY_FUNCTION__, __LINE__, DISKUNIT(dev), DISKPART(dev));
|
||||
}
|
||||
dksc = &sd->dk;
|
||||
|
||||
@ -207,28 +192,14 @@ sbusfpga_sdram_match(device_t parent, cfdata_t cf, void *aux)
|
||||
int
|
||||
sdram_init(struct sbusfpga_sdram_softc *sc);
|
||||
|
||||
int
|
||||
static int
|
||||
dma_init(struct sbusfpga_sdram_softc *sc);
|
||||
static int
|
||||
dma_uninit(struct sbusfpga_sdram_softc *sc);
|
||||
|
||||
int
|
||||
static int
|
||||
dma_memtest(struct sbusfpga_sdram_softc *sc);
|
||||
|
||||
int
|
||||
init_last_blocks(struct sbusfpga_sdram_softc *sc);
|
||||
int
|
||||
init_last_blocks(struct sbusfpga_sdram_softc *sc) {
|
||||
u_int32_t data[512];
|
||||
u_int32_t i;
|
||||
int res = 0;
|
||||
for (i = 0 ; i < 512 ; i++) {
|
||||
data[i] = 0x00FF00FF;
|
||||
}
|
||||
for (i = 254*1024*2 ; i < 256*1024*2 && !res; i+=4) {
|
||||
res = sbusfpga_sdram_write_block(sc, i, 4, data);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach all the sub-devices we can find
|
||||
*/
|
||||
@ -355,6 +326,11 @@ sbusfpga_sdram_attach(device_t parent, device_t self, void *aux)
|
||||
aprint_error_dev(self, "DMA-MEMTEST failed for SDRAM\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dma_uninit(sc)) {
|
||||
aprint_error_dev(self, "couldn't un-initialize DMA\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->bp = NULL;
|
||||
|
||||
@ -396,11 +372,6 @@ sbusfpga_sdram_attach(device_t parent, device_t self, void *aux)
|
||||
|
||||
bufq_alloc(&sc->dk.sc_bufq, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK);
|
||||
|
||||
/*
|
||||
// initialize some blocks were the FB lives to test the output
|
||||
init_last_blocks(sc);
|
||||
*/
|
||||
|
||||
/*
|
||||
aprint_normal_dev(self, "sc->dk.sc_dkdev.dk_blkshift = %d\n", sc->dk.sc_dkdev.dk_blkshift);
|
||||
aprint_normal_dev(self, "sc->dk.sc_dkdev.dk_byteshift = %d\n", sc->dk.sc_dkdev.dk_byteshift);
|
||||
@ -439,7 +410,14 @@ static void sbusfpga_sdram_set_geometry(struct sbusfpga_sdram_softc *sc) {
|
||||
int
|
||||
sbusfpga_sdram_size(dev_t dev) {
|
||||
struct sbusfpga_sdram_softc *sc = device_lookup_private(&sbusfpga_sdram_cd, DISKUNIT(dev));
|
||||
return sc->dma_real_mem_size / 512;
|
||||
if (sc == NULL)
|
||||
return -1;
|
||||
|
||||
if (!device_is_active(sc->dk.sc_dev)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return dk_size(&sc->dk, dev);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -550,7 +528,7 @@ sbusfpga_sdram_diskstart(device_t self, struct buf *bp)
|
||||
if (bp->b_bcount == 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
if (bp->b_flags & B_READ) {
|
||||
unsigned char* data = bp->b_data;
|
||||
daddr_t blk = bp->b_rawblkno;
|
||||
@ -670,20 +648,6 @@ static void reset_irq(struct sbusfpga_sdram_softc *sc) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/* not yet generated */
|
||||
static inline void exchange_with_mem_checksum_read(struct sbusfpga_sdram_softc *sc, uint32_t* data) {
|
||||
int i;
|
||||
for (i = 0 ; i < 8 ; i++) { // FIXME
|
||||
data[i] = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 4*i+(CSR_EXCHANGE_WITH_MEM_CHECKSUM_ADDR - CSR_EXCHANGE_WITH_MEM_BASE));
|
||||
}
|
||||
}
|
||||
static inline void exchange_with_mem_checksum_write(struct sbusfpga_sdram_softc *sc, uint32_t* data) {
|
||||
int i;
|
||||
for (i = 0 ; i < 8 ; i++) { // FIXME
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_exchange_with_mem, 4*i+(CSR_EXCHANGE_WITH_MEM_CHECKSUM_ADDR - CSR_EXCHANGE_WITH_MEM_BASE), data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sbusfpga_sdram_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
|
||||
{
|
||||
@ -694,37 +658,6 @@ sbusfpga_sdram_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l
|
||||
aprint_error("%s:%d: sc == NULL! giving up\n", __PRETTY_FUNCTION__, __LINE__);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case SBUSFPGA_READ_PG: {
|
||||
struct sbusfpga_sdram_rwpg* pg = (struct sbusfpga_sdram_rwpg*)data;
|
||||
exchange_with_mem_checksum_write(sc, pg->checksum);
|
||||
err = sbusfpga_sdram_read_block(sc, pg->pgnum * 4, 4, pg->pgdata);
|
||||
exchange_with_mem_checksum_read(sc, pg->checksum);
|
||||
delay(1);
|
||||
exchange_with_mem_checksum_read(sc, pg->checksumbis);
|
||||
pg->last_blk = exchange_with_mem_last_blk_read(sc);
|
||||
pg->last_dma = exchange_with_mem_last_dma_read(sc);
|
||||
pg->dma_wrdone = exchange_with_mem_dma_wrdone_read(sc);
|
||||
if (err != 0)
|
||||
err = EIO;
|
||||
goto done;
|
||||
}
|
||||
case SBUSFPGA_WRITE_PG: {
|
||||
struct sbusfpga_sdram_rwpg* pg = (struct sbusfpga_sdram_rwpg*)data;
|
||||
exchange_with_mem_checksum_write(sc, pg->checksum);
|
||||
err = sbusfpga_sdram_write_block(sc, pg->pgnum * 4, 4, pg->pgdata);
|
||||
exchange_with_mem_checksum_read(sc, pg->checksum);
|
||||
delay(1);
|
||||
exchange_with_mem_checksum_read(sc, pg->checksumbis);
|
||||
pg->last_blk = exchange_with_mem_last_blk_read(sc);
|
||||
pg->last_dma = exchange_with_mem_last_dma_read(sc);
|
||||
pg->dma_wrdone = exchange_with_mem_dma_wrdone_read(sc);
|
||||
if (err != 0)
|
||||
err = EIO;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
err = dk_ioctl(&sc->dk, dev, cmd, data, flag, l);
|
||||
/*if (err2 != EPASSTHROUGH)
|
||||
@ -732,11 +665,10 @@ sbusfpga_sdram_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l
|
||||
else
|
||||
err = ENOTTY;*/
|
||||
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
dma_init(struct sbusfpga_sdram_softc *sc) {
|
||||
sc->dma_blk_size = exchange_with_mem_blk_size_read(sc);
|
||||
sc->dma_blk_base = exchange_with_mem_blk_base_read(sc);
|
||||
@ -771,7 +703,7 @@ dma_init(struct sbusfpga_sdram_softc *sc) {
|
||||
if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, sc->sc_dma_kva, SBUSFPGA_SDRAM_VAL_DMA_MAX_SZ, /* kernel space */ NULL,
|
||||
BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_WRITE)) {
|
||||
aprint_error_dev(sc->dk.sc_dev, "cannot load dma map");
|
||||
bus_dmamem_unmap(sc->sc_dmatag, &sc->sc_dma_kva, SBUSFPGA_SDRAM_VAL_DMA_MAX_SZ);
|
||||
bus_dmamem_unmap(sc->sc_dmatag, sc->sc_dma_kva, SBUSFPGA_SDRAM_VAL_DMA_MAX_SZ);
|
||||
bus_dmamem_free(sc->sc_dmatag, &sc->sc_segs, 1);
|
||||
bus_dmamap_destroy(sc->sc_dmatag, sc->sc_dmamap);
|
||||
return 0;
|
||||
@ -782,13 +714,27 @@ dma_init(struct sbusfpga_sdram_softc *sc) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dma_uninit(struct sbusfpga_sdram_softc *sc) {
|
||||
bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap);
|
||||
bus_dmamem_unmap(sc->sc_dmatag, sc->sc_dma_kva, SBUSFPGA_SDRAM_VAL_DMA_MAX_SZ);
|
||||
bus_dmamem_free(sc->sc_dmatag, &sc->sc_segs, 1);
|
||||
sc->sc_dma_kva = NULL;
|
||||
sc->sc_rsegs = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* tuned on my SPARCstation 20 with 25 MHz SBus & 2*SM61 */
|
||||
/* asynchronous would be better ... */
|
||||
#define DEF_BLK_DELAY 14
|
||||
|
||||
static inline unsigned long
|
||||
lfsr (unsigned long bits, unsigned long prev);
|
||||
int
|
||||
|
||||
static int
|
||||
dma_memtest(struct sbusfpga_sdram_softc *sc) {
|
||||
unsigned long *kva_ulong = (unsigned long*)sc->sc_dma_kva;
|
||||
unsigned long val;
|
||||
@ -995,7 +941,12 @@ static int sbusfpga_sdram_read_block(struct sbusfpga_sdram_softc *sc, const u_in
|
||||
int res = 0;
|
||||
int count;
|
||||
unsigned int check;
|
||||
|
||||
|
||||
if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, data, blkcnt * 512, /* kernel space */ NULL,
|
||||
BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_WRITE)) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, blkcnt * 512, BUS_DMASYNC_PREWRITE);
|
||||
|
||||
exchange_with_mem_blk_addr_write(sc, sc->dma_blk_base + (block * 512 / sc->dma_blk_size) );
|
||||
@ -1018,7 +969,8 @@ static int sbusfpga_sdram_read_block(struct sbusfpga_sdram_softc *sc, const u_in
|
||||
exchange_with_mem_blk_rem_read(sc),
|
||||
exchange_with_mem_last_blk_read(sc),
|
||||
exchange_with_mem_wr_tosdram_read(sc));
|
||||
return ENXIO;
|
||||
res = ENXIO;
|
||||
goto done;
|
||||
}
|
||||
#if 0
|
||||
else {
|
||||
@ -1040,11 +992,13 @@ static int sbusfpga_sdram_read_block(struct sbusfpga_sdram_softc *sc, const u_in
|
||||
exchange_with_mem_last_blk_read(sc),
|
||||
exchange_with_mem_last_dma_read(sc),
|
||||
exchange_with_mem_blk_rem_read(sc));
|
||||
return ENXIO;
|
||||
res = ENXIO;
|
||||
goto done;
|
||||
}
|
||||
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, blkcnt * 512, BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
memcpy(data, sc->sc_dma_kva, blkcnt * 512);
|
||||
done:
|
||||
bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap);
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -1054,9 +1008,12 @@ static int sbusfpga_sdram_write_block(struct sbusfpga_sdram_softc *sc, const u_i
|
||||
int res = 0;
|
||||
int count;
|
||||
unsigned int check;
|
||||
|
||||
memcpy(sc->sc_dma_kva, data, blkcnt * 512);
|
||||
|
||||
|
||||
if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, data, blkcnt * 512, /* kernel space */ NULL,
|
||||
BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_READ)) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, blkcnt * 512, BUS_DMASYNC_PREREAD);
|
||||
|
||||
exchange_with_mem_blk_addr_write(sc, sc->dma_blk_base + (block * 512 / sc->dma_blk_size) );
|
||||
@ -1079,7 +1036,8 @@ static int sbusfpga_sdram_write_block(struct sbusfpga_sdram_softc *sc, const u_i
|
||||
exchange_with_mem_blk_rem_read(sc),
|
||||
exchange_with_mem_last_blk_read(sc),
|
||||
exchange_with_mem_wr_tosdram_read(sc));
|
||||
return ENXIO;
|
||||
res = ENXIO;
|
||||
goto done;
|
||||
}
|
||||
#if 0
|
||||
else {
|
||||
@ -1101,10 +1059,13 @@ static int sbusfpga_sdram_write_block(struct sbusfpga_sdram_softc *sc, const u_i
|
||||
exchange_with_mem_last_blk_read(sc),
|
||||
exchange_with_mem_last_dma_read(sc),
|
||||
exchange_with_mem_blk_rem_read(sc));
|
||||
return ENXIO;
|
||||
res = ENXIO;
|
||||
goto done;
|
||||
}
|
||||
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, blkcnt * 512, BUS_DMASYNC_POSTREAD);
|
||||
|
||||
|
||||
done:
|
||||
bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@ -307,4 +307,7 @@
|
||||
|
||||
map-in-sdcard
|
||||
sdcard-init-full
|
||||
sdcard-good encode-int " sdcard-good" property
|
||||
max_rd_blk_len encode-int " max_rd_blk_len" property
|
||||
max_size_in_blk encode-int " max_size_in_blk" property
|
||||
map-out-sdcard
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user