diff options
| -rw-r--r-- | drivers/clk/tegra/clk-tegra124.c | 68 | ||||
| -rw-r--r-- | include/dt-bindings/reset/tegra124-car.h | 12 |
2 files changed, 80 insertions, 0 deletions
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index e8cca3eac007..106ec458c945 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/export.h> | 24 | #include <linux/export.h> |
| 25 | #include <linux/clk/tegra.h> | 25 | #include <linux/clk/tegra.h> |
| 26 | #include <dt-bindings/clock/tegra124-car.h> | 26 | #include <dt-bindings/clock/tegra124-car.h> |
| 27 | #include <dt-bindings/reset/tegra124-car.h> | ||
| 27 | 28 | ||
| 28 | #include "clk.h" | 29 | #include "clk.h" |
| 29 | #include "clk-id.h" | 30 | #include "clk-id.h" |
| @@ -39,6 +40,9 @@ | |||
| 39 | #define CLK_SOURCE_CSITE 0x1d4 | 40 | #define CLK_SOURCE_CSITE 0x1d4 |
| 40 | #define CLK_SOURCE_EMC 0x19c | 41 | #define CLK_SOURCE_EMC 0x19c |
| 41 | 42 | ||
| 43 | #define RST_DFLL_DVCO 0x2f4 | ||
| 44 | #define DVFS_DFLL_RESET_SHIFT 0 | ||
| 45 | |||
| 42 | #define PLLC_BASE 0x80 | 46 | #define PLLC_BASE 0x80 |
| 43 | #define PLLC_OUT 0x84 | 47 | #define PLLC_OUT 0x84 |
| 44 | #define PLLC_MISC2 0x88 | 48 | #define PLLC_MISC2 0x88 |
| @@ -1415,6 +1419,68 @@ static void __init tegra124_clock_apply_init_table(void) | |||
| 1415 | } | 1419 | } |
| 1416 | 1420 | ||
| 1417 | /** | 1421 | /** |
| 1422 | * tegra124_car_barrier - wait for pending writes to the CAR to complete | ||
| 1423 | * | ||
| 1424 | * Wait for any outstanding writes to the CAR MMIO space from this CPU | ||
| 1425 | * to complete before continuing execution. No return value. | ||
| 1426 | */ | ||
| 1427 | static void tegra124_car_barrier(void) | ||
| 1428 | { | ||
| 1429 | readl_relaxed(clk_base + RST_DFLL_DVCO); | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | /** | ||
| 1433 | * tegra124_clock_assert_dfll_dvco_reset - assert the DFLL's DVCO reset | ||
| 1434 | * | ||
| 1435 | * Assert the reset line of the DFLL's DVCO. No return value. | ||
| 1436 | */ | ||
| 1437 | void tegra124_clock_assert_dfll_dvco_reset(void) | ||
| 1438 | { | ||
| 1439 | u32 v; | ||
| 1440 | |||
| 1441 | v = readl_relaxed(clk_base + RST_DFLL_DVCO); | ||
| 1442 | v |= (1 << DVFS_DFLL_RESET_SHIFT); | ||
| 1443 | writel_relaxed(v, clk_base + RST_DFLL_DVCO); | ||
| 1444 | tegra124_car_barrier(); | ||
| 1445 | } | ||
| 1446 | |||
| 1447 | /** | ||
| 1448 | * tegra124_clock_deassert_dfll_dvco_reset - deassert the DFLL's DVCO reset | ||
| 1449 | * | ||
| 1450 | * Deassert the reset line of the DFLL's DVCO, allowing the DVCO to | ||
| 1451 | * operate. No return value. | ||
| 1452 | */ | ||
| 1453 | void tegra124_clock_deassert_dfll_dvco_reset(void) | ||
| 1454 | { | ||
| 1455 | u32 v; | ||
| 1456 | |||
| 1457 | v = readl_relaxed(clk_base + RST_DFLL_DVCO); | ||
| 1458 | v &= ~(1 << DVFS_DFLL_RESET_SHIFT); | ||
| 1459 | writel_relaxed(v, clk_base + RST_DFLL_DVCO); | ||
| 1460 | tegra124_car_barrier(); | ||
| 1461 | } | ||
| 1462 | |||
| 1463 | int tegra124_reset_assert(unsigned long id) | ||
| 1464 | { | ||
| 1465 | if (id == TEGRA124_RST_DFLL_DVCO) | ||
| 1466 | tegra124_clock_assert_dfll_dvco_reset(); | ||
| 1467 | else | ||
| 1468 | return -EINVAL; | ||
| 1469 | |||
| 1470 | return 0; | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | int tegra124_reset_deassert(unsigned long id) | ||
| 1474 | { | ||
| 1475 | if (id == TEGRA124_RST_DFLL_DVCO) | ||
| 1476 | tegra124_clock_deassert_dfll_dvco_reset(); | ||
| 1477 | else | ||
| 1478 | return -EINVAL; | ||
| 1479 | |||
| 1480 | return 0; | ||
| 1481 | } | ||
| 1482 | |||
| 1483 | /** | ||
| 1418 | * tegra132_clock_apply_init_table - initialize clocks on Tegra132 SoCs | 1484 | * tegra132_clock_apply_init_table - initialize clocks on Tegra132 SoCs |
| 1419 | * | 1485 | * |
| 1420 | * Program an initial clock rate and enable or disable clocks needed | 1486 | * Program an initial clock rate and enable or disable clocks needed |
| @@ -1499,6 +1565,8 @@ static void __init tegra124_132_clock_init_post(struct device_node *np) | |||
| 1499 | { | 1565 | { |
| 1500 | tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks, | 1566 | tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks, |
| 1501 | &pll_x_params); | 1567 | &pll_x_params); |
| 1568 | tegra_init_special_resets(1, tegra124_reset_assert, | ||
| 1569 | tegra124_reset_deassert); | ||
| 1502 | tegra_add_of_provider(np); | 1570 | tegra_add_of_provider(np); |
| 1503 | 1571 | ||
| 1504 | clks[TEGRA124_CLK_EMC] = tegra_clk_register_emc(clk_base, np, | 1572 | clks[TEGRA124_CLK_EMC] = tegra_clk_register_emc(clk_base, np, |
diff --git a/include/dt-bindings/reset/tegra124-car.h b/include/dt-bindings/reset/tegra124-car.h new file mode 100644 index 000000000000..070e4f6e7486 --- /dev/null +++ b/include/dt-bindings/reset/tegra124-car.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | /* | ||
| 2 | * This header provides Tegra124-specific constants for binding | ||
| 3 | * nvidia,tegra124-car. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef _DT_BINDINGS_RESET_TEGRA124_CAR_H | ||
| 7 | #define _DT_BINDINGS_RESET_TEGRA124_CAR_H | ||
| 8 | |||
| 9 | #define TEGRA124_RESET(x) (6 * 32 + (x)) | ||
| 10 | #define TEGRA124_RST_DFLL_DVCO TEGRA124_RESET(0) | ||
| 11 | |||
| 12 | #endif /* _DT_BINDINGS_RESET_TEGRA124_CAR_H */ | ||
