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

clk: meson: g12a: add cpu clocks

Add the Amlogic G12A Family CPU Clock tree in read/only for now.

The CPU clock can either use the SYS_PLL for > 1GHz frequencies or
use a couple of div+mux from 1GHz/667MHz/24MHz source with 2 non-glitch
muxes.

Proper DVFS support will come in a second time.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Acked-by: Jerome Brunet <jbrunet@baylibre.com>
[narmstrong: fixed cpu clocks namings]
Link: https://lkml.kernel.org/r/20190304131129.7762-3-narmstrong@baylibre.com

+371 -1
+350
drivers/clk/meson/g12a.c
··· 150 150 }, 151 151 }; 152 152 153 + static struct clk_regmap g12a_sys_pll_div16_en = { 154 + .data = &(struct clk_regmap_gate_data){ 155 + .offset = HHI_SYS_CPU_CLK_CNTL1, 156 + .bit_idx = 24, 157 + }, 158 + .hw.init = &(struct clk_init_data) { 159 + .name = "sys_pll_div16_en", 160 + .ops = &clk_regmap_gate_ro_ops, 161 + .parent_names = (const char *[]){ "sys_pll" }, 162 + .num_parents = 1, 163 + /* 164 + * This clock is used to debug the sys_pll range 165 + * Linux should not change it at runtime 166 + */ 167 + }, 168 + }; 169 + 170 + static struct clk_fixed_factor g12a_sys_pll_div16 = { 171 + .mult = 1, 172 + .div = 16, 173 + .hw.init = &(struct clk_init_data){ 174 + .name = "sys_pll_div16", 175 + .ops = &clk_fixed_factor_ops, 176 + .parent_names = (const char *[]){ "sys_pll_div16_en" }, 177 + .num_parents = 1, 178 + }, 179 + }; 180 + 181 + /* Datasheet names this field as "premux0" */ 182 + static struct clk_regmap g12a_cpu_clk_premux0 = { 183 + .data = &(struct clk_regmap_mux_data){ 184 + .offset = HHI_SYS_CPU_CLK_CNTL0, 185 + .mask = 0x3, 186 + .shift = 0, 187 + }, 188 + .hw.init = &(struct clk_init_data){ 189 + .name = "cpu_clk_dyn0_sel", 190 + .ops = &clk_regmap_mux_ro_ops, 191 + .parent_names = (const char *[]){ IN_PREFIX "xtal", 192 + "fclk_div2", 193 + "fclk_div3" }, 194 + .num_parents = 3, 195 + }, 196 + }; 197 + 198 + /* Datasheet names this field as "mux0_divn_tcnt" */ 199 + static struct clk_regmap g12a_cpu_clk_mux0_div = { 200 + .data = &(struct clk_regmap_div_data){ 201 + .offset = HHI_SYS_CPU_CLK_CNTL0, 202 + .shift = 4, 203 + .width = 6, 204 + }, 205 + .hw.init = &(struct clk_init_data){ 206 + .name = "cpu_clk_dyn0_div", 207 + .ops = &clk_regmap_divider_ro_ops, 208 + .parent_names = (const char *[]){ "cpu_clk_dyn0_sel" }, 209 + .num_parents = 1, 210 + }, 211 + }; 212 + 213 + /* Datasheet names this field as "postmux0" */ 214 + static struct clk_regmap g12a_cpu_clk_postmux0 = { 215 + .data = &(struct clk_regmap_mux_data){ 216 + .offset = HHI_SYS_CPU_CLK_CNTL0, 217 + .mask = 0x1, 218 + .shift = 2, 219 + }, 220 + .hw.init = &(struct clk_init_data){ 221 + .name = "cpu_clk_dyn0", 222 + .ops = &clk_regmap_mux_ro_ops, 223 + .parent_names = (const char *[]){ "cpu_clk_dyn0_sel", 224 + "cpu_clk_dyn0_div" }, 225 + .num_parents = 2, 226 + }, 227 + }; 228 + 229 + /* Datasheet names this field as "premux1" */ 230 + static struct clk_regmap g12a_cpu_clk_premux1 = { 231 + .data = &(struct clk_regmap_mux_data){ 232 + .offset = HHI_SYS_CPU_CLK_CNTL0, 233 + .mask = 0x3, 234 + .shift = 16, 235 + }, 236 + .hw.init = &(struct clk_init_data){ 237 + .name = "cpu_clk_dyn1_sel", 238 + .ops = &clk_regmap_mux_ro_ops, 239 + .parent_names = (const char *[]){ IN_PREFIX "xtal", 240 + "fclk_div2", 241 + "fclk_div3" }, 242 + .num_parents = 3, 243 + }, 244 + }; 245 + 246 + /* Datasheet names this field as "Mux1_divn_tcnt" */ 247 + static struct clk_regmap g12a_cpu_clk_mux1_div = { 248 + .data = &(struct clk_regmap_div_data){ 249 + .offset = HHI_SYS_CPU_CLK_CNTL0, 250 + .shift = 20, 251 + .width = 6, 252 + }, 253 + .hw.init = &(struct clk_init_data){ 254 + .name = "cpu_clk_dyn1_div", 255 + .ops = &clk_regmap_divider_ro_ops, 256 + .parent_names = (const char *[]){ "cpu_clk_dyn1_sel" }, 257 + .num_parents = 1, 258 + }, 259 + }; 260 + 261 + /* Datasheet names this field as "postmux1" */ 262 + static struct clk_regmap g12a_cpu_clk_postmux1 = { 263 + .data = &(struct clk_regmap_mux_data){ 264 + .offset = HHI_SYS_CPU_CLK_CNTL0, 265 + .mask = 0x1, 266 + .shift = 18, 267 + }, 268 + .hw.init = &(struct clk_init_data){ 269 + .name = "cpu_clk_dyn1", 270 + .ops = &clk_regmap_mux_ro_ops, 271 + .parent_names = (const char *[]){ "cpu_clk_dyn1_sel", 272 + "cpu_clk_dyn1_div" }, 273 + .num_parents = 2, 274 + }, 275 + }; 276 + 277 + /* Datasheet names this field as "Final_dyn_mux_sel" */ 278 + static struct clk_regmap g12a_cpu_clk_dyn = { 279 + .data = &(struct clk_regmap_mux_data){ 280 + .offset = HHI_SYS_CPU_CLK_CNTL0, 281 + .mask = 0x1, 282 + .shift = 10, 283 + }, 284 + .hw.init = &(struct clk_init_data){ 285 + .name = "cpu_clk_dyn", 286 + .ops = &clk_regmap_mux_ro_ops, 287 + .parent_names = (const char *[]){ "cpu_clk_dyn0", 288 + "cpu_clk_dyn1" }, 289 + .num_parents = 2, 290 + }, 291 + }; 292 + 293 + /* Datasheet names this field as "Final_mux_sel" */ 294 + static struct clk_regmap g12a_cpu_clk = { 295 + .data = &(struct clk_regmap_mux_data){ 296 + .offset = HHI_SYS_CPU_CLK_CNTL0, 297 + .mask = 0x1, 298 + .shift = 11, 299 + }, 300 + .hw.init = &(struct clk_init_data){ 301 + .name = "cpu_clk", 302 + .ops = &clk_regmap_mux_ro_ops, 303 + .parent_names = (const char *[]){ "cpu_clk_dyn", 304 + "sys_pll" }, 305 + .num_parents = 2, 306 + }, 307 + }; 308 + 309 + static struct clk_regmap g12a_cpu_clk_div16_en = { 310 + .data = &(struct clk_regmap_gate_data){ 311 + .offset = HHI_SYS_CPU_CLK_CNTL1, 312 + .bit_idx = 1, 313 + }, 314 + .hw.init = &(struct clk_init_data) { 315 + .name = "cpu_clk_div16_en", 316 + .ops = &clk_regmap_gate_ro_ops, 317 + .parent_names = (const char *[]){ "cpu_clk" }, 318 + .num_parents = 1, 319 + /* 320 + * This clock is used to debug the cpu_clk range 321 + * Linux should not change it at runtime 322 + */ 323 + }, 324 + }; 325 + 326 + static struct clk_fixed_factor g12a_cpu_clk_div16 = { 327 + .mult = 1, 328 + .div = 16, 329 + .hw.init = &(struct clk_init_data){ 330 + .name = "cpu_clk_div16", 331 + .ops = &clk_fixed_factor_ops, 332 + .parent_names = (const char *[]){ "cpu_clk_div16_en" }, 333 + .num_parents = 1, 334 + }, 335 + }; 336 + 337 + static struct clk_regmap g12a_cpu_clk_apb_div = { 338 + .data = &(struct clk_regmap_div_data){ 339 + .offset = HHI_SYS_CPU_CLK_CNTL1, 340 + .shift = 3, 341 + .width = 3, 342 + .flags = CLK_DIVIDER_POWER_OF_TWO, 343 + }, 344 + .hw.init = &(struct clk_init_data){ 345 + .name = "cpu_clk_apb_div", 346 + .ops = &clk_regmap_divider_ro_ops, 347 + .parent_names = (const char *[]){ "cpu_clk" }, 348 + .num_parents = 1, 349 + }, 350 + }; 351 + 352 + static struct clk_regmap g12a_cpu_clk_apb = { 353 + .data = &(struct clk_regmap_gate_data){ 354 + .offset = HHI_SYS_CPU_CLK_CNTL1, 355 + .bit_idx = 1, 356 + }, 357 + .hw.init = &(struct clk_init_data) { 358 + .name = "cpu_clk_apb", 359 + .ops = &clk_regmap_gate_ro_ops, 360 + .parent_names = (const char *[]){ "cpu_clk_apb_div" }, 361 + .num_parents = 1, 362 + /* 363 + * This clock is set by the ROM monitor code, 364 + * Linux should not change it at runtime 365 + */ 366 + }, 367 + }; 368 + 369 + static struct clk_regmap g12a_cpu_clk_atb_div = { 370 + .data = &(struct clk_regmap_div_data){ 371 + .offset = HHI_SYS_CPU_CLK_CNTL1, 372 + .shift = 6, 373 + .width = 3, 374 + .flags = CLK_DIVIDER_POWER_OF_TWO, 375 + }, 376 + .hw.init = &(struct clk_init_data){ 377 + .name = "cpu_clk_atb_div", 378 + .ops = &clk_regmap_divider_ro_ops, 379 + .parent_names = (const char *[]){ "cpu_clk" }, 380 + .num_parents = 1, 381 + }, 382 + }; 383 + 384 + static struct clk_regmap g12a_cpu_clk_atb = { 385 + .data = &(struct clk_regmap_gate_data){ 386 + .offset = HHI_SYS_CPU_CLK_CNTL1, 387 + .bit_idx = 17, 388 + }, 389 + .hw.init = &(struct clk_init_data) { 390 + .name = "cpu_clk_atb", 391 + .ops = &clk_regmap_gate_ro_ops, 392 + .parent_names = (const char *[]){ "cpu_clk_atb_div" }, 393 + .num_parents = 1, 394 + /* 395 + * This clock is set by the ROM monitor code, 396 + * Linux should not change it at runtime 397 + */ 398 + }, 399 + }; 400 + 401 + static struct clk_regmap g12a_cpu_clk_axi_div = { 402 + .data = &(struct clk_regmap_div_data){ 403 + .offset = HHI_SYS_CPU_CLK_CNTL1, 404 + .shift = 9, 405 + .width = 3, 406 + .flags = CLK_DIVIDER_POWER_OF_TWO, 407 + }, 408 + .hw.init = &(struct clk_init_data){ 409 + .name = "cpu_clk_axi_div", 410 + .ops = &clk_regmap_divider_ro_ops, 411 + .parent_names = (const char *[]){ "cpu_clk" }, 412 + .num_parents = 1, 413 + }, 414 + }; 415 + 416 + static struct clk_regmap g12a_cpu_clk_axi = { 417 + .data = &(struct clk_regmap_gate_data){ 418 + .offset = HHI_SYS_CPU_CLK_CNTL1, 419 + .bit_idx = 18, 420 + }, 421 + .hw.init = &(struct clk_init_data) { 422 + .name = "cpu_clk_axi", 423 + .ops = &clk_regmap_gate_ro_ops, 424 + .parent_names = (const char *[]){ "cpu_clk_axi_div" }, 425 + .num_parents = 1, 426 + /* 427 + * This clock is set by the ROM monitor code, 428 + * Linux should not change it at runtime 429 + */ 430 + }, 431 + }; 432 + 433 + static struct clk_regmap g12a_cpu_clk_trace_div = { 434 + .data = &(struct clk_regmap_div_data){ 435 + .offset = HHI_SYS_CPU_CLK_CNTL1, 436 + .shift = 20, 437 + .width = 3, 438 + .flags = CLK_DIVIDER_POWER_OF_TWO, 439 + }, 440 + .hw.init = &(struct clk_init_data){ 441 + .name = "cpu_clk_trace_div", 442 + .ops = &clk_regmap_divider_ro_ops, 443 + .parent_names = (const char *[]){ "cpu_clk" }, 444 + .num_parents = 1, 445 + }, 446 + }; 447 + 448 + static struct clk_regmap g12a_cpu_clk_trace = { 449 + .data = &(struct clk_regmap_gate_data){ 450 + .offset = HHI_SYS_CPU_CLK_CNTL1, 451 + .bit_idx = 23, 452 + }, 453 + .hw.init = &(struct clk_init_data) { 454 + .name = "cpu_clk_trace", 455 + .ops = &clk_regmap_gate_ro_ops, 456 + .parent_names = (const char *[]){ "cpu_clk_trace_div" }, 457 + .num_parents = 1, 458 + /* 459 + * This clock is set by the ROM monitor code, 460 + * Linux should not change it at runtime 461 + */ 462 + }, 463 + }; 464 + 153 465 static const struct pll_mult_range g12a_gp0_pll_mult_range = { 154 466 .min = 55, 155 467 .max = 255, ··· 2479 2167 [CLKID_MALI] = &g12a_mali.hw, 2480 2168 [CLKID_MPLL_5OM_DIV] = &g12a_mpll_50m_div.hw, 2481 2169 [CLKID_MPLL_5OM] = &g12a_mpll_50m.hw, 2170 + [CLKID_SYS_PLL_DIV16_EN] = &g12a_sys_pll_div16_en.hw, 2171 + [CLKID_SYS_PLL_DIV16] = &g12a_sys_pll_div16.hw, 2172 + [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_premux0.hw, 2173 + [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_mux0_div.hw, 2174 + [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_postmux0.hw, 2175 + [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_premux1.hw, 2176 + [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_mux1_div.hw, 2177 + [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_postmux1.hw, 2178 + [CLKID_CPU_CLK_DYN] = &g12a_cpu_clk_dyn.hw, 2179 + [CLKID_CPU_CLK] = &g12a_cpu_clk.hw, 2180 + [CLKID_CPU_CLK_DIV16_EN] = &g12a_cpu_clk_div16_en.hw, 2181 + [CLKID_CPU_CLK_DIV16] = &g12a_cpu_clk_div16.hw, 2182 + [CLKID_CPU_CLK_APB_DIV] = &g12a_cpu_clk_apb_div.hw, 2183 + [CLKID_CPU_CLK_APB] = &g12a_cpu_clk_apb.hw, 2184 + [CLKID_CPU_CLK_ATB_DIV] = &g12a_cpu_clk_atb_div.hw, 2185 + [CLKID_CPU_CLK_ATB] = &g12a_cpu_clk_atb.hw, 2186 + [CLKID_CPU_CLK_AXI_DIV] = &g12a_cpu_clk_axi_div.hw, 2187 + [CLKID_CPU_CLK_AXI] = &g12a_cpu_clk_axi.hw, 2188 + [CLKID_CPU_CLK_TRACE_DIV] = &g12a_cpu_clk_trace_div.hw, 2189 + [CLKID_CPU_CLK_TRACE] = &g12a_cpu_clk_trace.hw, 2482 2190 [NR_CLKS] = NULL, 2483 2191 }, 2484 2192 .num = NR_CLKS, ··· 2667 2335 &g12a_mali_1, 2668 2336 &g12a_mali, 2669 2337 &g12a_mpll_50m, 2338 + &g12a_sys_pll_div16_en, 2339 + &g12a_cpu_clk_premux0, 2340 + &g12a_cpu_clk_mux0_div, 2341 + &g12a_cpu_clk_postmux0, 2342 + &g12a_cpu_clk_premux1, 2343 + &g12a_cpu_clk_mux1_div, 2344 + &g12a_cpu_clk_postmux1, 2345 + &g12a_cpu_clk_dyn, 2346 + &g12a_cpu_clk, 2347 + &g12a_cpu_clk_div16_en, 2348 + &g12a_cpu_clk_apb_div, 2349 + &g12a_cpu_clk_apb, 2350 + &g12a_cpu_clk_atb_div, 2351 + &g12a_cpu_clk_atb, 2352 + &g12a_cpu_clk_axi_div, 2353 + &g12a_cpu_clk_axi, 2354 + &g12a_cpu_clk_trace_div, 2355 + &g12a_cpu_clk_trace, 2670 2356 }; 2671 2357 2672 2358 static const struct meson_eeclkc_data g12a_clkc_data = {
+21 -1
drivers/clk/meson/g12a.h
··· 50 50 #define HHI_GCLK_MPEG2 0x148 51 51 #define HHI_GCLK_OTHER 0x150 52 52 #define HHI_GCLK_OTHER2 0x154 53 + #define HHI_SYS_CPU_CLK_CNTL1 0x15c 53 54 #define HHI_VID_CLK_DIV 0x164 54 55 #define HHI_MPEG_CLK_CNTL 0x174 55 56 #define HHI_AUD_CLK_CNTL 0x178 ··· 167 166 #define CLKID_MALI_0_DIV 170 168 167 #define CLKID_MALI_1_DIV 173 169 168 #define CLKID_MPLL_5OM_DIV 176 169 + #define CLKID_SYS_PLL_DIV16_EN 178 170 + #define CLKID_SYS_PLL_DIV16 179 171 + #define CLKID_CPU_CLK_DYN0_SEL 180 172 + #define CLKID_CPU_CLK_DYN0_DIV 181 173 + #define CLKID_CPU_CLK_DYN0 182 174 + #define CLKID_CPU_CLK_DYN1_SEL 183 175 + #define CLKID_CPU_CLK_DYN1_DIV 184 176 + #define CLKID_CPU_CLK_DYN1 185 177 + #define CLKID_CPU_CLK_DYN 186 178 + #define CLKID_CPU_CLK_DIV16_EN 188 179 + #define CLKID_CPU_CLK_DIV16 189 180 + #define CLKID_CPU_CLK_APB_DIV 190 181 + #define CLKID_CPU_CLK_APB 191 182 + #define CLKID_CPU_CLK_ATB_DIV 192 183 + #define CLKID_CPU_CLK_ATB 193 184 + #define CLKID_CPU_CLK_AXI_DIV 194 185 + #define CLKID_CPU_CLK_AXI 195 186 + #define CLKID_CPU_CLK_TRACE_DIV 196 187 + #define CLKID_CPU_CLK_TRACE 197 170 188 171 - #define NR_CLKS 178 189 + #define NR_CLKS 198 172 190 173 191 /* include the CLKIDs that have been made part of the DT binding */ 174 192 #include <dt-bindings/clock/g12a-clkc.h>