drm/panel: Add JDI LT070ME05000 WUXGA DSI Panel
Subsystems (4)
PATCH 1/1 drm/panel: Add JDI LT070ME05000 WUXGA DSI Panel
Add support for the JDI lt070me05000 WUXGA DSI panel used in Nexus 7 2013 devices.
Programming sequence for the panel is was originally found in the android-msm-flo-3.4-lollipop-release branch from:
https://android.googlesource.com/kernel/msm.git
And video mode setting is from dsi-panel-jdi-dualmipi1-video.dtsi file in:
git://codeaurora.org/kernel/msm-3.10.git LNX.LA.3.6_rb1.27
Other fixes folded in were provided
by Archit Taneja <[email protected]>
[jstultz: Cherry-picked to mainline, folded down other fixes
from Vinay and Archit]
--- .../bindings/display/panel/jdi,lt070me05000.txt | 27 + .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 685 +++++++++++++++++++++ 5 files changed, 725 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt create mode 100644 drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +27 -0
@@ -0,0 +1,27 @@ +JDI model LT070ME05000 1920x1200 7" DSI Panel + +Basic data sheet is at: + http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet + +This panel has video mode implemented currently in the driver. + +Required properties: +- compatible: should be "jdi,lt070me05000" + +Optional properties: +- power-supply: phandle of the regulator that provides the supply voltage +- reset-gpio: phandle of gpio for reset line +- backlight: phandle of the backlight device attached to the panel + +Example: + + dsi@54300000 { + panel: panel@0 { + compatible = "jdi,lt070me05000"; + reg = <0>; + + power-supply = <...>; + reset-gpio = <...>; + backlight = <...>; + }; + };
Documentation/devicetree/bindings/vendor-prefixes.txt +1 -0
@@ -130,6 +130,7 @@ invensense InvenSense Inc. isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jdi Japan Display Inc. jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH keymile Keymile GmbH
drivers/gpu/drm/panel/Kconfig +11 -0
@@ -61,6 +61,17 @@ config DRM_PANEL_SHARP_LQ101R1SX01 To compile this driver as a module, choose M here: the module will be called panel-sharp-lq101r1sx01. +config DRM_PANEL_JDI_LT070ME05000 + tristate "JDI LT070ME05000 WUXGA DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for JDI WUXGA DSI video/ + command mode panel as found in Google Nexus 7 (2013) devices. + The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses + 24 bit RGB per pixel. + config DRM_PANEL_SHARP_LS043T1LE01 tristate "Sharp LS043T1LE01 qHD video mode panel" depends on OF
drivers/gpu/drm/panel/Makefile +1 -0
@@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o +obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +685 -0
685 lines not on this page · raw message
Signature · 6 lines
2.1.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 20 lines · Vinay Simha BN
Add support for the JDI lt070me05000 WUXGA DSI panel used in Nexus 7 2013 devices.
Programming sequence for the panel is was originally found in the android-msm-flo-3.4-lollipop-release branch from:
https://android.googlesource.com/kernel/msm.gitAnd video mode setting is from
dsi-panel-jdi-dualmipi1-video.dtsifile in:git://codeaurora.org/kernel/msm-3.10.git LNX.LA.3.6_rb1.27Other fixes folded in were provided
by Archit Taneja <[email protected]>Signed-off-by Vinay Simha BN <[email protected]>[sumit.semwal: Ported to the drm/panel framework]Signed-off-by Sumit Semwal <[email protected]>[jstultz: Cherry-picked to mainline, folded down other fixes
from Vinay and Archit]Signed-off-by John Stultz <[email protected]>
Quoted 9 lines
--- .../bindings/display/panel/jdi,lt070me05000.txt | 27 + .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 685 +++++++++++++++++++++ 5 files changed, 725 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt create mode 100644 drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
What's the difference between this and the patch you sent earlier? I'm going to assume that the newer one is the correct patch, so I'll ignore the previous patch.
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt
Quoted 5 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +0
-0
The binding documentation should be a separate patch.
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 6
Quoted 7 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +6
-0@@ -0,0 +1,27 @@ +JDI model LT070ME05000 1920x1200 7" DSI Panel + +Basic data sheet is at: + http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet + +This panel has video mode implemented currently in the driver.
That's information irrelevant to the DT binding, since you're presumably talking about the Linux drm/panel driver, whereas the DT binding is supposed to specify the description of the panel hardware in OS-agnostic terms.
Quoted 25 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +20
-0+Required properties: +- compatible: should be "jdi,lt070me05000" + +Optional properties: +- power-supply: phandle of the regulator that provides the supply voltage +- reset-gpio: phandle of gpio for reset line +- backlight: phandle of the backlight device attached to the panel + +Example: + + dsi@54300000 { + panel: panel@0 { + compatible = "jdi,lt070me05000"; + reg = <0>; + + power-supply = <...>; + reset-gpio = <...>; + backlight = <...>; + }; + };Documentation/devicetree/bindings/vendor-prefixes.txt +0
-0
Documentation/devicetree/bindings/vendor-prefixes.txt invensense InvenSense Inc. · line 136
Quoted 7 lines
Documentation/devicetree/bindings/vendor-prefixes.txt +1
-0@@ -130,6 +130,7 @@ invensense InvenSense Inc. isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jdi Japan Display Inc. jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH keymile Keymile GmbH
This should be a separate patch as well.
Quoted 12 lines
drivers/gpu/drm/panel/Kconfig +4
-0@@ -61,6 +61,17 @@ config DRM_PANEL_SHARP_LQ101R1SX01 To compile this driver as a module, choose M here: the module will be called panel-sharp-lq101r1sx01. +config DRM_PANEL_JDI_LT070ME05000 + tristate "JDI LT070ME05000 WUXGA DSI panel" + depends on OF + depends on DRM_MIPI_DSI
drivers/gpu/drm/panel/Kconfig config DRM_PANEL_SHARP_LQ101R1SX01 · line 77
Quoted 10 lines
drivers/gpu/drm/panel/Kconfig +7
-0+ depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for JDI WUXGA DSI video/ + command mode panel as found in Google Nexus 7 (2013) devices. + The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses + 24 bit RGB per pixel. + config DRM_PANEL_SHARP_LS043T1LE01 tristate "Sharp LS043T1LE01 qHD video mode panel" depends on OF
Please keep these sorted alphabetically. I do realize that the list isn't sorted quite correctly at the moment, so you may as well leave this as-is and I'll fix up the order when applying and after fixing the current ordering.
drivers/gpu/drm/panel/Makefile obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o · line 8
Quoted 9 lines
drivers/gpu/drm/panel/Makefile +1
-0@@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o +obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
Same here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 6
Quoted 12 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0@@ -0,0 +1,685 @@ +/* +* Copyright (C) 2015 InforceComputing +* Author: Vinay Simha BN <[email protected]> +* +* Copyright (C) 2015 Linaro Ltd +* Author: Sumit Semwal <[email protected]>
Should either of those copyright lines include 2016? We're a pretty good way into 2016, and I'd be surprised if this wasn't touched this year at all.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 38
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+/* +* From internet archives, the panel for Nexus 7 2nd Gen, 2013 model is a +* JDI model LT070ME05000, and its data sheet is at: +* http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet +*/
This comment is oddly placed here above the struct jdi_panel definition. Perhaps move that information into the header comment?
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 43
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+struct jdi_panel { +struct drm_panel base; +struct mipi_dsi_device *dsi; + +/* TODO: Add backilght support */
"backlight". Also if this is still TODO, why even have parts of the code here? Just drop everything that's not used and move that to a follow-up patch that implements full support.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 54
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+struct backlight_device *backlight; +struct regulator *supply; +struct gpio_desc *reset_gpio; +struct gpio_desc *enable_gpio; +struct gpio_desc *vcc_gpio; + +struct regulator *backlit; +struct regulator *lvs7; +struct regulator *avdd; +struct regulator *iovdd; +struct gpio_desc *pwm_gpio;
Most of these resources aren't specified in the device tree binding, so your driver doesn't properly implement the binding. You'll have to fix the driver or the binding.
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+ +bool prepared; +bool enabled; + +const struct drm_display_mode *mode;
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 69
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+}; + +static inline struct jdi_panel *to_jdi_panel (struct drm_panel *panel) +{ + return container_of(panel, struct jdi_panel, base); +} + +static char MCAP [2 ] = {0xB0 ,0x00 }; +static char interface_setting_cmd[6 ] = {0xB3 ,0x04 ,0x08 ,0x00 ,0x22 ,0x00 }; +static char interface_setting[6 ] = {0xB3 ,0x26 ,0x08 ,0x00 ,0x20 ,0x00 };
Please make all of these (and the ones below) arrays of u8, since that's the type used in the prototype of the function that receives these as parameters. Also, please use consistent capitalization and a space after { and before }.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 74
Quoted 4 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +4
-0+static char interface_ID_setting[2 ] = {0xB4 ,0x0C }; +static char DSI_control[3 ] = {0xB6 ,0x3A ,0xD3 }; + +static char tear_scan_line[3 ] = {0x44 ,0x03 ,0x00 };
This is a standard DCS command, please turn this into a generic helper such as mipi_dsi_dcs_set_tear_scanline().
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 81
Quoted 6 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0+/* for fps control, set fps to 60.32Hz */ +static char LTPS_timing_setting[2 ] = {0xC6 ,0x78 }; +static char sequencer_timing_control[2 ] = {0xD6 ,0x01 }; + +/* set brightness */ +static char write_display_brightness[] = {0x51 ,0xFF };
Same here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 83
Quoted 2 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +2
-0+/* enable LEDPWM pin output, turn on LEDPWM output, turn off pwm dimming */ +static char write_control_display[] = {0x53 ,0x24 };
And here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 88
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+/* +* choose cabc mode, 0x00(-0%), 0x01(-15%), 0x02(-40%), 0x03(-54%), +* disable SRE(sunlight readability enhancement) +*/ +static char write_cabc[] = {0x55 ,0x00 };
And here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 112
Quoted 13 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +13
-0+static int jdi_panel_init (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + +if (dsi->mode_flags &MIPI_DSI_MODE_VIDEO ) { + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret; + +mdelay (10 );
Please don't use mdelay() because it will busy-loop for a very long time and waste precious CPU cycles. Instead, use usleep_range() for these cases (or msleep() for durations longer than ~10 ms). Same goes for the other occurrences below.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 116
Quoted 4 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +4
-0+ + ret =mipi_dsi_dcs_set_pixel_format (dsi,0x70 ); +if (ret <0 ) +return ret;
There are symbolic constants for the pixel formats, use them to convey meaning.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 124
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +8
-0+ + ret =mipi_dsi_dcs_set_column_address (dsi,0x0000 ,0x04AF ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_page_address (dsi,0x0000 ,0x077F ); +if (ret <0 ) +return ret;
These should be parameterized on the panel width and height, to make it clear where the values come from.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 135
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+ + ret =mipi_dsi_dcs_set_tear_on (dsi, +MIPI_DSI_DCS_TEAR_MODE_VBLANK ); +if (ret <0 ) +return ret; +mdelay (5 ); + + ret =mipi_dsi_generic_write (dsi, tear_scan_line, +sizeof (tear_scan_line)); +if (ret <0 ) +return ret;
Like I mentioned earlier, this should be a generic helper to help make its intention clearer.
Quoted 6 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0+ + ret =mipi_dsi_dcs_write_buffer (dsi, write_display_brightness, +sizeof (write_display_brightness) + ); +if (ret <0 ) +return ret;
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 151
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ + ret =mipi_dsi_dcs_write_buffer (dsi, write_control_display, +sizeof (write_control_display)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_cabc, +sizeof (write_cabc)); +if (ret <0 ) +return ret;
Same for these. I don't currently have access to the DCS 1.3 specification, but I suspect that some of the parameters for these commands could be defined via symbolic names.
Quoted 20 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +20
-0+ + ret =mipi_dsi_dcs_exit_sleep_mode (dsi); +if (ret <0 ) +return ret; +mdelay (120 ); + + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret; +mdelay (10 ); + + ret =mipi_dsi_generic_write (dsi, interface_setting, +sizeof (interface_setting)); +if (ret <0 ) +return ret; +mdelay (20 ); + + backlight_control4[18 ] =0x04 ; + backlight_control4[19 ] =0x00 ; +
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 181
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ ret =mipi_dsi_generic_write (dsi, backlight_control4, +sizeof (backlight_control4)); +if (ret <0 ) +return ret; +mdelay (20 ); + +MCAP [1 ] =0x03 ; + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret;
That's odd. Doesn't this break idempotence of this function? You modify the global MCAP array by writing 0x03 to MCAP[1], so when this function is called a second time, MCAP[1] will be 0x03 already in the first call a few lines above, instead of the 0x00 that it was initially.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 189
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +8
-0+ }else { +/* +* TODO : need to verify panel settings when +* dsi cmd mode supported for apq8064 - simhavcs +*/ + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret;
This whole else clause is dead code because the condition for the if clause is always true. Just drop it and add it back when you properly support both modes.
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+static int jdi_panel_on (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + + ret =mipi_dsi_dcs_set_display_on (dsi); +if (ret <0 ) +return ret;
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 298
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ +return 0 ; +} + +static int jdi_panel_off (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM ;
Should this not be cleared at the end of the function so that the below commands still get run in LP mode?
Quoted 16 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +16
-0+ + ret =mipi_dsi_dcs_set_display_off (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_enter_sleep_mode (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_tear_off (dsi); +if (ret <0 ) +return ret; + +msleep (100 ); + +return 0 ;
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 324
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+} + +static int jdi_panel_disable (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); + +if (!jdi->enabled) +return 0 ; + +DRM_DEBUG ("disable\n" );
This doesn't look very useful debug information. I think you should remove it. Same for other similar occurrences below.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 512
Quoted 13 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +13
-0+static const struct drm_panel_funcs jdi_panel_funcs = { + .disable = jdi_panel_disable, + .unprepare = jdi_panel_unprepare, + .prepare = jdi_panel_prepare, + .enable = jdi_panel_enable, + .get_modes = jdi_panel_get_modes, +}; + +static const struct of_device_id jdi_of_match[] = { + { .compatible ="jdi,lt070me05000" , }, + { } +}; +MODULE_DEVICE_TABLE (of, jdi_of_match);
A single tab is enough to indent the above.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 519
Quoted 6 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0+static int jdi_panel_add (struct jdi_panel *jdi) +{ +struct device *dev = &jdi->dsi->dev; +int ret; + + jdi->mode = &default_mode;
What do you keep this around for?
Quoted 48 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +48
-0+ +/* lvs5 */ + jdi->supply =devm_regulator_get (dev,"power" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply); + +/* l17 */ + jdi->backlit =devm_regulator_get (dev,"backlit" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply); + + jdi->lvs7 =devm_regulator_get (dev,"lvs7" ); +if (IS_ERR (jdi->lvs7)) +return PTR_ERR (jdi->lvs7); + + jdi->avdd =devm_regulator_get (dev,"avdd" ); +if (IS_ERR (jdi->avdd)) +return PTR_ERR (jdi->avdd); + + jdi->iovdd =devm_regulator_get (dev,"iovdd" ); +if (IS_ERR (jdi->iovdd)) +return PTR_ERR (jdi->iovdd); + + jdi->vcc_gpio =devm_gpiod_get (dev,"vcc" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->vcc_gpio)) { +dev_err (dev,"cannot get vcc-gpio %ld\n" , +PTR_ERR (jdi->vcc_gpio)); + jdi->vcc_gpio =NULL ; + }else { +gpiod_direction_output (jdi->vcc_gpio,0 ); + } + + jdi->reset_gpio =devm_gpiod_get (dev,"reset" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->reset_gpio)) { +dev_err (dev,"cannot get reset-gpios %ld\n" , +PTR_ERR (jdi->reset_gpio)); + jdi->reset_gpio =NULL ; + }else { +gpiod_direction_output (jdi->reset_gpio,0 ); + } + + jdi->enable_gpio =devm_gpiod_get (dev,"enable" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->enable_gpio)) { +dev_err (dev,"cannot get enable-gpio %ld\n" , +PTR_ERR (jdi->enable_gpio)); + jdi->enable_gpio =NULL ; + }else { +gpiod_direction_output (jdi->enable_gpio,0 );
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 577
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ } + + jdi->pwm_gpio =devm_gpiod_get (dev,"pwm" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->pwm_gpio)) { +dev_err (dev,"cannot get pwm-gpio %ld\n" , +PTR_ERR (jdi->pwm_gpio)); + jdi->pwm_gpio =NULL ; + }else { +gpiod_direction_output (jdi->pwm_gpio,0 ); + }
As I said earlier, most of these aren't specified in the binding, fix either the binding or the code.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 589
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+/* we don't have backlight right now, proceed further */ +#ifdef BACKLIGHT + np =of_parse_phandle (dev->of_node,"backlight" ,0 ); +if (np) { + jdi->backlight =of_find_backlight_by_node (np); +of_node_put (np); + +if (!jdi->backlight) +return -EPROBE_DEFER ; + } +#endif
Again, if you don't support it, don't submit it. We don't want dead code in the kernel.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 286
Quoted 3 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +3
-0+MODULE_AUTHOR ("Sumit Semwal <[email protected]>" ); +MODULE_AUTHOR ("Vinay Simha BN <[email protected]>" ); +MODULE_DESCRIPTION ("JDI WUXGA LT070ME05000 DSI video/command mode panel driver" );
Technically this doesn't support command mode yet, so you might want to remove that from the description to avoid confusion.
Thierry
In Previous email , forgot to add cc: archit.
regards,
vinay simha bn
Quoted 543 lines · Thierry Reding
Quoted 19 lines · Vinay Simha BN
Add support for the JDI lt070me05000 WUXGA DSI panel used in Nexus 7 2013 devices.
Programming sequence for the panel is was originally found in the android-msm-flo-3.4-lollipop-release branch from:
https://android.googlesource.com/kernel/msm.gitAnd video mode setting is from
dsi-panel-jdi-dualmipi1-video.dtsifile in:git://codeaurora.org/kernel/msm-3.10.git LNX.LA.3.6_rb1.27Other fixes folded in were provided
by Archit Taneja <[email protected]>Signed-off-by Vinay Simha BN <[email protected]>[sumit.semwal: Ported to the drm/panel framework]Signed-off-by Sumit Semwal <[email protected]>[jstultz: Cherry-picked to mainline, folded down other fixes
from Vinay and Archit]Quoted 7 lines
Signed-off-by John Stultz <[email protected]>--- .../bindings/display/panel/jdi,lt070me05000.txt | 27 + .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 685+++++++++++++++++++++
Quoted 2 lines
5 files changed, 725 insertions(+) create mode 100644
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txtQuoted 1 line
create mode 100644 drivers/gpu/drm/panel/panel-jdi-lt070me05000.cWhat's the difference between this and the patch you sent earlier? I'm going to assume that the newer one is the correct patch, so I'll ignore the previous patch.
Quoted 1 line
diff --git
a/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txtb/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txtQuoted 4 lines
new file mode 100644
index 0000000..35c5ac7
---/dev/null
+++
b/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txtThe binding documentation should be a separate patch.
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 4
Quoted 5 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +4
-0@@ -0,0 +1,27 @@ +JDI model LT070ME05000 1920x1200 7" DSI Panel + +Basic data sheet is at: +http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet
Review line 6
Quoted 2 lines
(quoted diff) +2
-0+ +This panel has video mode implemented currently in the driver.That's information irrelevant to the DT binding, since you're presumably talking about the Linux drm/panel driver, whereas the DT binding is supposed to specify the description of the panel hardware in OS-agnostic terms.
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt
Quoted 5 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +5
-0+Required properties: +- compatible: should be "jdi,lt070me05000" + +Optional properties: +- power-supply: phandle of the regulator that provides the supplyvoltage
Review
Quoted 16 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +15
-0+- reset-gpio: phandle of gpio for reset line +- backlight: phandle of the backlight device attached to the panel + +Example: + + dsi@54300000 { + panel: panel@0 { + compatible = "jdi,lt070me05000"; + reg = <0>; + + power-supply = <...>; + reset-gpio = <...>; + backlight = <...>; + }; + };(quoted diff) +0
-0
b/Documentation/devicetree/bindings/vendor-prefixes.txtDocumentation/devicetree/bindings/vendor-prefixes.txt invensense InvenSense Inc. · line 136
Quoted 11 lines
index a580f3e..ec42bb4 100644
Documentation/devicetree/bindings/vendor-prefixes.txt +1
-0@@ -130,6 +130,7 @@ invensense InvenSense Inc. isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jdi Japan Display Inc. jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH keymile Keymile GmbHThis should be a separate patch as well.
Review
Quoted 1 line
(quoted diff) +0
-0b/drivers/gpu/drm/panel/Kconfig
Quoted 11 lines
index 1500ab9..f41690e 100644
drivers/gpu/drm/panel/Kconfig +4
-0@@ -61,6 +61,17 @@ config DRM_PANEL_SHARP_LQ101R1SX01 To compile this driver as a module, choose M here: the module will be called panel-sharp-lq101r1sx01. +config DRM_PANEL_JDI_LT070ME05000 + tristate "JDI LT070ME05000 WUXGA DSI panel" + depends on OF + depends on DRM_MIPI_DSIdrivers/gpu/drm/panel/Kconfig config DRM_PANEL_SHARP_LQ101R1SX01 · line 77
Quoted 10 lines
drivers/gpu/drm/panel/Kconfig +7
-0+ depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for JDI WUXGA DSI video/ + command mode panel as found in Google Nexus 7 (2013) devices. + The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses + 24 bit RGB per pixel. + config DRM_PANEL_SHARP_LS043T1LE01 tristate "Sharp LS043T1LE01 qHD video mode panel" depends on OFPlease keep these sorted alphabetically. I do realize that the list isn't sorted quite correctly at the moment, so you may as well leave this as-is and I'll fix up the order when applying and after fixing the current ordering.
Review
Quoted 1 line
(quoted diff) +0
-0b/drivers/gpu/drm/panel/Makefile
drivers/gpu/drm/panel/Makefile obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) +=
Quoted 4 lines
index f277eed..e6c6fc8 100644
drivers/gpu/drm/panel/Makefile +0
-0@@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) +=panel-samsung-ld9040.o
drivers/gpu/drm/panel/Makefile obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o · line 8
Quoted 4 lines
drivers/gpu/drm/panel/Makefile +1
-0obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o +obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.oSame here.
Review
Quoted 1 line
(quoted diff) +0
-0
b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.cdrivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 6
Quoted 11 lines
new file mode 100644
index 0000000..051aa1bdrivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0@@ -0,0 +1,685 @@ +/* +* Copyright (C) 2015 InforceComputing +* Author: Vinay Simha BN <[email protected]> +* +* Copyright (C) 2015 Linaro Ltd +* Author: Sumit Semwal <[email protected]> Should either of those copyright lines include 2016? We're a pretty good way into 2016, and I'd be surprised if this wasn't touched this year at all.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 8
Quoted 2 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +2
-0+/* +* From internet archives, the panel for Nexus 7 2nd Gen, 2013 model is a
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 38
Quoted 3 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +3
-0+* JDI model LT070ME05000, and its data sheet is at: +* http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet +*/ This comment is oddly placed here above the struct
jdi_paneldefinition. Perhaps move that information into the header comment?drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 43
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+struct jdi_panel { +struct drm_panel base; +struct mipi_dsi_device *dsi; + +/* TODO: Add backilght support */ "backlight". Also if this is still TODO, why even have parts of the code here? Just drop everything that's not used and move that to a follow-up patch that implements full support.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 54
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+struct backlight_device *backlight; +struct regulator *supply; +struct gpio_desc *reset_gpio; +struct gpio_desc *enable_gpio; +struct gpio_desc *vcc_gpio; + +struct regulator *backlit; +struct regulator *lvs7; +struct regulator *avdd; +struct regulator *iovdd; +struct gpio_desc *pwm_gpio;Most of these resources aren't specified in the device tree binding, so your driver doesn't properly implement the binding. You'll have to fix the driver or the binding.
Quoted 4 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +4
-0+ +bool prepared; +bool enabled; +drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+const struct drm_display_mode *mode; +}; + +static inline struct jdi_panel *to_jdi_panel (struct drm_panel *panel) +{ + return container_of(panel, struct jdi_panel, base); +} + +static char MCAP [2 ] = {0xB0 ,0x00 }; +static char interface_setting_cmd[6 ] = {0xB3 ,0x04 ,0x08 ,0x00 ,0x22 ,
0x00};drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 69
Quoted 1 line
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +1
-0+static char interface_setting[6 ] = {0xB3 ,0x26 ,0x08 ,0x00 ,0x20 ,0x00 };Please make all of these (and the ones below) arrays of u8, since that's the type used in the prototype of the function that receives these as parameters. Also, please use consistent capitalization and a space after { and before }.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 74
Quoted 4 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +4
-0+static char interface_ID_setting[2 ] = {0xB4 ,0x0C }; +static char DSI_control[3 ] = {0xB6 ,0x3A ,0xD3 }; + +static char tear_scan_line[3 ] = {0x44 ,0x03 ,0x00 };This is a standard DCS command, please turn this into a generic helper such as
mipi_dsi_dcs_set_tear_scanline().drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 81
Quoted 6 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0+/* for fps control, set fps to 60.32Hz */ +static char LTPS_timing_setting[2 ] = {0xC6 ,0x78 }; +static char sequencer_timing_control[2 ] = {0xD6 ,0x01 }; + +/* set brightness */ +static char write_display_brightness[] = {0x51 ,0xFF };Same here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 53
Quoted 1 line
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +1
-0+/* enable LEDPWM pin output, turn on LEDPWM output, turn off pwm dimming */
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 83
Quoted 1 line
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +1
-0+static char write_control_display[] = {0x53 ,0x24 };And here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 88
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+/* +* choose cabc mode, 0x00(-0%), 0x01(-15%), 0x02(-40%), 0x03(-54%), +* disable SRE(sunlight readability enhancement) +*/ +static char write_cabc[] = {0x55 ,0x00 };And here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 112
Quoted 13 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +13
-0+static int jdi_panel_init (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + +if (dsi->mode_flags &MIPI_DSI_MODE_VIDEO ) { + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret; + +mdelay (10 );Please don't use
mdelay()because it will busy-loop for a very long time and waste precious CPU cycles. Instead, useusleep_range()for these cases (ormsleep()for durations longer than ~10 ms). Same goes for the other occurrences below.drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 116
Quoted 4 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +4
-0+ + ret =mipi_dsi_dcs_set_pixel_format (dsi,0x70 ); +if (ret <0 ) +return ret;There are symbolic constants for the pixel formats, use them to convey meaning.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 124
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +8
-0+ + ret =mipi_dsi_dcs_set_column_address (dsi,0x0000 ,0x04AF ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_page_address (dsi,0x0000 ,0x077F ); +if (ret <0 ) +return ret;These should be parameterized on the panel width and height, to make it clear where the values come from.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 131
Quoted 3 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +3
-0+ + ret = mipi_dsi_dcs_set_tear_on(dsi, +
MIPI_DSI_DCS_TEAR_MODE_VBLANK);drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 135
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +8
-0+if (ret <0 ) +return ret; +mdelay (5 ); + + ret =mipi_dsi_generic_write (dsi, tear_scan_line, +sizeof (tear_scan_line)); +if (ret <0 ) +return ret;Like I mentioned earlier, this should be a generic helper to help make its intention clearer.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 97
Quoted 2 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +2
-0+ + ret = mipi_dsi_dcs_write_buffer(dsi,
write_display_brightness,drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 98
Quoted 1 line
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +1
-0+
sizeof(write_display_brightness)drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 147
Quoted 6 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0+ ); +if (ret <0 ) +return ret; + + ret = mipi_dsi_dcs_write_buffer(dsi, write_control_display, +
sizeof(write_control_display));drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 151
Quoted 7 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +7
-0+if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_cabc, +sizeof (write_cabc)); +if (ret <0 ) +return ret;Same for these. I don't currently have access to the DCS 1.3 specification, but I suspect that some of the parameters for these commands could be defined via symbolic names.
Quoted 20 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +20
-0+ + ret =mipi_dsi_dcs_exit_sleep_mode (dsi); +if (ret <0 ) +return ret; +mdelay (120 ); + + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret; +mdelay (10 ); + + ret =mipi_dsi_generic_write (dsi, interface_setting, +sizeof (interface_setting)); +if (ret <0 ) +return ret; +mdelay (20 ); + + backlight_control4[18 ] =0x04 ; + backlight_control4[19 ] =0x00 ; +drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 181
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ ret =mipi_dsi_generic_write (dsi, backlight_control4, +sizeof (backlight_control4)); +if (ret <0 ) +return ret; +mdelay (20 ); + +MCAP [1 ] =0x03 ; + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret;That's odd. Doesn't this break idempotence of this function? You modify the global MCAP array by writing
0x03to MCAP[1], so when this function is called a second time, MCAP[1] will be0x03already in the first call a few lines above, instead of the0x00that it was initially.drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 189
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +8
-0+ }else { +/* +* TODO : need to verify panel settings when +* dsi cmd mode supported for apq8064 - simhavcs +*/ + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret;This whole else clause is dead code because the condition for the if clause is always true. Just drop it and add it back when you properly support both modes.
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+static int jdi_panel_on (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + + ret =mipi_dsi_dcs_set_display_on (dsi); +if (ret <0 ) +return ret;drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 298
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ +return 0 ; +} + +static int jdi_panel_off (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM ;Should this not be cleared at the end of the function so that the below commands still get run in LP mode?
Quoted 16 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +16
-0+ + ret =mipi_dsi_dcs_set_display_off (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_enter_sleep_mode (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_tear_off (dsi); +if (ret <0 ) +return ret; + +msleep (100 ); + +return 0 ;drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 324
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+} + +static int jdi_panel_disable (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); + +if (!jdi->enabled) +return 0 ; + +DRM_DEBUG ("disable\n" );This doesn't look very useful debug information. I think you should remove it. Same for other similar occurrences below.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 512
Quoted 13 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +13
-0+static const struct drm_panel_funcs jdi_panel_funcs = { + .disable = jdi_panel_disable, + .unprepare = jdi_panel_unprepare, + .prepare = jdi_panel_prepare, + .enable = jdi_panel_enable, + .get_modes = jdi_panel_get_modes, +}; + +static const struct of_device_id jdi_of_match[] = { + { .compatible ="jdi,lt070me05000" , }, + { } +}; +MODULE_DEVICE_TABLE (of, jdi_of_match);A single tab is enough to indent the above.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 519
Quoted 6 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0+static int jdi_panel_add (struct jdi_panel *jdi) +{ +struct device *dev = &jdi->dsi->dev; +int ret; + + jdi->mode = &default_mode;What do you keep this around for?
Quoted 48 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +48
-0+ +/* lvs5 */ + jdi->supply =devm_regulator_get (dev,"power" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply); + +/* l17 */ + jdi->backlit =devm_regulator_get (dev,"backlit" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply); + + jdi->lvs7 =devm_regulator_get (dev,"lvs7" ); +if (IS_ERR (jdi->lvs7)) +return PTR_ERR (jdi->lvs7); + + jdi->avdd =devm_regulator_get (dev,"avdd" ); +if (IS_ERR (jdi->avdd)) +return PTR_ERR (jdi->avdd); + + jdi->iovdd =devm_regulator_get (dev,"iovdd" ); +if (IS_ERR (jdi->iovdd)) +return PTR_ERR (jdi->iovdd); + + jdi->vcc_gpio =devm_gpiod_get (dev,"vcc" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->vcc_gpio)) { +dev_err (dev,"cannot get vcc-gpio %ld\n" , +PTR_ERR (jdi->vcc_gpio)); + jdi->vcc_gpio =NULL ; + }else { +gpiod_direction_output (jdi->vcc_gpio,0 ); + } + + jdi->reset_gpio =devm_gpiod_get (dev,"reset" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->reset_gpio)) { +dev_err (dev,"cannot get reset-gpios %ld\n" , +PTR_ERR (jdi->reset_gpio)); + jdi->reset_gpio =NULL ; + }else { +gpiod_direction_output (jdi->reset_gpio,0 ); + } + + jdi->enable_gpio =devm_gpiod_get (dev,"enable" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->enable_gpio)) { +dev_err (dev,"cannot get enable-gpio %ld\n" , +PTR_ERR (jdi->enable_gpio)); + jdi->enable_gpio =NULL ; + }else { +gpiod_direction_output (jdi->enable_gpio,0 );drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 577
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ } + + jdi->pwm_gpio =devm_gpiod_get (dev,"pwm" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->pwm_gpio)) { +dev_err (dev,"cannot get pwm-gpio %ld\n" , +PTR_ERR (jdi->pwm_gpio)); + jdi->pwm_gpio =NULL ; + }else { +gpiod_direction_output (jdi->pwm_gpio,0 ); + }As I said earlier, most of these aren't specified in the binding, fix either the binding or the code.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 589
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+/* we don't have backlight right now, proceed further */ +#ifdef BACKLIGHT + np =of_parse_phandle (dev->of_node,"backlight" ,0 ); +if (np) { + jdi->backlight =of_find_backlight_by_node (np); +of_node_put (np); + +if (!jdi->backlight) +return -EPROBE_DEFER ; + } +#endif Again, if you don't support it, don't submit it. We don't want dead code in the kernel.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 286
Quoted 3 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +3
-0+MODULE_AUTHOR ("Sumit Semwal <[email protected]>" ); +MODULE_AUTHOR ("Vinay Simha BN <[email protected]>" ); +MODULE_DESCRIPTION("JDI WUXGA LT070ME05000 DSI video/command mode paneldriver");
Technically this doesn't support command mode yet, so you might want to remove that from the description to avoid confusion.
Thierry
Thierry Reding,
Thanks for the review. Will address your reviews and resend the patches.
Quoted 522 lines · Thierry Reding
Quoted 20 lines · Vinay Simha BN
Add support for the JDI lt070me05000 WUXGA DSI panel used in Nexus 7 2013 devices.
Programming sequence for the panel is was originally found in the android-msm-flo-3.4-lollipop-release branch from:
https://android.googlesource.com/kernel/msm.gitAnd video mode setting is from
dsi-panel-jdi-dualmipi1-video.dtsifile in:git://codeaurora.org/kernel/msm-3.10.git LNX.LA.3.6_rb1.27Other fixes folded in were provided
by Archit Taneja <[email protected]>Signed-off-by Vinay Simha BN <[email protected]>[sumit.semwal: Ported to the drm/panel framework]Signed-off-by Sumit Semwal <[email protected]>[jstultz: Cherry-picked to mainline, folded down other fixes
from Vinay and Archit]Signed-off-by John Stultz <[email protected]>Quoted 9 lines
--- .../bindings/display/panel/jdi,lt070me05000.txt | 27 + .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 685 +++++++++++++++++++++ 5 files changed, 725 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt create mode 100644 drivers/gpu/drm/panel/panel-jdi-lt070me05000.cWhat's the difference between this and the patch you sent earlier? I'm going to assume that the newer one is the correct patch, so I'll ignore the previous patch.
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt
Quoted 5 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +0
-0The binding documentation should be a separate patch.
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 6
Quoted 7 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +6
-0@@ -0,0 +1,27 @@ +JDI model LT070ME05000 1920x1200 7" DSI Panel + +Basic data sheet is at: + http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet + +This panel has video mode implemented currently in the driver.That's information irrelevant to the DT binding, since you're presumably talking about the Linux drm/panel driver, whereas the DT binding is supposed to specify the description of the panel hardware in OS-agnostic terms.
Quoted 25 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +20
-0+Required properties: +- compatible: should be "jdi,lt070me05000" + +Optional properties: +- power-supply: phandle of the regulator that provides the supply voltage +- reset-gpio: phandle of gpio for reset line +- backlight: phandle of the backlight device attached to the panel + +Example: + + dsi@54300000 { + panel: panel@0 { + compatible = "jdi,lt070me05000"; + reg = <0>; + + power-supply = <...>; + reset-gpio = <...>; + backlight = <...>; + }; + };Documentation/devicetree/bindings/vendor-prefixes.txt +0
-0Documentation/devicetree/bindings/vendor-prefixes.txt invensense InvenSense Inc. · line 136
Quoted 7 lines
Documentation/devicetree/bindings/vendor-prefixes.txt +1
-0@@ -130,6 +130,7 @@ invensense InvenSense Inc. isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jdi Japan Display Inc. jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH keymile Keymile GmbHThis should be a separate patch as well.
Quoted 12 lines
drivers/gpu/drm/panel/Kconfig +4
-0@@ -61,6 +61,17 @@ config DRM_PANEL_SHARP_LQ101R1SX01 To compile this driver as a module, choose M here: the module will be called panel-sharp-lq101r1sx01. +config DRM_PANEL_JDI_LT070ME05000 + tristate "JDI LT070ME05000 WUXGA DSI panel" + depends on OF + depends on DRM_MIPI_DSIdrivers/gpu/drm/panel/Kconfig config DRM_PANEL_SHARP_LQ101R1SX01 · line 77
Quoted 10 lines
drivers/gpu/drm/panel/Kconfig +7
-0+ depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for JDI WUXGA DSI video/ + command mode panel as found in Google Nexus 7 (2013) devices. + The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses + 24 bit RGB per pixel. + config DRM_PANEL_SHARP_LS043T1LE01 tristate "Sharp LS043T1LE01 qHD video mode panel" depends on OFPlease keep these sorted alphabetically. I do realize that the list isn't sorted quite correctly at the moment, so you may as well leave this as-is and I'll fix up the order when applying and after fixing the current ordering.
drivers/gpu/drm/panel/Makefile obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o · line 8
Quoted 9 lines
drivers/gpu/drm/panel/Makefile +1
-0@@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o +obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.oSame here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 6
Quoted 12 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0@@ -0,0 +1,685 @@ +/* +* Copyright (C) 2015 InforceComputing +* Author: Vinay Simha BN <[email protected]> +* +* Copyright (C) 2015 Linaro Ltd +* Author: Sumit Semwal <[email protected]> Should either of those copyright lines include 2016? We're a pretty good way into 2016, and I'd be surprised if this wasn't touched this year at all.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 38
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+/* +* From internet archives, the panel for Nexus 7 2nd Gen, 2013 model is a +* JDI model LT070ME05000, and its data sheet is at: +* http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet +*/ This comment is oddly placed here above the struct
jdi_paneldefinition. Perhaps move that information into the header comment?drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 43
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+struct jdi_panel { +struct drm_panel base; +struct mipi_dsi_device *dsi; + +/* TODO: Add backilght support */ "backlight". Also if this is still TODO, why even have parts of the code here? Just drop everything that's not used and move that to a follow-up patch that implements full support.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 54
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+struct backlight_device *backlight; +struct regulator *supply; +struct gpio_desc *reset_gpio; +struct gpio_desc *enable_gpio; +struct gpio_desc *vcc_gpio; + +struct regulator *backlit; +struct regulator *lvs7; +struct regulator *avdd; +struct regulator *iovdd; +struct gpio_desc *pwm_gpio;Most of these resources aren't specified in the device tree binding, so your driver doesn't properly implement the binding. You'll have to fix the driver or the binding.
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+ +bool prepared; +bool enabled; + +const struct drm_display_mode *mode;drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 69
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+}; + +static inline struct jdi_panel *to_jdi_panel (struct drm_panel *panel) +{ + return container_of(panel, struct jdi_panel, base); +} + +static char MCAP [2 ] = {0xB0 ,0x00 }; +static char interface_setting_cmd[6 ] = {0xB3 ,0x04 ,0x08 ,0x00 ,0x22 ,0x00 }; +static char interface_setting[6 ] = {0xB3 ,0x26 ,0x08 ,0x00 ,0x20 ,0x00 };Please make all of these (and the ones below) arrays of u8, since that's the type used in the prototype of the function that receives these as parameters. Also, please use consistent capitalization and a space after { and before }.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 74
Quoted 4 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +4
-0+static char interface_ID_setting[2 ] = {0xB4 ,0x0C }; +static char DSI_control[3 ] = {0xB6 ,0x3A ,0xD3 }; + +static char tear_scan_line[3 ] = {0x44 ,0x03 ,0x00 };This is a standard DCS command, please turn this into a generic helper such as
mipi_dsi_dcs_set_tear_scanline().drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 81
Quoted 6 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0+/* for fps control, set fps to 60.32Hz */ +static char LTPS_timing_setting[2 ] = {0xC6 ,0x78 }; +static char sequencer_timing_control[2 ] = {0xD6 ,0x01 }; + +/* set brightness */ +static char write_display_brightness[] = {0x51 ,0xFF };Same here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 83
Quoted 2 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +2
-0+/* enable LEDPWM pin output, turn on LEDPWM output, turn off pwm dimming */ +static char write_control_display[] = {0x53 ,0x24 };And here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 88
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+/* +* choose cabc mode, 0x00(-0%), 0x01(-15%), 0x02(-40%), 0x03(-54%), +* disable SRE(sunlight readability enhancement) +*/ +static char write_cabc[] = {0x55 ,0x00 };And here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 112
Quoted 13 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +13
-0+static int jdi_panel_init (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + +if (dsi->mode_flags &MIPI_DSI_MODE_VIDEO ) { + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret; + +mdelay (10 );Please don't use
mdelay()because it will busy-loop for a very long time and waste precious CPU cycles. Instead, useusleep_range()for these cases (ormsleep()for durations longer than ~10 ms). Same goes for the other occurrences below.drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 116
Quoted 4 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +4
-0+ + ret =mipi_dsi_dcs_set_pixel_format (dsi,0x70 ); +if (ret <0 ) +return ret;There are symbolic constants for the pixel formats, use them to convey meaning.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 124
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +8
-0+ + ret =mipi_dsi_dcs_set_column_address (dsi,0x0000 ,0x04AF ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_page_address (dsi,0x0000 ,0x077F ); +if (ret <0 ) +return ret;These should be parameterized on the panel width and height, to make it clear where the values come from.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 135
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+ + ret =mipi_dsi_dcs_set_tear_on (dsi, +MIPI_DSI_DCS_TEAR_MODE_VBLANK ); +if (ret <0 ) +return ret; +mdelay (5 ); + + ret =mipi_dsi_generic_write (dsi, tear_scan_line, +sizeof (tear_scan_line)); +if (ret <0 ) +return ret;Like I mentioned earlier, this should be a generic helper to help make its intention clearer.
Quoted 6 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0+ + ret =mipi_dsi_dcs_write_buffer (dsi, write_display_brightness, +sizeof (write_display_brightness) + ); +if (ret <0 ) +return ret;drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 151
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ + ret =mipi_dsi_dcs_write_buffer (dsi, write_control_display, +sizeof (write_control_display)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_cabc, +sizeof (write_cabc)); +if (ret <0 ) +return ret;Same for these. I don't currently have access to the DCS 1.3 specification, but I suspect that some of the parameters for these commands could be defined via symbolic names.
Quoted 20 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +20
-0+ + ret =mipi_dsi_dcs_exit_sleep_mode (dsi); +if (ret <0 ) +return ret; +mdelay (120 ); + + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret; +mdelay (10 ); + + ret =mipi_dsi_generic_write (dsi, interface_setting, +sizeof (interface_setting)); +if (ret <0 ) +return ret; +mdelay (20 ); + + backlight_control4[18 ] =0x04 ; + backlight_control4[19 ] =0x00 ; +drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 181
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ ret =mipi_dsi_generic_write (dsi, backlight_control4, +sizeof (backlight_control4)); +if (ret <0 ) +return ret; +mdelay (20 ); + +MCAP [1 ] =0x03 ; + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret;That's odd. Doesn't this break idempotence of this function? You modify the global MCAP array by writing
0x03to MCAP[1], so when this function is called a second time, MCAP[1] will be0x03already in the first call a few lines above, instead of the0x00that it was initially.drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 189
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +8
-0+ }else { +/* +* TODO : need to verify panel settings when +* dsi cmd mode supported for apq8064 - simhavcs +*/ + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret;This whole else clause is dead code because the condition for the if clause is always true. Just drop it and add it back when you properly support both modes.
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+static int jdi_panel_on (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + + ret =mipi_dsi_dcs_set_display_on (dsi); +if (ret <0 ) +return ret;drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 298
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ +return 0 ; +} + +static int jdi_panel_off (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM ;Should this not be cleared at the end of the function so that the below commands still get run in LP mode?
Quoted 16 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +16
-0+ + ret =mipi_dsi_dcs_set_display_off (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_enter_sleep_mode (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_tear_off (dsi); +if (ret <0 ) +return ret; + +msleep (100 ); + +return 0 ;drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 324
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+} + +static int jdi_panel_disable (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); + +if (!jdi->enabled) +return 0 ; + +DRM_DEBUG ("disable\n" );This doesn't look very useful debug information. I think you should remove it. Same for other similar occurrences below.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 512
Quoted 13 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +13
-0+static const struct drm_panel_funcs jdi_panel_funcs = { + .disable = jdi_panel_disable, + .unprepare = jdi_panel_unprepare, + .prepare = jdi_panel_prepare, + .enable = jdi_panel_enable, + .get_modes = jdi_panel_get_modes, +}; + +static const struct of_device_id jdi_of_match[] = { + { .compatible ="jdi,lt070me05000" , }, + { } +}; +MODULE_DEVICE_TABLE (of, jdi_of_match);A single tab is enough to indent the above.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 519
Quoted 6 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0+static int jdi_panel_add (struct jdi_panel *jdi) +{ +struct device *dev = &jdi->dsi->dev; +int ret; + + jdi->mode = &default_mode;What do you keep this around for?
Quoted 48 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +48
-0+ +/* lvs5 */ + jdi->supply =devm_regulator_get (dev,"power" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply); + +/* l17 */ + jdi->backlit =devm_regulator_get (dev,"backlit" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply); + + jdi->lvs7 =devm_regulator_get (dev,"lvs7" ); +if (IS_ERR (jdi->lvs7)) +return PTR_ERR (jdi->lvs7); + + jdi->avdd =devm_regulator_get (dev,"avdd" ); +if (IS_ERR (jdi->avdd)) +return PTR_ERR (jdi->avdd); + + jdi->iovdd =devm_regulator_get (dev,"iovdd" ); +if (IS_ERR (jdi->iovdd)) +return PTR_ERR (jdi->iovdd); + + jdi->vcc_gpio =devm_gpiod_get (dev,"vcc" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->vcc_gpio)) { +dev_err (dev,"cannot get vcc-gpio %ld\n" , +PTR_ERR (jdi->vcc_gpio)); + jdi->vcc_gpio =NULL ; + }else { +gpiod_direction_output (jdi->vcc_gpio,0 ); + } + + jdi->reset_gpio =devm_gpiod_get (dev,"reset" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->reset_gpio)) { +dev_err (dev,"cannot get reset-gpios %ld\n" , +PTR_ERR (jdi->reset_gpio)); + jdi->reset_gpio =NULL ; + }else { +gpiod_direction_output (jdi->reset_gpio,0 ); + } + + jdi->enable_gpio =devm_gpiod_get (dev,"enable" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->enable_gpio)) { +dev_err (dev,"cannot get enable-gpio %ld\n" , +PTR_ERR (jdi->enable_gpio)); + jdi->enable_gpio =NULL ; + }else { +gpiod_direction_output (jdi->enable_gpio,0 );drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 577
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ } + + jdi->pwm_gpio =devm_gpiod_get (dev,"pwm" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->pwm_gpio)) { +dev_err (dev,"cannot get pwm-gpio %ld\n" , +PTR_ERR (jdi->pwm_gpio)); + jdi->pwm_gpio =NULL ; + }else { +gpiod_direction_output (jdi->pwm_gpio,0 ); + }As I said earlier, most of these aren't specified in the binding, fix either the binding or the code.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 589
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+/* we don't have backlight right now, proceed further */ +#ifdef BACKLIGHT + np =of_parse_phandle (dev->of_node,"backlight" ,0 ); +if (np) { + jdi->backlight =of_find_backlight_by_node (np); +of_node_put (np); + +if (!jdi->backlight) +return -EPROBE_DEFER ; + } +#endif Again, if you don't support it, don't submit it. We don't want dead code in the kernel.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 684
Quoted 3 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +3
-0+MODULE_AUTHOR ("Sumit Semwal <[email protected]>" ); +MODULE_AUTHOR ("Vinay Simha BN <[email protected]>" ); +MODULE_DESCRIPTION ("JDI WUXGA LT070ME05000 DSI video/command mode panel driver" );Technically this doesn't support command mode yet, so you might want to remove that from the description to avoid confusion.
Thierry
Signature · 7 lines
Regards, Vinay Simha.B.N. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 373 lines · Thierry Reding
Quoted 20 lines · Vinay Simha BN
Add support for the JDI lt070me05000 WUXGA DSI panel used in Nexus 7 2013 devices.
Programming sequence for the panel is was originally found in the android-msm-flo-3.4-lollipop-release branch from:
https://android.googlesource.com/kernel/msm.gitAnd video mode setting is from
dsi-panel-jdi-dualmipi1-video.dtsifile in:git://codeaurora.org/kernel/msm-3.10.git LNX.LA.3.6_rb1.27Other fixes folded in were provided
by Archit Taneja <[email protected]>Signed-off-by Vinay Simha BN <[email protected]>[sumit.semwal: Ported to the drm/panel framework]Signed-off-by Sumit Semwal <[email protected]>[jstultz: Cherry-picked to mainline, folded down other fixes
from Vinay and Archit]Signed-off-by John Stultz <[email protected]>Quoted 9 lines
--- .../bindings/display/panel/jdi,lt070me05000.txt | 27 + .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 685 +++++++++++++++++++++ 5 files changed, 725 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt create mode 100644 drivers/gpu/drm/panel/panel-jdi-lt070me05000.cWhat's the difference between this and the patch you sent earlier? I'm going to assume that the newer one is the correct patch, so I'll ignore the previous patch.
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt
Quoted 5 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +0
-0The binding documentation should be a separate patch.
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 6
Quoted 7 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +6
-0@@ -0,0 +1,27 @@ +JDI model LT070ME05000 1920x1200 7" DSI Panel + +Basic data sheet is at: + http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet + +This panel has video mode implemented currently in the driver.That's information irrelevant to the DT binding, since you're presumably talking about the Linux drm/panel driver, whereas the DT binding is supposed to specify the description of the panel hardware in OS-agnostic terms.
Quoted 25 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +20
-0+Required properties: +- compatible: should be "jdi,lt070me05000" + +Optional properties: +- power-supply: phandle of the regulator that provides the supply voltage +- reset-gpio: phandle of gpio for reset line +- backlight: phandle of the backlight device attached to the panel + +Example: + + dsi@54300000 { + panel: panel@0 { + compatible = "jdi,lt070me05000"; + reg = <0>; + + power-supply = <...>; + reset-gpio = <...>; + backlight = <...>; + }; + };Documentation/devicetree/bindings/vendor-prefixes.txt +0
-0Documentation/devicetree/bindings/vendor-prefixes.txt invensense InvenSense Inc. · line 136
Quoted 7 lines
Documentation/devicetree/bindings/vendor-prefixes.txt +1
-0@@ -130,6 +130,7 @@ invensense InvenSense Inc. isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jdi Japan Display Inc. jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH keymile Keymile GmbHThis should be a separate patch as well.
Quoted 12 lines
drivers/gpu/drm/panel/Kconfig +4
-0@@ -61,6 +61,17 @@ config DRM_PANEL_SHARP_LQ101R1SX01 To compile this driver as a module, choose M here: the module will be called panel-sharp-lq101r1sx01. +config DRM_PANEL_JDI_LT070ME05000 + tristate "JDI LT070ME05000 WUXGA DSI panel" + depends on OF + depends on DRM_MIPI_DSIdrivers/gpu/drm/panel/Kconfig config DRM_PANEL_SHARP_LQ101R1SX01 · line 77
Quoted 10 lines
drivers/gpu/drm/panel/Kconfig +7
-0+ depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for JDI WUXGA DSI video/ + command mode panel as found in Google Nexus 7 (2013) devices. + The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses + 24 bit RGB per pixel. + config DRM_PANEL_SHARP_LS043T1LE01 tristate "Sharp LS043T1LE01 qHD video mode panel" depends on OFPlease keep these sorted alphabetically. I do realize that the list isn't sorted quite correctly at the moment, so you may as well leave this as-is and I'll fix up the order when applying and after fixing the current ordering.
drivers/gpu/drm/panel/Makefile obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o · line 8
Quoted 9 lines
drivers/gpu/drm/panel/Makefile +1
-0@@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o +obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.oSame here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 6
Quoted 12 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0@@ -0,0 +1,685 @@ +/* +* Copyright (C) 2015 InforceComputing +* Author: Vinay Simha BN <[email protected]> +* +* Copyright (C) 2015 Linaro Ltd +* Author: Sumit Semwal <[email protected]> Should either of those copyright lines include 2016? We're a pretty good way into 2016, and I'd be surprised if this wasn't touched this year at all.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 38
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+/* +* From internet archives, the panel for Nexus 7 2nd Gen, 2013 model is a +* JDI model LT070ME05000, and its data sheet is at: +* http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet +*/ This comment is oddly placed here above the struct
jdi_paneldefinition. Perhaps move that information into the header comment?drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 43
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+struct jdi_panel { +struct drm_panel base; +struct mipi_dsi_device *dsi; + +/* TODO: Add backilght support */ "backlight". Also if this is still TODO, why even have parts of the code here? Just drop everything that's not used and move that to a follow-up patch that implements full support.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 54
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+struct backlight_device *backlight; +struct regulator *supply; +struct gpio_desc *reset_gpio; +struct gpio_desc *enable_gpio; +struct gpio_desc *vcc_gpio; + +struct regulator *backlit; +struct regulator *lvs7; +struct regulator *avdd; +struct regulator *iovdd; +struct gpio_desc *pwm_gpio;Most of these resources aren't specified in the device tree binding, so your driver doesn't properly implement the binding. You'll have to fix the driver or the binding.
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+ +bool prepared; +bool enabled; + +const struct drm_display_mode *mode;drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 69
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+}; + +static inline struct jdi_panel *to_jdi_panel (struct drm_panel *panel) +{ + return container_of(panel, struct jdi_panel, base); +} + +static char MCAP [2 ] = {0xB0 ,0x00 }; +static char interface_setting_cmd[6 ] = {0xB3 ,0x04 ,0x08 ,0x00 ,0x22 ,0x00 }; +static char interface_setting[6 ] = {0xB3 ,0x26 ,0x08 ,0x00 ,0x20 ,0x00 };Please make all of these (and the ones below) arrays of u8, since that's the type used in the prototype of the function that receives these as parameters. Also, please use consistent capitalization and a space after { and before }.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 74
Quoted 4 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +4
-0+static char interface_ID_setting[2 ] = {0xB4 ,0x0C }; +static char DSI_control[3 ] = {0xB6 ,0x3A ,0xD3 }; + +static char tear_scan_line[3 ] = {0x44 ,0x03 ,0x00 };This is a standard DCS command, please turn this into a generic helper such as
mipi_dsi_dcs_set_tear_scanline().drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 81
Quoted 6 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0+/* for fps control, set fps to 60.32Hz */ +static char LTPS_timing_setting[2 ] = {0xC6 ,0x78 }; +static char sequencer_timing_control[2 ] = {0xD6 ,0x01 }; + +/* set brightness */ +static char write_display_brightness[] = {0x51 ,0xFF };Same here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 83
Quoted 2 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +2
-0+/* enable LEDPWM pin output, turn on LEDPWM output, turn off pwm dimming */ +static char write_control_display[] = {0x53 ,0x24 };And here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 88
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+/* +* choose cabc mode, 0x00(-0%), 0x01(-15%), 0x02(-40%), 0x03(-54%), +* disable SRE(sunlight readability enhancement) +*/ +static char write_cabc[] = {0x55 ,0x00 };And here.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 112
Quoted 13 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +13
-0+static int jdi_panel_init (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + +if (dsi->mode_flags &MIPI_DSI_MODE_VIDEO ) { + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret; + +mdelay (10 );Please don't use
mdelay()because it will busy-loop for a very long time and waste precious CPU cycles. Instead, useusleep_range()for these cases (ormsleep()for durations longer than ~10 ms). Same goes for the other occurrences below.drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 116
Quoted 4 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +4
-0+ + ret =mipi_dsi_dcs_set_pixel_format (dsi,0x70 ); +if (ret <0 ) +return ret;There are symbolic constants for the pixel formats, use them to convey meaning.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 124
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +8
-0+ + ret =mipi_dsi_dcs_set_column_address (dsi,0x0000 ,0x04AF ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_page_address (dsi,0x0000 ,0x077F ); +if (ret <0 ) +return ret;These should be parameterized on the panel width and height, to make it clear where the values come from.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 135
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+ + ret =mipi_dsi_dcs_set_tear_on (dsi, +MIPI_DSI_DCS_TEAR_MODE_VBLANK ); +if (ret <0 ) +return ret; +mdelay (5 ); + + ret =mipi_dsi_generic_write (dsi, tear_scan_line, +sizeof (tear_scan_line)); +if (ret <0 ) +return ret;Like I mentioned earlier, this should be a generic helper to help make its intention clearer.
Quoted 6 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0+ + ret =mipi_dsi_dcs_write_buffer (dsi, write_display_brightness, +sizeof (write_display_brightness) + ); +if (ret <0 ) +return ret;drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 151
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ + ret =mipi_dsi_dcs_write_buffer (dsi, write_control_display, +sizeof (write_control_display)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_cabc, +sizeof (write_cabc)); +if (ret <0 ) +return ret;Same for these. I don't currently have access to the DCS 1.3 specification, but I suspect that some of the parameters for these commands could be defined via symbolic names.
Quoted 20 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +20
-0+ + ret =mipi_dsi_dcs_exit_sleep_mode (dsi); +if (ret <0 ) +return ret; +mdelay (120 ); + + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret; +mdelay (10 ); + + ret =mipi_dsi_generic_write (dsi, interface_setting, +sizeof (interface_setting)); +if (ret <0 ) +return ret; +mdelay (20 ); + + backlight_control4[18 ] =0x04 ; + backlight_control4[19 ] =0x00 ; +drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 181
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ ret =mipi_dsi_generic_write (dsi, backlight_control4, +sizeof (backlight_control4)); +if (ret <0 ) +return ret; +mdelay (20 ); + +MCAP [1 ] =0x03 ; + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret;That's odd. Doesn't this break idempotence of this function? You modify the global MCAP array by writing
0x03to MCAP[1], so when this function is called a second time, MCAP[1] will be0x03already in the first call a few lines above, instead of the0x00that it was initially.drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 189
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +8
-0+ }else { +/* +* TODO : need to verify panel settings when +* dsi cmd mode supported for apq8064 - simhavcs +*/ + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret;This whole else clause is dead code because the condition for the if clause is always true. Just drop it and add it back when you properly support both modes.
Quoted 15 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +15
-0+static int jdi_panel_on (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + + ret =mipi_dsi_dcs_set_display_on (dsi); +if (ret <0 ) +return ret; + +return 0 ; +} + +static int jdi_panel_off (struct jdi_panel *jdi)
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 298
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM ;Should this not be cleared at the end of the function so that the below commands still get run in LP mode?
display off is done in HS mode as per the clock diagram of the generic dsi panel datasheet.
Quoted 22 lines
Quoted 22 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +21
-0+ + ret =mipi_dsi_dcs_set_display_off (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_enter_sleep_mode (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_tear_off (dsi); +if (ret <0 ) +return ret; + +msleep (100 ); + +return 0 ; +} + +static int jdi_panel_disable (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel);
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 324
Quoted 5 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+ +if (!jdi->enabled) +return 0 ; + +DRM_DEBUG ("disable\n" );This doesn't look very useful debug information. I think you should remove it. Same for other similar occurrences below.
when we enable the drm.debug log in cmdline, we well get this information, It is good to have debug logs of the panel got disabled or not. If you suggest not required will remove in the v3 version
Quoted 17 lines
Quoted 4 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +3
-0+static const struct drm_panel_funcs jdi_panel_funcs = { + .disable = jdi_panel_disable, + .unprepare = jdi_panel_unprepare,drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 512
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ .prepare = jdi_panel_prepare, + .enable = jdi_panel_enable, + .get_modes = jdi_panel_get_modes, +}; + +static const struct of_device_id jdi_of_match[] = { + { .compatible ="jdi,lt070me05000" , }, + { } +}; +MODULE_DEVICE_TABLE (of, jdi_of_match);A single tab is enough to indent the above.
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 519
Quoted 6 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +6
-0+static int jdi_panel_add (struct jdi_panel *jdi) +{ +struct device *dev = &jdi->dsi->dev; +int ret; + + jdi->mode = &default_mode;What do you keep this around for?
This will have the default resolution of the dsi panel.
Quoted 78 lines
Quoted 49 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +48
-0+ +/* lvs5 */ + jdi->supply =devm_regulator_get (dev,"power" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply); + +/* l17 */ + jdi->backlit =devm_regulator_get (dev,"backlit" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply); + + jdi->lvs7 =devm_regulator_get (dev,"lvs7" ); +if (IS_ERR (jdi->lvs7)) +return PTR_ERR (jdi->lvs7); + + jdi->avdd =devm_regulator_get (dev,"avdd" ); +if (IS_ERR (jdi->avdd)) +return PTR_ERR (jdi->avdd); + + jdi->iovdd =devm_regulator_get (dev,"iovdd" ); +if (IS_ERR (jdi->iovdd)) +return PTR_ERR (jdi->iovdd); + + jdi->vcc_gpio =devm_gpiod_get (dev,"vcc" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->vcc_gpio)) { +dev_err (dev,"cannot get vcc-gpio %ld\n" , +PTR_ERR (jdi->vcc_gpio)); + jdi->vcc_gpio =NULL ; + }else { +gpiod_direction_output (jdi->vcc_gpio,0 ); + } + + jdi->reset_gpio =devm_gpiod_get (dev,"reset" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->reset_gpio)) { +dev_err (dev,"cannot get reset-gpios %ld\n" , +PTR_ERR (jdi->reset_gpio)); + jdi->reset_gpio =NULL ; + }else { +gpiod_direction_output (jdi->reset_gpio,0 ); + } + + jdi->enable_gpio =devm_gpiod_get (dev,"enable" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->enable_gpio)) { +dev_err (dev,"cannot get enable-gpio %ld\n" , +PTR_ERR (jdi->enable_gpio)); + jdi->enable_gpio =NULL ; + }else { +gpiod_direction_output (jdi->enable_gpio,0 );drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 577
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ } + + jdi->pwm_gpio =devm_gpiod_get (dev,"pwm" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->pwm_gpio)) { +dev_err (dev,"cannot get pwm-gpio %ld\n" , +PTR_ERR (jdi->pwm_gpio)); + jdi->pwm_gpio =NULL ; + }else { +gpiod_direction_output (jdi->pwm_gpio,0 ); + }As I said earlier, most of these aren't specified in the binding, fix either the binding or the code.
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 589
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+/* we don't have backlight right now, proceed further */ +#ifdef BACKLIGHT + np =of_parse_phandle (dev->of_node,"backlight" ,0 ); +if (np) { + jdi->backlight =of_find_backlight_by_node (np); +of_node_put (np); + +if (!jdi->backlight) +return -EPROBE_DEFER ; + } +#endif Again, if you don't support it, don't submit it. We don't want dead code in the kernel.
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 684
Quoted 3 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +3
-0+MODULE_AUTHOR ("Sumit Semwal <[email protected]>" ); +MODULE_AUTHOR ("Vinay Simha BN <[email protected]>" ); +MODULE_DESCRIPTION ("JDI WUXGA LT070ME05000 DSI video/command mode panel driver" );Technically this doesn't support command mode yet, so you might want to remove that from the description to avoid confusion.
Thierry
all other inputs are fixed in the v2 version
Signature · 7 lines
Regards, Vinay Simha.B.N. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH RESEND 1/1 drm/panel: Add JDI LT070ME05000 WUXGA DSI Panel
In reply to Vinay Simha BNAdd support for the JDI lt070me05000 WUXGA DSI panel used in Nexus 7 2013 devices.
Programming sequence for the panel is was originally found in the android-msm-flo-3.4-lollipop-release branch from:
https://android.googlesource.com/kernel/msm.git
And video mode setting is from dsi-panel-jdi-dualmipi1-video.dtsi file in:
git://codeaurora.org/kernel/msm-3.10.git LNX.LA.3.6_rb1.27
Other fixes folded in were provided
by Archit Taneja <[email protected]>
[jstultz: Cherry-picked to mainline, folded down other fixes
from Vinay and Archit]
[vinay simha bn: added interface setting cmd mode, cmd or video mode panel setting selection in panel_init based on mode_flags]
--- .../bindings/display/panel/jdi,lt070me05000.txt | 27 + .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 685 +++++++++++++++++++++ 5 files changed, 725 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt create mode 100644 drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +27 -0
@@ -0,0 +1,27 @@ +JDI model LT070ME05000 1920x1200 7" DSI Panel + +Basic data sheet is at: + http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet + +This panel has video mode implemented currently in the driver. + +Required properties: +- compatible: should be "jdi,lt070me05000" + +Optional properties: +- power-supply: phandle of the regulator that provides the supply voltage +- reset-gpio: phandle of gpio for reset line +- backlight: phandle of the backlight device attached to the panel + +Example: + + dsi@54300000 { + panel: panel@0 { + compatible = "jdi,lt070me05000"; + reg = <0>; + + power-supply = <...>; + reset-gpio = <...>; + backlight = <...>; + }; + };
Documentation/devicetree/bindings/vendor-prefixes.txt +1 -0
@@ -130,6 +130,7 @@ invensense InvenSense Inc. isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jdi Japan Display Inc. jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH keymile Keymile GmbH
drivers/gpu/drm/panel/Kconfig +11 -0
@@ -61,6 +61,17 @@ config DRM_PANEL_SHARP_LQ101R1SX01 To compile this driver as a module, choose M here: the module will be called panel-sharp-lq101r1sx01. +config DRM_PANEL_JDI_LT070ME05000 + tristate "JDI LT070ME05000 WUXGA DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for JDI WUXGA DSI video/ + command mode panel as found in Google Nexus 7 (2013) devices. + The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses + 24 bit RGB per pixel. + config DRM_PANEL_SHARP_LS043T1LE01 tristate "Sharp LS043T1LE01 qHD video mode panel" depends on OF
drivers/gpu/drm/panel/Makefile +1 -0
@@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o +obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +685 -0
685 lines not on this page · raw message
Signature · 1 line
2.1.2
Rob Herring
maintainerQuoted 41 lines · Vinay Simha BN
Add support for the JDI lt070me05000 WUXGA DSI panel used in Nexus 7 2013 devices.
Programming sequence for the panel is was originally found in the android-msm-flo-3.4-lollipop-release branch from:
https://android.googlesource.com/kernel/msm.gitAnd video mode setting is from
dsi-panel-jdi-dualmipi1-video.dtsifile in:git://codeaurora.org/kernel/msm-3.10.git LNX.LA.3.6_rb1.27Other fixes folded in were provided
by Archit Taneja <[email protected]>Cc Archit Taneja <[email protected]>Signed-off-by Vinay Simha BN <[email protected]>[sumit.semwal: Ported to the drm/panel framework]Signed-off-by Sumit Semwal <[email protected]>[jstultz: Cherry-picked to mainline, folded down other fixes
from Vinay and Archit]Signed-off-by John Stultz <[email protected]>Acked-by John Stultz <[email protected]>[vinay simha bn: added interface setting cmd mode, cmd or video mode panel setting selection in
panel_initbased onmode_flags]Signed-off-by Vinay Simha BN <[email protected]>--- .../bindings/display/panel/jdi,lt070me05000.txt | 27 + .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 685 +++++++++++++++++++++ 5 files changed, 725 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt create mode 100644 drivers/gpu/drm/panel/panel-jdi-lt070me05000.cDocumentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +0
-0
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 6
Quoted 6 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +6
-0@@ -0,0 +1,27 @@ +JDI model LT070ME05000 1920x1200 7" DSI Panel + +Basic data sheet is at: + http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet + +This panel has video mode implemented currently in the driver.
As Thierry already mentioned, this has nothing to do with the binding.
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 13
Quoted 7 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +7
-0+ +Required properties: +- compatible: should be "jdi,lt070me05000" + +Optional properties: +- power-supply: phandle of the regulator that provides the supply voltage +- reset-gpio: phandle of gpio for reset line
reset-gpios
Quoted 751 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +14
-0+- backlight: phandle of the backlight device attached to the panel + +Example: + + dsi@54300000 { + panel: panel@0 { + compatible = "jdi,lt070me05000"; + reg = <0>; + + power-supply = <...>; + reset-gpio = <...>; + backlight = <...>; + }; + };Documentation/devicetree/bindings/vendor-prefixes.txt +1
-0@@ -130,6 +130,7 @@ invensense InvenSense Inc. isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jdi Japan Display Inc. jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH keymile Keymile GmbHdrivers/gpu/drm/panel/Kconfig +11
-0@@ -61,6 +61,17 @@ config DRM_PANEL_SHARP_LQ101R1SX01 To compile this driver as a module, choose M here: the module will be called panel-sharp-lq101r1sx01. +config DRM_PANEL_JDI_LT070ME05000 + tristate "JDI LT070ME05000 WUXGA DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for JDI WUXGA DSI video/ + command mode panel as found in Google Nexus 7 (2013) devices. + The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses + 24 bit RGB per pixel. + config DRM_PANEL_SHARP_LS043T1LE01 tristate "Sharp LS043T1LE01 qHD video mode panel" depends on OFdrivers/gpu/drm/panel/Makefile +1
-0@@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o +obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.odrivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +685
-0@@ -0,0 +1,685 @@ +/* +* Copyright (C) 2015 InforceComputing +* Author: Vinay Simha BN <[email protected]> +* +* Copyright (C) 2015 Linaro Ltd +* Author: Sumit Semwal <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 as published by +* the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <linux/backlight.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include <drm/drmP.h> +#include <drm/drm_crtc.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_panel.h> + +#include <video/mipi_display.h> + +/* +* From internet archives, the panel for Nexus 7 2nd Gen, 2013 model is a +* JDI model LT070ME05000, and its data sheet is at: +* http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet +*/ +struct jdi_panel { +struct drm_panel base; +struct mipi_dsi_device *dsi; + +/* TODO: Add backilght support */ +struct backlight_device *backlight; +struct regulator *supply; +struct gpio_desc *reset_gpio; +struct gpio_desc *enable_gpio; +struct gpio_desc *vcc_gpio; + +struct regulator *backlit; +struct regulator *lvs7; +struct regulator *avdd; +struct regulator *iovdd; +struct gpio_desc *pwm_gpio; + +bool prepared; +bool enabled; + +const struct drm_display_mode *mode; +}; + +static inline struct jdi_panel *to_jdi_panel (struct drm_panel *panel) +{ + return container_of(panel, struct jdi_panel, base); +} + +static char MCAP [2 ] = {0xB0 ,0x00 }; +static char interface_setting_cmd[6 ] = {0xB3 ,0x04 ,0x08 ,0x00 ,0x22 ,0x00 }; +static char interface_setting[6 ] = {0xB3 ,0x26 ,0x08 ,0x00 ,0x20 ,0x00 }; + +static char interface_ID_setting[2 ] = {0xB4 ,0x0C }; +static char DSI_control[3 ] = {0xB6 ,0x3A ,0xD3 }; + +static char tear_scan_line[3 ] = {0x44 ,0x03 ,0x00 }; + +/* for fps control, set fps to 60.32Hz */ +static char LTPS_timing_setting[2 ] = {0xC6 ,0x78 }; +static char sequencer_timing_control[2 ] = {0xD6 ,0x01 }; + +/* set brightness */ +static char write_display_brightness[] = {0x51 ,0xFF }; +/* enable LEDPWM pin output, turn on LEDPWM output, turn off pwm dimming */ +static char write_control_display[] = {0x53 ,0x24 }; +/* +* choose cabc mode, 0x00(-0%), 0x01(-15%), 0x02(-40%), 0x03(-54%), +* disable SRE(sunlight readability enhancement) +*/ +static char write_cabc[] = {0x55 ,0x00 }; +/* for cabc mode 0x1(-15%) */ +static char backlight_control1[] = {0xB8 ,0x07 ,0x87 ,0x26 ,0x18 ,0x00 ,0x32 }; +/* for cabc mode 0x2(-40%) */ +static char backlight_control2[] = {0xB9 ,0x07 ,0x75 ,0x61 ,0x20 ,0x16 ,0x87 }; +/* for cabc mode 0x3(-54%) */ +static char backlight_control3[] = {0xBA ,0x07 ,0x70 ,0x81 ,0x20 ,0x45 ,0xB4 }; +/* for pwm frequency and dimming control */ +static char backlight_control4[] = {0xCE ,0x7D ,0x40 ,0x48 ,0x56 ,0x67 ,0x78 , +0x88 ,0x98 ,0xA7 ,0xB5 ,0xC3 ,0xD1 ,0xDE ,0xE9 ,0xF2 ,0xFA , +0xFF ,0x37 ,0xF5 ,0x0F ,0x0F ,0x42 ,0x00 }; + +static int jdi_panel_init (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + +if (dsi->mode_flags &MIPI_DSI_MODE_VIDEO ) { + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret; + +mdelay (10 ); + + ret =mipi_dsi_dcs_set_pixel_format (dsi,0x70 ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_column_address (dsi,0x0000 ,0x04AF ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_page_address (dsi,0x0000 ,0x077F ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_tear_on (dsi, +MIPI_DSI_DCS_TEAR_MODE_VBLANK ); +if (ret <0 ) +return ret; +mdelay (5 ); + + ret =mipi_dsi_generic_write (dsi, tear_scan_line, +sizeof (tear_scan_line)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_display_brightness, +sizeof (write_display_brightness) + ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_control_display, +sizeof (write_control_display)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_cabc, +sizeof (write_cabc)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_exit_sleep_mode (dsi); +if (ret <0 ) +return ret; +mdelay (120 ); + + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret; +mdelay (10 ); + + ret =mipi_dsi_generic_write (dsi, interface_setting, +sizeof (interface_setting)); +if (ret <0 ) +return ret; +mdelay (20 ); + + backlight_control4[18 ] =0x04 ; + backlight_control4[19 ] =0x00 ; + + ret =mipi_dsi_generic_write (dsi, backlight_control4, +sizeof (backlight_control4)); +if (ret <0 ) +return ret; +mdelay (20 ); + +MCAP [1 ] =0x03 ; + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret; + }else { +/* +* TODO : need to verify panel settings when +* dsi cmd mode supported for apq8064 - simhavcs +*/ + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret; + +mdelay (5 ); + + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, interface_setting_cmd, +sizeof (interface_setting_cmd)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, interface_ID_setting, +sizeof (interface_ID_setting)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, DSI_control, +sizeof (DSI_control)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, LTPS_timing_setting, +sizeof (LTPS_timing_setting)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, sequencer_timing_control, +sizeof (sequencer_timing_control)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_display_brightness, +sizeof (write_display_brightness) + ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_control_display, +sizeof (write_control_display)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_cabc, +sizeof (write_cabc)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, backlight_control1, +sizeof (backlight_control1)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, backlight_control2, +sizeof (backlight_control2)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, backlight_control3, +sizeof (backlight_control3)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, backlight_control4, +sizeof (backlight_control4)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_pixel_format (dsi,0x77 ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_column_address (dsi,0x0000 ,0x04AF ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_page_address (dsi,0x0000 ,0x077F ); +if (ret <0 ) +return ret; +mdelay (120 ); + + ret =mipi_dsi_dcs_exit_sleep_mode (dsi); +if (ret <0 ) +return ret; + } + +return 0 ; +} + +static int jdi_panel_on (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + + ret =mipi_dsi_dcs_set_display_on (dsi); +if (ret <0 ) +return ret; + +return 0 ; +} + +static int jdi_panel_off (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM ; + + ret =mipi_dsi_dcs_set_display_off (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_enter_sleep_mode (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_tear_off (dsi); +if (ret <0 ) +return ret; + +msleep (100 ); + +return 0 ; +} + +static int jdi_panel_disable (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); + +if (!jdi->enabled) +return 0 ; + +DRM_DEBUG ("disable\n" ); + +if (jdi->backlight) { + jdi->backlight->props.power =FB_BLANK_POWERDOWN ; +backlight_update_status (jdi->backlight); + } + + jdi->enabled = false; + +return 0 ; +} + +static int jdi_panel_unprepare (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); +int ret; + +if (!jdi->prepared) +return 0 ; + +DRM_DEBUG ("unprepare\n" ); + + ret =jdi_panel_off (jdi); +if (ret) { +dev_err (panel->dev,"failed to set panel off: %d\n" , ret); +return ret; + } + +regulator_disable (jdi->supply); + +if (jdi->vcc_gpio) +gpiod_set_value (jdi->vcc_gpio,0 ); + +if (jdi->reset_gpio) +gpiod_set_value (jdi->reset_gpio,0 ); + +if (jdi->enable_gpio) +gpiod_set_value (jdi->enable_gpio,0 ); + + jdi->prepared = false; + +return 0 ; +} + +static int jdi_panel_prepare (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); +int ret; + +if (jdi->prepared) +return 0 ; + +DRM_DEBUG ("prepare\n" ); + + ret =regulator_enable (jdi->iovdd); +if (ret <0 ) +return ret; + + ret =regulator_enable (jdi->avdd); +if (ret <0 ) +return ret; + + ret =regulator_enable (jdi->backlit); +if (ret <0 ) +return ret; + + ret =regulator_enable (jdi->lvs7); +if (ret <0 ) +return ret; + + ret =regulator_enable (jdi->supply); +if (ret <0 ) +return ret; + +msleep (20 ); + +if (jdi->vcc_gpio) { +gpiod_set_value (jdi->vcc_gpio,1 ); +usleep_range (10 ,20 ); + } + +if (jdi->reset_gpio) { +gpiod_set_value (jdi->reset_gpio,1 ); +usleep_range (10 ,20 ); + } + +if (jdi->pwm_gpio) { +gpiod_set_value (jdi->pwm_gpio,1 ); +usleep_range (10 ,20 ); + } + +if (jdi->enable_gpio) { +gpiod_set_value (jdi->enable_gpio,1 ); +usleep_range (10 ,20 ); + } + + ret =jdi_panel_init (jdi); +if (ret) { +dev_err (panel->dev,"failed to init panel: %d\n" , ret); + goto poweroff; + } + + ret =jdi_panel_on (jdi); +if (ret) { +dev_err (panel->dev,"failed to set panel on: %d\n" , ret); + goto poweroff; + } + + jdi->prepared = true; + +return 0 ; + +poweroff: +regulator_disable (jdi->supply); +if (jdi->reset_gpio) +gpiod_set_value (jdi->reset_gpio,0 ); +if (jdi->enable_gpio) +gpiod_set_value (jdi->enable_gpio,0 ); +if (jdi->vcc_gpio) +gpiod_set_value (jdi->vcc_gpio,0 ); + +return ret; +} + +static int jdi_panel_enable (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); + +if (jdi->enabled) +return 0 ; + +DRM_DEBUG ("enable\n" ); + +if (jdi->backlight) { + jdi->backlight->props.power =FB_BLANK_UNBLANK ; +backlight_update_status (jdi->backlight); + } + + jdi->enabled = true; + +return 0 ; +} + +static const struct drm_display_mode default_mode = { + .clock =155000 , + .hdisplay =1200 , + .hsync_start =1200 +48 , + .hsync_end =1200 +48 +32 , + .htotal =1200 +48 +32 +60 , + .vdisplay =1920 , + .vsync_start =1920 +3 , + .vsync_end =1920 +3 +5 , + .vtotal =1920 +3 +5 +6 , + .vrefresh =60 , + .flags =0 , +}; + +static int jdi_panel_get_modes (struct drm_panel *panel) +{ +struct drm_display_mode *mode; + + mode =drm_mode_duplicate (panel->drm, &default_mode); +if (!mode) { +dev_err (panel->drm->dev,"failed to add mode %ux%ux@%u\n" , + default_mode.hdisplay, default_mode.vdisplay, + default_mode.vrefresh); +return -ENOMEM ; + } + +drm_mode_set_name (mode); + +drm_mode_probed_add (panel->connector, mode); + +return 1 ; +} + +static const struct drm_panel_funcs jdi_panel_funcs = { + .disable = jdi_panel_disable, + .unprepare = jdi_panel_unprepare, + .prepare = jdi_panel_prepare, + .enable = jdi_panel_enable, + .get_modes = jdi_panel_get_modes, +}; + +static const struct of_device_id jdi_of_match[] = { + { .compatible ="jdi,lt070me05000" , }, + { } +}; +MODULE_DEVICE_TABLE (of, jdi_of_match); + +static int jdi_panel_add (struct jdi_panel *jdi) +{ +struct device *dev = &jdi->dsi->dev; +int ret; + + jdi->mode = &default_mode; + +/* lvs5 */ + jdi->supply =devm_regulator_get (dev,"power" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply); + +/* l17 */ + jdi->backlit =devm_regulator_get (dev,"backlit" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply); + + jdi->lvs7 =devm_regulator_get (dev,"lvs7" ); +if (IS_ERR (jdi->lvs7)) +return PTR_ERR (jdi->lvs7); + + jdi->avdd =devm_regulator_get (dev,"avdd" ); +if (IS_ERR (jdi->avdd)) +return PTR_ERR (jdi->avdd); + + jdi->iovdd =devm_regulator_get (dev,"iovdd" ); +if (IS_ERR (jdi->iovdd)) +return PTR_ERR (jdi->iovdd); + + jdi->vcc_gpio =devm_gpiod_get (dev,"vcc" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->vcc_gpio)) { +dev_err (dev,"cannot get vcc-gpio %ld\n" , +PTR_ERR (jdi->vcc_gpio)); + jdi->vcc_gpio =NULL ; + }else { +gpiod_direction_output (jdi->vcc_gpio,0 ); + } + + jdi->reset_gpio =devm_gpiod_get (dev,"reset" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->reset_gpio)) { +dev_err (dev,"cannot get reset-gpios %ld\n" , +PTR_ERR (jdi->reset_gpio)); + jdi->reset_gpio =NULL ; + }else { +gpiod_direction_output (jdi->reset_gpio,0 ); + } + + jdi->enable_gpio =devm_gpiod_get (dev,"enable" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->enable_gpio)) { +dev_err (dev,"cannot get enable-gpio %ld\n" , +PTR_ERR (jdi->enable_gpio)); + jdi->enable_gpio =NULL ; + }else { +gpiod_direction_output (jdi->enable_gpio,0 ); + } + + jdi->pwm_gpio =devm_gpiod_get (dev,"pwm" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->pwm_gpio)) { +dev_err (dev,"cannot get pwm-gpio %ld\n" , +PTR_ERR (jdi->pwm_gpio)); + jdi->pwm_gpio =NULL ; + }else { +gpiod_direction_output (jdi->pwm_gpio,0 ); + } + +/* we don't have backlight right now, proceed further */ +#ifdef BACKLIGHT + np =of_parse_phandle (dev->of_node,"backlight" ,0 ); +if (np) { + jdi->backlight =of_find_backlight_by_node (np); +of_node_put (np); + +if (!jdi->backlight) +return -EPROBE_DEFER ; + } +#endif + +drm_panel_init (&jdi->base); + jdi->base.funcs = &jdi_panel_funcs; + jdi->base.dev = &jdi->dsi->dev; + + ret =drm_panel_add (&jdi->base); +if (ret <0 ) + goto put_backlight; + +return 0 ; + +put_backlight: +if (jdi->backlight) +put_device (&jdi->backlight->dev); + +return ret; +} + +static void jdi_panel_del (struct jdi_panel *jdi) +{ +if (jdi->base.dev) +drm_panel_remove (&jdi->base); + +if (jdi->backlight) +put_device (&jdi->backlight->dev); +} + +static int jdi_panel_probe (struct mipi_dsi_device *dsi) +{ +struct jdi_panel *jdi; +int ret; + + dsi->lanes =4 ; + dsi->format =MIPI_DSI_FMT_RGB888 ; + dsi->mode_flags =MIPI_DSI_MODE_VIDEO_HSE |MIPI_DSI_MODE_VIDEO | +MIPI_DSI_MODE_VIDEO_HFP |MIPI_DSI_MODE_VIDEO_HBP | +MIPI_DSI_MODE_VIDEO_HSA | +MIPI_DSI_CLOCK_NON_CONTINUOUS ; + + jdi =devm_kzalloc (&dsi->dev,sizeof (*jdi),GFP_KERNEL ); +if (!jdi) +return -ENOMEM ; + +mipi_dsi_set_drvdata (dsi, jdi); + + jdi->dsi = dsi; + + ret =jdi_panel_add (jdi); +if (ret <0 ) +return ret; + +return mipi_dsi_attach (dsi); +} + +static int jdi_panel_remove (struct mipi_dsi_device *dsi) +{ +struct jdi_panel *jdi =mipi_dsi_get_drvdata (dsi); +int ret; + + ret =jdi_panel_disable (&jdi->base); +if (ret <0 ) +dev_err (&dsi->dev,"failed to disable panel: %d\n" , ret); + + ret =mipi_dsi_detach (dsi); +if (ret <0 ) +dev_err (&dsi->dev,"failed to detach from DSI host: %d\n" , + ret); + +drm_panel_detach (&jdi->base); +jdi_panel_del (jdi); + +return 0 ; +} + +static void jdi_panel_shutdown (struct mipi_dsi_device *dsi) +{ +struct jdi_panel *jdi =mipi_dsi_get_drvdata (dsi); + +jdi_panel_disable (&jdi->base); +} + +static struct mipi_dsi_driver jdi_panel_driver = { + .driver = { + .name ="panel-jdi-lt070me05000" , + .of_match_table = jdi_of_match, + }, + .probe = jdi_panel_probe, + .remove = jdi_panel_remove, + .shutdown = jdi_panel_shutdown, +}; +module_mipi_dsi_driver (jdi_panel_driver); + +MODULE_AUTHOR ("Sumit Semwal <[email protected]>" ); +MODULE_AUTHOR ("Vinay Simha BN <[email protected]>" ); +MODULE_DESCRIPTION ("JDI WUXGA LT070ME05000 DSI video/command mode panel driver" ); +MODULE_LICENSE ("GPL v2" );Signature · 1 line
2.1.2
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v2 1/4 dt-bindings: Add jdi panel vendor
Japan Display Inc.
--- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/vendor-prefixes.txt +1 -0
@@ -133,6 +133,7 @@ invensense InvenSense Inc. isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jdi Japan Display Inc. jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH keymile Keymile GmbH
Signature · 6 lines
2.1.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 2/4 dt-bindings: Add jdi lt070me05000 panel bindings
Add documentation for lt070me05000 panel
--- .../bindings/display/panel/jdi,lt070me05000.txt | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +43 -0
@@ -0,0 +1,43 @@ +JDI model LT070ME05000 1200x1920 7" DSI Panel + +Required properties: +- compatible: should be "jdi,lt070me05000" +- power-supply: phandle of the regulator that provides the supply voltage + IOVCC , power supply for LCM (1.8V) +- vddp-supply: phandle of the regulator that provides the supply voltage + Power IC supply (3-5V) +- dcdc_en-supply: phandle of the regulator that provides the supply voltage + Power IC supply enable, High active +- reset-gpio: phandle of gpio for reset line + This should be 8mA, gpio can be configured using mux and pinctrl. + XRES, Reset, Low active +- enable-gpio: phandle of gpio for enable line + LED_EN, LED backlight enable, High active +- vcc-gpio: phandle of regulator/gpio that provides the supply voltage + VDD, LED power supply (3-5V) + +Optional properties: +- pwm-gpio: phandle of gpio/pwm + pwm backlight control, this should be mapped to the backlight level + display brightness (0x51) + +Example: + + dsi0: qcom,mdss_dsi@4700000 { + panel@0 { + compatible = "jdi,lt070me05000"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&dsi_panel_pinctrl>; + + power-supply = <&pm8921_lvs5>; + vddp-supply = <&pm8921_l17>; + dcdc_en-supply = <&pm8921_lvs7>; + + reset-gpio = <&tlmm_pinmux 54 0>; + enable-gpio = <&pm8921_gpio 36 GPIO_ACTIVE_HIGH>; + vcc-gpio = <&pm8921_gpio 23 GPIO_ACTIVE_HIGH>; + + pwm-gpio = <&pm8921_gpio 26 GPIO_ACTIVE_HIGH>; + }; + };
Signature · 1 line
2.1.2
Rob Herring
maintainerRe: [PATCH v2 2/4] dt-bindings: Add jdi lt070me05000 panel bindings
Quoted 19 lines · Vinay Simha BN
Add documentation for lt070me05000 panel
Signed-off-by Vinay Simha BN <[email protected]>--- .../bindings/display/panel/jdi,lt070me05000.txt | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txtDocumentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +5
-0@@ -0,0 +1,43 @@ +JDI model LT070ME05000 1200x1920 7" DSI Panel + +Required properties: +- compatible: should be "jdi,lt070me05000" +- power-supply: phandle of the regulator that provides the supply voltage
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 15
Quoted 10 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +10
-0+ IOVCC , power supply for LCM (1.8V) +- vddp-supply: phandle of the regulator that provides the supply voltage + Power IC supply (3-5V) +- dcdc_en-supply: phandle of the regulator that provides the supply voltage + Power IC supply enable, High active +- reset-gpio: phandle of gpio for reset line + This should be 8mA, gpio can be configured using mux and pinctrl. + XRES, Reset, Low active +- enable-gpio: phandle of gpio for enable line + LED_EN, LED backlight enable, High active
These should all be -gpios instead.
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 17
Quoted 2 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +2
-0+- vcc-gpio: phandle of regulator/gpio that provides the supply voltage + VDD, LED power supply (3-5V)
Is it a regulator or gpio?
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 20
Quoted 3 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +3
-0+ +Optional properties: +- pwm-gpio: phandle of gpio/pwm
This should use the PWM binding. It may not be a GPIO on some hosts.
Quoted 26 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +23
-0+ pwm backlight control, this should be mapped to the backlight level + display brightness (0x51) + +Example: + + dsi0: qcom,mdss_dsi@4700000 { + panel@0 { + compatible = "jdi,lt070me05000"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&dsi_panel_pinctrl>; + + power-supply = <&pm8921_lvs5>; + vddp-supply = <&pm8921_l17>; + dcdc_en-supply = <&pm8921_lvs7>; + + reset-gpio = <&tlmm_pinmux 54 0>; + enable-gpio = <&pm8921_gpio 36 GPIO_ACTIVE_HIGH>; + vcc-gpio = <&pm8921_gpio 23 GPIO_ACTIVE_HIGH>; + + pwm-gpio = <&pm8921_gpio 26 GPIO_ACTIVE_HIGH>; + }; + };Signature · 1 line
2.1.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/4] dt-bindings: Add jdi lt070me05000 panel bindings
Quoted 24 lines · Rob Herring
Quoted 23 lines · Vinay Simha BN
Add documentation for lt070me05000 panel
Signed-off-by Vinay Simha BN <[email protected]>--- .../bindings/display/panel/jdi,lt070me05000.txt | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txtDocumentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +9
-0@@ -0,0 +1,43 @@ +JDI model LT070ME05000 1200x1920 7" DSI Panel + +Required properties: +- compatible: should be "jdi,lt070me05000" +- power-supply: phandle of the regulator that provides the supply voltage + IOVCC , power supply for LCM (1.8V) +- vddp-supply: phandle of the regulator that provides the supply voltage + Power IC supply (3-5V) +- dcdc_en-supply: phandle of the regulator that provides the supply voltage
Quoted 8 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 15
Quoted 6 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +6
-0+ Power IC supply enable, High active +- reset-gpio: phandle of gpio for reset line + This should be 8mA, gpio can be configured using mux and pinctrl. + XRES, Reset, Low active +- enable-gpio: phandle of gpio for enable line + LED_EN, LED backlight enable, High activeThese should all be -gpios instead.
will implement in v3
Quoted 6 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 17
Quoted 3 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +2
-0+- vcc-gpio: phandle of regulator/gpio that provides the supply voltage + VDD, LED power supply (3-5V)Is it a regulator or gpio?
VDD is LED power supply, but in nexus 7 2nd gen they are using gpio 23 instead of regulator.
if we use vcc-supply, not sure we can give the gpio device tree entry to it in nexus 7 dts. Any inputs ?
Quoted 5 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 20
Quoted 3 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +3
-0+ +Optional properties: +- pwm-gpio: phandle of gpio/pwmThis should use the PWM binding. It may not be a GPIO on some hosts.
pwm-gpio will go to the backlight (pwm). right now it is not used since pwm pm8921 upstream driver is not yet implemented. Shall i remove this pwm-gpio now and the backlight property when pwm pm8921 is implemented?
Quoted 27 lines
Quoted 27 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +23
-1+ pwm backlight control, this should be mapped to the backlight level + display brightness (0x51) + +Example: + + dsi0: qcom,mdss_dsi@4700000 { + panel@0 { + compatible = "jdi,lt070me05000"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&dsi_panel_pinctrl>; + + power-supply = <&pm8921_lvs5>; + vddp-supply = <&pm8921_l17>; + dcdc_en-supply = <&pm8921_lvs7>; + + reset-gpio = <&tlmm_pinmux 54 0>; + enable-gpio = <&pm8921_gpio 36 GPIO_ACTIVE_HIGH>; + vcc-gpio = <&pm8921_gpio 23 GPIO_ACTIVE_HIGH>; + + pwm-gpio = <&pm8921_gpio 26 GPIO_ACTIVE_HIGH>; + }; + }; --2.1.2
Signature · 7 lines
Regards, Vinay Simha.B.N. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/4] dt-bindings: Add jdi lt070me05000 panel bindings
Quoted 38 lines · Vinay Simha
Quoted 24 lines · Rob Herring
Quoted 23 lines · Vinay Simha BN
Add documentation for lt070me05000 panel
Signed-off-by Vinay Simha BN <[email protected]>--- .../bindings/display/panel/jdi,lt070me05000.txt | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txtDocumentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +9
-0@@ -0,0 +1,43 @@ +JDI model LT070ME05000 1200x1920 7" DSI Panel + +Required properties: +- compatible: should be "jdi,lt070me05000" +- power-supply: phandle of the regulator that provides the supply voltage + IOVCC , power supply for LCM (1.8V) +- vddp-supply: phandle of the regulator that provides the supply voltage + Power IC supply (3-5V) +- dcdc_en-supply: phandle of the regulator that provides the supply voltageQuoted 8 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 15
Quoted 6 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +6
-0+ Power IC supply enable, High active +- reset-gpio: phandle of gpio for reset line + This should be 8mA, gpio can be configured using mux and pinctrl. + XRES, Reset, Low active +- enable-gpio: phandle of gpio for enable line + LED_EN, LED backlight enable, High activeThese should all be -gpios instead.
will implement in v3
Quoted 4 lines
Quoted 3 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +2
-0+- vcc-gpio: phandle of regulator/gpio that provides the supply voltage + VDD, LED power supply (3-5V)
Quoted 6 lines
Quoted 2 lines
Is it a regulator or gpio?
VDD is LED power supply, but in nexus 7 2nd gen they are using gpio 23 instead of regulator.
if we use vcc-supply, not sure we can give the gpio device tree entry to it in nexus 7 dts. Any inputs ?
You can model it as a fixed regulator that's enabled by a GPIO. See:
Documentation/devicetree/bindings/regulator/fixed-regulator.txt
Quoted 10 lines
Quoted 5 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt line 20
Quoted 3 lines
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +3
-0+ +Optional properties: +- pwm-gpio: phandle of gpio/pwmThis should use the PWM binding. It may not be a GPIO on some hosts.
pwm-gpio will go to the backlight (pwm). right now it is not used since pwm pm8921 upstream driver is not yet implemented. Shall i remove this pwm-gpio now and the backlight property when pwm pm8921 is implemented?
This suggests to me that you don't have a good idea yet what the final binding would need to look like, so it might be better to get all the dependencies in place first so that the binding can be validated to work properly.
Thierry
PATCH v2 3/4 drm/dsi: Implement set tear scanline
In reply to Vinay Simha BNProvide a small convenience wrapper that transmits a set_tear_scanline command.
--- drivers/gpu/drm/drm_mipi_dsi.c | 22 ++++++++++++++++++++++ include/drm/drm_mipi_dsi.h | 2 ++ 2 files changed, 24 insertions(+)
drivers/gpu/drm/drm_mipi_dsi.c +22 -0
@@ -983,6 +983,28 @@ int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,EXPORT_SYMBOL (mipi_dsi_dcs_set_tear_on);/** +* mipi_dsi_set_tear_scanline() - turn on the display module's Tearing Effect +* output signal on the TE signal line when display module reaches line N +* defined by STS[n:0]. +* @dsi: DSI peripheral device +* @param1: STS[10:8] +* @param2: STS[7:0] +* Return: 0 on success or a negative error code on failure +*/ +int mipi_dsi_set_tear_scanline (struct mipi_dsi_device *dsi, +u8 param1,u8 param2) +{ +u8 payload[3 ] = {MIPI_DCS_SET_TEAR_SCANLINE , param1 , param2}; +ssize_t err; + + err =mipi_dsi_generic_write (dsi, &payload,sizeof (payload)); +if (err <0 ) +return err; + +return 0 ; +} +EXPORT_SYMBOL (mipi_dsi_dcs_set_tear_scanline); +/** * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image * data used by the interface * @dsi: DSI peripheral device
include/drm/drm_mipi_dsi.h +2 -0
@@ -263,6 +263,8 @@ int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, u16 end);int mipi_dsi_dcs_set_page_address (struct mipi_dsi_device *dsi,u16 start,u16 end); +int mipi_dsi_set_tear_scanline (struct mipi_dsi_device *dsi,u8 param1, +u8 param2);int mipi_dsi_dcs_set_tear_off (struct mipi_dsi_device *dsi);int mipi_dsi_dcs_set_tear_on (struct mipi_dsi_device *dsi,enum mipi_dsi_dcs_tear_mode mode);
Signature · 1 line
2.1.2
kbuild test robot
build botRe: [PATCH v2 3/4] drm/dsi: Implement set tear scanline
reproduce:
Hi,
[auto build test ERROR on tegra-drm/drm/tegra/for-next]
[also build test ERROR on v4.6-rc4 next-20160420]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Vinay-Simha-BN/dt-bindings-Add-jdi-panel-vendor/20160420-173456 base: git://anongit.freedesktop.org/tegra/linux.git drm/tegra/for-next config: x86_64-randconfig-x012-201616 (attached as .config) reproduce: # save the attached .config to linux build tree make ARCH=x86_64
All error/warnings (new ones prefixed by >>):
In file included from include/linux/linkage.h:6:0,
from include/linux/kernel.h:6,
from include/linux/list.h:8,
from include/linux/kobject.h:20,
from include/linux/device.h:17,
from include/drm/drm_mipi_dsi.h:15,
from drivers/gpu/drm/drm_mipi_dsi.c:28:
>> drivers/gpu/drm/drm_mipi_dsi.c:1006:15: error: 'mipi_dsi_dcs_set_tear_scanline' undeclared here (not in a function)
EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline);
^
include/linux/export.h:57:16: note: in definition of macro '__EXPORT_SYMBOL'
extern typeof(sym) sym; \
^
>> drivers/gpu/drm/drm_mipi_dsi.c:1006:1: note: in expansion of macro 'EXPORT_SYMBOL'
EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline);
^vim +/mipi_dsi_dcs_set_tear_scanline +1006 drivers/gpu/drm/drm_mipi_dsi.c
1000 err = mipi_dsi_generic_write(dsi, &payload, sizeof(payload));
1001 if (err < 0)
1002 return err;
1003
1004 return 0;
1005 }
> 1006 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline);
1007 /**
1008 * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
1009 * data used by the interface
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH v3 1/1 drm/dsi: Implement set tear scanline compile fix
Provide a small convenience wrapper that transmits a set_tear_scanline command.
compilation fix
--- drivers/gpu/drm/drm_mipi_dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/drm_mipi_dsi.c +1 -1
@@ -1003,7 +1003,7 @@ int mipi_dsi_set_tear_scanline(struct mipi_dsi_device *dsi,return 0 ; } -EXPORT_SYMBOL (mipi_dsi_dcs_set_tear_scanline); +EXPORT_SYMBOL (mipi_dsi_set_tear_scanline);/** * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image * data used by the interface
Signature · 1 line
2.1.2
PATCH v2 4/4 drm/panel: Add JDI LT070ME05000 WUXGA DSI Panel
In reply to Vinay Simha BNAdd support for the JDI lt070me05000 WUXGA DSI panel used in Nexus 7 2013 devices.
Programming sequence for the panel is was originally found in the android-msm-flo-3.4-lollipop-release branch from:
https://android.googlesource.com/kernel/msm.git
And video mode setting is from dsi-panel-jdi-dualmipi1-video.dtsi file in:
git://codeaurora.org/kernel/msm-3.10.git LNX.LA.3.6_rb1.27
Other fixes folded in were provided
by Archit Taneja <[email protected]>
[jstultz: Cherry-picked to mainline, folded down other fixes
from Vinay and Archit]
[vinay simha bn: removed interface setting cmd mode, video mode panel setting selection]
--- drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 506 +++++++++++++++++++++++++ 3 files changed, 518 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
drivers/gpu/drm/panel/Kconfig +11 -0
@@ -7,6 +7,17 @@ config DRM_PANEL menu "Display Panels" depends on DRM && DRM_PANEL +config DRM_PANEL_JDI_LT070ME05000 + tristate "JDI LT070ME05000 WUXGA DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for JDI WUXGA DSI video + mode panel as found in Google Nexus 7 (2013) devices. + The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses + 24 bit RGB per pixel. + config DRM_PANEL_SIMPLE tristate "support for simple panels" depends on OF
drivers/gpu/drm/panel/Makefile +1 -0
@@ -1,3 +1,4 @@ +obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +506 -0
506 lines not on this page · raw message
Signature · 1 line
2.1.2
Re: [PATCH v2 1/4] dt-bindings: Add jdi panel vendor
In reply to Vinay Simha BNQuoted 6 lines · Vinay Simha BN
Japan Display Inc.
Signed-off-by Vinay Simha BN <[email protected]>--- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+)
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 200 lines · Vinay Simha BN
Add support for the JDI lt070me05000 WUXGA DSI panel used in Nexus 7 2013 devices.
Programming sequence for the panel is was originally found in the android-msm-flo-3.4-lollipop-release branch from:
https://android.googlesource.com/kernel/msm.gitAnd video mode setting is from
dsi-panel-jdi-dualmipi1-video.dtsifile in:git://codeaurora.org/kernel/msm-3.10.git LNX.LA.3.6_rb1.27Other fixes folded in were provided
by Archit Taneja <[email protected]>Signed-off-by Vinay Simha BN <[email protected]>[sumit.semwal: Ported to the drm/panel framework]Signed-off-by Sumit Semwal <[email protected]>[jstultz: Cherry-picked to mainline, folded down other fixes
from Vinay and Archit]Signed-off-by John Stultz <[email protected]>--- .../bindings/display/panel/jdi,lt070me05000.txt | 27 + .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 685 +++++++++++++++++++++ 5 files changed, 725 insertions(+)create mode 100644
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txtcreate mode 100644drivers/gpu/drm/panel/panel-jdi-lt070me05000.cDocumentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +27
-0@@ -0,0 +1,27 @@ +JDI model LT070ME05000 1920x1200 7" DSI Panel + +Basic data sheet is at: + http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet + +This panel has video mode implemented currently in the driver. + +Required properties: +- compatible: should be "jdi,lt070me05000" + +Optional properties: +- power-supply: phandle of the regulator that provides the supply voltage +- reset-gpio: phandle of gpio for reset line +- backlight: phandle of the backlight device attached to the panel + +Example: + + dsi@54300000 { + panel: panel@0 { + compatible = "jdi,lt070me05000"; + reg = <0>; + + power-supply = <...>; + reset-gpio = <...>; + backlight = <...>; + }; + };Documentation/devicetree/bindings/vendor-prefixes.txt +1
-0@@ -130,6 +130,7 @@ invensense InvenSense Inc. isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jdi Japan Display Inc. jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH keymile Keymile GmbHdrivers/gpu/drm/panel/Kconfig +11
-0@@ -61,6 +61,17 @@ config DRM_PANEL_SHARP_LQ101R1SX01 To compile this driver as a module, choose M here: the module will be called panel-sharp-lq101r1sx01. +config DRM_PANEL_JDI_LT070ME05000 + tristate "JDI LT070ME05000 WUXGA DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for JDI WUXGA DSI video/ + command mode panel as found in Google Nexus 7 (2013) devices. + The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses + 24 bit RGB per pixel. + config DRM_PANEL_SHARP_LS043T1LE01 tristate "Sharp LS043T1LE01 qHD video mode panel" depends on OFdrivers/gpu/drm/panel/Makefile +1
-0@@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o +obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.odrivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +88
-0@@ -0,0 +1,685 @@ +/* +* Copyright (C) 2015 InforceComputing +* Author: Vinay Simha BN <[email protected]> +* +* Copyright (C) 2015 Linaro Ltd +* Author: Sumit Semwal <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 as published by +* the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <linux/backlight.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include <drm/drmP.h> +#include <drm/drm_crtc.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_panel.h> + +#include <video/mipi_display.h> + +/* +* From internet archives, the panel for Nexus 7 2nd Gen, 2013 model is a +* JDI model LT070ME05000, and its data sheet is at: +* http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet +*/ +struct jdi_panel { +struct drm_panel base; +struct mipi_dsi_device *dsi; + +/* TODO: Add backilght support */ +struct backlight_device *backlight; +struct regulator *supply; +struct gpio_desc *reset_gpio; +struct gpio_desc *enable_gpio; +struct gpio_desc *vcc_gpio; + +struct regulator *backlit; +struct regulator *lvs7; +struct regulator *avdd; +struct regulator *iovdd; +struct gpio_desc *pwm_gpio; + +bool prepared; +bool enabled; + +const struct drm_display_mode *mode; +}; + +static inline struct jdi_panel *to_jdi_panel (struct drm_panel *panel) +{ + return container_of(panel, struct jdi_panel, base); +} + +static char MCAP [2 ] = {0xB0 ,0x00 }; +static char interface_setting_cmd[6 ] = {0xB3 ,0x04 ,0x08 ,0x00 ,0x22 ,0x00 }; +static char interface_setting[6 ] = {0xB3 ,0x26 ,0x08 ,0x00 ,0x20 ,0x00 }; + +static char interface_ID_setting[2 ] = {0xB4 ,0x0C }; +static char DSI_control[3 ] = {0xB6 ,0x3A ,0xD3 }; + +static char tear_scan_line[3 ] = {0x44 ,0x03 ,0x00 }; + +/* for fps control, set fps to 60.32Hz */ +static char LTPS_timing_setting[2 ] = {0xC6 ,0x78 }; +static char sequencer_timing_control[2 ] = {0xD6 ,0x01 }; + +/* set brightness */ +static char write_display_brightness[] = {0x51 ,0xFF }; +/* enable LEDPWM pin output, turn on LEDPWM output, turn off pwm dimming */ +static char write_control_display[] = {0x53 ,0x24 }; +/* +* choose cabc mode, 0x00(-0%), 0x01(-15%), 0x02(-40%), 0x03(-54%), +* disable SRE(sunlight readability enhancement) +*/ +static char write_cabc[] = {0x55 ,0x00 };
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 98
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+/* for cabc mode 0x1(-15%) */ +static char backlight_control1[] = {0xB8 ,0x07 ,0x87 ,0x26 ,0x18 ,0x00 ,0x32 }; +/* for cabc mode 0x2(-40%) */ +static char backlight_control2[] = {0xB9 ,0x07 ,0x75 ,0x61 ,0x20 ,0x16 ,0x87 }; +/* for cabc mode 0x3(-54%) */ +static char backlight_control3[] = {0xBA ,0x07 ,0x70 ,0x81 ,0x20 ,0x45 ,0xB4 }; +/* for pwm frequency and dimming control */ +static char backlight_control4[] = {0xCE ,0x7D ,0x40 ,0x48 ,0x56 ,0x67 ,0x78 , +0x88 ,0x98 ,0xA7 ,0xB5 ,0xC3 ,0xD1 ,0xDE ,0xE9 ,0xF2 ,0xFA , +0xFF ,0x37 ,0xF5 ,0x0F ,0x0F ,0x42 ,0x00 };
Apart from the u8 conversion as mentioned by Thierry, you should convert these to const too.
Quoted 62 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +62
-0+ +static int jdi_panel_init (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + +if (dsi->mode_flags &MIPI_DSI_MODE_VIDEO ) { + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret; + +mdelay (10 ); + + ret =mipi_dsi_dcs_set_pixel_format (dsi,0x70 ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_column_address (dsi,0x0000 ,0x04AF ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_page_address (dsi,0x0000 ,0x077F ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_tear_on (dsi, +MIPI_DSI_DCS_TEAR_MODE_VBLANK ); +if (ret <0 ) +return ret; +mdelay (5 ); + + ret =mipi_dsi_generic_write (dsi, tear_scan_line, +sizeof (tear_scan_line)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_display_brightness, +sizeof (write_display_brightness) + ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_control_display, +sizeof (write_control_display)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_cabc, +sizeof (write_cabc)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_exit_sleep_mode (dsi); +if (ret <0 ) +return ret; +mdelay (120 ); + + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret;
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 170
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+mdelay (10 ); + + ret =mipi_dsi_generic_write (dsi, interface_setting, +sizeof (interface_setting)); +if (ret <0 ) +return ret; +mdelay (20 ); + + backlight_control4[18 ] =0x04 ; + backlight_control4[19 ] =0x00 ;
Any reason why these are overwritten? It would be better to have these values in the array itself.
Quoted 285 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +285
-0+ + ret =mipi_dsi_generic_write (dsi, backlight_control4, +sizeof (backlight_control4)); +if (ret <0 ) +return ret; +mdelay (20 ); + +MCAP [1 ] =0x03 ; + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret; + }else { +/* +* TODO : need to verify panel settings when +* dsi cmd mode supported for apq8064 - simhavcs +*/ + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret; + +mdelay (5 ); + + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, interface_setting_cmd, +sizeof (interface_setting_cmd)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, interface_ID_setting, +sizeof (interface_ID_setting)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, DSI_control, +sizeof (DSI_control)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, LTPS_timing_setting, +sizeof (LTPS_timing_setting)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, sequencer_timing_control, +sizeof (sequencer_timing_control)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_display_brightness, +sizeof (write_display_brightness) + ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_control_display, +sizeof (write_control_display)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_cabc, +sizeof (write_cabc)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, backlight_control1, +sizeof (backlight_control1)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, backlight_control2, +sizeof (backlight_control2)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, backlight_control3, +sizeof (backlight_control3)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, backlight_control4, +sizeof (backlight_control4)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_pixel_format (dsi,0x77 ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_column_address (dsi,0x0000 ,0x04AF ); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_page_address (dsi,0x0000 ,0x077F ); +if (ret <0 ) +return ret; +mdelay (120 ); + + ret =mipi_dsi_dcs_exit_sleep_mode (dsi); +if (ret <0 ) +return ret; + } + +return 0 ; +} + +static int jdi_panel_on (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + + ret =mipi_dsi_dcs_set_display_on (dsi); +if (ret <0 ) +return ret; + +return 0 ; +} + +static int jdi_panel_off (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM ; + + ret =mipi_dsi_dcs_set_display_off (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_enter_sleep_mode (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_tear_off (dsi); +if (ret <0 ) +return ret; + +msleep (100 ); + +return 0 ; +} + +static int jdi_panel_disable (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); + +if (!jdi->enabled) +return 0 ; + +DRM_DEBUG ("disable\n" ); + +if (jdi->backlight) { + jdi->backlight->props.power =FB_BLANK_POWERDOWN ; +backlight_update_status (jdi->backlight); + } + + jdi->enabled = false; + +return 0 ; +} + +static int jdi_panel_unprepare (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); +int ret; + +if (!jdi->prepared) +return 0 ; + +DRM_DEBUG ("unprepare\n" ); + + ret =jdi_panel_off (jdi); +if (ret) { +dev_err (panel->dev,"failed to set panel off: %d\n" , ret); +return ret; + } + +regulator_disable (jdi->supply); + +if (jdi->vcc_gpio) +gpiod_set_value (jdi->vcc_gpio,0 ); + +if (jdi->reset_gpio) +gpiod_set_value (jdi->reset_gpio,0 ); + +if (jdi->enable_gpio) +gpiod_set_value (jdi->enable_gpio,0 ); + + jdi->prepared = false; + +return 0 ; +} + +static int jdi_panel_prepare (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); +int ret; + +if (jdi->prepared) +return 0 ; + +DRM_DEBUG ("prepare\n" ); + + ret =regulator_enable (jdi->iovdd); +if (ret <0 ) +return ret; + + ret =regulator_enable (jdi->avdd); +if (ret <0 ) +return ret; + + ret =regulator_enable (jdi->backlit); +if (ret <0 ) +return ret; + + ret =regulator_enable (jdi->lvs7); +if (ret <0 ) +return ret; + + ret =regulator_enable (jdi->supply); +if (ret <0 ) +return ret; + +msleep (20 ); + +if (jdi->vcc_gpio) { +gpiod_set_value (jdi->vcc_gpio,1 ); +usleep_range (10 ,20 ); + } + +if (jdi->reset_gpio) { +gpiod_set_value (jdi->reset_gpio,1 ); +usleep_range (10 ,20 ); + } + +if (jdi->pwm_gpio) { +gpiod_set_value (jdi->pwm_gpio,1 ); +usleep_range (10 ,20 ); + } + +if (jdi->enable_gpio) { +gpiod_set_value (jdi->enable_gpio,1 ); +usleep_range (10 ,20 ); + } + + ret =jdi_panel_init (jdi); +if (ret) { +dev_err (panel->dev,"failed to init panel: %d\n" , ret); + goto poweroff; + } + + ret =jdi_panel_on (jdi); +if (ret) { +dev_err (panel->dev,"failed to set panel on: %d\n" , ret); + goto poweroff; + } + + jdi->prepared = true; + +return 0 ; + +poweroff: +regulator_disable (jdi->supply); +if (jdi->reset_gpio) +gpiod_set_value (jdi->reset_gpio,0 ); +if (jdi->enable_gpio) +gpiod_set_value (jdi->enable_gpio,0 ); +if (jdi->vcc_gpio) +gpiod_set_value (jdi->vcc_gpio,0 ); + +return ret; +} + +static int jdi_panel_enable (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); + +if (jdi->enabled) +return 0 ; + +DRM_DEBUG ("enable\n" );
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 465
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ +if (jdi->backlight) { + jdi->backlight->props.power =FB_BLANK_UNBLANK ; +backlight_update_status (jdi->backlight); + } + + jdi->enabled = true; + +return 0 ; +}
The prepare/enable split seems a bit strange. Don't we want to put mipi_dsi_dcs_set_display_on in the enable() op too?
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 468
Quoted 3 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +3
-0+ +static const struct drm_display_mode default_mode = { + .clock =155000 ,
htotal * vtotal * vrefresh (1934 * 1340 * 60.32(as in comment)) comes at around 156.3 Mhz. Could you plug in the correct frequency?
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+ .hdisplay = 1200, + .hsync_start = 1200 + 48, + .hsync_end = 1200 + 48 + 32, + .htotal = 1200 + 48 + 32 + 60, + .vdisplay = 1920, + .vsync_start = 1920 + 3, + .vsync_end = 1920 + 3 + 5, + .vtotal = 1920 + 3 + 5 + 6, + .vrefresh = 60, + .flags = 0, +};
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 489
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ +static int jdi_panel_get_modes (struct drm_panel *panel) +{ +struct drm_display_mode *mode; + + mode =drm_mode_duplicate (panel->drm, &default_mode); +if (!mode) { +dev_err (panel->drm->dev,"failed to add mode %ux%ux@%u\n" , + default_mode.hdisplay, default_mode.vdisplay, + default_mode.vrefresh);
We should use the dsi->dev device pointer here like used elsewhere, not the drm device pointer.
Quoted 25 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +25
-0+return -ENOMEM ; + } + +drm_mode_set_name (mode); + +drm_mode_probed_add (panel->connector, mode); + +return 1 ; +} + +static const struct drm_panel_funcs jdi_panel_funcs = { + .disable = jdi_panel_disable, + .unprepare = jdi_panel_unprepare, + .prepare = jdi_panel_prepare, + .enable = jdi_panel_enable, + .get_modes = jdi_panel_get_modes, +}; + +static const struct of_device_id jdi_of_match[] = { + { .compatible ="jdi,lt070me05000" , }, + { } +}; +MODULE_DEVICE_TABLE (of, jdi_of_match); + +static int jdi_panel_add (struct jdi_panel *jdi)
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 524
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+{ +struct device *dev = &jdi->dsi->dev; +int ret; + + jdi->mode = &default_mode; + +/* lvs5 */ + jdi->supply =devm_regulator_get (dev,"power" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply);
You could consider using regulator_get_bulk() api here, it would clean up the code a bit.
Quoted 117 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +117
-0+ +/* l17 */ + jdi->backlit =devm_regulator_get (dev,"backlit" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply); + + jdi->lvs7 =devm_regulator_get (dev,"lvs7" ); +if (IS_ERR (jdi->lvs7)) +return PTR_ERR (jdi->lvs7); + + jdi->avdd =devm_regulator_get (dev,"avdd" ); +if (IS_ERR (jdi->avdd)) +return PTR_ERR (jdi->avdd); + + jdi->iovdd =devm_regulator_get (dev,"iovdd" ); +if (IS_ERR (jdi->iovdd)) +return PTR_ERR (jdi->iovdd); + + jdi->vcc_gpio =devm_gpiod_get (dev,"vcc" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->vcc_gpio)) { +dev_err (dev,"cannot get vcc-gpio %ld\n" , +PTR_ERR (jdi->vcc_gpio)); + jdi->vcc_gpio =NULL ; + }else { +gpiod_direction_output (jdi->vcc_gpio,0 ); + } + + jdi->reset_gpio =devm_gpiod_get (dev,"reset" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->reset_gpio)) { +dev_err (dev,"cannot get reset-gpios %ld\n" , +PTR_ERR (jdi->reset_gpio)); + jdi->reset_gpio =NULL ; + }else { +gpiod_direction_output (jdi->reset_gpio,0 ); + } + + jdi->enable_gpio =devm_gpiod_get (dev,"enable" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->enable_gpio)) { +dev_err (dev,"cannot get enable-gpio %ld\n" , +PTR_ERR (jdi->enable_gpio)); + jdi->enable_gpio =NULL ; + }else { +gpiod_direction_output (jdi->enable_gpio,0 ); + } + + jdi->pwm_gpio =devm_gpiod_get (dev,"pwm" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->pwm_gpio)) { +dev_err (dev,"cannot get pwm-gpio %ld\n" , +PTR_ERR (jdi->pwm_gpio)); + jdi->pwm_gpio =NULL ; + }else { +gpiod_direction_output (jdi->pwm_gpio,0 ); + } + +/* we don't have backlight right now, proceed further */ +#ifdef BACKLIGHT + np =of_parse_phandle (dev->of_node,"backlight" ,0 ); +if (np) { + jdi->backlight =of_find_backlight_by_node (np); +of_node_put (np); + +if (!jdi->backlight) +return -EPROBE_DEFER ; + } +#endif + +drm_panel_init (&jdi->base); + jdi->base.funcs = &jdi_panel_funcs; + jdi->base.dev = &jdi->dsi->dev; + + ret =drm_panel_add (&jdi->base); +if (ret <0 ) + goto put_backlight; + +return 0 ; + +put_backlight: +if (jdi->backlight) +put_device (&jdi->backlight->dev); + +return ret; +} + +static void jdi_panel_del (struct jdi_panel *jdi) +{ +if (jdi->base.dev) +drm_panel_remove (&jdi->base); + +if (jdi->backlight) +put_device (&jdi->backlight->dev); +} + +static int jdi_panel_probe (struct mipi_dsi_device *dsi) +{ +struct jdi_panel *jdi; +int ret; + + dsi->lanes =4 ; + dsi->format =MIPI_DSI_FMT_RGB888 ; + dsi->mode_flags =MIPI_DSI_MODE_VIDEO_HSE |MIPI_DSI_MODE_VIDEO | +MIPI_DSI_MODE_VIDEO_HFP |MIPI_DSI_MODE_VIDEO_HBP | +MIPI_DSI_MODE_VIDEO_HSA | +MIPI_DSI_CLOCK_NON_CONTINUOUS ; + + jdi =devm_kzalloc (&dsi->dev,sizeof (*jdi),GFP_KERNEL ); +if (!jdi) +return -ENOMEM ; + +mipi_dsi_set_drvdata (dsi, jdi); + + jdi->dsi = dsi; + + ret =jdi_panel_add (jdi); +if (ret <0 ) +return ret; + +return mipi_dsi_attach (dsi);
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 651
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+} + +static int jdi_panel_remove (struct mipi_dsi_device *dsi) +{ +struct jdi_panel *jdi =mipi_dsi_get_drvdata (dsi); +int ret; + + ret =jdi_panel_disable (&jdi->base); +if (ret <0 ) +dev_err (&dsi->dev,"failed to disable panel: %d\n" , ret);
Ideally, the driver's remove op shouldn't try to disable the panel. It should be done by the dsi host's connector itself. We can drop this unless there is a specfic reason to do so.
Thanks for working on this.
Archit
Signature · 6 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 626 lines · Archit Taneja
Quoted 229 lines · Vinay Simha BN
Add support for the JDI lt070me05000 WUXGA DSI panel used in Nexus 7 2013 devices.
Programming sequence for the panel is was originally found in the android-msm-flo-3.4-lollipop-release branch from:
https://android.googlesource.com/kernel/msm.gitAnd video mode setting is from
dsi-panel-jdi-dualmipi1-video.dtsifile in:git://codeaurora.org/kernel/msm-3.10.git LNX.LA.3.6_rb1.27Other fixes folded in were provided
by Archit Taneja <[email protected]>Signed-off-by Vinay Simha BN <[email protected]>[sumit.semwal: Ported to the drm/panel framework]Signed-off-by Sumit Semwal <[email protected]>[jstultz: Cherry-picked to mainline, folded down other fixes
from Vinay and Archit]Signed-off-by John Stultz <[email protected]>--- .../bindings/display/panel/jdi,lt070me05000.txt | 27 + .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 685 +++++++++++++++++++++ 5 files changed, 725 insertions(+)create mode 100644
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt
create mode 100644drivers/gpu/drm/panel/panel-jdi-lt070me05000.cdiff --git
a/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txtb/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txtnew file mode 100644
index 0000000..35c5ac7Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +4
-0@@ -0,0 +1,27 @@ +JDI model LT070ME05000 1920x1200 7" DSI Panel + +Basic data sheet is at: +http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt new file +23
-0+ +This panel has video mode implemented currently in the driver. + +Required properties: +- compatible: should be "jdi,lt070me05000" + +Optional properties: +- power-supply: phandle of the regulator that provides the supply voltage +- reset-gpio: phandle of gpio for reset line +- backlight: phandle of the backlight device attached to the panel + +Example: + + dsi@54300000 { + panel: panel@0 { + compatible = "jdi,lt070me05000"; + reg = <0>; + + power-supply = <...>; + reset-gpio = <...>; + backlight = <...>; + }; + };Documentation/devicetree/bindings/vendor-prefixes.txt +1
-0@@ -130,6 +130,7 @@ invensense InvenSense Inc. isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jdi Japan Display Inc. jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH keymile Keymile GmbHdrivers/gpu/drm/panel/Kconfig +7
-0@@ -61,6 +61,17 @@ config DRM_PANEL_SHARP_LQ101R1SX01 To compile this driver as a module, choose M here: the module will be called panel-sharp-lq101r1sx01. +config DRM_PANEL_JDI_LT070ME05000 + tristate "JDI LT070ME05000 WUXGA DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for JDI WUXGA DSIvideo/
drivers/gpu/drm/panel/Kconfig +4
-0+ command mode panel as found in Google Nexus 7 (2013) devices. + The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses + 24 bit RGB per pixel. + config DRM_PANEL_SHARP_LS043T1LE01 tristate "Sharp LS043T1LE01 qHD video mode panel" depends on OFdrivers/gpu/drm/panel/Makefile +0
-0@@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) +=panel-samsung-ld9040.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.odrivers/gpu/drm/panel/Makefile +1
-0+obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.odrivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +8
-0@@ -0,0 +1,685 @@ +/* +* Copyright (C) 2015 InforceComputing +* Author: Vinay Simha BN <[email protected]> +* +* Copyright (C) 2015 Linaro Ltd +* Author: Sumit Semwal <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +49
-0+ +#include <linux/backlight.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include <drm/drmP.h> +#include <drm/drm_crtc.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_panel.h> + +#include <video/mipi_display.h> + +/* +* From internet archives, the panel for Nexus 7 2nd Gen, 2013 model is a +* JDI model LT070ME05000, and its data sheet is at: +* http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet +*/ +struct jdi_panel { +struct drm_panel base; +struct mipi_dsi_device *dsi; + +/* TODO: Add backilght support */ +struct backlight_device *backlight; +struct regulator *supply; +struct gpio_desc *reset_gpio; +struct gpio_desc *enable_gpio; +struct gpio_desc *vcc_gpio; + +struct regulator *backlit; +struct regulator *lvs7; +struct regulator *avdd; +struct regulator *iovdd; +struct gpio_desc *pwm_gpio; + +bool prepared; +bool enabled; + +const struct drm_display_mode *mode; +}; + +static inline struct jdi_panel *to_jdi_panel (struct drm_panel *panel) +{ + return container_of(panel, struct jdi_panel, base); +} + +static char MCAP [2 ] = {0xB0 ,0x00 }; +static char interface_setting_cmd[6 ] = {0xB3 ,0x04 ,0x08 ,0x00 ,0x22 ,
0x00};drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +14
-0+static char interface_setting[6 ] = {0xB3 ,0x26 ,0x08 ,0x00 ,0x20 ,0x00 }; + +static char interface_ID_setting[2 ] = {0xB4 ,0x0C }; +static char DSI_control[3 ] = {0xB6 ,0x3A ,0xD3 }; + +static char tear_scan_line[3 ] = {0x44 ,0x03 ,0x00 }; + +/* for fps control, set fps to 60.32Hz */ +static char LTPS_timing_setting[2 ] = {0xC6 ,0x78 }; +static char sequencer_timing_control[2 ] = {0xD6 ,0x01 }; + +/* set brightness */ +static char write_display_brightness[] = {0x51 ,0xFF }; +/* enable LEDPWM pin output, turn on LEDPWM output, turn off pwm dimming */
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +8
-0+static char write_control_display[] = {0x53 ,0x24 }; +/* +* choose cabc mode, 0x00(-0%), 0x01(-15%), 0x02(-40%), 0x03(-54%), +* disable SRE(sunlight readability enhancement) +*/ +static char write_cabc[] = {0x55 ,0x00 }; +/* for cabc mode 0x1(-15%) */ +static char backlight_control1[] = {0xB8 ,0x07 ,0x87 ,0x26 ,0x18 ,0x00 ,
0x32};drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +2
-0+/* for cabc mode 0x2(-40%) */ +static char backlight_control2[] = {0xB9 ,0x07 ,0x75 ,0x61 ,0x20 ,0x16 ,
0x87};drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +2
-0+/* for cabc mode 0x3(-54%) */ +static char backlight_control3[] = {0xBA ,0x07 ,0x70 ,0x81 ,0x20 ,0x45 ,
0xB4};drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +2
-0+/* for pwm frequency and dimming control */ +static char backlight_control4[] = {0xCE ,0x7D ,0x40 ,0x48 ,0x56 ,0x67 ,Quoted 4 lines
0x78,
+0x88,0x98,0xA7,0xB5,0xC3,0xD1,0xDE,0xE9,0xF2,0xFA,
+0xFF,0x37,0xF5,0x0F,0x0F,0x42,0x00};Apart from the u8 conversion as mentioned by Thierry, you should convert these to const too.
Quoted 68 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +20
-0+ +static int jdi_panel_init (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + +if (dsi->mode_flags &MIPI_DSI_MODE_VIDEO ) { + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret; + +mdelay (10 ); + + ret =mipi_dsi_dcs_set_pixel_format (dsi,0x70 ); +if (ret <0 ) +return ret; + + ret = mipi_dsi_dcs_set_column_address(dsi, 0x0000,
0x04AF);drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +9
-0+if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_page_address (dsi,0x0000 ,0x077F ); +if (ret <0 ) +return ret; + + ret = mipi_dsi_dcs_set_tear_on(dsi, +
MIPI_DSI_DCS_TEAR_MODE_VBLANK);drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+if (ret <0 ) +return ret; +mdelay (5 ); + + ret =mipi_dsi_generic_write (dsi, tear_scan_line, +sizeof (tear_scan_line)); +if (ret <0 ) +return ret; + + ret = mipi_dsi_dcs_write_buffer(dsi,
write_display_brightness,
+sizeof(write_display_brightness)drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+ ); +if (ret <0 ) +return ret; + + ret = mipi_dsi_dcs_write_buffer(dsi,
write_control_display,
+sizeof(write_control_display));drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +16
-0+if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_cabc, +sizeof (write_cabc)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_exit_sleep_mode (dsi); +if (ret <0 ) +return ret; +mdelay (120 ); + + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret;drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 170
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+mdelay (10 ); + + ret =mipi_dsi_generic_write (dsi, interface_setting, +sizeof (interface_setting)); +if (ret <0 ) +return ret; +mdelay (20 ); + + backlight_control4[18 ] =0x04 ; + backlight_control4[19 ] =0x00 ;Any reason why these are overwritten? It would be better to have these values in the array itself.
Quoted 300 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +28
-0+ + ret =mipi_dsi_generic_write (dsi, backlight_control4, +sizeof (backlight_control4)); +if (ret <0 ) +return ret; +mdelay (20 ); + +MCAP [1 ] =0x03 ; + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret; + }else { +/* +* TODO : need to verify panel settings when +* dsi cmd mode supported for apq8064 - simhavcs +*/ + ret =mipi_dsi_dcs_soft_reset (dsi); +if (ret <0 ) +return ret; + +mdelay (5 ); + + ret =mipi_dsi_generic_write (dsi,MCAP ,sizeof (MCAP )); +if (ret <0 ) +return ret; + + ret = mipi_dsi_generic_write(dsi, interface_setting_cmd, +
sizeof(interface_setting_cmd));drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+if (ret <0 ) +return ret; + + ret = mipi_dsi_generic_write(dsi, interface_ID_setting, +
sizeof(interface_ID_setting));drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +14
-0+if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, DSI_control, +sizeof (DSI_control)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, LTPS_timing_setting, +sizeof (LTPS_timing_setting)); +if (ret <0 ) +return ret; + + ret = mipi_dsi_generic_write(dsi,
sequencer_timing_control,
+sizeof(sequencer_timing_control));drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +4
-0+if (ret <0 ) +return ret; + + ret = mipi_dsi_dcs_write_buffer(dsi,
write_display_brightness,
+sizeof(write_display_brightness)drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +5
-0+ ); +if (ret <0 ) +return ret; + + ret = mipi_dsi_dcs_write_buffer(dsi,
write_control_display,
+sizeof(write_control_display));drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +33
-0+if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_write_buffer (dsi, write_cabc, +sizeof (write_cabc)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, backlight_control1, +sizeof (backlight_control1)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, backlight_control2, +sizeof (backlight_control2)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, backlight_control3, +sizeof (backlight_control3)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_generic_write (dsi, backlight_control4, +sizeof (backlight_control4)); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_pixel_format (dsi,0x77 ); +if (ret <0 ) +return ret; + + ret = mipi_dsi_dcs_set_column_address(dsi, 0x0000,
0x04AF);drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +199
-0+if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_page_address (dsi,0x0000 ,0x077F ); +if (ret <0 ) +return ret; +mdelay (120 ); + + ret =mipi_dsi_dcs_exit_sleep_mode (dsi); +if (ret <0 ) +return ret; + } + +return 0 ; +} + +static int jdi_panel_on (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags |=MIPI_DSI_MODE_LPM ; + + ret =mipi_dsi_dcs_set_display_on (dsi); +if (ret <0 ) +return ret; + +return 0 ; +} + +static int jdi_panel_off (struct jdi_panel *jdi) +{ +struct mipi_dsi_device *dsi = jdi->dsi; +int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM ; + + ret =mipi_dsi_dcs_set_display_off (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_enter_sleep_mode (dsi); +if (ret <0 ) +return ret; + + ret =mipi_dsi_dcs_set_tear_off (dsi); +if (ret <0 ) +return ret; + +msleep (100 ); + +return 0 ; +} + +static int jdi_panel_disable (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); + +if (!jdi->enabled) +return 0 ; + +DRM_DEBUG ("disable\n" ); + +if (jdi->backlight) { + jdi->backlight->props.power =FB_BLANK_POWERDOWN ; +backlight_update_status (jdi->backlight); + } + + jdi->enabled = false; + +return 0 ; +} + +static int jdi_panel_unprepare (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); +int ret; + +if (!jdi->prepared) +return 0 ; + +DRM_DEBUG ("unprepare\n" ); + + ret =jdi_panel_off (jdi); +if (ret) { +dev_err (panel->dev,"failed to set panel off: %d\n" , ret); +return ret; + } + +regulator_disable (jdi->supply); + +if (jdi->vcc_gpio) +gpiod_set_value (jdi->vcc_gpio,0 ); + +if (jdi->reset_gpio) +gpiod_set_value (jdi->reset_gpio,0 ); + +if (jdi->enable_gpio) +gpiod_set_value (jdi->enable_gpio,0 ); + + jdi->prepared = false; + +return 0 ; +} + +static int jdi_panel_prepare (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); +int ret; + +if (jdi->prepared) +return 0 ; + +DRM_DEBUG ("prepare\n" ); + + ret =regulator_enable (jdi->iovdd); +if (ret <0 ) +return ret; + + ret =regulator_enable (jdi->avdd); +if (ret <0 ) +return ret; + + ret =regulator_enable (jdi->backlit); +if (ret <0 ) +return ret; + + ret =regulator_enable (jdi->lvs7); +if (ret <0 ) +return ret; + + ret =regulator_enable (jdi->supply); +if (ret <0 ) +return ret; + +msleep (20 ); + +if (jdi->vcc_gpio) { +gpiod_set_value (jdi->vcc_gpio,1 ); +usleep_range (10 ,20 ); + } + +if (jdi->reset_gpio) { +gpiod_set_value (jdi->reset_gpio,1 ); +usleep_range (10 ,20 ); + } + +if (jdi->pwm_gpio) { +gpiod_set_value (jdi->pwm_gpio,1 ); +usleep_range (10 ,20 ); + } + +if (jdi->enable_gpio) { +gpiod_set_value (jdi->enable_gpio,1 ); +usleep_range (10 ,20 ); + } + + ret =jdi_panel_init (jdi); +if (ret) { +dev_err (panel->dev,"failed to init panel: %d\n" , ret); + goto poweroff; + } + + ret =jdi_panel_on (jdi); +if (ret) { +dev_err (panel->dev,"failed to set panel on: %d\n" , ret); + goto poweroff; + } + + jdi->prepared = true; + +return 0 ; + +poweroff: +regulator_disable (jdi->supply); +if (jdi->reset_gpio) +gpiod_set_value (jdi->reset_gpio,0 ); +if (jdi->enable_gpio) +gpiod_set_value (jdi->enable_gpio,0 ); +if (jdi->vcc_gpio) +gpiod_set_value (jdi->vcc_gpio,0 ); + +return ret; +} + +static int jdi_panel_enable (struct drm_panel *panel) +{ +struct jdi_panel *jdi =to_jdi_panel (panel); + +if (jdi->enabled) +return 0 ; + +DRM_DEBUG ("enable\n" ); + +if (jdi->backlight) { + jdi->backlight->props.power =FB_BLANK_UNBLANK ; +backlight_update_status (jdi->backlight); + } +
Quoted 8 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 465
Quoted 4 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +4
-0+ jdi->enabled = true; + +return 0 ; +}The prepare/enable split seems a bit strange. Don't we want to put
mipi_dsi_dcs_set_display_onin theenable()op too?
enable will be called after the prepare().enable() - usually the backlight update status BLANK/UNBLANK is done
Quoted 202 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 468
Quoted 4 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +3
-0+ +static const struct drm_display_mode default_mode = { + .clock =155000 ,htotal * vtotal * vrefresh (1934 * 1340 * 60.32(as in comment)) comes at around 156.3 Mhz. Could you plug in the correct frequency?
Quoted 11 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +11
-0+ .hdisplay = 1200, + .hsync_start = 1200 + 48, + .hsync_end = 1200 + 48 + 32, + .htotal = 1200 + 48 + 32 + 60, + .vdisplay = 1920, + .vsync_start = 1920 + 3, + .vsync_end = 1920 + 3 + 5, + .vtotal = 1920 + 3 + 5 + 6, + .vrefresh = 60, + .flags = 0, +};drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 489
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+ +static int jdi_panel_get_modes (struct drm_panel *panel) +{ +struct drm_display_mode *mode; + + mode =drm_mode_duplicate (panel->drm, &default_mode); +if (!mode) { +dev_err (panel->drm->dev,"failed to add mode %ux%ux@%u\n" , + default_mode.hdisplay, default_mode.vdisplay, + default_mode.vrefresh);We should use the
dsi->devdevice pointer here like used elsewhere, not the drm device pointer.Quoted 25 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +25
-0+return -ENOMEM ; + } + +drm_mode_set_name (mode); + +drm_mode_probed_add (panel->connector, mode); + +return 1 ; +} + +static const struct drm_panel_funcs jdi_panel_funcs = { + .disable = jdi_panel_disable, + .unprepare = jdi_panel_unprepare, + .prepare = jdi_panel_prepare, + .enable = jdi_panel_enable, + .get_modes = jdi_panel_get_modes, +}; + +static const struct of_device_id jdi_of_match[] = { + { .compatible ="jdi,lt070me05000" , }, + { } +}; +MODULE_DEVICE_TABLE (of, jdi_of_match); + +static int jdi_panel_add (struct jdi_panel *jdi)drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 524
Quoted 10 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +10
-0+{ +struct device *dev = &jdi->dsi->dev; +int ret; + + jdi->mode = &default_mode; + +/* lvs5 */ + jdi->supply =devm_regulator_get (dev,"power" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply);You could consider using
regulator_get_bulk()api here, it would clean up the code a bit.Quoted 125 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +101
-0+ +/* l17 */ + jdi->backlit =devm_regulator_get (dev,"backlit" ); +if (IS_ERR (jdi->supply)) +return PTR_ERR (jdi->supply); + + jdi->lvs7 =devm_regulator_get (dev,"lvs7" ); +if (IS_ERR (jdi->lvs7)) +return PTR_ERR (jdi->lvs7); + + jdi->avdd =devm_regulator_get (dev,"avdd" ); +if (IS_ERR (jdi->avdd)) +return PTR_ERR (jdi->avdd); + + jdi->iovdd =devm_regulator_get (dev,"iovdd" ); +if (IS_ERR (jdi->iovdd)) +return PTR_ERR (jdi->iovdd); + + jdi->vcc_gpio =devm_gpiod_get (dev,"vcc" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->vcc_gpio)) { +dev_err (dev,"cannot get vcc-gpio %ld\n" , +PTR_ERR (jdi->vcc_gpio)); + jdi->vcc_gpio =NULL ; + }else { +gpiod_direction_output (jdi->vcc_gpio,0 ); + } + + jdi->reset_gpio =devm_gpiod_get (dev,"reset" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->reset_gpio)) { +dev_err (dev,"cannot get reset-gpios %ld\n" , +PTR_ERR (jdi->reset_gpio)); + jdi->reset_gpio =NULL ; + }else { +gpiod_direction_output (jdi->reset_gpio,0 ); + } + + jdi->enable_gpio =devm_gpiod_get (dev,"enable" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->enable_gpio)) { +dev_err (dev,"cannot get enable-gpio %ld\n" , +PTR_ERR (jdi->enable_gpio)); + jdi->enable_gpio =NULL ; + }else { +gpiod_direction_output (jdi->enable_gpio,0 ); + } + + jdi->pwm_gpio =devm_gpiod_get (dev,"pwm" ,GPIOD_OUT_LOW ); +if (IS_ERR (jdi->pwm_gpio)) { +dev_err (dev,"cannot get pwm-gpio %ld\n" , +PTR_ERR (jdi->pwm_gpio)); + jdi->pwm_gpio =NULL ; + }else { +gpiod_direction_output (jdi->pwm_gpio,0 ); + } + +/* we don't have backlight right now, proceed further */ +#ifdef BACKLIGHT + np =of_parse_phandle (dev->of_node,"backlight" ,0 ); +if (np) { + jdi->backlight =of_find_backlight_by_node (np); +of_node_put (np); + +if (!jdi->backlight) +return -EPROBE_DEFER ; + } +#endif + +drm_panel_init (&jdi->base); + jdi->base.funcs = &jdi_panel_funcs; + jdi->base.dev = &jdi->dsi->dev; + + ret =drm_panel_add (&jdi->base); +if (ret <0 ) + goto put_backlight; + +return 0 ; + +put_backlight: +if (jdi->backlight) +put_device (&jdi->backlight->dev); + +return ret; +} + +static void jdi_panel_del (struct jdi_panel *jdi) +{ +if (jdi->base.dev) +drm_panel_remove (&jdi->base); + +if (jdi->backlight) +put_device (&jdi->backlight->dev); +} + +static int jdi_panel_probe (struct mipi_dsi_device *dsi) +{ +struct jdi_panel *jdi; +int ret; + + dsi->lanes =4 ; + dsi->format =MIPI_DSI_FMT_RGB888 ; + dsi->mode_flags =MIPI_DSI_MODE_VIDEO_HSE |MIPI_DSI_MODE_VIDEO | +MIPI_DSI_MODE_VIDEO_HFP |MIPI_DSI_MODE_VIDEO_HBP |
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +23
-0+MIPI_DSI_MODE_VIDEO_HSA | +MIPI_DSI_CLOCK_NON_CONTINUOUS ; + + jdi =devm_kzalloc (&dsi->dev,sizeof (*jdi),GFP_KERNEL ); +if (!jdi) +return -ENOMEM ; + +mipi_dsi_set_drvdata (dsi, jdi); + + jdi->dsi = dsi; + + ret =jdi_panel_add (jdi); +if (ret <0 ) +return ret; + +return mipi_dsi_attach (dsi); +} + +static int jdi_panel_remove (struct mipi_dsi_device *dsi) +{ +struct jdi_panel *jdi =mipi_dsi_get_drvdata (dsi); +int ret; +
Quoted 9 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c line 651
Quoted 3 lines
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c new file +3
-0+ ret =jdi_panel_disable (&jdi->base); +if (ret <0 ) +dev_err (&dsi->dev,"failed to disable panel: %d\n" , ret);Ideally, the driver's remove op shouldn't try to disable the panel. It should be done by the dsi host's connector itself. We can drop this unless there is a specfic reason to do so.
panel_disable() - sets the backlight brightness off
fyi,include/drm/drm_panel.h
Before stopping video transmission from the display controller it can be necessary to turn off the panel to avoid visual glitches. This is done in the .disable() function.
Quoted 7 lines
Thanks for working on this.
Archit
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Signature · 7 lines
Regards, Vinay Simha.B.N. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html