So this is a cold-coded attempt to move the TI nspire over to using DRM. It is more or less the last user of the old fbdev driver so it is a noble cause and interesting usecase.
This can be applied on top of a vanilla Torvalds v5.3-rc1 kernel out since sunday.
I do not expect these patches to "just work", I expect them to need some hacking, so someone who is actually working on the hardware will need to step in and fix it up.
It does outline the overall idea of how to do this.
I found no defconfig for nspire in the kernel so I used ARMv4t multi.
Configuring the driver for nspire:
- Disable CONFIG_FB_ARMCLCD - Enable CONFIG_DRM_PL111, CONFIG_DRM_PANEL_SIMPLE
Hacker notes for nspire:
- I don't know which PrimeCell ID this hardware has, I hope the amba_id mask in drivers/gpu/drm/pl111/pl111_drv.c for PL111 and PL110 will match it. Please confirm that you get a clean probe call, else report what ID this has.
- The 24bit RGB frame buffer may be a bit much for the PL111 in the TI nspire to handle. Try editing the .fb_bpp in drivers/gpu/drm/pl111/pl111_drv.c down to 16 if this is the PL111 variant. If it is the PL110 variant, we will get 16 buts framebuffer anyway.
- I have hard-coded the panels to 1MHz, based on the fact that the AHB clock into the CLCD appears to be 48 MHz and the hard-coded TIM2 value for the classic means "divide by 48" and this seems to want the clock freq divided down to 1MHz. Verify this by adding prints inside drivers/gpu/drm/pl111/pl111_display.c in the function pl111_clk_div_set_rate() to verify that the divider gets set to 48 in TIM2_PCD_HI and TIM2_PCD_LO. TIM2_PCD_LO bits 0..4 = 10000 and TIM2_PCD_HI bits 27..31 = 00001 in that register.
Please test and fix, if you can.
Linus Walleij (3): RFT: drm/pl111: Support grayscale RTF: drm/panel: simple: Add TI nspire panels RFT: ARM: nspire: Move CLCD set-up to device tree
arch/arm/boot/dts/nspire-classic.dtsi | 19 ++++- arch/arm/boot/dts/nspire-cx.dts | 18 +++- arch/arm/boot/dts/nspire.dtsi | 10 ++- arch/arm/mach-nspire/Makefile | 1 - arch/arm/mach-nspire/clcd.c | 114 -------------------------- arch/arm/mach-nspire/clcd.h | 10 --- arch/arm/mach-nspire/nspire.c | 25 ------ drivers/gpu/drm/panel/panel-simple.c | 63 ++++++++++++++ drivers/gpu/drm/pl111/pl111_display.c | 28 ++++++- include/linux/amba/clcd-regs.h | 1 + 10 files changed, 133 insertions(+), 156 deletions(-) delete mode 100644 arch/arm/mach-nspire/clcd.c delete mode 100644 arch/arm/mach-nspire/clcd.h
Migrating the TI nspire calculators to use the PL111 driver for framebuffer requires grayscale support for the elder panel which uses 8bit grayscale only.
DRM does not support 8bit grayscale framebuffers in memory, but by defining the bus format to be MEDIA_BUS_FMT_Y8_1X8 we can get the hardware to turn on a grayscaling feature and convert the RGB framebuffer to grayscale for us.
Cc: Daniel Tang dt.tangr@gmail.com Cc: Fabian Vogt fabian@ritter-vogt.de Signed-off-by: Linus Walleij linus.walleij@linaro.org --- drivers/gpu/drm/pl111/pl111_display.c | 28 +++++++++++++++++++++++++-- include/linux/amba/clcd-regs.h | 1 + 2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c index 15d2755fdba4..587b4d148c18 100644 --- a/drivers/gpu/drm/pl111/pl111_display.c +++ b/drivers/gpu/drm/pl111/pl111_display.c @@ -126,12 +126,17 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe, struct drm_framebuffer *fb = plane->state->fb; struct drm_connector *connector = priv->connector; struct drm_bridge *bridge = priv->bridge; + bool grayscale = false; u32 cntl; u32 ppl, hsw, hfp, hbp; u32 lpp, vsw, vfp, vbp; u32 cpl, tim2; int ret;
+ if (connector->display_info.num_bus_formats == 1 && + connector->display_info.bus_formats[0] == MEDIA_BUS_FMT_Y8_1X8) + grayscale = true; + ret = clk_set_rate(priv->clk, mode->clock * 1000); if (ret) { dev_err(drm->dev, @@ -185,6 +190,15 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe, if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) tim2 |= TIM2_IPC; + + /* + * The AC pin bias frequency is set to max count when using + * grayscale so at least once in a while we will reverse + * polarity and get rid of any DC built up that could + * damage the display. + */ + if (grayscale) + tim2 |= TIM2_ACB_MASK; }
if (bridge) { @@ -216,8 +230,18 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe,
writel(0, priv->regs + CLCD_TIM3);
- /* Hard-code TFT panel */ - cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDVCOMP(1); + /* + * Detect grayscale bus format. We do not support a grayscale mode + * toward userspace, instead we expose an RGB24 buffer and then the + * hardware will activate its grayscaler to convert to the grayscale + * format. + */ + if (grayscale) + cntl = CNTL_LCDEN | CNTL_LCDMONO8; + else + /* Else we assume TFT display */ + cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDVCOMP(1); + /* On the ST Micro variant, assume all 24 bits are connected */ if (priv->variant->st_bitmux_control) cntl |= CNTL_ST_CDWID_24; diff --git a/include/linux/amba/clcd-regs.h b/include/linux/amba/clcd-regs.h index 516a6fda83c5..421b0fa90d6a 100644 --- a/include/linux/amba/clcd-regs.h +++ b/include/linux/amba/clcd-regs.h @@ -42,6 +42,7 @@ #define TIM2_PCD_LO_MASK GENMASK(4, 0) #define TIM2_PCD_LO_BITS 5 #define TIM2_CLKSEL (1 << 5) +#define TIM2_ACB_MASK GENMASK(10, 6) #define TIM2_IVS (1 << 11) #define TIM2_IHS (1 << 12) #define TIM2_IPC (1 << 13)
Hi,
I gave the series a try (virtual CX and TP so far, will do on a real CX later): OOPS with a nullptr deref during probe. This diff which just moves some lines around fixes that and the LCD appears to work properly.
Once I verified the 24bit depth and clock speed config on HW as well, I can give you my Tested-by, or would you prefer that I resubmit your series with the fix below?
Thanks, Fabian
--- diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c index 587b4d148c18..bd84d7a5a0f4 100644 --- a/drivers/gpu/drm/pl111/pl111_display.c +++ b/drivers/gpu/drm/pl111/pl111_display.c @@ -133,10 +133,6 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe, u32 cpl, tim2; int ret;
- if (connector->display_info.num_bus_formats == 1 && - connector->display_info.bus_formats[0] == MEDIA_BUS_FMT_Y8_1X8) - grayscale = true; - ret = clk_set_rate(priv->clk, mode->clock * 1000); if (ret) { dev_err(drm->dev, @@ -191,6 +187,10 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe, DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) tim2 |= TIM2_IPC;
+ if (connector->display_info.num_bus_formats == 1 && + connector->display_info.bus_formats[0] == MEDIA_BUS_FMT_Y8_1X8) + grayscale = true; + /* * The AC pin bias frequency is set to max count when using * grayscale so at least once in a while we will reverse
On Tue, Jul 23, 2019 at 5:19 PM Fabian Vogt fabian@ritter-vogt.de wrote:
I gave the series a try (virtual CX and TP so far, will do on a real CX later): OOPS with a nullptr deref during probe. This diff which just moves some lines around fixes that and the LCD appears to work properly.
OK I folded this into my patch, thanks!
Once I verified the 24bit depth and clock speed config on HW as well, I can give you my Tested-by, or would you prefer that I resubmit your series with the fix below?
It's fine if you test it just with your patch as-is, I didn't change anything else.
I would be amazed if it "just works" now.
Yours, Linus Walleij
Hi,
Am Mittwoch, 24. Juli 2019, 14:33:06 CEST schrieb Linus Walleij:
On Tue, Jul 23, 2019 at 5:19 PM Fabian Vogt fabian@ritter-vogt.de wrote:
I gave the series a try (virtual CX and TP so far, will do on a real CX later): OOPS with a nullptr deref during probe. This diff which just moves some lines around fixes that and the LCD appears to work properly.
OK I folded this into my patch, thanks!
Once I verified the 24bit depth and clock speed config on HW as well, I can give you my Tested-by, or would you prefer that I resubmit your series with the fix below?
It's fine if you test it just with your patch as-is, I didn't change anything else.
I would be amazed if it "just works" now.
Indeed, you won't be. On a real CX the LCD displays shows content without any other changes to the set, but has a ~3Hz pulsating effect scrolling from the top to the bottom and the gray text changes color slightly.
Without the patchset applied everything looks perfectly.
I tried setting vrefresh to 20, fb_bpp to 16 and forcing an inverted panel clock, but the pulsing didn't change.
Using the emulated CX I compared the contents of the registers and found that only the IPC bit (which I tried to set, so that's likely not it) and the interrupt registers have a different content.
Any idea?
Thanks, Fabian
Yours, Linus Walleij
On Thu, Jul 25, 2019 at 9:26 PM Fabian Vogt fabian@ritter-vogt.de wrote:
On a real CX the LCD displays shows content without any other changes to the set, but has a ~3Hz pulsating effect scrolling from the top to the bottom and the gray text changes color slightly.
So you mean something meaningful appears in the LCD but there are visual disturbances?
Without the patchset applied everything looks perfectly.
I tried setting vrefresh to 20, fb_bpp to 16 and forcing an inverted panel clock, but the pulsing didn't change.
Using the emulated CX I compared the contents of the registers and found that only the IPC bit (which I tried to set, so that's likely not it) and the interrupt registers have a different content.
Any idea?
I think it's the clock settings in patch 2/3.
I just set them to "1000" (1MHz since its in kHz) based on some educated guesses.
The old driver set the clock to "1" (kHz) so just try that first, maybe it is really that slow.
It's just that the old driver also set refres to 60 fps which doesn't add up, but I think that setting is simply ignored and that is why it works.
Yours, Linus Walleij
Yours, Linus Walleij
Yours, Linus Walleij
Hi,
Am Samstag, 3. August 2019, 11:51:59 CEST schrieb Linus Walleij:
On Thu, Jul 25, 2019 at 9:26 PM Fabian Vogt fabian@ritter-vogt.de wrote:
On a real CX the LCD displays shows content without any other changes to the set, but has a ~3Hz pulsating effect scrolling from the top to the bottom and the gray text changes color slightly.
So you mean something meaningful appears in the LCD but there are visual disturbances?
Without the patchset applied everything looks perfectly.
I tried setting vrefresh to 20, fb_bpp to 16 and forcing an inverted panel clock, but the pulsing didn't change.
Using the emulated CX I compared the contents of the registers and found that only the IPC bit (which I tried to set, so that's likely not it) and the interrupt registers have a different content.
Any idea?
I think it's the clock settings in patch 2/3.
I just set them to "1000" (1MHz since its in kHz) based on some educated guesses.
The old driver set the clock to "1" (kHz) so just try that first, maybe it is really that slow.
Did that, it looked rather unhealthy for the LCD. Mostly white with some glitching except for ~2-3 lines with content scrolling on the screen.
200kHz was still way to slow, so tried the opposite direction. With a clock of 10MHz the display seems to be working fine and produces a visibly stable output.
Thanks, Fabian
It's just that the old driver also set refres to 60 fps which doesn't add up, but I think that setting is simply ignored and that is why it works.
Yours, Linus Walleij
--- diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index e5cfe1398a3b..3addcdab8adb 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2763,7 +2763,7 @@ static const struct panel_desc arm_rtsm = {
static const struct drm_display_mode nspire_cx_lcd_mode[] = { { - .clock = 1000, + .clock = 10000, .hdisplay = 320, .hsync_start = 320 + 50, .hsync_end = 320 + 50 + 6, @@ -2791,7 +2791,7 @@ static const struct panel_desc nspire_cx_lcd_panel = {
static const struct drm_display_mode nspire_classic_lcd_mode[] = { { - .clock = 1000, + .clock = 10000, .hdisplay = 320, .hsync_start = 320 + 6, .hsync_end = 320 + 6 + 6,
On 7/23/19 8:37 AM, Linus Walleij wrote:
Migrating the TI nspire calculators to use the PL111 driver for framebuffer requires grayscale support for the elder panel which uses 8bit grayscale only.
DRM does not support 8bit grayscale framebuffers in memory, but by defining the bus format to be MEDIA_BUS_FMT_Y8_1X8 we can get the hardware to turn on a grayscaling feature and convert the RGB framebuffer to grayscale for us.
What would it take to add proper grayscale framebuffer support to DRM? I've been using the RGB to gray conversion method for a while now with st7586 and it is OK but is creates extra work if you want things to actually look "good" instead of "OK" because you have to add code to userspace programs to craft images in a certain way so that they come out on the other side looking as intended on the actual display.
On Tue, 2019-07-23 at 15:37 +0200, Linus Walleij wrote:
Migrating the TI nspire calculators to use the PL111 driver for framebuffer requires grayscale support for the elder panel which uses 8bit grayscale only.
DRM does not support 8bit grayscale framebuffers in memory, but by defining the bus format to be MEDIA_BUS_FMT_Y8_1X8 we can get the hardware to turn on a grayscaling feature and convert the RGB framebuffer to grayscale for us.
What's wrong with DRM_FORMAT_R8? Yes the hardware is not really "redscale", but it's still a single color channel and there's not really any ambiguity.
- ajax
On Tue, Jul 23, 2019 at 7:25 PM Adam Jackson ajax@redhat.com wrote:
On Tue, 2019-07-23 at 15:37 +0200, Linus Walleij wrote:
Migrating the TI nspire calculators to use the PL111 driver for framebuffer requires grayscale support for the elder panel which uses 8bit grayscale only.
DRM does not support 8bit grayscale framebuffers in memory, but by defining the bus format to be MEDIA_BUS_FMT_Y8_1X8 we can get the hardware to turn on a grayscaling feature and convert the RGB framebuffer to grayscale for us.
What's wrong with DRM_FORMAT_R8? Yes the hardware is not really "redscale", but it's still a single color channel and there's not really any ambiguity.
Yeah, I think with a comment or an aliasing #define to _Y8 (or both) this is good to go.
You probably still want to expose the rgb format since too much userspace just assumes that xrgb8888 works. Same reason why the tinydrm drivers do the sw conversion. -Daniel
On Tue, Jul 23, 2019 at 11:07 PM Daniel Vetter daniel@ffwll.ch wrote:
On Tue, Jul 23, 2019 at 7:25 PM Adam Jackson ajax@redhat.com wrote:
On Tue, 2019-07-23 at 15:37 +0200, Linus Walleij wrote:
Migrating the TI nspire calculators to use the PL111 driver for framebuffer requires grayscale support for the elder panel which uses 8bit grayscale only.
DRM does not support 8bit grayscale framebuffers in memory, but by defining the bus format to be MEDIA_BUS_FMT_Y8_1X8 we can get the hardware to turn on a grayscaling feature and convert the RGB framebuffer to grayscale for us.
What's wrong with DRM_FORMAT_R8? Yes the hardware is not really "redscale", but it's still a single color channel and there's not really any ambiguity.
Yeah, I think with a comment or an aliasing #define to _Y8 (or both) this is good to go.
Is there something really wrong with just biting the bullet and do this:
/* 8 bpp grayscale */ #define DRM_FORMAT_Y8 fourcc_code('Y', '8', ' ', ' ') /* [7:0] Y */
It's quite an embarrasement for my OCD tendencies to talk about black-and-white TV as if it was 256 Shades of Red (good title for a novel by the way).
I don't know how these FOURCC things work, possibly new fourcc:s can only be defined by some especially enlightened cabal of standardization?
(It beats me how it can not already exist in that case.)
You probably still want to expose the rgb format since too much userspace just assumes that xrgb8888 works. Same reason why the tinydrm drivers do the sw conversion.
Yes this is what we do on PL111 now, we just run it through the hardware grayscaler.
This hardware graciously supports reading black-white and grayscale bitmaps with 1 (monochrome), 2, 4 and 8 bits per pixel which would be Y1, Y2, Y4 and Y8. But we only have hardware supporting Y8 at least on the other side so I don't see any need for the others ATM.
I suspect the Y1 etc could be useful for people doing not only Hercules video drivers (hah!) but also for ePaper displays of say, some random Kindle.
Yours, Linus Walleij
On Wed, Jul 24, 2019 at 2:52 PM Linus Walleij linus.walleij@linaro.org wrote:
On Tue, Jul 23, 2019 at 11:07 PM Daniel Vetter daniel@ffwll.ch wrote:
On Tue, Jul 23, 2019 at 7:25 PM Adam Jackson ajax@redhat.com wrote:
On Tue, 2019-07-23 at 15:37 +0200, Linus Walleij wrote:
Migrating the TI nspire calculators to use the PL111 driver for framebuffer requires grayscale support for the elder panel which uses 8bit grayscale only.
DRM does not support 8bit grayscale framebuffers in memory, but by defining the bus format to be MEDIA_BUS_FMT_Y8_1X8 we can get the hardware to turn on a grayscaling feature and convert the RGB framebuffer to grayscale for us.
What's wrong with DRM_FORMAT_R8? Yes the hardware is not really "redscale", but it's still a single color channel and there's not really any ambiguity.
Yeah, I think with a comment or an aliasing #define to _Y8 (or both) this is good to go.
Is there something really wrong with just biting the bullet and do this:
/* 8 bpp grayscale */ #define DRM_FORMAT_Y8 fourcc_code('Y', '8', ' ', ' ') /* [7:0] Y */
It's quite an embarrasement for my OCD tendencies to talk about black-and-white TV as if it was 256 Shades of Red (good title for a novel by the way).
I don't know how these FOURCC things work, possibly new fourcc:s can only be defined by some especially enlightened cabal of standardization?
(It beats me how it can not already exist in that case.)
The drm subsystem cabal owns drm_fourcc.h. And yeah I guess we can also add Y version of all these, I think the R/RG was added since that matches modern GL, where your texture contents are entirely up to interpretation by shaders. Y also exists in GL, but only in legacy contexts and is kinda discouraged. That was the idea behind just making them aliasing (since I just can't come up with any reason why you'd actually want a red-only texture). In a way R = red = the first channel in GL shaders, which happens to be called r for red != actually red color channel on the display.
Hence we might as well state that if you give a kms driver a single-channel fourcc code, then that should be interpreted as greyscale. Plus add a huge comment about why this single channel is called R :-) -Daniel
You probably still want to expose the rgb format since too much userspace just assumes that xrgb8888 works. Same reason why the tinydrm drivers do the sw conversion.
Yes this is what we do on PL111 now, we just run it through the hardware grayscaler.
This hardware graciously supports reading black-white and grayscale bitmaps with 1 (monochrome), 2, 4 and 8 bits per pixel which would be Y1, Y2, Y4 and Y8. But we only have hardware supporting Y8 at least on the other side so I don't see any need for the others ATM.
I suspect the Y1 etc could be useful for people doing not only Hercules video drivers (hah!) but also for ePaper displays of say, some random Kindle.
I guess if we bother with Y (whether aliased to R or new ones) we might as well roll out all of them. -Daniel
This adds support for the TI nspire panels to the simple panel roster. This code is based on arch/arm/mach-nspire/clcd.c. This includes likely the first grayscale panel supported.
These panels will be used with the PL11x DRM driver.
Cc: Daniel Tang dt.tangr@gmail.com Cc: Fabian Vogt fabian@ritter-vogt.de Signed-off-by: Linus Walleij linus.walleij@linaro.org --- drivers/gpu/drm/panel/panel-simple.c | 63 ++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 5a93c4edf1e4..e5cfe1398a3b 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2761,6 +2761,63 @@ static const struct panel_desc arm_rtsm = { .bus_format = MEDIA_BUS_FMT_RGB888_1X24, };
+static const struct drm_display_mode nspire_cx_lcd_mode[] = { + { + .clock = 1000, + .hdisplay = 320, + .hsync_start = 320 + 50, + .hsync_end = 320 + 50 + 6, + .htotal = 320 + 50 + 6 + 38, + .vdisplay = 240, + .vsync_start = 240 + 3, + .vsync_end = 240 + 3 + 1, + .vtotal = 240 + 3 + 1 + 17, + .vrefresh = 60, + .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, + }, +}; + +static const struct panel_desc nspire_cx_lcd_panel = { + .modes = nspire_cx_lcd_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 65, + .height = 49, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .bus_flags = DRM_BUS_FLAG_PIXDATA_NEGEDGE, +}; + +static const struct drm_display_mode nspire_classic_lcd_mode[] = { + { + .clock = 1000, + .hdisplay = 320, + .hsync_start = 320 + 6, + .hsync_end = 320 + 6 + 6, + .htotal = 320 + 6 + 6 + 6, + .vdisplay = 240, + .vsync_start = 240 + 0, + .vsync_end = 240 + 0 + 1, + .vtotal = 240 + 0 + 1 + 0, + .vrefresh = 60, + .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, + }, +}; + +static const struct panel_desc nspire_classic_lcd_panel = { + .modes = nspire_classic_lcd_mode, + .num_modes = 1, + /* The grayscale panel has 8 bit for the color .. Y (black) */ + .bpc = 8, + .size = { + .width = 71, + .height = 53, + }, + /* This is the grayscale bus format */ + .bus_format = MEDIA_BUS_FMT_Y8_1X8, +}; + static const struct of_device_id platform_of_match[] = { { .compatible = "ampire,am-480272h3tmqw-t01h", @@ -2966,6 +3023,12 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "nlt,nl192108ac18-02d", .data = &nlt_nl192108ac18_02d, + }, { + .compatible = "ti,nspire-cx-lcd-panel", + .data = &nspire_cx_lcd_panel, + }, { + .compatible = "ti,nspire-classic-lcd-panel", + .data = &nspire_classic_lcd_panel, }, { .compatible = "nvd,9128", .data = &nvd_9128,
Hi Linus
Good to see more panels and work on moving from fb to drm.
Also good to use media_bus_format to signal this is a greyscale display.
On Tue, Jul 23, 2019 at 03:37:54PM +0200, Linus Walleij wrote:
This adds support for the TI nspire panels to the simple panel roster. This code is based on arch/arm/mach-nspire/clcd.c. This includes likely the first grayscale panel supported.
These panels will be used with the PL11x DRM driver.
Cc: Daniel Tang dt.tangr@gmail.com Cc: Fabian Vogt fabian@ritter-vogt.de Signed-off-by: Linus Walleij linus.walleij@linaro.org
drivers/gpu/drm/panel/panel-simple.c | 63 ++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 5a93c4edf1e4..e5cfe1398a3b 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2761,6 +2761,63 @@ static const struct panel_desc arm_rtsm = { .bus_format = MEDIA_BUS_FMT_RGB888_1X24, };
+static const struct drm_display_mode nspire_cx_lcd_mode[] = {
Please name the variables like the compatible. So something like ti_nspire_xxxx Relevant for all variables.
When names are adjusted make sure the entries are sorted properly.
- {
.clock = 1000,
.hdisplay = 320,
.hsync_start = 320 + 50,
.hsync_end = 320 + 50 + 6,
.htotal = 320 + 50 + 6 + 38,
.vdisplay = 240,
.vsync_start = 240 + 3,
.vsync_end = 240 + 3 + 1,
.vtotal = 240 + 3 + 1 + 17,
.vrefresh = 60,
Can we achieve this refresh rate with a slow clock like this?
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
+1 for specifying .flags.
- },
+};
+static const struct panel_desc nspire_cx_lcd_panel = {
- .modes = nspire_cx_lcd_mode,
- .num_modes = 1,
- .bpc = 8,
- .size = {
.width = 65,
.height = 49,
- },
- .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
- .bus_flags = DRM_BUS_FLAG_PIXDATA_NEGEDGE,
+};
+static const struct drm_display_mode nspire_classic_lcd_mode[] = {
- {
.clock = 1000,
.hdisplay = 320,
.hsync_start = 320 + 6,
.hsync_end = 320 + 6 + 6,
.htotal = 320 + 6 + 6 + 6,
.vdisplay = 240,
.vsync_start = 240 + 0,
.vsync_end = 240 + 0 + 1,
.vtotal = 240 + 0 + 1 + 0,
.vrefresh = 60,
Ditto
.flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
- },
+};
+static const struct panel_desc nspire_classic_lcd_panel = {
- .modes = nspire_classic_lcd_mode,
- .num_modes = 1,
- /* The grayscale panel has 8 bit for the color .. Y (black) */
- .bpc = 8,
- .size = {
.width = 71,
.height = 53,
- },
- /* This is the grayscale bus format */
- .bus_format = MEDIA_BUS_FMT_Y8_1X8,
No DRM_BUS_FLAG_PIXDATA here?
+};
static const struct of_device_id platform_of_match[] = { { .compatible = "ampire,am-480272h3tmqw-t01h", @@ -2966,6 +3023,12 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "nlt,nl192108ac18-02d", .data = &nlt_nl192108ac18_02d,
- }, {
.compatible = "ti,nspire-cx-lcd-panel",
.data = &nspire_cx_lcd_panel,
- }, {
.compatible = "ti,nspire-classic-lcd-panel",
}, {.data = &nspire_classic_lcd_panel,
Should be sorted after compatible. And with fixed naming this is the same as if name is used for sorting.
.compatible = "nvd,9128", .data = &nvd_9128,
Furthermore I did not see any bindings for the panels. If they indeed are missing, then please provide bindings in the yaml format.
Thanks,
Sam
Hi Sam,
fixed most things, one question remain:
On Tue, Jul 23, 2019 at 7:54 PM Sam Ravnborg sam@ravnborg.org wrote:
Furthermore I did not see any bindings for the panels. If they indeed are missing, then please provide bindings in the yaml format.
IIUC we do not create binding documents for the simple panels, but I can do this of course, just vaguely remember that the DT people didn't want to see bindings that all look the same but instead rely on panel-common.txt
Yours, Linus Walleij
Hi Linus.
On Wed, Jul 24, 2019 at 03:58:40PM +0200, Linus Walleij wrote:
Hi Sam,
fixed most things, one question remain:
On Tue, Jul 23, 2019 at 7:54 PM Sam Ravnborg sam@ravnborg.org wrote:
Furthermore I did not see any bindings for the panels. If they indeed are missing, then please provide bindings in the yaml format.
IIUC we do not create binding documents for the simple panels, but I can do this of course, just vaguely remember that the DT people didn't want to see bindings that all look the same but instead rely on panel-common.txt
My understanding is that the bindings for th panels should list what is required/optional, but with reference to panel-common (which IIRC has a new name in the yaml world). If you look in bindings/display/panels you can see a lot of simple panels listed.
Sam
This moves the nspire over to using the device tree to set-up and probe the PL111 DRM driver and use the panels from the simple-panel drivers.
Cc: Daniel Tang dt.tangr@gmail.com Cc: Fabian Vogt fabian@ritter-vogt.de Signed-off-by: Linus Walleij linus.walleij@linaro.org --- arch/arm/boot/dts/nspire-classic.dtsi | 19 ++++- arch/arm/boot/dts/nspire-cx.dts | 18 +++- arch/arm/boot/dts/nspire.dtsi | 10 ++- arch/arm/mach-nspire/Makefile | 1 - arch/arm/mach-nspire/clcd.c | 114 -------------------------- arch/arm/mach-nspire/clcd.h | 10 --- arch/arm/mach-nspire/nspire.c | 25 ------ 7 files changed, 43 insertions(+), 154 deletions(-) delete mode 100644 arch/arm/mach-nspire/clcd.c delete mode 100644 arch/arm/mach-nspire/clcd.h
diff --git a/arch/arm/boot/dts/nspire-classic.dtsi b/arch/arm/boot/dts/nspire-classic.dtsi index c53f42777851..fabd8270f168 100644 --- a/arch/arm/boot/dts/nspire-classic.dtsi +++ b/arch/arm/boot/dts/nspire-classic.dtsi @@ -8,7 +8,13 @@ /include/ "nspire.dtsi"
&lcd { - lcd-type = "classic"; + port { + clcd_pads: endpoint { + remote-endpoint = <&panel_in>; + /* Dummy values, since we are grayscale */ + arm,pl11x,tft-r0g0b0-pads = <0 8 16>; + }; + }; };
&fast_timer { @@ -69,6 +75,17 @@ #interrupt-cells = <1>; }; }; + + panel { + compatible = "ti,nspire-classic-lcd-panel"; + ports { + port { + panel_in: endpoint { + remote-endpoint = <&clcd_pads>; + }; + }; + }; + }; chosen { bootargs = "debug earlyprintk console=tty0 console=ttyS0,115200n8 root=/dev/ram0"; }; diff --git a/arch/arm/boot/dts/nspire-cx.dts b/arch/arm/boot/dts/nspire-cx.dts index da95c3736651..1551d0d0189f 100644 --- a/arch/arm/boot/dts/nspire-cx.dts +++ b/arch/arm/boot/dts/nspire-cx.dts @@ -9,7 +9,12 @@ /include/ "nspire.dtsi"
&lcd { - lcd-type = "cx"; + port { + clcd_pads: endpoint { + remote-endpoint = <&panel_in>; + arm,pl11x,tft-r0g0b0-pads = <0 8 16>; + }; + }; };
&fast_timer { @@ -106,6 +111,17 @@ }; }; }; + + panel { + compatible = "ti,nspire-cx-lcd-panel"; + ports { + port { + panel_in: endpoint { + remote-endpoint = <&clcd_pads>; + }; + }; + }; + }; chosen { bootargs = "debug earlyprintk console=tty0 console=ttyAMA0,115200n8 root=/dev/ram0"; }; diff --git a/arch/arm/boot/dts/nspire.dtsi b/arch/arm/boot/dts/nspire.dtsi index c35fd6667716..d9a0fd7524dc 100644 --- a/arch/arm/boot/dts/nspire.dtsi +++ b/arch/arm/boot/dts/nspire.dtsi @@ -95,8 +95,14 @@ reg = <0xC0000000 0x1000>; interrupts = <21>;
- clocks = <&apb_pclk>; - clock-names = "apb_pclk"; + /* + * We assume the same clock is fed to APB and CLCDCLK. + * There is some code to scale the clock down by a factor + * 48 for the display so likely the frequency to the + * display is 1MHz and the CLCDCLK is 48 MHz. + */ + clocks = <&apb_pclk>, <&apb_pclk>; + clock-names = "clcdclk", "apb_pclk"; };
adc: adc@C4000000 { diff --git a/arch/arm/mach-nspire/Makefile b/arch/arm/mach-nspire/Makefile index 1d568c600452..4716b9b9aa7b 100644 --- a/arch/arm/mach-nspire/Makefile +++ b/arch/arm/mach-nspire/Makefile @@ -1,3 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only obj-y += nspire.o -obj-y += clcd.o diff --git a/arch/arm/mach-nspire/clcd.c b/arch/arm/mach-nspire/clcd.c deleted file mode 100644 index 44738dcb391d..000000000000 --- a/arch/arm/mach-nspire/clcd.c +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * linux/arch/arm/mach-nspire/clcd.c - * - * Copyright (C) 2013 Daniel Tang tangrs@tangrs.id.au - */ - -#include <linux/init.h> -#include <linux/of.h> -#include <linux/amba/bus.h> -#include <linux/amba/clcd.h> -#include <linux/dma-mapping.h> - -static struct clcd_panel nspire_cx_lcd_panel = { - .mode = { - .name = "Color LCD", - .refresh = 60, - .xres = 320, - .yres = 240, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - .pixclock = 1, - .hsync_len = 6, - .vsync_len = 1, - .right_margin = 50, - .left_margin = 38, - .lower_margin = 3, - .upper_margin = 17, - }, - .width = 65, /* ~6.50 cm */ - .height = 49, /* ~4.87 cm */ - .tim2 = TIM2_IPC, - .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), - .bpp = 16, - .caps = CLCD_CAP_565, -}; - -static struct clcd_panel nspire_classic_lcd_panel = { - .mode = { - .name = "Grayscale LCD", - .refresh = 60, - .xres = 320, - .yres = 240, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED, - .pixclock = 1, - .hsync_len = 6, - .vsync_len = 1, - .right_margin = 6, - .left_margin = 6, - }, - .width = 71, /* 7.11cm */ - .height = 53, /* 5.33cm */ - .tim2 = 0x80007d0, - .cntl = CNTL_LCDMONO8, - .bpp = 8, - .grayscale = 1, - .caps = CLCD_CAP_5551, -}; - -int nspire_clcd_setup(struct clcd_fb *fb) -{ - struct clcd_panel *panel; - size_t panel_size; - const char *type; - dma_addr_t dma; - int err; - - BUG_ON(!fb->dev->dev.of_node); - - err = of_property_read_string(fb->dev->dev.of_node, "lcd-type", &type); - if (err) { - pr_err("CLCD: Could not find lcd-type property\n"); - return err; - } - - if (!strcmp(type, "cx")) { - panel = &nspire_cx_lcd_panel; - } else if (!strcmp(type, "classic")) { - panel = &nspire_classic_lcd_panel; - } else { - pr_err("CLCD: Unknown lcd-type %s\n", type); - return -EINVAL; - } - - panel_size = ((panel->mode.xres * panel->mode.yres) * panel->bpp) / 8; - panel_size = ALIGN(panel_size, PAGE_SIZE); - - fb->fb.screen_base = dma_alloc_wc(&fb->dev->dev, panel_size, &dma, - GFP_KERNEL); - - if (!fb->fb.screen_base) { - pr_err("CLCD: unable to map framebuffer\n"); - return -ENOMEM; - } - - fb->fb.fix.smem_start = dma; - fb->fb.fix.smem_len = panel_size; - fb->panel = panel; - - return 0; -} - -int nspire_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) -{ - return dma_mmap_wc(&fb->dev->dev, vma, fb->fb.screen_base, - fb->fb.fix.smem_start, fb->fb.fix.smem_len); -} - -void nspire_clcd_remove(struct clcd_fb *fb) -{ - dma_free_wc(&fb->dev->dev, fb->fb.fix.smem_len, fb->fb.screen_base, - fb->fb.fix.smem_start); -} diff --git a/arch/arm/mach-nspire/clcd.h b/arch/arm/mach-nspire/clcd.h deleted file mode 100644 index 7f36bd8511c5..000000000000 --- a/arch/arm/mach-nspire/clcd.h +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * linux/arch/arm/mach-nspire/clcd.h - * - * Copyright (C) 2013 Daniel Tang tangrs@tangrs.id.au - */ - -int nspire_clcd_setup(struct clcd_fb *fb); -int nspire_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma); -void nspire_clcd_remove(struct clcd_fb *fb); diff --git a/arch/arm/mach-nspire/nspire.c b/arch/arm/mach-nspire/nspire.c index 957bd0c0fbd5..2d4abb0288b9 100644 --- a/arch/arm/mach-nspire/nspire.c +++ b/arch/arm/mach-nspire/nspire.c @@ -12,14 +12,12 @@ #include <linux/irqchip/arm-vic.h> #include <linux/clkdev.h> #include <linux/amba/bus.h> -#include <linux/amba/clcd.h>
#include <asm/mach/arch.h> #include <asm/mach-types.h> #include <asm/mach/map.h>
#include "mmio.h" -#include "clcd.h"
static const char *const nspire_dt_match[] __initconst = { "ti,nspire", @@ -29,28 +27,6 @@ static const char *const nspire_dt_match[] __initconst = { NULL, };
-static struct clcd_board nspire_clcd_data = { - .name = "LCD", - .caps = CLCD_CAP_5551 | CLCD_CAP_565, - .check = clcdfb_check, - .decode = clcdfb_decode, - .setup = nspire_clcd_setup, - .mmap = nspire_clcd_mmap, - .remove = nspire_clcd_remove, -}; - - -static struct of_dev_auxdata nspire_auxdata[] __initdata = { - OF_DEV_AUXDATA("arm,pl111", NSPIRE_LCD_PHYS_BASE, - NULL, &nspire_clcd_data), - { } -}; - -static void __init nspire_init(void) -{ - of_platform_default_populate(NULL, nspire_auxdata, NULL); -} - static void nspire_restart(enum reboot_mode mode, const char *cmd) { void __iomem *base = ioremap(NSPIRE_MISC_PHYS_BASE, SZ_4K); @@ -62,6 +38,5 @@ static void nspire_restart(enum reboot_mode mode, const char *cmd)
DT_MACHINE_START(NSPIRE, "TI-NSPIRE") .dt_compat = nspire_dt_match, - .init_machine = nspire_init, .restart = nspire_restart, MACHINE_END
Hi Linus.
On Tue, Jul 23, 2019 at 03:37:52PM +0200, Linus Walleij wrote:
So this is a cold-coded attempt to move the TI nspire over to using DRM. It is more or less the last user of the old fbdev driver so it is a noble cause and interesting usecase.
Do we need to support arm,pl11x,tft-r0g0b0-pads before we can obsolete fbdev stuff? Just checked and cannot see it in use today.
Looked through the patches. 1 and 3 are: Acked-by: Sam Ravnborg sam@ravnborg.org
As in - the patches looked fine to me - but I do not know the code in detail. But obviously need some testing feedback before they are applied.
Posted some comments on patch 2.
Sam
On Tue, Jul 23, 2019 at 8:10 PM Sam Ravnborg sam@ravnborg.org wrote:
On Tue, Jul 23, 2019 at 03:37:52PM +0200, Linus Walleij wrote:
So this is a cold-coded attempt to move the TI nspire over to using DRM. It is more or less the last user of the old fbdev driver so it is a noble cause and interesting usecase.
Do we need to support arm,pl11x,tft-r0g0b0-pads before we can obsolete fbdev stuff?
No I don't think so, the only in-tree platform that was using it was the Nomadik and all it did was to switch RGB to BGR and I already handle that in the driver using the hardware feature to switch RGB and BGR around instead.
Right now I just check that the pads are there, I might just remove the check.
However Pawel added this binding and might be able to tell something about if there are platforms out there that really needs this. Possibly Liviu knows more.
Looked through the patches. 1 and 3 are: Acked-by: Sam Ravnborg sam@ravnborg.org
Thanks!
Yours, Linus Walleij
On Wed, 2019-07-24 at 13:28 +0100, Linus Walleij wrote:
On Tue, Jul 23, 2019 at 8:10 PM Sam Ravnborg sam@ravnborg.org wrote:
On Tue, Jul 23, 2019 at 03:37:52PM +0200, Linus Walleij wrote: Do we need to support arm,pl11x,tft-r0g0b0-pads before we can obsolete fbdev stuff?
No I don't think so, the only in-tree platform that was using it was the Nomadik and all it did was to switch RGB to BGR and I already handle that in the driver using the hardware feature to switch RGB and BGR around instead.
Right now I just check that the pads are there, I might just remove the check.
However Pawel added this binding and might be able to tell something about if there are platforms out there that really needs this. Possibly Liviu knows more.
It was only there so the fbdev driver could figure out the output mode. I take that DRM "pipeline" now takes care of it, so I'd say that the moment the fbdev driver dies, the binding can go along :-)
Cheers!
Pawel
On Wed, Jul 24, 2019 at 2:47 PM Pawel Moll pawel.moll@arm.com wrote:
On Wed, 2019-07-24 at 13:28 +0100, Linus Walleij wrote:
On Tue, Jul 23, 2019 at 8:10 PM Sam Ravnborg sam@ravnborg.org wrote:
On Tue, Jul 23, 2019 at 03:37:52PM +0200, Linus Walleij wrote: Do we need to support arm,pl11x,tft-r0g0b0-pads before we can obsolete fbdev stuff?
No I don't think so, the only in-tree platform that was using it was the Nomadik and all it did was to switch RGB to BGR and I already handle that in the driver using the hardware feature to switch RGB and BGR around instead.
Right now I just check that the pads are there, I might just remove the check.
However Pawel added this binding and might be able to tell something about if there are platforms out there that really needs this. Possibly Liviu knows more.
It was only there so the fbdev driver could figure out the output mode. I take that DRM "pipeline" now takes care of it, so I'd say that the moment the fbdev driver dies, the binding can go along :-)
OK I'll get rid of it. :)
Yours, Linus Walleij
dri-devel@lists.freedesktop.org