Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  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
 14static 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
 22static 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
 45static 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
 54static 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
 61static 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;
 80err:
 81	dp_parser_unmap_io_resources(parser);
 82	return rc;
 83}
 84
 85static 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
103static 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
109static 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
187static 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
251static 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
281struct 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}