Пример #1
0
/*
 * make sure USB_CLK is running at 60 MHz +/- 1000 Hz
 */
static int fsl_check_usbclk(void)
{
	unsigned long freq;

	usb_ahb_clk = clk_get(NULL, "usb_ahb_clk");
	if (clk_enable(usb_ahb_clk)) {
		if (cpu_is_mx6q() || cpu_is_mx6dl())
			return 0; /* there is no ahb clock at mx6 */
		printk(KERN_ERR "clk_enable(usb_ahb_clk) failed\n");
		return -EINVAL;
	}
	clk_put(usb_ahb_clk);

	usb_clk = clk_get(NULL, "usb_clk");
	if (clk_enable(usb_clk)) {
		if (cpu_is_mx6q() || cpu_is_mx6dl())
			return 0; /* there is usb_clk at mx6 */
		printk(KERN_ERR "clk_enable(usb_clk) failed\n");
		return -EINVAL;
	}
	freq = clk_get_rate(usb_clk);
	clk_put(usb_clk);
	if ((freq < 59999000) || (freq > 60001000)) {
		printk(KERN_ERR "USB_CLK=%lu, should be 60MHz\n", freq);
		return -1;
	}

	return 0;
}
Пример #2
0
static int mx6q_seco_q7_fec_phy_reset(struct phy_device *phydev) {
	int ret;
	if(cpu_is_mx6q())
		mxc_iomux_v3_setup_pad(MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24);
	if(cpu_is_mx6dl())
                mxc_iomux_v3_setup_pad(MX6DL_PAD_RGMII_RX_CTL__GPIO_6_24);
	ret = gpio_request(MX6_ENET_125MHz_EN, "125mHz_en");
	if (!ret) {
		gpio_direction_output(MX6_ENET_125MHz_EN, 1);
		gpio_set_value(MX6_ENET_125MHz_EN, 1);
		printk("Resetting ethernet physical layer.\n");
		gpio_set_value(MX6_SECO_Q7_FEC_RESET, 0);
		msleep(2);
		gpio_set_value(MX6_SECO_Q7_FEC_RESET, 1);
		msleep(1);
		gpio_free(MX6_ENET_125MHz_EN);
		if(cpu_is_mx6q())
			mxc_iomux_v3_setup_pad(MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL);
		if(cpu_is_mx6dl())
			mxc_iomux_v3_setup_pad(MX6DL_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL);
	} else {
		printk(KERN_ERR "Reset of ethernet physical layer failed.\n");
	}
	return 0;
}
Пример #3
0
static void ov5640_mipi_camera_io_init(void)
{
	struct clk *clko1;
	
	if (cpu_is_mx6q())
	{
		mxc_iomux_v3_setup_pad(MX6Q_PAD_CSI0_MCLK__CCM_CLKO);
		mxc_iomux_v3_setup_pad(MX6Q_PAD_CSI0_DAT18__GPIO_6_4);
	}
	else
	{
		mxc_iomux_v3_setup_pad(MX6DL_PAD_CSI0_MCLK__CCM_CLKO);
		mxc_iomux_v3_setup_pad(MX6DL_PAD_CSI0_DAT18__GPIO_6_4);
	}
	
	clko1 = clk_get(NULL, "clko_clk");
	if (IS_ERR(clko1)) {
		pr_err("can't get CLKO1 clock.\n");
	} else {
		long round = clk_round_rate(clko1, 27000000);
		clk_set_rate(clko1, round);
		clk_enable(clko1);
	}
	
	/* Camera reset */
	gpio_request(MX6_CAMERA_RST, "cam-reset");
	gpio_direction_output(MX6_CAMERA_RST, 0);
	msleep(1);
	gpio_set_value(MX6_CAMERA_RST, 1);
	msleep(100);
	
/* for mx6dl, mipi virtual channel 1 connect to csi 0*/
	if (cpu_is_mx6dl())
		mxc_iomux_set_gpr_register(13, 0, 3, 0);	
}
Пример #4
0
static void __init imx6q_seco_q7_init_usb(void) {
	int ret = 0;

	imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
	/* disable external charger detect,
	 * or it will affect signal quality at dp .
	 */
	ret = gpio_request(MX6_SECO_A62_USB_OTG_PWR, "usb-pwr");
	if (ret) {
		pr_err("failed to get GPIO MX6_SECO_A62_USB_OTG_PWR: %d\n",
			ret);
		return;
	}
	gpio_direction_output(MX6_SECO_A62_USB_OTG_PWR, 0);
	mxc_iomux_set_gpr_register(1, 13, 1, 0);
	
	/*
	 * Setting pad control for OTG ID pin UP because the OTG port
	 * is used only as client
	*/
	if (cpu_is_mx6q())
		mxc_iomux_v3_setup_pad(mx6qd_seco_a62_otg_id_up_pads);
        else if (cpu_is_mx6dl()) 
		mxc_iomux_v3_setup_pad(mx6sdl_seco_a62_otg_id_up_pads);

	mx6_set_otghost_vbus_func(imx6q_seco_q7_usbotg_vbus);
//	mx6_usb_dr_init();
//	mx6_usb_h1_init();
}
static void mx6q_csi0_io_init(void)
{
	if (cpu_is_mx6q())
		mxc_iomux_set_gpr_register(1, 19, 1, 1);
	else if (cpu_is_mx6dl())
		mxc_iomux_set_gpr_register(13, 0, 3, 4);
}
Пример #6
0
struct cpu_op *mx6_get_cpu_op(int *op)
{
	if (cpu_is_mx6dl()) {
		if (arm_max_freq == CPU_AT_1_2GHz) {
			*op =  num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1_2G);
			return mx6dl_cpu_op_1_2G;
		} else if (arm_max_freq == CPU_AT_1GHz) {
			*op =  num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1G);
			return mx6dl_cpu_op_1G;
		} else {
			*op =  num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op);
			return mx6dl_cpu_op;
		}
	} else if (cpu_is_mx6q()) {
		if (arm_max_freq == CPU_AT_1_2GHz) {
			*op =  num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1_2G);
			return mx6q_cpu_op_1_2G;
		} else if (arm_max_freq == CPU_AT_1GHz) {
			*op =  num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1G);
			return mx6q_cpu_op_1G;
		} else {
			*op =  num_cpu_op = ARRAY_SIZE(mx6q_cpu_op);
			return mx6q_cpu_op;
		}
	} else {
		if (arm_max_freq == CPU_AT_1GHz) {
			*op =  num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op_1G);
			return mx6sl_cpu_op_1G;
		} else {
			*op =  num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op);
			return mx6sl_cpu_op;
		}
	}
}
void __init mx6_usb_h2_init(void)
{
	struct platform_device *pdev, *pdev_wakeup;
	static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
	usbh2_config.wakeup_pdata = &usbh2_wakeup_config;

	hsic_strobe_start_pad = cpu_is_mx6q() ? MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE_START :
			(cpu_is_mx6dl() ? MX6DL_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE_START :
			(cpu_is_mx6sl() ? MX6SL_PAD_HSIC_STROBE__USB_H_STROBE_START : 0));

	if (cpu_is_mx6sl())
		pdev = imx6sl_add_fsl_ehci_hs(2, &usbh2_config);
	else
		pdev = imx6q_add_fsl_ehci_hs(2, &usbh2_config);

	usbh2_wakeup_config.usb_pdata[0] = pdev->dev.platform_data;
	if (cpu_is_mx6sl())
		pdev_wakeup = imx6sl_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config);
	else
		pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config);
	platform_device_add(pdev);
	((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata =
		pdev_wakeup->dev.platform_data;
	/* Some phy and power's special controls for host2
	 * 1. Its 480M is from OTG's 480M
	 * 2. EN_USB_CLKS should always be opened
	 */
	__raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS,
			anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET);
	/* must change the clkgate delay to 2 or 3 to avoid
	 * 24M OSCI clock not stable issue */
	__raw_writel(BF_ANADIG_ANA_MISC0_CLKGATE_DELAY(3),
			anatop_base_addr + HW_ANADIG_ANA_MISC0);
}
Пример #8
0
void arch_idle_multi_core(void)
{
	u32 reg;
	int cpu = smp_processor_id();

#ifdef CONFIG_LOCAL_TIMERS
	if (!tick_broadcast_oneshot_active()
		|| !tick_oneshot_mode_active())
		return;

	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
#endif
	/* iMX6Q and iMX6DL */
	if ((cpu_is_mx6q() && chip_rev >= IMX_CHIP_REVISION_1_2) ||
		(cpu_is_mx6dl() && chip_rev >= IMX_CHIP_REVISION_1_1)) {
		/*
		  * This code should only be executed on MX6QTO1.2 or later
		  * and MX6DL TO1.1 or later.
		  * These chips have the HW fix for the WAIT mode issue.
		  * Ensure that the CGPR bit 17 is set to enable the fix.
		  */

		reg = __raw_readl(MXC_CCM_CGPR);
		reg |= MXC_CCM_CGPR_WAIT_MODE_FIX;
		__raw_writel(reg, MXC_CCM_CGPR);

		ca9_do_idle();
	} else
		arch_idle_with_workaround(cpu);
#ifdef CONFIG_LOCAL_TIMERS
	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
#endif

}
Пример #9
0
static int __init busfreq_init(void)
{
	if (platform_driver_register(&busfreq_driver) != 0) {
		printk(KERN_ERR "busfreq_driver register failed\n");
		return -ENODEV;
	}

	printk(KERN_INFO "Bus freq driver module loaded\n");

#ifdef CONFIG_MX6_VPU_352M
	if (cpu_is_mx6q())
		bus_freq_scaling_is_active = 0;/*disable bus_freq*/

#else
	/* Enable busfreq by default. */
	bus_freq_scaling_is_active = 1;
#endif
	if (cpu_is_mx6q())
		set_high_bus_freq(1);
	else if (cpu_is_mx6dl())
		set_high_bus_freq(0);

	printk(KERN_INFO "Bus freq driver Enabled\n");
	return 0;
}
Пример #10
0
static int plt_sd_pad_change(unsigned int index, int clock)
{
	/* LOW speed is the default state of SD pads */
	static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;

	iomux_v3_cfg_t *sd_pads_200mhz = NULL;
	iomux_v3_cfg_t *sd_pads_100mhz = NULL;
	iomux_v3_cfg_t *sd_pads_50mhz = NULL;

	u32 sd_pads_200mhz_cnt;
	u32 sd_pads_100mhz_cnt;
	u32 sd_pads_50mhz_cnt;

	if (index != 2) {
		printk(KERN_ERR"no such SD host controller index %d\n", index);
		return -EINVAL;
	}

	if (cpu_is_mx6q()) {
		sd_pads_200mhz = mx6q_sd3_200mhz;
		sd_pads_100mhz = mx6q_sd3_100mhz;
		sd_pads_50mhz = mx6q_sd3_50mhz;

		sd_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd3_200mhz);
		sd_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd3_100mhz);
		sd_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd3_50mhz);
	} else if (cpu_is_mx6dl()) {
		sd_pads_200mhz = mx6dl_sd3_200mhz;
		sd_pads_100mhz = mx6dl_sd3_100mhz;
		sd_pads_50mhz = mx6dl_sd3_50mhz;

		sd_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd3_200mhz);
		sd_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd3_100mhz);
		sd_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd3_50mhz);
	}

	if (clock > 100000000) {
		if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
			return 0;
		BUG_ON(!sd_pads_200mhz);
		pad_mode = SD_PAD_MODE_HIGH_SPEED;
		return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
							sd_pads_200mhz_cnt);
	} else if (clock > 52000000) {
		if (pad_mode == SD_PAD_MODE_MED_SPEED)
			return 0;
		BUG_ON(!sd_pads_100mhz);
		pad_mode = SD_PAD_MODE_MED_SPEED;
		return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
							sd_pads_100mhz_cnt);
	} else {
		if (pad_mode == SD_PAD_MODE_LOW_SPEED)
			return 0;
		BUG_ON(!sd_pads_50mhz);
		pad_mode = SD_PAD_MODE_LOW_SPEED;
		return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
							sd_pads_50mhz_cnt);
	}
}
Пример #11
0
static void hdmi_disable_ddc_pin(void)
{
	if (cpu_is_mx6dl())
		mxc_iomux_v3_setup_multiple_pads(mx6dl_sabreauto_i2c2_pads,
			ARRAY_SIZE(mx6dl_sabreauto_i2c2_pads));
	else
		mxc_iomux_v3_setup_multiple_pads(mx6q_sabreauto_i2c2_pads,
			ARRAY_SIZE(mx6q_sabreauto_i2c2_pads));
}
static void hdmi_enable_ddc_pin(void)
{
    if (cpu_is_mx6dl())
        mxc_iomux_v3_setup_multiple_pads(mx6dl_hdmidongle_hdmi_ddc_pads,
                                         ARRAY_SIZE(mx6dl_hdmidongle_hdmi_ddc_pads));
    else
        mxc_iomux_v3_setup_multiple_pads(mx6q_hdmidongle_hdmi_ddc_pads,
                                         ARRAY_SIZE(mx6q_hdmidongle_hdmi_ddc_pads));
}
Пример #13
0
static void mipi_camera_io_init(void)
{
	pr_info("%s\n", __func__);

	camera_reset(GP_CAMERA_RESET);
/* for mx6dl, mipi virtual channel 1 connect to csi 1*/
	if (cpu_is_mx6dl())
		mxc_iomux_set_gpr_register(13, 3, 3, 1);
}
Пример #14
0
/*
 * Returns:
 *	the silicon revision of the cpu
 */
