diff options
author | Ye Li <ye.li@nxp.com> | 2018-07-17 22:56:19 -0700 |
---|---|---|
committer | Ye Li <ye.li@nxp.com> | 2018-07-18 22:20:19 -0700 |
commit | 01e116ccd2e2705be3fb427da74cb19bab7ab4e0 (patch) | |
tree | 9443b1978657b755b3c40f05ef97114c846622b2 | |
parent | b08b17cde486a232b602b806862de56a26117c51 (diff) |
MLK-18945-7 video: Add mipi panel driver RM67191
Add a mipi dsi panel driver for RM67191 panel which is attached to mipi dsi
controller.
Signed-off-by: Ye Li <ye.li@nxp.com>
-rw-r--r-- | drivers/video/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/rm67191.c | 362 | ||||
-rw-r--r-- | include/mipi_display.h | 1 | ||||
-rw-r--r-- | include/mipi_dsi_panel.h | 1 | ||||
-rw-r--r-- | scripts/config_whitelist.txt | 1 |
5 files changed, 366 insertions, 0 deletions
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 306d4e4db6..09f48aab3e 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -72,6 +72,7 @@ obj-$(CONFIG_IMX_NORTHWEST_MIPI_DSI) += mipi_dsi_northwest.o obj-$(CONFIG_IMX_SEC_MIPI_DSI) += sec_mipi_dsim.o obj-$(CONFIG_IMX_MIPI_DSI_BRIDGE) += imx_mipi_dsi_bridge.o obj-$(CONFIG_HX8363) += hx8363_wvga.o +obj-$(CONFIG_RM67191) += rm67191.o obj-y += bridge/ obj-y += imx/ diff --git a/drivers/video/rm67191.c b/drivers/video/rm67191.c new file mode 100644 index 0000000000..4ef907f5dd --- /dev/null +++ b/drivers/video/rm67191.c @@ -0,0 +1,362 @@ +/* + * Copyright 2018 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <imx_mipi_dsi_bridge.h> +#include <mipi_display.h> +#include <linux/compat.h> + +#define CMD_TABLE_LEN 2 +typedef u8 cmd_set_table[CMD_TABLE_LEN]; + +/* Write Manufacture Command Set Control */ +#define WRMAUCCTR 0xFE + +/* Manufacturer Command Set pages (CMD2) */ +static const cmd_set_table manufacturer_cmd_set[] = { + {0xFE, 0x0B}, + {0x28, 0x40}, + {0x29, 0x4F}, + {0xFE, 0x0E}, + {0x4B, 0x00}, + {0x4C, 0x0F}, + {0x4D, 0x20}, + {0x4E, 0x40}, + {0x4F, 0x60}, + {0x50, 0xA0}, + {0x51, 0xC0}, + {0x52, 0xE0}, + {0x53, 0xFF}, + {0xFE, 0x0D}, + {0x18, 0x08}, + {0x42, 0x00}, + {0x08, 0x41}, + {0x46, 0x02}, + {0x72, 0x09}, + {0xFE, 0x0A}, + {0x24, 0x17}, + {0x04, 0x07}, + {0x1A, 0x0C}, + {0x0F, 0x44}, + {0xFE, 0x04}, + {0x00, 0x0C}, + {0x05, 0x08}, + {0x06, 0x08}, + {0x08, 0x08}, + {0x09, 0x08}, + {0x0A, 0xE6}, + {0x0B, 0x8C}, + {0x1A, 0x12}, + {0x1E, 0xE0}, + {0x29, 0x93}, + {0x2A, 0x93}, + {0x2F, 0x02}, + {0x31, 0x02}, + {0x33, 0x05}, + {0x37, 0x2D}, + {0x38, 0x2D}, + {0x3A, 0x1E}, + {0x3B, 0x1E}, + {0x3D, 0x27}, + {0x3F, 0x80}, + {0x40, 0x40}, + {0x41, 0xE0}, + {0x4F, 0x2F}, + {0x50, 0x1E}, + {0xFE, 0x06}, + {0x00, 0xCC}, + {0x05, 0x05}, + {0x07, 0xA2}, + {0x08, 0xCC}, + {0x0D, 0x03}, + {0x0F, 0xA2}, + {0x32, 0xCC}, + {0x37, 0x05}, + {0x39, 0x83}, + {0x3A, 0xCC}, + {0x41, 0x04}, + {0x43, 0x83}, + {0x44, 0xCC}, + {0x49, 0x05}, + {0x4B, 0xA2}, + {0x4C, 0xCC}, + {0x51, 0x03}, + {0x53, 0xA2}, + {0x75, 0xCC}, + {0x7A, 0x03}, + {0x7C, 0x83}, + {0x7D, 0xCC}, + {0x82, 0x02}, + {0x84, 0x83}, + {0x85, 0xEC}, + {0x86, 0x0F}, + {0x87, 0xFF}, + {0x88, 0x00}, + {0x8A, 0x02}, + {0x8C, 0xA2}, + {0x8D, 0xEA}, + {0x8E, 0x01}, + {0x8F, 0xE8}, + {0xFE, 0x06}, + {0x90, 0x0A}, + {0x92, 0x06}, + {0x93, 0xA0}, + {0x94, 0xA8}, + {0x95, 0xEC}, + {0x96, 0x0F}, + {0x97, 0xFF}, + {0x98, 0x00}, + {0x9A, 0x02}, + {0x9C, 0xA2}, + {0xAC, 0x04}, + {0xFE, 0x06}, + {0xB1, 0x12}, + {0xB2, 0x17}, + {0xB3, 0x17}, + {0xB4, 0x17}, + {0xB5, 0x17}, + {0xB6, 0x11}, + {0xB7, 0x08}, + {0xB8, 0x09}, + {0xB9, 0x06}, + {0xBA, 0x07}, + {0xBB, 0x17}, + {0xBC, 0x17}, + {0xBD, 0x17}, + {0xBE, 0x17}, + {0xBF, 0x17}, + {0xC0, 0x17}, + {0xC1, 0x17}, + {0xC2, 0x17}, + {0xC3, 0x17}, + {0xC4, 0x0F}, + {0xC5, 0x0E}, + {0xC6, 0x00}, + {0xC7, 0x01}, + {0xC8, 0x10}, + {0xFE, 0x06}, + {0x95, 0xEC}, + {0x8D, 0xEE}, + {0x44, 0xEC}, + {0x4C, 0xEC}, + {0x32, 0xEC}, + {0x3A, 0xEC}, + {0x7D, 0xEC}, + {0x75, 0xEC}, + {0x00, 0xEC}, + {0x08, 0xEC}, + {0x85, 0xEC}, + {0xA6, 0x21}, + {0xA7, 0x05}, + {0xA9, 0x06}, + {0x82, 0x06}, + {0x41, 0x06}, + {0x7A, 0x07}, + {0x37, 0x07}, + {0x05, 0x06}, + {0x49, 0x06}, + {0x0D, 0x04}, + {0x51, 0x04}, +}; + +static u8 color_format_from_dsi_format(enum mipi_dsi_pixel_format format) +{ + switch (format) { + case MIPI_DSI_FMT_RGB565: + return 0x55; + case MIPI_DSI_FMT_RGB666: + case MIPI_DSI_FMT_RGB666_PACKED: + return 0x66; + case MIPI_DSI_FMT_RGB888: + return 0x77; + default: + return 0x77; /* for backward compatibility */ + } +}; + +static int mipi_dsi_generic_write(const void *payload, size_t size) +{ + int ret; + u16 tx_buf; + u8 *tx; + + tx_buf = 0; + tx = (u8 *)&tx_buf; + + switch (size) { + case 0: + ret = imx_mipi_dsi_bridge_pkt_write(MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM, tx, 0); + break; + + case 1: + tx[0] = *(u8 *)payload; + ret = imx_mipi_dsi_bridge_pkt_write(MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM, tx, 0); + break; + + case 2: + ret = imx_mipi_dsi_bridge_pkt_write(MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM, (const u8 *)payload, 0); + break; + + default: + ret = imx_mipi_dsi_bridge_pkt_write(MIPI_DSI_GENERIC_LONG_WRITE, (const u8 *)payload, size); + break; + } + + return ret; +} + +static int mipi_dsi_dcs_write(u8 cmd, const void *data, size_t len) +{ + u32 size; + u8 *tx; + u16 tx_buf; + int ret; + + if (len > 0) { + size = 1 + len; + + tx = kmalloc(size, GFP_KERNEL); + if (!tx) + return -ENOMEM; + + /* concatenate the DCS command byte and the payload */ + tx[0] = cmd; + memcpy(&tx[1], data, len); + } else { + tx = (u8 *)&tx_buf; + tx[0] = cmd; + tx[1] = 0; + size = 1; + } + + switch (size) { + case 1: + ret = imx_mipi_dsi_bridge_pkt_write(MIPI_DSI_DCS_SHORT_WRITE, tx, 0); + break; + + case 2: + ret = imx_mipi_dsi_bridge_pkt_write(MIPI_DSI_DCS_SHORT_WRITE_PARAM, tx, 0); + break; + + default: + ret = imx_mipi_dsi_bridge_pkt_write(MIPI_DSI_DCS_LONG_WRITE, tx, size); + break; + } + + if (len > 0) + kfree(tx); + + return ret; +} + +static int rad_panel_push_cmd_list(void) +{ + size_t i; + const u8 *cmd; + size_t count = sizeof(manufacturer_cmd_set) / CMD_TABLE_LEN; + int ret = 0; + + for (i = 0; i < count ; i++) { + cmd = manufacturer_cmd_set[i]; + ret = mipi_dsi_generic_write(cmd, CMD_TABLE_LEN); + if (ret < 0) + return ret; + } + + return ret; +}; + +int rm67191_lcd_setup(struct mipi_dsi_client_dev *panel_dev) +{ + u8 color_format = color_format_from_dsi_format(panel_dev->format); + u16 brightness; + int ret; + + ret = rad_panel_push_cmd_list(); + if (ret < 0) { + printf("Failed to send MCS (%d)\n", ret); + return -EIO; + } + + /* Select User Command Set table (CMD1) */ + ret = mipi_dsi_generic_write((u8[]){ WRMAUCCTR, 0x00 }, 2); + if (ret < 0) + return -EIO; + + /* Software reset */ + ret = mipi_dsi_dcs_write(MIPI_DCS_SOFT_RESET, NULL, 0); + if (ret < 0) { + printf("Failed to do Software Reset (%d)\n", ret); + return -EIO; + } + + mdelay(10); + + /* Set DSI mode */ + ret = mipi_dsi_generic_write((u8[]){ 0xC2, 0x0B }, 2); + if (ret < 0) { + printf("Failed to set DSI mode (%d)\n", ret); + return -EIO; + } + + /* Set tear ON */ + ret = mipi_dsi_dcs_write(MIPI_DCS_SET_TEAR_ON, (u8[]){ 0x0 }, 1); + if (ret < 0) { + printf("Failed to set tear ON (%d)\n", ret); + return -EIO; + } + + /* Set tear scanline */ + ret = mipi_dsi_generic_write((u8[]){ MIPI_DCS_SET_TEAR_SCANLINE, 0x3, 0x80 }, 3); + if (ret < 0) { + printf("Failed to set tear scanline (%d)\n", ret); + return -EIO; + } + + /* Set pixel format */ + ret = mipi_dsi_dcs_write(MIPI_DCS_SET_PIXEL_FORMAT, &color_format, 1); + if (ret < 0) { + printf("Failed to set pixel format (%d)\n", ret); + return -EIO; + } + + + /* Set display brightness */ + brightness = 255; /* Max brightness */ + ret = mipi_dsi_dcs_write(MIPI_DCS_SET_DISPLAY_BRIGHTNESS, &brightness, 2); + if (ret < 0) { + printf("Failed to set display brightness (%d)\n", + ret); + return -EIO; + } + + /* Exit sleep mode */ + ret = mipi_dsi_dcs_write(MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); + if (ret < 0) { + printf("Failed to exit sleep mode (%d)\n", ret); + return -EIO; + } + + mdelay(5); + + ret = mipi_dsi_dcs_write(MIPI_DCS_SET_DISPLAY_ON, NULL, 0); + if (ret < 0) { + printf("Failed to set display ON (%d)\n", ret); + return -EIO; + } + + return 0; +} + +static struct mipi_dsi_client_driver rm67191_drv = { + .name = "RM67191_OLED", + .dsi_client_setup = rm67191_lcd_setup, +}; + +void rm67191_init(void) +{ + imx_mipi_dsi_bridge_add_client_driver(&rm67191_drv); +} diff --git a/include/mipi_display.h b/include/mipi_display.h index ddcc8ca731..1554ef70c7 100644 --- a/include/mipi_display.h +++ b/include/mipi_display.h @@ -115,6 +115,7 @@ enum { MIPI_DCS_READ_MEMORY_CONTINUE = 0x3E, MIPI_DCS_SET_TEAR_SCANLINE = 0x44, MIPI_DCS_GET_SCANLINE = 0x45, + MIPI_DCS_SET_DISPLAY_BRIGHTNESS = 0x51, /* MIPI DCS 1.3 */ MIPI_DCS_READ_DDB_START = 0xA1, MIPI_DCS_READ_DDB_CONTINUE = 0xA8, }; diff --git a/include/mipi_dsi_panel.h b/include/mipi_dsi_panel.h index d46ea4bec7..5b0d9c1c2c 100644 --- a/include/mipi_dsi_panel.h +++ b/include/mipi_dsi_panel.h @@ -9,5 +9,6 @@ #define __MIPI_DSI_PANEL_H void hx8363_init(void); +void rm67191_init(void); #endif diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 28141640c0..099d76041c 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -2559,6 +2559,7 @@ CONFIG_REVISION_TAG CONFIG_RFSPART CONFIG_RGMII CONFIG_RIO +CONFIG_RM67191 CONFIG_RMII CONFIG_RMOBILE_BOARD_STRING CONFIG_RMSTP0_ENA |