diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c index 9219f6ee9123..e9f612a7f6f0 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -337,6 +338,7 @@ struct dw_mipi_dsi_rockchip { u16 input_div; u16 feedback_div; u32 format; + u32 mode_flags; struct dw_mipi_dsi *dmd; const struct rockchip_dw_dsi_chip_data *cdata; @@ -345,6 +347,9 @@ struct dw_mipi_dsi_rockchip { struct rockchip_drm_sub_dev sub_dev; struct drm_panel *panel; struct drm_bridge *bridge; + + struct gpio_desc *te_gpio; + bool disable_hold_mode; }; static struct dw_mipi_dsi_rockchip *to_dsi(struct drm_encoder *encoder) @@ -855,6 +860,12 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder, if (dsi->id && dsi->cdata->soc_type == RK3399) s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP; + if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO)) { + s->output_flags |= ROCKCHIP_OUTPUT_MIPI_DS_MODE; + s->soft_te = dsi->te_gpio ? true : false; + s->hold_mode = dsi->disable_hold_mode ? false : true; + } + if (dsi->dsc_enable) { s->dsc_enable = 1; s->dsc_sink_cap.version_major = dsi->version_major; @@ -988,6 +999,17 @@ static struct device return NULL; } +static irqreturn_t dw_mipi_dsi_te_irq_handler(int irq, void *dev_id) +{ + struct dw_mipi_dsi_rockchip *dsi = (struct dw_mipi_dsi_rockchip *)dev_id; + struct drm_encoder *encoder = &dsi->encoder; + + if (encoder->crtc) + rockchip_drm_te_handle(encoder->crtc); + + return IRQ_HANDLED; +} + static int dw_mipi_dsi_get_dsc_info_from_sink(struct dw_mipi_dsi_rockchip *dsi, struct drm_panel *panel, struct drm_bridge *bridge) @@ -1012,6 +1034,7 @@ static int dw_mipi_dsi_get_dsc_info_from_sink(struct dw_mipi_dsi_rockchip *dsi, dsi->scrambling_en = of_property_read_bool(np, "scrambling-enable"); dsi->dsc_enable = of_property_read_bool(np, "compressed-data"); dsi->block_pred_enable = of_property_read_bool(np, "blk-pred-enable"); + of_property_read_u32(np, "dsi,flags", &dsi->mode_flags); of_property_read_u32(np, "slice-width", &dsi->slice_width); of_property_read_u32(np, "slice-height", &dsi->slice_height); of_property_read_u32(np, "slice-per-pkt", &dsi->slice_per_pkt); @@ -1511,6 +1534,23 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) return PTR_ERR(dsi->grf_regmap); } + if (device_property_read_bool(dev, "disable-hold-mode")) + dsi->disable_hold_mode = true; + + dsi->te_gpio = devm_gpiod_get_optional(dev, "te", GPIOD_IN); + if (IS_ERR(dsi->te_gpio)) + dsi->te_gpio = NULL; + + if (dsi->te_gpio) { + ret = devm_request_irq(dev, gpiod_to_irq(dsi->te_gpio), + dw_mipi_dsi_te_irq_handler, + IRQF_TRIGGER_RISING, "PANEL-TE", dsi); + if (ret) { + DRM_DEV_ERROR(dev, "failed to request TE IRQ: %d\n", ret); + return ret; + } + } + dsi->dev = dev; dsi->pdata.base = dsi->base; dsi->pdata.max_data_lanes = dsi->cdata->max_data_lanes;