summaryrefslogtreecommitdiff
path: root/src/soc/imgtec/pistachio/clocks.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/imgtec/pistachio/clocks.c')
-rw-r--r--src/soc/imgtec/pistachio/clocks.c513
1 files changed, 0 insertions, 513 deletions
diff --git a/src/soc/imgtec/pistachio/clocks.c b/src/soc/imgtec/pistachio/clocks.c
deleted file mode 100644
index aa54ebc43e..0000000000
--- a/src/soc/imgtec/pistachio/clocks.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2014 Imagination Technologies
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <device/mmio.h>
-#include <assert.h>
-#include <delay.h>
-#include <soc/clocks.h>
-#include <timer.h>
-
-/* Definitions for PLL enable */
-#define PISTACHIO_CLOCK_SWITCH 0xB8144200
-
-#define SYS_EXTERN_PLL_BYPASS_MASK 0x00002000
-#define SYS_PLL_CTRL4_ADDR 0xB8144048
-#define SYS_INTERNAL_PLL_BYPASS_MASK 0x10000000
-#define SYS_PLL_PD_CTRL_ADDR 0xB8144044
-#define SYS_PLL_PD_CTRL_PD_MASK 0x00000039
-#define SYS_PLL_DACPD_ADDR 0xB8144044
-#define SYS_PLL_DACPD_MASK 0x00000002
-#define SYS_PLL_DSMPD_ADDR 0xB8144044
-#define SYS_PLL_DSMPD_MASK 0x00000004
-
-#define MIPS_EXTERN_PLL_BYPASS_MASK 0x00000002
-#define MIPS_PLL_CTRL2_ADDR 0xB8144008
-#define MIPS_INTERNAL_PLL_BYPASS_MASK 0x10000000
-#define MIPS_PLL_PD_CTRL_ADDR 0xB8144004
-#define MIPS_PLL_PD_CTRL_PD_MASK 0x0D000000
-#define MIPS_PLL_DSMPD_ADDR 0xB8144004
-#define MIPS_PLL_DSMPD_MASK 0x02000000
-
-/* Definitions for PLL dividers */
-#define SYS_PLL_POSTDIV_ADDR 0xB8144040
-#define SYS_PLL_POSTDIV1_MASK 0x07000000
-#define SYS_PLL_POSTDIV1_SHIFT 24
-#define SYS_PLL_POSTDIV2_MASK 0x38000000
-#define SYS_PLL_POSTDIV2_SHIFT 27
-#define SYS_PLL_STATUS_ADDR 0xB8144038
-#define SYS_PLL_STATUS_LOCK_MASK 0x00000001
-
-#define SYS_PLL_REFDIV_ADDR 0xB814403C
-#define SYS_PLL_REFDIV_MASK 0x0000003F
-#define SYS_PLL_REFDIV_SHIFT 0
-#define SYS_PLL_FEEDBACK_ADDR 0xB814403C
-#define SYS_PLL_FEEDBACK_MASK 0x0003FFC0
-#define SYS_PLL_FEEDBACK_SHIFT 6
-
-#define MIPS_PLL_POSTDIV_ADDR 0xB8144004
-#define MIPS_PLL_POSTDIV1_MASK 0x001C0000
-#define MIPS_PLL_POSTDIV1_SHIFT 18
-#define MIPS_PLL_POSTDIV2_MASK 0x00E00000
-#define MIPS_PLL_POSTDIV2_SHIFT 21
-#define MIPS_PLL_STATUS_ADDR 0xB8144000
-#define MIPS_PLL_STATUS_LOCK_MASK 0x00000001
-
-#define MIPS_REFDIV_ADDR 0xB8144004
-#define MIPS_REFDIV_MASK 0x0000003F
-#define MIPS_REFDIV_SHIFT 0
-#define MIPS_FEEDBACK_ADDR 0xB8144004
-#define MIPS_FEEDBACK_MASK 0x0003FFC0
-#define MIPS_FEEDBACK_SHIFT 6
-
-/* Definitions for system clock setup */
-#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
-
-/* Peripheral Clock gate reg */
-#define MIPS_CLOCK_GATE_ADDR 0xB8144900
-#define RPU_CLOCK_GATE_ADDR 0xB8144904
-#define MIPS_CLOCK_GATE_ALL_ON 0x3fff
-#define RPU_CLOCK_GATE_ALL_OFF 0x0
-
-/* Definitions for USB clock setup */
-#define USBPHYCLKOUT_CTRL_ADDR 0xB814422C
-#define USBPHYCLKOUT_MASK 0X0000003F
-#define USBPHYCONTROL1_ADDR 0xB8149004
-#define USBPHYCONTROL1_FSEL_SHIFT 2
-#define USBPHYCONTROL1_FSEL_MASK 0x1C
-#define USBPHYSTRAPCTRL_ADDR 0xB8149010
-#define USBPHYSTRAPCTRL_REFCLKSEL_SHIFT 4
-#define USBPHYSTRAPCTRL_REFCLKSEL_MASK 0x30
-#define USBPHYSTATUS_ADDR 0xB8149014
-#define USBPHYSTATUS_RX_PHY_CLK_MASK 0x200
-#define USBPHYSTATUS_RX_UTMI_CLK_MASK 0x100
-#define USBPHYSTATUS_VBUS_FAULT_MASK 0x80
-
-/* Definitions for UART0/1 setup */
-#define UART0CLKINTERNAL_CTRL_ADDR 0xB8144234
-#define UART0CLKINTERNAL_MASK 0x00000007
-#define UART0CLKOUT_CTRL_ADDR 0xB8144238
-#define UART0CLKOUT_MASK 0x000003FF
-#define UART1CLKINTERNAL_CTRL_ADDR 0xB814423C
-#define UART1CLKINTERNAL_MASK 0x00000007
-#define UART1CLKOUT_CTRL_ADDR 0xB8144240
-#define UART1CLKOUT_MASK 0x000003FF
-
-/* Definitions for I2C setup */
-#define I2CCLKDIV1_CTRL_ADDR(i) (0xB8144800 + 0x013C + (2*(i)*4))
-#define I2CCLKDIV1_MASK 0x0000007F
-#define I2CCLKOUT_CTRL_ADDR(i) (0xB8144800 + 0x0140 + (2*(i)*4))
-#define I2CCLKOUT_MASK 0x0000007F
-
-/* Definitions for ROM clock setup */
-#define ROMCLKOUT_CTRL_ADDR 0xB814490C
-#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
-#define SYS_CLK_LOCK_DELAY 3
-
-struct pll_parameters {
- u32 external_bypass_mask;
- u32 ctrl_addr;
- u32 internal_bypass_mask;
- u32 power_down_ctrl_addr;
- u32 power_down_ctrl_mask;
- u32 dacpd_addr;
- u32 dacpd_mask;
- u32 dsmpd_addr;
- u32 dsmpd_mask;
- u32 postdiv_addr;
- u32 postdiv1_shift;
- u32 postdiv1_mask;
- u32 postdiv2_shift;
- u32 postdiv2_mask;
- u32 status_addr;
- u32 status_lock_mask;
- u32 refdivider;
- u32 refdiv_addr;
- u32 refdiv_shift;
- u32 refdiv_mask;
- u32 feedback;
- u32 feedback_addr;
- u32 feedback_shift;
- u32 feedback_mask;
-};
-
-enum plls {
- SYS_PLL = 0,
- MIPS_PLL = 1
-};
-
-static struct pll_parameters pll_params[] = {
- [SYS_PLL] = {
- .external_bypass_mask = SYS_EXTERN_PLL_BYPASS_MASK,
- .ctrl_addr = SYS_PLL_CTRL4_ADDR,
- .internal_bypass_mask = SYS_INTERNAL_PLL_BYPASS_MASK,
- .power_down_ctrl_addr = SYS_PLL_PD_CTRL_ADDR,
- .power_down_ctrl_mask = SYS_PLL_PD_CTRL_PD_MASK,
- /* Noise cancellation */
- .dacpd_addr = SYS_PLL_DACPD_ADDR,
- .dacpd_mask = SYS_PLL_DACPD_MASK,
- .dsmpd_addr = SYS_PLL_DSMPD_ADDR,
- /* 0 - Integer mode
- * SYS_PLL_DSMPD_MASK - Fractional mode
- */
- .dsmpd_mask = 0,
- .postdiv_addr = SYS_PLL_POSTDIV_ADDR,
- .postdiv1_shift = SYS_PLL_POSTDIV1_SHIFT,
- .postdiv1_mask = SYS_PLL_POSTDIV1_MASK,
- .postdiv2_shift = SYS_PLL_POSTDIV2_SHIFT,
- .postdiv2_mask = SYS_PLL_POSTDIV2_MASK,
- .status_addr = SYS_PLL_STATUS_ADDR,
- .status_lock_mask = SYS_PLL_STATUS_LOCK_MASK,
- .refdivider = 0, /* Not defined yet */
- .refdiv_addr = SYS_PLL_REFDIV_ADDR,
- .refdiv_shift = SYS_PLL_REFDIV_SHIFT,
- .refdiv_mask = SYS_PLL_REFDIV_MASK,
- .feedback = 0, /* Not defined yet */
- .feedback_addr = SYS_PLL_FEEDBACK_ADDR,
- .feedback_shift = SYS_PLL_FEEDBACK_SHIFT,
- .feedback_mask = SYS_PLL_FEEDBACK_MASK
- },
-
- [MIPS_PLL] = {
- .external_bypass_mask = MIPS_EXTERN_PLL_BYPASS_MASK,
- .ctrl_addr = MIPS_PLL_CTRL2_ADDR,
- .internal_bypass_mask = MIPS_INTERNAL_PLL_BYPASS_MASK,
- .power_down_ctrl_addr = MIPS_PLL_PD_CTRL_ADDR,
- .power_down_ctrl_mask = MIPS_PLL_PD_CTRL_PD_MASK,
- .dacpd_addr = 0,
- .dacpd_mask = 0,
- .dsmpd_addr = MIPS_PLL_DSMPD_ADDR,
- .dsmpd_mask = MIPS_PLL_DSMPD_MASK,
- .postdiv_addr = MIPS_PLL_POSTDIV_ADDR,
- .postdiv1_shift = MIPS_PLL_POSTDIV1_SHIFT,
- .postdiv1_mask = MIPS_PLL_POSTDIV1_MASK,
- .postdiv2_shift = MIPS_PLL_POSTDIV2_SHIFT,
- .postdiv2_mask = MIPS_PLL_POSTDIV2_MASK,
- .status_addr = MIPS_PLL_STATUS_ADDR,
- .status_lock_mask = MIPS_PLL_STATUS_LOCK_MASK,
- .refdivider = 0, /* Not defined yet */
- .refdiv_addr = MIPS_REFDIV_ADDR,
- .refdiv_shift = MIPS_REFDIV_SHIFT,
- .refdiv_mask = MIPS_REFDIV_MASK,
- .feedback = 0, /* Not defined yet */
- .feedback_addr = MIPS_FEEDBACK_ADDR,
- .feedback_shift = MIPS_FEEDBACK_SHIFT,
- .feedback_mask = MIPS_FEEDBACK_MASK
- }
-};
-
-static int pll_setup(struct pll_parameters *param, u8 divider1, u8 divider2)
-{
- u32 reg;
- struct stopwatch sw;
-
- /* Check input parameters */
- assert(!((divider1 << param->postdiv1_shift) &
- ~(param->postdiv1_mask)));
- assert(!((divider2 << param->postdiv2_shift) &
- ~(param->postdiv2_mask)));
-
- /* Temporary bypass PLL (select XTAL as clock input) */
- reg = read32_x(PISTACHIO_CLOCK_SWITCH);
- reg &= ~(param->external_bypass_mask);
- write32_x(PISTACHIO_CLOCK_SWITCH, reg);
-
- /* Un-bypass PLL's internal bypass */
- reg = read32_x(param->ctrl_addr);
- reg &= ~(param->internal_bypass_mask);
- write32_x(param->ctrl_addr, reg);
-
- /* Disable power down */
- reg = read32_x(param->power_down_ctrl_addr);
- reg &= ~(param->power_down_ctrl_mask);
- write32_x(param->power_down_ctrl_addr, reg);
-
- /* Noise cancellation */
- if (param->dacpd_addr) {
- reg = read32_x(param->dacpd_addr);
- reg &= ~(param->dacpd_mask);
- write32_x(param->dacpd_addr, reg);
- }
-
- /* Functional mode */
- if (param->dsmpd_addr) {
- reg = read32_x(param->dsmpd_addr);
- reg &= ~(param->dsmpd_mask);
- write32_x(param->dsmpd_addr, reg);
- }
-
- if (param->feedback_addr) {
- assert(!((param->feedback << param->feedback_shift) &
- ~(param->feedback_mask)));
- reg = read32_x(param->feedback_addr);
- reg &= ~(param->feedback_mask);
- reg |= (param->feedback << param->feedback_shift) &
- param->feedback_mask;
- write32_x(param->feedback_addr, reg);
- }
-
- if (param->refdiv_addr) {
- assert(!((param->refdivider << param->refdiv_shift) &
- ~(param->refdiv_mask)));
- reg = read32_x(param->refdiv_addr);
- reg &= ~(param->refdiv_mask);
- reg |= (param->refdivider << param->refdiv_shift) &
- param->refdiv_mask;
- write32_x(param->refdiv_addr, reg);
- }
-
- /* Read postdivider register value */
- reg = read32_x(param->postdiv_addr);
- /* Set divider 1 */
- reg &= ~(param->postdiv1_mask);
- reg |= (divider1 << param->postdiv1_shift) &
- param->postdiv1_mask;
- /* Set divider 2 */
- reg &= ~(param->postdiv2_mask);
- reg |= (divider2 << param->postdiv2_shift) &
- param->postdiv2_mask;
- /* Write back to register */
- write32_x(param->postdiv_addr, reg);
-
- /* Waiting for PLL to lock*/
- stopwatch_init_usecs_expire(&sw, PLL_TIMEOUT_VALUE_US);
- while (!(read32_x(param->status_addr) & param->status_lock_mask)) {
- if (stopwatch_expired(&sw))
- return PLL_TIMEOUT;
- }
-
- /* Start using PLL */
- reg = read32_x(PISTACHIO_CLOCK_SWITCH);
- reg |= param->external_bypass_mask;
- write32_x(PISTACHIO_CLOCK_SWITCH, reg);
-
- return CLOCKS_OK;
-}
-
-int sys_pll_setup(u8 divider1, u8 divider2, u8 refdivider, u32 feedback)
-{
- pll_params[SYS_PLL].refdivider = refdivider;
- pll_params[SYS_PLL].feedback = feedback;
- return pll_setup(&(pll_params[SYS_PLL]), divider1, divider2);
-}
-
-int mips_pll_setup(u8 divider1, u8 divider2, u8 refdivider, u32 feedback)
-{
- pll_params[MIPS_PLL].refdivider = refdivider;
- pll_params[MIPS_PLL].feedback = feedback;
- return pll_setup(&(pll_params[MIPS_PLL]), divider1, divider2);
-}
-
-/*
- * uart1_clk_setup: sets up clocks for UART1
- * divider1: 3-bit divider value
- * divider2: 10-bit divider value
- */
-void uart1_clk_setup(u8 divider1, u16 divider2)
-{
- u32 reg;
-
- /* Check input parameters */
- assert(!(divider1 & ~(UART1CLKINTERNAL_MASK)));
- assert(!(divider2 & ~(UART1CLKOUT_MASK)));
-
- /* Set divider 1 */
- reg = read32_x(UART1CLKINTERNAL_CTRL_ADDR);
- reg &= ~UART1CLKINTERNAL_MASK;
- reg |= divider1 & UART1CLKINTERNAL_MASK;
- write32_x(UART1CLKINTERNAL_CTRL_ADDR, reg);
-
- /* Set divider 2 */
- reg = read32_x(UART1CLKOUT_CTRL_ADDR);
- reg &= ~UART1CLKOUT_MASK;
- reg |= divider2 & UART1CLKOUT_MASK;
- write32_x(UART1CLKOUT_CTRL_ADDR, reg);
-}
-
-/*
- * i2c_clk_setup: sets up clocks for I2C
- * divider1: 7-bit divider value
- * divider2: 7-bit divider value
- */
-void i2c_clk_setup(u8 divider1, u16 divider2, u8 interface)
-{
- u32 reg;
-
- /* Check input parameters */
- assert(!(divider1 & ~(I2CCLKDIV1_MASK)));
- assert(!(divider2 & ~(I2CCLKOUT_MASK)));
- assert(interface < 4);
- /* Set divider 1 */
- reg = read32_x(I2CCLKDIV1_CTRL_ADDR(interface));
- reg &= ~I2CCLKDIV1_MASK;
- reg |= divider1 & I2CCLKDIV1_MASK;
- write32_x(I2CCLKDIV1_CTRL_ADDR(interface), reg);
-
- /* Set divider 2 */
- reg = read32_x(I2CCLKOUT_CTRL_ADDR(interface));
- reg &= ~I2CCLKOUT_MASK;
- reg |= divider2 & I2CCLKOUT_MASK;
- write32_x(I2CCLKOUT_CTRL_ADDR(interface), reg);
-}
-
-/* system_clk_setup: sets up the system (peripheral) clock */
-void system_clk_setup(u8 divider)
-{
- u32 reg;
-
- /* Check input parameters */
- assert(!(divider & ~(SYSCLKINTERNAL_MASK)));
-
- /* Set system clock divider */
- reg = read32_x(SYSCLKINTERNAL_CTRL_ADDR);
- reg &= ~SYSCLKINTERNAL_MASK;
- reg |= divider & SYSCLKINTERNAL_MASK;
- write32_x(SYSCLKINTERNAL_CTRL_ADDR, reg);
-
- /* Small delay to cover a maximum lock time of 1500 cycles */
- 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_x(MIPSCLKINTERNAL_CTRL_ADDR);
- reg &= ~MIPSCLKINTERNAL_MASK;
- reg |= divider1 & MIPSCLKINTERNAL_MASK;
- write32_x(MIPSCLKINTERNAL_CTRL_ADDR, reg);
-
- /* Set divider 2 */
- reg = read32_x(MIPSCLKOUT_CTRL_ADDR);
- reg &= ~MIPSCLKOUT_MASK;
- reg |= divider2 & MIPSCLKOUT_MASK;
- write32_x(MIPSCLKOUT_CTRL_ADDR, reg);
-}
-
-/* usb_clk_setup: sets up USB clock */
-int usb_clk_setup(u8 divider, u8 refclksel, u8 fsel)
-{
- u32 reg;
- struct stopwatch sw;
-
- /* Check input parameters */
- assert(!(divider & ~(USBPHYCLKOUT_MASK)));
- assert(!((refclksel << USBPHYSTRAPCTRL_REFCLKSEL_SHIFT) &
- ~(USBPHYSTRAPCTRL_REFCLKSEL_MASK)));
- assert(!((fsel << USBPHYCONTROL1_FSEL_SHIFT) &
- ~(USBPHYCONTROL1_FSEL_MASK)));
-
- /* Set USB divider */
- reg = read32_x(USBPHYCLKOUT_CTRL_ADDR);
- reg &= ~USBPHYCLKOUT_MASK;
- reg |= divider & USBPHYCLKOUT_MASK;
- write32_x(USBPHYCLKOUT_CTRL_ADDR, reg);
-
- /* Set REFCLKSEL */
- reg = read32_x(USBPHYSTRAPCTRL_ADDR);
- reg &= ~USBPHYSTRAPCTRL_REFCLKSEL_MASK;
- reg |= (refclksel << USBPHYSTRAPCTRL_REFCLKSEL_SHIFT) &
- USBPHYSTRAPCTRL_REFCLKSEL_MASK;
- write32_x(USBPHYSTRAPCTRL_ADDR, reg);
-
- /* Set FSEL */
- reg = read32_x(USBPHYCONTROL1_ADDR);
- reg &= ~USBPHYCONTROL1_FSEL_MASK;
- reg |= (fsel << USBPHYCONTROL1_FSEL_SHIFT) &
- USBPHYCONTROL1_FSEL_MASK;
- write32_x(USBPHYCONTROL1_ADDR, reg);
-
- /* Waiting for USB clock status */
- stopwatch_init_usecs_expire(&sw, USB_TIMEOUT_VALUE_US);
- while (1) {
- reg = read32_x(USBPHYSTATUS_ADDR);
- if (reg & USBPHYSTATUS_VBUS_FAULT_MASK)
- return USB_VBUS_FAULT;
- if (stopwatch_expired(&sw))
- return USB_TIMEOUT;
- /* Check if USB is set up properly */
- if ((reg & USBPHYSTATUS_RX_PHY_CLK_MASK) &&
- (reg & USBPHYSTATUS_RX_UTMI_CLK_MASK))
- break;
- }
-
- return CLOCKS_OK;
-}
-
-void rom_clk_setup(u8 divider)
-{
- u32 reg;
-
- /* Check input parameter */
- assert(!(divider & ~(ROMCLKOUT_MASK)));
-
- /* Set ROM divider */
- reg = read32_x(ROMCLKOUT_CTRL_ADDR);
- reg &= ~ROMCLKOUT_MASK;
- reg |= divider & ROMCLKOUT_MASK;
- write32_x(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_x(ENETCLKDIV_CTRL_ADDR);
- reg &= ~ENETCLKDIV_MASK;
- reg |= divider & ENETCLKDIV_MASK;
- write32_x(ENETCLKDIV_CTRL_ADDR, reg);
-
- /* Select source */
- if (mux) {
- reg = read32_x(PISTACHIO_CLOCK_SWITCH);
- reg |= ENETCLKMUX_MASK;
- write32_x(PISTACHIO_CLOCK_SWITCH, reg);
- }
-}
-
-void setup_clk_gate_defaults(void)
-{
- write32_x(MIPS_CLOCK_GATE_ADDR, MIPS_CLOCK_GATE_ALL_ON);
- write32_x(RPU_CLOCK_GATE_ADDR, RPU_CLOCK_GATE_ALL_OFF);
-}