Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: stm32f7: Introduce stm32f7 clocks for STM32F746 boards

This patch enables clocks for STM32F746 boards.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>

authored by

Gabriel Fernandez and committed by
Stephen Boyd
88c9b70b 0875dd59

+271 -6
+271 -6
drivers/clk/clk-stm32f4.c
··· 48 48 #define STM32F4_RCC_PLLI2SCFGR 0x84 49 49 #define STM32F4_RCC_PLLSAICFGR 0x88 50 50 #define STM32F4_RCC_DCKCFGR 0x8c 51 + #define STM32F7_RCC_DCKCFGR2 0x90 51 52 52 53 #define NONE -1 53 54 #define NO_IDX NONE ··· 225 224 { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, 226 225 }; 227 226 227 + static const struct stm32f4_gate_data stm32f746_gates[] __initconst = { 228 + { STM32F4_RCC_AHB1ENR, 0, "gpioa", "ahb_div" }, 229 + { STM32F4_RCC_AHB1ENR, 1, "gpiob", "ahb_div" }, 230 + { STM32F4_RCC_AHB1ENR, 2, "gpioc", "ahb_div" }, 231 + { STM32F4_RCC_AHB1ENR, 3, "gpiod", "ahb_div" }, 232 + { STM32F4_RCC_AHB1ENR, 4, "gpioe", "ahb_div" }, 233 + { STM32F4_RCC_AHB1ENR, 5, "gpiof", "ahb_div" }, 234 + { STM32F4_RCC_AHB1ENR, 6, "gpiog", "ahb_div" }, 235 + { STM32F4_RCC_AHB1ENR, 7, "gpioh", "ahb_div" }, 236 + { STM32F4_RCC_AHB1ENR, 8, "gpioi", "ahb_div" }, 237 + { STM32F4_RCC_AHB1ENR, 9, "gpioj", "ahb_div" }, 238 + { STM32F4_RCC_AHB1ENR, 10, "gpiok", "ahb_div" }, 239 + { STM32F4_RCC_AHB1ENR, 12, "crc", "ahb_div" }, 240 + { STM32F4_RCC_AHB1ENR, 18, "bkpsra", "ahb_div" }, 241 + { STM32F4_RCC_AHB1ENR, 20, "dtcmram", "ahb_div" }, 242 + { STM32F4_RCC_AHB1ENR, 21, "dma1", "ahb_div" }, 243 + { STM32F4_RCC_AHB1ENR, 22, "dma2", "ahb_div" }, 244 + { STM32F4_RCC_AHB1ENR, 23, "dma2d", "ahb_div" }, 245 + { STM32F4_RCC_AHB1ENR, 25, "ethmac", "ahb_div" }, 246 + { STM32F4_RCC_AHB1ENR, 26, "ethmactx", "ahb_div" }, 247 + { STM32F4_RCC_AHB1ENR, 27, "ethmacrx", "ahb_div" }, 248 + { STM32F4_RCC_AHB1ENR, 28, "ethmacptp", "ahb_div" }, 249 + { STM32F4_RCC_AHB1ENR, 29, "otghs", "ahb_div" }, 250 + { STM32F4_RCC_AHB1ENR, 30, "otghsulpi", "ahb_div" }, 251 + 252 + { STM32F4_RCC_AHB2ENR, 0, "dcmi", "ahb_div" }, 253 + { STM32F4_RCC_AHB2ENR, 4, "cryp", "ahb_div" }, 254 + { STM32F4_RCC_AHB2ENR, 5, "hash", "ahb_div" }, 255 + { STM32F4_RCC_AHB2ENR, 6, "rng", "pll48" }, 256 + { STM32F4_RCC_AHB2ENR, 7, "otgfs", "pll48" }, 257 + 258 + { STM32F4_RCC_AHB3ENR, 0, "fmc", "ahb_div", 259 + CLK_IGNORE_UNUSED }, 260 + { STM32F4_RCC_AHB3ENR, 1, "qspi", "ahb_div", 261 + CLK_IGNORE_UNUSED }, 262 + 263 + { STM32F4_RCC_APB1ENR, 0, "tim2", "apb1_mul" }, 264 + { STM32F4_RCC_APB1ENR, 1, "tim3", "apb1_mul" }, 265 + { STM32F4_RCC_APB1ENR, 2, "tim4", "apb1_mul" }, 266 + { STM32F4_RCC_APB1ENR, 3, "tim5", "apb1_mul" }, 267 + { STM32F4_RCC_APB1ENR, 4, "tim6", "apb1_mul" }, 268 + { STM32F4_RCC_APB1ENR, 5, "tim7", "apb1_mul" }, 269 + { STM32F4_RCC_APB1ENR, 6, "tim12", "apb1_mul" }, 270 + { STM32F4_RCC_APB1ENR, 7, "tim13", "apb1_mul" }, 271 + { STM32F4_RCC_APB1ENR, 8, "tim14", "apb1_mul" }, 272 + { STM32F4_RCC_APB1ENR, 11, "wwdg", "apb1_div" }, 273 + { STM32F4_RCC_APB1ENR, 14, "spi2", "apb1_div" }, 274 + { STM32F4_RCC_APB1ENR, 15, "spi3", "apb1_div" }, 275 + { STM32F4_RCC_APB1ENR, 16, "spdifrx", "apb1_div" }, 276 + { STM32F4_RCC_APB1ENR, 25, "can1", "apb1_div" }, 277 + { STM32F4_RCC_APB1ENR, 26, "can2", "apb1_div" }, 278 + { STM32F4_RCC_APB1ENR, 27, "cec", "apb1_div" }, 279 + { STM32F4_RCC_APB1ENR, 28, "pwr", "apb1_div" }, 280 + { STM32F4_RCC_APB1ENR, 29, "dac", "apb1_div" }, 281 + 282 + { STM32F4_RCC_APB2ENR, 0, "tim1", "apb2_mul" }, 283 + { STM32F4_RCC_APB2ENR, 1, "tim8", "apb2_mul" }, 284 + { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" }, 285 + { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" }, 286 + { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" }, 287 + { STM32F4_RCC_APB2ENR, 11, "sdmmc", "sdmux" }, 288 + { STM32F4_RCC_APB2ENR, 12, "spi1", "apb2_div" }, 289 + { STM32F4_RCC_APB2ENR, 13, "spi4", "apb2_div" }, 290 + { STM32F4_RCC_APB2ENR, 14, "syscfg", "apb2_div" }, 291 + { STM32F4_RCC_APB2ENR, 16, "tim9", "apb2_mul" }, 292 + { STM32F4_RCC_APB2ENR, 17, "tim10", "apb2_mul" }, 293 + { STM32F4_RCC_APB2ENR, 18, "tim11", "apb2_mul" }, 294 + { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, 295 + { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, 296 + { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, 297 + { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" }, 298 + { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, 299 + }; 300 + 228 301 /* 229 302 * This bitmask tells us which bit offsets (0..192) on STM32F4[23]xxx 230 303 * have gate bits associated with them. Its combined hweight is 71. ··· 313 238 0x0000000000000003ull, 314 239 0x0c777f33f6fec9ffull }; 315 240 241 + static const u64 stm32f746_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull, 242 + 0x0000000000000003ull, 243 + 0x04f77f033e01c9ffull }; 244 + 316 245 static const u64 *stm32f4_gate_map; 317 246 318 247 static struct clk_hw **clks; ··· 325 246 static void __iomem *base; 326 247 327 248 static struct regmap *pdrm; 249 + 250 + static int stm32fx_end_primary_clk; 328 251 329 252 /* 330 253 * "Multiplier" device for APBx clocks. ··· 766 685 u64 table[MAX_GATE_MAP]; 767 686 768 687 if (primary == 1) { 769 - if (WARN_ON(secondary >= END_PRIMARY_CLK)) 688 + if (WARN_ON(secondary >= stm32fx_end_primary_clk)) 770 689 return -EINVAL; 771 690 return secondary; 772 691 } ··· 783 702 table[BIT_ULL_WORD(secondary)] &= 784 703 GENMASK_ULL(secondary % BITS_PER_LONG_LONG, 0); 785 704 786 - return END_PRIMARY_CLK - 1 + hweight64(table[0]) + 705 + return stm32fx_end_primary_clk - 1 + hweight64(table[0]) + 787 706 (BIT_ULL_WORD(secondary) >= 1 ? hweight64(table[1]) : 0) + 788 707 (BIT_ULL_WORD(secondary) >= 2 ? hweight64(table[2]) : 0); 789 708 } ··· 1036 955 1037 956 static const char *sdmux_parents[2] = { "pll48", "sys" }; 1038 957 958 + static const char *hdmi_parents[2] = { "lse", "hsi_div488" }; 959 + 960 + static const char *spdif_parent[1] = { "plli2s-p" }; 961 + 962 + static const char *lptim_parent[4] = { "apb1_mul", "lsi", "hsi", "lse" }; 963 + 964 + static const char *uart_parents1[4] = { "apb2_div", "sys", "hsi", "lse" }; 965 + static const char *uart_parents2[4] = { "apb1_div", "sys", "hsi", "lse" }; 966 + 967 + static const char *i2c_parents[4] = { "apb1_div", "sys", "hsi", "no-clock" }; 968 + 1039 969 struct stm32_aux_clk { 1040 970 int idx; 1041 971 const char *name; ··· 1067 975 const struct stm32f4_pll_data *pll_data; 1068 976 const struct stm32_aux_clk *aux_clk; 1069 977 int aux_clk_num; 978 + int end_primary; 1070 979 }; 1071 980 1072 981 static const struct stm32_aux_clk stm32f429_aux_clk[] = { ··· 1136 1043 }, 1137 1044 }; 1138 1045 1046 + static const struct stm32_aux_clk stm32f746_aux_clk[] = { 1047 + { 1048 + CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent), 1049 + NO_MUX, 0, 0, 1050 + STM32F4_RCC_APB2ENR, 26, 1051 + CLK_SET_RATE_PARENT 1052 + }, 1053 + { 1054 + CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents), 1055 + STM32F4_RCC_CFGR, 23, 1, 1056 + NO_GATE, 0, 1057 + CLK_SET_RATE_PARENT 1058 + }, 1059 + { 1060 + CLK_SAI1, "sai1_clk", sai_parents, ARRAY_SIZE(sai_parents), 1061 + STM32F4_RCC_DCKCFGR, 20, 3, 1062 + STM32F4_RCC_APB2ENR, 22, 1063 + CLK_SET_RATE_PARENT 1064 + }, 1065 + { 1066 + CLK_SAI2, "sai2_clk", sai_parents, ARRAY_SIZE(sai_parents), 1067 + STM32F4_RCC_DCKCFGR, 22, 3, 1068 + STM32F4_RCC_APB2ENR, 23, 1069 + CLK_SET_RATE_PARENT 1070 + }, 1071 + { 1072 + NO_IDX, "pll48", pll48_parents, ARRAY_SIZE(pll48_parents), 1073 + STM32F7_RCC_DCKCFGR2, 27, 1, 1074 + NO_GATE, 0, 1075 + 0 1076 + }, 1077 + { 1078 + NO_IDX, "sdmux", sdmux_parents, ARRAY_SIZE(sdmux_parents), 1079 + STM32F7_RCC_DCKCFGR2, 28, 1, 1080 + NO_GATE, 0, 1081 + 0 1082 + }, 1083 + { 1084 + CLK_HDMI_CEC, "hdmi-cec", 1085 + hdmi_parents, ARRAY_SIZE(hdmi_parents), 1086 + STM32F7_RCC_DCKCFGR2, 26, 1, 1087 + NO_GATE, 0, 1088 + 0 1089 + }, 1090 + { 1091 + CLK_SPDIF, "spdif-rx", 1092 + spdif_parent, ARRAY_SIZE(spdif_parent), 1093 + STM32F7_RCC_DCKCFGR2, 22, 3, 1094 + STM32F4_RCC_APB2ENR, 23, 1095 + CLK_SET_RATE_PARENT 1096 + }, 1097 + { 1098 + CLK_USART1, "usart1", 1099 + uart_parents1, ARRAY_SIZE(uart_parents1), 1100 + STM32F7_RCC_DCKCFGR2, 0, 3, 1101 + STM32F4_RCC_APB2ENR, 4, 1102 + CLK_SET_RATE_PARENT, 1103 + }, 1104 + { 1105 + CLK_USART2, "usart2", 1106 + uart_parents2, ARRAY_SIZE(uart_parents1), 1107 + STM32F7_RCC_DCKCFGR2, 2, 3, 1108 + STM32F4_RCC_APB1ENR, 17, 1109 + CLK_SET_RATE_PARENT, 1110 + }, 1111 + { 1112 + CLK_USART3, "usart3", 1113 + uart_parents2, ARRAY_SIZE(uart_parents1), 1114 + STM32F7_RCC_DCKCFGR2, 4, 3, 1115 + STM32F4_RCC_APB1ENR, 18, 1116 + CLK_SET_RATE_PARENT, 1117 + }, 1118 + { 1119 + CLK_UART4, "uart4", 1120 + uart_parents2, ARRAY_SIZE(uart_parents1), 1121 + STM32F7_RCC_DCKCFGR2, 6, 3, 1122 + STM32F4_RCC_APB1ENR, 19, 1123 + CLK_SET_RATE_PARENT, 1124 + }, 1125 + { 1126 + CLK_UART5, "uart5", 1127 + uart_parents2, ARRAY_SIZE(uart_parents1), 1128 + STM32F7_RCC_DCKCFGR2, 8, 3, 1129 + STM32F4_RCC_APB1ENR, 20, 1130 + CLK_SET_RATE_PARENT, 1131 + }, 1132 + { 1133 + CLK_USART6, "usart6", 1134 + uart_parents1, ARRAY_SIZE(uart_parents1), 1135 + STM32F7_RCC_DCKCFGR2, 10, 3, 1136 + STM32F4_RCC_APB2ENR, 5, 1137 + CLK_SET_RATE_PARENT, 1138 + }, 1139 + 1140 + { 1141 + CLK_UART7, "uart7", 1142 + uart_parents2, ARRAY_SIZE(uart_parents1), 1143 + STM32F7_RCC_DCKCFGR2, 12, 3, 1144 + STM32F4_RCC_APB1ENR, 30, 1145 + CLK_SET_RATE_PARENT, 1146 + }, 1147 + { 1148 + CLK_UART8, "uart8", 1149 + uart_parents2, ARRAY_SIZE(uart_parents1), 1150 + STM32F7_RCC_DCKCFGR2, 14, 3, 1151 + STM32F4_RCC_APB1ENR, 31, 1152 + CLK_SET_RATE_PARENT, 1153 + }, 1154 + { 1155 + CLK_I2C1, "i2c1", 1156 + i2c_parents, ARRAY_SIZE(i2c_parents), 1157 + STM32F7_RCC_DCKCFGR2, 16, 3, 1158 + STM32F4_RCC_APB1ENR, 21, 1159 + CLK_SET_RATE_PARENT, 1160 + }, 1161 + { 1162 + CLK_I2C2, "i2c2", 1163 + i2c_parents, ARRAY_SIZE(i2c_parents), 1164 + STM32F7_RCC_DCKCFGR2, 18, 3, 1165 + STM32F4_RCC_APB1ENR, 22, 1166 + CLK_SET_RATE_PARENT, 1167 + }, 1168 + { 1169 + CLK_I2C3, "i2c3", 1170 + i2c_parents, ARRAY_SIZE(i2c_parents), 1171 + STM32F7_RCC_DCKCFGR2, 20, 3, 1172 + STM32F4_RCC_APB1ENR, 23, 1173 + CLK_SET_RATE_PARENT, 1174 + }, 1175 + { 1176 + CLK_I2C4, "i2c4", 1177 + i2c_parents, ARRAY_SIZE(i2c_parents), 1178 + STM32F7_RCC_DCKCFGR2, 22, 3, 1179 + STM32F4_RCC_APB1ENR, 24, 1180 + CLK_SET_RATE_PARENT, 1181 + }, 1182 + 1183 + { 1184 + CLK_LPTIMER, "lptim1", 1185 + lptim_parent, ARRAY_SIZE(lptim_parent), 1186 + STM32F7_RCC_DCKCFGR2, 24, 3, 1187 + STM32F4_RCC_APB1ENR, 9, 1188 + CLK_SET_RATE_PARENT 1189 + }, 1190 + }; 1191 + 1139 1192 static const struct stm32f4_clk_data stm32f429_clk_data = { 1193 + .end_primary = END_PRIMARY_CLK, 1140 1194 .gates_data = stm32f429_gates, 1141 1195 .gates_map = stm32f42xx_gate_map, 1142 1196 .gates_num = ARRAY_SIZE(stm32f429_gates), ··· 1293 1053 }; 1294 1054 1295 1055 static const struct stm32f4_clk_data stm32f469_clk_data = { 1056 + .end_primary = END_PRIMARY_CLK, 1296 1057 .gates_data = stm32f469_gates, 1297 1058 .gates_map = stm32f46xx_gate_map, 1298 1059 .gates_num = ARRAY_SIZE(stm32f469_gates), 1299 1060 .pll_data = stm32f469_pll, 1300 1061 .aux_clk = stm32f469_aux_clk, 1301 1062 .aux_clk_num = ARRAY_SIZE(stm32f469_aux_clk), 1063 + }; 1064 + 1065 + static const struct stm32f4_clk_data stm32f746_clk_data = { 1066 + .end_primary = END_PRIMARY_CLK_F7, 1067 + .gates_data = stm32f746_gates, 1068 + .gates_map = stm32f746_gate_map, 1069 + .gates_num = ARRAY_SIZE(stm32f746_gates), 1070 + .pll_data = stm32f469_pll, 1071 + .aux_clk = stm32f746_aux_clk, 1072 + .aux_clk_num = ARRAY_SIZE(stm32f746_aux_clk), 1302 1073 }; 1303 1074 1304 1075 static const struct of_device_id stm32f4_of_match[] = { ··· 1320 1069 { 1321 1070 .compatible = "st,stm32f469-rcc", 1322 1071 .data = &stm32f469_clk_data 1072 + }, 1073 + { 1074 + .compatible = "st,stm32f746-rcc", 1075 + .data = &stm32f746_clk_data 1323 1076 }, 1324 1077 {} 1325 1078 }; ··· 1418 1163 1419 1164 data = match->data; 1420 1165 1421 - clks = kmalloc_array(data->gates_num + END_PRIMARY_CLK, 1166 + stm32fx_end_primary_clk = data->end_primary; 1167 + 1168 + clks = kmalloc_array(data->gates_num + stm32fx_end_primary_clk, 1422 1169 sizeof(*clks), GFP_KERNEL); 1423 1170 if (!clks) 1424 1171 goto fail; ··· 1434 1177 i2s_parents[1] = i2s_in_clk; 1435 1178 sai_parents[2] = i2s_in_clk; 1436 1179 1437 - clk_register_fixed_rate_with_accuracy(NULL, "hsi", NULL, 0, 1438 - 16000000, 160000); 1180 + clks[CLK_HSI] = clk_hw_register_fixed_rate_with_accuracy(NULL, "hsi", 1181 + NULL, 0, 16000000, 160000); 1182 + 1439 1183 pllcfgr = readl(base + STM32F4_RCC_PLLCFGR); 1440 1184 pllsrc = pllcfgr & BIT(22) ? hse_clk : "hsi"; 1441 1185 pllm = pllcfgr & 0x3f; ··· 1475 1217 } 1476 1218 1477 1219 sys_parents[1] = hse_clk; 1478 - clk_register_mux_table( 1220 + 1221 + clks[CLK_SYSCLK] = clk_hw_register_mux_table( 1479 1222 NULL, "sys", sys_parents, ARRAY_SIZE(sys_parents), 0, 1480 1223 base + STM32F4_RCC_CFGR, 0, 3, 0, NULL, &stm32f4_clk_lock); 1481 1224 ··· 1580 1321 clks[aux_clk->idx] = hw; 1581 1322 } 1582 1323 1324 + if (of_device_is_compatible(np, "st,stm32f746-rcc")) 1325 + 1326 + clk_hw_register_fixed_factor(NULL, "hsi_div488", "hsi", 0, 1327 + 1, 488); 1328 + 1583 1329 of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL); 1584 1330 return; 1585 1331 fail: ··· 1593 1329 } 1594 1330 CLK_OF_DECLARE_DRIVER(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init); 1595 1331 CLK_OF_DECLARE_DRIVER(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init); 1332 + CLK_OF_DECLARE_DRIVER(stm32f746_rcc, "st,stm32f746-rcc", stm32f4_rcc_init);