1 #ifndef __PLAT_OMAP_DSP_MMU_H
2 #define __PLAT_OMAP_DSP_MMU_H
4 #ifdef CONFIG_ARCH_OMAP1
6 #ifdef CONFIG_ARCH_OMAP15XX
7 struct omap_mmu dsp_mmu = {
11 .membase = OMAP15XX_DSP_BASE,
12 .memsize = OMAP15XX_DSP_SIZE,
15 .ops = &omap1_mmu_ops,
18 #ifdef CONFIG_ARCH_OMAP16XX
19 struct omap_mmu dsp_mmu = {
23 .membase = OMAP16XX_DSP_BASE,
24 .memsize = OMAP16XX_DSP_SIZE,
27 .ops = &omap1_mmu_ops,
31 struct omap_mmu dsp_mmu = {
34 .base = DSP_MMU_24XX_VIRT,
35 .membase = DSP_MEM_24XX_VIRT,
36 .memsize = DSP_MEM_24XX_SIZE,
39 .ops = &omap2_mmu_ops,
42 #define IOMAP_VAL 0x3f
45 static u32 dsp_fault_adr;
47 #ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
48 static struct omapfb_notifier_block *omapfb_nb;
49 static int omapfb_ready;
55 #ifdef CONFIG_ARCH_OMAP1
56 #define EMIF_PRIO_LB_MASK 0x0000f000
57 #define EMIF_PRIO_LB_SHIFT 12
58 #define EMIF_PRIO_DMA_MASK 0x00000f00
59 #define EMIF_PRIO_DMA_SHIFT 8
60 #define EMIF_PRIO_DSP_MASK 0x00000070
61 #define EMIF_PRIO_DSP_SHIFT 4
62 #define EMIF_PRIO_MPU_MASK 0x00000007
63 #define EMIF_PRIO_MPU_SHIFT 0
64 #define set_emiff_dma_prio(prio) \
66 omap_writel((omap_readl(OMAP_TC_OCPT1_PRIOR) & \
67 ~EMIF_PRIO_DMA_MASK) | \
68 ((prio) << EMIF_PRIO_DMA_SHIFT), \
69 OMAP_TC_OCPT1_PRIOR); \
72 #define set_emiff_dma_prio(prio) do { } while (0)
73 #endif /* CONFIG_ARCH_OMAP1 */
76 * workqueue for mmu int
78 #ifdef CONFIG_ARCH_OMAP1
81 * We ignore prefetch err.
83 #define MMUFAULT_MASK \
84 (DSP_MMU_FAULT_ST_PERM |\
85 DSP_MMU_FAULT_ST_TLB_MISS |\
86 DSP_MMU_FAULT_ST_TRANS)
88 static void do_mmu_int(struct work_struct *unused)
91 unsigned long adh, adl;
94 status = omap_mmu_read_reg(&dsp_mmu, DSP_MMU_FAULT_ST);
95 adh = omap_mmu_read_reg(&dsp_mmu, DSP_MMU_FAULT_AD_H);
96 adl = omap_mmu_read_reg(&dsp_mmu, DSP_MMU_FAULT_AD_L);
97 dp = adh & DSP_MMU_FAULT_AD_H_DP;
98 dsp_fault_adr = MK32(adh & DSP_MMU_FAULT_AD_H_ADR_MASK, adl);
100 /* if the fault is masked, nothing to do */
101 if ((status & MMUFAULT_MASK) == 0) {
102 pr_debug( "DSP MMU interrupt, but ignoring.\n");
105 * when CACHE + DMA domain gets out of idle in DSP,
106 * MMU interrupt occurs but DSP_MMU_FAULT_ST is not set.
107 * in this case, we just ignore the interrupt.
110 pr_debug( "%s%s%s%s\n",
111 (status & DSP_MMU_FAULT_ST_PREF)?
112 " (prefetch err)" : "",
113 (status & DSP_MMU_FAULT_ST_PERM)?
114 " (permission fault)" : "",
115 (status & DSP_MMU_FAULT_ST_TLB_MISS)?
117 (status & DSP_MMU_FAULT_ST_TRANS) ?
118 " (translation fault)": "");
119 pr_debug( "fault address = %#08x\n", dsp_fault_adr);
121 enable_irq(omap_dsp->mmu_irq);
126 pr_info("%s%s%s%s\n",
127 (status & DSP_MMU_FAULT_ST_PREF)?
128 (MMUFAULT_MASK & DSP_MMU_FAULT_ST_PREF)?
132 (status & DSP_MMU_FAULT_ST_PERM)?
133 (MMUFAULT_MASK & DSP_MMU_FAULT_ST_PERM)?
135 " (permission fault)":
137 (status & DSP_MMU_FAULT_ST_TLB_MISS)?
138 (MMUFAULT_MASK & DSP_MMU_FAULT_ST_TLB_MISS)?
142 (status & DSP_MMU_FAULT_ST_TRANS)?
143 (MMUFAULT_MASK & DSP_MMU_FAULT_ST_TRANS)?
144 " translation fault":
145 " (translation fault)":
148 pr_info("fault address = %#08x\n", dsp_fault_adr);
150 if (dsp_cfgstat_get_stat() == CFGSTAT_READY)
151 dsp_err_set(ERRCODE_MMU, (unsigned long)dsp_fault_adr);
153 __dsp_mmu_itack(&dsp_mmu);
155 pr_info("Resetting DSP...\n");
156 dsp_cpustat_request(CPUSTAT_RESET);
158 * if we enable followings, semaphore lock should be avoided.
160 pr_info("Flushing DSP MMU...\n");
166 enable_irq(omap_dsp->mmu_irq);
168 #elif defined(CONFIG_ARCH_OMAP2)
169 static void do_mmu_int(struct work_struct *unused)
171 unsigned long status;
173 status = omap_mmu_read_reg(&dsp_mmu, DSP_MMU_IRQSTATUS);
174 dsp_fault_adr = omap_mmu_read_reg(&dsp_mmu, DSP_MMU_FAULT_AD);
176 #define MMU_IRQ_MASK \
177 (DSP_MMU_IRQ_MULTIHITFAULT | \
178 DSP_MMU_IRQ_TABLEWALKFAULT | \
179 DSP_MMU_IRQ_EMUMISS | \
180 DSP_MMU_IRQ_TRANSLATIONFAULT | \
183 pr_info("%s%s%s%s%s\n",
184 (status & DSP_MMU_IRQ_MULTIHITFAULT)?
185 (MMU_IRQ_MASK & DSP_MMU_IRQ_MULTIHITFAULT)?
189 (status & DSP_MMU_IRQ_TABLEWALKFAULT)?
190 (MMU_IRQ_MASK & DSP_MMU_IRQ_TABLEWALKFAULT)?
192 " (table walk fault)":
194 (status & DSP_MMU_IRQ_EMUMISS)?
195 (MMU_IRQ_MASK & DSP_MMU_IRQ_EMUMISS)?
199 (status & DSP_MMU_IRQ_TRANSLATIONFAULT)?
200 (MMU_IRQ_MASK & DSP_MMU_IRQ_TRANSLATIONFAULT)?
201 " translation fault":
202 " (translation fault)":
204 (status & DSP_MMU_IRQ_TLBMISS)?
205 (MMU_IRQ_MASK & DSP_MMU_IRQ_TLBMISS)?
210 pr_info("fault address = %#08x\n", dsp_fault_adr);
212 if (dsp_cfgstat_get_stat() == CFGSTAT_READY)
213 dsp_err_set(ERRCODE_MMU, (unsigned long)dsp_fault_adr);
215 pr_info("Resetting DSP...\n");
216 dsp_cpustat_request(CPUSTAT_RESET);
219 omap_mmu_disable(&dsp_mmu);
220 omap_mmu_write_reg(&dsp_mmu, status, DSP_MMU_IRQSTATUS);
221 omap_mmu_enable(&dsp_mmu, 0);
223 enable_irq(omap_dsp->mmu_irq);
227 static DECLARE_WORK(mmu_int_work, do_mmu_int);
229 #ifdef CONFIG_ARCH_OMAP1
230 static int dsp_mmu_itack(void)
232 unsigned long dspadr;
234 pr_info("omapdsp: sending DSP MMU interrupt ack.\n");
235 if (!dsp_err_isset(ERRCODE_MMU)) {
236 printk(KERN_ERR "omapdsp: DSP MMU error has not been set.\n");
239 dspadr = dsp_fault_adr & ~(SZ_4K-1);
240 /* FIXME: reserve TLB entry for this */
241 omap_mmu_exmap(&dsp_mmu, dspadr, 0, SZ_4K, EXMAP_TYPE_MEM);
242 pr_info("omapdsp: falling into recovery runlevel...\n");
243 dsp_set_runlevel(RUNLEVEL_RECOVERY);
244 __dsp_mmu_itack(&dsp_mmu);
246 omap_mmu_exunmap(&dsp_mmu, dspadr);
247 dsp_err_clear(ERRCODE_MMU);
252 * intmem_enable() / disable():
253 * if the address is in DSP internal memories,
254 * we send PM mailbox commands so that DSP DMA domain won't go in idle
255 * when ARM is accessing to those memories.
257 static int intmem_enable(void)
261 if (dsp_cfgstat_get_stat() == CFGSTAT_READY)
262 ret = mbcompose_send(PM, PM_ENABLE, DSPREG_ICR_DMA);
267 static void intmem_disable(void) {
268 if (dsp_cfgstat_get_stat() == CFGSTAT_READY)
269 mbcompose_send(PM, PM_DISABLE, DSPREG_ICR_DMA);
272 static int intmem_enable(void) { return 0; }
273 static void intmem_disable(void) { }
274 static int dsp_mmu_itack(void) { return 0; }
277 #ifdef CONFIG_ARCH_OMAP2
278 static inline void dsp_mem_ipi_init(void)
280 int i, dspmem_pg_count;
281 dspmem_pg_count = dspmem_size >> 12;
282 for (i = 0; i < dspmem_pg_count; i++) {
283 writel(i, DSP_IPI_INDEX);
284 writel(DSP_IPI_ENTRY_ELMSIZEVALUE_16, DSP_IPI_ENTRY);
286 writel(1, DSP_IPI_ENABLE);
287 writel(IOMAP_VAL, DSP_IPI_IOMAP);
290 static inline void dsp_mem_ipi_init(void) { }
293 #endif /* __PLAT_OMAP_DSP_MMU_H */