aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tilcdc/tilcdc_panel.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-14 03:39:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-14 03:39:08 -0400
commit2d65a9f48fcdf7866aab6457bc707ca233e0c791 (patch)
treef93e5838d6ac2e59434367f4ff905f7d9c45fc2b /drivers/gpu/drm/tilcdc/tilcdc_panel.c
parentda92da3638a04894afdca8b99e973ddd20268471 (diff)
parentdfda0df3426483cf5fc7441f23f318edbabecb03 (diff)
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie: "This is the main git pull for the drm, I pretty much froze major pulls at -rc5/6 time, and haven't had much fallout, so will probably continue doing that. Lots of changes all over, big internal header cleanup to make it clear drm features are legacy things and what are things that modern KMS drivers should be using. Also big move to use the new generic fences in all the TTM drivers. core: atomic prep work, vblank rework changes, allows immediate vblank disables major header reworking and cleanups to better delinate legacy interfaces from what KMS drivers should be using. cursor planes locking fixes ttm: move to generic fences (affects all TTM drivers) ppc64 caching fixes radeon: userptr support, uvd for old asics, reset rework for fence changes better buffer placement changes, dpm feature enablement hdmi audio support fixes intel: Cherryview work, 180 degree rotation, skylake prep work, execlist command submission full ppgtt prep work cursor improvements edid caching, vdd handling improvements nouveau: fence reworking kepler memory clock work gt21x clock work fan control improvements hdmi infoframe fixes DP audio ast: ppc64 fixes caching fix rcar: rcar-du DT support ipuv3: prep work for capture support msm: LVDS support for mdp4, new panel, gpu refactoring exynos: exynos3250 SoC support, drop bad mmap interface, mipi dsi changes, and component match support" * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (640 commits) drm/mst: rework payload table allocation to conform better. drm/ast: Fix HW cursor image drm/radeon/kv: add uvd/vce info to dpm debugfs output drm/radeon/ci: add uvd/vce info to dpm debugfs output drm/radeon: export reservation_object from dmabuf to ttm drm/radeon: cope with foreign fences inside the reservation object drm/radeon: cope with foreign fences inside display drm/core: use helper to check driver features drm/radeon/cik: write gfx ucode version to ucode addr reg drm/radeon/si: print full CS when we hit a packet 0 drm/radeon: remove unecessary includes drm/radeon/combios: declare legacy_connector_convert as static drm/radeon/atombios: declare connector convert tables as static drm/radeon: drop btc_get_max_clock_from_voltage_dependency_table drm/radeon/dpm: drop clk/voltage dependency filters for BTC drm/radeon/dpm: drop clk/voltage dependency filters for CI drm/radeon/dpm: drop clk/voltage dependency filters for SI drm/radeon/dpm: drop clk/voltage dependency filters for NI drm/radeon: disable audio when we disable hdmi (v2) drm/radeon: split audio enable between eg and r600 (v2) ...
Diffstat (limited to 'drivers/gpu/drm/tilcdc/tilcdc_panel.c')
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_panel.c74
1 files changed, 57 insertions, 17 deletions
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}