Skip to content

Commit

Permalink
Merge tag 'omapdrm-4.17' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/tomba/linux into drm-next

omapdrm patches for v4.17

* Fix sparse warnings from omapdrm
* HPD support for DVI connector
* Big cleanup to remove static variables

* tag 'omapdrm-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (69 commits)
  drm/omap: fix compile error when DPI is disabled
  drm/omap: fix compile error when debugfs is disabled
  drm: omapdrm: displays: panel-dsi-cm: Fix field access before set
  drm/omap: cleanup color space conversion
  drm/omap: Allow HDMI audio setup even if we do not have video configured
  drm/omap: fix maximum sizes
  drm/omap: add writeback funcs to dispc_ops
  drm/omap: fix scaling limits for WB
  drm/omap: fix WB height with interlace
  drm/omap: fix WBDELAYCOUNT with interlace
  drm/omap: fix WBDELAYCOUNT for HDMI
  drm/omap: set WB channel-in in wb_setup()
  drm/omap: Add pclk setting case when channel is DSS_WB
  drm/omap: dispc: disp_wb_setup to check return code
  drm/omap: remove leftover enums
  dt-bindings: display: add HPD gpio to DVI connector
  drm/omap: add HPD support to connector-dvi
  drm/omap: Init fbdev emulation only when we have displays
  drm/omap: cleanup fbdev init/free
  drm/omap: fix omap_fbdev_free() when omap_fbdev_create() wasn't called
  ...
  • Loading branch information
Dave Airlie committed Mar 21, 2018
2 parents b65bd40 + 037f031 commit 78230c4
Show file tree
Hide file tree
Showing 55 changed files with 4,277 additions and 3,831 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Optional properties:
- analog: the connector has DVI analog pins
- digital: the connector has DVI digital pins
- dual-link: the connector has pins for DVI dual-link
- hpd-gpios: HPD GPIO number

Required nodes:
- Video port for DVI input
Expand Down
50 changes: 15 additions & 35 deletions drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,32 @@ static const struct videomode tvc_pal_vm = {
DISPLAY_FLAGS_VSYNC_LOW,
};

static const struct of_device_id tvc_of_match[];

#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)

static int tvc_connect(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 *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)
if (r) {
omap_dss_put_device(in);
return r;
}

ddata->in = in;
return 0;
}

Expand All @@ -73,6 +80,9 @@ static void tvc_disconnect(struct omap_dss_device *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)
Expand Down Expand Up @@ -175,43 +185,19 @@ static struct omap_dss_driver tvc_driver = {
.set_wss = tvc_set_wss,
};

static int tvc_probe_of(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct device_node *node = pdev->dev.of_node;
struct omap_dss_device *in;

in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&pdev->dev, "failed to find video source\n");
return PTR_ERR(in);
}

ddata->in = in;

return 0;
}

static int tvc_probe(struct platform_device *pdev)
{
struct panel_drv_data *ddata;
struct omap_dss_device *dssdev;
int r;

if (!pdev->dev.of_node)
return -ENODEV;

ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;

platform_set_drvdata(pdev, ddata);
ddata->dev = &pdev->dev;

r = tvc_probe_of(pdev);
if (r)
return r;

ddata->vm = tvc_pal_vm;

dssdev = &ddata->dssdev;
Expand All @@ -224,28 +210,22 @@ static int tvc_probe(struct platform_device *pdev)
r = omapdss_register_display(dssdev);
if (r) {
dev_err(&pdev->dev, "Failed to register panel\n");
goto err_reg;
return r;
}

return 0;
err_reg:
omap_dss_put_device(ddata->in);
return r;
}

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;
struct omap_dss_device *in = ddata->in;

omapdss_unregister_display(&ddata->dssdev);

tvc_disable(dssdev);
tvc_disconnect(dssdev);

omap_dss_put_device(in);

return 0;
}

Expand Down
146 changes: 129 additions & 17 deletions drivers/gpu/drm/omapdrm/displays/connector-dvi.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* the Free Software Foundation.
*/

