diff options
Diffstat (limited to 'drivers/gpu/drm')
42 files changed, 2295 insertions, 3873 deletions
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c index 9eabd7201a12..28a3ce8f88d2 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c @@ -18,77 +18,27 @@ struct panel_drv_data { struct omap_dss_device dssdev; - struct omap_dss_device *in; struct device *dev; - - struct videomode vm; -}; - -static const struct videomode tvc_pal_vm = { - .hactive = 720, - .vactive = 574, - .pixelclock = 13500000, - .hsync_len = 64, - .hfront_porch = 12, - .hback_porch = 68, - .vsync_len = 5, - .vfront_porch = 5, - .vback_porch = 41, - - .flags = DISPLAY_FLAGS_INTERLACED | DISPLAY_FLAGS_HSYNC_LOW | - DISPLAY_FLAGS_VSYNC_LOW, }; #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) -static int tvc_connect(struct omap_dss_device *dssdev) +static int tvc_connect(struct omap_dss_device *src, + struct omap_dss_device *dst) { - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in; - int r; - - dev_dbg(ddata->dev, "connect\n"); - - if (omapdss_device_is_connected(dssdev)) - return 0; - - in = omapdss_of_find_source_for_first_ep(ddata->dev->of_node); - if (IS_ERR(in)) { - dev_err(ddata->dev, "failed to find video source\n"); - return PTR_ERR(in); - } - - r = in->ops.atv->connect(in, dssdev); - if (r) { - omap_dss_put_device(in); - return r; - } - - ddata->in = in; return 0; } -static void tvc_disconnect(struct omap_dss_device *dssdev) +static void tvc_disconnect(struct omap_dss_device *src, + struct omap_dss_device *dst) { - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - dev_dbg(ddata->dev, "disconnect\n"); - - if (!omapdss_device_is_connected(dssdev)) - return; - - in->ops.atv->disconnect(in, dssdev); - - omap_dss_put_device(in); - ddata->in = NULL; } static int tvc_enable(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; + struct omap_dss_device *src = dssdev->src; int r; dev_dbg(ddata->dev, "enable\n"); @@ -99,9 +49,7 @@ static int tvc_enable(struct omap_dss_device *dssdev) if (omapdss_device_is_enabled(dssdev)) return 0; - in->ops.atv->set_timings(in, &ddata->vm); - - r = in->ops.atv->enable(in); + r = src->ops->enable(src); if (r) return r; @@ -113,83 +61,30 @@ static int tvc_enable(struct omap_dss_device *dssdev) static void tvc_disable(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; + struct omap_dss_device *src = dssdev->src; dev_dbg(ddata->dev, "disable\n"); if (!omapdss_device_is_enabled(dssdev)) return; - in->ops.atv->disable(in); + src->ops->disable(src); dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } -static void tvc_set_timings(struct omap_dss_device *dssdev, - struct videomode *vm) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - ddata->vm = *vm; - dssdev->panel.vm = *vm; - - in->ops.atv->set_timings(in, vm); -} - -static void tvc_get_timings(struct omap_dss_device *dssdev, - struct videomode *vm) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - - *vm = ddata->vm; -} - -static int tvc_check_timings(struct omap_dss_device *dssdev, - struct videomode *vm) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - return in->ops.atv->check_timings(in, vm); -} - -static u32 tvc_get_wss(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - return in->ops.atv->get_wss(in); -} - -static int tvc_set_wss(struct omap_dss_device *dssdev, u32 wss) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - return in->ops.atv->set_wss(in, wss); -} - -static struct omap_dss_driver tvc_driver = { +static const struct omap_dss_device_ops tvc_ops = { .connect = tvc_connect, .disconnect = tvc_disconnect, .enable = tvc_enable, .disable = tvc_disable, - - .set_timings = tvc_set_timings, - .get_timings = tvc_get_timings, - .check_timings = tvc_check_timings, - - .get_wss = tvc_get_wss, - .set_wss = tvc_set_wss, }; static int tvc_probe(struct platform_device *pdev) { struct panel_drv_data *ddata; struct omap_dss_device *dssdev; - int r; ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); if (!ddata) @@ -198,20 +93,15 @@ static int tvc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ddata); ddata->dev = &pdev->dev; - ddata->vm = tvc_pal_vm; - dssdev = &ddata->dssdev; - dssdev->driver = &tvc_driver; + dssdev->ops = &tvc_ops; dssdev->dev = &pdev->dev; dssdev->type = OMAP_DISPLAY_TYPE_VENC; dssdev->owner = THIS_MODULE; - dssdev->panel.vm = tvc_pal_vm; + dssdev->of_ports = BIT(0); - r = omapdss_register_display(dssdev); - if (r) { - dev_err(&pdev->dev, "Failed to register panel\n"); - return r; - } + omapdss_display_init(dssdev); + omapdss_device_register(dssdev); return 0; } @@ -221,10 +111,9 @@ static int __exit tvc_remove(struct platform_device *pdev) struct panel_drv_data *ddata = platform_get_drvdata(pdev); struct omap_dss_device *dssdev = &ddata->dssdev; - omapdss_unregister_display(&ddata->dssdev); + omapdss_device_unregister(&ddata->dssdev); tvc_disable(dssdev); - tvc_disconnect(dssdev); return 0; } diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c index 6d8cbd9e2110..24b14f44248e 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c @@ -19,30 +19,8 @@ #include "../dss/omapdss.h" -static const struct videomode dvic_default_vm = { - .hactive = 640, - .vactive = 480, - - .pixelclock = 23500000, - - .hfront_porch = 48, - .hsync_len = 32, - .hback_porch = 80, - - .vfront_porch = 3, - .vsync_len = 4, - .vback_porch = 7, - - .flags = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH | - DISPLAY_FLAGS_SYNC_NEGEDGE | DISPLAY_FLAGS_DE_HIGH | - DISPLAY_FLAGS_PIXDATA_POSEDGE, -}; - struct panel_drv_data { struct omap_dss_device dssdev; - struct omap_dss_device *in; - - struct videomode vm; struct i2c_adapter *i2c_adapter; @@ -57,49 +35,20 @@ struct panel_drv_data { #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) -static int dvic_connect(struct omap_dss_device *dssdev) +static int dvic_connect(struct omap_dss_device *src, + struct omap_dss_device *dst) { - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in; - int r; - - if (omapdss_device_is_connected(dssdev)) - return 0; - - in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node); - if (IS_ERR(in)) { - dev_err(dssdev->dev, "failed to find video source\n"); - return PTR_ERR(in); - } - - r = in->ops.dvi->connect(in, dssdev); - if (r) { - omap_dss_put_device(in); - return r; - } - - ddata->in = in; return 0; } -static void dvic_disconnect(struct omap_dss_device *dssdev) +static void dvic_disconnect(struct omap_dss_device *src, + struct omap_dss_device *dst) { - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - if (!omapdss_device_is_connected(dssdev)) - return; - - in->ops.dvi->disconnect(in, dssdev); - - omap_dss_put_device(in); - ddata->in = NULL; } static int dvic_enable(struct omap_dss_device *dssdev) { - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; + struct omap_dss_device *src = dssdev->src; int r; if (!omapdss_device_is_connected(dssdev)) @@ -108,9 +57,7 @@ static int dvic_enable(struct omap_dss_device *dssdev) if (omapdss_device_is_enabled(dssdev)) return 0; - in->ops.dvi->set_timings(in, &ddata->vm); - - r = in->ops.dvi->enable(in); + r = src->ops->enable(src); if (r) return r; @@ -121,46 +68,16 @@ static int dvic_enable(struct omap_dss_device *dssdev) static void dvic_disable(struct omap_dss_device *dssdev) { - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; + struct omap_dss_device *src = dssdev->src; if (!omapdss_device_is_enabled(dssdev)) return; - in->ops.dvi->disable(in); + src->ops->disable(src); dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } -static void dvic_set_timings(struct omap_dss_device *dssdev, - struct videomode *vm) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - ddata->vm = *vm; - dssdev->panel.vm = *vm; - - in->ops.dvi->set_timings(in, vm); -} - -static void dvic_get_timings(struct omap_dss_device *dssdev, - struct videomode *vm) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - - *vm = ddata->vm; -} - -static int dvic_check_timings(struct omap_dss_device *dssdev, - struct videomode *vm) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - return in->ops.dvi->check_timings(in, vm); -} - static int dvic_ddc_read(struct i2c_adapter *adapter, unsigned char *buf, u16 count, u8 offset) { @@ -198,12 +115,6 @@ static int dvic_read_edid(struct omap_dss_device *dssdev, struct panel_drv_data *ddata = to_panel_data(dssdev); int r, l, bytes_read; - if (ddata->hpd_gpio && !gpiod_get_value_cansleep(ddata->hpd_gpio)) - return -ENODEV; - - if (!ddata->i2c_adapter) - return -ENODEV; - l = min(EDID_LENGTH, len); r = dvic_ddc_read(ddata->i2c_adapter, edid, l, 0); if (r) @@ -243,78 +154,41 @@ static bool dvic_detect(struct omap_dss_device *dssdev) return r == 0; } -static int dvic_register_hpd_cb(struct omap_dss_device *dssdev, +static void dvic_register_hpd_cb(struct omap_dss_device *dssdev, void (*cb)(void *cb_data, enum drm_connector_status status), void *cb_data) { struct panel_drv_data *ddata = to_panel_data(dssdev); - if (!ddata->hpd_gpio) - return -ENOTSUPP; - mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = cb; ddata->hpd_cb_data = cb_data; mutex_unlock(&ddata->hpd_lock); - return 0; } static void dvic_unregister_hpd_cb(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); - if (!ddata->hpd_gpio) - return; - mutex_lock(&ddata->hpd_lock); ddata->hpd_cb = NULL; ddata->hpd_cb_data = NULL; mutex_unlock(&ddata->hpd_lock); } -static void dvic_enable_hpd(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - - if (!ddata->hpd_gpio) - return; - - mutex_lock(&ddata->hpd_lock); - ddata->hpd_enabled = true; - mutex_unlock(&ddata->hpd_lock); -} - -static void dvic_disable_hpd(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - - if (!ddata->hpd_gpio) - return; - - mutex_lock(&ddata->hpd_lock); - ddata->hpd_enabled = false; - mutex_unlock(&ddata->hpd_lock); -} - -static struct omap_dss_driver dvic_driver = { +static const struct omap_dss_device_ops dvic_ops = { .connect = dvic_connect, .disconnect = dvic_disconnect, .enable = dvic_enable, .disable = dvic_disable, - .set_timings = dvic_set_timings, - .get_timings = dvic_get_timings, - .check_timings = dvic_check_timings, - .read_edid = dvic_read_edid, .detect = dvic_detect, .register_hpd_cb = dvic_register_hpd_cb, .unregister_hpd_cb = dvic_unregister_hpd_cb, - .enable_hpd = dvic_enable_hpd, - .disable_hpd = dvic_disable_hpd, }; static irqreturn_t dvic_hpd_isr(int irq, void *data) @@ -396,28 +270,24 @@ static int dvic_probe(struct platform_device *pdev) if (r) return r; - ddata->vm = dvic_default_vm; - dssdev = &ddata->dssdev; - dssdev->driver = &dvic_driver; + dssdev->ops = &dvic_ops; dssdev->dev = &pdev->dev; dssdev->type = OMAP_DISPLAY_TYPE_DVI; dssdev->owner = THIS_MODULE; - dssdev->panel.vm = dvic_default_vm; + dssdev->of_ports = BIT(0); - r = omapdss_register_display(dssdev); - if (r) { - dev_err(&pdev->dev, "Failed to register panel\n"); - goto err_reg; - } - - return 0; + if (ddata->hpd_gpio) + dssdev->ops_flags |= OMAP_DSS_DEVICE_OP_DETECT + | OMAP_DSS_DEVICE_OP_HPD; + if (ddata->i2c_adapter) + dssdev->ops_flags |= OMAP_DSS_DEVICE_OP_DETECT + | OMAP_DSS_DEVICE_OP_EDID; -err_reg: - i2c_put_adapter(ddata->i2c_adapter); - mutex_destroy(&ddata->hpd_lock); + omapdss_display_init(dssdev); + omapdss_device_register(dssdev); - return r; + return 0; } static int __exit dvic_remove(struct platform_device *pdev) @@ -425,10 +295,9 @@ static int __exit dvic_remove(struct platform_device *pdev) struct panel_drv_data *ddata = platform_get_drvdata(pdev); struct omap_dss_device *dssdev = &ddata->dssdev; - omapdss_unregister_display(&ddata->dssdev); + omapdss_device_unregister(&ddata->dssdev); dvic_disable(dssdev); - dvic_disconnect(dssdev); i2c_put_adapter(ddata->i2c_adapter); diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index ca30ed9da7eb..e602fa4a50a4 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c @@ -10,95 +10,41 @@ */ #include <linux/gpio/consumer.h> -#include <linux/slab.h> #include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/of.h> -#include <linux/of_gpio.h> #include <linux/mutex.h> - -#include <drm/drm_edid.h> +#include <linux/platform_device.h> +#include <linux/slab.h> #include "../dss/omapdss.h" -static const struct videomode hdmic_default_vm = { - .hactive = 640, - .vactive = 480, - .pixelclock = 25175000, - .hsync_len = 96, - .hfront_porch = 16, - .hback_porch = 48, - .vsync_len = 2, - .vfront_porch = 11, - .vback_porch = 31, - - .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW, -}; - struct panel_drv_data { struct omap_dss_device dssdev; - struct omap_dss_device *in; void (*hpd_cb)(void *cb_data, enum drm_connector_status status); void *hpd_cb_data; - bool hpd_enabled; struct mutex hpd_lock; struct device *dev; - struct videomode vm; - - int hpd_gpio; + struct gpio_desc *hpd_gpio; }; #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) -static int hdmic_connect(struct omap_dss_device *dssdev) +static int hdmic_connect(struct omap_dss_device *src, + struct omap_dss_device *dst) { - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in; - int r; - - dev_dbg(ddata->dev, "connect\n"); - - if (omapdss_device_is_connected(dssdev)) - return 0; - - in = omapdss_of_find_source_for_first_ep(ddata->dev->of_node); - if (IS_ERR(in)) { - dev_err(ddata->dev, "failed to find video source\n"); - return PTR_ERR(in); - } - - r = in->ops.hdmi->connect(in, dssdev); - if (r) { - omap_dss_put_device(in); - return r; - } - - ddata->in = in; return 0; } -static void hdmic_disconnect(struct omap_dss_device *dssdev) +static void hdmic_disconnect(struct omap_dss_device *src, + struct omap_dss_device *dst) { - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - dev_dbg(ddata->dev, "disconnect\n"); - - if (!omapdss_device_is_connected(dssdev)) - return; - - in->ops.hdmi->disconnect(in, dssdev); - - omap_dss_put_device(in); - ddata->in = NULL; } static int hdmic_enable(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; + struct omap_dss_device *src = dssdev->src; int r; dev_dbg(ddata->dev, "enable\n"); @@ -109,9 +55,7 @@ static int hdmic_enable(struct omap_dss_device *dssdev) if (omapdss_device_is_enabled(dssdev)) return 0; - in->ops.hdmi->set_timings(in, &ddata->vm); - - r = in->ops.hdmi->enable(in); + r = src->ops->enable(src); if (r) return r; @@ -123,171 +67,58 @@ static int hdmic_enable(struct omap_dss_device *dssdev) static void hdmic_disable(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; + struct omap_dss_device *src = dssdev->src; dev_dbg(ddata->dev, "disable\n"); if (!omapdss_device_is_enabled(dssdev)) return; - in->ops.hdmi->disable(in); + src->ops->disable(src); dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } -static void hdmic_set_timings(struct omap_dss_device *dssdev, - struct videomode *vm) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - ddata->vm = *vm; - dssdev->panel.vm = *vm; - - in->ops.hdmi->set_timings(in, vm); -} - -static void hdmic_get_timings(struct omap_dss_device *dssdev, - struct videomode *vm) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - - *vm = ddata->vm; -} - -static int hdmic_check_timings(struct omap_dss_device *dssdev, - struct videomode *vm) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - return in->ops.hdmi->check_timings(in, vm); -} - -static int hdmic_read_edid(struct omap_dss_device *dssdev, - u8 *edid, int len) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - return in->ops.hdmi->read_edid(in, edid, len); -} - static bool hdmic_detect(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - bool connected; - - if (gpio_is_valid(ddata->hpd_gpio)) - connected = gpio_get_value_cansleep(ddata->hpd_gpio); - else - connected = in->ops.hdmi->detect(in); - if (!connected && in->ops.hdmi->lost_hotplug) - in->ops.hdmi->lost_hotplug(in); - return connected; + + return gpiod_get_value_cansleep(ddata->hpd_gpio); } -static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev, - void (*cb)(void *cb_data, +static void hdmic_register_hpd_cb(struct omap_dss_device *dssdev, + void (*cb)(void *cb_data, enum drm_connector_status status), - void *cb_data) + void *cb_data) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - if (gpio_is_valid(ddata->hpd_gpio)) { - mutex_lock(&ddata->hpd_lock); - ddata->hpd_cb = cb; - ddata->hpd_cb_data = cb_data; - mutex_unlock(&ddata->hpd_lock); - return 0; - } else if (in->ops.hdmi->register_hpd_cb) { - return in->ops.hdmi->register_hpd_cb(in, cb, cb_data); - } - return -ENOTSUPP; + mutex_lock(&ddata->hpd_lock); + ddata->hpd_cb = cb; + ddata->hpd_cb_data = cb_data; + mutex_unlock(&ddata->hpd_lock); } static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev) { struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - if (gpio_is_valid(ddata->hpd_gpio)) { - mutex_lock(&ddata->hpd_lock); - ddata->hpd_cb = NULL; - ddata->hpd_cb_data = NULL; - mutex_unlock(&ddata->hpd_lock); - } else if (in->ops.hdmi->unregister_hpd_cb) { - in->ops.hdmi->unregister_hpd_cb(in); - } -} - -static void hdmic_enable_hpd(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - if (gpio_is_valid(ddata->hpd_gpio)) { - mutex_lock(&ddata->hpd_lock); - ddata->hpd_enabled = true; - mutex_unlock(&ddata->hpd_lock); - } else if (in->ops.hdmi->enable_hpd) { - in->ops.hdmi->enable_hpd(in); - } -} - -static void hdmic_disable_hpd(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = to_panel_data(dssdev); - struct omap_dss_device *in = ddata->in; - - if (gpio_is_valid(ddata->hpd_gpio)) { - mutex_lock(&ddata->hpd_lock); - ddata->hpd_enabled = false; - mutex_unlock(&ddata->hpd_lock); |