static int __init dvfs_init(void)
{
	int err = 0;
	pmic_voltage_init();

	cpu_clk = clk_get(NULL, "cpu_clk");
	ahb_clk = clk_get(NULL, "ahb_clk");
	err = init_dvfs_controller();
	if (err) {
		printk(KERN_ERR "DVFS: Unable to initialize DVFS");
		return err;
	}

	/* request the DVFS interrupt */
	err = request_irq(MXC_INT_DVFS, dvfs_irq, IRQF_DISABLED, "dvfs", NULL);
	if (err) {
		printk(KERN_ERR "DVFS: Unable to attach to DVFS interrupt");
	}

	err = dvfs_sysdev_ctrl_init();
	if (err) {
		printk(KERN_ERR
		       "DVFS: Unable to register sysdev entry for dvfs");
		return err;
	}

	return err;
}
Example #2
0
static int __init dvfs_init(void)
{
	int err = 0;
	u8 index;
	unsigned long curr_cpu;
	static struct regulator *sw2_dvs_reg, *sw1_wifi_reg, *sw4_reg;
	static struct regulator *viohi_reg, *vdig_reg, *swbst_reg, *vpll_reg, *vusb2_reg;	
	static struct regulator *sw2_stdby_reg, *sw3_normal_reg, *sw1_stby_reg;
	int finid = get_pmic_revision();
	unsigned int reg = 0;

	cpu_clk = clk_get(NULL, "cpu_clk");
	curr_cpu = clk_get_rate(cpu_clk);
	sw3_reg = regulator_get(NULL, "SW2");
	dvfs_is_active = 0;

	printk(KERN_INFO "Initializing MX35 DVFS on MC13892 Finid: %d\n", finid);

	/*
	 * WIFI SW1 - Turn off by default
	 */
	sw1_wifi_reg = regulator_get(NULL, "SW1");
	sw1_stby_reg = regulator_get(NULL, "SW1_STBY");
	regulator_enable(sw1_wifi_reg);
	regulator_set_voltage(sw1_wifi_reg, 0, 0);
	pmic_write_reg(28, 0, 0xf << 0);  /* Set to off in Normal mode */
	pmic_write_reg(24, 0, 0x1f << 0); /* Set 0V in Normal mode */
	regulator_set_voltage(sw1_stby_reg, 1200000, 1200000);
	if (finid == 2)
		pmic_write_reg(28, (0x0 << 0), (0xf << 0));
	mdelay(10);

	/*
	 * CPU SW2
	 */
	pmic_write_reg(25, (1 << 23), (1 << 23));
	sw2_dvs_reg = regulator_get(NULL, "SW2_DVS");
	sw2_stdby_reg = regulator_get(NULL, "SW2_STBY");
	regulator_set_voltage(sw2_dvs_reg, 1400000, 1400000);
	regulator_set_voltage(sw3_reg, 1400000, 1400000);
	regulator_set_voltage(sw2_stdby_reg, 1100000, 1100000);

	/*
	 * Turn off SW3
	 */
	sw3_normal_reg = regulator_get(NULL, "SW3");
	regulator_set_voltage(sw3_normal_reg, 0, 0);
	pmic_write_reg(29, 0, 0xf << 0); /* Set to off in Normal mode */
	pmic_write_reg(26, 0, 0x1f << 0); /* Set 0V in Normal mode */
	if (finid == 2)
		pmic_write_reg(28, (0x8 << 10), (0xf << 10));
	mdelay(20);

	/*
	 * Set SW4 to 1.8V by default
	 */
	if (finid == 2)
		pmic_write_reg(29, (0x8 << 8), (0xf << 8));
	sw4_reg = regulator_get(NULL, "SW4");
	regulator_set_voltage(sw4_reg, 1800000, 1800000);

	/* Set the SW4 Standby to 1.8V */
	pmic_write_reg(27, (0x1C << 10), (0x1f << 10));

	/*
	 * STANDBY and STANDBYSEC are both active low 
	 */
	pmic_write_reg(REG_POWER_CTL2, (0 << STANDBYINV), (1 << STANDBYINV));
	pmic_write_reg(REG_POWER_CTL2, (0 << STANDBYSECINV), (1 << STANDBYSECINV));

	/* Enable WDIRESET on the PMIC */
	pmic_write_reg(REG_POWER_CTL2, (1 << WDIRESET), (1 << WDIRESET));

	/* Turn on GPO2STBY to disable the regulator in Atlas standby mode */
	pmic_write_reg(REG_POWER_MISC, (GPO2STBY_ENABLE << GPO2STBY_LSH),
			(GPO2STBY_MASK << GPO2STBY_LSH));

	/*
	 * VIOHI
	 */
	viohi_reg = regulator_get(NULL, "VIOHI");
	regulator_enable(viohi_reg);

	/*
	 * VDIG
	 */
	vdig_reg = regulator_get(NULL, "VDIG");
	regulator_enable(vdig_reg);
	regulator_disable(vdig_reg);	

	/*
	 * VUSB2
	 */
	vusb2_reg = regulator_get(NULL, "VUSB2");
	regulator_enable(vusb2_reg);
	regulator_disable(vusb2_reg);

	/*
	 * SWBST - off
	 */
	swbst_reg = regulator_get(NULL, "SWBST");
	regulator_enable(swbst_reg);
	regulator_disable(swbst_reg);

	/* Turn off SWBST */
	pmic_write_reg(REG_SW_5, (0 << 20), (1 << 20));

	/*
	 * VPLL - Controlled by Standby
	 */
	vpll_reg = regulator_get(NULL, "VPLL");
	/* VPLL controlled by standby */
	pmic_write_reg(32, (1 << 16), (1 << 16));

	/*
	 * VSD - Controlled by Standby
	 */
	pmic_write_reg(33, (1 << 18), (1 << 18));
	pmic_write_reg(33, (1 << 19), (1 << 19));
	pmic_write_reg(32, (1 << 13), (1 << 13));

	/*
	 * Power button debounce time
	 */

	pmic_read_reg(REG_POWER_CTL2, &reg, 0xffffffff);
	printk(KERN_INFO "Power Button Debounce Settings: 0x%x\n", reg);

	/* Configure debounce time for power button 1 */
	pmic_write_reg(REG_POWER_CTL2, (PMIC_BUTTON_DEBOUNCE_VALUE << 4), (PMIC_BUTTON_DEBOUNCE_MASK << 4));
	
	/* Configure debounce time for power button 2 */
	pmic_write_reg(REG_POWER_CTL2, (PMIC_BUTTON_DEBOUNCE_VALUE << 6), (PMIC_BUTTON_DEBOUNCE_MASK << 6));

	/* Configure debounce time for power button 3 */
	pmic_write_reg(REG_POWER_CTL2, (PMIC_BUTTON_DEBOUNCE_VALUE << 8), (PMIC_BUTTON_DEBOUNCE_MASK << 8));

	/*
	 * Set the USEROFF Mode for the Switchers
	 */
	pmic_write_reg(REG_SW_4, (SW1_MHMODE_VALUE << SW1_MHMODE_LSH),
			(SW1_MHMODE_MASK << SW1_MHMODE_LSH));

	pmic_write_reg(REG_SW_4, (SW2_MHMODE_VALUE << SW2_MHMODE_LSH),
			(SW2_MHMODE_MASK << SW2_MHMODE_LSH));

	pmic_write_reg(REG_SW_5, (SW3_MHMODE_VALUE << SW3_MHMODE_LSH),
			(SW3_MHMODE_MASK << SW3_MHMODE_LSH));

	pmic_write_reg(REG_SW_5, (SW4_MHMODE_VALUE << SW4_MHMODE_LSH),
			(SW4_MHMODE_MASK << SW4_MHMODE_LSH));

	/* for auto path, only 3 working points are supported */
	if (!(__raw_readl(MXC_CCM_PDR0) & MXC_CCM_PDR0_AUTO_CON)) {
		if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
			dvfs_wp_num = 3;
			dvfs_wp_tbl[2].dvsup = DVFS_DVSUP(DVSUP_TURBO);
		}
	}

	printk(KERN_INFO "MX35 Luigi working points: %d\n", dvfs_wp_num);

	/*Set voltage */
	for (index = 0; index < dvfs_wp_num; index++) {
		if (dvfs_wp_tbl[index].cpu_rate == curr_cpu) {
			regulator_set_voltage(sw3_reg,
					      dvfs_wp_tbl[index].core_voltage,
					      dvfs_wp_tbl[index].core_voltage);
			break;
		}
	}

	err = init_dvfs_controller();
	if (err) {
		printk(KERN_ERR "DVFS: Unable to initialize DVFS");
		return err;
	}

	INIT_DELAYED_WORK(&dvfs_work, dvfs_workqueue_handler);

	/* request the DVFS interrupt */
	err = request_irq(MXC_INT_DVFS, dvfs_irq, IRQF_DISABLED, "dvfs", NULL);
	if (err) {
		printk(KERN_ERR "DVFS: Unable to attach to DVFS interrupt");
		return err;
	}

	err = dvfs_sysdev_ctrl_init();
	if (err) {
		printk(KERN_ERR
		       "DVFS: Unable to register sysdev entry for dvfs");
		return err;
	}

	return err;
}
Example #3
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);
	}

	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);
	}

	core_regulator = regulator_get(NULL, dvfs_data->reg_id);
	if (IS_ERR(core_regulator)) {
		clk_put(cpu_clk);
		clk_put(dvfs_clk);
		printk(KERN_ERR "%s: failed to get gp regulator\n", __func__);
		return PTR_ERR(core_regulator);
	}

	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;
	}

	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(&dvfs_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;
	}


	err = sysfs_create_file(&dvfs_dev->kobj, &dev_attr_down_threshold.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_down_count.attr);
	if (err) {
		printk(KERN_ERR
		       "DVFS: Unable to register sysdev entry for DVFS");
		goto err3;
	}

	/* Set the current working point. */
	cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr);
	old_wp = 0;
	curr_wp = 0;
	dvfs_core_resume = 0;
#if defined(CONFIG_CPU_FREQ)
	cpufreq_trig_needed = 0;
#endif

	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;
}