int mx6dl_revision(void)
{
	if (!cpu_is_mx6dl())
		return -EINVAL;

	if (cpu_silicon_rev == -1)
		cpu_silicon_rev = mx6_get_srev();

	return cpu_silicon_rev;
}
Пример #15
0
static void imx6_add_video_clks(void __iomem *anab, void __iomem *cb)
{
    clks[IMX6QDL_CLK_PLL5_POST_DIV] = imx_clk_divider_table("pll5_post_div", "pll5_video", anab + 0xa0, 19, 2, post_div_table);
    clks[IMX6QDL_CLK_PLL5_VIDEO_DIV] = imx_clk_divider_table("pll5_video_div", "pll5_post_div", anab + 0x170, 30, 2, video_div_table);

    clks[IMX6QDL_CLK_IPU1_SEL]         = imx_clk_mux("ipu1_sel",         cb + 0x3c, 9,  2, ipu_sels,          ARRAY_SIZE(ipu_sels));
    clks[IMX6QDL_CLK_IPU2_SEL]         = imx_clk_mux("ipu2_sel",         cb + 0x3c, 14, 2, ipu_sels,          ARRAY_SIZE(ipu_sels));
    clks[IMX6QDL_CLK_LDB_DI0_SEL]      = imx_clk_mux_p("ldb_di0_sel",      cb + 0x2c, 9,  3, ldb_di_sels,       ARRAY_SIZE(ldb_di_sels));
    clks[IMX6QDL_CLK_LDB_DI1_SEL]      = imx_clk_mux_p("ldb_di1_sel",      cb + 0x2c, 12, 3, ldb_di_sels,       ARRAY_SIZE(ldb_di_sels));
    clks[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_p("ipu1_di0_pre_sel", cb + 0x34, 6,  3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
    clks[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_p("ipu1_di1_pre_sel", cb + 0x34, 15, 3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
    clks[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_p("ipu2_di0_pre_sel", cb + 0x38, 6,  3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
    clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_p("ipu2_di1_pre_sel", cb + 0x38, 15, 3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
    clks[IMX6QDL_CLK_IPU1_DI0_SEL]     = imx_clk_mux_p("ipu1_di0_sel",     cb + 0x34, 0,  3, ipu1_di0_sels,     ARRAY_SIZE(ipu1_di0_sels));
    clks[IMX6QDL_CLK_IPU1_DI1_SEL]     = imx_clk_mux_p("ipu1_di1_sel",     cb + 0x34, 9,  3, ipu1_di1_sels,     ARRAY_SIZE(ipu1_di1_sels));
    clks[IMX6QDL_CLK_IPU2_DI0_SEL]     = imx_clk_mux_p("ipu2_di0_sel",     cb + 0x38, 0,  3, ipu2_di0_sels,     ARRAY_SIZE(ipu2_di0_sels));
    clks[IMX6QDL_CLK_IPU2_DI1_SEL]     = imx_clk_mux_p("ipu2_di1_sel",     cb + 0x38, 9,  3, ipu2_di1_sels,     ARRAY_SIZE(ipu2_di1_sels));

    clks[IMX6QDL_CLK_IPU1_PODF]        = imx_clk_divider("ipu1_podf",        "ipu1_sel",          cb + 0x3c, 11, 3);
    clks[IMX6QDL_CLK_IPU2_PODF]        = imx_clk_divider("ipu2_podf",        "ipu2_sel",          cb + 0x3c, 16, 3);
    clks[IMX6QDL_CLK_LDB_DI0_DIV_3_5]  = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
    clks[IMX6QDL_CLK_LDB_DI0_PODF]     = imx_clk_divider_np("ldb_di0_podf", "ldb_di0_div_3_5", cb + 0x20, 10, 1);
    clks[IMX6QDL_CLK_LDB_DI1_DIV_3_5]  = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
    clks[IMX6QDL_CLK_LDB_DI1_PODF]     = imx_clk_divider_np("ldb_di1_podf", "ldb_di1_div_3_5", cb + 0x20, 11, 1);
    clks[IMX6QDL_CLK_IPU1_DI0_PRE]     = imx_clk_divider("ipu1_di0_pre",     "ipu1_di0_pre_sel",  cb + 0x34, 3,  3);
    clks[IMX6QDL_CLK_IPU1_DI1_PRE]     = imx_clk_divider("ipu1_di1_pre",     "ipu1_di1_pre_sel",  cb + 0x34, 12, 3);
    clks[IMX6QDL_CLK_IPU2_DI0_PRE]     = imx_clk_divider("ipu2_di0_pre",     "ipu2_di0_pre_sel",  cb + 0x38, 3,  3);
    clks[IMX6QDL_CLK_IPU2_DI1_PRE]     = imx_clk_divider("ipu2_di1_pre",     "ipu2_di1_pre_sel",  cb + 0x38, 12, 3);

    clks[IMX6QDL_CLK_IPU1]         = imx_clk_gate2("ipu1",          "ipu1_podf",         cb + 0x74, 0);
    clks[IMX6QDL_CLK_IPU1_DI0]     = imx_clk_gate2("ipu1_di0",      "ipu1_di0_sel",      cb + 0x74, 2);
    clks[IMX6QDL_CLK_IPU1_DI1]     = imx_clk_gate2("ipu1_di1",      "ipu1_di1_sel",      cb + 0x74, 4);
    clks[IMX6QDL_CLK_IPU2]         = imx_clk_gate2("ipu2",          "ipu2_podf",         cb + 0x74, 6);
    clks[IMX6QDL_CLK_IPU2_DI0]     = imx_clk_gate2("ipu2_di0",      "ipu2_di0_sel",      cb + 0x74, 8);
    clks[IMX6QDL_CLK_LDB_DI0]      = imx_clk_gate2("ldb_di0",       "ldb_di0_podf",      cb + 0x74, 12);
    clks[IMX6QDL_CLK_LDB_DI1]      = imx_clk_gate2("ldb_di1",       "ldb_di1_podf",      cb + 0x74, 14);
    clks[IMX6QDL_CLK_IPU2_DI1]     = imx_clk_gate2("ipu2_di1",      "ipu2_di1_sel",      cb + 0x74, 10);

    clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI0_SEL], clks[IMX6QDL_CLK_IPU1_DI0_PRE]);
    clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI1_SEL], clks[IMX6QDL_CLK_IPU1_DI1_PRE]);
    clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI0_SEL], clks[IMX6QDL_CLK_IPU2_DI0_PRE]);
    clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_SEL], clks[IMX6QDL_CLK_IPU2_DI1_PRE]);

    clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI0_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
    clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
    clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI0_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
    clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);

    if ((imx_silicon_revision() != IMX_CHIP_REV_1_0) ||
            cpu_is_mx6dl()) {
        clk_set_parent(clks[IMX6QDL_CLK_LDB_DI0_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
        clk_set_parent(clks[IMX6QDL_CLK_LDB_DI1_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
    }

}
Пример #16
0
static void hsic_start(void)
{
	pr_debug("%s", __func__);
	/* strobe 47K pull up */
	if (cpu_is_mx6q())
		mxc_iomux_v3_setup_pad(
				MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE_START);
	else if (cpu_is_mx6dl())
		mxc_iomux_v3_setup_pad(
				MX6DL_PAD_RGMII_RXC__USBOH3_H3_STROBE_START);
}
Пример #17
0
static int plt_sd3_pad_change(int clock) {
	static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;

	if (clock > 100000000) {
		if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
			return 0;

		pad_mode = SD_PAD_MODE_HIGH_SPEED;
		if (cpu_is_mx6q()) {
			return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_200mhz,
						ARRAY_SIZE(mx6dl_sd3_200mhz));
		} else if (cpu_is_mx6dl()) {
			return mxc_iomux_v3_setup_multiple_pads(mx6dl_sd3_200mhz,
						ARRAY_SIZE(mx6dl_sd3_200mhz));
		}
	} else if (clock > 52000000) {
		if (pad_mode == SD_PAD_MODE_MED_SPEED)
			return 0;

		pad_mode = SD_PAD_MODE_MED_SPEED;
		if (cpu_is_mx6q()) {
			return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_100mhz,
						ARRAY_SIZE(mx6dl_sd3_200mhz));
		} else if (cpu_is_mx6dl()) {
			return mxc_iomux_v3_setup_multiple_pads(mx6dl_sd3_100mhz,
						ARRAY_SIZE(mx6dl_sd3_200mhz));
		}
	} else {
		if (pad_mode == SD_PAD_MODE_LOW_SPEED)
			return 0;

		pad_mode = SD_PAD_MODE_LOW_SPEED;
		if (cpu_is_mx6q()) {
			return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_50mhz,
						ARRAY_SIZE(mx6dl_sd3_200mhz));
		} else if (cpu_is_mx6dl()) {
			return mxc_iomux_v3_setup_multiple_pads(mx6dl_sd3_50mhz,
						ARRAY_SIZE(mx6dl_sd3_200mhz));
		}
	}
}
Пример #18
0
/*!
 * This is the probe routine for the bus frequency driver.
 *
 * @param   pdev   The platform device structure
 *
 * @return         The function returns 0 on success
 *
 */
