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

Merge branches 'clk-composite-determine-fix', 'clk-allwinner', 'clk-amlogic' and 'clk-samsung' into clk-next

* clk-composite-determine-fix:
clk: composite: Use rate_ops.determine_rate when also a mux is available
clk: composite: Also consider .determine_rate for rate + mux composites

* clk-allwinner:
clk: sunxi: sun8i-apb0: Make use of the helper function devm_platform_ioremap_resource()
clk: sunxi: sun6i-ar100: Make use of the helper function devm_platform_ioremap_resource()
clk: sunxi: sun6i-apb0-gates: Make use of the helper function devm_platform_ioremap_resource()
clk: sunxi: sun6i-apb0: Make use of the helper function devm_platform_ioremap_resource()
clk: sunxi-ng: ccu-sun9i-a80-usb: Make use of the helper function devm_platform_ioremap_resource()
clk: sunxi-ng: ccu-sun9i-a80-de: Make use of the helper function devm_platform_ioremap_resource()
clk: sunxi-ng: ccu-sun9i-a80: Make use of the helper function devm_platform_ioremap_resource()
clk: sunxi-ng: ccu-sun8i-r40: Make use of the helper function devm_platform_ioremap_resource()
clk: sunxi-ng: ccu-sun8i-de2: Make use of the helper function devm_platform_ioremap_resource()
clk: sunxi-ng: ccu-sun8i-a83t: Make use of the helper function devm_platform_ioremap_resource()
clk: sunxi-ng: ccu-sun50i-h6: Make use of the helper function devm_platform_ioremap_resource()
clk: sunxi-ng: ccu-sun50i-a64: Make use of the helper function devm_platform_ioremap_resource()
clk: sunxi: clk-mod0: Make use of the helper function devm_platform_ioremap_resource()
dt-bindings: clocks: Fix typo in the H6 compatible
clk: sunxi-ng: Use a separate lock for each CCU instance
clk: sunxi-ng: Prevent unbinding CCUs via sysfs
clk: sunxi-ng: Unregister clocks/resets when unbinding
clk: sunxi-ng: Add machine dependency to A83T CCU
clk: sunxi-ng: mux: Remove unused 'reg' field

* clk-amlogic:
clk: meson: meson8b: Make the video clock trees mutable
clk: meson: meson8b: Initialize the HDMI PLL registers
clk: meson: meson8b: Add the HDMI PLL M/N parameters
clk: meson: meson8b: Add the vid_pll_lvds_en gate clock
clk: meson: meson8b: Use CLK_SET_RATE_NO_REPARENT for vclk{,2}_in_sel
clk: meson: meson8b: Export the video clocks

* clk-samsung:
clk: samsung: describe drivers in Kconfig
clk: samsung: exynos5433: update apollo and atlas clock probing
clk: samsung: add support for CPU clocks
clk: samsung: Introduce Exynos850 clock driver
dt-bindings: clock: Document Exynos850 CMU bindings
dt-bindings: clock: Add bindings definitions for Exynos850 CMU
clk: samsung: clk-pll: Implement pll0831x PLL type
clk: samsung: clk-pll: Implement pll0822x PLL type
clk: samsung: s5pv210-audss: Make use of devm_platform_ioremap_resource()
clk: samsung: exynos5433: Make use of devm_platform_ioremap_resource()
clk: samsung: exynos4412-isp: Make use of devm_platform_ioremap_resource()
clk: samsung: exynos-audss: Make use of devm_platform_ioremap_resource()

