]> Git Repo - linux.git/blob - drivers/gpu/drm/msm/dp/dp_parser.c
Merge existing fixes from regulator/for-5.15
[linux.git] / drivers / gpu / drm / msm / dp / dp_parser.c
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 }
This page took 0.057332 seconds and 4 git commands to generate.