static int __devinit busfreq_probe(struct platform_device *pdev)
{
    u32 err;

    busfreq_dev = &pdev->dev;

    pll2_400 = clk_get(NULL, "pll2_pfd_400M");
    if (IS_ERR(pll2_400)) {
        printk(KERN_DEBUG "%s: failed to get axi_clk\n",
               __func__);
        return PTR_ERR(pll2_400);
    }

    cpu_clk = clk_get(NULL, "cpu_clk");
    if (IS_ERR(cpu_clk)) {
        printk(KERN_DEBUG "%s: failed to get cpu_clk\n",
               __func__);
        return PTR_ERR(cpu_clk);
    }

    pll3 = clk_get(NULL, "pll3_main_clk");

    err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
    if (err) {
        printk(KERN_ERR
               "Unable to register sysdev entry for BUSFREQ");
        return err;
    }

    cpu_op_tbl = get_cpu_op(&cpu_op_nr);
    low_bus_freq_mode = 0;
    high_bus_freq_mode = 1;
    med_bus_freq_mode = 0;
    bus_freq_scaling_is_active = 0;
    bus_freq_scaling_initialized = 1;

    if (cpu_is_mx6q()) {
        ddr_low_rate = LPAPM_CLK;
        ddr_med_rate = DDR_MED_CLK;
        ddr_normal_rate = DDR3_NORMAL_CLK;
    }
    if (cpu_is_mx6dl()) {
        ddr_low_rate = LPAPM_CLK;
        ddr_normal_rate = ddr_med_rate = DDR_MED_CLK;
    }

    INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler);

    mutex_init(&bus_freq_mutex);

    return 0;
}
Пример #19
0
static int __init gpmi_nand_platform_init(void)
{
	iomux_v3_cfg_t *nand_pads = NULL;
	u32 nand_pads_cnt;

	if (cpu_is_mx6q()) {
		nand_pads = mx6q_gpmi_nand;
		nand_pads_cnt = ARRAY_SIZE(mx6q_gpmi_nand);
	} else if (cpu_is_mx6dl()) {
		nand_pads = mx6dl_gpmi_nand;
		nand_pads_cnt = ARRAY_SIZE(mx6dl_gpmi_nand);

	}
	BUG_ON(!nand_pads);
	return mxc_iomux_v3_setup_multiple_pads(nand_pads, nand_pads_cnt);
}
Пример #20
0
static inline void __init mx6q_csi0_io_init(void)
{
	/* Camera reset */
	gpio_request(SABREAUTO_CSI0_RST, "cam-reset");
	gpio_direction_output(SABREAUTO_CSI0_RST, 1);

	/* Camera power down */
	gpio_request(SABREAUTO_CSI0_PWN, "cam-pwdn");
	gpio_direction_output(SABREAUTO_CSI0_PWN, 1);
	msleep(1);
	gpio_set_value(SABREAUTO_CSI0_PWN, 0);

	if (cpu_is_mx6q())
		mxc_iomux_set_gpr_register(1, 19, 1, 1);
	else if (cpu_is_mx6dl())
		mxc_iomux_set_gpr_register(13, 0, 3, 4);
}
Пример #21
0
static ssize_t I2C_enable_write(struct file *filp,
                                       const char *buff,
                                       size_t len,
                                       loff_t *off)
{
    char bbuf[128];
    int retlen;
    retlen=copy_from_user(bbuf,buff,len);
    bbuf[len]=0;
    printk("\n I2C_enable write -- Str=%s\n",bbuf);
    
    static iomux_v3_cfg_t mx6q_I2C_pads[] = {MX6Q_PAD_GPIO_3__GPIO_1_3, MX6Q_PAD_GPIO_6__GPIO_1_6, MX6Q_PAD_NANDF_ALE__GPIO_6_8, MX6Q_PAD_NANDF_CS3__GPIO_6_16};
    static iomux_v3_cfg_t mx6dl_I2C_pads[] = {MX6DL_PAD_GPIO_3__GPIO_1_3, MX6DL_PAD_GPIO_6__GPIO_1_6, MX6DL_PAD_NANDF_ALE__GPIO_6_8, MX6DL_PAD_NANDF_CS3__GPIO_6_16};
    if(strtoint(bbuf))
    {
        printk("set I2C Enable.\n");
	if (cpu_is_mx6q())
		mxc_iomux_v3_setup_multiple_pads(mx6q_I2C_pads, ARRAY_SIZE(mx6q_I2C_pads));
	else if (cpu_is_mx6dl())
		mxc_iomux_v3_setup_multiple_pads(mx6dl_I2C_pads, ARRAY_SIZE(mx6dl_I2C_pads));

	gpio_request(I2C_SCL_ENABLE, "I2CSCL");    	//willy add
        gpio_direction_input(I2C_SCL_ENABLE);
        gpio_export(I2C_SCL_ENABLE,0);
        gpio_request(I2C_SDA_ENABLE, "I2CSDA");		//willy add    
        gpio_direction_output(I2C_SDA_ENABLE, 0);
        gpio_export(I2C_SDA_ENABLE,0);
        gpio_request(I2C_IRQ_ENABLE, "I2CIRQ");    	//willy add
        gpio_direction_input(I2C_IRQ_ENABLE);
        gpio_export(I2C_IRQ_ENABLE,0);
        gpio_request(I2C_RST_ENABLE, "I2CRST");    	//willy add
        gpio_direction_output(I2C_RST_ENABLE, 0);
        gpio_export(I2C_RST_ENABLE,0);

//	sys_chmod("/sys/class/gpio/gpio3/value", 420);
//        sys_chmod("/sys/class/gpio/gpio6/value", 420);
//        sys_chmod("/sys/class/gpio/gpio168/value", 420);
//        sys_chmod("/sys/class/gpio/gpio176/value", 420);

    }
    else
    {
    }
	
    return len;
}
Пример #22
0
struct cpu_op *mx6_get_cpu_op(int *op)
{
	if (cpu_is_mx6dl()) {
		if (arm_max_freq == CPU_AT_1_2GHz) {
			*op =  num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1_2G);
			return mx6dl_cpu_op_1_2G;
		} else if (arm_max_freq == CPU_AT_1GHz) {
			*op =  num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1G);
			return mx6dl_cpu_op_1G;
		} else {
			*op =  num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op);
			return mx6dl_cpu_op;
		}
	} else if (cpu_is_mx6q()) {
		if (arm_max_freq == CPU_AT_1_2GHz) {
			*op =  num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1_2G);
			return mx6q_cpu_op_1_2G;
		} else if (arm_max_freq == CPU_AT_1GHz) {
			*op =  num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1G);
			return mx6q_cpu_op_1G;
		} else {
			*op =  num_cpu_op = ARRAY_SIZE(mx6q_cpu_op);
			return mx6q_cpu_op;
		}
	} else {
		if (arm_max_freq == CPU_AT_1GHz) {
			*op =  num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op_1G);
#ifdef CONFIG_LAB126
        		if(lab126_board_is(BOARD_ID_BOURBON_WFO) ||
				lab126_board_is(BOARD_ID_WARIO_4_256M_CFG_C) ||
				lab126_board_is(BOARD_ID_BOURBON_WFO_PREEVT2)) {
				return mx6sl_cpu_op_1G_Bourbon;
			} else 
#endif
			{
				return mx6sl_cpu_op_1G;
			}
		} else {
			*op =  num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op);
			return mx6sl_cpu_op;
		}
	}
}
Пример #23
0
/*
 * set_mclk_rate
 *
 * @param       p_mclk_freq  mclk frequence
 * @param	csi         csi 0 or csi 1
 *
 */
