Lines Matching +full:panel +full:- +full:dsi
1 // SPDX-License-Identifier: GPL-2.0
3 * Raydium RM67191 MIPI-DSI panel driver
11 #include <linux/media-bus-format.h>
24 /* Panel specific color-format bits */
198 struct drm_panel panel; member
199 struct mipi_dsi_device *dsi; member
226 static inline struct rad_panel *to_rad_panel(struct drm_panel *panel) in to_rad_panel() argument
228 return container_of(panel, struct rad_panel, panel); in to_rad_panel()
231 static int rad_panel_push_cmd_list(struct mipi_dsi_device *dsi) in rad_panel_push_cmd_list() argument
239 u8 buffer[2] = { entry->cmd, entry->param }; in rad_panel_push_cmd_list()
241 ret = mipi_dsi_generic_write(dsi, &buffer, sizeof(buffer)); in rad_panel_push_cmd_list()
264 static int rad_panel_prepare(struct drm_panel *panel) in rad_panel_prepare() argument
266 struct rad_panel *rad = to_rad_panel(panel); in rad_panel_prepare()
269 ret = regulator_bulk_enable(rad->num_supplies, rad->supplies); in rad_panel_prepare()
273 if (rad->reset) { in rad_panel_prepare()
274 gpiod_set_value_cansleep(rad->reset, 1); in rad_panel_prepare()
276 gpiod_set_value_cansleep(rad->reset, 0); in rad_panel_prepare()
280 rad->prepared = true; in rad_panel_prepare()
285 static int rad_panel_unprepare(struct drm_panel *panel) in rad_panel_unprepare() argument
287 struct rad_panel *rad = to_rad_panel(panel); in rad_panel_unprepare()
295 if (rad->reset) { in rad_panel_unprepare()
296 gpiod_set_value_cansleep(rad->reset, 1); in rad_panel_unprepare()
298 gpiod_set_value_cansleep(rad->reset, 0); in rad_panel_unprepare()
301 ret = regulator_bulk_disable(rad->num_supplies, rad->supplies); in rad_panel_unprepare()
305 rad->prepared = false; in rad_panel_unprepare()
310 static int rad_panel_enable(struct drm_panel *panel) in rad_panel_enable() argument
312 struct rad_panel *rad = to_rad_panel(panel); in rad_panel_enable()
313 struct mipi_dsi_device *dsi = rad->dsi; in rad_panel_enable() local
314 struct device *dev = &dsi->dev; in rad_panel_enable()
315 int color_format = color_format_from_dsi_format(dsi->format); in rad_panel_enable()
318 dsi->mode_flags |= MIPI_DSI_MODE_LPM; in rad_panel_enable()
320 ret = rad_panel_push_cmd_list(dsi); in rad_panel_enable()
327 ret = mipi_dsi_generic_write(dsi, (u8[]){ WRMAUCCTR, 0x00 }, 2); in rad_panel_enable()
332 ret = mipi_dsi_dcs_soft_reset(dsi); in rad_panel_enable()
340 /* Set DSI mode */ in rad_panel_enable()
341 ret = mipi_dsi_generic_write(dsi, (u8[]){ 0xC2, 0x0B }, 2); in rad_panel_enable()
343 dev_err(dev, "Failed to set DSI mode (%d)\n", ret); in rad_panel_enable()
347 ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); in rad_panel_enable()
353 ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0x380); in rad_panel_enable()
359 ret = mipi_dsi_dcs_set_pixel_format(dsi, color_format); in rad_panel_enable()
366 ret = mipi_dsi_dcs_exit_sleep_mode(dsi); in rad_panel_enable()
374 ret = mipi_dsi_dcs_set_display_on(dsi); in rad_panel_enable()
380 backlight_enable(rad->backlight); in rad_panel_enable()
385 gpiod_set_value_cansleep(rad->reset, 1); in rad_panel_enable()
390 static int rad_panel_disable(struct drm_panel *panel) in rad_panel_disable() argument
392 struct rad_panel *rad = to_rad_panel(panel); in rad_panel_disable()
393 struct mipi_dsi_device *dsi = rad->dsi; in rad_panel_disable() local
394 struct device *dev = &dsi->dev; in rad_panel_disable()
397 dsi->mode_flags |= MIPI_DSI_MODE_LPM; in rad_panel_disable()
399 backlight_disable(rad->backlight); in rad_panel_disable()
403 ret = mipi_dsi_dcs_set_display_off(dsi); in rad_panel_disable()
411 ret = mipi_dsi_dcs_enter_sleep_mode(dsi); in rad_panel_disable()
420 static int rad_panel_get_modes(struct drm_panel *panel, in rad_panel_get_modes() argument
425 mode = drm_mode_duplicate(connector->dev, &default_mode); in rad_panel_get_modes()
427 dev_err(panel->dev, "failed to add mode %ux%u@%u\n", in rad_panel_get_modes()
430 return -ENOMEM; in rad_panel_get_modes()
434 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; in rad_panel_get_modes()
437 connector->display_info.width_mm = mode->width_mm; in rad_panel_get_modes()
438 connector->display_info.height_mm = mode->height_mm; in rad_panel_get_modes()
439 connector->display_info.bus_flags = rad_bus_flags; in rad_panel_get_modes()
441 drm_display_info_set_bus_formats(&connector->display_info, in rad_panel_get_modes()
449 struct mipi_dsi_device *dsi = bl_get_data(bl); in rad_bl_get_brightness() local
450 struct rad_panel *rad = mipi_dsi_get_drvdata(dsi); in rad_bl_get_brightness()
454 if (!rad->prepared) in rad_bl_get_brightness()
457 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; in rad_bl_get_brightness()
459 ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness); in rad_bl_get_brightness()
463 bl->props.brightness = brightness; in rad_bl_get_brightness()
470 struct mipi_dsi_device *dsi = bl_get_data(bl); in rad_bl_update_status() local
471 struct rad_panel *rad = mipi_dsi_get_drvdata(dsi); in rad_bl_update_status()
474 if (!rad->prepared) in rad_bl_update_status()
477 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; in rad_bl_update_status()
479 ret = mipi_dsi_dcs_set_display_brightness(dsi, bl->props.brightness); in rad_bl_update_status()
506 struct device *dev = &rad->dsi->dev; in rad_init_regulators()
509 rad->num_supplies = ARRAY_SIZE(rad_supply_names); in rad_init_regulators()
510 rad->supplies = devm_kcalloc(dev, rad->num_supplies, in rad_init_regulators()
511 sizeof(*rad->supplies), GFP_KERNEL); in rad_init_regulators()
512 if (!rad->supplies) in rad_init_regulators()
513 return -ENOMEM; in rad_init_regulators()
515 for (i = 0; i < rad->num_supplies; i++) in rad_init_regulators()
516 rad->supplies[i].supply = rad_supply_names[i]; in rad_init_regulators()
518 return devm_regulator_bulk_get(dev, rad->num_supplies, rad->supplies); in rad_init_regulators()
521 static int rad_panel_probe(struct mipi_dsi_device *dsi) in rad_panel_probe() argument
523 struct device *dev = &dsi->dev; in rad_panel_probe()
524 struct device_node *np = dev->of_node; in rad_panel_probe()
525 struct rad_panel *panel; in rad_panel_probe() local
530 panel = devm_kzalloc(&dsi->dev, sizeof(*panel), GFP_KERNEL); in rad_panel_probe()
531 if (!panel) in rad_panel_probe()
532 return -ENOMEM; in rad_panel_probe()
534 mipi_dsi_set_drvdata(dsi, panel); in rad_panel_probe()
536 panel->dsi = dsi; in rad_panel_probe()
538 dsi->format = MIPI_DSI_FMT_RGB888; in rad_panel_probe()
539 dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO; in rad_panel_probe()
541 ret = of_property_read_u32(np, "video-mode", &video_mode); in rad_panel_probe()
546 dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_BURST; in rad_panel_probe()
549 /* non-burst mode with sync event */ in rad_panel_probe()
552 /* non-burst mode with sync pulse */ in rad_panel_probe()
553 dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_SYNC_PULSE; in rad_panel_probe()
561 ret = of_property_read_u32(np, "dsi-lanes", &dsi->lanes); in rad_panel_probe()
563 dev_err(dev, "Failed to get dsi-lanes property (%d)\n", ret); in rad_panel_probe()
567 panel->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); in rad_panel_probe()
568 if (IS_ERR(panel->reset)) in rad_panel_probe()
569 return PTR_ERR(panel->reset); in rad_panel_probe()
576 panel->backlight = devm_backlight_device_register(dev, dev_name(dev), in rad_panel_probe()
577 dev, dsi, &rad_bl_ops, in rad_panel_probe()
579 if (IS_ERR(panel->backlight)) { in rad_panel_probe()
580 ret = PTR_ERR(panel->backlight); in rad_panel_probe()
585 ret = rad_init_regulators(panel); in rad_panel_probe()
589 drm_panel_init(&panel->panel, dev, &rad_panel_funcs, in rad_panel_probe()
591 dev_set_drvdata(dev, panel); in rad_panel_probe()
593 drm_panel_add(&panel->panel); in rad_panel_probe()
595 ret = mipi_dsi_attach(dsi); in rad_panel_probe()
597 drm_panel_remove(&panel->panel); in rad_panel_probe()
602 static void rad_panel_remove(struct mipi_dsi_device *dsi) in rad_panel_remove() argument
604 struct rad_panel *rad = mipi_dsi_get_drvdata(dsi); in rad_panel_remove()
605 struct device *dev = &dsi->dev; in rad_panel_remove()
608 ret = mipi_dsi_detach(dsi); in rad_panel_remove()
612 drm_panel_remove(&rad->panel); in rad_panel_remove()
623 .name = "panel-raydium-rm67191",
632 MODULE_DESCRIPTION("DRM Driver for Raydium RM67191 MIPI DSI panel");