Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b5514952 authored by Jean-Christophe PLAGNIOL-VILLARD's avatar Jean-Christophe PLAGNIOL-VILLARD Committed by Nicolas Ferre
Browse files

ARM: at91/PMC: make register base soc independent

parent 940192e3
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -295,7 +295,7 @@ static void at91rm9200_idle(void)
	 * Disable the processor clock.  The processor will be automatically
	 * re-enabled by an interrupt or by a reset.
	 */
	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
	at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
}

static void at91rm9200_restart(char mode, const char *cmd)
+40 −35
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include "clock.h"
#include "generic.h"

void __iomem *at91_pmc_base;

/*
 * There's a lot more which can be done with clocks, including cpufreq
@@ -125,11 +126,11 @@ static void pllb_mode(struct clk *clk, int is_on)
		value = 0;

	// REVISIT: Add work-around for AT91RM9200 Errata #26 ?
	at91_sys_write(AT91_CKGR_PLLBR, value);
	at91_pmc_write(AT91_CKGR_PLLBR, value);

	do {
		cpu_relax();
	} while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on);
	} while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on);
}

static struct clk pllb = {
@@ -144,24 +145,24 @@ static struct clk pllb = {
static void pmc_sys_mode(struct clk *clk, int is_on)
{
	if (is_on)
		at91_sys_write(AT91_PMC_SCER, clk->pmc_mask);
		at91_pmc_write(AT91_PMC_SCER, clk->pmc_mask);
	else
		at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask);
		at91_pmc_write(AT91_PMC_SCDR, clk->pmc_mask);
}

static void pmc_uckr_mode(struct clk *clk, int is_on)
{
	unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
	unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);

	if (is_on) {
		is_on = AT91_PMC_LOCKU;
		at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
		at91_pmc_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
	} else
		at91_sys_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask));
		at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask));

	do {
		cpu_relax();
	} while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on);
	} while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on);
}

/* USB function clocks (PLLB must be 48 MHz) */
@@ -197,9 +198,9 @@ struct clk mck = {
static void pmc_periph_mode(struct clk *clk, int is_on)
{
	if (is_on)
		at91_sys_write(AT91_PMC_PCER, clk->pmc_mask);
		at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask);
	else
		at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask);
		at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask);
}

static struct clk __init *at91_css_to_clk(unsigned long css)
@@ -359,10 +360,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
		if (actual && actual <= rate) {
			u32	pckr;

			pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
			pckr = at91_pmc_read(AT91_PMC_PCKR(clk->id));
			pckr &= css_mask;	/* keep clock selection */
			pckr |= prescale << prescale_offset;
			at91_sys_write(AT91_PMC_PCKR(clk->id), pckr);
			at91_pmc_write(AT91_PMC_PCKR(clk->id), pckr);
			clk->rate_hz = actual;
			break;
		}
@@ -396,7 +397,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)

	clk->rate_hz = parent->rate_hz;
	clk->parent = parent;
	at91_sys_write(AT91_PMC_PCKR(clk->id), parent->id);
	at91_pmc_write(AT91_PMC_PCKR(clk->id), parent->id);

	spin_unlock_irqrestore(&clk_lock, flags);
	return 0;
@@ -415,7 +416,7 @@ static void __init init_programmable_clock(struct clk *clk)
	else
		css_mask = AT91_PMC_CSS;

	pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
	pckr = at91_pmc_read(AT91_PMC_PCKR(clk->id));
	parent = at91_css_to_clk(pckr & css_mask);
	clk->parent = parent;
	clk->rate_hz = parent->rate_hz / pmc_prescaler_divider(pckr);
