Skip to content

Commit

Permalink
mfd: db8500-prcmu: get base address from resource
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Linus Walleij committed Apr 8, 2013
1 parent 9a47a8d commit b047d98
Showing 5 changed files with 131 additions and 130 deletions.
2 changes: 0 additions & 2 deletions arch/arm/mach-ux500/cpu-db8500.c
Original file line number Diff line number Diff line change
@@ -94,8 +94,6 @@ void __init u8500_map_io(void)
iotable_init(u9540_io_desc, ARRAY_SIZE(u9540_io_desc));
else
iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));

_PRCMU_BASE = __io_address(U8500_PRCMU_BASE);
}

static struct resource db8500_pmu_resources[] = {
2 changes: 0 additions & 2 deletions arch/arm/mach-ux500/cpu.c
Original file line number Diff line number Diff line change
@@ -30,8 +30,6 @@
#include "board-mop500.h"
#include "id.h"

void __iomem *_PRCMU_BASE;

/*
* FIXME: Should we set up the GPIO domain here?
*
2 changes: 0 additions & 2 deletions arch/arm/mach-ux500/include/mach/hardware.h
Original file line number Diff line number Diff line change
@@ -39,8 +39,6 @@

#ifndef __ASSEMBLY__

extern void __iomem *_PRCMU_BASE;

#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)

#endif /* __ASSEMBLY__ */
47 changes: 29 additions & 18 deletions drivers/mfd/db8500-prcmu.c
Original file line number Diff line number Diff line change
@@ -422,9 +422,10 @@ static DEFINE_SPINLOCK(clkout_lock);

/* Global var to runtime determine TCDM base for v2 or v1 */
static __iomem void *tcdm_base;
static __iomem void *prcmu_base;

struct clk_mgt {
void __iomem *reg;
u32 offset;
u32 pllsw;
int branch;
bool clk38div;
@@ -599,9 +600,9 @@ int db8500_prcmu_set_display_clocks(void)
while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
cpu_relax();

writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT);
writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT);
writel(PRCMU_DPI_CLOCK_SETTING, PRCM_LCDCLK_MGT);
writel(PRCMU_DSI_CLOCK_SETTING, prcmu_base + PRCM_HDMICLK_MGT);
writel(PRCMU_DSI_LP_CLOCK_SETTING, prcmu_base + PRCM_TVCLK_MGT);
writel(PRCMU_DPI_CLOCK_SETTING, prcmu_base + PRCM_LCDCLK_MGT);

/* Release the HW semaphore. */
writel(0, PRCM_SEM);
@@ -613,15 +614,15 @@ int db8500_prcmu_set_display_clocks(void)

u32 db8500_prcmu_read(unsigned int reg)
{
return readl(_PRCMU_BASE + reg);
return readl(prcmu_base + reg);
}

void db8500_prcmu_write(unsigned int reg, u32 value)
{
unsigned long flags;

spin_lock_irqsave(&prcmu_lock, flags);
writel(value, (_PRCMU_BASE + reg));
writel(value, (prcmu_base + reg));
spin_unlock_irqrestore(&prcmu_lock, flags);
}

@@ -631,9 +632,9 @@ void db8500_prcmu_write_masked(unsigned int reg, u32 mask, u32 value)
unsigned long flags;

spin_lock_irqsave(&prcmu_lock, flags);
val = readl(_PRCMU_BASE + reg);
val = readl(prcmu_base + reg);
val = ((val & ~mask) | (value & mask));
writel(val, (_PRCMU_BASE + reg));
writel(val, (prcmu_base + reg));
spin_unlock_irqrestore(&prcmu_lock, flags);
}

