arm: tegra: Move driver files to drivers/platform
[linux-3.10.git] / drivers / platform / tegra / tegra21_clocks.c
index a64d484..64dd550 100644 (file)
 
 #include <tegra/mc.h>
 
-#include "clock.h"
+#include <linux/platform/tegra/clock.h>
 #include "tegra_clocks_ops.h"
-#include "dvfs.h"
+#include <linux/platform/tegra/dvfs.h>
 #include "pm.h"
 #include "sleep.h"
 #include "devices.h"
-#include "tegra_cl_dvfs.h"
-#include "cpu-tegra.h"
+#include <linux/platform/tegra/tegra_cl_dvfs.h>
+#include <linux/platform/tegra/cpu-tegra.h>
 
+/* FIXME: Disable for initial Si bringup */
 #undef USE_PLLE_SS
-#define USE_PLLE_SS 1
+#define USE_PLLE_SS 0
 
 #define RST_DEVICES_L                  0x004
 #define RST_DEVICES_H                  0x008
 #define PLLE_SS_COEFFICIENTS_MASK      \
        (PLLE_SS_INCINTRV_MASK | PLLE_SS_INC_MASK | PLLE_SS_MAX_MASK)
 #define PLLE_SS_COEFFICIENTS_VAL       \
-       ((0x1F<<PLLE_SS_INCINTRV_SHIFT) | (0x1<<PLLE_SS_INC_SHIFT) | \
+       ((0x20<<PLLE_SS_INCINTRV_SHIFT) | (0x1<<PLLE_SS_INC_SHIFT) | \
         (0x25<<PLLE_SS_MAX_SHIFT))
 #define PLLE_SS_DISABLE                        (PLLE_SS_CNTL_SSC_BYP |\
        PLLE_SS_CNTL_INTERP_RESET | PLLE_SS_CNTL_BYPASS_SS)
@@ -628,7 +629,7 @@ static const struct utmi_clk_param utmi_parameters[] =
 
        {19200000,      0x03,           0x4B,           0x06,           0xBB},
        /* HACK!!! FIXME!!! following entry for 38.4MHz is a stub */
-       {38400000,      0x0,            0x50,           0x06,           0x3},
+       {38400000,      0x03,           0x4B,           0x06,           0x80}
 };
 
 static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
@@ -1741,6 +1742,10 @@ static void sbus_build_round_table_one(struct clk *c, unsigned long rate, int j)
                c, sel.src, flags, rate, false, &sel.div);
        sbus_round_table[j] = sel;
 
+       /* Don't use high frequency source above threshold */
+       if (rate <= c->u.system.threshold)
+               return;
+
        sel.src = c->u.system.sclk_high;
        sel.rate = fixed_src_bus_round_updown(
                c, sel.src, flags, rate, false, &sel.div);
@@ -2234,6 +2239,10 @@ static void tegra21_utmi_param_configure(struct clk *c)
                return;
        }
 
+       reg = clk_readl(UTMIPLL_HW_PWRDN_CFG0);
+       reg &= ~UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE;
+       pll_writel_delay(reg, UTMIPLL_HW_PWRDN_CFG0);
+
        reg = clk_readl(UTMIP_PLL_CFG2);
        /* Program UTMIP PLL stable and active counts */
        /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */
@@ -2272,6 +2281,21 @@ static void tegra21_utmi_param_configure(struct clk *c)
        reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_D_POWERDOWN;
        clk_writel(reg, UTMIP_PLL_CFG2);
 
+       /* Enable HW Power Sequencer */
+       reg = clk_readl(UTMIP_PLL_CFG1);
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP;
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
+       clk_writel(reg, UTMIP_PLL_CFG1);
+
+       reg = clk_readl(UTMIPLL_HW_PWRDN_CFG0);
+       reg &= ~UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL;
+       reg |= UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET;
+       pll_writel_delay(reg, UTMIPLL_HW_PWRDN_CFG0);
+
+       /* Enable HW control UTMIPLL */
+       reg = clk_readl(UTMIPLL_HW_PWRDN_CFG0);
+       reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE;
+       pll_writel_delay(reg, UTMIPLL_HW_PWRDN_CFG0);
 }
 
 /*
@@ -5276,6 +5300,22 @@ static struct clk_ops tegra_mc_clk_ops = {
        .disable                = &tegra21_periph_clk_disable,
 };
 
+#ifdef CONFIG_PM_SLEEP
+static void tegra21_emc_clk_suspend(struct clk *c, unsigned long rate)
+{
+       /* No change in emc configuration for LP1 */
+       if (!tegra_is_lp0_suspend_mode())
+               return;
+
+       /*
+        * Scale EMC rate at/below boot rate - required for entering SC7(LP0)
+        * on LPDDR4, but applied to LPDDR3 as well.
+        * FIXME: keep it general or check for LPDDR4 below?
+        */
+       if (rate > c->boot_rate)
+               tegra21_emc_clk_set_rate(c, c->boot_rate);
+}
+#endif
 
 /* Clock doubler ops (non-atomic shared register access) */
 static DEFINE_SPINLOCK(doubler_lock);
