Ejemplo n.º 1
0
bool usb_icbug_swfix_need(void)
{
	if (cpu_is_mx6sl())
		return false;
	else if ((mx6q_revision() > IMX_CHIP_REVISION_1_1))
		return false;
	else if ((mx6dl_revision() > IMX_CHIP_REVISION_1_0))
		return false;
	return true;
}
Ejemplo n.º 2
0
static void mx6_set_cpu_type(void)
{
	u32 cpu_type = readl(IO_ADDRESS(ANATOP_BASE_ADDR + 0x280));

	cpu_type >>= 16;
	if (cpu_type == 0x60) {
		mxc_set_cpu_type(MXC_CPU_MX6SL);
		imx_print_silicon_rev("i.MX6SoloLite", mx6sl_revision());
		return;
	}

	cpu_type = readl(IO_ADDRESS(ANATOP_BASE_ADDR + 0x260));
	cpu_type >>= 16;
	if (cpu_type == 0x63) {
		mxc_set_cpu_type(MXC_CPU_MX6Q);
		imx_print_silicon_rev("i.MX6Q", mx6q_revision());
	} else if (cpu_type == 0x61) {
		mxc_set_cpu_type(MXC_CPU_MX6DL);
		imx_print_silicon_rev("i.MX6DL/SOLO", mx6dl_revision());
	} else
		pr_err("Unknown CPU type: %x\n", cpu_type);
}
Ejemplo n.º 3
0
static int mx6_suspend_enter(suspend_state_t state)
{
	unsigned int wake_irq_isr[4];
	unsigned int cpu_type;
	struct gic_dist_state gds;
	struct gic_cpu_state gcs;
	bool arm_pg = false;

	if (cpu_is_mx6q())
		cpu_type = MXC_CPU_MX6Q;
	else if (cpu_is_mx6dl())
		cpu_type = MXC_CPU_MX6DL;
	else
		cpu_type = MXC_CPU_MX6SL;

	wake_irq_isr[0] = __raw_readl(gpc_base +
			GPC_ISR1_OFFSET) & gpc_wake_irq[0];
	wake_irq_isr[1] = __raw_readl(gpc_base +
			GPC_ISR2_OFFSET) & gpc_wake_irq[1];
	wake_irq_isr[2] = __raw_readl(gpc_base +
			GPC_ISR3_OFFSET) & gpc_wake_irq[2];
	wake_irq_isr[3] = __raw_readl(gpc_base +
			GPC_ISR4_OFFSET) & gpc_wake_irq[3];
	if (wake_irq_isr[0] | wake_irq_isr[1] |
			wake_irq_isr[2] | wake_irq_isr[3]) {
		printk(KERN_INFO "There are wakeup irq pending,system resume!\n");
		printk(KERN_INFO "wake_irq_isr[0-3]: 0x%x, 0x%x, 0x%x, 0x%x\n",
				wake_irq_isr[0], wake_irq_isr[1],
				wake_irq_isr[2], wake_irq_isr[3]);
		return 0;
	}
	mx6_suspend_store();

	/*
	 * i.MX6dl TO1.0/i.MX6dq TO1.1/1.0 TKT094231: can't support
	 * ARM_POWER_OFF mode.
	 */
	if (state == PM_SUSPEND_MEM &&
		((mx6dl_revision() == IMX_CHIP_REVISION_1_0) ||
		(cpu_is_mx6q() && mx6q_revision() <= IMX_CHIP_REVISION_1_1))) {
		state = PM_SUSPEND_STANDBY;
	}

	switch (state) {
	case PM_SUSPEND_MEM:
		disp_power_down();
		usb_power_down_handler();
		mxc_cpu_lp_set(ARM_POWER_OFF);
		arm_pg = true;
		break;
	case PM_SUSPEND_STANDBY:
		if (cpu_is_mx6sl()) {
			disp_power_down();
			usb_power_down_handler();
			mxc_cpu_lp_set(STOP_XTAL_ON);
			arm_pg = true;
		} else
			mxc_cpu_lp_set(STOP_POWER_OFF);
		break;
	default:
		return -EINVAL;
	}

	/*
	 * L2 can exit by 'reset' or Inband beacon (from remote EP)
	 * toggling phy_powerdown has same effect as 'inband beacon'
	 * So, toggle bit18 of GPR1, to fix errata
	 * "PCIe PCIe does not support L2 Power Down"
	 */
	__raw_writel(__raw_readl(IOMUXC_GPR1) | (1 << 18), IOMUXC_GPR1);

	if (state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY) {

		local_flush_tlb_all();
		flush_cache_all();

		if (arm_pg) {
			/* preserve gic state */
			save_gic_dist_state(0, &gds);
			save_gic_cpu_state(0, &gcs);
		}

		if (pm_data && pm_data->suspend_enter)
			pm_data->suspend_enter();

		suspend_in_iram(state, (unsigned long)iram_paddr,
			(unsigned long)suspend_iram_base, cpu_type);

		if (pm_data && pm_data->suspend_exit)
			pm_data->suspend_exit();

		/* Reset the RBC counter. */
		/* All interrupts should be masked before the
		  * RBC counter is reset.
		 */
		/* Mask all interrupts. These will be unmasked by
		  * the mx6_suspend_restore routine below.
		  */
		__raw_writel(0xffffffff, gpc_base + 0x08);
		__raw_writel(0xffffffff, gpc_base + 0x0c);
		__raw_writel(0xffffffff, gpc_base + 0x10);
		__raw_writel(0xffffffff, gpc_base + 0x14);

		/* Clear the RBC counter and RBC_EN bit. */
		/* Disable the REG_BYPASS_COUNTER. */
		__raw_writel(__raw_readl(MXC_CCM_CCR) &
			~MXC_CCM_CCR_RBC_EN, MXC_CCM_CCR);
		/* Make sure we clear REG_BYPASS_COUNT*/
		__raw_writel(__raw_readl(MXC_CCM_CCR) &
		(~MXC_CCM_CCR_REG_BYPASS_CNT_MASK), MXC_CCM_CCR);
		/* Need to wait for a minimum of 2 CLKILS (32KHz) for the
		  * counter to clear and reset.
		  */
		udelay(80);

		if (arm_pg) {
			/* restore gic registers */
			restore_gic_dist_state(0, &gds);
			restore_gic_cpu_state(0, &gcs);
		}
		if (state == PM_SUSPEND_MEM || (cpu_is_mx6sl())) {
			usb_power_up_handler();
			disp_power_up();
		}

		mx6_suspend_restore();

		__raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG,
			anatop_base + HW_ANADIG_ANA_MISC0_CLR);

	} else {
			cpu_do_idle();
	}

	/*
	 * L2 can exit by 'reset' or Inband beacon (from remote EP)
	 * toggling phy_powerdown has same effect as 'inband beacon'
	 * So, toggle bit18 of GPR1, to fix errata
	 * "PCIe PCIe does not support L2 Power Down"
	 */
	__raw_writel(__raw_readl(IOMUXC_GPR1) & (~(1 << 18)), IOMUXC_GPR1);

	return 0;
}
Ejemplo n.º 4
0
/* set cpu low power mode before WFI instruction */
void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
{

	int stop_mode = 0;
	void __iomem *anatop_base = IO_ADDRESS(ANATOP_BASE_ADDR);
	u32 ccm_clpcr, anatop_val;

	ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);

	switch (mode) {
	case WAIT_CLOCKED:
		break;
	case WAIT_UNCLOCKED:
		ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
		break;
	case WAIT_UNCLOCKED_POWER_OFF:
	case STOP_POWER_OFF:
	case ARM_POWER_OFF:
		if (mode == WAIT_UNCLOCKED_POWER_OFF) {
			ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
			ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
			ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
			if (cpu_is_mx6sl()) {
				ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS;
				ccm_clpcr |= MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY;
			} else
				ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
			stop_mode = 0;
		} else if (mode == STOP_POWER_OFF) {
			ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
			ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
			ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
			ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
			if (cpu_is_mx6sl()) {
				ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS;
				ccm_clpcr |= MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY;
			} else
				ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
			stop_mode = 1;
		} else {
			ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
			ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
			ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
			ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
			if (cpu_is_mx6sl()) {
				ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS;
				ccm_clpcr |= MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY;
			} else
				ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
			stop_mode = 2;
		}
		break;
	case STOP_XTAL_ON:
		ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
		ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
		ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
		if (cpu_is_mx6sl()) {
			ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS;
			ccm_clpcr |= MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY;
		} else
			ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
		stop_mode = 3;

		break;
	default:
		printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
		return;
	}

	if (stop_mode > 0) {
		gpc_set_wakeup(gpc_wake_irq);
		/* Power down and power up sequence */
		/* The PUPSCR counter counts in terms of CLKIL (32KHz) cycles.
		   * The PUPSCR should include the time it takes for the ARM LDO to
		   * ramp up.
		   */
		__raw_writel(0x202, gpc_base + GPC_PGC_CPU_PUPSCR_OFFSET);
		/* The PDNSCR is a counter that counts in IPG_CLK cycles. This counter
		  * can be set to minimum values to power down faster.
		  */
		__raw_writel(0x101, gpc_base + GPC_PGC_CPU_PDNSCR_OFFSET);
		if (stop_mode >= 2) {
			/* dormant mode, need to power off the arm core */
			__raw_writel(0x1, gpc_base + GPC_PGC_CPU_PDN_OFFSET);
			if (cpu_is_mx6q() || cpu_is_mx6dl()) {
				/* If stop_mode_config is clear, then 2P5 will be off,
				need to enable weak 2P5, as DDR IO need 2P5 as
				pre-driver */
				if ((__raw_readl(anatop_base + HW_ANADIG_ANA_MISC0)
					& BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) {
					/* Enable weak 2P5 linear regulator */
					anatop_val = __raw_readl(anatop_base +
						HW_ANADIG_REG_2P5);
					anatop_val |= BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG;
					__raw_writel(anatop_val, anatop_base +
						HW_ANADIG_REG_2P5);
				}
				if (mx6q_revision() != IMX_CHIP_REVISION_1_0) {
					/* Enable fet_odrive */
					anatop_val = __raw_readl(anatop_base +
						HW_ANADIG_REG_CORE);
					anatop_val |= BM_ANADIG_REG_CORE_FET_ODRIVE;
					__raw_writel(anatop_val, anatop_base +
						HW_ANADIG_REG_CORE);
				}
			} else {
				if (stop_mode == 2) {
					/* Disable VDDHIGH_IN to VDDSNVS_IN
					  * power path, only used when VDDSNVS_IN
					  * is powered by dedicated
					 * power rail */
					anatop_val = __raw_readl(anatop_base +
						HW_ANADIG_ANA_MISC0);
					anatop_val |= BM_ANADIG_ANA_MISC0_RTC_RINGOSC_EN;
					__raw_writel(anatop_val, anatop_base +
						HW_ANADIG_ANA_MISC0);
					/* Need to enable pull down if 2P5 is disabled */
					anatop_val = __raw_readl(anatop_base +
						HW_ANADIG_REG_2P5);
					anatop_val |= BM_ANADIG_REG_2P5_ENABLE_PULLDOWN;
					__raw_writel(anatop_val, anatop_base +
						HW_ANADIG_REG_2P5);
				}
			}
			if (stop_mode != 3) {
				/* Make sure we clear WB_COUNT
				  * and re-config it.
				  */
				__raw_writel(__raw_readl(MXC_CCM_CCR) &
					(~MXC_CCM_CCR_WB_COUNT_MASK),
					MXC_CCM_CCR);
				/* Reconfigure WB, need to set WB counter
				 * to 0x7 to make sure it work normally */
				__raw_writel(__raw_readl(MXC_CCM_CCR) |
					(0x7 << MXC_CCM_CCR_WB_COUNT_OFFSET),
					MXC_CCM_CCR);

				/* Set WB_PER enable */
				ccm_clpcr |= MXC_CCM_CLPCR_WB_PER_AT_LPM;
			}
		}
		if (cpu_is_mx6sl() ||
			(mx6q_revision() > IMX_CHIP_REVISION_1_1) ||
			(mx6dl_revision() > IMX_CHIP_REVISION_1_0)) {
			u32 reg;
			/* We need to allow the memories to be clock gated
			  * in STOP mode, else the power consumption will
			  * be very high.
			  */
			reg = __raw_readl(MXC_CCM_CGPR);
			reg |= MXC_CCM_CGPR_MEM_IPG_STOP_MASK;
			if (!cpu_is_mx6sl()) {
				/*
				  * For MX6QTO1.2 or later and MX6DLTO1.1 or later,
				  * ensure that the CCM_CGPR bit 17 is cleared before
				  * dormant mode is entered.
				  */
				reg &= ~MXC_CCM_CGPR_WAIT_MODE_FIX;
			}
			__raw_writel(reg, MXC_CCM_CGPR);
		}
	}
	__raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
}
Ejemplo n.º 5
0
unsigned int hdmi_SDMA_check(void)
{
    return (mx6q_revision() > IMX_CHIP_REVISION_1_1) ||
           (mx6dl_revision() > IMX_CHIP_REVISION_1_0);
}
Ejemplo n.º 6
0
static int __init post_cpu_init(void)
{
	unsigned int reg;
	void __iomem *base;
	u32	iram_size;

	if (cpu_is_mx6q())
		iram_size = MX6Q_IRAM_SIZE;
	else
		iram_size = MX6DL_MX6SL_IRAM_SIZE;

	iram_init(MX6Q_IRAM_BASE_ADDR, iram_size);

	base = ioremap(AIPS1_ON_BASE_ADDR, PAGE_SIZE);
	__raw_writel(0x0, base + 0x40);
	__raw_writel(0x0, base + 0x44);
	__raw_writel(0x0, base + 0x48);
	__raw_writel(0x0, base + 0x4C);
	reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
	__raw_writel(reg, base + 0x50);
	iounmap(base);

	base = ioremap(AIPS2_ON_BASE_ADDR, PAGE_SIZE);
	__raw_writel(0x0, base + 0x40);
	__raw_writel(0x0, base + 0x44);
	__raw_writel(0x0, base + 0x48);
	__raw_writel(0x0, base + 0x4C);
	reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
	__raw_writel(reg, base + 0x50);
	iounmap(base);

	/* Allow SCU_CLK to be disabled when all cores are in WFI*/
	base = IO_ADDRESS(SCU_BASE_ADDR);
	reg = __raw_readl(base);
	reg |= 0x20;
	__raw_writel(reg, base);

	/* Disable SRC warm reset to work aound system reboot issue */
	base = IO_ADDRESS(SRC_BASE_ADDR);
	reg = __raw_readl(base);
	reg &= ~0x1;
	__raw_writel(reg, base);

	gpc_base = MX6_IO_ADDRESS(GPC_BASE_ADDR);
	ccm_base = MX6_IO_ADDRESS(CCM_BASE_ADDR);

	/* enable AXI cache for VDOA/VPU/IPU
	 * set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7
	 * clear OCRAM_CTL bits to disable pipeline control
	 */
	reg = __raw_readl(IOMUXC_GPR3);
	reg &= ~IOMUXC_GPR3_OCRAM_CTL_EN;
	__raw_writel(reg, IOMUXC_GPR3);
	reg = __raw_readl(IOMUXC_GPR4);
	reg |= IOMUXC_GPR4_VDOA_CACHE_EN | IOMUXC_GPR4_VPU_CACHE_EN |
		IOMUXC_GPR4_IPU_CACHE_EN;
	__raw_writel(reg, IOMUXC_GPR4);
	__raw_writel(IOMUXC_GPR6_IPU1_QOS, IOMUXC_GPR6);
	__raw_writel(IOMUXC_GPR7_IPU2_QOS, IOMUXC_GPR7);

	num_cpu_idle_lock = 0x0;
	if (cpu_is_mx6dl())
		num_cpu_idle_lock = 0xffff0000;

#ifdef CONFIG_SMP
	switch (setup_max_cpus) {
	case 3:
		num_cpu_idle_lock = 0xff000000;
		break;
	case 2:
		num_cpu_idle_lock = 0xffff0000;
		break;
	case 1:
	case 0:
		num_cpu_idle_lock = 0xffffff00;
		break;
	}
#endif
	/*
	  * The option to keep ARM memory clocks enabled during WAIT
	  * is only available on MX6SL, MX6DQ TO1.2  (or later) and
	  * MX6DL TO1.1 (or later)
	  * So if the user specifies "mem_clk_on" on any other chip,
	  * ensure that it is disabled.
	  */
	if (!cpu_is_mx6sl() && (mx6q_revision() < IMX_CHIP_REVISION_1_2) &&
		(mx6dl_revision() < IMX_CHIP_REVISION_1_1))
		mem_clk_on_in_wait = false;

	if (cpu_is_mx6q())
		chip_rev = mx6q_revision();
	else if (cpu_is_mx6dl())
		chip_rev = mx6dl_revision();
	else
		chip_rev = mx6sl_revision();

	/* mx6sl doesn't have pcie. save power, disable PCIe PHY */
	if (!cpu_is_mx6sl()) {
		reg = __raw_readl(IOMUXC_GPR1);
		reg = reg & (~IOMUXC_GPR1_PCIE_REF_CLK_EN);
		reg |= IOMUXC_GPR1_TEST_POWERDOWN;
		__raw_writel(reg, IOMUXC_GPR1);
	}
	return 0;
}