summaryrefslogtreecommitdiffstats
path: root/sys/arm/at91/at91_pmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arm/at91/at91_pmc.c')
-rw-r--r--sys/arm/at91/at91_pmc.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/sys/arm/at91/at91_pmc.c b/sys/arm/at91/at91_pmc.c
index f4784fa..78d33a0 100644
--- a/sys/arm/at91/at91_pmc.c
+++ b/sys/arm/at91/at91_pmc.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <machine/frame.h>
#include <machine/intr.h>
#include <arm/at91/at91rm92reg.h>
+#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
@@ -119,20 +120,54 @@ static struct at91_pmc_clock mck = {
.refcnt = 0,
};
+#ifdef AT91SAM9G20
+#define IRQ_UDP AT91SAM9G20_IRQ_UDP
+#define IRQ_UHP AT91SAM9G20_IRQ_UHP
+#else
+#define IRQ_UDP AT91RM92_IRQ_UDP
+#define IRQ_UHP AT91RM92_IRQ_UHP
+#endif /* AT91SAM9G20 */
+
static struct at91_pmc_clock udc_clk = {
.name = "udc_clk",
.parent = &mck,
- .pmc_mask = 1 << AT91RM92_IRQ_UDP,
+ .pmc_mask = 1 << IRQ_UDP,
.set_mode = &at91_pmc_set_periph_mode
};
static struct at91_pmc_clock ohci_clk = {
.name = "ohci_clk",
.parent = &mck,
- .pmc_mask = 1 << AT91RM92_IRQ_UHP,
+ .pmc_mask = 1 << IRQ_UHP,
+ .set_mode = &at91_pmc_set_periph_mode
+};
+
+#ifdef AT91SAM9G20
+static struct at91_pmc_clock macb_clk = {
+ .name = "macb_clk",
+ .parent = &mck,
+
+ .pmc_mask = 1 << 21,
+ .set_mode = &at91_pmc_set_periph_mode
+};
+
+static struct at91_pmc_clock spi0_clk = {
+ .name = "spi0_clk",
+ .parent = &mck,
+
+ .pmc_mask = 1 << 12,
+ .set_mode = &at91_pmc_set_periph_mode
+};
+
+static struct at91_pmc_clock spi1_clk = {
+ .name = "spi1_clk",
+ .parent = &mck,
+ .pmc_mask = 1 << 13,
.set_mode = &at91_pmc_set_periph_mode
};
+#endif /* AT91SAM9G20 */
+
static struct at91_pmc_clock *const clock_list[] = {
&slck,
&main_ck,
@@ -142,6 +177,11 @@ static struct at91_pmc_clock *const clock_list[] = {
&uhpck,
&mck,
&udc_clk,
+#ifdef AT91SAM9G20
+ &macb_clk,
+ &spi0_clk,
+ &spi1_clk,
+#endif /* AT91SAM9G20 */
&ohci_clk
};
@@ -257,15 +297,24 @@ at91_pmc_pll_rate(int freq, uint32_t reg, int is_pllb)
uint32_t mul, div;
div = reg & 0xff;
+#ifdef AT91SAM9G20
+ if (is_pllb)
+ mul = (reg >> 16) & 0x3f;
+ else
+ mul = (reg >> 16) & 0xff;
+#else
mul = (reg >> 16) & 0x7ff;
+#endif
if (div != 0 && mul != 0) {
freq /= div;
freq *= mul + 1;
} else {
freq = 0;
}
+#ifndef AT91SAM9G20
if (is_pllb && (reg & (1 << 28)))
freq >>= 1;
+#endif
return (freq);
}
@@ -328,10 +377,12 @@ at91_pmc_init_clock(struct at91_pmc_softc *sc, unsigned int main_clock)
*/
sc->pllb_init = at91_pmc_pll_calc(main_clock, 48000000 * 2) |0x10000000;
pllb.hz = at91_pmc_pll_rate(main_clock, sc->pllb_init, 1);
- WR4(sc, PMC_PCDR, (1 << AT91RM92_IRQ_UHP) | (1 << AT91RM92_IRQ_UDP));
+ WR4(sc, PMC_PCDR, (1 << IRQ_UHP) | (1 << IRQ_UDP));
WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP);
WR4(sc, CKGR_PLLBR, 0);
+#ifndef AT91SAM9G20
WR4(sc, PMC_SCER, PMC_SCER_MCKUDP);
+#endif
/*
* MCK and PCU derive from one of the primary clocks. Initialize
OpenPOWER on IntegriCloud