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,7 +700,6 @@ int omap_mmu_clear_pte_entry(struct omap_mmu *mmu, unsigned long vadr) ...@@ -702,7 +700,6 @@ 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;
} }
...@@ -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,14 +1461,11 @@ int omap_mmu_register(struct omap_mmu *mmu) ...@@ -1463,14 +1461,11 @@ 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);
if (unlikely(ret)) if (unlikely(ret))
...@@ -1532,12 +1527,10 @@ void omap_mmu_unregister(struct omap_mmu *mmu) ...@@ -1532,12 +1527,10 @@ 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