aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tilcdc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/tilcdc')
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.c61
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_panel.c74
2 files changed, 108 insertions, 27 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 6be623b4a86f..79a34cbd29f5 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -84,6 +84,7 @@ static int modeset_init(struct drm_device *dev)
84 if ((priv->num_encoders == 0) || (priv->num_connectors == 0)) { 84 if ((priv->num_encoders == 0) || (priv->num_connectors == 0)) {
85 /* oh nos! */ 85 /* oh nos! */
86 dev_err(dev->dev, "no encoders/connectors found\n"); 86 dev_err(dev->dev, "no encoders/connectors found\n");
87 drm_mode_config_cleanup(dev);
87 return -ENXIO; 88 return -ENXIO;
88 } 89 }
89 90
@@ -172,33 +173,37 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
172 dev->dev_private = priv; 173 dev->dev_private = priv;
173 174
174 priv->wq = alloc_ordered_workqueue("tilcdc", 0); 175 priv->wq = alloc_ordered_workqueue("tilcdc", 0);
176 if (!priv->wq) {
177 ret = -ENOMEM;
178 goto fail_free_priv;
179 }
175 180
176 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 181 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
177 if (!res) { 182 if (!res) {
178 dev_err(dev->dev, "failed to get memory resource\n"); 183 dev_err(dev->dev, "failed to get memory resource\n");
179 ret = -EINVAL; 184 ret = -EINVAL;
180 goto fail; 185 goto fail_free_wq;
181 } 186 }
182 187
183 priv->mmio = ioremap_nocache(res->start, resource_size(res)); 188 priv->mmio = ioremap_nocache(res->start, resource_size(res));
184 if (!priv->mmio) { 189 if (!priv->mmio) {
185 dev_err(dev->dev, "failed to ioremap\n"); 190 dev_err(dev->dev, "failed to ioremap\n");
186 ret = -ENOMEM; 191 ret = -ENOMEM;
187 goto fail; 192 goto fail_free_wq;
188 } 193 }
189 194
190 priv->clk = clk_get(dev->dev, "fck"); 195 priv->clk = clk_get(dev->dev, "fck");
191 if (IS_ERR(priv->clk)) { 196 if (IS_ERR(priv->clk)) {
192 dev_err(dev->dev, "failed to get functional clock\n"); 197 dev_err(dev->dev, "failed to get functional clock\n");
193 ret = -ENODEV; 198 ret = -ENODEV;
194 goto fail; 199 goto fail_iounmap;
195 } 200 }
196 201
197 priv->disp_clk = clk_get(dev->dev, "dpll_disp_ck"); 202 priv->disp_clk = clk_get(dev->dev, "dpll_disp_ck");
198 if (IS_ERR(priv->clk)) { 203 if (IS_ERR(priv->clk)) {
199 dev_err(dev->dev, "failed to get display clock\n"); 204 dev_err(dev->dev, "failed to get display clock\n");
200 ret = -ENODEV; 205 ret = -ENODEV;
201 goto fail; 206 goto fail_put_clk;
202 } 207 }
203 208
204#ifdef CONFIG_CPU_FREQ 209#ifdef CONFIG_CPU_FREQ
@@ -208,7 +213,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
208 CPUFREQ_TRANSITION_NOTIFIER); 213 CPUFREQ_TRANSITION_NOTIFIER);
209 if (ret) { 214 if (ret) {
210 dev_err(dev->dev, "failed to register cpufreq notifier\n"); 215 dev_err(dev->dev, "failed to register cpufreq notifier\n");
211 goto fail; 216 goto fail_put_disp_clk;
212 } 217 }
213#endif 218#endif
214 219
@@ -253,13 +258,13 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
253 ret = modeset_init(dev); 258 ret = modeset_init(dev);
254 if (ret < 0) { 259 if (ret < 0) {
255 dev_err(dev->dev, "failed to initialize mode setting\n"); 260 dev_err(dev->dev, "failed to initialize mode setting\n");
256 goto fail; 261 goto fail_cpufreq_unregister;
257 } 262 }
258 263
259 ret = drm_vblank_init(dev, 1); 264 ret = drm_vblank_init(dev, 1);
260 if (ret < 0) { 265 if (ret < 0) {
261 dev_err(dev->dev, "failed to initialize vblank\n"); 266 dev_err(dev->dev, "failed to initialize vblank\n");
262 goto fail; 267 goto fail_mode_config_cleanup;
263 } 268 }
264 269
265 pm_runtime_get_sync(dev->dev); 270 pm_runtime_get_sync(dev->dev);
@@ -267,7 +272,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
267 pm_runtime_put_sync(dev->dev); 272 pm_runtime_put_sync(dev->dev);
268 if (ret < 0) { 273 if (ret < 0) {
269 dev_err(dev->dev, "failed to install IRQ handler\n"); 274 dev_err(dev->dev, "failed to install IRQ handler\n");
270 goto fail; 275 goto fail_vblank_cleanup;
271 } 276 }
272 277
273 platform_set_drvdata(pdev, dev); 278 platform_set_drvdata(pdev, dev);
@@ -283,13 +288,48 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
283 priv->fbdev = drm_fbdev_cma_init(dev, bpp, 288 priv->fbdev = drm_fbdev_cma_init(dev, bpp,
284 dev->mode_config.num_crtc, 289 dev->mode_config.num_crtc,
285 dev->mode_config.num_connector); 290 dev->mode_config.num_connector);
291 if (IS_ERR(priv->fbdev)) {
292 ret = PTR_ERR(priv->fbdev);
293 goto fail_irq_uninstall;
294 }
286 295
287 drm_kms_helper_poll_init(dev); 296 drm_kms_helper_poll_init(dev);
288 297
289 return 0; 298 return 0;
290 299
291fail: 300fail_irq_uninstall:
292 tilcdc_unload(dev); 301 pm_runtime_get_sync(dev->dev);
302 drm_irq_uninstall(dev);
303 pm_runtime_put_sync(dev->dev);
304
305fail_vblank_cleanup:
306 drm_vblank_cleanup(dev);
307
308fail_mode_config_cleanup:
309 drm_mode_config_cleanup(dev);
310
311fail_cpufreq_unregister:
312 pm_runtime_disable(dev->dev);
313#ifdef CONFIG_CPU_FREQ
314 cpufreq_unregister_notifier(&priv->freq_transition,
315 CPUFREQ_TRANSITION_NOTIFIER);
316fail_put_disp_clk:
317 clk_put(priv->disp_clk);
318#endif
319
320fail_put_clk:
321 clk_put(priv->clk);
322
323fail_iounmap:
324 iounmap(priv->mmio);
325
326fail_free_wq:
327 flush_workqueue(priv->wq);
328 destroy_workqueue(priv->wq);
329
330fail_free_priv:
331 dev->dev_private = NULL;
332 kfree(priv);
293 return ret; 333 return ret;
294} 334}
295 335
@@ -502,6 +542,7 @@ static struct drm_driver tilcdc_driver = {
502 .unload = tilcdc_unload, 542 .unload = tilcdc_unload,
503 .preclose = tilcdc_preclose, 543 .preclose = tilcdc_preclose,
504 .lastclose = tilcdc_lastclose, 544 .lastclose = tilcdc_lastclose,
545 .set_busid = drm_platform_set_busid,
505 .irq_handler = tilcdc_irq, 546 .irq_handler = tilcdc_irq,
506 .irq_preinstall = tilcdc_irq_preinstall, 547 .irq_preinstall = tilcdc_irq_preinstall,
507 .irq_postinstall = tilcdc_irq_postinstall, 548 .irq_postinstall = tilcdc_irq_postinstall,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
index 4c7aa1d8134f..7a0315855e90 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
@@ -18,6 +18,7 @@
18#include <linux/pinctrl/pinmux.h> 18#include <linux/pinctrl/pinmux.h>
19#include <linux/pinctrl/consumer.h> 19#include <linux/pinctrl/consumer.h>
20#include <linux/backlight.h> 20#include <linux/backlight.h>
21#include <linux/gpio/consumer.h>
21#include <video/display_timing.h> 22#include <video/display_timing.h>
22#include <video/of_display_timing.h> 23#include <video/of_display_timing.h>
23#include <video/videomode.h> 24#include <video/videomode.h>
@@ -29,6 +30,7 @@ struct panel_module {
29 struct tilcdc_panel_info *info; 30 struct tilcdc_panel_info *info;
30 struct display_timings *timings; 31 struct display_timings *timings;
31 struct backlight_device *backlight; 32 struct backlight_device *backlight;
33 struct gpio_desc *enable_gpio;
32}; 34};
33#define to_panel_module(x) container_of(x, struct panel_module, base) 35#define to_panel_module(x) container_of(x, struct panel_module, base)
34 36
@@ -55,13 +57,17 @@ static void panel_encoder_dpms(struct drm_encoder *encoder, int mode)
55{ 57{
56 struct panel_encoder *panel_encoder = to_panel_encoder(encoder); 58 struct panel_encoder *panel_encoder = to_panel_encoder(encoder);
57 struct backlight_device *backlight = panel_encoder->mod->backlight; 59 struct backlight_device *backlight = panel_encoder->mod->backlight;
60 struct gpio_desc *gpio = panel_encoder->mod->enable_gpio;
58 61
59 if (!backlight) 62 if (backlight) {
60 return; 63 backlight->props.power = mode == DRM_MODE_DPMS_ON ?
64 FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
65 backlight_update_status(backlight);
66 }
61 67
62 backlight->props.power = mode == DRM_MODE_DPMS_ON 68 if (gpio)
63 ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; 69 gpiod_set_value_cansleep(gpio,
64 backlight_update_status(backlight); 70 mode == DRM_MODE_DPMS_ON ? 1 : 0);
65} 71}
66 72
67static bool panel_encoder_mode_fixup(struct drm_encoder *encoder, 73static bool panel_encoder_mode_fixup(struct drm_encoder *encoder,
@@ -311,6 +317,7 @@ static struct tilcdc_panel_info *of_get_panel_info(struct device_node *np)
311 info = kzalloc(sizeof(*info), GFP_KERNEL); 317 info = kzalloc(sizeof(*info), GFP_KERNEL);
312 if (!info) { 318 if (!info) {
313 pr_err("%s: allocation failed\n", __func__); 319 pr_err("%s: allocation failed\n", __func__);
320 of_node_put(info_np);
314 return NULL; 321 return NULL;
315 } 322 }
316 323
@@ -331,22 +338,21 @@ static struct tilcdc_panel_info *of_get_panel_info(struct device_node *np)
331 if (ret) { 338 if (ret) {
332 pr_err("%s: error reading panel-info properties\n", __func__); 339 pr_err("%s: error reading panel-info properties\n", __func__);
333 kfree(info); 340 kfree(info);
341 of_node_put(info_np);
334 return NULL; 342 return NULL;
335 } 343 }
344 of_node_put(info_np);
336 345
337 return info; 346 return info;
338} 347}
339 348
340static struct of_device_id panel_of_match[];
341
342static int panel_probe(struct platform_device *pdev) 349static int panel_probe(struct platform_device *pdev)
343{ 350{
344 struct device_node *node = pdev->dev.of_node; 351 struct device_node *bl_node, *node = pdev->dev.of_node;
345 struct panel_module *panel_mod; 352 struct panel_module *panel_mod;
346 struct tilcdc_module *mod; 353 struct tilcdc_module *mod;
347 struct pinctrl *pinctrl; 354 struct pinctrl *pinctrl;
348 int ret = -EINVAL; 355 int ret;
349
350 356
351 /* bail out early if no DT data: */ 357 /* bail out early if no DT data: */
352 if (!node) { 358 if (!node) {
@@ -354,10 +360,40 @@ static int panel_probe(struct platform_device *pdev)
354 return -ENXIO; 360 return -ENXIO;
355 } 361 }
356 362
357 panel_mod = kzalloc(sizeof(*panel_mod), GFP_KERNEL); 363 panel_mod = devm_kzalloc(&pdev->dev, sizeof(*panel_mod), GFP_KERNEL);
358 if (!panel_mod) 364 if (!panel_mod)
359 return -ENOMEM; 365 return -ENOMEM;
360 366
367 bl_node = of_parse_phandle(node, "backlight", 0);
368 if (bl_node) {
369 panel_mod->backlight = of_find_backlight_by_node(bl_node);
370 of_node_put(bl_node);
371
372 if (!panel_mod->backlight)
373 return -EPROBE_DEFER;
374
375 dev_info(&pdev->dev, "found backlight\n");
376 }
377
378 panel_mod->enable_gpio = devm_gpiod_get(&pdev->dev, "enable");
379 if (IS_ERR(panel_mod->enable_gpio)) {
380 ret = PTR_ERR(panel_mod->enable_gpio);
381 if (ret != -ENOENT) {
382 dev_err(&pdev->dev, "failed to request enable GPIO\n");
383 goto fail_backlight;
384 }
385
386 /* Optional GPIO is not here, continue silently. */
387 panel_mod->enable_gpio = NULL;
388 } else {
389 ret = gpiod_direction_output(panel_mod->enable_gpio, 0);
390 if (ret < 0) {
391 dev_err(&pdev->dev, "failed to setup GPIO\n");
392 goto fail_backlight;
393 }
394 dev_info(&pdev->dev, "found enable GPIO\n");
395 }
396
361 mod = &panel_mod->base; 397 mod = &panel_mod->base;
362 pdev->dev.platform_data = mod; 398 pdev->dev.platform_data = mod;
363 399
@@ -370,29 +406,30 @@ static int panel_probe(struct platform_device *pdev)
370 panel_mod->timings = of_get_display_timings(node); 406 panel_mod->timings = of_get_display_timings(node);
371 if (!panel_mod->timings) { 407 if (!panel_mod->timings) {
372 dev_err(&pdev->dev, "could not get panel timings\n"); 408 dev_err(&pdev->dev, "could not get panel timings\n");
409 ret = -EINVAL;
373 goto fail_free; 410 goto fail_free;
374 } 411 }
375 412
376 panel_mod->info = of_get_panel_info(node); 413 panel_mod->info = of_get_panel_info(node);
377 if (!panel_mod->info) { 414 if (!panel_mod->info) {
378 dev_err(&pdev->dev, "could not get panel info\n"); 415 dev_err(&pdev->dev, "could not get panel info\n");
416 ret = -EINVAL;
379 goto fail_timings; 417 goto fail_timings;
380 } 418 }
381 419
382 mod->preferred_bpp = panel_mod->info->bpp; 420 mod->preferred_bpp = panel_mod->info->bpp;
383 421
384 panel_mod->backlight = of_find_backlight_by_node(node);
385 if (panel_mod->backlight)
386 dev_info(&pdev->dev, "found backlight\n");
387
388 return 0; 422 return 0;
389 423
390fail_timings: 424fail_timings:
391 display_timings_release(panel_mod->timings); 425 display_timings_release(panel_mod->timings);
392 426
393fail_free: 427fail_free:
394 kfree(panel_mod);
395 tilcdc_module_cleanup(mod); 428 tilcdc_module_cleanup(mod);
429
430fail_backlight:
431 if (panel_mod->backlight)
432 put_device(&panel_mod->backlight->dev);
396 return ret; 433 return ret;
397} 434}
398 435
@@ -400,12 +437,15 @@ static int panel_remove(struct platform_device *pdev)
400{ 437{
401 struct tilcdc_module *mod = dev_get_platdata(&pdev->dev); 438 struct tilcdc_module *mod = dev_get_platdata(&pdev->dev);
402 struct panel_module *panel_mod = to_panel_module(mod); 439 struct panel_module *panel_mod = to_panel_module(mod);
440 struct backlight_device *backlight = panel_mod->backlight;
441
442 if (backlight)
443 put_device(&backlight->dev);
403 444
404 display_timings_release(panel_mod->timings); 445 display_timings_release(panel_mod->timings);
405 446
406 tilcdc_module_cleanup(mod); 447 tilcdc_module_cleanup(mod);
407 kfree(panel_mod->info); 448 kfree(panel_mod->info);
408 kfree(panel_mod);
409 449
410 return 0; 450 return 0;
411} 451}