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

clk: stm32f469: Add QSPI clock

This patch adds the QSPI clock for stm32f469 discovery board.
The gate mapping is a little bit different from stm32f429 soc.

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

authored by

Gabriel Fernandez and committed by
Stephen Boyd
a064a07f 4261a881

+158 -19
+3 -1
Documentation/devicetree/bindings/clock/st,stm32-rcc.txt
··· 7 7 Please also refer to reset.txt for common reset controller binding usage. 8 8 9 9 Required properties: 10 - - compatible: Should be "st,stm32f42xx-rcc" 10 + - compatible: Should be: 11 + "st,stm32f42xx-rcc" 12 + "st,stm32f469-rcc" 11 13 - reg: should be register base and length as documented in the 12 14 datasheet 13 15 - #reset-cells: 1, see below
+155 -18
drivers/clk/clk-stm32f4.c
··· 46 46 unsigned long flags; 47 47 }; 48 48 49 - static const struct stm32f4_gate_data stm32f4_gates[] __initconst = { 49 + static const struct stm32f4_gate_data stm32f429_gates[] __initconst = { 50 50 { STM32F4_RCC_AHB1ENR, 0, "gpioa", "ahb_div" }, 51 51 { STM32F4_RCC_AHB1ENR, 1, "gpiob", "ahb_div" }, 52 52 { STM32F4_RCC_AHB1ENR, 2, "gpioc", "ahb_div" }, ··· 126 126 { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, 127 127 }; 128 128 129 + static const struct stm32f4_gate_data stm32f469_gates[] __initconst = { 130 + { STM32F4_RCC_AHB1ENR, 0, "gpioa", "ahb_div" }, 131 + { STM32F4_RCC_AHB1ENR, 1, "gpiob", "ahb_div" }, 132 + { STM32F4_RCC_AHB1ENR, 2, "gpioc", "ahb_div" }, 133 + { STM32F4_RCC_AHB1ENR, 3, "gpiod", "ahb_div" }, 134 + { STM32F4_RCC_AHB1ENR, 4, "gpioe", "ahb_div" }, 135 + { STM32F4_RCC_AHB1ENR, 5, "gpiof", "ahb_div" }, 136 + { STM32F4_RCC_AHB1ENR, 6, "gpiog", "ahb_div" }, 137 + { STM32F4_RCC_AHB1ENR, 7, "gpioh", "ahb_div" }, 138 + { STM32F4_RCC_AHB1ENR, 8, "gpioi", "ahb_div" }, 139 + { STM32F4_RCC_AHB1ENR, 9, "gpioj", "ahb_div" }, 140 + { STM32F4_RCC_AHB1ENR, 10, "gpiok", "ahb_div" }, 141 + { STM32F4_RCC_AHB1ENR, 12, "crc", "ahb_div" }, 142 + { STM32F4_RCC_AHB1ENR, 18, "bkpsra", "ahb_div" }, 143 + { STM32F4_RCC_AHB1ENR, 20, "ccmdatam", "ahb_div" }, 144 + { STM32F4_RCC_AHB1ENR, 21, "dma1", "ahb_div" }, 145 + { STM32F4_RCC_AHB1ENR, 22, "dma2", "ahb_div" }, 146 + { STM32F4_RCC_AHB1ENR, 23, "dma2d", "ahb_div" }, 147 + { STM32F4_RCC_AHB1ENR, 25, "ethmac", "ahb_div" }, 148 + { STM32F4_RCC_AHB1ENR, 26, "ethmactx", "ahb_div" }, 149 + { STM32F4_RCC_AHB1ENR, 27, "ethmacrx", "ahb_div" }, 150 + { STM32F4_RCC_AHB1ENR, 28, "ethmacptp", "ahb_div" }, 151 + { STM32F4_RCC_AHB1ENR, 29, "otghs", "ahb_div" }, 152 + { STM32F4_RCC_AHB1ENR, 30, "otghsulpi", "ahb_div" }, 153 + 154 + { STM32F4_RCC_AHB2ENR, 0, "dcmi", "ahb_div" }, 155 + { STM32F4_RCC_AHB2ENR, 4, "cryp", "ahb_div" }, 156 + { STM32F4_RCC_AHB2ENR, 5, "hash", "ahb_div" }, 157 + { STM32F4_RCC_AHB2ENR, 6, "rng", "pll48" }, 158 + { STM32F4_RCC_AHB2ENR, 7, "otgfs", "pll48" }, 159 + 160 + { STM32F4_RCC_AHB3ENR, 0, "fmc", "ahb_div", 161 + CLK_IGNORE_UNUSED }, 162 + { STM32F4_RCC_AHB3ENR, 1, "qspi", "ahb_div", 163 + CLK_IGNORE_UNUSED }, 164 + 165 + { STM32F4_RCC_APB1ENR, 0, "tim2", "apb1_mul" }, 166 + { STM32F4_RCC_APB1ENR, 1, "tim3", "apb1_mul" }, 167 + { STM32F4_RCC_APB1ENR, 2, "tim4", "apb1_mul" }, 168 + { STM32F4_RCC_APB1ENR, 3, "tim5", "apb1_mul" }, 169 + { STM32F4_RCC_APB1ENR, 4, "tim6", "apb1_mul" }, 170 + { STM32F4_RCC_APB1ENR, 5, "tim7", "apb1_mul" }, 171 + { STM32F4_RCC_APB1ENR, 6, "tim12", "apb1_mul" }, 172 + { STM32F4_RCC_APB1ENR, 7, "tim13", "apb1_mul" }, 173 + { STM32F4_RCC_APB1ENR, 8, "tim14", "apb1_mul" }, 174 + { STM32F4_RCC_APB1ENR, 11, "wwdg", "apb1_div" }, 175 + { STM32F4_RCC_APB1ENR, 14, "spi2", "apb1_div" }, 176 + { STM32F4_RCC_APB1ENR, 15, "spi3", "apb1_div" }, 177 + { STM32F4_RCC_APB1ENR, 17, "uart2", "apb1_div" }, 178 + { STM32F4_RCC_APB1ENR, 18, "uart3", "apb1_div" }, 179 + { STM32F4_RCC_APB1ENR, 19, "uart4", "apb1_div" }, 180 + { STM32F4_RCC_APB1ENR, 20, "uart5", "apb1_div" }, 181 + { STM32F4_RCC_APB1ENR, 21, "i2c1", "apb1_div" }, 182 + { STM32F4_RCC_APB1ENR, 22, "i2c2", "apb1_div" }, 183 + { STM32F4_RCC_APB1ENR, 23, "i2c3", "apb1_div" }, 184 + { STM32F4_RCC_APB1ENR, 25, "can1", "apb1_div" }, 185 + { STM32F4_RCC_APB1ENR, 26, "can2", "apb1_div" }, 186 + { STM32F4_RCC_APB1ENR, 28, "pwr", "apb1_div" }, 187 + { STM32F4_RCC_APB1ENR, 29, "dac", "apb1_div" }, 188 + { STM32F4_RCC_APB1ENR, 30, "uart7", "apb1_div" }, 189 + { STM32F4_RCC_APB1ENR, 31, "uart8", "apb1_div" }, 190 + 191 + { STM32F4_RCC_APB2ENR, 0, "tim1", "apb2_mul" }, 192 + { STM32F4_RCC_APB2ENR, 1, "tim8", "apb2_mul" }, 193 + { STM32F4_RCC_APB2ENR, 4, "usart1", "apb2_div" }, 194 + { STM32F4_RCC_APB2ENR, 5, "usart6", "apb2_div" }, 195 + { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" }, 196 + { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" }, 197 + { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" }, 198 + { STM32F4_RCC_APB2ENR, 11, "sdio", "pll48" }, 199 + { STM32F4_RCC_APB2ENR, 12, "spi1", "apb2_div" }, 200 + { STM32F4_RCC_APB2ENR, 13, "spi4", "apb2_div" }, 201 + { STM32F4_RCC_APB2ENR, 14, "syscfg", "apb2_div" }, 202 + { STM32F4_RCC_APB2ENR, 16, "tim9", "apb2_mul" }, 203 + { STM32F4_RCC_APB2ENR, 17, "tim10", "apb2_mul" }, 204 + { STM32F4_RCC_APB2ENR, 18, "tim11", "apb2_mul" }, 205 + { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, 206 + { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, 207 + { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, 208 + { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, 209 + }; 210 + 129 211 enum { SYSTICK, FCLK, CLK_LSI, CLK_LSE, CLK_HSE_RTC, CLK_RTC, END_PRIMARY_CLK }; 130 - /* 131 - * MAX_CLKS is the maximum value in the enumeration below plus the combined 132 - * hweight of stm32f42xx_gate_map (plus one). 133 - */ 134 - #define MAX_CLKS (71 + END_PRIMARY_CLK + 1) 135 212 136 213 /* 137 214 * This bitmask tells us which bit offsets (0..192) on STM32F4[23]xxx 138 215 * have gate bits associated with them. Its combined hweight is 71. 139 216 */ 140 - static const u64 stm32f42xx_gate_map[] = { 0x000000f17ef417ffull, 141 - 0x0000000000000001ull, 142 - 0x04777f33f6fec9ffull }; 217 + #define MAX_GATE_MAP 3 143 218 144 - static struct clk_hw *clks[MAX_CLKS]; 219 + static const u64 stm32f42xx_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull, 220 + 0x0000000000000001ull, 221 + 0x04777f33f6fec9ffull }; 222 + 223 + static const u64 stm32f46xx_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull, 224 + 0x0000000000000003ull, 225 + 0x0c777f33f6fec9ffull }; 226 + 227 + static const u64 *stm32f4_gate_map; 228 + 229 + static struct clk_hw **clks; 230 + 145 231 static DEFINE_SPINLOCK(stm32f4_clk_lock); 146 232 static void __iomem *base; 147 233 ··· 349 263 */ 350 264 static int stm32f4_rcc_lookup_clk_idx(u8 primary, u8 secondary) 351 265 { 352 - u64 table[ARRAY_SIZE(stm32f42xx_gate_map)]; 266 + u64 table[MAX_GATE_MAP]; 353 267 354 268 if (primary == 1) { 355 269 if (WARN_ON(secondary >= END_PRIMARY_CLK)) ··· 357 271 return secondary; 358 272 } 359 273 360 - memcpy(table, stm32f42xx_gate_map, sizeof(table)); 274 + memcpy(table, stm32f4_gate_map, sizeof(table)); 361 275 362 276 /* only bits set in table can be used as indices */ 363 277 if (WARN_ON(secondary >= BITS_PER_BYTE * sizeof(table) || ··· 611 525 "no-clock", "lse", "lsi", "hse-rtc" 612 526 }; 613 527 528 + struct stm32f4_clk_data { 529 + const struct stm32f4_gate_data *gates_data; 530 + const u64 *gates_map; 531 + int gates_num; 532 + }; 533 + 534 + static const struct stm32f4_clk_data stm32f429_clk_data = { 535 + .gates_data = stm32f429_gates, 536 + .gates_map = stm32f42xx_gate_map, 537 + .gates_num = ARRAY_SIZE(stm32f429_gates), 538 + }; 539 + 540 + static const struct stm32f4_clk_data stm32f469_clk_data = { 541 + .gates_data = stm32f469_gates, 542 + .gates_map = stm32f46xx_gate_map, 543 + .gates_num = ARRAY_SIZE(stm32f469_gates), 544 + }; 545 + 546 + static const struct of_device_id stm32f4_of_match[] = { 547 + { 548 + .compatible = "st,stm32f42xx-rcc", 549 + .data = &stm32f429_clk_data 550 + }, 551 + { 552 + .compatible = "st,stm32f469-rcc", 553 + .data = &stm32f469_clk_data 554 + }, 555 + {} 556 + }; 557 + 614 558 static void __init stm32f4_rcc_init(struct device_node *np) 615 559 { 616 560 const char *hse_clk; 617 561 int n; 562 + const struct of_device_id *match; 563 + const struct stm32f4_clk_data *data; 618 564 619 565 base = of_iomap(np, 0); 620 566 if (!base) { ··· 659 541 pdrm = NULL; 660 542 pr_warn("%s: Unable to get syscfg\n", __func__); 661 543 } 544 + 545 + match = of_match_node(stm32f4_of_match, np); 546 + if (WARN_ON(!match)) 547 + return; 548 + 549 + data = match->data; 550 + 551 + clks = kmalloc_array(data->gates_num + END_PRIMARY_CLK, 552 + sizeof(*clks), GFP_KERNEL); 553 + if (!clks) 554 + goto fail; 555 + 556 + stm32f4_gate_map = data->gates_map; 662 557 663 558 hse_clk = of_clk_get_parent_name(np, 0); 664 559 ··· 705 574 clks[FCLK] = clk_hw_register_fixed_factor(NULL, "fclk", "ahb_div", 706 575 0, 1, 1); 707 576 708 - for (n = 0; n < ARRAY_SIZE(stm32f4_gates); n++) { 709 - const struct stm32f4_gate_data *gd = &stm32f4_gates[n]; 710 - unsigned int secondary = 711 - 8 * (gd->offset - STM32F4_RCC_AHB1ENR) + gd->bit_idx; 712 - int idx = stm32f4_rcc_lookup_clk_idx(0, secondary); 577 + for (n = 0; n < data->gates_num; n++) { 578 + const struct stm32f4_gate_data *gd; 579 + unsigned int secondary; 580 + int idx; 581 + 582 + gd = &data->gates_data[n]; 583 + secondary = 8 * (gd->offset - STM32F4_RCC_AHB1ENR) + 584 + gd->bit_idx; 585 + idx = stm32f4_rcc_lookup_clk_idx(0, secondary); 713 586 714 587 if (idx < 0) 715 588 goto fail; ··· 765 630 of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL); 766 631 return; 767 632 fail: 633 + kfree(clks); 768 634 iounmap(base); 769 635 } 770 - CLK_OF_DECLARE(stm32f4_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init); 636 + CLK_OF_DECLARE(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init); 637 + CLK_OF_DECLARE(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init);