void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi)
{
	struct clk *clk;
	uint32_t freq = 0;
	char *mclk;

	if (cpu_is_mx53()) {
		if (csi == 0)
			mclk = "ssi_ext1_clk";
		else {
			pr_err("invalid csi num %d\n", csi);
			return;
		}
	} else if (cpu_is_mx6q() || cpu_is_mx6dl()) {
		if (csi == 0) {
			mclk = "clko2_clk";
		} else {
			pr_err("invalid csi num %d\n", csi);
			return;
		};
	} else if (cpu_is_mx25() || cpu_is_mx6sl()) {	/* only has CSI0 */
		mclk = "csi_clk";
	} else {
		if (csi == 0) {
			mclk = "csi_mclk1";
		} else if (csi == 1) {
			mclk = "csi_mclk2";
		} else {
			pr_err("invalid csi num %d\n", csi);
			return;
		}
	}

	clk = clk_get(NULL, mclk);

	freq = clk_round_rate(clk, *p_mclk_freq);
	clk_set_rate(clk, freq);

	*p_mclk_freq = freq;

	clk_put(clk);
	pr_debug("%s frequency = %d\n", mclk, *p_mclk_freq);
}
static void ov5640_mipi_camera_io_init(void)
{
	IOMUX_SETUP(mipi_pads);

	pr_info("%s\n", __func__);
	mipi_pwm = pwm_request(2, "mipi_clock");
	if (IS_ERR(mipi_pwm)) {
		pr_err("unable to request PWM for mipi_clock\n");
	} else {
		unsigned period = 1000/22;
		pr_info("got pwm for mipi_clock\n");
		pwm_config(mipi_pwm, period >> 1, period);
		pwm_enable(mipi_pwm);
	}

	camera_reset(IMX_GPIO_NR(6, 9), 1, IMX_GPIO_NR(2, 5), IMX_GPIO_NR(6, 11));
/* for mx6dl, mipi virtual channel 1 connect to csi 1*/
	if (cpu_is_mx6dl())
		mxc_iomux_set_gpr_register(13, 3, 3, 1);
}
Пример #25
0
void arch_idle_multi_core(int cpu)
{
	u32 reg;

	/* iMX6Q and iMX6DL */
	if ((cpu_is_mx6q() && chip_rev >= IMX_CHIP_REVISION_1_2) ||
		(cpu_is_mx6dl() && chip_rev >= IMX_CHIP_REVISION_1_1)) {
		/*
		  * This code should only be executed on MX6QTO1.2 or later
		  * and MX6DL TO1.1 or later.
		  * These chips have the HW fix for the WAIT mode issue.
		  * Ensure that the CGPR bit 17 is set to enable the fix.
		  */

		reg = __raw_readl(MXC_CCM_CGPR);
		reg |= MXC_CCM_CGPR_WAIT_MODE_FIX;
		__raw_writel(reg, MXC_CCM_CGPR);

		ca9_do_idle();
	} else
		arch_idle_with_workaround(cpu);
}
Пример #26
0
static void phyflex_err006282_workaround(void)
{
	/*
	 * Boards beginning with 1362.2 have the SD4_DAT3 pin connected
	 * to the CMIC. If this pin isn't toggled within 10s the boards
	 * reset. The pin is unconnected on older boards, so we do not
	 * need a check for older boards before applying this fixup.
	 */

	gpio_direction_output(MX6_PHYFLEX_ERR006282, 0);
	mdelay(2);
	gpio_direction_output(MX6_PHYFLEX_ERR006282, 1);
	mdelay(2);
	gpio_set_value(MX6_PHYFLEX_ERR006282, 0);

	if (cpu_is_mx6q())
		mxc_iomux_v3_setup_pad(MX6Q_PAD_SD4_DAT3__GPIO_2_11_PD);
	else if (cpu_is_mx6dl())
		mxc_iomux_v3_setup_pad(MX6DL_PAD_SD4_DAT3__GPIO_2_11);

	gpio_direction_input(MX6_PHYFLEX_ERR006282);
}
Пример #27
0
static int ldb_disp_init(struct mxc_dispdrv_handle *disp,
	struct mxc_dispdrv_setting *setting)
{
	int ret = 0, i;
	struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
	struct fsl_mxc_ldb_platform_data *plat_data = ldb->pdev->dev.platform_data;
	struct resource *res;
	uint32_t base_addr;
	uint32_t reg, setting_idx;
	uint32_t ch_mask = 0, ch_val = 0;
	uint32_t ipu_id, disp_id;