+1800 -259
+1 -1
Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml
··· 24 24 - const: allwinner,sun8i-v3s-de2-clk 25 25 - const: allwinner,sun50i-a64-de2-clk 26 26 - const: allwinner,sun50i-h5-de2-clk 27 - - const: allwinner,sun50i-h6-de2-clk 27 + - const: allwinner,sun50i-h6-de3-clk 28 28 - items: 29 29 - const: allwinner,sun8i-r40-de2-clk 30 30 - const: allwinner,sun8i-h3-de2-clk
+185
Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/samsung,exynos850-clock.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Samsung Exynos850 SoC clock controller 8 + 9 + maintainers: 10 + - Sam Protsenko <semen.protsenko@linaro.org> 11 + - Chanwoo Choi <cw00.choi@samsung.com> 12 + - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> 13 + - Sylwester Nawrocki <s.nawrocki@samsung.com> 14 + - Tomasz Figa <tomasz.figa@gmail.com> 15 + 16 + description: | 17 + Exynos850 clock controller is comprised of several CMU units, generating 18 + clocks for different domains. Those CMU units are modeled as separate device 19 + tree nodes, and might depend on each other. Root clocks in that clock tree are 20 + two external clocks:: OSCCLK (26 MHz) and RTCCLK (32768 Hz). Those external 21 + clocks must be defined as fixed-rate clocks in dts. 22 + 23 + CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and 24 + dividers; all other leaf clocks (other CMUs) are usually derived from CMU_TOP. 25 + 26 + Each clock is assigned an identifier and client nodes can use this identifier 27 + to specify the clock which they consume. All clocks available for usage 28 + in clock consumer nodes are defined as preprocessor macros in 29 + 'dt-bindings/clock/exynos850.h' header. 30 + 31 + properties: 32 + compatible: 33 + enum: 34 + - samsung,exynos850-cmu-top 35 + - samsung,exynos850-cmu-core 36 + - samsung,exynos850-cmu-dpu 37 + - samsung,exynos850-cmu-hsi 38 + - samsung,exynos850-cmu-peri 39 + 40 + clocks: 41 + minItems: 1 42 + maxItems: 5 43 + 44 + clock-names: 45 + minItems: 1 46 + maxItems: 5 47 + 48 + "#clock-cells": 49 + const: 1 50 + 51 + reg: 52 + maxItems: 1 53 + 54 + allOf: 55 + - if: 56 + properties: 57 + compatible: 58 + contains: 59 + const: samsung,exynos850-cmu-top 60 + 61 + then: 62 + properties: 63 + clocks: 64 + items: 65 + - description: External reference clock (26 MHz) 66 + 67 + clock-names: 68 + items: 69 + - const: oscclk 70 + 71 + - if: 72 + properties: 73 + compatible: 74 + contains: 75 + const: samsung,exynos850-cmu-core 76 + 77 + then: 78 + properties: 79 + clocks: 80 + items: 81 + - description: External reference clock (26 MHz) 82 + - description: CMU_CORE bus clock (from CMU_TOP) 83 + - description: CCI clock (from CMU_TOP) 84 + - description: eMMC clock (from CMU_TOP) 85 + - description: SSS clock (from CMU_TOP) 86 + 87 + clock-names: 88 + items: 89 + - const: oscclk 90 + - const: dout_core_bus 91 + - const: dout_core_cci 92 + - const: dout_core_mmc_embd 93 + - const: dout_core_sss 94 + 95 + - if: 96 + properties: 97 + compatible: 98 + contains: 99 + const: samsung,exynos850-cmu-dpu 100 + 101 + then: 102 + properties: 103 + clocks: 104 + items: 105 + - description: External reference clock (26 MHz) 106 + - description: DPU clock (from CMU_TOP) 107 + 108 + clock-names: 109 + items: 110 + - const: oscclk 111 + - const: dout_dpu 112 + 113 + - if: 114 + properties: 115 + compatible: 116 + contains: 117 + const: samsung,exynos850-cmu-hsi 118 + 119 + then: 120 + properties: 121 + clocks: 122 + items: 123 + - description: External reference clock (26 MHz) 124 + - description: External RTC clock (32768 Hz) 125 + - description: CMU_HSI bus clock (from CMU_TOP) 126 + - description: SD card clock (from CMU_TOP) 127 + - description: "USB 2.0 DRD clock (from CMU_TOP)" 128 + 129 + clock-names: 130 + items: 131 + - const: oscclk 132 + - const: rtcclk 133 + - const: dout_hsi_bus 134 + - const: dout_hsi_mmc_card 135 + - const: dout_hsi_usb20drd 136 + 137 + - if: 138 + properties: 139 + compatible: 140 + contains: 141 + const: samsung,exynos850-cmu-peri 142 + 143 + then: 144 + properties: 145 + clocks: 146 + items: 147 + - description: External reference clock (26 MHz) 148 + - description: CMU_PERI bus clock (from CMU_TOP) 149 + - description: UART clock (from CMU_TOP) 150 + - description: Parent clock for HSI2C and SPI (from CMU_TOP) 151 + 152 + clock-names: 153 + items: 154 + - const: oscclk 155 + - const: dout_peri_bus 156 + - const: dout_peri_uart 157 + - const: dout_peri_ip 158 + 159 + required: 160 + - compatible 161 + - "#clock-cells" 162 + - clocks 163 + - clock-names 164 + - reg 165 + 166 + additionalProperties: false 167 + 168 + examples: 169 + # Clock controller node for CMU_PERI 170 + - | 171 + #include <dt-bindings/clock/exynos850.h> 172 + 173 + cmu_peri: clock-controller@10030000 { 174 + compatible = "samsung,exynos850-cmu-peri"; 175 + reg = <0x10030000 0x8000>; 176 + #clock-cells = <1>; 177 + 178 + clocks = <&oscclk>, <&cmu_top CLK_DOUT_PERI_BUS>, 179 + <&cmu_top CLK_DOUT_PERI_UART>, 180 + <&cmu_top CLK_DOUT_PERI_IP>; 181 + clock-names = "oscclk", "dout_peri_bus", 182 + "dout_peri_uart", "dout_peri_ip"; 183 + }; 184 + 185 + ...
+52 -24
drivers/clk/clk-composite.c
··· 42 42 return rate_ops->recalc_rate(rate_hw, parent_rate); 43 43 } 44 44 45 + static int clk_composite_determine_rate_for_parent(struct clk_hw *rate_hw, 46 + struct clk_rate_request *req, 47 + struct clk_hw *parent_hw, 48 + const struct clk_ops *rate_ops) 49 + { 50 + long rate; 51 + 52 + req->best_parent_hw = parent_hw; 53 + req->best_parent_rate = clk_hw_get_rate(parent_hw); 54 + 55 + if (rate_ops->determine_rate) 56 + return rate_ops->determine_rate(rate_hw, req); 57 + 58 + rate = rate_ops->round_rate(rate_hw, req->rate, 59 + &req->best_parent_rate); 60 + if (rate < 0) 61 + return rate; 62 + 63 + req->rate = rate; 64 + 65 + return 0; 66 + } 67 + 45 68 static int clk_composite_determine_rate(struct clk_hw *hw, 46 69 struct clk_rate_request *req) 47 70 { ··· 74 51 struct clk_hw *rate_hw = composite->rate_hw; 75 52 struct clk_hw *mux_hw = composite->mux_hw; 76 53 struct clk_hw *parent; 77 - unsigned long parent_rate; 78 - long tmp_rate, best_rate = 0; 79 54 unsigned long rate_diff; 80 55 unsigned long best_rate_diff = ULONG_MAX; 81 - long rate; 82 - int i; 56 + unsigned long best_rate = 0; 57 + int i, ret; 83 58 84 - if (rate_hw && rate_ops && rate_ops->determine_rate) { 85 - __clk_hw_set_clk(rate_hw, hw); 86 - return rate_ops->determine_rate(rate_hw, req); 87 - } else if (rate_hw && rate_ops && rate_ops->round_rate && 88 - mux_hw && mux_ops && mux_ops->set_parent) { 59 + if (rate_hw && rate_ops && 60 + (rate_ops->determine_rate || rate_ops->round_rate) && 61 + mux_hw && mux_ops && mux_ops->set_parent) { 89 62 req->best_parent_hw = NULL; 90 63 91 64 if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) { 65 + struct clk_rate_request tmp_req = *req; 66 + 92 67 parent = clk_hw_get_parent(mux_hw); 93 - req->best_parent_hw = parent; 94 - req->best_parent_rate = clk_hw_get_rate(parent); 95 68 96 - rate = rate_ops->round_rate(rate_hw, req->rate, 97 - &req->best_parent_rate); 98 - if (rate < 0) 99 - return rate; 69 + ret = clk_composite_determine_rate_for_parent(rate_hw, 70 + &tmp_req, 71 + parent, 72 + rate_ops); 73 + if (ret) 74 + return ret; 100 75 101 - req->rate = rate; 76 + req->rate = tmp_req.rate; 77 + req->best_parent_rate = tmp_req.best_parent_rate; 78 + 102 79 return 0; 103 80 } 104 81 105 82 for (i = 0; i < clk_hw_get_num_parents(mux_hw); i++) { 83 + struct clk_rate_request tmp_req = *req; 84 + 106 85 parent = clk_hw_get_parent_by_index(mux_hw, i); 107 86 if (!parent) 108 87 continue; 109 88 110 - parent_rate = clk_hw_get_rate(parent); 111 - 112 - tmp_rate = rate_ops->round_rate(rate_hw, req->rate, 113 - &parent_rate); 114 - if (tmp_rate < 0) 89 + ret = clk_composite_determine_rate_for_parent(rate_hw, 90 + &tmp_req, 91 + parent, 92 + rate_ops); 93 + if (ret) 115 94 continue; 116 95 117 - rate_diff = abs(req->rate - tmp_rate); 96 + rate_diff = abs(req->rate - tmp_req.rate); 118 97 119 98 if (!rate_diff || !req->best_parent_hw 120 99 || best_rate_diff > rate_diff) { 121 100 req->best_parent_hw = parent; 122 - req->best_parent_rate = parent_rate; 101 + req->best_parent_rate = tmp_req.best_parent_rate; 123 102 best_rate_diff = rate_diff; 124 - best_rate = tmp_rate; 103 + best_rate = tmp_req.rate; 125 104 } 126 105 127 106 if (!rate_diff) ··· 132 107 133 108 req->rate = best_rate; 134 109 return 0; 110 + } else if (rate_hw && rate_ops && rate_ops->determine_rate) { 111 + __clk_hw_set_clk(rate_hw, hw); 112 + return rate_ops->determine_rate(rate_hw, req); 135 113 } else if (mux_hw && mux_ops && mux_ops->determine_rate) { 136 114 __clk_hw_set_clk(mux_hw, hw); 137 115 return mux_ops->determine_rate(mux_hw, req);
+119 -44
drivers/clk/meson/meson8b.c
··· 118 118 }, 119 119 }; 120 120 121 + static struct clk_fixed_factor hdmi_pll_dco_in = { 122 + .mult = 2, 123 + .div = 1, 124 + .hw.init = &(struct clk_init_data){ 125 + .name = "hdmi_pll_dco_in", 126 + .ops = &clk_fixed_factor_ops, 127 + .parent_data = &(const struct clk_parent_data) { 128 + .fw_name = "xtal", 129 + .index = -1, 130 + }, 131 + .num_parents = 1, 132 + }, 133 + }; 134 + 135 + /* 136 + * Taken from the vendor driver for the 2970/2975MHz (both only differ in the 137 + * FRAC part in HHI_VID_PLL_CNTL2) where these values are identical for Meson8, 138 + * Meson8b and Meson8m2. This doubles the input (or output - it's not clear 139 + * which one but the result is the same) clock. The vendor driver additionally 140 + * has the following comment about: "optimise HPLL VCO 2.97GHz performance". 141 + */ 142 + static const struct reg_sequence meson8b_hdmi_pll_init_regs[] = { 143 + { .reg = HHI_VID_PLL_CNTL2, .def = 0x69c84000 }, 144 + { .reg = HHI_VID_PLL_CNTL3, .def = 0x8a46c023 }, 145 + { .reg = HHI_VID_PLL_CNTL4, .def = 0x4123b100 }, 146 + { .reg = HHI_VID_PLL_CNTL5, .def = 0x00012385 }, 147 + { .reg = HHI_VID2_PLL_CNTL2, .def = 0x0430a800 }, 148 + }; 149 + 150 + static const struct pll_params_table hdmi_pll_params_table[] = { 151 + PLL_PARAMS(40, 1), 152 + PLL_PARAMS(42, 1), 153 + PLL_PARAMS(44, 1), 154 + PLL_PARAMS(45, 1), 155 + PLL_PARAMS(49, 1), 156 + PLL_PARAMS(52, 1), 157 + PLL_PARAMS(54, 1), 158 + PLL_PARAMS(56, 1), 159 + PLL_PARAMS(59, 1), 160 + PLL_PARAMS(60, 1), 161 + PLL_PARAMS(61, 1), 162 + PLL_PARAMS(62, 1), 163 + PLL_PARAMS(64, 1), 164 + PLL_PARAMS(66, 1), 165 + PLL_PARAMS(68, 1), 166 + PLL_PARAMS(71, 1), 167 + PLL_PARAMS(82, 1), 168 + { /* sentinel */ } 169 + }; 170 + 121 171 static struct clk_regmap meson8b_hdmi_pll_dco = { 122 172 .data = &(struct meson_clk_pll_data){ 123 173 .en = { ··· 200 150 .shift = 29, 201 151 .width = 1, 202 152 }, 153 + .table = hdmi_pll_params_table, 154 + .init_regs = meson8b_hdmi_pll_init_regs, 155 + .init_count = ARRAY_SIZE(meson8b_hdmi_pll_init_regs), 203 156 }, 204 157 .hw.init = &(struct clk_init_data){ 205 158 /* sometimes also called "HPLL" or "HPLL PLL" */ 206 159 .name = "hdmi_pll_dco", 207 - .ops = &meson_clk_pll_ro_ops, 208 - .parent_data = &(const struct clk_parent_data) { 209 - .fw_name = "xtal", 210 - .name = "xtal", 211 - .index = -1, 160 + .ops = &meson_clk_pll_ops, 161 + .parent_hws = (const struct clk_hw *[]) { 162 + &hdmi_pll_dco_in.hw 212 163 }, 213 164 .num_parents = 1, 214 165 }, ··· 224 173 }, 225 174 .hw.init = &(struct clk_init_data){ 226 175 .name = "hdmi_pll_lvds_out", 227 - .ops = &clk_regmap_divider_ro_ops, 176 + .ops = &clk_regmap_divider_ops, 228 177 .parent_hws = (const struct clk_hw *[]) { 229 178 &meson8b_hdmi_pll_dco.hw 230 179 }, ··· 242 191 }, 243 192 .hw.init = &(struct clk_init_data){ 244 193 .name = "hdmi_pll_hdmi_out", 245 - .ops = &clk_regmap_divider_ro_ops, 194 + .ops = &clk_regmap_divider_ops, 246 195 .parent_hws = (const struct clk_hw *[]) { 247 196 &meson8b_hdmi_pll_dco.hw 248 197 }, ··· 1096 1045 }, 1097 1046 }; 1098 1047 1048 + /* also called LVDS_CLK_EN */ 1049 + static struct clk_regmap meson8b_vid_pll_lvds_en = { 1050 + .data = &(struct clk_regmap_gate_data){ 1051 + .offset = HHI_VID_DIVIDER_CNTL, 1052 + .bit_idx = 11, 1053 + }, 1054 + .hw.init = &(struct clk_init_data){ 1055 + .name = "vid_pll_lvds_en", 1056 + .ops = &clk_regmap_gate_ops, 1057 + .parent_hws = (const struct clk_hw *[]) { 1058 + &meson8b_hdmi_pll_lvds_out.hw 1059 + }, 1060 + .num_parents = 1, 1061 + .flags = CLK_SET_RATE_PARENT, 1062 + }, 1063 + }; 1064 + 1099 1065 static struct clk_regmap meson8b_vid_pll_in_sel = { 1100 1066 .data = &(struct clk_regmap_mux_data){ 1101 1067 .offset = HHI_VID_DIVIDER_CNTL, ··· 1121 1053 }, 1122 1054 .hw.init = &(struct clk_init_data){ 1123 1055 .name = "vid_pll_in_sel", 1124 - .ops = &clk_regmap_mux_ro_ops, 1056 + .ops = &clk_regmap_mux_ops, 1125 1057 /* 1126 1058 * TODO: depending on the SoC there is also a second parent: 1127 1059 * Meson8: unknown ··· 1129 1061 * Meson8m2: vid2_pll 1130 1062 */ 1131 1063 .parent_hws = (const struct clk_hw *[]) { 1132 - &meson8b_hdmi_pll_lvds_out.hw 1064 + &meson8b_vid_pll_lvds_en.hw 1133 1065 }, 1134 1066 .num_parents = 1, 1135 1067 .flags = CLK_SET_RATE_PARENT, ··· 1143 1075 }, 1144 1076 .hw.init = &(struct clk_init_data){ 1145 1077 .name = "vid_pll_in_en", 1146 - .ops = &clk_regmap_gate_ro_ops, 1078 + .ops = &clk_regmap_gate_ops, 1147 1079 .parent_hws = (const struct clk_hw *[]) { 1148 1080 &meson8b_vid_pll_in_sel.hw 1149 1081 }, ··· 1160 1092 }, 1161 1093 .hw.init = &(struct clk_init_data){ 1162 1094 .name = "vid_pll_pre_div", 1163 - .ops = &clk_regmap_divider_ro_ops, 1095 + .ops = &clk_regmap_divider_ops, 1164 1096 .parent_hws = (const struct clk_hw *[]) { 1165 1097 &meson8b_vid_pll_in_en.hw 1166 1098 }, ··· 1177 1109 }, 1178 1110 .hw.init = &(struct clk_init_data){ 1179 1111 .name = "vid_pll_post_div", 1180 - .ops = &clk_regmap_divider_ro_ops, 1112 + .ops = &clk_regmap_divider_ops, 1181 1113 .parent_hws = (const struct clk_hw *[]) { 1182 1114 &meson8b_vid_pll_pre_div.hw 1183 1115 }, ··· 1194 1126 }, 1195 1127 .hw.init = &(struct clk_init_data){ 1196 1128 .name = "vid_pll", 1197 - .ops = &clk_regmap_mux_ro_ops, 1129 + .ops = &clk_regmap_mux_ops, 1198 1130 /* TODO: parent 0x2 is vid_pll_pre_div_mult7_div2 */ 1199 1131 .parent_hws = (const struct clk_hw *[]) { 1200 1132 &meson8b_vid_pll_pre_div.hw, ··· 1213 1145 }, 1214 1146 .hw.init = &(struct clk_init_data){ 1215 1147 .name = "vid_pll_final_div", 1216 - .ops = &clk_regmap_divider_ro_ops, 1148 + .ops = &clk_regmap_divider_ops, 1217 1149 .parent_hws = (const struct clk_hw *[]) { 1218 1150 &meson8b_vid_pll.hw 1219 1151 }, ··· 1240 1172 }, 1241 1173 .hw.init = &(struct clk_init_data){ 1242 1174 .name = "vclk_in_sel", 1243 - .ops = &clk_regmap_mux_ro_ops, 1175 + .ops = &clk_regmap_mux_ops, 1244 1176 .parent_hws = meson8b_vclk_mux_parent_hws, 1245 1177 .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws), 1246 - .flags = CLK_SET_RATE_PARENT, 1178 + .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 1247 1179 }, 1248 1180 }; 1249 1181 ··· 1254 1186 }, 1255 1187 .hw.init = &(struct clk_init_data){ 1256 1188 .name = "vclk_in_en", 1257 - .ops = &clk_regmap_gate_ro_ops, 1189 + .ops = &clk_regmap_gate_ops, 1258 1190 .parent_hws = (const struct clk_hw *[]) { 1259 1191 &meson8b_vclk_in_sel.hw 1260 1192 }, ··· 1270 1202 }, 1271 1203 .hw.init = &(struct clk_init_data){ 1272 1204 .name = "vclk_en", 1273 - .ops = &clk_regmap_gate_ro_ops, 1205 + .ops = &clk_regmap_gate_ops, 1274 1206 .parent_hws = (const struct clk_hw *[]) { 1275 1207 &meson8b_vclk_in_en.hw 1276 1208 }, ··· 1286 1218 }, 1287 1219 .hw.init = &(struct clk_init_data){ 1288 1220 .name = "vclk_div1_en", 1289 - .ops = &clk_regmap_gate_ro_ops, 1221 + .ops = &clk_regmap_gate_ops, 1290 1222 .parent_hws = (const struct clk_hw *[]) { 1291 1223 &meson8b_vclk_en.hw 1292 1224 }, ··· 1316 1248 }, 1317 1249 .hw.init = &(struct clk_init_data){ 1318 1250 .name = "vclk_div2_en", 1319 - .ops = &clk_regmap_gate_ro_ops, 1251 + .ops = &clk_regmap_gate_ops, 1320 1252 .parent_hws = (const struct clk_hw *[]) { 1321 1253 &meson8b_vclk_div2_div.hw 1322 1254 }, ··· 1346 1278 }, 1347 1279 .hw.init = &(struct clk_init_data){ 1348 1280 .name = "vclk_div4_en", 1349 - .ops = &clk_regmap_gate_ro_ops, 1281 + .ops = &clk_regmap_gate_ops, 1350 1282 .parent_hws = (const struct clk_hw *[]) { 1351 1283 &meson8b_vclk_div4_div.hw 1352 1284 }, ··· 1376 1308 }, 1377 1309 .hw.init = &(struct clk_init_data){ 1378 1310 .name = "vclk_div6_en", 1379 - .ops = &clk_regmap_gate_ro_ops, 1311 + .ops = &clk_regmap_gate_ops, 1380 1312 .parent_hws = (const struct clk_hw *[]) { 1381 1313 &meson8b_vclk_div6_div.hw 1382 1314 }, ··· 1406 1338 }, 1407 1339 .hw.init = &(struct clk_init_data){ 1408 1340 .name = "vclk_div12_en", 1409 - .ops = &clk_regmap_gate_ro_ops, 1341 + .ops = &clk_regmap_gate_ops, 1410 1342 .parent_hws = (const struct clk_hw *[]) { 1411 1343 &meson8b_vclk_div12_div.hw 1412 1344 }, ··· 1423 1355 }, 1424 1356 .hw.init = &(struct clk_init_data){ 1425 1357 .name = "vclk2_in_sel", 1426 - .ops = &clk_regmap_mux_ro_ops, 1358 + .ops = &clk_regmap_mux_ops, 1427 1359 .parent_hws = meson8b_vclk_mux_parent_hws, 1428 1360 .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws), 1429 - .flags = CLK_SET_RATE_PARENT, 1361 + .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 1430 1362 }, 1431 1363 }; 1432 1364 ··· 1437 1369 }, 1438 1370 .hw.init = &(struct clk_init_data){ 1439 1371 .name = "vclk2_in_en", 1440 - .ops = &clk_regmap_gate_ro_ops, 1372 + .ops = &clk_regmap_gate_ops, 1441 1373 .parent_hws = (const struct clk_hw *[]) { 1442 1374 &meson8b_vclk2_in_sel.hw 1443 1375 }, ··· 1453 1385 }, 1454 1386 .hw.init = &(struct clk_init_data){ 1455 1387 .name = "vclk2_en", 1456 - .ops = &clk_regmap_gate_ro_ops, 1388 + .ops = &clk_regmap_gate_ops, 1457 1389 .parent_hws = (const struct clk_hw *[]) { 1458 1390 &meson8b_vclk2_clk_in_en.hw 1459 1391 }, ··· 1469 1401 }, 1470 1402 .hw.init = &(struct clk_init_data){ 1471 1403 .name = "vclk2_div1_en", 1472 - .ops = &clk_regmap_gate_ro_ops, 1404 + .ops = &clk_regmap_gate_ops, 1473 1405 .parent_hws = (const struct clk_hw *[]) { 1474 1406 &meson8b_vclk2_clk_en.hw 1475 1407 }, ··· 1499 1431 }, 1500 1432 .hw.init = &(struct clk_init_data){ 1501 1433 .name = "vclk2_div2_en", 1502 - .ops = &clk_regmap_gate_ro_ops, 1434 + .ops = &clk_regmap_gate_ops, 1503 1435 .parent_hws = (const struct clk_hw *[]) { 1504 1436 &meson8b_vclk2_div2_div.hw 1505 1437 }, ··· 1529 1461 }, 1530 1462 .hw.init = &(struct clk_init_data){ 1531 1463 .name = "vclk2_div4_en", 1532 - .ops = &clk_regmap_gate_ro_ops, 1464 + .ops = &clk_regmap_gate_ops, 1533 1465 .parent_hws = (const struct clk_hw *[]) { 1534 1466 &meson8b_vclk2_div4_div.hw 1535 1467 }, ··· 1559 1491 }, 1560 1492 .hw.init = &(struct clk_init_data){ 1561 1493 .name = "vclk2_div6_en", 1562 - .ops = &clk_regmap_gate_ro_ops, 1494 + .ops = &clk_regmap_gate_ops, 1563 1495 .parent_hws = (const struct clk_hw *[]) { 1564 1496 &meson8b_vclk2_div6_div.hw 1565 1497 }, ··· 1589 1521 }, 1590 1522 .hw.init = &(struct clk_init_data){ 1591 1523 .name = "vclk2_div12_en", 1592 - .ops = &clk_regmap_gate_ro_ops, 1524 + .ops = &clk_regmap_gate_ops, 1593 1525 .parent_hws = (const struct clk_hw *[]) { 1594 1526 &meson8b_vclk2_div12_div.hw 1595 1527 }, ··· 1614 1546 }, 1615 1547 .hw.init = &(struct clk_init_data){ 1616 1548 .name = "cts_enct_sel", 1617 - .ops = &clk_regmap_mux_ro_ops, 1549 + .ops = &clk_regmap_mux_ops, 1618 1550 .parent_hws = meson8b_vclk_enc_mux_parent_hws, 1619 1551 .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), 1620 1552 .flags = CLK_SET_RATE_PARENT, ··· 1628 1560 }, 1629 1561 .hw.init = &(struct clk_init_data){ 1630 1562 .name = "cts_enct", 1631 - .ops = &clk_regmap_gate_ro_ops, 1563 + .ops = &clk_regmap_gate_ops, 1632 1564 .parent_hws = (const struct clk_hw *[]) { 1633 1565 &meson8b_cts_enct_sel.hw 1634 1566 }, ··· 1645 1577 }, 1646 1578 .hw.init = &(struct clk_init_data){ 1647 1579 .name = "cts_encp_sel", 1648 - .ops = &clk_regmap_mux_ro_ops, 1580 + .ops = &clk_regmap_mux_ops, 1649 1581 .parent_hws = meson8b_vclk_enc_mux_parent_hws, 1650 1582 .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), 1651 1583 .flags = CLK_SET_RATE_PARENT, ··· 1659 1591 }, 1660 1592 .hw.init = &(struct clk_init_data){ 1661 1593 .name = "cts_encp", 1662 - .ops = &clk_regmap_gate_ro_ops, 1594 + .ops = &clk_regmap_gate_ops, 1663 1595 .parent_hws = (const struct clk_hw *[]) { 1664 1596 &meson8b_cts_encp_sel.hw 1665 1597 }, ··· 1676 1608 }, 1677 1609 .hw.init = &(struct clk_init_data){ 1678 1610 .name = "cts_enci_sel", 1679 - .ops = &clk_regmap_mux_ro_ops, 1611 + .ops = &clk_regmap_mux_ops, 1680 1612 .parent_hws = meson8b_vclk_enc_mux_parent_hws, 1681 1613 .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), 1682 1614 .flags = CLK_SET_RATE_PARENT, ··· 1690 1622 }, 1691 1623 .hw.init = &(struct clk_init_data){ 1692 1624 .name = "cts_enci", 1693 - .ops = &clk_regmap_gate_ro_ops, 1625 + .ops = &clk_regmap_gate_ops, 1694 1626 .parent_hws = (const struct clk_hw *[]) { 1695 1627 &meson8b_cts_enci_sel.hw 1696 1628 }, ··· 1707 1639 }, 1708 1640 .hw.init = &(struct clk_init_data){ 1709 1641 .name = "hdmi_tx_pixel_sel", 1710 - .ops = &clk_regmap_mux_ro_ops, 1642 + .ops = &clk_regmap_mux_ops, 1711 1643 .parent_hws = meson8b_vclk_enc_mux_parent_hws, 1712 1644 .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), 1713 1645 .flags = CLK_SET_RATE_PARENT, ··· 1721 1653 }, 1722 1654 .hw.init = &(struct clk_init_data){ 1723 1655 .name = "hdmi_tx_pixel", 1724 - .ops = &clk_regmap_gate_ro_ops, 1656 + .ops = &clk_regmap_gate_ops, 1725 1657 .parent_hws = (const struct clk_hw *[]) { 1726 1658 &meson8b_hdmi_tx_pixel_sel.hw 1727 1659 }, ··· 1746 1678 }, 1747 1679 .hw.init = &(struct clk_init_data){ 1748 1680 .name = "cts_encl_sel", 1749 - .ops = &clk_regmap_mux_ro_ops, 1681 + .ops = &clk_regmap_mux_ops, 1750 1682 .parent_hws = meson8b_vclk2_enc_mux_parent_hws, 1751 1683 .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws), 1752 1684 .flags = CLK_SET_RATE_PARENT, ··· 1760 1692 }, 1761 1693 .hw.init = &(struct clk_init_data){ 1762 1694 .name = "cts_encl", 1763 - .ops = &clk_regmap_gate_ro_ops, 1695 + .ops = &clk_regmap_gate_ops, 1764 1696 .parent_hws = (const struct clk_hw *[]) { 1765 1697 &meson8b_cts_encl_sel.hw 1766 1698 }, ··· 1777 1709 }, 1778 1710 .hw.init = &(struct clk_init_data){ 1779 1711 .name = "cts_vdac0_sel", 1780 - .ops = &clk_regmap_mux_ro_ops, 1712 + .ops = &clk_regmap_mux_ops, 1781 1713 .parent_hws = meson8b_vclk2_enc_mux_parent_hws, 1782 1714 .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws), 1783 1715 .flags = CLK_SET_RATE_PARENT, ··· 1791 1723 }, 1792 1724 .hw.init = &(struct clk_init_data){ 1793 1725 .name = "cts_vdac0", 1794 - .ops = &clk_regmap_gate_ro_ops, 1726 + .ops = &clk_regmap_gate_ops, 1795 1727 .parent_hws = (const struct clk_hw *[]) { 1796 1728 &meson8b_cts_vdac0_sel.hw 1797 1729 }, ··· 2973 2905 [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, 2974 2906 [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, 2975 2907 [CLKID_CTS_I958] = &meson8b_cts_i958.hw, 2908 + [CLKID_VID_PLL_LVDS_EN] = &meson8b_vid_pll_lvds_en.hw, 2909 + [CLKID_HDMI_PLL_DCO_IN] = &hdmi_pll_dco_in.hw, 2976 2910 [CLK_NR_CLKS] = NULL, 2977 2911 }, 2978 2912 .num = CLK_NR_CLKS, ··· 3192 3122 [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, 3193 3123 [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, 3194 3124 [CLKID_CTS_I958] = &meson8b_cts_i958.hw, 3125 + [CLKID_VID_PLL_LVDS_EN] = &meson8b_vid_pll_lvds_en.hw, 3126 + [CLKID_HDMI_PLL_DCO_IN] = &hdmi_pll_dco_in.hw, 3195 3127 [CLK_NR_CLKS] = NULL, 3196 3128 }, 3197 3129 .num = CLK_NR_CLKS, ··· 3413 3341 [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, 3414 3342 [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, 3415 3343 [CLKID_CTS_I958] = &meson8b_cts_i958.hw, 3344 + [CLKID_VID_PLL_LVDS_EN] = &meson8b_vid_pll_lvds_en.hw, 3345 + [CLKID_HDMI_PLL_DCO_IN] = &hdmi_pll_dco_in.hw, 3416 3346 [CLK_NR_CLKS] = NULL, 3417 3347 }, 3418 3348 .num = CLK_NR_CLKS, ··· 3613 3539 &meson8b_cts_mclk_i958_div, 3614 3540 &meson8b_cts_mclk_i958, 3615 3541 &meson8b_cts_i958, 3542 + &meson8b_vid_pll_lvds_en, 3616 3543 }; 3617 3544 3618 3545 static const struct meson8b_clk_reset_line {
+14 -12
drivers/clk/meson/meson8b.h
··· 51 51 #define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */ 52 52 #define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */ 53 53 #define HHI_VID_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */ 54 + #define HHI_VID_PLL_CNTL3 0x328 /* 0xca offset in data sheet */ 55 + #define HHI_VID_PLL_CNTL4 0x32c /* 0xcb offset in data sheet */ 56 + #define HHI_VID_PLL_CNTL5 0x330 /* 0xcc offset in data sheet */ 57 + #define HHI_VID_PLL_CNTL6 0x334 /* 0xcd offset in data sheet */ 58 + #define HHI_VID2_PLL_CNTL 0x380 /* 0xe0 offset in data sheet */ 59 + #define HHI_VID2_PLL_CNTL2 0x384 /* 0xe1 offset in data sheet */ 60 + #define HHI_VID2_PLL_CNTL3 0x388 /* 0xe2 offset in data sheet */ 61 + #define HHI_VID2_PLL_CNTL4 0x38c /* 0xe3 offset in data sheet */ 62 + #define HHI_VID2_PLL_CNTL5 0x390 /* 0xe4 offset in data sheet */ 63 + #define HHI_VID2_PLL_CNTL6 0x394 /* 0xe5 offset in data sheet */ 54 64 55 65 /* 56 66 * MPLL register offeset taken from the S905 datasheet. Vendor kernel source ··· 117 107 #define CLKID_PERIPH_SEL 125 118 108 #define CLKID_AXI_SEL 127 119 109 #define CLKID_L2_DRAM_SEL 129 120 - #define CLKID_HDMI_PLL_LVDS_OUT 131 121 - #define CLKID_HDMI_PLL_HDMI_OUT 132 110 + #define CLKID_HDMI_PLL_LVDS_OUT 131 122 111 #define CLKID_VID_PLL_IN_SEL 133 123 112 #define CLKID_VID_PLL_IN_EN 134 124 113 #define CLKID_VID_PLL_PRE_DIV 135 125 114 #define CLKID_VID_PLL_POST_DIV 136 126 - #define CLKID_VID_PLL_FINAL_DIV 137 127 - #define CLKID_VCLK_IN_SEL 138 128 115 #define CLKID_VCLK_IN_EN 139 129 116 #define CLKID_VCLK_DIV1 140 130 117 #define CLKID_VCLK_DIV2_DIV 141 ··· 132 125 #define CLKID_VCLK_DIV6 146 133 126 #define CLKID_VCLK_DIV12_DIV 147 134 127 #define CLKID_VCLK_DIV12 148 135 - #define CLKID_VCLK2_IN_SEL 149 136 128 #define CLKID_VCLK2_IN_EN 150 137 129 #define CLKID_VCLK2_DIV1 151 138 130 #define CLKID_VCLK2_DIV2_DIV 152 ··· 143 137 #define CLKID_VCLK2_DIV12_DIV 158 144 138 #define CLKID_VCLK2_DIV12 159 145 139 #define CLKID_CTS_ENCT_SEL 160 146 - #define CLKID_CTS_ENCT 161 147 140 #define CLKID_CTS_ENCP_SEL 162 148 - #define CLKID_CTS_ENCP 163 149 141 #define CLKID_CTS_ENCI_SEL 164 150 - #define CLKID_CTS_ENCI 165 151 142 #define CLKID_HDMI_TX_PIXEL_SEL 166 152 - #define CLKID_HDMI_TX_PIXEL 167 153 143 #define CLKID_CTS_ENCL_SEL 168 154 - #define CLKID_CTS_ENCL 169 155 144 #define CLKID_CTS_VDAC0_SEL 170 156 - #define CLKID_CTS_VDAC0 171 157 145 #define CLKID_HDMI_SYS_SEL 172 158 146 #define CLKID_HDMI_SYS_DIV 173 159 147 #define CLKID_MALI_0_SEL 175 ··· 182 182 #define CLKID_CTS_MCLK_I958_DIV 211 183 183 #define CLKID_VCLK_EN 214 184 184 #define CLKID_VCLK2_EN 215 185 + #define CLKID_VID_PLL_LVDS_EN 216 186 + #define CLKID_HDMI_PLL_DCO_IN 217 185 187 186 - #define CLK_NR_CLKS 216 188 + #define CLK_NR_CLKS 218 187 189 188 190 /* 189 191 * include the CLKID and RESETID that have
+20 -10
drivers/clk/samsung/Kconfig
··· 67 67 depends on COMMON_CLK_SAMSUNG 68 68 help 69 69 Support for the clock controller present on the Samsung 70 - Exynos5420 SoCs. Choose Y here only if you build for this SoC. 70 + Exynos5420/Exynos5422/Exynos5800 SoCs. Choose Y here only if you 71 + build for this SoC. 71 72 72 73 config EXYNOS_ARM64_COMMON_CLK 73 74 bool "Samsung Exynos ARMv8-family clock controller support" if COMPILE_TEST ··· 80 79 default y if ARCH_EXYNOS 81 80 help 82 81 Support for the Audio Subsystem CLKCON clock controller present 83 - on some Exynos SoC variants. Choose M or Y here if you want to 84 - use audio devices such as I2S, PCM, etc. 82 + on some Samsung Exynos SoC variants. Choose M or Y here if you want 83 + to use audio devices such as I2S, PCM, etc. 85 84 86 85 config EXYNOS_CLKOUT 87 86 tristate "Samsung Exynos clock output driver" 88 87 depends on COMMON_CLK_SAMSUNG 89 88 default y if ARCH_EXYNOS 90 89 help 91 - Support for the clock output (XCLKOUT) present on some of Exynos SoC 92 - variants. Usually the XCLKOUT is used to monitor the status of the 93 - certains clocks from SoC, but it could also be tied to other devices 94 - as an input clock. 90 + Support for the clock output (XCLKOUT) present on some of Samsung 91 + Exynos SoC variants. Usually the XCLKOUT is used to monitor the 92 + status of the certains clocks from SoC, but it could also be tied to 93 + other devices as an input clock. 95 94 96 95 # For S3C24XX platforms, select following symbols: 97 96 config S3C2410_COMMON_CLK 98 97 bool "Samsung S3C2410 clock controller support" if COMPILE_TEST 99 98 select COMMON_CLK_SAMSUNG 100 99 help 101 - Build the s3c2410 clock driver based on the common clock framework. 100 + Support for the clock controller present on the Samsung 101 + S3C2410/S3C2440/S3C2442 SoCs. Choose Y here only if you build for 102 + this SoC. 102 103 103 104 config S3C2410_COMMON_DCLK 104 105 bool 105 106 select COMMON_CLK_SAMSUNG 106 107 select REGMAP_MMIO 107 108 help 108 - Temporary symbol to build the dclk driver based on the common clock 109 - framework. 109 + Support for the dclk clock controller present on the Samsung 110 + S3C2410/S3C2412/S3C2440/S3C2443 SoCs. Choose Y here only if you build 111 + for this SoC. 110 112 111 113 config S3C2412_COMMON_CLK 112 114 bool "Samsung S3C2412 clock controller support" if COMPILE_TEST 113 115 select COMMON_CLK_SAMSUNG 116 + help 117 + Support for the clock controller present on the Samsung S3C2412 SoCs. 118 + Choose Y here only if you build for this SoC. 114 119 115 120 config S3C2443_COMMON_CLK 116 121 bool "Samsung S3C2443 clock controller support" if COMPILE_TEST 117 122 select COMMON_CLK_SAMSUNG 123 + help 124 + Support for the clock controller present on the Samsung 125 + S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.
+1
drivers/clk/samsung/Makefile
··· 17 17 obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o 18 18 obj-$(CONFIG_EXYNOS_CLKOUT) += clk-exynos-clkout.o 19 19 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7.o 20 + obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos850.o 20 21 obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o 21 22 obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o 22 23 obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
+18
drivers/clk/samsung/clk-cpu.c
··· 469 469 kfree(cpuclk); 470 470 return ret; 471 471 } 472 + 473 + void __init samsung_clk_register_cpu(struct samsung_clk_provider *ctx, 474 + const struct samsung_cpu_clock *list, unsigned int nr_clk) 475 + { 476 + unsigned int idx; 477 + unsigned int num_cfgs; 478 + struct clk_hw **hws = ctx->clk_data.hws; 479 + 480 + for (idx = 0; idx < nr_clk; idx++, list++) { 481 + /* find count of configuration rates in cfg */ 482 + for (num_cfgs = 0; list->cfg[num_cfgs].prate != 0; ) 483 + num_cfgs++; 484 + 485 + exynos_register_cpu_clock(ctx, list->id, list->name, hws[list->parent_id], 486 + hws[list->alt_parent_id], list->offset, list->cfg, num_cfgs, 487 + list->flags); 488 + } 489 + }
+1 -3
drivers/clk/samsung/clk-exynos-audss.c
··· 129 129 struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in; 130 130 const struct exynos_audss_clk_drvdata *variant; 131 131 struct clk_hw **clk_table; 132 - struct resource *res; 133 132 struct device *dev = &pdev->dev; 134 133 int i, ret = 0; 135 134 ··· 136 137 if (!variant) 137 138 return -EINVAL; 138 139 139 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 140 - reg_base = devm_ioremap_resource(dev, res); 140 + reg_base = devm_platform_ioremap_resource(pdev, 0); 141 141 if (IS_ERR(reg_base)) 142 142 return PTR_ERR(reg_base); 143 143
+1 -3
drivers/clk/samsung/clk-exynos4412-isp.c
··· 110 110 struct samsung_clk_provider *ctx; 111 111 struct device *dev = &pdev->dev; 112 112 struct device_node *np = dev->of_node; 113 - struct resource *res; 114 113 void __iomem *reg_base; 115 114 116 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 117 - reg_base = devm_ioremap_resource(dev, res); 115 + reg_base = devm_platform_ioremap_resource(pdev, 0); 118 116 if (IS_ERR(reg_base)) 119 117 return PTR_ERR(reg_base); 120 118
+49 -75
drivers/clk/samsung/clk-exynos5433.c
··· 3675 3675 { 0 }, 3676 3676 }; 3677 3677 3678 + static const struct samsung_cpu_clock apollo_cpu_clks[] __initconst = { 3679 + CPU_CLK(CLK_SCLK_APOLLO, "apolloclk", CLK_MOUT_APOLLO_PLL, 3680 + CLK_MOUT_BUS_PLL_APOLLO_USER, 3681 + CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200, 3682 + exynos5433_apolloclk_d), 3683 + }; 3684 + 3685 + static const struct samsung_cmu_info apollo_cmu_info __initconst = { 3686 + .pll_clks = apollo_pll_clks, 3687 + .nr_pll_clks = ARRAY_SIZE(apollo_pll_clks), 3688 + .mux_clks = apollo_mux_clks, 3689 + .nr_mux_clks = ARRAY_SIZE(apollo_mux_clks), 3690 + .div_clks = apollo_div_clks, 3691 + .nr_div_clks = ARRAY_SIZE(apollo_div_clks), 3692 + .gate_clks = apollo_gate_clks, 3693 + .nr_gate_clks = ARRAY_SIZE(apollo_gate_clks), 3694 + .cpu_clks = apollo_cpu_clks, 3695 + .nr_cpu_clks = ARRAY_SIZE(apollo_cpu_clks), 3696 + .nr_clk_ids = APOLLO_NR_CLK, 3697 + .clk_regs = apollo_clk_regs, 3698 + .nr_clk_regs = ARRAY_SIZE(apollo_clk_regs), 3699 + }; 3700 + 3678 3701 static void __init exynos5433_cmu_apollo_init(struct device_node *np) 3679 3702 { 3680 - void __iomem *reg_base; 3681 - struct samsung_clk_provider *ctx; 3682 - struct clk_hw **hws; 3683 - 3684 - reg_base = of_iomap(np, 0); 3685 - if (!reg_base) { 3686 - panic("%s: failed to map registers\n", __func__); 3687 - return; 3688 - } 3689 - 3690 - ctx = samsung_clk_init(np, reg_base, APOLLO_NR_CLK); 3691 - if (!ctx) { 3692 - panic("%s: unable to allocate ctx\n", __func__); 3693 - return; 3694 - } 3695 - 3696 - samsung_clk_register_pll(ctx, apollo_pll_clks, 3697 - ARRAY_SIZE(apollo_pll_clks), reg_base); 3698 - samsung_clk_register_mux(ctx, apollo_mux_clks, 3699 - ARRAY_SIZE(apollo_mux_clks)); 3700 - samsung_clk_register_div(ctx, apollo_div_clks, 3701 - ARRAY_SIZE(apollo_div_clks)); 3702 - samsung_clk_register_gate(ctx, apollo_gate_clks, 3703 - ARRAY_SIZE(apollo_gate_clks)); 3704 - 3705 - hws = ctx->clk_data.hws; 3706 - 3707 - exynos_register_cpu_clock(ctx, CLK_SCLK_APOLLO, "apolloclk", 3708 - hws[CLK_MOUT_APOLLO_PLL], hws[CLK_MOUT_BUS_PLL_APOLLO_USER], 0x200, 3709 - exynos5433_apolloclk_d, ARRAY_SIZE(exynos5433_apolloclk_d), 3710 - CLK_CPU_HAS_E5433_REGS_LAYOUT); 3711 - 3712 - samsung_clk_sleep_init(reg_base, apollo_clk_regs, 3713 - ARRAY_SIZE(apollo_clk_regs)); 3714 - 3715 - samsung_clk_of_add_provider(np, ctx); 3703 + samsung_cmu_register_one(np, &apollo_cmu_info); 3716 3704 } 3717 3705 CLK_OF_DECLARE(exynos5433_cmu_apollo, "samsung,exynos5433-cmu-apollo", 3718 3706 exynos5433_cmu_apollo_init); ··· 3920 3932 { 0 }, 3921 3933 }; 3922 3934 3935 + static const struct samsung_cpu_clock atlas_cpu_clks[] __initconst = { 3936 + CPU_CLK(CLK_SCLK_ATLAS, "atlasclk", CLK_MOUT_ATLAS_PLL, 3937 + CLK_MOUT_BUS_PLL_ATLAS_USER, 3938 + CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200, 3939 + exynos5433_atlasclk_d), 3940 + }; 3941 + 3942 + static const struct samsung_cmu_info atlas_cmu_info __initconst = { 3943 + .pll_clks = atlas_pll_clks, 3944 + .nr_pll_clks = ARRAY_SIZE(atlas_pll_clks), 3945 + .mux_clks = atlas_mux_clks, 3946 + .nr_mux_clks = ARRAY_SIZE(atlas_mux_clks), 3947 + .div_clks = atlas_div_clks, 3948 + .nr_div_clks = ARRAY_SIZE(atlas_div_clks), 3949 + .gate_clks = atlas_gate_clks, 3950 + .nr_gate_clks = ARRAY_SIZE(atlas_gate_clks), 3951 + .cpu_clks = atlas_cpu_clks, 3952 + .nr_cpu_clks = ARRAY_SIZE(atlas_cpu_clks), 3953 + .nr_clk_ids = ATLAS_NR_CLK, 3954 + .clk_regs = atlas_clk_regs, 3955 + .nr_clk_regs = ARRAY_SIZE(atlas_clk_regs), 3956 + }; 3957 + 3923 3958 static void __init exynos5433_cmu_atlas_init(struct device_node *np) 3924 3959 { 3925 - void __iomem *reg_base; 3926 - struct samsung_clk_provider *ctx; 3927 - struct clk_hw **hws; 3928 - 3929 - reg_base = of_iomap(np, 0); 3930 - if (!reg_base) { 3931 - panic("%s: failed to map registers\n", __func__); 3932 - return; 3933 - } 3934 - 3935 - ctx = samsung_clk_init(np, reg_base, ATLAS_NR_CLK); 3936 - if (!ctx) { 3937 - panic("%s: unable to allocate ctx\n", __func__); 3938 - return; 3939 - } 3940 - 3941 - samsung_clk_register_pll(ctx, atlas_pll_clks, 3942 - ARRAY_SIZE(atlas_pll_clks), reg_base); 3943 - samsung_clk_register_mux(ctx, atlas_mux_clks, 3944 - ARRAY_SIZE(atlas_mux_clks)); 3945 - samsung_clk_register_div(ctx, atlas_div_clks, 3946 - ARRAY_SIZE(atlas_div_clks)); 3947 - samsung_clk_register_gate(ctx, atlas_gate_clks, 3948 - ARRAY_SIZE(atlas_gate_clks)); 3949 - 3950 - hws = ctx->clk_data.hws; 3951 - 3952 - exynos_register_cpu_clock(ctx, CLK_SCLK_ATLAS, "atlasclk", 3953 - hws[CLK_MOUT_ATLAS_PLL], hws[CLK_MOUT_BUS_PLL_ATLAS_USER], 0x200, 3954 - exynos5433_atlasclk_d, ARRAY_SIZE(exynos5433_atlasclk_d), 3955 - CLK_CPU_HAS_E5433_REGS_LAYOUT); 3956 - 3957 - samsung_clk_sleep_init(reg_base, atlas_clk_regs, 3958 - ARRAY_SIZE(atlas_clk_regs)); 3959 - 3960 - samsung_clk_of_add_provider(np, ctx); 3960 + samsung_cmu_register_one(np, &atlas_cmu_info); 3961 3961 } 3962 3962 CLK_OF_DECLARE(exynos5433_cmu_atlas, "samsung,exynos5433-cmu-atlas", 3963 3963 exynos5433_cmu_atlas_init); ··· 5540 5564 struct exynos5433_cmu_data *data; 5541 5565 struct samsung_clk_provider *ctx; 5542 5566 struct device *dev = &pdev->dev; 5543 - struct resource *res; 5544 5567 void __iomem *reg_base; 5545 5568 int i; 5546 5569 ··· 5552 5577 return -ENOMEM; 5553 5578 ctx = &data->ctx; 5554 5579 5555 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 5556 - reg_base = devm_ioremap_resource(dev, res); 5580 + reg_base = devm_platform_ioremap_resource(pdev, 0); 5557 5581 if (IS_ERR(reg_base)) 5558 5582 return PTR_ERR(reg_base); 5559 5583
+835
drivers/clk/samsung/clk-exynos850.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2021 Linaro Ltd. 4 + * Author: Sam Protsenko <semen.protsenko@linaro.org> 5 + * 6 + * Common Clock Framework support for Exynos850 SoC. 7 + */ 8 + 9 + #include <linux/clk.h> 10 + #include <linux/clk-provider.h> 11 + #include <linux/of.h> 12 + #include <linux/of_address.h> 13 + #include <linux/of_device.h> 14 + #include <linux/platform_device.h> 15 + 16 + #include <dt-bindings/clock/exynos850.h> 17 + 18 + #include "clk.h" 19 + 20 + /* Gate register bits */ 21 + #define GATE_MANUAL BIT(20) 22 + #define GATE_ENABLE_HWACG BIT(28) 23 + 24 + /* Gate register offsets range */ 25 + #define GATE_OFF_START 0x2000 26 + #define GATE_OFF_END 0x2fff 27 + 28 + /** 29 + * exynos850_init_clocks - Set clocks initial configuration 30 + * @np: CMU device tree node with "reg" property (CMU addr) 31 + * @reg_offs: Register offsets array for clocks to init 32 + * @reg_offs_len: Number of register offsets in reg_offs array 33 + * 34 + * Set manual control mode for all gate clocks. 35 + */ 36 + static void __init exynos850_init_clocks(struct device_node *np, 37 + const unsigned long *reg_offs, size_t reg_offs_len) 38 + { 39 + void __iomem *reg_base; 40 + size_t i; 41 + 42 + reg_base = of_iomap(np, 0); 43 + if (!reg_base) 44 + panic("%s: failed to map registers\n", __func__); 45 + 46 + for (i = 0; i < reg_offs_len; ++i) { 47 + void __iomem *reg = reg_base + reg_offs[i]; 48 + u32 val; 49 + 50 + /* Modify only gate clock registers */ 51 + if (reg_offs[i] < GATE_OFF_START || reg_offs[i] > GATE_OFF_END) 52 + continue; 53 + 54 + val = readl(reg); 55 + val |= GATE_MANUAL; 56 + val &= ~GATE_ENABLE_HWACG; 57 + writel(val, reg); 58 + } 59 + 60 + iounmap(reg_base); 61 + } 62 + 63 + /* ---- CMU_TOP ------------------------------------------------------------- */ 64 + 65 + /* Register Offset definitions for CMU_TOP (0x120e0000) */ 66 + #define PLL_LOCKTIME_PLL_MMC 0x0000 67 + #define PLL_LOCKTIME_PLL_SHARED0 0x0004 68 + #define PLL_LOCKTIME_PLL_SHARED1 0x0008 69 + #define PLL_CON0_PLL_MMC 0x0100 70 + #define PLL_CON3_PLL_MMC 0x010c 71 + #define PLL_CON0_PLL_SHARED0 0x0140 72 + #define PLL_CON3_PLL_SHARED0 0x014c 73 + #define PLL_CON0_PLL_SHARED1 0x0180 74 + #define PLL_CON3_PLL_SHARED1 0x018c 75 + #define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS 0x1014 76 + #define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI 0x1018 77 + #define CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD 0x101c 78 + #define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS 0x1020 79 + #define CLK_CON_MUX_MUX_CLKCMU_DPU 0x1034 80 + #define CLK_CON_MUX_MUX_CLKCMU_HSI_BUS 0x103c 81 + #define CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD 0x1040 82 + #define CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD 0x1044 83 + #define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS 0x1070 84 + #define CLK_CON_MUX_MUX_CLKCMU_PERI_IP 0x1074 85 + #define CLK_CON_MUX_MUX_CLKCMU_PERI_UART 0x1078 86 + #define CLK_CON_DIV_CLKCMU_CORE_BUS 0x1820 87 + #define CLK_CON_DIV_CLKCMU_CORE_CCI 0x1824 88 + #define CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD 0x1828 89 + #define CLK_CON_DIV_CLKCMU_CORE_SSS 0x182c 90 + #define CLK_CON_DIV_CLKCMU_DPU 0x1840 91 + #define CLK_CON_DIV_CLKCMU_HSI_BUS 0x1848 92 + #define CLK_CON_DIV_CLKCMU_HSI_MMC_CARD 0x184c 93 + #define CLK_CON_DIV_CLKCMU_HSI_USB20DRD 0x1850 94 + #define CLK_CON_DIV_CLKCMU_PERI_BUS 0x187c 95 + #define CLK_CON_DIV_CLKCMU_PERI_IP 0x1880 96 + #define CLK_CON_DIV_CLKCMU_PERI_UART 0x1884 97 + #define CLK_CON_DIV_PLL_SHARED0_DIV2 0x188c 98 + #define CLK_CON_DIV_PLL_SHARED0_DIV3 0x1890 99 + #define CLK_CON_DIV_PLL_SHARED0_DIV4 0x1894 100 + #define CLK_CON_DIV_PLL_SHARED1_DIV2 0x1898 101 + #define CLK_CON_DIV_PLL_SHARED1_DIV3 0x189c 102 + #define CLK_CON_DIV_PLL_SHARED1_DIV4 0x18a0 103 + #define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS 0x201c 104 + #define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI 0x2020 105 + #define CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD 0x2024 106 + #define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS 0x2028 107 + #define CLK_CON_GAT_GATE_CLKCMU_DPU 0x203c 108 + #define CLK_CON_GAT_GATE_CLKCMU_HSI_BUS 0x2044 109 + #define CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD 0x2048 110 + #define CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD 0x204c 111 + #define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS 0x2080 112 + #define CLK_CON_GAT_GATE_CLKCMU_PERI_IP 0x2084 113 + #define CLK_CON_GAT_GATE_CLKCMU_PERI_UART 0x2088 114 + 115 + static const unsigned long top_clk_regs[] __initconst = { 116 + PLL_LOCKTIME_PLL_MMC, 117 + PLL_LOCKTIME_PLL_SHARED0, 118 + PLL_LOCKTIME_PLL_SHARED1, 119 + PLL_CON0_PLL_MMC, 120 + PLL_CON3_PLL_MMC, 121 + PLL_CON0_PLL_SHARED0, 122 + PLL_CON3_PLL_SHARED0, 123 + PLL_CON0_PLL_SHARED1, 124 + PLL_CON3_PLL_SHARED1, 125 + CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 126 + CLK_CON_MUX_MUX_CLKCMU_CORE_CCI, 127 + CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD, 128 + CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, 129 + CLK_CON_MUX_MUX_CLKCMU_DPU, 130 + CLK_CON_MUX_MUX_CLKCMU_HSI_BUS, 131 + CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD, 132 + CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD, 133 + CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 134 + CLK_CON_MUX_MUX_CLKCMU_PERI_IP, 135 + CLK_CON_MUX_MUX_CLKCMU_PERI_UART, 136 + CLK_CON_DIV_CLKCMU_CORE_BUS, 137 + CLK_CON_DIV_CLKCMU_CORE_CCI, 138 + CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD, 139 + CLK_CON_DIV_CLKCMU_CORE_SSS, 140 + CLK_CON_DIV_CLKCMU_DPU, 141 + CLK_CON_DIV_CLKCMU_HSI_BUS, 142 + CLK_CON_DIV_CLKCMU_HSI_MMC_CARD, 143 + CLK_CON_DIV_CLKCMU_HSI_USB20DRD, 144 + CLK_CON_DIV_CLKCMU_PERI_BUS, 145 + CLK_CON_DIV_CLKCMU_PERI_IP, 146 + CLK_CON_DIV_CLKCMU_PERI_UART, 147 + CLK_CON_DIV_PLL_SHARED0_DIV2, 148 + CLK_CON_DIV_PLL_SHARED0_DIV3, 149 + CLK_CON_DIV_PLL_SHARED0_DIV4, 150 + CLK_CON_DIV_PLL_SHARED1_DIV2, 151 + CLK_CON_DIV_PLL_SHARED1_DIV3, 152 + CLK_CON_DIV_PLL_SHARED1_DIV4, 153 + CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 154 + CLK_CON_GAT_GATE_CLKCMU_CORE_CCI, 155 + CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD, 156 + CLK_CON_GAT_GATE_CLKCMU_CORE_SSS, 157 + CLK_CON_GAT_GATE_CLKCMU_DPU, 158 + CLK_CON_GAT_GATE_CLKCMU_HSI_BUS, 159 + CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD, 160 + CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD, 161 + CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 162 + CLK_CON_GAT_GATE_CLKCMU_PERI_IP, 163 + CLK_CON_GAT_GATE_CLKCMU_PERI_UART, 164 + }; 165 + 166 + /* 167 + * Do not provide PLL tables to core PLLs, as MANUAL_PLL_CTRL bit is not set 168 + * for those PLLs by default, so set_rate operation would fail. 169 + */ 170 + static const struct samsung_pll_clock top_pll_clks[] __initconst = { 171 + /* CMU_TOP_PURECLKCOMP */ 172 + PLL(pll_0822x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk", 173 + PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, 174 + NULL), 175 + PLL(pll_0822x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk", 176 + PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1, 177 + NULL), 178 + PLL(pll_0831x, CLK_FOUT_MMC_PLL, "fout_mmc_pll", "oscclk", 179 + PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, NULL), 180 + }; 181 + 182 + /* List of parent clocks for Muxes in CMU_TOP */ 183 + PNAME(mout_shared0_pll_p) = { "oscclk", "fout_shared0_pll" }; 184 + PNAME(mout_shared1_pll_p) = { "oscclk", "fout_shared1_pll" }; 185 + PNAME(mout_mmc_pll_p) = { "oscclk", "fout_mmc_pll" }; 186 + /* List of parent clocks for Muxes in CMU_TOP: for CMU_CORE */ 187 + PNAME(mout_core_bus_p) = { "dout_shared1_div2", "dout_shared0_div3", 188 + "dout_shared1_div3", "dout_shared0_div4" }; 189 + PNAME(mout_core_cci_p) = { "dout_shared0_div2", "dout_shared1_div2", 190 + "dout_shared0_div3", "dout_shared1_div3" }; 191 + PNAME(mout_core_mmc_embd_p) = { "oscclk", "dout_shared0_div2", 192 + "dout_shared1_div2", "dout_shared0_div3", 193 + "dout_shared1_div3", "mout_mmc_pll", 194 + "oscclk", "oscclk" }; 195 + PNAME(mout_core_sss_p) = { "dout_shared0_div3", "dout_shared1_div3", 196 + "dout_shared0_div4", "dout_shared1_div4" }; 197 + /* List of parent clocks for Muxes in CMU_TOP: for CMU_HSI */ 198 + PNAME(mout_hsi_bus_p) = { "dout_shared0_div2", "dout_shared1_div2" }; 199 + PNAME(mout_hsi_mmc_card_p) = { "oscclk", "dout_shared0_div2", 200 + "dout_shared1_div2", "dout_shared0_div3", 201 + "dout_shared1_div3", "mout_mmc_pll", 202 + "oscclk", "oscclk" }; 203 + PNAME(mout_hsi_usb20drd_p) = { "oscclk", "dout_shared0_div4", 204 + "dout_shared1_div4", "oscclk" }; 205 + /* List of parent clocks for Muxes in CMU_TOP: for CMU_PERI */ 206 + PNAME(mout_peri_bus_p) = { "dout_shared0_div4", "dout_shared1_div4" }; 207 + PNAME(mout_peri_uart_p) = { "oscclk", "dout_shared0_div4", 208 + "dout_shared1_div4", "oscclk" }; 209 + PNAME(mout_peri_ip_p) = { "oscclk", "dout_shared0_div4", 210 + "dout_shared1_div4", "oscclk" }; 211 + 212 + /* List of parent clocks for Muxes in CMU_TOP: for CMU_DPU */ 213 + PNAME(mout_dpu_p) = { "dout_shared0_div3", "dout_shared1_div3", 214 + "dout_shared0_div4", "dout_shared1_div4" }; 215 + 216 + static const struct samsung_mux_clock top_mux_clks[] __initconst = { 217 + /* CMU_TOP_PURECLKCOMP */ 218 + MUX(CLK_MOUT_SHARED0_PLL, "mout_shared0_pll", mout_shared0_pll_p, 219 + PLL_CON0_PLL_SHARED0, 4, 1), 220 + MUX(CLK_MOUT_SHARED1_PLL, "mout_shared1_pll", mout_shared1_pll_p, 221 + PLL_CON0_PLL_SHARED1, 4, 1), 222 + MUX(CLK_MOUT_MMC_PLL, "mout_mmc_pll", mout_mmc_pll_p, 223 + PLL_CON0_PLL_MMC, 4, 1), 224 + 225 + /* CORE */ 226 + MUX(CLK_MOUT_CORE_BUS, "mout_core_bus", mout_core_bus_p, 227 + CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 2), 228 + MUX(CLK_MOUT_CORE_CCI, "mout_core_cci", mout_core_cci_p, 229 + CLK_CON_MUX_MUX_CLKCMU_CORE_CCI, 0, 2), 230 + MUX(CLK_MOUT_CORE_MMC_EMBD, "mout_core_mmc_embd", mout_core_mmc_embd_p, 231 + CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD, 0, 3), 232 + MUX(CLK_MOUT_CORE_SSS, "mout_core_sss", mout_core_sss_p, 233 + CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, 0, 2), 234 + 235 + /* DPU */ 236 + MUX(CLK_MOUT_DPU, "mout_dpu", mout_dpu_p, 237 + CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 2), 238 + 239 + /* HSI */ 240 + MUX(CLK_MOUT_HSI_BUS, "mout_hsi_bus", mout_hsi_bus_p, 241 + CLK_CON_MUX_MUX_CLKCMU_HSI_BUS, 0, 1), 242 + MUX(CLK_MOUT_HSI_MMC_CARD, "mout_hsi_mmc_card", mout_hsi_mmc_card_p, 243 + CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD, 0, 3), 244 + MUX(CLK_MOUT_HSI_USB20DRD, "mout_hsi_usb20drd", mout_hsi_usb20drd_p, 245 + CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD, 0, 2), 246 + 247 + /* PERI */ 248 + MUX(CLK_MOUT_PERI_BUS, "mout_peri_bus", mout_peri_bus_p, 249 + CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 0, 1), 250 + MUX(CLK_MOUT_PERI_UART, "mout_peri_uart", mout_peri_uart_p, 251 + CLK_CON_MUX_MUX_CLKCMU_PERI_UART, 0, 2), 252 + MUX(CLK_MOUT_PERI_IP, "mout_peri_ip", mout_peri_ip_p, 253 + CLK_CON_MUX_MUX_CLKCMU_PERI_IP, 0, 2), 254 + }; 255 + 256 + static const struct samsung_div_clock top_div_clks[] __initconst = { 257 + /* CMU_TOP_PURECLKCOMP */ 258 + DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "mout_shared0_pll", 259 + CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2), 260 + DIV(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "mout_shared0_pll", 261 + CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1), 262 + DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "mout_shared1_pll", 263 + CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2), 264 + DIV(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "mout_shared1_pll", 265 + CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1), 266 + DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "dout_shared0_div2", 267 + CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1), 268 + DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "dout_shared1_div2", 269 + CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1), 270 + 271 + /* CORE */ 272 + DIV(CLK_DOUT_CORE_BUS, "dout_core_bus", "gout_core_bus", 273 + CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4), 274 + DIV(CLK_DOUT_CORE_CCI, "dout_core_cci", "gout_core_cci", 275 + CLK_CON_DIV_CLKCMU_CORE_CCI, 0, 4), 276 + DIV(CLK_DOUT_CORE_MMC_EMBD, "dout_core_mmc_embd", "gout_core_mmc_embd", 277 + CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD, 0, 9), 278 + DIV(CLK_DOUT_CORE_SSS, "dout_core_sss", "gout_core_sss", 279 + CLK_CON_DIV_CLKCMU_CORE_SSS, 0, 4), 280 + 281 + /* DPU */ 282 + DIV(CLK_DOUT_DPU, "dout_dpu", "gout_dpu", 283 + CLK_CON_DIV_CLKCMU_DPU, 0, 4), 284 + 285 + /* HSI */ 286 + DIV(CLK_DOUT_HSI_BUS, "dout_hsi_bus", "gout_hsi_bus", 287 + CLK_CON_DIV_CLKCMU_HSI_BUS, 0, 4), 288 + DIV(CLK_DOUT_HSI_MMC_CARD, "dout_hsi_mmc_card", "gout_hsi_mmc_card", 289 + CLK_CON_DIV_CLKCMU_HSI_MMC_CARD, 0, 9), 290 + DIV(CLK_DOUT_HSI_USB20DRD, "dout_hsi_usb20drd", "gout_hsi_usb20drd", 291 + CLK_CON_DIV_CLKCMU_HSI_USB20DRD, 0, 4), 292 + 293 + /* PERI */ 294 + DIV(CLK_DOUT_PERI_BUS, "dout_peri_bus", "gout_peri_bus", 295 + CLK_CON_DIV_CLKCMU_PERI_BUS, 0, 4), 296 + DIV(CLK_DOUT_PERI_UART, "dout_peri_uart", "gout_peri_uart", 297 + CLK_CON_DIV_CLKCMU_PERI_UART, 0, 4), 298 + DIV(CLK_DOUT_PERI_IP, "dout_peri_ip", "gout_peri_ip", 299 + CLK_CON_DIV_CLKCMU_PERI_IP, 0, 4), 300 + }; 301 + 302 + static const struct samsung_gate_clock top_gate_clks[] __initconst = { 303 + /* CORE */ 304 + GATE(CLK_GOUT_CORE_BUS, "gout_core_bus", "mout_core_bus", 305 + CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, 0, 0), 306 + GATE(CLK_GOUT_CORE_CCI, "gout_core_cci", "mout_core_cci", 307 + CLK_CON_GAT_GATE_CLKCMU_CORE_CCI, 21, 0, 0), 308 + GATE(CLK_GOUT_CORE_MMC_EMBD, "gout_core_mmc_embd", "mout_core_mmc_embd", 309 + CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD, 21, 0, 0), 310 + GATE(CLK_GOUT_CORE_SSS, "gout_core_sss", "mout_core_sss", 311 + CLK_CON_GAT_GATE_CLKCMU_CORE_SSS, 21, 0, 0), 312 + 313 + /* DPU */ 314 + GATE(CLK_GOUT_DPU, "gout_dpu", "mout_dpu", 315 + CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0), 316 + 317 + /* HSI */ 318 + GATE(CLK_GOUT_HSI_BUS, "gout_hsi_bus", "mout_hsi_bus", 319 + CLK_CON_GAT_GATE_CLKCMU_HSI_BUS, 21, 0, 0), 320 + GATE(CLK_GOUT_HSI_MMC_CARD, "gout_hsi_mmc_card", "mout_hsi_mmc_card", 321 + CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD, 21, 0, 0), 322 + GATE(CLK_GOUT_HSI_USB20DRD, "gout_hsi_usb20drd", "mout_hsi_usb20drd", 323 + CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD, 21, 0, 0), 324 + 325 + /* PERI */ 326 + GATE(CLK_GOUT_PERI_BUS, "gout_peri_bus", "mout_peri_bus", 327 + CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 21, 0, 0), 328 + GATE(CLK_GOUT_PERI_UART, "gout_peri_uart", "mout_peri_uart", 329 + CLK_CON_GAT_GATE_CLKCMU_PERI_UART, 21, 0, 0), 330 + GATE(CLK_GOUT_PERI_IP, "gout_peri_ip", "mout_peri_ip", 331 + CLK_CON_GAT_GATE_CLKCMU_PERI_IP, 21, 0, 0), 332 + }; 333 + 334 + static const struct samsung_cmu_info top_cmu_info __initconst = { 335 + .pll_clks = top_pll_clks, 336 + .nr_pll_clks = ARRAY_SIZE(top_pll_clks), 337 + .mux_clks = top_mux_clks, 338 + .nr_mux_clks = ARRAY_SIZE(top_mux_clks), 339 + .div_clks = top_div_clks, 340 + .nr_div_clks = ARRAY_SIZE(top_div_clks), 341 + .gate_clks = top_gate_clks, 342 + .nr_gate_clks = ARRAY_SIZE(top_gate_clks), 343 + .nr_clk_ids = TOP_NR_CLK, 344 + .clk_regs = top_clk_regs, 345 + .nr_clk_regs = ARRAY_SIZE(top_clk_regs), 346 + }; 347 + 348 + static void __init exynos850_cmu_top_init(struct device_node *np) 349 + { 350 + exynos850_init_clocks(np, top_clk_regs, ARRAY_SIZE(top_clk_regs)); 351 + samsung_cmu_register_one(np, &top_cmu_info); 352 + } 353 + 354 + CLK_OF_DECLARE(exynos850_cmu_top, "samsung,exynos850-cmu-top", 355 + exynos850_cmu_top_init); 356 + 357 + /* ---- CMU_HSI ------------------------------------------------------------- */ 358 + 359 + /* Register Offset definitions for CMU_HSI (0x13400000) */ 360 + #define PLL_CON0_MUX_CLKCMU_HSI_BUS_USER 0x0600 361 + #define PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER 0x0610 362 + #define PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER 0x0620 363 + #define CLK_CON_MUX_MUX_CLK_HSI_RTC 0x1000 364 + #define CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV 0x2008 365 + #define CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50 0x200c 366 + #define CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26 0x2010 367 + #define CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK 0x2018 368 + #define CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK 0x2024 369 + #define CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN 0x2028 370 + #define CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK 0x2038 371 + #define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20 0x203c 372 + #define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY 0x2040 373 + 374 + static const unsigned long hsi_clk_regs[] __initconst = { 375 + PLL_CON0_MUX_CLKCMU_HSI_BUS_USER, 376 + PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER, 377 + PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER, 378 + CLK_CON_MUX_MUX_CLK_HSI_RTC, 379 + CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV, 380 + CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50, 381 + CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26, 382 + CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK, 383 + CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK, 384 + CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN, 385 + CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK, 386 + CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20, 387 + CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY, 388 + }; 389 + 390 + /* List of parent clocks for Muxes in CMU_PERI */ 391 + PNAME(mout_hsi_bus_user_p) = { "oscclk", "dout_hsi_bus" }; 392 + PNAME(mout_hsi_mmc_card_user_p) = { "oscclk", "dout_hsi_mmc_card" }; 393 + PNAME(mout_hsi_usb20drd_user_p) = { "oscclk", "dout_hsi_usb20drd" }; 394 + PNAME(mout_hsi_rtc_p) = { "rtcclk", "oscclk" }; 395 + 396 + static const struct samsung_mux_clock hsi_mux_clks[] __initconst = { 397 + MUX(CLK_MOUT_HSI_BUS_USER, "mout_hsi_bus_user", mout_hsi_bus_user_p, 398 + PLL_CON0_MUX_CLKCMU_HSI_BUS_USER, 4, 1), 399 + MUX_F(CLK_MOUT_HSI_MMC_CARD_USER, "mout_hsi_mmc_card_user", 400 + mout_hsi_mmc_card_user_p, PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER, 401 + 4, 1, CLK_SET_RATE_PARENT, 0), 402 + MUX(CLK_MOUT_HSI_USB20DRD_USER, "mout_hsi_usb20drd_user", 403 + mout_hsi_usb20drd_user_p, PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER, 404 + 4, 1), 405 + MUX(CLK_MOUT_HSI_RTC, "mout_hsi_rtc", mout_hsi_rtc_p, 406 + CLK_CON_MUX_MUX_CLK_HSI_RTC, 0, 1), 407 + }; 408 + 409 + static const struct samsung_gate_clock hsi_gate_clks[] __initconst = { 410 + GATE(CLK_GOUT_USB_RTC_CLK, "gout_usb_rtc", "mout_hsi_rtc", 411 + CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV, 21, 0, 0), 412 + GATE(CLK_GOUT_USB_REF_CLK, "gout_usb_ref", "mout_hsi_usb20drd_user", 413 + CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50, 21, 0, 0), 414 + GATE(CLK_GOUT_USB_PHY_REF_CLK, "gout_usb_phy_ref", "oscclk", 415 + CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26, 21, 0, 0), 416 + GATE(CLK_GOUT_GPIO_HSI_PCLK, "gout_gpio_hsi_pclk", "mout_hsi_bus_user", 417 + CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK, 21, 0, 0), 418 + GATE(CLK_GOUT_MMC_CARD_ACLK, "gout_mmc_card_aclk", "mout_hsi_bus_user", 419 + CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK, 21, 0, 0), 420 + GATE(CLK_GOUT_MMC_CARD_SDCLKIN, "gout_mmc_card_sdclkin", 421 + "mout_hsi_mmc_card_user", 422 + CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN, 21, CLK_SET_RATE_PARENT, 0), 423 + GATE(CLK_GOUT_SYSREG_HSI_PCLK, "gout_sysreg_hsi_pclk", 424 + "mout_hsi_bus_user", 425 + CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK, 21, 0, 0), 426 + GATE(CLK_GOUT_USB_PHY_ACLK, "gout_usb_phy_aclk", "mout_hsi_bus_user", 427 + CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20, 21, 0, 0), 428 + GATE(CLK_GOUT_USB_BUS_EARLY_CLK, "gout_usb_bus_early", 429 + "mout_hsi_bus_user", 430 + CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY, 21, 0, 0), 431 + }; 432 + 433 + static const struct samsung_cmu_info hsi_cmu_info __initconst = { 434 + .mux_clks = hsi_mux_clks, 435 + .nr_mux_clks = ARRAY_SIZE(hsi_mux_clks), 436 + .gate_clks = hsi_gate_clks, 437 + .nr_gate_clks = ARRAY_SIZE(hsi_gate_clks), 438 + .nr_clk_ids = HSI_NR_CLK, 439 + .clk_regs = hsi_clk_regs, 440 + .nr_clk_regs = ARRAY_SIZE(hsi_clk_regs), 441 + .clk_name = "dout_hsi_bus", 442 + }; 443 + 444 + /* ---- CMU_PERI ------------------------------------------------------------ */ 445 + 446 + /* Register Offset definitions for CMU_PERI (0x10030000) */ 447 + #define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER 0x0600 448 + #define PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER 0x0610 449 + #define PLL_CON0_MUX_CLKCMU_PERI_SPI_USER 0x0620 450 + #define PLL_CON0_MUX_CLKCMU_PERI_UART_USER 0x0630 451 + #define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0 0x1800 452 + #define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1 0x1804 453 + #define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2 0x1808 454 + #define CLK_CON_DIV_DIV_CLK_PERI_SPI_0 0x180c 455 + #define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0 0x200c 456 + #define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1 0x2010 457 + #define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2 0x2014 458 + #define CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK 0x2020 459 + #define CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK 0x2024 460 + #define CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK 0x2028 461 + #define CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK 0x202c 462 + #define CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK 0x2030 463 + #define CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK 0x2034 464 + #define CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK 0x2038 465 + #define CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK 0x203c 466 + #define CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK 0x2040 467 + #define CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK 0x2044 468 + #define CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK 0x2048 469 + #define CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK 0x204c 470 + #define CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK 0x2050 471 + #define CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK 0x2054 472 + #define CLK_CON_GAT_GOUT_PERI_MCT_PCLK 0x205c 473 + #define CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK 0x2064 474 + #define CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK 0x209c 475 + #define CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK 0x20a0 476 + #define CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK 0x20a4 477 + #define CLK_CON_GAT_GOUT_PERI_UART_IPCLK 0x20a8 478 + #define CLK_CON_GAT_GOUT_PERI_UART_PCLK 0x20ac 479 + #define CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK 0x20b0 480 + #define CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK 0x20b4 481 + 482 + static const unsigned long peri_clk_regs[] __initconst = { 483 + PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, 484 + PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, 485 + PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 486 + PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 487 + CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0, 488 + CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, 489 + CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, 490 + CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 491 + CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0, 492 + CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1, 493 + CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2, 494 + CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK, 495 + CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK, 496 + CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK, 497 + CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK, 498 + CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK, 499 + CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK, 500 + CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK, 501 + CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK, 502 + CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK, 503 + CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK, 504 + CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK, 505 + CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK, 506 + CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK, 507 + CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK, 508 + CLK_CON_GAT_GOUT_PERI_MCT_PCLK, 509 + CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 510 + CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 511 + CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 512 + CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK, 513 + CLK_CON_GAT_GOUT_PERI_UART_IPCLK, 514 + CLK_CON_GAT_GOUT_PERI_UART_PCLK, 515 + CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK, 516 + CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK, 517 + }; 518 + 519 + /* List of parent clocks for Muxes in CMU_PERI */ 520 + PNAME(mout_peri_bus_user_p) = { "oscclk", "dout_peri_bus" }; 521 + PNAME(mout_peri_uart_user_p) = { "oscclk", "dout_peri_uart" }; 522 + PNAME(mout_peri_hsi2c_user_p) = { "oscclk", "dout_peri_ip" }; 523 + PNAME(mout_peri_spi_user_p) = { "oscclk", "dout_peri_ip" }; 524 + 525 + static const struct samsung_mux_clock peri_mux_clks[] __initconst = { 526 + MUX(CLK_MOUT_PERI_BUS_USER, "mout_peri_bus_user", mout_peri_bus_user_p, 527 + PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, 4, 1), 528 + MUX(CLK_MOUT_PERI_UART_USER, "mout_peri_uart_user", 529 + mout_peri_uart_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 4, 1), 530 + MUX(CLK_MOUT_PERI_HSI2C_USER, "mout_peri_hsi2c_user", 531 + mout_peri_hsi2c_user_p, PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, 4, 1), 532 + MUX(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user", mout_peri_spi_user_p, 533 + PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1), 534 + }; 535 + 536 + static const struct samsung_div_clock peri_div_clks[] __initconst = { 537 + DIV(CLK_DOUT_PERI_HSI2C0, "dout_peri_hsi2c0", "gout_peri_hsi2c0", 538 + CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0, 0, 5), 539 + DIV(CLK_DOUT_PERI_HSI2C1, "dout_peri_hsi2c1", "gout_peri_hsi2c1", 540 + CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, 0, 5), 541 + DIV(CLK_DOUT_PERI_HSI2C2, "dout_peri_hsi2c2", "gout_peri_hsi2c2", 542 + CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, 0, 5), 543 + DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user", 544 + CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5), 545 + }; 546 + 547 + static const struct samsung_gate_clock peri_gate_clks[] __initconst = { 548 + GATE(CLK_GOUT_PERI_HSI2C0, "gout_peri_hsi2c0", "mout_peri_hsi2c_user", 549 + CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0, 21, 0, 0), 550 + GATE(CLK_GOUT_PERI_HSI2C1, "gout_peri_hsi2c1", "mout_peri_hsi2c_user", 551 + CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1, 21, 0, 0), 552 + GATE(CLK_GOUT_PERI_HSI2C2, "gout_peri_hsi2c2", "mout_peri_hsi2c_user", 553 + CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2, 21, 0, 0), 554 + GATE(CLK_GOUT_HSI2C0_IPCLK, "gout_hsi2c0_ipclk", "dout_peri_hsi2c0", 555 + CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK, 21, 0, 0), 556 + GATE(CLK_GOUT_HSI2C0_PCLK, "gout_hsi2c0_pclk", "mout_peri_bus_user", 557 + CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK, 21, 0, 0), 558 + GATE(CLK_GOUT_HSI2C1_IPCLK, "gout_hsi2c1_ipclk", "dout_peri_hsi2c1", 559 + CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK, 21, 0, 0), 560 + GATE(CLK_GOUT_HSI2C1_PCLK, "gout_hsi2c1_pclk", "mout_peri_bus_user", 561 + CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK, 21, 0, 0), 562 + GATE(CLK_GOUT_HSI2C2_IPCLK, "gout_hsi2c2_ipclk", "dout_peri_hsi2c2", 563 + CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK, 21, 0, 0), 564 + GATE(CLK_GOUT_HSI2C2_PCLK, "gout_hsi2c2_pclk", "mout_peri_bus_user", 565 + CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK, 21, 0, 0), 566 + GATE(CLK_GOUT_I2C0_PCLK, "gout_i2c0_pclk", "mout_peri_bus_user", 567 + CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK, 21, 0, 0), 568 + GATE(CLK_GOUT_I2C1_PCLK, "gout_i2c1_pclk", "mout_peri_bus_user", 569 + CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK, 21, 0, 0), 570 + GATE(CLK_GOUT_I2C2_PCLK, "gout_i2c2_pclk", "mout_peri_bus_user", 571 + CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK, 21, 0, 0), 572 + GATE(CLK_GOUT_I2C3_PCLK, "gout_i2c3_pclk", "mout_peri_bus_user", 573 + CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK, 21, 0, 0), 574 + GATE(CLK_GOUT_I2C4_PCLK, "gout_i2c4_pclk", "mout_peri_bus_user", 575 + CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK, 21, 0, 0), 576 + GATE(CLK_GOUT_I2C5_PCLK, "gout_i2c5_pclk", "mout_peri_bus_user", 577 + CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK, 21, 0, 0), 578 + GATE(CLK_GOUT_I2C6_PCLK, "gout_i2c6_pclk", "mout_peri_bus_user", 579 + CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK, 21, 0, 0), 580 + GATE(CLK_GOUT_MCT_PCLK, "gout_mct_pclk", "mout_peri_bus_user", 581 + CLK_CON_GAT_GOUT_PERI_MCT_PCLK, 21, 0, 0), 582 + GATE(CLK_GOUT_PWM_MOTOR_PCLK, "gout_pwm_motor_pclk", 583 + "mout_peri_bus_user", 584 + CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0), 585 + GATE(CLK_GOUT_SPI0_IPCLK, "gout_spi0_ipclk", "dout_peri_spi0", 586 + CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, 0, 0), 587 + GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user", 588 + CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0), 589 + GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk", 590 + "mout_peri_bus_user", 591 + CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK, 21, 0, 0), 592 + GATE(CLK_GOUT_UART_IPCLK, "gout_uart_ipclk", "mout_peri_uart_user", 593 + CLK_CON_GAT_GOUT_PERI_UART_IPCLK, 21, 0, 0), 594 + GATE(CLK_GOUT_UART_PCLK, "gout_uart_pclk", "mout_peri_bus_user", 595 + CLK_CON_GAT_GOUT_PERI_UART_PCLK, 21, 0, 0), 596 + GATE(CLK_GOUT_WDT0_PCLK, "gout_wdt0_pclk", "mout_peri_bus_user", 597 + CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK, 21, 0, 0), 598 + GATE(CLK_GOUT_WDT1_PCLK, "gout_wdt1_pclk", "mout_peri_bus_user", 599 + CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK, 21, 0, 0), 600 + GATE(CLK_GOUT_GPIO_PERI_PCLK, "gout_gpio_peri_pclk", 601 + "mout_peri_bus_user", 602 + CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK, 21, 0, 0), 603 + }; 604 + 605 + static const struct samsung_cmu_info peri_cmu_info __initconst = { 606 + .mux_clks = peri_mux_clks, 607 + .nr_mux_clks = ARRAY_SIZE(peri_mux_clks), 608 + .div_clks = peri_div_clks, 609 + .nr_div_clks = ARRAY_SIZE(peri_div_clks), 610 + .gate_clks = peri_gate_clks, 611 + .nr_gate_clks = ARRAY_SIZE(peri_gate_clks), 612 + .nr_clk_ids = PERI_NR_CLK, 613 + .clk_regs = peri_clk_regs, 614 + .nr_clk_regs = ARRAY_SIZE(peri_clk_regs), 615 + .clk_name = "dout_peri_bus", 616 + }; 617 + 618 + /* ---- CMU_CORE ------------------------------------------------------------ */ 619 + 620 + /* Register Offset definitions for CMU_CORE (0x12000000) */ 621 + #define PLL_CON0_MUX_CLKCMU_CORE_BUS_USER 0x0600 622 + #define PLL_CON0_MUX_CLKCMU_CORE_CCI_USER 0x0610 623 + #define PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER 0x0620 624 + #define PLL_CON0_MUX_CLKCMU_CORE_SSS_USER 0x0630 625 + #define CLK_CON_MUX_MUX_CLK_CORE_GIC 0x1000 626 + #define CLK_CON_DIV_DIV_CLK_CORE_BUSP 0x1800 627 + #define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK 0x2038 628 + #define CLK_CON_GAT_GOUT_CORE_GIC_CLK 0x2040 629 + #define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK 0x20e8 630 + #define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN 0x20ec 631 + #define CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK 0x2128 632 + #define CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK 0x212c 633 + 634 + static const unsigned long core_clk_regs[] __initconst = { 635 + PLL_CON0_MUX_CLKCMU_CORE_BUS_USER, 636 + PLL_CON0_MUX_CLKCMU_CORE_CCI_USER, 637 + PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER, 638 + PLL_CON0_MUX_CLKCMU_CORE_SSS_USER, 639 + CLK_CON_MUX_MUX_CLK_CORE_GIC, 640 + CLK_CON_DIV_DIV_CLK_CORE_BUSP, 641 + CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 642 + CLK_CON_GAT_GOUT_CORE_GIC_CLK, 643 + CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK, 644 + CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN, 645 + CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK, 646 + CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK, 647 + }; 648 + 649 + /* List of parent clocks for Muxes in CMU_CORE */ 650 + PNAME(mout_core_bus_user_p) = { "oscclk", "dout_core_bus" }; 651 + PNAME(mout_core_cci_user_p) = { "oscclk", "dout_core_cci" }; 652 + PNAME(mout_core_mmc_embd_user_p) = { "oscclk", "dout_core_mmc_embd" }; 653 + PNAME(mout_core_sss_user_p) = { "oscclk", "dout_core_sss" }; 654 + PNAME(mout_core_gic_p) = { "dout_core_busp", "oscclk" }; 655 + 656 + static const struct samsung_mux_clock core_mux_clks[] __initconst = { 657 + MUX(CLK_MOUT_CORE_BUS_USER, "mout_core_bus_user", mout_core_bus_user_p, 658 + PLL_CON0_MUX_CLKCMU_CORE_BUS_USER, 4, 1), 659 + MUX(CLK_MOUT_CORE_CCI_USER, "mout_core_cci_user", mout_core_cci_user_p, 660 + PLL_CON0_MUX_CLKCMU_CORE_CCI_USER, 4, 1), 661 + MUX_F(CLK_MOUT_CORE_MMC_EMBD_USER, "mout_core_mmc_embd_user", 662 + mout_core_mmc_embd_user_p, PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER, 663 + 4, 1, CLK_SET_RATE_PARENT, 0), 664 + MUX(CLK_MOUT_CORE_SSS_USER, "mout_core_sss_user", mout_core_sss_user_p, 665 + PLL_CON0_MUX_CLKCMU_CORE_SSS_USER, 4, 1), 666 + MUX(CLK_MOUT_CORE_GIC, "mout_core_gic", mout_core_gic_p, 667 + CLK_CON_MUX_MUX_CLK_CORE_GIC, 0, 1), 668 + }; 669 + 670 + static const struct samsung_div_clock core_div_clks[] __initconst = { 671 + DIV(CLK_DOUT_CORE_BUSP, "dout_core_busp", "mout_core_bus_user", 672 + CLK_CON_DIV_DIV_CLK_CORE_BUSP, 0, 2), 673 + }; 674 + 675 + static const struct samsung_gate_clock core_gate_clks[] __initconst = { 676 + GATE(CLK_GOUT_CCI_ACLK, "gout_cci_aclk", "mout_core_cci_user", 677 + CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 21, 0, 0), 678 + GATE(CLK_GOUT_GIC_CLK, "gout_gic_clk", "mout_core_gic", 679 + CLK_CON_GAT_GOUT_CORE_GIC_CLK, 21, 0, 0), 680 + GATE(CLK_GOUT_MMC_EMBD_ACLK, "gout_mmc_embd_aclk", "dout_core_busp", 681 + CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK, 21, 0, 0), 682 + GATE(CLK_GOUT_MMC_EMBD_SDCLKIN, "gout_mmc_embd_sdclkin", 683 + "mout_core_mmc_embd_user", CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN, 684 + 21, CLK_SET_RATE_PARENT, 0), 685 + GATE(CLK_GOUT_SSS_ACLK, "gout_sss_aclk", "mout_core_sss_user", 686 + CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK, 21, 0, 0), 687 + GATE(CLK_GOUT_SSS_PCLK, "gout_sss_pclk", "dout_core_busp", 688 + CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK, 21, 0, 0), 689 + }; 690 + 691 + static const struct samsung_cmu_info core_cmu_info __initconst = { 692 + .mux_clks = core_mux_clks, 693 + .nr_mux_clks = ARRAY_SIZE(core_mux_clks), 694 + .div_clks = core_div_clks, 695 + .nr_div_clks = ARRAY_SIZE(core_div_clks), 696 + .gate_clks = core_gate_clks, 697 + .nr_gate_clks = ARRAY_SIZE(core_gate_clks), 698 + .nr_clk_ids = CORE_NR_CLK, 699 + .clk_regs = core_clk_regs, 700 + .nr_clk_regs = ARRAY_SIZE(core_clk_regs), 701 + .clk_name = "dout_core_bus", 702 + }; 703 + 704 + /* ---- CMU_DPU ------------------------------------------------------------- */ 705 + 706 + /* Register Offset definitions for CMU_DPU (0x13000000) */ 707 + #define PLL_CON0_MUX_CLKCMU_DPU_USER 0x0600 708 + #define CLK_CON_DIV_DIV_CLK_DPU_BUSP 0x1800 709 + #define CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK 0x2004 710 + #define CLK_CON_GAT_GOUT_DPU_ACLK_DECON0 0x2010 711 + #define CLK_CON_GAT_GOUT_DPU_ACLK_DMA 0x2014 712 + #define CLK_CON_GAT_GOUT_DPU_ACLK_DPP 0x2018 713 + #define CLK_CON_GAT_GOUT_DPU_PPMU_ACLK 0x2028 714 + #define CLK_CON_GAT_GOUT_DPU_PPMU_PCLK 0x202c 715 + #define CLK_CON_GAT_GOUT_DPU_SMMU_CLK 0x2038 716 + #define CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK 0x203c 717 + 718 + static const unsigned long dpu_clk_regs[] __initconst = { 719 + PLL_CON0_MUX_CLKCMU_DPU_USER, 720 + CLK_CON_DIV_DIV_CLK_DPU_BUSP, 721 + CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK, 722 + CLK_CON_GAT_GOUT_DPU_ACLK_DECON0, 723 + CLK_CON_GAT_GOUT_DPU_ACLK_DMA, 724 + CLK_CON_GAT_GOUT_DPU_ACLK_DPP, 725 + CLK_CON_GAT_GOUT_DPU_PPMU_ACLK, 726 + CLK_CON_GAT_GOUT_DPU_PPMU_PCLK, 727 + CLK_CON_GAT_GOUT_DPU_SMMU_CLK, 728 + CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK, 729 + }; 730 + 731 + /* List of parent clocks for Muxes in CMU_CORE */ 732 + PNAME(mout_dpu_user_p) = { "oscclk", "dout_dpu" }; 733 + 734 + static const struct samsung_mux_clock dpu_mux_clks[] __initconst = { 735 + MUX(CLK_MOUT_DPU_USER, "mout_dpu_user", mout_dpu_user_p, 736 + PLL_CON0_MUX_CLKCMU_DPU_USER, 4, 1), 737 + }; 738 + 739 + static const struct samsung_div_clock dpu_div_clks[] __initconst = { 740 + DIV(CLK_DOUT_DPU_BUSP, "dout_dpu_busp", "mout_dpu_user", 741 + CLK_CON_DIV_DIV_CLK_DPU_BUSP, 0, 3), 742 + }; 743 + 744 + static const struct samsung_gate_clock dpu_gate_clks[] __initconst = { 745 + GATE(CLK_GOUT_DPU_CMU_DPU_PCLK, "gout_dpu_cmu_dpu_pclk", 746 + "dout_dpu_busp", CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK, 21, 0, 0), 747 + GATE(CLK_GOUT_DPU_DECON0_ACLK, "gout_dpu_decon0_aclk", "mout_dpu_user", 748 + CLK_CON_GAT_GOUT_DPU_ACLK_DECON0, 21, 0, 0), 749 + GATE(CLK_GOUT_DPU_DMA_ACLK, "gout_dpu_dma_aclk", "mout_dpu_user", 750 + CLK_CON_GAT_GOUT_DPU_ACLK_DMA, 21, 0, 0), 751 + GATE(CLK_GOUT_DPU_DPP_ACLK, "gout_dpu_dpp_aclk", "mout_dpu_user", 752 + CLK_CON_GAT_GOUT_DPU_ACLK_DPP, 21, 0, 0), 753 + GATE(CLK_GOUT_DPU_PPMU_ACLK, "gout_dpu_ppmu_aclk", "mout_dpu_user", 754 + CLK_CON_GAT_GOUT_DPU_PPMU_ACLK, 21, 0, 0), 755 + GATE(CLK_GOUT_DPU_PPMU_PCLK, "gout_dpu_ppmu_pclk", "dout_dpu_busp", 756 + CLK_CON_GAT_GOUT_DPU_PPMU_PCLK, 21, 0, 0), 757 + GATE(CLK_GOUT_DPU_SMMU_CLK, "gout_dpu_smmu_clk", "mout_dpu_user", 758 + CLK_CON_GAT_GOUT_DPU_SMMU_CLK, 21, 0, 0), 759 + GATE(CLK_GOUT_DPU_SYSREG_PCLK, "gout_dpu_sysreg_pclk", "dout_dpu_busp", 760 + CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK, 21, 0, 0), 761 + }; 762 + 763 + static const struct samsung_cmu_info dpu_cmu_info __initconst = { 764 + .mux_clks = dpu_mux_clks, 765 + .nr_mux_clks = ARRAY_SIZE(dpu_mux_clks), 766 + .div_clks = dpu_div_clks, 767 + .nr_div_clks = ARRAY_SIZE(dpu_div_clks), 768 + .gate_clks = dpu_gate_clks, 769 + .nr_gate_clks = ARRAY_SIZE(dpu_gate_clks), 770 + .nr_clk_ids = DPU_NR_CLK, 771 + .clk_regs = dpu_clk_regs, 772 + .nr_clk_regs = ARRAY_SIZE(dpu_clk_regs), 773 + .clk_name = "dout_dpu", 774 + }; 775 + 776 + /* ---- platform_driver ----------------------------------------------------- */ 777 + 778 + static int __init exynos850_cmu_probe(struct platform_device *pdev) 779 + { 780 + const struct samsung_cmu_info *info; 781 + struct device *dev = &pdev->dev; 782 + struct device_node *np = dev->of_node; 783 + 784 + info = of_device_get_match_data(dev); 785 + exynos850_init_clocks(np, info->clk_regs, info->nr_clk_regs); 786 + samsung_cmu_register_one(np, info); 787 + 788 + /* Keep bus clock running, so it's possible to access CMU registers */ 789 + if (info->clk_name) { 790 + struct clk *bus_clk; 791 + 792 + bus_clk = clk_get(dev, info->clk_name); 793 + if (IS_ERR(bus_clk)) { 794 + pr_err("%s: could not find bus clock %s; err = %ld\n", 795 + __func__, info->clk_name, PTR_ERR(bus_clk)); 796 + } else { 797 + clk_prepare_enable(bus_clk); 798 + } 799 + } 800 + 801 + return 0; 802 + } 803 + 804 + /* CMUs which belong to Power Domains and need runtime PM to be implemented */ 805 + static const struct of_device_id exynos850_cmu_of_match[] = { 806 + { 807 + .compatible = "samsung,exynos850-cmu-hsi", 808 + .data = &hsi_cmu_info, 809 + }, { 810 + .compatible = "samsung,exynos850-cmu-peri", 811 + .data = &peri_cmu_info, 812 + }, { 813 + .compatible = "samsung,exynos850-cmu-core", 814 + .data = &core_cmu_info, 815 + }, { 816 + .compatible = "samsung,exynos850-cmu-dpu", 817 + .data = &dpu_cmu_info, 818 + }, { 819 + }, 820 + }; 821 + 822 + static struct platform_driver exynos850_cmu_driver __refdata = { 823 + .driver = { 824 + .name = "exynos850-cmu", 825 + .of_match_table = exynos850_cmu_of_match, 826 + .suppress_bind_attrs = true, 827 + }, 828 + .probe = exynos850_cmu_probe, 829 + }; 830 + 831 + static int __init exynos850_cmu_init(void) 832 + { 833 + return platform_driver_register(&exynos850_cmu_driver); 834 + } 835 + core_initcall(exynos850_cmu_init);
+196
drivers/clk/samsung/clk-pll.c
··· 416 416 }; 417 417 418 418 /* 419 + * PLL0822x Clock Type 420 + */ 421 + /* Maximum lock time can be 150 * PDIV cycles */ 422 + #define PLL0822X_LOCK_FACTOR (150) 423 + 424 + #define PLL0822X_MDIV_MASK (0x3FF) 425 + #define PLL0822X_PDIV_MASK (0x3F) 426 + #define PLL0822X_SDIV_MASK (0x7) 427 + #define PLL0822X_MDIV_SHIFT (16) 428 + #define PLL0822X_PDIV_SHIFT (8) 429 + #define PLL0822X_SDIV_SHIFT (0) 430 + #define PLL0822X_LOCK_STAT_SHIFT (29) 431 + #define PLL0822X_ENABLE_SHIFT (31) 432 + 433 + static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw, 434 + unsigned long parent_rate) 435 + { 436 + struct samsung_clk_pll *pll = to_clk_pll(hw); 437 + u32 mdiv, pdiv, sdiv, pll_con3; 438 + u64 fvco = parent_rate; 439 + 440 + pll_con3 = readl_relaxed(pll->con_reg); 441 + mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK; 442 + pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK; 443 + sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK; 444 + 445 + fvco *= mdiv; 446 + do_div(fvco, (pdiv << sdiv)); 447 + 448 + return (unsigned long)fvco; 449 + } 450 + 451 + static int samsung_pll0822x_set_rate(struct clk_hw *hw, unsigned long drate, 452 + unsigned long prate) 453 + { 454 + const struct samsung_pll_rate_table *rate; 455 + struct samsung_clk_pll *pll = to_clk_pll(hw); 456 + u32 pll_con3; 457 + 458 + /* Get required rate settings from table */ 459 + rate = samsung_get_pll_settings(pll, drate); 460 + if (!rate) { 461 + pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 462 + drate, clk_hw_get_name(hw)); 463 + return -EINVAL; 464 + } 465 + 466 + /* Change PLL PMS values */ 467 + pll_con3 = readl_relaxed(pll->con_reg); 468 + pll_con3 &= ~((PLL0822X_MDIV_MASK << PLL0822X_MDIV_SHIFT) | 469 + (PLL0822X_PDIV_MASK << PLL0822X_PDIV_SHIFT) | 470 + (PLL0822X_SDIV_MASK << PLL0822X_SDIV_SHIFT)); 471 + pll_con3 |= (rate->mdiv << PLL0822X_MDIV_SHIFT) | 472 + (rate->pdiv << PLL0822X_PDIV_SHIFT) | 473 + (rate->sdiv << PLL0822X_SDIV_SHIFT); 474 + 475 + /* Set PLL lock time */ 476 + writel_relaxed(rate->pdiv * PLL0822X_LOCK_FACTOR, 477 + pll->lock_reg); 478 + 479 + /* Write PMS values */ 480 + writel_relaxed(pll_con3, pll->con_reg); 481 + 482 + /* Wait for PLL lock if the PLL is enabled */ 483 + if (pll_con3 & BIT(pll->enable_offs)) 484 + return samsung_pll_lock_wait(pll, BIT(pll->lock_offs)); 485 + 486 + return 0; 487 + } 488 + 489 + static const struct clk_ops samsung_pll0822x_clk_ops = { 490 + .recalc_rate = samsung_pll0822x_recalc_rate, 491 + .round_rate = samsung_pll_round_rate, 492 + .set_rate = samsung_pll0822x_set_rate, 493 + .enable = samsung_pll3xxx_enable, 494 + .disable = samsung_pll3xxx_disable, 495 + }; 496 + 497 + static const struct clk_ops samsung_pll0822x_clk_min_ops = { 498 + .recalc_rate = samsung_pll0822x_recalc_rate, 499 + }; 500 + 501 + /* 502 + * PLL0831x Clock Type 503 + */ 504 + /* Maximum lock time can be 500 * PDIV cycles */ 505 + #define PLL0831X_LOCK_FACTOR (500) 506 + 507 + #define PLL0831X_KDIV_MASK (0xFFFF) 508 + #define PLL0831X_MDIV_MASK (0x1FF) 509 + #define PLL0831X_PDIV_MASK (0x3F) 510 + #define PLL0831X_SDIV_MASK (0x7) 511 + #define PLL0831X_MDIV_SHIFT (16) 512 + #define PLL0831X_PDIV_SHIFT (8) 513 + #define PLL0831X_SDIV_SHIFT (0) 514 + #define PLL0831X_KDIV_SHIFT (0) 515 + #define PLL0831X_LOCK_STAT_SHIFT (29) 516 + #define PLL0831X_ENABLE_SHIFT (31) 517 + 518 + static unsigned long samsung_pll0831x_recalc_rate(struct clk_hw *hw, 519 + unsigned long parent_rate) 520 + { 521 + struct samsung_clk_pll *pll = to_clk_pll(hw); 522 + u32 mdiv, pdiv, sdiv, pll_con3, pll_con5; 523 + s16 kdiv; 524 + u64 fvco = parent_rate; 525 + 526 + pll_con3 = readl_relaxed(pll->con_reg); 527 + pll_con5 = readl_relaxed(pll->con_reg + 8); 528 + mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK; 529 + pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK; 530 + sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK; 531 + kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) & PLL0831X_KDIV_MASK); 532 + 533 + fvco *= (mdiv << 16) + kdiv; 534 + do_div(fvco, (pdiv << sdiv)); 535 + fvco >>= 16; 536 + 537 + return (unsigned long)fvco; 538 + } 539 + 540 + static int samsung_pll0831x_set_rate(struct clk_hw *hw, unsigned long drate, 541 + unsigned long parent_rate) 542 + { 543 + const struct samsung_pll_rate_table *rate; 544 + struct samsung_clk_pll *pll = to_clk_pll(hw); 545 + u32 pll_con3, pll_con5; 546 + 547 + /* Get required rate settings from table */ 548 + rate = samsung_get_pll_settings(pll, drate); 549 + if (!rate) { 550 + pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 551 + drate, clk_hw_get_name(hw)); 552 + return -EINVAL; 553 + } 554 + 555 + pll_con3 = readl_relaxed(pll->con_reg); 556 + pll_con5 = readl_relaxed(pll->con_reg + 8); 557 + 558 + /* Change PLL PMSK values */ 559 + pll_con3 &= ~((PLL0831X_MDIV_MASK << PLL0831X_MDIV_SHIFT) | 560 + (PLL0831X_PDIV_MASK << PLL0831X_PDIV_SHIFT) | 561 + (PLL0831X_SDIV_MASK << PLL0831X_SDIV_SHIFT)); 562 + pll_con3 |= (rate->mdiv << PLL0831X_MDIV_SHIFT) | 563 + (rate->pdiv << PLL0831X_PDIV_SHIFT) | 564 + (rate->sdiv << PLL0831X_SDIV_SHIFT); 565 + pll_con5 &= ~(PLL0831X_KDIV_MASK << PLL0831X_KDIV_SHIFT); 566 + /* 567 + * kdiv is 16-bit 2's complement (s16), but stored as unsigned int. 568 + * Cast it to u16 to avoid leading 0xffff's in case of negative value. 569 + */ 570 + pll_con5 |= ((u16)rate->kdiv << PLL0831X_KDIV_SHIFT); 571 + 572 + /* Set PLL lock time */ 573 + writel_relaxed(rate->pdiv * PLL0831X_LOCK_FACTOR, pll->lock_reg); 574 + 575 + /* Write PMSK values */ 576 + writel_relaxed(pll_con3, pll->con_reg); 577 + writel_relaxed(pll_con5, pll->con_reg + 8); 578 + 579 + /* Wait for PLL lock if the PLL is enabled */ 580 + if (pll_con3 & BIT(pll->enable_offs)) 581 + return samsung_pll_lock_wait(pll, BIT(pll->lock_offs)); 582 + 583 + return 0; 584 + } 585 + 586 + static const struct clk_ops samsung_pll0831x_clk_ops = { 587 + .recalc_rate = samsung_pll0831x_recalc_rate, 588 + .set_rate = samsung_pll0831x_set_rate, 589 + .round_rate = samsung_pll_round_rate, 590 + .enable = samsung_pll3xxx_enable, 591 + .disable = samsung_pll3xxx_disable, 592 + }; 593 + 594 + static const struct clk_ops samsung_pll0831x_clk_min_ops = { 595 + .recalc_rate = samsung_pll0831x_recalc_rate, 596 + }; 597 + 598 + /* 419 599 * PLL45xx Clock Type 420 600 */ 421 601 #define PLL4502_LOCK_FACTOR 400 ··· 1476 1296 else 1477 1297 init.ops = &samsung_pll35xx_clk_ops; 1478 1298 break; 1299 + case pll_0822x: 1300 + pll->enable_offs = PLL0822X_ENABLE_SHIFT; 1301 + pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT; 1302 + if (!pll->rate_table) 1303 + init.ops = &samsung_pll0822x_clk_min_ops; 1304 + else 1305 + init.ops = &samsung_pll0822x_clk_ops; 1306 + break; 1479 1307 case pll_4500: 1480 1308 init.ops = &samsung_pll45xx_clk_min_ops; 1481 1309 break; ··· 1503 1315 init.ops = &samsung_pll36xx_clk_min_ops; 1504 1316 else 1505 1317 init.ops = &samsung_pll36xx_clk_ops; 1318 + break; 1319 + case pll_0831x: 1320 + pll->enable_offs = PLL0831X_ENABLE_SHIFT; 1321 + pll->lock_offs = PLL0831X_LOCK_STAT_SHIFT; 1322 + if (!pll->rate_table) 1323 + init.ops = &samsung_pll0831x_clk_min_ops; 1324 + else 1325 + init.ops = &samsung_pll0831x_clk_ops; 1506 1326 break; 1507 1327 case pll_6552: 1508 1328 case pll_6552_s3c2416:
+2
drivers/clk/samsung/clk-pll.h
··· 36 36 pll_1451x, 37 37 pll_1452x, 38 38 pll_1460x, 39 + pll_0822x, 40 + pll_0831x, 39 41 }; 40 42 41 43 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
+1 -3
drivers/clk/samsung/clk-s5pv210-audss.c
··· 63 63 static int s5pv210_audss_clk_probe(struct platform_device *pdev) 64 64 { 65 65 int i, ret = 0; 66 - struct resource *res; 67 66 const char *mout_audss_p[2]; 68 67 const char *mout_i2s_p[3]; 69 68 const char *hclk_p; 70 69 struct clk_hw **clk_table; 71 70 struct clk *hclk, *pll_ref, *pll_in, *cdclk, *sclk_audio; 72 71 73 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 74 - reg_base = devm_ioremap_resource(&pdev->dev, res); 72 + reg_base = devm_platform_ioremap_resource(pdev, 0); 75 73 if (IS_ERR(reg_base)) 76 74 return PTR_ERR(reg_base); 77 75
+2
drivers/clk/samsung/clk.c
··· 378 378 samsung_clk_extended_sleep_init(reg_base, 379 379 cmu->clk_regs, cmu->nr_clk_regs, 380 380 cmu->suspend_regs, cmu->nr_suspend_regs); 381 + if (cmu->cpu_clks) 382 + samsung_clk_register_cpu(ctx, cmu->cpu_clks, cmu->nr_cpu_clks); 381 383 382 384 samsung_clk_of_add_provider(np, ctx); 383 385
+26
drivers/clk/samsung/clk.h
··· 271 271 __PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock, \ 272 272 _con, _rtable) 273 273 274 + struct samsung_cpu_clock { 275 + unsigned int id; 276 + const char *name; 277 + unsigned int parent_id; 278 + unsigned int alt_parent_id; 279 + unsigned long flags; 280 + int offset; 281 + const struct exynos_cpuclk_cfg_data *cfg; 282 + }; 283 + 284 + #define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _cfg) \ 285 + { \ 286 + .id = _id, \ 287 + .name = _name, \ 288 + .parent_id = _pid, \ 289 + .alt_parent_id = _apid, \ 290 + .flags = _flags, \ 291 + .offset = _offset, \ 292 + .cfg = _cfg, \ 293 + } 294 + 274 295 struct samsung_clock_reg_cache { 275 296 struct list_head node; 276 297 void __iomem *reg_base; ··· 322 301 unsigned int nr_fixed_factor_clks; 323 302 /* total number of clocks with IDs assigned*/ 324 303 unsigned int nr_clk_ids; 304 + /* list of cpu clocks and respective count */ 305 + const struct samsung_cpu_clock *cpu_clks; 306 + unsigned int nr_cpu_clks; 325 307 326 308 /* list and number of clocks registers */ 327 309 const unsigned long *clk_regs; ··· 374 350 extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, 375 351 const struct samsung_pll_clock *pll_list, 376 352 unsigned int nr_clk, void __iomem *base); 353 + extern void samsung_clk_register_cpu(struct samsung_clk_provider *ctx, 354 + const struct samsung_cpu_clock *list, unsigned int nr_clk); 377 355 378 356 extern struct samsung_clk_provider __init *samsung_cmu_register_one( 379 357 struct device_node *,
+1
drivers/clk/sunxi-ng/Kconfig
··· 71 71 config SUN8I_A83T_CCU 72 72 bool "Support for the Allwinner A83T CCU" 73 73 default MACH_SUN8I 74 + depends on MACH_SUN8I || COMPILE_TEST 74 75 75 76 config SUN8I_H3_CCU 76 77 bool "Support for the Allwinner H3 CCU"
+1 -1
drivers/clk/sunxi-ng/ccu-sun4i-a10.c
··· 1464 1464 val &= ~GENMASK(7, 6); 1465 1465 writel(val | (2 << 6), reg + SUN4I_AHB_REG); 1466 1466 1467 - sunxi_ccu_probe(node, reg, desc); 1467 + of_sunxi_ccu_probe(node, reg, desc); 1468 1468 } 1469 1469 1470 1470 static void __init sun4i_a10_ccu_setup(struct device_node *node)
+2 -1
drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c
··· 196 196 if (IS_ERR(reg)) 197 197 return PTR_ERR(reg); 198 198 199 - return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_r_ccu_desc); 199 + return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a100_r_ccu_desc); 200 200 } 201 201 202 202 static const struct of_device_id sun50i_a100_r_ccu_ids[] = { ··· 208 208 .probe = sun50i_a100_r_ccu_probe, 209 209 .driver = { 210 210 .name = "sun50i-a100-r-ccu", 211 + .suppress_bind_attrs = true, 211 212 .of_match_table = sun50i_a100_r_ccu_ids, 212 213 }, 213 214 };
+2 -1
drivers/clk/sunxi-ng/ccu-sun50i-a100.c
··· 1247 1247 writel(val, reg + sun50i_a100_usb2_clk_regs[i]); 1248 1248 } 1249 1249 1250 - ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_ccu_desc); 1250 + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a100_ccu_desc); 1251 1251 if (ret) 1252 1252 return ret; 1253 1253 ··· 1270 1270 .probe = sun50i_a100_ccu_probe, 1271 1271 .driver = { 1272 1272 .name = "sun50i-a100-ccu", 1273 + .suppress_bind_attrs = true, 1273 1274 .of_match_table = sun50i_a100_ccu_ids, 1274 1275 }, 1275 1276 };
+3 -4
drivers/clk/sunxi-ng/ccu-sun50i-a64.c
··· 938 938 939 939 static int sun50i_a64_ccu_probe(struct platform_device *pdev) 940 940 { 941 - struct resource *res; 942 941 void __iomem *reg; 943 942 u32 val; 944 943 int ret; 945 944 946 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 947 - reg = devm_ioremap_resource(&pdev->dev, res); 945 + reg = devm_platform_ioremap_resource(pdev, 0); 948 946 if (IS_ERR(reg)) 949 947 return PTR_ERR(reg); 950 948 ··· 953 955 954 956 writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG); 955 957 956 - ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc); 958 + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a64_ccu_desc); 957 959 if (ret) 958 960 return ret; 959 961 ··· 976 978 .probe = sun50i_a64_ccu_probe, 977 979 .driver = { 978 980 .name = "sun50i-a64-ccu", 981 + .suppress_bind_attrs = true, 979 982 .of_match_table = sun50i_a64_ccu_ids, 980 983 }, 981 984 };
+1 -1
drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
··· 232 232 return; 233 233 } 234 234 235 - sunxi_ccu_probe(node, reg, desc); 235 + of_sunxi_ccu_probe(node, reg, desc); 236 236 } 237 237 238 238 static void __init sun50i_h6_r_ccu_setup(struct device_node *node)
+3 -4
drivers/clk/sunxi-ng/ccu-sun50i-h6.c
··· 1183 1183 1184 1184 static int sun50i_h6_ccu_probe(struct platform_device *pdev) 1185 1185 { 1186 - struct resource *res; 1187 1186 void __iomem *reg; 1188 1187 u32 val; 1189 1188 int i; 1190 1189 1191 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1192 - reg = devm_ioremap_resource(&pdev->dev, res); 1190 + reg = devm_platform_ioremap_resource(pdev, 0); 1193 1191 if (IS_ERR(reg)) 1194 1192 return PTR_ERR(reg); 1195 1193 ··· 1238 1240 val |= BIT(24); 1239 1241 writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG); 1240 1242 1241 - return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc); 1243 + return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc); 1242 1244 } 1243 1245 1244 1246 static const struct of_device_id sun50i_h6_ccu_ids[] = { ··· 1250 1252 .probe = sun50i_h6_ccu_probe, 1251 1253 .driver = { 1252 1254 .name = "sun50i-h6-ccu", 1255 + .suppress_bind_attrs = true, 1253 1256 .of_match_table = sun50i_h6_ccu_ids, 1254 1257 }, 1255 1258 };
+1 -3
drivers/clk/sunxi-ng/ccu-sun50i-h616.c
··· 1141 1141 val |= BIT(24); 1142 1142 writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG); 1143 1143 1144 - i = sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc); 1145 - if (i) 1146 - pr_err("%pOF: probing clocks fails: %d\n", node, i); 1144 + of_sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc); 1147 1145 } 1148 1146 1149 1147 CLK_OF_DECLARE(sun50i_h616_ccu, "allwinner,sun50i-h616-ccu",
+1 -1
drivers/clk/sunxi-ng/ccu-sun5i.c
··· 1012 1012 val &= ~GENMASK(7, 6); 1013 1013 writel(val | (2 << 6), reg + SUN5I_AHB_REG); 1014 1014 1015 - sunxi_ccu_probe(node, reg, desc); 1015 + of_sunxi_ccu_probe(node, reg, desc); 1016 1016 } 1017 1017 1018 1018 static void __init sun5i_a10s_ccu_setup(struct device_node *node)
+1 -1
drivers/clk/sunxi-ng/ccu-sun6i-a31.c
··· 1257 1257 val |= 0x3 << 12; 1258 1258 writel(val, reg + SUN6I_A31_AHB1_REG); 1259 1259 1260 - sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc); 1260 + of_sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc); 1261 1261 1262 1262 ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk, 1263 1263 &sun6i_a31_cpu_nb);
+1 -1
drivers/clk/sunxi-ng/ccu-sun8i-a23.c
··· 745 745 val &= ~BIT(16); 746 746 writel(val, reg + SUN8I_A23_PLL_MIPI_REG); 747 747 748 - sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc); 748 + of_sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc); 749 749 } 750 750 CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu", 751 751 sun8i_a23_ccu_setup);
+1 -1
drivers/clk/sunxi-ng/ccu-sun8i-a33.c
··· 805 805 val &= ~BIT(16); 806 806 writel(val, reg + SUN8I_A33_PLL_MIPI_REG); 807 807 808 - sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc); 808 + of_sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc); 809 809 810 810 /* Gate then ungate PLL CPU after any rate changes */ 811 811 ccu_pll_notifier_register(&sun8i_a33_pll_cpu_nb);
+3 -4
drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
··· 887 887 888 888 static int sun8i_a83t_ccu_probe(struct platform_device *pdev) 889 889 { 890 - struct resource *res; 891 890 void __iomem *reg; 892 891 u32 val; 893 892 894 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 895 - reg = devm_ioremap_resource(&pdev->dev, res); 893 + reg = devm_platform_ioremap_resource(pdev, 0); 896 894 if (IS_ERR(reg)) 897 895 return PTR_ERR(reg); 898 896 ··· 904 906 sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C0CPUX_REG); 905 907 sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C1CPUX_REG); 906 908 907 - return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_a83t_ccu_desc); 909 + return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a83t_ccu_desc); 908 910 } 909 911 910 912 static const struct of_device_id sun8i_a83t_ccu_ids[] = { ··· 916 918 .probe = sun8i_a83t_ccu_probe, 917 919 .driver = { 918 920 .name = "sun8i-a83t-ccu", 921 + .suppress_bind_attrs = true, 919 922 .of_match_table = sun8i_a83t_ccu_ids, 920 923 }, 921 924 };
+2 -4
drivers/clk/sunxi-ng/ccu-sun8i-de2.c
··· 280 280 281 281 static int sunxi_de2_clk_probe(struct platform_device *pdev) 282 282 { 283 - struct resource *res; 284 283 struct clk *bus_clk, *mod_clk; 285 284 struct reset_control *rstc; 286 285 void __iomem *reg; ··· 290 291 if (!ccu_desc) 291 292 return -EINVAL; 292 293 293 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 294 - reg = devm_ioremap_resource(&pdev->dev, res); 294 + reg = devm_platform_ioremap_resource(pdev, 0); 295 295 if (IS_ERR(reg)) 296 296 return PTR_ERR(reg); 297 297 ··· 340 342 goto err_disable_mod_clk; 341 343 } 342 344 343 - ret = sunxi_ccu_probe(pdev->dev.of_node, reg, ccu_desc); 345 + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, ccu_desc); 344 346 if (ret) 345 347 goto err_assert_reset; 346 348
+1 -1
drivers/clk/sunxi-ng/ccu-sun8i-h3.c
··· 1154 1154 val &= ~GENMASK(19, 16); 1155 1155 writel(val | (0 << 16), reg + SUN8I_H3_PLL_AUDIO_REG); 1156 1156 1157 - sunxi_ccu_probe(node, reg, desc); 1157 + of_sunxi_ccu_probe(node, reg, desc); 1158 1158 1159 1159 /* Gate then ungate PLL CPU after any rate changes */ 1160 1160 ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb);
+1 -1
drivers/clk/sunxi-ng/ccu-sun8i-r.c
··· 265 265 return; 266 266 } 267 267 268 - sunxi_ccu_probe(node, reg, desc); 268 + of_sunxi_ccu_probe(node, reg, desc); 269 269 } 270 270 271 271 static void __init sun8i_a83t_r_ccu_setup(struct device_node *node)
+3 -4
drivers/clk/sunxi-ng/ccu-sun8i-r40.c
··· 1307 1307 1308 1308 static int sun8i_r40_ccu_probe(struct platform_device *pdev) 1309 1309 { 1310 - struct resource *res; 1311 1310 struct regmap *regmap; 1312 1311 void __iomem *reg; 1313 1312 u32 val; 1314 1313 int ret; 1315 1314 1316 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1317 - reg = devm_ioremap_resource(&pdev->dev, res); 1315 + reg = devm_platform_ioremap_resource(pdev, 0); 1318 1316 if (IS_ERR(reg)) 1319 1317 return PTR_ERR(reg); 1320 1318 ··· 1344 1346 if (IS_ERR(regmap)) 1345 1347 return PTR_ERR(regmap); 1346 1348 1347 - ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_r40_ccu_desc); 1349 + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_r40_ccu_desc); 1348 1350 if (ret) 1349 1351 return ret; 1350 1352 ··· 1367 1369 .probe = sun8i_r40_ccu_probe, 1368 1370 .driver = { 1369 1371 .name = "sun8i-r40-ccu", 1372 + .suppress_bind_attrs = true, 1370 1373 .of_match_table = sun8i_r40_ccu_ids, 1371 1374 }, 1372 1375 };
+1 -1
drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
··· 822 822 val &= ~GENMASK(19, 16); 823 823 writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG); 824 824 825 - sunxi_ccu_probe(node, reg, ccu_desc); 825 + of_sunxi_ccu_probe(node, reg, ccu_desc); 826 826 } 827 827 828 828 static void __init sun8i_v3s_ccu_setup(struct device_node *node)
+3 -5
drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
··· 203 203 204 204 static int sun9i_a80_de_clk_probe(struct platform_device *pdev) 205 205 { 206 - struct resource *res; 207 206 struct clk *bus_clk; 208 207 struct reset_control *rstc; 209 208 void __iomem *reg; 210 209 int ret; 211 210 212 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 213 - reg = devm_ioremap_resource(&pdev->dev, res); 211 + reg = devm_platform_ioremap_resource(pdev, 0); 214 212 if (IS_ERR(reg)) 215 213 return PTR_ERR(reg); 216 214 ··· 244 246 goto err_disable_clk; 245 247 } 246 248 247 - ret = sunxi_ccu_probe(pdev->dev.of_node, reg, 248 - &sun9i_a80_de_clk_desc); 249 + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_de_clk_desc); 249 250 if (ret) 250 251 goto err_assert_reset; 251 252 ··· 266 269 .probe = sun9i_a80_de_clk_probe, 267 270 .driver = { 268 271 .name = "sun9i-a80-de-clks", 272 + .suppress_bind_attrs = true, 269 273 .of_match_table = sun9i_a80_de_clk_ids, 270 274 }, 271 275 };
+2 -5
drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c
··· 92 92 93 93 static int sun9i_a80_usb_clk_probe(struct platform_device *pdev) 94 94 { 95 - struct resource *res; 96 95 struct clk *bus_clk; 97 96 void __iomem *reg; 98 97 int ret; 99 98 100 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 101 - reg = devm_ioremap_resource(&pdev->dev, res); 99 + reg = devm_platform_ioremap_resource(pdev, 0); 102 100 if (IS_ERR(reg)) 103 101 return PTR_ERR(reg); 104 102 ··· 115 117 return ret; 116 118 } 117 119 118 - ret = sunxi_ccu_probe(pdev->dev.of_node, reg, 119 - &sun9i_a80_usb_clk_desc); 120 + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_usb_clk_desc); 120 121 if (ret) 121 122 goto err_disable_clk; 122 123
+3 -4
drivers/clk/sunxi-ng/ccu-sun9i-a80.c
··· 1213 1213 1214 1214 static int sun9i_a80_ccu_probe(struct platform_device *pdev) 1215 1215 { 1216 - struct resource *res; 1217 1216 void __iomem *reg; 1218 1217 u32 val; 1219 1218 1220 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1221 - reg = devm_ioremap_resource(&pdev->dev, res); 1219 + reg = devm_platform_ioremap_resource(pdev, 0); 1222 1220 if (IS_ERR(reg)) 1223 1221 return PTR_ERR(reg); 1224 1222 ··· 1229 1231 sun9i_a80_cpu_pll_fixup(reg + SUN9I_A80_PLL_C0CPUX_REG); 1230 1232 sun9i_a80_cpu_pll_fixup(reg + SUN9I_A80_PLL_C1CPUX_REG); 1231 1233 1232 - return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun9i_a80_ccu_desc); 1234 + return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_ccu_desc); 1233 1235 } 1234 1236 1235 1237 static const struct of_device_id sun9i_a80_ccu_ids[] = { ··· 1241 1243 .probe = sun9i_a80_ccu_probe, 1242 1244 .driver = { 1243 1245 .name = "sun9i-a80-ccu", 1246 + .suppress_bind_attrs = true, 1244 1247 .of_match_table = sun9i_a80_ccu_ids, 1245 1248 }, 1246 1249 };
+1 -1
drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
··· 538 538 val &= ~GENMASK(19, 16); 539 539 writel(val | (3 << 16), reg + SUNIV_PLL_AUDIO_REG); 540 540 541 - sunxi_ccu_probe(node, reg, &suniv_ccu_desc); 541 + of_sunxi_ccu_probe(node, reg, &suniv_ccu_desc); 542 542 543 543 /* Gate then ungate PLL CPU after any rate changes */ 544 544 ccu_pll_notifier_register(&suniv_pll_cpu_nb);
+79 -17
drivers/clk/sunxi-ng/ccu_common.c
··· 7 7 8 8 #include <linux/clk.h> 9 9 #include <linux/clk-provider.h> 10 + #include <linux/device.h> 10 11 #include <linux/iopoll.h> 11 12 #include <linux/slab.h> 12 13 ··· 15 14 #include "ccu_gate.h" 16 15 #include "ccu_reset.h" 17 16 18 - static DEFINE_SPINLOCK(ccu_lock); 17 + struct sunxi_ccu { 18 + const struct sunxi_ccu_desc *desc; 19 + spinlock_t lock; 20 + struct ccu_reset reset; 21 + }; 19 22 20 23 void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock) 21 24 { ··· 84 79 &pll_nb->clk_nb); 85 80 } 86 81 87 - int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, 88 - const struct sunxi_ccu_desc *desc) 82 + static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, 83 + struct device_node *node, void __iomem *reg, 84 + const struct sunxi_ccu_desc *desc) 89 85 { 90 86 struct ccu_reset *reset; 91 87 int i, ret; 88 + 89 + ccu->desc = desc; 90 + 91 + spin_lock_init(&ccu->lock); 92 92 93 93 for (i = 0; i < desc->num_ccu_clks; i++) { 94 94 struct ccu_common *cclk = desc->ccu_clks[i]; ··· 102 92 continue; 103 93 104 94 cclk->base = reg; 105 - cclk->lock = &ccu_lock; 95 + cclk->lock = &ccu->lock; 106 96 } 107 97 108 98 for (i = 0; i < desc->hw_clks->num ; i++) { ··· 113 103 continue; 114 104 115 105 name = hw->init->name; 116 - ret = of_clk_hw_register(node, hw); 106 + if (dev) 107 + ret = clk_hw_register(dev, hw); 108 + else 109 + ret = of_clk_hw_register(node, hw); 117 110 if (ret) { 118 111 pr_err("Couldn't register clock %d - %s\n", i, name); 119 112 goto err_clk_unreg; ··· 128 115 if (ret) 129 116 goto err_clk_unreg; 130 117 131 - reset = kzalloc(sizeof(*reset), GFP_KERNEL); 132 - if (!reset) { 133 - ret = -ENOMEM; 134 - goto err_alloc_reset; 135 - } 136 - 118 + reset = &ccu->reset; 137 119 reset->rcdev.of_node = node; 138 120 reset->rcdev.ops = &ccu_reset_ops; 139 - reset->rcdev.owner = THIS_MODULE; 121 + reset->rcdev.owner = dev ? dev->driver->owner : THIS_MODULE; 140 122 reset->rcdev.nr_resets = desc->num_resets; 141 123 reset->base = reg; 142 - reset->lock = &ccu_lock; 124 + reset->lock = &ccu->lock; 143 125 reset->reset_map = desc->resets; 144 126 145 127 ret = reset_controller_register(&reset->rcdev); 146 128 if (ret) 147 - goto err_of_clk_unreg; 129 + goto err_del_provider; 148 130 149 131 return 0; 150 132 151 - err_of_clk_unreg: 152 - kfree(reset); 153 - err_alloc_reset: 133 + err_del_provider: 154 134 of_clk_del_provider(node); 155 135 err_clk_unreg: 156 136 while (--i >= 0) { ··· 154 148 clk_hw_unregister(hw); 155 149 } 156 150 return ret; 151 + } 152 + 153 + static void devm_sunxi_ccu_release(struct device *dev, void *res) 154 + { 155 + struct sunxi_ccu *ccu = res; 156 + const struct sunxi_ccu_desc *desc = ccu->desc; 157 + int i; 158 + 159 + reset_controller_unregister(&ccu->reset.rcdev); 160 + of_clk_del_provider(dev->of_node); 161 + 162 + for (i = 0; i < desc->hw_clks->num; i++) { 163 + struct clk_hw *hw = desc->hw_clks->hws[i]; 164 + 165 + if (!hw) 166 + continue; 167 + clk_hw_unregister(hw); 168 + } 169 + } 170 + 171 + int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg, 172 + const struct sunxi_ccu_desc *desc) 173 + { 174 + struct sunxi_ccu *ccu; 175 + int ret; 176 + 177 + ccu = devres_alloc(devm_sunxi_ccu_release, sizeof(*ccu), GFP_KERNEL); 178 + if (!ccu) 179 + return -ENOMEM; 180 + 181 + ret = sunxi_ccu_probe(ccu, dev, dev->of_node, reg, desc); 182 + if (ret) { 183 + devres_free(ccu); 184 + return ret; 185 + } 186 + 187 + devres_add(dev, ccu); 188 + 189 + return 0; 190 + } 191 + 192 + void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg, 193 + const struct sunxi_ccu_desc *desc) 194 + { 195 + struct sunxi_ccu *ccu; 196 + int ret; 197 + 198 + ccu = kzalloc(sizeof(*ccu), GFP_KERNEL); 199 + if (!ccu) 200 + return; 201 + 202 + ret = sunxi_ccu_probe(ccu, NULL, node, reg, desc); 203 + if (ret) { 204 + pr_err("%pOF: probing clocks failed: %d\n", node, ret); 205 + kfree(ccu); 206 + } 157 207 }
+4 -2
drivers/clk/sunxi-ng/ccu_common.h
··· 63 63 64 64 int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb); 65 65 66 - int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, 67 - const struct sunxi_ccu_desc *desc); 66 + int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg, 67 + const struct sunxi_ccu_desc *desc); 68 + void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg, 69 + const struct sunxi_ccu_desc *desc); 68 70 69 71 #endif /* _COMMON_H_ */
-1
drivers/clk/sunxi-ng/ccu_mux.h
··· 40 40 _SUNXI_CCU_MUX_TABLE(_shift, _width, NULL) 41 41 42 42 struct ccu_mux { 43 - u16 reg; 44 43 u32 enable; 45 44 46 45 struct ccu_mux_internal mux;
+1 -3
drivers/clk/sunxi/clk-mod0.c
··· 88 88 static int sun4i_a10_mod0_clk_probe(struct platform_device *pdev) 89 89 { 90 90 struct device_node *np = pdev->dev.of_node; 91 - struct resource *r; 92 91 void __iomem *reg; 93 92 94 93 if (!np) 95 94 return -ENODEV; 96 95 97 - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 98 - reg = devm_ioremap_resource(&pdev->dev, r); 96 + reg = devm_platform_ioremap_resource(pdev, 0); 99 97 if (IS_ERR(reg)) 100 98 return PTR_ERR(reg); 101 99
+1 -3
drivers/clk/sunxi/clk-sun6i-apb0-gates.c
··· 40 40 const struct gates_data *data; 41 41 const char *clk_parent; 42 42 const char *clk_name; 43 - struct resource *r; 44 43 void __iomem *reg; 45 44 int ngates; 46 45 int i; ··· 52 53 if (!data) 53 54 return -ENODEV; 54 55 55 - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 56 - reg = devm_ioremap_resource(&pdev->dev, r); 56 + reg = devm_platform_ioremap_resource(pdev, 0); 57 57 if (IS_ERR(reg)) 58 58 return PTR_ERR(reg); 59 59
+1 -3
drivers/clk/sunxi/clk-sun6i-apb0.c
··· 32 32 struct device_node *np = pdev->dev.of_node; 33 33 const char *clk_name = np->name; 34 34 const char *clk_parent; 35 - struct resource *r; 36 35 void __iomem *reg; 37 36 struct clk *clk; 38 37 39 - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 40 - reg = devm_ioremap_resource(&pdev->dev, r); 38 + reg = devm_platform_ioremap_resource(pdev, 0); 41 39 if (IS_ERR(reg)) 42 40 return PTR_ERR(reg); 43 41
+1 -3
drivers/clk/sunxi/clk-sun6i-ar100.c
··· 71 71 static int sun6i_a31_ar100_clk_probe(struct platform_device *pdev) 72 72 { 73 73 struct device_node *np = pdev->dev.of_node; 74 - struct resource *r; 75 74 void __iomem *reg; 76 75 struct clk *clk; 77 76 78 - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 79 - reg = devm_ioremap_resource(&pdev->dev, r); 77 + reg = devm_platform_ioremap_resource(pdev, 0); 80 78 if (IS_ERR(reg)) 81 79 return PTR_ERR(reg); 82 80
+1 -3
drivers/clk/sunxi/clk-sun8i-apb0.c
··· 87 87 static int sun8i_a23_apb0_clk_probe(struct platform_device *pdev) 88 88 { 89 89 struct device_node *np = pdev->dev.of_node; 90 - struct resource *r; 91 90 void __iomem *reg; 92 91 struct clk *clk; 93 92 94 - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 95 - reg = devm_ioremap_resource(&pdev->dev, r); 93 + reg = devm_platform_ioremap_resource(pdev, 0); 96 94 if (IS_ERR(reg)) 97 95 return PTR_ERR(reg); 98 96
+141
include/dt-bindings/clock/exynos850.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ 2 + /* 3 + * Copyright (C) 2021 Linaro Ltd. 4 + * Author: Sam Protsenko <semen.protsenko@linaro.org> 5 + * 6 + * Device Tree binding constants for Exynos850 clock controller. 7 + */ 8 + 9 + #ifndef _DT_BINDINGS_CLOCK_EXYNOS_850_H 10 + #define _DT_BINDINGS_CLOCK_EXYNOS_850_H 11 + 12 + /* CMU_TOP */ 13 + #define CLK_FOUT_SHARED0_PLL 1 14 + #define CLK_FOUT_SHARED1_PLL 2 15 + #define CLK_FOUT_MMC_PLL 3 16 + #define CLK_MOUT_SHARED0_PLL 4 17 + #define CLK_MOUT_SHARED1_PLL 5 18 + #define CLK_MOUT_MMC_PLL 6 19 + #define CLK_MOUT_CORE_BUS 7 20 + #define CLK_MOUT_CORE_CCI 8 21 + #define CLK_MOUT_CORE_MMC_EMBD 9 22 + #define CLK_MOUT_CORE_SSS 10 23 + #define CLK_MOUT_DPU 11 24 + #define CLK_MOUT_HSI_BUS 12 25 + #define CLK_MOUT_HSI_MMC_CARD 13 26 + #define CLK_MOUT_HSI_USB20DRD 14 27 + #define CLK_MOUT_PERI_BUS 15 28 + #define CLK_MOUT_PERI_UART 16 29 + #define CLK_MOUT_PERI_IP 17 30 + #define CLK_DOUT_SHARED0_DIV3 18 31 + #define CLK_DOUT_SHARED0_DIV2 19 32 + #define CLK_DOUT_SHARED1_DIV3 20 33 + #define CLK_DOUT_SHARED1_DIV2 21 34 + #define CLK_DOUT_SHARED0_DIV4 22 35 + #define CLK_DOUT_SHARED1_DIV4 23 36 + #define CLK_DOUT_CORE_BUS 24 37 + #define CLK_DOUT_CORE_CCI 25 38 + #define CLK_DOUT_CORE_MMC_EMBD 26 39 + #define CLK_DOUT_CORE_SSS 27 40 + #define CLK_DOUT_DPU 28 41 + #define CLK_DOUT_HSI_BUS 29 42 + #define CLK_DOUT_HSI_MMC_CARD 30 43 + #define CLK_DOUT_HSI_USB20DRD 31 44 + #define CLK_DOUT_PERI_BUS 32 45 + #define CLK_DOUT_PERI_UART 33 46 + #define CLK_DOUT_PERI_IP 34 47 + #define CLK_GOUT_CORE_BUS 35 48 + #define CLK_GOUT_CORE_CCI 36 49 + #define CLK_GOUT_CORE_MMC_EMBD 37 50 + #define CLK_GOUT_CORE_SSS 38 51 + #define CLK_GOUT_DPU 39 52 + #define CLK_GOUT_HSI_BUS 40 53 + #define CLK_GOUT_HSI_MMC_CARD 41 54 + #define CLK_GOUT_HSI_USB20DRD 42 55 + #define CLK_GOUT_PERI_BUS 43 56 + #define CLK_GOUT_PERI_UART 44 57 + #define CLK_GOUT_PERI_IP 45 58 + #define TOP_NR_CLK 46 59 + 60 + /* CMU_HSI */ 61 + #define CLK_MOUT_HSI_BUS_USER 1 62 + #define CLK_MOUT_HSI_MMC_CARD_USER 2 63 + #define CLK_MOUT_HSI_USB20DRD_USER 3 64 + #define CLK_MOUT_HSI_RTC 4 65 + #define CLK_GOUT_USB_RTC_CLK 5 66 + #define CLK_GOUT_USB_REF_CLK 6 67 + #define CLK_GOUT_USB_PHY_REF_CLK 7 68 + #define CLK_GOUT_USB_PHY_ACLK 8 69 + #define CLK_GOUT_USB_BUS_EARLY_CLK 9 70 + #define CLK_GOUT_GPIO_HSI_PCLK 10 71 + #define CLK_GOUT_MMC_CARD_ACLK 11 72 + #define CLK_GOUT_MMC_CARD_SDCLKIN 12 73 + #define CLK_GOUT_SYSREG_HSI_PCLK 13 74 + #define HSI_NR_CLK 14 75 + 76 + /* CMU_PERI */ 77 + #define CLK_MOUT_PERI_BUS_USER 1 78 + #define CLK_MOUT_PERI_UART_USER 2 79 + #define CLK_MOUT_PERI_HSI2C_USER 3 80 + #define CLK_MOUT_PERI_SPI_USER 4 81 + #define CLK_DOUT_PERI_HSI2C0 5 82 + #define CLK_DOUT_PERI_HSI2C1 6 83 + #define CLK_DOUT_PERI_HSI2C2 7 84 + #define CLK_DOUT_PERI_SPI0 8 85 + #define CLK_GOUT_PERI_HSI2C0 9 86 + #define CLK_GOUT_PERI_HSI2C1 10 87 + #define CLK_GOUT_PERI_HSI2C2 11 88 + #define CLK_GOUT_GPIO_PERI_PCLK 12 89 + #define CLK_GOUT_HSI2C0_IPCLK 13 90 + #define CLK_GOUT_HSI2C0_PCLK 14 91 + #define CLK_GOUT_HSI2C1_IPCLK 15 92 + #define CLK_GOUT_HSI2C1_PCLK 16 93 + #define CLK_GOUT_HSI2C2_IPCLK 17 94 + #define CLK_GOUT_HSI2C2_PCLK 18 95 + #define CLK_GOUT_I2C0_PCLK 19 96 + #define CLK_GOUT_I2C1_PCLK 20 97 + #define CLK_GOUT_I2C2_PCLK 21 98 + #define CLK_GOUT_I2C3_PCLK 22 99 + #define CLK_GOUT_I2C4_PCLK 23 100 + #define CLK_GOUT_I2C5_PCLK 24 101 + #define CLK_GOUT_I2C6_PCLK 25 102 + #define CLK_GOUT_MCT_PCLK 26 103 + #define CLK_GOUT_PWM_MOTOR_PCLK 27 104 + #define CLK_GOUT_SPI0_IPCLK 28 105 + #define CLK_GOUT_SPI0_PCLK 29 106 + #define CLK_GOUT_SYSREG_PERI_PCLK 30 107 + #define CLK_GOUT_UART_IPCLK 31 108 + #define CLK_GOUT_UART_PCLK 32 109 + #define CLK_GOUT_WDT0_PCLK 33 110 + #define CLK_GOUT_WDT1_PCLK 34 111 + #define PERI_NR_CLK 35 112 + 113 + /* CMU_CORE */ 114 + #define CLK_MOUT_CORE_BUS_USER 1 115 + #define CLK_MOUT_CORE_CCI_USER 2 116 + #define CLK_MOUT_CORE_MMC_EMBD_USER 3 117 + #define CLK_MOUT_CORE_SSS_USER 4 118 + #define CLK_MOUT_CORE_GIC 5 119 + #define CLK_DOUT_CORE_BUSP 6 120 + #define CLK_GOUT_CCI_ACLK 7 121 + #define CLK_GOUT_GIC_CLK 8 122 + #define CLK_GOUT_MMC_EMBD_ACLK 9 123 + #define CLK_GOUT_MMC_EMBD_SDCLKIN 10 124 + #define CLK_GOUT_SSS_ACLK 11 125 + #define CLK_GOUT_SSS_PCLK 12 126 + #define CORE_NR_CLK 13 127 + 128 + /* CMU_DPU */ 129 + #define CLK_MOUT_DPU_USER 1 130 + #define CLK_DOUT_DPU_BUSP 2 131 + #define CLK_GOUT_DPU_CMU_DPU_PCLK 3 132 + #define CLK_GOUT_DPU_DECON0_ACLK 4 133 + #define CLK_GOUT_DPU_DMA_ACLK 5 134 + #define CLK_GOUT_DPU_DPP_ACLK 6 135 + #define CLK_GOUT_DPU_PPMU_ACLK 7 136 + #define CLK_GOUT_DPU_PPMU_PCLK 8 137 + #define CLK_GOUT_DPU_SMMU_CLK 9 138 + #define CLK_GOUT_DPU_SYSREG_PCLK 10 139 + #define DPU_NR_CLK 11 140 + 141 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS_850_H */
+10
include/dt-bindings/clock/meson8b-clkc.h
··· 105 105 #define CLKID_PERIPH 126 106 106 #define CLKID_AXI 128 107 107 #define CLKID_L2_DRAM 130 108 + #define CLKID_HDMI_PLL_HDMI_OUT 132 109 + #define CLKID_VID_PLL_FINAL_DIV 137 110 + #define CLKID_VCLK_IN_SEL 138 111 + #define CLKID_VCLK2_IN_SEL 149 112 + #define CLKID_CTS_ENCT 161 113 + #define CLKID_CTS_ENCP 163 114 + #define CLKID_CTS_ENCI 165 115 + #define CLKID_HDMI_TX_PIXEL 167 116 + #define CLKID_CTS_ENCL 169 117 + #define CLKID_CTS_VDAC0 171 108 118 #define CLKID_HDMI_SYS 174 109 119 #define CLKID_VPU 190 110 120 #define CLKID_VDEC_1 196