1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
4 */
5
6 #include <linux/of_gpio.h>
7 #include <linux/phy/phy.h>
8
9 #include <drm/drm_of.h>
10 #include <drm/drm_print.h>
11 #include <drm/drm_bridge.h>
12
13 #include "dp_parser.h"
14 #include "dp_reg.h"
15
16 #define DP_DEFAULT_AHB_OFFSET 0x0000
17 #define DP_DEFAULT_AHB_SIZE 0x0200
18 #define DP_DEFAULT_AUX_OFFSET 0x0200
19 #define DP_DEFAULT_AUX_SIZE 0x0200
20 #define DP_DEFAULT_LINK_OFFSET 0x0400
21 #define DP_DEFAULT_LINK_SIZE 0x0C00
22 #define DP_DEFAULT_P0_OFFSET 0x1000
23 #define DP_DEFAULT_P0_SIZE 0x0400
24
dp_ioremap(struct platform_device * pdev,int idx,size_t * len)25 static void __iomem *dp_ioremap(struct platform_device *pdev, int idx, size_t *len)
26 {
27 struct resource *res;
28 void __iomem *base;
29
30 base = devm_platform_get_and_ioremap_resource(pdev, idx, &res);
31 if (!IS_ERR(base))
32 *len = resource_size(res);
33
34 return base;
35 }
36
dp_parser_ctrl_res(struct dp_parser * parser)37 static int dp_parser_ctrl_res(struct dp_parser *parser)
38 {
39 struct platform_device *pdev = parser->pdev;
40 struct dp_io *io = &parser->io;
41 struct dss_io_data *dss = &io->dp_controller;
42
43 dss->ahb.base = dp_ioremap(pdev, 0, &dss->ahb.len);
44 if (IS_ERR(dss->ahb.base))
45 return PTR_ERR(dss->ahb.base);
46
47 dss->aux.base = dp_ioremap(pdev, 1, &dss->aux.len);
48 if (IS_ERR(dss->aux.base)) {
49 /*
50 * The initial binding had a single reg, but in order to
51 * support variation in the sub-region sizes this was split.
52 * dp_ioremap() will fail with -EINVAL here if only a single
53 * reg is specified, so fill in the sub-region offsets and
54 * lengths based on this single region.
55 */
56 if (PTR_ERR(dss->aux.base) == -EINVAL) {
57 if (dss->ahb.len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) {
58 DRM_ERROR("legacy memory region not large enough\n");
59 return -EINVAL;
60 }
61
62 dss->ahb.len = DP_DEFAULT_AHB_SIZE;
63 dss->aux.base = dss->ahb.base + DP_DEFAULT_AUX_OFFSET;
64 dss->aux.len = DP_DEFAULT_AUX_SIZE;
65 dss->link.base = dss->ahb.base + DP_DEFAULT_LINK_OFFSET;
66 dss->link.len = DP_DEFAULT_LINK_SIZE;
67 dss->p0.base = dss->ahb.base + DP_DEFAULT_P0_OFFSET;
68 dss->p0.len = DP_DEFAULT_P0_SIZE;
69 } else {
70 DRM_ERROR("unable to remap aux region: %pe\n", dss->aux.base);
71 return PTR_ERR(dss->aux.base);
72 }
73 } else {
74 dss->link.base = dp_ioremap(pdev, 2, &dss->link.len);
75 if (IS_ERR(dss->link.base)) {
76 DRM_ERROR("unable to remap link region: %pe\n", dss->link.base);
77 return PTR_ERR(dss->link.base);
78 }
79
80 dss->p0.base = dp_ioremap(pdev, 3, &dss->p0.len);
81 if (IS_ERR(dss->p0.base)) {
82 DRM_ERROR("unable to remap p0 region: %pe\n", dss->p0.base);
83 return PTR_ERR(dss->p0.base);
84 }
85 }
86
87 io->phy = devm_phy_get(&pdev->dev, "dp");
88 if (IS_ERR(io->phy))
89 return PTR_ERR(io->phy);
90
91 return 0;
92 }
93
dp_parser_misc(struct dp_parser * parser)94 static int dp_parser_misc(struct dp_parser *parser)
95 {
96 struct device_node *of_node = parser->pdev->dev.of_node;
97 int len;
98
99 len = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
100 if (len < 0) {
101 DRM_WARN("Invalid property \"data-lanes\", default max DP lanes = %d\n",
102 DP_MAX_NUM_DP_LANES);
103 len = DP_MAX_NUM_DP_LANES;
104 }
105
106 parser->max_dp_lanes = len;
107 return 0;
108 }
109
dp_parser_check_prefix(const char * clk_prefix,const char * clk_name)110 static inline bool dp_parser_check_prefix(const char *clk_prefix,
111 const char *clk_name)
112 {
113 return !strncmp(clk_prefix, clk_name, strlen(clk_prefix));
114 }
115
dp_parser_init_clk_data(struct dp_parser * parser)116 static int dp_parser_init_clk_data(struct dp_parser *parser)
117 {
118 int num_clk, i, rc;
119 int core_clk_count = 0, ctrl_clk_count = 0, stream_clk_count = 0;
120 const char *clk_name;
121 struct device *dev = &parser->pdev->dev;
122 struct dss_module_power *core_power = &parser->mp[DP_CORE_PM];
123 struct dss_module_power *ctrl_power = &parser->mp[DP_CTRL_PM];
124 struct dss_module_power *stream_power = &parser->mp[DP_STREAM_PM];
125
126 num_clk = of_property_count_strings(dev->of_node, "clock-names");
127 if (num_clk <= 0) {
128 DRM_ERROR("no clocks are defined\n");
129 return -EINVAL;
130 }
131
132 for (i = 0; i < num_clk; i++) {
133 rc = of_property_read_string_index(dev->of_node,
134 "clock-names", i, &clk_name);
135 if (rc < 0)
136 return rc;
137
138 if (dp_parser_check_prefix("core", clk_name))
139 core_clk_count++;
140
141 if (dp_parser_check_prefix("ctrl", clk_name))
142 ctrl_clk_count++;
143
144 if (dp_parser_check_prefix("stream", clk_name))
145 stream_clk_count++;
146 }
147
148 /* Initialize the CORE power module */
149 if (core_clk_count == 0) {
150 DRM_ERROR("no core clocks are defined\n");
151 return -EINVAL;
152 }
153
154 core_power->num_clk = core_clk_count;
155 core_power->clocks = devm_kcalloc(dev,
156 core_power->num_clk, sizeof(struct clk_bulk_data),
157 GFP_KERNEL);
158 if (!core_power->clocks)
159 return -ENOMEM;
160
161 /* Initialize the CTRL power module */
162 if (ctrl_clk_count == 0) {
163 DRM_ERROR("no ctrl clocks are defined\n");
164 return -EINVAL;
165 }
166
167 ctrl_power->num_clk = ctrl_clk_count;
168 ctrl_power->clocks = devm_kcalloc(dev,
169 ctrl_power->num_clk, sizeof(struct clk_bulk_data),
170 GFP_KERNEL);
171 if (!ctrl_power->clocks) {
172 ctrl_power->num_clk = 0;
173 return -ENOMEM;
174 }
175
176 /* Initialize the STREAM power module */
177 if (stream_clk_count == 0) {
178 DRM_ERROR("no stream (pixel) clocks are defined\n");
179 return -EINVAL;
180 }
181
182 stream_power->num_clk = stream_clk_count;
183 stream_power->clocks = devm_kcalloc(dev,
184 stream_power->num_clk, sizeof(struct clk_bulk_data),
185 GFP_KERNEL);
186 if (!stream_power->clocks) {
187 stream_power->num_clk = 0;
188 return -ENOMEM;
189 }
190
191 return 0;
192 }
193
dp_parser_clock(struct dp_parser * parser)194 static int dp_parser_clock(struct dp_parser *parser)
195 {
196 int rc = 0, i = 0;
197 int num_clk = 0;
198 int core_clk_index = 0, ctrl_clk_index = 0, stream_clk_index = 0;
199 int core_clk_count = 0, ctrl_clk_count = 0, stream_clk_count = 0;
200 const char *clk_name;
201 struct device *dev = &parser->pdev->dev;
202 struct dss_module_power *core_power = &parser->mp[DP_CORE_PM];
203 struct dss_module_power *ctrl_power = &parser->mp[DP_CTRL_PM];
204 struct dss_module_power *stream_power = &parser->mp[DP_STREAM_PM];
205
206 rc = dp_parser_init_clk_data(parser);
207 if (rc) {
208 DRM_ERROR("failed to initialize power data %d\n", rc);
209 return -EINVAL;
210 }
211
212 core_clk_count = core_power->num_clk;
213 ctrl_clk_count = ctrl_power->num_clk;
214 stream_clk_count = stream_power->num_clk;
215
216 num_clk = core_clk_count + ctrl_clk_count + stream_clk_count;
217
218 for (i = 0; i < num_clk; i++) {
219 rc = of_property_read_string_index(dev->of_node, "clock-names",
220 i, &clk_name);
221 if (rc) {
222 DRM_ERROR("error reading clock-names %d\n", rc);
223 return rc;
224 }
225 if (dp_parser_check_prefix("core", clk_name) &&
226 core_clk_index < core_clk_count) {
227 core_power->clocks[core_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL);
228 core_clk_index++;
229 } else if (dp_parser_check_prefix("stream", clk_name) &&
230 stream_clk_index < stream_clk_count) {
231 stream_power->clocks[stream_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL);
232 stream_clk_index++;
233 } else if (dp_parser_check_prefix("ctrl", clk_name) &&
234 ctrl_clk_index < ctrl_clk_count) {
235 ctrl_power->clocks[ctrl_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL);
236 ctrl_clk_index++;
237 }
238 }
239
240 return 0;
241 }
242
devm_dp_parser_find_next_bridge(struct device * dev,struct dp_parser * parser)243 int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser)
244 {
245 struct platform_device *pdev = parser->pdev;
246 struct drm_bridge *bridge;
247
248 bridge = devm_drm_of_get_bridge(dev, pdev->dev.of_node, 1, 0);
249 if (IS_ERR(bridge))
250 return PTR_ERR(bridge);
251
252 parser->next_bridge = bridge;
253
254 return 0;
255 }
256
dp_parser_parse(struct dp_parser * parser)257 static int dp_parser_parse(struct dp_parser *parser)
258 {
259 int rc = 0;
260
261 if (!parser) {
262 DRM_ERROR("invalid input\n");
263 return -EINVAL;
264 }
265
266 rc = dp_parser_ctrl_res(parser);
267 if (rc)
268 return rc;
269
270 rc = dp_parser_misc(parser);
271 if (rc)
272 return rc;
273
274 rc = dp_parser_clock(parser);
275 if (rc)
276 return rc;
277
278 return 0;
279 }
280
dp_parser_get(struct platform_device * pdev)281 struct dp_parser *dp_parser_get(struct platform_device *pdev)
282 {
283 struct dp_parser *parser;
284
285 parser = devm_kzalloc(&pdev->dev, sizeof(*parser), GFP_KERNEL);
286 if (!parser)
287 return ERR_PTR(-ENOMEM);
288
289 parser->parse = dp_parser_parse;
290 parser->pdev = pdev;
291
292 return parser;
293 }
294