	/* if input format not valid, make RGB666 as default*/
	if (!valid_mode(setting->if_fmt)) {
		dev_warn(&ldb->pdev->dev, "Input pixel format not valid"
					" use default RGB666\n");
		setting->if_fmt = IPU_PIX_FMT_RGB666;
	}

	if (!ldb->inited) {
		char di_clk[] = "ipu1_di0_clk";
		char ldb_clk[] = "ldb_di0_clk";
		int lvds_channel = 0;

		setting_idx = 0;
		res = platform_get_resource(ldb->pdev, IORESOURCE_MEM, 0);
		if (IS_ERR(res))
			return -ENOMEM;

		base_addr = res->start;
		ldb->reg = ioremap(base_addr, res->end - res->start + 1);
		ldb->control_reg = ldb->reg + 2;
		ldb->gpr3_reg = ldb->reg + 3;

		ldb->lvds_bg_reg = regulator_get(&ldb->pdev->dev, plat_data->lvds_bg_reg);
		if (!IS_ERR(ldb->lvds_bg_reg)) {
			regulator_set_voltage(ldb->lvds_bg_reg, 2500000, 2500000);
			regulator_enable(ldb->lvds_bg_reg);
		}

		/* ipu selected by platform data setting */
		setting->dev_id = plat_data->ipu_id;

		reg = readl(ldb->control_reg);

		/* refrence resistor select */
		reg &= ~LDB_BGREF_RMODE_MASK;
		if (plat_data->ext_ref)
			reg |= LDB_BGREF_RMODE_EXT;
		else
			reg |= LDB_BGREF_RMODE_INT;

		/* TODO: now only use SPWG data mapping for both channel */
		reg &= ~(LDB_BIT_MAP_CH0_MASK | LDB_BIT_MAP_CH1_MASK);
		reg |= LDB_BIT_MAP_CH0_SPWG | LDB_BIT_MAP_CH1_SPWG;

		/* channel mode setting */
		reg &= ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
		reg &= ~(LDB_DATA_WIDTH_CH0_MASK | LDB_DATA_WIDTH_CH1_MASK);

		if (bits_per_pixel(setting->if_fmt) == 24)
			reg |= LDB_DATA_WIDTH_CH0_24 | LDB_DATA_WIDTH_CH1_24;
		else
			reg |= LDB_DATA_WIDTH_CH0_18 | LDB_DATA_WIDTH_CH1_18;

		if (g_ldb_mode)
			ldb->mode = g_ldb_mode;
		else
			ldb->mode = plat_data->mode;

		if ((ldb->mode == LDB_SIN0) || (ldb->mode == LDB_SIN1)) {
			ret = ldb->mode - LDB_SIN0;
			if (plat_data->disp_id != ret) {
				dev_warn(&ldb->pdev->dev,
					"change IPU DI%d to IPU DI%d for LDB "
					"channel%d.\n",
					plat_data->disp_id, ret, ret);
				plat_data->disp_id = ret;
			}
		} else if (((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1))
				&& (cpu_is_mx6q() || cpu_is_mx6dl())) {
			if (plat_data->disp_id == plat_data->sec_disp_id) {
				dev_err(&ldb->pdev->dev,
					"For LVDS separate mode,"
					"two DIs should be different!\n");
				return -EINVAL;
			}

			if (((!plat_data->disp_id) && (ldb->mode == LDB_SEP1))
				|| ((plat_data->disp_id) &&
					(ldb->mode == LDB_SEP0))) {
				dev_dbg(&ldb->pdev->dev,
					"LVDS separate mode:"
					"swap DI configuration!\n");
				ipu_id = plat_data->ipu_id;
				disp_id = plat_data->disp_id;
				plat_data->ipu_id = plat_data->sec_ipu_id;
				plat_data->disp_id = plat_data->sec_disp_id;
				plat_data->sec_ipu_id = ipu_id;
				plat_data->sec_disp_id = disp_id;
			}
		}

		if (ldb->mode == LDB_SPL_DI0) {
			reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI0
				| LDB_CH1_MODE_EN_TO_DI0;
			setting->disp_id = 0;
		} else if (ldb->mode == LDB_SPL_DI1) {
			reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI1
				| LDB_CH1_MODE_EN_TO_DI1;
			setting->disp_id = 1;
		} else if (ldb->mode == LDB_DUL_DI0) {
			reg &= ~LDB_SPLIT_MODE_EN;
			reg |= LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI0;
			setting->disp_id = 0;
		} else if (ldb->mode == LDB_DUL_DI1) {
			reg &= ~LDB_SPLIT_MODE_EN;
			reg |= LDB_CH0_MODE_EN_TO_DI1 | LDB_CH1_MODE_EN_TO_DI1;
			setting->disp_id = 1;
		} else if (ldb->mode == LDB_SIN0) {
			reg &= ~LDB_SPLIT_MODE_EN;
			setting->disp_id = plat_data->disp_id;
			if (setting->disp_id == 0)
				reg |= LDB_CH0_MODE_EN_TO_DI0;
			else
				reg |= LDB_CH0_MODE_EN_TO_DI1;
			ch_mask = LDB_CH0_MODE_MASK;
			ch_val = reg & LDB_CH0_MODE_MASK;
		} else if (ldb->mode == LDB_SIN1) {
			reg &= ~LDB_SPLIT_MODE_EN;
			setting->disp_id = plat_data->disp_id;
			if (setting->disp_id == 0)
				reg |= LDB_CH1_MODE_EN_TO_DI0;
			else
				reg |= LDB_CH1_MODE_EN_TO_DI1;
			ch_mask = LDB_CH1_MODE_MASK;
			ch_val = reg & LDB_CH1_MODE_MASK;
		} else { /* separate mode*/
			setting->disp_id = plat_data->disp_id;

			/* first output is LVDS0 or LVDS1 */
			if (ldb->mode == LDB_SEP0)
				lvds_channel = 0;
			else
				lvds_channel = 1;

			reg &= ~LDB_SPLIT_MODE_EN;

			if ((lvds_channel == 0) && (setting->disp_id == 0))
				reg |= LDB_CH0_MODE_EN_TO_DI0;
			else if ((lvds_channel == 0) && (setting->disp_id == 1))
				reg |= LDB_CH0_MODE_EN_TO_DI1;
			else if ((lvds_channel == 1) && (setting->disp_id == 0))
				reg |= LDB_CH1_MODE_EN_TO_DI0;
			else
				reg |= LDB_CH1_MODE_EN_TO_DI1;
			ch_mask = lvds_channel ? LDB_CH1_MODE_MASK :
					LDB_CH0_MODE_MASK;
			ch_val = reg & ch_mask;

			if (bits_per_pixel(setting->if_fmt) == 24) {
				if (lvds_channel == 0)
					reg &= ~LDB_DATA_WIDTH_CH1_24;
				else
					reg &= ~LDB_DATA_WIDTH_CH0_24;
			} else {
				if (lvds_channel == 0)
					reg &= ~LDB_DATA_WIDTH_CH1_18;
				else
					reg &= ~LDB_DATA_WIDTH_CH0_18;
			}
		}

		writel(reg, ldb->control_reg);
		if (ldb->mode <  LDB_SIN0) {
			ch_mask = LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK;
			ch_val = reg & (LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
		}

		/* clock setting */
		if ((cpu_is_mx6q() || cpu_is_mx6dl()) &&
			((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1)))
			ldb_clk[6] += lvds_channel;
		else
			ldb_clk[6] += setting->disp_id;
		ldb->setting[setting_idx].ldb_di_clk = clk_get(&ldb->pdev->dev,
								ldb_clk);
		if (IS_ERR(ldb->setting[setting_idx].ldb_di_clk)) {
			dev_err(&ldb->pdev->dev, "get ldb clk0 failed\n");
			iounmap(ldb->reg);
			return PTR_ERR(ldb->setting[setting_idx].ldb_di_clk);
		}
		di_clk[3] += setting->dev_id;
		di_clk[7] += setting->disp_id;
		ldb->setting[setting_idx].di_clk = clk_get(&ldb->pdev->dev,
								di_clk);
		if (IS_ERR(ldb->setting[setting_idx].di_clk)) {
			dev_err(&ldb->pdev->dev, "get di clk0 failed\n");
			iounmap(ldb->reg);
			return PTR_ERR(ldb->setting[setting_idx].di_clk);
		}

		dev_dbg(&ldb->pdev->dev, "ldb_clk to di clk: %s -> %s\n", ldb_clk, di_clk);

		/* fb notifier for clk setting */
		ldb->nb.notifier_call = ldb_fb_event,
		ret = fb_register_client(&ldb->nb);
		if (ret < 0) {
			iounmap(ldb->reg);
			return ret;
		}

		ldb->inited = true;
	} else { /* second time for separate mode */
		char di_clk[] = "ipu1_di0_clk";
		char ldb_clk[] = "ldb_di0_clk";
		int lvds_channel;

		if ((ldb->mode == LDB_SPL_DI0) ||
			(ldb->mode == LDB_SPL_DI1) ||
			(ldb->mode == LDB_DUL_DI0) ||
			(ldb->mode == LDB_DUL_DI1) ||
			(ldb->mode == LDB_SIN0) ||
			(ldb->mode == LDB_SIN1)) {
			dev_err(&ldb->pdev->dev, "for second ldb disp"
					"ldb mode should in separate mode\n");
			return -EINVAL;
		}

		setting_idx = 1;
		if (cpu_is_mx6q() || cpu_is_mx6dl()) {
			setting->dev_id = plat_data->sec_ipu_id;
			setting->disp_id = plat_data->sec_disp_id;
		} else {
			setting->dev_id = plat_data->ipu_id;
			setting->disp_id = !plat_data->disp_id;
		}
		if (setting->disp_id == ldb->setting[0].di) {
			dev_err(&ldb->pdev->dev, "Err: for second ldb disp in"
				"separate mode, DI should be different!\n");
			return -EINVAL;
		}

		/* second output is LVDS0 or LVDS1 */
		if (ldb->mode == LDB_SEP0)
			lvds_channel = 1;
		else
			lvds_channel = 0;

		reg = readl(ldb->control_reg);
		if ((lvds_channel == 0) && (setting->disp_id == 0))
			reg |= LDB_CH0_MODE_EN_TO_DI0;
		else if ((lvds_channel == 0) && (setting->disp_id == 1))
			reg |= LDB_CH0_MODE_EN_TO_DI1;
		else if ((lvds_channel == 1) && (setting->disp_id == 0))
			reg |= LDB_CH1_MODE_EN_TO_DI0;
		else
			reg |= LDB_CH1_MODE_EN_TO_DI1;
		ch_mask = lvds_channel ?  LDB_CH1_MODE_MASK :
				LDB_CH0_MODE_MASK;
		ch_val = reg & ch_mask;

		if (bits_per_pixel(setting->if_fmt) == 24) {
			if (lvds_channel == 0)
				reg |= LDB_DATA_WIDTH_CH0_24;
			else
				reg |= LDB_DATA_WIDTH_CH1_24;
		} else {
			if (lvds_channel == 0)
				reg |= LDB_DATA_WIDTH_CH0_18;
			else
				reg |= LDB_DATA_WIDTH_CH1_18;
		}
		writel(reg, ldb->control_reg);

		/* clock setting */
		if (cpu_is_mx6q() || cpu_is_mx6dl())
			ldb_clk[6] += lvds_channel;
		else
			ldb_clk[6] += setting->disp_id;
		ldb->setting[setting_idx].ldb_di_clk = clk_get(&ldb->pdev->dev,
								ldb_clk);
		if (IS_ERR(ldb->setting[setting_idx].ldb_di_clk)) {
			dev_err(&ldb->pdev->dev, "get ldb clk1 failed\n");
			return PTR_ERR(ldb->setting[setting_idx].ldb_di_clk);
		}
		di_clk[3] += setting->dev_id;
		di_clk[7] += setting->disp_id;
		ldb->setting[setting_idx].di_clk = clk_get(&ldb->pdev->dev,
								di_clk);
		if (IS_ERR(ldb->setting[setting_idx].di_clk)) {
			dev_err(&ldb->pdev->dev, "get di clk1 failed\n");
			return PTR_ERR(ldb->setting[setting_idx].di_clk);
		}

		dev_dbg(&ldb->pdev->dev, "ldb_clk to di clk: %s -> %s\n", ldb_clk, di_clk);
	}

	ldb->setting[setting_idx].ch_mask = ch_mask;
	ldb->setting[setting_idx].ch_val = ch_val;

	if (cpu_is_mx6q() || cpu_is_mx6dl())
		ldb_ipu_ldb_route(setting->dev_id, setting->disp_id, ldb);

	/*
	 * ldb_di0_clk -> ipux_di0_clk
	 * ldb_di1_clk -> ipux_di1_clk
	 */
	clk_set_parent(ldb->setting[setting_idx].di_clk,
			ldb->setting[setting_idx].ldb_di_clk);

	/* must use spec video mode defined by driver */
	ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str,
				ldb_modedb, ldb_modedb_sz, NULL, setting->default_bpp);
	if (ret != 1)
		fb_videomode_to_var(&setting->fbi->var, &ldb_modedb[0]);