@@ -432,23 +433,23 @@ static int at91_clk_show(struct seq_file *s, void *unused)
	u32		scsr, pcsr, uckr = 0, sr;
	struct clk	*clk;

	scsr = at91_sys_read(AT91_PMC_SCSR);
	pcsr = at91_sys_read(AT91_PMC_PCSR);
	sr = at91_sys_read(AT91_PMC_SR);
	scsr = at91_pmc_read(AT91_PMC_SCSR);
	pcsr = at91_pmc_read(AT91_PMC_PCSR);
	sr = at91_pmc_read(AT91_PMC_SR);
	seq_printf(s, "SCSR = %8x\n", scsr);
	seq_printf(s, "PCSR = %8x\n", pcsr);
	seq_printf(s, "MOR  = %8x\n", at91_sys_read(AT91_CKGR_MOR));
	seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR));
	seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR));
	seq_printf(s, "MOR  = %8x\n", at91_pmc_read(AT91_CKGR_MOR));
	seq_printf(s, "MCFR = %8x\n", at91_pmc_read(AT91_CKGR_MCFR));
	seq_printf(s, "PLLA = %8x\n", at91_pmc_read(AT91_CKGR_PLLAR));
	if (cpu_has_pllb())
		seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR));
		seq_printf(s, "PLLB = %8x\n", at91_pmc_read(AT91_CKGR_PLLBR));
	if (cpu_has_utmi()) {
		uckr = at91_sys_read(AT91_CKGR_UCKR);
		uckr = at91_pmc_read(AT91_CKGR_UCKR);
		seq_printf(s, "UCKR = %8x\n", uckr);
	}
	seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR));
	seq_printf(s, "MCKR = %8x\n", at91_pmc_read(AT91_PMC_MCKR));
	if (cpu_has_upll())
		seq_printf(s, "USB  = %8x\n", at91_sys_read(AT91_PMC_USB));
		seq_printf(s, "USB  = %8x\n", at91_pmc_read(AT91_PMC_USB));
	seq_printf(s, "SR   = %8x\n", sr);

	seq_printf(s, "\n");
@@ -637,14 +638,14 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
	if (cpu_is_at91rm9200()) {
		uhpck.pmc_mask = AT91RM9200_PMC_UHP;
		udpck.pmc_mask = AT91RM9200_PMC_UDP;
		at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
		at91_pmc_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
		   cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
		   cpu_is_at91sam9g10()) {
		uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
	}
	at91_sys_write(AT91_CKGR_PLLBR, 0);
	at91_pmc_write(AT91_CKGR_PLLBR, 0);

	udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
	uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
@@ -661,13 +662,13 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
	/* Setup divider by 10 to reach 48 MHz */
	usbr |= ((10 - 1) << 8) & AT91_PMC_OHCIUSBDIV;

	at91_sys_write(AT91_PMC_USB, usbr);
	at91_pmc_write(AT91_PMC_USB, usbr);

	/* Now set uhpck values */
	uhpck.parent = &utmi_clk;
	uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
	uhpck.rate_hz = utmi_clk.rate_hz;
	uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
	uhpck.rate_hz /= 1 + ((at91_pmc_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
}

int __init at91_clock_init(unsigned long main_clock)
@@ -676,6 +677,10 @@ int __init at91_clock_init(unsigned long main_clock)
	int i;
	int pll_overclock = false;

	at91_pmc_base = ioremap(AT91_PMC, 256);
	if (!at91_pmc_base)
		panic("Impossible to ioremap AT91_PMC 0x%x\n", AT91_PMC);

	/*
	 * When the bootloader initialized the main oscillator correctly,
	 * there's no problem using the cycle counter.  But if it didn't,
@@ -684,14 +689,14 @@ int __init at91_clock_init(unsigned long main_clock)
	 */
	if (!main_clock) {
		do {
			tmp = at91_sys_read(AT91_CKGR_MCFR);
			tmp = at91_pmc_read(AT91_CKGR_MCFR);
		} while (!(tmp & AT91_PMC_MAINRDY));
		main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16);
	}
	main_clk.rate_hz = main_clock;

	/* report if PLLA is more than mildly overclocked */
	plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
	plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_pmc_read(AT91_CKGR_PLLAR));
	if (cpu_has_300M_plla()) {
		if (plla.rate_hz > 300000000)
			pll_overclock = true;
@@ -706,7 +711,7 @@ int __init at91_clock_init(unsigned long main_clock)
		pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);

	if (cpu_has_plladiv2()) {
		mckr = at91_sys_read(AT91_PMC_MCKR);
		mckr = at91_pmc_read(AT91_PMC_MCKR);
		plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12));	/* plla divisor by 2 */
	}

