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; }
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; }
/* * 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; }
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); }
static int imx6_mmu_init(void) { void __iomem *l2x0_base = IOMEM(0x00a02000); u32 val; if (!cpu_is_mx6()) return 0; /* Configure the L2 PREFETCH and POWER registers */ val = readl(l2x0_base + L310_PREFETCH_CTRL); val |= 0x70800000; /* * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0 * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2 * But according to ARM PL310 errata: 752271 * ID: 752271: Double linefill feature can cause data corruption * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2 * Workaround: The only workaround to this erratum is to disable the * double linefill feature. This is the default behavior. */ if (cpu_is_mx6q()) val &= ~(1 << 30 | 1 << 23); writel(val, l2x0_base + L310_PREFETCH_CTRL); l2x0_init(l2x0_base, 0x0, ~0UL); return 0; }
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); }
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; } } }
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 ssize_t bus_freq_scaling_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { if (strncmp(buf, "1", 1) == 0) { #ifdef CONFIG_MX6_VPU_352M if (cpu_is_mx6q()) /*do not enable bus freq*/ bus_freq_scaling_is_active = 0; printk(KERN_WARNING "Bus frequency can't be enabled if using VPU 352M!\n"); return size; #else bus_freq_scaling_is_active = 1; #endif set_high_bus_freq(0); /* Make sure system can enter low bus mode if it should be in low bus mode */ if (low_freq_bus_used() && !low_bus_freq_mode) set_low_bus_freq(); } else if (strncmp(buf, "0", 1) == 0) { if (bus_freq_scaling_is_active) set_high_bus_freq(1); bus_freq_scaling_is_active = 0; } return size; }
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 }
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); }
void wand_mux_pads_init_ipu2_lcd0(void) { if (!cpu_is_mx6q()) return; mxc_iomux_v3_setup_pad(MX6Q_PAD_DI0_DISP_CLK__IPU2_DI0_DISP_CLK); mxc_iomux_v3_setup_pad(MX6Q_PAD_DI0_PIN2__IPU2_DI0_PIN2); // HSync mxc_iomux_v3_setup_pad(MX6Q_PAD_DI0_PIN3__IPU2_DI0_PIN3); // VSync mxc_iomux_v3_setup_pad(MX6Q_PAD_DI0_PIN4__IPU2_DI0_PIN4); // Contrast mxc_iomux_v3_setup_pad(MX6Q_PAD_DI0_PIN15__IPU2_DI0_PIN15); // DISP0_DRDY mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT0__IPU2_DISP0_DAT_0); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT1__IPU2_DISP0_DAT_1); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT2__IPU2_DISP0_DAT_2); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT3__IPU2_DISP0_DAT_3); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT4__IPU2_DISP0_DAT_4); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT5__IPU2_DISP0_DAT_5); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT6__IPU2_DISP0_DAT_6); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT7__IPU2_DISP0_DAT_7); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT8__IPU2_DISP0_DAT_8); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT9__IPU2_DISP0_DAT_9); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT10__IPU2_DISP0_DAT_10); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT11__IPU2_DISP0_DAT_11); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT12__IPU2_DISP0_DAT_12); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT13__IPU2_DISP0_DAT_13); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT14__IPU2_DISP0_DAT_14); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT15__IPU2_DISP0_DAT_15); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT16__IPU2_DISP0_DAT_16); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT17__IPU2_DISP0_DAT_17); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT18__IPU2_DISP0_DAT_18); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT19__IPU2_DISP0_DAT_19); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT20__IPU2_DISP0_DAT_20); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT21__IPU2_DISP0_DAT_21); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT22__IPU2_DISP0_DAT_22); mxc_iomux_v3_setup_pad(MX6Q_PAD_DISP0_DAT23__IPU2_DISP0_DAT_23); }
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); } }
static void adv7180_io_init(void) { camera_reset(IMX_GPIO_NR(3, 13), 0, IMX_GPIO_NR(3, 14), -1); if (cpu_is_mx6q()) mxc_iomux_set_gpr_register(1, 20, 1, 1); else mxc_iomux_set_gpr_register(13, 3, 3, 4); }
static void reduce_bus_freq_handler(struct work_struct *work) { unsigned long reg; if (low_bus_freq_mode || !low_freq_bus_used()) return; if (audio_bus_freq_mode && lp_audio_freq) return; while (!mutex_trylock(&bus_freq_mutex)) msleep(1); /* PLL3 is used in the DDR freq change process, enable it. */ if (low_bus_freq_mode || !low_freq_bus_used()) { mutex_unlock(&bus_freq_mutex); return; } if (audio_bus_freq_mode && lp_audio_freq) { mutex_unlock(&bus_freq_mutex); return; } clk_enable(pll3); if (lp_audio_freq) { /* Need to ensure that PLL2_PFD_400M is kept ON. */ clk_enable(pll2_400); update_ddr_freq(50000000); audio_bus_freq_mode = 1; low_bus_freq_mode = 0; } else { update_ddr_freq(24000000); if (audio_bus_freq_mode) clk_disable(pll2_400); low_bus_freq_mode = 1; audio_bus_freq_mode = 0; } if (med_bus_freq_mode) clk_disable(pll2_400); high_bus_freq_mode = 0; med_bus_freq_mode = 0; if (cpu_is_mx6q()) { /* Power gate the PU LDO. */ org_ldo = reg = __raw_readl(ANADIG_REG_CORE); reg &= ~(ANADIG_REG_TARGET_MASK << ANADIG_REG1_PU_TARGET_OFFSET); __raw_writel(reg, ANADIG_REG_CORE); } clk_disable(pll3); mutex_unlock(&bus_freq_mutex); }
/* * Returns: * the silicon revision of the cpu * -EINVAL - not a mx50 */ int mx6q_revision(void) { if (!cpu_is_mx6q()) return -EINVAL; if (cpu_silicon_rev == -1) cpu_silicon_rev = get_mx6q_srev(); return cpu_silicon_rev; }
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); }
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)); } } }
static __init void wand_init_ahci(void) { /* SATA is not supported by MX6DL/Solo */ if (cpu_is_mx6q()) #ifdef CONFIG_SATA_AHCI_PLATFORM imx6q_add_ahci(0, &wand_sata_data); #else wand_sata_init(NULL, (void __iomem *)ioremap(MX6Q_SATA_BASE_ADDR, SZ_4K)); #endif }
/* Set the DDR to either 528MHz or 400MHz for MX6q * or 400MHz for MX6DL. */ int set_high_bus_freq(int high_bus_freq) { if (busfreq_suspended) return 0; if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active) return 0; if (high_bus_freq_mode && high_bus_freq) return 0; if (med_bus_freq_mode && !high_bus_freq) return 0; while (!mutex_trylock(&bus_freq_mutex)) msleep(1); if ((high_bus_freq_mode && (high_bus_freq || lp_high_freq)) || (med_bus_freq_mode && !high_bus_freq && lp_med_freq && !lp_high_freq)) { mutex_unlock(&bus_freq_mutex); return 0; } clk_enable(pll3); /* Enable the PU LDO */ if (cpu_is_mx6q() && low_bus_freq_mode) __raw_writel(org_ldo, ANADIG_REG_CORE); if (high_bus_freq) { update_ddr_freq(ddr_normal_rate); 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); high_bus_freq_mode = 0; med_bus_freq_mode = 1; } if (audio_bus_freq_mode) clk_disable(pll2_400); low_bus_freq_mode = 0; audio_bus_freq_mode = 0; low_bus_freq_mode = 0; clk_disable(pll3); mutex_unlock(&bus_freq_mutex); return 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; }
int mxc_iomux_v3_setup_pads(iomux_v3_cfg_t *mx6q_pad_list, iomux_v3_cfg_t *mx6dl_solo_pad_list) { iomux_v3_cfg_t *p = cpu_is_mx6q() ? mx6q_pad_list : mx6dl_solo_pad_list; int ret; while (*p) { ret = mxc_iomux_v3_setup_pad(*p); if (ret) return ret; p++; } return 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); }
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); }
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; }
void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) { uint32_t tctl_val; u32 reg; clk_enable(timer_clk); timer_base = base; /* * Initialise to a known state (all timers off, and timing reset) */ __raw_writel(0, timer_base + MXC_TCTL); __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ if (timer_is_v2()) { if (cpu_is_mx5() || cpu_is_mx6sl() || mx6q_revision() == IMX_CHIP_REVISION_1_0) tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; else { tctl_val = V2_TCTL_CLK_OSC_DIV8 | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; if (!cpu_is_mx6q()) { reg = __raw_readl(timer_base + MXC_TPRER); reg |= (V2_TPRER_PRE24M_DIV8 << V2_TPRER_PRE24M_OFFSET); __raw_writel(reg, timer_base + MXC_TPRER); /* Enable the 24MHz input clock. */ tctl_val |= V2_TCTL_ENABLE24M; } } } else tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; __raw_writel(tctl_val, timer_base + MXC_TCTL); /* init and register the timer to the framework */ mxc_clocksource_init(timer_clk); mxc_clockevent_init(timer_clk); /* Make irqs happen */ setup_irq(irq, &mxc_timer_irq); }
/* * 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); }
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; } } }
int mxc_init_l2x0(void) { unsigned int val; #define IOMUXC_GPR11_L2CACHE_AS_OCRAM 0x00000002 val = readl(IOMUXC_GPR11); if (cpu_is_mx6sl() && (val & IOMUXC_GPR11_L2CACHE_AS_OCRAM)) { /* L2 cache configured as OCRAM, reset it */ val &= ~IOMUXC_GPR11_L2CACHE_AS_OCRAM; writel(val, IOMUXC_GPR11); } writel(0x132, IO_ADDRESS(L2_BASE_ADDR + L2X0_TAG_LATENCY_CTRL)); writel(0x132, IO_ADDRESS(L2_BASE_ADDR + L2X0_DATA_LATENCY_CTRL)); val = readl(IO_ADDRESS(L2_BASE_ADDR + L2X0_PREFETCH_CTRL)); /* Turn on the L2 I/D prefetch */ val |= 0x30000000; /* * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0 * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2 * But according to ARM PL310 errata: 752271 * ID: 752271: Double linefill feature can cause data corruption * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2 * Workaround: The only workaround to this erratum is to disable the * double linefill feature. This is the default behavior. */ if (!cpu_is_mx6q()) val |= 0x40800000; writel(val, IO_ADDRESS(L2_BASE_ADDR + L2X0_PREFETCH_CTRL)); val = readl(IO_ADDRESS(L2_BASE_ADDR + L2X0_POWER_CTRL)); val |= L2X0_DYNAMIC_CLK_GATING_EN; val |= L2X0_STNDBY_MODE_EN; writel(val, IO_ADDRESS(L2_BASE_ADDR + L2X0_POWER_CTRL)); l2x0_init(IO_ADDRESS(L2_BASE_ADDR), 0x0, ~0x00000000); return 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); }