	INIT_LIST_HEAD(&setting->fbi->modelist);
	for (i = 0; i < ldb_modedb_sz; i++) {
		struct fb_videomode m;
		fb_var_to_videomode(&m, &setting->fbi->var);
		if (fb_mode_is_equal(&m, &ldb_modedb[i])) {
			fb_add_videomode(&ldb_modedb[i],
					&setting->fbi->modelist);
			break;
		}
	}

	/* save current ldb setting for fb notifier */
	ldb->setting[setting_idx].active = true;
	ldb->setting[setting_idx].ipu = setting->dev_id;
	ldb->setting[setting_idx].di = setting->disp_id;

	return ret;
}
Пример #28
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;
}
Пример #29
0
static int __devinit busfreq_probe(struct platform_device *pdev)
{
	u32 err;

	busfreq_dev = &pdev->dev;

	pll2_400 = clk_get(NULL, "pll2_pfd_400M");
	if (IS_ERR(pll2_400)) {
		printk(KERN_DEBUG "%s: failed to get pll2_pfd_400M\n",
		       __func__);
		return PTR_ERR(pll2_400);
	}

	pll2_200 = clk_get(NULL, "pll2_200M");
	if (IS_ERR(pll2_200)) {
		printk(KERN_DEBUG "%s: failed to get pll2_200M\n",
		       __func__);
		return PTR_ERR(pll2_200);
	}

	pll2 = clk_get(NULL, "pll2");
	if (IS_ERR(pll2)) {
		printk(KERN_DEBUG "%s: failed to get pll2\n",
		       __func__);
		return PTR_ERR(pll2);
	}

	pll1 = clk_get(NULL, "pll1_main_clk");
	if (IS_ERR(pll1)) {
		printk(KERN_DEBUG "%s: failed to get pll1\n",
		       __func__);
		return PTR_ERR(pll1);
	}

	pll1_sw_clk = clk_get(NULL, "pll1_sw_clk");
	if (IS_ERR(pll1_sw_clk)) {
		printk(KERN_DEBUG "%s: failed to get pll1_sw_clk\n",
		       __func__);
		return PTR_ERR(pll1_sw_clk);
	}


	if (IS_ERR(pll2)) {
		printk(KERN_DEBUG "%s: failed to get pll2\n",
		       __func__);
		return PTR_ERR(pll2);
	}


	cpu_clk = clk_get(NULL, "cpu_clk");
	if (IS_ERR(cpu_clk)) {
		printk(KERN_DEBUG "%s: failed to get cpu_clk\n",
		       __func__);
		return PTR_ERR(cpu_clk);
	}

	pll3 = clk_get(NULL, "pll3_main_clk");
	if (IS_ERR(pll3)) {
		printk(KERN_DEBUG "%s: failed to get pll3\n",
		       __func__);
		return PTR_ERR(pll3);
	}

	pll3_540 = clk_get(NULL, "pll3_pfd_540M");
	if (IS_ERR(pll3_540)) {
		printk(KERN_DEBUG "%s: failed to get periph_clk\n",
		       __func__);
		return PTR_ERR(pll3_540);
	}

	pll3_sw_clk = clk_get(NULL, "pll3_sw_clk");
	if (IS_ERR(pll3_sw_clk)) {
		printk(KERN_DEBUG "%s: failed to get pll3_sw_clk\n",
		       __func__);
		return PTR_ERR(pll3_sw_clk);
	}

	axi_clk = clk_get(NULL, "axi_clk");
	if (IS_ERR(axi_clk)) {
		printk(KERN_DEBUG "%s: failed to get axi_clk\n",
		       __func__);
		return PTR_ERR(axi_clk);
	}

	ahb_clk = clk_get(NULL, "ahb");
	if (IS_ERR(ahb_clk)) {
		printk(KERN_DEBUG "%s: failed to get ahb_clk\n",
		       __func__);
		return PTR_ERR(ahb_clk);
	}

	periph_clk = clk_get(NULL, "periph_clk");
	if (IS_ERR(periph_clk)) {
		printk(KERN_DEBUG "%s: failed to get periph_clk\n",
		       __func__);
		return PTR_ERR(periph_clk);
	}

	osc_clk = clk_get(NULL, "osc");
	if (IS_ERR(osc_clk)) {
		printk(KERN_DEBUG "%s: failed to get osc_clk\n",
		       __func__);
		return PTR_ERR(osc_clk);
	}

	mmdc_ch0_axi = clk_get(NULL, "mmdc_ch0_axi");
	if (IS_ERR(mmdc_ch0_axi)) {
		printk(KERN_DEBUG "%s: failed to get mmdc_ch0_axi\n",
		       __func__);
		return PTR_ERR(mmdc_ch0_axi);
	}

	err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
	if (err) {
		printk(KERN_ERR
		       "Unable to register sysdev entry for BUSFREQ");
		return err;
	}

	cpu_op_tbl = get_cpu_op(&cpu_op_nr);
	low_bus_freq_mode = 0;
	if (cpu_is_mx6dl()) {
		high_bus_freq_mode = 0;
		med_bus_freq_mode = 1;
		/* To make pll2_400 use count right, as when
		system enter 24M, it will disable pll2_400 */
		clk_enable(pll2_400);
	} else if (cpu_is_mx6sl()) {
		/* Set med_bus_freq_mode to 1 since med_bus_freq_mode
		is not supported as yet for MX6SL */
		high_bus_freq_mode = 1;
		med_bus_freq_mode = 1;
	} else {
		high_bus_freq_mode = 1;
		med_bus_freq_mode = 0;
	}
	bus_freq_scaling_is_active = 0;
	bus_freq_scaling_initialized = 1;

	if (cpu_is_mx6q()) {
		ddr_low_rate = LPAPM_CLK;
		ddr_med_rate = DDR_MED_CLK;
		ddr_normal_rate = DDR3_NORMAL_CLK;
	}
	if (cpu_is_mx6dl() || cpu_is_mx6sl()) {
		ddr_low_rate = LPAPM_CLK;
		ddr_normal_rate = ddr_med_rate = DDR_MED_CLK;
	}

	INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler);
	register_pm_notifier(&imx_bus_freq_pm_notifier);

	if (!cpu_is_mx6sl())
		init_mmdc_settings();
	else {
		/* Use preallocated memory */
		mx6sl_wfi_iram_phys_addr = MX6SL_WFI_IRAM_CODE;

		/*
		 * Don't ioremap the address, we have fixed the IRAM address
		 * at IRAM_BASE_ADDR_VIRT
		 */
		mx6sl_wfi_iram_base = (void *)IRAM_BASE_ADDR_VIRT +
			(mx6sl_wfi_iram_phys_addr - IRAM_BASE_ADDR);

		memcpy(mx6sl_wfi_iram_base, mx6sl_wait, MX6SL_WFI_IRAM_CODE_SIZE);
		mx6sl_wfi_iram = (void *)mx6sl_wfi_iram_base;

		/* Use preallocated memory */
		mx6sl_ddr_freq_phys_addr = MX6_DDR_FREQ_IRAM_CODE;

		/*
		 * Don't ioremap the address, we have fixed the IRAM address
		 * at IRAM_BASE_ADDR_VIRT
		 */
		mx6sl_ddr_freq_base = (void *)IRAM_BASE_ADDR_VIRT +
			(mx6sl_ddr_freq_phys_addr - IRAM_BASE_ADDR);

		memcpy(mx6sl_ddr_freq_base, mx6sl_ddr_iram, MX6SL_DDR_FREQ_CODE_SIZE);
		mx6sl_ddr_freq_change_iram = (void *)mx6sl_ddr_freq_base;
	}

	return 0;
}
Пример #30
0
/* Set the DDR to either 528MHz or 400MHz for MX6q
 * or 400MHz for MX6DL.
 */
