static void mali_meson_poweron(int first_poweron) { unsigned long flags; u32 p, p_aligned; dma_addr_t p_phy; int i; unsigned int_mask; if(!first_poweron) { if ((last_power_mode != -1) && (last_power_mode != MALI_POWER_MODE_DEEP_SLEEP)) { MALI_DEBUG_PRINT(3, ("Maybe your system not deep sleep now.......\n")); //printk("Maybe your system not deep sleep now.......\n"); return; } } MALI_DEBUG_PRINT(2, ("mali_meson_poweron: Mali APB bus accessing\n")); if (READ_MALI_REG(MALI_PP_PP_VERSION) != MALI_PP_PP_VERSION_MAGIC) { MALI_DEBUG_PRINT(3, ("mali_meson_poweron: Mali APB bus access failed\n")); //printk("mali_meson_poweron: Mali APB bus access failed."); return; } MALI_DEBUG_PRINT(2, ("..........accessing done.\n")); if (READ_MALI_REG(MALI_MMU_DTE_ADDR) != 0) { MALI_DEBUG_PRINT(3, ("mali_meson_poweron: Mali is not really powered off\n")); //printk("mali_meson_poweron: Mali is not really powered off."); return; } p = (u32)kcalloc(4096 * 4, 1, GFP_KERNEL); if (!p) { printk("mali_meson_poweron: NOMEM in meson_poweron\n"); return; } p_aligned = __ALIGN_MASK(p, 4096); /* DTE */ *(u32 *)(p_aligned) = (virt_to_phys((void *)p_aligned) + OFFSET_MMU_PTE) | MMU_FLAG_DTE_PRESENT; /* PTE */ for (i=0; i<1024; i++) { *(u32 *)(p_aligned + OFFSET_MMU_PTE + i*4) = (virt_to_phys((void *)p_aligned) + OFFSET_MMU_VIRTUAL_ZERO + 4096 * i) | MMU_FLAG_PTE_PAGE_PRESENT | MMU_FLAG_PTE_RD_PERMISSION; } /* command & data */ memcpy((void *)(p_aligned + OFFSET_MMU_VIRTUAL_ZERO), poweron_data, 4096); p_phy = dma_map_single(NULL, (void *)p_aligned, 4096 * 3, DMA_TO_DEVICE); /* Set up Mali GP MMU */ WRITE_MALI_REG(MALI_MMU_DTE_ADDR, p_phy); WRITE_MALI_REG(MALI_MMU_CMD, 0); if ((READ_MALI_REG(MALI_MMU_STATUS) & 1) != 1) printk("mali_meson_poweron: MMU enabling failed.\n"); /* Set up Mali command registers */ WRITE_MALI_REG(MALI_APB_GP_VSCL_START, 0); WRITE_MALI_REG(MALI_APB_GP_VSCL_END, 0x38); spin_lock_irqsave(&lock, flags); int_mask = READ_MALI_REG(MALI_APB_GP_INT_MASK); WRITE_MALI_REG(MALI_APB_GP_INT_CLEAR, 0x707bff); WRITE_MALI_REG(MALI_APB_GP_INT_MASK, 0); /* Start GP */ WRITE_MALI_REG(MALI_APB_GP_CMD, 1); for (i = 0; i<100; i++) udelay(500); /* check Mali GP interrupt */ if (READ_MALI_REG(MALI_APB_GP_INT_RAWSTAT) & 0x707bff) printk("mali_meson_poweron: Interrupt received.\n"); else printk("mali_meson_poweron: No interrupt received.\n"); /* force reset GP */ WRITE_MALI_REG(MALI_APB_GP_CMD, 1 << 5); /* stop MMU paging and reset */ WRITE_MALI_REG(MALI_MMU_CMD, 1); WRITE_MALI_REG(MALI_MMU_CMD, 6); for (i = 0; i<100; i++) udelay(500); WRITE_MALI_REG(MALI_APB_GP_INT_CLEAR, 0x3ff); WRITE_MALI_REG(MALI_MMU_INT_CLEAR, INT_ALL); WRITE_MALI_REG(MALI_MMU_INT_MASK, 0); WRITE_MALI_REG(MALI_APB_GP_INT_CLEAR, 0x707bff); WRITE_MALI_REG(MALI_APB_GP_INT_MASK, int_mask); spin_unlock_irqrestore(&lock, flags); dma_unmap_single(NULL, p_phy, 4096 * 3, DMA_TO_DEVICE); kfree((void *)p); /* Mali revision detection */ if (last_power_mode == -1) mali_revb_flag = mali_meson_is_revb(); }
void mali_meson_poweron(void) { unsigned long flags; u32 p, p_aligned; dma_addr_t p_phy; int i; unsigned int_mask; if ((last_power_mode != -1) && (last_power_mode != MALI_POWER_MODE_DEEP_SLEEP)) { return; } if (READ_MALI_REG(MALI_PP_PP_VERSION) != MALI_PP_PP_VERSION_MAGIC) { printk("mali_meson_poweron: Mali APB bus access failed."); return; } if (READ_MALI_REG(MALI_MMU_DTE_ADDR) != 0) { printk("mali_meson_poweron: Mali is not really powered off."); return; } p = (u32)kcalloc(4096 * 4, 1, GFP_KERNEL); if (!p) { printk("mali_meson_poweron: NOMEM in meson_poweron\n"); return; } p_aligned = __ALIGN_MASK(p, 4096); /* DTE */ *(u32 *)(p_aligned) = (virt_to_phys((void *)p_aligned) + OFFSET_MMU_PTE) | MMU_FLAG_DTE_PRESENT; /* PTE */ for (i=0; i<1024; i++) { *(u32 *)(p_aligned + OFFSET_MMU_PTE + i*4) = (virt_to_phys((void *)p_aligned) + OFFSET_MMU_VIRTUAL_ZERO + 4096 * i) | MMU_FLAG_PTE_PAGE_PRESENT | MMU_FLAG_PTE_RD_PERMISSION; } /* command & data */ memcpy((void *)(p_aligned + OFFSET_MMU_VIRTUAL_ZERO), poweron_data, 4096); p_phy = dma_map_single(NULL, (void *)p_aligned, 4096 * 3, DMA_TO_DEVICE); /* Set up Mali GP MMU */ WRITE_MALI_REG(MALI_MMU_DTE_ADDR, p_phy); WRITE_MALI_REG(MALI_MMU_CMD, 0); if ((READ_MALI_REG(MALI_MMU_STATUS) & 1) != 1) { printk("mali_meson_poweron: MMU enabling failed.\n"); } /* Set up Mali command registers */ WRITE_MALI_REG(MALI_APB_GP_VSCL_START, 0); WRITE_MALI_REG(MALI_APB_GP_VSCL_END, 0x38); WRITE_MALI_REG(MALI_APB_GP_INT_MASK, 0x3ff); spin_lock_irqsave(&lock, flags); int_mask = READ_CBUS_REG(A9_0_IRQ_IN1_INTR_MASK); /* Set up ARM Mali interrupt */ WRITE_CBUS_REG(A9_0_IRQ_IN1_INTR_STAT_CLR, 1 << 16); SET_CBUS_REG_MASK(A9_0_IRQ_IN1_INTR_MASK, 1 << 16); /* Start GP */ WRITE_MALI_REG(MALI_APB_GP_CMD, 1); for (i = 0; i<100; i++) udelay(500); /* check Mali GP interrupt */ if (READ_CBUS_REG(A9_0_IRQ_IN1_INTR_STAT) & (1<<16)) { printk("mali_meson_poweron: Interrupt received.\n"); } else { printk("mali_meson_poweron: No interrupt received.\n"); } WRITE_CBUS_REG(A9_0_IRQ_IN1_INTR_STAT_CLR, 1 << 16); CLEAR_CBUS_REG_MASK(A9_0_IRQ_IN1_INTR_MASK, 1 << 16); /* force reset GP */ WRITE_MALI_REG(MALI_APB_GP_CMD, 1 << 5); /* stop MMU paging and reset */ WRITE_MALI_REG(MALI_MMU_CMD, 1); WRITE_MALI_REG(MALI_MMU_CMD, 1 << 6); WRITE_CBUS_REG(A9_0_IRQ_IN1_INTR_MASK, int_mask); spin_unlock_irqrestore(&lock, flags); dma_unmap_single(NULL, p_phy, 4096 * 3, DMA_TO_DEVICE); kfree((void *)p); }