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
227 static inline struct rad_panel *to_rad_panel(struct drm_panel *panel) in to_rad_panel() argument
229 return container_of(panel, struct rad_panel, panel); in to_rad_panel()
232 static int rad_panel_push_cmd_list(struct mipi_dsi_device *dsi) in rad_panel_push_cmd_list() argument
240 u8 buffer[2] = { entry->cmd, entry->param }; in rad_panel_push_cmd_list()
242 ret = mipi_dsi_generic_write(dsi, &buffer, sizeof(buffer)); in rad_panel_push_cmd_list()
265 static int rad_panel_prepare(struct drm_panel *panel) in rad_panel_prepare() argument
267 struct rad_panel *rad = to_rad_panel(panel); in rad_panel_prepare()
270 if (rad->prepared) in rad_panel_prepare()
273 ret = regulator_bulk_enable(rad->num_supplies, rad->supplies); in rad_panel_prepare()
277 if (rad->reset) { in rad_panel_prepare()
278 gpiod_set_value_cansleep(rad->reset, 1); in rad_panel_prepare()
280 gpiod_set_value_cansleep(rad->reset, 0); in rad_panel_prepare()
284 rad->prepared = true; in rad_panel_prepare()
289 static int rad_panel_unprepare(struct drm_panel *panel) in rad_panel_unprepare() argument
291 struct rad_panel *rad = to_rad_panel(panel); in rad_panel_unprepare()
294 if (!rad->prepared) in rad_panel_unprepare()
302 if (rad->reset) { in rad_panel_unprepare()
303 gpiod_set_value_cansleep(rad->reset, 1); in rad_panel_unprepare()
305 gpiod_set_value_cansleep(rad->reset, 0); in rad_panel_unprepare()
308 ret = regulator_bulk_disable(rad->num_supplies, rad->supplies); in rad_panel_unprepare()
312 rad->prepared = false; in rad_panel_unprepare()
317 static int rad_panel_enable(struct drm_panel *panel) in rad_panel_enable() argument
319 struct rad_panel *rad = to_rad_panel(panel); in rad_panel_enable()
320 struct mipi_dsi_device *dsi = rad->dsi; in rad_panel_enable() local
321 struct device *dev = &dsi->dev; in rad_panel_enable()
322 int color_format = color_format_from_dsi_format(dsi->format); in rad_panel_enable()
325 if (rad->enabled) in rad_panel_enable()
328 dsi->mode_flags |= MIPI_DSI_MODE_LPM; in rad_panel_enable()
330 ret = rad_panel_push_cmd_list(dsi); in rad_panel_enable()
337 ret = mipi_dsi_generic_write(dsi, (u8[]){ WRMAUCCTR, 0x00 }, 2); in rad_panel_enable()
342 ret = mipi_dsi_dcs_soft_reset(dsi); in rad_panel_enable()
350 /* Set DSI mode */ in rad_panel_enable()
351 ret = mipi_dsi_generic_write(dsi, (u8[]){ 0xC2, 0x0B }, 2); in rad_panel_enable()
353 dev_err(dev, "Failed to set DSI mode (%d)\n", ret); in rad_panel_enable()
357 ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); in rad_panel_enable()
363 ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0x380); in rad_panel_enable()
369 ret = mipi_dsi_dcs_set_pixel_format(dsi, color_format); in rad_panel_enable()
376 ret = mipi_dsi_dcs_exit_sleep_mode(dsi); in rad_panel_enable()
384 ret = mipi_dsi_dcs_set_display_on(dsi); in rad_panel_enable()
390 backlight_enable(rad->backlight); in rad_panel_enable()
392 rad->enabled = true; in rad_panel_enable()
397 gpiod_set_value_cansleep(rad->reset, 1); in rad_panel_enable()
402 static int rad_panel_disable(struct drm_panel *panel) in rad_panel_disable() argument
404 struct rad_panel *rad = to_rad_panel(panel); in rad_panel_disable()
405 struct mipi_dsi_device *dsi = rad->dsi; in rad_panel_disable() local
406 struct device *dev = &dsi->dev; in rad_panel_disable()
409 if (!rad->enabled) in rad_panel_disable()
412 dsi->mode_flags |= MIPI_DSI_MODE_LPM; in rad_panel_disable()
414 backlight_disable(rad->backlight); in rad_panel_disable()
418 ret = mipi_dsi_dcs_set_display_off(dsi); in rad_panel_disable()
426 ret = mipi_dsi_dcs_enter_sleep_mode(dsi); in rad_panel_disable()
432 rad->enabled = false; in rad_panel_disable()
437 static int rad_panel_get_modes(struct drm_panel *panel, in rad_panel_get_modes() argument
442 mode = drm_mode_duplicate(connector->dev, &default_mode); in rad_panel_get_modes()
444 dev_err(panel->dev, "failed to add mode %ux%u@%u\n", in rad_panel_get_modes()
447 return -ENOMEM; in rad_panel_get_modes()
451 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; in rad_panel_get_modes()
454 connector->display_info.width_mm = mode->width_mm; in rad_panel_get_modes()
455 connector->display_info.height_mm = mode->height_mm; in rad_panel_get_modes()
456 connector->display_info.bus_flags = rad_bus_flags; in rad_panel_get_modes()
458 drm_display_info_set_bus_formats(&connector->display_info, in rad_panel_get_modes()
466 struct mipi_dsi_device *dsi = bl_get_data(bl); in rad_bl_get_brightness() local
467 struct rad_panel *rad = mipi_dsi_get_drvdata(dsi); in rad_bl_get_brightness()
471 if (!rad->prepared) in rad_bl_get_brightness()
474 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; in rad_bl_get_brightness()
476 ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness); in rad_bl_get_brightness()
480 bl->props.brightness = brightness; in rad_bl_get_brightness()
487 struct mipi_dsi_device *dsi = bl_get_data(bl); in rad_bl_update_status() local
488 struct rad_panel *rad = mipi_dsi_get_drvdata(dsi); in rad_bl_update_status()
491 if (!rad->prepared) in rad_bl_update_status()
494 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; in rad_bl_update_status()
496 ret = mipi_dsi_dcs_set_display_brightness(dsi, bl->props.brightness); in rad_bl_update_status()
523 struct device *dev = &rad->dsi->dev; in rad_init_regulators()
526 rad->num_supplies = ARRAY_SIZE(rad_supply_names); in rad_init_regulators()
527 rad->supplies = devm_kcalloc(dev, rad->num_supplies, in rad_init_regulators()
528 sizeof(*rad->supplies), GFP_KERNEL); in rad_init_regulators()
529 if (!rad->supplies) in rad_init_regulators()
530 return -ENOMEM; in rad_init_regulators()
532 for (i = 0; i < rad->num_supplies; i++) in rad_init_regulators()
533 rad->supplies[i].supply = rad_supply_names[i]; in rad_init_regulators()
535 return devm_regulator_bulk_get(dev, rad->num_supplies, rad->supplies); in rad_init_regulators()
538 static int rad_panel_probe(struct mipi_dsi_device *dsi) in rad_panel_probe() argument
540 struct device *dev = &dsi->dev; in rad_panel_probe()
541 struct device_node *np = dev->of_node; in rad_panel_probe()
542 struct rad_panel *panel; in rad_panel_probe() local
547 panel = devm_kzalloc(&dsi->dev, sizeof(*panel), GFP_KERNEL); in rad_panel_probe()
548 if (!panel) in rad_panel_probe()
549 return -ENOMEM; in rad_panel_probe()
551 mipi_dsi_set_drvdata(dsi, panel); in rad_panel_probe()
553 panel->dsi = dsi; in rad_panel_probe()
555 dsi->format = MIPI_DSI_FMT_RGB888; in rad_panel_probe()
556 dsi->mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO; in rad_panel_probe()
558 ret = of_property_read_u32(np, "video-mode", &video_mode); in rad_panel_probe()
563 dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_BURST; in rad_panel_probe()
566 /* non-burst mode with sync event */ in rad_panel_probe()
569 /* non-burst mode with sync pulse */ in rad_panel_probe()
570 dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_SYNC_PULSE; in rad_panel_probe()
578 ret = of_property_read_u32(np, "dsi-lanes", &dsi->lanes); in rad_panel_probe()
580 dev_err(dev, "Failed to get dsi-lanes property (%d)\n", ret); in rad_panel_probe()
584 panel->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); in rad_panel_probe()
585 if (IS_ERR(panel->reset)) in rad_panel_probe()
586 return PTR_ERR(panel->reset); in rad_panel_probe()
593 panel->backlight = devm_backlight_device_register(dev, dev_name(dev), in rad_panel_probe()
594 dev, dsi, &rad_bl_ops, in rad_panel_probe()
596 if (IS_ERR(panel->backlight)) { in rad_panel_probe()
597 ret = PTR_ERR(panel->backlight); in rad_panel_probe()
602 ret = rad_init_regulators(panel); in rad_panel_probe()
606 drm_panel_init(&panel->panel, dev, &rad_panel_funcs, in rad_panel_probe()
608 dev_set_drvdata(dev, panel); in rad_panel_probe()
610 drm_panel_add(&panel->panel); in rad_panel_probe()
612 ret = mipi_dsi_attach(dsi); in rad_panel_probe()
614 drm_panel_remove(&panel->panel); in rad_panel_probe()
619 static void rad_panel_remove(struct mipi_dsi_device *dsi) in rad_panel_remove() argument
621 struct rad_panel *rad = mipi_dsi_get_drvdata(dsi); in rad_panel_remove()
622 struct device *dev = &dsi->dev; in rad_panel_remove()
625 ret = mipi_dsi_detach(dsi); in rad_panel_remove()
629 drm_panel_remove(&rad->panel); in rad_panel_remove()
632 static void rad_panel_shutdown(struct mipi_dsi_device *dsi) in rad_panel_shutdown() argument
634 struct rad_panel *rad = mipi_dsi_get_drvdata(dsi); in rad_panel_shutdown()
636 rad_panel_disable(&rad->panel); in rad_panel_shutdown()
637 rad_panel_unprepare(&rad->panel); in rad_panel_shutdown()
648 .name = "panel-raydium-rm67191",
658 MODULE_DESCRIPTION("DRM Driver for Raydium RM67191 MIPI DSI panel");