int set_high_bus_freq(int high_bus_freq)
{
	if (bus_freq_scaling_initialized && bus_freq_scaling_is_active)
		cancel_delayed_work_sync(&low_bus_freq_handler);

	if (busfreq_suspended)
		return 0;


	if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
		return 0;

	if (cpu_is_mx6sl())
		high_bus_freq = 1;

	if (high_bus_freq_mode && high_bus_freq)
		return 0;


	/* medium bus freq is only supported for MX6DQ */
	if (cpu_is_mx6q() && med_bus_freq_mode && !high_bus_freq)
		return 0;

	if (cpu_is_mx6dl() && high_bus_freq)
		high_bus_freq = 0;

	if (cpu_is_mx6dl() && med_bus_freq_mode)
		return 0;

	if ((high_bus_freq_mode && (high_bus_freq || lp_high_freq)) ||
	    (med_bus_freq_mode && !high_bus_freq && lp_med_freq &&
	     !lp_high_freq))
		return 0;

	if (cpu_is_mx6sl()) {
		u32 reg;
		unsigned long flags;
		u32 ttbr1;

		spin_lock_irqsave(&freq_lock, flags);
		/* sync the outer cache. */
		outer_sync();

		ttbr1 = save_ttbr1();

		/* Change DDR freq in IRAM. */
		mx6sl_ddr_freq_change_iram(ddr_normal_rate, low_bus_freq_mode);

		restore_ttbr1(ttbr1);

		spin_unlock_irqrestore(&freq_lock, flags);

		/* Set periph_clk to be sourced from pll2_pfd2_400M */
		/* First need to set the divider before changing the */
		/* parent if parent clock is larger than previous one */
		clk_set_rate(ahb_clk, clk_round_rate(ahb_clk,
						     LPAPM_CLK / 3));
		clk_set_rate(axi_clk,
			     clk_round_rate(axi_clk, LPAPM_CLK / 2));
		clk_set_parent(periph_clk, pll2_400);

		if (low_bus_freq_mode) {
			/* Now move ARM to be sourced from PLL2_400 too. */
			clk_set_parent(pll1_sw_clk, pll2_400);

			/* Ensure that the clock will be at original speed. */
			reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR);
			while (__raw_readl(MXC_CCM_CDHIPR))
				;
			clk_disable(pll1);
		}
		high_bus_freq_mode = 1;
		low_bus_freq_mode = 0;
		audio_bus_freq_mode = 0;
	} else {
		clk_enable(pll3);
		if (high_bus_freq) {
			update_ddr_freq(ddr_normal_rate);
			/* Make sure periph clk's parent also got updated */
			clk_set_parent(periph_clk, pll2);
			if (med_bus_freq_mode)
				clk_disable(pll2_400);
			high_bus_freq_mode = 1;
			med_bus_freq_mode = 0;
		} else {
			clk_enable(pll2_400);
			update_ddr_freq(ddr_med_rate);
			/* Make sure periph clk's parent also got updated */
			clk_set_parent(periph_clk, pll2_400);
			high_bus_freq_mode = 0;
			med_bus_freq_mode = 1;
		}
		if (audio_bus_freq_mode)
			clk_disable(pll2_400);

		/* AXI_CLK is sourced from PLL3_PFD_540 on MX6DL */
		if (cpu_is_mx6dl() &&
			clk_get_parent(axi_clk) != pll3_540)
			clk_set_parent(axi_clk, pll3_540);

		low_bus_freq_mode = 0;
		audio_bus_freq_mode = 0;

		clk_disable(pll3);
	}
	return 0;
}