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

clk: st: Support for PLLs inside ClockGenA(s)

The patch supports the c65/c32 type PLLs used by ClockGenA(s)

PLL clock : It includes support for all c65/c32 type PLLs
inside ClockGenA(s) : implemented as Fixed Parent / Fixed Rate clock,
with clock rate calculated reading H/w settings done at BOOT.

c65 PLLs have 2 outputs : HS and LS
c32 PLLs have 1-4 outputs : ODFx

Signed-off-by: Pankaj Dev <pankaj.dev@st.com>
Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>

authored by

Gabriel FERNANDEZ and committed by
Mike Turquette
b9b8e614 94885faf

+608 -1
+1 -1
drivers/clk/st/Makefile
··· 1 - obj-y += clkgen-mux.o 1 + obj-y += clkgen-mux.o clkgen-pll.o
+559
drivers/clk/st/clkgen-pll.c
··· 1 + /* 2 + * Copyright (C) 2014 STMicroelectronics (R&D) Limited 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + */ 10 + 11 + /* 12 + * Authors: 13 + * Stephen Gallimore <stephen.gallimore@st.com>, 14 + * Pankaj Dev <pankaj.dev@st.com>. 15 + */ 16 + 17 + #include <linux/slab.h> 18 + #include <linux/of_address.h> 19 + #include <linux/clk-provider.h> 20 + 21 + #include "clkgen.h" 22 + 23 + static DEFINE_SPINLOCK(clkgena_c32_odf_lock); 24 + 25 + /* 26 + * Common PLL configuration register bits for PLL800 and PLL1600 C65 27 + */ 28 + #define C65_MDIV_PLL800_MASK (0xff) 29 + #define C65_MDIV_PLL1600_MASK (0x7) 30 + #define C65_NDIV_MASK (0xff) 31 + #define C65_PDIV_MASK (0x7) 32 + 33 + /* 34 + * PLL configuration register bits for PLL3200 C32 35 + */ 36 + #define C32_NDIV_MASK (0xff) 37 + #define C32_IDF_MASK (0x7) 38 + #define C32_ODF_MASK (0x3f) 39 + #define C32_LDF_MASK (0x7f) 40 + 41 + #define C32_MAX_ODFS (4) 42 + 43 + struct clkgen_pll_data { 44 + struct clkgen_field pdn_status; 45 + struct clkgen_field locked_status; 46 + struct clkgen_field mdiv; 47 + struct clkgen_field ndiv; 48 + struct clkgen_field pdiv; 49 + struct clkgen_field idf; 50 + struct clkgen_field ldf; 51 + unsigned int num_odfs; 52 + struct clkgen_field odf[C32_MAX_ODFS]; 53 + struct clkgen_field odf_gate[C32_MAX_ODFS]; 54 + const struct clk_ops *ops; 55 + }; 56 + 57 + static const struct clk_ops st_pll1600c65_ops; 58 + static const struct clk_ops st_pll800c65_ops; 59 + static const struct clk_ops stm_pll3200c32_ops; 60 + static const struct clk_ops st_pll1200c32_ops; 61 + 62 + static struct clkgen_pll_data st_pll1600c65_ax = { 63 + .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19), 64 + .locked_status = CLKGEN_FIELD(0x0, 0x1, 31), 65 + .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK, 0), 66 + .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8), 67 + .ops = &st_pll1600c65_ops 68 + }; 69 + 70 + static struct clkgen_pll_data st_pll800c65_ax = { 71 + .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19), 72 + .locked_status = CLKGEN_FIELD(0x0, 0x1, 31), 73 + .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL800_MASK, 0), 74 + .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8), 75 + .pdiv = CLKGEN_FIELD(0x0, C65_PDIV_MASK, 16), 76 + .ops = &st_pll800c65_ops 77 + }; 78 + 79 + static struct clkgen_pll_data st_pll3200c32_a1x_0 = { 80 + .pdn_status = CLKGEN_FIELD(0x0, 0x1, 31), 81 + .locked_status = CLKGEN_FIELD(0x4, 0x1, 31), 82 + .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 0x0), 83 + .idf = CLKGEN_FIELD(0x4, C32_IDF_MASK, 0x0), 84 + .num_odfs = 4, 85 + .odf = { CLKGEN_FIELD(0x54, C32_ODF_MASK, 4), 86 + CLKGEN_FIELD(0x54, C32_ODF_MASK, 10), 87 + CLKGEN_FIELD(0x54, C32_ODF_MASK, 16), 88 + CLKGEN_FIELD(0x54, C32_ODF_MASK, 22) }, 89 + .odf_gate = { CLKGEN_FIELD(0x54, 0x1, 0), 90 + CLKGEN_FIELD(0x54, 0x1, 1), 91 + CLKGEN_FIELD(0x54, 0x1, 2), 92 + CLKGEN_FIELD(0x54, 0x1, 3) }, 93 + .ops = &stm_pll3200c32_ops, 94 + }; 95 + 96 + static struct clkgen_pll_data st_pll3200c32_a1x_1 = { 97 + .pdn_status = CLKGEN_FIELD(0xC, 0x1, 31), 98 + .locked_status = CLKGEN_FIELD(0x10, 0x1, 31), 99 + .ndiv = CLKGEN_FIELD(0xC, C32_NDIV_MASK, 0x0), 100 + .idf = CLKGEN_FIELD(0x10, C32_IDF_MASK, 0x0), 101 + .num_odfs = 4, 102 + .odf = { CLKGEN_FIELD(0x58, C32_ODF_MASK, 4), 103 + CLKGEN_FIELD(0x58, C32_ODF_MASK, 10), 104 + CLKGEN_FIELD(0x58, C32_ODF_MASK, 16), 105 + CLKGEN_FIELD(0x58, C32_ODF_MASK, 22) }, 106 + .odf_gate = { CLKGEN_FIELD(0x58, 0x1, 0), 107 + CLKGEN_FIELD(0x58, 0x1, 1), 108 + CLKGEN_FIELD(0x58, 0x1, 2), 109 + CLKGEN_FIELD(0x58, 0x1, 3) }, 110 + .ops = &stm_pll3200c32_ops, 111 + }; 112 + 113 + /** 114 + * DOC: Clock Generated by PLL, rate set and enabled by bootloader 115 + * 116 + * Traits of this clock: 117 + * prepare - clk_(un)prepare only ensures parent is (un)prepared 118 + * enable - clk_enable/disable only ensures parent is enabled 119 + * rate - rate is fixed. No clk_set_rate support 120 + * parent - fixed parent. No clk_set_parent support 121 + */ 122 + 123 + /** 124 + * PLL clock that is integrated in the ClockGenA instances on the STiH415 125 + * and STiH416. 126 + * 127 + * @hw: handle between common and hardware-specific interfaces. 128 + * @type: PLL instance type. 129 + * @regs_base: base of the PLL configuration register(s). 130 + * 131 + */ 132 + struct clkgen_pll { 133 + struct clk_hw hw; 134 + struct clkgen_pll_data *data; 135 + void __iomem *regs_base; 136 + }; 137 + 138 + #define to_clkgen_pll(_hw) container_of(_hw, struct clkgen_pll, hw) 139 + 140 + static int clkgen_pll_is_locked(struct clk_hw *hw) 141 + { 142 + struct clkgen_pll *pll = to_clkgen_pll(hw); 143 + u32 locked = CLKGEN_READ(pll, locked_status); 144 + 145 + return !!locked; 146 + } 147 + 148 + static int clkgen_pll_is_enabled(struct clk_hw *hw) 149 + { 150 + struct clkgen_pll *pll = to_clkgen_pll(hw); 151 + u32 poweroff = CLKGEN_READ(pll, pdn_status); 152 + return !poweroff; 153 + } 154 + 155 + unsigned long recalc_stm_pll800c65(struct clk_hw *hw, 156 + unsigned long parent_rate) 157 + { 158 + struct clkgen_pll *pll = to_clkgen_pll(hw); 159 + unsigned long mdiv, ndiv, pdiv; 160 + unsigned long rate; 161 + uint64_t res; 162 + 163 + if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw)) 164 + return 0; 165 + 166 + pdiv = CLKGEN_READ(pll, pdiv); 167 + mdiv = CLKGEN_READ(pll, mdiv); 168 + ndiv = CLKGEN_READ(pll, ndiv); 169 + 170 + if (!mdiv) 171 + mdiv++; /* mdiv=0 or 1 => MDIV=1 */ 172 + 173 + res = (uint64_t)2 * (uint64_t)parent_rate * (uint64_t)ndiv; 174 + rate = (unsigned long)div64_u64(res, mdiv * (1 << pdiv)); 175 + 176 + pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate); 177 + 178 + return rate; 179 + 180 + } 181 + 182 + unsigned long recalc_stm_pll1600c65(struct clk_hw *hw, 183 + unsigned long parent_rate) 184 + { 185 + struct clkgen_pll *pll = to_clkgen_pll(hw); 186 + unsigned long mdiv, ndiv; 187 + unsigned long rate; 188 + 189 + if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw)) 190 + return 0; 191 + 192 + mdiv = CLKGEN_READ(pll, mdiv); 193 + ndiv = CLKGEN_READ(pll, ndiv); 194 + 195 + if (!mdiv) 196 + mdiv = 1; 197 + 198 + /* Note: input is divided by 1000 to avoid overflow */ 199 + rate = ((2 * (parent_rate / 1000) * ndiv) / mdiv) * 1000; 200 + 201 + pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate); 202 + 203 + return rate; 204 + } 205 + 206 + unsigned long recalc_stm_pll3200c32(struct clk_hw *hw, 207 + unsigned long parent_rate) 208 + { 209 + struct clkgen_pll *pll = to_clkgen_pll(hw); 210 + unsigned long ndiv, idf; 211 + unsigned long rate = 0; 212 + 213 + if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw)) 214 + return 0; 215 + 216 + ndiv = CLKGEN_READ(pll, ndiv); 217 + idf = CLKGEN_READ(pll, idf); 218 + 219 + if (idf) 220 + /* Note: input is divided to avoid overflow */ 221 + rate = ((2 * (parent_rate/1000) * ndiv) / idf) * 1000; 222 + 223 + pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate); 224 + 225 + return rate; 226 + } 227 + 228 + unsigned long recalc_stm_pll1200c32(struct clk_hw *hw, 229 + unsigned long parent_rate) 230 + { 231 + struct clkgen_pll *pll = to_clkgen_pll(hw); 232 + unsigned long odf, ldf, idf; 233 + unsigned long rate; 234 + 235 + if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw)) 236 + return 0; 237 + 238 + odf = CLKGEN_READ(pll, odf[0]); 239 + ldf = CLKGEN_READ(pll, ldf); 240 + idf = CLKGEN_READ(pll, idf); 241 + 242 + if (!idf) /* idf==0 means 1 */ 243 + idf = 1; 244 + if (!odf) /* odf==0 means 1 */ 245 + odf = 1; 246 + 247 + /* Note: input is divided by 1000 to avoid overflow */ 248 + rate = (((parent_rate / 1000) * ldf) / (odf * idf)) * 1000; 249 + 250 + pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate); 251 + 252 + return rate; 253 + } 254 + 255 + static const struct clk_ops st_pll1600c65_ops = { 256 + .is_enabled = clkgen_pll_is_enabled, 257 + .recalc_rate = recalc_stm_pll1600c65, 258 + }; 259 + 260 + static const struct clk_ops st_pll800c65_ops = { 261 + .is_enabled = clkgen_pll_is_enabled, 262 + .recalc_rate = recalc_stm_pll800c65, 263 + }; 264 + 265 + static const struct clk_ops stm_pll3200c32_ops = { 266 + .is_enabled = clkgen_pll_is_enabled, 267 + .recalc_rate = recalc_stm_pll3200c32, 268 + }; 269 + 270 + static const struct clk_ops st_pll1200c32_ops = { 271 + .is_enabled = clkgen_pll_is_enabled, 272 + .recalc_rate = recalc_stm_pll1200c32, 273 + }; 274 + 275 + static struct clk * __init clkgen_pll_register(const char *parent_name, 276 + struct clkgen_pll_data *pll_data, 277 + void __iomem *reg, 278 + const char *clk_name) 279 + { 280 + struct clkgen_pll *pll; 281 + struct clk *clk; 282 + struct clk_init_data init; 283 + 284 + pll = kzalloc(sizeof(*pll), GFP_KERNEL); 285 + if (!pll) 286 + return ERR_PTR(-ENOMEM); 287 + 288 + init.name = clk_name; 289 + init.ops = pll_data->ops; 290 + 291 + init.flags = CLK_IS_BASIC; 292 + init.parent_names = &parent_name; 293 + init.num_parents = 1; 294 + 295 + pll->data = pll_data; 296 + pll->regs_base = reg; 297 + pll->hw.init = &init; 298 + 299 + clk = clk_register(NULL, &pll->hw); 300 + if (IS_ERR(clk)) { 301 + kfree(pll); 302 + return clk; 303 + } 304 + 305 + pr_debug("%s: parent %s rate %lu\n", 306 + __clk_get_name(clk), 307 + __clk_get_name(clk_get_parent(clk)), 308 + clk_get_rate(clk)); 309 + 310 + return clk; 311 + } 312 + 313 + static struct clk * __init clkgen_c65_lsdiv_register(const char *parent_name, 314 + const char *clk_name) 315 + { 316 + struct clk *clk; 317 + 318 + clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0, 1, 2); 319 + if (IS_ERR(clk)) 320 + return clk; 321 + 322 + pr_debug("%s: parent %s rate %lu\n", 323 + __clk_get_name(clk), 324 + __clk_get_name(clk_get_parent(clk)), 325 + clk_get_rate(clk)); 326 + return clk; 327 + } 328 + 329 + static void __iomem * __init clkgen_get_register_base( 330 + struct device_node *np) 331 + { 332 + struct device_node *pnode; 333 + void __iomem *reg = NULL; 334 + 335 + pnode = of_get_parent(np); 336 + if (!pnode) 337 + return NULL; 338 + 339 + reg = of_iomap(pnode, 0); 340 + 341 + of_node_put(pnode); 342 + return reg; 343 + } 344 + 345 + #define CLKGENAx_PLL0_OFFSET 0x0 346 + #define CLKGENAx_PLL1_OFFSET 0x4 347 + 348 + static void __init clkgena_c65_pll_setup(struct device_node *np) 349 + { 350 + const int num_pll_outputs = 3; 351 + struct clk_onecell_data *clk_data; 352 + const char *parent_name; 353 + void __iomem *reg; 354 + const char *clk_name; 355 + 356 + parent_name = of_clk_get_parent_name(np, 0); 357 + if (!parent_name) 358 + return; 359 + 360 + reg = clkgen_get_register_base(np); 361 + if (!reg) 362 + return; 363 + 364 + clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); 365 + if (!clk_data) 366 + return; 367 + 368 + clk_data->clk_num = num_pll_outputs; 369 + clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *), 370 + GFP_KERNEL); 371 + 372 + if (!clk_data->clks) 373 + goto err; 374 + 375 + if (of_property_read_string_index(np, "clock-output-names", 376 + 0, &clk_name)) 377 + goto err; 378 + 379 + /* 380 + * PLL0 HS (high speed) output 381 + */ 382 + clk_data->clks[0] = clkgen_pll_register(parent_name, 383 + &st_pll1600c65_ax, 384 + reg + CLKGENAx_PLL0_OFFSET, 385 + clk_name); 386 + 387 + if (IS_ERR(clk_data->clks[0])) 388 + goto err; 389 + 390 + if (of_property_read_string_index(np, "clock-output-names", 391 + 1, &clk_name)) 392 + goto err; 393 + 394 + /* 395 + * PLL0 LS (low speed) output, which is a fixed divide by 2 of the 396 + * high speed output. 397 + */ 398 + clk_data->clks[1] = clkgen_c65_lsdiv_register(__clk_get_name 399 + (clk_data->clks[0]), 400 + clk_name); 401 + 402 + if (IS_ERR(clk_data->clks[1])) 403 + goto err; 404 + 405 + if (of_property_read_string_index(np, "clock-output-names", 406 + 2, &clk_name)) 407 + goto err; 408 + 409 + /* 410 + * PLL1 output 411 + */ 412 + clk_data->clks[2] = clkgen_pll_register(parent_name, 413 + &st_pll800c65_ax, 414 + reg + CLKGENAx_PLL1_OFFSET, 415 + clk_name); 416 + 417 + if (IS_ERR(clk_data->clks[2])) 418 + goto err; 419 + 420 + of_clk_add_provider(np, of_clk_src_onecell_get, clk_data); 421 + return; 422 + 423 + err: 424 + kfree(clk_data->clks); 425 + kfree(clk_data); 426 + } 427 + CLK_OF_DECLARE(clkgena_c65_plls, 428 + "st,clkgena-plls-c65", clkgena_c65_pll_setup); 429 + 430 + static struct clk * __init clkgen_odf_register(const char *parent_name, 431 + void * __iomem reg, 432 + struct clkgen_pll_data *pll_data, 433 + int odf, 434 + spinlock_t *odf_lock, 435 + const char *odf_name) 436 + { 437 + struct clk *clk; 438 + unsigned long flags; 439 + struct clk_gate *gate; 440 + struct clk_divider *div; 441 + 442 + flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_GATE; 443 + 444 + gate = kzalloc(sizeof(*gate), GFP_KERNEL); 445 + if (!gate) 446 + return ERR_PTR(-ENOMEM); 447 + 448 + gate->flags = CLK_GATE_SET_TO_DISABLE; 449 + gate->reg = reg + pll_data->odf_gate[odf].offset; 450 + gate->bit_idx = pll_data->odf_gate[odf].shift; 451 + gate->lock = odf_lock; 452 + 453 + div = kzalloc(sizeof(*div), GFP_KERNEL); 454 + if (!div) 455 + return ERR_PTR(-ENOMEM); 456 + 457 + div->flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO; 458 + div->reg = reg + pll_data->odf[odf].offset; 459 + div->shift = pll_data->odf[odf].shift; 460 + div->width = fls(pll_data->odf[odf].mask); 461 + div->lock = odf_lock; 462 + 463 + clk = clk_register_composite(NULL, odf_name, &parent_name, 1, 464 + NULL, NULL, 465 + &div->hw, &clk_divider_ops, 466 + &gate->hw, &clk_gate_ops, 467 + flags); 468 + if (IS_ERR(clk)) 469 + return clk; 470 + 471 + pr_debug("%s: parent %s rate %lu\n", 472 + __clk_get_name(clk), 473 + __clk_get_name(clk_get_parent(clk)), 474 + clk_get_rate(clk)); 475 + return clk; 476 + } 477 + 478 + static struct of_device_id c32_pll_of_match[] = { 479 + { 480 + .compatible = "st,plls-c32-a1x-0", 481 + .data = &st_pll3200c32_a1x_0, 482 + }, 483 + { 484 + .compatible = "st,plls-c32-a1x-1", 485 + .data = &st_pll3200c32_a1x_1, 486 + }, 487 + {} 488 + }; 489 + 490 + static void __init clkgen_c32_pll_setup(struct device_node *np) 491 + { 492 + const struct of_device_id *match; 493 + struct clk *clk; 494 + const char *parent_name, *pll_name; 495 + void __iomem *pll_base; 496 + int num_odfs, odf; 497 + struct clk_onecell_data *clk_data; 498 + struct clkgen_pll_data *data; 499 + 500 + match = of_match_node(c32_pll_of_match, np); 501 + if (!match) { 502 + pr_err("%s: No matching data\n", __func__); 503 + return; 504 + } 505 + 506 + data = (struct clkgen_pll_data *) match->data; 507 + 508 + parent_name = of_clk_get_parent_name(np, 0); 509 + if (!parent_name) 510 + return; 511 + 512 + pll_base = clkgen_get_register_base(np); 513 + if (!pll_base) 514 + return; 515 + 516 + clk = clkgen_pll_register(parent_name, data, pll_base, np->name); 517 + if (IS_ERR(clk)) 518 + return; 519 + 520 + pll_name = __clk_get_name(clk); 521 + 522 + num_odfs = data->num_odfs; 523 + 524 + clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); 525 + if (!clk_data) 526 + return; 527 + 528 + clk_data->clk_num = num_odfs; 529 + clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *), 530 + GFP_KERNEL); 531 + 532 + if (!clk_data->clks) 533 + goto err; 534 + 535 + for (odf = 0; odf < num_odfs; odf++) { 536 + struct clk *clk; 537 + const char *clk_name; 538 + 539 + if (of_property_read_string_index(np, "clock-output-names", 540 + odf, &clk_name)) 541 + return; 542 + 543 + clk = clkgen_odf_register(pll_name, pll_base, data, 544 + odf, &clkgena_c32_odf_lock, clk_name); 545 + if (IS_ERR(clk)) 546 + goto err; 547 + 548 + clk_data->clks[odf] = clk; 549 + } 550 + 551 + of_clk_add_provider(np, of_clk_src_onecell_get, clk_data); 552 + return; 553 + 554 + err: 555 + kfree(pll_name); 556 + kfree(clk_data->clks); 557 + kfree(clk_data); 558 + } 559 + CLK_OF_DECLARE(clkgen_c32_pll, "st,clkgen-plls-c32", clkgen_c32_pll_setup);
+48
drivers/clk/st/clkgen.h
··· 1 + /************************************************************************ 2 + File : Clock H/w specific Information 3 + 4 + Author: Pankaj Dev <pankaj.dev@st.com> 5 + 6 + Copyright (C) 2014 STMicroelectronics 7 + ************************************************************************/ 8 + 9 + #ifndef __CLKGEN_INFO_H 10 + #define __CLKGEN_INFO_H 11 + 12 + struct clkgen_field { 13 + unsigned int offset; 14 + unsigned int mask; 15 + unsigned int shift; 16 + }; 17 + 18 + static inline unsigned long clkgen_read(void __iomem *base, 19 + struct clkgen_field *field) 20 + { 21 + return (readl(base + field->offset) >> field->shift) & field->mask; 22 + } 23 + 24 + 25 + static inline void clkgen_write(void __iomem *base, struct clkgen_field *field, 26 + unsigned long val) 27 + { 28 + writel((readl(base + field->offset) & 29 + ~(field->mask << field->shift)) | (val << field->shift), 30 + base + field->offset); 31 + 32 + return; 33 + } 34 + 35 + #define CLKGEN_FIELD(_offset, _mask, _shift) { \ 36 + .offset = _offset, \ 37 + .mask = _mask, \ 38 + .shift = _shift, \ 39 + } 40 + 41 + #define CLKGEN_READ(pll, field) clkgen_read(pll->regs_base, \ 42 + &pll->data->field) 43 + 44 + #define CLKGEN_WRITE(pll, field, val) clkgen_write(pll->regs_base, \ 45 + &pll->data->field, val) 46 + 47 + #endif /*__CLKGEN_INFO_H*/ 48 +