xref: /openbmc/linux/drivers/gpu/drm/msm/dp/dp_parser.c (revision fc7a6209)
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_print.h>
10 
11 #include "dp_parser.h"
12 #include "dp_reg.h"
13 
14 static const struct dp_regulator_cfg sdm845_dp_reg_cfg = {
15 	.num = 2,
16 	.regs = {
17 		{"vdda-1p2", 21800, 4 },	/* 1.2 V */
18 		{"vdda-0p9", 36000, 32 },	/* 0.9 V */
19 	},
20 };
21 
22 static int msm_dss_ioremap(struct platform_device *pdev,
23 				struct dss_io_data *io_data)
24 {
25 	struct resource *res = NULL;
26 
27 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
28 	if (!res) {
29 		DRM_ERROR("%pS->%s: msm_dss_get_res failed\n",
30 			__builtin_return_address(0), __func__);
31 		return -ENODEV;
32 	}
33 
34 	io_data->len = (u32)resource_size(res);
35 	io_data->base = ioremap(res->start, io_data->len);
36 	if (!io_data->base) {
37 		DRM_ERROR("%pS->%s: ioremap failed\n",
38 			__builtin_return_address(0), __func__);
39 		return -EIO;
40 	}
41 
42 	return 0;
43 }
44 
45 static void msm_dss_iounmap(struct dss_io_data *io_data)
46 {
47 	if (io_data->base) {
48 		iounmap(io_data->base);
49 		io_data->base = NULL;
50 	}
51 	io_data->len = 0;
52 }
53 
54 static void dp_parser_unmap_io_resources(struct dp_parser *parser)
55 {
56 	struct dp_io *io = &parser->io;
57 
58 	msm_dss_iounmap(&io->dp_controller);
59 }
60 
61 static int dp_parser_ctrl_res(struct dp_parser *parser)
62 {
63 	int rc = 0;
64 	struct platform_device *pdev = parser->pdev;
65 	struct dp_io *io = &parser->io;
66 
67 	rc = msm_dss_ioremap(pdev, &io->dp_controller);
68 	if (rc) {
69 		DRM_ERROR("unable to remap dp io resources, rc=%d\n", rc);
70 		goto err;
71 	}
72 
73 	io->phy = devm_phy_get(&pdev->dev, "dp");
74 	if (IS_ERR(io->phy)) {
75 		rc = PTR_ERR(io->phy);
76 		goto err;
77 	}
78 
79 	return 0;
80 err:
81 	dp_parser_unmap_io_resources(parser);
82 	return rc;
83 }
84 
85 static int dp_parser_misc(struct dp_parser *parser)
86 {
87 	struct device_node *of_node = parser->pdev->dev.of_node;
88 	int len = 0;
89 	const char *data_lane_property = "data-lanes";
90 
91 	len = of_property_count_elems_of_size(of_node,
92 			 data_lane_property, sizeof(u32));
93 	if (len < 0) {
94 		DRM_WARN("Invalid property %s, default max DP lanes = %d\n",
95 				data_lane_property, DP_MAX_NUM_DP_LANES);
96 		len = DP_MAX_NUM_DP_LANES;
97 	}
98 
99 	parser->max_dp_lanes = len;
100 	return 0;
101 }
102 
103 static inline bool dp_parser_check_prefix(const char *clk_prefix,
104 						const char *clk_name)
105 {
106 	return !strncmp(clk_prefix, clk_name, strlen(clk_prefix));
107 }
108 
109 static int dp_parser_init_clk_data(struct dp_parser *parser)
110 {
111 	int num_clk, i, rc;
112 	int core_clk_count = 0, ctrl_clk_count = 0, stream_clk_count = 0;
113 	const char *clk_name;
114 	struct device *dev = &parser->pdev->dev;
115 	struct dss_module_power *core_power = &parser->mp[DP_CORE_PM];
116 	struct dss_module_power *ctrl_power = &parser->mp[DP_CTRL_PM];
117 	struct dss_module_power *stream_power = &parser->mp[DP_STREAM_PM];
118 
119 	num_clk = of_property_count_strings(dev->of_node, "clock-names");
120 	if (num_clk <= 0) {
121 		DRM_ERROR("no clocks are defined\n");
122 		return -EINVAL;
123 	}
124 
125 	for (i = 0; i < num_clk; i++) {
126 		rc = of_property_read_string_index(dev->of_node,
127 				"clock-names", i, &clk_name);
128 		if (rc < 0)
129 			return rc;
130 
131 		if (dp_parser_check_prefix("core", clk_name))
132 			core_clk_count++;
133 
134 		if (dp_parser_check_prefix("ctrl", clk_name))
135 			ctrl_clk_count++;
136 
137 		if (dp_parser_check_prefix("stream", clk_name))
138 			stream_clk_count++;
139 	}
140 
141 	/* Initialize the CORE power module */
142 	if (core_clk_count == 0) {
143 		DRM_ERROR("no core clocks are defined\n");
144 		return -EINVAL;
145 	}
146 
147 	core_power->num_clk = core_clk_count;
148 	core_power->clk_config = devm_kzalloc(dev,
149 			sizeof(struct dss_clk) * core_power->num_clk,
150 			GFP_KERNEL);
151 	if (!core_power->clk_config)
152 		return -EINVAL;
153 
154 	/* Initialize the CTRL power module */
155 	if (ctrl_clk_count == 0) {
156 		DRM_ERROR("no ctrl clocks are defined\n");
157 		return -EINVAL;
158 	}
159 
160 	ctrl_power->num_clk = ctrl_clk_count;
161 	ctrl_power->clk_config = devm_kzalloc(dev,
162 			sizeof(struct dss_clk) * ctrl_power->num_clk,
163 			GFP_KERNEL);
164 	if (!ctrl_power->clk_config) {
165 		ctrl_power->num_clk = 0;
166 		return -EINVAL;
167 	}
168 
169 	/* Initialize the STREAM power module */
170 	if (stream_clk_count == 0) {
171 		DRM_ERROR("no stream (pixel) clocks are defined\n");
172 		return -EINVAL;
173 	}
174 
175 	stream_power->num_clk = stream_clk_count;
176 	stream_power->clk_config = devm_kzalloc(dev,
177 			sizeof(struct dss_clk) * stream_power->num_clk,
178 			GFP_KERNEL);
179 	if (!stream_power->clk_config) {
180 		stream_power->num_clk = 0;
181 		return -EINVAL;
182 	}
183 
184 	return 0;
185 }
186 
187 static int dp_parser_clock(struct dp_parser *parser)
188 {
189 	int rc = 0, i = 0;
190 	int num_clk = 0;
191 	int core_clk_index = 0, ctrl_clk_index = 0, stream_clk_index = 0;
192 	int core_clk_count = 0, ctrl_clk_count = 0, stream_clk_count = 0;
193 	const char *clk_name;
194 	struct device *dev = &parser->pdev->dev;
195 	struct dss_module_power *core_power = &parser->mp[DP_CORE_PM];
196 	struct dss_module_power *ctrl_power = &parser->mp[DP_CTRL_PM];
197 	struct dss_module_power *stream_power = &parser->mp[DP_STREAM_PM];
198 
199 	rc =  dp_parser_init_clk_data(parser);
200 	if (rc) {
201 		DRM_ERROR("failed to initialize power data %d\n", rc);
202 		return -EINVAL;
203 	}
204 
205 	core_clk_count = core_power->num_clk;
206 	ctrl_clk_count = ctrl_power->num_clk;
207 	stream_clk_count = stream_power->num_clk;
208 
209 	num_clk = core_clk_count + ctrl_clk_count + stream_clk_count;
210 
211 	for (i = 0; i < num_clk; i++) {
212 		rc = of_property_read_string_index(dev->of_node, "clock-names",
213 				i, &clk_name);
214 		if (rc) {
215 			DRM_ERROR("error reading clock-names %d\n", rc);
216 			return rc;
217 		}
218 		if (dp_parser_check_prefix("core", clk_name) &&
219 				core_clk_index < core_clk_count) {
220 			struct dss_clk *clk =
221 				&core_power->clk_config[core_clk_index];
222 			strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
223 			clk->type = DSS_CLK_AHB;
224 			core_clk_index++;
225 		} else if (dp_parser_check_prefix("stream", clk_name) &&
226 				stream_clk_index < stream_clk_count) {
227 			struct dss_clk *clk =
228 				&stream_power->clk_config[stream_clk_index];
229 			strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
230 			clk->type = DSS_CLK_PCLK;
231 			stream_clk_index++;
232 		} else if (dp_parser_check_prefix("ctrl", clk_name) &&
233 			   ctrl_clk_index < ctrl_clk_count) {
234 			struct dss_clk *clk =
235 				&ctrl_power->clk_config[ctrl_clk_index];
236 			strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
237 			ctrl_clk_index++;
238 			if (dp_parser_check_prefix("ctrl_link", clk_name) ||
239 			    dp_parser_check_prefix("stream_pixel", clk_name))
240 				clk->type = DSS_CLK_PCLK;
241 			else
242 				clk->type = DSS_CLK_AHB;
243 		}
244 	}
245 
246 	DRM_DEBUG_DP("clock parsing successful\n");
247 
248 	return 0;
249 }
250 
251 static int dp_parser_parse(struct dp_parser *parser)
252 {
253 	int rc = 0;
254 
255 	if (!parser) {
256 		DRM_ERROR("invalid input\n");
257 		return -EINVAL;
258 	}
259 
260 	rc = dp_parser_ctrl_res(parser);
261 	if (rc)
262 		return rc;
263 
264 	rc = dp_parser_misc(parser);
265 	if (rc)
266 		return rc;
267 
268 	rc = dp_parser_clock(parser);
269 	if (rc)
270 		return rc;
271 
272 	/* Map the corresponding regulator information according to
273 	 * version. Currently, since we only have one supported platform,
274 	 * mapping the regulator directly.
275 	 */
276 	parser->regulator_cfg = &sdm845_dp_reg_cfg;
277 
278 	return 0;
279 }
280 
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