Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'drm/panel/for-3.15-rc1' of git://anongit.freedesktop.org/tegra/linux into drm-next

drm/panel: Changes for v3.15-rc1

Add support for a couple more simple panels. A few cleanups to the
simple panel driver are also included (gpiod interface conversion,
removal of redundant call to regulator_disable()).

* tag 'drm/panel/for-3.15-rc1' of git://anongit.freedesktop.org/tegra/linux:
drm/panel: add support for LG LD070WX3-SL01 panel
drm/panel: add support for LG LH500WX1-SD03 panel
drm/panel: simple: Allow DSI panels to provide mode flags
drm/panel: simple: Allow GPIO accesses to sleep
drm/panel: remove redundant regulator_disable()
drm/panel: use gpiod interface for enable GPIO
drm/panel: Add LG 12.9" LCD panel
MAINTAINERS: Add entry for DRM panel drivers

Conflicts:
MAINTAINERS

+137 -51
+7
Documentation/devicetree/bindings/panel/lg,ld070wx3-sl01.txt
··· 1 + LG Corporation 7" WXGA TFT LCD panel 2 + 3 + Required properties: 4 + - compatible: should be "lg,ld070wx3-sl01" 5 + 6 + This binding is compatible with the simple-panel binding, which is specified 7 + in simple-panel.txt in this directory.
+7
Documentation/devicetree/bindings/panel/lg,lh500wx1-sd03.txt
··· 1 + LG Corporation 5" HD TFT LCD panel 2 + 3 + Required properties: 4 + - compatible: should be "lg,lh500wx1-sd03" 5 + 6 + This binding is compatible with the simple-panel binding, which is specified 7 + in simple-panel.txt in this directory.
+7
Documentation/devicetree/bindings/panel/lg,lp129qe.txt
··· 1 + LG 12.9" (2560x1700 pixels) TFT LCD panel 2 + 3 + Required properties: 4 + - compatible: should be "lg,lp129qe" 5 + 6 + This binding is compatible with the simple-panel binding, which is specified 7 + in simple-panel.txt in this directory.
+10
MAINTAINERS
··· 2866 2866 F: include/drm/radeon* 2867 2867 F: include/uapi/drm/radeon* 2868 2868 2869 + DRM PANEL DRIVERS 2870 + M: Thierry Reding <thierry.reding@gmail.com> 2871 + L: dri-devel@lists.freedesktop.org 2872 + T: git git://anongit.freedesktop.org/tegra/linux.git 2873 + S: Maintained 2874 + F: drivers/gpu/drm/drm_panel.c 2875 + F: drivers/gpu/drm/panel/ 2876 + F: include/drm/drm_panel.h 2877 + F: Documentation/devicetree/bindings/panel/ 2878 + 2869 2879 INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets) 2870 2880 M: Daniel Vetter <daniel.vetter@ffwll.ch> 2871 2881 M: Jani Nikula <jani.nikula@linux.intel.com>
+106 -51
drivers/gpu/drm/panel/panel-simple.c
··· 22 22 */ 23 23 24 24 #include <linux/backlight.h> 25 - #include <linux/gpio.h> 25 + #include <linux/gpio/consumer.h> 26 26 #include <linux/module.h> 27 - #include <linux/of_gpio.h> 28 27 #include <linux/of_platform.h> 29 28 #include <linux/platform_device.h> 30 29 #include <linux/regulator/consumer.h> ··· 43 44 } size; 44 45 }; 45 46 46 - /* TODO: convert to gpiod_*() API once it's been merged */ 47 - #define GPIO_ACTIVE_LOW (1 << 0) 48 - 49 47 struct panel_simple { 50 48 struct drm_panel base; 51 49 bool enabled; ··· 53 57 struct regulator *supply; 54 58 struct i2c_adapter *ddc; 55 59 56 - unsigned long enable_gpio_flags; 57 - int enable_gpio; 60 + struct gpio_desc *enable_gpio; 58 61 }; 59 62 60 63 static inline struct panel_simple *to_panel_simple(struct drm_panel *panel) ··· 105 110 backlight_update_status(p->backlight); 106 111 } 107 112 108 - if (gpio_is_valid(p->enable_gpio)) { 109 - if (p->enable_gpio_flags & GPIO_ACTIVE_LOW) 110 - gpio_set_value(p->enable_gpio, 1); 111 - else 112 - gpio_set_value(p->enable_gpio, 0); 113 - } 113 + if (p->enable_gpio) 114 + gpiod_set_value_cansleep(p->enable_gpio, 0); 114 115 115 116 regulator_disable(p->supply); 116 117 p->enabled = false; ··· 128 137 return err; 129 138 } 130 139 131 - if (gpio_is_valid(p->enable_gpio)) { 132 - if (p->enable_gpio_flags & GPIO_ACTIVE_LOW) 133 - gpio_set_value(p->enable_gpio, 0); 134 - else 135 - gpio_set_value(p->enable_gpio, 1); 136 - } 140 + if (p->enable_gpio) 141 + gpiod_set_value_cansleep(p->enable_gpio, 1); 137 142 138 143 if (p->backlight) { 139 144 p->backlight->props.power = FB_BLANK_UNBLANK; ··· 172 185 { 173 186 struct device_node *backlight, *ddc; 174 187 struct panel_simple *panel; 175 - enum of_gpio_flags flags; 176 188 int err; 177 189 178 190 panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL); ··· 185 199 if (IS_ERR(panel->supply)) 186 200 return PTR_ERR(panel->supply); 187 201 188 - panel->enable_gpio = of_get_named_gpio_flags(dev->of_node, 189 - "enable-gpios", 0, 190 - &flags); 191 - if (gpio_is_valid(panel->enable_gpio)) { 192 - unsigned int value; 193 - 194 - if (flags & OF_GPIO_ACTIVE_LOW) 195 - panel->enable_gpio_flags |= GPIO_ACTIVE_LOW; 196 - 197 - err = gpio_request(panel->enable_gpio, "enable"); 198 - if (err < 0) { 199 - dev_err(dev, "failed to request GPIO#%u: %d\n", 200 - panel->enable_gpio, err); 202 + panel->enable_gpio = devm_gpiod_get(dev, "enable"); 203 + if (IS_ERR(panel->enable_gpio)) { 204 + err = PTR_ERR(panel->enable_gpio); 205 + if (err != -ENOENT) { 206 + dev_err(dev, "failed to request GPIO: %d\n", err); 201 207 return err; 202 208 } 203 209 204 - value = (panel->enable_gpio_flags & GPIO_ACTIVE_LOW) != 0; 205 - 206 - err = gpio_direction_output(panel->enable_gpio, value); 210 + panel->enable_gpio = NULL; 211 + } else { 212 + err = gpiod_direction_output(panel->enable_gpio, 0); 207 213 if (err < 0) { 208 - dev_err(dev, "failed to setup GPIO%u: %d\n", 209 - panel->enable_gpio, err); 210 - goto free_gpio; 214 + dev_err(dev, "failed to setup GPIO: %d\n", err); 215 + return err; 211 216 } 212 217 } 213 218 ··· 207 230 panel->backlight = of_find_backlight_by_node(backlight); 208 231 of_node_put(backlight); 209 232 210 - if (!panel->backlight) { 211 - err = -EPROBE_DEFER; 212 - goto free_gpio; 213 - } 233 + if (!panel->backlight) 234 + return -EPROBE_DEFER; 214 235 } 215 236 216 237 ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0); ··· 240 265 free_backlight: 241 266 if (panel->backlight) 242 267 put_device(&panel->backlight->dev); 243 - free_gpio: 244 - if (gpio_is_valid(panel->enable_gpio)) 245 - gpio_free(panel->enable_gpio); 246 268 247 269 return err; 248 270 } ··· 258 286 259 287 if (panel->backlight) 260 288 put_device(&panel->backlight->dev); 261 - 262 - if (gpio_is_valid(panel->enable_gpio)) 263 - gpio_free(panel->enable_gpio); 264 - 265 - regulator_disable(panel->supply); 266 289 267 290 return 0; 268 291 } ··· 328 361 }, 329 362 }; 330 363 364 + static const struct drm_display_mode lg_lp129qe_mode = { 365 + .clock = 285250, 366 + .hdisplay = 2560, 367 + .hsync_start = 2560 + 48, 368 + .hsync_end = 2560 + 48 + 32, 369 + .htotal = 2560 + 48 + 32 + 80, 370 + .vdisplay = 1700, 371 + .vsync_start = 1700 + 3, 372 + .vsync_end = 1700 + 3 + 10, 373 + .vtotal = 1700 + 3 + 10 + 36, 374 + .vrefresh = 60, 375 + }; 376 + 377 + static const struct panel_desc lg_lp129qe = { 378 + .modes = &lg_lp129qe_mode, 379 + .num_modes = 1, 380 + .size = { 381 + .width = 272, 382 + .height = 181, 383 + }, 384 + }; 385 + 331 386 static const struct drm_display_mode samsung_ltn101nt05_mode = { 332 387 .clock = 54030, 333 388 .hdisplay = 1024, ··· 382 393 }, { 383 394 .compatible = "chunghwa,claa101wb01", 384 395 .data = &chunghwa_claa101wb01 396 + }, { 397 + .compatible = "lg,lp129qe", 398 + .data = &lg_lp129qe, 385 399 }, { 386 400 .compatible = "samsung,ltn101nt05", 387 401 .data = &samsung_ltn101nt05, ··· 425 433 struct panel_desc_dsi { 426 434 struct panel_desc desc; 427 435 436 + unsigned long flags; 428 437 enum mipi_dsi_pixel_format format; 429 438 unsigned int lanes; 439 + }; 440 + 441 + static const struct drm_display_mode lg_ld070wx3_sl01_mode = { 442 + .clock = 71000, 443 + .hdisplay = 800, 444 + .hsync_start = 800 + 32, 445 + .hsync_end = 800 + 32 + 1, 446 + .htotal = 800 + 32 + 1 + 57, 447 + .vdisplay = 1280, 448 + .vsync_start = 1280 + 28, 449 + .vsync_end = 1280 + 28 + 1, 450 + .vtotal = 1280 + 28 + 1 + 14, 451 + .vrefresh = 60, 452 + }; 453 + 454 + static const struct panel_desc_dsi lg_ld070wx3_sl01 = { 455 + .desc = { 456 + .modes = &lg_ld070wx3_sl01_mode, 457 + .num_modes = 1, 458 + .size = { 459 + .width = 94, 460 + .height = 151, 461 + }, 462 + }, 463 + .flags = MIPI_DSI_MODE_VIDEO, 464 + .format = MIPI_DSI_FMT_RGB888, 465 + .lanes = 4, 466 + }; 467 + 468 + static const struct drm_display_mode lg_lh500wx1_sd03_mode = { 469 + .clock = 67000, 470 + .hdisplay = 720, 471 + .hsync_start = 720 + 12, 472 + .hsync_end = 720 + 12 + 4, 473 + .htotal = 720 + 12 + 4 + 112, 474 + .vdisplay = 1280, 475 + .vsync_start = 1280 + 8, 476 + .vsync_end = 1280 + 8 + 4, 477 + .vtotal = 1280 + 8 + 4 + 12, 478 + .vrefresh = 60, 479 + }; 480 + 481 + static const struct panel_desc_dsi lg_lh500wx1_sd03 = { 482 + .desc = { 483 + .modes = &lg_lh500wx1_sd03_mode, 484 + .num_modes = 1, 485 + .size = { 486 + .width = 62, 487 + .height = 110, 488 + }, 489 + }, 490 + .flags = MIPI_DSI_MODE_VIDEO, 491 + .format = MIPI_DSI_FMT_RGB888, 492 + .lanes = 4, 430 493 }; 431 494 432 495 static const struct drm_display_mode panasonic_vvx10f004b00_mode = { ··· 506 459 .height = 136, 507 460 }, 508 461 }, 462 + .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE, 509 463 .format = MIPI_DSI_FMT_RGB888, 510 464 .lanes = 4, 511 465 }; 512 466 513 467 static const struct of_device_id dsi_of_match[] = { 514 468 { 469 + .compatible = "lg,ld070wx3-sl01", 470 + .data = &lg_ld070wx3_sl01 471 + }, { 472 + .compatible = "lg,lh500wx1-sd03", 473 + .data = &lg_lh500wx1_sd03 474 + }, { 515 475 .compatible = "panasonic,vvx10f004b00", 516 476 .data = &panasonic_vvx10f004b00 517 477 }, { ··· 543 489 if (err < 0) 544 490 return err; 545 491 492 + dsi->mode_flags = desc->flags; 546 493 dsi->format = desc->format; 547 494 dsi->lanes = desc->lanes; 548 495