0001
0002
0003
0004
0005
0006
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
0022 #define MCS_CMD_MODE_SW 0xFE
0023 #define MCS_CMD1_UCS 0x00
0024 #define MCS_CMD2_P0 0x01
0025 #define MCS_CMD2_P1 0x02
0026 #define MCS_CMD2_P2 0x03
0027 #define MCS_CMD2_P3 0x04
0028
0029
0030 #define MCS_STBCTR 0x12
0031 #define MCS_SGOPCTR 0x16
0032 #define MCS_SDCTR 0x1A
0033 #define MCS_INVCTR 0x1B
0034 #define MCS_EXT_PWR_IC 0x24
0035 #define MCS_SETAVDD 0x27
0036 #define MCS_SETAVEE 0x29
0037 #define MCS_BT2CTR 0x2B
0038 #define MCS_BT3CTR 0x2F
0039 #define MCS_BT4CTR 0x34
0040 #define MCS_VCMCTR 0x46
0041 #define MCS_SETVGN 0x52
0042 #define MCS_SETVGP 0x54
0043 #define MCS_SW_CTRL 0x5F
0044
0045
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
0072 #define MCS_GAMMA_VP 0x60
0073 #define MCS_GAMMA_VN 0x70
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
0134
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
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);
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);
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
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");