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

clk: tegra: Reimplement SOR clocks on Tegra210

In order to allow the display driver to deal uniformly with all SOR
generations, implement the SOR clocks in a way that is compatible with
Tegra186 and later.

Acked-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Thierry Reding <treding@nvidia.com>

+60 -21
+57 -18
drivers/clk/tegra/clk-tegra210.c
··· 33 33 #define CLK_SOURCE_CSITE 0x1d4 34 34 #define CLK_SOURCE_EMC 0x19c 35 35 #define CLK_SOURCE_SOR1 0x410 36 + #define CLK_SOURCE_SOR0 0x414 36 37 #define CLK_SOURCE_LA 0x1f8 37 38 #define CLK_SOURCE_SDMMC2 0x154 38 39 #define CLK_SOURCE_SDMMC4 0x164 ··· 299 298 static DEFINE_SPINLOCK(pll_e_lock); 300 299 static DEFINE_SPINLOCK(pll_re_lock); 301 300 static DEFINE_SPINLOCK(pll_u_lock); 301 + static DEFINE_SPINLOCK(sor0_lock); 302 302 static DEFINE_SPINLOCK(sor1_lock); 303 303 static DEFINE_SPINLOCK(emc_lock); 304 304 static DEFINE_MUTEX(lvl2_ovr_lock); ··· 2553 2551 { .con_id = "pll_c4_out2", .dt_id = TEGRA210_CLK_PLL_C4_OUT2 }, 2554 2552 { .con_id = "pll_c4_out3", .dt_id = TEGRA210_CLK_PLL_C4_OUT3 }, 2555 2553 { .con_id = "dpaux", .dt_id = TEGRA210_CLK_DPAUX }, 2556 - { .con_id = "sor0", .dt_id = TEGRA210_CLK_SOR0 }, 2557 2554 }; 2558 2555 2559 2556 static struct tegra_audio_clk_info tegra210_audio_plls[] = { ··· 2916 2915 return 0; 2917 2916 } 2918 2917 2919 - static const char * const sor1_out_parents[] = { 2920 - /* 2921 - * Bit 0 of the mux selects sor1_pad_clkout, irrespective of bit 1, so 2922 - * the sor1_pad_clkout parent appears twice in the list below. This is 2923 - * merely to support clk_get_parent() if firmware happened to set 2924 - * these bits to 0b11. While not an invalid setting, code should 2925 - * always set the bits to 0b01 to select sor1_pad_clkout. 2926 - */ 2927 - "sor_safe", "sor1_pad_clkout", "sor1", "sor1_pad_clkout", 2918 + /* 2919 + * The SOR hardware blocks are driven by two clocks: a module clock that is 2920 + * used to access registers and a pixel clock that is sourced from the same 2921 + * pixel clock that also drives the head attached to the SOR. The module 2922 + * clock is typically called sorX (with X being the SOR instance) and the 2923 + * pixel clock is called sorX_out. The source for the SOR pixel clock is 2924 + * referred to as the "parent" clock. 2925 + * 2926 + * On Tegra186 and newer, clocks are provided by the BPMP. Unfortunately the 2927 + * BPMP implementation for the SOR clocks doesn't exactly match the above in 2928 + * some aspects. For example, the SOR module is really clocked by the pad or 2929 + * sor_safe clocks, but BPMP models the sorX clock as being sourced by the 2930 + * pixel clocks. Conversely the sorX_out clock is sourced by the sor_safe or 2931 + * pad clocks on BPMP. 2932 + * 2933 + * In order to allow the display driver to deal with all SoC generations in 2934 + * a unified way, implement the BPMP semantics in this driver. 2935 + */ 2936 + 2937 + static const char * const sor0_parents[] = { 2938 + "pll_d_out0", 2939 + }; 2940 + 2941 + static const char * const sor0_out_parents[] = { 2942 + "sor_safe", "sor0_pad_clkout", 2928 2943 }; 2929 2944 2930 2945 static const char * const sor1_parents[] = { ··· 2949 2932 2950 2933 static u32 sor1_parents_idx[] = { 0, 2, 5, 6 }; 2951 2934 2935 + static const char * const sor1_out_parents[] = { 2936 + /* 2937 + * Bit 0 of the mux selects sor1_pad_clkout, irrespective of bit 1, so 2938 + * the sor1_pad_clkout parent appears twice in the list below. This is 2939 + * merely to support clk_get_parent() if firmware happened to set 2940 + * these bits to 0b11. While not an invalid setting, code should 2941 + * always set the bits to 0b01 to select sor1_pad_clkout. 2942 + */ 2943 + "sor_safe", "sor1_pad_clkout", "sor1_out", "sor1_pad_clkout", 2944 + }; 2945 + 2952 2946 static struct tegra_periph_init_data tegra210_periph[] = { 2947 + /* 2948 + * On Tegra210, the sor0 clock doesn't have a mux it bitfield 31:29, 2949 + * but it is hardwired to the pll_d_out0 clock. 2950 + */ 2951 + TEGRA_INIT_DATA_TABLE("sor0", NULL, NULL, sor0_parents, 2952 + CLK_SOURCE_SOR0, 29, 0x0, 0, 0, 0, 0, 2953 + 0, 182, 0, tegra_clk_sor0, NULL, 0, 2954 + &sor0_lock), 2955 + TEGRA_INIT_DATA_TABLE("sor0_out", NULL, NULL, sor0_out_parents, 2956 + CLK_SOURCE_SOR0, 14, 0x1, 0, 0, 0, 0, 2957 + 0, 0, TEGRA_PERIPH_NO_GATE, tegra_clk_sor0_out, 2958 + NULL, 0, &sor0_lock), 2953 2959 TEGRA_INIT_DATA_TABLE("sor1", NULL, NULL, sor1_parents, 2954 2960 CLK_SOURCE_SOR1, 29, 0x7, 0, 0, 8, 1, 2955 - TEGRA_DIVIDER_ROUND_UP, 183, 0, tegra_clk_sor1, 2956 - sor1_parents_idx, 0, &sor1_lock), 2961 + TEGRA_DIVIDER_ROUND_UP, 183, 0, 2962 + tegra_clk_sor1, sor1_parents_idx, 0, 2963 + &sor1_lock), 2964 + TEGRA_INIT_DATA_TABLE("sor1_out", NULL, NULL, sor1_out_parents, 2965 + CLK_SOURCE_SOR1, 14, 0x3, 0, 0, 0, 0, 2966 + 0, 0, TEGRA_PERIPH_NO_GATE, 2967 + tegra_clk_sor1_out, NULL, 0, &sor1_lock), 2957 2968 }; 2958 2969 2959 2970 static const char * const la_parents[] = { ··· 3013 2968 clk = tegra_clk_register_periph_fixed("dpaux1", "sor_safe", 0, clk_base, 3014 2969 1, 17, 207); 3015 2970 clks[TEGRA210_CLK_DPAUX1] = clk; 3016 - 3017 - clk = clk_register_mux_table(NULL, "sor1_out", sor1_out_parents, 3018 - ARRAY_SIZE(sor1_out_parents), 0, 3019 - clk_base + CLK_SOURCE_SOR1, 14, 0x3, 3020 - 0, NULL, &sor1_lock); 3021 - clks[TEGRA210_CLK_SOR1_OUT] = clk; 3022 2971 3023 2972 /* pll_d_dsi_out */ 3024 2973 clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0,
+3 -3
include/dt-bindings/clock/tegra210-car.h
··· 308 308 #define TEGRA210_CLK_CLK_OUT_2 278 309 309 #define TEGRA210_CLK_CLK_OUT_3 279 310 310 #define TEGRA210_CLK_BLINK 280 311 - /* 281 */ 311 + #define TEGRA210_CLK_SOR0_LVDS 281 /* deprecated */ 312 + #define TEGRA210_CLK_SOR0_OUT 281 312 313 #define TEGRA210_CLK_SOR1_OUT 282 313 314 /* 283 */ 314 315 #define TEGRA210_CLK_XUSB_HOST_SRC 284 ··· 391 390 #define TEGRA210_CLK_CLK_OUT_3_MUX 358 392 391 #define TEGRA210_CLK_DSIA_MUX 359 393 392 #define TEGRA210_CLK_DSIB_MUX 360 394 - #define TEGRA210_CLK_SOR0_LVDS 361 /* deprecated */ 395 - #define TEGRA210_CLK_SOR0_OUT 361 393 + /* 361 */ 396 394 #define TEGRA210_CLK_XUSB_SS_DIV2 362 397 395 398 396 #define TEGRA210_CLK_PLL_M_UD 363