Patrick Georgi | 7051707 | 2020-05-10 18:47:05 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: BSD-3-Clause */ |
Varadarajan Narayanan | a6935c2 | 2016-03-02 16:57:10 +0530 | [diff] [blame] | 2 | |
Kyösti Mälkki | 13f6650 | 2019-03-03 08:01:05 +0200 | [diff] [blame] | 3 | #include <device/mmio.h> |
Varadarajan Narayanan | a6935c2 | 2016-03-02 16:57:10 +0530 | [diff] [blame] | 4 | #include <delay.h> |
Varadarajan Narayanan | 2596764 | 2016-03-08 15:02:56 +0530 | [diff] [blame] | 5 | #include <soc/blsp.h> |
Varadarajan Narayanan | a6935c2 | 2016-03-02 16:57:10 +0530 | [diff] [blame] | 6 | #include <soc/clock.h> |
| 7 | #include <types.h> |
Varadarajan Narayanan | 2596764 | 2016-03-08 15:02:56 +0530 | [diff] [blame] | 8 | #include <console/console.h> |
Varadarajan Narayanan | a6935c2 | 2016-03-02 16:57:10 +0530 | [diff] [blame] | 9 | |
Varadarajan Narayanan | 9541ba8 | 2016-03-03 13:30:07 +0530 | [diff] [blame] | 10 | #define CLOCK_UPDATE_DELAY 1000 |
Varadarajan Narayanan | a6935c2 | 2016-03-02 16:57:10 +0530 | [diff] [blame] | 11 | |
| 12 | /** |
| 13 | * uart_clock_config - configures UART clocks |
| 14 | * |
| 15 | * Configures GSBI UART dividers, enable root and branch clocks. |
| 16 | */ |
Varadarajan Narayanan | 9541ba8 | 2016-03-03 13:30:07 +0530 | [diff] [blame] | 17 | void uart_clock_config(unsigned int blsp_uart, unsigned int m, |
| 18 | unsigned int n, unsigned int d) |
Varadarajan Narayanan | a6935c2 | 2016-03-02 16:57:10 +0530 | [diff] [blame] | 19 | { |
Varadarajan Narayanan | 9541ba8 | 2016-03-03 13:30:07 +0530 | [diff] [blame] | 20 | int i; |
| 21 | |
| 22 | /* Setup M, N & D */ |
| 23 | write32(GCC_BLSP1_UART_APPS_M(blsp_uart), m); |
| 24 | write32(GCC_BLSP1_UART_APPS_N(blsp_uart), ~(n - m)); |
| 25 | write32(GCC_BLSP1_UART_APPS_D(blsp_uart), ~d); |
| 26 | write32(GCC_BLSP1_UART_MISC(blsp_uart), 0); |
| 27 | |
| 28 | /* Setup source sel etc. */ |
| 29 | write32(GCC_BLSP1_UART_APPS_CFG_RCGR(blsp_uart), |
| 30 | 0 | /* 0: 4 SRC_DIV = Bypass */ |
| 31 | 0 << 8 | /* 8:10 SRC_SEL = CxO */ |
| 32 | 2 << 12); /* 13:12 Mode = Dual Edge */ |
| 33 | |
| 34 | /* Trigger update */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 35 | setbits32(GCC_BLSP1_UART_APPS_CMD_RCGR(blsp_uart), 1); |
Varadarajan Narayanan | 9541ba8 | 2016-03-03 13:30:07 +0530 | [diff] [blame] | 36 | |
| 37 | /* Wait for update */ |
| 38 | for (i = 0; i < CLOCK_UPDATE_DELAY; i++) { |
| 39 | if (!(read32(GCC_BLSP1_UART_APPS_CMD_RCGR(blsp_uart)) & 1)) { |
| 40 | /* Updated */ |
| 41 | break; |
| 42 | } |
| 43 | udelay(1); |
| 44 | } |
| 45 | |
Varadarajan Narayanan | 2596764 | 2016-03-08 15:02:56 +0530 | [diff] [blame] | 46 | /* Please refer to the comments in blsp_i2c_clock_config() */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 47 | setbits32(GCC_CLK_BRANCH_ENA, BLSP1_AHB | BLSP1_SLEEP); |
Varadarajan Narayanan | a6935c2 | 2016-03-02 16:57:10 +0530 | [diff] [blame] | 48 | } |
| 49 | |
| 50 | /** |
| 51 | * nand_clock_config - configure NAND controller clocks |
| 52 | * |
| 53 | * Enable clocks to EBI2. Must be invoked before touching EBI2 |
| 54 | * registers. |
| 55 | */ |
| 56 | void nand_clock_config(void) |
| 57 | { |
| 58 | write32(EBI2_CLK_CTL_REG, |
| 59 | CLK_BRANCH_ENA(1) | ALWAYS_ON_CLK_BRANCH_ENA(1)); |
| 60 | |
| 61 | /* Wait for clock to stabilize. */ |
| 62 | udelay(10); |
| 63 | } |
| 64 | |
| 65 | /** |
| 66 | * usb_clock_config - configure USB controller clocks and reset the controller |
| 67 | */ |
| 68 | void usb_clock_config(void) |
| 69 | { |
| 70 | /* Magic clock initialization numbers, nobody knows how they work... */ |
| 71 | write32(USB30_MASTER_CLK_CTL_REG, 0x10); |
| 72 | write32(USB30_1_MASTER_CLK_CTL_REG, 0x10); |
| 73 | write32(USB30_MASTER_CLK_MD, 0x500DF); |
| 74 | write32(USB30_MASTER_CLK_NS, 0xE40942); |
| 75 | write32(USB30_MOC_UTMI_CLK_MD, 0x100D7); |
| 76 | write32(USB30_MOC_UTMI_CLK_NS, 0xD80942); |
| 77 | write32(USB30_MOC_UTMI_CLK_CTL, 0x10); |
| 78 | write32(USB30_1_MOC_UTMI_CLK_CTL, 0x10); |
| 79 | |
| 80 | write32(USB30_RESET, |
| 81 | 1 << 5 | /* assert port2 HS PHY async reset */ |
| 82 | 1 << 4 | /* assert master async reset */ |
| 83 | 1 << 3 | /* assert sleep async reset */ |
| 84 | 1 << 2 | /* assert MOC UTMI async reset */ |
| 85 | 1 << 1 | /* assert power-on async reset */ |
| 86 | 1 << 0); /* assert PHY async reset */ |
| 87 | udelay(5); |
| 88 | write32(USB30_RESET, 0); /* deassert all USB resets again */ |
| 89 | } |
Varadarajan Narayanan | 2596764 | 2016-03-08 15:02:56 +0530 | [diff] [blame] | 90 | |
| 91 | int blsp_i2c_clock_config(blsp_qup_id_t id) |
| 92 | { |
| 93 | int i; |
| 94 | const int max_tries = 200; |
| 95 | struct { void *cbcr, *cmd, *cfg; } clk[] = { |
| 96 | { |
| 97 | GCC_BLSP1_QUP1_I2C_APPS_CBCR, |
| 98 | GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR, |
| 99 | GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR, |
| 100 | }, |
| 101 | { |
| 102 | GCC_BLSP1_QUP1_I2C_APPS_CBCR, |
| 103 | GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR, |
| 104 | GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR, |
| 105 | }, |
| 106 | { |
| 107 | GCC_BLSP1_QUP1_I2C_APPS_CBCR, |
| 108 | GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR, |
| 109 | GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR, |
| 110 | }, |
| 111 | { |
| 112 | GCC_BLSP1_QUP1_I2C_APPS_CBCR, |
| 113 | GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR, |
| 114 | GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR, |
| 115 | }, |
| 116 | }; |
| 117 | |
| 118 | /* |
| 119 | * uart_clock_config() does this. Ideally, setting these bits once |
| 120 | * should suffice. However, if for some reason the order of invocation |
| 121 | * of uart_clock_config and blsp_i2c_clock_config gets changed or |
| 122 | * something, then one of the functions might not work. Hence, to steer |
| 123 | * clear of such dependencies, just replicating the setting of this |
| 124 | * bits. |
| 125 | * |
| 126 | * Moreover, they are read-modify-write and HW wise repeated setting of |
| 127 | * the same bits is harmless. Hence repeating them here should be ok. |
| 128 | * This will ensure root and branch clocks remain on. |
| 129 | */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 130 | setbits32(GCC_CLK_BRANCH_ENA, BLSP1_AHB | BLSP1_SLEEP); |
Varadarajan Narayanan | 2596764 | 2016-03-08 15:02:56 +0530 | [diff] [blame] | 131 | |
| 132 | /* Src Sel 1 (fepll 200), Src Div 10.5 */ |
| 133 | write32(clk[id].cfg, (1u << 8) | (20u << 0)); |
| 134 | |
| 135 | write32(clk[id].cmd, BIT(0)); /* Update En */ |
| 136 | |
| 137 | for (i = 0; i < max_tries; i++) { |
| 138 | if (read32(clk[id].cmd) & BIT(0)) { |
| 139 | udelay(5); |
| 140 | continue; |
| 141 | } |
| 142 | break; |
| 143 | } |
| 144 | |
| 145 | if (i == max_tries) { |
| 146 | printk(BIOS_ERR, "%s failed\n", __func__); |
| 147 | return -ETIMEDOUT; |
| 148 | } |
| 149 | |
| 150 | write32(clk[id].cbcr, BIT(0)); /* Enable */ |
| 151 | |
| 152 | return 0; |
| 153 | } |