@@ -746,7 +751,7 @@ int __init at91_clock_init(unsigned long main_clock)
	 * MCK and CPU derive from one of those primary clocks.
	 * For now, assume this parentage won't change.
	 */
	mckr = at91_sys_read(AT91_PMC_MCKR);
	mckr = at91_pmc_read(AT91_PMC_MCKR);
	mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
	freq = mck.parent->rate_hz;
	freq /= pmc_prescaler_divider(mckr);					/* prescale */
@@ -819,8 +824,8 @@ static int __init at91_clock_reset(void)
		pr_debug("Clocks: disable unused %s\n", clk->name);
	}

	at91_sys_write(AT91_PMC_PCDR, pcdr);
	at91_sys_write(AT91_PMC_SCDR, scdr);
	at91_pmc_write(AT91_PMC_PCDR, pcdr);
	at91_pmc_write(AT91_PMC_SCDR, scdr);

	return 0;
}
@@ -828,6 +833,6 @@ late_initcall(at91_clock_reset);

void at91sam9_idle(void)
{
	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
	at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
	cpu_do_idle();
}
+34 −22
Original line number Diff line number Diff line
@@ -16,10 +16,22 @@
#ifndef AT91_PMC_H
#define AT91_PMC_H

#define	AT91_PMC_SCER		(AT91_PMC + 0x00)	/* System Clock Enable Register */
#define	AT91_PMC_SCDR		(AT91_PMC + 0x04)	/* System Clock Disable Register */
#ifndef __ASSEMBLY__
extern void __iomem *at91_pmc_base;

#define	AT91_PMC_SCSR		(AT91_PMC + 0x08)	/* System Clock Status Register */
#define at91_pmc_read(field) \
	__raw_readl(at91_pmc_base + field)

#define at91_pmc_write(field, value) \
	__raw_writel(value, at91_pmc_base + field)
#else
.extern at91_aic_base
#endif

#define	AT91_PMC_SCER		0x00			/* System Clock Enable Register */
#define	AT91_PMC_SCDR		0x04			/* System Clock Disable Register */

#define	AT91_PMC_SCSR		0x08			/* System Clock Status Register */
#define		AT91_PMC_PCK		(1 <<  0)		/* Processor Clock */
#define		AT91RM9200_PMC_UDP	(1 <<  1)		/* USB Devcice Port Clock [AT91RM9200 only] */
#define		AT91RM9200_PMC_MCKUDP	(1 <<  2)		/* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */
@@ -34,17 +46,17 @@
#define		AT91_PMC_HCK0		(1 << 16)		/* AHB Clock (USB host) [AT91SAM9261 only] */
#define		AT91_PMC_HCK1		(1 << 17)		/* AHB Clock (LCD) [AT91SAM9261 only] */

#define	AT91_PMC_PCER		(AT91_PMC + 0x10)	/* Peripheral Clock Enable Register */
#define	AT91_PMC_PCDR		(AT91_PMC + 0x14)	/* Peripheral Clock Disable Register */
#define	AT91_PMC_PCSR		(AT91_PMC + 0x18)	/* Peripheral Clock Status Register */
#define	AT91_PMC_PCER		0x10			/* Peripheral Clock Enable Register */
#define	AT91_PMC_PCDR		0x14			/* Peripheral Clock Disable Register */
#define	AT91_PMC_PCSR		0x18			/* Peripheral Clock Status Register */

#define	AT91_CKGR_UCKR		(AT91_PMC + 0x1C)	/* UTMI Clock Register [some SAM9] */
#define	AT91_CKGR_UCKR		0x1C			/* UTMI Clock Register [some SAM9] */
#define		AT91_PMC_UPLLEN		(1   << 16)		/* UTMI PLL Enable */
#define		AT91_PMC_UPLLCOUNT	(0xf << 20)		/* UTMI PLL Start-up Time */
#define		AT91_PMC_BIASEN		(1   << 24)		/* UTMI BIAS Enable */
#define		AT91_PMC_BIASCOUNT	(0xf << 28)		/* UTMI BIAS Start-up Time */

