Commit 5c6603e7 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

cpufreq: pxa3: move clk register access to clk driver



The driver needs some low-level register access for setting
the core and bus frequencies. These registers are owned
by the clk driver, so move the low-level access into that
driver with a slightly higher-level interface and avoid
any machine header file dependencies.

Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Acked-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Cc: linux-clk@vger.kernel.org
Cc: linux-pm@vger.kernel.org
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent e0a3596e
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@
 */

#include <linux/reboot.h>
#include <mach/generic.h>

struct irq_data;

+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/platform_data/i2c-pxa.h>
#include <linux/platform_data/mmp_dma.h>
#include <linux/soc/pxa/cpu.h>
#include <linux/clk/pxa.h>

#include <asm/mach/map.h>
#include <asm/suspend.h>
+16 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/of.h>
#include <linux/soc/pxa/cpu.h>
#include <mach/smemc.h>
#include <linux/clk/pxa.h>
#include <mach/pxa3xx-regs.h>

#include <dt-bindings/clock/pxa-clock.h>
@@ -79,6 +80,21 @@ unsigned int pxa3xx_get_clk_frequency_khz(int info)
	return (unsigned int)clks[0] / KHz;
}

void pxa3xx_clk_update_accr(u32 disable, u32 enable, u32 xclkcfg, u32 mask)
{
	u32 accr = ACCR;

	accr &= ~disable;
	accr |= enable;

	ACCR = accr;
	if (xclkcfg)
		__asm__("mcr p14, 0, %0, c6, c0, 0\n" : : "r"(xclkcfg));

	while ((ACSR & mask) != (accr & mask))
		cpu_relax();
}

static unsigned long clk_pxa3xx_ac97_get_rate(struct clk_hw *hw,
					     unsigned long parent_rate)
{
+0 −3
Original line number Diff line number Diff line
@@ -27,9 +27,6 @@
#include <linux/soc/pxa/cpu.h>
#include <linux/io.h>

#include <mach/pxa2xx-regs.h>
#include <mach/smemc.h>

#ifdef DEBUG
static unsigned int freq_debug;
module_param(freq_debug, uint, 0);
+36 −28
Original line number Diff line number Diff line
@@ -9,12 +9,10 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/soc/pxa/cpu.h>
#include <linux/clk/pxa.h>
#include <linux/slab.h>
#include <linux/io.h>

#include <mach/generic.h>
#include <mach/pxa3xx-regs.h>

#define HSS_104M	(0)
#define HSS_156M	(1)
#define HSS_208M	(2)
@@ -35,6 +33,28 @@
#define DMCFS_26M	(0)
#define DMCFS_260M	(3)

#define ACCR_XPDIS		(1 << 31)	/* Core PLL Output Disable */
#define ACCR_SPDIS		(1 << 30)	/* System PLL Output Disable */
#define ACCR_D0CS		(1 << 26)	/* D0 Mode Clock Select */
#define ACCR_PCCE		(1 << 11)	/* Power Mode Change Clock Enable */
#define ACCR_DDR_D0CS		(1 << 7)	/* DDR SDRAM clock frequency in D0CS (PXA31x only) */

#define ACCR_SMCFS_MASK		(0x7 << 23)	/* Static Memory Controller Frequency Select */
#define ACCR_SFLFS_MASK		(0x3 << 18)	/* Frequency Select for Internal Memory Controller */
#define ACCR_XSPCLK_MASK	(0x3 << 16)	/* Core Frequency during Frequency Change */
#define ACCR_HSS_MASK		(0x3 << 14)	/* System Bus-Clock Frequency Select */
#define ACCR_DMCFS_MASK		(0x3 << 12)	/* Dynamic Memory Controller Clock Frequency Select */
#define ACCR_XN_MASK		(0x7 << 8)	/* Core PLL Turbo-Mode-to-Run-Mode Ratio */
#define ACCR_XL_MASK		(0x1f)		/* Core PLL Run-Mode-to-Oscillator Ratio */

#define ACCR_SMCFS(x)		(((x) & 0x7) << 23)
#define ACCR_SFLFS(x)		(((x) & 0x3) << 18)
#define ACCR_XSPCLK(x)		(((x) & 0x3) << 16)
#define ACCR_HSS(x)		(((x) & 0x3) << 14)
#define ACCR_DMCFS(x)		(((x) & 0x3) << 12)
#define ACCR_XN(x)		(((x) & 0x7) << 8)
#define ACCR_XL(x)		((x) & 0x1f)

struct pxa3xx_freq_info {
	unsigned int cpufreq_mhz;
	unsigned int core_xl : 5;
@@ -112,41 +132,29 @@ static int setup_freqs_table(struct cpufreq_policy *policy,

static void __update_core_freq(struct pxa3xx_freq_info *info)
{
	uint32_t mask = ACCR_XN_MASK | ACCR_XL_MASK;
	uint32_t accr = ACCR;
	uint32_t xclkcfg;

	accr &= ~(ACCR_XN_MASK | ACCR_XL_MASK | ACCR_XSPCLK_MASK);
	accr |= ACCR_XN(info->core_xn) | ACCR_XL(info->core_xl);
	u32 mask, disable, enable, xclkcfg;

	mask	= ACCR_XN_MASK | ACCR_XL_MASK;
	disable = mask | ACCR_XSPCLK_MASK;
	enable  = ACCR_XN(info->core_xn) | ACCR_XL(info->core_xl);
	/* No clock until core PLL is re-locked */
	accr |= ACCR_XSPCLK(XSPCLK_NONE);

	enable |= ACCR_XSPCLK(XSPCLK_NONE);
	xclkcfg = (info->core_xn == 2) ? 0x3 : 0x2;	/* turbo bit */

	ACCR = accr;
	__asm__("mcr p14, 0, %0, c6, c0, 0\n" : : "r"(xclkcfg));

	while ((ACSR & mask) != (accr & mask))
		cpu_relax();
	pxa3xx_clk_update_accr(disable, enable, xclkcfg, mask);
}

static void __update_bus_freq(struct pxa3xx_freq_info *info)
{
	uint32_t mask;
	uint32_t accr = ACCR;
	u32 mask, disable, enable;

	mask	= ACCR_SMCFS_MASK | ACCR_SFLFS_MASK | ACCR_HSS_MASK |
		  ACCR_DMCFS_MASK;

	accr &= ~mask;
	accr |= ACCR_SMCFS(info->smcfs) | ACCR_SFLFS(info->sflfs) |
	disable = mask;
	enable	= ACCR_SMCFS(info->smcfs) | ACCR_SFLFS(info->sflfs) |
		  ACCR_HSS(info->hss) | ACCR_DMCFS(info->dmcfs);

	ACCR = accr;

	while ((ACSR & mask) != (accr & mask))
		cpu_relax();
	pxa3xx_clk_update_accr(disable, enable, 0, mask);
}

static unsigned int pxa3xx_cpufreq_get(unsigned int cpu)
Loading