1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * SAMA7G5 PMC clock support. 4 * 5 * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries 6 * 7 * Author: Claudiu Beznea <claudiu.beznea@microchip.com> 8 * 9 * Based on drivers/clk/at91/sama7g5.c from Linux. 10 */ 11 12#include <common.h> 13#include <clk-uclass.h> 14#include <dm.h> 15#include <dt-bindings/clk/at91.h> 16#include <linux/clk-provider.h> 17 18#include "pmc.h" 19 20/** 21 * Clock identifiers to be used in conjunction with macros like 22 * AT91_TO_CLK_ID() 23 * 24 * @ID_MD_SLCK: TD slow clock identifier 25 * @ID_TD_SLCK: MD slow clock identifier 26 * @ID_MAIN_XTAL: Main Xtal clock identifier 27 * @ID_MAIN_RC: Main RC clock identifier 28 * @ID_MAIN_RC_OSC: Main RC Oscillator clock identifier 29 * @ID_MAIN_OSC: Main Oscillator clock identifier 30 * @ID_MAINCK: MAINCK clock identifier 31 * @ID_PLL_CPU_FRAC: CPU PLL fractional clock identifier 32 * @ID_PLL_CPU_DIV: CPU PLL divider clock identifier 33 * @ID_PLL_SYS_FRAC: SYS PLL fractional clock identifier 34 * @ID_PLL_SYS_DIV: SYS PLL divider clock identifier 35 * @ID_PLL_DDR_FRAC: DDR PLL fractional clock identifier 36 * @ID_PLL_DDR_DIV: DDR PLL divider clock identifier 37 * @ID_PLL_IMG_FRAC: IMC PLL fractional clock identifier 38 * @ID_PLL_IMG_DIV: IMG PLL divider clock identifier 39 * @ID_PLL_BAUD_FRAC: Baud PLL fractional clock identifier 40 * @ID_PLL_BAUD_DIV: Baud PLL divider clock identifier 41 * @ID_PLL_AUDIO_FRAC: Audio PLL fractional clock identifier 42 * @ID_PLL_AUDIO_DIVPMC: Audio PLL PMC divider clock identifier 43 * @ID_PLL_AUDIO_DIVIO: Audio PLL IO divider clock identifier 44 * @ID_PLL_ETH_FRAC: Ethernet PLL fractional clock identifier 45 * @ID_PLL_ETH_DIV: Ethernet PLL divider clock identifier 46 47 * @ID_MCK0_PRES: MCK0 PRES clock identifier 48 * @ID_MCK0_DIV: MCK0 DIV clock identifier 49 * @ID_MCK1: MCK1 clock identifier 50 * @ID_MCK2: MCK2 clock identifier 51 * @ID_MCK3: MCK3 clock identifier 52 * @ID_MCK4: MCK4 clock identifier 53 54 * @ID_UTMI: UTMI clock identifier 55 56 * @ID_PROG0: Programmable 0 clock identifier 57 * @ID_PROG1: Programmable 1 clock identifier 58 * @ID_PROG2: Programmable 2 clock identifier 59 * @ID_PROG3: Programmable 3 clock identifier 60 * @ID_PROG4: Programmable 4 clock identifier 61 * @ID_PROG5: Programmable 5 clock identifier 62 * @ID_PROG6: Programmable 6 clock identifier 63 * @ID_PROG7: Programmable 7 clock identifier 64 65 * @ID_PCK0: System clock 0 clock identifier 66 * @ID_PCK1: System clock 1 clock identifier 67 * @ID_PCK2: System clock 2 clock identifier 68 * @ID_PCK3: System clock 3 clock identifier 69 * @ID_PCK4: System clock 4 clock identifier 70 * @ID_PCK5: System clock 5 clock identifier 71 * @ID_PCK6: System clock 6 clock identifier 72 * @ID_PCK7: System clock 7 clock identifier 73 */ 74enum pmc_clk_ids { 75 ID_MD_SLCK = 0, 76 ID_TD_SLCK = 1, 77 ID_MAIN_XTAL = 2, 78 ID_MAIN_RC = 3, 79 ID_MAIN_RC_OSC = 4, 80 ID_MAIN_OSC = 5, 81 ID_MAINCK = 6, 82 83 ID_PLL_CPU_FRAC = 7, 84 ID_PLL_CPU_DIV = 8, 85 ID_PLL_SYS_FRAC = 9, 86 ID_PLL_SYS_DIV = 10, 87 ID_PLL_DDR_FRAC = 11, 88 ID_PLL_DDR_DIV = 12, 89 ID_PLL_IMG_FRAC = 13, 90 ID_PLL_IMG_DIV = 14, 91 ID_PLL_BAUD_FRAC = 15, 92 ID_PLL_BAUD_DIV = 16, 93 ID_PLL_AUDIO_FRAC = 17, 94 ID_PLL_AUDIO_DIVPMC = 18, 95 ID_PLL_AUDIO_DIVIO = 19, 96 ID_PLL_ETH_FRAC = 20, 97 ID_PLL_ETH_DIV = 21, 98 99 ID_MCK0_DIV = 22, 100 ID_MCK1 = 23, 101 ID_MCK2 = 24, 102 ID_MCK3 = 25, 103 ID_MCK4 = 26, 104 105 ID_UTMI = 27, 106 107 ID_PROG0 = 28, 108 ID_PROG1 = 29, 109 ID_PROG2 = 30, 110 ID_PROG3 = 31, 111 ID_PROG4 = 32, 112 ID_PROG5 = 33, 113 ID_PROG6 = 34, 114 ID_PROG7 = 35, 115 116 ID_PCK0 = 36, 117 ID_PCK1 = 37, 118 ID_PCK2 = 38, 119 ID_PCK3 = 39, 120 ID_PCK4 = 40, 121 ID_PCK5 = 41, 122 ID_PCK6 = 42, 123 ID_PCK7 = 43, 124 125 ID_MCK0_PRES = 44, 126 127 ID_MAX, 128}; 129 130/** 131 * PLL type identifiers 132 * @PLL_TYPE_FRAC: fractional PLL identifier 133 * @PLL_TYPE_DIV: divider PLL identifier 134 */ 135enum pll_type { 136 PLL_TYPE_FRAC, 137 PLL_TYPE_DIV, 138}; 139 140/* Clock names used as parents for multiple clocks. */ 141static const char *clk_names[] = { 142 [ID_MAIN_RC_OSC] = "main_rc_osc", 143 [ID_MAIN_OSC] = "main_osc", 144 [ID_MAINCK] = "mainck", 145 [ID_PLL_CPU_DIV] = "cpupll_divpmcck", 146 [ID_PLL_SYS_DIV] = "syspll_divpmcck", 147 [ID_PLL_DDR_DIV] = "ddrpll_divpmcck", 148 [ID_PLL_IMG_DIV] = "imgpll_divpmcck", 149 [ID_PLL_BAUD_DIV] = "baudpll_divpmcck", 150 [ID_PLL_AUDIO_DIVPMC] = "audiopll_divpmcck", 151 [ID_PLL_AUDIO_DIVIO] = "audiopll_diviock", 152 [ID_PLL_ETH_DIV] = "ethpll_divpmcck", 153 [ID_MCK0_DIV] = "mck0_div", 154 [ID_MCK0_PRES] = "mck0_pres", 155}; 156 157/* Fractional PLL output range. */ 158static const struct clk_range pll_outputs[] = { 159 { .min = 2343750, .max = 1200000000 }, 160}; 161 162/* PLL characteristics. */ 163static const struct clk_pll_characteristics pll_characteristics = { 164 .input = { .min = 12000000, .max = 50000000 }, 165 .num_output = ARRAY_SIZE(pll_outputs), 166 .output = pll_outputs, 167}; 168 169/* Layout for fractional PLLs. */ 170static const struct clk_pll_layout pll_layout_frac = { 171 .mul_mask = GENMASK(31, 24), 172 .frac_mask = GENMASK(21, 0), 173 .mul_shift = 24, 174 .frac_shift = 0, 175}; 176 177/* Layout for DIVPMC dividers. */ 178static const struct clk_pll_layout pll_layout_divpmc = { 179 .div_mask = GENMASK(7, 0), 180 .endiv_mask = BIT(29), 181 .div_shift = 0, 182 .endiv_shift = 29, 183}; 184 185/* Layout for DIVIO dividers. */ 186static const struct clk_pll_layout pll_layout_divio = { 187 .div_mask = GENMASK(19, 12), 188 .endiv_mask = BIT(30), 189 .div_shift = 12, 190 .endiv_shift = 30, 191}; 192 193/* MCK0 characteristics. */ 194static const struct clk_master_characteristics mck0_characteristics = { 195 .output = { .min = 140000000, .max = 200000000 }, 196 .divisors = { 1, 2, 4, 3, 5 }, 197 .have_div3_pres = 1, 198}; 199 200/* MCK0 layout. */ 201static const struct clk_master_layout mck0_layout = { 202 .mask = 0x773, 203 .pres_shift = 4, 204 .offset = 0x28, 205}; 206 207/* Programmable clock layout. */ 208static const struct clk_programmable_layout programmable_layout = { 209 .pres_mask = 0xff, 210 .pres_shift = 8, 211 .css_mask = 0x1f, 212 .have_slck_mck = 0, 213 .is_pres_direct = 1, 214}; 215 216/* Peripheral clock layout. */ 217static const struct clk_pcr_layout sama7g5_pcr_layout = { 218 .offset = 0x88, 219 .cmd = BIT(31), 220 .gckcss_mask = GENMASK(12, 8), 221 .pid_mask = GENMASK(6, 0), 222 .div_mask = GENMASK(15, 14), 223}; 224 225/** 226 * PLL clocks description 227 * @n: clock name 228 * @p: clock parent 229 * @l: clock layout 230 * @t: clock type 231 * @c: true if clock is critical and cannot be disabled 232 * @id: clock id corresponding to PLL driver 233 * @cid: clock id corresponding to clock subsystem 234 */ 235static const struct { 236 const char *n; 237 const char *p; 238 const struct clk_pll_layout *l; 239 u8 t; 240 u8 c; 241 u8 id; 242 u8 cid; 243} sama7g5_plls[] = { 244 { 245 .n = "cpupll_fracck", 246 .p = "mainck", 247 .l = &pll_layout_frac, 248 .t = PLL_TYPE_FRAC, 249 .c = 1, 250 .id = 0, 251 .cid = ID_PLL_CPU_FRAC, 252 }, 253 254 { 255 .n = "cpupll_divpmcck", 256 .p = "cpupll_fracck", 257 .l = &pll_layout_divpmc, 258 .t = PLL_TYPE_DIV, 259 .c = 1, 260 .id = 0, 261 .cid = ID_PLL_CPU_DIV, 262 }, 263 264 { 265 .n = "syspll_fracck", 266 .p = "mainck", 267 .l = &pll_layout_frac, 268 .t = PLL_TYPE_FRAC, 269 .c = 1, 270 .id = 1, 271 .cid = ID_PLL_SYS_FRAC, 272 }, 273 274 { 275 .n = "syspll_divpmcck", 276 .p = "syspll_fracck", 277 .l = &pll_layout_divpmc, 278 .t = PLL_TYPE_DIV, 279 .c = 1, 280 .id = 1, 281 .cid = ID_PLL_SYS_DIV, 282 }, 283 284 { 285 .n = "ddrpll_fracck", 286 .p = "mainck", 287 .l = &pll_layout_frac, 288 .t = PLL_TYPE_FRAC, 289 .c = 1, 290 .id = 2, 291 .cid = ID_PLL_DDR_FRAC, 292 }, 293 294 { 295 .n = "ddrpll_divpmcck", 296 .p = "ddrpll_fracck", 297 .l = &pll_layout_divpmc, 298 .t = PLL_TYPE_DIV, 299 .c = 1, 300 .id = 2, 301 .cid = ID_PLL_DDR_DIV, 302 }, 303 304 { 305 .n = "imgpll_fracck", 306 .p = "mainck", 307 .l = &pll_layout_frac, 308 .t = PLL_TYPE_FRAC, 309 .id = 3, 310 .cid = ID_PLL_IMG_FRAC, 311 }, 312 313 { 314 .n = "imgpll_divpmcck", 315 .p = "imgpll_fracck", 316 .l = &pll_layout_divpmc, 317 .t = PLL_TYPE_DIV, 318 .id = 3, 319 .cid = ID_PLL_IMG_DIV 320 }, 321 322 { 323 .n = "baudpll_fracck", 324 .p = "mainck", 325 .l = &pll_layout_frac, 326 .t = PLL_TYPE_FRAC, 327 .id = 4, 328 .cid = ID_PLL_BAUD_FRAC, 329 }, 330 331 { 332 .n = "baudpll_divpmcck", 333 .p = "baudpll_fracck", 334 .l = &pll_layout_divpmc, 335 .t = PLL_TYPE_DIV, 336 .id = 4, 337 .cid = ID_PLL_BAUD_DIV, 338 }, 339 340 { 341 .n = "audiopll_fracck", 342 .p = "main_osc", 343 .l = &pll_layout_frac, 344 .t = PLL_TYPE_FRAC, 345 .id = 5, 346 .cid = ID_PLL_AUDIO_FRAC, 347 }, 348 349 { 350 .n = "audiopll_divpmcck", 351 .p = "audiopll_fracck", 352 .l = &pll_layout_divpmc, 353 .t = PLL_TYPE_DIV, 354 .id = 5, 355 .cid = ID_PLL_AUDIO_DIVPMC, 356 }, 357 358 { 359 .n = "audiopll_diviock", 360 .p = "audiopll_fracck", 361 .l = &pll_layout_divio, 362 .t = PLL_TYPE_DIV, 363 .id = 5, 364 .cid = ID_PLL_AUDIO_DIVIO, 365 }, 366 367 { 368 .n = "ethpll_fracck", 369 .p = "main_osc", 370 .l = &pll_layout_frac, 371 .t = PLL_TYPE_FRAC, 372 .id = 6, 373 .cid = ID_PLL_ETH_FRAC, 374 }, 375 376 { 377 .n = "ethpll_divpmcck", 378 .p = "ethpll_fracck", 379 .l = &pll_layout_divpmc, 380 .t = PLL_TYPE_DIV, 381 .id = 6, 382 .cid = ID_PLL_ETH_DIV, 383 }, 384}; 385 386/** 387 * Master clock (MCK[1..4]) description 388 * @n: clock name 389 * @ep: extra parents names array 390 * @ep_chg_chg_id: index in parents array that specifies the changeable 391 * parent 392 * @ep_count: extra parents count 393 * @ep_mux_table: mux table for extra parents 394 * @ep_clk_mux_table: mux table to deal with subsystem clock ids 395 * @id: clock id corresponding to MCK driver 396 * @cid: clock id corresponding to clock subsystem 397 * @c: true if clock is critical and cannot be disabled 398 */ 399static const struct { 400 const char *n; 401 const char *ep[4]; 402 u8 ep_count; 403 u8 ep_mux_table[4]; 404 u8 ep_clk_mux_table[4]; 405 u8 id; 406 u8 cid; 407 u8 c; 408} sama7g5_mckx[] = { 409 { 410 .n = "mck1", 411 .id = 1, 412 .cid = ID_MCK1, 413 .ep = { "syspll_divpmcck", }, 414 .ep_mux_table = { 5, }, 415 .ep_clk_mux_table = { ID_PLL_SYS_DIV, }, 416 .ep_count = 1, 417 .c = 1, 418 }, 419 420 { 421 .n = "mck2", 422 .id = 2, 423 .cid = ID_MCK2, 424 .ep = { "ddrpll_divpmcck", }, 425 .ep_mux_table = { 6, }, 426 .ep_clk_mux_table = { ID_PLL_DDR_DIV, }, 427 .ep_count = 1, 428 .c = 1, 429 }, 430 431 { 432 .n = "mck3", 433 .id = 3, 434 .cid = ID_MCK3, 435 .ep = { "syspll_divpmcck", "ddrpll_divpmcck", "imgpll_divpmcck", }, 436 .ep_mux_table = { 5, 6, 7, }, 437 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_DDR_DIV, ID_PLL_IMG_DIV, }, 438 .ep_count = 3, 439 }, 440 441 { 442 .n = "mck4", 443 .id = 4, 444 .cid = ID_MCK4, 445 .ep = { "syspll_divpmcck", }, 446 .ep_mux_table = { 5, }, 447 .ep_clk_mux_table = { ID_PLL_SYS_DIV, }, 448 .ep_count = 1, 449 .c = 1, 450 }, 451}; 452 453/** 454 * Programmable clock description 455 * @n: clock name 456 * @cid: clock id corresponding to clock subsystem 457 */ 458static const struct { 459 const char *n; 460 u8 cid; 461} sama7g5_prog[] = { 462 { .n = "prog0", .cid = ID_PROG0, }, 463 { .n = "prog1", .cid = ID_PROG1, }, 464 { .n = "prog2", .cid = ID_PROG2, }, 465 { .n = "prog3", .cid = ID_PROG3, }, 466 { .n = "prog4", .cid = ID_PROG4, }, 467 { .n = "prog5", .cid = ID_PROG5, }, 468 { .n = "prog6", .cid = ID_PROG6, }, 469 { .n = "prog7", .cid = ID_PROG7, }, 470}; 471 472/* Mux table for programmable clocks. */ 473static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, }; 474 475/** 476 * System clock description 477 * @n: clock name 478 * @p: parent clock name 479 * @id: clock id corresponding to system clock driver 480 * @cid: clock id corresponding to clock subsystem 481 */ 482static const struct { 483 const char *n; 484 const char *p; 485 u8 id; 486 u8 cid; 487} sama7g5_systemck[] = { 488 { .n = "pck0", .p = "prog0", .id = 8, .cid = ID_PCK0, }, 489 { .n = "pck1", .p = "prog1", .id = 9, .cid = ID_PCK1, }, 490 { .n = "pck2", .p = "prog2", .id = 10, .cid = ID_PCK2, }, 491 { .n = "pck3", .p = "prog3", .id = 11, .cid = ID_PCK3, }, 492 { .n = "pck4", .p = "prog4", .id = 12, .cid = ID_PCK4, }, 493 { .n = "pck5", .p = "prog5", .id = 13, .cid = ID_PCK5, }, 494 { .n = "pck6", .p = "prog6", .id = 14, .cid = ID_PCK6, }, 495 { .n = "pck7", .p = "prog7", .id = 15, .cid = ID_PCK7, }, 496}; 497 498/** 499 * Peripheral clock description 500 * @n: clock name 501 * @p: clock parent name 502 * @r: clock range values 503 * @id: clock id 504 */ 505static const struct { 506 const char *n; 507 const char *p; 508 struct clk_range r; 509 u8 id; 510} sama7g5_periphck[] = { 511 { .n = "pioA_clk", .p = "mck0_div", .id = 11, }, 512 { .n = "sfr_clk", .p = "mck1", .id = 19, }, 513 { .n = "hsmc_clk", .p = "mck1", .id = 21, }, 514 { .n = "xdmac0_clk", .p = "mck1", .id = 22, }, 515 { .n = "xdmac1_clk", .p = "mck1", .id = 23, }, 516 { .n = "xdmac2_clk", .p = "mck1", .id = 24, }, 517 { .n = "acc_clk", .p = "mck1", .id = 25, }, 518 { .n = "aes_clk", .p = "mck1", .id = 27, }, 519 { .n = "tzaesbasc_clk", .p = "mck1", .id = 28, }, 520 { .n = "asrc_clk", .p = "mck1", .id = 30, .r = { .max = 200000000, }, }, 521 { .n = "cpkcc_clk", .p = "mck0_div", .id = 32, }, 522 { .n = "csi_clk", .p = "mck3", .id = 33, .r = { .max = 266000000, }, }, 523 { .n = "csi2dc_clk", .p = "mck3", .id = 34, .r = { .max = 266000000, }, }, 524 { .n = "eic_clk", .p = "mck1", .id = 37, }, 525 { .n = "flex0_clk", .p = "mck1", .id = 38, }, 526 { .n = "flex1_clk", .p = "mck1", .id = 39, }, 527 { .n = "flex2_clk", .p = "mck1", .id = 40, }, 528 { .n = "flex3_clk", .p = "mck1", .id = 41, }, 529 { .n = "flex4_clk", .p = "mck1", .id = 42, }, 530 { .n = "flex5_clk", .p = "mck1", .id = 43, }, 531 { .n = "flex6_clk", .p = "mck1", .id = 44, }, 532 { .n = "flex7_clk", .p = "mck1", .id = 45, }, 533 { .n = "flex8_clk", .p = "mck1", .id = 46, }, 534 { .n = "flex9_clk", .p = "mck1", .id = 47, }, 535 { .n = "flex10_clk", .p = "mck1", .id = 48, }, 536 { .n = "flex11_clk", .p = "mck1", .id = 49, }, 537 { .n = "gmac0_clk", .p = "mck1", .id = 51, }, 538 { .n = "gmac1_clk", .p = "mck1", .id = 52, }, 539 { .n = "gmac0_tsu_clk", .p = "mck1", .id = 53, }, 540 { .n = "gmac1_tsu_clk", .p = "mck1", .id = 54, }, 541 { .n = "icm_clk", .p = "mck1", .id = 55, }, 542 { .n = "isc_clk", .p = "mck3", .id = 56, .r = { .max = 266000000, }, }, 543 { .n = "i2smcc0_clk", .p = "mck1", .id = 57, .r = { .max = 200000000, }, }, 544 { .n = "i2smcc1_clk", .p = "mck1", .id = 58, .r = { .max = 200000000, }, }, 545 { .n = "matrix_clk", .p = "mck1", .id = 60, }, 546 { .n = "mcan0_clk", .p = "mck1", .id = 61, .r = { .max = 200000000, }, }, 547 { .n = "mcan1_clk", .p = "mck1", .id = 62, .r = { .max = 200000000, }, }, 548 { .n = "mcan2_clk", .p = "mck1", .id = 63, .r = { .max = 200000000, }, }, 549 { .n = "mcan3_clk", .p = "mck1", .id = 64, .r = { .max = 200000000, }, }, 550 { .n = "mcan4_clk", .p = "mck1", .id = 65, .r = { .max = 200000000, }, }, 551 { .n = "mcan5_clk", .p = "mck1", .id = 66, .r = { .max = 200000000, }, }, 552 { .n = "pdmc0_clk", .p = "mck1", .id = 68, .r = { .max = 200000000, }, }, 553 { .n = "pdmc1_clk", .p = "mck1", .id = 69, .r = { .max = 200000000, }, }, 554 { .n = "pit64b0_clk", .p = "mck1", .id = 70, }, 555 { .n = "pit64b1_clk", .p = "mck1", .id = 71, }, 556 { .n = "pit64b2_clk", .p = "mck1", .id = 72, }, 557 { .n = "pit64b3_clk", .p = "mck1", .id = 73, }, 558 { .n = "pit64b4_clk", .p = "mck1", .id = 74, }, 559 { .n = "pit64b5_clk", .p = "mck1", .id = 75, }, 560 { .n = "pwm_clk", .p = "mck1", .id = 77, }, 561 { .n = "qspi0_clk", .p = "mck1", .id = 78, }, 562 { .n = "qspi1_clk", .p = "mck1", .id = 79, }, 563 { .n = "sdmmc0_clk", .p = "mck1", .id = 80, }, 564 { .n = "sdmmc1_clk", .p = "mck1", .id = 81, }, 565 { .n = "sdmmc2_clk", .p = "mck1", .id = 82, }, 566 { .n = "sha_clk", .p = "mck1", .id = 83, }, 567 { .n = "spdifrx_clk", .p = "mck1", .id = 84, .r = { .max = 200000000, }, }, 568 { .n = "spdiftx_clk", .p = "mck1", .id = 85, .r = { .max = 200000000, }, }, 569 { .n = "ssc0_clk", .p = "mck1", .id = 86, .r = { .max = 200000000, }, }, 570 { .n = "ssc1_clk", .p = "mck1", .id = 87, .r = { .max = 200000000, }, }, 571 { .n = "tcb0_ch0_clk", .p = "mck1", .id = 88, .r = { .max = 200000000, }, }, 572 { .n = "tcb0_ch1_clk", .p = "mck1", .id = 89, .r = { .max = 200000000, }, }, 573 { .n = "tcb0_ch2_clk", .p = "mck1", .id = 90, .r = { .max = 200000000, }, }, 574 { .n = "tcb1_ch0_clk", .p = "mck1", .id = 91, .r = { .max = 200000000, }, }, 575 { .n = "tcb1_ch1_clk", .p = "mck1", .id = 92, .r = { .max = 200000000, }, }, 576 { .n = "tcb1_ch2_clk", .p = "mck1", .id = 93, .r = { .max = 200000000, }, }, 577 { .n = "tcpca_clk", .p = "mck1", .id = 94, }, 578 { .n = "tcpcb_clk", .p = "mck1", .id = 95, }, 579 { .n = "tdes_clk", .p = "mck1", .id = 96, }, 580 { .n = "trng_clk", .p = "mck1", .id = 97, }, 581 { .n = "udphsa_clk", .p = "mck1", .id = 104, }, 582 { .n = "udphsb_clk", .p = "mck1", .id = 105, }, 583 { .n = "uhphs_clk", .p = "mck1", .id = 106, }, 584}; 585 586/** 587 * Generic clock description 588 * @n: clock name 589 * @ep: extra parents names 590 * @ep_mux_table: extra parents mux table 591 * @ep_clk_mux_table: extra parents clock mux table (for CCF) 592 * @r: clock output range 593 * @ep_count: extra parents count 594 * @id: clock id 595 */ 596static const struct { 597 const char *n; 598 const char *ep[8]; 599 const char ep_mux_table[8]; 600 const char ep_clk_mux_table[8]; 601 struct clk_range r; 602 u8 ep_count; 603 u8 id; 604} sama7g5_gck[] = { 605 { 606 .n = "adc_gclk", 607 .id = 26, 608 .r = { .max = 100000000, }, 609 .ep = { "syspll_divpmcck", "imgpll_divpmcck", "audiopll_divpmcck", }, 610 .ep_mux_table = { 5, 7, 9, }, 611 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV, 612 ID_PLL_AUDIO_DIVPMC, }, 613 .ep_count = 3, 614 }, 615 616 { 617 .n = "asrc_gclk", 618 .id = 30, 619 .r = { .max = 200000000 }, 620 .ep = { "audiopll_divpmcck", }, 621 .ep_mux_table = { 9, }, 622 .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, }, 623 .ep_count = 1, 624 }, 625 626 { 627 .n = "csi_gclk", 628 .id = 33, 629 .r = { .max = 27000000 }, 630 .ep = { "ddrpll_divpmcck", "imgpll_divpmcck", }, 631 .ep_clk_mux_table = { ID_PLL_DDR_DIV, ID_PLL_IMG_DIV, }, 632 .ep_mux_table = { 6, 7, }, 633 .ep_count = 2, 634 }, 635 636 { 637 .n = "flex0_gclk", 638 .id = 38, 639 .r = { .max = 200000000 }, 640 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 641 .ep_mux_table = { 5, 8, }, 642 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 643 .ep_count = 2, 644 }, 645 646 { 647 .n = "flex1_gclk", 648 .id = 39, 649 .r = { .max = 200000000 }, 650 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 651 .ep_mux_table = { 5, 8, }, 652 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 653 .ep_count = 2, 654 }, 655 656 { 657 .n = "flex2_gclk", 658 .id = 40, 659 .r = { .max = 200000000 }, 660 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 661 .ep_mux_table = { 5, 8, }, 662 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 663 .ep_count = 2, 664 }, 665 666 { 667 .n = "flex3_gclk", 668 .id = 41, 669 .r = { .max = 200000000 }, 670 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 671 .ep_mux_table = { 5, 8, }, 672 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 673 .ep_count = 2, 674 }, 675 676 { 677 .n = "flex4_gclk", 678 .id = 42, 679 .r = { .max = 200000000 }, 680 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 681 .ep_mux_table = { 5, 8, }, 682 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 683 .ep_count = 2, 684 }, 685 686 { 687 .n = "flex5_gclk", 688 .id = 43, 689 .r = { .max = 200000000 }, 690 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 691 .ep_mux_table = { 5, 8, }, 692 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 693 .ep_count = 2, 694 }, 695 696 { 697 .n = "flex6_gclk", 698 .id = 44, 699 .r = { .max = 200000000 }, 700 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 701 .ep_mux_table = { 5, 8, }, 702 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 703 .ep_count = 2, 704 }, 705 706 { 707 .n = "flex7_gclk", 708 .id = 45, 709 .r = { .max = 200000000 }, 710 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 711 .ep_mux_table = { 5, 8, }, 712 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 713 .ep_count = 2, 714 }, 715 716 { 717 .n = "flex8_gclk", 718 .id = 46, 719 .r = { .max = 200000000 }, 720 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 721 .ep_mux_table = { 5, 8, }, 722 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 723 .ep_count = 2, 724 }, 725 726 { 727 .n = "flex9_gclk", 728 .id = 47, 729 .r = { .max = 200000000 }, 730 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 731 .ep_mux_table = { 5, 8, }, 732 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 733 .ep_count = 2, 734 }, 735 736 { 737 .n = "flex10_gclk", 738 .id = 48, 739 .r = { .max = 200000000 }, 740 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 741 .ep_mux_table = { 5, 8, }, 742 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 743 .ep_count = 2, 744 }, 745 746 { 747 .n = "flex11_gclk", 748 .id = 49, 749 .r = { .max = 200000000 }, 750 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 751 .ep_mux_table = { 5, 8, }, 752 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 753 .ep_count = 2, 754 }, 755 756 { 757 .n = "gmac0_gclk", 758 .id = 51, 759 .r = { .max = 125000000 }, 760 .ep = { "ethpll_divpmcck", }, 761 .ep_clk_mux_table = { ID_PLL_ETH_DIV, }, 762 .ep_mux_table = { 10, }, 763 .ep_count = 1, 764 }, 765 766 { 767 .n = "gmac1_gclk", 768 .id = 52, 769 .r = { .max = 50000000 }, 770 .ep = { "ethpll_divpmcck", }, 771 .ep_mux_table = { 10, }, 772 .ep_clk_mux_table = { ID_PLL_ETH_DIV, }, 773 .ep_count = 1, 774 }, 775 776 { 777 .n = "gmac0_tsu_gclk", 778 .id = 53, 779 .r = { .max = 300000000 }, 780 .ep = { "audiopll_divpmcck", "ethpll_divpmcck", }, 781 .ep_mux_table = { 9, 10, }, 782 .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_ETH_DIV, }, 783 .ep_count = 2, 784 }, 785 786 { 787 .n = "gmac1_tsu_gclk", 788 .id = 54, 789 .r = { .max = 300000000 }, 790 .ep = { "audiopll_divpmcck", "ethpll_divpmcck", }, 791 .ep_mux_table = { 9, 10, }, 792 .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_ETH_DIV, }, 793 .ep_count = 2, 794 }, 795 796 { 797 .n = "i2smcc0_gclk", 798 .id = 57, 799 .r = { .max = 100000000 }, 800 .ep = { "syspll_divpmcck", "audiopll_divpmcck", }, 801 .ep_mux_table = { 5, 9, }, 802 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, }, 803 .ep_count = 2, 804 }, 805 806 { 807 .n = "i2smcc1_gclk", 808 .id = 58, 809 .r = { .max = 100000000 }, 810 .ep = { "syspll_divpmcck", "audiopll_divpmcck", }, 811 .ep_mux_table = { 5, 9, }, 812 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, }, 813 .ep_count = 2, 814 }, 815 816 { 817 .n = "mcan0_gclk", 818 .id = 61, 819 .r = { .max = 200000000 }, 820 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 821 .ep_mux_table = { 5, 8, }, 822 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 823 .ep_count = 2, 824 }, 825 826 { 827 .n = "mcan1_gclk", 828 .id = 62, 829 .r = { .max = 200000000 }, 830 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 831 .ep_mux_table = { 5, 8, }, 832 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 833 .ep_count = 2, 834 }, 835 836 { 837 .n = "mcan2_gclk", 838 .id = 63, 839 .r = { .max = 200000000 }, 840 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 841 .ep_mux_table = { 5, 8, }, 842 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 843 .ep_count = 2, 844 }, 845 846 { 847 .n = "mcan3_gclk", 848 .id = 64, 849 .r = { .max = 200000000 }, 850 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 851 .ep_mux_table = { 5, 8, }, 852 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 853 .ep_count = 2, 854 }, 855 856 { 857 .n = "mcan4_gclk", 858 .id = 65, 859 .r = { .max = 200000000 }, 860 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 861 .ep_mux_table = { 5, 8, }, 862 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 863 .ep_count = 2, 864 }, 865 866 { 867 .n = "mcan5_gclk", 868 .id = 66, 869 .r = { .max = 200000000 }, 870 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 871 .ep_mux_table = { 5, 8, }, 872 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 873 .ep_count = 2, 874 }, 875 876 { 877 .n = "pdmc0_gclk", 878 .id = 68, 879 .r = { .max = 50000000 }, 880 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 881 .ep_mux_table = { 5, 8, }, 882 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 883 .ep_count = 2, 884 }, 885 886 { 887 .n = "pdmc1_gclk", 888 .id = 69, 889 .r = { .max = 50000000, }, 890 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 891 .ep_mux_table = { 5, 8, }, 892 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 893 .ep_count = 2, 894 }, 895 896 { 897 .n = "pit64b0_gclk", 898 .id = 70, 899 .r = { .max = 200000000 }, 900 .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 901 "audiopll_divpmcck", "ethpll_divpmcck", }, 902 .ep_mux_table = { 5, 7, 8, 9, 10, }, 903 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV, 904 ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC, 905 ID_PLL_ETH_DIV, }, 906 .ep_count = 5, 907 }, 908 909 { 910 .n = "pit64b1_gclk", 911 .id = 71, 912 .r = { .max = 200000000 }, 913 .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 914 "audiopll_divpmcck", "ethpll_divpmcck", }, 915 .ep_mux_table = { 5, 7, 8, 9, 10, }, 916 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV, 917 ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC, 918 ID_PLL_ETH_DIV, }, 919 .ep_count = 5, 920 }, 921 922 { 923 .n = "pit64b2_gclk", 924 .id = 72, 925 .r = { .max = 200000000 }, 926 .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 927 "audiopll_divpmcck", "ethpll_divpmcck", }, 928 .ep_mux_table = { 5, 7, 8, 9, 10, }, 929 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV, 930 ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC, 931 ID_PLL_ETH_DIV, }, 932 .ep_count = 5, 933 }, 934 935 { 936 .n = "pit64b3_gclk", 937 .id = 73, 938 .r = { .max = 200000000 }, 939 .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 940 "audiopll_divpmcck", "ethpll_divpmcck", }, 941 .ep_mux_table = { 5, 7, 8, 9, 10, }, 942 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV, 943 ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC, 944 ID_PLL_ETH_DIV, }, 945 .ep_count = 5, 946 }, 947 948 { 949 .n = "pit64b4_gclk", 950 .id = 74, 951 .r = { .max = 200000000 }, 952 .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 953 "audiopll_divpmcck", "ethpll_divpmcck", }, 954 .ep_mux_table = { 5, 7, 8, 9, 10, }, 955 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV, 956 ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC, 957 ID_PLL_ETH_DIV, }, 958 .ep_count = 5, 959 }, 960 961 { 962 .n = "pit64b5_gclk", 963 .id = 75, 964 .r = { .max = 200000000 }, 965 .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 966 "audiopll_divpmcck", "ethpll_divpmcck", }, 967 .ep_mux_table = { 5, 7, 8, 9, 10, }, 968 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV, 969 ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC, 970 ID_PLL_ETH_DIV, }, 971 .ep_count = 5, 972 }, 973 974 { 975 .n = "qspi0_gclk", 976 .id = 78, 977 .r = { .max = 200000000 }, 978 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 979 .ep_mux_table = { 5, 8, }, 980 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV, 981 ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC, 982 ID_PLL_ETH_DIV, }, 983 .ep_count = 2, 984 }, 985 986 { 987 .n = "qspi1_gclk", 988 .id = 79, 989 .r = { .max = 200000000 }, 990 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 991 .ep_mux_table = { 5, 8, }, 992 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 993 .ep_count = 2, 994 }, 995 996 { 997 .n = "sdmmc0_gclk", 998 .id = 80, 999 .r = { .max = 208000000 }, 1000 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 1001 .ep_mux_table = { 5, 8, }, 1002 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 1003 .ep_count = 2, 1004 }, 1005 1006 { 1007 .n = "sdmmc1_gclk", 1008 .id = 81, 1009 .r = { .max = 208000000 }, 1010 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 1011 .ep_mux_table = { 5, 8, }, 1012 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 1013 .ep_count = 2, 1014 }, 1015 1016 { 1017 .n = "sdmmc2_gclk", 1018 .id = 82, 1019 .r = { .max = 208000000 }, 1020 .ep = { "syspll_divpmcck", "baudpll_divpmcck", }, 1021 .ep_mux_table = { 5, 8, }, 1022 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, }, 1023 .ep_count = 2, 1024 }, 1025 1026 { 1027 .n = "spdifrx_gclk", 1028 .id = 84, 1029 .r = { .max = 150000000 }, 1030 .ep = { "syspll_divpmcck", "audiopll_divpmcck", }, 1031 .ep_mux_table = { 5, 9, }, 1032 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, }, 1033 .ep_count = 2, 1034 }, 1035 1036 { 1037 .n = "spdiftx_gclk", 1038 .id = 85, 1039 .r = { .max = 25000000 }, 1040 .ep = { "syspll_divpmcck", "audiopll_divpmcck", }, 1041 .ep_mux_table = { 5, 9, }, 1042 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, }, 1043 .ep_count = 2, 1044 }, 1045 1046 { 1047 .n = "tcb0_ch0_gclk", 1048 .id = 88, 1049 .r = { .max = 200000000 }, 1050 .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 1051 "audiopll_divpmcck", "ethpll_divpmcck", }, 1052 .ep_mux_table = { 5, 7, 8, 9, 10, }, 1053 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV, 1054 ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC, 1055 ID_PLL_ETH_DIV, }, 1056 .ep_count = 5, 1057 }, 1058 1059 { 1060 .n = "tcb1_ch0_gclk", 1061 .id = 91, 1062 .r = { .max = 200000000 }, 1063 .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck", 1064 "audiopll_divpmcck", "ethpll_divpmcck", }, 1065 .ep_mux_table = { 5, 7, 8, 9, 10, }, 1066 .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV, 1067 ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC, 1068 ID_PLL_ETH_DIV, }, 1069 .ep_count = 5, 1070 }, 1071}; 1072 1073/* Clock setup description */ 1074static const struct pmc_clk_setup sama7g5_clk_setup[] = { 1075 { 1076 .cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_ETH_FRAC), 1077 .rate = 625000000, 1078 }, 1079 1080 { 1081 .cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_ETH_DIV), 1082 .rate = 625000000, 1083 }, 1084}; 1085 1086#define SAMA7G5_MAX_MUX_ALLOCS (64) 1087 1088#define prepare_mux_table(_allocs, _index, _dst, _src, _num, _label) \ 1089 do { \ 1090 int _i; \ 1091 if ((_index) >= SAMA7G5_MAX_MUX_ALLOCS) { \ 1092 debug("%s(): AT91: MUX: insufficient space\n", \ 1093 __func__); \ 1094 goto _label; \ 1095 } \ 1096 (_dst) = kzalloc(sizeof(*(_dst)) * (_num), GFP_KERNEL); \ 1097 if (!(_dst)) \ 1098 goto _label; \ 1099 (_allocs)[(_index)++] = (_dst); \ 1100 for (_i = 0; _i < (_num); _i++) \ 1101 (_dst)[_i] = (_src)[_i]; \ 1102 } while (0) 1103 1104static int sama7g5_clk_probe(struct udevice *dev) 1105{ 1106 void __iomem *base = devfdt_get_addr_ptr(dev); 1107 unsigned int *clkmuxallocs[SAMA7G5_MAX_MUX_ALLOCS]; 1108 unsigned int *muxallocs[SAMA7G5_MAX_MUX_ALLOCS]; 1109 const char *p[10]; 1110 unsigned int cm[10], m[10], *tmpclkmux, *tmpmux; 1111 struct clk clk, *c; 1112 bool main_osc_bypass; 1113 int ret, muxallocindex = 0, clkmuxallocindex = 0, i, j; 1114 1115 if (IS_ERR(base)) 1116 return PTR_ERR(base); 1117 1118 memset(muxallocs, 0, sizeof(muxallocs)); 1119 memset(clkmuxallocs, 0, sizeof(clkmuxallocs)); 1120 1121 ret = clk_get_by_index(dev, 0, &clk); 1122 if (ret) 1123 return ret; 1124 ret = clk_get_by_id(clk.id, &c); 1125 if (ret) 1126 return ret; 1127 clk_names[ID_TD_SLCK] = kmemdup(clk_hw_get_name(c), 1128 strlen(clk_hw_get_name(c)) + 1, GFP_KERNEL); 1129 if (!clk_names[ID_TD_SLCK]) 1130 return -ENOMEM; 1131 1132 ret = clk_get_by_index(dev, 1, &clk); 1133 if (ret) 1134 return ret; 1135 ret = clk_get_by_id(clk.id, &c); 1136 if (ret) 1137 return ret; 1138 clk_names[ID_MD_SLCK] = kmemdup(clk_hw_get_name(c), 1139 strlen(clk_hw_get_name(c)) + 1, GFP_KERNEL); 1140 if (!clk_names[ID_MD_SLCK]) 1141 return -ENOMEM; 1142 1143 ret = clk_get_by_index(dev, 2, &clk); 1144 if (ret) 1145 return ret; 1146 clk_names[ID_MAIN_XTAL] = kmemdup(clk_hw_get_name(&clk), 1147 strlen(clk_hw_get_name(&clk)) + 1, GFP_KERNEL); 1148 if (!clk_names[ID_MAIN_XTAL]) 1149 return -ENOMEM; 1150 1151 ret = clk_get_by_index(dev, 3, &clk); 1152 if (ret) 1153 goto fail; 1154 clk_names[ID_MAIN_RC] = kmemdup(clk_hw_get_name(&clk), 1155 strlen(clk_hw_get_name(&clk)) + 1, GFP_KERNEL); 1156 if (ret) 1157 goto fail; 1158 1159 main_osc_bypass = dev_read_bool(dev, "atmel,main-osc-bypass"); 1160 1161 /* Register main rc oscillator. */ 1162 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC), 1163 at91_clk_main_rc(base, clk_names[ID_MAIN_RC_OSC], 1164 clk_names[ID_MAIN_RC])); 1165 1166 /* Register main oscillator. */ 1167 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC), 1168 at91_clk_main_osc(base, clk_names[ID_MAIN_OSC], 1169 clk_names[ID_MAIN_XTAL], main_osc_bypass)); 1170 1171 /* Register mainck. */ 1172 p[0] = clk_names[ID_MAIN_RC_OSC]; 1173 p[1] = clk_names[ID_MAIN_OSC]; 1174 cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC); 1175 cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC); 1176 prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2, 1177 fail); 1178 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK), 1179 at91_clk_sam9x5_main(base, clk_names[ID_MAINCK], p, 1180 2, tmpclkmux, PMC_TYPE_CORE)); 1181 1182 /* Register PLL fracs clocks. */ 1183 for (i = 0; i < ARRAY_SIZE(sama7g5_plls); i++) { 1184 if (sama7g5_plls[i].t != PLL_TYPE_FRAC) 1185 continue; 1186 1187 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_plls[i].cid), 1188 sam9x60_clk_register_frac_pll(base, sama7g5_plls[i].n, 1189 sama7g5_plls[i].p, sama7g5_plls[i].id, 1190 &pll_characteristics, sama7g5_plls[i].l, 1191 sama7g5_plls[i].c)); 1192 } 1193 1194 /* Register PLL div clocks. */ 1195 for (i = 0; i < ARRAY_SIZE(sama7g5_plls); i++) { 1196 if (sama7g5_plls[i].t != PLL_TYPE_DIV) 1197 continue; 1198 1199 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_plls[i].cid), 1200 sam9x60_clk_register_div_pll(base, sama7g5_plls[i].n, 1201 sama7g5_plls[i].p, sama7g5_plls[i].id, 1202 &pll_characteristics, sama7g5_plls[i].l, 1203 sama7g5_plls[i].c)); 1204 } 1205 1206 /* Register MCK0_PRES clock. */ 1207 p[0] = clk_names[ID_MD_SLCK]; 1208 p[1] = clk_names[ID_MAINCK]; 1209 p[2] = clk_names[ID_PLL_CPU_DIV]; 1210 p[3] = clk_names[ID_PLL_SYS_DIV]; 1211 cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); 1212 cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); 1213 cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_CPU_DIV); 1214 cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_SYS_DIV); 1215 prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2, 1216 fail); 1217 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_PRES), 1218 at91_clk_register_master_pres(base, clk_names[ID_MCK0_PRES], p, 1219 4, &mck0_layout, &mck0_characteristics, tmpclkmux)); 1220 1221 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_DIV), 1222 at91_clk_register_master_div(base, clk_names[ID_MCK0_DIV], 1223 clk_names[ID_MCK0_PRES], &mck0_layout, &mck0_characteristics)); 1224 1225 /* Register MCK1-4 clocks. */ 1226 p[0] = clk_names[ID_MD_SLCK]; 1227 p[1] = clk_names[ID_TD_SLCK]; 1228 p[2] = clk_names[ID_MAINCK]; 1229 p[3] = clk_names[ID_MCK0_DIV]; 1230 m[0] = 0; 1231 m[1] = 1; 1232 m[2] = 2; 1233 m[3] = 3; 1234 cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); 1235 cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); 1236 cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); 1237 cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_DIV); 1238 for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) { 1239 for (j = 0; j < sama7g5_mckx[i].ep_count; j++) { 1240 p[4 + j] = sama7g5_mckx[i].ep[j]; 1241 m[4 + j] = sama7g5_mckx[i].ep_mux_table[j]; 1242 cm[4 + j] = AT91_TO_CLK_ID(PMC_TYPE_CORE, 1243 sama7g5_mckx[i].ep_clk_mux_table[j]); 1244 } 1245 1246 prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 1247 4 + sama7g5_mckx[i].ep_count, fail); 1248 prepare_mux_table(muxallocs, muxallocindex, tmpmux, m, 1249 4 + sama7g5_mckx[i].ep_count, fail); 1250 1251 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_mckx[i].cid), 1252 at91_clk_sama7g5_register_master(base, 1253 sama7g5_mckx[i].n, p, 4 + sama7g5_mckx[i].ep_count, 1254 tmpmux, tmpclkmux, sama7g5_mckx[i].c, 1255 sama7g5_mckx[i].id)); 1256 } 1257 1258 /* Register UTMI clock. */ 1259 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_UTMI), 1260 at91_clk_sama7g5_register_utmi(base, "utmick", 1261 clk_names[ID_MAIN_XTAL])); 1262 1263 /* Register programmable clocks. */ 1264 p[0] = clk_names[ID_MD_SLCK]; 1265 p[1] = clk_names[ID_TD_SLCK]; 1266 p[2] = clk_names[ID_MAINCK]; 1267 p[3] = clk_names[ID_MCK0_DIV]; 1268 p[4] = clk_names[ID_PLL_SYS_DIV]; 1269 p[5] = clk_names[ID_PLL_DDR_DIV]; 1270 p[6] = clk_names[ID_PLL_IMG_DIV]; 1271 p[7] = clk_names[ID_PLL_BAUD_DIV]; 1272 p[8] = clk_names[ID_PLL_AUDIO_DIVPMC]; 1273 p[9] = clk_names[ID_PLL_ETH_DIV]; 1274 cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); 1275 cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); 1276 cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); 1277 cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_DIV); 1278 cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_SYS_DIV); 1279 cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_DDR_DIV); 1280 cm[6] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_IMG_DIV); 1281 cm[7] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_BAUD_DIV); 1282 cm[8] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_AUDIO_DIVPMC); 1283 cm[9] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_ETH_DIV); 1284 for (i = 0; i < ARRAY_SIZE(sama7g5_prog); i++) { 1285 prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 1286 10, fail); 1287 1288 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_prog[i].cid), 1289 at91_clk_register_programmable(base, sama7g5_prog[i].n, 1290 p, 10, i, &programmable_layout, tmpclkmux, 1291 sama7g5_prog_mux_table)); 1292 } 1293 1294 /* System clocks. */ 1295 for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) { 1296 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_SYSTEM, sama7g5_systemck[i].cid), 1297 at91_clk_register_system(base, sama7g5_systemck[i].n, 1298 sama7g5_systemck[i].p, sama7g5_systemck[i].id)); 1299 } 1300 1301 /* Peripheral clocks. */ 1302 for (i = 0; i < ARRAY_SIZE(sama7g5_periphck); i++) { 1303 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_PERIPHERAL, 1304 sama7g5_periphck[i].id), 1305 at91_clk_register_sam9x5_peripheral(base, 1306 &sama7g5_pcr_layout, sama7g5_periphck[i].n, 1307 sama7g5_periphck[i].p, sama7g5_periphck[i].id, 1308 &sama7g5_periphck[i].r)); 1309 } 1310 1311 /* Generic clocks. */ 1312 p[0] = clk_names[ID_MD_SLCK]; 1313 p[1] = clk_names[ID_TD_SLCK]; 1314 p[2] = clk_names[ID_MAINCK]; 1315 p[3] = clk_names[ID_MCK0_DIV]; 1316 m[0] = 0; 1317 m[1] = 1; 1318 m[2] = 2; 1319 m[3] = 3; 1320 cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK); 1321 cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK); 1322 cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK); 1323 cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0_DIV); 1324 for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) { 1325 for (j = 0; j < sama7g5_gck[i].ep_count; j++) { 1326 p[4 + j] = sama7g5_gck[i].ep[j]; 1327 m[4 + j] = sama7g5_gck[i].ep_mux_table[j]; 1328 cm[4 + j] = AT91_TO_CLK_ID(PMC_TYPE_CORE, 1329 sama7g5_gck[i].ep_clk_mux_table[j]); 1330 } 1331 1332 prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 1333 4 + sama7g5_gck[i].ep_count, fail); 1334 prepare_mux_table(muxallocs, muxallocindex, tmpmux, m, 1335 4 + sama7g5_gck[i].ep_count, fail); 1336 1337 clk_dm(AT91_TO_CLK_ID(PMC_TYPE_GCK, sama7g5_gck[i].id), 1338 at91_clk_register_generic(base, &sama7g5_pcr_layout, 1339 sama7g5_gck[i].n, p, tmpclkmux, tmpmux, 1340 4 + sama7g5_gck[i].ep_count, sama7g5_gck[i].id, 1341 &sama7g5_gck[i].r)); 1342 } 1343 1344 /* Setup clocks. */ 1345 ret = at91_clk_setup(sama7g5_clk_setup, ARRAY_SIZE(sama7g5_clk_setup)); 1346 if (ret) 1347 goto fail; 1348 1349 return 0; 1350 1351fail: 1352 for (i = 0; i < ARRAY_SIZE(muxallocs); i++) 1353 kfree(muxallocs[i]); 1354 1355 for (i = 0; i < ARRAY_SIZE(clkmuxallocs); i++) 1356 kfree(clkmuxallocs[i]); 1357 1358 return -ENOMEM; 1359} 1360 1361static const struct udevice_id sama7g5_clk_ids[] = { 1362 { .compatible = "microchip,sama7g5-pmc" }, 1363 { /* Sentinel. */ }, 1364}; 1365 1366U_BOOT_DRIVER(at91_sama7g5_pmc) = { 1367 .name = "at91-sama7g5-pmc", 1368 .id = UCLASS_CLK, 1369 .of_match = sama7g5_clk_ids, 1370 .ops = &at91_clk_ops, 1371 .probe = sama7g5_clk_probe, 1372 .flags = DM_FLAG_PRE_RELOC, 1373}; 1374