* Determine the UART clock source for @p bp and return the * corresponding clock configuration, if any. */
| 109 | * corresponding clock configuration, if any. |
| 110 | */ |
| 111 | static struct bcm_uart_clkcfg |
| 112 | bcm_get_uart_clkcfg(struct bcm_platform *bp) |
| 113 | { |
| 114 | struct bcm_uart_clkcfg cfg; |
| 115 | struct bhnd_core_info *cc_id; |
| 116 | |
| 117 | cc_id = &bp->cc_id; |
| 118 | |
| 119 | /* These tests are ordered by precedence. */ |
| 120 | |
| 121 | /* PLL M2 clock source? */ |
| 122 | if (!bcm_has_pmu(bp) && BCM_PMU_PLL_TYPE(bp) == CHIPC_PLL_TYPE1) { |
| 123 | uint32_t n, m; |
| 124 | |
| 125 | n = BCM_CHIPC_READ_4(bp, CHIPC_CLKC_N); |
| 126 | m = BCM_CHIPC_READ_4(bp, CHIPC_CLKC_M2); |
| 127 | |
| 128 | cfg = (struct bcm_uart_clkcfg) { |
| 129 | BCM_UART_RCLK_PLL_T1, |
| 130 | BCM_UART_RCLK_PLL_T1_DIV, |
| 131 | bhnd_pwrctl_clock_rate(BCM_PMU_PLL_TYPE(bp), n, m) |
| 132 | }; |
| 133 | |
| 134 | return (cfg); |
| 135 | } |
| 136 | |
| 137 | /* ALP clock source? */ |
| 138 | if (cc_id->hwrev != 15 && cc_id->hwrev >= 11) { |
| 139 | cfg = (struct bcm_uart_clkcfg) { |
| 140 | BCM_UART_RCLK_ALP, |
| 141 | BCM_UART_RCLK_ALP_DIV, |
| 142 | bcm_get_alpfreq(bp) |
| 143 | }; |
| 144 | return (cfg); |
| 145 | } |
| 146 | |
| 147 | /* External clock? */ |
| 148 | if (CHIPC_HWREV_HAS_CORECTRL(cc_id->hwrev)) { |
| 149 | uint32_t corectrl, uclksel; |
| 150 | bool uintclk0; |
| 151 | |
| 152 | /* Fetch UART clock support flag */ |
| 153 | uclksel = CHIPC_GET_BITS(bp->cc_caps, CHIPC_CAP_UCLKSEL); |
| 154 | |
| 155 | /* Is UART using internal clock? */ |
| 156 | corectrl = BCM_CHIPC_READ_4(bp, CHIPC_CORECTRL); |
| 157 | uintclk0 = CHIPC_GET_FLAG(corectrl, CHIPC_UARTCLKO); |
| 158 | |
| 159 | if (uintclk0 && uclksel == CHIPC_CAP_UCLKSEL_UINTCLK) { |
| 160 | cfg = (struct bcm_uart_clkcfg) { |
| 161 | BCM_UART_RCLK_EXT, |
| 162 | BCM_UART_RCLK_EXT_DIV, |
| 163 | BCM_UART_RCLK_EXT_HZ |
| 164 | }; |
| 165 | return (cfg); |
| 166 | } |
| 167 | } |
| 168 |
no test coverage detected