xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/hisilicon/kirin/kirin_drm_dsi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * DesignWare MIPI DSI Host Controller v1.02 driver
4  *
5  * Copyright (c) 2016 Linaro Limited.
6  * Copyright (c) 2014-2016 Hisilicon Limited.
7  *
8  * Author:
9  *	<shizongxuan@huawei.com>
10  *	<zhangxiubin@huawei.com>
11  *	<lvda3@hisilicon.com>
12  */
13 #include <linux/clk.h>
14 #include <linux/component.h>
15 #include <linux/delay.h>
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
18 
19 #include <drm/drm_atomic_helper.h>
20 #include <drm/drm_device.h>
21 #include <drm/drm_encoder_slave.h>
22 #include <drm/drm_mipi_dsi.h>
23 #include <drm/drm_of.h>
24 #include <drm/drm_print.h>
25 #include <drm/drm_probe_helper.h>
26 #include <drm/drm_sysfs.h>
27 
28 #include "kirin_drm_dsi.h"
29 #include "dw_dsi_reg.h"
30 
31 static struct kirin_dsi_ops *hisi_dsi_ops;
32 
dsi_set_output_client(struct drm_device * dev)33 void dsi_set_output_client(struct drm_device *dev)
34 {
35 	enum dsi_output_client client;
36 	struct drm_connector *connector;
37 	struct drm_encoder *encoder;
38 	struct drm_connector_list_iter conn_iter;
39 	struct dw_dsi *dsi;
40 
41 	mutex_lock(&dev->mode_config.mutex);
42 
43 	/* find dsi encoder */
44 	drm_for_each_encoder(encoder, dev)
45 		if (encoder->encoder_type == DRM_MODE_ENCODER_DSI)
46 			break;
47 	dsi = encoder_to_dsi(encoder);
48 
49 	/* find HDMI connector */
50 	drm_connector_list_iter_begin(dev, &conn_iter);
51 	drm_for_each_connector_iter(connector, &conn_iter)
52 		if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA)
53 			break;
54 	drm_connector_list_iter_end(&conn_iter);
55 
56 	/*
57 	 * set the proper dsi output client
58 	 */
59 	client = connector->status == connector_status_connected ? OUT_HDMI :
60 								   OUT_PANEL;
61 	if (client != dsi->cur_client) {
62 		/*
63 		 * set the switch ic to select the HDMI or MIPI_DSI
64 		 */
65 		if (hisi_dsi_ops->version == KIRIN960_DSI)
66 			gpiod_set_value_cansleep(dsi->gpio_mux, client);
67 
68 		dsi->cur_client = client;
69 		/* let the userspace know panel connector status has changed */
70 		drm_sysfs_hotplug_event(dev);
71 		DRM_INFO("client change to %s\n",
72 			 client == OUT_HDMI ? "HDMI" : "panel");
73 	}
74 
75 	mutex_unlock(&dev->mode_config.mutex);
76 }
77 EXPORT_SYMBOL_GPL(dsi_set_output_client);
78 /************************for the panel attach to dsi*****************************/
dsi_connector_get_modes(struct drm_connector * connector)79 static int dsi_connector_get_modes(struct drm_connector *connector)
80 {
81 	struct dw_dsi *dsi = connector_to_dsi(connector);
82 
83 	return drm_panel_get_modes(dsi->panel, connector);
84 }
85 
86 static enum drm_mode_status
dsi_connector_mode_valid(struct drm_connector * connector,struct drm_display_mode * mode)87 dsi_connector_mode_valid(struct drm_connector *connector,
88 			 struct drm_display_mode *mode)
89 {
90 	enum drm_mode_status mode_status = MODE_OK;
91 
92 	return mode_status;
93 }
94 
95 static struct drm_encoder *
dsi_connector_best_encoder(struct drm_connector * connector)96 dsi_connector_best_encoder(struct drm_connector *connector)
97 {
98 	struct dw_dsi *dsi = connector_to_dsi(connector);
99 
100 	return &dsi->encoder;
101 }
102 
103 static struct drm_connector_helper_funcs dsi_connector_helper_funcs = {
104 	.get_modes = dsi_connector_get_modes,
105 	.mode_valid = dsi_connector_mode_valid,
106 	.best_encoder = dsi_connector_best_encoder,
107 };
108 
109 static enum drm_connector_status
dsi_connector_detect(struct drm_connector * connector,bool force)110 dsi_connector_detect(struct drm_connector *connector, bool force)
111 {
112 	struct dw_dsi *dsi = connector_to_dsi(connector);
113 	enum drm_connector_status status;
114 
115 	status = dsi->cur_client == OUT_PANEL ? connector_status_connected :
116 						connector_status_disconnected;
117 
118 	return status;
119 }
120 
dsi_connector_destroy(struct drm_connector * connector)121 static void dsi_connector_destroy(struct drm_connector *connector)
122 {
123 	drm_connector_unregister(connector);
124 	drm_connector_cleanup(connector);
125 }
126 
127 static struct drm_connector_funcs dsi_atomic_connector_funcs = {
128 	.fill_modes = drm_helper_probe_single_connector_modes,
129 	.detect = dsi_connector_detect,
130 	.destroy = dsi_connector_destroy,
131 	.reset = drm_atomic_helper_connector_reset,
132 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
133 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
134 };
135 
dsi_connector_init(struct drm_device * dev,struct dw_dsi * dsi)136 static int dsi_connector_init(struct drm_device *dev, struct dw_dsi *dsi)
137 {
138 	struct drm_encoder *encoder = &dsi->encoder;
139 	struct drm_connector *connector = &dsi->connector;
140 	int ret;
141 
142 	connector->polled = DRM_CONNECTOR_POLL_HPD;
143 	drm_connector_helper_add(connector, &dsi_connector_helper_funcs);
144 
145 	ret = drm_connector_init(dev, &dsi->connector,
146 				 &dsi_atomic_connector_funcs,
147 				 DRM_MODE_CONNECTOR_DSI);
148 	if (ret)
149 		return ret;
150 
151 	ret = drm_connector_attach_encoder(connector, encoder);
152 	if (ret)
153 		return ret;
154 
155 	DRM_INFO("connector init\n");
156 	return 0;
157 }
158 
159 /****************************************************************************/
160 
161 /***************************for the encoder_helper_funcs****************************************/
162 static const struct drm_encoder_funcs dw_encoder_funcs = {
163 	.destroy = drm_encoder_cleanup,
164 };
165 
dsi_encoder_atomic_check(struct drm_encoder * encoder,struct drm_crtc_state * crtc_state,struct drm_connector_state * conn_state)166 static int dsi_encoder_atomic_check(struct drm_encoder *encoder,
167 				    struct drm_crtc_state *crtc_state,
168 				    struct drm_connector_state *conn_state)
169 {
170 	/* do nothing */
171 	return 0;
172 }
173 
174 static enum drm_mode_status
dsi_encoder_mode_valid(struct drm_encoder * encoder,const struct drm_display_mode * mode)175 dsi_encoder_mode_valid(struct drm_encoder *encoder,
176 		       const struct drm_display_mode *mode)
177 
178 {
179 	return hisi_dsi_ops->encoder_valid(encoder, mode);
180 }
181 
dsi_encoder_mode_set(struct drm_encoder * encoder,struct drm_display_mode * mode,struct drm_display_mode * adj_mode)182 static void dsi_encoder_mode_set(struct drm_encoder *encoder,
183 				 struct drm_display_mode *mode,
184 				 struct drm_display_mode *adj_mode)
185 {
186 	struct dw_dsi *dsi = encoder_to_dsi(encoder);
187 
188 	drm_mode_copy(&dsi->cur_mode, adj_mode);
189 }
190 
dsi_encoder_enable(struct drm_encoder * encoder)191 static void dsi_encoder_enable(struct drm_encoder *encoder)
192 {
193 	struct dw_dsi *dsi = encoder_to_dsi(encoder);
194 
195 	if (dsi->enable)
196 		return;
197 
198 	hisi_dsi_ops->encoder_enable(encoder);
199 
200 	if (hisi_dsi_ops->version == KIRIN960_DSI) {
201 		/* turn on panel */
202 		if (dsi->panel && drm_panel_prepare(dsi->panel))
203 			DRM_ERROR("failed to prepare panel\n");
204 
205 		/*dw_dsi_set_mode(dsi, DSI_VIDEO_MODE);*/
206 
207 		/* turn on panel's back light */
208 		if (dsi->panel && drm_panel_enable(dsi->panel))
209 			DRM_ERROR("failed to enable panel\n");
210 	}
211 
212 	dsi->enable = true;
213 }
214 
dw_dsi_set_mode(struct dw_dsi * dsi,enum dsi_work_mode mode)215 static void dw_dsi_set_mode(struct dw_dsi *dsi, enum dsi_work_mode mode)
216 {
217 	struct dsi_hw_ctx *ctx = dsi->ctx;
218 	void __iomem *base = ctx->base;
219 
220 	writel(RESET, base + PWR_UP);
221 	writel(mode, base + MODE_CFG);
222 	writel(POWERUP, base + PWR_UP);
223 }
224 
dsi_encoder_disable(struct drm_encoder * encoder)225 static void dsi_encoder_disable(struct drm_encoder *encoder)
226 {
227 	struct dw_dsi *dsi = encoder_to_dsi(encoder);
228 	struct dsi_hw_ctx *ctx = dsi->ctx;
229 
230 	if (!dsi->enable)
231 		return;
232 
233 	dw_dsi_set_mode(dsi, DSI_COMMAND_MODE);
234 
235 	if (hisi_dsi_ops->version == KIRIN960_DSI) {
236 		/* turn off panel's backlight */
237 		if (dsi->panel && drm_panel_disable(dsi->panel))
238 			DRM_ERROR("failed to disable panel\n");
239 
240 		/* turn off panel */
241 		if (dsi->panel && drm_panel_unprepare(dsi->panel))
242 			DRM_ERROR("failed to unprepare panel\n");
243 
244 		clk_disable_unprepare(ctx->dss_dphy0_ref_clk);
245 		clk_disable_unprepare(ctx->dss_dphy0_cfg_clk);
246 		clk_disable_unprepare(ctx->dss_pclk_dsi0_clk);
247 	}
248 
249 	dsi->enable = false;
250 }
251 
252 static const struct drm_encoder_helper_funcs dw_encoder_helper_funcs = {
253 	.atomic_check = dsi_encoder_atomic_check,
254 	.mode_valid = dsi_encoder_mode_valid,
255 	.mode_set = dsi_encoder_mode_set,
256 	.enable = dsi_encoder_enable,
257 	.disable = dsi_encoder_disable
258 };
259 
260 /****************************************************************************/
dsi_bridge_init(struct drm_device * dev,struct dw_dsi * dsi)261 static int dsi_bridge_init(struct drm_device *dev, struct dw_dsi *dsi)
262 {
263 	struct drm_encoder *encoder = &dsi->encoder;
264 	struct drm_bridge *bridge = dsi->bridge;
265 	int ret;
266 
267 	/* associate the bridge to dsi encoder */
268 	ret = drm_bridge_attach(encoder, bridge, NULL, 0);
269 
270 	if (ret) {
271 		DRM_ERROR("failed to attach external bridge\n");
272 		return ret;
273 	}
274 
275 	return 0;
276 }
277 
dw_drm_encoder_init(struct device * dev,struct drm_device * drm_dev,struct drm_encoder * encoder)278 static int dw_drm_encoder_init(struct device *dev, struct drm_device *drm_dev,
279 			       struct drm_encoder *encoder)
280 {
281 	int ret;
282 	u32 crtc_mask = drm_of_find_possible_crtcs(drm_dev, dev->of_node);
283 
284 	if (!crtc_mask) {
285 		DRM_ERROR("failed to find crtc mask\n");
286 		return -EINVAL;
287 	}
288 
289 	encoder->possible_crtcs = crtc_mask;
290 	ret = drm_encoder_init(drm_dev, encoder, &dw_encoder_funcs,
291 			       DRM_MODE_ENCODER_DSI, NULL);
292 	if (ret) {
293 		DRM_ERROR("failed to init dsi encoder\n");
294 		return ret;
295 	}
296 
297 	drm_encoder_helper_add(encoder, &dw_encoder_helper_funcs);
298 
299 	return 0;
300 }
301 
dsi_bind(struct device * dev,struct device * master,void * data)302 static int dsi_bind(struct device *dev, struct device *master, void *data)
303 {
304 	struct dsi_data *ddata = dev_get_drvdata(dev);
305 	struct dw_dsi *dsi = &ddata->dsi;
306 	struct drm_device *drm_dev = data;
307 	int ret;
308 
309 	DRM_INFO("+.\n");
310 	ret = dw_drm_encoder_init(dev, drm_dev, &dsi->encoder);
311 	if (ret)
312 		return ret;
313 
314 	if (dsi->bridge) {
315 		ret = dsi_bridge_init(drm_dev, dsi);
316 		if (ret)
317 			return ret;
318 	}
319 
320 	if (hisi_dsi_ops->version == KIRIN960_DSI) {
321 		if (dsi->panel) {
322 			ret = dsi_connector_init(drm_dev, dsi);
323 			if (ret)
324 				return ret;
325 		}
326 	} else if (hisi_dsi_ops->version == KIRIN620_DSI) {
327 		/*the panel for the kirin620 drm have not support*/
328 	}
329 
330 	DRM_INFO("-.\n");
331 	return 0;
332 }
333 
dsi_unbind(struct device * dev,struct device * master,void * data)334 static void dsi_unbind(struct device *dev, struct device *master, void *data)
335 {
336 	/* do nothing */
337 }
338 
339 static const struct component_ops dsi_ops = {
340 	.bind = dsi_bind,
341 	.unbind = dsi_unbind,
342 };
343 
dsi_probe(struct platform_device * pdev)344 static int dsi_probe(struct platform_device *pdev)
345 {
346 	struct device *dev = &pdev->dev;
347 	struct dsi_data *data;
348 	struct dw_dsi *dsi;
349 	struct dsi_hw_ctx *ctx;
350 	int ret;
351 
352 	hisi_dsi_ops = (struct kirin_dsi_ops *)of_device_get_match_data(dev);
353 
354 	DRM_INFO("+.\n");
355 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
356 	if (!data) {
357 		DRM_ERROR("failed to allocate dsi data.\n");
358 		return -ENOMEM;
359 	}
360 	dsi = &data->dsi;
361 	ctx = &data->ctx;
362 	dsi->ctx = ctx;
363 
364 	if (hisi_dsi_ops == NULL)
365 		DRM_ERROR("hisi_dsi_ops is not bind\n");
366 	ret = hisi_dsi_ops->host_init(dev, dsi);
367 	if (ret)
368 		return ret;
369 
370 	ret = hisi_dsi_ops->parse_dt(pdev, dsi);
371 	if (ret)
372 		goto err_host_unregister;
373 
374 	platform_set_drvdata(pdev, data);
375 
376 	ret = component_add(dev, &dsi_ops);
377 	if (ret)
378 		goto err_host_unregister;
379 
380 	DRM_INFO("-.\n");
381 	return 0;
382 
383 err_host_unregister:
384 	mipi_dsi_host_unregister(&dsi->host);
385 	return ret;
386 }
387 
dsi_remove(struct platform_device * pdev)388 static int dsi_remove(struct platform_device *pdev)
389 {
390 	component_del(&pdev->dev, &dsi_ops);
391 
392 	return 0;
393 }
394 
395 static const struct of_device_id dsi_of_match[] = {
396 #ifdef CONFIG_DRM_HISI_KIRIN960
397 	{
398 		.compatible = "hisilicon,hi3660-dsi",
399 		.data = &kirin_dsi_960,
400 	},
401 #endif
402 #ifdef CONFIG_DRM_HISI_KIRIN620
403 	{
404 		.compatible = "hisilicon,hi6220-dsi",
405 		.data = &kirin_dsi_620,
406 	},
407 #endif
408 	{ /* end node */ }
409 };
410 MODULE_DEVICE_TABLE(of, dsi_of_match);
411 
412 static struct platform_driver dsi_driver = {
413 	.probe = dsi_probe,
414 	.remove = dsi_remove,
415 	.driver = {
416 		.name = "dw-dsi",
417 		.of_match_table = dsi_of_match,
418 	},
419 };
420 
421 module_platform_driver(dsi_driver);
422 
423 MODULE_DESCRIPTION("DesignWare MIPI DSI Host Controller v1.02 driver");
424 MODULE_LICENSE("GPL v2");
425