forked from len0rd/rockbox
XduooX3 Sources WS changes
Change-Id: I17ae59e7ef0440756527ce50ab30f8bf34f79007
This commit is contained in:
parent
6296b220e5
commit
3867f0b959
5 changed files with 147 additions and 147 deletions
|
|
@ -149,20 +149,20 @@ static inline void jz_nand_read_buf8(void *buf, int count)
|
||||||
static void jz_nand_write_dma(void *source, unsigned int len, int bw)
|
static void jz_nand_write_dma(void *source, unsigned int len, int bw)
|
||||||
{
|
{
|
||||||
mutex_lock(&nand_dma_mtx);
|
mutex_lock(&nand_dma_mtx);
|
||||||
|
|
||||||
if(((unsigned int)source < 0xa0000000) && len)
|
if(((unsigned int)source < 0xa0000000) && len)
|
||||||
dma_cache_wback_inv((unsigned long)source, len);
|
dma_cache_wback_inv((unsigned long)source, len);
|
||||||
|
|
||||||
dma_enable();
|
dma_enable();
|
||||||
|
|
||||||
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES;
|
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES;
|
||||||
REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)source);
|
REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)source);
|
||||||
REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT);
|
REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT);
|
||||||
REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 16;
|
REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 16;
|
||||||
REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO;
|
REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO;
|
||||||
REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_16BYTE |
|
REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_16BYTE |
|
||||||
(bw == 8 ? DMAC_DCMD_DWDH_8 : DMAC_DCMD_DWDH_16));
|
(bw == 8 ? DMAC_DCMD_DWDH_8 : DMAC_DCMD_DWDH_16));
|
||||||
|
|
||||||
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
|
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
|
||||||
#if 1
|
#if 1
|
||||||
while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) )
|
while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) )
|
||||||
|
|
@ -173,26 +173,26 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
|
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
|
||||||
|
|
||||||
dma_disable();
|
dma_disable();
|
||||||
|
|
||||||
mutex_unlock(&nand_dma_mtx);
|
mutex_unlock(&nand_dma_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jz_nand_read_dma(void *target, unsigned int len, int bw)
|
static void jz_nand_read_dma(void *target, unsigned int len, int bw)
|
||||||
{
|
{
|
||||||
mutex_lock(&nand_dma_mtx);
|
mutex_lock(&nand_dma_mtx);
|
||||||
|
|
||||||
if(((unsigned int)target < 0xa0000000) && len)
|
if(((unsigned int)target < 0xa0000000) && len)
|
||||||
dma_cache_wback_inv((unsigned long)target, len);
|
dma_cache_wback_inv((unsigned long)target, len);
|
||||||
|
|
||||||
dma_enable();
|
dma_enable();
|
||||||
|
|
||||||
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES ;
|
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES ;
|
||||||
REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT);
|
REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT);
|
||||||
REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)target);
|
REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)target);
|
||||||
REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 4;
|
REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 4;
|
||||||
REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO;
|
REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO;
|
||||||
REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT |
|
REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT |
|
||||||
(bw == 8 ? DMAC_DCMD_SWDH_8 : DMAC_DCMD_SWDH_16));
|
(bw == 8 ? DMAC_DCMD_SWDH_8 : DMAC_DCMD_SWDH_16));
|
||||||
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
|
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
|
||||||
|
|
@ -205,9 +205,9 @@ static void jz_nand_read_dma(void *target, unsigned int len, int bw)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
|
//REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
|
||||||
|
|
||||||
dma_disable();
|
dma_disable();
|
||||||
|
|
||||||
mutex_unlock(&nand_dma_mtx);
|
mutex_unlock(&nand_dma_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,7 +224,7 @@ void DMA_CALLBACK(DMA_NAND_CHANNEL)(void)
|
||||||
|
|
||||||
if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_TT)
|
if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_TT)
|
||||||
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_TT;
|
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_TT;
|
||||||
|
|
||||||
semaphore_release(&nand_dma_complete);
|
semaphore_release(&nand_dma_complete);
|
||||||
}
|
}
|
||||||
#endif /* USE_DMA */
|
#endif /* USE_DMA */
|
||||||
|
|
@ -246,7 +246,7 @@ static inline void jz_nand_read_buf(void *buf, int count, int bw)
|
||||||
|
|
||||||
#ifdef USE_ECC
|
#ifdef USE_ECC
|
||||||
/*
|
/*
|
||||||
* Correct 1~9-bit errors in 512-bytes data
|
* Correct 1~9-bit errors in 512-bytes data
|
||||||
*/
|
*/
|
||||||
static void jz_rs_correct(unsigned char *dat, int idx, int mask)
|
static void jz_rs_correct(unsigned char *dat, int idx, int mask)
|
||||||
{
|
{
|
||||||
|
|
@ -349,7 +349,7 @@ static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst)
|
||||||
#endif
|
#endif
|
||||||
unsigned char *data_buf;
|
unsigned char *data_buf;
|
||||||
unsigned char oob_buf[nandp->oob_size];
|
unsigned char oob_buf[nandp->oob_size];
|
||||||
|
|
||||||
if(nand_address == 0)
|
if(nand_address == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
@ -484,28 +484,28 @@ static void jz_nand_disable(void)
|
||||||
* Enable NAND controller
|
* Enable NAND controller
|
||||||
*/
|
*/
|
||||||
static void jz_nand_enable(void)
|
static void jz_nand_enable(void)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
/* OF RE */
|
/* OF RE */
|
||||||
REG_GPIO_PXFUNS(1) = 0x1E018000; // __gpio_as_func0() start
|
REG_GPIO_PXFUNS(1) = 0x1E018000; // __gpio_as_func0() start
|
||||||
REG_GPIO_PXSELC(1) = 0x1E018000; // __gpio_as_func0() end
|
REG_GPIO_PXSELC(1) = 0x1E018000; // __gpio_as_func0() end
|
||||||
|
|
||||||
REG_GPIO_PXFUNS(2) = 0x3000<<16; // __gpio_as_func0() start
|
REG_GPIO_PXFUNS(2) = 0x3000<<16; // __gpio_as_func0() start
|
||||||
REG_GPIO_PXSELC(2) = 0x3000<<16; // __gpio_as_func0() end
|
REG_GPIO_PXSELC(2) = 0x3000<<16; // __gpio_as_func0() end
|
||||||
|
|
||||||
REG_GPIO_PXFUNC(2) = 0x4000<<16; // __gpio_port_as_input() start
|
REG_GPIO_PXFUNC(2) = 0x4000<<16; // __gpio_port_as_input() start
|
||||||
REG_GPIO_PXSELC(2) = 0x4000<<16;
|
REG_GPIO_PXSELC(2) = 0x4000<<16;
|
||||||
REG_GPIO_PXDIRC(2) = 0x4000<<16; // __gpio_port_as_input() end
|
REG_GPIO_PXDIRC(2) = 0x4000<<16; // __gpio_port_as_input() end
|
||||||
REG_GPIO_PXPES(2) = 0x4000<<16; // __gpio_disable_pull()
|
REG_GPIO_PXPES(2) = 0x4000<<16; // __gpio_disable_pull()
|
||||||
|
|
||||||
REG_GPIO_PXFUNS(1) = 0x40<<16; // __gpio_as_func0() start
|
REG_GPIO_PXFUNS(1) = 0x40<<16; // __gpio_as_func0() start
|
||||||
REG_GPIO_PXSELC(1) = 0x40<<16; // __gpio_as_func0() end
|
REG_GPIO_PXSELC(1) = 0x40<<16; // __gpio_as_func0() end
|
||||||
|
|
||||||
REG_EMC_SMCR1 = (REG_EMC_SMCR1 & 0xFF) | 0x4621200;
|
REG_EMC_SMCR1 = (REG_EMC_SMCR1 & 0xFF) | 0x4621200;
|
||||||
REG_EMC_SMCR2 = (REG_EMC_SMCR2 & 0xFF) | 0x4621200;
|
REG_EMC_SMCR2 = (REG_EMC_SMCR2 & 0xFF) | 0x4621200;
|
||||||
REG_EMC_SMCR3 = (REG_EMC_SMCR3 & 0xFF) | 0x4621200;
|
REG_EMC_SMCR3 = (REG_EMC_SMCR3 & 0xFF) | 0x4621200;
|
||||||
REG_EMC_SMCR4 = (REG_EMC_SMCR4 & 0xFF) | 0x4621200;
|
REG_EMC_SMCR4 = (REG_EMC_SMCR4 & 0xFF) | 0x4621200;
|
||||||
|
|
||||||
REG_EMC_SMCR1 = REG_EMC_SMCR2 = REG_EMC_SMCR3 = REG_EMC_SMCR4 = 0x6621200;
|
REG_EMC_SMCR1 = REG_EMC_SMCR2 = REG_EMC_SMCR3 = REG_EMC_SMCR4 = 0x6621200;
|
||||||
#else
|
#else
|
||||||
REG_EMC_SMCR1 = REG_EMC_SMCR2 = REG_EMC_SMCR3 = REG_EMC_SMCR4 = 0x04444400;
|
REG_EMC_SMCR1 = REG_EMC_SMCR2 = REG_EMC_SMCR3 = REG_EMC_SMCR4 = 0x04444400;
|
||||||
|
|
@ -543,13 +543,13 @@ static int jz_nand_init(void)
|
||||||
{
|
{
|
||||||
unsigned char cData[5];
|
unsigned char cData[5];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
jz_nand_enable();
|
jz_nand_enable();
|
||||||
|
|
||||||
for(i=0; i<4; i++)
|
for(i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
jz_nand_select(i);
|
jz_nand_select(i);
|
||||||
|
|
||||||
__nand_cmd(NAND_CMD_READID);
|
__nand_cmd(NAND_CMD_READID);
|
||||||
__nand_addr(NAND_CMD_READ0);
|
__nand_addr(NAND_CMD_READ0);
|
||||||
cData[0] = __nand_data8();
|
cData[0] = __nand_data8();
|
||||||
|
|
@ -557,17 +557,17 @@ static int jz_nand_init(void)
|
||||||
cData[2] = __nand_data8();
|
cData[2] = __nand_data8();
|
||||||
cData[3] = __nand_data8();
|
cData[3] = __nand_data8();
|
||||||
cData[4] = __nand_data8();
|
cData[4] = __nand_data8();
|
||||||
|
|
||||||
jz_nand_deselect(i);
|
jz_nand_deselect(i);
|
||||||
|
|
||||||
logf("NAND chip %d: 0x%x 0x%x 0x%x 0x%x 0x%x", i+1, cData[0], cData[1],
|
logf("NAND chip %d: 0x%x 0x%x 0x%x 0x%x 0x%x", i+1, cData[0], cData[1],
|
||||||
cData[2], cData[3], cData[4]);
|
cData[2], cData[3], cData[4]);
|
||||||
|
|
||||||
banks[i] = nand_identify(cData);
|
banks[i] = nand_identify(cData);
|
||||||
|
|
||||||
if(banks[i] != NULL)
|
if(banks[i] != NULL)
|
||||||
nr_banks++;
|
nr_banks++;
|
||||||
|
|
||||||
if(i == 0 && banks[i] == NULL)
|
if(i == 0 && banks[i] == NULL)
|
||||||
{
|
{
|
||||||
panicf("Unknown NAND flash chip: 0x%x 0x%x 0x%x 0x%x 0x%x", cData[0],
|
panicf("Unknown NAND flash chip: 0x%x 0x%x 0x%x 0x%x 0x%x", cData[0],
|
||||||
|
|
@ -576,17 +576,17 @@ static int jz_nand_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chip_info = banks[0];
|
chip_info = banks[0];
|
||||||
|
|
||||||
internal_param.bus_width = 8;
|
internal_param.bus_width = 8;
|
||||||
internal_param.row_cycle = chip_info->row_cycles;
|
internal_param.row_cycle = chip_info->row_cycles;
|
||||||
internal_param.page_size = chip_info->page_size;
|
internal_param.page_size = chip_info->page_size;
|
||||||
internal_param.oob_size = chip_info->spare_size;
|
internal_param.oob_size = chip_info->spare_size;
|
||||||
internal_param.page_per_block = chip_info->pages_per_block;
|
internal_param.page_per_block = chip_info->pages_per_block;
|
||||||
|
|
||||||
bank_size = chip_info->page_size * chip_info->blocks_per_bank / 512 * chip_info->pages_per_block;
|
bank_size = chip_info->page_size * chip_info->blocks_per_bank / 512 * chip_info->pages_per_block;
|
||||||
|
|
||||||
jz_nand_disable();
|
jz_nand_disable();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -594,7 +594,7 @@ int nand_init(void)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
static bool inited = false;
|
static bool inited = false;
|
||||||
|
|
||||||
if(!inited)
|
if(!inited)
|
||||||
{
|
{
|
||||||
res = jz_nand_init();
|
res = jz_nand_init();
|
||||||
|
|
@ -604,7 +604,7 @@ int nand_init(void)
|
||||||
semaphore_init(&nand_dma_complete, 1, 0);
|
semaphore_init(&nand_dma_complete, 1, 0);
|
||||||
system_enable_irq(DMA_IRQ(DMA_NAND_CHANNEL));
|
system_enable_irq(DMA_IRQ(DMA_NAND_CHANNEL));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inited = true;
|
inited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -615,7 +615,7 @@ static inline int read_sector(unsigned long start, unsigned int count,
|
||||||
void* buf, unsigned int chip_size)
|
void* buf, unsigned int chip_size)
|
||||||
{
|
{
|
||||||
register int ret;
|
register int ret;
|
||||||
|
|
||||||
if(UNLIKELY(start % chip_size == 0 && count == chip_size))
|
if(UNLIKELY(start % chip_size == 0 && count == chip_size))
|
||||||
ret = jz_nand_read_page(start / chip_size, buf);
|
ret = jz_nand_read_page(start / chip_size, buf);
|
||||||
else
|
else
|
||||||
|
|
@ -623,7 +623,7 @@ static inline int read_sector(unsigned long start, unsigned int count,
|
||||||
ret = jz_nand_read_page(start / chip_size, temp_page);
|
ret = jz_nand_read_page(start / chip_size, temp_page);
|
||||||
memcpy(buf, temp_page + (start % chip_size), count);
|
memcpy(buf, temp_page + (start % chip_size), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -635,13 +635,13 @@ int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* bu
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned int i, _count, chip_size = chip_info->page_size;
|
unsigned int i, _count, chip_size = chip_info->page_size;
|
||||||
unsigned long _start;
|
unsigned long _start;
|
||||||
|
|
||||||
logf("start");
|
logf("start");
|
||||||
mutex_lock(&nand_mtx);
|
mutex_lock(&nand_mtx);
|
||||||
|
|
||||||
_start = start << 9;
|
_start = start << 9;
|
||||||
_count = count << 9;
|
_count = count << 9;
|
||||||
|
|
||||||
if(_count <= chip_size)
|
if(_count <= chip_size)
|
||||||
{
|
{
|
||||||
jz_nand_select(start / bank_size);
|
jz_nand_select(start / bank_size);
|
||||||
|
|
@ -653,19 +653,19 @@ int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* bu
|
||||||
for(i=0; i<_count && ret==0; i+=chip_size)
|
for(i=0; i<_count && ret==0; i+=chip_size)
|
||||||
{
|
{
|
||||||
jz_nand_select((start+(i>>9)) / bank_size);
|
jz_nand_select((start+(i>>9)) / bank_size);
|
||||||
|
|
||||||
ret = read_sector(_start+i, (_count-i < chip_size ?
|
ret = read_sector(_start+i, (_count-i < chip_size ?
|
||||||
_count-i : chip_size),
|
_count-i : chip_size),
|
||||||
buf+i, chip_size);
|
buf+i, chip_size);
|
||||||
|
|
||||||
jz_nand_deselect((start+(i>>9)) / bank_size);
|
jz_nand_deselect((start+(i>>9)) / bank_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&nand_mtx);
|
mutex_unlock(&nand_mtx);
|
||||||
|
|
||||||
logf("nand_read_sectors(%ld, %d, 0x%x): %d", start, count, (int)buf, ret);
|
logf("nand_read_sectors(%ld, %d, 0x%x): %d", start, count, (int)buf, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -732,7 +732,7 @@ void nand_get_info(IF_MV(int drive,) struct storage_info *info)
|
||||||
#ifdef HAVE_MULTIVOLUME
|
#ifdef HAVE_MULTIVOLUME
|
||||||
(void)drive;
|
(void)drive;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* firmware version */
|
/* firmware version */
|
||||||
info->revision="0.00";
|
info->revision="0.00";
|
||||||
|
|
||||||
|
|
@ -750,7 +750,7 @@ int nand_num_drives(int first_drive)
|
||||||
{
|
{
|
||||||
/* We don't care which logical drive number(s) we have been assigned */
|
/* We don't care which logical drive number(s) we have been assigned */
|
||||||
(void)first_drive;
|
(void)first_drive;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -148,20 +148,20 @@ static inline void jz_nand_read_buf8(void *buf, int count)
|
||||||
static void jz_nand_write_dma(void *source, unsigned int len, int bw)
|
static void jz_nand_write_dma(void *source, unsigned int len, int bw)
|
||||||
{
|
{
|
||||||
mutex_lock(&nand_dma_mtx);
|
mutex_lock(&nand_dma_mtx);
|
||||||
|
|
||||||
if(((unsigned int)source < 0xa0000000) && len)
|
if(((unsigned int)source < 0xa0000000) && len)
|
||||||
dma_cache_wback_inv((unsigned long)source, len);
|
dma_cache_wback_inv((unsigned long)source, len);
|
||||||
|
|
||||||
dma_enable();
|
dma_enable();
|
||||||
|
|
||||||
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES;
|
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES;
|
||||||
REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)source);
|
REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)source);
|
||||||
REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT);
|
REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT);
|
||||||
REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 16;
|
REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 16;
|
||||||
REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO;
|
REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO;
|
||||||
REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_16BYTE |
|
REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_16BYTE |
|
||||||
(bw == 8 ? DMAC_DCMD_DWDH_8 : DMAC_DCMD_DWDH_16));
|
(bw == 8 ? DMAC_DCMD_DWDH_8 : DMAC_DCMD_DWDH_16));
|
||||||
|
|
||||||
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
|
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
|
||||||
#if 1
|
#if 1
|
||||||
while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) )
|
while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) )
|
||||||
|
|
@ -172,26 +172,26 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
|
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
|
||||||
|
|
||||||
dma_disable();
|
dma_disable();
|
||||||
|
|
||||||
mutex_unlock(&nand_dma_mtx);
|
mutex_unlock(&nand_dma_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jz_nand_read_dma(void *target, unsigned int len, int bw)
|
static void jz_nand_read_dma(void *target, unsigned int len, int bw)
|
||||||
{
|
{
|
||||||
mutex_lock(&nand_dma_mtx);
|
mutex_lock(&nand_dma_mtx);
|
||||||
|
|
||||||
if(((unsigned int)target < 0xa0000000) && len)
|
if(((unsigned int)target < 0xa0000000) && len)
|
||||||
dma_cache_wback_inv((unsigned long)target, len);
|
dma_cache_wback_inv((unsigned long)target, len);
|
||||||
|
|
||||||
dma_enable();
|
dma_enable();
|
||||||
|
|
||||||
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES ;
|
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES ;
|
||||||
REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT);
|
REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT);
|
||||||
REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)target);
|
REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)target);
|
||||||
REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 4;
|
REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 4;
|
||||||
REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO;
|
REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO;
|
||||||
REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT |
|
REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT |
|
||||||
(bw == 8 ? DMAC_DCMD_SWDH_8 : DMAC_DCMD_SWDH_16));
|
(bw == 8 ? DMAC_DCMD_SWDH_8 : DMAC_DCMD_SWDH_16));
|
||||||
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
|
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
|
||||||
|
|
@ -204,9 +204,9 @@ static void jz_nand_read_dma(void *target, unsigned int len, int bw)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
|
//REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
|
||||||
|
|
||||||
dma_disable();
|
dma_disable();
|
||||||
|
|
||||||
mutex_unlock(&nand_dma_mtx);
|
mutex_unlock(&nand_dma_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,7 +223,7 @@ void DMA_CALLBACK(DMA_NAND_CHANNEL)(void)
|
||||||
|
|
||||||
if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_TT)
|
if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_TT)
|
||||||
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_TT;
|
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_TT;
|
||||||
|
|
||||||
semaphore_release(&nand_dma_complete);
|
semaphore_release(&nand_dma_complete);
|
||||||
}
|
}
|
||||||
#endif /* USE_DMA */
|
#endif /* USE_DMA */
|
||||||
|
|
@ -245,7 +245,7 @@ static inline void jz_nand_read_buf(void *buf, int count, int bw)
|
||||||
|
|
||||||
#ifdef USE_ECC
|
#ifdef USE_ECC
|
||||||
/*
|
/*
|
||||||
* Correct 1~9-bit errors in 512-bytes data
|
* Correct 1~9-bit errors in 512-bytes data
|
||||||
*/
|
*/
|
||||||
static void jz_rs_correct(unsigned char *dat, int idx, int mask)
|
static void jz_rs_correct(unsigned char *dat, int idx, int mask)
|
||||||
{
|
{
|
||||||
|
|
@ -348,7 +348,7 @@ static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst)
|
||||||
#endif
|
#endif
|
||||||
unsigned char *data_buf;
|
unsigned char *data_buf;
|
||||||
unsigned char oob_buf[nandp->oob_size];
|
unsigned char oob_buf[nandp->oob_size];
|
||||||
|
|
||||||
page_size = nandp->page_size;
|
page_size = nandp->page_size;
|
||||||
oob_size = nandp->oob_size;
|
oob_size = nandp->oob_size;
|
||||||
row_cycle = nandp->row_cycle;
|
row_cycle = nandp->row_cycle;
|
||||||
|
|
@ -472,9 +472,9 @@ static int jz_nand_init(void)
|
||||||
__gpio_as_nand_16bit(1);
|
__gpio_as_nand_16bit(1);
|
||||||
|
|
||||||
REG_NEMC_SMCR1 = CFG_NAND_SMCR1 | 0x40;
|
REG_NEMC_SMCR1 = CFG_NAND_SMCR1 | 0x40;
|
||||||
|
|
||||||
__nand_select();
|
__nand_select();
|
||||||
|
|
||||||
__nand_cmd(NAND_CMD_READID);
|
__nand_cmd(NAND_CMD_READID);
|
||||||
__nand_addr(NAND_CMD_READ0);
|
__nand_addr(NAND_CMD_READ0);
|
||||||
cData[0] = __nand_data8();
|
cData[0] = __nand_data8();
|
||||||
|
|
@ -482,14 +482,14 @@ static int jz_nand_init(void)
|
||||||
cData[2] = __nand_data8();
|
cData[2] = __nand_data8();
|
||||||
cData[3] = __nand_data8();
|
cData[3] = __nand_data8();
|
||||||
cData[4] = __nand_data8();
|
cData[4] = __nand_data8();
|
||||||
|
|
||||||
__nand_deselect();
|
__nand_deselect();
|
||||||
|
|
||||||
logf("NAND chip %d: 0x%x 0x%x 0x%x 0x%x 0x%x", i+1, cData[0], cData[1],
|
logf("NAND chip %d: 0x%x 0x%x 0x%x 0x%x 0x%x", i+1, cData[0], cData[1],
|
||||||
cData[2], cData[3], cData[4]);
|
cData[2], cData[3], cData[4]);
|
||||||
|
|
||||||
bank = nand_identify(cData);
|
bank = nand_identify(cData);
|
||||||
|
|
||||||
if(bank == NULL)
|
if(bank == NULL)
|
||||||
{
|
{
|
||||||
panicf("Unknown NAND flash chip: 0x%x 0x%x 0x%x 0x%x 0x%x", cData[0],
|
panicf("Unknown NAND flash chip: 0x%x 0x%x 0x%x 0x%x 0x%x", cData[0],
|
||||||
|
|
@ -498,16 +498,16 @@ static int jz_nand_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
chip_info = bank;
|
chip_info = bank;
|
||||||
|
|
||||||
internal_param.bus_width = 16;
|
internal_param.bus_width = 16;
|
||||||
internal_param.row_cycle = chip_info->row_cycles;
|
internal_param.row_cycle = chip_info->row_cycles;
|
||||||
internal_param.page_size = chip_info->page_size;
|
internal_param.page_size = chip_info->page_size;
|
||||||
internal_param.oob_size = chip_info->spare_size;
|
internal_param.oob_size = chip_info->spare_size;
|
||||||
internal_param.page_per_block = chip_info->pages_per_block;
|
internal_param.page_per_block = chip_info->pages_per_block;
|
||||||
internal_param.bad_block_pos = 0;
|
internal_param.bad_block_pos = 0;
|
||||||
|
|
||||||
nand_size = ((chip_info->page_size * chip_info->blocks_per_bank * chip_info->pages_per_block) - 0x200000) / 512;
|
nand_size = ((chip_info->page_size * chip_info->blocks_per_bank * chip_info->pages_per_block) - 0x200000) / 512;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -515,7 +515,7 @@ int nand_init(void)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
static bool inited = false;
|
static bool inited = false;
|
||||||
|
|
||||||
if(!inited)
|
if(!inited)
|
||||||
{
|
{
|
||||||
res = jz_nand_init();
|
res = jz_nand_init();
|
||||||
|
|
@ -525,7 +525,7 @@ int nand_init(void)
|
||||||
semaphore_init(&nand_dma_complete, 1, 0);
|
semaphore_init(&nand_dma_complete, 1, 0);
|
||||||
system_enable_irq(DMA_IRQ(DMA_NAND_CHANNEL));
|
system_enable_irq(DMA_IRQ(DMA_NAND_CHANNEL));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inited = true;
|
inited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -536,7 +536,7 @@ static inline int read_sector(unsigned long start, unsigned int count,
|
||||||
void* buf, unsigned int chip_size)
|
void* buf, unsigned int chip_size)
|
||||||
{
|
{
|
||||||
register int ret;
|
register int ret;
|
||||||
|
|
||||||
if(UNLIKELY(start % chip_size == 0 && count == chip_size))
|
if(UNLIKELY(start % chip_size == 0 && count == chip_size))
|
||||||
ret = jz_nand_read_page(start / chip_size, buf);
|
ret = jz_nand_read_page(start / chip_size, buf);
|
||||||
else
|
else
|
||||||
|
|
@ -544,7 +544,7 @@ static inline int read_sector(unsigned long start, unsigned int count,
|
||||||
ret = jz_nand_read_page(start / chip_size, temp_page);
|
ret = jz_nand_read_page(start / chip_size, temp_page);
|
||||||
memcpy(buf, temp_page + (start % chip_size), count);
|
memcpy(buf, temp_page + (start % chip_size), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -559,7 +559,7 @@ static inline int write_sector(unsigned long start, unsigned int count,
|
||||||
(void)chip_size;
|
(void)chip_size;
|
||||||
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -571,20 +571,20 @@ int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* bu
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned int _count, chip_size = chip_info->page_size;
|
unsigned int _count, chip_size = chip_info->page_size;
|
||||||
unsigned long _start;
|
unsigned long _start;
|
||||||
|
|
||||||
logf("start");
|
logf("start");
|
||||||
mutex_lock(&nand_mtx);
|
mutex_lock(&nand_mtx);
|
||||||
|
|
||||||
_start = start << 9;
|
_start = start << 9;
|
||||||
_start += 0x200000; /* skip BL */
|
_start += 0x200000; /* skip BL */
|
||||||
_count = count << 9;
|
_count = count << 9;
|
||||||
|
|
||||||
__nand_select();
|
__nand_select();
|
||||||
ret = read_sector(_start, _count, buf, chip_size);
|
ret = read_sector(_start, _count, buf, chip_size);
|
||||||
__nand_deselect();
|
__nand_deselect();
|
||||||
|
|
||||||
mutex_unlock(&nand_mtx);
|
mutex_unlock(&nand_mtx);
|
||||||
|
|
||||||
logf("nand_read_sectors(%ld, %d, 0x%x): %d", start, count, (int)buf, ret);
|
logf("nand_read_sectors(%ld, %d, 0x%x): %d", start, count, (int)buf, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -598,20 +598,20 @@ int nand_write_sectors(IF_MV(int drive,) unsigned long start, int count, const v
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned int _count, chip_size = chip_info->page_size;
|
unsigned int _count, chip_size = chip_info->page_size;
|
||||||
unsigned long _start;
|
unsigned long _start;
|
||||||
|
|
||||||
logf("start");
|
logf("start");
|
||||||
mutex_lock(&nand_mtx);
|
mutex_lock(&nand_mtx);
|
||||||
|
|
||||||
_start = start << 9;
|
_start = start << 9;
|
||||||
_start += chip_info->page_size * chip_info->pages_per_block; /* skip BL */
|
_start += chip_info->page_size * chip_info->pages_per_block; /* skip BL */
|
||||||
_count = count << 9;
|
_count = count << 9;
|
||||||
|
|
||||||
__nand_select();
|
__nand_select();
|
||||||
ret = write_sector(_start, _count, buf, chip_size);
|
ret = write_sector(_start, _count, buf, chip_size);
|
||||||
__nand_deselect();
|
__nand_deselect();
|
||||||
|
|
||||||
mutex_unlock(&nand_mtx);
|
mutex_unlock(&nand_mtx);
|
||||||
|
|
||||||
logf("nand_write_sectors(%ld, %d, 0x%x): %d", start, count, (int)buf, ret);
|
logf("nand_write_sectors(%ld, %d, 0x%x): %d", start, count, (int)buf, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -667,7 +667,7 @@ void nand_get_info(IF_MV(int drive,) struct storage_info *info)
|
||||||
#ifdef HAVE_MULTIVOLUME
|
#ifdef HAVE_MULTIVOLUME
|
||||||
(void)drive;
|
(void)drive;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* firmware version */
|
/* firmware version */
|
||||||
info->revision="0.00";
|
info->revision="0.00";
|
||||||
|
|
||||||
|
|
@ -685,7 +685,7 @@ int nand_num_drives(int first_drive)
|
||||||
{
|
{
|
||||||
/* We don't care which logical drive number(s) we have been assigned */
|
/* We don't care which logical drive number(s) we have been assigned */
|
||||||
(void)first_drive;
|
(void)first_drive;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,14 @@ void memset(void *target, unsigned char c, size_t len)
|
||||||
int ch = DMA_CHANNEL;
|
int ch = DMA_CHANNEL;
|
||||||
unsigned int d;
|
unsigned int d;
|
||||||
unsigned char *dp;
|
unsigned char *dp;
|
||||||
|
|
||||||
if(len < 32)
|
if(len < 32)
|
||||||
_memset(target,c,len);
|
_memset(target,c,len);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(((unsigned int)target < 0xa0000000) && len)
|
if(((unsigned int)target < 0xa0000000) && len)
|
||||||
dma_cache_wback_inv((unsigned long)target, len);
|
dma_cache_wback_inv((unsigned long)target, len);
|
||||||
|
|
||||||
dp = (unsigned char *)((unsigned int)(&d) | 0xa0000000);
|
dp = (unsigned char *)((unsigned int)(&d) | 0xa0000000);
|
||||||
*(dp + 0) = c;
|
*(dp + 0) = c;
|
||||||
*(dp + 1) = c;
|
*(dp + 1) = c;
|
||||||
|
|
@ -45,16 +45,16 @@ void memset(void *target, unsigned char c, size_t len)
|
||||||
REG_DMAC_DRSR(ch) = DMAC_DRSR_RS_AUTO;
|
REG_DMAC_DRSR(ch) = DMAC_DRSR_RS_AUTO;
|
||||||
REG_DMAC_DCMD(ch) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE;
|
REG_DMAC_DCMD(ch) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE;
|
||||||
REG_DMAC_DCCSR(ch) = DMAC_DCCSR_EN | DMAC_DCCSR_NDES;
|
REG_DMAC_DCCSR(ch) = DMAC_DCCSR_EN | DMAC_DCCSR_NDES;
|
||||||
|
|
||||||
while (REG_DMAC_DTCR(ch));
|
while (REG_DMAC_DTCR(ch));
|
||||||
if(len % 32)
|
if(len % 32)
|
||||||
{
|
{
|
||||||
dp = (unsigned char *)((unsigned int)target + (len & (32 - 1)));
|
dp = (unsigned char *)((unsigned int)target + (len & (32 - 1)));
|
||||||
for(d = 0;d < (len % 32); d++)
|
for(d = 0;d < (len % 32); d++)
|
||||||
*dp++ = c;
|
*dp++ = c;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void memset16(void *target, unsigned short c, size_t len)
|
void memset16(void *target, unsigned short c, size_t len)
|
||||||
|
|
@ -62,14 +62,14 @@ void memset16(void *target, unsigned short c, size_t len)
|
||||||
int ch = DMA_CHANNEL;
|
int ch = DMA_CHANNEL;
|
||||||
unsigned short d;
|
unsigned short d;
|
||||||
unsigned short *dp;
|
unsigned short *dp;
|
||||||
|
|
||||||
if(len < 32)
|
if(len < 32)
|
||||||
_memset16(target,c,len);
|
_memset16(target,c,len);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(((unsigned int)target < 0xa0000000) && len)
|
if(((unsigned int)target < 0xa0000000) && len)
|
||||||
dma_cache_wback_inv((unsigned long)target, len);
|
dma_cache_wback_inv((unsigned long)target, len);
|
||||||
|
|
||||||
d = c;
|
d = c;
|
||||||
REG_DMAC_DSAR(ch) = PHYSADDR((unsigned long)&d);
|
REG_DMAC_DSAR(ch) = PHYSADDR((unsigned long)&d);
|
||||||
REG_DMAC_DTAR(ch) = PHYSADDR((unsigned long)target);
|
REG_DMAC_DTAR(ch) = PHYSADDR((unsigned long)target);
|
||||||
|
|
@ -77,7 +77,7 @@ void memset16(void *target, unsigned short c, size_t len)
|
||||||
REG_DMAC_DRSR(ch) = DMAC_DRSR_RS_AUTO;
|
REG_DMAC_DRSR(ch) = DMAC_DRSR_RS_AUTO;
|
||||||
REG_DMAC_DCMD(ch) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_32BYTE;
|
REG_DMAC_DCMD(ch) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_32BYTE;
|
||||||
REG_DMAC_DCCSR(ch) = DMAC_DCCSR_EN | DMAC_DCCSR_NDES;
|
REG_DMAC_DCCSR(ch) = DMAC_DCCSR_EN | DMAC_DCCSR_NDES;
|
||||||
|
|
||||||
while (REG_DMAC_DTCR(ch));
|
while (REG_DMAC_DTCR(ch));
|
||||||
if(len % 32)
|
if(len % 32)
|
||||||
{
|
{
|
||||||
|
|
@ -85,29 +85,29 @@ void memset16(void *target, unsigned short c, size_t len)
|
||||||
for(d = 0; d < (len % 32); d++)
|
for(d = 0; d < (len % 32); d++)
|
||||||
*dp++ = c;
|
*dp++ = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void memcpy(void *target, const void *source, size_t len)
|
void memcpy(void *target, const void *source, size_t len)
|
||||||
{
|
{
|
||||||
int ch = DMA_CHANNEL;
|
int ch = DMA_CHANNEL;
|
||||||
unsigned char *dp;
|
unsigned char *dp;
|
||||||
|
|
||||||
if(len < 4)
|
if(len < 4)
|
||||||
_memcpy(target, source, len);
|
_memcpy(target, source, len);
|
||||||
|
|
||||||
if(((unsigned int)source < 0xa0000000) && len)
|
if(((unsigned int)source < 0xa0000000) && len)
|
||||||
dma_cache_wback_inv((unsigned long)source, len);
|
dma_cache_wback_inv((unsigned long)source, len);
|
||||||
|
|
||||||
if(((unsigned int)target < 0xa0000000) && len)
|
if(((unsigned int)target < 0xa0000000) && len)
|
||||||
dma_cache_wback_inv((unsigned long)target, len);
|
dma_cache_wback_inv((unsigned long)target, len);
|
||||||
|
|
||||||
REG_DMAC_DSAR(ch) = PHYSADDR((unsigned long)source);
|
REG_DMAC_DSAR(ch) = PHYSADDR((unsigned long)source);
|
||||||
REG_DMAC_DTAR(ch) = PHYSADDR((unsigned long)target);
|
REG_DMAC_DTAR(ch) = PHYSADDR((unsigned long)target);
|
||||||
REG_DMAC_DTCR(ch) = len / 4;
|
REG_DMAC_DTCR(ch) = len / 4;
|
||||||
REG_DMAC_DRSR(ch) = DMAC_DRSR_RS_AUTO;
|
REG_DMAC_DRSR(ch) = DMAC_DRSR_RS_AUTO;
|
||||||
REG_DMAC_DCMD(ch) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT;
|
REG_DMAC_DCMD(ch) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT;
|
||||||
|
|
||||||
REG_DMAC_DCCSR(ch) = DMAC_DCCSR_EN | DMAC_DCCSR_NDES;
|
REG_DMAC_DCCSR(ch) = DMAC_DCCSR_EN | DMAC_DCCSR_NDES;
|
||||||
while (REG_DMAC_DTCR(ch));
|
while (REG_DMAC_DTCR(ch));
|
||||||
if(len % 4)
|
if(len % 4)
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ void lcd_clock_disable(void)
|
||||||
void lcd_init_device(void)
|
void lcd_init_device(void)
|
||||||
{
|
{
|
||||||
lcd_init_controller();
|
lcd_init_controller();
|
||||||
|
|
||||||
lcd_is_on = true;
|
lcd_is_on = true;
|
||||||
mutex_init(&lcd_mtx);
|
mutex_init(&lcd_mtx);
|
||||||
semaphore_init(&lcd_wkup, 1, 0);
|
semaphore_init(&lcd_wkup, 1, 0);
|
||||||
|
|
@ -93,41 +93,41 @@ void lcd_update_rect(int x, int y, int width, int height)
|
||||||
width = LCD_WIDTH;
|
width = LCD_WIDTH;
|
||||||
|
|
||||||
mutex_lock(&lcd_mtx);
|
mutex_lock(&lcd_mtx);
|
||||||
|
|
||||||
lcd_clock_enable();
|
lcd_clock_enable();
|
||||||
|
|
||||||
lcd_set_target(x, y, width, height);
|
lcd_set_target(x, y, width, height);
|
||||||
|
|
||||||
dma_enable();
|
dma_enable();
|
||||||
|
|
||||||
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) = DMAC_DCCSR_NDES;
|
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) = DMAC_DCCSR_NDES;
|
||||||
REG_DMAC_DSAR(DMA_LCD_CHANNEL) = PHYSADDR((unsigned long)FBADDR(x,y));
|
REG_DMAC_DSAR(DMA_LCD_CHANNEL) = PHYSADDR((unsigned long)FBADDR(x,y));
|
||||||
REG_DMAC_DRSR(DMA_LCD_CHANNEL) = DMAC_DRSR_RS_SLCD;
|
REG_DMAC_DRSR(DMA_LCD_CHANNEL) = DMAC_DRSR_RS_SLCD;
|
||||||
REG_DMAC_DTAR(DMA_LCD_CHANNEL) = PHYSADDR(SLCD_FIFO);
|
REG_DMAC_DTAR(DMA_LCD_CHANNEL) = PHYSADDR(SLCD_FIFO);
|
||||||
REG_DMAC_DTCR(DMA_LCD_CHANNEL) = (width * height) >> 3;
|
REG_DMAC_DTCR(DMA_LCD_CHANNEL) = (width * height) >> 3;
|
||||||
|
|
||||||
REG_DMAC_DCMD(DMA_LCD_CHANNEL) = ( DMAC_DCMD_SAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32
|
REG_DMAC_DCMD(DMA_LCD_CHANNEL) = ( DMAC_DCMD_SAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32
|
||||||
| DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BYTE );
|
| DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BYTE );
|
||||||
|
|
||||||
__dcache_writeback_all(); /* Size of framebuffer is way bigger than cache size.
|
__dcache_writeback_all(); /* Size of framebuffer is way bigger than cache size.
|
||||||
We need to find a way to make the framebuffer uncached, so this statement can get removed. */
|
We need to find a way to make the framebuffer uncached, so this statement can get removed. */
|
||||||
|
|
||||||
while(REG_SLCD_STATE & SLCD_STATE_BUSY);
|
while(REG_SLCD_STATE & SLCD_STATE_BUSY);
|
||||||
REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN; /* Enable SLCD DMA support */
|
REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN; /* Enable SLCD DMA support */
|
||||||
|
|
||||||
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
|
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
|
||||||
REG_DMAC_DCMD(DMA_LCD_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */
|
REG_DMAC_DCMD(DMA_LCD_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */
|
||||||
|
|
||||||
semaphore_wait(&lcd_wkup, TIMEOUT_BLOCK); /* Sleeping in lcd_update() should be safe */
|
semaphore_wait(&lcd_wkup, TIMEOUT_BLOCK); /* Sleeping in lcd_update() should be safe */
|
||||||
|
|
||||||
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
|
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
|
||||||
dma_disable();
|
dma_disable();
|
||||||
|
|
||||||
while(REG_SLCD_STATE & SLCD_STATE_BUSY);
|
while(REG_SLCD_STATE & SLCD_STATE_BUSY);
|
||||||
REG_SLCD_CTRL &= ~SLCD_CTRL_DMA_EN; /* Disable SLCD DMA support */
|
REG_SLCD_CTRL &= ~SLCD_CTRL_DMA_EN; /* Disable SLCD DMA support */
|
||||||
|
|
||||||
lcd_clock_disable();
|
lcd_clock_disable();
|
||||||
|
|
||||||
mutex_unlock(&lcd_mtx);
|
mutex_unlock(&lcd_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,7 +144,7 @@ void DMA_CALLBACK(DMA_LCD_CHANNEL)(void)
|
||||||
|
|
||||||
if (REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT)
|
if (REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT)
|
||||||
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_TT;
|
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_TT;
|
||||||
|
|
||||||
semaphore_release(&lcd_wkup);
|
semaphore_release(&lcd_wkup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,7 +154,7 @@ void lcd_update(void)
|
||||||
{
|
{
|
||||||
if(!lcd_is_on)
|
if(!lcd_is_on)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
|
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,55 +165,55 @@ void lcd_blit_yuv(unsigned char * const src[3],
|
||||||
{
|
{
|
||||||
unsigned char const * yuv_src[3];
|
unsigned char const * yuv_src[3];
|
||||||
register off_t z;
|
register off_t z;
|
||||||
|
|
||||||
if(!lcd_is_on)
|
if(!lcd_is_on)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
z = stride * src_y;
|
z = stride * src_y;
|
||||||
yuv_src[0] = src[0] + z + src_x;
|
yuv_src[0] = src[0] + z + src_x;
|
||||||
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
|
yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
|
||||||
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
|
||||||
|
|
||||||
__dcache_writeback_all();
|
__dcache_writeback_all();
|
||||||
|
|
||||||
__cpm_start_ipu();
|
__cpm_start_ipu();
|
||||||
|
|
||||||
IPU_STOP_IPU();
|
IPU_STOP_IPU();
|
||||||
IPU_RESET_IPU();
|
IPU_RESET_IPU();
|
||||||
IPU_CLEAR_END_FLAG();
|
IPU_CLEAR_END_FLAG();
|
||||||
|
|
||||||
IPU_DISABLE_RSIZE();
|
IPU_DISABLE_RSIZE();
|
||||||
IPU_DISABLE_IRQ();
|
IPU_DISABLE_IRQ();
|
||||||
|
|
||||||
IPU_SET_INFMT(INFMT_YUV420);
|
IPU_SET_INFMT(INFMT_YUV420);
|
||||||
IPU_SET_OUTFMT(OUTFMT_RGB565);
|
IPU_SET_OUTFMT(OUTFMT_RGB565);
|
||||||
|
|
||||||
IPU_SET_IN_FM(width, height);
|
IPU_SET_IN_FM(width, height);
|
||||||
IPU_SET_Y_STRIDE(stride);
|
IPU_SET_Y_STRIDE(stride);
|
||||||
IPU_SET_UV_STRIDE(stride, stride);
|
IPU_SET_UV_STRIDE(stride, stride);
|
||||||
|
|
||||||
IPU_SET_Y_ADDR(PHYSADDR((unsigned long)yuv_src[0]));
|
IPU_SET_Y_ADDR(PHYSADDR((unsigned long)yuv_src[0]));
|
||||||
IPU_SET_U_ADDR(PHYSADDR((unsigned long)yuv_src[1]));
|
IPU_SET_U_ADDR(PHYSADDR((unsigned long)yuv_src[1]));
|
||||||
IPU_SET_V_ADDR(PHYSADDR((unsigned long)yuv_src[2]));
|
IPU_SET_V_ADDR(PHYSADDR((unsigned long)yuv_src[2]));
|
||||||
IPU_SET_OUT_ADDR(PHYSADDR((unsigned long)FBADDR(y,x)));
|
IPU_SET_OUT_ADDR(PHYSADDR((unsigned long)FBADDR(y,x)));
|
||||||
|
|
||||||
IPU_SET_OUT_FM(height, width);
|
IPU_SET_OUT_FM(height, width);
|
||||||
IPU_SET_OUT_STRIDE(height);
|
IPU_SET_OUT_STRIDE(height);
|
||||||
|
|
||||||
IPU_SET_CSC_C0_COEF(YUV_CSC_C0);
|
IPU_SET_CSC_C0_COEF(YUV_CSC_C0);
|
||||||
IPU_SET_CSC_C1_COEF(YUV_CSC_C1);
|
IPU_SET_CSC_C1_COEF(YUV_CSC_C1);
|
||||||
IPU_SET_CSC_C2_COEF(YUV_CSC_C2);
|
IPU_SET_CSC_C2_COEF(YUV_CSC_C2);
|
||||||
IPU_SET_CSC_C3_COEF(YUV_CSC_C3);
|
IPU_SET_CSC_C3_COEF(YUV_CSC_C3);
|
||||||
IPU_SET_CSC_C4_COEF(YUV_CSC_C4);
|
IPU_SET_CSC_C4_COEF(YUV_CSC_C4);
|
||||||
|
|
||||||
IPU_RUN_IPU();
|
IPU_RUN_IPU();
|
||||||
|
|
||||||
while(!(IPU_POLLING_END_FLAG()) && IPU_IS_ENABLED());
|
while(!(IPU_POLLING_END_FLAG()) && IPU_IS_ENABLED());
|
||||||
|
|
||||||
IPU_CLEAR_END_FLAG();
|
IPU_CLEAR_END_FLAG();
|
||||||
IPU_STOP_IPU();
|
IPU_STOP_IPU();
|
||||||
IPU_RESET_IPU();
|
IPU_RESET_IPU();
|
||||||
|
|
||||||
__cpm_stop_ipu();
|
__cpm_stop_ipu();
|
||||||
|
|
||||||
/* YUV speed is limited by LCD speed */
|
/* YUV speed is limited by LCD speed */
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ static void local_flush_tlb_all(void)
|
||||||
unsigned long old_ctx;
|
unsigned long old_ctx;
|
||||||
int entry;
|
int entry;
|
||||||
unsigned int old_irq = disable_irq_save();
|
unsigned int old_irq = disable_irq_save();
|
||||||
|
|
||||||
/* Save old context and create impossible VPN2 value */
|
/* Save old context and create impossible VPN2 value */
|
||||||
old_ctx = read_c0_entryhi();
|
old_ctx = read_c0_entryhi();
|
||||||
write_c0_entrylo0(0);
|
write_c0_entrylo0(0);
|
||||||
|
|
@ -66,7 +66,7 @@ static void local_flush_tlb_all(void)
|
||||||
}
|
}
|
||||||
BARRIER;
|
BARRIER;
|
||||||
write_c0_entryhi(old_ctx);
|
write_c0_entryhi(old_ctx);
|
||||||
|
|
||||||
restore_irq(old_irq);
|
restore_irq(old_irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,7 +77,7 @@ static void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
|
||||||
unsigned long old_pagemask;
|
unsigned long old_pagemask;
|
||||||
unsigned long old_ctx;
|
unsigned long old_ctx;
|
||||||
unsigned int old_irq = disable_irq_save();
|
unsigned int old_irq = disable_irq_save();
|
||||||
|
|
||||||
old_ctx = read_c0_entryhi() & ASID_MASK;
|
old_ctx = read_c0_entryhi() & ASID_MASK;
|
||||||
old_pagemask = read_c0_pagemask();
|
old_pagemask = read_c0_pagemask();
|
||||||
wired = read_c0_wired();
|
wired = read_c0_wired();
|
||||||
|
|
@ -105,10 +105,10 @@ void map_address(unsigned long virtual, unsigned long physical,
|
||||||
unsigned long entry0 = (physical & PFN_MASK) << PFN_SHIFT;
|
unsigned long entry0 = (physical & PFN_MASK) << PFN_SHIFT;
|
||||||
unsigned long entry1 = ((physical+length) & PFN_MASK) << PFN_SHIFT;
|
unsigned long entry1 = ((physical+length) & PFN_MASK) << PFN_SHIFT;
|
||||||
unsigned long entryhi = virtual & ~VPN2_SHIFT;
|
unsigned long entryhi = virtual & ~VPN2_SHIFT;
|
||||||
|
|
||||||
entry0 |= (M_EntryLoG | M_EntryLoV | (cache_flags << S_EntryLoC) );
|
entry0 |= (M_EntryLoG | M_EntryLoV | (cache_flags << S_EntryLoC) );
|
||||||
entry1 |= (M_EntryLoG | M_EntryLoV | (cache_flags << S_EntryLoC) );
|
entry1 |= (M_EntryLoG | M_EntryLoV | (cache_flags << S_EntryLoC) );
|
||||||
|
|
||||||
add_wired_entry(entry0, entry1, entryhi, DEFAULT_PAGE_MASK);
|
add_wired_entry(entry0, entry1, entryhi, DEFAULT_PAGE_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,7 +117,7 @@ void mmu_init(void)
|
||||||
write_c0_pagemask(DEFAULT_PAGE_MASK);
|
write_c0_pagemask(DEFAULT_PAGE_MASK);
|
||||||
write_c0_wired(0);
|
write_c0_wired(0);
|
||||||
write_c0_framemask(0);
|
write_c0_framemask(0);
|
||||||
|
|
||||||
local_flush_tlb_all();
|
local_flush_tlb_all();
|
||||||
/*
|
/*
|
||||||
map_address(0x80000000, 0x80000000, 0x4000, K_CacheAttrC);
|
map_address(0x80000000, 0x80000000, 0x4000, K_CacheAttrC);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue