Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 173331
b: refs/heads/master
c: 683b1e1
h: refs/heads/master
i:
  173329: 78aafbd
  173327: da18e84
v: v3
  • Loading branch information
Sekhar Nori authored and Kevin Hilman committed Nov 25, 2009
1 parent c7d4aec commit a8021a8
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6601b8030de3e9c29930684eeac15302a59f991a
refs/heads/master: 683b1e1f0e6f7b2690c0ce76751ba8f26f0235c6
153 changes: 153 additions & 0 deletions trunk/arch/arm/mach-davinci/da850.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/cpufreq.h>

#include <asm/mach/map.h>

Expand All @@ -26,6 +27,7 @@
#include <mach/common.h>
#include <mach/time.h>
#include <mach/da8xx.h>
#include <mach/cpufreq.h>

#include "clock.h"
#include "mux.h"
Expand All @@ -40,6 +42,11 @@
#define DA850_REF_FREQ 24000000

#define CFGCHIP3_ASYNC3_CLKSRC BIT(4)
#define CFGCHIP0_PLL_MASTER_LOCK BIT(4)

static int da850_set_armrate(struct clk *clk, unsigned long rate);
static int da850_round_armrate(struct clk *clk, unsigned long rate);
static int da850_set_pll0rate(struct clk *clk, unsigned long armrate);

static struct pll_data pll0_data = {
.num = 1,
Expand All @@ -57,6 +64,7 @@ static struct clk pll0_clk = {
.parent = &ref_clk,
.pll_data = &pll0_data,
.flags = CLK_PLL,
.set_rate = da850_set_pll0rate,
};

static struct clk pll0_aux_clk = {
Expand Down Expand Up @@ -283,6 +291,8 @@ static struct clk arm_clk = {
.parent = &pll0_sysclk6,
.lpsc = DA8XX_LPSC0_ARM,
.flags = ALWAYS_ENABLED,
.set_rate = da850_set_armrate,
.round_rate = da850_round_armrate,
};

static struct clk rmii_clk = {
Expand Down Expand Up @@ -820,6 +830,149 @@ static void da850_set_async3_src(int pllnum)
__raw_writel(v, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP3_REG));
}

#ifdef CONFIG_CPU_FREQ
/*
* Notes:
* According to the TRM, minimum PLLM results in maximum power savings.
* The OPP definitions below should keep the PLLM as low as possible.
*
* The output of the PLLM must be between 400 to 600 MHz.
* This rules out prediv of anything but divide-by-one for 24Mhz OSC input.
*/
struct da850_opp {
unsigned int freq; /* in KHz */
unsigned int prediv;
unsigned int mult;
unsigned int postdiv;
};

static const struct da850_opp da850_opp_300 = {
.freq = 300000,
.prediv = 1,
.mult = 25,
.postdiv = 2,
};

static const struct da850_opp da850_opp_200 = {
.freq = 200000,
.prediv = 1,
.mult = 25,
.postdiv = 3,
};

static const struct da850_opp da850_opp_96 = {
.freq = 96000,
.prediv = 1,
.mult = 20,
.postdiv = 5,
};

#define OPP(freq) \
{ \
.index = (unsigned int) &da850_opp_##freq, \
.frequency = freq * 1000, \
}

static struct cpufreq_frequency_table da850_freq_table[] = {
OPP(300),
OPP(200),
OPP(96),
{
.index = 0,
.frequency = CPUFREQ_TABLE_END,
},
};

static struct davinci_cpufreq_config cpufreq_info = {
.freq_table = &da850_freq_table[0],
};

static struct platform_device da850_cpufreq_device = {
.name = "cpufreq-davinci",
.dev = {
.platform_data = &cpufreq_info,
},
};

int __init da850_register_cpufreq(void)
{
return platform_device_register(&da850_cpufreq_device);
}

static int da850_round_armrate(struct clk *clk, unsigned long rate)
{
int i, ret = 0, diff;
unsigned int best = (unsigned int) -1;

rate /= 1000; /* convert to kHz */

for (i = 0; da850_freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
diff = da850_freq_table[i].frequency - rate;
if (diff < 0)
diff = -diff;

if (diff < best) {
best = diff;
ret = da850_freq_table[i].frequency;
}
}

return ret * 1000;
}

static int da850_set_armrate(struct clk *clk, unsigned long index)
{
struct clk *pllclk = &pll0_clk;

return clk_set_rate(pllclk, index);
}

static int da850_set_pll0rate(struct clk *clk, unsigned long index)
{
unsigned int prediv, mult, postdiv;
struct da850_opp *opp;
struct pll_data *pll = clk->pll_data;
unsigned int v;
int ret;

opp = (struct da850_opp *) da850_freq_table[index].index;
prediv = opp->prediv;
mult = opp->mult;
postdiv = opp->postdiv;

/* Unlock writing to PLL registers */
v = __raw_readl(DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP0_REG));
v &= ~CFGCHIP0_PLL_MASTER_LOCK;
__raw_writel(v, DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP0_REG));

ret = davinci_set_pllrate(pll, prediv, mult, postdiv);
if (WARN_ON(ret))
return ret;

return 0;
}
#else
int __init da850_register_cpufreq(void)
{
return 0;
}

static int da850_set_armrate(struct clk *clk, unsigned long rate)
{
return -EINVAL;
}

static int da850_set_pll0rate(struct clk *clk, unsigned long armrate)
{
return -EINVAL;
}

static int da850_round_armrate(struct clk *clk, unsigned long rate)
{
return clk->rate;
}
#endif

static struct davinci_soc_info davinci_soc_info_da850 = {
.io_desc = da850_io_desc,
.io_desc_num = ARRAY_SIZE(da850_io_desc),
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/arm/mach-davinci/include/mach/da8xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ extern void __iomem *da8xx_syscfg_base;
#define DA8XX_SYSCFG_BASE (IO_PHYS + 0x14000)
#define DA8XX_SYSCFG_VIRT(x) (da8xx_syscfg_base + (x))
#define DA8XX_JTAG_ID_REG 0x18
#define DA8XX_CFGCHIP0_REG 0x17c
#define DA8XX_CFGCHIP2_REG 0x184
#define DA8XX_CFGCHIP3_REG 0x188

Expand Down Expand Up @@ -85,6 +86,7 @@ int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
int da8xx_register_mmcsd0(struct davinci_mmc_config *config);
void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
int da8xx_register_rtc(void);
int da850_register_cpufreq(void);

extern struct platform_device da8xx_serial_device;
extern struct emac_platform_data da8xx_emac_pdata;
Expand Down

0 comments on commit a8021a8

Please sign in to comment.