| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2010,2015 Broadcom |
|---|
| 3 | 4 | * Copyright (C) 2012 Stephen Warren |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 6 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 7 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 8 | | - * (at your option) any later version. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 11 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | | - * GNU General Public License for more details. |
|---|
| 14 | | - * |
|---|
| 15 | 5 | */ |
|---|
| 16 | 6 | |
|---|
| 17 | 7 | /** |
|---|
| .. | .. |
|---|
| 39 | 29 | #include <linux/clk.h> |
|---|
| 40 | 30 | #include <linux/debugfs.h> |
|---|
| 41 | 31 | #include <linux/delay.h> |
|---|
| 32 | +#include <linux/io.h> |
|---|
| 42 | 33 | #include <linux/module.h> |
|---|
| 43 | | -#include <linux/of.h> |
|---|
| 34 | +#include <linux/of_device.h> |
|---|
| 44 | 35 | #include <linux/platform_device.h> |
|---|
| 45 | 36 | #include <linux/slab.h> |
|---|
| 46 | 37 | #include <dt-bindings/clock/bcm2835.h> |
|---|
| .. | .. |
|---|
| 123 | 114 | #define CM_AVEODIV 0x1bc |
|---|
| 124 | 115 | #define CM_EMMCCTL 0x1c0 |
|---|
| 125 | 116 | #define CM_EMMCDIV 0x1c4 |
|---|
| 117 | +#define CM_EMMC2CTL 0x1d0 |
|---|
| 118 | +#define CM_EMMC2DIV 0x1d4 |
|---|
| 126 | 119 | |
|---|
| 127 | 120 | /* General bits for the CM_*CTL regs */ |
|---|
| 128 | 121 | # define CM_ENABLE BIT(4) |
|---|
| .. | .. |
|---|
| 298 | 291 | #define LOCK_TIMEOUT_NS 100000000 |
|---|
| 299 | 292 | #define BCM2835_MAX_FB_RATE 1750000000u |
|---|
| 300 | 293 | |
|---|
| 294 | +#define SOC_BCM2835 BIT(0) |
|---|
| 295 | +#define SOC_BCM2711 BIT(1) |
|---|
| 296 | +#define SOC_ALL (SOC_BCM2835 | SOC_BCM2711) |
|---|
| 297 | + |
|---|
| 301 | 298 | /* |
|---|
| 302 | 299 | * Names of clocks used within the driver that need to be replaced |
|---|
| 303 | 300 | * with an external parent's name. This array is in the order that |
|---|
| .. | .. |
|---|
| 317 | 314 | struct device *dev; |
|---|
| 318 | 315 | void __iomem *regs; |
|---|
| 319 | 316 | spinlock_t regs_lock; /* spinlock for all clocks */ |
|---|
| 317 | + unsigned int soc; |
|---|
| 320 | 318 | |
|---|
| 321 | 319 | /* |
|---|
| 322 | 320 | * Real names of cprman clock parents looked up through |
|---|
| .. | .. |
|---|
| 327 | 325 | |
|---|
| 328 | 326 | /* Must be last */ |
|---|
| 329 | 327 | struct clk_hw_onecell_data onecell; |
|---|
| 328 | +}; |
|---|
| 329 | + |
|---|
| 330 | +struct cprman_plat_data { |
|---|
| 331 | + unsigned int soc; |
|---|
| 330 | 332 | }; |
|---|
| 331 | 333 | |
|---|
| 332 | 334 | static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val) |
|---|
| .. | .. |
|---|
| 395 | 397 | } |
|---|
| 396 | 398 | |
|---|
| 397 | 399 | static void bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base, |
|---|
| 398 | | - struct debugfs_reg32 *regs, size_t nregs, |
|---|
| 399 | | - struct dentry *dentry) |
|---|
| 400 | + const struct debugfs_reg32 *regs, |
|---|
| 401 | + size_t nregs, struct dentry *dentry) |
|---|
| 400 | 402 | { |
|---|
| 401 | 403 | struct debugfs_regset32 *regset; |
|---|
| 402 | 404 | |
|---|
| .. | .. |
|---|
| 420 | 422 | u32 reference_enable_mask; |
|---|
| 421 | 423 | /* Bit in CM_LOCK to indicate when the PLL has locked. */ |
|---|
| 422 | 424 | u32 lock_mask; |
|---|
| 425 | + u32 flags; |
|---|
| 423 | 426 | |
|---|
| 424 | 427 | const struct bcm2835_pll_ana_bits *ana; |
|---|
| 425 | 428 | |
|---|
| .. | .. |
|---|
| 524 | 527 | A2W_PLL_CTRL_PRST_DISABLE; |
|---|
| 525 | 528 | } |
|---|
| 526 | 529 | |
|---|
| 530 | +static u32 bcm2835_pll_get_prediv_mask(struct bcm2835_cprman *cprman, |
|---|
| 531 | + const struct bcm2835_pll_data *data) |
|---|
| 532 | +{ |
|---|
| 533 | + /* |
|---|
| 534 | + * On BCM2711 there isn't a pre-divisor available in the PLL feedback |
|---|
| 535 | + * loop. Bits 13:14 of ANA1 (PLLA,PLLB,PLLC,PLLD) have been re-purposed |
|---|
| 536 | + * for to for VCO RANGE bits. |
|---|
| 537 | + */ |
|---|
| 538 | + if (cprman->soc & SOC_BCM2711) |
|---|
| 539 | + return 0; |
|---|
| 540 | + |
|---|
| 541 | + return data->ana->fb_prediv_mask; |
|---|
| 542 | +} |
|---|
| 543 | + |
|---|
| 527 | 544 | static void bcm2835_pll_choose_ndiv_and_fdiv(unsigned long rate, |
|---|
| 528 | 545 | unsigned long parent_rate, |
|---|
| 529 | 546 | u32 *ndiv, u32 *fdiv) |
|---|
| .. | .. |
|---|
| 581 | 598 | ndiv = (a2wctrl & A2W_PLL_CTRL_NDIV_MASK) >> A2W_PLL_CTRL_NDIV_SHIFT; |
|---|
| 582 | 599 | pdiv = (a2wctrl & A2W_PLL_CTRL_PDIV_MASK) >> A2W_PLL_CTRL_PDIV_SHIFT; |
|---|
| 583 | 600 | using_prediv = cprman_read(cprman, data->ana_reg_base + 4) & |
|---|
| 584 | | - data->ana->fb_prediv_mask; |
|---|
| 601 | + bcm2835_pll_get_prediv_mask(cprman, data); |
|---|
| 585 | 602 | |
|---|
| 586 | 603 | if (using_prediv) { |
|---|
| 587 | 604 | ndiv *= 2; |
|---|
| .. | .. |
|---|
| 664 | 681 | struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); |
|---|
| 665 | 682 | struct bcm2835_cprman *cprman = pll->cprman; |
|---|
| 666 | 683 | const struct bcm2835_pll_data *data = pll->data; |
|---|
| 684 | + u32 prediv_mask = bcm2835_pll_get_prediv_mask(cprman, data); |
|---|
| 667 | 685 | bool was_using_prediv, use_fb_prediv, do_ana_setup_first; |
|---|
| 668 | 686 | u32 ndiv, fdiv, a2w_ctl; |
|---|
| 669 | 687 | u32 ana[4]; |
|---|
| .. | .. |
|---|
| 681 | 699 | for (i = 3; i >= 0; i--) |
|---|
| 682 | 700 | ana[i] = cprman_read(cprman, data->ana_reg_base + i * 4); |
|---|
| 683 | 701 | |
|---|
| 684 | | - was_using_prediv = ana[1] & data->ana->fb_prediv_mask; |
|---|
| 702 | + was_using_prediv = ana[1] & prediv_mask; |
|---|
| 685 | 703 | |
|---|
| 686 | 704 | ana[0] &= ~data->ana->mask0; |
|---|
| 687 | 705 | ana[0] |= data->ana->set0; |
|---|
| .. | .. |
|---|
| 691 | 709 | ana[3] |= data->ana->set3; |
|---|
| 692 | 710 | |
|---|
| 693 | 711 | if (was_using_prediv && !use_fb_prediv) { |
|---|
| 694 | | - ana[1] &= ~data->ana->fb_prediv_mask; |
|---|
| 712 | + ana[1] &= ~prediv_mask; |
|---|
| 695 | 713 | do_ana_setup_first = true; |
|---|
| 696 | 714 | } else if (!was_using_prediv && use_fb_prediv) { |
|---|
| 697 | | - ana[1] |= data->ana->fb_prediv_mask; |
|---|
| 715 | + ana[1] |= prediv_mask; |
|---|
| 698 | 716 | do_ana_setup_first = false; |
|---|
| 699 | 717 | } else { |
|---|
| 700 | 718 | do_ana_setup_first = true; |
|---|
| .. | .. |
|---|
| 950 | 968 | return div; |
|---|
| 951 | 969 | } |
|---|
| 952 | 970 | |
|---|
| 953 | | -static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, |
|---|
| 954 | | - unsigned long parent_rate, |
|---|
| 955 | | - u32 div) |
|---|
| 971 | +static unsigned long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, |
|---|
| 972 | + unsigned long parent_rate, |
|---|
| 973 | + u32 div) |
|---|
| 956 | 974 | { |
|---|
| 957 | 975 | const struct bcm2835_clock_data *data = clock->data; |
|---|
| 958 | 976 | u64 temp; |
|---|
| .. | .. |
|---|
| 1234 | 1252 | return (src & CM_SRC_MASK) >> CM_SRC_SHIFT; |
|---|
| 1235 | 1253 | } |
|---|
| 1236 | 1254 | |
|---|
| 1237 | | -static struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = { |
|---|
| 1255 | +static const struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = { |
|---|
| 1238 | 1256 | { |
|---|
| 1239 | 1257 | .name = "ctl", |
|---|
| 1240 | 1258 | .offset = 0, |
|---|
| .. | .. |
|---|
| 1290 | 1308 | }; |
|---|
| 1291 | 1309 | |
|---|
| 1292 | 1310 | static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman, |
|---|
| 1293 | | - const struct bcm2835_pll_data *data) |
|---|
| 1311 | + const void *data) |
|---|
| 1294 | 1312 | { |
|---|
| 1313 | + const struct bcm2835_pll_data *pll_data = data; |
|---|
| 1295 | 1314 | struct bcm2835_pll *pll; |
|---|
| 1296 | | - struct clk_init_data init = {}; |
|---|
| 1315 | + struct clk_init_data init; |
|---|
| 1297 | 1316 | int ret; |
|---|
| 1298 | 1317 | |
|---|
| 1299 | 1318 | memset(&init, 0, sizeof(init)); |
|---|
| .. | .. |
|---|
| 1301 | 1320 | /* All of the PLLs derive from the external oscillator. */ |
|---|
| 1302 | 1321 | init.parent_names = &cprman->real_parent_names[0]; |
|---|
| 1303 | 1322 | init.num_parents = 1; |
|---|
| 1304 | | - init.name = data->name; |
|---|
| 1323 | + init.name = pll_data->name; |
|---|
| 1305 | 1324 | init.ops = &bcm2835_pll_clk_ops; |
|---|
| 1306 | | - init.flags = CLK_IGNORE_UNUSED; |
|---|
| 1325 | + init.flags = pll_data->flags | CLK_IGNORE_UNUSED; |
|---|
| 1307 | 1326 | |
|---|
| 1308 | 1327 | pll = kzalloc(sizeof(*pll), GFP_KERNEL); |
|---|
| 1309 | 1328 | if (!pll) |
|---|
| 1310 | 1329 | return NULL; |
|---|
| 1311 | 1330 | |
|---|
| 1312 | 1331 | pll->cprman = cprman; |
|---|
| 1313 | | - pll->data = data; |
|---|
| 1332 | + pll->data = pll_data; |
|---|
| 1314 | 1333 | pll->hw.init = &init; |
|---|
| 1315 | 1334 | |
|---|
| 1316 | 1335 | ret = devm_clk_hw_register(cprman->dev, &pll->hw); |
|---|
| .. | .. |
|---|
| 1323 | 1342 | |
|---|
| 1324 | 1343 | static struct clk_hw * |
|---|
| 1325 | 1344 | bcm2835_register_pll_divider(struct bcm2835_cprman *cprman, |
|---|
| 1326 | | - const struct bcm2835_pll_divider_data *data) |
|---|
| 1345 | + const void *data) |
|---|
| 1327 | 1346 | { |
|---|
| 1347 | + const struct bcm2835_pll_divider_data *divider_data = data; |
|---|
| 1328 | 1348 | struct bcm2835_pll_divider *divider; |
|---|
| 1329 | | - struct clk_init_data init = {}; |
|---|
| 1349 | + struct clk_init_data init; |
|---|
| 1330 | 1350 | const char *divider_name; |
|---|
| 1331 | 1351 | int ret; |
|---|
| 1332 | 1352 | |
|---|
| 1333 | | - if (data->fixed_divider != 1) { |
|---|
| 1353 | + if (divider_data->fixed_divider != 1) { |
|---|
| 1334 | 1354 | divider_name = devm_kasprintf(cprman->dev, GFP_KERNEL, |
|---|
| 1335 | | - "%s_prediv", data->name); |
|---|
| 1355 | + "%s_prediv", divider_data->name); |
|---|
| 1336 | 1356 | if (!divider_name) |
|---|
| 1337 | 1357 | return NULL; |
|---|
| 1338 | 1358 | } else { |
|---|
| 1339 | | - divider_name = data->name; |
|---|
| 1359 | + divider_name = divider_data->name; |
|---|
| 1340 | 1360 | } |
|---|
| 1341 | 1361 | |
|---|
| 1342 | 1362 | memset(&init, 0, sizeof(init)); |
|---|
| 1343 | 1363 | |
|---|
| 1344 | | - init.parent_names = &data->source_pll; |
|---|
| 1364 | + init.parent_names = ÷r_data->source_pll; |
|---|
| 1345 | 1365 | init.num_parents = 1; |
|---|
| 1346 | 1366 | init.name = divider_name; |
|---|
| 1347 | 1367 | init.ops = &bcm2835_pll_divider_clk_ops; |
|---|
| 1348 | | - init.flags = data->flags | CLK_IGNORE_UNUSED; |
|---|
| 1368 | + init.flags = divider_data->flags | CLK_IGNORE_UNUSED; |
|---|
| 1349 | 1369 | |
|---|
| 1350 | 1370 | divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL); |
|---|
| 1351 | 1371 | if (!divider) |
|---|
| 1352 | 1372 | return NULL; |
|---|
| 1353 | 1373 | |
|---|
| 1354 | | - divider->div.reg = cprman->regs + data->a2w_reg; |
|---|
| 1374 | + divider->div.reg = cprman->regs + divider_data->a2w_reg; |
|---|
| 1355 | 1375 | divider->div.shift = A2W_PLL_DIV_SHIFT; |
|---|
| 1356 | 1376 | divider->div.width = A2W_PLL_DIV_BITS; |
|---|
| 1357 | 1377 | divider->div.flags = CLK_DIVIDER_MAX_AT_ZERO; |
|---|
| .. | .. |
|---|
| 1360 | 1380 | divider->div.table = NULL; |
|---|
| 1361 | 1381 | |
|---|
| 1362 | 1382 | divider->cprman = cprman; |
|---|
| 1363 | | - divider->data = data; |
|---|
| 1383 | + divider->data = divider_data; |
|---|
| 1364 | 1384 | |
|---|
| 1365 | 1385 | ret = devm_clk_hw_register(cprman->dev, ÷r->div.hw); |
|---|
| 1366 | 1386 | if (ret) |
|---|
| .. | .. |
|---|
| 1370 | 1390 | * PLLH's channels have a fixed divide by 10 afterwards, which |
|---|
| 1371 | 1391 | * is what our consumers are actually using. |
|---|
| 1372 | 1392 | */ |
|---|
| 1373 | | - if (data->fixed_divider != 1) { |
|---|
| 1374 | | - return clk_hw_register_fixed_factor(cprman->dev, data->name, |
|---|
| 1393 | + if (divider_data->fixed_divider != 1) { |
|---|
| 1394 | + return clk_hw_register_fixed_factor(cprman->dev, |
|---|
| 1395 | + divider_data->name, |
|---|
| 1375 | 1396 | divider_name, |
|---|
| 1376 | 1397 | CLK_SET_RATE_PARENT, |
|---|
| 1377 | 1398 | 1, |
|---|
| 1378 | | - data->fixed_divider); |
|---|
| 1399 | + divider_data->fixed_divider); |
|---|
| 1379 | 1400 | } |
|---|
| 1380 | 1401 | |
|---|
| 1381 | 1402 | return ÷r->div.hw; |
|---|
| 1382 | 1403 | } |
|---|
| 1383 | 1404 | |
|---|
| 1384 | 1405 | static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, |
|---|
| 1385 | | - const struct bcm2835_clock_data *data) |
|---|
| 1406 | + const void *data) |
|---|
| 1386 | 1407 | { |
|---|
| 1408 | + const struct bcm2835_clock_data *clock_data = data; |
|---|
| 1387 | 1409 | struct bcm2835_clock *clock; |
|---|
| 1388 | | - struct clk_init_data init = {}; |
|---|
| 1410 | + struct clk_init_data init; |
|---|
| 1389 | 1411 | const char *parents[1 << CM_SRC_BITS]; |
|---|
| 1390 | 1412 | size_t i; |
|---|
| 1391 | 1413 | int ret; |
|---|
| .. | .. |
|---|
| 1394 | 1416 | * Replace our strings referencing parent clocks with the |
|---|
| 1395 | 1417 | * actual clock-output-name of the parent. |
|---|
| 1396 | 1418 | */ |
|---|
| 1397 | | - for (i = 0; i < data->num_mux_parents; i++) { |
|---|
| 1398 | | - parents[i] = data->parents[i]; |
|---|
| 1419 | + for (i = 0; i < clock_data->num_mux_parents; i++) { |
|---|
| 1420 | + parents[i] = clock_data->parents[i]; |
|---|
| 1399 | 1421 | |
|---|
| 1400 | 1422 | ret = match_string(cprman_parent_names, |
|---|
| 1401 | 1423 | ARRAY_SIZE(cprman_parent_names), |
|---|
| .. | .. |
|---|
| 1406 | 1428 | |
|---|
| 1407 | 1429 | memset(&init, 0, sizeof(init)); |
|---|
| 1408 | 1430 | init.parent_names = parents; |
|---|
| 1409 | | - init.num_parents = data->num_mux_parents; |
|---|
| 1410 | | - init.name = data->name; |
|---|
| 1411 | | - init.flags = data->flags | CLK_IGNORE_UNUSED; |
|---|
| 1431 | + init.num_parents = clock_data->num_mux_parents; |
|---|
| 1432 | + init.name = clock_data->name; |
|---|
| 1433 | + init.flags = clock_data->flags | CLK_IGNORE_UNUSED; |
|---|
| 1412 | 1434 | |
|---|
| 1413 | 1435 | /* |
|---|
| 1414 | 1436 | * Pass the CLK_SET_RATE_PARENT flag if we are allowed to propagate |
|---|
| 1415 | 1437 | * rate changes on at least of the parents. |
|---|
| 1416 | 1438 | */ |
|---|
| 1417 | | - if (data->set_rate_parent) |
|---|
| 1439 | + if (clock_data->set_rate_parent) |
|---|
| 1418 | 1440 | init.flags |= CLK_SET_RATE_PARENT; |
|---|
| 1419 | 1441 | |
|---|
| 1420 | | - if (data->is_vpu_clock) { |
|---|
| 1442 | + if (clock_data->is_vpu_clock) { |
|---|
| 1421 | 1443 | init.ops = &bcm2835_vpu_clock_clk_ops; |
|---|
| 1422 | 1444 | } else { |
|---|
| 1423 | 1445 | init.ops = &bcm2835_clock_clk_ops; |
|---|
| .. | .. |
|---|
| 1426 | 1448 | /* If the clock wasn't actually enabled at boot, it's not |
|---|
| 1427 | 1449 | * critical. |
|---|
| 1428 | 1450 | */ |
|---|
| 1429 | | - if (!(cprman_read(cprman, data->ctl_reg) & CM_ENABLE)) |
|---|
| 1451 | + if (!(cprman_read(cprman, clock_data->ctl_reg) & CM_ENABLE)) |
|---|
| 1430 | 1452 | init.flags &= ~CLK_IS_CRITICAL; |
|---|
| 1431 | 1453 | } |
|---|
| 1432 | 1454 | |
|---|
| .. | .. |
|---|
| 1435 | 1457 | return NULL; |
|---|
| 1436 | 1458 | |
|---|
| 1437 | 1459 | clock->cprman = cprman; |
|---|
| 1438 | | - clock->data = data; |
|---|
| 1460 | + clock->data = clock_data; |
|---|
| 1439 | 1461 | clock->hw.init = &init; |
|---|
| 1440 | 1462 | |
|---|
| 1441 | 1463 | ret = devm_clk_hw_register(cprman->dev, &clock->hw); |
|---|
| .. | .. |
|---|
| 1445 | 1467 | } |
|---|
| 1446 | 1468 | |
|---|
| 1447 | 1469 | static struct clk_hw *bcm2835_register_gate(struct bcm2835_cprman *cprman, |
|---|
| 1448 | | - const struct bcm2835_gate_data *data) |
|---|
| 1470 | + const void *data) |
|---|
| 1449 | 1471 | { |
|---|
| 1450 | | - return clk_hw_register_gate(cprman->dev, data->name, data->parent, |
|---|
| 1472 | + const struct bcm2835_gate_data *gate_data = data; |
|---|
| 1473 | + |
|---|
| 1474 | + return clk_hw_register_gate(cprman->dev, gate_data->name, |
|---|
| 1475 | + gate_data->parent, |
|---|
| 1451 | 1476 | CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, |
|---|
| 1452 | | - cprman->regs + data->ctl_reg, |
|---|
| 1477 | + cprman->regs + gate_data->ctl_reg, |
|---|
| 1453 | 1478 | CM_GATE_BIT, 0, &cprman->regs_lock); |
|---|
| 1454 | 1479 | } |
|---|
| 1455 | 1480 | |
|---|
| 1456 | | -typedef struct clk_hw *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman, |
|---|
| 1457 | | - const void *data); |
|---|
| 1458 | 1481 | struct bcm2835_clk_desc { |
|---|
| 1459 | | - bcm2835_clk_register clk_register; |
|---|
| 1482 | + struct clk_hw *(*clk_register)(struct bcm2835_cprman *cprman, |
|---|
| 1483 | + const void *data); |
|---|
| 1484 | + unsigned int supported; |
|---|
| 1460 | 1485 | const void *data; |
|---|
| 1461 | 1486 | }; |
|---|
| 1462 | 1487 | |
|---|
| 1463 | 1488 | /* assignment helper macros for different clock types */ |
|---|
| 1464 | | -#define _REGISTER(f, ...) { .clk_register = (bcm2835_clk_register)f, \ |
|---|
| 1465 | | - .data = __VA_ARGS__ } |
|---|
| 1466 | | -#define REGISTER_PLL(...) _REGISTER(&bcm2835_register_pll, \ |
|---|
| 1489 | +#define _REGISTER(f, s, ...) { .clk_register = f, \ |
|---|
| 1490 | + .supported = s, \ |
|---|
| 1491 | + .data = __VA_ARGS__ } |
|---|
| 1492 | +#define REGISTER_PLL(s, ...) _REGISTER(&bcm2835_register_pll, \ |
|---|
| 1493 | + s, \ |
|---|
| 1467 | 1494 | &(struct bcm2835_pll_data) \ |
|---|
| 1468 | 1495 | {__VA_ARGS__}) |
|---|
| 1469 | | -#define REGISTER_PLL_DIV(...) _REGISTER(&bcm2835_register_pll_divider, \ |
|---|
| 1470 | | - &(struct bcm2835_pll_divider_data) \ |
|---|
| 1471 | | - {__VA_ARGS__}) |
|---|
| 1472 | | -#define REGISTER_CLK(...) _REGISTER(&bcm2835_register_clock, \ |
|---|
| 1496 | +#define REGISTER_PLL_DIV(s, ...) _REGISTER(&bcm2835_register_pll_divider, \ |
|---|
| 1497 | + s, \ |
|---|
| 1498 | + &(struct bcm2835_pll_divider_data) \ |
|---|
| 1499 | + {__VA_ARGS__}) |
|---|
| 1500 | +#define REGISTER_CLK(s, ...) _REGISTER(&bcm2835_register_clock, \ |
|---|
| 1501 | + s, \ |
|---|
| 1473 | 1502 | &(struct bcm2835_clock_data) \ |
|---|
| 1474 | 1503 | {__VA_ARGS__}) |
|---|
| 1475 | | -#define REGISTER_GATE(...) _REGISTER(&bcm2835_register_gate, \ |
|---|
| 1504 | +#define REGISTER_GATE(s, ...) _REGISTER(&bcm2835_register_gate, \ |
|---|
| 1505 | + s, \ |
|---|
| 1476 | 1506 | &(struct bcm2835_gate_data) \ |
|---|
| 1477 | 1507 | {__VA_ARGS__}) |
|---|
| 1478 | 1508 | |
|---|
| .. | .. |
|---|
| 1486 | 1516 | "testdebug1" |
|---|
| 1487 | 1517 | }; |
|---|
| 1488 | 1518 | |
|---|
| 1489 | | -#define REGISTER_OSC_CLK(...) REGISTER_CLK( \ |
|---|
| 1519 | +#define REGISTER_OSC_CLK(s, ...) REGISTER_CLK( \ |
|---|
| 1520 | + s, \ |
|---|
| 1490 | 1521 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), \ |
|---|
| 1491 | 1522 | .parents = bcm2835_clock_osc_parents, \ |
|---|
| 1492 | 1523 | __VA_ARGS__) |
|---|
| .. | .. |
|---|
| 1503 | 1534 | "pllh_aux", |
|---|
| 1504 | 1535 | }; |
|---|
| 1505 | 1536 | |
|---|
| 1506 | | -#define REGISTER_PER_CLK(...) REGISTER_CLK( \ |
|---|
| 1537 | +#define REGISTER_PER_CLK(s, ...) REGISTER_CLK( \ |
|---|
| 1538 | + s, \ |
|---|
| 1507 | 1539 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), \ |
|---|
| 1508 | 1540 | .parents = bcm2835_clock_per_parents, \ |
|---|
| 1509 | 1541 | __VA_ARGS__) |
|---|
| .. | .. |
|---|
| 1528 | 1560 | "-", |
|---|
| 1529 | 1561 | }; |
|---|
| 1530 | 1562 | |
|---|
| 1531 | | -#define REGISTER_PCM_CLK(...) REGISTER_CLK( \ |
|---|
| 1563 | +#define REGISTER_PCM_CLK(s, ...) REGISTER_CLK( \ |
|---|
| 1564 | + s, \ |
|---|
| 1532 | 1565 | .num_mux_parents = ARRAY_SIZE(bcm2835_pcm_per_parents), \ |
|---|
| 1533 | 1566 | .parents = bcm2835_pcm_per_parents, \ |
|---|
| 1534 | 1567 | __VA_ARGS__) |
|---|
| .. | .. |
|---|
| 1547 | 1580 | "pllc_core2", |
|---|
| 1548 | 1581 | }; |
|---|
| 1549 | 1582 | |
|---|
| 1550 | | -#define REGISTER_VPU_CLK(...) REGISTER_CLK( \ |
|---|
| 1583 | +#define REGISTER_VPU_CLK(s, ...) REGISTER_CLK( \ |
|---|
| 1584 | + s, \ |
|---|
| 1551 | 1585 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), \ |
|---|
| 1552 | 1586 | .parents = bcm2835_clock_vpu_parents, \ |
|---|
| 1553 | 1587 | __VA_ARGS__) |
|---|
| .. | .. |
|---|
| 1583 | 1617 | "dsi1_byte_inv", |
|---|
| 1584 | 1618 | }; |
|---|
| 1585 | 1619 | |
|---|
| 1586 | | -#define REGISTER_DSI0_CLK(...) REGISTER_CLK( \ |
|---|
| 1620 | +#define REGISTER_DSI0_CLK(s, ...) REGISTER_CLK( \ |
|---|
| 1621 | + s, \ |
|---|
| 1587 | 1622 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi0_parents), \ |
|---|
| 1588 | 1623 | .parents = bcm2835_clock_dsi0_parents, \ |
|---|
| 1589 | 1624 | __VA_ARGS__) |
|---|
| 1590 | 1625 | |
|---|
| 1591 | | -#define REGISTER_DSI1_CLK(...) REGISTER_CLK( \ |
|---|
| 1626 | +#define REGISTER_DSI1_CLK(s, ...) REGISTER_CLK( \ |
|---|
| 1627 | + s, \ |
|---|
| 1592 | 1628 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi1_parents), \ |
|---|
| 1593 | 1629 | .parents = bcm2835_clock_dsi1_parents, \ |
|---|
| 1594 | 1630 | __VA_ARGS__) |
|---|
| .. | .. |
|---|
| 1608 | 1644 | * AUDIO domain is on. |
|---|
| 1609 | 1645 | */ |
|---|
| 1610 | 1646 | [BCM2835_PLLA] = REGISTER_PLL( |
|---|
| 1647 | + SOC_ALL, |
|---|
| 1611 | 1648 | .name = "plla", |
|---|
| 1612 | 1649 | .cm_ctrl_reg = CM_PLLA, |
|---|
| 1613 | 1650 | .a2w_ctrl_reg = A2W_PLLA_CTRL, |
|---|
| .. | .. |
|---|
| 1622 | 1659 | .max_rate = 2400000000u, |
|---|
| 1623 | 1660 | .max_fb_rate = BCM2835_MAX_FB_RATE), |
|---|
| 1624 | 1661 | [BCM2835_PLLA_CORE] = REGISTER_PLL_DIV( |
|---|
| 1662 | + SOC_ALL, |
|---|
| 1625 | 1663 | .name = "plla_core", |
|---|
| 1626 | 1664 | .source_pll = "plla", |
|---|
| 1627 | 1665 | .cm_reg = CM_PLLA, |
|---|
| .. | .. |
|---|
| 1631 | 1669 | .fixed_divider = 1, |
|---|
| 1632 | 1670 | .flags = CLK_SET_RATE_PARENT), |
|---|
| 1633 | 1671 | [BCM2835_PLLA_PER] = REGISTER_PLL_DIV( |
|---|
| 1672 | + SOC_ALL, |
|---|
| 1634 | 1673 | .name = "plla_per", |
|---|
| 1635 | 1674 | .source_pll = "plla", |
|---|
| 1636 | 1675 | .cm_reg = CM_PLLA, |
|---|
| .. | .. |
|---|
| 1640 | 1679 | .fixed_divider = 1, |
|---|
| 1641 | 1680 | .flags = CLK_SET_RATE_PARENT), |
|---|
| 1642 | 1681 | [BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV( |
|---|
| 1682 | + SOC_ALL, |
|---|
| 1643 | 1683 | .name = "plla_dsi0", |
|---|
| 1644 | 1684 | .source_pll = "plla", |
|---|
| 1645 | 1685 | .cm_reg = CM_PLLA, |
|---|
| .. | .. |
|---|
| 1648 | 1688 | .hold_mask = CM_PLLA_HOLDDSI0, |
|---|
| 1649 | 1689 | .fixed_divider = 1), |
|---|
| 1650 | 1690 | [BCM2835_PLLA_CCP2] = REGISTER_PLL_DIV( |
|---|
| 1691 | + SOC_ALL, |
|---|
| 1651 | 1692 | .name = "plla_ccp2", |
|---|
| 1652 | 1693 | .source_pll = "plla", |
|---|
| 1653 | 1694 | .cm_reg = CM_PLLA, |
|---|
| .. | .. |
|---|
| 1659 | 1700 | |
|---|
| 1660 | 1701 | /* PLLB is used for the ARM's clock. */ |
|---|
| 1661 | 1702 | [BCM2835_PLLB] = REGISTER_PLL( |
|---|
| 1703 | + SOC_ALL, |
|---|
| 1662 | 1704 | .name = "pllb", |
|---|
| 1663 | 1705 | .cm_ctrl_reg = CM_PLLB, |
|---|
| 1664 | 1706 | .a2w_ctrl_reg = A2W_PLLB_CTRL, |
|---|
| .. | .. |
|---|
| 1671 | 1713 | |
|---|
| 1672 | 1714 | .min_rate = 600000000u, |
|---|
| 1673 | 1715 | .max_rate = 3000000000u, |
|---|
| 1674 | | - .max_fb_rate = BCM2835_MAX_FB_RATE), |
|---|
| 1716 | + .max_fb_rate = BCM2835_MAX_FB_RATE, |
|---|
| 1717 | + .flags = CLK_GET_RATE_NOCACHE), |
|---|
| 1675 | 1718 | [BCM2835_PLLB_ARM] = REGISTER_PLL_DIV( |
|---|
| 1719 | + SOC_ALL, |
|---|
| 1676 | 1720 | .name = "pllb_arm", |
|---|
| 1677 | 1721 | .source_pll = "pllb", |
|---|
| 1678 | 1722 | .cm_reg = CM_PLLB, |
|---|
| .. | .. |
|---|
| 1680 | 1724 | .load_mask = CM_PLLB_LOADARM, |
|---|
| 1681 | 1725 | .hold_mask = CM_PLLB_HOLDARM, |
|---|
| 1682 | 1726 | .fixed_divider = 1, |
|---|
| 1683 | | - .flags = CLK_SET_RATE_PARENT), |
|---|
| 1727 | + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE), |
|---|
| 1684 | 1728 | |
|---|
| 1685 | 1729 | /* |
|---|
| 1686 | 1730 | * PLLC is the core PLL, used to drive the core VPU clock. |
|---|
| .. | .. |
|---|
| 1689 | 1733 | * AUDIO domain is on. |
|---|
| 1690 | 1734 | */ |
|---|
| 1691 | 1735 | [BCM2835_PLLC] = REGISTER_PLL( |
|---|
| 1736 | + SOC_ALL, |
|---|
| 1692 | 1737 | .name = "pllc", |
|---|
| 1693 | 1738 | .cm_ctrl_reg = CM_PLLC, |
|---|
| 1694 | 1739 | .a2w_ctrl_reg = A2W_PLLC_CTRL, |
|---|
| .. | .. |
|---|
| 1703 | 1748 | .max_rate = 3000000000u, |
|---|
| 1704 | 1749 | .max_fb_rate = BCM2835_MAX_FB_RATE), |
|---|
| 1705 | 1750 | [BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV( |
|---|
| 1751 | + SOC_ALL, |
|---|
| 1706 | 1752 | .name = "pllc_core0", |
|---|
| 1707 | 1753 | .source_pll = "pllc", |
|---|
| 1708 | 1754 | .cm_reg = CM_PLLC, |
|---|
| .. | .. |
|---|
| 1712 | 1758 | .fixed_divider = 1, |
|---|
| 1713 | 1759 | .flags = CLK_SET_RATE_PARENT), |
|---|
| 1714 | 1760 | [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV( |
|---|
| 1761 | + SOC_ALL, |
|---|
| 1715 | 1762 | .name = "pllc_core1", |
|---|
| 1716 | 1763 | .source_pll = "pllc", |
|---|
| 1717 | 1764 | .cm_reg = CM_PLLC, |
|---|
| .. | .. |
|---|
| 1721 | 1768 | .fixed_divider = 1, |
|---|
| 1722 | 1769 | .flags = CLK_SET_RATE_PARENT), |
|---|
| 1723 | 1770 | [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV( |
|---|
| 1771 | + SOC_ALL, |
|---|
| 1724 | 1772 | .name = "pllc_core2", |
|---|
| 1725 | 1773 | .source_pll = "pllc", |
|---|
| 1726 | 1774 | .cm_reg = CM_PLLC, |
|---|
| .. | .. |
|---|
| 1730 | 1778 | .fixed_divider = 1, |
|---|
| 1731 | 1779 | .flags = CLK_SET_RATE_PARENT), |
|---|
| 1732 | 1780 | [BCM2835_PLLC_PER] = REGISTER_PLL_DIV( |
|---|
| 1781 | + SOC_ALL, |
|---|
| 1733 | 1782 | .name = "pllc_per", |
|---|
| 1734 | 1783 | .source_pll = "pllc", |
|---|
| 1735 | 1784 | .cm_reg = CM_PLLC, |
|---|
| .. | .. |
|---|
| 1737 | 1786 | .load_mask = CM_PLLC_LOADPER, |
|---|
| 1738 | 1787 | .hold_mask = CM_PLLC_HOLDPER, |
|---|
| 1739 | 1788 | .fixed_divider = 1, |
|---|
| 1740 | | - .flags = CLK_SET_RATE_PARENT), |
|---|
| 1789 | + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), |
|---|
| 1741 | 1790 | |
|---|
| 1742 | 1791 | /* |
|---|
| 1743 | 1792 | * PLLD is the display PLL, used to drive DSI display panels. |
|---|
| .. | .. |
|---|
| 1746 | 1795 | * AUDIO domain is on. |
|---|
| 1747 | 1796 | */ |
|---|
| 1748 | 1797 | [BCM2835_PLLD] = REGISTER_PLL( |
|---|
| 1798 | + SOC_ALL, |
|---|
| 1749 | 1799 | .name = "plld", |
|---|
| 1750 | 1800 | .cm_ctrl_reg = CM_PLLD, |
|---|
| 1751 | 1801 | .a2w_ctrl_reg = A2W_PLLD_CTRL, |
|---|
| .. | .. |
|---|
| 1760 | 1810 | .max_rate = 2400000000u, |
|---|
| 1761 | 1811 | .max_fb_rate = BCM2835_MAX_FB_RATE), |
|---|
| 1762 | 1812 | [BCM2835_PLLD_CORE] = REGISTER_PLL_DIV( |
|---|
| 1813 | + SOC_ALL, |
|---|
| 1763 | 1814 | .name = "plld_core", |
|---|
| 1764 | 1815 | .source_pll = "plld", |
|---|
| 1765 | 1816 | .cm_reg = CM_PLLD, |
|---|
| .. | .. |
|---|
| 1768 | 1819 | .hold_mask = CM_PLLD_HOLDCORE, |
|---|
| 1769 | 1820 | .fixed_divider = 1, |
|---|
| 1770 | 1821 | .flags = CLK_SET_RATE_PARENT), |
|---|
| 1822 | + /* |
|---|
| 1823 | + * VPU firmware assumes that PLLD_PER isn't disabled by the ARM core. |
|---|
| 1824 | + * Otherwise this could cause firmware lookups. That's why we mark |
|---|
| 1825 | + * it as critical. |
|---|
| 1826 | + */ |
|---|
| 1771 | 1827 | [BCM2835_PLLD_PER] = REGISTER_PLL_DIV( |
|---|
| 1828 | + SOC_ALL, |
|---|
| 1772 | 1829 | .name = "plld_per", |
|---|
| 1773 | 1830 | .source_pll = "plld", |
|---|
| 1774 | 1831 | .cm_reg = CM_PLLD, |
|---|
| .. | .. |
|---|
| 1776 | 1833 | .load_mask = CM_PLLD_LOADPER, |
|---|
| 1777 | 1834 | .hold_mask = CM_PLLD_HOLDPER, |
|---|
| 1778 | 1835 | .fixed_divider = 1, |
|---|
| 1779 | | - .flags = CLK_SET_RATE_PARENT), |
|---|
| 1836 | + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), |
|---|
| 1780 | 1837 | [BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV( |
|---|
| 1838 | + SOC_ALL, |
|---|
| 1781 | 1839 | .name = "plld_dsi0", |
|---|
| 1782 | 1840 | .source_pll = "plld", |
|---|
| 1783 | 1841 | .cm_reg = CM_PLLD, |
|---|
| .. | .. |
|---|
| 1786 | 1844 | .hold_mask = CM_PLLD_HOLDDSI0, |
|---|
| 1787 | 1845 | .fixed_divider = 1), |
|---|
| 1788 | 1846 | [BCM2835_PLLD_DSI1] = REGISTER_PLL_DIV( |
|---|
| 1847 | + SOC_ALL, |
|---|
| 1789 | 1848 | .name = "plld_dsi1", |
|---|
| 1790 | 1849 | .source_pll = "plld", |
|---|
| 1791 | 1850 | .cm_reg = CM_PLLD, |
|---|
| .. | .. |
|---|
| 1801 | 1860 | * It is in the HDMI power domain. |
|---|
| 1802 | 1861 | */ |
|---|
| 1803 | 1862 | [BCM2835_PLLH] = REGISTER_PLL( |
|---|
| 1863 | + SOC_BCM2835, |
|---|
| 1804 | 1864 | "pllh", |
|---|
| 1805 | 1865 | .cm_ctrl_reg = CM_PLLH, |
|---|
| 1806 | 1866 | .a2w_ctrl_reg = A2W_PLLH_CTRL, |
|---|
| .. | .. |
|---|
| 1815 | 1875 | .max_rate = 3000000000u, |
|---|
| 1816 | 1876 | .max_fb_rate = BCM2835_MAX_FB_RATE), |
|---|
| 1817 | 1877 | [BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV( |
|---|
| 1878 | + SOC_BCM2835, |
|---|
| 1818 | 1879 | .name = "pllh_rcal", |
|---|
| 1819 | 1880 | .source_pll = "pllh", |
|---|
| 1820 | 1881 | .cm_reg = CM_PLLH, |
|---|
| .. | .. |
|---|
| 1824 | 1885 | .fixed_divider = 10, |
|---|
| 1825 | 1886 | .flags = CLK_SET_RATE_PARENT), |
|---|
| 1826 | 1887 | [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV( |
|---|
| 1888 | + SOC_BCM2835, |
|---|
| 1827 | 1889 | .name = "pllh_aux", |
|---|
| 1828 | 1890 | .source_pll = "pllh", |
|---|
| 1829 | 1891 | .cm_reg = CM_PLLH, |
|---|
| .. | .. |
|---|
| 1833 | 1895 | .fixed_divider = 1, |
|---|
| 1834 | 1896 | .flags = CLK_SET_RATE_PARENT), |
|---|
| 1835 | 1897 | [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV( |
|---|
| 1898 | + SOC_BCM2835, |
|---|
| 1836 | 1899 | .name = "pllh_pix", |
|---|
| 1837 | 1900 | .source_pll = "pllh", |
|---|
| 1838 | 1901 | .cm_reg = CM_PLLH, |
|---|
| .. | .. |
|---|
| 1848 | 1911 | |
|---|
| 1849 | 1912 | /* One Time Programmable Memory clock. Maximum 10Mhz. */ |
|---|
| 1850 | 1913 | [BCM2835_CLOCK_OTP] = REGISTER_OSC_CLK( |
|---|
| 1914 | + SOC_ALL, |
|---|
| 1851 | 1915 | .name = "otp", |
|---|
| 1852 | 1916 | .ctl_reg = CM_OTPCTL, |
|---|
| 1853 | 1917 | .div_reg = CM_OTPDIV, |
|---|
| .. | .. |
|---|
| 1859 | 1923 | * bythe watchdog timer and the camera pulse generator. |
|---|
| 1860 | 1924 | */ |
|---|
| 1861 | 1925 | [BCM2835_CLOCK_TIMER] = REGISTER_OSC_CLK( |
|---|
| 1926 | + SOC_ALL, |
|---|
| 1862 | 1927 | .name = "timer", |
|---|
| 1863 | 1928 | .ctl_reg = CM_TIMERCTL, |
|---|
| 1864 | 1929 | .div_reg = CM_TIMERDIV, |
|---|
| .. | .. |
|---|
| 1869 | 1934 | * Generally run at 2Mhz, max 5Mhz. |
|---|
| 1870 | 1935 | */ |
|---|
| 1871 | 1936 | [BCM2835_CLOCK_TSENS] = REGISTER_OSC_CLK( |
|---|
| 1937 | + SOC_ALL, |
|---|
| 1872 | 1938 | .name = "tsens", |
|---|
| 1873 | 1939 | .ctl_reg = CM_TSENSCTL, |
|---|
| 1874 | 1940 | .div_reg = CM_TSENSDIV, |
|---|
| 1875 | 1941 | .int_bits = 5, |
|---|
| 1876 | 1942 | .frac_bits = 0), |
|---|
| 1877 | 1943 | [BCM2835_CLOCK_TEC] = REGISTER_OSC_CLK( |
|---|
| 1944 | + SOC_ALL, |
|---|
| 1878 | 1945 | .name = "tec", |
|---|
| 1879 | 1946 | .ctl_reg = CM_TECCTL, |
|---|
| 1880 | 1947 | .div_reg = CM_TECDIV, |
|---|
| .. | .. |
|---|
| 1883 | 1950 | |
|---|
| 1884 | 1951 | /* clocks with vpu parent mux */ |
|---|
| 1885 | 1952 | [BCM2835_CLOCK_H264] = REGISTER_VPU_CLK( |
|---|
| 1953 | + SOC_ALL, |
|---|
| 1886 | 1954 | .name = "h264", |
|---|
| 1887 | 1955 | .ctl_reg = CM_H264CTL, |
|---|
| 1888 | 1956 | .div_reg = CM_H264DIV, |
|---|
| .. | .. |
|---|
| 1890 | 1958 | .frac_bits = 8, |
|---|
| 1891 | 1959 | .tcnt_mux = 1), |
|---|
| 1892 | 1960 | [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK( |
|---|
| 1961 | + SOC_ALL, |
|---|
| 1893 | 1962 | .name = "isp", |
|---|
| 1894 | 1963 | .ctl_reg = CM_ISPCTL, |
|---|
| 1895 | 1964 | .div_reg = CM_ISPDIV, |
|---|
| .. | .. |
|---|
| 1902 | 1971 | * in the SDRAM controller can't be used. |
|---|
| 1903 | 1972 | */ |
|---|
| 1904 | 1973 | [BCM2835_CLOCK_SDRAM] = REGISTER_VPU_CLK( |
|---|
| 1974 | + SOC_ALL, |
|---|
| 1905 | 1975 | .name = "sdram", |
|---|
| 1906 | 1976 | .ctl_reg = CM_SDCCTL, |
|---|
| 1907 | 1977 | .div_reg = CM_SDCDIV, |
|---|
| .. | .. |
|---|
| 1909 | 1979 | .frac_bits = 0, |
|---|
| 1910 | 1980 | .tcnt_mux = 3), |
|---|
| 1911 | 1981 | [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK( |
|---|
| 1982 | + SOC_ALL, |
|---|
| 1912 | 1983 | .name = "v3d", |
|---|
| 1913 | 1984 | .ctl_reg = CM_V3DCTL, |
|---|
| 1914 | 1985 | .div_reg = CM_V3DDIV, |
|---|
| .. | .. |
|---|
| 1922 | 1993 | * in various hardware documentation. |
|---|
| 1923 | 1994 | */ |
|---|
| 1924 | 1995 | [BCM2835_CLOCK_VPU] = REGISTER_VPU_CLK( |
|---|
| 1996 | + SOC_ALL, |
|---|
| 1925 | 1997 | .name = "vpu", |
|---|
| 1926 | 1998 | .ctl_reg = CM_VPUCTL, |
|---|
| 1927 | 1999 | .div_reg = CM_VPUDIV, |
|---|
| .. | .. |
|---|
| 1933 | 2005 | |
|---|
| 1934 | 2006 | /* clocks with per parent mux */ |
|---|
| 1935 | 2007 | [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK( |
|---|
| 2008 | + SOC_ALL, |
|---|
| 1936 | 2009 | .name = "aveo", |
|---|
| 1937 | 2010 | .ctl_reg = CM_AVEOCTL, |
|---|
| 1938 | 2011 | .div_reg = CM_AVEODIV, |
|---|
| .. | .. |
|---|
| 1940 | 2013 | .frac_bits = 0, |
|---|
| 1941 | 2014 | .tcnt_mux = 38), |
|---|
| 1942 | 2015 | [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK( |
|---|
| 2016 | + SOC_ALL, |
|---|
| 1943 | 2017 | .name = "cam0", |
|---|
| 1944 | 2018 | .ctl_reg = CM_CAM0CTL, |
|---|
| 1945 | 2019 | .div_reg = CM_CAM0DIV, |
|---|
| .. | .. |
|---|
| 1947 | 2021 | .frac_bits = 8, |
|---|
| 1948 | 2022 | .tcnt_mux = 14), |
|---|
| 1949 | 2023 | [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK( |
|---|
| 2024 | + SOC_ALL, |
|---|
| 1950 | 2025 | .name = "cam1", |
|---|
| 1951 | 2026 | .ctl_reg = CM_CAM1CTL, |
|---|
| 1952 | 2027 | .div_reg = CM_CAM1DIV, |
|---|
| .. | .. |
|---|
| 1954 | 2029 | .frac_bits = 8, |
|---|
| 1955 | 2030 | .tcnt_mux = 15), |
|---|
| 1956 | 2031 | [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK( |
|---|
| 2032 | + SOC_ALL, |
|---|
| 1957 | 2033 | .name = "dft", |
|---|
| 1958 | 2034 | .ctl_reg = CM_DFTCTL, |
|---|
| 1959 | 2035 | .div_reg = CM_DFTDIV, |
|---|
| 1960 | 2036 | .int_bits = 5, |
|---|
| 1961 | 2037 | .frac_bits = 0), |
|---|
| 1962 | 2038 | [BCM2835_CLOCK_DPI] = REGISTER_PER_CLK( |
|---|
| 2039 | + SOC_ALL, |
|---|
| 1963 | 2040 | .name = "dpi", |
|---|
| 1964 | 2041 | .ctl_reg = CM_DPICTL, |
|---|
| 1965 | 2042 | .div_reg = CM_DPIDIV, |
|---|
| .. | .. |
|---|
| 1969 | 2046 | |
|---|
| 1970 | 2047 | /* Arasan EMMC clock */ |
|---|
| 1971 | 2048 | [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK( |
|---|
| 2049 | + SOC_ALL, |
|---|
| 1972 | 2050 | .name = "emmc", |
|---|
| 1973 | 2051 | .ctl_reg = CM_EMMCCTL, |
|---|
| 1974 | 2052 | .div_reg = CM_EMMCDIV, |
|---|
| .. | .. |
|---|
| 1976 | 2054 | .frac_bits = 8, |
|---|
| 1977 | 2055 | .tcnt_mux = 39), |
|---|
| 1978 | 2056 | |
|---|
| 2057 | + /* EMMC2 clock (only available for BCM2711) */ |
|---|
| 2058 | + [BCM2711_CLOCK_EMMC2] = REGISTER_PER_CLK( |
|---|
| 2059 | + SOC_BCM2711, |
|---|
| 2060 | + .name = "emmc2", |
|---|
| 2061 | + .ctl_reg = CM_EMMC2CTL, |
|---|
| 2062 | + .div_reg = CM_EMMC2DIV, |
|---|
| 2063 | + .int_bits = 4, |
|---|
| 2064 | + .frac_bits = 8, |
|---|
| 2065 | + .tcnt_mux = 42), |
|---|
| 2066 | + |
|---|
| 1979 | 2067 | /* General purpose (GPIO) clocks */ |
|---|
| 1980 | 2068 | [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK( |
|---|
| 2069 | + SOC_ALL, |
|---|
| 1981 | 2070 | .name = "gp0", |
|---|
| 1982 | 2071 | .ctl_reg = CM_GP0CTL, |
|---|
| 1983 | 2072 | .div_reg = CM_GP0DIV, |
|---|
| .. | .. |
|---|
| 1986 | 2075 | .is_mash_clock = true, |
|---|
| 1987 | 2076 | .tcnt_mux = 20), |
|---|
| 1988 | 2077 | [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK( |
|---|
| 2078 | + SOC_ALL, |
|---|
| 1989 | 2079 | .name = "gp1", |
|---|
| 1990 | 2080 | .ctl_reg = CM_GP1CTL, |
|---|
| 1991 | 2081 | .div_reg = CM_GP1DIV, |
|---|
| .. | .. |
|---|
| 1995 | 2085 | .is_mash_clock = true, |
|---|
| 1996 | 2086 | .tcnt_mux = 21), |
|---|
| 1997 | 2087 | [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK( |
|---|
| 2088 | + SOC_ALL, |
|---|
| 1998 | 2089 | .name = "gp2", |
|---|
| 1999 | 2090 | .ctl_reg = CM_GP2CTL, |
|---|
| 2000 | 2091 | .div_reg = CM_GP2DIV, |
|---|
| .. | .. |
|---|
| 2004 | 2095 | |
|---|
| 2005 | 2096 | /* HDMI state machine */ |
|---|
| 2006 | 2097 | [BCM2835_CLOCK_HSM] = REGISTER_PER_CLK( |
|---|
| 2098 | + SOC_ALL, |
|---|
| 2007 | 2099 | .name = "hsm", |
|---|
| 2008 | 2100 | .ctl_reg = CM_HSMCTL, |
|---|
| 2009 | 2101 | .div_reg = CM_HSMDIV, |
|---|
| .. | .. |
|---|
| 2011 | 2103 | .frac_bits = 8, |
|---|
| 2012 | 2104 | .tcnt_mux = 22), |
|---|
| 2013 | 2105 | [BCM2835_CLOCK_PCM] = REGISTER_PCM_CLK( |
|---|
| 2106 | + SOC_ALL, |
|---|
| 2014 | 2107 | .name = "pcm", |
|---|
| 2015 | 2108 | .ctl_reg = CM_PCMCTL, |
|---|
| 2016 | 2109 | .div_reg = CM_PCMDIV, |
|---|
| .. | .. |
|---|
| 2020 | 2113 | .low_jitter = true, |
|---|
| 2021 | 2114 | .tcnt_mux = 23), |
|---|
| 2022 | 2115 | [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK( |
|---|
| 2116 | + SOC_ALL, |
|---|
| 2023 | 2117 | .name = "pwm", |
|---|
| 2024 | 2118 | .ctl_reg = CM_PWMCTL, |
|---|
| 2025 | 2119 | .div_reg = CM_PWMDIV, |
|---|
| .. | .. |
|---|
| 2028 | 2122 | .is_mash_clock = true, |
|---|
| 2029 | 2123 | .tcnt_mux = 24), |
|---|
| 2030 | 2124 | [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK( |
|---|
| 2125 | + SOC_ALL, |
|---|
| 2031 | 2126 | .name = "slim", |
|---|
| 2032 | 2127 | .ctl_reg = CM_SLIMCTL, |
|---|
| 2033 | 2128 | .div_reg = CM_SLIMDIV, |
|---|
| .. | .. |
|---|
| 2036 | 2131 | .is_mash_clock = true, |
|---|
| 2037 | 2132 | .tcnt_mux = 25), |
|---|
| 2038 | 2133 | [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK( |
|---|
| 2134 | + SOC_ALL, |
|---|
| 2039 | 2135 | .name = "smi", |
|---|
| 2040 | 2136 | .ctl_reg = CM_SMICTL, |
|---|
| 2041 | 2137 | .div_reg = CM_SMIDIV, |
|---|
| .. | .. |
|---|
| 2043 | 2139 | .frac_bits = 8, |
|---|
| 2044 | 2140 | .tcnt_mux = 27), |
|---|
| 2045 | 2141 | [BCM2835_CLOCK_UART] = REGISTER_PER_CLK( |
|---|
| 2142 | + SOC_ALL, |
|---|
| 2046 | 2143 | .name = "uart", |
|---|
| 2047 | 2144 | .ctl_reg = CM_UARTCTL, |
|---|
| 2048 | 2145 | .div_reg = CM_UARTDIV, |
|---|
| .. | .. |
|---|
| 2052 | 2149 | |
|---|
| 2053 | 2150 | /* TV encoder clock. Only operating frequency is 108Mhz. */ |
|---|
| 2054 | 2151 | [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK( |
|---|
| 2152 | + SOC_ALL, |
|---|
| 2055 | 2153 | .name = "vec", |
|---|
| 2056 | 2154 | .ctl_reg = CM_VECCTL, |
|---|
| 2057 | 2155 | .div_reg = CM_VECDIV, |
|---|
| .. | .. |
|---|
| 2066 | 2164 | |
|---|
| 2067 | 2165 | /* dsi clocks */ |
|---|
| 2068 | 2166 | [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK( |
|---|
| 2167 | + SOC_ALL, |
|---|
| 2069 | 2168 | .name = "dsi0e", |
|---|
| 2070 | 2169 | .ctl_reg = CM_DSI0ECTL, |
|---|
| 2071 | 2170 | .div_reg = CM_DSI0EDIV, |
|---|
| .. | .. |
|---|
| 2073 | 2172 | .frac_bits = 8, |
|---|
| 2074 | 2173 | .tcnt_mux = 18), |
|---|
| 2075 | 2174 | [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK( |
|---|
| 2175 | + SOC_ALL, |
|---|
| 2076 | 2176 | .name = "dsi1e", |
|---|
| 2077 | 2177 | .ctl_reg = CM_DSI1ECTL, |
|---|
| 2078 | 2178 | .div_reg = CM_DSI1EDIV, |
|---|
| .. | .. |
|---|
| 2080 | 2180 | .frac_bits = 8, |
|---|
| 2081 | 2181 | .tcnt_mux = 19), |
|---|
| 2082 | 2182 | [BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK( |
|---|
| 2183 | + SOC_ALL, |
|---|
| 2083 | 2184 | .name = "dsi0p", |
|---|
| 2084 | 2185 | .ctl_reg = CM_DSI0PCTL, |
|---|
| 2085 | 2186 | .div_reg = CM_DSI0PDIV, |
|---|
| .. | .. |
|---|
| 2087 | 2188 | .frac_bits = 0, |
|---|
| 2088 | 2189 | .tcnt_mux = 12), |
|---|
| 2089 | 2190 | [BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK( |
|---|
| 2191 | + SOC_ALL, |
|---|
| 2090 | 2192 | .name = "dsi1p", |
|---|
| 2091 | 2193 | .ctl_reg = CM_DSI1PCTL, |
|---|
| 2092 | 2194 | .div_reg = CM_DSI1PDIV, |
|---|
| .. | .. |
|---|
| 2103 | 2205 | * non-stop vpu clock. |
|---|
| 2104 | 2206 | */ |
|---|
| 2105 | 2207 | [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE( |
|---|
| 2208 | + SOC_ALL, |
|---|
| 2106 | 2209 | .name = "peri_image", |
|---|
| 2107 | 2210 | .parent = "vpu", |
|---|
| 2108 | 2211 | .ctl_reg = CM_PERIICTL), |
|---|
| .. | .. |
|---|
| 2132 | 2235 | struct device *dev = &pdev->dev; |
|---|
| 2133 | 2236 | struct clk_hw **hws; |
|---|
| 2134 | 2237 | struct bcm2835_cprman *cprman; |
|---|
| 2135 | | - struct resource *res; |
|---|
| 2136 | 2238 | const struct bcm2835_clk_desc *desc; |
|---|
| 2137 | 2239 | const size_t asize = ARRAY_SIZE(clk_desc_array); |
|---|
| 2240 | + const struct cprman_plat_data *pdata; |
|---|
| 2138 | 2241 | size_t i; |
|---|
| 2139 | 2242 | int ret; |
|---|
| 2243 | + |
|---|
| 2244 | + pdata = of_device_get_match_data(&pdev->dev); |
|---|
| 2245 | + if (!pdata) |
|---|
| 2246 | + return -ENODEV; |
|---|
| 2140 | 2247 | |
|---|
| 2141 | 2248 | cprman = devm_kzalloc(dev, |
|---|
| 2142 | 2249 | struct_size(cprman, onecell.hws, asize), |
|---|
| .. | .. |
|---|
| 2146 | 2253 | |
|---|
| 2147 | 2254 | spin_lock_init(&cprman->regs_lock); |
|---|
| 2148 | 2255 | cprman->dev = dev; |
|---|
| 2149 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 2150 | | - cprman->regs = devm_ioremap_resource(dev, res); |
|---|
| 2256 | + cprman->regs = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 2151 | 2257 | if (IS_ERR(cprman->regs)) |
|---|
| 2152 | 2258 | return PTR_ERR(cprman->regs); |
|---|
| 2153 | 2259 | |
|---|
| .. | .. |
|---|
| 2169 | 2275 | platform_set_drvdata(pdev, cprman); |
|---|
| 2170 | 2276 | |
|---|
| 2171 | 2277 | cprman->onecell.num = asize; |
|---|
| 2278 | + cprman->soc = pdata->soc; |
|---|
| 2172 | 2279 | hws = cprman->onecell.hws; |
|---|
| 2173 | 2280 | |
|---|
| 2174 | 2281 | for (i = 0; i < asize; i++) { |
|---|
| 2175 | 2282 | desc = &clk_desc_array[i]; |
|---|
| 2176 | | - if (desc->clk_register && desc->data) |
|---|
| 2283 | + if (desc->clk_register && desc->data && |
|---|
| 2284 | + (desc->supported & pdata->soc)) { |
|---|
| 2177 | 2285 | hws[i] = desc->clk_register(cprman, desc->data); |
|---|
| 2286 | + } |
|---|
| 2178 | 2287 | } |
|---|
| 2179 | 2288 | |
|---|
| 2180 | 2289 | ret = bcm2835_mark_sdc_parent_critical(hws[BCM2835_CLOCK_SDRAM]->clk); |
|---|
| .. | .. |
|---|
| 2185 | 2294 | &cprman->onecell); |
|---|
| 2186 | 2295 | } |
|---|
| 2187 | 2296 | |
|---|
| 2297 | +static const struct cprman_plat_data cprman_bcm2835_plat_data = { |
|---|
| 2298 | + .soc = SOC_BCM2835, |
|---|
| 2299 | +}; |
|---|
| 2300 | + |
|---|
| 2301 | +static const struct cprman_plat_data cprman_bcm2711_plat_data = { |
|---|
| 2302 | + .soc = SOC_BCM2711, |
|---|
| 2303 | +}; |
|---|
| 2304 | + |
|---|
| 2188 | 2305 | static const struct of_device_id bcm2835_clk_of_match[] = { |
|---|
| 2189 | | - { .compatible = "brcm,bcm2835-cprman", }, |
|---|
| 2306 | + { .compatible = "brcm,bcm2835-cprman", .data = &cprman_bcm2835_plat_data }, |
|---|
| 2307 | + { .compatible = "brcm,bcm2711-cprman", .data = &cprman_bcm2711_plat_data }, |
|---|
| 2190 | 2308 | {} |
|---|
| 2191 | 2309 | }; |
|---|
| 2192 | 2310 | MODULE_DEVICE_TABLE(of, bcm2835_clk_of_match); |
|---|
| .. | .. |
|---|
| 2203 | 2321 | |
|---|
| 2204 | 2322 | MODULE_AUTHOR("Eric Anholt <eric@anholt.net>"); |
|---|
| 2205 | 2323 | MODULE_DESCRIPTION("BCM2835 clock driver"); |
|---|
| 2206 | | -MODULE_LICENSE("GPL v2"); |
|---|
| 2324 | +MODULE_LICENSE("GPL"); |
|---|