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

clk: tegra: Add support for the Tegra132 CAR IP block

Tegra132 CAR supports almost the same clocks as Tegra124 CAR. This
patch mostly deals with the small differences.

Since Tegra132 contains many of the same PLL clock sources used on
Tegra114 and Tegra124, enable them in drivers/clk/tegra/clk-pll.c when
the kernel is configured to include Tegra132 support.

This patch is based on several patches from others:

1. a patch from Peter De Schrijver:

http://lkml.iu.edu/hypermail/linux/kernel/1407.1/06094.html

2. a patch from Bill Huang ("clk: tegra: enable cclk_g at boot on
Tegra132"), and

3. a patch from Allen Martin ("clk: Enable tegra clock driver for
tegra132").

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Paul Walmsley <pwalmsley@nvidia.com>
Cc: Peter De Schrijver <pdeschrijver@nvidia.com>
Cc: Allen Martin <amartin@nvidia.com>
Cc: Prashant Gaikwad <pgaikwad@nvidia.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Bill Huang <bilhuang@nvidia.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Stephen Boyd <sboyd@codeaurora.org>

authored by

Paul Walmsley and committed by
Peter De Schrijver
08acae34 4ef0f2fd

+131 -14
+1
drivers/clk/tegra/Makefile
··· 15 15 obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o 16 16 obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o 17 17 obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o 18 + obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o
+7 -3
drivers/clk/tegra/clk-pll.c
··· 816 816 .enable = clk_plle_enable, 817 817 }; 818 818 819 - #if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) 819 + #if defined(CONFIG_ARCH_TEGRA_114_SOC) || \ 820 + defined(CONFIG_ARCH_TEGRA_124_SOC) || \ 821 + defined(CONFIG_ARCH_TEGRA_132_SOC) 820 822 821 823 static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, 822 824 unsigned long parent_rate) ··· 1507 1505 return clk; 1508 1506 } 1509 1507 1510 - #if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) 1508 + #if defined(CONFIG_ARCH_TEGRA_114_SOC) || \ 1509 + defined(CONFIG_ARCH_TEGRA_124_SOC) || \ 1510 + defined(CONFIG_ARCH_TEGRA_132_SOC) 1511 1511 static const struct clk_ops tegra_clk_pllxc_ops = { 1512 1512 .is_enabled = clk_pll_is_enabled, 1513 1513 .enable = clk_pll_iddq_enable, ··· 1806 1802 } 1807 1803 #endif 1808 1804 1809 - #ifdef CONFIG_ARCH_TEGRA_124_SOC 1805 + #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC) 1810 1806 static const struct clk_ops tegra_clk_pllss_ops = { 1811 1807 .is_enabled = clk_pll_is_enabled, 1812 1808 .enable = clk_pll_iddq_enable,
+123 -11
drivers/clk/tegra/clk-tegra124.c
··· 1 1 /* 2 - * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. 2 + * Copyright (c) 2012-2014 NVIDIA CORPORATION. All rights reserved. 3 3 * 4 4 * This program is free software; you can redistribute it and/or modify it 5 5 * under the terms and conditions of the GNU General Public License, ··· 27 27 28 28 #include "clk.h" 29 29 #include "clk-id.h" 30 + 31 + /* 32 + * TEGRA124_CAR_BANK_COUNT: the number of peripheral clock register 33 + * banks present in the Tegra124/132 CAR IP block. The banks are 34 + * identified by single letters, e.g.: L, H, U, V, W, X. See 35 + * periph_regs[] in drivers/clk/tegra/clk.c 36 + */ 37 + #define TEGRA124_CAR_BANK_COUNT 6 30 38 31 39 #define CLK_SOURCE_CSITE 0x1d4 32 40 #define CLK_SOURCE_EMC 0x19c ··· 1359 1351 {}, 1360 1352 }; 1361 1353 1362 - static struct tegra_clk_init_table init_table[] __initdata = { 1354 + static struct tegra_clk_init_table common_init_table[] __initdata = { 1363 1355 {TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 408000000, 0}, 1364 1356 {TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0}, 1365 1357 {TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0}, ··· 1395 1387 {TEGRA124_CLK_SATA, TEGRA124_CLK_PLL_P, 104000000, 0}, 1396 1388 {TEGRA124_CLK_SATA_OOB, TEGRA124_CLK_PLL_P, 204000000, 0}, 1397 1389 {TEGRA124_CLK_EMC, TEGRA124_CLK_CLK_MAX, 0, 1}, 1398 - {TEGRA124_CLK_CCLK_G, TEGRA124_CLK_CLK_MAX, 0, 1}, 1399 1390 {TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1}, 1400 1391 {TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1}, 1401 1392 {TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0}, 1402 - {TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 0}, 1403 1393 /* This MUST be the last entry. */ 1404 1394 {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, 1405 1395 }; 1406 1396 1397 + static struct tegra_clk_init_table tegra124_init_table[] __initdata = { 1398 + {TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 0}, 1399 + {TEGRA124_CLK_CCLK_G, TEGRA124_CLK_CLK_MAX, 0, 1}, 1400 + /* This MUST be the last entry. */ 1401 + {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, 1402 + }; 1403 + 1404 + /* Tegra132 requires the SOC_THERM clock to remain active */ 1405 + static struct tegra_clk_init_table tegra132_init_table[] __initdata = { 1406 + {TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 1}, 1407 + /* This MUST be the last entry. */ 1408 + {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, 1409 + }; 1410 + 1411 + /** 1412 + * tegra124_clock_apply_init_table - initialize clocks on Tegra124 SoCs 1413 + * 1414 + * Program an initial clock rate and enable or disable clocks needed 1415 + * by the rest of the kernel, for Tegra124 SoCs. It is intended to be 1416 + * called by assigning a pointer to it to tegra_clk_apply_init_table - 1417 + * this will be called as an arch_initcall. No return value. 1418 + */ 1407 1419 static void __init tegra124_clock_apply_init_table(void) 1408 1420 { 1409 - tegra_init_from_table(init_table, clks, TEGRA124_CLK_CLK_MAX); 1421 + tegra_init_from_table(common_init_table, clks, TEGRA124_CLK_CLK_MAX); 1422 + tegra_init_from_table(tegra124_init_table, clks, TEGRA124_CLK_CLK_MAX); 1410 1423 } 1411 1424 1412 - static void __init tegra124_clock_init(struct device_node *np) 1425 + /** 1426 + * tegra132_clock_apply_init_table - initialize clocks on Tegra132 SoCs 1427 + * 1428 + * Program an initial clock rate and enable or disable clocks needed 1429 + * by the rest of the kernel, for Tegra132 SoCs. It is intended to be 1430 + * called by assigning a pointer to it to tegra_clk_apply_init_table - 1431 + * this will be called as an arch_initcall. No return value. 1432 + */ 1433 + static void __init tegra132_clock_apply_init_table(void) 1434 + { 1435 + tegra_init_from_table(common_init_table, clks, TEGRA124_CLK_CLK_MAX); 1436 + tegra_init_from_table(tegra132_init_table, clks, TEGRA124_CLK_CLK_MAX); 1437 + } 1438 + 1439 + /** 1440 + * tegra124_132_clock_init_pre - clock initialization preamble for T124/T132 1441 + * @np: struct device_node * of the DT node for the SoC CAR IP block 1442 + * 1443 + * Register most of the clocks controlled by the CAR IP block, along 1444 + * with a few clocks controlled by the PMC IP block. Everything in 1445 + * this function should be common to Tegra124 and Tegra132. XXX The 1446 + * PMC clock initialization should probably be moved to PMC-specific 1447 + * driver code. No return value. 1448 + */ 1449 + static void __init tegra124_132_clock_init_pre(struct device_node *np) 1413 1450 { 1414 1451 struct device_node *node; 1415 1452 1416 1453 clk_base = of_iomap(np, 0); 1417 1454 if (!clk_base) { 1418 - pr_err("ioremap tegra124 CAR failed\n"); 1455 + pr_err("ioremap tegra124/tegra132 CAR failed\n"); 1419 1456 return; 1420 1457 } 1421 1458 ··· 1478 1425 return; 1479 1426 } 1480 1427 1481 - clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX, 6); 1428 + clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX, 1429 + TEGRA124_CAR_BANK_COUNT); 1482 1430 if (!clks) 1483 1431 return; 1484 1432 ··· 1492 1438 tegra124_periph_clk_init(clk_base, pmc_base); 1493 1439 tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, &pll_a_params); 1494 1440 tegra_pmc_clk_init(pmc_base, tegra124_clks); 1441 + } 1495 1442 1443 + /** 1444 + * tegra124_132_clock_init_post - clock initialization postamble for T124/T132 1445 + * @np: struct device_node * of the DT node for the SoC CAR IP block 1446 + * 1447 + * Register most of the along with a few clocks controlled by the PMC 1448 + * IP block. Everything in this function should be common to Tegra124 1449 + * and Tegra132. This function must be called after 1450 + * tegra124_132_clock_init_pre(), otherwise clk_base and pmc_base will 1451 + * not be set. No return value. 1452 + */ 1453 + static void __init tegra124_132_clock_init_post(struct device_node *np) 1454 + { 1496 1455 tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks, 1497 - &pll_x_params); 1456 + &pll_x_params); 1498 1457 tegra_add_of_provider(np); 1499 1458 tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); 1500 1459 1501 - tegra_clk_apply_init_table = tegra124_clock_apply_init_table; 1502 - 1503 1460 tegra_cpu_car_ops = &tegra124_cpu_car_ops; 1504 1461 } 1462 + 1463 + /** 1464 + * tegra124_clock_init - Tegra124-specific clock initialization 1465 + * @np: struct device_node * of the DT node for the SoC CAR IP block 1466 + * 1467 + * Register most SoC clocks for the Tegra124 system-on-chip. Most of 1468 + * this code is shared between the Tegra124 and Tegra132 SoCs, 1469 + * although some of the initial clock settings and CPU clocks differ. 1470 + * Intended to be called by the OF init code when a DT node with the 1471 + * "nvidia,tegra124-car" string is encountered, and declared with 1472 + * CLK_OF_DECLARE. No return value. 1473 + */ 1474 + static void __init tegra124_clock_init(struct device_node *np) 1475 + { 1476 + tegra124_132_clock_init_pre(np); 1477 + tegra_clk_apply_init_table = tegra124_clock_apply_init_table; 1478 + tegra124_132_clock_init_post(np); 1479 + } 1480 + 1481 + /** 1482 + * tegra132_clock_init - Tegra132-specific clock initialization 1483 + * @np: struct device_node * of the DT node for the SoC CAR IP block 1484 + * 1485 + * Register most SoC clocks for the Tegra132 system-on-chip. Most of 1486 + * this code is shared between the Tegra124 and Tegra132 SoCs, 1487 + * although some of the initial clock settings and CPU clocks differ. 1488 + * Intended to be called by the OF init code when a DT node with the 1489 + * "nvidia,tegra132-car" string is encountered, and declared with 1490 + * CLK_OF_DECLARE. No return value. 1491 + */ 1492 + static void __init tegra132_clock_init(struct device_node *np) 1493 + { 1494 + tegra124_132_clock_init_pre(np); 1495 + 1496 + /* 1497 + * On Tegra132, these clocks are controlled by the 1498 + * CLUSTER_clocks IP block, located in the CPU complex 1499 + */ 1500 + tegra124_clks[tegra_clk_cclk_g].present = false; 1501 + tegra124_clks[tegra_clk_cclk_lp].present = false; 1502 + tegra124_clks[tegra_clk_pll_x].present = false; 1503 + tegra124_clks[tegra_clk_pll_x_out0].present = false; 1504 + 1505 + tegra_clk_apply_init_table = tegra132_clock_apply_init_table; 1506 + tegra124_132_clock_init_post(np); 1507 + } 1505 1508 CLK_OF_DECLARE(tegra124, "nvidia,tegra124-car", tegra124_clock_init); 1509 + CLK_OF_DECLARE(tegra132, "nvidia,tegra132-car", tegra132_clock_init);