#define	AT91_CKGR_MOR		(AT91_PMC + 0x20)	/* Main Oscillator Register [not on SAM9RL] */
#define	AT91_CKGR_MOR		0x20			/* Main Oscillator Register [not on SAM9RL] */
#define		AT91_PMC_MOSCEN		(1    <<  0)		/* Main Oscillator Enable */
#define		AT91_PMC_OSCBYPASS	(1    <<  1)		/* Oscillator Bypass */
#define		AT91_PMC_MOSCRCEN	(1    <<  3)		/* Main On-Chip RC Oscillator Enable [some SAM9] */
@@ -53,12 +65,12 @@
#define		AT91_PMC_MOSCSEL	(1    << 24)		/* Main Oscillator Selection [some SAM9] */
#define		AT91_PMC_CFDEN		(1    << 25)		/* Clock Failure Detector Enable [some SAM9] */

#define	AT91_CKGR_MCFR		(AT91_PMC + 0x24)	/* Main Clock Frequency Register */
#define	AT91_CKGR_MCFR		0x24			/* Main Clock Frequency Register */
#define		AT91_PMC_MAINF		(0xffff <<  0)		/* Main Clock Frequency */
#define		AT91_PMC_MAINRDY	(1	<< 16)		/* Main Clock Ready */

#define	AT91_CKGR_PLLAR		(AT91_PMC + 0x28)	/* PLL A Register */
#define	AT91_CKGR_PLLBR		(AT91_PMC + 0x2c)	/* PLL B Register */
#define	AT91_CKGR_PLLAR		0x28			/* PLL A Register */
#define	AT91_CKGR_PLLBR		0x2c			/* PLL B Register */
#define		AT91_PMC_DIV		(0xff  <<  0)		/* Divider */
#define		AT91_PMC_PLLCOUNT	(0x3f  <<  8)		/* PLL Counter */
#define		AT91_PMC_OUT		(3     << 14)		/* PLL Clock Frequency Range */
@@ -69,7 +81,7 @@
#define			AT91_PMC_USBDIV_4		(2 << 28)
#define		AT91_PMC_USB96M		(1     << 28)		/* Divider by 2 Enable (PLLB only) */

#define	AT91_PMC_MCKR		(AT91_PMC + 0x30)	/* Master Clock Register */
#define	AT91_PMC_MCKR		0x30			/* Master Clock Register */
#define		AT91_PMC_CSS		(3 <<  0)		/* Master Clock Selection */
#define			AT91_PMC_CSS_SLOW		(0 << 0)
#define			AT91_PMC_CSS_MAIN		(1 << 0)
@@ -111,27 +123,27 @@
#define			AT91_PMC_PLLADIV2_OFF		(0 << 12)
#define			AT91_PMC_PLLADIV2_ON		(1 << 12)

#define	AT91_PMC_USB		(AT91_PMC + 0x38)	/* USB Clock Register [some SAM9 only] */
#define	AT91_PMC_USB		0x38			/* USB Clock Register [some SAM9 only] */
#define		AT91_PMC_USBS		(0x1 <<  0)		/* USB OHCI Input clock selection */
#define			AT91_PMC_USBS_PLLA		(0 << 0)
#define			AT91_PMC_USBS_UPLL		(1 << 0)
#define		AT91_PMC_OHCIUSBDIV	(0xF <<  8)		/* Divider for USB OHCI Clock */

#define	AT91_PMC_SMD		(AT91_PMC + 0x3c)	/* Soft Modem Clock Register [some SAM9 only] */
#define	AT91_PMC_SMD		0x3c			/* Soft Modem Clock Register [some SAM9 only] */
#define		AT91_PMC_SMDS		(0x1  <<  0)		/* SMD input clock selection */
#define		AT91_PMC_SMD_DIV	(0x1f <<  8)		/* SMD input clock divider */
#define		AT91_PMC_SMDDIV(n)	(((n) <<  8) & AT91_PMC_SMD_DIV)

