Commit c6a2af22 authored by Hiroshi DOYU's avatar Hiroshi DOYU Committed by Tony Lindgren

ARM: OMAP: Add MMU TWL support for omap1

Table Walking Logic(TWL) is supported in omap1.
Signed-off-by: default avatarHiroshi DOYU <Hiroshi.DOYU@nokia.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 92e21ae7
/* /*
* linux/arch/arm/mach-omap2/mmu.c * linux/arch/arm/mach-omap1/mmu.c
* *
* Support for non-MPU OMAP1 MMUs. * Support for non-MPU OMAP1 MMUs.
* *
...@@ -329,6 +329,14 @@ static void omap1_mmu_interrupt(struct omap_mmu *mmu) ...@@ -329,6 +329,14 @@ static void omap1_mmu_interrupt(struct omap_mmu *mmu)
schedule_work(&mmu->irq_work); schedule_work(&mmu->irq_work);
} }
static pgprot_t omap1_mmu_pte_get_attr(struct omap_mmu_tlb_entry *entry)
{
/* 4KB AP position as default */
u32 attr = entry->ap >> 4;
attr <<= ((entry->pgsz == OMAP_MMU_CAM_PAGESIZE_1MB) ? 6:0);
return attr;
}
struct omap_mmu_ops omap1_mmu_ops = { struct omap_mmu_ops omap1_mmu_ops = {
.startup = omap1_mmu_startup, .startup = omap1_mmu_startup,
.shutdown = omap1_mmu_shutdown, .shutdown = omap1_mmu_shutdown,
...@@ -341,5 +349,6 @@ struct omap_mmu_ops omap1_mmu_ops = { ...@@ -341,5 +349,6 @@ struct omap_mmu_ops omap1_mmu_ops = {
.cam_ram_alloc = omap1_mmu_cam_ram_alloc, .cam_ram_alloc = omap1_mmu_cam_ram_alloc,
.cam_ram_valid = omap1_mmu_cam_ram_valid, .cam_ram_valid = omap1_mmu_cam_ram_valid,
.interrupt = omap1_mmu_interrupt, .interrupt = omap1_mmu_interrupt,
.pte_get_attr = omap1_mmu_pte_get_attr,
}; };
EXPORT_SYMBOL_GPL(omap1_mmu_ops); EXPORT_SYMBOL_GPL(omap1_mmu_ops);
...@@ -685,12 +685,10 @@ int omap_mmu_load_pte_entry(struct omap_mmu *mmu, ...@@ -685,12 +685,10 @@ int omap_mmu_load_pte_entry(struct omap_mmu *mmu,
struct omap_mmu_tlb_entry *entry) struct omap_mmu_tlb_entry *entry)
{ {
int ret = -1; int ret = -1;
if ((!entry->prsvd) && (mmu->ops->pte_get_attr)) { /*XXX use PG_flag for prsvd */
/*XXX use PG_flag for prsvd */ ret = omap_mmu_load_pte(mmu, entry);
ret = omap_mmu_load_pte(mmu, entry); if (ret)
if (ret) return ret;
return ret;
}
if (entry->tlb) if (entry->tlb)
ret = omap_mmu_load_tlb_entry(mmu, entry); ret = omap_mmu_load_tlb_entry(mmu, entry);
return ret; return ret;
...@@ -702,8 +700,7 @@ int omap_mmu_clear_pte_entry(struct omap_mmu *mmu, unsigned long vadr) ...@@ -702,8 +700,7 @@ int omap_mmu_clear_pte_entry(struct omap_mmu *mmu, unsigned long vadr)
int ret = omap_mmu_clear_tlb_entry(mmu, vadr); int ret = omap_mmu_clear_tlb_entry(mmu, vadr);
if (ret) if (ret)
return ret; return ret;
if (mmu->ops->pte_get_attr) omap_mmu_clear_pte(mmu, vadr);
omap_mmu_clear_pte(mmu, vadr);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(omap_mmu_clear_pte_entry); EXPORT_SYMBOL_GPL(omap_mmu_clear_pte_entry);
...@@ -1036,17 +1033,18 @@ EXPORT_SYMBOL_GPL(omap_mmu_disable); ...@@ -1036,17 +1033,18 @@ EXPORT_SYMBOL_GPL(omap_mmu_disable);
void omap_mmu_enable(struct omap_mmu *mmu, int reset) void omap_mmu_enable(struct omap_mmu *mmu, int reset)
{ {
u32 val = OMAP_MMU_CNTL_MMU_EN; u32 val = OMAP_MMU_CNTL_MMU_EN | MMU_CNTL_TWLENABLE;
if (likely(reset)) if (likely(reset))
omap_mmu_reset(mmu); omap_mmu_reset(mmu);
#if defined(CONFIG_ARCH_OMAP2) /* FIXME */ #if defined(CONFIG_ARCH_OMAP2) /* FIXME */
if (mmu->ops->pte_get_attr) { omap_mmu_write_reg(mmu, (u32)virt_to_phys(mmu->twl_mm->pgd),
omap_mmu_write_reg(mmu, (u32)virt_to_phys(mmu->twl_mm->pgd), OMAP_MMU_TTB);
OMAP_MMU_TTB);
val |= MMU_CNTL_TWLENABLE;
}
#else #else
omap_mmu_write_reg(mmu, (u32)virt_to_phys(mmu->twl_mm->pgd) & 0xffff,
OMAP_MMU_TTB_L);
omap_mmu_write_reg(mmu, (u32)virt_to_phys(mmu->twl_mm->pgd) >> 16,
OMAP_MMU_TTB_H);
val |= OMAP_MMU_CNTL_RESET_SW; val |= OMAP_MMU_CNTL_RESET_SW;
#endif #endif
omap_mmu_write_reg(mmu, val, OMAP_MMU_CNTL); omap_mmu_write_reg(mmu, val, OMAP_MMU_CNTL);
...@@ -1463,13 +1461,10 @@ int omap_mmu_register(struct omap_mmu *mmu) ...@@ -1463,13 +1461,10 @@ int omap_mmu_register(struct omap_mmu *mmu)
if (!mmu->exmap_tbl) if (!mmu->exmap_tbl)
return -ENOMEM; return -ENOMEM;
if (mmu->ops->pte_get_attr) { mmu->twl_mm = mm_alloc();
struct mm_struct *mm = mm_alloc(); if (!mmu->twl_mm) {
if (!mm) { ret = -ENOMEM;
ret = -ENOMEM; goto err_mm_alloc;
goto err_mm_alloc;
}
mmu->twl_mm = mm;
} }
ret = device_register(&mmu->dev); ret = device_register(&mmu->dev);
...@@ -1532,11 +1527,9 @@ void omap_mmu_unregister(struct omap_mmu *mmu) ...@@ -1532,11 +1527,9 @@ void omap_mmu_unregister(struct omap_mmu *mmu)
kfree(mmu->exmap_tbl); kfree(mmu->exmap_tbl);
mmu->exmap_tbl = NULL; mmu->exmap_tbl = NULL;
if (mmu->ops->pte_get_attr) { if (mmu->twl_mm) {
if (mmu->twl_mm) { __mmdrop(mmu->twl_mm);
__mmdrop(mmu->twl_mm); mmu->twl_mm = NULL;
mmu->twl_mm = NULL;
}
} }
device_unregister(&mmu->dev); device_unregister(&mmu->dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment