Sekhar Nori <[email protected]> writes:
> AM18x/DA850/OMAP-L138 SoCs have variants that can operate
> at a maximum of 456 MHz at 1.3V operating point. Also the
> 1.2V operating point has a variant that can support a maximum
> of 375 MHz.
>
> This patch adds three new OPPs (456 MHz, 408 MHz and 372 MHz)
> to the list of DA850 OPPs.
>
> Not all silicon is qualified to run at higher speeds and
> unfortunately the maximum speed the chip can support can only
> be determined from the label on the package (not software
> readable).
>
> Because of this, we depend on the maximum speed grade information
> to be provided to us in some board specific way. The board informs
> the maximum speed grade information to the SoC by calling the
> da850_set_max_speed() function.
>
> Signed-off-by: Sekhar Nori <[email protected]>
> ---
> Since v3:
> Fixed pre-div and post-div for 372MHz OPP based on PLLOUT range
> limitations documented in OMAP-L138 datasheet. AM1808 datasheet
> will be updated to match this.
This series looks good, but can you (re)post one more time and Cc
the linux-arm-kernel list please?
Thanks,
Kevin
> arch/arm/mach-davinci/da850.c | 75
> ++++++++++++++++++++++------
> arch/arm/mach-davinci/include/mach/da8xx.h | 7 +++
> 2 files changed, 67 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
> index 63916b9..78b5ae2 100644
> --- a/arch/arm/mach-davinci/da850.c
> +++ b/arch/arm/mach-davinci/da850.c
> @@ -830,8 +830,7 @@ static void da850_set_async3_src(int pllnum)
> * 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.
> + * The output of the PLLM must be between 300 to 600 MHz.
> */
> struct da850_opp {
> unsigned int freq; /* in KHz */
> @@ -842,6 +841,33 @@ struct da850_opp {
> unsigned int cvdd_max; /* in uV */
> };
>
> +static const struct da850_opp da850_opp_456 = {
> + .freq = 456000,
> + .prediv = 1,
> + .mult = 19,
> + .postdiv = 1,
> + .cvdd_min = 1300000,
> + .cvdd_max = 1350000,
> +};
> +
> +static const struct da850_opp da850_opp_408 = {
> + .freq = 408000,
> + .prediv = 1,
> + .mult = 17,
> + .postdiv = 1,
> + .cvdd_min = 1300000,
> + .cvdd_max = 1350000,
> +};
> +
> +static const struct da850_opp da850_opp_372 = {
> + .freq = 372000,
> + .prediv = 2,
> + .mult = 31,
> + .postdiv = 1,
> + .cvdd_min = 1200000,
> + .cvdd_max = 1320000,
> +};
> +
> static const struct da850_opp da850_opp_300 = {
> .freq = 300000,
> .prediv = 1,
> @@ -876,6 +902,9 @@ static const struct da850_opp da850_opp_96 = {
> }
>
> static struct cpufreq_frequency_table da850_freq_table[] = {
> + OPP(456),
> + OPP(408),
> + OPP(372),
> OPP(300),
> OPP(200),
> OPP(96),
> @@ -886,6 +915,19 @@ static struct cpufreq_frequency_table da850_freq_table[]
> = {
> };
>
> #ifdef CONFIG_REGULATOR
> +static int da850_set_voltage(unsigned int index);
> +static int da850_regulator_init(void);
> +#endif
> +
> +static struct davinci_cpufreq_config cpufreq_info = {
> + .freq_table = da850_freq_table,
> +#ifdef CONFIG_REGULATOR
> + .init = da850_regulator_init,
> + .set_voltage = da850_set_voltage,
> +#endif
> +};
> +
> +#ifdef CONFIG_REGULATOR
> static struct regulator *cvdd;
>
> static int da850_set_voltage(unsigned int index)
> @@ -895,7 +937,7 @@ static int da850_set_voltage(unsigned int index)
> if (!cvdd)
> return -ENODEV;
>
> - opp = (struct da850_opp *) da850_freq_table[index].index;
> + opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
>
> return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max);
> }
> @@ -912,14 +954,6 @@ static int da850_regulator_init(void)
> }
> #endif
>
> -static struct davinci_cpufreq_config cpufreq_info = {
> - .freq_table = &da850_freq_table[0],
> -#ifdef CONFIG_REGULATOR
> - .init = da850_regulator_init,
> - .set_voltage = da850_set_voltage,
> -#endif
> -};
> -
> static struct platform_device da850_cpufreq_device = {
> .name = "cpufreq-davinci",
> .dev = {
> @@ -928,12 +962,22 @@ static struct platform_device da850_cpufreq_device = {
> .id = -1,
> };
>
> +unsigned int da850_max_speed = 300000;
> +
> int __init da850_register_cpufreq(char *async_clk)
> {
> + int i;
> +
> /* cpufreq driver can help keep an "async" clock constant */
> if (async_clk)
> clk_add_alias("async", da850_cpufreq_device.name,
> async_clk, NULL);
> + for (i = 0; i < ARRAY_SIZE(da850_freq_table); i++) {
> + if (da850_freq_table[i].frequency <= da850_max_speed) {
> + cpufreq_info.freq_table = &da850_freq_table[i];
> + break;
> + }
> + }
>
> return platform_device_register(&da850_cpufreq_device);
> }
> @@ -942,17 +986,18 @@ static int da850_round_armrate(struct clk *clk,
> unsigned long rate)
> {
> int i, ret = 0, diff;
> unsigned int best = (unsigned int) -1;
> + struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
>
> rate /= 1000; /* convert to kHz */
>
> - for (i = 0; da850_freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
> - diff = da850_freq_table[i].frequency - rate;
> + for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
> + diff = table[i].frequency - rate;
> if (diff < 0)
> diff = -diff;
>
> if (diff < best) {
> best = diff;
> - ret = da850_freq_table[i].frequency;
> + ret = table[i].frequency;
> }
> }
>
> @@ -973,7 +1018,7 @@ static int da850_set_pll0rate(struct clk *clk, unsigned
> long index)
> struct pll_data *pll = clk->pll_data;
> int ret;
>
> - opp = (struct da850_opp *) da850_freq_table[index].index;
> + opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
> prediv = opp->prediv;
> mult = opp->mult;
> postdiv = opp->postdiv;
> diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h
> b/arch/arm/mach-davinci/include/mach/da8xx.h
> index 4247b3f..e7f9520 100644
> --- a/arch/arm/mach-davinci/include/mach/da8xx.h
> +++ b/arch/arm/mach-davinci/include/mach/da8xx.h
> @@ -28,6 +28,13 @@ extern void __iomem *da8xx_syscfg0_base;
> extern void __iomem *da8xx_syscfg1_base;
>
> /*
> + * If the DA850/OMAP-L138/AM18x SoC on board is of a higher speed grade
> + * (than the regular 300Mhz variant), the board code should set this up
> + * with the supported speed before calling da850_register_cpufreq().
> + */
> +extern unsigned int da850_max_speed;
> +
> +/*
> * The cp_intc interrupt controller for the da8xx isn't in the same
> * chunk of physical memory space as the other registers (like it is
> * on the davincis) so it needs to be mapped separately. It will be
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source