#define	AT91_PMC_PCKR(n)	(AT91_PMC + 0x40 + ((n) * 4))	/* Programmable Clock 0-N Registers */
#define	AT91_PMC_PCKR(n)	(0x40 + ((n) * 4))	/* Programmable Clock 0-N Registers */
#define		AT91_PMC_ALT_PCKR_CSS	(0x7 <<  0)		/* Programmable Clock Source Selection [alternate length] */
#define			AT91_PMC_CSS_MASTER		(4 << 0)	/* [some SAM9 only] */
#define		AT91_PMC_CSSMCK		(0x1 <<  8)		/* CSS or Master Clock Selection */
#define			AT91_PMC_CSSMCK_CSS		(0 << 8)
#define			AT91_PMC_CSSMCK_MCK		(1 << 8)

#define	AT91_PMC_IER		(AT91_PMC + 0x60)	/* Interrupt Enable Register */
#define	AT91_PMC_IDR		(AT91_PMC + 0x64)	/* Interrupt Disable Register */
#define	AT91_PMC_SR		(AT91_PMC + 0x68)	/* Status Register */
#define	AT91_PMC_IER		0x60			/* Interrupt Enable Register */
#define	AT91_PMC_IDR		0x64			/* Interrupt Disable Register */
#define	AT91_PMC_SR		0x68			/* Status Register */
#define		AT91_PMC_MOSCS		(1 <<  0)		/* MOSCS Flag */
#define		AT91_PMC_LOCKA		(1 <<  1)		/* PLLA Lock */
#define		AT91_PMC_LOCKB		(1 <<  2)		/* PLLB Lock */
@@ -144,18 +156,18 @@
#define		AT91_PMC_MOSCSELS	(1 << 16)		/* Main Oscillator Selection [some SAM9] */
#define		AT91_PMC_MOSCRCS	(1 << 17)		/* Main On-Chip RC [some SAM9] */
#define		AT91_PMC_CFDEV		(1 << 18)		/* Clock Failure Detector Event [some SAM9] */
#define	AT91_PMC_IMR		(AT91_PMC + 0x6c)	/* Interrupt Mask Register */
#define	AT91_PMC_IMR		0x6c			/* Interrupt Mask Register */

#define AT91_PMC_PROT		(AT91_PMC + 0xe4)	/* Write Protect Mode Register [some SAM9] */
#define AT91_PMC_PROT		0xe4			/* Write Protect Mode Register [some SAM9] */
#define		AT91_PMC_WPEN		(0x1  <<  0)		/* Write Protect Enable */
#define		AT91_PMC_WPKEY		(0xffffff << 8)		/* Write Protect Key */
#define		AT91_PMC_PROTKEY	(0x504d43 << 8)		/* Activation Code */

#define AT91_PMC_WPSR		(AT91_PMC + 0xe8)	/* Write Protect Status Register [some SAM9] */
#define AT91_PMC_WPSR		0xe8			/* Write Protect Status Register [some SAM9] */
#define		AT91_PMC_WPVS		(0x1  <<  0)		/* Write Protect Violation Status */
#define		AT91_PMC_WPVSRC		(0xffff  <<  8)		/* Write Protect Violation Source */

#define AT91_PMC_PCR		(AT91_PMC + 0x10c)	/* Peripheral Control Register [some SAM9] */
#define AT91_PMC_PCR		0x10c			/* Peripheral Control Register [some SAM9] */
#define		AT91_PMC_PCR_PID	(0x3f  <<  0)		/* Peripheral ID */
#define		AT91_PMC_PCR_CMD	(0x1  <<  12)		/* Command */
#define		AT91_PMC_PCR_DIV	(0x3  <<  16)		/* Divisor Value */
+1 −3
Original line number Diff line number Diff line
@@ -77,10 +77,8 @@


/*
 * System Peripherals (offset from AT91_BASE_SYS)
 * System Peripherals
 */
#define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)	/* Power Management Controller */

#define AT91RM9200_BASE_DBGU	AT91_BASE_DBGU0	/* Debug Unit */
#define AT91RM9200_BASE_PIOA	0xfffff400	/* PIO Controller A */
#define AT91RM9200_BASE_PIOB	0xfffff600	/* PIO Controller B */
+0 −1
Original line number Diff line number Diff line
@@ -80,7 +80,6 @@
/*
 * System Peripherals (offset from AT91_BASE_SYS)
 */
#define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
#define AT91_GPBR	(0xfffffd50 - AT91_BASE_SYS)

#define AT91SAM9260_BASE_ECC	0xffffe800
Loading