Commit b360ada3 authored by Michael Turquette's avatar Michael Turquette

Merge tag 'tegra-for-4.5-clk' of...

Merge tag 'tegra-for-4.5-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into clk-next

clk: tegra: Changes for v4.5-rc1

This set of changes adds support for the Tegra210 SoC and contains a
couple fixes and cleanups.
parents 7ed88aa2 2d7f61f3
NVIDIA Tegra210 Clock And Reset Controller
This binding uses the common clock binding:
Documentation/devicetree/bindings/clock/clock-bindings.txt
The CAR (Clock And Reset) Controller on Tegra is the HW module responsible
for muxing and gating Tegra's clocks, and setting their rates.
Required properties :
- compatible : Should be "nvidia,tegra210-car"
- reg : Should contain CAR registers location and length
- clocks : Should contain phandle and clock specifiers for two clocks:
the 32 KHz "32k_in".
- #clock-cells : Should be 1.
In clock consumers, this cell represents the clock ID exposed by the
CAR. The assignments may be found in header file
<dt-bindings/clock/tegra210-car.h>.
- #reset-cells : Should be 1.
In clock consumers, this cell represents the bit number in the CAR's
array of CLK_RST_CONTROLLER_RST_DEVICES_* registers.
Example SoC include file:
/ {
tegra_car: clock {
compatible = "nvidia,tegra210-car";
reg = <0x60006000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
usb@c5004000 {
clocks = <&tegra_car TEGRA210_CLK_USB2>;
};
};
Example board file:
/ {
clocks {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
clk_32k: clock@1 {
compatible = "fixed-clock";
reg = <1>;
#clock-cells = <0>;
clock-frequency = <32768>;
};
};
&tegra_car {
clocks = <&clk_32k>;
};
};
...@@ -20,3 +20,4 @@ obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o ...@@ -20,3 +20,4 @@ obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o
obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124-dfll-fcpu.o obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124-dfll-fcpu.o
obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o
obj-y += cvb.o obj-y += cvb.o
obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o
...@@ -13,6 +13,7 @@ enum clk_id { ...@@ -13,6 +13,7 @@ enum clk_id {
tegra_clk_amx1, tegra_clk_amx1,
tegra_clk_apbdma, tegra_clk_apbdma,
tegra_clk_apbif, tegra_clk_apbif,
tegra_clk_ape,
tegra_clk_audio0, tegra_clk_audio0,
tegra_clk_audio0_2x, tegra_clk_audio0_2x,
tegra_clk_audio0_mux, tegra_clk_audio0_mux,
...@@ -38,6 +39,7 @@ enum clk_id { ...@@ -38,6 +39,7 @@ enum clk_id {
tegra_clk_cile, tegra_clk_cile,
tegra_clk_clk_32k, tegra_clk_clk_32k,
tegra_clk_clk72Mhz, tegra_clk_clk72Mhz,
tegra_clk_clk72Mhz_8,
tegra_clk_clk_m, tegra_clk_clk_m,
tegra_clk_clk_m_div2, tegra_clk_clk_m_div2,
tegra_clk_clk_m_div4, tegra_clk_clk_m_div4,
...@@ -51,17 +53,21 @@ enum clk_id { ...@@ -51,17 +53,21 @@ enum clk_id {
tegra_clk_cml1, tegra_clk_cml1,
tegra_clk_csi, tegra_clk_csi,
tegra_clk_csite, tegra_clk_csite,
tegra_clk_csite_8,
tegra_clk_csus, tegra_clk_csus,
tegra_clk_cve, tegra_clk_cve,
tegra_clk_dam0, tegra_clk_dam0,
tegra_clk_dam1, tegra_clk_dam1,
tegra_clk_dam2, tegra_clk_dam2,
tegra_clk_d_audio, tegra_clk_d_audio,
tegra_clk_dbgapb,
tegra_clk_dds, tegra_clk_dds,
tegra_clk_dfll_ref, tegra_clk_dfll_ref,
tegra_clk_dfll_soc, tegra_clk_dfll_soc,
tegra_clk_disp1, tegra_clk_disp1,
tegra_clk_disp1_8,
tegra_clk_disp2, tegra_clk_disp2,
tegra_clk_disp2_8,
tegra_clk_dp2, tegra_clk_dp2,
tegra_clk_dpaux, tegra_clk_dpaux,
tegra_clk_dsialp, tegra_clk_dsialp,
...@@ -71,6 +77,7 @@ enum clk_id { ...@@ -71,6 +77,7 @@ enum clk_id {
tegra_clk_dtv, tegra_clk_dtv,
tegra_clk_emc, tegra_clk_emc,
tegra_clk_entropy, tegra_clk_entropy,
tegra_clk_entropy_8,
tegra_clk_epp, tegra_clk_epp,
tegra_clk_epp_8, tegra_clk_epp_8,
tegra_clk_extern1, tegra_clk_extern1,
...@@ -85,12 +92,16 @@ enum clk_id { ...@@ -85,12 +92,16 @@ enum clk_id {
tegra_clk_gr3d_8, tegra_clk_gr3d_8,
tegra_clk_hclk, tegra_clk_hclk,
tegra_clk_hda, tegra_clk_hda,
tegra_clk_hda_8,
tegra_clk_hda2codec_2x, tegra_clk_hda2codec_2x,
tegra_clk_hda2codec_2x_8,
tegra_clk_hda2hdmi, tegra_clk_hda2hdmi,
tegra_clk_hdmi, tegra_clk_hdmi,
tegra_clk_hdmi_audio, tegra_clk_hdmi_audio,
tegra_clk_host1x, tegra_clk_host1x,
tegra_clk_host1x_8, tegra_clk_host1x_8,
tegra_clk_host1x_9,
tegra_clk_hsic_trk,
tegra_clk_i2c1, tegra_clk_i2c1,
tegra_clk_i2c2, tegra_clk_i2c2,
tegra_clk_i2c3, tegra_clk_i2c3,
...@@ -110,11 +121,14 @@ enum clk_id { ...@@ -110,11 +121,14 @@ enum clk_id {
tegra_clk_i2s4_sync, tegra_clk_i2s4_sync,
tegra_clk_isp, tegra_clk_isp,
tegra_clk_isp_8, tegra_clk_isp_8,
tegra_clk_isp_9,
tegra_clk_ispb, tegra_clk_ispb,
tegra_clk_kbc, tegra_clk_kbc,
tegra_clk_kfuse, tegra_clk_kfuse,
tegra_clk_la, tegra_clk_la,
tegra_clk_maud,
tegra_clk_mipi, tegra_clk_mipi,
tegra_clk_mipibif,
tegra_clk_mipi_cal, tegra_clk_mipi_cal,
tegra_clk_mpe, tegra_clk_mpe,
tegra_clk_mselect, tegra_clk_mselect,
...@@ -124,15 +138,24 @@ enum clk_id { ...@@ -124,15 +138,24 @@ enum clk_id {
tegra_clk_ndspeed, tegra_clk_ndspeed,
tegra_clk_ndspeed_8, tegra_clk_ndspeed_8,
tegra_clk_nor, tegra_clk_nor,
tegra_clk_nvdec,
tegra_clk_nvenc,
tegra_clk_nvjpg,
tegra_clk_owr, tegra_clk_owr,
tegra_clk_owr_8,
tegra_clk_pcie, tegra_clk_pcie,
tegra_clk_pclk, tegra_clk_pclk,
tegra_clk_pll_a, tegra_clk_pll_a,
tegra_clk_pll_a_out0, tegra_clk_pll_a_out0,
tegra_clk_pll_a1,
tegra_clk_pll_c, tegra_clk_pll_c,
tegra_clk_pll_c2, tegra_clk_pll_c2,
tegra_clk_pll_c3, tegra_clk_pll_c3,
tegra_clk_pll_c4, tegra_clk_pll_c4,
tegra_clk_pll_c4_out0,
tegra_clk_pll_c4_out1,
tegra_clk_pll_c4_out2,
tegra_clk_pll_c4_out3,
tegra_clk_pll_c_out1, tegra_clk_pll_c_out1,
tegra_clk_pll_d, tegra_clk_pll_d,
tegra_clk_pll_d2, tegra_clk_pll_d2,
...@@ -140,19 +163,29 @@ enum clk_id { ...@@ -140,19 +163,29 @@ enum clk_id {
tegra_clk_pll_d_out0, tegra_clk_pll_d_out0,
tegra_clk_pll_dp, tegra_clk_pll_dp,
tegra_clk_pll_e_out0, tegra_clk_pll_e_out0,
tegra_clk_pll_g_ref,
tegra_clk_pll_m, tegra_clk_pll_m,
tegra_clk_pll_m_out1, tegra_clk_pll_m_out1,
tegra_clk_pll_mb,
tegra_clk_pll_p, tegra_clk_pll_p,
tegra_clk_pll_p_out1, tegra_clk_pll_p_out1,
tegra_clk_pll_p_out2, tegra_clk_pll_p_out2,
tegra_clk_pll_p_out2_int, tegra_clk_pll_p_out2_int,
tegra_clk_pll_p_out3, tegra_clk_pll_p_out3,
tegra_clk_pll_p_out4, tegra_clk_pll_p_out4,
tegra_clk_pll_p_out4_cpu,
tegra_clk_pll_p_out5, tegra_clk_pll_p_out5,
tegra_clk_pll_p_out_hsio,
tegra_clk_pll_p_out_xusb,
tegra_clk_pll_p_out_cpu,
tegra_clk_pll_p_out_adsp,
tegra_clk_pll_ref, tegra_clk_pll_ref,
tegra_clk_pll_re_out, tegra_clk_pll_re_out,
tegra_clk_pll_re_vco, tegra_clk_pll_re_vco,
tegra_clk_pll_u, tegra_clk_pll_u,
tegra_clk_pll_u_out,
tegra_clk_pll_u_out1,
tegra_clk_pll_u_out2,
tegra_clk_pll_u_12m, tegra_clk_pll_u_12m,
tegra_clk_pll_u_480m, tegra_clk_pll_u_480m,
tegra_clk_pll_u_48m, tegra_clk_pll_u_48m,
...@@ -160,53 +193,80 @@ enum clk_id { ...@@ -160,53 +193,80 @@ enum clk_id {
tegra_clk_pll_x, tegra_clk_pll_x,
tegra_clk_pll_x_out0, tegra_clk_pll_x_out0,
tegra_clk_pwm, tegra_clk_pwm,
tegra_clk_qspi,
tegra_clk_rtc, tegra_clk_rtc,
tegra_clk_sata, tegra_clk_sata,
tegra_clk_sata_8,
tegra_clk_sata_cold, tegra_clk_sata_cold,
tegra_clk_sata_oob, tegra_clk_sata_oob,
tegra_clk_sata_oob_8,
tegra_clk_sbc1, tegra_clk_sbc1,
tegra_clk_sbc1_8, tegra_clk_sbc1_8,
tegra_clk_sbc1_9,
tegra_clk_sbc2, tegra_clk_sbc2,
tegra_clk_sbc2_8, tegra_clk_sbc2_8,
tegra_clk_sbc2_9,
tegra_clk_sbc3, tegra_clk_sbc3,
tegra_clk_sbc3_8, tegra_clk_sbc3_8,
tegra_clk_sbc3_9,
tegra_clk_sbc4, tegra_clk_sbc4,
tegra_clk_sbc4_8, tegra_clk_sbc4_8,
tegra_clk_sbc4_9,
tegra_clk_sbc5, tegra_clk_sbc5,
tegra_clk_sbc5_8, tegra_clk_sbc5_8,
tegra_clk_sbc6, tegra_clk_sbc6,
tegra_clk_sbc6_8, tegra_clk_sbc6_8,
tegra_clk_sclk, tegra_clk_sclk,
tegra_clk_sdmmc_legacy,
tegra_clk_sdmmc1, tegra_clk_sdmmc1,
tegra_clk_sdmmc1_8, tegra_clk_sdmmc1_8,
tegra_clk_sdmmc1_9,
tegra_clk_sdmmc2, tegra_clk_sdmmc2,
tegra_clk_sdmmc2_8, tegra_clk_sdmmc2_8,
tegra_clk_sdmmc2_9,
tegra_clk_sdmmc3, tegra_clk_sdmmc3,
tegra_clk_sdmmc3_8, tegra_clk_sdmmc3_8,
tegra_clk_sdmmc3_9,
tegra_clk_sdmmc4, tegra_clk_sdmmc4,
tegra_clk_sdmmc4_8, tegra_clk_sdmmc4_8,
tegra_clk_sdmmc4_9,
tegra_clk_se, tegra_clk_se,
tegra_clk_soc_therm, tegra_clk_soc_therm,
tegra_clk_soc_therm_8,
tegra_clk_sor0, tegra_clk_sor0,
tegra_clk_sor0_lvds, tegra_clk_sor0_lvds,
tegra_clk_sor1,
tegra_clk_sor1_brick,
tegra_clk_sor1_src,
tegra_clk_spdif, tegra_clk_spdif,
tegra_clk_spdif_2x, tegra_clk_spdif_2x,
tegra_clk_spdif_in, tegra_clk_spdif_in,
tegra_clk_spdif_in_8,
tegra_clk_spdif_in_sync, tegra_clk_spdif_in_sync,
tegra_clk_spdif_mux, tegra_clk_spdif_mux,
tegra_clk_spdif_out, tegra_clk_spdif_out,
tegra_clk_timer, tegra_clk_timer,
tegra_clk_trace, tegra_clk_trace,
tegra_clk_tsec, tegra_clk_tsec,
tegra_clk_tsec_8,
tegra_clk_tsecb,
tegra_clk_tsensor, tegra_clk_tsensor,
tegra_clk_tvdac, tegra_clk_tvdac,
tegra_clk_tvo, tegra_clk_tvo,
tegra_clk_uarta, tegra_clk_uarta,
tegra_clk_uarta_8,
tegra_clk_uartb, tegra_clk_uartb,
tegra_clk_uartb_8,
tegra_clk_uartc, tegra_clk_uartc,
tegra_clk_uartc_8,
tegra_clk_uartd, tegra_clk_uartd,
tegra_clk_uartd_8,
tegra_clk_uarte, tegra_clk_uarte,
tegra_clk_uarte_8,
tegra_clk_uartape,
tegra_clk_usb2, tegra_clk_usb2,
tegra_clk_usb2_hsic_trk,
tegra_clk_usb2_trk,
tegra_clk_usb3, tegra_clk_usb3,
tegra_clk_usbd, tegra_clk_usbd,
tegra_clk_vcp, tegra_clk_vcp,
...@@ -216,22 +276,35 @@ enum clk_id { ...@@ -216,22 +276,35 @@ enum clk_id {
tegra_clk_vi, tegra_clk_vi,
tegra_clk_vi_8, tegra_clk_vi_8,
tegra_clk_vi_9, tegra_clk_vi_9,
tegra_clk_vi_10,
tegra_clk_vi_i2c,
tegra_clk_vic03, tegra_clk_vic03,
tegra_clk_vic03_8,
tegra_clk_vim2_clk, tegra_clk_vim2_clk,
tegra_clk_vimclk_sync, tegra_clk_vimclk_sync,
tegra_clk_vi_sensor, tegra_clk_vi_sensor,
tegra_clk_vi_sensor2,
tegra_clk_vi_sensor_8, tegra_clk_vi_sensor_8,
tegra_clk_vi_sensor_9,
tegra_clk_vi_sensor2,
tegra_clk_vi_sensor2_8,
tegra_clk_xusb_dev, tegra_clk_xusb_dev,
tegra_clk_xusb_dev_src, tegra_clk_xusb_dev_src,
tegra_clk_xusb_dev_src_8,
tegra_clk_xusb_falcon_src, tegra_clk_xusb_falcon_src,
tegra_clk_xusb_falcon_src_8,
tegra_clk_xusb_fs_src, tegra_clk_xusb_fs_src,
tegra_clk_xusb_gate,
tegra_clk_xusb_host, tegra_clk_xusb_host,
tegra_clk_xusb_host_src, tegra_clk_xusb_host_src,
tegra_clk_xusb_host_src_8,
tegra_clk_xusb_hs_src, tegra_clk_xusb_hs_src,
tegra_clk_xusb_hs_src_4,
tegra_clk_xusb_ss, tegra_clk_xusb_ss,
tegra_clk_xusb_ss_src, tegra_clk_xusb_ss_src,
tegra_clk_xusb_ss_src_8,
tegra_clk_xusb_ss_div2, tegra_clk_xusb_ss_div2,
tegra_clk_xusb_ssp_src,
tegra_clk_sclk_mux,
tegra_clk_max, tegra_clk_max,
}; };
......
This diff is collapsed.
This diff is collapsed.
...@@ -34,9 +34,25 @@ ...@@ -34,9 +34,25 @@
#define CCLKLP_BURST_POLICY 0x370 #define CCLKLP_BURST_POLICY 0x370
#define SCLK_BURST_POLICY 0x028 #define SCLK_BURST_POLICY 0x028
#define SYSTEM_CLK_RATE 0x030 #define SYSTEM_CLK_RATE 0x030
#define SCLK_DIVIDER 0x2c
static DEFINE_SPINLOCK(sysrate_lock); static DEFINE_SPINLOCK(sysrate_lock);
enum tegra_super_gen {
gen4 = 4,
gen5,
};
struct tegra_super_gen_info {
enum tegra_super_gen gen;
const char **sclk_parents;
const char **cclk_g_parents;
const char **cclk_lp_parents;
int num_sclk_parents;
int num_cclk_g_parents;
int num_cclk_lp_parents;
};
static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4",
"pll_p", "pll_p_out2", "unused", "pll_p", "pll_p_out2", "unused",
"clk_32k", "pll_m_out1" }; "clk_32k", "pll_m_out1" };
...@@ -51,21 +67,81 @@ static const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", ...@@ -51,21 +67,81 @@ static const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
"pll_p", "pll_p_out4", "unused", "pll_p", "pll_p_out4", "unused",
"unused", "pll_x", "pll_x_out0" }; "unused", "pll_x", "pll_x_out0" };
const struct tegra_super_gen_info tegra_super_gen_info_gen4 = {
.gen = gen4,
.sclk_parents = sclk_parents,
.cclk_g_parents = cclk_g_parents,
.cclk_lp_parents = cclk_lp_parents,
.num_sclk_parents = ARRAY_SIZE(sclk_parents),
.num_cclk_g_parents = ARRAY_SIZE(cclk_g_parents),
.num_cclk_lp_parents = ARRAY_SIZE(cclk_lp_parents),
};
static const char *sclk_parents_gen5[] = { "clk_m", "pll_c_out1", "pll_c4_out3",
"pll_p", "pll_p_out2", "pll_c4_out1",
"clk_32k", "pll_c4_out2" };
static const char *cclk_g_parents_gen5[] = { "clk_m", "unused", "clk_32k", "unused",
"pll_p", "pll_p_out4", "unused",
"unused", "pll_x", "unused", "unused",
"unused", "unused", "unused", "unused",
"dfllCPU_out" };
static const char *cclk_lp_parents_gen5[] = { "clk_m", "unused", "clk_32k", "unused",
"pll_p", "pll_p_out4", "unused",
"unused", "pll_x", "unused", "unused",
"unused", "unused", "unused", "unused",
"dfllCPU_out" };
const struct tegra_super_gen_info tegra_super_gen_info_gen5 = {
.gen = gen5,
.sclk_parents = sclk_parents_gen5,
.cclk_g_parents = cclk_g_parents_gen5,
.cclk_lp_parents = cclk_lp_parents_gen5,
.num_sclk_parents = ARRAY_SIZE(sclk_parents_gen5),
.num_cclk_g_parents = ARRAY_SIZE(cclk_g_parents_gen5),
.num_cclk_lp_parents = ARRAY_SIZE(cclk_lp_parents_gen5),
};
static void __init tegra_sclk_init(void __iomem *clk_base, static void __init tegra_sclk_init(void __iomem *clk_base,
struct tegra_clk *tegra_clks) struct tegra_clk *tegra_clks,
const struct tegra_super_gen_info *gen_info)
{ {
struct clk *clk; struct clk *clk;
struct clk **dt_clk; struct clk **dt_clk;
/* SCLK */ /* SCLK_MUX */
dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks); dt_clk = tegra_lookup_dt_id(tegra_clk_sclk_mux, tegra_clks);
if (dt_clk) { if (dt_clk) {
clk = tegra_clk_register_super_mux("sclk", sclk_parents, clk = tegra_clk_register_super_mux("sclk_mux",
ARRAY_SIZE(sclk_parents), gen_info->sclk_parents,
gen_info->num_sclk_parents,
CLK_SET_RATE_PARENT, CLK_SET_RATE_PARENT,
clk_base + SCLK_BURST_POLICY, clk_base + SCLK_BURST_POLICY,
0, 4, 0, 0, NULL); 0, 4, 0, 0, NULL);
*dt_clk = clk; *dt_clk = clk;
/* SCLK */
dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks);
if (dt_clk) {
clk = clk_register_divider(NULL, "sclk", "sclk_mux", 0,
clk_base + SCLK_DIVIDER, 0, 8,
0, &sysrate_lock);
*dt_clk = clk;
}
} else {
/* SCLK */
dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks);
if (dt_clk) {
clk = tegra_clk_register_super_mux("sclk",
gen_info->sclk_parents,
gen_info->num_sclk_parents,
CLK_SET_RATE_PARENT,
clk_base + SCLK_BURST_POLICY,
0, 4, 0, 0, NULL);
*dt_clk = clk;
}
} }
/* HCLK */ /* HCLK */
...@@ -95,10 +171,11 @@ static void __init tegra_sclk_init(void __iomem *clk_base, ...@@ -95,10 +171,11 @@ static void __init tegra_sclk_init(void __iomem *clk_base,
*dt_clk = clk; *dt_clk = clk;
} }
void __init tegra_super_clk_gen4_init(void __iomem *clk_base, void __init tegra_super_clk_init(void __iomem *clk_base,
void __iomem *pmc_base, void __iomem *pmc_base,
struct tegra_clk *tegra_clks, struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *params) struct tegra_clk_pll_params *params,
const struct tegra_super_gen_info *gen_info)
{ {
struct clk *clk; struct clk *clk;
struct clk **dt_clk; struct clk **dt_clk;
...@@ -106,28 +183,50 @@ void __init tegra_super_clk_gen4_init(void __iomem *clk_base, ...@@ -106,28 +183,50 @@ void __init tegra_super_clk_gen4_init(void __iomem *clk_base,
/* CCLKG */ /* CCLKG */
dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_g, tegra_clks); dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_g, tegra_clks);
if (dt_clk) { if (dt_clk) {
clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents, if (gen_info->gen == gen5) {
ARRAY_SIZE(cclk_g_parents), clk = tegra_clk_register_super_mux("cclk_g",
gen_info->cclk_g_parents,
gen_info->num_cclk_g_parents,
CLK_SET_RATE_PARENT,
clk_base + CCLKG_BURST_POLICY,
0, 4, 8, 0, NULL);
} else {
clk = tegra_clk_register_super_mux("cclk_g",
gen_info->cclk_g_parents,
gen_info->num_cclk_g_parents,
CLK_SET_RATE_PARENT, CLK_SET_RATE_PARENT,
clk_base + CCLKG_BURST_POLICY, clk_base + CCLKG_BURST_POLICY,
0, 4, 0, 0, NULL); 0, 4, 0, 0, NULL);
}
*dt_clk = clk; *dt_clk = clk;
} }
/* CCLKLP */ /* CCLKLP */
dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_lp, tegra_clks); dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_lp, tegra_clks);
if (dt_clk) { if (dt_clk) {
clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents, if (gen_info->gen == gen5) {
ARRAY_SIZE(cclk_lp_parents), clk = tegra_clk_register_super_mux("cclk_lp",
gen_info->cclk_lp_parents,
gen_info->num_cclk_lp_parents,
CLK_SET_RATE_PARENT,
clk_base + CCLKLP_BURST_POLICY,
0, 4, 8, 0, NULL);
} else {
clk = tegra_clk_register_super_mux("cclk_lp",
gen_info->cclk_lp_parents,
gen_info->num_cclk_lp_parents,
CLK_SET_RATE_PARENT, CLK_SET_RATE_PARENT,
clk_base + CCLKLP_BURST_POLICY, clk_base + CCLKLP_BURST_POLICY,
TEGRA_DIVIDER_2, 4, 8, 9, NULL); TEGRA_DIVIDER_2, 4, 8, 9, NULL);
}
*dt_clk = clk; *dt_clk = clk;
} }
tegra_sclk_init(clk_base, tegra_clks); tegra_sclk_init(clk_base, tegra_clks, gen_info);
#if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) #if defined(CONFIG_ARCH_TEGRA_114_SOC) || \
defined(CONFIG_ARCH_TEGRA_124_SOC) || \
defined(CONFIG_ARCH_TEGRA_210_SOC)
/* PLLX */ /* PLLX */
dt_clk = tegra_lookup_dt_id(tegra_clk_pll_x, tegra_clks); dt_clk = tegra_lookup_dt_id(tegra_clk_pll_x, tegra_clks);
if (!dt_clk) if (!dt_clk)
...@@ -148,3 +247,20 @@ void __init tegra_super_clk_gen4_init(void __iomem *clk_base, ...@@ -148,3 +247,20 @@ void __init tegra_super_clk_gen4_init(void __iomem *clk_base,
#endif #endif
} }
void __init tegra_super_clk_gen4_init(void __iomem *clk_base,
void __iomem *pmc_base,
struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *params)
{
tegra_super_clk_init(clk_base, pmc_base, tegra_clks, params,
&tegra_super_gen_info_gen4);
}
void __init tegra_super_clk_gen5_init(void __iomem *clk_base,
void __iomem *pmc_base,
struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *params)
{
tegra_super_clk_init(clk_base, pmc_base, tegra_clks, params,
&tegra_super_gen_info_gen5);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -110,14 +110,16 @@ struct clk *tegra_clk_register_mc(const char *name, const char *parent_name, ...@@ -110,14 +110,16 @@ struct clk *tegra_clk_register_mc(const char *name, const char *parent_name,
* @m: input divider * @m: input divider
* @p: post divider * @p: post divider
* @cpcon: charge pump current * @cpcon: charge pump current
* @sdm_data: fraction divider setting (0 = disabled)
*/ */
struct tegra_clk_pll_freq_table { struct tegra_clk_pll_freq_table {
unsigned long input_rate; unsigned long input_rate;
unsigned long output_rate; unsigned long output_rate;
u16 n; u32 n;
u16 m; u16 m;
u8 p; u8 p;
u8 cpcon; u8 cpcon;
u16 sdm_data;
}; };
/** /**
...@@ -156,6 +158,10 @@ struct div_nmp { ...@@ -156,6 +158,10 @@ struct div_nmp {
u8 override_divp_shift; u8 override_divp_shift;
}; };
#define MAX_PLL_MISC_REG_COUNT 6
struct tegra_clk_pll;
/** /**
* struct tegra_clk_pll_params - PLL parameters * struct tegra_clk_pll_params - PLL parameters
* *
...@@ -172,6 +178,14 @@ struct div_nmp { ...@@ -172,6 +178,14 @@ struct div_nmp {
* @lock_enable_bit_idx: Bit index to enable PLL lock * @lock_enable_bit_idx: Bit index to enable PLL lock
* @iddq_reg: PLL IDDQ register offset * @iddq_reg: PLL IDDQ register offset
* @iddq_bit_idx: Bit index to enable PLL IDDQ * @iddq_bit_idx: Bit index to enable PLL IDDQ
* @reset_reg: Register offset of where RESET bit is
* @reset_bit_idx: Shift of reset bit in reset_reg
* @sdm_din_reg: Register offset where SDM settings are
* @sdm_din_mask: Mask of SDM divider bits
* @sdm_ctrl_reg: Register offset where SDM enable is
* @sdm_ctrl_en_mask: Mask of SDM enable bit
* @ssc_ctrl_reg: Register offset where SSC settings are
* @ssc_ctrl_en_mask: Mask of SSC enable bit
* @aux_reg: AUX register offset * @aux_reg: AUX register offset
* @dyn_ramp_reg: Dynamic ramp control register offset * @dyn_ramp_reg: Dynamic ramp control register offset
* @ext_misc_reg: Miscellaneous control register offsets * @ext_misc_reg: Miscellaneous control register offsets
...@@ -182,10 +196,27 @@ struct div_nmp { ...@@ -182,10 +196,27 @@ struct div_nmp {
* @stepb_shift: Dynamic ramp step B field shift * @stepb_shift: Dynamic ramp step B field shift
* @lock_delay: Delay in us if PLL lock is not used * @lock_delay: Delay in us if PLL lock is not used
* @max_p: maximum value for the p divider * @max_p: maximum value for the p divider
* @defaults_set: Boolean signaling all reg defaults for PLL set.
* @pdiv_tohw: mapping of p divider to register values * @pdiv_tohw: mapping of p divider to register values
* @div_nmp: offsets and widths on n, m and p fields * @div_nmp: offsets and widths on n, m and p fields
* @freq_table: array of frequencies supported by PLL * @freq_table: array of frequencies supported by PLL
* @fixed_rate: PLL rate if it is fixed * @fixed_rate: PLL rate if it is fixed
* @mdiv_default: Default value for fixed mdiv for this PLL
* @round_p_to_pdiv: Callback used to round p to the closed pdiv
* @set_gain: Callback to adjust N div for SDM enabled
* PLL's based on fractional divider value.
* @calc_rate: Callback used to change how out of table
* rates (dividers and multipler) are calculated.
* @adjust_vco: Callback to adjust the programming range of the
* divider range (if SDM is present)
* @set_defaults: Callback which will try to initialize PLL
* registers to sane default values. This is first
* tried during PLL registration, but if the PLL
* is already enabled, it will be done the first
* time the rate is changed while the PLL is
* disabled.
* @dyn_ramp: Callback which can be used to define a custom
* dynamic ramp function for a given PLL.
* *
* Flags: * Flags:
* TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
...@@ -207,6 +238,11 @@ struct div_nmp { ...@@ -207,6 +238,11 @@ struct div_nmp {
* base register. * base register.
* TEGRA_PLL_BYPASS - PLL has bypass bit * TEGRA_PLL_BYPASS - PLL has bypass bit
* TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring
* TEGRA_MDIV_NEW - Switch to new method for calculating fixed mdiv
* it may be more accurate (especially if SDM present)
* TEGRA_PLLMB - PLLMB has should be treated similar to PLLM. This
* flag indicated that it is PLLMB.
* TEGRA_PLL_VCO_OUT - Used to indicate that the PLL has a VCO output
*/ */
struct tegra_clk_pll_params { struct tegra_clk_pll_params {
unsigned long input_min; unsigned long input_min;
...@@ -223,9 +259,17 @@ struct tegra_clk_pll_params { ...@@ -223,9 +259,17 @@ struct tegra_clk_pll_params {
u32 lock_enable_bit_idx; u32 lock_enable_bit_idx;
u32 iddq_reg; u32 iddq_reg;
u32 iddq_bit_idx; u32 iddq_bit_idx;
u32 reset_reg;
u32 reset_bit_idx;
u32 sdm_din_reg;
u32 sdm_din_mask;
u32 sdm_ctrl_reg;
u32 sdm_ctrl_en_mask;
u32 ssc_ctrl_reg;
u32 ssc_ctrl_en_mask;
u32 aux_reg; u32 aux_reg;
u32 dyn_ramp_reg; u32 dyn_ramp_reg;
u32 ext_misc_reg[3]; u32 ext_misc_reg[MAX_PLL_MISC_REG_COUNT];
u32 pmc_divnm_reg; u32 pmc_divnm_reg;
u32 pmc_divp_reg; u32 pmc_divp_reg;
u32 flags; u32 flags;
...@@ -233,10 +277,22 @@ struct tegra_clk_pll_params { ...@@ -233,10 +277,22 @@ struct tegra_clk_pll_params {
int stepb_shift; int stepb_shift;
int lock_delay; int lock_delay;
int max_p; int max_p;
struct pdiv_map *pdiv_tohw; bool defaults_set;
const struct pdiv_map *pdiv_tohw;
struct div_nmp *div_nmp; struct div_nmp *div_nmp;
struct tegra_clk_pll_freq_table *freq_table; struct tegra_clk_pll_freq_table *freq_table;
unsigned long fixed_rate; unsigned long fixed_rate;
u16 mdiv_default;
u32 (*round_p_to_pdiv)(u32 p, u32 *pdiv);
void (*set_gain)(struct tegra_clk_pll_freq_table *cfg);
int (*calc_rate)(struct clk_hw *hw,
struct tegra_clk_pll_freq_table *cfg,
unsigned long rate, unsigned long parent_rate);
unsigned long (*adjust_vco)(struct tegra_clk_pll_params *pll_params,
unsigned long parent_rate);
void (*set_defaults)(struct tegra_clk_pll *pll);
int (*dyn_ramp)(struct tegra_clk_pll *pll,
struct tegra_clk_pll_freq_table *cfg);
}; };
#define TEGRA_PLL_USE_LOCK BIT(0) #define TEGRA_PLL_USE_LOCK BIT(0)
...@@ -250,6 +306,9 @@ struct tegra_clk_pll_params { ...@@ -250,6 +306,9 @@ struct tegra_clk_pll_params {
#define TEGRA_PLL_LOCK_MISC BIT(8) #define TEGRA_PLL_LOCK_MISC BIT(8)
#define TEGRA_PLL_BYPASS BIT(9) #define TEGRA_PLL_BYPASS BIT(9)
#define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10) #define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10)
#define TEGRA_MDIV_NEW BIT(11)
#define TEGRA_PLLMB BIT(12)
#define TEGRA_PLL_VCO_OUT BIT(13)
/** /**
* struct tegra_clk_pll - Tegra PLL clock * struct tegra_clk_pll - Tegra PLL clock
...@@ -303,6 +362,12 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, ...@@ -303,6 +362,12 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
struct tegra_clk_pll_params *pll_params, struct tegra_clk_pll_params *pll_params,
spinlock_t *lock); spinlock_t *lock);
struct clk *tegra_clk_register_pllxc_tegra210(const char *name,
const char *parent_name, void __iomem *clk_base,
void __iomem *pmc, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
void __iomem *clk_base, void __iomem *pmc, void __iomem *clk_base, void __iomem *pmc,
unsigned long flags, unsigned long flags,
...@@ -327,11 +392,35 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, ...@@ -327,11 +392,35 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
struct tegra_clk_pll_params *pll_params, struct tegra_clk_pll_params *pll_params,
spinlock_t *lock); spinlock_t *lock);
struct clk *tegra_clk_register_plle_tegra210(const char *name,
const char *parent_name,
void __iomem *clk_base, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
struct clk *tegra_clk_register_pllc_tegra210(const char *name,
const char *parent_name, void __iomem *clk_base,
void __iomem *pmc, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
struct clk *tegra_clk_register_pllss_tegra210(const char *name,
const char *parent_name, void __iomem *clk_base,
unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
void __iomem *clk_base, unsigned long flags, void __iomem *clk_base, unsigned long flags,
struct tegra_clk_pll_params *pll_params, struct tegra_clk_pll_params *pll_params,
spinlock_t *lock); spinlock_t *lock);
struct clk *tegra_clk_register_pllmb(const char *name, const char *parent_name,
void __iomem *clk_base, void __iomem *pmc,
unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
/** /**
* struct tegra_clk_pll_out - PLL divider down clock * struct tegra_clk_pll_out - PLL divider down clock
* *
...@@ -653,6 +742,9 @@ int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks, ...@@ -653,6 +742,9 @@ int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
void tegra_super_clk_gen4_init(void __iomem *clk_base, void tegra_super_clk_gen4_init(void __iomem *clk_base,
void __iomem *pmc_base, struct tegra_clk *tegra_clks, void __iomem *pmc_base, struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *pll_params); struct tegra_clk_pll_params *pll_params);
void tegra_super_clk_gen5_init(void __iomem *clk_base,
void __iomem *pmc_base, struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *pll_params);
#ifdef CONFIG_TEGRA_CLK_EMC #ifdef CONFIG_TEGRA_CLK_EMC
struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np, struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
...@@ -674,5 +766,8 @@ void tegra114_clock_deassert_dfll_dvco_reset(void); ...@@ -674,5 +766,8 @@ void tegra114_clock_deassert_dfll_dvco_reset(void);
typedef void (*tegra_clk_apply_init_table_func)(void); typedef void (*tegra_clk_apply_init_table_func)(void);
extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table; extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll);
u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate);
int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
#endif /* TEGRA_CLK_H */ #endif /* TEGRA_CLK_H */
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment