summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
diff options
context:
space:
mode:
authorSebastian Reichel <sebastian.reichel@collabora.com>2020-12-15 11:46:05 +0100
committerTomi Valkeinen <tomi.valkeinen@ti.com>2020-12-15 15:08:24 +0100
commit1cac9ba2526ff53838165b48005cf7e876f610e6 (patch)
treea39a89f73542627c7dbe8b07aac8c1b09545778a /drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
parentdrm/omap: dsi: drop custom panel capability support (diff)
downloadlinux-1cac9ba2526ff53838165b48005cf7e876f610e6.tar.xz
linux-1cac9ba2526ff53838165b48005cf7e876f610e6.zip
drm/omap: dsi: convert to drm_panel
This converts the DSI module to expect common drm_panel display drivers instead of dssdev based ones. Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Link: https://patchwork.freedesktop.org/patch/msgid/20201215104657.802264-33-tomi.valkeinen@ti.com
Diffstat (limited to 'drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c')
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c203
1 files changed, 77 insertions, 126 deletions
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index da925d23b629..72dce2fa8ced 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.valkeinen@ti.com>
*/
-/* #define DEBUG */
-
#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
@@ -19,11 +17,14 @@
#include <linux/regulator/consumer.h>
#include <drm/drm_connector.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+#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
@@ -34,11 +35,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;
@@ -66,7 +64,10 @@ struct panel_drv_data {
bool intro_printed;
};
-#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
+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);
@@ -281,7 +282,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;
@@ -318,10 +318,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) {
@@ -341,15 +337,12 @@ err:
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);
@@ -359,51 +352,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(ARRAY_SIZE(ddata->supplies), 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);
@@ -416,33 +383,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(ARRAY_SIZE(ddata->supplies), 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(ARRAY_SIZE(ddata->supplies), 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)
@@ -461,50 +434,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)
@@ -513,6 +473,10 @@ 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 = {
+ .hactive = 864,
+ .vactive = 480,
+ };
int err;
ddata->reset_gpio = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
@@ -524,15 +488,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);
@@ -564,7 +529,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");
@@ -576,30 +540,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;
@@ -628,6 +579,8 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
dsi->hs_rate = 300000000;
dsi->lp_rate = 10000000;
+ drm_panel_add(&ddata->panel);
+
r = mipi_dsi_attach(dsi);
if (r < 0)
goto err_dsi_attach;
@@ -635,6 +588,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)
@@ -646,15 +600,12 @@ err_bl:
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);
@@ -668,7 +619,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", },
{},
};