@@ -1059,7 +1060,7 @@ int db8500_prcmu_set_ddr_opp(u8 opp)
/* Divide the frequency of certain clocks by 2 for APE_50_PARTLY_25_OPP. */
static void request_even_slower_clocks(bool enable)
{
void __iomem *clock_reg[] = {
u32 clock_reg[] = {
PRCM_ACLK_MGT,
PRCM_DMACLK_MGT
};
@@ -1076,7 +1077,7 @@ static void request_even_slower_clocks(bool enable)
u32 val;
u32 div;

val = readl(clock_reg[i]);
val = readl(prcmu_base + clock_reg[i]);
div = (val & PRCM_CLK_MGT_CLKPLLDIV_MASK);
if (enable) {
if ((div <= 1) || (div > 15)) {
@@ -1092,7 +1093,7 @@ static void request_even_slower_clocks(bool enable)
}
val = ((val & ~PRCM_CLK_MGT_CLKPLLDIV_MASK) |
(div & PRCM_CLK_MGT_CLKPLLDIV_MASK));
writel(val, clock_reg[i]);
writel(val, prcmu_base + clock_reg[i]);
}

unlock_and_return:
@@ -1446,14 +1447,14 @@ static int request_clock(u8 clock, bool enable)
while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
cpu_relax();

val = readl(clk_mgt[clock].reg);
val = readl(prcmu_base + clk_mgt[clock].offset);
if (enable) {
val |= (PRCM_CLK_MGT_CLKEN | clk_mgt[clock].pllsw);
} else {
clk_mgt[clock].pllsw = (val & PRCM_CLK_MGT_CLKPLLSW_MASK);
val &= ~(PRCM_CLK_MGT_CLKEN | PRCM_CLK_MGT_CLKPLLSW_MASK);
}
writel(val, clk_mgt[clock].reg);
writel(val, prcmu_base + clk_mgt[clock].offset);

/* Release the HW semaphore. */
writel(0, PRCM_SEM);
@@ -1629,7 +1630,7 @@ static unsigned long clock_rate(u8 clock)
u32 pllsw;
unsigned long rate = ROOT_CLOCK_RATE;

val = readl(clk_mgt[clock].reg);
val = readl(prcmu_base + clk_mgt[clock].offset);

if (val & PRCM_CLK_MGT_CLK38) {
if (clk_mgt[clock].clk38div && (val & PRCM_CLK_MGT_CLK38DIV))
@@ -1785,7 +1786,7 @@ static long round_clock_rate(u8 clock, unsigned long rate)
unsigned long src_rate;
long rounded_rate;

val = readl(clk_mgt[clock].reg);
val = readl(prcmu_base + clk_mgt[clock].offset);
src_rate = clock_source_rate((val | clk_mgt[clock].pllsw),
clk_mgt[clock].branch);
div = clock_divider(src_rate, rate);
@@ -1933,7 +1934,7 @@ static void set_clock_rate(u8 clock, unsigned long rate)
while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
cpu_relax();

val = readl(clk_mgt[clock].reg);
val = readl(prcmu_base + clk_mgt[clock].offset);
src_rate = clock_source_rate((val | clk_mgt[clock].pllsw),
clk_mgt[clock].branch);
div = clock_divider(src_rate, rate);
@@ -1961,7 +1962,7 @@ static void set_clock_rate(u8 clock, unsigned long rate)
val &= ~PRCM_CLK_MGT_CLKPLLDIV_MASK;
val |= min(div, (u32)31);
}
writel(val, clk_mgt[clock].reg);
writel(val, prcmu_base + clk_mgt[clock].offset);

/* Release the HW semaphore. */
writel(0, PRCM_SEM);
@@ -3163,8 +3164,18 @@ static int db8500_prcmu_probe(struct platform_device *pdev)
int irq = 0, err = 0, i;
struct resource *res;

res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu");
if (!res) {
dev_err(&pdev->dev, "no prcmu memory region provided\n");
return -ENOENT;
}
prcmu_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
if (!prcmu_base) {
dev_err(&pdev->dev,
"failed to ioremap prcmu register memory\n");
return -ENOENT;
}
init_prcm_registers();

dbx500_fw_version_init(pdev, pdata->version_offset);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm");
if (!res) {
Loading

0 comments on commit b047d98

Please sign in to comment.