Exemplo n.º 1
0
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);
}