aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Walmsley <pwalmsley@nvidia.com>2014-12-16 15:38:29 -0500
committerPeter De Schrijver <pdeschrijver@nvidia.com>2015-02-02 08:47:53 -0500
commit08acae34e8dadaa8c3a0a432760555bba1db8bfb (patch)
treecbba6132ec3a5a3acdd4d1785a376d775a9e6114
parent4ef0f2fded3fedf0786c6c032e210e108c19f19a (diff)
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>
-rw-r--r--drivers/clk/tegra/Makefile1
-rw-r--r--drivers/clk/tegra/clk-pll.c10
-rw-r--r--drivers/clk/tegra/clk-tegra124.c130
3 files changed, 129 insertions, 12 deletions
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index f7dfb72884a4..edb8358fa6ce 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o
15obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o 15obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o
16obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o 16obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o
17obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o 17obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o
18obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index fd18d2e30c4c..bfef9abdf232 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -816,7 +816,9 @@ const struct clk_ops tegra_clk_plle_ops = {
816 .enable = clk_plle_enable, 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
821static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, 823static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params,
822 unsigned long parent_rate) 824 unsigned long parent_rate)
@@ -1505,7 +1507,9 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
1505 return clk; 1507 return clk;
1506} 1508}
1507 1509
1508#if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) 1510#if defined(CONFIG_ARCH_TEGRA_114_SOC) || \
1511 defined(CONFIG_ARCH_TEGRA_124_SOC) || \
1512 defined(CONFIG_ARCH_TEGRA_132_SOC)
1509static const struct clk_ops tegra_clk_pllxc_ops = { 1513static const struct clk_ops tegra_clk_pllxc_ops = {
1510 .is_enabled = clk_pll_is_enabled, 1514 .is_enabled = clk_pll_is_enabled,
1511 .enable = clk_pll_iddq_enable, 1515 .enable = clk_pll_iddq_enable,
@@ -1802,7 +1806,7 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
1802} 1806}
1803#endif 1807#endif
1804 1808
1805#ifdef CONFIG_ARCH_TEGRA_124_SOC 1809#if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC)
1806static const struct clk_ops tegra_clk_pllss_ops = { 1810static const struct clk_ops tegra_clk_pllss_ops = {
1807 .is_enabled = clk_pll_is_enabled, 1811 .is_enabled = clk_pll_is_enabled,
1808 .enable = clk_pll_iddq_enable, 1812 .enable = clk_pll_iddq_enable,
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index 5b9bd8a59fe8..5c11ed9f5e54 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -1,5 +1,5 @@
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 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -28,6 +28,14 @@
28#include "clk.h" 28#include "clk.h"
29#include "clk-id.h" 29#include "clk-id.h"
30 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
38
31#define CLK_SOURCE_CSITE 0x1d4 39#define CLK_SOURCE_CSITE 0x1d4
32#define CLK_SOURCE_EMC 0x19c 40#define CLK_SOURCE_EMC 0x19c
33 41
@@ -1351,7 +1359,7 @@ static const struct of_device_id pmc_match[] __initconst = {
1351 {}, 1359 {},
1352}; 1360};
1353 1361
1354static struct tegra_clk_init_table init_table[] __initdata = { 1362static struct tegra_clk_init_table common_init_table[] __initdata = {
1355 {TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 408000000, 0}, 1363 {TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 408000000, 0},
1356 {TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0}, 1364 {TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0},
1357 {TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0}, 1365 {TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0},
@@ -1387,27 +1395,72 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1387 {TEGRA124_CLK_SATA, TEGRA124_CLK_PLL_P, 104000000, 0}, 1395 {TEGRA124_CLK_SATA, TEGRA124_CLK_PLL_P, 104000000, 0},
1388 {TEGRA124_CLK_SATA_OOB, TEGRA124_CLK_PLL_P, 204000000, 0}, 1396 {TEGRA124_CLK_SATA_OOB, TEGRA124_CLK_PLL_P, 204000000, 0},
1389 {TEGRA124_CLK_EMC, TEGRA124_CLK_CLK_MAX, 0, 1}, 1397 {TEGRA124_CLK_EMC, TEGRA124_CLK_CLK_MAX, 0, 1},
1390 {TEGRA124_CLK_CCLK_G, TEGRA124_CLK_CLK_MAX, 0, 1},
1391 {TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1}, 1398 {TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1},
1392 {TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1}, 1399 {TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1},
1393 {TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0}, 1400 {TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0},
1401 /* This MUST be the last entry. */
1402 {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
1403};
1404
1405static struct tegra_clk_init_table tegra124_init_table[] __initdata = {
1394 {TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 0}, 1406 {TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 0},
1407 {TEGRA124_CLK_CCLK_G, TEGRA124_CLK_CLK_MAX, 0, 1},
1408 /* This MUST be the last entry. */
1409 {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
1410};
1411
1412/* Tegra132 requires the SOC_THERM clock to remain active */
1413static struct tegra_clk_init_table tegra132_init_table[] __initdata = {
1414 {TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 1},
1395 /* This MUST be the last entry. */ 1415 /* This MUST be the last entry. */
1396 {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, 1416 {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
1397}; 1417};
1398 1418
1419/**
1420 * tegra124_clock_apply_init_table - initialize clocks on Tegra124 SoCs
1421 *
1422 * Program an initial clock rate and enable or disable clocks needed
1423 * by the rest of the kernel, for Tegra124 SoCs. It is intended to be
1424 * called by assigning a pointer to it to tegra_clk_apply_init_table -
1425 * this will be called as an arch_initcall. No return value.
1426 */
1399static void __init tegra124_clock_apply_init_table(void) 1427static void __init tegra124_clock_apply_init_table(void)
1400{ 1428{
1401 tegra_init_from_table(init_table, clks, TEGRA124_CLK_CLK_MAX); 1429 tegra_init_from_table(common_init_table, clks, TEGRA124_CLK_CLK_MAX);
1430 tegra_init_from_table(tegra124_init_table, clks, TEGRA124_CLK_CLK_MAX);
1402} 1431}
1403 1432
1404static void __init tegra124_clock_init(struct device_node *np) 1433/**
1434 * tegra132_clock_apply_init_table - initialize clocks on Tegra132 SoCs
1435 *
1436 * Program an initial clock rate and enable or disable clocks needed
1437 * by the rest of the kernel, for Tegra132 SoCs. It is intended to be
1438 * called by assigning a pointer to it to tegra_clk_apply_init_table -
1439 * this will be called as an arch_initcall. No return value.
1440 */
1441static void __init tegra132_clock_apply_init_table(void)
1442{
1443 tegra_init_from_table(common_init_table, clks, TEGRA124_CLK_CLK_MAX);
1444 tegra_init_from_table(tegra132_init_table, clks, TEGRA124_CLK_CLK_MAX);
1445}
1446
1447/**
1448 * tegra124_132_clock_init_pre - clock initialization preamble for T124/T132
1449 * @np: struct device_node * of the DT node for the SoC CAR IP block
1450 *
1451 * Register most of the clocks controlled by the CAR IP block, along
1452 * with a few clocks controlled by the PMC IP block. Everything in
1453 * this function should be common to Tegra124 and Tegra132. XXX The
1454 * PMC clock initialization should probably be moved to PMC-specific
1455 * driver code. No return value.
1456 */
1457static void __init tegra124_132_clock_init_pre(struct device_node *np)
1405{ 1458{
1406 struct device_node *node; 1459 struct device_node *node;
1407 1460
1408 clk_base = of_iomap(np, 0); 1461 clk_base = of_iomap(np, 0);
1409 if (!clk_base) { 1462 if (!clk_base) {
1410 pr_err("ioremap tegra124 CAR failed\n"); 1463 pr_err("ioremap tegra124/tegra132 CAR failed\n");
1411 return; 1464 return;
1412 } 1465 }
1413 1466
@@ -1425,7 +1478,8 @@ static void __init tegra124_clock_init(struct device_node *np)
1425 return; 1478 return;
1426 } 1479 }
1427 1480
1428 clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX, 6); 1481 clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX,
1482 TEGRA124_CAR_BANK_COUNT);
1429 if (!clks) 1483 if (!clks)
1430 return; 1484 return;
1431 1485
@@ -1438,14 +1492,72 @@ static void __init tegra124_clock_init(struct device_node *np)
1438 tegra124_periph_clk_init(clk_base, pmc_base); 1492 tegra124_periph_clk_init(clk_base, pmc_base);
1439 tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, &pll_a_params); 1493 tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, &pll_a_params);
1440 tegra_pmc_clk_init(pmc_base, tegra124_clks); 1494 tegra_pmc_clk_init(pmc_base, tegra124_clks);
1495}
1441 1496
1497/**
1498 * tegra124_132_clock_init_post - clock initialization postamble for T124/T132
1499 * @np: struct device_node * of the DT node for the SoC CAR IP block
1500 *
1501 * Register most of the along with a few clocks controlled by the PMC
1502 * IP block. Everything in this function should be common to Tegra124
1503 * and Tegra132. This function must be called after
1504 * tegra124_132_clock_init_pre(), otherwise clk_base and pmc_base will
1505 * not be set. No return value.
1506 */
1507static void __init tegra124_132_clock_init_post(struct device_node *np)
1508{
1442 tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks, 1509 tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks,
1443 &pll_x_params); 1510 &pll_x_params);
1444 tegra_add_of_provider(np); 1511 tegra_add_of_provider(np);
1445 tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); 1512 tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
1446 1513
1514 tegra_cpu_car_ops = &tegra124_cpu_car_ops;
1515}
1516
1517/**
1518 * tegra124_clock_init - Tegra124-specific clock initialization
1519 * @np: struct device_node * of the DT node for the SoC CAR IP block
1520 *
1521 * Register most SoC clocks for the Tegra124 system-on-chip. Most of
1522 * this code is shared between the Tegra124 and Tegra132 SoCs,
1523 * although some of the initial clock settings and CPU clocks differ.
1524 * Intended to be called by the OF init code when a DT node with the
1525 * "nvidia,tegra124-car" string is encountered, and declared with
1526 * CLK_OF_DECLARE. No return value.
1527 */
1528static void __init tegra124_clock_init(struct device_node *np)
1529{
1530 tegra124_132_clock_init_pre(np);
1447 tegra_clk_apply_init_table = tegra124_clock_apply_init_table; 1531 tegra_clk_apply_init_table = tegra124_clock_apply_init_table;
1532 tegra124_132_clock_init_post(np);
1533}
1448 1534
1449 tegra_cpu_car_ops = &tegra124_cpu_car_ops; 1535/**
1536 * tegra132_clock_init - Tegra132-specific clock initialization
1537 * @np: struct device_node * of the DT node for the SoC CAR IP block
1538 *
1539 * Register most SoC clocks for the Tegra132 system-on-chip. Most of
1540 * this code is shared between the Tegra124 and Tegra132 SoCs,
1541 * although some of the initial clock settings and CPU clocks differ.
1542 * Intended to be called by the OF init code when a DT node with the
1543 * "nvidia,tegra132-car" string is encountered, and declared with
1544 * CLK_OF_DECLARE. No return value.
1545 */
1546static void __init tegra132_clock_init(struct device_node *np)
1547{
1548 tegra124_132_clock_init_pre(np);
1549
1550 /*
1551 * On Tegra132, these clocks are controlled by the
1552 * CLUSTER_clocks IP block, located in the CPU complex
1553 */
1554 tegra124_clks[tegra_clk_cclk_g].present = false;
1555 tegra124_clks[tegra_clk_cclk_lp].present = false;
1556 tegra124_clks[tegra_clk_pll_x].present = false;
1557 tegra124_clks[tegra_clk_pll_x_out0].present = false;
1558
1559 tegra_clk_apply_init_table = tegra132_clock_apply_init_table;
1560 tegra124_132_clock_init_post(np);
1450} 1561}
1451CLK_OF_DECLARE(tegra124, "nvidia,tegra124-car", tegra124_clock_init); 1562CLK_OF_DECLARE(tegra124, "nvidia,tegra124-car", tegra124_clock_init);
1563CLK_OF_DECLARE(tegra132, "nvidia,tegra132-car", tegra132_clock_init);