#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/platform_device.h>
Expand Down Expand Up @@ -44,23 +45,40 @@ struct panel_drv_data {
struct videomode vm;

struct i2c_adapter *i2c_adapter;

struct gpio_desc *hpd_gpio;

void (*hpd_cb)(void *cb_data, enum drm_connector_status status);
void *hpd_cb_data;
bool hpd_enabled;
/* mutex for hpd fields above */
struct mutex hpd_lock;
};

#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)

static int dvic_connect(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 *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)
if (r) {
omap_dss_put_device(in);
return r;
}

ddata->in = in;
return 0;
}

Expand All @@ -73,6 +91,9 @@ static void dvic_disconnect(struct omap_dss_device *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)
Expand Down Expand Up @@ -177,6 +198,9 @@ 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;

Expand Down Expand Up @@ -208,6 +232,9 @@ static bool dvic_detect(struct omap_dss_device *dssdev)
unsigned char out;
int r;

if (ddata->hpd_gpio)
return gpiod_get_value_cansleep(ddata->hpd_gpio);

if (!ddata->i2c_adapter)
return true;

Expand All @@ -216,6 +243,60 @@ static bool dvic_detect(struct omap_dss_device *dssdev)
return r == 0;
}

static int 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 = {
.connect = dvic_connect,
.disconnect = dvic_disconnect,
Expand All @@ -229,31 +310,67 @@ static struct omap_dss_driver dvic_driver = {

.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)
{
struct panel_drv_data *ddata = data;

mutex_lock(&ddata->hpd_lock);
if (ddata->hpd_enabled && ddata->hpd_cb) {
enum drm_connector_status status;

if (dvic_detect(&ddata->dssdev))
status = connector_status_connected;
else
status = connector_status_disconnected;

ddata->hpd_cb(ddata->hpd_cb_data, status);
}
mutex_unlock(&ddata->hpd_lock);

return IRQ_HANDLED;
}

static int dvic_probe_of(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct device_node *node = pdev->dev.of_node;
struct omap_dss_device *in;
struct device_node *adapter_node;
struct i2c_adapter *adapter;
struct gpio_desc *gpio;
int r;

in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&pdev->dev, "failed to find video source\n");
return PTR_ERR(in);
gpio = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN);
if (IS_ERR(gpio)) {
dev_err(&pdev->dev, "failed to parse HPD gpio\n");
return PTR_ERR(gpio);
}

ddata->in = in;
ddata->hpd_gpio = gpio;

mutex_init(&ddata->hpd_lock);

if (ddata->hpd_gpio) {
r = devm_request_threaded_irq(&pdev->dev,
gpiod_to_irq(ddata->hpd_gpio), NULL, dvic_hpd_isr,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"DVI HPD", ddata);
if (r)
return r;
}

adapter_node = of_parse_phandle(node, "ddc-i2c-bus", 0);
if (adapter_node) {
adapter = of_get_i2c_adapter_by_node(adapter_node);
of_node_put(adapter_node);
if (adapter == NULL) {
dev_err(&pdev->dev, "failed to parse ddc-i2c-bus\n");
omap_dss_put_device(ddata->in);
return -EPROBE_DEFER;
}

Expand All @@ -275,9 +392,6 @@ static int dvic_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, ddata);

if (!pdev->dev.of_node)
return -ENODEV;

r = dvic_probe_of(pdev);
if (r)
return r;
Expand All @@ -300,9 +414,8 @@ static int dvic_probe(struct platform_device *pdev)
return 0;

err_reg:
omap_dss_put_device(ddata->in);

i2c_put_adapter(ddata->i2c_adapter);
mutex_destroy(&ddata->hpd_lock);

return r;
}
Expand All @@ -311,17 +424,16 @@ 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;
struct omap_dss_device *in = ddata->in;

omapdss_unregister_display(&ddata->dssdev);

dvic_disable(dssdev);
dvic_disconnect(dssdev);

omap_dss_put_device(in);

i2c_put_adapter(ddata->i2c_adapter);

mutex_destroy(&ddata->hpd_lock);

return 0;
}

Expand Down
Loading

0 comments on commit 78230c4

Please sign in to comment.