aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/db8500-prcmu.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2013-03-19 09:21:47 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-04-08 07:57:38 -0400
commitb047d98127ccbf9fe83b6192a3562b3ead0b2415 (patch)
treef37f0f6dcbeccbdc67621a84ceabf7f16d05ba0f /drivers/mfd/db8500-prcmu.c
parent9a47a8dccf8866b497bd80809da1c665e7b07c2c (diff)
mfd: db8500-prcmu: get base address from resource
We cannot use a global variable stored in <mach/hardware.h> to find the base address of the PRCMU. The real resource is already there from the board, so use this to look up the base address instead. Currently the patch is kept minimal so as not to interfere with other work being done on refactoring this driver, but at a later point the defines using (prcmu_base + 0xnnn) need to be replaced by pure offset defined for (0xnnn) and the base inlined with the readl()/writel() and similar codepaths. Acked-by: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/mfd/db8500-prcmu.c')
-rw-r--r--drivers/mfd/db8500-prcmu.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 0d0cc91f30e8..75a60c4721ff 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -422,9 +422,10 @@ static DEFINE_SPINLOCK(clkout_lock);
422 422
423/* Global var to runtime determine TCDM base for v2 or v1 */ 423/* Global var to runtime determine TCDM base for v2 or v1 */
424static __iomem void *tcdm_base; 424static __iomem void *tcdm_base;
425static __iomem void *prcmu_base;
425 426
426struct clk_mgt { 427struct clk_mgt {
427 void __iomem *reg; 428 u32 offset;
428 u32 pllsw; 429 u32 pllsw;
429 int branch; 430 int branch;
430 bool clk38div; 431 bool clk38div;
@@ -599,9 +600,9 @@ int db8500_prcmu_set_display_clocks(void)
599 while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) 600 while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
600 cpu_relax(); 601 cpu_relax();
601 602
602 writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT); 603 writel(PRCMU_DSI_CLOCK_SETTING, prcmu_base + PRCM_HDMICLK_MGT);
603 writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT); 604 writel(PRCMU_DSI_LP_CLOCK_SETTING, prcmu_base + PRCM_TVCLK_MGT);
604 writel(PRCMU_DPI_CLOCK_SETTING, PRCM_LCDCLK_MGT); 605 writel(PRCMU_DPI_CLOCK_SETTING, prcmu_base + PRCM_LCDCLK_MGT);
605 606
606 /* Release the HW semaphore. */ 607 /* Release the HW semaphore. */
607 writel(0, PRCM_SEM); 608 writel(0, PRCM_SEM);
@@ -613,7 +614,7 @@ int db8500_prcmu_set_display_clocks(void)
613 614
614u32 db8500_prcmu_read(unsigned int reg) 615u32 db8500_prcmu_read(unsigned int reg)
615{ 616{
616 return readl(_PRCMU_BASE + reg); 617 return readl(prcmu_base + reg);
617} 618}
618 619
619void db8500_prcmu_write(unsigned int reg, u32 value) 620void db8500_prcmu_write(unsigned int reg, u32 value)
@@ -621,7 +622,7 @@ void db8500_prcmu_write(unsigned int reg, u32 value)
621 unsigned long flags; 622 unsigned long flags;
622 623
623 spin_lock_irqsave(&prcmu_lock, flags); 624 spin_lock_irqsave(&prcmu_lock, flags);
624 writel(value, (_PRCMU_BASE + reg)); 625 writel(value, (prcmu_base + reg));
625 spin_unlock_irqrestore(&prcmu_lock, flags); 626 spin_unlock_irqrestore(&prcmu_lock, flags);
626} 627}
627 628
@@ -631,9 +632,9 @@ void db8500_prcmu_write_masked(unsigned int reg, u32 mask, u32 value)
631 unsigned long flags; 632 unsigned long flags;
632 633
633 spin_lock_irqsave(&prcmu_lock, flags); 634 spin_lock_irqsave(&prcmu_lock, flags);
634 val = readl(_PRCMU_BASE + reg); 635 val = readl(prcmu_base + reg);
635 val = ((val & ~mask) | (value & mask)); 636 val = ((val & ~mask) | (value & mask));
636 writel(val, (_PRCMU_BASE + reg)); 637 writel(val, (prcmu_base + reg));
637 spin_unlock_irqrestore(&prcmu_lock, flags); 638 spin_unlock_irqrestore(&prcmu_lock, flags);
638} 639}
639 640
@@ -1059,7 +1060,7 @@ int db8500_prcmu_set_ddr_opp(u8 opp)
1059/* Divide the frequency of certain clocks by 2 for APE_50_PARTLY_25_OPP. */ 1060/* Divide the frequency of certain clocks by 2 for APE_50_PARTLY_25_OPP. */
1060static void request_even_slower_clocks(bool enable) 1061static void request_even_slower_clocks(bool enable)
1061{ 1062{
1062 void __iomem *clock_reg[] = { 1063 u32 clock_reg[] = {
1063 PRCM_ACLK_MGT, 1064 PRCM_ACLK_MGT,
1064 PRCM_DMACLK_MGT 1065 PRCM_DMACLK_MGT
1065 }; 1066 };
@@ -1076,7 +1077,7 @@ static void request_even_slower_clocks(bool enable)
1076 u32 val; 1077 u32 val;
1077 u32 div; 1078 u32 div;
1078 1079
1079 val = readl(clock_reg[i]); 1080 val = readl(prcmu_base + clock_reg[i]);
1080 div = (val & PRCM_CLK_MGT_CLKPLLDIV_MASK); 1081 div = (val & PRCM_CLK_MGT_CLKPLLDIV_MASK);
1081 if (enable) { 1082 if (enable) {
1082 if ((div <= 1) || (div > 15)) { 1083 if ((div <= 1) || (div > 15)) {
@@ -1092,7 +1093,7 @@ static void request_even_slower_clocks(bool enable)
1092 } 1093 }
1093 val = ((val & ~PRCM_CLK_MGT_CLKPLLDIV_MASK) | 1094 val = ((val & ~PRCM_CLK_MGT_CLKPLLDIV_MASK) |
1094 (div & PRCM_CLK_MGT_CLKPLLDIV_MASK)); 1095 (div & PRCM_CLK_MGT_CLKPLLDIV_MASK));
1095 writel(val, clock_reg[i]); 1096 writel(val, prcmu_base + clock_reg[i]);
1096 } 1097 }
1097 1098
1098unlock_and_return: 1099unlock_and_return:
@@ -1446,14 +1447,14 @@ static int request_clock(u8 clock, bool enable)
1446 while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) 1447 while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
1447 cpu_relax(); 1448 cpu_relax();
1448 1449
1449 val = readl(clk_mgt[clock].reg); 1450 val = readl(prcmu_base + clk_mgt[clock].offset);
1450 if (enable) { 1451 if (enable) {
1451 val |= (PRCM_CLK_MGT_CLKEN | clk_mgt[clock].pllsw); 1452 val |= (PRCM_CLK_MGT_CLKEN | clk_mgt[clock].pllsw);
1452 } else { 1453 } else {
1453 clk_mgt[clock].pllsw = (val & PRCM_CLK_MGT_CLKPLLSW_MASK); 1454 clk_mgt[clock].pllsw = (val & PRCM_CLK_MGT_CLKPLLSW_MASK);
1454 val &= ~(PRCM_CLK_MGT_CLKEN | PRCM_CLK_MGT_CLKPLLSW_MASK); 1455 val &= ~(PRCM_CLK_MGT_CLKEN | PRCM_CLK_MGT_CLKPLLSW_MASK);
1455 } 1456 }
1456 writel(val, clk_mgt[clock].reg); 1457 writel(val, prcmu_base + clk_mgt[clock].offset);
1457 1458
1458 /* Release the HW semaphore. */ 1459 /* Release the HW semaphore. */
1459 writel(0, PRCM_SEM); 1460 writel(0, PRCM_SEM);
@@ -1629,7 +1630,7 @@ static unsigned long clock_rate(u8 clock)
1629 u32 pllsw; 1630 u32 pllsw;
1630 unsigned long rate = ROOT_CLOCK_RATE; 1631 unsigned long rate = ROOT_CLOCK_RATE;
1631 1632
1632 val = readl(clk_mgt[clock].reg); 1633 val = readl(prcmu_base + clk_mgt[clock].offset);
1633 1634
1634 if (val & PRCM_CLK_MGT_CLK38) { 1635 if (val & PRCM_CLK_MGT_CLK38) {
1635 if (clk_mgt[clock].clk38div && (val & PRCM_CLK_MGT_CLK38DIV)) 1636 if (clk_mgt[clock].clk38div && (val & PRCM_CLK_MGT_CLK38DIV))
@@ -1785,7 +1786,7 @@ static long round_clock_rate(u8 clock, unsigned long rate)
1785 unsigned long src_rate; 1786 unsigned long src_rate;
1786 long rounded_rate; 1787 long rounded_rate;
1787 1788
1788 val = readl(clk_mgt[clock].reg); 1789 val = readl(prcmu_base + clk_mgt[clock].offset);
1789 src_rate = clock_source_rate((val | clk_mgt[clock].pllsw), 1790 src_rate = clock_source_rate((val | clk_mgt[clock].pllsw),
1790 clk_mgt[clock].branch); 1791 clk_mgt[clock].branch);
1791 div = clock_divider(src_rate, rate); 1792 div = clock_divider(src_rate, rate);
@@ -1933,7 +1934,7 @@ static void set_clock_rate(u8 clock, unsigned long rate)
1933 while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) 1934 while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
1934 cpu_relax(); 1935 cpu_relax();
1935 1936
1936 val = readl(clk_mgt[clock].reg); 1937 val = readl(prcmu_base + clk_mgt[clock].offset);
1937 src_rate = clock_source_rate((val | clk_mgt[clock].pllsw), 1938 src_rate = clock_source_rate((val | clk_mgt[clock].pllsw),
1938 clk_mgt[clock].branch); 1939 clk_mgt[clock].branch);
1939 div = clock_divider(src_rate, rate); 1940 div = clock_divider(src_rate, rate);
@@ -1961,7 +1962,7 @@ static void set_clock_rate(u8 clock, unsigned long rate)
1961 val &= ~PRCM_CLK_MGT_CLKPLLDIV_MASK; 1962 val &= ~PRCM_CLK_MGT_CLKPLLDIV_MASK;
1962 val |= min(div, (u32)31); 1963 val |= min(div, (u32)31);
1963 } 1964 }
1964 writel(val, clk_mgt[clock].reg); 1965 writel(val, prcmu_base + clk_mgt[clock].offset);
1965 1966
1966 /* Release the HW semaphore. */ 1967 /* Release the HW semaphore. */
1967 writel(0, PRCM_SEM); 1968 writel(0, PRCM_SEM);
@@ -3163,8 +3164,18 @@ static int db8500_prcmu_probe(struct platform_device *pdev)
3163 int irq = 0, err = 0, i; 3164 int irq = 0, err = 0, i;
3164 struct resource *res; 3165 struct resource *res;
3165 3166
3167 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu");
3168 if (!res) {
3169 dev_err(&pdev->dev, "no prcmu memory region provided\n");
3170 return -ENOENT;
3171 }
3172 prcmu_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
3173 if (!prcmu_base) {
3174 dev_err(&pdev->dev,
3175 "failed to ioremap prcmu register memory\n");
3176 return -ENOENT;
3177 }
3166 init_prcm_registers(); 3178 init_prcm_registers();
3167
3168 dbx500_fw_version_init(pdev, pdata->version_offset); 3179 dbx500_fw_version_init(pdev, pdata->version_offset);
3169 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm"); 3180 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm");
3170 if (!res) { 3181 if (!res) {