diff options
| author | Felipe Contreras <felipe.contreras@gmail.com> | 2010-11-10 13:11:49 -0500 |
|---|---|---|
| committer | Omar Ramirez Luna <omar.ramirez@ti.com> | 2010-11-10 19:34:43 -0500 |
| commit | 6c4c899ee27963357a7df1f5e15a5677978cd842 (patch) | |
| tree | 3750afedb6e830771b710f81de06a41516a89f8a | |
| parent | 58c1ceb156df5a005f7fc9afc75064a2c1df4b65 (diff) | |
Revert "staging: tidspbridge - fix mmufault support"
This reverts commit f265846db1e755c11498f6f7c011127dfcc5634a.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Omar Ramirez Luna <omar.ramirez@ti.com>
| -rw-r--r-- | drivers/staging/tidspbridge/core/_deh.h | 2 | ||||
| -rw-r--r-- | drivers/staging/tidspbridge/core/tiomap3430.c | 2 | ||||
| -rw-r--r-- | drivers/staging/tidspbridge/core/ue_deh.c | 93 |
3 files changed, 57 insertions, 40 deletions
diff --git a/drivers/staging/tidspbridge/core/_deh.h b/drivers/staging/tidspbridge/core/_deh.h index f1254f0aa037..16723cd34831 100644 --- a/drivers/staging/tidspbridge/core/_deh.h +++ b/drivers/staging/tidspbridge/core/_deh.h | |||
| @@ -32,6 +32,4 @@ struct deh_mgr { | |||
| 32 | struct tasklet_struct dpc_tasklet; | 32 | struct tasklet_struct dpc_tasklet; |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | int mmu_fault_isr(struct iommu *mmu); | ||
| 36 | |||
| 37 | #endif /* _DEH_ */ | 35 | #endif /* _DEH_ */ |
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index b68050a969a6..d643c2ba9dc1 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c | |||
| @@ -57,7 +57,6 @@ | |||
| 57 | #include "_tiomap.h" | 57 | #include "_tiomap.h" |
| 58 | #include "_tiomap_pwr.h" | 58 | #include "_tiomap_pwr.h" |
| 59 | #include "tiomap_io.h" | 59 | #include "tiomap_io.h" |
| 60 | #include "_deh.h" | ||
| 61 | 60 | ||
| 62 | /* Offset in shared mem to write to in order to synchronize start with DSP */ | 61 | /* Offset in shared mem to write to in order to synchronize start with DSP */ |
| 63 | #define SHMSYNCOFFSET 4 /* GPP byte offset */ | 62 | #define SHMSYNCOFFSET 4 /* GPP byte offset */ |
| @@ -380,7 +379,6 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, | |||
| 380 | } | 379 | } |
| 381 | if (!status) { | 380 | if (!status) { |
| 382 | dev_context->dsp_mmu = mmu; | 381 | dev_context->dsp_mmu = mmu; |
| 383 | mmu->isr = mmu_fault_isr; | ||
| 384 | sm_sg = &dev_context->sh_s; | 382 | sm_sg = &dev_context->sh_s; |
| 385 | sg0_da = iommu_kmap(mmu, sm_sg->seg0_da, sm_sg->seg0_pa, | 383 | sg0_da = iommu_kmap(mmu, sm_sg->seg0_da, sm_sg->seg0_pa, |
| 386 | sm_sg->seg0_size, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); | 384 | sm_sg->seg0_size, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); |
diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c index 2e1ac89644d3..14f319134357 100644 --- a/drivers/staging/tidspbridge/core/ue_deh.c +++ b/drivers/staging/tidspbridge/core/ue_deh.c | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | #include <dspbridge/drv.h> | 31 | #include <dspbridge/drv.h> |
| 32 | #include <dspbridge/wdt.h> | 32 | #include <dspbridge/wdt.h> |
| 33 | 33 | ||
| 34 | #define MMU_CNTL_TWL_EN (1 << 2) | 34 | static u32 fault_addr; |
| 35 | 35 | ||
| 36 | static void mmu_fault_dpc(unsigned long data) | 36 | static void mmu_fault_dpc(unsigned long data) |
| 37 | { | 37 | { |
| @@ -43,18 +43,43 @@ static void mmu_fault_dpc(unsigned long data) | |||
| 43 | bridge_deh_notify(deh, DSP_MMUFAULT, 0); | 43 | bridge_deh_notify(deh, DSP_MMUFAULT, 0); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | int mmu_fault_isr(struct iommu *mmu) | 46 | static irqreturn_t mmu_fault_isr(int irq, void *data) |
| 47 | { | 47 | { |
| 48 | struct deh_mgr *dm; | 48 | struct deh_mgr *deh = data; |
| 49 | struct cfg_hostres *resources; | ||
| 50 | u32 event; | ||
| 49 | 51 | ||
| 50 | dev_get_deh_mgr(dev_get_first(), &dm); | 52 | if (!deh) |
| 53 | return IRQ_HANDLED; | ||
| 51 | 54 | ||
| 52 | if (!dm) | 55 | resources = deh->hbridge_context->resources; |
| 53 | return -EPERM; | 56 | if (!resources) { |
| 57 | dev_dbg(bridge, "%s: Failed to get Host Resources\n", | ||
| 58 | __func__); | ||
| 59 | return IRQ_HANDLED; | ||
| 60 | } | ||
| 54 | 61 | ||
| 55 | iommu_write_reg(mmu, 0, MMU_IRQENABLE); | 62 | hw_mmu_event_status(resources->dw_dmmu_base, &event); |
| 56 | tasklet_schedule(&dm->dpc_tasklet); | 63 | if (event == HW_MMU_TRANSLATION_FAULT) { |
| 57 | return 0; | 64 | hw_mmu_fault_addr_read(resources->dw_dmmu_base, &fault_addr); |
| 65 | dev_dbg(bridge, "%s: event=0x%x, fault_addr=0x%x\n", __func__, | ||
| 66 | event, fault_addr); | ||
| 67 | /* | ||
| 68 | * Schedule a DPC directly. In the future, it may be | ||
| 69 | * necessary to check if DSP MMU fault is intended for | ||
| 70 | * Bridge. | ||
| 71 | */ | ||
| 72 | tasklet_schedule(&deh->dpc_tasklet); | ||
| 73 | |||
| 74 | /* Disable the MMU events, else once we clear it will | ||
| 75 | * start to raise INTs again */ | ||
| 76 | hw_mmu_event_disable(resources->dw_dmmu_base, | ||
| 77 | HW_MMU_TRANSLATION_FAULT); | ||
| 78 | } else { | ||
| 79 | hw_mmu_event_disable(resources->dw_dmmu_base, | ||
| 80 | HW_MMU_ALL_INTERRUPTS); | ||
| 81 | } | ||
| 82 | return IRQ_HANDLED; | ||
| 58 | } | 83 | } |
| 59 | 84 | ||
| 60 | int bridge_deh_create(struct deh_mgr **ret_deh, | 85 | int bridge_deh_create(struct deh_mgr **ret_deh, |
| @@ -136,45 +161,42 @@ int bridge_deh_register_notify(struct deh_mgr *deh, u32 event_mask, | |||
| 136 | #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE | 161 | #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE |
| 137 | static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) | 162 | static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) |
| 138 | { | 163 | { |
| 139 | void *dummy_addr; | 164 | struct cfg_hostres *resources; |
| 140 | u32 fa, tmp; | 165 | struct hw_mmu_map_attrs_t map_attrs = { |
| 141 | struct iotlb_entry e; | 166 | .endianism = HW_LITTLE_ENDIAN, |
| 142 | struct iommu *mmu = dev_context->dsp_mmu; | 167 | .element_size = HW_ELEM_SIZE16BIT, |
| 143 | dummy_addr = (void *)__get_free_page(GFP_ATOMIC); | 168 | .mixed_size = HW_MMU_CPUES, |
| 169 | }; | ||
| 170 | void *dummy_va_addr; | ||
| 171 | |||
| 172 | resources = dev_context->resources; | ||
| 173 | dummy_va_addr = (void*)__get_free_page(GFP_ATOMIC); | ||
| 144 | 174 | ||
| 145 | /* | 175 | /* |
| 146 | * Before acking the MMU fault, let's make sure MMU can only | 176 | * Before acking the MMU fault, let's make sure MMU can only |
| 147 | * access entry #0. Then add a new entry so that the DSP OS | 177 | * access entry #0. Then add a new entry so that the DSP OS |
| 148 | * can continue in order to dump the stack. | 178 | * can continue in order to dump the stack. |
| 149 | */ | 179 | */ |
| 150 | tmp = iommu_read_reg(mmu, MMU_CNTL); | 180 | hw_mmu_twl_disable(resources->dw_dmmu_base); |
| 151 | tmp &= ~MMU_CNTL_TWL_EN; | 181 | hw_mmu_tlb_flush_all(resources->dw_dmmu_base); |
| 152 | iommu_write_reg(mmu, tmp, MMU_CNTL); | 182 | |
| 153 | fa = iommu_read_reg(mmu, MMU_FAULT_AD); | 183 | hw_mmu_tlb_add(resources->dw_dmmu_base, |
| 154 | e.da = fa & PAGE_MASK; | 184 | virt_to_phys(dummy_va_addr), fault_addr, |
| 155 | e.pa = virt_to_phys(dummy_addr); | 185 | HW_PAGE_SIZE4KB, 1, |
| 156 | e.valid = 1; | 186 | &map_attrs, HW_SET, HW_SET); |
| 157 | e.prsvd = 1; | ||
| 158 | e.pgsz = IOVMF_PGSZ_4K & MMU_CAM_PGSZ_MASK; | ||
| 159 | e.endian = MMU_RAM_ENDIAN_LITTLE; | ||
| 160 | e.elsz = MMU_RAM_ELSZ_32; | ||
| 161 | e.mixed = 0; | ||
| 162 | |||
| 163 | load_iotlb_entry(dev_context->dsp_mmu, &e); | ||
| 164 | 187 | ||
| 165 | dsp_clk_enable(DSP_CLK_GPT8); | 188 | dsp_clk_enable(DSP_CLK_GPT8); |
| 166 | 189 | ||
| 167 | dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe); | 190 | dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe); |
| 168 | 191 | ||
| 169 | /* Clear MMU interrupt */ | 192 | /* Clear MMU interrupt */ |
| 170 | tmp = iommu_read_reg(mmu, MMU_IRQSTATUS); | 193 | hw_mmu_event_ack(resources->dw_dmmu_base, |
| 171 | iommu_write_reg(mmu, tmp, MMU_IRQSTATUS); | 194 | HW_MMU_TRANSLATION_FAULT); |
| 172 | |||
| 173 | dump_dsp_stack(dev_context); | 195 | dump_dsp_stack(dev_context); |
| 174 | dsp_clk_disable(DSP_CLK_GPT8); | 196 | dsp_clk_disable(DSP_CLK_GPT8); |
| 175 | 197 | ||
| 176 | iopgtable_clear_entry(mmu, fa); | 198 | hw_mmu_disable(resources->dw_dmmu_base); |
| 177 | free_page((unsigned long)dummy_addr); | 199 | free_page((unsigned long)dummy_va_addr); |
| 178 | } | 200 | } |
| 179 | #endif | 201 | #endif |
| 180 | 202 | ||
| @@ -193,7 +215,6 @@ void bridge_deh_notify(struct deh_mgr *deh, int event, int info) | |||
| 193 | { | 215 | { |
| 194 | struct bridge_dev_context *dev_context; | 216 | struct bridge_dev_context *dev_context; |
| 195 | const char *str = event_to_string(event); | 217 | const char *str = event_to_string(event); |
| 196 | u32 fa; | ||
| 197 | 218 | ||
| 198 | if (!deh) | 219 | if (!deh) |
| 199 | return; | 220 | return; |
| @@ -211,8 +232,8 @@ void bridge_deh_notify(struct deh_mgr *deh, int event, int info) | |||
| 211 | #endif | 232 | #endif |
| 212 | break; | 233 | break; |
| 213 | case DSP_MMUFAULT: | 234 | case DSP_MMUFAULT: |
| 214 | fa = iommu_read_reg(dev_context->dsp_mmu, MMU_FAULT_AD); | 235 | dev_err(bridge, "%s: %s, addr=0x%x", __func__, |
| 215 | dev_err(bridge, "%s: %s, addr=0x%x", __func__, str, fa); | 236 | str, fault_addr); |
| 216 | #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE | 237 | #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE |
| 217 | print_dsp_trace_buffer(dev_context); | 238 | print_dsp_trace_buffer(dev_context); |
| 218 | dump_dl_modules(dev_context); | 239 | dump_dl_modules(dev_context); |
