From a9d2ba1444b0af6c2d8534f0b306660ffc045bc6 Mon Sep 17 00:00:00 2001 From: Ian Wisbon Date: Thu, 10 Feb 2011 17:15:15 -0500 Subject: Linux 2.6.31 Release for Digi ConnectCore Wi-i.MX boards --- arch/arm/plat-mxc/dvfs_core.c | 191 ++++++++++++++++++++++++------------------ 1 file changed, 111 insertions(+), 80 deletions(-) (limited to 'arch/arm/plat-mxc/dvfs_core.c') diff --git a/arch/arm/plat-mxc/dvfs_core.c b/arch/arm/plat-mxc/dvfs_core.c index 43d0a3a8adeb..143bc07834ed 100644 --- a/arch/arm/plat-mxc/dvfs_core.c +++ b/arch/arm/plat-mxc/dvfs_core.c @@ -135,18 +135,19 @@ static void dvfs_load_config(int set_point) reg |= dvfs_core_setpoint[set_point].downthr << MXC_DVFSTHRS_DNTHR_OFFSET; reg |= dvfs_core_setpoint[set_point].panicthr; - __raw_writel(reg, dvfs_data->dvfs_thrs_reg_addr); + __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_THRS); reg = 0; reg |= dvfs_core_setpoint[set_point].downcnt << MXC_DVFSCOUN_DNCNT_OFFSET; reg |= dvfs_core_setpoint[set_point].upcnt << MXC_DVFSCOUN_UPCNT_OFFSET; - __raw_writel(reg, dvfs_data->dvfs_coun_reg_addr); + __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_COUN); /* Set EMAC value */ __raw_writel((dvfs_core_setpoint[set_point].emac << MXC_DVFSEMAC_EMAC_OFFSET), - dvfs_data->dvfs_emac_reg_addr); + dvfs_data->membase + + MXC_DVFSCORE_EMAC); } @@ -187,14 +188,14 @@ static int set_cpu_freq(int wp) } spin_lock_irqsave(&mxc_dvfs_core_lock, flags); /* PLL_RELOCK, set ARM_FREQ_SHIFT_DIVIDER */ - reg = __raw_readl(dvfs_data->ccm_cdcr_reg_addr); + reg = __raw_readl(ccm_base + dvfs_data->ccm_cdcr_offset); reg &= 0xFFFFFFFB; - __raw_writel(reg, dvfs_data->ccm_cdcr_reg_addr); + __raw_writel(reg, ccm_base + dvfs_data->ccm_cdcr_offset); setup_pll(); /* START the GPC main control FSM */ /* set VINC */ - reg = __raw_readl(dvfs_data->gpc_vcr_reg_addr); + reg = __raw_readl(gpc_base + dvfs_data->gpc_vcr_offset); reg &= ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK | MXC_GPCVCR_VCNT_MASK); @@ -202,18 +203,19 @@ static int set_cpu_freq(int wp) reg |= 1 << MXC_GPCVCR_VINC_OFFSET; reg |= (1 << MXC_GPCVCR_VCNTU_OFFSET) | - (1 << MXC_GPCVCR_VCNT_OFFSET); - __raw_writel(reg, dvfs_data->gpc_vcr_reg_addr); + (1 << MXC_GPCVCR_VCNT_OFFSET); + __raw_writel(reg, gpc_base + dvfs_data->gpc_vcr_offset); - reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr); + reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset); reg &= ~(MXC_GPCCNTR_ADU_MASK | MXC_GPCCNTR_FUPD_MASK); reg |= MXC_GPCCNTR_FUPD; reg |= MXC_GPCCNTR_ADU; - __raw_writel(reg, dvfs_data->gpc_cntr_reg_addr); + __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); reg |= MXC_GPCCNTR_STRT; - __raw_writel(reg, dvfs_data->gpc_cntr_reg_addr); - while (__raw_readl(dvfs_data->gpc_cntr_reg_addr) & 0x4000) + __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); + while (__raw_readl(gpc_base + dvfs_data->gpc_cntr_offset) + & 0x4000) udelay(10); spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags); @@ -234,13 +236,13 @@ static int set_cpu_freq(int wp) /* Change arm_podf only */ /* set ARM_FREQ_SHIFT_DIVIDER */ - reg = __raw_readl(dvfs_data->ccm_cdcr_reg_addr); + reg = __raw_readl(ccm_base + dvfs_data->ccm_cdcr_offset); reg &= 0xFFFFFFFB; reg |= 1 << 2; - __raw_writel(reg, dvfs_data->ccm_cdcr_reg_addr); + __raw_writel(reg, ccm_base + dvfs_data->ccm_cdcr_offset); /* Get ARM_PODF */ - reg = __raw_readl(dvfs_data->ccm_cacrr_reg_addr); + reg = __raw_readl(ccm_base + dvfs_data->ccm_cacrr_offset); arm_podf = reg & 0x07; if (podf == arm_podf) { printk(KERN_DEBUG @@ -268,37 +270,38 @@ static int set_cpu_freq(int wp) reg &= 0xFFFFFFF8; reg |= arm_podf; - reg1 = __raw_readl(dvfs_data->ccm_cdhipr_reg_addr); + reg1 = __raw_readl(ccm_base + dvfs_data->ccm_cdhipr_offset); if ((reg1 & 0x00010000) == 0) - __raw_writel(reg, dvfs_data->ccm_cacrr_reg_addr); + __raw_writel(reg, + ccm_base + dvfs_data->ccm_cacrr_offset); else { printk(KERN_DEBUG "ARM_PODF still in busy!!!!\n"); return 0; } /* START the GPC main control FSM */ - reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr); + reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset); reg |= MXC_GPCCNTR_FUPD; /* ADU=1, select ARM domain */ reg |= MXC_GPCCNTR_ADU; - __raw_writel(reg, dvfs_data->gpc_cntr_reg_addr); + __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); /* set VINC */ - reg = __raw_readl(dvfs_data->gpc_vcr_reg_addr); + reg = __raw_readl(gpc_base + dvfs_data->gpc_vcr_offset); reg &= ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK | MXC_GPCVCR_VCNT_MASK); reg |= (1 << MXC_GPCVCR_VCNTU_OFFSET) | (100 << MXC_GPCVCR_VCNT_OFFSET) | (vinc << MXC_GPCVCR_VINC_OFFSET); - __raw_writel(reg, dvfs_data->gpc_vcr_reg_addr); + __raw_writel(reg, gpc_base + dvfs_data->gpc_vcr_offset); - reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr); + reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset); reg &= (~(MXC_GPCCNTR_ADU | MXC_GPCCNTR_FUPD)); reg |= MXC_GPCCNTR_ADU | MXC_GPCCNTR_FUPD | MXC_GPCCNTR_STRT; - __raw_writel(reg, dvfs_data->gpc_cntr_reg_addr); + __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); /* Wait for arm podf Enable */ - while ((__raw_readl(dvfs_data->gpc_cntr_reg_addr) & + while ((__raw_readl(gpc_base + dvfs_data->gpc_cntr_offset) & MXC_GPCCNTR_STRT) == MXC_GPCCNTR_STRT) { printk(KERN_DEBUG "Waiting arm_podf enabled!\n"); udelay(10); @@ -317,9 +320,9 @@ static int set_cpu_freq(int wp) propagate_rate(pll1_sw_clk); /* Clear the ARM_FREQ_SHIFT_DIVIDER */ - reg = __raw_readl(dvfs_data->ccm_cdcr_reg_addr); + reg = __raw_readl(ccm_base + dvfs_data->ccm_cdcr_offset); reg &= 0xFFFFFFFB; - __raw_writel(reg, dvfs_data->ccm_cdcr_reg_addr); + __raw_writel(reg, ccm_base + dvfs_data->ccm_cdcr_offset); } #if defined(CONFIG_CPU_FREQ_IMX) cpufreq_trig_needed = 1; @@ -344,23 +347,23 @@ static int start_dvfs(void) dvfs_load_config(0); /* config reg GPC_CNTR */ - reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr); + reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset); reg &= ~MXC_GPCCNTR_GPCIRQM; /* GPCIRQ=1, select ARM IRQ */ reg |= MXC_GPCCNTR_GPCIRQ_ARM; /* ADU=1, select ARM domain */ reg |= MXC_GPCCNTR_ADU; - __raw_writel(reg, dvfs_data->gpc_cntr_reg_addr); + __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); /* Set PREDIV bits */ - reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); reg = (reg & ~(dvfs_data->prediv_mask)); reg |= (dvfs_data->prediv_val) << (dvfs_data->prediv_offset); - __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr); + __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); /* Enable DVFS interrupt */ - reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); /* FSVAIM=0 */ reg = (reg & ~MXC_DVFSCNTR_FSVAIM); /* Set MAXF, MINF */ @@ -376,12 +379,12 @@ static int start_dvfs(void) /* Set DIV3CK */ reg = (reg & ~(dvfs_data->div3ck_mask)); reg |= (dvfs_data->div3ck_val) << (dvfs_data->div3ck_offset); - __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr); + __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); /* Enable DVFS */ - reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); reg |= MXC_DVFSCNTR_DVFEN; - __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr); + __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); dvfs_core_is_active = 1; @@ -416,20 +419,20 @@ static irqreturn_t dvfs_irq(int irq, void *dev_id) u32 reg; /* Check if DVFS0 (ARM) id requesting for freqency/voltage update */ - if ((__raw_readl(dvfs_data->gpc_cntr_reg_addr) & MXC_GPCCNTR_DVFS0CR) == - 0) + if ((__raw_readl(gpc_base + dvfs_data->gpc_cntr_offset) + & MXC_GPCCNTR_DVFS0CR) == 0) return IRQ_NONE; /* Mask DVFS irq */ - reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); /* FSVAIM=1 */ reg |= MXC_DVFSCNTR_FSVAIM; - __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr); + __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); /* Mask GPC1 irq */ - reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr); + reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset); reg |= MXC_GPCCNTR_GPCIRQM | 0x1000000; - __raw_writel(reg, dvfs_data->gpc_cntr_reg_addr); + __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); schedule_delayed_work(&dvfs_core_handler, 0); return IRQ_HANDLED; @@ -448,7 +451,7 @@ static void dvfs_core_work_handler(struct work_struct *work) low_freq_bus_ready = low_freq_bus_used(); /* Check DVFS frequency adjustment interrupt status */ - reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); fsvai = (reg & MXC_DVFSCNTR_FSVAI_MASK) >> MXC_DVFSCNTR_FSVAI_OFFSET; /* Check FSVAI, FSVAI=0 is error */ if (fsvai == FSVAI_FREQ_NOCHANGE) { @@ -520,7 +523,7 @@ static void dvfs_core_work_handler(struct work_struct *work) END: /* Set MAXF, MINF */ - reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); reg = (reg & ~(MXC_DVFSCNTR_MAXF_MASK | MXC_DVFSCNTR_MINF_MASK)); reg |= maxf << MXC_DVFSCNTR_MAXF_OFFSET; reg |= minf << MXC_DVFSCNTR_MINF_OFFSET; @@ -532,11 +535,11 @@ END: /* Set MAXF, MINF */ /* LBFL=1 */ reg = (reg & ~MXC_DVFSCNTR_LBFL); reg |= MXC_DVFSCNTR_LBFL; - __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr); + __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); /*Unmask GPC1 IRQ */ - reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr); + reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset); reg &= ~MXC_GPCCNTR_GPCIRQM; - __raw_writel(reg, dvfs_data->gpc_cntr_reg_addr); + __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); #if defined(CONFIG_CPU_FREQ_IMX) if (cpufreq_trig_needed == 1) { @@ -559,10 +562,12 @@ static void stop_dvfs(void) if (dvfs_core_is_active) { /* Mask dvfs irq, disable DVFS */ - reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + reg = __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_CNTR); /* FSVAIM=1 */ reg |= MXC_DVFSCNTR_FSVAIM; - __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr); + __raw_writel(reg, dvfs_data->membase + + MXC_DVFSCORE_CNTR); curr_wp = 0; if (!high_bus_freq_mode) @@ -580,9 +585,11 @@ static void stop_dvfs(void) } spin_lock_irqsave(&mxc_dvfs_core_lock, flags); - reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + reg = __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_CNTR); reg = (reg & ~MXC_DVFSCNTR_DVFEN); - __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr); + __raw_writel(reg, dvfs_data->membase + + MXC_DVFSCORE_CNTR); spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags); @@ -610,39 +617,56 @@ void dump_dvfs_core_regs() printk(KERN_DEBUG "diff = %d\n", diff); printk(KERN_INFO "THRS = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS)); printk(KERN_INFO "COUNT = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x04)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x04)); printk(KERN_INFO "SIG1 = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x08)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x08)); printk(KERN_INFO "SIG0 = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x0c)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x0c)); printk(KERN_INFO "GPC0 = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x10)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x10)); printk(KERN_INFO "GPC1 = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x14)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x14)); printk(KERN_INFO "GPBT = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x18)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x18)); printk(KERN_INFO "EMAC = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x1c)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x1c)); printk(KERN_INFO "CNTR = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x20)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x20)); printk(KERN_INFO "LTR0_0 = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x24)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x24)); printk(KERN_INFO "LTR0_1 = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x28)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x28)); printk(KERN_INFO "LTR1_0 = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x2c)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x2c)); printk(KERN_DEBUG "LTR1_1 = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x30)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x30)); printk(KERN_INFO "PT0 = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x34)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x34)); printk(KERN_INFO "PT1 = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x38)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x38)); printk(KERN_INFO "PT2 = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x3c)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x3c)); printk(KERN_INFO "PT3 = 0x%08x\n", - __raw_readl(dvfs_data->dvfs_thrs_reg_addr+0x40)); + __raw_readl(dvfs_data->membase + + MXC_DVFSCORE_THRS + 0x40)); } static ssize_t downthreshold_show(struct device *dev, @@ -741,7 +765,6 @@ static int __devinit mxc_dvfs_core_probe(struct platform_device *pdev) { int err = 0; struct resource *res; - int irq; printk(KERN_INFO "mxc_dvfs_core_probe\n"); dvfs_dev = &pdev->dev; @@ -780,22 +803,25 @@ static int __devinit mxc_dvfs_core_probe(struct platform_device *pdev) err = -ENODEV; goto err1; } - + dvfs_data->membase = ioremap(res->start, res->end - res->start + 1); /* * Request the DVFS interrupt */ - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - err = irq; - goto err1; + 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(irq, dvfs_irq, IRQF_SHARED, "dvfs", dvfs_dev); - if (err) + 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(); @@ -809,14 +835,14 @@ static int __devinit mxc_dvfs_core_probe(struct platform_device *pdev) if (err) { printk(KERN_ERR "DVFS: Unable to register sysdev entry for DVFS"); - return err; + 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"); - return err; + goto err3; } @@ -824,14 +850,14 @@ static int __devinit mxc_dvfs_core_probe(struct platform_device *pdev) if (err) { printk(KERN_ERR "DVFS: Unable to register sysdev entry for DVFS"); - return err; + 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"); - return err; + goto err3; } /* Set the current working point. */ @@ -844,7 +870,10 @@ static int __devinit mxc_dvfs_core_probe(struct platform_device *pdev) #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; @@ -914,13 +943,15 @@ static void __exit dvfs_cleanup(void) stop_dvfs(); /* release the DVFS interrupt */ - free_irq(MXC_INT_GPC1, NULL); + free_irq(dvfs_data->irq, dvfs_dev); sysfs_remove_file(&dvfs_dev->kobj, &dev_attr_enable.attr); /* Unregister the device structure */ platform_driver_unregister(&mxc_dvfs_core_driver); + iounmap(ccm_base); + iounmap(dvfs_data->membase); clk_put(cpu_clk); clk_put(dvfs_clk); -- cgit v1.2.3