From 8b1f23ef0307974737f49b237664f66f5e2c35c7 Mon Sep 17 00:00:00 2001 From: Ionela Voinescu Date: Mon, 26 Jan 2015 13:15:12 +0000 Subject: [PATCH] urara: add clock setup for MIPS CPU, ROM and Ethernet BUG=chrome-os-partner:31438 TEST=tested on Pistachio bring up board; works properly BRANCH=none Change-Id: Ie386d6af9eeba7a72b1b88d515e6cb1821569c6b Signed-off-by: Stefan Reinauer Original-Commit-Id: d4b8d8b6f965296f9ecf62da8e5f383c3667b077 Original-Change-Id: I9eb464340b0475ae735ba5573ab0841dac0d74eb Original-Signed-off-by: Ionela Voinescu Original-Reviewed-on: https://chromium-review.googlesource.com/243215 Original-Reviewed-by: David Hendricks Reviewed-on: http://review.coreboot.org/9669 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/mainboard/google/urara/bootblock.c | 14 ++++ src/soc/imgtec/pistachio/clocks.c | 75 +++++++++++++++++++ src/soc/imgtec/pistachio/include/soc/clocks.h | 8 +- 3 files changed, 94 insertions(+), 3 deletions(-) diff --git a/src/mainboard/google/urara/bootblock.c b/src/mainboard/google/urara/bootblock.c index 6d90d5932e..b21a8885f4 100644 --- a/src/mainboard/google/urara/bootblock.c +++ b/src/mainboard/google/urara/bootblock.c @@ -110,13 +110,27 @@ static int init_clocks(void) /* System PLL divided by 2 -> 400 MHz */ /* The same frequency will be the input frequency for the SPFI block */ system_clk_setup(1); + + /* MIPS CPU dividers: division by 1 -> 550 MHz + * This is set up as we cannot make any assumption about + * the values set or not by the boot ROM code */ + mips_clk_setup(0, 0); + /* System clock divided by 8 -> 50 MHz */ ret = usb_clk_setup(7, 2, 7); if (ret != CLOCKS_OK) return ret; + /* System PLL divided by 7 divided by 62 -> 1.8433 Mhz */ uart1_clk_setup(6, 61); + /* Ethernet clocks setup: ENET as clock source */ + eth_clk_setup(0, 7); + + /* ROM clock setup: system clock divided by 2 -> 200 MHz */ + /* Hash accelerator is driven from the ROM clock */ + rom_clk_setup(1); + /* Setup system PLL at 800 MHz */ ret = sys_pll_setup(2, 1); if (ret != CLOCKS_OK) diff --git a/src/soc/imgtec/pistachio/clocks.c b/src/soc/imgtec/pistachio/clocks.c index 1b7722fe74..d50abf578d 100644 --- a/src/soc/imgtec/pistachio/clocks.c +++ b/src/soc/imgtec/pistachio/clocks.c @@ -68,6 +68,12 @@ #define SYSCLKINTERNAL_CTRL_ADDR 0xB8144244 #define SYSCLKINTERNAL_MASK 0X00000007 +/* Definitions for MIPS clock setup */ +#define MIPSCLKINTERNAL_CTRL_ADDR 0xB8144204 +#define MIPSCLKINTERNAL_MASK 0x00000003 +#define MIPSCLKOUT_CTRL_ADDR 0xB8144208 +#define MIPSCLKOUT_MASK 0x000000FF + /* Definitions for USB clock setup */ #define USBPHYCLKOUT_CTRL_ADDR 0xB814422C #define USBPHYCLKOUT_MASK 0X0000003F @@ -92,6 +98,15 @@ #define UART1CLKOUT_CTRL_ADDR 0xB8144240 #define UART1CLKOUT_MASK 0x000003FF +/* Definitions for ROM clock setup */ +#define ROMCLKOUT_CTRL_ADDR 0xB814410C +#define ROMCLKOUT_MASK 0x0000007F + +/* Definitions for ETH clock setup */ +#define ENETCLKMUX_MASK 0x00004000 +#define ENETCLKDIV_CTRL_ADDR 0xB8144230 +#define ENETCLKDIV_MASK 0x0000003F + /* Definitions for timeout values */ #define PLL_TIMEOUT_VALUE_US 20000 #define USB_TIMEOUT_VALUE_US 200000 @@ -303,6 +318,27 @@ void system_clk_setup(u8 divider) udelay(SYS_CLK_LOCK_DELAY); } +void mips_clk_setup(u8 divider1, u8 divider2) +{ + u32 reg; + + /* Check input parameters */ + assert(!(divider1 & ~(MIPSCLKINTERNAL_MASK))); + assert(!(divider2 & ~(MIPSCLKOUT_MASK))); + + /* Set divider 1 */ + reg = read32(MIPSCLKINTERNAL_CTRL_ADDR); + reg &= ~MIPSCLKINTERNAL_MASK; + reg |= divider1 & MIPSCLKINTERNAL_MASK; + write32(MIPSCLKINTERNAL_CTRL_ADDR, reg); + + /* Set divider 2 */ + reg = read32(MIPSCLKOUT_CTRL_ADDR); + reg &= ~MIPSCLKOUT_MASK; + reg |= divider2 & MIPSCLKOUT_MASK; + write32(MIPSCLKOUT_CTRL_ADDR, reg); +} + /* usb_clk_setup: sets up USB clock */ int usb_clk_setup(u8 divider, u8 refclksel, u8 fsel) { @@ -352,3 +388,42 @@ int usb_clk_setup(u8 divider, u8 refclksel, u8 fsel) return CLOCKS_OK; } + +void rom_clk_setup(u8 divider) +{ + u32 reg; + + /* Check input parameter */ + assert(!(divider & ~(ROMCLKOUT_MASK))); + + /* Set ROM divider */ + reg = read32(ROMCLKOUT_CTRL_ADDR); + reg &= ~ROMCLKOUT_MASK; + reg |= divider & ROMCLKOUT_MASK; + write32(ROMCLKOUT_CTRL_ADDR, reg); +} + +void eth_clk_setup(u8 mux, u8 divider) +{ + + u32 reg; + + /* Check input parameters */ + assert(!(divider & ~(ENETCLKDIV_MASK))); + /* This can be either 0 or 1, selecting between + * ENET and system clock as clocksource */ + assert(!(mux & ~(0x1))); + + /* Set ETH divider */ + reg = read32(ENETCLKDIV_CTRL_ADDR); + reg &= ~ENETCLKDIV_MASK; + reg |= divider & ENETCLKDIV_MASK; + write32(ENETCLKDIV_CTRL_ADDR, reg); + + /* Select source */ + if (mux) { + reg = read32(PISTACHIO_CLOCK_SWITCH); + reg |= ENETCLKMUX_MASK; + write32(PISTACHIO_CLOCK_SWITCH, reg); + } +} diff --git a/src/soc/imgtec/pistachio/include/soc/clocks.h b/src/soc/imgtec/pistachio/include/soc/clocks.h index 95b35857a5..f57d43d89e 100644 --- a/src/soc/imgtec/pistachio/include/soc/clocks.h +++ b/src/soc/imgtec/pistachio/include/soc/clocks.h @@ -22,13 +22,15 @@ /* Functions for PLL setting */ int sys_pll_setup(u8 divider1, u8 divider2); -int mips_pll_setup(u8 divider1, u8 divider2i, u8 predivider, u32 feedback); +int mips_pll_setup(u8 divider1, u8 divider2, u8 predivider, u32 feedback); /* Peripheral divider setting */ -void uart1_clk_setup(u8 divider1, u16 divider2); void system_clk_setup(u8 divider); +void mips_clk_setup(u8 divider1, u8 divider2); +void uart1_clk_setup(u8 divider1, u16 divider2); int usb_clk_setup(u8 divider, u8 refclksel, u8 fsel); - +void rom_clk_setup(u8 divider); +void eth_clk_setup(u8 mux, u8 divider); enum { CLOCKS_OK = 0, PLL_TIMEOUT = -1,