/*! * 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; }
void mx6_cpu_regulator_init(void) { int cpu; u32 curr_cpu = 0; cpu_regulator = regulator_get(NULL, gp_reg_id); if (IS_ERR(cpu_regulator)) printk(KERN_ERR "%s: failed to get cpu regulator\n", __func__); else { cpu_clk = clk_get(NULL, "cpu_clk"); if (IS_ERR(cpu_clk)) { printk(KERN_ERR "%s: failed to get cpu clock\n", __func__); } else { curr_cpu = clk_get_rate(cpu_clk); cpu_op_tbl = get_cpu_op(&cpu_op_nr); /* Set the core to max frequency requested. */ regulator_set_voltage(cpu_regulator, cpu_op_tbl[0].cpu_voltage, cpu_op_tbl[0].cpu_voltage); clk_set_rate(cpu_clk, cpu_op_tbl[0].cpu_rate); /*Fix loops-per-jiffy */ #ifdef CONFIG_SMP for_each_online_cpu(cpu) per_cpu(cpu_data, cpu).loops_per_jiffy = mx6_cpu_jiffies( per_cpu(cpu_data, cpu).loops_per_jiffy, curr_cpu / 1000, clk_get_rate(cpu_clk) / 1000); #else u32 old_loops_per_jiffy = loops_per_jiffy; loops_per_jiffy = mx6_cpu_jiffies(old_loops_per_jiffy, curr_cpu/1000, clk_get_rate(cpu_clk) / 1000); #endif #if defined(CONFIG_CPU_FREQ) /* Fix CPU frequency for CPUFREQ. */ for (cpu = 0; cpu < num_online_cpus(); cpu++) cpufreq_get(cpu); #endif } } soc_regulator = regulator_get(NULL, soc_reg_id); if (IS_ERR(soc_regulator)) printk(KERN_ERR "%s: failed to get soc regulator\n", __func__); pu_regulator = regulator_get(NULL, pu_reg_id); if (IS_ERR(pu_regulator)) printk(KERN_ERR "%s: failed to get pu regulator\n", __func__); }
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; }
/*! * This is the probe routine for the DVFS driver. * * @param pdev The platform device structure * * @return The function returns 0 on success */ static int __devinit mxc_dvfs_core_probe(struct platform_device *pdev) { int err = 0; struct resource *res; printk(KERN_INFO "mxc_dvfs_core_probe\n"); dvfs_dev = &pdev->dev; dvfs_data = pdev->dev.platform_data; INIT_DELAYED_WORK(&dvfs_core_handler, dvfs_core_work_handler); pll1_sw_clk = clk_get(NULL, "pll1_sw_clk"); if (IS_ERR(pll1_sw_clk)) { printk(KERN_INFO "%s: failed to get pll1_sw_clk\n", __func__); return PTR_ERR(pll1_sw_clk); } cpu_clk = clk_get(NULL, dvfs_data->clk1_id); if (IS_ERR(cpu_clk)) { printk(KERN_ERR "%s: failed to get cpu clock\n", __func__); return PTR_ERR(cpu_clk); } if (!cpu_is_mx6()) { dvfs_clk = clk_get(NULL, dvfs_data->clk2_id); if (IS_ERR(dvfs_clk)) { printk(KERN_ERR "%s: failed to get dvfs clock\n", __func__); return PTR_ERR(dvfs_clk); } } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { err = -ENODEV; goto err1; } dvfs_data->membase = ioremap(res->start, res->end - res->start + 1); /* * Request the DVFS interrupt */ dvfs_data->irq = platform_get_irq(pdev, 0); if (dvfs_data->irq < 0) { err = dvfs_data->irq; goto err2; } /* request the DVFS interrupt */ err = request_irq(dvfs_data->irq, dvfs_irq, IRQF_SHARED, "dvfs", dvfs_dev); if (err) { printk(KERN_ERR "DVFS: Unable to attach to DVFS interrupt,err = %d", err); goto err2; } dvfs_core_setpoint = get_dvfs_core_op(&dvfs_core_op); if (dvfs_core_setpoint == NULL) { printk(KERN_ERR "No dvfs_core working point table defined\n"); goto err3; } clk_enable(dvfs_clk); err = init_dvfs_controller(); if (err) { printk(KERN_ERR "DVFS: Unable to initialize DVFS"); return err; } clk_disable(dvfs_clk); err = sysfs_create_file(&pdev->dev.kobj, &dev_attr_enable.attr); if (err) { printk(KERN_ERR "DVFS: Unable to register sysdev entry for DVFS"); goto err3; } err = sysfs_create_file(&dvfs_dev->kobj, &dev_attr_show_regs.attr); if (err) { printk(KERN_ERR "DVFS: Unable to register sysdev entry for DVFS"); goto err3; } /* Set the current working point. */ cpu_op_tbl = get_cpu_op(&cpu_op_nr); old_op = 0; curr_op = 0; dvfs_core_resume = 0; cpufreq_trig_needed = 0; return err; err3: free_irq(dvfs_data->irq, dvfs_dev); err2: iounmap(dvfs_data->membase); err1: dev_err(&pdev->dev, "Failed to probe DVFS CORE\n"); return err; }
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 { unsigned long iram_paddr; /* Allocate IRAM for WFI code when system is * in low freq mode. */ iram_alloc(SZ_4K, &iram_paddr); /* Need to remap the area here since we want * the memory region to be executable. */ mx6sl_wfi_iram_base = __arm_ioremap(iram_paddr, SZ_4K, MT_MEMORY_NONCACHED); memcpy(mx6sl_wfi_iram_base, mx6sl_wait, SZ_4K); mx6sl_wfi_iram = (void *)mx6sl_wfi_iram_base; /* Allocate IRAM for WFI code when system is *in low freq mode. */ iram_alloc(SZ_4K, &iram_paddr); /* Need to remap the area here since we want the memory region to be executable. */ mx6sl_ddr_freq_base = __arm_ioremap(iram_paddr, SZ_4K, MT_MEMORY_NONCACHED); memcpy(mx6sl_ddr_freq_base, mx6sl_ddr_iram, SZ_4K); mx6sl_ddr_freq_change_iram = (void *)mx6sl_ddr_freq_base; } return 0; }
void mx6_cpu_regulator_init(void) { int cpu; u32 curr_cpu = 0; unsigned int reg; #ifndef CONFIG_SMP unsigned long old_loops_per_jiffy; #endif void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR); if (initialized) return; initialized = true; external_pureg = 0; /*If internal ldo actived, use internal cpu_* regulator to replace the *regulator ids from board file. If internal ldo bypassed, use the *regulator ids which defined in board file and source from extern pmic *power rails. *If you want to use ldo bypass,you should do: *1.set enable_ldo_mode=LDO_MODE_BYPASSED in your board file by default * or set in commandline from u-boot *2.set your extern pmic regulator name in your board file. */ if (enable_ldo_mode != LDO_MODE_BYPASSED) { gp_reg_id = "cpu_vddgp"; soc_reg_id = "cpu_vddsoc"; pu_reg_id = "cpu_vddgpu"; } printk(KERN_INFO "cpu regulator mode:%s\n", (enable_ldo_mode == LDO_MODE_BYPASSED) ? "ldo_bypass" : "ldo_enable"); cpu_regulator = regulator_get(NULL, gp_reg_id); if (IS_ERR(cpu_regulator)) printk(KERN_ERR "%s: failed to get cpu regulator\n", __func__); else { cpu_clk = clk_get(NULL, "cpu_clk"); if (IS_ERR(cpu_clk)) { printk(KERN_ERR "%s: failed to get cpu clock\n", __func__); } else { curr_cpu = clk_get_rate(cpu_clk); cpu_op_tbl = get_cpu_op(&cpu_op_nr); soc_regulator = regulator_get(NULL, soc_reg_id); if (IS_ERR(soc_regulator)) printk(KERN_ERR "%s: failed to get soc regulator\n", __func__); else /* set soc to highest setpoint voltage. */ regulator_set_voltage(soc_regulator, cpu_op_tbl[0].soc_voltage, cpu_op_tbl[0].soc_voltage); pu_regulator = regulator_get(NULL, pu_reg_id); if (IS_ERR(pu_regulator)) printk(KERN_ERR "%s: failed to get pu regulator\n", __func__); else /* set pu to higheset setpoint voltage. */ regulator_set_voltage(pu_regulator, cpu_op_tbl[0].pu_voltage, cpu_op_tbl[0].pu_voltage); /* set the core to higheset setpoint voltage. */ regulator_set_voltage(cpu_regulator, cpu_op_tbl[0].cpu_voltage, cpu_op_tbl[0].cpu_voltage); if (enable_ldo_mode == LDO_MODE_BYPASSED) { /* digital bypass VDDPU/VDDSOC/VDDARM */ reg = __raw_readl(ANADIG_REG_CORE); reg &= ~BM_ANADIG_REG_CORE_REG0_TRG; reg |= BF_ANADIG_REG_CORE_REG0_TRG(0x1f); reg &= ~BM_ANADIG_REG_CORE_REG1_TRG; reg |= BF_ANADIG_REG_CORE_REG1_TRG(0x1f); reg &= ~BM_ANADIG_REG_CORE_REG2_TRG; reg |= BF_ANADIG_REG_CORE_REG2_TRG(0x1f); __raw_writel(reg, ANADIG_REG_CORE); /* mask the ANATOP brown out irq in the GPC. */ reg = __raw_readl(gpc_base + 0x14); reg |= 0x80000000; __raw_writel(reg, gpc_base + 0x14); } clk_set_rate(cpu_clk, cpu_op_tbl[0].cpu_rate); /* fix loops-per-jiffy */ #ifdef CONFIG_SMP for_each_online_cpu(cpu) per_cpu(cpu_data, cpu).loops_per_jiffy = mx6_cpu_jiffies( per_cpu(cpu_data, cpu).loops_per_jiffy, curr_cpu / 1000, clk_get_rate(cpu_clk) / 1000); #else old_loops_per_jiffy = loops_per_jiffy; loops_per_jiffy = mx6_cpu_jiffies(old_loops_per_jiffy, curr_cpu/1000, clk_get_rate(cpu_clk) / 1000); #endif #if defined(CONFIG_CPU_FREQ) /* Fix CPU frequency for CPUFREQ. */ for (cpu = 0; cpu < num_online_cpus(); cpu++) cpufreq_get(cpu); #endif } } /* * if use ldo bypass and VDDPU_IN is single supplied * by external pmic, it means VDDPU_IN can be turned off * if GPU/VPU driver not running.In this case we should set * external_pureg which can be used in pu_enable/pu_disable of * arch/arm/mach-mx6/mx6_anatop_regulator.c to * enable or disable external VDDPU regulator from pmic. But for FSL * reference boards, VDDSOC_IN connect with VDDPU_IN, so we didn't set * pu_reg_id to the external pmic regulator supply name in the board * file. In this case external_pureg should be 0 and can't turn off * extern pmic regulator, but can turn off VDDPU by internal anatop * power gate. * * if enable internal ldo , external_pureg will be 0, and * VDDPU can be turned off by internal anatop anatop power gate. * */ if (!IS_ERR(pu_regulator) && strcmp(pu_reg_id, "cpu_vddgpu")) external_pureg = 1; }