@@ -7942,12 +7982,11 @@ static struct clk_mux_sel mux_pllc_pllp_plla[] = {
        { 0, 0},
 };
 
-static struct clk_mux_sel mux_pllc_pllp_plla_pllc4[] = {
+static struct clk_mux_sel mux_clkm_pllc_pllp_plla[] = {
+       { .input = &tegra_clk_m, .value = 0},
        { .input = &tegra_pll_c, .value = 1},
        { .input = &tegra_pll_p, .value = 2},
        { .input = &tegra_pll_a_out0, .value = 3},
-       /* Skip C2(4) */
-       { .input = &tegra_pll_c4_out0, .value = 5},
        { 0, 0},
 };
 
@@ -7961,11 +8000,12 @@ static struct clk_mux_sel mux_pllc_pllp_plla1_pllc2_c3_clkm[] = {
        { 0, 0},
 };
 
-static struct clk_mux_sel mux_pllc2_c_c3_pllp_plla1_pllc4[] = {
+static struct clk_mux_sel mux_pllc2_c_c3_pllp_clkm_plla1_pllc4[] = {
        { .input = &tegra_pll_c2, .value = 1},
        { .input = &tegra_pll_c, .value = 2},
        { .input = &tegra_pll_c3, .value = 3},
        { .input = &tegra_pll_p, .value = 4},
+       { .input = &tegra_clk_m, .value = 5},
        { .input = &tegra_pll_a1, .value = 6},
        { .input = &tegra_pll_c4_out0, .value = 7},
        { 0, 0},
@@ -8108,8 +8148,9 @@ static struct clk_mux_sel mux_pllp_pllc_pllc4_out0_pllc4_out1_clkm_pllc4_out2[]
        { 0, 0},
 };
 
-static struct clk_mux_sel mux_pllp_pllc_pllc4_out2_pllc4_out1_clkm_pllc4_out0[] = {
+static struct clk_mux_sel mux_pllp_pllc_pllc_out1_pllc4_out2_pllc4_out1_clkm_pllc4_out0[] = {
        {.input = &tegra_pll_p,             .value = 0},
+       {.input = &tegra_pll_c_out1,        .value = 1},
        {.input = &tegra_pll_c,             .value = 2},
        {.input = &tegra_pll_c4_out2,       .value = 4},
        {.input = &tegra_pll_c4_out1,       .value = 5},
@@ -8148,9 +8189,10 @@ static struct clk_mux_sel mux_pllp_pllc2_c_c3_clkm[] = {
        { 0, 0},
 };
 
-static struct clk_mux_sel mux_pllp_pllc[] = {
+static struct clk_mux_sel mux_pllp_pllc_clkm_1[] = {
        {.input = &tegra_pll_p,     .value = 0},
-       {.input = &tegra_pll_c,     .value = 1},
+       {.input = &tegra_pll_c,     .value = 2},
+       {.input = &tegra_clk_m,     .value = 5},
        { 0, 0},
 };
 
@@ -8160,9 +8202,11 @@ static struct clk_mux_sel mux_pllp_clkm_2[] = {
        { 0, 0},
 };
 
-static struct clk_mux_sel mux_pllp_clkm_1[] = {
+static struct clk_mux_sel mux_pllp_clkm_clk32_plle[] = {
        { .input = &tegra_pll_p, .value = 0},
        { .input = &tegra_clk_m, .value = 2},
+       { .input = &tegra_clk_32k, .value = 4},
+       { .input = &tegra_pll_e, .value = 6},
        { 0, 0},
 };
 
@@ -8875,7 +8919,7 @@ struct clk tegra_list_clks[] = {
        PERIPH_CLK("i2s3",      "tegra210-i2s.3",       NULL,   101,    0x3bc,  204000000,  mux_pllaout0_audio3_pllp_clkm,      MUX | DIV_U71 | PERIPH_NO_RESET | PERIPH_ON_APB),
        PERIPH_CLK("i2s4",      "tegra210-i2s.4",       NULL,   102,    0x3c0,  204000000,  mux_pllaout0_audio4_pllp_clkm,      MUX | DIV_U71 | PERIPH_NO_RESET | PERIPH_ON_APB),
        PERIPH_CLK("spdif_out", "tegra210-spdif", "spdif_out",  10,     0x108,   49152000, mux_pllaout0_audio_2x_pllp_clkm,     MUX | DIV_U71 | PERIPH_NO_RESET | PERIPH_ON_APB),
-       PERIPH_CLK("spdif_in",  "tegra210-spdif",  "spdif_in",  10,     0x10c,  408000000, mux_pllp_pllc,                       MUX | DIV_U71 | PERIPH_NO_RESET | PERIPH_ON_APB),
+       PERIPH_CLK("spdif_in",  "tegra210-spdif",  "spdif_in",  10,     0x10c,  408000000, mux_pllp_pllc_clkm_1,                MUX | DIV_U71 | PERIPH_NO_RESET | PERIPH_ON_APB),
        PERIPH_CLK("dmic1",     "tegra210-dmic.0",      NULL,   161,    0x64c,  24576000, mux_pllaout0_audio0_dmic_pllp_clkm,   MUX | DIV_U71 | PERIPH_NO_RESET | PERIPH_ON_APB),
        PERIPH_CLK("dmic2",     "tegra210-dmic.1",      NULL,   162,    0x650,  24576000, mux_pllaout0_audio1_dmic_pllp_clkm,   MUX | DIV_U71 | PERIPH_NO_RESET | PERIPH_ON_APB),
        PERIPH_CLK("dmic3",     "tegra210-dmic.2",      NULL,   197,    0x6bc,  24576000, mux_pllaout0_audio2_dmic_pllp_clkm,   MUX | DIV_U71 | PERIPH_NO_RESET | PERIPH_ON_APB),
@@ -8887,7 +8931,7 @@ struct clk tegra_list_clks[] = {
        PERIPH_CLK("hda2codec_2x", "tegra30-hda", "hda2codec",  111,    0x3e4,  102000000,  mux_pllp_pllc_plla_clkm,            MUX | DIV_U71 | PERIPH_ON_APB),
        PERIPH_CLK("hda2hdmi",  "tegra30-hda",     "hda2hdmi",  128,    0,      408000000,  mux_clk_m,                          PERIPH_ON_APB),
 
-       PERIPH_CLK("qspi",      "qspi",                 NULL,   211,    0x6c4, 166000000, mux_pllp_pllc_pllc4_out2_pllc4_out1_clkm_pllc4_out0, MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("qspi",      "qspi",                 NULL,   211,    0x6c4, 166000000, mux_pllp_pllc_pllc_out1_pllc4_out2_pllc4_out1_clkm_pllc4_out0, MUX | DIV_U71 | PERIPH_ON_APB),
        PERIPH_CLK("vii2c",     "vii2c",                NULL,   208,    0x6c8, 136000000, mux_pllp_pllc_clkm,   MUX | DIV_U16 | PERIPH_ON_APB),
        PERIPH_CLK("sbc1",      "spi-tegra114.0",       NULL,   41,     0x134,  51000000, mux_pllp_pllc_clkm,   MUX | DIV_U71 | PERIPH_ON_APB),
        PERIPH_CLK("sbc2",      "spi-tegra114.1",       NULL,   44,     0x118,  51000000, mux_pllp_pllc_clkm,   MUX | DIV_U71 | PERIPH_ON_APB),
@@ -8956,7 +9000,7 @@ struct clk tegra_list_clks[] = {
        PERIPH_CLK("dsialp",    "tegradc.0",        "dsialp",   147,    0x620,  204000000, mux_pllp_pllc_clkm,          MUX | DIV_U71 | PERIPH_NO_RESET),
        PERIPH_CLK("dsiblp",    "tegradc.1",        "dsiblp",   148,    0x624,  204000000, mux_pllp_pllc_clkm,          MUX | DIV_U71 | PERIPH_NO_RESET),
 
-       PERIPH_CLK("entropy",   "entropy",              NULL,   149,    0x628,  102000000, mux_pllp_clkm_1,             MUX | DIV_U71),
+       PERIPH_CLK("entropy",   "entropy",              NULL,   149,    0x628,  102000000, mux_pllp_clkm_clk32_plle,            MUX | DIV_U71),
        PERIPH_CLK("uart_mipi_cal", "uart_mipi_cal",    NULL,   177,    0x66c,  102000000, mux_pllp_out3_pllp_pllc_clkm,        MUX | DIV_U71 | PERIPH_NO_RESET),
        PERIPH_CLK("dbgapb",    "dbgapb",               NULL,   185,    0x718,  136000000, mux_pllp_clkm_2,             MUX | DIV_U71 | PERIPH_NO_RESET),
        PERIPH_CLK("tsensor",   "tegra-tsensor",        NULL,   100,    0x3b8,  216000000, mux_pllp_pllc_clkm_clk32,    MUX | DIV_U71 | PERIPH_NO_RESET | PERIPH_ON_APB),
@@ -8969,7 +9013,7 @@ struct clk tegra_list_clks[] = {
        PERIPH_CLK("afi",       "tegra-pcie",           "afi",  72,     0,      250000000, mux_clk_m,                   0),
        PERIPH_CLK("cl_dvfs_ref", "tegra_cl_dvfs",      "ref",  155,    0x62c,  54000000,  mux_pllp_clkm,               MUX | DIV_U71 | DIV_U71_INT | PERIPH_ON_APB),
        PERIPH_CLK("cl_dvfs_soc", "tegra_cl_dvfs",      "soc",  155,    0x630,  54000000,  mux_pllp_clkm,               MUX | DIV_U71 | DIV_U71_INT | PERIPH_ON_APB),
-       PERIPH_CLK("soc_therm", "soc_therm",            NULL,   78,     0x644,  408000000, mux_pllc_pllp_plla_pllc4,    MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("soc_therm", "soc_therm",            NULL,   78,     0x644,  408000000, mux_clkm_pllc_pllp_plla,     MUX | DIV_U71 | PERIPH_ON_APB),
 
        PERIPH_CLK("dp2",       "dp2",                  NULL,   152,    0,      38400000, mux_clk_m,                    PERIPH_ON_APB),
        PERIPH_CLK("mc_bbc",    "mc_bbc",               NULL,   170,    0,      1066000000, mux_clk_mc,                 PERIPH_NO_RESET),
@@ -8992,7 +9036,7 @@ struct clk tegra_list_clks[] = {
        PERIPH_CLK_SKIP("tsecb", "tsecb",       NULL,   206,    0x6d8,  0x70c,  700000000, mux_pllp_pllc2_c_c3_clkm,    MUX | DIV_U71 | DIV_U71_INT),
        PERIPH_CLK_SKIP("ispa", "isp",          "ispa", 23,     0,      0x6f8,  700000000, mux_isp,                             PERIPH_ON_APB),
        PERIPH_CLK_SKIP("ispb", "isp",          "ispb", 3,      0,      0x6fc,  700000000, mux_isp,                             PERIPH_ON_APB),
-       PERIPH_CLK_EX("vi",     "vi",           "vi",   20,     0x148,          700000000, mux_pllc2_c_c3_pllp_plla1_pllc4,     MUX | DIV_U71 | DIV_U71_INT, &tegra_vi_clk_ops),
+       PERIPH_CLK_EX("vi",     "vi",           "vi",   20,     0x148,          700000000, mux_pllc2_c_c3_pllp_clkm_plla1_pllc4,        MUX | DIV_U71 | DIV_U71_INT, &tegra_vi_clk_ops),
        SUPER_SKIP_CLK("vi_skip", "vi",         "skip",         0x6ec,             NULL, 0),
 
        SHARED_CLK("avp.sclk",  "nvavp",                "sclk", &tegra_clk_sbus_cmplx, NULL, 0, 0),
@@ -9484,6 +9528,31 @@ struct clk *tegra_ptr_camera_mclks[] = {
        &tegra_camera_mipical,
 };
 
+#ifdef CONFIG_DEBUG_FS
+static struct tegra_pto_table ptodefs[] = {
+       { .name = "pll_c",  .divider = 2, .pto_id = 1,   .presel_reg = 0x088, .presel_value = BIT(3),  .presel_mask = BIT(3) },
+       { .name = "pll_a1", .divider = 2, .pto_id = 85,  .presel_reg = 0x6a8, .presel_value = BIT(3),  .presel_mask = BIT(3) },
+       { .name = "pll_c2", .divider = 2, .pto_id = 88,  .presel_reg = 0x4ec, .presel_value = BIT(3),  .presel_mask = BIT(3) },
+       { .name = "pll_c3", .divider = 2, .pto_id = 89,  .presel_reg = 0x500, .presel_value = BIT(3),  .presel_mask = BIT(3) },
+
+       { .name = "pll_a",  .divider = 2, .pto_id = 4,   .presel_reg = 0x0bc, .presel_value = BIT(29), .presel_mask = BIT(29) },
+       { .name = "pll_x",  .divider = 2, .pto_id = 5,   .presel_reg = 0x0e4, .presel_value = BIT(22), .presel_mask = BIT(22) },
+
+       { .name = "pll_d",  .divider = 2, .pto_id = 203, .presel_reg = 0x0dc, .presel_value = BIT(25), .presel_mask = BIT(25) },
+       { .name = "pll_d2", .divider = 2, .pto_id = 205, .presel_reg = 0x4b8, .presel_value = BIT(16), .presel_mask = BIT(16) },
+       { .name = "pll_dp", .divider = 2, .pto_id = 207, .presel_reg = 0x590, .presel_value = BIT(16), .presel_mask = BIT(16) },
+       { .name = "pll_c4", .divider = 2, .pto_id = 81,  .presel_reg = 0x5a4, .presel_value = BIT(16), .presel_mask = BIT(16) },
+
+       { .name = "pll_m",  .divider = 2, .pto_id = 2,   .presel_reg = 0x9c,  .presel_value = BIT(8),  .presel_mask = BIT(8) },
+       { .name = "pll_mb", .divider = 2, .pto_id = 37,  .presel_reg = 0x9c,  .presel_value = BIT(9),  .presel_mask = BIT(9) },
+
+       { .name = "pll_u", .divider = 2,  .pto_id = 269, .presel_reg = 0xcc,  .presel_value = BIT(27), .presel_mask = BIT(27) },
+       { .name = "pll_re_vco", .divider = 2, .pto_id = 271, .presel_reg = 0x4c8, .presel_value = BIT(26), .presel_mask = BIT(26) },
+
+       { .name = NULL, },
+};
+#endif
+
 /*
  * Handle special clocks to check if they can be set to safe rate
  */
@@ -9631,6 +9700,7 @@ static void tegra21_pllp_init_dependencies(unsigned long pllp_rate)
                tegra_pll_p_out3.u.pll_div.default_rate = 72000000;
                tegra_pll_p_out4.u.pll_div.default_rate = 108000000;
                tegra_pll_p_out5.u.pll_div.default_rate = 108000000;
+               tegra_clk_sbus_cmplx.u.system.threshold = 108000000;
                tegra_clk_host1x.u.periph.threshold = 108000000;
                tegra_clk_aclk_adsp.u.cclk.div71 = 2; /* reg settings */
                break;
@@ -9638,6 +9708,7 @@ static void tegra21_pllp_init_dependencies(unsigned long pllp_rate)
                tegra_pll_p_out3.u.pll_div.default_rate = 102000000;
                tegra_pll_p_out4.u.pll_div.default_rate = 204000000;
                tegra_pll_p_out5.u.pll_div.default_rate = 204000000;
+               tegra_clk_sbus_cmplx.u.system.threshold = 204000000;
                tegra_clk_host1x.u.periph.threshold = 204000000;
                tegra_clk_aclk_adsp.u.cclk.div71 = 2; /* reg settings */
                break;
@@ -9645,6 +9716,7 @@ static void tegra21_pllp_init_dependencies(unsigned long pllp_rate)
                tegra_pll_p_out3.u.pll_div.default_rate = 102000000;
                tegra_pll_p_out4.u.pll_div.default_rate = 204000000;
                tegra_pll_p_out5.u.pll_div.default_rate = 204000000;
+               tegra_clk_sbus_cmplx.u.system.threshold = 204000000;
                tegra_clk_host1x.u.periph.threshold = 204000000;
                tegra_clk_aclk_adsp.u.cclk.div71 = 0; /* reg settings */
                break;
@@ -9986,7 +10058,8 @@ static int tegra21_clk_suspend(void)
        *ctx++ = clk_readl(tegra_clk_cclk_lp.reg);
        *ctx++ = clk_readl(tegra_clk_cclk_lp.reg + SUPER_CLK_DIVIDER);
 
-       *ctx++ = clk_get_rate_all_locked(&tegra_clk_emc);
+       *ctx = clk_get_rate_all_locked(&tegra_clk_emc);
+       tegra21_emc_clk_suspend(&tegra_clk_emc, *ctx++);
 
        pr_debug("%s: suspend entries: %d, suspend array: %u\n", __func__,
                (s32)(ctx - clk_rst_suspend), (u32)ARRAY_SIZE(clk_rst_suspend));
@@ -10400,6 +10473,10 @@ void __init tegra21x_init_clocks(void)
 #ifdef CONFIG_PM_SLEEP
        register_syscore_ops(&tegra_clk_syscore_ops);
 #endif
+
+#ifdef CONFIG_DEBUG_FS
+       tegra_clk_add_pto_entries(ptodefs);
+#endif
 }
 
 static int __init tegra21x_clk_late_init(void)