drivers: update DCNANO LCDIF IP to use shared LCDIF binding

Update DCNANO LCDIF IP to use shared lcd interface binding. This
requires changes to the RT5xx SOC and RT595 EVK, as this SOC
uses the LCDIF IP, and configures the clock for it based off
the new pixel-clock property.

Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
This commit is contained in:
Daniel DeGrasse 2023-01-17 15:36:31 -06:00 committed by Carles Cufí
commit a4afa7d164
5 changed files with 64 additions and 122 deletions

View file

@ -10,6 +10,8 @@
#include "mimxrt595_evk_cm33-pinctrl.dtsi"
#include <zephyr/dt-bindings/display/panel.h>
/ {
model = "NXP MIMXRT595-EVK board";
compatible = "nxp,mimxrt595";
@ -157,17 +159,28 @@
status = "okay";
width = <720>;
height = <1280>;
clk-div = <7>;
polarity = <12>;
hsync = <8>;
hfp = <32>;
hbp = <32>;
vsync = <2>;
vfp = <16>;
vbp = <14>;
display-timings {
compatible = "zephyr,panel-timing";
hsync-len = <8>;
hfront-porch = <32>;
hback-porch = <32>;
vsync-len = <2>;
vfront-porch = <16>;
vback-porch = <14>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <1>;
/*
* Pixel clock is given by the following formula:
* (height + vsync-len + vfront-porch + vback-porch) *
* (width + hsync-len + hfront-porch + hback-porch) * frame rate
*/
clock-frequency = <62346240>;
};
backlight-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
data-bus-width = "24-bit";
pixel-format = "rgb-565";
pixel-format = <PANEL_PIXEL_FORMAT_BGR_565>;
};
&mipi_dsi {

View file

@ -211,6 +211,12 @@ static int mcux_dcnano_lcdif_init(const struct device *dev)
return ret;
}
/* Convert pixel format from devicetree to the format used by HAL */
ret = mcux_dcnano_lcdif_set_pixel_format(dev, data->fb_config.format);
if (ret) {
return ret;
}
LCDIF_Init(config->base);
LCDIF_DpiModeSetConfig(config->base, 0, &config->dpi_config);
@ -242,11 +248,8 @@ static const struct display_driver_api mcux_dcnano_lcdif_api = {
.get_framebuffer = mcux_dcnano_lcdif_get_framebuffer,
};
/* This macro evaluates to 4 when the pixel format enum is set to 4,
* and 2 for all other enum values.
*/
#define MCUX_DCNANO_LCDIF_PIXEL_BYTES(n) \
(((DT_INST_ENUM_IDX(n, pixel_format) / 4) * 2) + 2)
(DISPLAY_BITS_PER_PIXEL(DT_INST_PROP(n, pixel_format)) / 8)
/* When using external framebuffer mem, we should not allocate framebuffers
* in SRAM. Instead, we use external framebuffer address and size
@ -284,7 +287,7 @@ static const struct display_driver_api mcux_dcnano_lcdif_api = {
.fb_config = { \
.enable = true, \
.enableGamma = false, \
.format = DT_INST_ENUM_IDX(n, pixel_format), \
.format = DT_INST_PROP(n, pixel_format), \
}, \
.pixel_bytes = MCUX_DCNANO_LCDIF_PIXEL_BYTES(n), \
}; \
@ -295,13 +298,24 @@ static const struct display_driver_api mcux_dcnano_lcdif_api = {
.dpi_config = { \
.panelWidth = DT_INST_PROP(n, width), \
.panelHeight = DT_INST_PROP(n, height), \
.hsw = DT_INST_PROP(n, hsync), \
.hfp = DT_INST_PROP(n, hfp), \
.hbp = DT_INST_PROP(n, hbp), \
.vsw = DT_INST_PROP(n, vsync), \
.vfp = DT_INST_PROP(n, vfp), \
.vbp = DT_INST_PROP(n, vbp), \
.polarityFlags = DT_INST_PROP(n, polarity), \
.hsw = DT_INST_PROP(n, hsync_len), \
.hfp = DT_INST_PROP(n, hfront_porch), \
.hbp = DT_INST_PROP(n, hback_porch), \
.vsw = DT_INST_PROP(n, vsync_len), \
.vfp = DT_INST_PROP(n, vfront_porch), \
.vbp = DT_INST_PROP(n, vback_porch), \
.polarityFlags = (DT_INST_PROP(n, de_active) ? \
kLCDIF_DataEnableActiveHigh : \
kLCDIF_DataEnableActiveLow) | \
(DT_INST_PROP(n, pixelclk_active) ? \
kLCDIF_DriveDataOnRisingClkEdge : \
kLCDIF_DriveDataOnFallingClkEdge) | \
(DT_INST_PROP(n, hsync_active) ? \
kLCDIF_HsyncActiveHigh : \
kLCDIF_HsyncActiveLow) | \
(DT_INST_PROP(n, vsync_active) ? \
kLCDIF_VsyncActiveHigh : \
kLCDIF_VsyncActiveLow), \
.format = DT_INST_ENUM_IDX(n, data_bus_width), \
}, \
.fb_ptr = MCUX_DCNANO_LCDIF_FRAMEBUFFER(n), \

View file

@ -210,13 +210,17 @@ static int mcux_mipi_dsi_init(const struct device *dev)
.bllpMode = DT_INST_ENUM_IDX(id, dpi_bllp_mode), \
.pixelPayloadSize = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, width), \
.panelHeight = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, height), \
.polarityFlags = DT_INST_PROP_BY_PHANDLE_IDX( \
id, nxp_lcdif, id, polarity) & 0x3, \
.hfp = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, hfp), \
.hbp = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, hbp), \
.hsw = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, hsync), \
.vfp = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, vfp), \
.vbp = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, vbp), \
.polarityFlags = (DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, vsync_active) ?\
kDSI_DpiVsyncActiveHigh : \
kDSI_DpiVsyncActiveLow) | \
(DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, hsync_active) ? \
kDSI_DpiHsyncActiveHigh : \
kDSI_DpiHsyncActiveLow), \
.hfp = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, hfront_porch), \
.hbp = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, hback_porch), \
.hsw = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, hsync_len), \
.vfp = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, vfront_porch), \
.vbp = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, vback_porch), \
}, \
.auto_insert_eotp = DT_INST_PROP(id, autoinsert_eotp), \
.dphy_ref_freq = DT_INST_PROP_OR(id, dphy_ref_frequency, 0), \

View file

@ -5,7 +5,7 @@ description: NXP DCNano LCDIF (LCD Interface) controller
compatible: "nxp,dcnano-lcdif"
include: [display-controller.yaml, pinctrl-device.yaml]
include: [panel-controller.yaml, pinctrl-device.yaml]
properties:
reg:
@ -14,53 +14,12 @@ properties:
interrupts:
required: true
clk-div:
type: int
required: true
description: |
Clock divider for LCDIF. This should be used to set the pixel clock
based on the root clock provided to the module.
The clock should follow the following formula:
(display height + VSYNC pulse width + vertical front porch + vertical back porch) *
(display width + HSYNC pulse width + horizontal front porch + horizontal back porch) *
frame rate
backlight-gpios:
type: phandle-array
required: true
description:
LCB backlight control gpio. Driver will initialize this GPIO to active high
hsync:
type: int
required: true
description: HSYNC pulse width in display clock cycles
hfp:
type: int
required: true
description: Horizontal front porch in display clock cycles
hbp:
type: int
required: true
description: Horizontal back porch in display clock cycles
vsync:
type: int
required: true
description: VSYNC pulse width in display clock cycles
vfp:
type: int
required: true
description: Vertical front porch in display clock cycles
vbp:
type: int
required: true
description: Vertical back porch in display clock cycles
data-bus-width:
type: string
default: "24-bit"
@ -73,54 +32,3 @@ properties:
- "24-bit" # 24 Bit
description:
LCD data bus width. The default is set to the reset value of 24-bit
pixel-format:
type: string
required: true
enum:
- "unused"
- "xrgb-4444" # XRGB4444, 16-bit each pixel, 4-bit each element. R4G4B4 in reference manual.
- "xrgb-1555" # XRGB1555, 16-bit each pixel, 5-bit each element. R5G5B5 in reference manual.
- "rgb-565" # RGB565, 16-bit each pixel. R5G6B5 in reference manual.
- "xrgb-8888" # XRGB8888, 32-bit each pixel, 8-bit each element. R8G8B8 in reference manual.
description:
Display pixel format.
polarity:
type: int
required: true
enum:
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
description:
OR'ed value of lcdif_polarity_flags, used to control the signal polarity.
0000 VSYNC active low, HSYNC active low, DE active low, Drive data on falling edge.
0001 VSYNC active high, HSYNC active low, DE active low, Drive data on falling edge.
0010 VSYNC active low, HSYNC active high, DE active low, Drive data on falling edge.
0011 VSYNC active high, HSYNC active high, DE active low, Drive data on falling edge.
0100 VSYNC active low, HSYNC active low, DE active high, Drive data on falling edge.
0101 VSYNC active high, HSYNC active low, DE active high, Drive data on falling edge.
0110 VSYNC active low, HSYNC active high, DE active high, Drive data on falling edge.
0111 VSYNC active high, HSYNC active high, DE active high, Drive data on falling edge.
1000 VSYNC active low, HSYNC active low, DE active low, Drive data on rising edge.
1001 VSYNC active high, HSYNC active low, DE active low, Drive data on rising edge.
1010 VSYNC active low, HSYNC active high, DE active low, Drive data on rising edge.
1011 VSYNC active high, HSYNC active high, DE active low, Drive data on rising edge.
1100 VSYNC active low, HSYNC active low, DE active high, Drive data on rising edge.
1101 VSYNC active high, HSYNC active low, DE active high, Drive data on rising edge.
1110 VSYNC active low, HSYNC active high, DE active high, Drive data on rising edge.
1111 VSYNC active high, HSYNC active high, DE active high, Drive data on rising edge.

View file

@ -312,9 +312,12 @@ static void clock_init(void)
* (height + VSW + VFP + VBP) * (width + HSW + HFP + HBP) * frame rate.
* this means the clock divider will vary depending on
* the attached display.
*
* The root clock used here is the AUX0 PLL (PLL0 PFD2).
*/
CLOCK_SetClkDiv(kCLOCK_DivDcPixelClk,
DT_PROP(DT_NODELABEL(lcdif), clk_div));
((CLOCK_GetSysPfdFreq(kCLOCK_Pfd2) /
DT_PROP(DT_NODELABEL(lcdif), clock_frequency)) + 1));
CLOCK_EnableClock(kCLOCK_DisplayCtrl);
RESET_ClearPeripheralReset(kDISP_CTRL_RST_SHIFT_RSTn);