On 09/11/2020 12:39, Laurent Pinchart wrote:
> On Thu, Nov 05, 2020 at 02:03:10PM +0200, Tomi Valkeinen wrote:
>> From: Sebastian Reichel <sebastian.reic...@collabora.com>
>>
>> This converts the DSI module to expect common drm_panel display
>> drivers instead of dssdev based ones.
>>
>> Signed-off-by: Sebastian Reichel <sebastian.reic...@collabora.com>
>> Signed-off-by: Tomi Valkeinen <tomi.valkei...@ti.com>
>> ---
>>  .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 204 +++++++-----------
>>  drivers/gpu/drm/omapdrm/dss/dsi.c             | 133 ++++++++++--
>>  .../gpu/drm/omapdrm/dss/omapdss-boot-init.c   |   1 -
>>  drivers/gpu/drm/omapdrm/dss/omapdss.h         |   8 -
>>  4 files changed, 189 insertions(+), 157 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c 
>> b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
>> index d9b3444b4faf..3668b3f0aff2 100644
>> --- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
>> +++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
>> @@ -6,8 +6,6 @@
>>   * Author: Tomi Valkeinen <tomi.valkei...@ti.com>
>>   */
>>  
>> -/* #define DEBUG */
>> -
>>  #include <linux/backlight.h>
>>  #include <linux/delay.h>
>>  #include <linux/gpio/consumer.h>
>> @@ -20,11 +18,14 @@
>>  #include <linux/regulator/consumer.h>
>>  
>>  #include <drm/drm_connector.h>
>> +#include <drm/drm_mipi_dsi.h>
>> +#include <drm/drm_panel.h>
>> +#include <drm/drm_modes.h>
> 
> Alphabetically ordered please.
> 
>>  
>> +#include <video/display_timing.h>
>>  #include <video/mipi_display.h>
>>  #include <video/of_display_timing.h>
>> -
>> -#include "../dss/omapdss.h"
>> +#include <video/videomode.h>
>>  
>>  #define DCS_READ_NUM_ERRORS 0x05
>>  #define DCS_GET_ID1         0xda
>> @@ -35,11 +36,8 @@
>>  
>>  struct panel_drv_data {
>>      struct mipi_dsi_device *dsi;
>> -
>> -    struct omap_dss_device dssdev;
>> -    struct omap_dss_device *src;
>> -
>> -    struct videomode vm;
>> +    struct drm_panel panel;
>> +    struct drm_display_mode mode;
>>  
>>      struct mutex lock;
>>  
>> @@ -71,7 +69,11 @@ struct panel_drv_data {
>>      bool ulps_enabled;
>>  };
>>  
>> -#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
>> +
> 
> A single blank line is enough.
> 
>> +static inline struct panel_drv_data *panel_to_ddata(struct drm_panel *panel)
>> +{
>> +    return container_of(panel, struct panel_drv_data, panel);
>> +}
>>  
>>  static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable);
>>  
>> @@ -285,7 +287,6 @@ static void dsicm_hw_reset(struct panel_drv_data *ddata)
>>  
>>  static int dsicm_power_on(struct panel_drv_data *ddata)
>>  {
>> -    struct omap_dss_device *src = ddata->src;
>>      u8 id1, id2, id3;
>>      int r;
>>  
>> @@ -322,10 +323,6 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
>>      if (r)
>>              goto err;
>>  
>> -    r = src->ops->dsi.enable_video_output(src, ddata->dsi->channel);
>> -    if (r)
>> -            goto err;
>> -
>>      ddata->enabled = true;
>>  
>>      if (!ddata->intro_printed) {
>> @@ -345,15 +342,12 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
>>      return r;
>>  }
>>  
>> -static void dsicm_power_off(struct panel_drv_data *ddata)
>> +static int dsicm_power_off(struct panel_drv_data *ddata)
>>  {
>> -    struct omap_dss_device *src = ddata->src;
>>      int r;
>>  
>>      ddata->enabled = false;
>>  
>> -    src->ops->dsi.disable_video_output(src, ddata->dsi->channel);
>> -
>>      r = mipi_dsi_dcs_set_display_off(ddata->dsi);
>>      if (!r)
>>              r = dsicm_sleep_in(ddata);
>> @@ -363,51 +357,25 @@ static void dsicm_power_off(struct panel_drv_data 
>> *ddata)
>>                              "error disabling panel, issuing HW reset\n");
>>              dsicm_hw_reset(ddata);
>>      }
>> -}
>> -
>> -static int dsicm_connect(struct omap_dss_device *src,
>> -                     struct omap_dss_device *dst)
>> -{
>> -    struct panel_drv_data *ddata = to_panel_data(dst);
>> -
>> -    ddata->src = src;
>> -    return 0;
>> -}
>> -
>> -static void dsicm_disconnect(struct omap_dss_device *src,
>> -                         struct omap_dss_device *dst)
>> -{
>> -    struct panel_drv_data *ddata = to_panel_data(dst);
>>  
>> -    ddata->src = NULL;
>> +    return r;
>>  }
>>  
>> -static void dsicm_pre_enable(struct omap_dss_device *dssdev)
>> +static int dsicm_prepare(struct drm_panel *panel)
>>  {
>> -    struct panel_drv_data *ddata = to_panel_data(dssdev);
>> -    struct omap_dss_device *src = ddata->src;
>> +    struct panel_drv_data *ddata = panel_to_ddata(panel);
>>      int r;
>> -    struct omap_dss_dsi_config dsi_config = {
>> -            .vm = &ddata->vm,
>> -            .hs_clk_min = 150000000,
>> -            .hs_clk_max = 300000000,
>> -            .lp_clk_min = 7000000,
>> -            .lp_clk_max = 10000000,
>> -    };
>>  
>>      r = regulator_bulk_enable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
>>      if (r)
>>              dev_err(&ddata->dsi->dev, "failed to enable supplies: %d\n", r);
>>  
>> -    r = src->ops->dsi.set_config(src, &dsi_config);
>> -    if (r) {
>> -            dev_err(&ddata->dsi->dev, "failed to configure DSI\n");
>> -    }
>> +    return r;
>>  }
>>  
>> -static void dsicm_enable(struct omap_dss_device *dssdev)
>> +static int dsicm_enable(struct drm_panel *panel)
>>  {
>> -    struct panel_drv_data *ddata = to_panel_data(dssdev);
>> +    struct panel_drv_data *ddata = panel_to_ddata(panel);
>>      int r;
>>  
>>      mutex_lock(&ddata->lock);
>> @@ -420,33 +388,39 @@ static void dsicm_enable(struct omap_dss_device 
>> *dssdev)
>>  
>>      dsicm_bl_power(ddata, true);
>>  
>> -    return;
>> +    return 0;
>>  err:
>> -    dev_dbg(&ddata->dsi->dev, "enable failed (%d)\n", r);
>> +    dev_err(&ddata->dsi->dev, "enable failed (%d)\n", r);
>>      mutex_unlock(&ddata->lock);
>> +    return r;
>> +}
>> +
>> +static int dsicm_unprepare(struct drm_panel *panel)
>> +{
>> +    struct panel_drv_data *ddata = panel_to_ddata(panel);
>> +    int r;
>> +
>> +    r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
>> +    if (r)
>> +            dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", 
>> r);
>> +
>> +    return r;
>>  }
>>  
>> -static void dsicm_disable(struct omap_dss_device *dssdev)
>> +static int dsicm_disable(struct drm_panel *panel)
>>  {
>> -    struct panel_drv_data *ddata = to_panel_data(dssdev);
>> +    struct panel_drv_data *ddata = panel_to_ddata(panel);
>> +    int r;
>>  
>>      dsicm_bl_power(ddata, false);
>>  
>>      mutex_lock(&ddata->lock);
>>  
>> -    dsicm_power_off(ddata);
>> +    r = dsicm_power_off(ddata);
>>  
>>      mutex_unlock(&ddata->lock);
>> -}
>> -
>> -static void dsicm_post_disable(struct omap_dss_device *dssdev)
>> -{
>> -    struct panel_drv_data *ddata = to_panel_data(dssdev);
>> -    int r;
>>  
>> -    r = regulator_bulk_disable(DCS_REGULATOR_SUPPLY_NUM, ddata->supplies);
>> -    if (r)
>> -            dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", 
>> r);
>> +    return r;
>>  }
>>  
>>  static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
>> @@ -465,50 +439,37 @@ static int _dsicm_enable_te(struct panel_drv_data 
>> *ddata, bool enable)
>>      return r;
>>  }
>>  
>> -static int dsicm_get_modes(struct omap_dss_device *dssdev,
>> +static int dsicm_get_modes(struct drm_panel *panel,
>>                         struct drm_connector *connector)
>>  {
>> -    struct panel_drv_data *ddata = to_panel_data(dssdev);
>> +    struct panel_drv_data *ddata = panel_to_ddata(panel);
>> +    struct drm_display_mode *mode;
>> +
>> +    mode = drm_mode_duplicate(connector->dev, &ddata->mode);
>> +    if (!mode) {
>> +            dev_err(&ddata->dsi->dev, "failed to add mode %ux%ux@%u kHz\n",
>> +                    ddata->mode.hdisplay, ddata->mode.vdisplay,
>> +                    ddata->mode.clock);
>> +            return -ENOMEM;
>> +    }
>> +
>> +    drm_mode_set_name(mode);
>> +    mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
>>  
>>      connector->display_info.width_mm = ddata->width_mm;
>>      connector->display_info.height_mm = ddata->height_mm;
>>  
>> -    return omapdss_display_get_modes(connector, &ddata->vm);
>> -}
>> -
>> -static int dsicm_check_timings(struct omap_dss_device *dssdev,
>> -                           struct drm_display_mode *mode)
>> -{
>> -    struct panel_drv_data *ddata = to_panel_data(dssdev);
>> -    int ret = 0;
>> -
>> -    if (mode->hdisplay != ddata->vm.hactive)
>> -            ret = -EINVAL;
>> -
>> -    if (mode->vdisplay != ddata->vm.vactive)
>> -            ret = -EINVAL;
>> +    drm_mode_probed_add(connector, mode);
>>  
>> -    if (ret) {
>> -            dev_warn(dssdev->dev, "wrong resolution: %d x %d",
>> -                     mode->hdisplay, mode->vdisplay);
>> -            dev_warn(dssdev->dev, "panel resolution: %d x %d",
>> -                     ddata->vm.hactive, ddata->vm.vactive);
>> -    }
>> -
>> -    return ret;
>> +    return 1;
>>  }
>>  
>> -static const struct omap_dss_device_ops dsicm_ops = {
>> -    .connect        = dsicm_connect,
>> -    .disconnect     = dsicm_disconnect,
>> -
>> -    .pre_enable     = dsicm_pre_enable,
>> -    .enable         = dsicm_enable,
>> -    .disable        = dsicm_disable,
>> -    .post_disable   = dsicm_post_disable,
>> -
>> -    .get_modes      = dsicm_get_modes,
>> -    .check_timings  = dsicm_check_timings,
>> +static const struct drm_panel_funcs dsicm_panel_funcs = {
>> +    .unprepare = dsicm_unprepare,
>> +    .disable = dsicm_disable,
>> +    .prepare = dsicm_prepare,
>> +    .enable = dsicm_enable,
>> +    .get_modes = dsicm_get_modes,
>>  };
>>  
>>  static int dsicm_probe_of(struct mipi_dsi_device *dsi)
>> @@ -517,8 +478,12 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
>>      struct backlight_device *backlight;
>>      struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
>>      struct display_timing timing;
>> +    struct videomode vm = { 0 };
> 
> How about
> 
>       struct videomode vm = {
>               .hactive = 864,
>               .vactive = 480,
>       };
> 
>>      int err;
>>  
>> +    vm.hactive = 864;
>> +    vm.vactive = 480;
>> +
>>      ddata->reset_gpio = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
>>      if (IS_ERR(ddata->reset_gpio)) {
>>              err = PTR_ERR(ddata->reset_gpio);
>> @@ -528,15 +493,16 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
>>  
>>      err = of_get_display_timing(node, "panel-timing", &timing);
>>      if (!err) {
>> -            videomode_from_timing(&timing, &ddata->vm);
>> -            if (!ddata->vm.pixelclock)
>> -                    ddata->vm.pixelclock =
>> -                            ddata->vm.hactive * ddata->vm.vactive * 60;
>> +            videomode_from_timing(&timing, &vm);
>>      } else {
>>              dev_warn(&dsi->dev,
>>                       "failed to get video timing, using defaults\n");
>>      }
>>  
>> +    if (!vm.pixelclock)
>> +            vm.pixelclock = vm.hactive * vm.vactive * 60;
>> +    drm_display_mode_from_videomode(&vm, &ddata->mode);
>> +
>>      ddata->width_mm = 0;
>>      of_property_read_u32(node, "width-mm", &ddata->width_mm);
>>  
>> @@ -570,7 +536,6 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
>>      struct panel_drv_data *ddata;
>>      struct backlight_device *bldev = NULL;
>>      struct device *dev = &dsi->dev;
>> -    struct omap_dss_device *dssdev;
>>      int r;
>>  
>>      dev_dbg(dev, "probe\n");
>> @@ -582,30 +547,17 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
>>      mipi_dsi_set_drvdata(dsi, ddata);
>>      ddata->dsi = dsi;
>>  
>> -    ddata->vm.hactive = 864;
>> -    ddata->vm.vactive = 480;
>> -    ddata->vm.pixelclock = 864 * 480 * 60;
>> -
>>      r = dsicm_probe_of(dsi);
>>      if (r)
>>              return r;
>>  
>> -    dssdev = &ddata->dssdev;
>> -    dssdev->dev = dev;
>> -    dssdev->ops = &dsicm_ops;
>> -    dssdev->type = OMAP_DISPLAY_TYPE_DSI;
>> -    dssdev->display = true;
>> -    dssdev->owner = THIS_MODULE;
>> -    dssdev->of_port = 0;
>> -    dssdev->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
>> -
>> -    omapdss_display_init(dssdev);
>> -    omapdss_device_register(dssdev);
>> -
>>      mutex_init(&ddata->lock);
>>  
>>      dsicm_hw_reset(ddata);
>>  
>> +    drm_panel_init(&ddata->panel, dev, &dsicm_panel_funcs,
>> +                   DRM_MODE_CONNECTOR_DSI);
>> +
>>      if (ddata->use_dsi_backlight) {
>>              struct backlight_properties props = { 0 };
>>              props.max_brightness = 255;
>> @@ -637,6 +589,8 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
>>      if (ddata->ulps_enabled)
>>              dsi->mode_flags |= MIPI_DSI_MODE_ULPS_IDLE;
>>  
>> +    drm_panel_add(&ddata->panel);
>> +
>>      r = mipi_dsi_attach(dsi);
>>      if (r < 0)
>>              goto err_dsi_attach;
>> @@ -644,6 +598,7 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
>>      return 0;
>>  
>>  err_dsi_attach:
>> +    drm_panel_remove(&ddata->panel);
>>      sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
>>  err_bl:
>>      if (ddata->extbldev)
>> @@ -655,15 +610,12 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
>>  static int __exit dsicm_remove(struct mipi_dsi_device *dsi)
>>  {
>>      struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
>> -    struct omap_dss_device *dssdev = &ddata->dssdev;
>>  
>>      dev_dbg(&dsi->dev, "remove\n");
>>  
>>      mipi_dsi_detach(dsi);
>>  
>> -    omapdss_device_unregister(dssdev);
>> -
>> -    omapdss_device_disconnect(ddata->src, dssdev);
>> +    drm_panel_remove(&ddata->panel);
>>  
>>      sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
>>  
>> @@ -677,7 +629,7 @@ static int __exit dsicm_remove(struct mipi_dsi_device 
>> *dsi)
>>  }
>>  
>>  static const struct of_device_id dsicm_of_match[] = {
>> -    { .compatible = "omapdss,panel-dsi-cm", },
>> +    { .compatible = "panel-dsi-cm", },
>>      {},
>>  };
>>  
>> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
>> b/drivers/gpu/drm/omapdrm/dss/dsi.c
>> index 620cef8bb1f2..a1a867a7d91d 100644
>> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
>> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
>> @@ -36,6 +36,7 @@
>>  #include <linux/sys_soc.h>
>>  
>>  #include <drm/drm_mipi_dsi.h>
>> +#include <drm/drm_panel.h>
>>  #include <video/mipi_display.h>
>>  
>>  #include "omapdss.h"
>> @@ -217,6 +218,8 @@ static int dsi_vc_send_null(struct dsi_data *dsi, int 
>> channel);
>>  static ssize_t _omap_dsi_host_transfer(struct dsi_data *dsi,
>>                                     const struct mipi_dsi_msg *msg);
>>  
>> +static void dsi_display_disable(struct omap_dss_device *dssdev);
>> +
> 
> Could you reorder functions to avoid forward-declarations ? This can be
> done on top if it generates annoying conflicts.
> 
>>  /* DSI PLL HSDIV indices */
>>  #define HSDIV_DISPC 0
>>  #define HSDIV_DSI   1
>> @@ -383,6 +386,7 @@ struct dsi_data {
>>      bool te_enabled;
>>      bool ulps_enabled;
>>      bool ulps_auto_idle;
>> +    bool video_enabled;
>>  
>>      struct delayed_work ulps_work;
>>  
>> @@ -423,6 +427,8 @@ struct dsi_data {
>>  
>>      unsigned int scp_clk_refcount;
>>  
>> +    struct omap_dss_dsi_config config;
>> +
>>      struct dss_lcd_mgr_config mgr_config;
>>      struct videomode vm;
>>      enum mipi_dsi_pixel_format pix_fmt;
>> @@ -3622,7 +3628,7 @@ static int dsi_configure_pins(struct omap_dss_device 
>> *dssdev,
>>      return 0;
>>  }
>>  
>> -static int dsi_enable_video_output(struct omap_dss_device *dssdev, int 
>> channel)
>> +static void dsi_enable_video_output(struct omap_dss_device *dssdev, int 
>> channel)
>>  {
>>      struct dsi_data *dsi = to_dsi_data(dssdev);
>>      int bpp = mipi_dsi_pixel_format_to_bpp(dsi->pix_fmt);
>> @@ -3631,8 +3637,10 @@ static int dsi_enable_video_output(struct 
>> omap_dss_device *dssdev, int channel)
>>      int r;
>>  
>>      r = dsi_display_init_dispc(dsi);
>> -    if (r)
>> -            return r;
>> +    if (r) {
>> +            dev_err(dsi->dev, "failed to init dispc!\n");
>> +            return;
>> +    }
>>  
>>      if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
>>              switch (dsi->pix_fmt) {
>> @@ -3672,7 +3680,7 @@ static int dsi_enable_video_output(struct 
>> omap_dss_device *dssdev, int channel)
>>      if (r)
>>              goto err_mgr_enable;
>>  
>> -    return 0;
>> +    return;
>>  
>>  err_mgr_enable:
>>      if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
>> @@ -3681,7 +3689,8 @@ static int dsi_enable_video_output(struct 
>> omap_dss_device *dssdev, int channel)
>>      }
>>  err_pix_fmt:
>>      dsi_display_uninit_dispc(dsi);
>> -    return r;
>> +    dev_err(dsi->dev, "failed to enable DSI encoder!\n");
>> +    return;
>>  }
>>  
>>  static void dsi_disable_video_output(struct omap_dss_device *dssdev, int 
>> channel)
>> @@ -3704,6 +3713,25 @@ static void dsi_disable_video_output(struct 
>> omap_dss_device *dssdev, int channel
>>      dsi_display_uninit_dispc(dsi);
>>  }
>>  
>> +static void dsi_disable_video_outputs(struct omap_dss_device *dssdev)
>> +{
>> +    struct dsi_data *dsi = to_dsi_data(dssdev);
>> +    int i;
>> +
>> +    dsi_bus_lock(dsi);
>> +    dsi->video_enabled = false;
>> +
>> +    for (i = 0; i < 3; i++) {
>> +            if (!dsi->vc[i].dest)
>> +                    continue;
>> +            dsi_disable_video_output(dssdev, i);
>> +    }
>> +
>> +    dsi_display_disable(dssdev);
>> +
>> +    dsi_bus_unlock(dsi);
>> +}
>> +
>>  static void dsi_update_screen_dispc(struct dsi_data *dsi)
>>  {
>>      unsigned int bytespp;
>> @@ -3897,6 +3925,11 @@ static int dsi_update_channel(struct omap_dss_device 
>> *dssdev, int channel)
>>  
>>      dsi_bus_lock(dsi);
>>  
>> +    if (!dsi->video_enabled) {
>> +            r = -EIO;
>> +            goto err;
>> +    }
>> +
>>      if (!dsi->vc[channel].dest) {
>>              r = -ENODEV;
>>              goto err;
>> @@ -3942,7 +3975,7 @@ static int dsi_update_all(struct omap_dss_device 
>> *dssdev)
>>  
>>      for (i = 0; i < 4; i++) {
>>              r = dsi_update_channel(dssdev, i);
>> -            if (r != -ENODEV)
>> +            if (r && r != -ENODEV)
> 
> Does this belong to this patch ? I haven't flagged it when reviwing the
> patch that introduced this code, assuming that you meant to exit from
> the loop once a channel with a client is found, given that we don't
> support multiple clients. In any case this should be coordinated with
> dsi_enable_video_outputs() and dsi_disable_video_outputs(), all should
> stop on the first client, or loop over all clients.

Yes, it should be in an earlier patch.

I think this code needs more work, but in any case this change belongs to the 
patch that added
dsi_update_all.

>> @@ -5057,6 +5138,10 @@ static int omap_dsi_host_attach(struct mipi_dsi_host 
>> *host,
>>  
>>      dsi_bus_lock(dsi);
>>  
>> +    panel = of_drm_find_panel(client->dev.of_node);
>> +    if (IS_ERR(panel))
>> +            return PTR_ERR(panel);
> 
> Is it intended that the panel isn't used ?

I think it's left over code. I'll drop.

 Tomi

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to