Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) STMicroelectronics SA 2017
0004  *
0005  * Authors: Philippe Cornu <philippe.cornu@st.com>
0006  *          Yannick Fertre <yannick.fertre@st.com>
0007  */
0008 
0009 #include <linux/delay.h>
0010 #include <linux/gpio/consumer.h>
0011 #include <linux/mod_devicetable.h>
0012 #include <linux/module.h>
0013 #include <linux/regulator/consumer.h>
0014 
0015 #include <video/mipi_display.h>
0016 
0017 #include <drm/drm_mipi_dsi.h>
0018 #include <drm/drm_modes.h>
0019 #include <drm/drm_panel.h>
0020 
0021 /*** Manufacturer Command Set ***/
0022 #define MCS_CMD_MODE_SW     0xFE /* CMD Mode Switch */
0023 #define MCS_CMD1_UCS        0x00 /* User Command Set (UCS = CMD1) */
0024 #define MCS_CMD2_P0     0x01 /* Manufacture Command Set Page0 (CMD2 P0) */
0025 #define MCS_CMD2_P1     0x02 /* Manufacture Command Set Page1 (CMD2 P1) */
0026 #define MCS_CMD2_P2     0x03 /* Manufacture Command Set Page2 (CMD2 P2) */
0027 #define MCS_CMD2_P3     0x04 /* Manufacture Command Set Page3 (CMD2 P3) */
0028 
0029 /* CMD2 P0 commands (Display Options and Power) */
0030 #define MCS_STBCTR      0x12 /* TE1 Output Setting Zig-Zag Connection */
0031 #define MCS_SGOPCTR     0x16 /* Source Bias Current */
0032 #define MCS_SDCTR       0x1A /* Source Output Delay Time */
0033 #define MCS_INVCTR      0x1B /* Inversion Type */
0034 #define MCS_EXT_PWR_IC      0x24 /* External PWR IC Control */
0035 #define MCS_SETAVDD     0x27 /* PFM Control for AVDD Output */
0036 #define MCS_SETAVEE     0x29 /* PFM Control for AVEE Output */
0037 #define MCS_BT2CTR      0x2B /* DDVDL Charge Pump Control */
0038 #define MCS_BT3CTR      0x2F /* VGH Charge Pump Control */
0039 #define MCS_BT4CTR      0x34 /* VGL Charge Pump Control */
0040 #define MCS_VCMCTR      0x46 /* VCOM Output Level Control */
0041 #define MCS_SETVGN      0x52 /* VG M/S N Control */
0042 #define MCS_SETVGP      0x54 /* VG M/S P Control */
0043 #define MCS_SW_CTRL     0x5F /* Interface Control for PFM and MIPI */
0044 
0045 /* CMD2 P2 commands (GOA Timing Control) - no description in datasheet */
0046 #define GOA_VSTV1       0x00
0047 #define GOA_VSTV2       0x07
0048 #define GOA_VCLK1       0x0E
0049 #define GOA_VCLK2       0x17
0050 #define GOA_VCLK_OPT1       0x20
0051 #define GOA_BICLK1      0x2A
0052 #define GOA_BICLK2      0x37
0053 #define GOA_BICLK3      0x44
0054 #define GOA_BICLK4      0x4F
0055 #define GOA_BICLK_OPT1      0x5B
0056 #define GOA_BICLK_OPT2      0x60
0057 #define MCS_GOA_GPO1        0x6D
0058 #define MCS_GOA_GPO2        0x71
0059 #define MCS_GOA_EQ      0x74
0060 #define MCS_GOA_CLK_GALLON  0x7C
0061 #define MCS_GOA_FS_SEL0     0x7E
0062 #define MCS_GOA_FS_SEL1     0x87
0063 #define MCS_GOA_FS_SEL2     0x91
0064 #define MCS_GOA_FS_SEL3     0x9B
0065 #define MCS_GOA_BS_SEL0     0xAC
0066 #define MCS_GOA_BS_SEL1     0xB5
0067 #define MCS_GOA_BS_SEL2     0xBF
0068 #define MCS_GOA_BS_SEL3     0xC9
0069 #define MCS_GOA_BS_SEL4     0xD3
0070 
0071 /* CMD2 P3 commands (Gamma) */
0072 #define MCS_GAMMA_VP        0x60 /* Gamma VP1~VP16 */
0073 #define MCS_GAMMA_VN        0x70 /* Gamma VN1~VN16 */
0074 
0075 struct rm68200 {
0076     struct device *dev;
0077     struct drm_panel panel;
0078     struct gpio_desc *reset_gpio;
0079     struct regulator *supply;
0080     bool prepared;
0081     bool enabled;
0082 };
0083 
0084 static const struct drm_display_mode default_mode = {
0085     .clock = 54000,
0086     .hdisplay = 720,
0087     .hsync_start = 720 + 48,
0088     .hsync_end = 720 + 48 + 9,
0089     .htotal = 720 + 48 + 9 + 48,
0090     .vdisplay = 1280,
0091     .vsync_start = 1280 + 12,
0092     .vsync_end = 1280 + 12 + 5,
0093     .vtotal = 1280 + 12 + 5 + 12,
0094     .flags = 0,
0095     .width_mm = 68,
0096     .height_mm = 122,
0097 };
0098 
0099 static inline struct rm68200 *panel_to_rm68200(struct drm_panel *panel)
0100 {
0101     return container_of(panel, struct rm68200, panel);
0102 }
0103 
0104 static void rm68200_dcs_write_buf(struct rm68200 *ctx, const void *data,
0105                   size_t len)
0106 {
0107     struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
0108     int err;
0109 
0110     err = mipi_dsi_dcs_write_buffer(dsi, data, len);
0111     if (err < 0)
0112         dev_err_ratelimited(ctx->dev, "MIPI DSI DCS write buffer failed: %d\n", err);
0113 }
0114 
0115 static void rm68200_dcs_write_cmd(struct rm68200 *ctx, u8 cmd, u8 value)
0116 {
0117     struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
0118     int err;
0119 
0120     err = mipi_dsi_dcs_write(dsi, cmd, &value, 1);
0121     if (err < 0)
0122         dev_err_ratelimited(ctx->dev, "MIPI DSI DCS write failed: %d\n", err);
0123 }
0124 
0125 #define dcs_write_seq(ctx, seq...)              \
0126 ({                              \
0127     static const u8 d[] = { seq };              \
0128                                 \
0129     rm68200_dcs_write_buf(ctx, d, ARRAY_SIZE(d));       \
0130 })
0131 
0132 /*
0133  * This panel is not able to auto-increment all cmd addresses so for some of
0134  * them, we need to send them one by one...
0135  */
0136 #define dcs_write_cmd_seq(ctx, cmd, seq...)         \
0137 ({                              \
0138     static const u8 d[] = { seq };              \
0139     unsigned int i;                     \
0140                                 \
0141     for (i = 0; i < ARRAY_SIZE(d) ; i++)            \
0142         rm68200_dcs_write_cmd(ctx, cmd + i, d[i]);  \
0143 })
0144 
0145 static void rm68200_init_sequence(struct rm68200 *ctx)
0146 {
0147     /* Enter CMD2 with page 0 */
0148     dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD2_P0);
0149     dcs_write_cmd_seq(ctx, MCS_EXT_PWR_IC, 0xC0, 0x53, 0x00);
0150     dcs_write_seq(ctx, MCS_BT2CTR, 0xE5);
0151     dcs_write_seq(ctx, MCS_SETAVDD, 0x0A);
0152     dcs_write_seq(ctx, MCS_SETAVEE, 0x0A);
0153     dcs_write_seq(ctx, MCS_SGOPCTR, 0x52);
0154     dcs_write_seq(ctx, MCS_BT3CTR, 0x53);
0155     dcs_write_seq(ctx, MCS_BT4CTR, 0x5A);
0156     dcs_write_seq(ctx, MCS_INVCTR, 0x00);
0157     dcs_write_seq(ctx, MCS_STBCTR, 0x0A);
0158     dcs_write_seq(ctx, MCS_SDCTR, 0x06);
0159     dcs_write_seq(ctx, MCS_VCMCTR, 0x56);
0160     dcs_write_seq(ctx, MCS_SETVGN, 0xA0, 0x00);
0161     dcs_write_seq(ctx, MCS_SETVGP, 0xA0, 0x00);
0162     dcs_write_seq(ctx, MCS_SW_CTRL, 0x11); /* 2 data lanes, see doc */
0163 
0164     dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD2_P2);
0165     dcs_write_seq(ctx, GOA_VSTV1, 0x05);
0166     dcs_write_seq(ctx, 0x02, 0x0B);
0167     dcs_write_seq(ctx, 0x03, 0x0F);
0168     dcs_write_seq(ctx, 0x04, 0x7D, 0x00, 0x50);
0169     dcs_write_cmd_seq(ctx, GOA_VSTV2, 0x05, 0x16, 0x0D, 0x11, 0x7D, 0x00,
0170               0x50);
0171     dcs_write_cmd_seq(ctx, GOA_VCLK1, 0x07, 0x08, 0x01, 0x02, 0x00, 0x7D,
0172               0x00, 0x85, 0x08);
0173     dcs_write_cmd_seq(ctx, GOA_VCLK2, 0x03, 0x04, 0x05, 0x06, 0x00, 0x7D,
0174               0x00, 0x85, 0x08);
0175     dcs_write_seq(ctx, GOA_VCLK_OPT1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0176               0x00, 0x00, 0x00, 0x00);
0177     dcs_write_cmd_seq(ctx, GOA_BICLK1, 0x07, 0x08);
0178     dcs_write_seq(ctx, 0x2D, 0x01);
0179     dcs_write_seq(ctx, 0x2F, 0x02, 0x00, 0x40, 0x05, 0x08, 0x54, 0x7D,
0180               0x00);
0181     dcs_write_cmd_seq(ctx, GOA_BICLK2, 0x03, 0x04, 0x05, 0x06, 0x00);
0182     dcs_write_seq(ctx, 0x3D, 0x40);
0183     dcs_write_seq(ctx, 0x3F, 0x05, 0x08, 0x54, 0x7D, 0x00);
0184     dcs_write_seq(ctx, GOA_BICLK3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0185               0x00, 0x00, 0x00, 0x00, 0x00);
0186     dcs_write_seq(ctx, GOA_BICLK4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0187               0x00, 0x00);
0188     dcs_write_seq(ctx, 0x58, 0x00, 0x00, 0x00);
0189     dcs_write_seq(ctx, GOA_BICLK_OPT1, 0x00, 0x00, 0x00, 0x00, 0x00);
0190     dcs_write_seq(ctx, GOA_BICLK_OPT2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0191               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
0192     dcs_write_seq(ctx, MCS_GOA_GPO1, 0x00, 0x00, 0x00, 0x00);
0193     dcs_write_seq(ctx, MCS_GOA_GPO2, 0x00, 0x20, 0x00);
0194     dcs_write_seq(ctx, MCS_GOA_EQ, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0195               0x00, 0x00);
0196     dcs_write_seq(ctx, MCS_GOA_CLK_GALLON, 0x00, 0x00);
0197     dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL0, 0xBF, 0x02, 0x06, 0x14, 0x10,
0198               0x16, 0x12, 0x08, 0x3F);
0199     dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL1, 0x3F, 0x3F, 0x3F, 0x3F, 0x0C,
0200               0x0A, 0x0E, 0x3F, 0x3F, 0x00);
0201     dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL2, 0x04, 0x3F, 0x3F, 0x3F, 0x3F,
0202               0x05, 0x01, 0x3F, 0x3F, 0x0F);
0203     dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL3, 0x0B, 0x0D, 0x3F, 0x3F, 0x3F,
0204               0x3F);
0205     dcs_write_cmd_seq(ctx, 0xA2, 0x3F, 0x09, 0x13, 0x17, 0x11, 0x15);
0206     dcs_write_cmd_seq(ctx, 0xA9, 0x07, 0x03, 0x3F);
0207     dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL0, 0x3F, 0x05, 0x01, 0x17, 0x13,
0208               0x15, 0x11, 0x0F, 0x3F);
0209     dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL1, 0x3F, 0x3F, 0x3F, 0x3F, 0x0B,
0210               0x0D, 0x09, 0x3F, 0x3F, 0x07);
0211     dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL2, 0x03, 0x3F, 0x3F, 0x3F, 0x3F,
0212               0x02, 0x06, 0x3F, 0x3F, 0x08);
0213     dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL3, 0x0C, 0x0A, 0x3F, 0x3F, 0x3F,
0214               0x3F, 0x3F, 0x0E, 0x10, 0x14);
0215     dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL4, 0x12, 0x16, 0x00, 0x04, 0x3F);
0216     dcs_write_seq(ctx, 0xDC, 0x02);
0217     dcs_write_seq(ctx, 0xDE, 0x12);
0218 
0219     dcs_write_seq(ctx, MCS_CMD_MODE_SW, 0x0E); /* No documentation */
0220     dcs_write_seq(ctx, 0x01, 0x75);
0221 
0222     dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD2_P3);
0223     dcs_write_cmd_seq(ctx, MCS_GAMMA_VP, 0x00, 0x0C, 0x12, 0x0E, 0x06,
0224               0x12, 0x0E, 0x0B, 0x15, 0x0B, 0x10, 0x07, 0x0F,
0225               0x12, 0x0C, 0x00);
0226     dcs_write_cmd_seq(ctx, MCS_GAMMA_VN, 0x00, 0x0C, 0x12, 0x0E, 0x06,
0227               0x12, 0x0E, 0x0B, 0x15, 0x0B, 0x10, 0x07, 0x0F,
0228               0x12, 0x0C, 0x00);
0229 
0230     /* Exit CMD2 */
0231     dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD1_UCS);
0232 }
0233 
0234 static int rm68200_disable(struct drm_panel *panel)
0235 {
0236     struct rm68200 *ctx = panel_to_rm68200(panel);
0237 
0238     if (!ctx->enabled)
0239         return 0;
0240 
0241     ctx->enabled = false;
0242 
0243     return 0;
0244 }
0245 
0246 static int rm68200_unprepare(struct drm_panel *panel)
0247 {
0248     struct rm68200 *ctx = panel_to_rm68200(panel);
0249     struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
0250     int ret;
0251 
0252     if (!ctx->prepared)
0253         return 0;
0254 
0255     ret = mipi_dsi_dcs_set_display_off(dsi);
0256     if (ret)
0257         dev_warn(panel->dev, "failed to set display off: %d\n", ret);
0258 
0259     ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
0260     if (ret)
0261         dev_warn(panel->dev, "failed to enter sleep mode: %d\n", ret);
0262 
0263     msleep(120);
0264 
0265     if (ctx->reset_gpio) {
0266         gpiod_set_value_cansleep(ctx->reset_gpio, 1);
0267         msleep(20);
0268     }
0269 
0270     regulator_disable(ctx->supply);
0271 
0272     ctx->prepared = false;
0273 
0274     return 0;
0275 }
0276 
0277 static int rm68200_prepare(struct drm_panel *panel)
0278 {
0279     struct rm68200 *ctx = panel_to_rm68200(panel);
0280     struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
0281     int ret;
0282 
0283     if (ctx->prepared)
0284         return 0;
0285 
0286     ret = regulator_enable(ctx->supply);
0287     if (ret < 0) {
0288         dev_err(ctx->dev, "failed to enable supply: %d\n", ret);
0289         return ret;
0290     }
0291 
0292     if (ctx->reset_gpio) {
0293         gpiod_set_value_cansleep(ctx->reset_gpio, 1);
0294         msleep(20);
0295         gpiod_set_value_cansleep(ctx->reset_gpio, 0);
0296         msleep(100);
0297     }
0298 
0299     rm68200_init_sequence(ctx);
0300 
0301     ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
0302     if (ret)
0303         return ret;
0304 
0305     msleep(125);
0306 
0307     ret = mipi_dsi_dcs_set_display_on(dsi);
0308     if (ret)
0309         return ret;
0310 
0311     msleep(20);
0312 
0313     ctx->prepared = true;
0314 
0315     return 0;
0316 }
0317 
0318 static int rm68200_enable(struct drm_panel *panel)
0319 {
0320     struct rm68200 *ctx = panel_to_rm68200(panel);
0321 
0322     if (ctx->enabled)
0323         return 0;
0324 
0325     ctx->enabled = true;
0326 
0327     return 0;
0328 }
0329 
0330 static int rm68200_get_modes(struct drm_panel *panel,
0331                  struct drm_connector *connector)
0332 {
0333     struct drm_display_mode *mode;
0334 
0335     mode = drm_mode_duplicate(connector->dev, &default_mode);
0336     if (!mode) {
0337         dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
0338             default_mode.hdisplay, default_mode.vdisplay,
0339             drm_mode_vrefresh(&default_mode));
0340         return -ENOMEM;
0341     }
0342 
0343     drm_mode_set_name(mode);
0344 
0345     mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
0346     drm_mode_probed_add(connector, mode);
0347 
0348     connector->display_info.width_mm = mode->width_mm;
0349     connector->display_info.height_mm = mode->height_mm;
0350 
0351     return 1;
0352 }
0353 
0354 static const struct drm_panel_funcs rm68200_drm_funcs = {
0355     .disable = rm68200_disable,
0356     .unprepare = rm68200_unprepare,
0357     .prepare = rm68200_prepare,
0358     .enable = rm68200_enable,
0359     .get_modes = rm68200_get_modes,
0360 };
0361 
0362 static int rm68200_probe(struct mipi_dsi_device *dsi)
0363 {
0364     struct device *dev = &dsi->dev;
0365     struct rm68200 *ctx;
0366     int ret;
0367 
0368     ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
0369     if (!ctx)
0370         return -ENOMEM;
0371 
0372     ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
0373     if (IS_ERR(ctx->reset_gpio)) {
0374         ret = PTR_ERR(ctx->reset_gpio);
0375         dev_err(dev, "cannot get reset GPIO: %d\n", ret);
0376         return ret;
0377     }
0378 
0379     ctx->supply = devm_regulator_get(dev, "power");
0380     if (IS_ERR(ctx->supply)) {
0381         ret = PTR_ERR(ctx->supply);
0382         if (ret != -EPROBE_DEFER)
0383             dev_err(dev, "cannot get regulator: %d\n", ret);
0384         return ret;
0385     }
0386 
0387     mipi_dsi_set_drvdata(dsi, ctx);
0388 
0389     ctx->dev = dev;
0390 
0391     dsi->lanes = 2;
0392     dsi->format = MIPI_DSI_FMT_RGB888;
0393     dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
0394               MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS;
0395 
0396     drm_panel_init(&ctx->panel, dev, &rm68200_drm_funcs,
0397                DRM_MODE_CONNECTOR_DSI);
0398 
0399     ret = drm_panel_of_backlight(&ctx->panel);
0400     if (ret)
0401         return ret;
0402 
0403     drm_panel_add(&ctx->panel);
0404 
0405     ret = mipi_dsi_attach(dsi);
0406     if (ret < 0) {
0407         dev_err(dev, "mipi_dsi_attach() failed: %d\n", ret);
0408         drm_panel_remove(&ctx->panel);
0409         return ret;
0410     }
0411 
0412     return 0;
0413 }
0414 
0415 static int rm68200_remove(struct mipi_dsi_device *dsi)
0416 {
0417     struct rm68200 *ctx = mipi_dsi_get_drvdata(dsi);
0418 
0419     mipi_dsi_detach(dsi);
0420     drm_panel_remove(&ctx->panel);
0421 
0422     return 0;
0423 }
0424 
0425 static const struct of_device_id raydium_rm68200_of_match[] = {
0426     { .compatible = "raydium,rm68200" },
0427     { }
0428 };
0429 MODULE_DEVICE_TABLE(of, raydium_rm68200_of_match);
0430 
0431 static struct mipi_dsi_driver raydium_rm68200_driver = {
0432     .probe = rm68200_probe,
0433     .remove = rm68200_remove,
0434     .driver = {
0435         .name = "panel-raydium-rm68200",
0436         .of_match_table = raydium_rm68200_of_match,
0437     },
0438 };
0439 module_mipi_dsi_driver(raydium_rm68200_driver);
0440 
0441 MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>");
0442 MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
0443 MODULE_DESCRIPTION("DRM Driver for Raydium RM68200 MIPI DSI panel");
0444 MODULE_LICENSE("GPL v2");