summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/rolo.c2
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c4
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c4
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c4
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c8
-rw-r--r--firmware/target/mips/ingenic_jz47xx/dma_acc-jz4740.c9
-rw-r--r--firmware/target/mips/ingenic_jz47xx/dma_acc-jz4760.c12
-rw-r--r--firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c7
-rw-r--r--firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c3
-rw-r--r--firmware/target/mips/ingenic_jz47xx/pcm-jz4760.c5
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-jz4740.c15
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-jz4760.c3
-rw-r--r--firmware/target/mips/ingenic_jz47xx/usb-jz4740.c10
-rw-r--r--firmware/target/mips/ingenic_jz47xx/usb-jz4760.c10
-rw-r--r--firmware/target/mips/mmu-mips.c185
-rw-r--r--firmware/target/mips/mmu-mips.h34
16 files changed, 187 insertions, 128 deletions
diff --git a/firmware/rolo.c b/firmware/rolo.c
index de19c8e925..e60af46704 100644
--- a/firmware/rolo.c
+++ b/firmware/rolo.c
@@ -201,7 +201,7 @@ void rolo_restart(const unsigned char* source, unsigned char* dest,
201 : : "r"(dest) 201 : : "r"(dest)
202 ); 202 );
203#elif defined(CPU_MIPS) 203#elif defined(CPU_MIPS)
204 __dcache_writeback_all(); 204 commit_discard_idcache();
205 asm volatile( 205 asm volatile(
206 "jr %0 \n" 206 "jr %0 \n"
207 : : "r"(dest) 207 : : "r"(dest)
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
index a582db82cc..5f320f8e9b 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
@@ -151,7 +151,7 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw)
151 mutex_lock(&nand_dma_mtx); 151 mutex_lock(&nand_dma_mtx);
152 152
153 if(((unsigned int)source < 0xa0000000) && len) 153 if(((unsigned int)source < 0xa0000000) && len)
154 dma_cache_wback_inv((unsigned long)source, len); 154 commit_discard_dcache_range(source, len);
155 155
156 dma_enable(); 156 dma_enable();
157 157
@@ -184,7 +184,7 @@ static void jz_nand_read_dma(void *target, unsigned int len, int bw)
184 mutex_lock(&nand_dma_mtx); 184 mutex_lock(&nand_dma_mtx);
185 185
186 if(((unsigned int)target < 0xa0000000) && len) 186 if(((unsigned int)target < 0xa0000000) && len)
187 dma_cache_wback_inv((unsigned long)target, len); 187 discard_dcache_range(target, len);
188 188
189 dma_enable(); 189 dma_enable();
190 190
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c
index 1eacf9170a..efce5742d0 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c
@@ -150,7 +150,7 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw)
150 mutex_lock(&nand_dma_mtx); 150 mutex_lock(&nand_dma_mtx);
151 151
152 if(((unsigned int)source < 0xa0000000) && len) 152 if(((unsigned int)source < 0xa0000000) && len)
153 dma_cache_wback_inv((unsigned long)source, len); 153 commit_discard_dcache_range(source, len);
154 154
155 dma_enable(); 155 dma_enable();
156 156
@@ -183,7 +183,7 @@ static void jz_nand_read_dma(void *target, unsigned int len, int bw)
183 mutex_lock(&nand_dma_mtx); 183 mutex_lock(&nand_dma_mtx);
184 184
185 if(((unsigned int)target < 0xa0000000) && len) 185 if(((unsigned int)target < 0xa0000000) && len)
186 dma_cache_wback_inv((unsigned long)target, len); 186 discard_dcache_range(target, len);
187 187
188 dma_enable(); 188 dma_enable();
189 189
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
index 0eb175c03f..56dd50814a 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
@@ -417,7 +417,7 @@ static void jz_sd_receive_data_dma(struct sd_request *req)
417#endif 417#endif
418 418
419 /* flush dcache */ 419 /* flush dcache */
420 //dma_cache_wback_inv((unsigned long) req->buffer, size); 420 discard_dcache_range(req->buffer, size);
421 /* setup dma channel */ 421 /* setup dma channel */
422 REG_DMAC_DSAR(DMA_SD_RX_CHANNEL) = PHYSADDR(MSC_RXFIFO); /* DMA source addr */ 422 REG_DMAC_DSAR(DMA_SD_RX_CHANNEL) = PHYSADDR(MSC_RXFIFO); /* DMA source addr */
423 REG_DMAC_DTAR(DMA_SD_RX_CHANNEL) = PHYSADDR((unsigned long) req->buffer); /* DMA dest addr */ 423 REG_DMAC_DTAR(DMA_SD_RX_CHANNEL) = PHYSADDR((unsigned long) req->buffer); /* DMA dest addr */
@@ -452,7 +452,7 @@ static void jz_mmc_transmit_data_dma(struct mmc_request *req)
452#endif 452#endif
453 453
454 /* flush dcache */ 454 /* flush dcache */
455 //dma_cache_wback_inv((unsigned long) req->buffer, size); 455 commit_discard_dcache_range(req->buffer, size);
456 /* setup dma channel */ 456 /* setup dma channel */
457 REG_DMAC_DSAR(DMA_SD_TX_CHANNEL) = PHYSADDR((unsigned long) req->buffer); /* DMA source addr */ 457 REG_DMAC_DSAR(DMA_SD_TX_CHANNEL) = PHYSADDR((unsigned long) req->buffer); /* DMA source addr */
458 REG_DMAC_DTAR(DMA_SD_TX_CHANNEL) = PHYSADDR(MSC_TXFIFO); /* DMA dest addr */ 458 REG_DMAC_DTAR(DMA_SD_TX_CHANNEL) = PHYSADDR(MSC_TXFIFO); /* DMA dest addr */
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c
index 55ffecce09..1960fcbd35 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c
@@ -532,6 +532,9 @@ static int jz_sd_transmit_data(const int drive, struct sd_request *req)
532#if SD_DMA_ENABLE 532#if SD_DMA_ENABLE
533static int jz_sd_receive_data_dma(const int drive, struct sd_request *req) 533static int jz_sd_receive_data_dma(const int drive, struct sd_request *req)
534{ 534{
535 /* flush dcache */
536 discard_dcache_range(req->buffer, req->cnt);
537
535 /* setup dma channel */ 538 /* setup dma channel */
536 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(drive)) = 0; 539 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(drive)) = 0;
537 REG_DMAC_DSAR(DMA_SD_RX_CHANNEL(drive)) = PHYSADDR(MSC_RXFIFO(MSC_CHN(drive))); /* DMA source addr */ 540 REG_DMAC_DSAR(DMA_SD_RX_CHANNEL(drive)) = PHYSADDR(MSC_RXFIFO(MSC_CHN(drive))); /* DMA source addr */
@@ -558,16 +561,13 @@ static int jz_sd_receive_data_dma(const int drive, struct sd_request *req)
558 /* clear status and disable channel */ 561 /* clear status and disable channel */
559 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(drive)) = 0; 562 REG_DMAC_DCCSR(DMA_SD_RX_CHANNEL(drive)) = 0;
560 563
561 /* flush dcache */
562 dma_cache_wback_inv((unsigned long) req->buffer, req->cnt);
563
564 return SD_NO_ERROR; 564 return SD_NO_ERROR;
565} 565}
566 566
567static int jz_sd_transmit_data_dma(const int drive, struct sd_request *req) 567static int jz_sd_transmit_data_dma(const int drive, struct sd_request *req)
568{ 568{
569 /* flush dcache */ 569 /* flush dcache */
570 dma_cache_wback_inv((unsigned long) req->buffer, req->cnt); 570 commit_discard_dcache_range(req->buffer, req->cnt);
571 571
572 /* setup dma channel */ 572 /* setup dma channel */
573 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(drive)) = 0; 573 REG_DMAC_DCCSR(DMA_SD_TX_CHANNEL(drive)) = 0;
diff --git a/firmware/target/mips/ingenic_jz47xx/dma_acc-jz4740.c b/firmware/target/mips/ingenic_jz47xx/dma_acc-jz4740.c
index 6f317f7b3f..f4f363b25b 100644
--- a/firmware/target/mips/ingenic_jz47xx/dma_acc-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/dma_acc-jz4740.c
@@ -32,7 +32,7 @@ void memset(void *target, unsigned char c, size_t len)
32 else 32 else
33 { 33 {
34 if(((unsigned int)target < 0xa0000000) && len) 34 if(((unsigned int)target < 0xa0000000) && len)
35 dma_cache_wback_inv((unsigned long)target, len); 35 discard_dcache_range(target, len);
36 36
37 dp = (unsigned char *)((unsigned int)(&d) | 0xa0000000); 37 dp = (unsigned char *)((unsigned int)(&d) | 0xa0000000);
38 *(dp + 0) = c; 38 *(dp + 0) = c;
@@ -52,7 +52,6 @@ void memset(void *target, unsigned char c, size_t len)
52 dp = (unsigned char *)((unsigned int)target + (len & (32 - 1))); 52 dp = (unsigned char *)((unsigned int)target + (len & (32 - 1)));
53 for(d = 0;d < (len % 32); d++) 53 for(d = 0;d < (len % 32); d++)
54 *dp++ = c; 54 *dp++ = c;
55
56 } 55 }
57 } 56 }
58} 57}
@@ -68,7 +67,7 @@ void memset16(void *target, unsigned short c, size_t len)
68 else 67 else
69 { 68 {
70 if(((unsigned int)target < 0xa0000000) && len) 69 if(((unsigned int)target < 0xa0000000) && len)
71 dma_cache_wback_inv((unsigned long)target, len); 70 discard_dcache_range(target, len);
72 71
73 d = c; 72 d = c;
74 REG_DMAC_DSAR(ch) = PHYSADDR((unsigned long)&d); 73 REG_DMAC_DSAR(ch) = PHYSADDR((unsigned long)&d);
@@ -97,10 +96,10 @@ void memcpy(void *target, const void *source, size_t len)
97 _memcpy(target, source, len); 96 _memcpy(target, source, len);
98 97
99 if(((unsigned int)source < 0xa0000000) && len) 98 if(((unsigned int)source < 0xa0000000) && len)
100 dma_cache_wback_inv((unsigned long)source, len); 99 commit_dcache_range(source, len);
101 100
102 if(((unsigned int)target < 0xa0000000) && len) 101 if(((unsigned int)target < 0xa0000000) && len)
103 dma_cache_wback_inv((unsigned long)target, len); 102 discard_dcache_range(target, len);
104 103
105 REG_DMAC_DSAR(ch) = PHYSADDR((unsigned long)source); 104 REG_DMAC_DSAR(ch) = PHYSADDR((unsigned long)source);
106 REG_DMAC_DTAR(ch) = PHYSADDR((unsigned long)target); 105 REG_DMAC_DTAR(ch) = PHYSADDR((unsigned long)target);
diff --git a/firmware/target/mips/ingenic_jz47xx/dma_acc-jz4760.c b/firmware/target/mips/ingenic_jz47xx/dma_acc-jz4760.c
index 4cdea2ad08..87d2b4e210 100644
--- a/firmware/target/mips/ingenic_jz47xx/dma_acc-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/dma_acc-jz4760.c
@@ -29,7 +29,7 @@ void memset_dma(void *target, int c, size_t len, unsigned int bits)
29 unsigned char *dp; 29 unsigned char *dp;
30 30
31 if(((unsigned int)target < 0xa0000000) && len) 31 if(((unsigned int)target < 0xa0000000) && len)
32 dma_cache_wback_inv((unsigned long)target, len); 32 discard_dcache_range(target, len);
33 33
34 dp = (unsigned char *)((unsigned int)(&d) | 0xa0000000); 34 dp = (unsigned char *)((unsigned int)(&d) | 0xa0000000);
35 *(dp + 0) = c; 35 *(dp + 0) = c;
@@ -68,14 +68,14 @@ void memset_dma(void *target, int c, size_t len, unsigned int bits)
68void memcpy_dma(void *target, const void *source, size_t len, unsigned int bits) 68void memcpy_dma(void *target, const void *source, size_t len, unsigned int bits)
69{ 69{
70 if(((unsigned int)source < 0xa0000000) && len) 70 if(((unsigned int)source < 0xa0000000) && len)
71 dma_cache_wback_inv((unsigned long)source, len); 71 commit_dcache_range(source, len);
72 72
73 if(((unsigned int)target < 0xa0000000) && len) 73 if(((unsigned int)target < 0xa0000000) && len)
74 dma_cache_wback_inv((unsigned long)target, len); 74 discard_dcache_range(target, len);
75 75
76 REG_MDMAC_DCCSR(MDMA_CHANNEL) = 0; 76 REG_MDMAC_DCCSR(MDMA_CHANNEL) = 0;
77 REG_MDMAC_DSAR(MDMA_CHANNEL) = PHYSADDR((unsigned long)source); 77 REG_MDMAC_DSAR(MDMA_CHANNEL) = PHYSADDR((unsigned long)source);
78 REG_MDMAC_DTAR(MDMA_CHANNEL) = PHYSADDR((unsigned long)target); 78 REG_MDMAC_DTAR(MDMA_CHANNEL) = PHYSADDR((unsigned long)target);
79 REG_MDMAC_DRSR(MDMA_CHANNEL) = DMAC_DRSR_RS_AUTO; 79 REG_MDMAC_DRSR(MDMA_CHANNEL) = DMAC_DRSR_RS_AUTO;
80 switch (bits) 80 switch (bits)
81 { 81 {
diff --git a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
index cf676622f1..a2d5b73ea8 100644
--- a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
@@ -109,8 +109,9 @@ void lcd_update_rect(int x, int y, int width, int height)
109 REG_DMAC_DCMD(DMA_LCD_CHANNEL) = ( DMAC_DCMD_SAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 109 REG_DMAC_DCMD(DMA_LCD_CHANNEL) = ( DMAC_DCMD_SAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32
110 | DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BYTE ); 110 | DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BYTE );
111 111
112 __dcache_writeback_all(); /* Size of framebuffer is way bigger than cache size. 112 // XXX range
113 We need to find a way to make the framebuffer uncached, so this statement can get removed. */ 113 commit_discard_dcache(); /* Size of framebuffer is way bigger than cache size.
114 We need to find a way to make the framebuffer uncached, so this statement can get removed. */
114 115
115 while(REG_SLCD_STATE & SLCD_STATE_BUSY); 116 while(REG_SLCD_STATE & SLCD_STATE_BUSY);
116 REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN; /* Enable SLCD DMA support */ 117 REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN; /* Enable SLCD DMA support */
@@ -174,7 +175,7 @@ void lcd_blit_yuv(unsigned char * const src[3],
174 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); 175 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
175 yuv_src[2] = src[2] + (yuv_src[1] - src[1]); 176 yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
176 177
177 __dcache_writeback_all(); 178 commit_discard_dcache(); // XXX range
178 179
179 __cpm_start_ipu(); 180 __cpm_start_ipu();
180 181
diff --git a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
index 83d3646ed1..00a2b22591 100644
--- a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
@@ -69,6 +69,8 @@ static inline void set_dma(const void *addr, size_t size)
69 int burst_size; 69 int burst_size;
70 logf("%x %d %x", (unsigned int)addr, size, REG_AIC_SR); 70 logf("%x %d %x", (unsigned int)addr, size, REG_AIC_SR);
71 71
72 commit_discard_dcache_range(addr, size);
73
72 if(size % 16) 74 if(size % 16)
73 { 75 {
74 if(size % 4) 76 if(size % 4)
@@ -88,7 +90,6 @@ static inline void set_dma(const void *addr, size_t size)
88 burst_size = DMAC_DCMD_DS_16BYTE; 90 burst_size = DMAC_DCMD_DS_16BYTE;
89 } 91 }
90 92
91 __dcache_writeback_all();
92 REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = DMAC_DCCSR_NDES; 93 REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = DMAC_DCCSR_NDES;
93 REG_DMAC_DSAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)addr); 94 REG_DMAC_DSAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)addr);
94 REG_DMAC_DTAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)AIC_DR); 95 REG_DMAC_DTAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)AIC_DR);
diff --git a/firmware/target/mips/ingenic_jz47xx/pcm-jz4760.c b/firmware/target/mips/ingenic_jz47xx/pcm-jz4760.c
index 39df037f76..59b086e4f8 100644
--- a/firmware/target/mips/ingenic_jz47xx/pcm-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/pcm-jz4760.c
@@ -28,7 +28,6 @@
28#include "pcm-internal.h" 28#include "pcm-internal.h"
29#include "cpu.h" 29#include "cpu.h"
30 30
31
32/**************************************************************************** 31/****************************************************************************
33 ** Playback DMA transfer 32 ** Playback DMA transfer
34 **/ 33 **/
@@ -60,8 +59,8 @@ static inline void set_dma(const void *addr, size_t size)
60 int burst_size; 59 int burst_size;
61 logf("%x %d %x", (unsigned int)addr, size, REG_AIC_SR); 60 logf("%x %d %x", (unsigned int)addr, size, REG_AIC_SR);
62 61
63 dma_cache_wback_inv((unsigned long)addr, size); 62 commit_discard_dcache_range(addr, size);
64 63
65 if(size % 16) 64 if(size % 16)
66 { 65 {
67 if(size % 4) 66 if(size % 4)
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
index 87094dd7ae..d3a753a58e 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
@@ -511,24 +511,23 @@ static void sdram_init(void)
511void ICODE_ATTR system_main(void) 511void ICODE_ATTR system_main(void)
512{ 512{
513 int i; 513 int i;
514 514
515 __dcache_writeback_all(); 515 commit_discard_idcache();
516 __icache_invalidate_all(); 516
517
518 write_c0_status(1 << 28 | 1 << 10 ); /* Enable CP | Mask interrupt 2 */ 517 write_c0_status(1 << 28 | 1 << 10 ); /* Enable CP | Mask interrupt 2 */
519 518
520 /* Disable all interrupts */ 519 /* Disable all interrupts */
521 for(i=0; i<IRQ_MAX; i++) 520 for(i=0; i<IRQ_MAX; i++)
522 dis_irq(i); 521 dis_irq(i);
523 522
524 mmu_init(); 523 mmu_init();
525 pll_init(); 524 pll_init();
526 sdram_init(); 525 sdram_init();
527 526
528 /* Disable unneeded clocks, clocks are enabled when needed */ 527 /* Disable unneeded clocks, clocks are enabled when needed */
529 __cpm_stop_all(); 528 __cpm_stop_all();
530 __cpm_suspend_usbhost(); 529 __cpm_suspend_usbhost();
531 530
532 /* Enable interrupts at core level */ 531 /* Enable interrupts at core level */
533 enable_interrupt(); 532 enable_interrupt();
534} 533}
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4760.c b/firmware/target/mips/ingenic_jz47xx/system-jz4760.c
index ff87e5ad9e..eee767c5ca 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/system-jz4760.c
@@ -673,8 +673,7 @@ void ICODE_ATTR system_main(void)
673{ 673{
674 int i; 674 int i;
675 675
676 __dcache_writeback_all(); 676 commit_discard_idcache();
677 __icache_invalidate_all();
678 677
679 write_c0_status(1 << 28 | 1 << 10 ); /* Enable CP | Mask interrupt 2 */ 678 write_c0_status(1 << 28 | 1 << 10 ); /* Enable CP | Mask interrupt 2 */
680 679
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
index e8cd2033ff..fd38b2b1a4 100644
--- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
@@ -274,7 +274,7 @@ static void EPIN_handler(unsigned int endpoint)
274 } 274 }
275 275
276 logf("EP%d: %d -> %d", endpoint, ep->sent, ep->length); 276 logf("EP%d: %d -> %d", endpoint, ep->sent, ep->length);
277 277
278 if(ep->sent == 0) 278 if(ep->sent == 0)
279 length = MIN(ep->length, ep->fifo_size); 279 length = MIN(ep->length, ep->fifo_size);
280 else 280 else
@@ -365,7 +365,7 @@ static void EPDMA_handler(int number)
365 /* Disable DMA */ 365 /* Disable DMA */
366 REG_USB_REG_CNTL2 = 0; 366 REG_USB_REG_CNTL2 = 0;
367 367
368 __dcache_invalidate_all(); 368 commit_discard_dcache(); // XXX range?
369 369
370 select_endpoint(endpoint); 370 select_endpoint(endpoint);
371 /* Read out last packet manually */ 371 /* Read out last packet manually */
@@ -707,8 +707,7 @@ static void usb_drv_send_internal(struct usb_endpoint* ep, void* ptr, int length
707 { 707 {
708 if(ep->use_dma) 708 if(ep->use_dma)
709 { 709 {
710 //dma_cache_wback_inv((unsigned long)ptr, length); 710 commit_discard_dcache_range(ptr, length);
711 __dcache_writeback_all();
712 REG_USB_REG_ADDR1 = PHYSADDR((unsigned long)ptr); 711 REG_USB_REG_ADDR1 = PHYSADDR((unsigned long)ptr);
713 REG_USB_REG_COUNT1 = length; 712 REG_USB_REG_COUNT1 = length;
714 REG_USB_REG_CNTL1 = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | 713 REG_USB_REG_CNTL1 = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 |
@@ -767,8 +766,7 @@ int usb_drv_recv(int endpoint, void* ptr, int length)
767 ep->busy = true; 766 ep->busy = true;
768 if(ep->use_dma) 767 if(ep->use_dma)
769 { 768 {
770 //dma_cache_wback_inv((unsigned long)ptr, length); 769 discard_dcache_range(ptr, length);
771 __dcache_writeback_all();
772 REG_USB_REG_ADDR2 = PHYSADDR((unsigned long)ptr); 770 REG_USB_REG_ADDR2 = PHYSADDR((unsigned long)ptr);
773 REG_USB_REG_COUNT2 = length; 771 REG_USB_REG_COUNT2 = length;
774 REG_USB_REG_CNTL2 = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | 772 REG_USB_REG_CNTL2 = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 |
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c
index 3c7bb80f2c..275fd3fd2b 100644
--- a/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c
@@ -360,7 +360,7 @@ static void EPIN_handler(unsigned int endpoint)
360 } 360 }
361 361
362 logf("EP%d: %d -> %d", endpoint, ep->sent, ep->length); 362 logf("EP%d: %d -> %d", endpoint, ep->sent, ep->length);
363 363
364 if(ep->sent == 0) 364 if(ep->sent == 0)
365 length = MIN(ep->length, ep->fifo_size); 365 length = MIN(ep->length, ep->fifo_size);
366 else 366 else
@@ -456,7 +456,7 @@ static void EPDMA_handler(int number)
456 /* Disable DMA */ 456 /* Disable DMA */
457 REG_USB_CNTL(1) = 0; 457 REG_USB_CNTL(1) = 0;
458 458
459 __dcache_invalidate_all(); 459 commit_discard_dcache(); // XXX range?
460 460
461 select_endpoint(endpoint); 461 select_endpoint(endpoint);
462 /* Read out last packet manually */ 462 /* Read out last packet manually */
@@ -846,8 +846,7 @@ static void usb_drv_send_internal(struct usb_endpoint* ep, void* ptr, int length
846 { 846 {
847 if(ep->use_dma) 847 if(ep->use_dma)
848 { 848 {
849 //dma_cache_wback_inv((unsigned long)ptr, length); 849 commit_discard_dcache_range(ptr, length);
850 __dcache_writeback_all();
851 REG_USB_ADDR(0) = PHYSADDR((unsigned long)ptr); 850 REG_USB_ADDR(0) = PHYSADDR((unsigned long)ptr);
852 REG_USB_COUNT(0) = length; 851 REG_USB_COUNT(0) = length;
853 REG_USB_CNTL(0) = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | 852 REG_USB_CNTL(0) = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 |
@@ -921,8 +920,7 @@ int usb_drv_recv(int endpoint, void* ptr, int length)
921 ep->busy = true; 920 ep->busy = true;
922 if(ep->use_dma) 921 if(ep->use_dma)
923 { 922 {
924 //dma_cache_wback_inv((unsigned long)ptr, length); 923 discard_dcache_range(ptr, length);
925 __dcache_writeback_all();
926 REG_USB_ADDR(1) = PHYSADDR((unsigned long)ptr); 924 REG_USB_ADDR(1) = PHYSADDR((unsigned long)ptr);
927 REG_USB_COUNT(1) = length; 925 REG_USB_COUNT(1) = length;
928 REG_USB_CNTL(1) = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | 926 REG_USB_CNTL(1) = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 |
diff --git a/firmware/target/mips/mmu-mips.c b/firmware/target/mips/mmu-mips.c
index 552348014e..14a013211d 100644
--- a/firmware/target/mips/mmu-mips.c
+++ b/firmware/target/mips/mmu-mips.c
@@ -5,9 +5,9 @@
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$
9 * 8 *
10 * Copyright (C) 2009 by Maurus Cuelenaere 9 * Copyright (C) 2009 by Maurus Cuelenaere
10 * Copyright (C) 2015 by Marcin Bukat
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
@@ -25,8 +25,16 @@
25#include "system.h" 25#include "system.h"
26#include "mmu-mips.h" 26#include "mmu-mips.h"
27 27
28#if CONFIG_CPU == JZ4732 || CONFIG_CPU == JZ4760B
29/* XBurst core has 32 JTLB entries */
30#define NR_TLB_ENTRIES 32
31#else
32#error please define NR_TLB_ENTRIES
33#endif
34
28#define BARRIER \ 35#define BARRIER \
29 __asm__ __volatile__( \ 36 __asm__ __volatile__( \
37 " .set push \n" \
30 " .set noreorder \n" \ 38 " .set noreorder \n" \
31 " nop \n" \ 39 " nop \n" \
32 " nop \n" \ 40 " nop \n" \
@@ -34,7 +42,7 @@
34 " nop \n" \ 42 " nop \n" \
35 " nop \n" \ 43 " nop \n" \
36 " nop \n" \ 44 " nop \n" \
37 " .set reorder \n"); 45 " .set pop \n");
38 46
39#define DEFAULT_PAGE_SHIFT PL_4K 47#define DEFAULT_PAGE_SHIFT PL_4K
40#define DEFAULT_PAGE_MASK PM_4K 48#define DEFAULT_PAGE_MASK PM_4K
@@ -43,6 +51,7 @@
43#define VPN2_SHIFT S_EntryHiVPN2 51#define VPN2_SHIFT S_EntryHiVPN2
44#define PFN_SHIFT S_EntryLoPFN 52#define PFN_SHIFT S_EntryLoPFN
45#define PFN_MASK 0xffffff 53#define PFN_MASK 0xffffff
54
46static void local_flush_tlb_all(void) 55static void local_flush_tlb_all(void)
47{ 56{
48 unsigned long old_ctx; 57 unsigned long old_ctx;
@@ -55,10 +64,11 @@ static void local_flush_tlb_all(void)
55 write_c0_entrylo1(0); 64 write_c0_entrylo1(0);
56 BARRIER; 65 BARRIER;
57 66
58 /* Blast 'em all away. */ 67 /* blast all entries except the wired one */
59 for(entry = 0; entry < 32; entry++) 68 for(entry = read_c0_wired(); entry < NR_TLB_ENTRIES; entry++)
60 { 69 {
61 /* Make sure all entries differ. */ 70 /* Make sure all entries differ and are in unmapped space, making them
71 * impossible to match */
62 write_c0_entryhi(UNIQUE_ENTRYHI(entry, DEFAULT_PAGE_SHIFT)); 72 write_c0_entryhi(UNIQUE_ENTRYHI(entry, DEFAULT_PAGE_SHIFT));
63 write_c0_index(entry); 73 write_c0_index(entry);
64 BARRIER; 74 BARRIER;
@@ -119,84 +129,133 @@ void mmu_init(void)
119 write_c0_framemask(0); 129 write_c0_framemask(0);
120 130
121 local_flush_tlb_all(); 131 local_flush_tlb_all();
122/*
123 map_address(0x80000000, 0x80000000, 0x4000, K_CacheAttrC);
124 map_address(0x80004000, 0x80004000, MEMORYSIZE * 0x100000, K_CacheAttrC);
125*/
126} 132}
127 133
128#define SYNC_WB() __asm__ __volatile__ ("sync") 134/* Target specific operations:
135 * - invalidate BTB (Branch Table Buffer)
136 * - sync barrier after cache operations */
137#if CONFIG_CPU == JZ4732 || CONFIG_CPU == JZ4760B
138#define INVALIDATE_BTB() \
139do { \
140 unsigned long tmp; \
141 __asm__ __volatile__( \
142 " .set push \n" \
143 " .set noreorder \n" \
144 " .set mips32 \n" \
145 " mfc0 %0, $16, 7 \n" \
146 " nop \n" \
147 " ori %0, 2 \n" \
148 " mtc0 %0, $16, 7 \n" \
149 " nop \n" \
150 " .set pop \n" \
151 : "=&r"(tmp)); \
152 } while (0)
153
154#define SYNC_WB() __asm__ __volatile__ ("sync":::"memory")
155#else /* !JZ4732 */
156#define INVALIDATE_BTB() do { } while(0)
157#define SYNC_WB() do { } while(0)
158#endif /* CONFIG_CPU */
159
160#define __CACHE_OP(op, addr) \
161 __asm__ __volatile__( \
162 " .set push\n\t \n" \
163 " .set noreorder \n" \
164 " .set mips32\n\t \n" \
165 " cache %0, %1 \n" \
166 " .set pop \n" \
167 : \
168 : "i" (op), "m"(*(unsigned char *)(addr)))
129 169
130#define cache_op(base,op) \ 170/* rockbox cache api */
131 __asm__ __volatile__(" \
132 .set noreorder; \
133 .set mips3; \
134 cache %1, (%0); \
135 .set mips0; \
136 .set reorder" \
137 : \
138 : "r" (base), \
139 "i" (op));
140 171
141void __icache_invalidate_all(void) 172/* Writeback whole D-cache
173 * Alias to commit_discard_dcache() as there is no index type
174 * variant of writeback-only operation
175 */
176void commit_dcache(void) __attribute__((alias("commit_discard_dcache")));
177
178/* Writeback whole D-cache and invalidate D-cache lines */
179void commit_discard_dcache(void)
142{ 180{
143 unsigned long start; 181 unsigned int i;
144 unsigned long end; 182
183 /* Use index type operation and iterate whole cache */
184 for (i=A_K0BASE; i<A_K0BASE+CACHE_SIZE; i+=CACHEALIGN_SIZE)
185 __CACHE_OP(DCIndexWBInv, i);
145 186
146 start = A_K0BASE;
147 end = start + CACHE_SIZE;
148 while(start < end)
149 {
150 cache_op(start,ICIndexInv);
151 start += CACHE_LINE_SIZE;
152 }
153 SYNC_WB(); 187 SYNC_WB();
154} 188}
155 189
156void __dcache_invalidate_all(void) 190/* Writeback lines of D-cache corresponding to address range and
191 * invalidate those D-cache lines
192 */
193void commit_discard_dcache_range(const void *base, unsigned int size)
157{ 194{
158 unsigned long start; 195 char *s;
159 unsigned long end; 196
197 for (s=(char *)base; s<(char *)base+size; s+=CACHEALIGN_SIZE)
198 __CACHE_OP(DCHitWBInv, s);
160 199
161 start = A_K0BASE;
162 end = start + CACHE_SIZE;
163 while (start < end)
164 {
165 cache_op(start,DCIndexWBInv);
166 start += CACHE_LINE_SIZE;
167 }
168 SYNC_WB(); 200 SYNC_WB();
169} 201}
170 202
171void __idcache_invalidate_all(void) 203/* Writeback lines of D-cache corresponding to address range
204 */
205void commit_dcache_range(const void *base, unsigned int size)
172{ 206{
173 __dcache_invalidate_all(); 207 char *s;
174 __icache_invalidate_all(); 208
209 for (s=(char *)base; s<(char *)base+size; s+=CACHEALIGN_SIZE)
210 __CACHE_OP(DCHitWB, s);
211
212 SYNC_WB();
175} 213}
176 214
177void __dcache_writeback_all(void) 215/* Invalidate D-cache lines corresponding to address range
216 * WITHOUT writeback
217 */
218void discard_dcache_range(const void *base, unsigned int size)
178{ 219{
179 __dcache_invalidate_all(); 220 char *s;
221
222 if (((int)base & CACHEALIGN_SIZE - 1) ||
223 (((int)base + size) & CACHEALIGN_SIZE - 1)) {
224 /* Overlapping sections, so we need to write back instead */
225 commit_discard_dcache_range(base, size);
226 return;
227 };
228
229 for (s=(char *)base; s<(char *)base+size; s+=CACHEALIGN_SIZE)
230 __CACHE_OP(DCHitInv, s);
231
232 SYNC_WB();
180} 233}
181 234
182void dma_cache_wback_inv(unsigned long addr, unsigned long size) 235/* Invalidate whole I-cache */
236static void discard_icache(void)
183{ 237{
184 unsigned long end, a; 238 unsigned int i;
185 239
186 if (size >= CACHE_SIZE*2) { 240 asm volatile (".set push \n"
187 __dcache_writeback_all(); 241 ".set noreorder \n"
188 } 242 ".set mips32 \n"
189 else { 243 "mtc0 $0, $28 \n" /* TagLo */
190 unsigned long dc_lsize = CACHE_LINE_SIZE; 244 "mtc0 $0, $29 \n" /* TagHi */
191 245 ".set pop \n"
192 a = addr & ~(dc_lsize - 1); 246 );
193 end = (addr + size - 1) & ~(dc_lsize - 1); 247 /* Use index type operation and iterate whole cache */
194 while (1) { 248 for (i=A_K0BASE; i<A_K0BASE+CACHE_SIZE; i+=CACHEALIGN_SIZE)
195 cache_op(a,DCHitWBInv); 249 __CACHE_OP(ICIndexStTag, i);
196 if (a == end) 250
197 break; 251 INVALIDATE_BTB();
198 a += dc_lsize; 252}
199 } 253
200 } 254/* Invalidate the entire I-cache
201 SYNC_WB(); 255 * and writeback + invalidate the entire D-cache
256 */
257void commit_discard_idcache(void)
258{
259 commit_discard_dcache();
260 discard_icache();
202} 261}
diff --git a/firmware/target/mips/mmu-mips.h b/firmware/target/mips/mmu-mips.h
index 7e1e36d3f4..f96ddcc28d 100644
--- a/firmware/target/mips/mmu-mips.h
+++ b/firmware/target/mips/mmu-mips.h
@@ -28,19 +28,25 @@ void map_address(unsigned long virtual, unsigned long physical,
28 unsigned long length, unsigned int cache_flags); 28 unsigned long length, unsigned int cache_flags);
29void mmu_init(void); 29void mmu_init(void);
30 30
31#define HAVE_CPUCACHE_INVALIDATE 31/* Commits entire DCache */
32//#define HAVE_CPUCACHE_FLUSH 32void commit_dcache(void);
33 33/* Commit and discard entire DCache, will do writeback */
34void __idcache_invalidate_all(void); 34void commit_discard_dcache(void);
35void __icache_invalidate_all(void); 35
36void __dcache_invalidate_all(void); 36/* Write DCache back to RAM for the given range and remove cache lines
37void __dcache_writeback_all(void); 37 * from DCache afterwards */
38 38void commit_discard_dcache_range(const void *base, unsigned int size);
39void dma_cache_wback_inv(unsigned long addr, unsigned long size); 39
40 40/* Write DCache back to RAM for the given range */
41#define commit_discard_idcache __idcache_invalidate_all 41void commit_dcache_range(const void *base, unsigned int size);
42#define commit_discard_icache __icache_invalidate_all 42
43#define commit_discard_dcache __dcache_invalidate_all 43/*
44#define commit_dcache __dcache_writeback_all 44 * Remove cache lines for the given range from DCache
45 * will *NOT* do write back except for buffer edges not on a line boundary
46 */
47void discard_dcache_range(const void *base, unsigned int size);
48
49/* Discards the entire ICache, and commit+discards the entire DCache */
50void commit_discard_idcache(void);
45 51
46#endif /* __MMU_MIPS_INCLUDE_H */ 52#endif /* __MMU_MIPS_INCLUDE_H */