aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Blumenstingl <martin.blumenstingl@googlemail.com>2019-03-24 11:14:23 -0400
committerNeil Armstrong <narmstrong@baylibre.com>2019-04-01 07:34:29 -0400
commit90751f686e3f0415f1f931bf47ff14dd34316ea5 (patch)
tree31c78dfc96631864eceff819fec56ae8d7744486
parent41785ce562491db935471b31211481941a65c68f (diff)
clk: meson: meson8b: add the video decoder clock trees
This adds the four video decoder clock trees. VDEC_1 is split into two paths on Meson8b and Meson8m2: - input mux called "vdec_1_sel" - two dividers ("vdec_1_1_div" and "vdec_1_2_div") and gates ("vdec_1_1" and "vdec_1_2") - and an output mux (probably glitch-free) called "vdec_1" On Meson8 the VDEC_1 tree is simpler because there's only one path: - input mux called "vdec_1_sel" - divider ("vdec_1_1_div") and gate ("vdec_1_1") - (the gate is used as output directly, there's no mux) The VDEC_HCODEC and VDEC_2 clocks are simple composite clocks each consisting of an input mux, divider and a gate. The VDEC_HEVC clock seems to have two paths similar to the VDEC_1 clock. However, the register offsets of the second clock path is not known. Amlogic's 3.10 kernel (which is used as reference) sets HHI_VDEC2_CLK_CNTL[31] to 1 before changing the VDEC_HEVC clock and back to 0 afterwards. For now, leave a TODO comment and only add the first path. Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Maxime Jourdan <mjourdan@baylibre.com> Acked-by: Jerome Brunet <jbrunet@baylibre.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Link: https://lkml.kernel.org/r/20190324151423.19063-3-martin.blumenstingl@googlemail.com
-rw-r--r--drivers/clk/meson/meson8b.c312
-rw-r--r--drivers/clk/meson/meson8b.h17
2 files changed, 328 insertions, 1 deletions
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index 8e091c2d10e6..37cf0f01bb5d 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -1902,6 +1902,257 @@ static struct clk_regmap meson8b_vpu = {
1902 }, 1902 },
1903}; 1903};
1904 1904
1905static const char * const meson8b_vdec_parent_names[] = {
1906 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "mpll2", "mpll1"
1907};
1908
1909static struct clk_regmap meson8b_vdec_1_sel = {
1910 .data = &(struct clk_regmap_mux_data){
1911 .offset = HHI_VDEC_CLK_CNTL,
1912 .mask = 0x3,
1913 .shift = 9,
1914 .flags = CLK_MUX_ROUND_CLOSEST,
1915 },
1916 .hw.init = &(struct clk_init_data){
1917 .name = "vdec_1_sel",
1918 .ops = &clk_regmap_mux_ops,
1919 .parent_names = meson8b_vdec_parent_names,
1920 .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
1921 .flags = CLK_SET_RATE_PARENT,
1922 },
1923};
1924
1925static struct clk_regmap meson8b_vdec_1_1_div = {
1926 .data = &(struct clk_regmap_div_data){
1927 .offset = HHI_VDEC_CLK_CNTL,
1928 .shift = 0,
1929 .width = 7,
1930 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1931 },
1932 .hw.init = &(struct clk_init_data){
1933 .name = "vdec_1_1_div",
1934 .ops = &clk_regmap_divider_ops,
1935 .parent_names = (const char *[]){ "vdec_1_sel" },
1936 .num_parents = 1,
1937 .flags = CLK_SET_RATE_PARENT,
1938 },
1939};
1940
1941static struct clk_regmap meson8b_vdec_1_1 = {
1942 .data = &(struct clk_regmap_gate_data){
1943 .offset = HHI_VDEC_CLK_CNTL,
1944 .bit_idx = 8,
1945 },
1946 .hw.init = &(struct clk_init_data) {
1947 .name = "vdec_1_1",
1948 .ops = &clk_regmap_gate_ops,
1949 .parent_names = (const char *[]){ "vdec_1_1_div" },
1950 .num_parents = 1,
1951 .flags = CLK_SET_RATE_PARENT,
1952 },
1953};
1954
1955static struct clk_regmap meson8b_vdec_1_2_div = {
1956 .data = &(struct clk_regmap_div_data){
1957 .offset = HHI_VDEC3_CLK_CNTL,
1958 .shift = 0,
1959 .width = 7,
1960 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1961 },
1962 .hw.init = &(struct clk_init_data){
1963 .name = "vdec_1_2_div",
1964 .ops = &clk_regmap_divider_ops,
1965 .parent_names = (const char *[]){ "vdec_1_sel" },
1966 .num_parents = 1,
1967 .flags = CLK_SET_RATE_PARENT,
1968 },
1969};
1970
1971static struct clk_regmap meson8b_vdec_1_2 = {
1972 .data = &(struct clk_regmap_gate_data){
1973 .offset = HHI_VDEC3_CLK_CNTL,
1974 .bit_idx = 8,
1975 },
1976 .hw.init = &(struct clk_init_data) {
1977 .name = "vdec_1_2",
1978 .ops = &clk_regmap_gate_ops,
1979 .parent_names = (const char *[]){ "vdec_1_2_div" },
1980 .num_parents = 1,
1981 .flags = CLK_SET_RATE_PARENT,
1982 },
1983};
1984
1985static struct clk_regmap meson8b_vdec_1 = {
1986 .data = &(struct clk_regmap_mux_data){
1987 .offset = HHI_VDEC3_CLK_CNTL,
1988 .mask = 0x1,
1989 .shift = 15,
1990 .flags = CLK_MUX_ROUND_CLOSEST,
1991 },
1992 .hw.init = &(struct clk_init_data){
1993 .name = "vdec_1",
1994 .ops = &clk_regmap_mux_ops,
1995 .parent_names = (const char *[]){ "vdec_1_1", "vdec_1_2" },
1996 .num_parents = 2,
1997 .flags = CLK_SET_RATE_PARENT,
1998 },
1999};
2000
2001static struct clk_regmap meson8b_vdec_hcodec_sel = {
2002 .data = &(struct clk_regmap_mux_data){
2003 .offset = HHI_VDEC_CLK_CNTL,
2004 .mask = 0x3,
2005 .shift = 25,
2006 .flags = CLK_MUX_ROUND_CLOSEST,
2007 },
2008 .hw.init = &(struct clk_init_data){
2009 .name = "vdec_hcodec_sel",
2010 .ops = &clk_regmap_mux_ops,
2011 .parent_names = meson8b_vdec_parent_names,
2012 .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
2013 .flags = CLK_SET_RATE_PARENT,
2014 },
2015};
2016
2017static struct clk_regmap meson8b_vdec_hcodec_div = {
2018 .data = &(struct clk_regmap_div_data){
2019 .offset = HHI_VDEC_CLK_CNTL,
2020 .shift = 16,
2021 .width = 7,
2022 .flags = CLK_DIVIDER_ROUND_CLOSEST,
2023 },
2024 .hw.init = &(struct clk_init_data){
2025 .name = "vdec_hcodec_div",
2026 .ops = &clk_regmap_divider_ops,
2027 .parent_names = (const char *[]){ "vdec_hcodec_sel" },
2028 .num_parents = 1,
2029 .flags = CLK_SET_RATE_PARENT,
2030 },
2031};
2032
2033static struct clk_regmap meson8b_vdec_hcodec = {
2034 .data = &(struct clk_regmap_gate_data){
2035 .offset = HHI_VDEC_CLK_CNTL,
2036 .bit_idx = 24,
2037 },
2038 .hw.init = &(struct clk_init_data) {
2039 .name = "vdec_hcodec",
2040 .ops = &clk_regmap_gate_ops,
2041 .parent_names = (const char *[]){ "vdec_hcodec_div" },
2042 .num_parents = 1,
2043 .flags = CLK_SET_RATE_PARENT,
2044 },
2045};
2046
2047static struct clk_regmap meson8b_vdec_2_sel = {
2048 .data = &(struct clk_regmap_mux_data){
2049 .offset = HHI_VDEC2_CLK_CNTL,
2050 .mask = 0x3,
2051 .shift = 9,
2052 .flags = CLK_MUX_ROUND_CLOSEST,
2053 },
2054 .hw.init = &(struct clk_init_data){
2055 .name = "vdec_2_sel",
2056 .ops = &clk_regmap_mux_ops,
2057 .parent_names = meson8b_vdec_parent_names,
2058 .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
2059 .flags = CLK_SET_RATE_PARENT,
2060 },
2061};
2062
2063static struct clk_regmap meson8b_vdec_2_div = {
2064 .data = &(struct clk_regmap_div_data){
2065 .offset = HHI_VDEC2_CLK_CNTL,
2066 .shift = 0,
2067 .width = 7,
2068 .flags = CLK_DIVIDER_ROUND_CLOSEST,
2069 },
2070 .hw.init = &(struct clk_init_data){
2071 .name = "vdec_2_div",
2072 .ops = &clk_regmap_divider_ops,
2073 .parent_names = (const char *[]){ "vdec_2_sel" },
2074 .num_parents = 1,
2075 .flags = CLK_SET_RATE_PARENT,
2076 },
2077};
2078
2079static struct clk_regmap meson8b_vdec_2 = {
2080 .data = &(struct clk_regmap_gate_data){
2081 .offset = HHI_VDEC2_CLK_CNTL,
2082 .bit_idx = 8,
2083 },
2084 .hw.init = &(struct clk_init_data) {
2085 .name = "vdec_2",
2086 .ops = &clk_regmap_gate_ops,
2087 .parent_names = (const char *[]){ "vdec_2_div" },
2088 .num_parents = 1,
2089 .flags = CLK_SET_RATE_PARENT,
2090 },
2091};
2092
2093static struct clk_regmap meson8b_vdec_hevc_sel = {
2094 .data = &(struct clk_regmap_mux_data){
2095 .offset = HHI_VDEC2_CLK_CNTL,
2096 .mask = 0x3,
2097 .shift = 25,
2098 .flags = CLK_MUX_ROUND_CLOSEST,
2099 },
2100 .hw.init = &(struct clk_init_data){
2101 .name = "vdec_hevc_sel",
2102 .ops = &clk_regmap_mux_ops,
2103 .parent_names = meson8b_vdec_parent_names,
2104 .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
2105 .flags = CLK_SET_RATE_PARENT,
2106 },
2107};
2108
2109static struct clk_regmap meson8b_vdec_hevc_div = {
2110 .data = &(struct clk_regmap_div_data){
2111 .offset = HHI_VDEC2_CLK_CNTL,
2112 .shift = 16,
2113 .width = 7,
2114 .flags = CLK_DIVIDER_ROUND_CLOSEST,
2115 },
2116 .hw.init = &(struct clk_init_data){
2117 .name = "vdec_hevc_div",
2118 .ops = &clk_regmap_divider_ops,
2119 .parent_names = (const char *[]){ "vdec_hevc_sel" },
2120 .num_parents = 1,
2121 .flags = CLK_SET_RATE_PARENT,
2122 },
2123};
2124
2125static struct clk_regmap meson8b_vdec_hevc_en = {
2126 .data = &(struct clk_regmap_gate_data){
2127 .offset = HHI_VDEC2_CLK_CNTL,
2128 .bit_idx = 24,
2129 },
2130 .hw.init = &(struct clk_init_data) {
2131 .name = "vdec_hevc_en",
2132 .ops = &clk_regmap_gate_ops,
2133 .parent_names = (const char *[]){ "vdec_hevc_div" },
2134 .num_parents = 1,
2135 .flags = CLK_SET_RATE_PARENT,
2136 },
2137};
2138
2139static struct clk_regmap meson8b_vdec_hevc = {
2140 .data = &(struct clk_regmap_mux_data){
2141 .offset = HHI_VDEC2_CLK_CNTL,
2142 .mask = 0x1,
2143 .shift = 31,
2144 .flags = CLK_MUX_ROUND_CLOSEST,
2145 },
2146 .hw.init = &(struct clk_init_data){
2147 .name = "vdec_hevc",
2148 .ops = &clk_regmap_mux_ops,
2149 /* TODO: The second parent is currently unknown */
2150 .parent_names = (const char *[]){ "vdec_hevc_en" },
2151 .num_parents = 1,
2152 .flags = CLK_SET_RATE_PARENT,
2153 },
2154};
2155
1905/* Everything Else (EE) domain gates */ 2156/* Everything Else (EE) domain gates */
1906 2157
1907static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); 2158static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
@@ -2168,6 +2419,19 @@ static struct clk_hw_onecell_data meson8_hw_onecell_data = {
2168 [CLKID_VPU_0_SEL] = &meson8b_vpu_0_sel.hw, 2419 [CLKID_VPU_0_SEL] = &meson8b_vpu_0_sel.hw,
2169 [CLKID_VPU_0_DIV] = &meson8b_vpu_0_div.hw, 2420 [CLKID_VPU_0_DIV] = &meson8b_vpu_0_div.hw,
2170 [CLKID_VPU] = &meson8b_vpu_0.hw, 2421 [CLKID_VPU] = &meson8b_vpu_0.hw,
2422 [CLKID_VDEC_1_SEL] = &meson8b_vdec_1_sel.hw,
2423 [CLKID_VDEC_1_1_DIV] = &meson8b_vdec_1_1_div.hw,
2424 [CLKID_VDEC_1] = &meson8b_vdec_1_1.hw,
2425 [CLKID_VDEC_HCODEC_SEL] = &meson8b_vdec_hcodec_sel.hw,
2426 [CLKID_VDEC_HCODEC_DIV] = &meson8b_vdec_hcodec_div.hw,
2427 [CLKID_VDEC_HCODEC] = &meson8b_vdec_hcodec.hw,
2428 [CLKID_VDEC_2_SEL] = &meson8b_vdec_2_sel.hw,
2429 [CLKID_VDEC_2_DIV] = &meson8b_vdec_2_div.hw,
2430 [CLKID_VDEC_2] = &meson8b_vdec_2.hw,
2431 [CLKID_VDEC_HEVC_SEL] = &meson8b_vdec_hevc_sel.hw,
2432 [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw,
2433 [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw,
2434 [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw,
2171 [CLK_NR_CLKS] = NULL, 2435 [CLK_NR_CLKS] = NULL,
2172 }, 2436 },
2173 .num = CLK_NR_CLKS, 2437 .num = CLK_NR_CLKS,
@@ -2361,6 +2625,22 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
2361 [CLKID_VPU_1_DIV] = &meson8b_vpu_1_div.hw, 2625 [CLKID_VPU_1_DIV] = &meson8b_vpu_1_div.hw,
2362 [CLKID_VPU_1] = &meson8b_vpu_1.hw, 2626 [CLKID_VPU_1] = &meson8b_vpu_1.hw,
2363 [CLKID_VPU] = &meson8b_vpu.hw, 2627 [CLKID_VPU] = &meson8b_vpu.hw,
2628 [CLKID_VDEC_1_SEL] = &meson8b_vdec_1_sel.hw,
2629 [CLKID_VDEC_1_1_DIV] = &meson8b_vdec_1_1_div.hw,
2630 [CLKID_VDEC_1_1] = &meson8b_vdec_1_1.hw,
2631 [CLKID_VDEC_1_2_DIV] = &meson8b_vdec_1_2_div.hw,
2632 [CLKID_VDEC_1_2] = &meson8b_vdec_1_2.hw,
2633 [CLKID_VDEC_1] = &meson8b_vdec_1.hw,
2634 [CLKID_VDEC_HCODEC_SEL] = &meson8b_vdec_hcodec_sel.hw,
2635 [CLKID_VDEC_HCODEC_DIV] = &meson8b_vdec_hcodec_div.hw,
2636 [CLKID_VDEC_HCODEC] = &meson8b_vdec_hcodec.hw,
2637 [CLKID_VDEC_2_SEL] = &meson8b_vdec_2_sel.hw,
2638 [CLKID_VDEC_2_DIV] = &meson8b_vdec_2_div.hw,
2639 [CLKID_VDEC_2] = &meson8b_vdec_2.hw,
2640 [CLKID_VDEC_HEVC_SEL] = &meson8b_vdec_hevc_sel.hw,
2641 [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw,
2642 [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw,
2643 [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw,
2364 [CLK_NR_CLKS] = NULL, 2644 [CLK_NR_CLKS] = NULL,
2365 }, 2645 },
2366 .num = CLK_NR_CLKS, 2646 .num = CLK_NR_CLKS,
@@ -2556,6 +2836,22 @@ static struct clk_hw_onecell_data meson8m2_hw_onecell_data = {
2556 [CLKID_VPU_1_DIV] = &meson8b_vpu_1_div.hw, 2836 [CLKID_VPU_1_DIV] = &meson8b_vpu_1_div.hw,
2557 [CLKID_VPU_1] = &meson8b_vpu_1.hw, 2837 [CLKID_VPU_1] = &meson8b_vpu_1.hw,
2558 [CLKID_VPU] = &meson8b_vpu.hw, 2838 [CLKID_VPU] = &meson8b_vpu.hw,
2839 [CLKID_VDEC_1_SEL] = &meson8b_vdec_1_sel.hw,
2840 [CLKID_VDEC_1_1_DIV] = &meson8b_vdec_1_1_div.hw,
2841 [CLKID_VDEC_1_1] = &meson8b_vdec_1_1.hw,
2842 [CLKID_VDEC_1_2_DIV] = &meson8b_vdec_1_2_div.hw,
2843 [CLKID_VDEC_1_2] = &meson8b_vdec_1_2.hw,
2844 [CLKID_VDEC_1] = &meson8b_vdec_1.hw,
2845 [CLKID_VDEC_HCODEC_SEL] = &meson8b_vdec_hcodec_sel.hw,
2846 [CLKID_VDEC_HCODEC_DIV] = &meson8b_vdec_hcodec_div.hw,
2847 [CLKID_VDEC_HCODEC] = &meson8b_vdec_hcodec.hw,
2848 [CLKID_VDEC_2_SEL] = &meson8b_vdec_2_sel.hw,
2849 [CLKID_VDEC_2_DIV] = &meson8b_vdec_2_div.hw,
2850 [CLKID_VDEC_2] = &meson8b_vdec_2.hw,
2851 [CLKID_VDEC_HEVC_SEL] = &meson8b_vdec_hevc_sel.hw,
2852 [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw,
2853 [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw,
2854 [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw,
2559 [CLK_NR_CLKS] = NULL, 2855 [CLK_NR_CLKS] = NULL,
2560 }, 2856 },
2561 .num = CLK_NR_CLKS, 2857 .num = CLK_NR_CLKS,
@@ -2729,6 +3025,22 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
2729 &meson8b_vpu_1_div, 3025 &meson8b_vpu_1_div,
2730 &meson8b_vpu_1, 3026 &meson8b_vpu_1,
2731 &meson8b_vpu, 3027 &meson8b_vpu,
3028 &meson8b_vdec_1_sel,
3029 &meson8b_vdec_1_1_div,
3030 &meson8b_vdec_1_1,
3031 &meson8b_vdec_1_2_div,
3032 &meson8b_vdec_1_2,
3033 &meson8b_vdec_1,
3034 &meson8b_vdec_hcodec_sel,
3035 &meson8b_vdec_hcodec_div,
3036 &meson8b_vdec_hcodec,
3037 &meson8b_vdec_2_sel,
3038 &meson8b_vdec_2_div,
3039 &meson8b_vdec_2,
3040 &meson8b_vdec_hevc_sel,
3041 &meson8b_vdec_hevc_div,
3042 &meson8b_vdec_hevc_en,
3043 &meson8b_vdec_hevc,
2732}; 3044};
2733 3045
2734static const struct meson8b_clk_reset_line { 3046static const struct meson8b_clk_reset_line {
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
index e775f91ccce9..ed37196187e6 100644
--- a/drivers/clk/meson/meson8b.h
+++ b/drivers/clk/meson/meson8b.h
@@ -37,6 +37,9 @@
37#define HHI_MALI_CLK_CNTL 0x1b0 /* 0x6c offset in data sheet */ 37#define HHI_MALI_CLK_CNTL 0x1b0 /* 0x6c offset in data sheet */
38#define HHI_VPU_CLK_CNTL 0x1bc /* 0x6f offset in data sheet */ 38#define HHI_VPU_CLK_CNTL 0x1bc /* 0x6f offset in data sheet */
39#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 offset in data sheet */ 39#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 offset in data sheet */
40#define HHI_VDEC_CLK_CNTL 0x1e0 /* 0x78 offset in data sheet */
41#define HHI_VDEC2_CLK_CNTL 0x1e4 /* 0x79 offset in data sheet */
42#define HHI_VDEC3_CLK_CNTL 0x1e8 /* 0x7a offset in data sheet */
40#define HHI_NAND_CLK_CNTL 0x25c /* 0x97 offset in data sheet */ 43#define HHI_NAND_CLK_CNTL 0x25c /* 0x97 offset in data sheet */
41#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */ 44#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
42#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */ 45#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */
@@ -156,8 +159,20 @@
156#define CLKID_VPU_1_SEL 186 159#define CLKID_VPU_1_SEL 186
157#define CLKID_VPU_1_DIV 187 160#define CLKID_VPU_1_DIV 187
158#define CLKID_VPU_1 189 161#define CLKID_VPU_1 189
162#define CLKID_VDEC_1_SEL 191
163#define CLKID_VDEC_1_1_DIV 192
164#define CLKID_VDEC_1_1 193
165#define CLKID_VDEC_1_2_DIV 194
166#define CLKID_VDEC_1_2 195
167#define CLKID_VDEC_HCODEC_SEL 197
168#define CLKID_VDEC_HCODEC_DIV 198
169#define CLKID_VDEC_2_SEL 200
170#define CLKID_VDEC_2_DIV 201
171#define CLKID_VDEC_HEVC_SEL 203
172#define CLKID_VDEC_HEVC_DIV 204
173#define CLKID_VDEC_HEVC_EN 205
159 174
160#define CLK_NR_CLKS 191 175#define CLK_NR_CLKS 207
161 176
162/* 177/*
163 * include the CLKID and RESETID that have 178 * include the CLKID and RESETID that have