xref: /linux/drivers/gpu/drm/bridge/ti-tfp410.c (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2016 Texas Instruments
4  * Author: Jyri Sarha <jsarha@ti.com>
5  */
6 
7 #include <linux/gpio/consumer.h>
8 #include <linux/i2c.h>
9 #include <linux/media-bus-format.h>
10 #include <linux/module.h>
11 #include <linux/of_graph.h>
12 #include <linux/platform_device.h>
13 #include <linux/workqueue.h>
14 
15 #include <drm/drm_atomic_helper.h>
16 #include <drm/drm_bridge.h>
17 #include <drm/drm_crtc.h>
18 #include <drm/drm_edid.h>
19 #include <drm/drm_print.h>
20 #include <drm/drm_probe_helper.h>
21 
22 #define HOTPLUG_DEBOUNCE_MS		1100
23 
24 struct tfp410 {
25 	struct drm_bridge	bridge;
26 	struct drm_connector	connector;
27 
28 	u32			bus_format;
29 	struct delayed_work	hpd_work;
30 	struct gpio_desc	*powerdown;
31 
32 	struct drm_bridge_timings timings;
33 
34 	struct device *dev;
35 };
36 
37 static inline struct tfp410 *
38 drm_bridge_to_tfp410(struct drm_bridge *bridge)
39 {
40 	return container_of(bridge, struct tfp410, bridge);
41 }
42 
43 static inline struct tfp410 *
44 drm_connector_to_tfp410(struct drm_connector *connector)
45 {
46 	return container_of(connector, struct tfp410, connector);
47 }
48 
49 static int tfp410_get_modes(struct drm_connector *connector)
50 {
51 	struct tfp410 *dvi = drm_connector_to_tfp410(connector);
52 	const struct drm_edid *drm_edid;
53 	int ret;
54 
55 	if (dvi->bridge.next_bridge->ops & DRM_BRIDGE_OP_EDID) {
56 		drm_edid = drm_bridge_edid_read(dvi->bridge.next_bridge, connector);
57 		if (!drm_edid)
58 			DRM_INFO("EDID read failed. Fallback to standard modes\n");
59 	} else {
60 		drm_edid = NULL;
61 	}
62 
63 	drm_edid_connector_update(connector, drm_edid);
64 
65 	if (!drm_edid) {
66 		/*
67 		 * No EDID, fallback on the XGA standard modes and prefer a mode
68 		 * pretty much anything can handle.
69 		 */
70 		ret = drm_add_modes_noedid(connector, 1920, 1200);
71 		drm_set_preferred_mode(connector, 1024, 768);
72 		return ret;
73 	}
74 
75 	ret = drm_edid_connector_add_modes(connector);
76 
77 	drm_edid_free(drm_edid);
78 
79 	return ret;
80 }
81 
82 static const struct drm_connector_helper_funcs tfp410_con_helper_funcs = {
83 	.get_modes	= tfp410_get_modes,
84 };
85 
86 static enum drm_connector_status
87 tfp410_connector_detect(struct drm_connector *connector, bool force)
88 {
89 	struct tfp410 *dvi = drm_connector_to_tfp410(connector);
90 
91 	return drm_bridge_detect(dvi->bridge.next_bridge, connector);
92 }
93 
94 static const struct drm_connector_funcs tfp410_con_funcs = {
95 	.detect			= tfp410_connector_detect,
96 	.fill_modes		= drm_helper_probe_single_connector_modes,
97 	.destroy		= drm_connector_cleanup,
98 	.reset			= drm_atomic_helper_connector_reset,
99 	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
100 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
101 };
102 
103 static void tfp410_hpd_work_func(struct work_struct *work)
104 {
105 	struct tfp410 *dvi;
106 
107 	dvi = container_of(work, struct tfp410, hpd_work.work);
108 
109 	if (dvi->bridge.dev)
110 		drm_helper_hpd_irq_event(dvi->bridge.dev);
111 }
112 
113 static void tfp410_hpd_callback(void *arg, enum drm_connector_status status)
114 {
115 	struct tfp410 *dvi = arg;
116 
117 	mod_delayed_work(system_percpu_wq, &dvi->hpd_work,
118 			 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
119 }
120 
121 static int tfp410_attach(struct drm_bridge *bridge,
122 			 struct drm_encoder *encoder,
123 			 enum drm_bridge_attach_flags flags)
124 {
125 	struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
126 	int ret;
127 
128 	ret = drm_bridge_attach(encoder, dvi->bridge.next_bridge, bridge,
129 				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
130 	if (ret < 0)
131 		return ret;
132 
133 	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
134 		return 0;
135 
136 	if (dvi->bridge.next_bridge->ops & DRM_BRIDGE_OP_DETECT)
137 		dvi->connector.polled = DRM_CONNECTOR_POLL_HPD;
138 	else
139 		dvi->connector.polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
140 
141 	if (dvi->bridge.next_bridge->ops & DRM_BRIDGE_OP_HPD) {
142 		INIT_DELAYED_WORK(&dvi->hpd_work, tfp410_hpd_work_func);
143 		drm_bridge_hpd_enable(dvi->bridge.next_bridge, tfp410_hpd_callback,
144 				      dvi);
145 	}
146 
147 	drm_connector_helper_add(&dvi->connector,
148 				 &tfp410_con_helper_funcs);
149 	ret = drm_connector_init_with_ddc(bridge->dev, &dvi->connector,
150 					  &tfp410_con_funcs,
151 					  dvi->bridge.next_bridge->type,
152 					  dvi->bridge.next_bridge->ddc);
153 	if (ret) {
154 		dev_err(dvi->dev, "drm_connector_init_with_ddc() failed: %d\n",
155 			ret);
156 		return ret;
157 	}
158 
159 	drm_display_info_set_bus_formats(&dvi->connector.display_info,
160 					 &dvi->bus_format, 1);
161 
162 	drm_connector_attach_encoder(&dvi->connector, encoder);
163 
164 	return 0;
165 }
166 
167 static void tfp410_detach(struct drm_bridge *bridge)
168 {
169 	struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
170 
171 	if (dvi->connector.dev && dvi->bridge.next_bridge->ops & DRM_BRIDGE_OP_HPD) {
172 		drm_bridge_hpd_disable(dvi->bridge.next_bridge);
173 		cancel_delayed_work_sync(&dvi->hpd_work);
174 	}
175 }
176 
177 static void tfp410_enable(struct drm_bridge *bridge,
178 			  struct drm_atomic_commit *commit)
179 {
180 	struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
181 
182 	gpiod_set_value_cansleep(dvi->powerdown, 0);
183 }
184 
185 static void tfp410_disable(struct drm_bridge *bridge,
186 			   struct drm_atomic_commit *commit)
187 {
188 	struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
189 
190 	gpiod_set_value_cansleep(dvi->powerdown, 1);
191 }
192 
193 static enum drm_mode_status tfp410_mode_valid(struct drm_bridge *bridge,
194 					      const struct drm_display_info *info,
195 					      const struct drm_display_mode *mode)
196 {
197 	if (mode->clock < 25000)
198 		return MODE_CLOCK_LOW;
199 
200 	if (mode->clock > 165000)
201 		return MODE_CLOCK_HIGH;
202 
203 	return MODE_OK;
204 }
205 
206 static u32 *tfp410_get_input_bus_fmts(struct drm_bridge *bridge,
207 				      struct drm_bridge_state *bridge_state,
208 				      struct drm_crtc_state *crtc_state,
209 				      struct drm_connector_state *conn_state,
210 				      u32 output_fmt,
211 				      unsigned int *num_input_fmts)
212 {
213 	struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
214 	u32 *input_fmts;
215 
216 	*num_input_fmts = 0;
217 
218 	input_fmts = kzalloc_obj(*input_fmts);
219 	if (!input_fmts)
220 		return NULL;
221 
222 	*num_input_fmts = 1;
223 	input_fmts[0] = dvi->bus_format;
224 
225 	return input_fmts;
226 }
227 
228 static int tfp410_atomic_check(struct drm_bridge *bridge,
229 			       struct drm_bridge_state *bridge_state,
230 			       struct drm_crtc_state *crtc_state,
231 			       struct drm_connector_state *conn_state)
232 {
233 	struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
234 
235 	/*
236 	 * There might be flags negotiation supported in future.
237 	 * Set the bus flags in atomic_check statically for now.
238 	 */
239 	bridge_state->input_bus_cfg.flags = dvi->timings.input_bus_flags;
240 
241 	return 0;
242 }
243 
244 static const struct drm_bridge_funcs tfp410_bridge_funcs = {
245 	.attach		= tfp410_attach,
246 	.detach		= tfp410_detach,
247 	.atomic_enable = tfp410_enable,
248 	.atomic_disable = tfp410_disable,
249 	.mode_valid	= tfp410_mode_valid,
250 	.atomic_create_state = drm_atomic_helper_bridge_create_state,
251 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
252 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
253 	.atomic_get_input_bus_fmts = tfp410_get_input_bus_fmts,
254 	.atomic_check = tfp410_atomic_check,
255 };
256 
257 static const struct drm_bridge_timings tfp410_default_timings = {
258 	.input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE
259 			 | DRM_BUS_FLAG_DE_HIGH,
260 	.setup_time_ps = 1200,
261 	.hold_time_ps = 1300,
262 };
263 
264 static int tfp410_parse_timings(struct tfp410 *dvi, bool i2c)
265 {
266 	struct drm_bridge_timings *timings = &dvi->timings;
267 	struct device_node *ep;
268 	u32 pclk_sample = 0;
269 	u32 bus_width = 24;
270 	u32 deskew = 0;
271 
272 	/* Start with defaults. */
273 	*timings = tfp410_default_timings;
274 
275 	if (i2c)
276 		/*
277 		 * In I2C mode timings are configured through the I2C interface.
278 		 * As the driver doesn't support I2C configuration yet, we just
279 		 * go with the defaults (BSEL=1, DSEL=1, DKEN=0, EDGE=1).
280 		 */
281 		return 0;
282 
283 	/*
284 	 * In non-I2C mode, timings are configured through the BSEL, DSEL, DKEN
285 	 * and EDGE pins. They are specified in DT through endpoint properties
286 	 * and vendor-specific properties.
287 	 */
288 	ep = of_graph_get_endpoint_by_regs(dvi->dev->of_node, 0, 0);
289 	if (!ep)
290 		return -EINVAL;
291 
292 	/* Get the sampling edge from the endpoint. */
293 	of_property_read_u32(ep, "pclk-sample", &pclk_sample);
294 	of_property_read_u32(ep, "bus-width", &bus_width);
295 	of_node_put(ep);
296 
297 	timings->input_bus_flags = DRM_BUS_FLAG_DE_HIGH;
298 
299 	switch (pclk_sample) {
300 	case 0:
301 		timings->input_bus_flags |= DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE
302 					 |  DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE;
303 		break;
304 	case 1:
305 		timings->input_bus_flags |= DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE
306 					 |  DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE;
307 		break;
308 	default:
309 		return -EINVAL;
310 	}
311 
312 	switch (bus_width) {
313 	case 12:
314 		dvi->bus_format = MEDIA_BUS_FMT_RGB888_2X12_LE;
315 		break;
316 	case 24:
317 		dvi->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
318 		break;
319 	default:
320 		return -EINVAL;
321 	}
322 
323 	/* Get the setup and hold time from vendor-specific properties. */
324 	of_property_read_u32(dvi->dev->of_node, "ti,deskew", &deskew);
325 	if (deskew > 7)
326 		return -EINVAL;
327 
328 	timings->setup_time_ps = 1200 - 350 * ((s32)deskew - 4);
329 	timings->hold_time_ps = max(0, 1300 + 350 * ((s32)deskew - 4));
330 
331 	return 0;
332 }
333 
334 static int tfp410_init(struct device *dev, bool i2c)
335 {
336 	struct device_node *node;
337 	struct tfp410 *dvi;
338 	int ret;
339 
340 	if (!dev->of_node) {
341 		dev_err(dev, "device-tree data is missing\n");
342 		return -ENXIO;
343 	}
344 
345 	dvi = devm_drm_bridge_alloc(dev, struct tfp410, bridge,
346 				    &tfp410_bridge_funcs);
347 	if (IS_ERR(dvi))
348 		return PTR_ERR(dvi);
349 
350 	dvi->dev = dev;
351 	dev_set_drvdata(dev, dvi);
352 
353 	dvi->bridge.of_node = dev->of_node;
354 	dvi->bridge.timings = &dvi->timings;
355 	dvi->bridge.type = DRM_MODE_CONNECTOR_DVID;
356 
357 	ret = tfp410_parse_timings(dvi, i2c);
358 	if (ret)
359 		return ret;
360 
361 	/* Get the next bridge, connected to port@1. */
362 	node = of_graph_get_remote_node(dev->of_node, 1, -1);
363 	if (!node)
364 		return -ENODEV;
365 
366 	dvi->bridge.next_bridge = of_drm_find_and_get_bridge(node);
367 	of_node_put(node);
368 
369 	if (!dvi->bridge.next_bridge)
370 		return -EPROBE_DEFER;
371 
372 	/* Get the powerdown GPIO. */
373 	dvi->powerdown = devm_gpiod_get_optional(dev, "powerdown",
374 						 GPIOD_OUT_HIGH);
375 	if (IS_ERR(dvi->powerdown)) {
376 		dev_err(dev, "failed to parse powerdown gpio\n");
377 		return PTR_ERR(dvi->powerdown);
378 	}
379 
380 	/*  Register the DRM bridge. */
381 	drm_bridge_add(&dvi->bridge);
382 
383 	return 0;
384 }
385 
386 static void tfp410_fini(struct device *dev)
387 {
388 	struct tfp410 *dvi = dev_get_drvdata(dev);
389 
390 	drm_bridge_remove(&dvi->bridge);
391 }
392 
393 static int tfp410_probe(struct platform_device *pdev)
394 {
395 	return tfp410_init(&pdev->dev, false);
396 }
397 
398 static void tfp410_remove(struct platform_device *pdev)
399 {
400 	tfp410_fini(&pdev->dev);
401 }
402 
403 static const struct of_device_id tfp410_match[] = {
404 	{ .compatible = "ti,tfp410" },
405 	{},
406 };
407 MODULE_DEVICE_TABLE(of, tfp410_match);
408 
409 static struct platform_driver tfp410_platform_driver = {
410 	.probe	= tfp410_probe,
411 	.remove = tfp410_remove,
412 	.driver	= {
413 		.name		= "tfp410-bridge",
414 		.of_match_table	= tfp410_match,
415 	},
416 };
417 
418 #if IS_ENABLED(CONFIG_I2C)
419 /* There is currently no i2c functionality. */
420 static int tfp410_i2c_probe(struct i2c_client *client)
421 {
422 	int reg;
423 
424 	if (!client->dev.of_node ||
425 	    of_property_read_u32(client->dev.of_node, "reg", &reg)) {
426 		dev_err(&client->dev,
427 			"Can't get i2c reg property from device-tree\n");
428 		return -ENXIO;
429 	}
430 
431 	return tfp410_init(&client->dev, true);
432 }
433 
434 static void tfp410_i2c_remove(struct i2c_client *client)
435 {
436 	tfp410_fini(&client->dev);
437 }
438 
439 static const struct i2c_device_id tfp410_i2c_ids[] = {
440 	{ .name = "tfp410" },
441 	{ }
442 };
443 MODULE_DEVICE_TABLE(i2c, tfp410_i2c_ids);
444 
445 static struct i2c_driver tfp410_i2c_driver = {
446 	.driver = {
447 		.name	= "tfp410",
448 		.of_match_table = tfp410_match,
449 	},
450 	.id_table	= tfp410_i2c_ids,
451 	.probe		= tfp410_i2c_probe,
452 	.remove		= tfp410_i2c_remove,
453 };
454 #endif /* IS_ENABLED(CONFIG_I2C) */
455 
456 static struct {
457 	uint i2c:1;
458 	uint platform:1;
459 }  tfp410_registered_driver;
460 
461 static int __init tfp410_module_init(void)
462 {
463 	int ret;
464 
465 #if IS_ENABLED(CONFIG_I2C)
466 	ret = i2c_add_driver(&tfp410_i2c_driver);
467 	if (ret)
468 		pr_err("%s: registering i2c driver failed: %d",
469 		       __func__, ret);
470 	else
471 		tfp410_registered_driver.i2c = 1;
472 #endif
473 
474 	ret = platform_driver_register(&tfp410_platform_driver);
475 	if (ret)
476 		pr_err("%s: registering platform driver failed: %d",
477 		       __func__, ret);
478 	else
479 		tfp410_registered_driver.platform = 1;
480 
481 	if (tfp410_registered_driver.i2c ||
482 	    tfp410_registered_driver.platform)
483 		return 0;
484 
485 	return ret;
486 }
487 module_init(tfp410_module_init);
488 
489 static void __exit tfp410_module_exit(void)
490 {
491 #if IS_ENABLED(CONFIG_I2C)
492 	if (tfp410_registered_driver.i2c)
493 		i2c_del_driver(&tfp410_i2c_driver);
494 #endif
495 	if (tfp410_registered_driver.platform)
496 		platform_driver_unregister(&tfp410_platform_driver);
497 }
498 module_exit(tfp410_module_exit);
499 
500 MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
501 MODULE_DESCRIPTION("TI TFP410 DVI bridge driver");
502 MODULE_LICENSE("GPL");
503