0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/backlight.h>
0010 #include <linux/delay.h>
0011 #include <linux/gpio/consumer.h>
0012 #include <linux/jiffies.h>
0013 #include <linux/module.h>
0014 #include <linux/of_device.h>
0015 #include <linux/regulator/consumer.h>
0016
0017 #include <drm/drm_connector.h>
0018 #include <drm/drm_mipi_dsi.h>
0019 #include <drm/drm_modes.h>
0020 #include <drm/drm_panel.h>
0021
0022 #include <video/mipi_display.h>
0023
0024 #define DCS_GET_ID1 0xda
0025 #define DCS_GET_ID2 0xdb
0026 #define DCS_GET_ID3 0xdc
0027
0028 #define DCS_REGULATOR_SUPPLY_NUM 2
0029
0030 static const struct of_device_id dsicm_of_match[];
0031
0032 struct dsic_panel_data {
0033 u32 xres;
0034 u32 yres;
0035 u32 refresh;
0036 u32 width_mm;
0037 u32 height_mm;
0038 u32 max_hs_rate;
0039 u32 max_lp_rate;
0040 bool te_support;
0041 };
0042
0043 struct panel_drv_data {
0044 struct mipi_dsi_device *dsi;
0045 struct drm_panel panel;
0046 struct drm_display_mode mode;
0047
0048 struct mutex lock;
0049
0050 struct backlight_device *bldev;
0051 struct backlight_device *extbldev;
0052
0053 unsigned long hw_guard_end;
0054
0055
0056 unsigned long hw_guard_wait;
0057
0058 const struct dsic_panel_data *panel_data;
0059
0060 struct gpio_desc *reset_gpio;
0061
0062 struct regulator_bulk_data supplies[DCS_REGULATOR_SUPPLY_NUM];
0063
0064 bool use_dsi_backlight;
0065
0066
0067 bool enabled;
0068
0069 bool intro_printed;
0070 };
0071
0072 static inline struct panel_drv_data *panel_to_ddata(struct drm_panel *panel)
0073 {
0074 return container_of(panel, struct panel_drv_data, panel);
0075 }
0076
0077 static void dsicm_bl_power(struct panel_drv_data *ddata, bool enable)
0078 {
0079 struct backlight_device *backlight;
0080
0081 if (ddata->bldev)
0082 backlight = ddata->bldev;
0083 else if (ddata->extbldev)
0084 backlight = ddata->extbldev;
0085 else
0086 return;
0087
0088 if (enable)
0089 backlight_enable(backlight);
0090 else
0091 backlight_disable(backlight);
0092 }
0093
0094 static void hw_guard_start(struct panel_drv_data *ddata, int guard_msec)
0095 {
0096 ddata->hw_guard_wait = msecs_to_jiffies(guard_msec);
0097 ddata->hw_guard_end = jiffies + ddata->hw_guard_wait;
0098 }
0099
0100 static void hw_guard_wait(struct panel_drv_data *ddata)
0101 {
0102 unsigned long wait = ddata->hw_guard_end - jiffies;
0103
0104 if ((long)wait > 0 && wait <= ddata->hw_guard_wait) {
0105 set_current_state(TASK_UNINTERRUPTIBLE);
0106 schedule_timeout(wait);
0107 }
0108 }
0109
0110 static int dsicm_dcs_read_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 *data)
0111 {
0112 return mipi_dsi_dcs_read(ddata->dsi, dcs_cmd, data, 1);
0113 }
0114
0115 static int dsicm_dcs_write_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 param)
0116 {
0117 return mipi_dsi_dcs_write(ddata->dsi, dcs_cmd, ¶m, 1);
0118 }
0119
0120 static int dsicm_sleep_in(struct panel_drv_data *ddata)
0121
0122 {
0123 int r;
0124
0125 hw_guard_wait(ddata);
0126
0127 r = mipi_dsi_dcs_enter_sleep_mode(ddata->dsi);
0128 if (r)
0129 return r;
0130
0131 hw_guard_start(ddata, 120);
0132
0133 usleep_range(5000, 10000);
0134
0135 return 0;
0136 }
0137
0138 static int dsicm_sleep_out(struct panel_drv_data *ddata)
0139 {
0140 int r;
0141
0142 hw_guard_wait(ddata);
0143
0144 r = mipi_dsi_dcs_exit_sleep_mode(ddata->dsi);
0145 if (r)
0146 return r;
0147
0148 hw_guard_start(ddata, 120);
0149
0150 usleep_range(5000, 10000);
0151
0152 return 0;
0153 }
0154
0155 static int dsicm_get_id(struct panel_drv_data *ddata, u8 *id1, u8 *id2, u8 *id3)
0156 {
0157 int r;
0158
0159 r = dsicm_dcs_read_1(ddata, DCS_GET_ID1, id1);
0160 if (r)
0161 return r;
0162 r = dsicm_dcs_read_1(ddata, DCS_GET_ID2, id2);
0163 if (r)
0164 return r;
0165 r = dsicm_dcs_read_1(ddata, DCS_GET_ID3, id3);
0166 if (r)
0167 return r;
0168
0169 return 0;
0170 }
0171
0172 static int dsicm_set_update_window(struct panel_drv_data *ddata)
0173 {
0174 struct mipi_dsi_device *dsi = ddata->dsi;
0175 int r;
0176
0177 r = mipi_dsi_dcs_set_column_address(dsi, 0, ddata->mode.hdisplay - 1);
0178 if (r < 0)
0179 return r;
0180
0181 r = mipi_dsi_dcs_set_page_address(dsi, 0, ddata->mode.vdisplay - 1);
0182 if (r < 0)
0183 return r;
0184
0185 return 0;
0186 }
0187
0188 static int dsicm_bl_update_status(struct backlight_device *dev)
0189 {
0190 struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
0191 int r = 0;
0192 int level = backlight_get_brightness(dev);
0193
0194 dev_dbg(&ddata->dsi->dev, "update brightness to %d\n", level);
0195
0196 mutex_lock(&ddata->lock);
0197
0198 if (ddata->enabled)
0199 r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
0200 level);
0201
0202 mutex_unlock(&ddata->lock);
0203
0204 return r;
0205 }
0206
0207 static int dsicm_bl_get_intensity(struct backlight_device *dev)
0208 {
0209 return backlight_get_brightness(dev);
0210 }
0211
0212 static const struct backlight_ops dsicm_bl_ops = {
0213 .get_brightness = dsicm_bl_get_intensity,
0214 .update_status = dsicm_bl_update_status,
0215 };
0216
0217 static ssize_t num_dsi_errors_show(struct device *dev,
0218 struct device_attribute *attr, char *buf)
0219 {
0220 struct panel_drv_data *ddata = dev_get_drvdata(dev);
0221 u8 errors = 0;
0222 int r = -ENODEV;
0223
0224 mutex_lock(&ddata->lock);
0225
0226 if (ddata->enabled)
0227 r = dsicm_dcs_read_1(ddata, MIPI_DCS_GET_ERROR_COUNT_ON_DSI, &errors);
0228
0229 mutex_unlock(&ddata->lock);
0230
0231 if (r)
0232 return r;
0233
0234 return sysfs_emit(buf, "%d\n", errors);
0235 }
0236
0237 static ssize_t hw_revision_show(struct device *dev,
0238 struct device_attribute *attr, char *buf)
0239 {
0240 struct panel_drv_data *ddata = dev_get_drvdata(dev);
0241 u8 id1, id2, id3;
0242 int r = -ENODEV;
0243
0244 mutex_lock(&ddata->lock);
0245
0246 if (ddata->enabled)
0247 r = dsicm_get_id(ddata, &id1, &id2, &id3);
0248
0249 mutex_unlock(&ddata->lock);
0250
0251 if (r)
0252 return r;
0253
0254 return sysfs_emit(buf, "%02x.%02x.%02x\n", id1, id2, id3);
0255 }
0256
0257 static DEVICE_ATTR_RO(num_dsi_errors);
0258 static DEVICE_ATTR_RO(hw_revision);
0259
0260 static struct attribute *dsicm_attrs[] = {
0261 &dev_attr_num_dsi_errors.attr,
0262 &dev_attr_hw_revision.attr,
0263 NULL,
0264 };
0265
0266 static const struct attribute_group dsicm_attr_group = {
0267 .attrs = dsicm_attrs,
0268 };
0269
0270 static void dsicm_hw_reset(struct panel_drv_data *ddata)
0271 {
0272 gpiod_set_value(ddata->reset_gpio, 1);
0273 udelay(10);
0274
0275 gpiod_set_value(ddata->reset_gpio, 0);
0276
0277 udelay(10);
0278 gpiod_set_value(ddata->reset_gpio, 1);
0279
0280 usleep_range(5000, 10000);
0281 }
0282
0283 static int dsicm_power_on(struct panel_drv_data *ddata)
0284 {
0285 u8 id1, id2, id3;
0286 int r;
0287
0288 dsicm_hw_reset(ddata);
0289
0290 ddata->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
0291
0292 r = dsicm_sleep_out(ddata);
0293 if (r)
0294 goto err;
0295
0296 r = dsicm_get_id(ddata, &id1, &id2, &id3);
0297 if (r)
0298 goto err;
0299
0300 r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 0xff);
0301 if (r)
0302 goto err;
0303
0304 r = dsicm_dcs_write_1(ddata, MIPI_DCS_WRITE_CONTROL_DISPLAY,
0305 (1<<2) | (1<<5));
0306 if (r)
0307 goto err;
0308
0309 r = mipi_dsi_dcs_set_pixel_format(ddata->dsi, MIPI_DCS_PIXEL_FMT_24BIT);
0310 if (r)
0311 goto err;
0312
0313 r = dsicm_set_update_window(ddata);
0314 if (r)
0315 goto err;
0316
0317 r = mipi_dsi_dcs_set_display_on(ddata->dsi);
0318 if (r)
0319 goto err;
0320
0321 if (ddata->panel_data->te_support) {
0322 r = mipi_dsi_dcs_set_tear_on(ddata->dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
0323 if (r)
0324 goto err;
0325 }
0326
0327
0328 msleep(100);
0329
0330 ddata->enabled = true;
0331
0332 if (!ddata->intro_printed) {
0333 dev_info(&ddata->dsi->dev, "panel revision %02x.%02x.%02x\n",
0334 id1, id2, id3);
0335 ddata->intro_printed = true;
0336 }
0337
0338 ddata->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
0339
0340 return 0;
0341 err:
0342 dev_err(&ddata->dsi->dev, "error while enabling panel, issuing HW reset\n");
0343
0344 dsicm_hw_reset(ddata);
0345
0346 return r;
0347 }
0348
0349 static int dsicm_power_off(struct panel_drv_data *ddata)
0350 {
0351 int r;
0352
0353 ddata->enabled = false;
0354
0355 r = mipi_dsi_dcs_set_display_off(ddata->dsi);
0356 if (!r)
0357 r = dsicm_sleep_in(ddata);
0358
0359 if (r) {
0360 dev_err(&ddata->dsi->dev,
0361 "error disabling panel, issuing HW reset\n");
0362 dsicm_hw_reset(ddata);
0363 }
0364
0365 return r;
0366 }
0367
0368 static int dsicm_prepare(struct drm_panel *panel)
0369 {
0370 struct panel_drv_data *ddata = panel_to_ddata(panel);
0371 int r;
0372
0373 r = regulator_bulk_enable(ARRAY_SIZE(ddata->supplies), ddata->supplies);
0374 if (r)
0375 dev_err(&ddata->dsi->dev, "failed to enable supplies: %d\n", r);
0376
0377 return r;
0378 }
0379
0380 static int dsicm_enable(struct drm_panel *panel)
0381 {
0382 struct panel_drv_data *ddata = panel_to_ddata(panel);
0383 int r;
0384
0385 mutex_lock(&ddata->lock);
0386
0387 r = dsicm_power_on(ddata);
0388 if (r)
0389 goto err;
0390
0391 mutex_unlock(&ddata->lock);
0392
0393 dsicm_bl_power(ddata, true);
0394
0395 return 0;
0396 err:
0397 dev_err(&ddata->dsi->dev, "enable failed (%d)\n", r);
0398 mutex_unlock(&ddata->lock);
0399 return r;
0400 }
0401
0402 static int dsicm_unprepare(struct drm_panel *panel)
0403 {
0404 struct panel_drv_data *ddata = panel_to_ddata(panel);
0405 int r;
0406
0407 r = regulator_bulk_disable(ARRAY_SIZE(ddata->supplies), ddata->supplies);
0408 if (r)
0409 dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", r);
0410
0411 return r;
0412 }
0413
0414 static int dsicm_disable(struct drm_panel *panel)
0415 {
0416 struct panel_drv_data *ddata = panel_to_ddata(panel);
0417 int r;
0418
0419 dsicm_bl_power(ddata, false);
0420
0421 mutex_lock(&ddata->lock);
0422
0423 r = dsicm_power_off(ddata);
0424
0425 mutex_unlock(&ddata->lock);
0426
0427 return r;
0428 }
0429
0430 static int dsicm_get_modes(struct drm_panel *panel,
0431 struct drm_connector *connector)
0432 {
0433 struct panel_drv_data *ddata = panel_to_ddata(panel);
0434 struct drm_display_mode *mode;
0435
0436 mode = drm_mode_duplicate(connector->dev, &ddata->mode);
0437 if (!mode) {
0438 dev_err(&ddata->dsi->dev, "failed to add mode %ux%ux@%u kHz\n",
0439 ddata->mode.hdisplay, ddata->mode.vdisplay,
0440 ddata->mode.clock);
0441 return -ENOMEM;
0442 }
0443
0444 connector->display_info.width_mm = ddata->panel_data->width_mm;
0445 connector->display_info.height_mm = ddata->panel_data->height_mm;
0446
0447 drm_mode_probed_add(connector, mode);
0448
0449 return 1;
0450 }
0451
0452 static const struct drm_panel_funcs dsicm_panel_funcs = {
0453 .unprepare = dsicm_unprepare,
0454 .disable = dsicm_disable,
0455 .prepare = dsicm_prepare,
0456 .enable = dsicm_enable,
0457 .get_modes = dsicm_get_modes,
0458 };
0459
0460 static int dsicm_probe_of(struct mipi_dsi_device *dsi)
0461 {
0462 struct backlight_device *backlight;
0463 struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
0464 int err;
0465 struct drm_display_mode *mode = &ddata->mode;
0466
0467 ddata->reset_gpio = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
0468 if (IS_ERR(ddata->reset_gpio)) {
0469 err = PTR_ERR(ddata->reset_gpio);
0470 dev_err(&dsi->dev, "reset gpio request failed: %d", err);
0471 return err;
0472 }
0473
0474 mode->hdisplay = mode->hsync_start = mode->hsync_end = mode->htotal =
0475 ddata->panel_data->xres;
0476 mode->vdisplay = mode->vsync_start = mode->vsync_end = mode->vtotal =
0477 ddata->panel_data->yres;
0478 mode->clock = ddata->panel_data->xres * ddata->panel_data->yres *
0479 ddata->panel_data->refresh / 1000;
0480 mode->width_mm = ddata->panel_data->width_mm;
0481 mode->height_mm = ddata->panel_data->height_mm;
0482 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
0483 drm_mode_set_name(mode);
0484
0485 ddata->supplies[0].supply = "vpnl";
0486 ddata->supplies[1].supply = "vddi";
0487 err = devm_regulator_bulk_get(&dsi->dev, ARRAY_SIZE(ddata->supplies),
0488 ddata->supplies);
0489 if (err)
0490 return err;
0491
0492 backlight = devm_of_find_backlight(&dsi->dev);
0493 if (IS_ERR(backlight))
0494 return PTR_ERR(backlight);
0495
0496
0497 if (backlight)
0498 ddata->extbldev = backlight;
0499 else
0500 ddata->use_dsi_backlight = true;
0501
0502 return 0;
0503 }
0504
0505 static int dsicm_probe(struct mipi_dsi_device *dsi)
0506 {
0507 struct panel_drv_data *ddata;
0508 struct backlight_device *bldev = NULL;
0509 struct device *dev = &dsi->dev;
0510 int r;
0511
0512 dev_dbg(dev, "probe\n");
0513
0514 ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
0515 if (!ddata)
0516 return -ENOMEM;
0517
0518 mipi_dsi_set_drvdata(dsi, ddata);
0519 ddata->dsi = dsi;
0520
0521 ddata->panel_data = of_device_get_match_data(dev);
0522 if (!ddata->panel_data)
0523 return -ENODEV;
0524
0525 r = dsicm_probe_of(dsi);
0526 if (r)
0527 return r;
0528
0529 mutex_init(&ddata->lock);
0530
0531 dsicm_hw_reset(ddata);
0532
0533 drm_panel_init(&ddata->panel, dev, &dsicm_panel_funcs,
0534 DRM_MODE_CONNECTOR_DSI);
0535
0536 if (ddata->use_dsi_backlight) {
0537 struct backlight_properties props = { 0 };
0538 props.max_brightness = 255;
0539 props.type = BACKLIGHT_RAW;
0540
0541 bldev = devm_backlight_device_register(dev, dev_name(dev),
0542 dev, ddata, &dsicm_bl_ops, &props);
0543 if (IS_ERR(bldev)) {
0544 r = PTR_ERR(bldev);
0545 goto err_bl;
0546 }
0547
0548 ddata->bldev = bldev;
0549 }
0550
0551 r = sysfs_create_group(&dev->kobj, &dsicm_attr_group);
0552 if (r) {
0553 dev_err(dev, "failed to create sysfs files\n");
0554 goto err_bl;
0555 }
0556
0557 dsi->lanes = 2;
0558 dsi->format = MIPI_DSI_FMT_RGB888;
0559 dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS |
0560 MIPI_DSI_MODE_NO_EOT_PACKET;
0561 dsi->hs_rate = ddata->panel_data->max_hs_rate;
0562 dsi->lp_rate = ddata->panel_data->max_lp_rate;
0563
0564 drm_panel_add(&ddata->panel);
0565
0566 r = mipi_dsi_attach(dsi);
0567 if (r < 0)
0568 goto err_dsi_attach;
0569
0570 return 0;
0571
0572 err_dsi_attach:
0573 drm_panel_remove(&ddata->panel);
0574 sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
0575 err_bl:
0576 if (ddata->extbldev)
0577 put_device(&ddata->extbldev->dev);
0578
0579 return r;
0580 }
0581
0582 static int dsicm_remove(struct mipi_dsi_device *dsi)
0583 {
0584 struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
0585
0586 dev_dbg(&dsi->dev, "remove\n");
0587
0588 mipi_dsi_detach(dsi);
0589
0590 drm_panel_remove(&ddata->panel);
0591
0592 sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
0593
0594 if (ddata->extbldev)
0595 put_device(&ddata->extbldev->dev);
0596
0597 return 0;
0598 }
0599
0600 static const struct dsic_panel_data taal_data = {
0601 .xres = 864,
0602 .yres = 480,
0603 .refresh = 60,
0604 .width_mm = 0,
0605 .height_mm = 0,
0606 .max_hs_rate = 300000000,
0607 .max_lp_rate = 10000000,
0608 .te_support = true,
0609 };
0610
0611 static const struct dsic_panel_data himalaya_data = {
0612 .xres = 480,
0613 .yres = 864,
0614 .refresh = 60,
0615 .width_mm = 49,
0616 .height_mm = 88,
0617 .max_hs_rate = 300000000,
0618 .max_lp_rate = 10000000,
0619 .te_support = false,
0620 };
0621
0622 static const struct dsic_panel_data droid4_data = {
0623 .xres = 540,
0624 .yres = 960,
0625 .refresh = 60,
0626 .width_mm = 50,
0627 .height_mm = 89,
0628 .max_hs_rate = 300000000,
0629 .max_lp_rate = 10000000,
0630 .te_support = false,
0631 };
0632
0633 static const struct of_device_id dsicm_of_match[] = {
0634 { .compatible = "tpo,taal", .data = &taal_data },
0635 { .compatible = "nokia,himalaya", &himalaya_data },
0636 { .compatible = "motorola,droid4-panel", &droid4_data },
0637 {},
0638 };
0639
0640 MODULE_DEVICE_TABLE(of, dsicm_of_match);
0641
0642 static struct mipi_dsi_driver dsicm_driver = {
0643 .probe = dsicm_probe,
0644 .remove = dsicm_remove,
0645 .driver = {
0646 .name = "panel-dsi-cm",
0647 .of_match_table = dsicm_of_match,
0648 },
0649 };
0650 module_mipi_dsi_driver(dsicm_driver);
0651
0652 MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
0653 MODULE_DESCRIPTION("Generic DSI Command Mode Panel Driver");
0654 MODULE_LICENSE("GPL");