Commit 78230c46 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'omapdrm-4.17' of git://git.kernel.org/pub/scm/linux/kernel/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
  ...
parents b65bd403 037f0315
......@@ -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
......
......@@ -40,14 +40,12 @@ 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");
......@@ -55,10 +53,19 @@ static int tvc_connect(struct omap_dss_device *dssdev)
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;
}
......@@ -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)
......@@ -175,32 +185,12 @@ 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;
......@@ -208,10 +198,6 @@ static int tvc_probe(struct platform_device *pdev)
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;
......@@ -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;
}
......
......@@ -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>
......@@ -44,6 +45,14 @@ 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)
......@@ -51,16 +60,25 @@ struct panel_drv_data {
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;
}
......@@ -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)
......@@ -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;
......@@ -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;
......@@ -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,
......@@ -229,23 +310,60 @@ 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) {
......@@ -253,7 +371,6 @@ static int dvic_probe_of(struct platform_device *pdev)
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;
}
......@@ -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;
......@@ -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;
}
......@@ -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;
}
......
......@@ -55,7 +55,7 @@ struct panel_drv_data {
static int hdmic_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");
......@@ -63,10 +63,19 @@ static int hdmic_connect(struct omap_dss_device *dssdev)
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)
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
......@@ -81,6 +90,9 @@ static void hdmic_disconnect(struct omap_dss_device *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)
......@@ -302,7 +314,6 @@ static int hdmic_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;
int gpio;
/* HPD GPIO */
......@@ -312,14 +323,6 @@ static int hdmic_probe_of(struct platform_device *pdev)
else
ddata->hpd_gpio = -ENODEV;
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;
}
......@@ -336,9 +339,6 @@ static int hdmic_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
ddata->dev = &pdev->dev;
if (!pdev->dev.of_node)
return -ENODEV;
r = hdmic_probe_of(pdev);
if (r)
return r;
......@@ -349,7 +349,7 @@ static int hdmic_probe(struct platform_device *pdev)
r = devm_gpio_request_one(&pdev->dev, ddata->hpd_gpio,
GPIOF_DIR_IN, "hdmi_hpd");
if (r)
goto err_reg;
return r;
r = devm_request_threaded_irq(&pdev->dev,
gpio_to_irq(ddata->hpd_gpio),
......@@ -358,7 +358,7 @@ static int hdmic_probe(struct platform_device *pdev)
IRQF_ONESHOT,
"hdmic hpd", ddata);
if (r)
goto err_reg;
return r;
}
ddata->vm = hdmic_default_vm;
......@@ -373,28 +373,22 @@ static int hdmic_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 hdmic_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);
hdmic_disable(dssdev);
hdmic_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}
......
......@@ -36,7 +36,7 @@ static int opa362_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
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(dssdev->dev, "connect\n");
......@@ -44,13 +44,22 @@ static int opa362_connect(struct omap_dss_device *dssdev,
if (omapdss_device_is_connected(dssdev))
return -EBUSY;
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.atv->connect(in, dssdev);
if (r)
if (r) {
omap_dss_put_device(in);
return r;
}
dst->src = dssdev;
dssdev->dst = dst;
ddata->in = in;
return 0;
}
......@@ -74,6 +83,9 @@ static void opa362_disconnect(struct omap_dss_device *dssdev,
dssdev->dst = NULL;
in->ops.atv->disconnect(in, &ddata->dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int opa362_enable(struct omap_dss_device *dssdev)
......@@ -171,19 +183,13 @@ static const struct omapdss_atv_ops opa362_atv_ops = {
static int opa362_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct panel_drv_data *ddata;
struct omap_dss_device *dssdev, *in;
struct omap_dss_device *dssdev;
struct gpio_desc *gpio;
int r;
dev_dbg(&pdev->dev, "probe\n");
if (node == NULL) {
dev_err(&pdev->dev, "Unable to find device tree\n");
return -EINVAL;
}
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
......@@ -196,14 +202,6 @@ static int opa362_probe(struct platform_device *pdev)
ddata->enable_gpio = gpio;
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;
dssdev = &ddata->dssdev;
dssdev->ops.atv = &opa362_atv_ops;
dssdev->dev = &pdev->dev;
......@@ -214,20 +212,16 @@ static int opa362_probe(struct platform_device *pdev)
r = omapdss_register_output(dssdev);
if (r) {
dev_err(&pdev->dev, "Failed to register output\n");
goto err_reg;
return r;
}
return 0;
err_reg:
omap_dss_put_device(ddata->in);
return r;
}
static int __exit opa362_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_output(&ddata->dssdev);
......@@ -239,8 +233,6 @@ static int __exit opa362_remove(struct platform_device *pdev)
if (omapdss_device_is_connected(dssdev))
opa362_disconnect(dssdev, dssdev->dst);
omap_dss_put_device(in);
return 0;
}
......
......@@ -32,19 +32,28 @@ static int tfp410_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
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 -EBUSY;
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.dpi->connect(in, dssdev);
if (r)
if (r) {
omap_dss_put_device(in);
return r;
}
dst->src = dssdev;
dssdev->dst = dst;
ddata->in = in;
return 0;
}
......@@ -66,6 +75,9 @@ static void tfp410_disconnect(struct omap_dss_device *dssdev,
dssdev->dst = NULL;
in->ops.dpi->disconnect(in, &ddata->dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int tfp410_enable(struct omap_dss_device *dssdev)
......@@ -165,7 +177,6 @@ static int tfp410_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;
int gpio;
gpio = of_get_named_gpio(node, "powerdown-gpios", 0);
......@@ -178,14 +189,6 @@ static int tfp410_probe_of(struct platform_device *pdev)
return gpio;
}
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;
}
......@@ -201,9 +204,6 @@ static int tfp410_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
if (!pdev->dev.of_node)
return -ENODEV;
r = tfp410_probe_of(pdev);
if (r)
return r;
......@@ -214,7 +214,7 @@ static int tfp410_probe(struct platform_device *pdev)
if (r) {
dev_err(&pdev->dev, "Failed to request PD GPIO %d\n",
ddata->pd_gpio);
goto err_gpio;
return r;
}
}
......@@ -229,21 +229,16 @@ static int tfp410_probe(struct platform_device *pdev)
r = omapdss_register_output(dssdev);
if (r) {
dev_err(&pdev->dev, "Failed to register output\n");
goto err_reg;
return r;
}
return 0;
err_reg:
err_gpio:
omap_dss_put_device(ddata->in);
return r;
}
static int __exit tfp410_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_output(&ddata->dssdev);
......@@ -255,8 +250,6 @@ static int __exit tfp410_remove(struct platform_device *pdev)
if (omapdss_device_is_connected(dssdev))
tfp410_disconnect(dssdev, dssdev->dst);
omap_dss_put_device(in);
return 0;
}
......
......@@ -40,12 +40,20 @@ static int tpd_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *in = ddata->in;
struct omap_dss_device *in;
int r;
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.hdmi->connect(in, dssdev);
if (r)
if (r) {
omap_dss_put_device(in);
return r;
}
dst->src = dssdev;
dssdev->dst = dst;
......@@ -56,6 +64,7 @@ static int tpd_connect(struct omap_dss_device *dssdev,
/* DC-DC converter needs at max 300us to get to 90% of 5V */
udelay(300);
ddata->in = in;
return 0;
}
......@@ -77,6 +86,9 @@ static void tpd_disconnect(struct omap_dss_device *dssdev,
dssdev->dst = NULL;
in->ops.hdmi->disconnect(in, &ddata->dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int tpd_enable(struct omap_dss_device *dssdev)
......@@ -269,23 +281,6 @@ static irqreturn_t tpd_hpd_isr(int irq, void *data)
return IRQ_HANDLED;
}
static int tpd_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 tpd_probe(struct platform_device *pdev)
{
struct omap_dss_device *in, *dssdev;
......@@ -299,37 +294,24 @@ static int tpd_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
if (!pdev->dev.of_node)
return -ENODEV;
r = tpd_probe_of(pdev);
if (r)
return r;
gpio = devm_gpiod_get_index_optional(&pdev->dev, NULL, 0,
GPIOD_OUT_LOW);
if (IS_ERR(gpio)) {
r = PTR_ERR(gpio);
goto err_gpio;
}
if (IS_ERR(gpio))
return PTR_ERR(gpio);
ddata->ct_cp_hpd_gpio = gpio;
gpio = devm_gpiod_get_index_optional(&pdev->dev, NULL, 1,
GPIOD_OUT_LOW);
if (IS_ERR(gpio)) {
r = PTR_ERR(gpio);
goto err_gpio;
}
if (IS_ERR(gpio))
return PTR_ERR(gpio);
ddata->ls_oe_gpio = gpio;
gpio = devm_gpiod_get_index(&pdev->dev, NULL, 2,
GPIOD_IN);
if (IS_ERR(gpio)) {
r = PTR_ERR(gpio);
goto err_gpio;
}
if (IS_ERR(gpio))
return PTR_ERR(gpio);
ddata->hpd_gpio = gpio;
......@@ -340,7 +322,7 @@ static int tpd_probe(struct platform_device *pdev)
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"tpd12s015 hpd", ddata);
if (r)
goto err_gpio;
return r;
dssdev = &ddata->dssdev;
dssdev->ops.hdmi = &tpd_hdmi_ops;
......@@ -355,21 +337,16 @@ static int tpd_probe(struct platform_device *pdev)
r = omapdss_register_output(dssdev);
if (r) {
dev_err(&pdev->dev, "Failed to register output\n");
goto err_reg;
return r;
}
return 0;
err_reg:
err_gpio:
omap_dss_put_device(ddata->in);
return r;
}
static int __exit tpd_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_output(&ddata->dssdev);
......@@ -381,8 +358,6 @@ static int __exit tpd_remove(struct platform_device *pdev)
if (omapdss_device_is_connected(dssdev))
tpd_disconnect(dssdev, dssdev->dst);
omap_dss_put_device(in);
return 0;
}
......
......@@ -38,16 +38,25 @@ struct panel_drv_data {
static int panel_dpi_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.dpi->connect(in, dssdev);
if (r)
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
......@@ -60,6 +69,9 @@ static void panel_dpi_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dpi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int panel_dpi_enable(struct omap_dss_device *dssdev)
......@@ -157,7 +169,6 @@ static int panel_dpi_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;
int r;
struct display_timing timing;
struct gpio_desc *gpio;
......@@ -195,14 +206,6 @@ static int panel_dpi_probe_of(struct platform_device *pdev)
videomode_from_timing(&timing, &ddata->vm);
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;
}
......@@ -212,9 +215,6 @@ static int panel_dpi_probe(struct platform_device *pdev)
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 == NULL)
return -ENOMEM;
......@@ -235,29 +235,22 @@ static int panel_dpi_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 panel_dpi_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(dssdev);
panel_dpi_disable(dssdev);
panel_dpi_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}
......
......@@ -86,7 +86,7 @@ struct panel_drv_data {
struct workqueue_struct *workqueue;
bool ulps_enabled;
unsigned ulps_timeout;
unsigned int ulps_timeout;
struct delayed_work ulps_work;
};
......@@ -513,7 +513,7 @@ static ssize_t dsicm_show_ulps(struct device *dev,
{
struct platform_device *pdev = to_platform_device(dev);
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
unsigned t;
unsigned int t;
mutex_lock(&ddata->lock);
t = ddata->ulps_enabled;
......@@ -560,7 +560,7 @@ static ssize_t dsicm_show_ulps_timeout(struct device *dev,
{
struct platform_device *pdev = to_platform_device(dev);
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
unsigned t;
unsigned int t;
mutex_lock(&ddata->lock);
t = ddata->ulps_timeout;
......@@ -759,37 +759,46 @@ static int dsicm_panel_reset(struct panel_drv_data *ddata)
static int dsicm_connect(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *in = ddata->in;
struct device *dev = &ddata->pdev->dev;
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.dsi->connect(in, dssdev);
if (r) {
dev_err(dev, "Failed to connect to video source\n");
return r;
goto err_connect;
}
r = in->ops.dsi->request_vc(ddata->in, &ddata->channel);
r = in->ops.dsi->request_vc(in, &ddata->channel);
if (r) {
dev_err(dev, "failed to get virtual channel\n");
goto err_req_vc;
}
r = in->ops.dsi->set_vc_id(ddata->in, ddata->channel, TCH);
r = in->ops.dsi->set_vc_id(in, ddata->channel, TCH);
if (r) {
dev_err(dev, "failed to set VC_ID\n");
goto err_vc_id;
}
ddata->in = in;
return 0;
err_vc_id:
in->ops.dsi->release_vc(ddata->in, ddata->channel);
in->ops.dsi->release_vc(in, ddata->channel);
err_req_vc:
in->ops.dsi->disconnect(in, dssdev);
err_connect:
omap_dss_put_device(in);
return r;
}
......@@ -803,6 +812,9 @@ static void dsicm_disconnect(struct omap_dss_device *dssdev)
in->ops.dsi->release_vc(in, ddata->channel);
in->ops.dsi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int dsicm_enable(struct omap_dss_device *dssdev)
......@@ -1064,7 +1076,7 @@ static int dsicm_memory_read(struct omap_dss_device *dssdev,
int r;
int first = 1;
int plen;
unsigned buf_used = 0;
unsigned int buf_used = 0;
if (size < w * h * 3)
return -ENOMEM;
......@@ -1223,7 +1235,6 @@ static int dsicm_probe_of(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
struct device_node *backlight;
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct omap_dss_device *in;
struct display_timing timing;
int err;
......@@ -1259,12 +1270,6 @@ static int dsicm_probe_of(struct platform_device *pdev)
ddata->height_mm = 0;
of_property_read_u32(node, "height-mm", &ddata->height_mm);
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->vpnl = devm_regulator_get_optional(&pdev->dev, "vpnl");
if (IS_ERR(ddata->vpnl)) {
err = PTR_ERR(ddata->vpnl);
......@@ -1281,8 +1286,6 @@ static int dsicm_probe_of(struct platform_device *pdev)
ddata->vddi = NULL;
}
ddata->in = in;
backlight = of_parse_phandle(node, "backlight", 0);
if (backlight) {
ddata->extbldev = of_find_backlight_by_node(backlight);
......@@ -1317,9 +1320,6 @@ static int dsicm_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
ddata->pdev = pdev;
if (!pdev->dev.of_node)
return -ENODEV;
ddata->vm.hactive = 864;
ddata->vm.vactive = 480;
ddata->vm.pixelclock = 864 * 480 * 60;
......@@ -1424,8 +1424,6 @@ static int __exit dsicm_remove(struct platform_device *pdev)
if (ddata->extbldev)
put_device(&ddata->extbldev->dev);
omap_dss_put_device(ddata->in);
dsicm_cancel_ulps_work(ddata);
destroy_workqueue(ddata->workqueue);
......
......@@ -119,18 +119,27 @@ static void init_lb035q02_panel(struct spi_device *spi)
static int lb035q02_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.dpi->connect(in, dssdev);
if (r)
if (r) {
omap_dss_put_device(in);
return r;
}
init_lb035q02_panel(ddata->spi);
ddata->in = in;
return 0;
}
......@@ -143,6 +152,9 @@ static void lb035q02_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dpi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int lb035q02_enable(struct omap_dss_device *dssdev)
......@@ -230,9 +242,7 @@ static struct omap_dss_driver lb035q02_ops = {
static int lb035q02_probe_of(struct spi_device *spi)
{
struct device_node *node = spi->dev.of_node;
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *in;
struct gpio_desc *gpio;
gpio = devm_gpiod_get(&spi->dev, "enable", GPIOD_OUT_LOW);
......@@ -243,14 +253,6 @@ static int lb035q02_probe_of(struct spi_device *spi)
ddata->enable_gpio = gpio;
in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&spi->dev, "failed to find video source\n");
return PTR_ERR(in);
}
ddata->in = in;
return 0;
}
......@@ -268,9 +270,6 @@ static int lb035q02_panel_spi_probe(struct spi_device *spi)
ddata->spi = spi;
if (!spi->dev.of_node)
return -ENODEV;
r = lb035q02_probe_of(spi);
if (r)
return r;
......@@ -287,29 +286,22 @@ static int lb035q02_panel_spi_probe(struct spi_device *spi)
r = omapdss_register_display(dssdev);
if (r) {
dev_err(&spi->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 lb035q02_panel_spi_remove(struct spi_device *spi)
{
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
omapdss_unregister_display(dssdev);
lb035q02_disable(dssdev);
lb035q02_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}
......
......@@ -115,16 +115,25 @@ static int init_nec_8048_wvga_lcd(struct spi_device *spi)
static int nec_8048_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.dpi->connect(in, dssdev);
if (r)
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
......@@ -137,6 +146,9 @@ static void nec_8048_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dpi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int nec_8048_enable(struct omap_dss_device *dssdev)
......@@ -226,7 +238,6 @@ static int nec_8048_probe_of(struct spi_device *spi)
{
struct device_node *node = spi->dev.of_node;
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *in;
int gpio;
gpio = of_get_named_gpio(node, "reset-gpios", 0);
......@@ -239,14 +250,6 @@ static int nec_8048_probe_of(struct spi_device *spi)
/* XXX the panel spec doesn't mention any QVGA pin?? */
ddata->qvga_gpio = -ENOENT;
in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&spi->dev, "failed to find video source\n");
return PTR_ERR(in);
}
ddata->in = in;
return 0;
}
......@@ -277,9 +280,6 @@ static int nec_8048_probe(struct spi_device *spi)
ddata->spi = spi;
if (!spi->dev.of_node)
return -ENODEV;
r = nec_8048_probe_of(spi);
if (r)
return r;
......@@ -288,14 +288,14 @@ static int nec_8048_probe(struct spi_device *spi)
r = devm_gpio_request_one(&spi->dev, ddata->qvga_gpio,
GPIOF_OUT_INIT_HIGH, "lcd QVGA");
if (r)
goto err_gpio;
return r;
}
if (gpio_is_valid(ddata->res_gpio)) {
r = devm_gpio_request_one(&spi->dev, ddata->res_gpio,
GPIOF_OUT_INIT_LOW, "lcd RES");
if (r)
goto err_gpio;
return r;
}
ddata->vm = nec_8048_panel_vm;
......@@ -310,22 +310,16 @@ static int nec_8048_probe(struct spi_device *spi)
r = omapdss_register_display(dssdev);
if (r) {
dev_err(&spi->dev, "Failed to register panel\n");
goto err_reg;
return r;
}
return 0;
err_reg:
err_gpio:
omap_dss_put_device(ddata->in);
return r;
}
static int nec_8048_remove(struct spi_device *spi)
{
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
......@@ -334,8 +328,6 @@ static int nec_8048_remove(struct spi_device *spi)
nec_8048_disable(dssdev);
nec_8048_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}
......
......@@ -61,16 +61,25 @@ static const struct videomode sharp_ls_vm = {
static int sharp_ls_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.dpi->connect(in, dssdev);
if (r)
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
......@@ -83,6 +92,9 @@ static void sharp_ls_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dpi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int sharp_ls_enable(struct omap_dss_device *dssdev)
......@@ -210,8 +222,6 @@ static int sharp_ls_get_gpio_of(struct device *dev, int index, int val,
static int sharp_ls_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;
int r;
ddata->vcc = devm_regulator_get(&pdev->dev, "envdd");
......@@ -245,14 +255,6 @@ static int sharp_ls_probe_of(struct platform_device *pdev)
if (r)
return 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);
}
ddata->in = in;
return 0;
}
......@@ -268,9 +270,6 @@ static int sharp_ls_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
if (!pdev->dev.of_node)
return -ENODEV;
r = sharp_ls_probe_of(pdev);
if (r)
return r;
......@@ -287,29 +286,22 @@ static int sharp_ls_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 sharp_ls_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(dssdev);
sharp_ls_disable(dssdev);
sharp_ls_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}
......
......@@ -216,12 +216,12 @@ static void set_display_state(struct panel_drv_data *ddata, int enabled)
static int panel_enabled(struct panel_drv_data *ddata)
{
__be32 v;
u32 disp_status;
int enabled;
acx565akm_read(ddata, MIPID_CMD_READ_DISP_STATUS,
(u8 *)&disp_status, 4);
disp_status = __be32_to_cpu(disp_status);
acx565akm_read(ddata, MIPID_CMD_READ_DISP_STATUS, (u8 *)&v, 4);
disp_status = __be32_to_cpu(v);
enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10));
dev_dbg(&ddata->spi->dev,
"LCD panel %senabled by bootloader (status 0x%04x)\n",
......@@ -289,7 +289,7 @@ static void enable_backlight_ctrl(struct panel_drv_data *ddata, int enable)
acx565akm_write(ddata, MIPID_CMD_WRITE_CTRL_DISP, (u8 *)&ctrl, 2);
}
static void set_cabc_mode(struct panel_drv_data *ddata, unsigned mode)
static void set_cabc_mode(struct panel_drv_data *ddata, unsigned int mode)
{
u16 cabc_ctrl;
......@@ -303,12 +303,12 @@ static void set_cabc_mode(struct panel_drv_data *ddata, unsigned mode)
acx565akm_write(ddata, MIPID_CMD_WRITE_CABC, (u8 *)&cabc_ctrl, 2);
}
static unsigned get_cabc_mode(struct panel_drv_data *ddata)
static unsigned int get_cabc_mode(struct panel_drv_data *ddata)
{
return ddata->cabc_mode;
}
static unsigned get_hw_cabc_mode(struct panel_drv_data *ddata)
static unsigned int get_hw_cabc_mode(struct panel_drv_data *ddata)
{
u8 cabc_ctrl;
......@@ -510,16 +510,25 @@ static const struct attribute_group bldev_attr_group = {
static int acx565akm_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.sdi->connect(in, dssdev);
if (r)
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
......@@ -532,6 +541,9 @@ static void acx565akm_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.sdi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
......@@ -700,12 +712,6 @@ static int acx565akm_probe_of(struct spi_device *spi)
ddata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
ddata->in = omapdss_of_find_source_for_first_ep(np);
if (IS_ERR(ddata->in)) {
dev_err(&spi->dev, "failed to find video source\n");
return PTR_ERR(ddata->in);
}
return 0;
}
......@@ -720,9 +726,6 @@ static int acx565akm_probe(struct spi_device *spi)
dev_dbg(&spi->dev, "%s\n", __func__);
if (!spi->dev.of_node)
return -ENODEV;
spi->mode = SPI_MODE_3;
ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
......@@ -826,7 +829,6 @@ static int acx565akm_probe(struct spi_device *spi)
err_reg_bl:
err_detect:
err_gpio:
omap_dss_put_device(ddata->in);
return r;
}
......@@ -834,7 +836,6 @@ static int acx565akm_remove(struct spi_device *spi)
{
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
......@@ -846,8 +847,6 @@ static int acx565akm_remove(struct spi_device *spi)
acx565akm_disable(dssdev);
acx565akm_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}
......
......@@ -169,16 +169,25 @@ enum jbt_register {
static int td028ttec1_panel_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.dpi->connect(in, dssdev);
if (r)
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
......@@ -191,6 +200,9 @@ static void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dpi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
......@@ -362,23 +374,6 @@ static struct omap_dss_driver td028ttec1_ops = {
.check_timings = td028ttec1_panel_check_timings,
};
static int td028ttec1_probe_of(struct spi_device *spi)
{
struct device_node *node = spi->dev.of_node;
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *in;
in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&spi->dev, "failed to find video source\n");
return PTR_ERR(in);
}
ddata->in = in;
return 0;
}
static int td028ttec1_panel_probe(struct spi_device *spi)
{
struct panel_drv_data *ddata;
......@@ -404,13 +399,6 @@ static int td028ttec1_panel_probe(struct spi_device *spi)
ddata->spi_dev = spi;
if (!spi->dev.of_node)
return -ENODEV;
r = td028ttec1_probe_of(spi);
if (r)
return r;
ddata->vm = td028ttec1_panel_vm;
dssdev = &ddata->dssdev;
......@@ -423,21 +411,16 @@ static int td028ttec1_panel_probe(struct spi_device *spi)
r = omapdss_register_display(dssdev);
if (r) {
dev_err(&spi->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 td028ttec1_panel_remove(struct spi_device *spi)
{
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
dev_dbg(&ddata->spi_dev->dev, "%s\n", __func__);
......@@ -446,8 +429,6 @@ static int td028ttec1_panel_remove(struct spi_device *spi)
td028ttec1_panel_disable(dssdev);
td028ttec1_panel_disconnect(dssdev);
omap_dss_put_device(in);
return 0;
}
......
......@@ -340,16 +340,25 @@ static void tpo_td043_power_off(struct panel_drv_data *ddata)
static int tpo_td043_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.dpi->connect(in, dssdev);
if (r)
if (r) {
omap_dss_put_device(in);
return r;
}
ddata->in = in;
return 0;
}
......@@ -362,6 +371,9 @@ static void tpo_td043_disconnect(struct omap_dss_device *dssdev)
return;
in->ops.dpi->disconnect(in, dssdev);
omap_dss_put_device(in);
ddata->in = NULL;
}
static int tpo_td043_enable(struct omap_dss_device *dssdev)
......@@ -463,7 +475,6 @@ static int tpo_td043_probe_of(struct spi_device *spi)
{
struct device_node *node = spi->dev.of_node;
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *in;
int gpio;
gpio = of_get_named_gpio(node, "reset-gpios", 0);
......@@ -473,14 +484,6 @@ static int tpo_td043_probe_of(struct spi_device *spi)
}
ddata->nreset_gpio = gpio;
in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&spi->dev, "failed to find video source\n");
return PTR_ERR(in);
}
ddata->in = in;
return 0;
}
......@@ -509,9 +512,6 @@ static int tpo_td043_probe(struct spi_device *spi)
ddata->spi = spi;
if (!spi->dev.of_node)
return -ENODEV;
r = tpo_td043_probe_of(spi);
if (r)
return r;
......@@ -564,7 +564,6 @@ static int tpo_td043_probe(struct spi_device *spi)
err_sysfs:
err_gpio_req:
err_regulator:
omap_dss_put_device(ddata->in);
return r;
}
......@@ -572,7 +571,6 @@ static int tpo_td043_remove(struct spi_device *spi)
{
struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
struct omap_dss_device *dssdev = &ddata->dssdev;
struct omap_dss_device *in = ddata->in;
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
......@@ -581,8 +579,6 @@ static int tpo_td043_remove(struct spi_device *spi)
tpo_td043_disable(dssdev);
tpo_td043_disconnect(dssdev);
omap_dss_put_device(in);
sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group);
return 0;
......
......@@ -18,10 +18,11 @@
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/list.h>
#include "dss.h"
#include "omapdss.h"
static bool dss_initialized;
static const struct dispc_ops *ops;
static struct dss_device *dss_device;
static struct list_head omapdss_comp_list;
......@@ -31,27 +32,27 @@ struct omapdss_comp_node {
bool dss_core_component;
};
void omapdss_set_is_initialized(bool set)
struct dss_device *omapdss_get_dss(void)
{
dss_initialized = set;
return dss_device;
}
EXPORT_SYMBOL(omapdss_set_is_initialized);
EXPORT_SYMBOL(omapdss_get_dss);
bool omapdss_is_initialized(void)
void omapdss_set_dss(struct dss_device *dss)
{
return dss_initialized;
dss_device = dss;
}
EXPORT_SYMBOL(omapdss_is_initialized);
EXPORT_SYMBOL(omapdss_set_dss);
void dispc_set_ops(const struct dispc_ops *o)
struct dispc_device *dispc_get_dispc(struct dss_device *dss)
{
ops = o;
return dss->dispc;
}
EXPORT_SYMBOL(dispc_set_ops);
EXPORT_SYMBOL(dispc_get_dispc);
const struct dispc_ops *dispc_get_ops(void)
const struct dispc_ops *dispc_get_ops(struct dss_device *dss)
{
return ops;
return dss->dispc_ops;
}
EXPORT_SYMBOL(dispc_get_ops);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -28,12 +28,11 @@
#include "omapdss.h"
void omapdss_default_get_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
static void omapdss_default_get_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
{
*vm = dssdev->panel.vm;
}
EXPORT_SYMBOL(omapdss_default_get_timings);
static LIST_HEAD(panel_list);
static DEFINE_MUTEX(panel_list_mutex);
......
......@@ -38,6 +38,7 @@
struct dpi_data {
struct platform_device *pdev;
enum dss_model dss_model;
struct dss_device *dss;
struct regulator *vdds_dsi_reg;
enum dss_clk_source clk_src;
......@@ -57,7 +58,8 @@ static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device *dssdev)
return container_of(dssdev, struct dpi_data, output);
}
static enum dss_clk_source dpi_get_clk_src_dra7xx(enum omap_channel channel)
static enum dss_clk_source dpi_get_clk_src_dra7xx(struct dpi_data *dpi,
enum omap_channel channel)
{
/*
* Possible clock sources:
......@@ -69,23 +71,23 @@ static enum dss_clk_source dpi_get_clk_src_dra7xx(enum omap_channel channel)
switch (channel) {
case OMAP_DSS_CHANNEL_LCD:
{
if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_1))
if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_1))
return DSS_CLK_SRC_PLL1_1;
break;
}
case OMAP_DSS_CHANNEL_LCD2:
{
if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3))
if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_3))
return DSS_CLK_SRC_PLL1_3;
if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_3))
if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL2_3))
return DSS_CLK_SRC_PLL2_3;
break;
}
case OMAP_DSS_CHANNEL_LCD3:
{
if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_1))
if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL2_1))
return DSS_CLK_SRC_PLL2_1;
if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3))
if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_3))
return DSS_CLK_SRC_PLL1_3;
break;
}
......@@ -132,7 +134,7 @@ static enum dss_clk_source dpi_get_clk_src(struct dpi_data *dpi)
}
case DSS_MODEL_DRA7:
return dpi_get_clk_src_dra7xx(channel);
return dpi_get_clk_src_dra7xx(dpi, channel);
default:
return DSS_CLK_SRC_FCK;
......@@ -141,7 +143,7 @@ static enum dss_clk_source dpi_get_clk_src(struct dpi_data *dpi)
struct dpi_clk_calc_ctx {
struct dss_pll *pll;
unsigned clkout_idx;
unsigned int clkout_idx;
/* inputs */
......@@ -189,8 +191,9 @@ static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc;
ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc;
return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max,
dpi_calc_dispc_cb, ctx);
return dispc_div_calc(ctx->pll->dss->dispc, dispc,
ctx->pck_min, ctx->pck_max,
dpi_calc_dispc_cb, ctx);
}
......@@ -206,7 +209,7 @@ static bool dpi_calc_pll_cb(int n, int m, unsigned long fint,
ctx->pll_cinfo.clkdco = clkdco;
return dss_pll_hsdiv_calc_a(ctx->pll, clkdco,
ctx->pck_min, dss_get_max_fck_rate(),
ctx->pck_min, dss_get_max_fck_rate(ctx->pll->dss),
dpi_calc_hsdiv_cb, ctx);
}
......@@ -216,8 +219,9 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
ctx->fck = fck;
return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max,
dpi_calc_dispc_cb, ctx);
return dispc_div_calc(ctx->pll->dss->dispc, fck,
ctx->pck_min, ctx->pck_max,
dpi_calc_dispc_cb, ctx);
}
static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned long pck,
......@@ -255,7 +259,8 @@ static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned long pck,
}
}
static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
static bool dpi_dss_clk_calc(struct dpi_data *dpi, unsigned long pck,
struct dpi_clk_calc_ctx *ctx)
{
int i;
......@@ -276,7 +281,8 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
ctx->pck_min = 0;
ctx->pck_max = pck + 1000 * i * i * i;
ok = dss_div_calc(pck, ctx->pck_min, dpi_calc_dss_cb, ctx);
ok = dss_div_calc(dpi->dss, pck, ctx->pck_min,
dpi_calc_dss_cb, ctx);
if (ok)
return ok;
}
......@@ -302,7 +308,7 @@ static int dpi_set_pll_clk(struct dpi_data *dpi, enum omap_channel channel,
if (r)
return r;
dss_select_lcd_clk_source(channel, dpi->clk_src);
dss_select_lcd_clk_source(dpi->dss, channel, dpi->clk_src);
dpi->mgr_config.clock_info = ctx.dispc_cinfo;
......@@ -320,11 +326,11 @@ static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req,
int r;
bool ok;
ok = dpi_dss_clk_calc(pck_req, &ctx);
ok = dpi_dss_clk_calc(dpi, pck_req, &ctx);
if (!ok)
return -EINVAL;
r = dss_set_fck_rate(ctx.fck);
r = dss_set_fck_rate(dpi->dss, ctx.fck);
if (r)
return r;
......@@ -339,8 +345,6 @@ static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req,
static int dpi_set_mode(struct dpi_data *dpi)
{
struct omap_dss_device *out = &dpi->output;
enum omap_channel channel = out->dispc_channel;
struct videomode *vm = &dpi->vm;
int lck_div = 0, pck_div = 0;
unsigned long fck = 0;
......@@ -348,8 +352,8 @@ static int dpi_set_mode(struct dpi_data *dpi)
int r = 0;
if (dpi->pll)
r = dpi_set_pll_clk(dpi, channel, vm->pixelclock, &fck,
&lck_div, &pck_div);
r = dpi_set_pll_clk(dpi, dpi->output.dispc_channel,
vm->pixelclock, &fck, &lck_div, &pck_div);
else
r = dpi_set_dispc_clk(dpi, vm->pixelclock, &fck,
&lck_div, &pck_div);
......@@ -365,16 +369,13 @@ static int dpi_set_mode(struct dpi_data *dpi)
vm->pixelclock = pck;
}
dss_mgr_set_timings(channel, vm);
dss_mgr_set_timings(&dpi->output, vm);
return 0;
}
static void dpi_config_lcd_manager(struct dpi_data *dpi)
{
struct omap_dss_device *out = &dpi->output;
enum omap_channel channel = out->dispc_channel;
dpi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
dpi->mgr_config.stallmode = false;
......@@ -384,14 +385,13 @@ static void dpi_config_lcd_manager(struct dpi_data *dpi)
dpi->mgr_config.lcden_sig_polarity = 0;
dss_mgr_set_lcd_config(channel, &dpi->mgr_config);
dss_mgr_set_lcd_config(&dpi->output, &dpi->mgr_config);
}
static int dpi_display_enable(struct omap_dss_device *dssdev)
{
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
struct omap_dss_device *out = &dpi->output;
enum omap_channel channel = out->dispc_channel;
int r;
mutex_lock(&dpi->lock);
......@@ -408,11 +408,11 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
goto err_reg_enable;
}
r = dispc_runtime_get();
r = dispc_runtime_get(dpi->dss->dispc);
if (r)
goto err_get_dispc;
r = dss_dpi_select_source(out->port_num, channel);
r = dss_dpi_select_source(dpi->dss, out->port_num, out->dispc_channel);
if (r)
goto err_src_sel;
......@@ -430,7 +430,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
mdelay(2);
r = dss_mgr_enable(channel);
r = dss_mgr_enable(&dpi->output);
if (r)
goto err_mgr_enable;
......@@ -444,7 +444,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
dss_pll_disable(dpi->pll);
err_pll_init:
err_src_sel:
dispc_runtime_put();
dispc_runtime_put(dpi->dss->dispc);
err_get_dispc:
if (dpi->vdds_dsi_reg)
regulator_disable(dpi->vdds_dsi_reg);
......@@ -457,18 +457,18 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
static void dpi_display_disable(struct omap_dss_device *dssdev)
{
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
enum omap_channel channel = dpi->output.dispc_channel;
mutex_lock(&dpi->lock);
dss_mgr_disable(channel);
dss_mgr_disable(&dpi->output);
if (dpi->pll) {
dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
dss_select_lcd_clk_source(dpi->dss, dpi->output.dispc_channel,
DSS_CLK_SRC_FCK);
dss_pll_disable(dpi->pll);
}
dispc_runtime_put();
dispc_runtime_put(dpi->dss->dispc);
if (dpi->vdds_dsi_reg)
regulator_disable(dpi->vdds_dsi_reg);
......@@ -516,7 +516,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
if (vm->hactive % 8 != 0)
return -EINVAL;
if (!dispc_mgr_timings_ok(channel, vm))
if (!dispc_mgr_timings_ok(dpi->dss->dispc, channel, vm))
return -EINVAL;
if (vm->pixelclock == 0)
......@@ -529,7 +529,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
} else {
ok = dpi_dss_clk_calc(vm->pixelclock, &ctx);
ok = dpi_dss_clk_calc(dpi, vm->pixelclock, &ctx);
if (!ok)
return -EINVAL;
......@@ -602,7 +602,7 @@ static void dpi_init_pll(struct dpi_data *dpi)
dpi->clk_src = dpi_get_clk_src(dpi);
pll = dss_pll_find_by_src(dpi->clk_src);
pll = dss_pll_find_by_src(dpi->dss, dpi->clk_src);
if (!pll)
return;
......@@ -654,7 +654,6 @@ static int dpi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
enum omap_channel channel = dpi->output.dispc_channel;
int r;
r = dpi_init_regulator(dpi);
......@@ -663,7 +662,7 @@ static int dpi_connect(struct omap_dss_device *dssdev,
dpi_init_pll(dpi);
r = dss_mgr_connect(channel, dssdev);
r = dss_mgr_connect(&dpi->output, dssdev);
if (r)
return r;
......@@ -671,7 +670,7 @@ static int dpi_connect(struct omap_dss_device *dssdev,
if (r) {
DSSERR("failed to connect output to new device: %s\n",
dst->name);
dss_mgr_disconnect(channel, dssdev);
dss_mgr_disconnect(&dpi->output, dssdev);
return r;
}
......@@ -682,7 +681,6 @@ static void dpi_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
enum omap_channel channel = dpi->output.dispc_channel;
WARN_ON(dst != dssdev->dst);
......@@ -691,7 +689,7 @@ static void dpi_disconnect(struct omap_dss_device *dssdev,
omapdss_output_unset_device(dssdev);
dss_mgr_disconnect(channel, dssdev);
dss_mgr_disconnect(&dpi->output, dssdev);
}
static const struct omapdss_dpi_ops dpi_ops = {
......@@ -748,8 +746,8 @@ static void dpi_uninit_output_port(struct device_node *port)
omapdss_unregister_output(out);
}
int dpi_init_port(struct platform_device *pdev, struct device_node *port,
enum dss_model dss_model)
int dpi_init_port(struct dss_device *dss, struct platform_device *pdev,
struct device_node *port, enum dss_model dss_model)
{
struct dpi_data *dpi;
struct device_node *ep;
......@@ -776,6 +774,7 @@ int dpi_init_port(struct platform_device *pdev, struct device_node *port,
dpi->pdev = pdev;
dpi->dss_model = dss_model;
dpi->dss = dss;
port->data = dpi;
mutex_init(&dpi->lock);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -44,7 +44,6 @@ struct device_node *dss_of_port_get_parent_device(struct device_node *port)
return NULL;
}
EXPORT_SYMBOL_GPL(dss_of_port_get_parent_device);
u32 dss_of_port_get_port_number(struct device_node *port)
{
......@@ -57,7 +56,6 @@ u32 dss_of_port_get_port_number(struct device_node *port)
return reg;
}
EXPORT_SYMBOL_GPL(dss_of_port_get_port_number);
struct omap_dss_device *
omapdss_of_find_source_for_first_ep(struct device_node *node)
......
......@@ -48,8 +48,6 @@
#include "omapdss.h"
#include "dss.h"
#define DSS_SZ_REGS SZ_512
struct dss_reg {
u16 idx;
};
......@@ -64,16 +62,19 @@ struct dss_reg {
#define DSS_PLL_CONTROL DSS_REG(0x0048)
#define DSS_SDI_STATUS DSS_REG(0x005C)
#define REG_GET(idx, start, end) \
FLD_GET(dss_read_reg(idx), start, end)
#define REG_GET(dss, idx, start, end) \
FLD_GET(dss_read_reg(dss, idx), start, end)
#define REG_FLD_MOD(idx, val, start, end) \
dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
#define REG_FLD_MOD(dss, idx, val, start, end) \
dss_write_reg(dss, idx, \
FLD_MOD(dss_read_reg(dss, idx), val, start, end))
struct dss_ops {
int (*dpi_select_source)(int port, enum omap_channel channel);
int (*select_lcd_source)(enum omap_channel channel,
enum dss_clk_source clk_src);
int (*dpi_select_source)(struct dss_device *dss, int port,
enum omap_channel channel);
int (*select_lcd_source)(struct dss_device *dss,
enum omap_channel channel,
enum dss_clk_source clk_src);
};
struct dss_features {
......@@ -90,33 +91,6 @@ struct dss_features {
bool has_lcd_clk_src;
};
static struct {
struct platform_device *pdev;
void __iomem *base;
struct regmap *syscon_pll_ctrl;
u32 syscon_pll_ctrl_offset;
struct clk *parent_clk;
struct clk *dss_clk;
unsigned long dss_clk_rate;
unsigned long cache_req_pck;
unsigned long cache_prate;
struct dispc_clock_info cache_dispc_cinfo;
enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
enum dss_clk_source dispc_clk_source;
enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
bool ctx_valid;
u32 ctx[DSS_SZ_REGS / sizeof(u32)];
const struct dss_features *feat;
struct dss_pll *video1_pll;
struct dss_pll *video2_pll;
} dss;
static const char * const dss_generic_clk_source_names[] = {
[DSS_CLK_SRC_FCK] = "FCK",
[DSS_CLK_SRC_PLL1_1] = "PLL1:1",
......@@ -128,49 +102,50 @@ static const char * const dss_generic_clk_source_names[] = {
[DSS_CLK_SRC_HDMI_PLL] = "HDMI PLL",
};
static inline void dss_write_reg(const struct dss_reg idx, u32 val)
static inline void dss_write_reg(struct dss_device *dss,
const struct dss_reg idx, u32 val)
{
__raw_writel(val, dss.base + idx.idx);
__raw_writel(val, dss->base + idx.idx);
}
static inline u32 dss_read_reg(const struct dss_reg idx)
static inline u32 dss_read_reg(struct dss_device *dss, const struct dss_reg idx)
{
return __raw_readl(dss.base + idx.idx);
return __raw_readl(dss->base + idx.idx);
}
#define SR(reg) \
dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
#define RR(reg) \
dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
#define SR(dss, reg) \
dss->ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(dss, DSS_##reg)
#define RR(dss, reg) \
dss_write_reg(dss, DSS_##reg, dss->ctx[(DSS_##reg).idx / sizeof(u32)])
static void dss_save_context(void)
static void dss_save_context(struct dss_device *dss)
{
DSSDBG("dss_save_context\n");
SR(CONTROL);
SR(dss, CONTROL);
if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
SR(SDI_CONTROL);
SR(PLL_CONTROL);
if (dss->feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
SR(dss, SDI_CONTROL);
SR(dss, PLL_CONTROL);
}
dss.ctx_valid = true;
dss->ctx_valid = true;
DSSDBG("context saved\n");
}
static void dss_restore_context(void)
static void dss_restore_context(struct dss_device *dss)
{
DSSDBG("dss_restore_context\n");
if (!dss.ctx_valid)
if (!dss->ctx_valid)
return;
RR(CONTROL);
RR(dss, CONTROL);
if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
RR(SDI_CONTROL);
RR(PLL_CONTROL);
if (dss->feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
RR(dss, SDI_CONTROL);
RR(dss, PLL_CONTROL);
}
DSSDBG("context restored\n");
......@@ -179,17 +154,17 @@ static void dss_restore_context(void)
#undef SR
#undef RR
void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable)
void dss_ctrl_pll_enable(struct dss_pll *pll, bool enable)
{
unsigned shift;
unsigned val;
unsigned int shift;
unsigned int val;
if (!dss.syscon_pll_ctrl)
if (!pll->dss->syscon_pll_ctrl)
return;
val = !enable;
switch (pll_id) {
switch (pll->id) {
case DSS_PLL_VIDEO1:
shift = 0;
break;
......@@ -200,20 +175,22 @@ void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable)
shift = 2;
break;
default:
DSSERR("illegal DSS PLL ID %d\n", pll_id);
DSSERR("illegal DSS PLL ID %d\n", pll->id);
return;
}
regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
1 << shift, val << shift);
regmap_update_bits(pll->dss->syscon_pll_ctrl,
pll->dss->syscon_pll_ctrl_offset,
1 << shift, val << shift);
}
static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src,
enum omap_channel channel)
static int dss_ctrl_pll_set_control_mux(struct dss_device *dss,
enum dss_clk_source clk_src,
enum omap_channel channel)
{
unsigned shift, val;
unsigned int shift, val;
if (!dss.syscon_pll_ctrl)
if (!dss->syscon_pll_ctrl)
return -EINVAL;
switch (channel) {
......@@ -268,47 +245,47 @@ static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src,
return -EINVAL;
}
regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
regmap_update_bits(dss->syscon_pll_ctrl, dss->syscon_pll_ctrl_offset,
0x3 << shift, val << shift);
return 0;
}
void dss_sdi_init(int datapairs)
void dss_sdi_init(struct dss_device *dss, int datapairs)
{
u32 l;
BUG_ON(datapairs > 3 || datapairs < 1);
l = dss_read_reg(DSS_SDI_CONTROL);
l = dss_read_reg(dss, DSS_SDI_CONTROL);
l = FLD_MOD(l, 0xf, 19, 15); /* SDI_PDIV */
l = FLD_MOD(l, datapairs-1, 3, 2); /* SDI_PRSEL */
l = FLD_MOD(l, 2, 1, 0); /* SDI_BWSEL */
dss_write_reg(DSS_SDI_CONTROL, l);
dss_write_reg(dss, DSS_SDI_CONTROL, l);
l = dss_read_reg(DSS_PLL_CONTROL);
l = dss_read_reg(dss, DSS_PLL_CONTROL);
l = FLD_MOD(l, 0x7, 25, 22); /* SDI_PLL_FREQSEL */
l = FLD_MOD(l, 0xb, 16, 11); /* SDI_PLL_REGN */
l = FLD_MOD(l, 0xb4, 10, 1); /* SDI_PLL_REGM */
dss_write_reg(DSS_PLL_CONTROL, l);
dss_write_reg(dss, DSS_PLL_CONTROL, l);
}
int dss_sdi_enable(void)
int dss_sdi_enable(struct dss_device *dss)
{
unsigned long timeout;
dispc_pck_free_enable(1);
dispc_pck_free_enable(dss->dispc, 1);
/* Reset SDI PLL */
REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */
REG_FLD_MOD(dss, DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */
udelay(1); /* wait 2x PCLK */
/* Lock SDI PLL */
REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */
REG_FLD_MOD(dss, DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */
/* Waiting for PLL lock request to complete */
timeout = jiffies + msecs_to_jiffies(500);
while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) {
while (dss_read_reg(dss, DSS_SDI_STATUS) & (1 << 6)) {
if (time_after_eq(jiffies, timeout)) {
DSSERR("PLL lock request timed out\n");
goto err1;
......@@ -316,22 +293,22 @@ int dss_sdi_enable(void)
}
/* Clearing PLL_GO bit */
REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28);
REG_FLD_MOD(dss, DSS_PLL_CONTROL, 0, 28, 28);
/* Waiting for PLL to lock */
timeout = jiffies + msecs_to_jiffies(500);
while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) {
while (!(dss_read_reg(dss, DSS_SDI_STATUS) & (1 << 5))) {
if (time_after_eq(jiffies, timeout)) {
DSSERR("PLL lock timed out\n");
goto err1;
}
}
dispc_lcd_enable_signal(1);
dispc_lcd_enable_signal(dss->dispc, 1);
/* Waiting for SDI reset to complete */
timeout = jiffies + msecs_to_jiffies(500);
while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) {
while (!(dss_read_reg(dss, DSS_SDI_STATUS) & (1 << 2))) {
if (time_after_eq(jiffies, timeout)) {
DSSERR("SDI reset timed out\n");
goto err2;
......@@ -341,24 +318,24 @@ int dss_sdi_enable(void)
return 0;
err2:
dispc_lcd_enable_signal(0);
dispc_lcd_enable_signal(dss->dispc, 0);
err1:
/* Reset SDI PLL */
REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
REG_FLD_MOD(dss, DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
dispc_pck_free_enable(0);
dispc_pck_free_enable(dss->dispc, 0);
return -ETIMEDOUT;
}
void dss_sdi_disable(void)
void dss_sdi_disable(struct dss_device *dss)
{
dispc_lcd_enable_signal(0);
dispc_lcd_enable_signal(dss->dispc, 0);
dispc_pck_free_enable(0);
dispc_pck_free_enable(dss->dispc, 0);
/* Reset SDI PLL */
REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
REG_FLD_MOD(dss, DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
}
const char *dss_get_clk_source_name(enum dss_clk_source clk_src)
......@@ -366,48 +343,61 @@ const char *dss_get_clk_source_name(enum dss_clk_source clk_src)
return dss_generic_clk_source_names[clk_src];
}
#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
static void dss_dump_clocks(struct seq_file *s)
static void dss_dump_clocks(struct dss_device *dss, struct seq_file *s)
{
const char *fclk_name;
unsigned long fclk_rate;
if (dss_runtime_get())
if (dss_runtime_get(dss))
return;
seq_printf(s, "- DSS -\n");
fclk_name = dss_get_clk_source_name(DSS_CLK_SRC_FCK);
fclk_rate = clk_get_rate(dss.dss_clk);
fclk_rate = clk_get_rate(dss->dss_clk);
seq_printf(s, "%s = %lu\n",
fclk_name,
fclk_rate);
dss_runtime_put();
dss_runtime_put(dss);
}
#endif
static void dss_dump_regs(struct seq_file *s)
static int dss_dump_regs(struct seq_file *s, void *p)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
struct dss_device *dss = s->private;
if (dss_runtime_get())
return;
#define DUMPREG(dss, r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(dss, r))
if (dss_runtime_get(dss))
return 0;
DUMPREG(DSS_REVISION);
DUMPREG(DSS_SYSCONFIG);
DUMPREG(DSS_SYSSTATUS);
DUMPREG(DSS_CONTROL);
DUMPREG(dss, DSS_REVISION);
DUMPREG(dss, DSS_SYSCONFIG);
DUMPREG(dss, DSS_SYSSTATUS);
DUMPREG(dss, DSS_CONTROL);
if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
DUMPREG(DSS_SDI_CONTROL);
DUMPREG(DSS_PLL_CONTROL);
DUMPREG(DSS_SDI_STATUS);
if (dss->feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
DUMPREG(dss, DSS_SDI_CONTROL);
DUMPREG(dss, DSS_PLL_CONTROL);
DUMPREG(dss, DSS_SDI_STATUS);
}
dss_runtime_put();
dss_runtime_put(dss);
#undef DUMPREG
return 0;
}
static int dss_debug_dump_clocks(struct seq_file *s, void *p)
{
struct dss_device *dss = s->private;
dss_dump_clocks(dss, s);
dispc_dump_clocks(dss->dispc, s);
#ifdef CONFIG_OMAP2_DSS_DSI
dsi_dump_clocks(s);
#endif
return 0;
}
static int dss_get_channel_index(enum omap_channel channel)
......@@ -425,7 +415,8 @@ static int dss_get_channel_index(enum omap_channel channel)
}
}
static void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
static void dss_select_dispc_clk_source(struct dss_device *dss,
enum dss_clk_source clk_src)
{
int b;
......@@ -433,7 +424,7 @@ static void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
* We always use PRCM clock as the DISPC func clock, except on DSS3,
* where we don't have separate DISPC and LCD clock sources.
*/
if (WARN_ON(dss.feat->has_lcd_clk_src && clk_src != DSS_CLK_SRC_FCK))
if (WARN_ON(dss->feat->has_lcd_clk_src && clk_src != DSS_CLK_SRC_FCK))
return;
switch (clk_src) {
......@@ -451,15 +442,15 @@ static void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
return;
}
REG_FLD_MOD(DSS_CONTROL, b, /* DISPC_CLK_SWITCH */
dss.feat->dispc_clk_switch.start,
dss.feat->dispc_clk_switch.end);
REG_FLD_MOD(dss, DSS_CONTROL, b, /* DISPC_CLK_SWITCH */
dss->feat->dispc_clk_switch.start,
dss->feat->dispc_clk_switch.end);
dss.dispc_clk_source = clk_src;
dss->dispc_clk_source = clk_src;
}
void dss_select_dsi_clk_source(int dsi_module,
enum dss_clk_source clk_src)
void dss_select_dsi_clk_source(struct dss_device *dss, int dsi_module,
enum dss_clk_source clk_src)
{
int b, pos;
......@@ -481,13 +472,14 @@ void dss_select_dsi_clk_source(int dsi_module,
}
pos = dsi_module == 0 ? 1 : 10;
REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* DSIx_CLK_SWITCH */
REG_FLD_MOD(dss, DSS_CONTROL, b, pos, pos); /* DSIx_CLK_SWITCH */
dss.dsi_clk_source[dsi_module] = clk_src;
dss->dsi_clk_source[dsi_module] = clk_src;
}
static int dss_lcd_clk_mux_dra7(enum omap_channel channel,
enum dss_clk_source clk_src)
static int dss_lcd_clk_mux_dra7(struct dss_device *dss,
enum omap_channel channel,
enum dss_clk_source clk_src)
{
const u8 ctrl_bits[] = {
[OMAP_DSS_CHANNEL_LCD] = 0,
......@@ -500,21 +492,22 @@ static int dss_lcd_clk_mux_dra7(enum omap_channel channel,
if (clk_src == DSS_CLK_SRC_FCK) {
/* LCDx_CLK_SWITCH */
REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
REG_FLD_MOD(dss, DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
return -EINVAL;
}
r = dss_ctrl_pll_set_control_mux(clk_src, channel);
r = dss_ctrl_pll_set_control_mux(dss, clk_src, channel);
if (r)
return r;
REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
REG_FLD_MOD(dss, DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
return 0;
}
static int dss_lcd_clk_mux_omap5(enum omap_channel channel,
enum dss_clk_source clk_src)
static int dss_lcd_clk_mux_omap5(struct dss_device *dss,
enum omap_channel channel,
enum dss_clk_source clk_src)
{
const u8 ctrl_bits[] = {
[OMAP_DSS_CHANNEL_LCD] = 0,
......@@ -531,20 +524,21 @@ static int dss_lcd_clk_mux_omap5(enum omap_channel channel,
if (clk_src == DSS_CLK_SRC_FCK) {
/* LCDx_CLK_SWITCH */
REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
REG_FLD_MOD(dss, DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
return -EINVAL;
}
if (WARN_ON(allowed_plls[channel] != clk_src))
return -EINVAL;
REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
REG_FLD_MOD(dss, DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
return 0;
}
static int dss_lcd_clk_mux_omap4(enum omap_channel channel,
enum dss_clk_source clk_src)
static int dss_lcd_clk_mux_omap4(struct dss_device *dss,
enum omap_channel channel,
enum dss_clk_source clk_src)
{
const u8 ctrl_bits[] = {
[OMAP_DSS_CHANNEL_LCD] = 0,
......@@ -559,87 +553,90 @@ static int dss_lcd_clk_mux_omap4(enum omap_channel channel,
if (clk_src == DSS_CLK_SRC_FCK) {
/* LCDx_CLK_SWITCH */
REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
REG_FLD_MOD(dss, DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
return 0;
}
if (WARN_ON(allowed_plls[channel] != clk_src))
return -EINVAL;
REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
REG_FLD_MOD(dss, DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
return 0;
}
void dss_select_lcd_clk_source(enum omap_channel channel,
enum dss_clk_source clk_src)
void dss_select_lcd_clk_source(struct dss_device *dss,
enum omap_channel channel,
enum dss_clk_source clk_src)
{
int idx = dss_get_channel_index(channel);
int r;
if (!dss.feat->has_lcd_clk_src) {
dss_select_dispc_clk_source(clk_src);
dss.lcd_clk_source[idx] = clk_src;
if (!dss->feat->has_lcd_clk_src) {
dss_select_dispc_clk_source(dss, clk_src);
dss->lcd_clk_source[idx] = clk_src;
return;
}
r = dss.feat->ops->select_lcd_source(channel, clk_src);
r = dss->feat->ops->select_lcd_source(dss, channel, clk_src);
if (r)
return;
dss.lcd_clk_source[idx] = clk_src;
dss->lcd_clk_source[idx] = clk_src;
}
enum dss_clk_source dss_get_dispc_clk_source(void)
enum dss_clk_source dss_get_dispc_clk_source(struct dss_device *dss)
{
return dss.dispc_clk_source;
return dss->dispc_clk_source;
}
enum dss_clk_source dss_get_dsi_clk_source(int dsi_module)
enum dss_clk_source dss_get_dsi_clk_source(struct dss_device *dss,
int dsi_module)
{
return dss.dsi_clk_source[dsi_module];
return dss->dsi_clk_source[dsi_module];
}
enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
enum dss_clk_source dss_get_lcd_clk_source(struct dss_device *dss,
enum omap_channel channel)
{
if (dss.feat->has_lcd_clk_src) {
if (dss->feat->has_lcd_clk_src) {
int idx = dss_get_channel_index(channel);
return dss.lcd_clk_source[idx];
return dss->lcd_clk_source[idx];
} else {
/* LCD_CLK source is the same as DISPC_FCLK source for
* OMAP2 and OMAP3 */
return dss.dispc_clk_source;
return dss->dispc_clk_source;
}
}
bool dss_div_calc(unsigned long pck, unsigned long fck_min,
dss_div_calc_func func, void *data)
bool dss_div_calc(struct dss_device *dss, unsigned long pck,
unsigned long fck_min, dss_div_calc_func func, void *data)
{
int fckd, fckd_start, fckd_stop;
unsigned long fck;
unsigned long fck_hw_max;
unsigned long fckd_hw_max;
unsigned long prate;
unsigned m;
unsigned int m;
fck_hw_max = dss.feat->fck_freq_max;
fck_hw_max = dss->feat->fck_freq_max;
if (dss.parent_clk == NULL) {
unsigned pckd;
if (dss->parent_clk == NULL) {
unsigned int pckd;
pckd = fck_hw_max / pck;
fck = pck * pckd;
fck = clk_round_rate(dss.dss_clk, fck);
fck = clk_round_rate(dss->dss_clk, fck);
return func(fck, data);
}
fckd_hw_max = dss.feat->fck_div_max;
fckd_hw_max = dss->feat->fck_div_max;
m = dss.feat->dss_fck_multiplier;
prate = clk_get_rate(dss.parent_clk);
m = dss->feat->dss_fck_multiplier;
prate = clk_get_rate(dss->parent_clk);
fck_min = fck_min ? fck_min : 1;
......@@ -656,67 +653,68 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
return false;
}
int dss_set_fck_rate(unsigned long rate)
int dss_set_fck_rate(struct dss_device *dss, unsigned long rate)
{
int r;
DSSDBG("set fck to %lu\n", rate);
r = clk_set_rate(dss.dss_clk, rate);
r = clk_set_rate(dss->dss_clk, rate);
if (r)
return r;
dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
dss->dss_clk_rate = clk_get_rate(dss->dss_clk);
WARN_ONCE(dss.dss_clk_rate != rate,
"clk rate mismatch: %lu != %lu", dss.dss_clk_rate,
rate);
WARN_ONCE(dss->dss_clk_rate != rate, "clk rate mismatch: %lu != %lu",
dss->dss_clk_rate, rate);
return 0;
}
unsigned long dss_get_dispc_clk_rate(void)
unsigned long dss_get_dispc_clk_rate(struct dss_device *dss)
{
return dss.dss_clk_rate;
return dss->dss_clk_rate;
}
unsigned long dss_get_max_fck_rate(void)
unsigned long dss_get_max_fck_rate(struct dss_device *dss)
{
return dss.feat->fck_freq_max;
return dss->feat->fck_freq_max;
}
enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel)
enum omap_dss_output_id dss_get_supported_outputs(struct dss_device *dss,
enum omap_channel channel)
{
return dss.feat->outputs[channel];
return dss->feat->outputs[channel];
}
static int dss_setup_default_clock(void)
static int dss_setup_default_clock(struct dss_device *dss)
{
unsigned long max_dss_fck, prate;
unsigned long fck;
unsigned fck_div;
unsigned int fck_div;
int r;
max_dss_fck = dss.feat->fck_freq_max;
max_dss_fck = dss->feat->fck_freq_max;
if (dss.parent_clk == NULL) {
fck = clk_round_rate(dss.dss_clk, max_dss_fck);
if (dss->parent_clk == NULL) {
fck = clk_round_rate(dss->dss_clk, max_dss_fck);
} else {
prate = clk_get_rate(dss.parent_clk);
prate = clk_get_rate(dss->parent_clk);
fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
fck_div = DIV_ROUND_UP(prate * dss->feat->dss_fck_multiplier,
max_dss_fck);
fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier;
fck = DIV_ROUND_UP(prate, fck_div)
* dss->feat->dss_fck_multiplier;
}
r = dss_set_fck_rate(fck);
r = dss_set_fck_rate(dss, fck);
if (r)
return r;
return 0;
}
void dss_set_venc_output(enum omap_dss_venc_type type)
void dss_set_venc_output(struct dss_device *dss, enum omap_dss_venc_type type)
{
int l = 0;
......@@ -728,19 +726,21 @@ void dss_set_venc_output(enum omap_dss_venc_type type)
BUG();
/* venc out selection. 0 = comp, 1 = svideo */
REG_FLD_MOD(DSS_CONTROL, l, 6, 6);
REG_FLD_MOD(dss, DSS_CONTROL, l, 6, 6);
}
void dss_set_dac_pwrdn_bgz(bool enable)
void dss_set_dac_pwrdn_bgz(struct dss_device *dss, bool enable)
{
REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
/* DAC Power-Down Control */
REG_FLD_MOD(dss, DSS_CONTROL, enable, 5, 5);
}
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
void dss_select_hdmi_venc_clk_source(struct dss_device *dss,
enum dss_hdmi_venc_clk_source_select src)
{
enum omap_dss_output_id outputs;
outputs = dss.feat->outputs[OMAP_DSS_CHANNEL_DIGIT];
outputs = dss->feat->outputs[OMAP_DSS_CHANNEL_DIGIT];
/* Complain about invalid selections */
WARN_ON((src == DSS_VENC_TV_CLK) && !(outputs & OMAP_DSS_OUTPUT_VENC));
......@@ -749,24 +749,12 @@ void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
/* Select only if we have options */
if ((outputs & OMAP_DSS_OUTPUT_VENC) &&
(outputs & OMAP_DSS_OUTPUT_HDMI))
REG_FLD_MOD(DSS_CONTROL, src, 15, 15); /* VENC_HDMI_SWITCH */
}
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
{
enum omap_dss_output_id outputs;
outputs = dss.feat->outputs[OMAP_DSS_CHANNEL_DIGIT];
if ((outputs & OMAP_DSS_OUTPUT_HDMI) == 0)
return DSS_VENC_TV_CLK;
if ((outputs & OMAP_DSS_OUTPUT_VENC) == 0)
return DSS_HDMI_M_PCLK;
return REG_GET(DSS_CONTROL, 15, 15);
/* VENC_HDMI_SWITCH */
REG_FLD_MOD(dss, DSS_CONTROL, src, 15, 15);
}
static int dss_dpi_select_source_omap2_omap3(int port, enum omap_channel channel)
static int dss_dpi_select_source_omap2_omap3(struct dss_device *dss, int port,
enum omap_channel channel)
{
if (channel != OMAP_DSS_CHANNEL_LCD)
return -EINVAL;
......@@ -774,7 +762,8 @@ static int dss_dpi_select_source_omap2_omap3(int port, enum omap_channel channel
return 0;
}
static int dss_dpi_select_source_omap4(int port, enum omap_channel channel)
static int dss_dpi_select_source_omap4(struct dss_device *dss, int port,
enum omap_channel channel)
{
int val;
......@@ -789,12 +778,13 @@ static int dss_dpi_select_source_omap4(int port, enum omap_channel channel)
return -EINVAL;
}
REG_FLD_MOD(DSS_CONTROL, val, 17, 17);
REG_FLD_MOD(dss, DSS_CONTROL, val, 17, 17);
return 0;
}
static int dss_dpi_select_source_omap5(int port, enum omap_channel channel)
static int dss_dpi_select_source_omap5(struct dss_device *dss, int port,
enum omap_channel channel)
{
int val;
......@@ -815,16 +805,17 @@ static int dss_dpi_select_source_omap5(int port, enum omap_channel channel)
return -EINVAL;
}
REG_FLD_MOD(DSS_CONTROL, val, 17, 16);
REG_FLD_MOD(dss, DSS_CONTROL, val, 17, 16);
return 0;
}
static int dss_dpi_select_source_dra7xx(int port, enum omap_channel channel)
static int dss_dpi_select_source_dra7xx(struct dss_device *dss, int port,
enum omap_channel channel)
{
switch (port) {
case 0:
return dss_dpi_select_source_omap5(port, channel);
return dss_dpi_select_source_omap5(dss, port, channel);
case 1:
if (channel != OMAP_DSS_CHANNEL_LCD2)
return -EINVAL;
......@@ -840,135 +831,153 @@ static int dss_dpi_select_source_dra7xx(int port, enum omap_channel channel)
return 0;
}
int dss_dpi_select_source(int port, enum omap_channel channel)
int dss_dpi_select_source(struct dss_device *dss, int port,
enum omap_channel channel)
{
return dss.feat->ops->dpi_select_source(port, channel);
return dss->feat->ops->dpi_select_source(dss, port, channel);
}
static int dss_get_clocks(void)
static int dss_get_clocks(struct dss_device *dss)
{
struct clk *clk;
clk = devm_clk_get(&dss.pdev->dev, "fck");
clk = devm_clk_get(&dss->pdev->dev, "fck");
if (IS_ERR(clk)) {
DSSERR("can't get clock fck\n");
return PTR_ERR(clk);
}
dss.dss_clk = clk;
dss->dss_clk = clk;
if (dss.feat->parent_clk_name) {
clk = clk_get(NULL, dss.feat->parent_clk_name);
if (dss->feat->parent_clk_name) {
clk = clk_get(NULL, dss->feat->parent_clk_name);
if (IS_ERR(clk)) {
DSSERR("Failed to get %s\n", dss.feat->parent_clk_name);
DSSERR("Failed to get %s\n",
dss->feat->parent_clk_name);
return PTR_ERR(clk);
}
} else {
clk = NULL;
}
dss.parent_clk = clk;
dss->parent_clk = clk;
return 0;
}
static void dss_put_clocks(void)
static void dss_put_clocks(struct dss_device *dss)
{
if (dss.parent_clk)
clk_put(dss.parent_clk);
if (dss->parent_clk)
clk_put(dss->parent_clk);
}
int dss_runtime_get(void)
int dss_runtime_get(struct dss_device *dss)
{
int r;
DSSDBG("dss_runtime_get\n");
r = pm_runtime_get_sync(&dss.pdev->dev);
r = pm_runtime_get_sync(&dss->pdev->dev);
WARN_ON(r < 0);
return r < 0 ? r : 0;
}
void dss_runtime_put(void)
void dss_runtime_put(struct dss_device *dss)
{
int r;
DSSDBG("dss_runtime_put\n");
r = pm_runtime_put_sync(&dss.pdev->dev);
r = pm_runtime_put_sync(&dss->pdev->dev);
WARN_ON(r < 0 && r != -ENOSYS && r != -EBUSY);
}
/* DEBUGFS */
#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
static void dss_debug_dump_clocks(struct seq_file *s)
struct dss_device *dss_get_device(struct device *dev)
{
dss_dump_clocks(s);
dispc_dump_clocks(s);
#ifdef CONFIG_OMAP2_DSS_DSI
dsi_dump_clocks(s);
#endif
return dev_get_drvdata(dev);
}
static int dss_debug_show(struct seq_file *s, void *unused)
/* DEBUGFS */
#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
static int dss_initialize_debugfs(struct dss_device *dss)
{
void (*func)(struct seq_file *) = s->private;
struct dentry *dir;
dir = debugfs_create_dir("omapdss", NULL);
if (IS_ERR(dir))
return PTR_ERR(dir);
dss->debugfs.root = dir;
func(s);
return 0;
}
static void dss_uninitialize_debugfs(struct dss_device *dss)
{
debugfs_remove_recursive(dss->debugfs.root);
}
struct dss_debugfs_entry {
struct dentry *dentry;
int (*show_fn)(struct seq_file *s, void *data);
void *data;
};
static int dss_debug_open(struct inode *inode, struct file *file)
{
return single_open(file, dss_debug_show, inode->i_private);
struct dss_debugfs_entry *entry = inode->i_private;
return single_open(file, entry->show_fn, entry->data);
}
static const struct file_operations dss_debug_fops = {
.open = dss_debug_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.open = dss_debug_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static struct dentry *dss_debugfs_dir;
static int dss_initialize_debugfs(void)
struct dss_debugfs_entry *
dss_debugfs_create_file(struct dss_device *dss, const char *name,
int (*show_fn)(struct seq_file *s, void *data),
void *data)
{
dss_debugfs_dir = debugfs_create_dir("omapdss", NULL);
if (IS_ERR(dss_debugfs_dir)) {
int err = PTR_ERR(dss_debugfs_dir);
struct dss_debugfs_entry *entry;
struct dentry *d;
dss_debugfs_dir = NULL;
return err;
}
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
return ERR_PTR(-ENOMEM);
debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
&dss_debug_dump_clocks, &dss_debug_fops);
entry->show_fn = show_fn;
entry->data = data;
return 0;
}
d = debugfs_create_file(name, 0444, dss->debugfs.root, entry,
&dss_debug_fops);
if (IS_ERR(d)) {
kfree(entry);
return ERR_PTR(PTR_ERR(d));
}
static void dss_uninitialize_debugfs(void)
{
if (dss_debugfs_dir)
debugfs_remove_recursive(dss_debugfs_dir);
entry->dentry = d;
return entry;
}
int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
void dss_debugfs_remove_file(struct dss_debugfs_entry *entry)
{
struct dentry *d;
d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir,
write, &dss_debug_fops);
if (IS_ERR_OR_NULL(entry))
return;
return PTR_ERR_OR_ZERO(d);
debugfs_remove(entry->dentry);
kfree(entry);
}
#else /* CONFIG_OMAP2_DSS_DEBUGFS */
static inline int dss_initialize_debugfs(void)
static inline int dss_initialize_debugfs(struct dss_device *dss)
{
return 0;
}
static inline void dss_uninitialize_debugfs(void)
static inline void dss_uninitialize_debugfs(struct dss_device *dss)
{
}
#endif /* CONFIG_OMAP2_DSS_DEBUGFS */
......@@ -1169,23 +1178,24 @@ static const struct dss_features dra7xx_dss_feats = {
.has_lcd_clk_src = true,
};
static int dss_init_ports(struct platform_device *pdev)
static int dss_init_ports(struct dss_device *dss)
{
struct platform_device *pdev = dss->pdev;
struct device_node *parent = pdev->dev.of_node;
struct device_node *port;
int i;
for (i = 0; i < dss.feat->num_ports; i++) {
for (i = 0; i < dss->feat->num_ports; i++) {
port = of_graph_get_port_by_id(parent, i);
if (!port)
continue;
switch (dss.feat->ports[i]) {
switch (dss->feat->ports[i]) {
case OMAP_DISPLAY_TYPE_DPI:
dpi_init_port(pdev, port, dss.feat->model);
dpi_init_port(dss, pdev, port, dss->feat->model);
break;
case OMAP_DISPLAY_TYPE_SDI:
sdi_init_port(pdev, port);
sdi_init_port(dss, pdev, port);
break;
default:
break;
......@@ -1195,18 +1205,19 @@ static int dss_init_ports(struct platform_device *pdev)
return 0;
}
static void dss_uninit_ports(struct platform_device *pdev)
static void dss_uninit_ports(struct dss_device *dss)
{
struct platform_device *pdev = dss->pdev;
struct device_node *parent = pdev->dev.of_node;
struct device_node *port;
int i;
for (i = 0; i < dss.feat->num_ports; i++) {
for (i = 0; i < dss->feat->num_ports; i++) {
port = of_graph_get_port_by_id(parent, i);
if (!port)
continue;
switch (dss.feat->ports[i]) {
switch (dss->feat->ports[i]) {
case OMAP_DISPLAY_TYPE_DPI:
dpi_uninit_port(port);
break;
......@@ -1219,8 +1230,9 @@ static void dss_uninit_ports(struct platform_device *pdev)
}
}
static int dss_video_pll_probe(struct platform_device *pdev)
static int dss_video_pll_probe(struct dss_device *dss)
{
struct platform_device *pdev = dss->pdev;
struct device_node *np = pdev->dev.of_node;
struct regulator *pll_regulator;
int r;
......@@ -1229,16 +1241,16 @@ static int dss_video_pll_probe(struct platform_device *pdev)
return 0;
if (of_property_read_bool(np, "syscon-pll-ctrl")) {
dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np,
dss->syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np,
"syscon-pll-ctrl");
if (IS_ERR(dss.syscon_pll_ctrl)) {
if (IS_ERR(dss->syscon_pll_ctrl)) {
dev_err(&pdev->dev,
"failed to get syscon-pll-ctrl regmap\n");
return PTR_ERR(dss.syscon_pll_ctrl);
return PTR_ERR(dss->syscon_pll_ctrl);
}
if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1,
&dss.syscon_pll_ctrl_offset)) {
&dss->syscon_pll_ctrl_offset)) {
dev_err(&pdev->dev,
"failed to get syscon-pll-ctrl offset\n");
return -EINVAL;
......@@ -1264,16 +1276,18 @@ static int dss_video_pll_probe(struct platform_device *pdev)
}
if (of_property_match_string(np, "reg-names", "pll1") >= 0) {
dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator);
if (IS_ERR(dss.video1_pll))
return PTR_ERR(dss.video1_pll);
dss->video1_pll = dss_video_pll_init(dss, pdev, 0,
pll_regulator);
if (IS_ERR(dss->video1_pll))
return PTR_ERR(dss->video1_pll);
}
if (of_property_match_string(np, "reg-names", "pll2") >= 0) {
dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator);
if (IS_ERR(dss.video2_pll)) {
dss_video_pll_uninit(dss.video1_pll);
return PTR_ERR(dss.video2_pll);
dss->video2_pll = dss_video_pll_init(dss, pdev, 1,
pll_regulator);
if (IS_ERR(dss->video2_pll)) {
dss_video_pll_uninit(dss->video1_pll);
return PTR_ERR(dss->video2_pll);
}
}
......@@ -1300,109 +1314,26 @@ static const struct soc_device_attribute dss_soc_devices[] = {
static int dss_bind(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct resource *dss_mem;
u32 rev;
struct dss_device *dss = dev_get_drvdata(dev);
int r;
dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
dss.base = devm_ioremap_resource(&pdev->dev, dss_mem);
if (IS_ERR(dss.base))
return PTR_ERR(dss.base);
r = dss_get_clocks();
r = component_bind_all(dev, NULL);
if (r)
return r;
r = dss_setup_default_clock();
if (r)
goto err_setup_clocks;
r = dss_video_pll_probe(pdev);
if (r)
goto err_pll_init;
r = dss_init_ports(pdev);
if (r)
goto err_init_ports;
pm_runtime_enable(&pdev->dev);
r = dss_runtime_get();
if (r)
goto err_runtime_get;
dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
/* Select DPLL */
REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
#ifdef CONFIG_OMAP2_DSS_VENC
REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */
REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
#endif
dss.dsi_clk_source[0] = DSS_CLK_SRC_FCK;
dss.dsi_clk_source[1] = DSS_CLK_SRC_FCK;
dss.dispc_clk_source = DSS_CLK_SRC_FCK;
dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
rev = dss_read_reg(DSS_REVISION);
pr_info("OMAP DSS rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
dss_runtime_put();
r = component_bind_all(&pdev->dev, NULL);
if (r)
goto err_component;
dss_debugfs_create_file("dss", dss_dump_regs);
pm_set_vt_switch(0);
omapdss_gather_components(dev);
omapdss_set_is_initialized(true);
omapdss_set_dss(dss);
return 0;
err_component:
err_runtime_get:
pm_runtime_disable(&pdev->dev);
dss_uninit_ports(pdev);
err_init_ports:
if (dss.video1_pll)
dss_video_pll_uninit(dss.video1_pll);
if (dss.video2_pll)
dss_video_pll_uninit(dss.video2_pll);
err_pll_init:
err_setup_clocks:
dss_put_clocks();
return r;
}
static void dss_unbind(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
omapdss_set_is_initialized(false);
omapdss_set_dss(NULL);
component_unbind_all(&pdev->dev, NULL);
if (dss.video1_pll)
dss_video_pll_uninit(dss.video1_pll);
if (dss.video2_pll)
dss_video_pll_uninit(dss.video2_pll);
dss_uninit_ports(pdev);
pm_runtime_disable(&pdev->dev);
dss_put_clocks();
component_unbind_all(dev, NULL);
}
static const struct component_master_ops dss_component_ops = {
......@@ -1434,18 +1365,60 @@ static int dss_add_child_component(struct device *dev, void *data)
return 0;
}
static int dss_probe_hardware(struct dss_device *dss)
{
u32 rev;
int r;
r = dss_runtime_get(dss);
if (r)
return r;
dss->dss_clk_rate = clk_get_rate(dss->dss_clk);
/* Select DPLL */
REG_FLD_MOD(dss, DSS_CONTROL, 0, 0, 0);
dss_select_dispc_clk_source(dss, DSS_CLK_SRC_FCK);
#ifdef CONFIG_OMAP2_DSS_VENC
REG_FLD_MOD(dss, DSS_CONTROL, 1, 4, 4); /* venc dac demen */
REG_FLD_MOD(dss, DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
REG_FLD_MOD(dss, DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
#endif
dss->dsi_clk_source[0] = DSS_CLK_SRC_FCK;
dss->dsi_clk_source[1] = DSS_CLK_SRC_FCK;
dss->dispc_clk_source = DSS_CLK_SRC_FCK;
dss->lcd_clk_source[0] = DSS_CLK_SRC_FCK;
dss->lcd_clk_source[1] = DSS_CLK_SRC_FCK;
rev = dss_read_reg(dss, DSS_REVISION);
pr_info("OMAP DSS rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
dss_runtime_put(dss);
return 0;
}
static int dss_probe(struct platform_device *pdev)
{
const struct soc_device_attribute *soc;
struct component_match *match = NULL;
struct resource *dss_mem;
struct dss_device *dss;
int r;
dss.pdev = pdev;
dss = kzalloc(sizeof(*dss), GFP_KERNEL);
if (!dss)
return -ENOMEM;
dss->pdev = pdev;
platform_set_drvdata(pdev, dss);
r = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (r) {
dev_err(&pdev->dev, "Failed to set the DMA mask\n");
return r;
goto err_free_dss;
}
/*
......@@ -1454,31 +1427,108 @@ static int dss_probe(struct platform_device *pdev)
*/
soc = soc_device_match(dss_soc_devices);
if (soc)
dss.feat = soc->data;
dss->feat = soc->data;
else
dss.feat = of_match_device(dss_of_match, &pdev->dev)->data;
dss->feat = of_match_device(dss_of_match, &pdev->dev)->data;
/* Map I/O registers, get and setup clocks. */
dss_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dss->base = devm_ioremap_resource(&pdev->dev, dss_mem);
if (IS_ERR(dss->base)) {
r = PTR_ERR(dss->base);
goto err_free_dss;
}
r = dss_initialize_debugfs();
r = dss_get_clocks(dss);
if (r)
return r;
goto err_free_dss;
r = dss_setup_default_clock(dss);
if (r)
goto err_put_clocks;
/* add all the child devices as components */
/* Setup the video PLLs and the DPI and SDI ports. */
r = dss_video_pll_probe(dss);
if (r)
goto err_put_clocks;
r = dss_init_ports(dss);
if (r)
goto err_uninit_plls;
/* Enable runtime PM and probe the hardware. */
pm_runtime_enable(&pdev->dev);
r = dss_probe_hardware(dss);
if (r)
goto err_pm_runtime_disable;
/* Initialize debugfs. */
r = dss_initialize_debugfs(dss);
if (r)
goto err_pm_runtime_disable;
dss->debugfs.clk = dss_debugfs_create_file(dss, "clk",
dss_debug_dump_clocks, dss);
dss->debugfs.dss = dss_debugfs_create_file(dss, "dss", dss_dump_regs,
dss);
/* Add all the child devices as components. */
device_for_each_child(&pdev->dev, &match, dss_add_child_component);
r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
if (r) {
dss_uninitialize_debugfs();
return r;
}
if (r)
goto err_uninit_debugfs;
return 0;
err_uninit_debugfs:
dss_debugfs_remove_file(dss->debugfs.clk);
dss_debugfs_remove_file(dss->debugfs.dss);
dss_uninitialize_debugfs(dss);
err_pm_runtime_disable:
pm_runtime_disable(&pdev->dev);
dss_uninit_ports(dss);
err_uninit_plls:
if (dss->video1_pll)
dss_video_pll_uninit(dss->video1_pll);
if (dss->video2_pll)
dss_video_pll_uninit(dss->video2_pll);
err_put_clocks:
dss_put_clocks(dss);
err_free_dss:
kfree(dss);
return r;
}
static int dss_remove(struct platform_device *pdev)
{
struct dss_device *dss = platform_get_drvdata(pdev);
component_master_del(&pdev->dev, &dss_component_ops);
dss_uninitialize_debugfs();
dss_debugfs_remove_file(dss->debugfs.clk);
dss_debugfs_remove_file(dss->debugfs.dss);
dss_uninitialize_debugfs(dss);
pm_runtime_disable(&pdev->dev);
dss_uninit_ports(dss);
if (dss->video1_pll)
dss_video_pll_uninit(dss->video1_pll);
if (dss->video2_pll)
dss_video_pll_uninit(dss->video2_pll);
dss_put_clocks(dss);
kfree(dss);
return 0;
}
......@@ -1500,7 +1550,9 @@ static void dss_shutdown(struct platform_device *pdev)
static int dss_runtime_suspend(struct device *dev)
{
dss_save_context();
struct dss_device *dss = dev_get_drvdata(dev);
dss_save_context(dss);
dss_set_min_bus_tput(dev, 0);
pinctrl_pm_select_sleep_state(dev);
......@@ -1510,6 +1562,7 @@ static int dss_runtime_suspend(struct device *dev)
static int dss_runtime_resume(struct device *dev)
{
struct dss_device *dss = dev_get_drvdata(dev);
int r;
pinctrl_pm_select_default_state(dev);
......@@ -1525,7 +1578,7 @@ static int dss_runtime_resume(struct device *dev)
if (r)
return r;
dss_restore_context();
dss_restore_context(dss);
return 0;
}
......
......@@ -25,6 +25,11 @@
#include "omapdss.h"
struct dispc_device;
struct dss_debugfs_entry;
struct platform_device;
struct seq_file;
#define MAX_DSS_LCD_MANAGERS 3
#define MAX_NUM_DSI 2
......@@ -97,17 +102,6 @@ enum dss_dsi_content_type {
DSS_DSI_CONTENT_GENERIC,
};
enum dss_writeback_channel {
DSS_WB_LCD1_MGR = 0,
DSS_WB_LCD2_MGR = 1,
DSS_WB_TV_MGR = 2,
DSS_WB_OVL0 = 3,
DSS_WB_OVL1 = 4,
DSS_WB_OVL2 = 5,
DSS_WB_OVL3 = 6,
DSS_WB_LCD3_MGR = 7,
};
enum dss_clk_source {
DSS_CLK_SRC_FCK = 0,
......@@ -167,10 +161,10 @@ struct dss_pll_ops {
struct dss_pll_hw {
enum dss_pll_type type;
unsigned n_max;
unsigned m_min;
unsigned m_max;
unsigned mX_max;
unsigned int n_max;
unsigned int m_min;
unsigned int m_max;
unsigned int mX_max;
unsigned long fint_min, fint_max;
unsigned long clkdco_min, clkdco_low, clkdco_max;
......@@ -191,6 +185,7 @@ struct dss_pll_hw {
struct dss_pll {
const char *name;
enum dss_pll_id id;
struct dss_device *dss;
struct clk *clkin;
struct regulator *regulator;
......@@ -232,8 +227,44 @@ struct dss_lcd_mgr_config {
int lcden_sig_polarity;
};
struct seq_file;
struct platform_device;
#define DSS_SZ_REGS SZ_512
struct dss_device {
struct platform_device *pdev;
void __iomem *base;
struct regmap *syscon_pll_ctrl;
u32 syscon_pll_ctrl_offset;
struct clk *parent_clk;
struct clk *dss_clk;
unsigned long dss_clk_rate;
unsigned long cache_req_pck;
unsigned long cache_prate;
struct dispc_clock_info cache_dispc_cinfo;
enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
enum dss_clk_source dispc_clk_source;
enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
bool ctx_valid;
u32 ctx[DSS_SZ_REGS / sizeof(u32)];
const struct dss_features *feat;
struct {
struct dentry *root;
struct dss_debugfs_entry *clk;
struct dss_debugfs_entry *dss;
} debugfs;
struct dss_pll *plls[4];
struct dss_pll *video1_pll;
struct dss_pll *video2_pll;
struct dispc_device *dispc;
const struct dispc_ops *dispc_ops;
};
/* core */
static inline int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
......@@ -253,61 +284,81 @@ static inline bool dss_mgr_is_lcd(enum omap_channel id)
/* DSS */
#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
struct dss_debugfs_entry *
dss_debugfs_create_file(struct dss_device *dss, const char *name,
int (*show_fn)(struct seq_file *s, void *data),
void *data);
void dss_debugfs_remove_file(struct dss_debugfs_entry *entry);
#else
static inline int dss_debugfs_create_file(const char *name,
void (*write)(struct seq_file *))
static inline struct dss_debugfs_entry *
dss_debugfs_create_file(struct dss_device *dss, const char *name,
int (*show_fn)(struct seq_file *s, void *data),
void *data)
{
return NULL;
}
static inline void dss_debugfs_remove_file(struct dss_debugfs_entry *entry)
{
return 0;
}
#endif /* CONFIG_OMAP2_DSS_DEBUGFS */
int dss_runtime_get(void);
void dss_runtime_put(void);
struct dss_device *dss_get_device(struct device *dev);
unsigned long dss_get_dispc_clk_rate(void);
unsigned long dss_get_max_fck_rate(void);
enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel);
int dss_dpi_select_source(int port, enum omap_channel channel);
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
int dss_runtime_get(struct dss_device *dss);
void dss_runtime_put(struct dss_device *dss);
unsigned long dss_get_dispc_clk_rate(struct dss_device *dss);
unsigned long dss_get_max_fck_rate(struct dss_device *dss);
enum omap_dss_output_id dss_get_supported_outputs(struct dss_device *dss,
enum omap_channel channel);
int dss_dpi_select_source(struct dss_device *dss, int port,
enum omap_channel channel);
void dss_select_hdmi_venc_clk_source(struct dss_device *dss,
enum dss_hdmi_venc_clk_source_select src);
const char *dss_get_clk_source_name(enum dss_clk_source clk_src);
/* DSS VIDEO PLL */
struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id,
struct regulator *regulator);
struct dss_pll *dss_video_pll_init(struct dss_device *dss,
struct platform_device *pdev, int id,
struct regulator *regulator);
void dss_video_pll_uninit(struct dss_pll *pll);
void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable);
void dss_ctrl_pll_enable(struct dss_pll *pll, bool enable);
void dss_sdi_init(int datapairs);
int dss_sdi_enable(void);
void dss_sdi_disable(void);
void dss_sdi_init(struct dss_device *dss, int datapairs);
int dss_sdi_enable(struct dss_device *dss);
void dss_sdi_disable(struct dss_device *dss);
void dss_select_dsi_clk_source(int dsi_module,
enum dss_clk_source clk_src);
void dss_select_lcd_clk_source(enum omap_channel channel,
enum dss_clk_source clk_src);
enum dss_clk_source dss_get_dispc_clk_source(void);
enum dss_clk_source dss_get_dsi_clk_source(int dsi_module);
enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
void dss_select_dsi_clk_source(struct dss_device *dss, int dsi_module,
enum dss_clk_source clk_src);
void dss_select_lcd_clk_source(struct dss_device *dss,
enum omap_channel channel,
enum dss_clk_source clk_src);
enum dss_clk_source dss_get_dispc_clk_source(struct dss_device *dss);
enum dss_clk_source dss_get_dsi_clk_source(struct dss_device *dss,
int dsi_module);
enum dss_clk_source dss_get_lcd_clk_source(struct dss_device *dss,
enum omap_channel channel);
void dss_set_venc_output(enum omap_dss_venc_type type);
void dss_set_dac_pwrdn_bgz(bool enable);
void dss_set_venc_output(struct dss_device *dss, enum omap_dss_venc_type type);
void dss_set_dac_pwrdn_bgz(struct dss_device *dss, bool enable);
int dss_set_fck_rate(unsigned long rate);
int dss_set_fck_rate(struct dss_device *dss, unsigned long rate);
typedef bool (*dss_div_calc_func)(unsigned long fck, void *data);
bool dss_div_calc(unsigned long pck, unsigned long fck_min,
dss_div_calc_func func, void *data);
bool dss_div_calc(struct dss_device *dss, unsigned long pck,
unsigned long fck_min, dss_div_calc_func func, void *data);
/* SDI */
#ifdef CONFIG_OMAP2_DSS_SDI
int sdi_init_port(struct platform_device *pdev, struct device_node *port);
int sdi_init_port(struct dss_device *dss, struct platform_device *pdev,
struct device_node *port);
void sdi_uninit_port(struct device_node *port);
#else
static inline int sdi_init_port(struct platform_device *pdev,
struct device_node *port)
static inline int sdi_init_port(struct dss_device *dss,
struct platform_device *pdev,
struct device_node *port)
{
return 0;
}
......@@ -320,9 +371,6 @@ static inline void sdi_uninit_port(struct device_node *port)
#ifdef CONFIG_OMAP2_DSS_DSI
struct dentry;
struct file_operations;
void dsi_dump_clocks(struct seq_file *s);
void dsi_irq_handler(void);
......@@ -331,12 +379,14 @@ void dsi_irq_handler(void);
/* DPI */
#ifdef CONFIG_OMAP2_DSS_DPI
int dpi_init_port(struct platform_device *pdev, struct device_node *port,
enum dss_model dss_model);
int dpi_init_port(struct dss_device *dss, struct platform_device *pdev,
struct device_node *port, enum dss_model dss_model);
void dpi_uninit_port(struct device_node *port);
#else
static inline int dpi_init_port(struct platform_device *pdev,
struct device_node *port, enum dss_model dss_model)
static inline int dpi_init_port(struct dss_device *dss,
struct platform_device *pdev,
struct device_node *port,
enum dss_model dss_model)
{
return 0;
}
......@@ -346,51 +396,49 @@ static inline void dpi_uninit_port(struct device_node *port)
#endif
/* DISPC */
void dispc_dump_clocks(struct seq_file *s);
void dispc_dump_clocks(struct dispc_device *dispc, struct seq_file *s);
int dispc_runtime_get(void);
void dispc_runtime_put(void);
int dispc_runtime_get(struct dispc_device *dispc);
void dispc_runtime_put(struct dispc_device *dispc);
void dispc_enable_sidle(void);
void dispc_disable_sidle(void);
void dispc_enable_sidle(struct dispc_device *dispc);
void dispc_disable_sidle(struct dispc_device *dispc);
void dispc_lcd_enable_signal(bool enable);
void dispc_pck_free_enable(bool enable);
void dispc_enable_fifomerge(bool enable);
void dispc_enable_gamma_table(bool enable);
void dispc_lcd_enable_signal(struct dispc_device *dispc, bool enable);
void dispc_pck_free_enable(struct dispc_device *dispc, bool enable);
void dispc_enable_fifomerge(struct dispc_device *dispc, bool enable);
typedef bool (*dispc_div_calc_func)(int lckd, int pckd, unsigned long lck,
unsigned long pck, void *data);
bool dispc_div_calc(unsigned long dispc,
unsigned long pck_min, unsigned long pck_max,
dispc_div_calc_func func, void *data);
bool dispc_mgr_timings_ok(enum omap_channel channel, const struct videomode *vm);
int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
struct dispc_clock_info *cinfo);
void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low,
u32 high);
void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane,
u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
bool manual_update);
void dispc_mgr_set_clock_div(enum omap_channel channel,
const struct dispc_clock_info *cinfo);
int dispc_mgr_get_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
void dispc_set_tv_pclk(unsigned long pclk);
u32 dispc_wb_get_framedone_irq(void);
bool dispc_wb_go_busy(void);
void dispc_wb_go(void);
void dispc_wb_set_channel_in(enum dss_writeback_channel channel);
int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
bool mem_to_mem, const struct videomode *vm);
bool dispc_div_calc(struct dispc_device *dispc, unsigned long dispc_freq,
unsigned long pck_min, unsigned long pck_max,
dispc_div_calc_func func, void *data);
bool dispc_mgr_timings_ok(struct dispc_device *dispc,
enum omap_channel channel,
const struct videomode *vm);
int dispc_calc_clock_rates(struct dispc_device *dispc,
unsigned long dispc_fclk_rate,
struct dispc_clock_info *cinfo);
void dispc_ovl_set_fifo_threshold(struct dispc_device *dispc,
enum omap_plane_id plane, u32 low, u32 high);
void dispc_ovl_compute_fifo_thresholds(struct dispc_device *dispc,
enum omap_plane_id plane,
u32 *fifo_low, u32 *fifo_high,
bool use_fifomerge, bool manual_update);
void dispc_mgr_set_clock_div(struct dispc_device *dispc,
enum omap_channel channel,
const struct dispc_clock_info *cinfo);
int dispc_mgr_get_clock_div(struct dispc_device *dispc,
enum omap_channel channel,
struct dispc_clock_info *cinfo);
void dispc_set_tv_pclk(struct dispc_device *dispc, unsigned long pclk);
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr)
static inline void dss_collect_irq_stats(u32 irqstatus, unsigned int *irq_arr)
{
int b;
for (b = 0; b < 32; ++b) {
......@@ -406,11 +454,12 @@ typedef bool (*dss_pll_calc_func)(int n, int m, unsigned long fint,
typedef bool (*dss_hsdiv_calc_func)(int m_dispc, unsigned long dispc,
void *data);
int dss_pll_register(struct dss_pll *pll);
int dss_pll_register(struct dss_device *dss, struct dss_pll *pll);
void dss_pll_unregister(struct dss_pll *pll);
struct dss_pll *dss_pll_find(const char *name);
struct dss_pll *dss_pll_find_by_src(enum dss_clk_source src);
unsigned dss_pll_get_clkout_idx_for_src(enum dss_clk_source src);
struct dss_pll *dss_pll_find(struct dss_device *dss, const char *name);
struct dss_pll *dss_pll_find_by_src(struct dss_device *dss,
enum dss_clk_source src);
unsigned int dss_pll_get_clkout_idx_for_src(enum dss_clk_source src);
int dss_pll_enable(struct dss_pll *pll);
void dss_pll_disable(struct dss_pll *pll);
int dss_pll_set_config(struct dss_pll *pll,
......
......@@ -29,6 +29,8 @@
#include "omapdss.h"
#include "dss.h"
struct dss_device;
/* HDMI Wrapper */
#define HDMI_WP_REVISION 0x0
......@@ -324,8 +326,8 @@ phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp);
/* HDMI PLL funcs */
void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s);
int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
struct hdmi_wp_data *wp);
int hdmi_pll_init(struct dss_device *dss, struct platform_device *pdev,
struct hdmi_pll_data *pll, struct hdmi_wp_data *wp);
void hdmi_pll_uninit(struct hdmi_pll_data *hpll);
/* HDMI PHY funcs */
......@@ -357,6 +359,9 @@ static inline bool hdmi_mode_has_audio(struct hdmi_config *cfg)
struct omap_hdmi {
struct mutex lock;
struct platform_device *pdev;
struct dss_device *dss;
struct dss_debugfs_entry *debugfs;
struct hdmi_wp_data wp;
struct hdmi_pll_data pll;
......@@ -384,4 +389,6 @@ struct omap_hdmi {
bool display_enabled;
};
#define dssdev_to_hdmi(dssdev) container_of(dssdev, struct omap_hdmi, output)
#endif
......@@ -45,15 +45,13 @@
#include "dss.h"
#include "hdmi.h"
static struct omap_hdmi hdmi;
static int hdmi_runtime_get(void)
static int hdmi_runtime_get(struct omap_hdmi *hdmi)
{
int r;
DSSDBG("hdmi_runtime_get\n");
r = pm_runtime_get_sync(&hdmi.pdev->dev);
r = pm_runtime_get_sync(&hdmi->pdev->dev);
WARN_ON(r < 0);
if (r < 0)
return r;
......@@ -61,13 +59,13 @@ static int hdmi_runtime_get(void)
return 0;
}
static void hdmi_runtime_put(void)
static void hdmi_runtime_put(struct omap_hdmi *hdmi)
{
int r;
DSSDBG("hdmi_runtime_put\n");
r = pm_runtime_put_sync(&hdmi.pdev->dev);
r = pm_runtime_put_sync(&hdmi->pdev->dev);
WARN_ON(r < 0 && r != -ENOSYS);
}
......@@ -110,14 +108,14 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data)
return IRQ_HANDLED;
}
static int hdmi_init_regulator(void)
static int hdmi_init_regulator(struct omap_hdmi *hdmi)
{
struct regulator *reg;
if (hdmi.vdda_reg != NULL)
if (hdmi->vdda_reg != NULL)
return 0;
reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
reg = devm_regulator_get(&hdmi->pdev->dev, "vdda");
if (IS_ERR(reg)) {
if (PTR_ERR(reg) != -EPROBE_DEFER)
......@@ -125,64 +123,63 @@ static int hdmi_init_regulator(void)
return PTR_ERR(reg);
}
hdmi.vdda_reg = reg;
hdmi->vdda_reg = reg;
return 0;
}
static int hdmi_power_on_core(struct omap_dss_device *dssdev)
static int hdmi_power_on_core(struct omap_hdmi *hdmi)
{
int r;
if (hdmi.core.core_pwr_cnt++)
if (hdmi->core.core_pwr_cnt++)
return 0;
r = regulator_enable(hdmi.vdda_reg);
r = regulator_enable(hdmi->vdda_reg);
if (r)
goto err_reg_enable;
r = hdmi_runtime_get();
r = hdmi_runtime_get(hdmi);
if (r)
goto err_runtime_get;
hdmi4_core_powerdown_disable(&hdmi.core);
hdmi4_core_powerdown_disable(&hdmi->core);
/* Make selection of HDMI in DSS */
dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
dss_select_hdmi_venc_clk_source(hdmi->dss, DSS_HDMI_M_PCLK);
hdmi.core_enabled = true;
hdmi->core_enabled = true;
return 0;
err_runtime_get:
regulator_disable(hdmi.vdda_reg);
regulator_disable(hdmi->vdda_reg);
err_reg_enable:
hdmi.core.core_pwr_cnt--;
hdmi->core.core_pwr_cnt--;
return r;
}
static void hdmi_power_off_core(struct omap_dss_device *dssdev)
static void hdmi_power_off_core(struct omap_hdmi *hdmi)
{
if (--hdmi.core.core_pwr_cnt)
if (--hdmi->core.core_pwr_cnt)
return;
hdmi.core_enabled = false;
hdmi->core_enabled = false;
hdmi_runtime_put();
regulator_disable(hdmi.vdda_reg);
hdmi_runtime_put(hdmi);
regulator_disable(hdmi->vdda_reg);
}
static int hdmi_power_on_full(struct omap_dss_device *dssdev)
static int hdmi_power_on_full(struct omap_hdmi *hdmi)
{
int r;
struct videomode *vm;
enum omap_channel channel = dssdev->dispc_channel;
struct hdmi_wp_data *wp = &hdmi.wp;
struct hdmi_wp_data *wp = &hdmi->wp;
struct dss_pll_clock_info hdmi_cinfo = { 0 };
unsigned pc;
unsigned int pc;
r = hdmi_power_on_core(dssdev);
r = hdmi_power_on_core(hdmi);
if (r)
return r;
......@@ -190,7 +187,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
hdmi_wp_clear_irqenable(wp, ~HDMI_IRQ_CORE);
hdmi_wp_set_irqstatus(wp, ~HDMI_IRQ_CORE);
vm = &hdmi.cfg.vm;
vm = &hdmi->cfg.vm;
DSSDBG("hdmi_power_on hactive= %d vactive = %d\n", vm->hactive,
vm->vactive);
......@@ -202,22 +199,22 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
/* DSS_HDMI_TCLK is bitclk / 10 */
pc *= 10;
dss_pll_calc_b(&hdmi.pll.pll, clk_get_rate(hdmi.pll.pll.clkin),
dss_pll_calc_b(&hdmi->pll.pll, clk_get_rate(hdmi->pll.pll.clkin),
pc, &hdmi_cinfo);
r = dss_pll_enable(&hdmi.pll.pll);
r = dss_pll_enable(&hdmi->pll.pll);
if (r) {
DSSERR("Failed to enable PLL\n");
goto err_pll_enable;
}
r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo);
r = dss_pll_set_config(&hdmi->pll.pll, &hdmi_cinfo);
if (r) {
DSSERR("Failed to configure PLL\n");
goto err_pll_cfg;
}
r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco,
r = hdmi_phy_configure(&hdmi->phy, hdmi_cinfo.clkdco,
hdmi_cinfo.clkout[0]);
if (r) {
DSSDBG("Failed to configure PHY\n");
......@@ -228,16 +225,16 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
if (r)
goto err_phy_pwr;
hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
hdmi4_configure(&hdmi->core, &hdmi->wp, &hdmi->cfg);
/* tv size */
dss_mgr_set_timings(channel, vm);
dss_mgr_set_timings(&hdmi->output, vm);
r = dss_mgr_enable(channel);
r = dss_mgr_enable(&hdmi->output);
if (r)
goto err_mgr_enable;
r = hdmi_wp_video_start(&hdmi.wp);
r = hdmi_wp_video_start(&hdmi->wp);
if (r)
goto err_vid_enable;
......@@ -247,39 +244,39 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
return 0;
err_vid_enable:
dss_mgr_disable(channel);
dss_mgr_disable(&hdmi->output);
err_mgr_enable:
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
hdmi_wp_set_phy_pwr(&hdmi->wp, HDMI_PHYPWRCMD_OFF);
err_phy_pwr:
err_phy_cfg:
err_pll_cfg:
dss_pll_disable(&hdmi.pll.pll);
dss_pll_disable(&hdmi->pll.pll);
err_pll_enable:
hdmi_power_off_core(dssdev);
hdmi_power_off_core(hdmi);
return -EIO;
}
static void hdmi_power_off_full(struct omap_dss_device *dssdev)
static void hdmi_power_off_full(struct omap_hdmi *hdmi)
{
enum omap_channel channel = dssdev->dispc_channel;
hdmi_wp_clear_irqenable(&hdmi.wp, ~HDMI_IRQ_CORE);
hdmi_wp_clear_irqenable(&hdmi->wp, ~HDMI_IRQ_CORE);
hdmi_wp_video_stop(&hdmi.wp);
hdmi_wp_video_stop(&hdmi->wp);
dss_mgr_disable(channel);
dss_mgr_disable(&hdmi->output);
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
hdmi_wp_set_phy_pwr(&hdmi->wp, HDMI_PHYPWRCMD_OFF);
dss_pll_disable(&hdmi.pll.pll);
dss_pll_disable(&hdmi->pll.pll);
hdmi_power_off_core(dssdev);
hdmi_power_off_core(hdmi);
}
static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
struct videomode *vm)
{
if (!dispc_mgr_timings_ok(dssdev->dispc_channel, vm))
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
if (!dispc_mgr_timings_ok(hdmi->dss->dispc, dssdev->dispc_channel, vm))
return -EINVAL;
return 0;
......@@ -288,52 +285,59 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
struct videomode *vm)
{
mutex_lock(&hdmi.lock);
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
mutex_lock(&hdmi->lock);
hdmi.cfg.vm = *vm;
hdmi->cfg.vm = *vm;
dispc_set_tv_pclk(vm->pixelclock);
dispc_set_tv_pclk(hdmi->dss->dispc, vm->pixelclock);
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
}
static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
{
*vm = hdmi.cfg.vm;
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
*vm = hdmi->cfg.vm;
}
static void hdmi_dump_regs(struct seq_file *s)
static int hdmi_dump_regs(struct seq_file *s, void *p)
{
mutex_lock(&hdmi.lock);
struct omap_hdmi *hdmi = s->private;
if (hdmi_runtime_get()) {
mutex_unlock(&hdmi.lock);
return;
mutex_lock(&hdmi->lock);
if (hdmi_runtime_get(hdmi)) {
mutex_unlock(&hdmi->lock);
return 0;
}
hdmi_wp_dump(&hdmi.wp, s);
hdmi_pll_dump(&hdmi.pll, s);
hdmi_phy_dump(&hdmi.phy, s);
hdmi4_core_dump(&hdmi.core, s);
hdmi_wp_dump(&hdmi->wp, s);
hdmi_pll_dump(&hdmi->pll, s);
hdmi_phy_dump(&hdmi->phy, s);
hdmi4_core_dump(&hdmi->core, s);
hdmi_runtime_put();
mutex_unlock(&hdmi.lock);
hdmi_runtime_put(hdmi);
mutex_unlock(&hdmi->lock);
return 0;
}
static int read_edid(u8 *buf, int len)
static int read_edid(struct omap_hdmi *hdmi, u8 *buf, int len)
{
int r;
mutex_lock(&hdmi.lock);
mutex_lock(&hdmi->lock);
r = hdmi_runtime_get();
r = hdmi_runtime_get(hdmi);
BUG_ON(r);
r = hdmi4_read_edid(&hdmi.core, buf, len);
r = hdmi4_read_edid(&hdmi->core, buf, len);
hdmi_runtime_put();
mutex_unlock(&hdmi.lock);
hdmi_runtime_put(hdmi);
mutex_unlock(&hdmi->lock);
return r;
}
......@@ -352,112 +356,117 @@ static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
static int hdmi_display_enable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *out = &hdmi.output;
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
unsigned long flags;
int r = 0;
DSSDBG("ENTER hdmi_display_enable\n");
mutex_lock(&hdmi.lock);
mutex_lock(&hdmi->lock);
if (!out->dispc_channel_connected) {
if (!dssdev->dispc_channel_connected) {
DSSERR("failed to enable display: no output/manager\n");
r = -ENODEV;
goto err0;
}
r = hdmi_power_on_full(dssdev);
r = hdmi_power_on_full(hdmi);
if (r) {
DSSERR("failed to power on device\n");
goto err0;
}
if (hdmi.audio_configured) {
r = hdmi4_audio_config(&hdmi.core, &hdmi.wp, &hdmi.audio_config,
hdmi.cfg.vm.pixelclock);
if (hdmi->audio_configured) {
r = hdmi4_audio_config(&hdmi->core, &hdmi->wp,
&hdmi->audio_config,
hdmi->cfg.vm.pixelclock);
if (r) {
DSSERR("Error restoring audio configuration: %d", r);
hdmi.audio_abort_cb(&hdmi.pdev->dev);
hdmi.audio_configured = false;
hdmi->audio_abort_cb(&hdmi->pdev->dev);
hdmi->audio_configured = false;
}
}
spin_lock_irqsave(&hdmi.audio_playing_lock, flags);
if (hdmi.audio_configured && hdmi.audio_playing)
hdmi_start_audio_stream(&hdmi);
hdmi.display_enabled = true;
spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags);
spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
if (hdmi->audio_configured && hdmi->audio_playing)
hdmi_start_audio_stream(hdmi);
hdmi->display_enabled = true;
spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
return 0;
err0:
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
return r;
}
static void hdmi_display_disable(struct omap_dss_device *dssdev)
{
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
unsigned long flags;
DSSDBG("Enter hdmi_display_disable\n");
mutex_lock(&hdmi.lock);
mutex_lock(&hdmi->lock);
spin_lock_irqsave(&hdmi.audio_playing_lock, flags);
hdmi_stop_audio_stream(&hdmi);
hdmi.display_enabled = false;
spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags);
spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
hdmi_stop_audio_stream(hdmi);
hdmi->display_enabled = false;
spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
hdmi_power_off_full(dssdev);
hdmi_power_off_full(hdmi);
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
}
int hdmi4_core_enable(struct omap_dss_device *dssdev)
int hdmi4_core_enable(struct hdmi_core_data *core)
{
struct omap_hdmi *hdmi = container_of(core, struct omap_hdmi, core);
int r = 0;
DSSDBG("ENTER omapdss_hdmi4_core_enable\n");
mutex_lock(&hdmi.lock);
mutex_lock(&hdmi->lock);
r = hdmi_power_on_core(dssdev);
r = hdmi_power_on_core(hdmi);
if (r) {
DSSERR("failed to power on device\n");
goto err0;
}
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
return 0;
err0:
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
return r;
}
void hdmi4_core_disable(struct omap_dss_device *dssdev)
void hdmi4_core_disable(struct hdmi_core_data *core)
{
struct omap_hdmi *hdmi = container_of(core, struct omap_hdmi, core);
DSSDBG("Enter omapdss_hdmi4_core_disable\n");
mutex_lock(&hdmi.lock);
mutex_lock(&hdmi->lock);
hdmi_power_off_core(dssdev);
hdmi_power_off_core(hdmi);
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
}
static int hdmi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
enum omap_channel channel = dssdev->dispc_channel;
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
int r;
r = hdmi_init_regulator();
r = hdmi_init_regulator(hdmi);
if (r)
return r;
r = dss_mgr_connect(channel, dssdev);
r = dss_mgr_connect(&hdmi->output, dssdev);
if (r)
return r;
......@@ -465,7 +474,7 @@ static int hdmi_connect(struct omap_dss_device *dssdev,
if (r) {
DSSERR("failed to connect output to new device: %s\n",
dst->name);
dss_mgr_disconnect(channel, dssdev);
dss_mgr_disconnect(&hdmi->output, dssdev);
return r;
}
......@@ -475,7 +484,7 @@ static int hdmi_connect(struct omap_dss_device *dssdev,
static void hdmi_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
enum omap_channel channel = dssdev->dispc_channel;
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
WARN_ON(dst != dssdev->dst);
......@@ -484,51 +493,58 @@ static void hdmi_disconnect(struct omap_dss_device *dssdev,
omapdss_output_unset_device(dssdev);
dss_mgr_disconnect(channel, dssdev);
dss_mgr_disconnect(&hdmi->output, dssdev);
}
static int hdmi_read_edid(struct omap_dss_device *dssdev,
u8 *edid, int len)
{
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
bool need_enable;
int r;
need_enable = hdmi.core_enabled == false;
need_enable = hdmi->core_enabled == false;
if (need_enable) {
r = hdmi4_core_enable(dssdev);
r = hdmi4_core_enable(&hdmi->core);
if (r)
return r;
}
r = read_edid(edid, len);
r = read_edid(hdmi, edid, len);
if (r >= 256)
hdmi4_cec_set_phys_addr(&hdmi.core,
hdmi4_cec_set_phys_addr(&hdmi->core,
cec_get_edid_phys_addr(edid, r, NULL));
else
hdmi4_cec_set_phys_addr(&hdmi.core, CEC_PHYS_ADDR_INVALID);
hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
if (need_enable)
hdmi4_core_disable(dssdev);
hdmi4_core_disable(&hdmi->core);
return r;
}
static void hdmi_lost_hotplug(struct omap_dss_device *dssdev)
{
hdmi4_cec_set_phys_addr(&hdmi.core, CEC_PHYS_ADDR_INVALID);
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
}
static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
const struct hdmi_avi_infoframe *avi)
{
hdmi.cfg.infoframe = *avi;
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
hdmi->cfg.infoframe = *avi;
return 0;
}
static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
bool hdmi_mode)
{
hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
hdmi->cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
return 0;
}
......@@ -549,11 +565,11 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
.set_hdmi_mode = hdmi_set_hdmi_mode,
};
static void hdmi_init_output(struct platform_device *pdev)
static void hdmi_init_output(struct omap_hdmi *hdmi)
{
struct omap_dss_device *out = &hdmi.output;
struct omap_dss_device *out = &hdmi->output;
out->dev = &pdev->dev;
out->dev = &hdmi->pdev->dev;
out->id = OMAP_DSS_OUTPUT_HDMI;
out->output_type = OMAP_DISPLAY_TYPE_HDMI;
out->name = "hdmi.0";
......@@ -564,15 +580,16 @@ static void hdmi_init_output(struct platform_device *pdev)
omapdss_register_output(out);
}
static void hdmi_uninit_output(struct platform_device *pdev)
static void hdmi_uninit_output(struct omap_hdmi *hdmi)
{
struct omap_dss_device *out = &hdmi.output;
struct omap_dss_device *out = &hdmi->output;
omapdss_unregister_output(out);
}
static int hdmi_probe_of(struct platform_device *pdev)
static int hdmi_probe_of(struct omap_hdmi *hdmi)
{
struct platform_device *pdev = hdmi->pdev;
struct device_node *node = pdev->dev.of_node;
struct device_node *ep;
int r;
......@@ -581,7 +598,7 @@ static int hdmi_probe_of(struct platform_device *pdev)
if (!ep)
return 0;
r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy);
r = hdmi_parse_lanes_of(pdev, ep, &hdmi->phy);
if (r)
goto err;
......@@ -598,21 +615,16 @@ static int hdmi_audio_startup(struct device *dev,
void (*abort_cb)(struct device *dev))
{
struct omap_hdmi *hd = dev_get_drvdata(dev);
int ret = 0;
mutex_lock(&hd->lock);
if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
ret = -EPERM;
goto out;
}
WARN_ON(hd->audio_abort_cb != NULL);
hd->audio_abort_cb = abort_cb;
out:
mutex_unlock(&hd->lock);
return ret;
return 0;
}
static int hdmi_audio_shutdown(struct device *dev)
......@@ -633,12 +645,14 @@ static int hdmi_audio_start(struct device *dev)
struct omap_hdmi *hd = dev_get_drvdata(dev);
unsigned long flags;
WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
spin_lock_irqsave(&hd->audio_playing_lock, flags);
if (hd->display_enabled)
if (hd->display_enabled) {
if (!hdmi_mode_has_audio(&hd->cfg))
DSSERR("%s: Video mode does not support audio\n",
__func__);
hdmi_start_audio_stream(hd);
}
hd->audio_playing = true;
spin_unlock_irqrestore(&hd->audio_playing_lock, flags);
......@@ -669,17 +683,15 @@ static int hdmi_audio_config(struct device *dev,
mutex_lock(&hd->lock);
if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
ret = -EPERM;
goto out;
if (hd->display_enabled) {
ret = hdmi4_audio_config(&hd->core, &hd->wp, dss_audio,
hd->cfg.vm.pixelclock);
if (ret)
goto out;
}
ret = hdmi4_audio_config(&hd->core, &hd->wp, dss_audio,
hd->cfg.vm.pixelclock);
if (!ret) {
hd->audio_configured = true;
hd->audio_config = *dss_audio;
}
hd->audio_configured = true;
hd->audio_config = *dss_audio;
out:
mutex_unlock(&hd->lock);
......@@ -694,21 +706,21 @@ static const struct omap_hdmi_audio_ops hdmi_audio_ops = {
.audio_config = hdmi_audio_config,
};
static int hdmi_audio_register(struct device *dev)
static int hdmi_audio_register(struct omap_hdmi *hdmi)
{
struct omap_hdmi_audio_pdata pdata = {
.dev = dev,
.dev = &hdmi->pdev->dev,
.version = 4,
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi->wp),
.ops = &hdmi_audio_ops,
};
hdmi.audio_pdev = platform_device_register_data(
dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
hdmi->audio_pdev = platform_device_register_data(
&hdmi->pdev->dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
&pdata, sizeof(pdata));
if (IS_ERR(hdmi.audio_pdev))
return PTR_ERR(hdmi.audio_pdev);
if (IS_ERR(hdmi->audio_pdev))
return PTR_ERR(hdmi->audio_pdev);
return 0;
}
......@@ -717,88 +729,103 @@ static int hdmi_audio_register(struct device *dev)
static int hdmi4_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
struct dss_device *dss = dss_get_device(master);
struct omap_hdmi *hdmi;
int r;
int irq;
hdmi.pdev = pdev;
dev_set_drvdata(&pdev->dev, &hdmi);
hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
if (!hdmi)
return -ENOMEM;
hdmi->pdev = pdev;
hdmi->dss = dss;
dev_set_drvdata(&pdev->dev, hdmi);
mutex_init(&hdmi.lock);
spin_lock_init(&hdmi.audio_playing_lock);
mutex_init(&hdmi->lock);
spin_lock_init(&hdmi->audio_playing_lock);
r = hdmi_probe_of(pdev);
r = hdmi_probe_of(hdmi);
if (r)
return r;
goto err_free;
r = hdmi_wp_init(pdev, &hdmi.wp, 4);
r = hdmi_wp_init(pdev, &hdmi->wp, 4);
if (r)
return r;
goto err_free;
r = hdmi_pll_init(pdev, &hdmi.pll, &hdmi.wp);
r = hdmi_pll_init(dss, pdev, &hdmi->pll, &hdmi->wp);
if (r)
return r;
goto err_free;
r = hdmi_phy_init(pdev, &hdmi.phy, 4);
r = hdmi_phy_init(pdev, &hdmi->phy, 4);
if (r)
goto err;
goto err_pll;
r = hdmi4_core_init(pdev, &hdmi.core);
r = hdmi4_core_init(pdev, &hdmi->core);
if (r)
goto err;
goto err_pll;
r = hdmi4_cec_init(pdev, &hdmi.core, &hdmi.wp);
r = hdmi4_cec_init(pdev, &hdmi->core, &hdmi->wp);
if (r)
goto err;
goto err_pll;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
DSSERR("platform_get_irq failed\n");
r = -ENODEV;
goto err;
goto err_pll;
}
r = devm_request_threaded_irq(&pdev->dev, irq,
NULL, hdmi_irq_handler,
IRQF_ONESHOT, "OMAP HDMI", &hdmi);
IRQF_ONESHOT, "OMAP HDMI", hdmi);
if (r) {
DSSERR("HDMI IRQ request failed\n");
goto err;
goto err_pll;
}
pm_runtime_enable(&pdev->dev);
hdmi_init_output(pdev);
hdmi_init_output(hdmi);
r = hdmi_audio_register(&pdev->dev);
r = hdmi_audio_register(hdmi);
if (r) {
DSSERR("Registering HDMI audio failed\n");
hdmi_uninit_output(pdev);
hdmi_uninit_output(hdmi);
pm_runtime_disable(&pdev->dev);
return r;
}
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs,
hdmi);
return 0;
err:
hdmi_pll_uninit(&hdmi.pll);
err_pll:
hdmi_pll_uninit(&hdmi->pll);
err_free:
kfree(hdmi);
return r;
}
static void hdmi4_unbind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_hdmi *hdmi = dev_get_drvdata(dev);
dss_debugfs_remove_file(hdmi->debugfs);
if (hdmi.audio_pdev)
platform_device_unregister(hdmi.audio_pdev);
if (hdmi->audio_pdev)
platform_device_unregister(hdmi->audio_pdev);
hdmi_uninit_output(pdev);
hdmi_uninit_output(hdmi);
hdmi4_cec_uninit(&hdmi.core);
hdmi4_cec_uninit(&hdmi->core);
hdmi_pll_uninit(&hdmi.pll);
hdmi_pll_uninit(&hdmi->pll);
pm_runtime_disable(&pdev->dev);
pm_runtime_disable(dev);
kfree(hdmi);
}
static const struct component_ops hdmi4_component_ops = {
......@@ -819,16 +846,19 @@ static int hdmi4_remove(struct platform_device *pdev)
static int hdmi_runtime_suspend(struct device *dev)
{
dispc_runtime_put();
struct omap_hdmi *hdmi = dev_get_drvdata(dev);
dispc_runtime_put(hdmi->dss->dispc);
return 0;
}
static int hdmi_runtime_resume(struct device *dev)
{
struct omap_hdmi *hdmi = dev_get_drvdata(dev);
int r;
r = dispc_runtime_get();
r = dispc_runtime_get(hdmi->dss->dispc);
if (r < 0)
return r;
......
......@@ -175,10 +175,10 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
REG_FLD_MOD(core->base, HDMI_CORE_SYS_INTR_UNMASK4, 0, 3, 3);
hdmi_wp_clear_irqenable(core->wp, HDMI_IRQ_CORE);
hdmi_wp_set_irqstatus(core->wp, HDMI_IRQ_CORE);
hdmi4_core_disable(NULL);
hdmi4_core_disable(core);
return 0;
}
err = hdmi4_core_enable(NULL);
err = hdmi4_core_enable(core);
if (err)
return err;
......
......@@ -266,8 +266,8 @@ void hdmi4_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s);
int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core);
int hdmi4_core_enable(struct omap_dss_device *dssdev);
void hdmi4_core_disable(struct omap_dss_device *dssdev);
int hdmi4_core_enable(struct hdmi_core_data *core);
void hdmi4_core_disable(struct hdmi_core_data *core);
void hdmi4_core_powerdown_disable(struct hdmi_core_data *core);
int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp);
......
......@@ -46,15 +46,13 @@
#include "hdmi5_core.h"
#include "dss.h"
static struct omap_hdmi hdmi;
static int hdmi_runtime_get(void)
static int hdmi_runtime_get(struct omap_hdmi *hdmi)
{
int r;
DSSDBG("hdmi_runtime_get\n");
r = pm_runtime_get_sync(&hdmi.pdev->dev);
r = pm_runtime_get_sync(&hdmi->pdev->dev);
WARN_ON(r < 0);
if (r < 0)
return r;
......@@ -62,19 +60,20 @@ static int hdmi_runtime_get(void)
return 0;
}
static void hdmi_runtime_put(void)
static void hdmi_runtime_put(struct omap_hdmi *hdmi)
{
int r;
DSSDBG("hdmi_runtime_put\n");
r = pm_runtime_put_sync(&hdmi.pdev->dev);
r = pm_runtime_put_sync(&hdmi->pdev->dev);
WARN_ON(r < 0 && r != -ENOSYS);
}
static irqreturn_t hdmi_irq_handler(int irq, void *data)
{
struct hdmi_wp_data *wp = data;
struct omap_hdmi *hdmi = data;
struct hdmi_wp_data *wp = &hdmi->wp;
u32 irqstatus;
irqstatus = hdmi_wp_get_irqstatus(wp);
......@@ -97,17 +96,17 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data)
* setting the PHY to LDOON. To ignore those, we force the RXDET
* line to 0 until the PHY power state has been changed.
*/
v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL);
v = hdmi_read_reg(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL);
v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */
v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */
hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v);
hdmi_write_reg(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v);
hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
HDMI_IRQ_LINK_DISCONNECT);
hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15);
REG_FLD_MOD(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15);
} else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
......@@ -118,70 +117,69 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data)
return IRQ_HANDLED;
}
static int hdmi_init_regulator(void)
static int hdmi_init_regulator(struct omap_hdmi *hdmi)
{
struct regulator *reg;
if (hdmi.vdda_reg != NULL)
if (hdmi->vdda_reg != NULL)
return 0;
reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
reg = devm_regulator_get(&hdmi->pdev->dev, "vdda");
if (IS_ERR(reg)) {
DSSERR("can't get VDDA regulator\n");
return PTR_ERR(reg);
}
hdmi.vdda_reg = reg;
hdmi->vdda_reg = reg;
return 0;
}
static int hdmi_power_on_core(struct omap_dss_device *dssdev)
static int hdmi_power_on_core(struct omap_hdmi *hdmi)
{
int r;
r = regulator_enable(hdmi.vdda_reg);
r = regulator_enable(hdmi->vdda_reg);
if (r)
return r;
r = hdmi_runtime_get();
r = hdmi_runtime_get(hdmi);
if (r)
goto err_runtime_get;
/* Make selection of HDMI in DSS */
dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
dss_select_hdmi_venc_clk_source(hdmi->dss, DSS_HDMI_M_PCLK);
hdmi.core_enabled = true;
hdmi->core_enabled = true;
return 0;
err_runtime_get:
regulator_disable(hdmi.vdda_reg);
regulator_disable(hdmi->vdda_reg);
return r;
}
static void hdmi_power_off_core(struct omap_dss_device *dssdev)
static void hdmi_power_off_core(struct omap_hdmi *hdmi)
{
hdmi.core_enabled = false;
hdmi->core_enabled = false;
hdmi_runtime_put();
regulator_disable(hdmi.vdda_reg);
hdmi_runtime_put(hdmi);
regulator_disable(hdmi->vdda_reg);
}
static int hdmi_power_on_full(struct omap_dss_device *dssdev)
static int hdmi_power_on_full(struct omap_hdmi *hdmi)
{
int r;
struct videomode *vm;
enum omap_channel channel = dssdev->dispc_channel;
struct dss_pll_clock_info hdmi_cinfo = { 0 };
unsigned pc;
unsigned int pc;
r = hdmi_power_on_core(dssdev);
r = hdmi_power_on_core(hdmi);
if (r)
return r;
vm = &hdmi.cfg.vm;
vm = &hdmi->cfg.vm;
DSSDBG("hdmi_power_on hactive= %d vactive = %d\n", vm->hactive,
vm->vactive);
......@@ -193,89 +191,89 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
/* DSS_HDMI_TCLK is bitclk / 10 */
pc *= 10;
dss_pll_calc_b(&hdmi.pll.pll, clk_get_rate(hdmi.pll.pll.clkin),
dss_pll_calc_b(&hdmi->pll.pll, clk_get_rate(hdmi->pll.pll.clkin),
pc, &hdmi_cinfo);
/* disable and clear irqs */
hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
hdmi_wp_set_irqstatus(&hdmi.wp,
hdmi_wp_get_irqstatus(&hdmi.wp));
hdmi_wp_clear_irqenable(&hdmi->wp, 0xffffffff);
hdmi_wp_set_irqstatus(&hdmi->wp,
hdmi_wp_get_irqstatus(&hdmi->wp));
r = dss_pll_enable(&hdmi.pll.pll);
r = dss_pll_enable(&hdmi->pll.pll);
if (r) {
DSSERR("Failed to enable PLL\n");
goto err_pll_enable;
}
r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo);
r = dss_pll_set_config(&hdmi->pll.pll, &hdmi_cinfo);
if (r) {
DSSERR("Failed to configure PLL\n");
goto err_pll_cfg;
}
r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco,
r = hdmi_phy_configure(&hdmi->phy, hdmi_cinfo.clkdco,
hdmi_cinfo.clkout[0]);
if (r) {
DSSDBG("Failed to start PHY\n");
goto err_phy_cfg;
}
r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON);
r = hdmi_wp_set_phy_pwr(&hdmi->wp, HDMI_PHYPWRCMD_LDOON);
if (r)
goto err_phy_pwr;
hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
hdmi5_configure(&hdmi->core, &hdmi->wp, &hdmi->cfg);
/* tv size */
dss_mgr_set_timings(channel, vm);
dss_mgr_set_timings(&hdmi->output, vm);
r = dss_mgr_enable(channel);
r = dss_mgr_enable(&hdmi->output);
if (r)
goto err_mgr_enable;
r = hdmi_wp_video_start(&hdmi.wp);
r = hdmi_wp_video_start(&hdmi->wp);
if (r)
goto err_vid_enable;
hdmi_wp_set_irqenable(&hdmi.wp,
hdmi_wp_set_irqenable(&hdmi->wp,
HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
return 0;
err_vid_enable:
dss_mgr_disable(channel);
dss_mgr_disable(&hdmi->output);
err_mgr_enable:
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
hdmi_wp_set_phy_pwr(&hdmi->wp, HDMI_PHYPWRCMD_OFF);
err_phy_pwr:
err_phy_cfg:
err_pll_cfg:
dss_pll_disable(&hdmi.pll.pll);
dss_pll_disable(&hdmi->pll.pll);
err_pll_enable:
hdmi_power_off_core(dssdev);
hdmi_power_off_core(hdmi);
return -EIO;
}
static void hdmi_power_off_full(struct omap_dss_device *dssdev)
static void hdmi_power_off_full(struct omap_hdmi *hdmi)
{
enum omap_channel channel = dssdev->dispc_channel;
hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
hdmi_wp_clear_irqenable(&hdmi->wp, 0xffffffff);
hdmi_wp_video_stop(&hdmi.wp);
hdmi_wp_video_stop(&hdmi->wp);
dss_mgr_disable(channel);
dss_mgr_disable(&hdmi->output);
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
hdmi_wp_set_phy_pwr(&hdmi->wp, HDMI_PHYPWRCMD_OFF);
dss_pll_disable(&hdmi.pll.pll);
dss_pll_disable(&hdmi->pll.pll);
hdmi_power_off_core(dssdev);
hdmi_power_off_core(hdmi);
}
static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
struct videomode *vm)
{
if (!dispc_mgr_timings_ok(dssdev->dispc_channel, vm))
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
if (!dispc_mgr_timings_ok(hdmi->dss->dispc, dssdev->dispc_channel, vm))
return -EINVAL;
return 0;
......@@ -284,66 +282,73 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
struct videomode *vm)
{
mutex_lock(&hdmi.lock);
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
hdmi.cfg.vm = *vm;
mutex_lock(&hdmi->lock);
dispc_set_tv_pclk(vm->pixelclock);
hdmi->cfg.vm = *vm;
mutex_unlock(&hdmi.lock);
dispc_set_tv_pclk(hdmi->dss->dispc, vm->pixelclock);
mutex_unlock(&hdmi->lock);
}
static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
{
*vm = hdmi.cfg.vm;
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
*vm = hdmi->cfg.vm;
}
static void hdmi_dump_regs(struct seq_file *s)
static int hdmi_dump_regs(struct seq_file *s, void *p)
{
mutex_lock(&hdmi.lock);
struct omap_hdmi *hdmi = s->private;
if (hdmi_runtime_get()) {
mutex_unlock(&hdmi.lock);
return;
mutex_lock(&hdmi->lock);
if (hdmi_runtime_get(hdmi)) {
mutex_unlock(&hdmi->lock);
return 0;
}
hdmi_wp_dump(&hdmi.wp, s);
hdmi_pll_dump(&hdmi.pll, s);
hdmi_phy_dump(&hdmi.phy, s);
hdmi5_core_dump(&hdmi.core, s);
hdmi_wp_dump(&hdmi->wp, s);
hdmi_pll_dump(&hdmi->pll, s);
hdmi_phy_dump(&hdmi->phy, s);
hdmi5_core_dump(&hdmi->core, s);
hdmi_runtime_put();
mutex_unlock(&hdmi.lock);
hdmi_runtime_put(hdmi);
mutex_unlock(&hdmi->lock);
return 0;
}
static int read_edid(u8 *buf, int len)
static int read_edid(struct omap_hdmi *hdmi, u8 *buf, int len)
{
int r;
int idlemode;
mutex_lock(&hdmi.lock);
mutex_lock(&hdmi->lock);
r = hdmi_runtime_get();
r = hdmi_runtime_get(hdmi);
BUG_ON(r);
idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
idlemode = REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
/* No-idle mode */
REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
r = hdmi5_read_edid(&hdmi.core, buf, len);
r = hdmi5_read_edid(&hdmi->core, buf, len);
REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
hdmi_runtime_put();
mutex_unlock(&hdmi.lock);
hdmi_runtime_put(hdmi);
mutex_unlock(&hdmi->lock);
return r;
}
static void hdmi_start_audio_stream(struct omap_hdmi *hd)
{
REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
hdmi_wp_audio_enable(&hd->wp, true);
hdmi_wp_audio_core_req_enable(&hd->wp, true);
}
......@@ -357,112 +362,114 @@ static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
static int hdmi_display_enable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *out = &hdmi.output;
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
unsigned long flags;
int r = 0;
DSSDBG("ENTER hdmi_display_enable\n");
mutex_lock(&hdmi.lock);
mutex_lock(&hdmi->lock);
if (!out->dispc_channel_connected) {
if (!dssdev->dispc_channel_connected) {
DSSERR("failed to enable display: no output/manager\n");
r = -ENODEV;
goto err0;
}
r = hdmi_power_on_full(dssdev);
r = hdmi_power_on_full(hdmi);
if (r) {
DSSERR("failed to power on device\n");
goto err0;
}
if (hdmi.audio_configured) {
r = hdmi5_audio_config(&hdmi.core, &hdmi.wp, &hdmi.audio_config,
hdmi.cfg.vm.pixelclock);
if (hdmi->audio_configured) {
r = hdmi5_audio_config(&hdmi->core, &hdmi->wp,
&hdmi->audio_config,
hdmi->cfg.vm.pixelclock);
if (r) {
DSSERR("Error restoring audio configuration: %d", r);
hdmi.audio_abort_cb(&hdmi.pdev->dev);
hdmi.audio_configured = false;
hdmi->audio_abort_cb(&hdmi->pdev->dev);
hdmi->audio_configured = false;
}
}
spin_lock_irqsave(&hdmi.audio_playing_lock, flags);
if (hdmi.audio_configured && hdmi.audio_playing)
hdmi_start_audio_stream(&hdmi);
hdmi.display_enabled = true;
spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags);
spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
if (hdmi->audio_configured && hdmi->audio_playing)
hdmi_start_audio_stream(hdmi);
hdmi->display_enabled = true;
spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
return 0;
err0:
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
return r;
}
static void hdmi_display_disable(struct omap_dss_device *dssdev)
{
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
unsigned long flags;
DSSDBG("Enter hdmi_display_disable\n");
mutex_lock(&hdmi.lock);
mutex_lock(&hdmi->lock);
spin_lock_irqsave(&hdmi.audio_playing_lock, flags);
hdmi_stop_audio_stream(&hdmi);
hdmi.display_enabled = false;
spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags);
spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
hdmi_stop_audio_stream(hdmi);
hdmi->display_enabled = false;
spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
hdmi_power_off_full(dssdev);
hdmi_power_off_full(hdmi);
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
}
static int hdmi_core_enable(struct omap_dss_device *dssdev)
static int hdmi_core_enable(struct omap_hdmi *hdmi)
{
int r = 0;
DSSDBG("ENTER omapdss_hdmi_core_enable\n");
mutex_lock(&hdmi.lock);
mutex_lock(&hdmi->lock);
r = hdmi_power_on_core(dssdev);
r = hdmi_power_on_core(hdmi);
if (r) {
DSSERR("failed to power on device\n");
goto err0;
}
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
return 0;
err0:
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
return r;
}
static void hdmi_core_disable(struct omap_dss_device *dssdev)
static void hdmi_core_disable(struct omap_hdmi *hdmi)
{
DSSDBG("Enter omapdss_hdmi_core_disable\n");
mutex_lock(&hdmi.lock);
mutex_lock(&hdmi->lock);
hdmi_power_off_core(dssdev);
hdmi_power_off_core(hdmi);
mutex_unlock(&hdmi.lock);
mutex_unlock(&hdmi->lock);
}
static int hdmi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
enum omap_channel channel = dssdev->dispc_channel;
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
int r;
r = hdmi_init_regulator();
r = hdmi_init_regulator(hdmi);
if (r)
return r;
r = dss_mgr_connect(channel, dssdev);
r = dss_mgr_connect(&hdmi->output, dssdev);
if (r)
return r;
......@@ -470,7 +477,7 @@ static int hdmi_connect(struct omap_dss_device *dssdev,
if (r) {
DSSERR("failed to connect output to new device: %s\n",
dst->name);
dss_mgr_disconnect(channel, dssdev);
dss_mgr_disconnect(&hdmi->output, dssdev);
return r;
}
......@@ -480,7 +487,7 @@ static int hdmi_connect(struct omap_dss_device *dssdev,
static void hdmi_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
enum omap_channel channel = dssdev->dispc_channel;
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
WARN_ON(dst != dssdev->dst);
......@@ -489,27 +496,28 @@ static void hdmi_disconnect(struct omap_dss_device *dssdev,
omapdss_output_unset_device(dssdev);
dss_mgr_disconnect(channel, dssdev);
dss_mgr_disconnect(&hdmi->output, dssdev);
}
static int hdmi_read_edid(struct omap_dss_device *dssdev,
u8 *edid, int len)
{
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
bool need_enable;
int r;
need_enable = hdmi.core_enabled == false;
need_enable = hdmi->core_enabled == false;
if (need_enable) {
r = hdmi_core_enable(dssdev);
r = hdmi_core_enable(hdmi);
if (r)
return r;
}
r = read_edid(edid, len);
r = read_edid(hdmi, edid, len);
if (need_enable)
hdmi_core_disable(dssdev);
hdmi_core_disable(hdmi);
return r;
}
......@@ -517,14 +525,18 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev,
static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
const struct hdmi_avi_infoframe *avi)
{
hdmi.cfg.infoframe = *avi;
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
hdmi->cfg.infoframe = *avi;
return 0;
}
static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
bool hdmi_mode)
{
hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
hdmi->cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
return 0;
}
......@@ -544,11 +556,11 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
.set_hdmi_mode = hdmi_set_hdmi_mode,
};
static void hdmi_init_output(struct platform_device *pdev)
static void hdmi_init_output(struct omap_hdmi *hdmi)
{
struct omap_dss_device *out = &hdmi.output;
struct omap_dss_device *out = &hdmi->output;
out->dev = &pdev->dev;
out->dev = &hdmi->pdev->dev;
out->id = OMAP_DSS_OUTPUT_HDMI;
out->output_type = OMAP_DISPLAY_TYPE_HDMI;
out->name = "hdmi.0";
......@@ -559,15 +571,16 @@ static void hdmi_init_output(struct platform_device *pdev)
omapdss_register_output(out);
}
static void hdmi_uninit_output(struct platform_device *pdev)
static void hdmi_uninit_output(struct omap_hdmi *hdmi)
{
struct omap_dss_device *out = &hdmi.output;
struct omap_dss_device *out = &hdmi->output;
omapdss_unregister_output(out);
}
static int hdmi_probe_of(struct platform_device *pdev)
static int hdmi_probe_of(struct omap_hdmi *hdmi)
{
struct platform_device *pdev = hdmi->pdev;
struct device_node *node = pdev->dev.of_node;
struct device_node *ep;
int r;
......@@ -576,7 +589,7 @@ static int hdmi_probe_of(struct platform_device *pdev)
if (!ep)
return 0;
r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy);
r = hdmi_parse_lanes_of(pdev, ep, &hdmi->phy);
if (r)
goto err;
......@@ -593,21 +606,16 @@ static int hdmi_audio_startup(struct device *dev,
void (*abort_cb)(struct device *dev))
{
struct omap_hdmi *hd = dev_get_drvdata(dev);
int ret = 0;
mutex_lock(&hd->lock);
if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
ret = -EPERM;
goto out;
}
WARN_ON(hd->audio_abort_cb != NULL);
hd->audio_abort_cb = abort_cb;
out:
mutex_unlock(&hd->lock);
return ret;
return 0;
}
static int hdmi_audio_shutdown(struct device *dev)
......@@ -628,12 +636,14 @@ static int hdmi_audio_start(struct device *dev)
struct omap_hdmi *hd = dev_get_drvdata(dev);
unsigned long flags;
WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
spin_lock_irqsave(&hd->audio_playing_lock, flags);
if (hd->display_enabled)
if (hd->display_enabled) {
if (!hdmi_mode_has_audio(&hd->cfg))
DSSERR("%s: Video mode does not support audio\n",
__func__);
hdmi_start_audio_stream(hd);
}
hd->audio_playing = true;
spin_unlock_irqrestore(&hd->audio_playing_lock, flags);
......@@ -645,7 +655,8 @@ static void hdmi_audio_stop(struct device *dev)
struct omap_hdmi *hd = dev_get_drvdata(dev);
unsigned long flags;
WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
if (!hdmi_mode_has_audio(&hd->cfg))
DSSERR("%s: Video mode does not support audio\n", __func__);
spin_lock_irqsave(&hd->audio_playing_lock, flags);
......@@ -664,18 +675,15 @@ static int hdmi_audio_config(struct device *dev,
mutex_lock(&hd->lock);
if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
ret = -EPERM;
goto out;
if (hd->display_enabled) {
ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio,
hd->cfg.vm.pixelclock);
if (ret)
goto out;
}
ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio,
hd->cfg.vm.pixelclock);
if (!ret) {
hd->audio_configured = true;
hd->audio_config = *dss_audio;
}
hd->audio_configured = true;
hd->audio_config = *dss_audio;
out:
mutex_unlock(&hd->lock);
......@@ -690,26 +698,26 @@ static const struct omap_hdmi_audio_ops hdmi_audio_ops = {
.audio_config = hdmi_audio_config,
};
static int hdmi_audio_register(struct device *dev)
static int hdmi_audio_register(struct omap_hdmi *hdmi)
{
struct omap_hdmi_audio_pdata pdata = {
.dev = dev,
.dev = &hdmi->pdev->dev,
.version = 5,
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi->wp),
.ops = &hdmi_audio_ops,
};
hdmi.audio_pdev = platform_device_register_data(
dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
hdmi->audio_pdev = platform_device_register_data(
&hdmi->pdev->dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
&pdata, sizeof(pdata));
if (IS_ERR(hdmi.audio_pdev))
return PTR_ERR(hdmi.audio_pdev);
if (IS_ERR(hdmi->audio_pdev))
return PTR_ERR(hdmi->audio_pdev);
hdmi_runtime_get();
hdmi.wp_idlemode =
REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
hdmi_runtime_put();
hdmi_runtime_get(hdmi);
hdmi->wp_idlemode =
REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
hdmi_runtime_put(hdmi);
return 0;
}
......@@ -718,82 +726,97 @@ static int hdmi_audio_register(struct device *dev)
static int hdmi5_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
struct dss_device *dss = dss_get_device(master);
struct omap_hdmi *hdmi;
int r;
int irq;
hdmi.pdev = pdev;
dev_set_drvdata(&pdev->dev, &hdmi);
hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
if (!hdmi)
return -ENOMEM;
mutex_init(&hdmi.lock);
spin_lock_init(&hdmi.audio_playing_lock);
hdmi->pdev = pdev;
hdmi->dss = dss;
dev_set_drvdata(&pdev->dev, hdmi);
r = hdmi_probe_of(pdev);
mutex_init(&hdmi->lock);
spin_lock_init(&hdmi->audio_playing_lock);
r = hdmi_probe_of(hdmi);
if (r)
return r;
goto err_free;
r = hdmi_wp_init(pdev, &hdmi.wp, 5);
r = hdmi_wp_init(pdev, &hdmi->wp, 5);
if (r)
return r;
goto err_free;
r = hdmi_pll_init(pdev, &hdmi.pll, &hdmi.wp);
r = hdmi_pll_init(dss, pdev, &hdmi->pll, &hdmi->wp);
if (r)
return r;
goto err_free;
r = hdmi_phy_init(pdev, &hdmi.phy, 5);
r = hdmi_phy_init(pdev, &hdmi->phy, 5);
if (r)
goto err;
goto err_pll;
r = hdmi5_core_init(pdev, &hdmi.core);
r = hdmi5_core_init(pdev, &hdmi->core);
if (r)
goto err;
goto err_pll;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
DSSERR("platform_get_irq failed\n");
r = -ENODEV;
goto err;
goto err_pll;
}
r = devm_request_threaded_irq(&pdev->dev, irq,
NULL, hdmi_irq_handler,
IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
IRQF_ONESHOT, "OMAP HDMI", hdmi);
if (r) {
DSSERR("HDMI IRQ request failed\n");
goto err;
goto err_pll;
}
pm_runtime_enable(&pdev->dev);
hdmi_init_output(pdev);
hdmi_init_output(hdmi);
r = hdmi_audio_register(&pdev->dev);
r = hdmi_audio_register(hdmi);
if (r) {
DSSERR("Registering HDMI audio failed %d\n", r);
hdmi_uninit_output(pdev);
hdmi_uninit_output(hdmi);
pm_runtime_disable(&pdev->dev);
return r;
}
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs,
hdmi);
return 0;
err:
hdmi_pll_uninit(&hdmi.pll);
err_pll:
hdmi_pll_uninit(&hdmi->pll);
err_free:
kfree(hdmi);
return r;
}
static void hdmi5_unbind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_hdmi *hdmi = dev_get_drvdata(dev);
dss_debugfs_remove_file(hdmi->debugfs);
if (hdmi.audio_pdev)
platform_device_unregister(hdmi.audio_pdev);
if (hdmi->audio_pdev)
platform_device_unregister(hdmi->audio_pdev);
hdmi_uninit_output(pdev);
hdmi_uninit_output(hdmi);
hdmi_pll_uninit(&hdmi.pll);
hdmi_pll_uninit(&hdmi->pll);
pm_runtime_disable(&pdev->dev);
pm_runtime_disable(dev);
kfree(hdmi);
}
static const struct component_ops hdmi5_component_ops = {
......@@ -814,16 +837,19 @@ static int hdmi5_remove(struct platform_device *pdev)
static int hdmi_runtime_suspend(struct device *dev)
{
dispc_runtime_put();
struct omap_hdmi *hdmi = dev_get_drvdata(dev);
dispc_runtime_put(hdmi->dss->dispc);
return 0;
}
static int hdmi_runtime_resume(struct device *dev)
{
struct omap_hdmi *hdmi = dev_get_drvdata(dev);
int r;
r = dispc_runtime_get();
r = dispc_runtime_get(hdmi->dss->dispc);
if (r < 0)
return r;
......
......@@ -50,14 +50,14 @@ static void hdmi_core_ddc_init(struct hdmi_core_data *core)
{
void __iomem *base = core->base;
const unsigned long long iclk = 266000000; /* DSS L3 ICLK */
const unsigned ss_scl_high = 4600; /* ns */
const unsigned ss_scl_low = 5400; /* ns */
const unsigned fs_scl_high = 600; /* ns */
const unsigned fs_scl_low = 1300; /* ns */
const unsigned sda_hold = 1000; /* ns */
const unsigned sfr_div = 10;
const unsigned int ss_scl_high = 4600; /* ns */
const unsigned int ss_scl_low = 5400; /* ns */
const unsigned int fs_scl_high = 600; /* ns */
const unsigned int fs_scl_low = 1300; /* ns */
const unsigned int sda_hold = 1000; /* ns */
const unsigned int sfr_div = 10;
unsigned long long sfr;
unsigned v;
unsigned int v;
sfr = iclk / sfr_div; /* SFR_DIV */
sfr /= 1000; /* SFR clock in kHz */
......@@ -430,11 +430,11 @@ static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
void __iomem *base = core->base;
u8 data[HDMI_INFOFRAME_SIZE(AVI)];
u8 *ptr;
unsigned y, a, b, s;
unsigned c, m, r;
unsigned itc, ec, q, sc;
unsigned vic;
unsigned yq, cn, pr;
unsigned int y, a, b, s;
unsigned int c, m, r;
unsigned int itc, ec, q, sc;
unsigned int vic;
unsigned int yq, cn, pr;
hdmi_avi_infoframe_pack(frame, data, sizeof(data));
......
......@@ -99,7 +99,7 @@ static void hdmi_phy_configure_lanes(struct hdmi_phy_data *phy)
u16 lane_cfg = 0;
int i;
unsigned lane_cfg_val;
unsigned int lane_cfg_val;
u16 pol_val = 0;
for (i = 0; i < 4; ++i)
......
......@@ -48,7 +48,7 @@ static int hdmi_pll_enable(struct dss_pll *dsspll)
r = pm_runtime_get_sync(&pll->pdev->dev);
WARN_ON(r < 0);
dss_ctrl_pll_enable(DSS_PLL_HDMI, true);
dss_ctrl_pll_enable(dsspll, true);
r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
if (r)
......@@ -65,7 +65,7 @@ static void hdmi_pll_disable(struct dss_pll *dsspll)
hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
dss_ctrl_pll_enable(DSS_PLL_HDMI, false);
dss_ctrl_pll_enable(dsspll, false);
r = pm_runtime_put_sync(&pll->pdev->dev);
WARN_ON(r < 0 && r != -ENOSYS);
......@@ -128,7 +128,8 @@ static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = {
.has_refsel = true,
};
static int hdmi_init_pll_data(struct platform_device *pdev,
static int hdmi_init_pll_data(struct dss_device *dss,
struct platform_device *pdev,
struct hdmi_pll_data *hpll)
{
struct dss_pll *pll = &hpll->pll;
......@@ -153,15 +154,15 @@ static int hdmi_init_pll_data(struct platform_device *pdev,
pll->ops = &hdmi_pll_ops;
r = dss_pll_register(pll);
r = dss_pll_register(dss, pll);
if (r)
return r;
return 0;
}
int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
struct hdmi_wp_data *wp)
int hdmi_pll_init(struct dss_device *dss, struct platform_device *pdev,
struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
{
int r;
struct resource *res;
......@@ -174,7 +175,7 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
if (IS_ERR(pll->base))
return PTR_ERR(pll->base);
r = hdmi_init_pll_data(pdev, pll);
r = hdmi_init_pll_data(dss, pdev, pll);
if (r) {
DSSERR("failed to init HDMI PLL\n");
return r;
......
......@@ -168,7 +168,7 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
{
u32 timing_h = 0;
u32 timing_v = 0;
unsigned hsync_len_offset = 1;
unsigned int hsync_len_offset = 1;
DSSDBG("Enter hdmi_wp_video_config_timing\n");
......
......@@ -59,7 +59,11 @@
#define DISPC_IRQ_ACBIAS_COUNT_STAT3 (1 << 29)
#define DISPC_IRQ_FRAMEDONE3 (1 << 30)
struct dss_device;
struct omap_drm_private;
struct omap_dss_device;
struct dispc_device;
struct dss_device;
struct dss_lcd_mgr_config;
struct snd_aes_iec958;
struct snd_cea_861_aud_if;
......@@ -159,21 +163,6 @@ enum omap_overlay_caps {
OMAP_DSS_OVL_CAP_REPLICATION = 1 << 5,
};
enum omap_dss_clk_source {
OMAP_DSS_CLK_SRC_FCK = 0, /* OMAP2/3: DSS1_ALWON_FCLK
* OMAP4: DSS_FCLK */
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK
* OMAP4: PLL1_CLK1 */
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK
* OMAP4: PLL1_CLK2 */
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC, /* OMAP4: PLL2_CLK1 */
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI, /* OMAP4: PLL2_CLK2 */
};
enum omap_hdmi_flags {
OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
};
enum omap_dss_output_id {
OMAP_DSS_OUTPUT_DPI = 1 << 0,
OMAP_DSS_OUTPUT_DBI = 1 << 1,
......@@ -198,8 +187,8 @@ enum omap_dss_dsi_trans_mode {
struct omap_dss_dsi_videomode_timings {
unsigned long hsclk;
unsigned ndl;
unsigned bitspp;
unsigned int ndl;
unsigned int bitspp;
/* pixels */
u16 hact;
......@@ -585,7 +574,12 @@ struct omap_dss_driver {
const struct hdmi_avi_infoframe *avi);
};
bool omapdss_is_initialized(void);
struct dss_device *omapdss_get_dss(void);
void omapdss_set_dss(struct dss_device *dss);
static inline bool omapdss_is_initialized(void)
{
return !!omapdss_get_dss();
}
int omapdss_register_display(struct omap_dss_device *dssdev);
void omapdss_unregister_display(struct omap_dss_device *dssdev);
......@@ -609,9 +603,6 @@ int omapdss_output_unset_device(struct omap_dss_device *out);
struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev);
void omapdss_default_get_timings(struct omap_dss_device *dssdev,
struct videomode *vm);
typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
......@@ -632,97 +623,139 @@ static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev)
struct omap_dss_device *
omapdss_of_find_source_for_first_ep(struct device_node *node);
void omapdss_set_is_initialized(bool set);
struct device_node *dss_of_port_get_parent_device(struct device_node *port);
u32 dss_of_port_get_port_number(struct device_node *port);
enum dss_writeback_channel {
DSS_WB_LCD1_MGR = 0,
DSS_WB_LCD2_MGR = 1,
DSS_WB_TV_MGR = 2,
DSS_WB_OVL0 = 3,
DSS_WB_OVL1 = 4,
DSS_WB_OVL2 = 5,
DSS_WB_OVL3 = 6,
DSS_WB_LCD3_MGR = 7,
};
struct dss_mgr_ops {
int (*connect)(enum omap_channel channel,
struct omap_dss_device *dst);
void (*disconnect)(enum omap_channel channel,
struct omap_dss_device *dst);
void (*start_update)(enum omap_channel channel);
int (*enable)(enum omap_channel channel);
void (*disable)(enum omap_channel channel);
void (*set_timings)(enum omap_channel channel,
const struct videomode *vm);
void (*set_lcd_config)(enum omap_channel channel,
const struct dss_lcd_mgr_config *config);
int (*register_framedone_handler)(enum omap_channel channel,
int (*connect)(struct omap_drm_private *priv,
enum omap_channel channel,
struct omap_dss_device *dst);
void (*disconnect)(struct omap_drm_private *priv,
enum omap_channel channel,
struct omap_dss_device *dst);
void (*start_update)(struct omap_drm_private *priv,
enum omap_channel channel);
int (*enable)(struct omap_drm_private *priv,
enum omap_channel channel);
void (*disable)(struct omap_drm_private *priv,
enum omap_channel channel);
void (*set_timings)(struct omap_drm_private *priv,
enum omap_channel channel,
const struct videomode *vm);
void (*set_lcd_config)(struct omap_drm_private *priv,
enum omap_channel channel,
const struct dss_lcd_mgr_config *config);
int (*register_framedone_handler)(struct omap_drm_private *priv,
enum omap_channel channel,
void (*handler)(void *), void *data);
void (*unregister_framedone_handler)(enum omap_channel channel,
void (*unregister_framedone_handler)(struct omap_drm_private *priv,
enum omap_channel channel,
void (*handler)(void *), void *data);
};
int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops);
int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops,
struct omap_drm_private *priv);
void dss_uninstall_mgr_ops(void);
int dss_mgr_connect(enum omap_channel channel,
struct omap_dss_device *dst);
void dss_mgr_disconnect(enum omap_channel channel,
struct omap_dss_device *dst);
void dss_mgr_set_timings(enum omap_channel channel,
int dss_mgr_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst);
void dss_mgr_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst);
void dss_mgr_set_timings(struct omap_dss_device *dssdev,
const struct videomode *vm);
void dss_mgr_set_lcd_config(enum omap_channel channel,
void dss_mgr_set_lcd_config(struct omap_dss_device *dssdev,
const struct dss_lcd_mgr_config *config);
int dss_mgr_enable(enum omap_channel channel);
void dss_mgr_disable(enum omap_channel channel);
void dss_mgr_start_update(enum omap_channel channel);
int dss_mgr_register_framedone_handler(enum omap_channel channel,
int dss_mgr_enable(struct omap_dss_device *dssdev);
void dss_mgr_disable(struct omap_dss_device *dssdev);
void dss_mgr_start_update(struct omap_dss_device *dssdev);
int dss_mgr_register_framedone_handler(struct omap_dss_device *dssdev,
void (*handler)(void *), void *data);
void dss_mgr_unregister_framedone_handler(enum omap_channel channel,
void dss_mgr_unregister_framedone_handler(struct omap_dss_device *dssdev,
void (*handler)(void *), void *data);
/* dispc ops */
struct dispc_ops {
u32 (*read_irqstatus)(void);
void (*clear_irqstatus)(u32 mask);
void (*write_irqenable)(u32 mask);
int (*request_irq)(irq_handler_t handler, void *dev_id);
void (*free_irq)(void *dev_id);
int (*runtime_get)(void);
void (*runtime_put)(void);
int (*get_num_ovls)(void);
int (*get_num_mgrs)(void);
u32 (*get_memory_bandwidth_limit)(void);
void (*mgr_enable)(enum omap_channel channel, bool enable);
bool (*mgr_is_enabled)(enum omap_channel channel);
u32 (*mgr_get_vsync_irq)(enum omap_channel channel);
u32 (*mgr_get_framedone_irq)(enum omap_channel channel);
u32 (*mgr_get_sync_lost_irq)(enum omap_channel channel);
bool (*mgr_go_busy)(enum omap_channel channel);
void (*mgr_go)(enum omap_channel channel);
void (*mgr_set_lcd_config)(enum omap_channel channel,
const struct dss_lcd_mgr_config *config);
void (*mgr_set_timings)(enum omap_channel channel,
const struct videomode *vm);
void (*mgr_setup)(enum omap_channel channel,
const struct omap_overlay_manager_info *info);
enum omap_dss_output_id (*mgr_get_supported_outputs)(enum omap_channel channel);
u32 (*mgr_gamma_size)(enum omap_channel channel);
void (*mgr_set_gamma)(enum omap_channel channel,
const struct drm_color_lut *lut,
unsigned int length);
int (*ovl_enable)(enum omap_plane_id plane, bool enable);
int (*ovl_setup)(enum omap_plane_id plane,
u32 (*read_irqstatus)(struct dispc_device *dispc);
void (*clear_irqstatus)(struct dispc_device *dispc, u32 mask);
void (*write_irqenable)(struct dispc_device *dispc, u32 mask);
int (*request_irq)(struct dispc_device *dispc, irq_handler_t handler,
void *dev_id);
void (*free_irq)(struct dispc_device *dispc, void *dev_id);
int (*runtime_get)(struct dispc_device *dispc);
void (*runtime_put)(struct dispc_device *dispc);
int (*get_num_ovls)(struct dispc_device *dispc);
int (*get_num_mgrs)(struct dispc_device *dispc);
u32 (*get_memory_bandwidth_limit)(struct dispc_device *dispc);
void (*mgr_enable)(struct dispc_device *dispc,
enum omap_channel channel, bool enable);
bool (*mgr_is_enabled)(struct dispc_device *dispc,
enum omap_channel channel);
u32 (*mgr_get_vsync_irq)(struct dispc_device *dispc,
enum omap_channel channel);
u32 (*mgr_get_framedone_irq)(struct dispc_device *dispc,
enum omap_channel channel);
u32 (*mgr_get_sync_lost_irq)(struct dispc_device *dispc,
enum omap_channel channel);
bool (*mgr_go_busy)(struct dispc_device *dispc,
enum omap_channel channel);
void (*mgr_go)(struct dispc_device *dispc, enum omap_channel channel);
void (*mgr_set_lcd_config)(struct dispc_device *dispc,
enum omap_channel channel,
const struct dss_lcd_mgr_config *config);
void (*mgr_set_timings)(struct dispc_device *dispc,
enum omap_channel channel,
const struct videomode *vm);
void (*mgr_setup)(struct dispc_device *dispc, enum omap_channel channel,
const struct omap_overlay_manager_info *info);
enum omap_dss_output_id (*mgr_get_supported_outputs)(
struct dispc_device *dispc, enum omap_channel channel);
u32 (*mgr_gamma_size)(struct dispc_device *dispc,
enum omap_channel channel);
void (*mgr_set_gamma)(struct dispc_device *dispc,
enum omap_channel channel,
const struct drm_color_lut *lut,
unsigned int length);
int (*ovl_enable)(struct dispc_device *dispc, enum omap_plane_id plane,
bool enable);
int (*ovl_setup)(struct dispc_device *dispc, enum omap_plane_id plane,
const struct omap_overlay_info *oi,
const struct videomode *vm, bool mem_to_mem,
enum omap_channel channel);
const struct videomode *vm, bool mem_to_mem,
enum omap_channel channel);
const u32 *(*ovl_get_color_modes)(struct dispc_device *dispc,
enum omap_plane_id plane);
const u32 *(*ovl_get_color_modes)(enum omap_plane_id plane);
u32 (*wb_get_framedone_irq)(struct dispc_device *dispc);
int (*wb_setup)(struct dispc_device *dispc,
const struct omap_dss_writeback_info *wi,
bool mem_to_mem, const struct videomode *vm,
enum dss_writeback_channel channel_in);
bool (*has_writeback)(struct dispc_device *dispc);
bool (*wb_go_busy)(struct dispc_device *dispc);
void (*wb_go)(struct dispc_device *dispc);
};
void dispc_set_ops(const struct dispc_ops *o);
const struct dispc_ops *dispc_get_ops(void);
struct dispc_device *dispc_get_dispc(struct dss_device *dss);
const struct dispc_ops *dispc_get_ops(struct dss_device *dss);
bool omapdss_component_is_display(struct device_node *node);
bool omapdss_component_is_output(struct device_node *node);
......
......@@ -156,7 +156,6 @@ struct omap_dss_device *omap_dss_find_output_by_port_node(struct device_node *po
return NULL;
}
EXPORT_SYMBOL(omap_dss_find_output_by_port_node);
struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev)
{
......@@ -171,13 +170,16 @@ struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device
EXPORT_SYMBOL(omapdss_find_output_from_display);
static const struct dss_mgr_ops *dss_mgr_ops;
static struct omap_drm_private *dss_mgr_ops_priv;
int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops)
int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops,
struct omap_drm_private *priv)
{
if (dss_mgr_ops)
return -EBUSY;
dss_mgr_ops = mgr_ops;
dss_mgr_ops_priv = priv;
return 0;
}
......@@ -186,64 +188,71 @@ EXPORT_SYMBOL(dss_install_mgr_ops);
void dss_uninstall_mgr_ops(void)
{
dss_mgr_ops = NULL;
dss_mgr_ops_priv = NULL;
}
EXPORT_SYMBOL(dss_uninstall_mgr_ops);
int dss_mgr_connect(enum omap_channel channel,
struct omap_dss_device *dst)
int dss_mgr_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst)
{
return dss_mgr_ops->connect(channel, dst);
return dss_mgr_ops->connect(dss_mgr_ops_priv,
dssdev->dispc_channel, dst);
}
EXPORT_SYMBOL(dss_mgr_connect);
void dss_mgr_disconnect(enum omap_channel channel,
struct omap_dss_device *dst)
void dss_mgr_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
dss_mgr_ops->disconnect(channel, dst);
dss_mgr_ops->disconnect(dss_mgr_ops_priv, dssdev->dispc_channel, dst);
}
EXPORT_SYMBOL(dss_mgr_disconnect);
void dss_mgr_set_timings(enum omap_channel channel, const struct videomode *vm)
void dss_mgr_set_timings(struct omap_dss_device *dssdev,
const struct videomode *vm)
{
dss_mgr_ops->set_timings(channel, vm);
dss_mgr_ops->set_timings(dss_mgr_ops_priv, dssdev->dispc_channel, vm);
}
EXPORT_SYMBOL(dss_mgr_set_timings);
void dss_mgr_set_lcd_config(enum omap_channel channel,
void dss_mgr_set_lcd_config(struct omap_dss_device *dssdev,
const struct dss_lcd_mgr_config *config)
{
dss_mgr_ops->set_lcd_config(channel, config);
dss_mgr_ops->set_lcd_config(dss_mgr_ops_priv,
dssdev->dispc_channel, config);
}
EXPORT_SYMBOL(dss_mgr_set_lcd_config);
int dss_mgr_enable(enum omap_channel channel)
int dss_mgr_enable(struct omap_dss_device *dssdev)
{
return dss_mgr_ops->enable(channel);
return dss_mgr_ops->enable(dss_mgr_ops_priv, dssdev->dispc_channel);
}
EXPORT_SYMBOL(dss_mgr_enable);
void dss_mgr_disable(enum omap_channel channel)
void dss_mgr_disable(struct omap_dss_device *dssdev)
{
dss_mgr_ops->disable(channel);
dss_mgr_ops->disable(dss_mgr_ops_priv, dssdev->dispc_channel);
}
EXPORT_SYMBOL(dss_mgr_disable);
void dss_mgr_start_update(enum omap_channel channel)
void dss_mgr_start_update(struct omap_dss_device *dssdev)
{
dss_mgr_ops->start_update(channel);
dss_mgr_ops->start_update(dss_mgr_ops_priv, dssdev->dispc_channel);
}
EXPORT_SYMBOL(dss_mgr_start_update);
int dss_mgr_register_framedone_handler(enum omap_channel channel,
int dss_mgr_register_framedone_handler(struct omap_dss_device *dssdev,
void (*handler)(void *), void *data)
{
return dss_mgr_ops->register_framedone_handler(channel, handler, data);
return dss_mgr_ops->register_framedone_handler(dss_mgr_ops_priv,
dssdev->dispc_channel,
handler, data);
}
EXPORT_SYMBOL(dss_mgr_register_framedone_handler);
void dss_mgr_unregister_framedone_handler(enum omap_channel channel,
void dss_mgr_unregister_framedone_handler(struct omap_dss_device *dssdev,
void (*handler)(void *), void *data)
{
dss_mgr_ops->unregister_framedone_handler(channel, handler, data);
dss_mgr_ops->unregister_framedone_handler(dss_mgr_ops_priv,
dssdev->dispc_channel,
handler, data);
}
EXPORT_SYMBOL(dss_mgr_unregister_framedone_handler);
......@@ -35,15 +35,14 @@
#define PLL_SSC_CONFIGURATION2 0x001C
#define PLL_CONFIGURATION4 0x0020
static struct dss_pll *dss_plls[4];
int dss_pll_register(struct dss_pll *pll)
int dss_pll_register(struct dss_device *dss, struct dss_pll *pll)
{
int i;
for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
if (!dss_plls[i]) {
dss_plls[i] = pll;
for (i = 0; i < ARRAY_SIZE(dss->plls); ++i) {
if (!dss->plls[i]) {
dss->plls[i] = pll;
pll->dss = dss;
return 0;
}
}
......@@ -53,29 +52,32 @@ int dss_pll_register(struct dss_pll *pll)
void dss_pll_unregister(struct dss_pll *pll)
{
struct dss_device *dss = pll->dss;
int i;
for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
if (dss_plls[i] == pll) {
dss_plls[i] = NULL;
for (i = 0; i < ARRAY_SIZE(dss->plls); ++i) {
if (dss->plls[i] == pll) {
dss->plls[i] = NULL;
pll->dss = NULL;
return;
}
}
}
struct dss_pll *dss_pll_find(const char *name)
struct dss_pll *dss_pll_find(struct dss_device *dss, const char *name)
{
int i;
for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
if (dss_plls[i] && strcmp(dss_plls[i]->name, name) == 0)
return dss_plls[i];
for (i = 0; i < ARRAY_SIZE(dss->plls); ++i) {
if (dss->plls[i] && strcmp(dss->plls[i]->name, name) == 0)
return dss->plls[i];
}
return NULL;
}
struct dss_pll *dss_pll_find_by_src(enum dss_clk_source src)
struct dss_pll *dss_pll_find_by_src(struct dss_device *dss,
enum dss_clk_source src)
{
struct dss_pll *pll;
......@@ -85,27 +87,27 @@ struct dss_pll *dss_pll_find_by_src(enum dss_clk_source src)
return NULL;
case DSS_CLK_SRC_HDMI_PLL:
return dss_pll_find("hdmi");
return dss_pll_find(dss, "hdmi");
case DSS_CLK_SRC_PLL1_1:
case DSS_CLK_SRC_PLL1_2:
case DSS_CLK_SRC_PLL1_3:
pll = dss_pll_find("dsi0");
pll = dss_pll_find(dss, "dsi0");
if (!pll)
pll = dss_pll_find("video0");
pll = dss_pll_find(dss, "video0");
return pll;
case DSS_CLK_SRC_PLL2_1:
case DSS_CLK_SRC_PLL2_2:
case DSS_CLK_SRC_PLL2_3:
pll = dss_pll_find("dsi1");
pll = dss_pll_find(dss, "dsi1");
if (!pll)
pll = dss_pll_find("video1");
pll = dss_pll_find(dss, "video1");
return pll;
}
}
unsigned dss_pll_get_clkout_idx_for_src(enum dss_clk_source src)
unsigned int dss_pll_get_clkout_idx_for_src(enum dss_clk_source src)
{
switch (src) {
case DSS_CLK_SRC_HDMI_PLL:
......@@ -277,7 +279,7 @@ bool dss_pll_calc_b(const struct dss_pll *pll, unsigned long clkin,
unsigned long fint, clkdco, clkout;
unsigned long target_clkdco;
unsigned long min_dco;
unsigned n, m, mf, m2, sd;
unsigned int n, m, mf, m2, sd;
const struct dss_pll_hw *hw = pll->hw;
DSSDBG("clkin %lu, target clkout %lu\n", clkin, target_clkout);
......
......@@ -29,8 +29,9 @@
#include "omapdss.h"
#include "dss.h"
static struct {
struct sdi_device {
struct platform_device *pdev;
struct dss_device *dss;
bool update_enabled;
struct regulator *vdds_sdi_reg;
......@@ -40,11 +41,12 @@ static struct {
int datapairs;
struct omap_dss_device output;
};
bool port_initialized;
} sdi;
#define dssdev_to_sdi(dssdev) container_of(dssdev, struct sdi_device, output)
struct sdi_clk_calc_ctx {
struct sdi_device *sdi;
unsigned long pck_min, pck_max;
unsigned long fck;
......@@ -70,16 +72,17 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
ctx->fck = fck;
return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max,
dpi_calc_dispc_cb, ctx);
return dispc_div_calc(ctx->sdi->dss->dispc, fck,
ctx->pck_min, ctx->pck_max,
dpi_calc_dispc_cb, ctx);
}
static int sdi_calc_clock_div(unsigned long pclk,
unsigned long *fck,
struct dispc_clock_info *dispc_cinfo)
static int sdi_calc_clock_div(struct sdi_device *sdi, unsigned long pclk,
unsigned long *fck,
struct dispc_clock_info *dispc_cinfo)
{
int i;
struct sdi_clk_calc_ctx ctx;
struct sdi_clk_calc_ctx ctx = { .sdi = sdi };
/*
* DSS fclk gives us very few possibilities, so finding a good pixel
......@@ -98,7 +101,8 @@ static int sdi_calc_clock_div(unsigned long pclk,
ctx.pck_min = 0;
ctx.pck_max = pclk + 1000 * i * i * i;
ok = dss_div_calc(pclk, ctx.pck_min, dpi_calc_dss_cb, &ctx);
ok = dss_div_calc(sdi->dss, pclk, ctx.pck_min,
dpi_calc_dss_cb, &ctx);
if (ok) {
*fck = ctx.fck;
*dispc_cinfo = ctx.dispc_cinfo;
......@@ -109,52 +113,49 @@ static int sdi_calc_clock_div(unsigned long pclk,
return -EINVAL;
}
static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
static void sdi_config_lcd_manager(struct sdi_device *sdi)
{
enum omap_channel channel = dssdev->dispc_channel;
sdi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
sdi->mgr_config.stallmode = false;
sdi->mgr_config.fifohandcheck = false;
sdi.mgr_config.stallmode = false;
sdi.mgr_config.fifohandcheck = false;
sdi->mgr_config.video_port_width = 24;
sdi->mgr_config.lcden_sig_polarity = 1;
sdi.mgr_config.video_port_width = 24;
sdi.mgr_config.lcden_sig_polarity = 1;
dss_mgr_set_lcd_config(channel, &sdi.mgr_config);
dss_mgr_set_lcd_config(&sdi->output, &sdi->mgr_config);
}
static int sdi_display_enable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *out = &sdi.output;
enum omap_channel channel = dssdev->dispc_channel;
struct videomode *vm = &sdi.vm;
struct sdi_device *sdi = dssdev_to_sdi(dssdev);
struct videomode *vm = &sdi->vm;
unsigned long fck;
struct dispc_clock_info dispc_cinfo;
unsigned long pck;
int r;
if (!out->dispc_channel_connected) {
if (!sdi->output.dispc_channel_connected) {
DSSERR("failed to enable display: no output/manager\n");
return -ENODEV;
}
r = regulator_enable(sdi.vdds_sdi_reg);
r = regulator_enable(sdi->vdds_sdi_reg);
if (r)
goto err_reg_enable;
r = dispc_runtime_get();
r = dispc_runtime_get(sdi->dss->dispc);
if (r)
goto err_get_dispc;
/* 15.5.9.1.2 */
vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_SYNC_POSEDGE;
r = sdi_calc_clock_div(vm->pixelclock, &fck, &dispc_cinfo);
r = sdi_calc_clock_div(sdi, vm->pixelclock, &fck, &dispc_cinfo);
if (r)
goto err_calc_clock_div;
sdi.mgr_config.clock_info = dispc_cinfo;
sdi->mgr_config.clock_info = dispc_cinfo;
pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div;
......@@ -166,13 +167,13 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
}
dss_mgr_set_timings(channel, vm);
dss_mgr_set_timings(&sdi->output, vm);
r = dss_set_fck_rate(fck);
r = dss_set_fck_rate(sdi->dss, fck);
if (r)
goto err_set_dss_clock_div;
sdi_config_lcd_manager(dssdev);
sdi_config_lcd_manager(sdi);
/*
* LCLK and PCLK divisors are located in shadow registers, and we
......@@ -185,63 +186,69 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
* need to care about the shadow register mechanism for pck-free. The
* exact reason for this is unknown.
*/
dispc_mgr_set_clock_div(channel, &sdi.mgr_config.clock_info);
dispc_mgr_set_clock_div(sdi->dss->dispc, sdi->output.dispc_channel,
&sdi->mgr_config.clock_info);
dss_sdi_init(sdi.datapairs);
r = dss_sdi_enable();
dss_sdi_init(sdi->dss, sdi->datapairs);
r = dss_sdi_enable(sdi->dss);
if (r)
goto err_sdi_enable;
mdelay(2);
r = dss_mgr_enable(channel);
r = dss_mgr_enable(&sdi->output);
if (r)
goto err_mgr_enable;
return 0;
err_mgr_enable:
dss_sdi_disable();
dss_sdi_disable(sdi->dss);
err_sdi_enable:
err_set_dss_clock_div:
err_calc_clock_div:
dispc_runtime_put();
dispc_runtime_put(sdi->dss->dispc);
err_get_dispc:
regulator_disable(sdi.vdds_sdi_reg);
regulator_disable(sdi->vdds_sdi_reg);
err_reg_enable:
return r;
}
static void sdi_display_disable(struct omap_dss_device *dssdev)
{
enum omap_channel channel = dssdev->dispc_channel;
struct sdi_device *sdi = dssdev_to_sdi(dssdev);
dss_mgr_disable(channel);
dss_mgr_disable(&sdi->output);
dss_sdi_disable();
dss_sdi_disable(sdi->dss);
dispc_runtime_put();
dispc_runtime_put(sdi->dss->dispc);
regulator_disable(sdi.vdds_sdi_reg);
regulator_disable(sdi->vdds_sdi_reg);
}
static void sdi_set_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
{
sdi.vm = *vm;
struct sdi_device *sdi = dssdev_to_sdi(dssdev);
sdi->vm = *vm;
}
static void sdi_get_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
{
*vm = sdi.vm;
struct sdi_device *sdi = dssdev_to_sdi(dssdev);
*vm = sdi->vm;
}
static int sdi_check_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
{
struct sdi_device *sdi = dssdev_to_sdi(dssdev);
enum omap_channel channel = dssdev->dispc_channel;
if (!dispc_mgr_timings_ok(channel, vm))
if (!dispc_mgr_timings_ok(sdi->dss->dispc, channel, vm))
return -EINVAL;
if (vm->pixelclock == 0)
......@@ -250,21 +257,21 @@ static int sdi_check_timings(struct omap_dss_device *dssdev,
return 0;
}
static int sdi_init_regulator(void)
static int sdi_init_regulator(struct sdi_device *sdi)
{
struct regulator *vdds_sdi;
if (sdi.vdds_sdi_reg)
if (sdi->vdds_sdi_reg)
return 0;
vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi");
vdds_sdi = devm_regulator_get(&sdi->pdev->dev, "vdds_sdi");
if (IS_ERR(vdds_sdi)) {
if (PTR_ERR(vdds_sdi) != -EPROBE_DEFER)
DSSERR("can't get VDDS_SDI regulator\n");
return PTR_ERR(vdds_sdi);
}
sdi.vdds_sdi_reg = vdds_sdi;
sdi->vdds_sdi_reg = vdds_sdi;
return 0;
}
......@@ -272,14 +279,14 @@ static int sdi_init_regulator(void)
static int sdi_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
enum omap_channel channel = dssdev->dispc_channel;
struct sdi_device *sdi = dssdev_to_sdi(dssdev);
int r;
r = sdi_init_regulator();
r = sdi_init_regulator(sdi);
if (r)
return r;
r = dss_mgr_connect(channel, dssdev);
r = dss_mgr_connect(&sdi->output, dssdev);
if (r)
return r;
......@@ -287,7 +294,7 @@ static int sdi_connect(struct omap_dss_device *dssdev,
if (r) {
DSSERR("failed to connect output to new device: %s\n",
dst->name);
dss_mgr_disconnect(channel, dssdev);
dss_mgr_disconnect(&sdi->output, dssdev);
return r;
}
......@@ -297,7 +304,7 @@ static int sdi_connect(struct omap_dss_device *dssdev,
static void sdi_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
enum omap_channel channel = dssdev->dispc_channel;
struct sdi_device *sdi = dssdev_to_sdi(dssdev);
WARN_ON(dst != dssdev->dst);
......@@ -306,7 +313,7 @@ static void sdi_disconnect(struct omap_dss_device *dssdev,
omapdss_output_unset_device(dssdev);
dss_mgr_disconnect(channel, dssdev);
dss_mgr_disconnect(&sdi->output, dssdev);
}
static const struct omapdss_sdi_ops sdi_ops = {
......@@ -321,11 +328,11 @@ static const struct omapdss_sdi_ops sdi_ops = {
.get_timings = sdi_get_timings,
};
static void sdi_init_output(struct platform_device *pdev)
static void sdi_init_output(struct sdi_device *sdi)
{
struct omap_dss_device *out = &sdi.output;
struct omap_dss_device *out = &sdi->output;
out->dev = &pdev->dev;
out->dev = &sdi->pdev->dev;
out->id = OMAP_DSS_OUTPUT_SDI;
out->output_type = OMAP_DISPLAY_TYPE_SDI;
out->name = "sdi.0";
......@@ -338,22 +345,28 @@ static void sdi_init_output(struct platform_device *pdev)
omapdss_register_output(out);
}
static void sdi_uninit_output(struct platform_device *pdev)
static void sdi_uninit_output(struct sdi_device *sdi)
{
struct omap_dss_device *out = &sdi.output;
omapdss_unregister_output(out);
omapdss_unregister_output(&sdi->output);
}
int sdi_init_port(struct platform_device *pdev, struct device_node *port)
int sdi_init_port(struct dss_device *dss, struct platform_device *pdev,
struct device_node *port)
{
struct sdi_device *sdi;
struct device_node *ep;
u32 datapairs;
int r;
sdi = kzalloc(sizeof(*sdi), GFP_KERNEL);
if (!sdi)
return -ENOMEM;
ep = of_get_next_child(port, NULL);
if (!ep)
return 0;
if (!ep) {
r = 0;
goto err_free;
}
r = of_property_read_u32(ep, "datapairs", &datapairs);
if (r) {
......@@ -361,28 +374,33 @@ int sdi_init_port(struct platform_device *pdev, struct device_node *port)
goto err_datapairs;
}
sdi.datapairs = datapairs;
sdi->datapairs = datapairs;
sdi->dss = dss;
of_node_put(ep);
sdi.pdev = pdev;
sdi_init_output(pdev);
sdi->pdev = pdev;
port->data = sdi;
sdi.port_initialized = true;
sdi_init_output(sdi);
return 0;
err_datapairs:
of_node_put(ep);
err_free:
kfree(sdi);
return r;
}
void sdi_uninit_port(struct device_node *port)
{
if (!sdi.port_initialized)
struct sdi_device *sdi = port->data;
if (!sdi)
return;
sdi_uninit_output(sdi.pdev);
sdi_uninit_output(sdi);
kfree(sdi);
}
......@@ -319,12 +319,15 @@ static enum venc_videomode venc_get_videomode(const struct videomode *vm)
return VENC_MODE_UNKNOWN;
}
static struct {
struct venc_device {
struct platform_device *pdev;
void __iomem *base;
struct mutex venc_lock;
u32 wss_data;
struct regulator *vdda_dac_reg;
struct dss_device *dss;
struct dss_debugfs_entry *debugfs;
struct clk *tv_dac_clk;
......@@ -334,81 +337,87 @@ static struct {
bool requires_tv_dac_clk;
struct omap_dss_device output;
} venc;
};
#define dssdev_to_venc(dssdev) container_of(dssdev, struct venc_device, output)
static inline void venc_write_reg(int idx, u32 val)
static inline void venc_write_reg(struct venc_device *venc, int idx, u32 val)
{
__raw_writel(val, venc.base + idx);
__raw_writel(val, venc->base + idx);
}
static inline u32 venc_read_reg(int idx)
static inline u32 venc_read_reg(struct venc_device *venc, int idx)
{
u32 l = __raw_readl(venc.base + idx);
u32 l = __raw_readl(venc->base + idx);
return l;
}
static void venc_write_config(const struct venc_config *config)
static void venc_write_config(struct venc_device *venc,
const struct venc_config *config)
{
DSSDBG("write venc conf\n");
venc_write_reg(VENC_LLEN, config->llen);
venc_write_reg(VENC_FLENS, config->flens);
venc_write_reg(VENC_CC_CARR_WSS_CARR, config->cc_carr_wss_carr);
venc_write_reg(VENC_C_PHASE, config->c_phase);
venc_write_reg(VENC_GAIN_U, config->gain_u);
venc_write_reg(VENC_GAIN_V, config->gain_v);
venc_write_reg(VENC_GAIN_Y, config->gain_y);
venc_write_reg(VENC_BLACK_LEVEL, config->black_level);
venc_write_reg(VENC_BLANK_LEVEL, config->blank_level);
venc_write_reg(VENC_M_CONTROL, config->m_control);
venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data |
venc.wss_data);
venc_write_reg(VENC_S_CARR, config->s_carr);
venc_write_reg(VENC_L21__WC_CTL, config->l21__wc_ctl);
venc_write_reg(VENC_SAVID__EAVID, config->savid__eavid);
venc_write_reg(VENC_FLEN__FAL, config->flen__fal);
venc_write_reg(VENC_LAL__PHASE_RESET, config->lal__phase_reset);
venc_write_reg(VENC_HS_INT_START_STOP_X, config->hs_int_start_stop_x);
venc_write_reg(VENC_HS_EXT_START_STOP_X, config->hs_ext_start_stop_x);
venc_write_reg(VENC_VS_INT_START_X, config->vs_int_start_x);
venc_write_reg(VENC_VS_INT_STOP_X__VS_INT_START_Y,
venc_write_reg(venc, VENC_LLEN, config->llen);
venc_write_reg(venc, VENC_FLENS, config->flens);
venc_write_reg(venc, VENC_CC_CARR_WSS_CARR, config->cc_carr_wss_carr);
venc_write_reg(venc, VENC_C_PHASE, config->c_phase);
venc_write_reg(venc, VENC_GAIN_U, config->gain_u);
venc_write_reg(venc, VENC_GAIN_V, config->gain_v);
venc_write_reg(venc, VENC_GAIN_Y, config->gain_y);
venc_write_reg(venc, VENC_BLACK_LEVEL, config->black_level);
venc_write_reg(venc, VENC_BLANK_LEVEL, config->blank_level);
venc_write_reg(venc, VENC_M_CONTROL, config->m_control);
venc_write_reg(venc, VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data |
venc->wss_data);
venc_write_reg(venc, VENC_S_CARR, config->s_carr);
venc_write_reg(venc, VENC_L21__WC_CTL, config->l21__wc_ctl);
venc_write_reg(venc, VENC_SAVID__EAVID, config->savid__eavid);
venc_write_reg(venc, VENC_FLEN__FAL, config->flen__fal);
venc_write_reg(venc, VENC_LAL__PHASE_RESET, config->lal__phase_reset);
venc_write_reg(venc, VENC_HS_INT_START_STOP_X,
config->hs_int_start_stop_x);
venc_write_reg(venc, VENC_HS_EXT_START_STOP_X,
config->hs_ext_start_stop_x);
venc_write_reg(venc, VENC_VS_INT_START_X, config->vs_int_start_x);
venc_write_reg(venc, VENC_VS_INT_STOP_X__VS_INT_START_Y,
config->vs_int_stop_x__vs_int_start_y);
venc_write_reg(VENC_VS_INT_STOP_Y__VS_EXT_START_X,
venc_write_reg(venc, VENC_VS_INT_STOP_Y__VS_EXT_START_X,
config->vs_int_stop_y__vs_ext_start_x);
venc_write_reg(VENC_VS_EXT_STOP_X__VS_EXT_START_Y,
venc_write_reg(venc, VENC_VS_EXT_STOP_X__VS_EXT_START_Y,
config->vs_ext_stop_x__vs_ext_start_y);
venc_write_reg(VENC_VS_EXT_STOP_Y, config->vs_ext_stop_y);
venc_write_reg(VENC_AVID_START_STOP_X, config->avid_start_stop_x);
venc_write_reg(VENC_AVID_START_STOP_Y, config->avid_start_stop_y);
venc_write_reg(VENC_FID_INT_START_X__FID_INT_START_Y,
venc_write_reg(venc, VENC_VS_EXT_STOP_Y, config->vs_ext_stop_y);
venc_write_reg(venc, VENC_AVID_START_STOP_X, config->avid_start_stop_x);
venc_write_reg(venc, VENC_AVID_START_STOP_Y, config->avid_start_stop_y);
venc_write_reg(venc, VENC_FID_INT_START_X__FID_INT_START_Y,
config->fid_int_start_x__fid_int_start_y);
venc_write_reg(VENC_FID_INT_OFFSET_Y__FID_EXT_START_X,
venc_write_reg(venc, VENC_FID_INT_OFFSET_Y__FID_EXT_START_X,
config->fid_int_offset_y__fid_ext_start_x);
venc_write_reg(VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y,
venc_write_reg(venc, VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y,
config->fid_ext_start_y__fid_ext_offset_y);
venc_write_reg(VENC_DAC_B__DAC_C, venc_read_reg(VENC_DAC_B__DAC_C));
venc_write_reg(VENC_VIDOUT_CTRL, config->vidout_ctrl);
venc_write_reg(VENC_HFLTR_CTRL, config->hfltr_ctrl);
venc_write_reg(VENC_X_COLOR, config->x_color);
venc_write_reg(VENC_LINE21, config->line21);
venc_write_reg(VENC_LN_SEL, config->ln_sel);
venc_write_reg(VENC_HTRIGGER_VTRIGGER, config->htrigger_vtrigger);
venc_write_reg(VENC_TVDETGP_INT_START_STOP_X,
venc_write_reg(venc, VENC_DAC_B__DAC_C,
venc_read_reg(venc, VENC_DAC_B__DAC_C));
venc_write_reg(venc, VENC_VIDOUT_CTRL, config->vidout_ctrl);
venc_write_reg(venc, VENC_HFLTR_CTRL, config->hfltr_ctrl);
venc_write_reg(venc, VENC_X_COLOR, config->x_color);
venc_write_reg(venc, VENC_LINE21, config->line21);
venc_write_reg(venc, VENC_LN_SEL, config->ln_sel);
venc_write_reg(venc, VENC_HTRIGGER_VTRIGGER, config->htrigger_vtrigger);
venc_write_reg(venc, VENC_TVDETGP_INT_START_STOP_X,
config->tvdetgp_int_start_stop_x);
venc_write_reg(VENC_TVDETGP_INT_START_STOP_Y,
venc_write_reg(venc, VENC_TVDETGP_INT_START_STOP_Y,
config->tvdetgp_int_start_stop_y);
venc_write_reg(VENC_GEN_CTRL, config->gen_ctrl);
venc_write_reg(VENC_F_CONTROL, config->f_control);
venc_write_reg(VENC_SYNC_CTRL, config->sync_ctrl);
venc_write_reg(venc, VENC_GEN_CTRL, config->gen_ctrl);
venc_write_reg(venc, VENC_F_CONTROL, config->f_control);
venc_write_reg(venc, VENC_SYNC_CTRL, config->sync_ctrl);
}
static void venc_reset(void)
static void venc_reset(struct venc_device *venc)
{
int t = 1000;
venc_write_reg(VENC_F_CONTROL, 1<<8);
while (venc_read_reg(VENC_F_CONTROL) & (1<<8)) {
venc_write_reg(venc, VENC_F_CONTROL, 1<<8);
while (venc_read_reg(venc, VENC_F_CONTROL) & (1<<8)) {
if (--t == 0) {
DSSERR("Failed to reset venc\n");
return;
......@@ -422,24 +431,24 @@ static void venc_reset(void)
#endif
}
static int venc_runtime_get(void)
static int venc_runtime_get(struct venc_device *venc)
{
int r;
DSSDBG("venc_runtime_get\n");
r = pm_runtime_get_sync(&venc.pdev->dev);
r = pm_runtime_get_sync(&venc->pdev->dev);
WARN_ON(r < 0);
return r < 0 ? r : 0;
}
static void venc_runtime_put(void)
static void venc_runtime_put(struct venc_device *venc)
{
int r;
DSSDBG("venc_runtime_put\n");
r = pm_runtime_put_sync(&venc.pdev->dev);
r = pm_runtime_put_sync(&venc->pdev->dev);
WARN_ON(r < 0 && r != -ENOSYS);
}
......@@ -455,119 +464,119 @@ static const struct venc_config *venc_timings_to_config(struct videomode *vm)
}
}
static int venc_power_on(struct omap_dss_device *dssdev)
static int venc_power_on(struct venc_device *venc)
{
enum omap_channel channel = dssdev->dispc_channel;
u32 l;
int r;
r = venc_runtime_get();
r = venc_runtime_get(venc);
if (r)
goto err0;
venc_reset();
venc_write_config(venc_timings_to_config(&venc.vm));
venc_reset(venc);
venc_write_config(venc, venc_timings_to_config(&venc->vm));
dss_set_venc_output(venc.type);
dss_set_dac_pwrdn_bgz(1);
dss_set_venc_output(venc->dss, venc->type);
dss_set_dac_pwrdn_bgz(venc->dss, 1);
l = 0;
if (venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE)
if (venc->type == OMAP_DSS_VENC_TYPE_COMPOSITE)
l |= 1 << 1;
else /* S-Video */
l |= (1 << 0) | (1 << 2);
if (venc.invert_polarity == false)
if (venc->invert_polarity == false)
l |= 1 << 3;
venc_write_reg(VENC_OUTPUT_CONTROL, l);
venc_write_reg(venc, VENC_OUTPUT_CONTROL, l);
dss_mgr_set_timings(channel, &venc.vm);
dss_mgr_set_timings(&venc->output, &venc->vm);
r = regulator_enable(venc.vdda_dac_reg);
r = regulator_enable(venc->vdda_dac_reg);
if (r)
goto err1;
r = dss_mgr_enable(channel);
r = dss_mgr_enable(&venc->output);
if (r)
goto err2;
return 0;
err2:
regulator_disable(venc.vdda_dac_reg);
regulator_disable(venc->vdda_dac_reg);
err1:
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
dss_set_dac_pwrdn_bgz(0);
venc_write_reg(venc, VENC_OUTPUT_CONTROL, 0);
dss_set_dac_pwrdn_bgz(venc->dss, 0);
venc_runtime_put();
venc_runtime_put(venc);
err0:
return r;
}
static void venc_power_off(struct omap_dss_device *dssdev)
static void venc_power_off(struct venc_device *venc)
{
enum omap_channel channel = dssdev->dispc_channel;
venc_write_reg(venc, VENC_OUTPUT_CONTROL, 0);
dss_set_dac_pwrdn_bgz(venc->dss, 0);
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
dss_set_dac_pwrdn_bgz(0);
dss_mgr_disable(&venc->output);
dss_mgr_disable(channel);
regulator_disable(venc->vdda_dac_reg);
regulator_disable(venc.vdda_dac_reg);
venc_runtime_put();
venc_runtime_put(venc);
}
static int venc_display_enable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *out = &venc.output;
struct venc_device *venc = dssdev_to_venc(dssdev);
int r;
DSSDBG("venc_display_enable\n");
mutex_lock(&venc.venc_lock);
mutex_lock(&venc->venc_lock);
if (!out->dispc_channel_connected) {
if (!dssdev->dispc_channel_connected) {
DSSERR("Failed to enable display: no output/manager\n");
r = -ENODEV;
goto err0;
}
r = venc_power_on(dssdev);
r = venc_power_on(venc);
if (r)
goto err0;
venc.wss_data = 0;
venc->wss_data = 0;
mutex_unlock(&venc.venc_lock);
mutex_unlock(&venc->venc_lock);
return 0;
err0:
mutex_unlock(&venc.venc_lock);
mutex_unlock(&venc->venc_lock);
return r;
}
static void venc_display_disable(struct omap_dss_device *dssdev)
{
struct venc_device *venc = dssdev_to_venc(dssdev);
DSSDBG("venc_display_disable\n");
mutex_lock(&venc.venc_lock);
mutex_lock(&venc->venc_lock);
venc_power_off(dssdev);
venc_power_off(venc);
mutex_unlock(&venc.venc_lock);
mutex_unlock(&venc->venc_lock);
}
static void venc_set_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
{
struct venc_device *venc = dssdev_to_venc(dssdev);
struct videomode actual_vm;
DSSDBG("venc_set_timings\n");
mutex_lock(&venc.venc_lock);
mutex_lock(&venc->venc_lock);
switch (venc_get_videomode(vm)) {
default:
......@@ -581,14 +590,14 @@ static void venc_set_timings(struct omap_dss_device *dssdev,
}
/* Reset WSS data when the TV standard changes. */
if (memcmp(&venc.vm, &actual_vm, sizeof(actual_vm)))
venc.wss_data = 0;
if (memcmp(&venc->vm, &actual_vm, sizeof(actual_vm)))
venc->wss_data = 0;
venc.vm = actual_vm;
venc->vm = actual_vm;
dispc_set_tv_pclk(13500000);
dispc_set_tv_pclk(venc->dss->dispc, 13500000);
mutex_unlock(&venc.venc_lock);
mutex_unlock(&venc->venc_lock);
}
static int venc_check_timings(struct omap_dss_device *dssdev,
......@@ -608,127 +617,136 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
static void venc_get_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
{
mutex_lock(&venc.venc_lock);
struct venc_device *venc = dssdev_to_venc(dssdev);
*vm = venc.vm;
mutex_lock(&venc->venc_lock);
mutex_unlock(&venc.venc_lock);
*vm = venc->vm;
mutex_unlock(&venc->venc_lock);
}
static u32 venc_get_wss(struct omap_dss_device *dssdev)
{
struct venc_device *venc = dssdev_to_venc(dssdev);
/* Invert due to VENC_L21_WC_CTL:INV=1 */
return (venc.wss_data >> 8) ^ 0xfffff;
return (venc->wss_data >> 8) ^ 0xfffff;
}
static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
{
struct venc_device *venc = dssdev_to_venc(dssdev);
const struct venc_config *config;
int r;
DSSDBG("venc_set_wss\n");
mutex_lock(&venc.venc_lock);
mutex_lock(&venc->venc_lock);
config = venc_timings_to_config(&venc.vm);
config = venc_timings_to_config(&venc->vm);
/* Invert due to VENC_L21_WC_CTL:INV=1 */
venc.wss_data = (wss ^ 0xfffff) << 8;
venc->wss_data = (wss ^ 0xfffff) << 8;
r = venc_runtime_get();
r = venc_runtime_get(venc);
if (r)
goto err;
venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data |
venc.wss_data);
venc_write_reg(venc, VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data |
venc->wss_data);
venc_runtime_put();
venc_runtime_put(venc);
err:
mutex_unlock(&venc.venc_lock);
mutex_unlock(&venc->venc_lock);
return r;
}
static int venc_init_regulator(void)
static int venc_init_regulator(struct venc_device *venc)
{
struct regulator *vdda_dac;
if (venc.vdda_dac_reg != NULL)
if (venc->vdda_dac_reg != NULL)
return 0;
vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda");
vdda_dac = devm_regulator_get(&venc->pdev->dev, "vdda");
if (IS_ERR(vdda_dac)) {
if (PTR_ERR(vdda_dac) != -EPROBE_DEFER)
DSSERR("can't get VDDA_DAC regulator\n");
return PTR_ERR(vdda_dac);
}
venc.vdda_dac_reg = vdda_dac;
venc->vdda_dac_reg = vdda_dac;
return 0;
}
static void venc_dump_regs(struct seq_file *s)
static int venc_dump_regs(struct seq_file *s, void *p)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
struct venc_device *venc = s->private;
if (venc_runtime_get())
return;
#define DUMPREG(venc, r) \
seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(venc, r))
if (venc_runtime_get(venc))
return 0;
DUMPREG(VENC_F_CONTROL);
DUMPREG(VENC_VIDOUT_CTRL);
DUMPREG(VENC_SYNC_CTRL);
DUMPREG(VENC_LLEN);
DUMPREG(VENC_FLENS);
DUMPREG(VENC_HFLTR_CTRL);
DUMPREG(VENC_CC_CARR_WSS_CARR);
DUMPREG(VENC_C_PHASE);
DUMPREG(VENC_GAIN_U);
DUMPREG(VENC_GAIN_V);
DUMPREG(VENC_GAIN_Y);
DUMPREG(VENC_BLACK_LEVEL);
DUMPREG(VENC_BLANK_LEVEL);
DUMPREG(VENC_X_COLOR);
DUMPREG(VENC_M_CONTROL);
DUMPREG(VENC_BSTAMP_WSS_DATA);
DUMPREG(VENC_S_CARR);
DUMPREG(VENC_LINE21);
DUMPREG(VENC_LN_SEL);
DUMPREG(VENC_L21__WC_CTL);
DUMPREG(VENC_HTRIGGER_VTRIGGER);
DUMPREG(VENC_SAVID__EAVID);
DUMPREG(VENC_FLEN__FAL);
DUMPREG(VENC_LAL__PHASE_RESET);
DUMPREG(VENC_HS_INT_START_STOP_X);
DUMPREG(VENC_HS_EXT_START_STOP_X);
DUMPREG(VENC_VS_INT_START_X);
DUMPREG(VENC_VS_INT_STOP_X__VS_INT_START_Y);
DUMPREG(VENC_VS_INT_STOP_Y__VS_EXT_START_X);
DUMPREG(VENC_VS_EXT_STOP_X__VS_EXT_START_Y);
DUMPREG(VENC_VS_EXT_STOP_Y);
DUMPREG(VENC_AVID_START_STOP_X);
DUMPREG(VENC_AVID_START_STOP_Y);
DUMPREG(VENC_FID_INT_START_X__FID_INT_START_Y);
DUMPREG(VENC_FID_INT_OFFSET_Y__FID_EXT_START_X);
DUMPREG(VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y);
DUMPREG(VENC_TVDETGP_INT_START_STOP_X);
DUMPREG(VENC_TVDETGP_INT_START_STOP_Y);
DUMPREG(VENC_GEN_CTRL);
DUMPREG(VENC_OUTPUT_CONTROL);
DUMPREG(VENC_OUTPUT_TEST);
venc_runtime_put();
DUMPREG(venc, VENC_F_CONTROL);
DUMPREG(venc, VENC_VIDOUT_CTRL);
DUMPREG(venc, VENC_SYNC_CTRL);
DUMPREG(venc, VENC_LLEN);
DUMPREG(venc, VENC_FLENS);
DUMPREG(venc, VENC_HFLTR_CTRL);
DUMPREG(venc, VENC_CC_CARR_WSS_CARR);
DUMPREG(venc, VENC_C_PHASE);
DUMPREG(venc, VENC_GAIN_U);
DUMPREG(venc, VENC_GAIN_V);
DUMPREG(venc, VENC_GAIN_Y);
DUMPREG(venc, VENC_BLACK_LEVEL);
DUMPREG(venc, VENC_BLANK_LEVEL);
DUMPREG(venc, VENC_X_COLOR);
DUMPREG(venc, VENC_M_CONTROL);
DUMPREG(venc, VENC_BSTAMP_WSS_DATA);
DUMPREG(venc, VENC_S_CARR);
DUMPREG(venc, VENC_LINE21);
DUMPREG(venc, VENC_LN_SEL);
DUMPREG(venc, VENC_L21__WC_CTL);
DUMPREG(venc, VENC_HTRIGGER_VTRIGGER);
DUMPREG(venc, VENC_SAVID__EAVID);
DUMPREG(venc, VENC_FLEN__FAL);
DUMPREG(venc, VENC_LAL__PHASE_RESET);
DUMPREG(venc, VENC_HS_INT_START_STOP_X);
DUMPREG(venc, VENC_HS_EXT_START_STOP_X);
DUMPREG(venc, VENC_VS_INT_START_X);
DUMPREG(venc, VENC_VS_INT_STOP_X__VS_INT_START_Y);
DUMPREG(venc, VENC_VS_INT_STOP_Y__VS_EXT_START_X);
DUMPREG(venc, VENC_VS_EXT_STOP_X__VS_EXT_START_Y);
DUMPREG(venc, VENC_VS_EXT_STOP_Y);
DUMPREG(venc, VENC_AVID_START_STOP_X);
DUMPREG(venc, VENC_AVID_START_STOP_Y);
DUMPREG(venc, VENC_FID_INT_START_X__FID_INT_START_Y);
DUMPREG(venc, VENC_FID_INT_OFFSET_Y__FID_EXT_START_X);
DUMPREG(venc, VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y);
DUMPREG(venc, VENC_TVDETGP_INT_START_STOP_X);
DUMPREG(venc, VENC_TVDETGP_INT_START_STOP_Y);
DUMPREG(venc, VENC_GEN_CTRL);
DUMPREG(venc, VENC_OUTPUT_CONTROL);
DUMPREG(venc, VENC_OUTPUT_TEST);
venc_runtime_put(venc);
#undef DUMPREG
return 0;
}
static int venc_get_clocks(struct platform_device *pdev)
static int venc_get_clocks(struct venc_device *venc)
{
struct clk *clk;
if (venc.requires_tv_dac_clk) {
clk = devm_clk_get(&pdev->dev, "tv_dac_clk");
if (venc->requires_tv_dac_clk) {
clk = devm_clk_get(&venc->pdev->dev, "tv_dac_clk");
if (IS_ERR(clk)) {
DSSERR("can't get tv_dac_clk\n");
return PTR_ERR(clk);
......@@ -737,7 +755,7 @@ static int venc_get_clocks(struct platform_device *pdev)
clk = NULL;
}
venc.tv_dac_clk = clk;
venc->tv_dac_clk = clk;
return 0;
}
......@@ -745,14 +763,14 @@ static int venc_get_clocks(struct platform_device *pdev)
static int venc_connect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
enum omap_channel channel = dssdev->dispc_channel;
struct venc_device *venc = dssdev_to_venc(dssdev);
int r;
r = venc_init_regulator();
r = venc_init_regulator(venc);
if (r)
return r;
r = dss_mgr_connect(channel, dssdev);
r = dss_mgr_connect(&venc->output, dssdev);
if (r)
return r;
......@@ -760,7 +778,7 @@ static int venc_connect(struct omap_dss_device *dssdev,
if (r) {
DSSERR("failed to connect output to new device: %s\n",
dst->name);
dss_mgr_disconnect(channel, dssdev);
dss_mgr_disconnect(&venc->output, dssdev);
return r;
}
......@@ -770,7 +788,7 @@ static int venc_connect(struct omap_dss_device *dssdev,
static void venc_disconnect(struct omap_dss_device *dssdev,
struct omap_dss_device *dst)
{
enum omap_channel channel = dssdev->dispc_channel;
struct venc_device *venc = dssdev_to_venc(dssdev);
WARN_ON(dst != dssdev->dst);
......@@ -779,7 +797,7 @@ static void venc_disconnect(struct omap_dss_device *dssdev,
omapdss_output_unset_device(dssdev);
dss_mgr_disconnect(channel, dssdev);
dss_mgr_disconnect(&venc->output, dssdev);
}
static const struct omapdss_atv_ops venc_ops = {
......@@ -797,11 +815,11 @@ static const struct omapdss_atv_ops venc_ops = {
.get_wss = venc_get_wss,
};
static void venc_init_output(struct platform_device *pdev)
static void venc_init_output(struct venc_device *venc)
{
struct omap_dss_device *out = &venc.output;
struct omap_dss_device *out = &venc->output;
out->dev = &pdev->dev;
out->dev = &venc->pdev->dev;
out->id = OMAP_DSS_OUTPUT_VENC;
out->output_type = OMAP_DISPLAY_TYPE_VENC;
out->name = "venc.0";
......@@ -812,16 +830,14 @@ static void venc_init_output(struct platform_device *pdev)
omapdss_register_output(out);
}
static void venc_uninit_output(struct platform_device *pdev)
static void venc_uninit_output(struct venc_device *venc)
{
struct omap_dss_device *out = &venc.output;
omapdss_unregister_output(out);
omapdss_unregister_output(&venc->output);
}
static int venc_probe_of(struct platform_device *pdev)
static int venc_probe_of(struct venc_device *venc)
{
struct device_node *node = pdev->dev.of_node;
struct device_node *node = venc->pdev->dev.of_node;
struct device_node *ep;
u32 channels;
int r;
......@@ -830,24 +846,25 @@ static int venc_probe_of(struct platform_device *pdev)
if (!ep)
return 0;
venc.invert_polarity = of_property_read_bool(ep, "ti,invert-polarity");
venc->invert_polarity = of_property_read_bool(ep, "ti,invert-polarity");
r = of_property_read_u32(ep, "ti,channels", &channels);
if (r) {
dev_err(&pdev->dev,
dev_err(&venc->pdev->dev,
"failed to read property 'ti,channels': %d\n", r);
goto err;
}
switch (channels) {
case 1:
venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE;
venc->type = OMAP_DSS_VENC_TYPE_COMPOSITE;
break;
case 2:
venc.type = OMAP_DSS_VENC_TYPE_SVIDEO;
venc->type = OMAP_DSS_VENC_TYPE_SVIDEO;
break;
default:
dev_err(&pdev->dev, "bad channel propert '%d'\n", channels);
dev_err(&venc->pdev->dev, "bad channel propert '%d'\n",
channels);
r = -EINVAL;
goto err;
}
......@@ -871,65 +888,82 @@ static const struct soc_device_attribute venc_soc_devices[] = {
static int venc_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
struct dss_device *dss = dss_get_device(master);
struct venc_device *venc;
u8 rev_id;
struct resource *venc_mem;
int r;
venc.pdev = pdev;
venc = kzalloc(sizeof(*venc), GFP_KERNEL);
if (!venc)
return -ENOMEM;
venc->pdev = pdev;
venc->dss = dss;
dev_set_drvdata(dev, venc);
/* The OMAP34xx, OMAP35xx and AM35xx VENC require the TV DAC clock. */
if (soc_device_match(venc_soc_devices))
venc.requires_tv_dac_clk = true;
venc->requires_tv_dac_clk = true;
mutex_init(&venc.venc_lock);
mutex_init(&venc->venc_lock);
venc.wss_data = 0;
venc->wss_data = 0;
venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
venc.base = devm_ioremap_resource(&pdev->dev, venc_mem);
if (IS_ERR(venc.base))
return PTR_ERR(venc.base);
venc_mem = platform_get_resource(venc->pdev, IORESOURCE_MEM, 0);
venc->base = devm_ioremap_resource(&pdev->dev, venc_mem);
if (IS_ERR(venc->base)) {
r = PTR_ERR(venc->base);
goto err_free;
}
r = venc_get_clocks(pdev);
r = venc_get_clocks(venc);
if (r)
return r;
goto err_free;
pm_runtime_enable(&pdev->dev);
r = venc_runtime_get();
r = venc_runtime_get(venc);
if (r)
goto err_runtime_get;
rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
rev_id = (u8)(venc_read_reg(venc, VENC_REV_ID) & 0xff);
dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id);
venc_runtime_put();
venc_runtime_put(venc);
r = venc_probe_of(pdev);
r = venc_probe_of(venc);
if (r) {
DSSERR("Invalid DT data\n");
goto err_probe_of;
}
dss_debugfs_create_file("venc", venc_dump_regs);
venc->debugfs = dss_debugfs_create_file(dss, "venc", venc_dump_regs,
venc);
venc_init_output(pdev);
venc_init_output(venc);
return 0;
err_probe_of:
err_runtime_get:
pm_runtime_disable(&pdev->dev);
err_free:
kfree(venc);
return r;
}
static void venc_unbind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
struct venc_device *venc = dev_get_drvdata(dev);
venc_uninit_output(pdev);
dss_debugfs_remove_file(venc->debugfs);
pm_runtime_disable(&pdev->dev);
venc_uninit_output(venc);
pm_runtime_disable(dev);
kfree(venc);
}
static const struct component_ops venc_component_ops = {
......@@ -950,24 +984,27 @@ static int venc_remove(struct platform_device *pdev)
static int venc_runtime_suspend(struct device *dev)
{
if (venc.tv_dac_clk)
clk_disable_unprepare(venc.tv_dac_clk);
struct venc_device *venc = dev_get_drvdata(dev);
if (venc->tv_dac_clk)
clk_disable_unprepare(venc->tv_dac_clk);
dispc_runtime_put();
dispc_runtime_put(venc->dss->dispc);
return 0;
}
static int venc_runtime_resume(struct device *dev)
{
struct venc_device *venc = dev_get_drvdata(dev);
int r;
r = dispc_runtime_get();
r = dispc_runtime_get(venc->dss->dispc);
if (r < 0)
return r;
if (venc.tv_dac_clk)
clk_prepare_enable(venc.tv_dac_clk);
if (venc->tv_dac_clk)
clk_prepare_enable(venc->tv_dac_clk);
return 0;
}
......
......@@ -64,11 +64,11 @@ static int dss_video_pll_enable(struct dss_pll *pll)
struct dss_video_pll *vpll = container_of(pll, struct dss_video_pll, pll);
int r;
r = dss_runtime_get();
r = dss_runtime_get(pll->dss);
if (r)
return r;
dss_ctrl_pll_enable(pll->id, true);
dss_ctrl_pll_enable(pll, true);
dss_dpll_enable_scp_clk(vpll);
......@@ -82,8 +82,8 @@ static int dss_video_pll_enable(struct dss_pll *pll)
err_reset:
dss_dpll_disable_scp_clk(vpll);
dss_ctrl_pll_enable(pll->id, false);
dss_runtime_put();
dss_ctrl_pll_enable(pll, false);
dss_runtime_put(pll->dss);
return r;
}
......@@ -96,9 +96,9 @@ static void dss_video_pll_disable(struct dss_pll *pll)
dss_dpll_disable_scp_clk(vpll);
dss_ctrl_pll_enable(pll->id, false);
dss_ctrl_pll_enable(pll, false);
dss_runtime_put();
dss_runtime_put(pll->dss);
}
static const struct dss_pll_ops dss_pll_ops = {
......@@ -136,8 +136,9 @@ static const struct dss_pll_hw dss_dra7_video_pll_hw = {
.errata_i886 = true,
};
struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id,
struct regulator *regulator)
struct dss_pll *dss_video_pll_init(struct dss_device *dss,
struct platform_device *pdev, int id,
struct regulator *regulator)
{
const char * const reg_name[] = { "pll1", "pll2" };
const char * const clkctrl_name[] = { "pll1_clkctrl", "pll2_clkctrl" };
......@@ -190,7 +191,7 @@ struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id,
pll->hw = &dss_dra7_video_pll_hw;
pll->ops = &dss_pll_ops;
r = dss_pll_register(pll);
r = dss_pll_register(dss, pll);
if (r)
return ERR_PTR(r);
......
......@@ -113,15 +113,17 @@ static struct omap_crtc *omap_crtcs[8];
static struct omap_dss_device *omap_crtc_output[8];
/* we can probably ignore these until we support command-mode panels: */
static int omap_crtc_dss_connect(enum omap_channel channel,
static int omap_crtc_dss_connect(struct omap_drm_private *priv,
enum omap_channel channel,
struct omap_dss_device *dst)
{
const struct dispc_ops *dispc_ops = dispc_get_ops();
const struct dispc_ops *dispc_ops = priv->dispc_ops;
struct dispc_device *dispc = priv->dispc;
if (omap_crtc_output[channel])
return -EINVAL;
if ((dispc_ops->mgr_get_supported_outputs(channel) & dst->id) == 0)
if (!(dispc_ops->mgr_get_supported_outputs(dispc, channel) & dst->id))
return -EINVAL;
omap_crtc_output[channel] = dst;
......@@ -130,14 +132,16 @@ static int omap_crtc_dss_connect(enum omap_channel channel,
return 0;
}
static void omap_crtc_dss_disconnect(enum omap_channel channel,
static void omap_crtc_dss_disconnect(struct omap_drm_private *priv,
enum omap_channel channel,
struct omap_dss_device *dst)
{
omap_crtc_output[channel] = NULL;
dst->dispc_channel_connected = false;
}
static void omap_crtc_dss_start_update(enum omap_channel channel)
static void omap_crtc_dss_start_update(struct omap_drm_private *priv,
enum omap_channel channel)
{
}
......@@ -156,7 +160,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
return;
if (omap_crtc_output[channel]->output_type == OMAP_DISPLAY_TYPE_HDMI) {
priv->dispc_ops->mgr_enable(channel, enable);
priv->dispc_ops->mgr_enable(priv->dispc, channel, enable);
omap_crtc->enabled = enable;
return;
}
......@@ -169,8 +173,9 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
omap_crtc->ignore_digit_sync_lost = true;
}
framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(channel);
vsync_irq = priv->dispc_ops->mgr_get_vsync_irq(channel);
framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(priv->dispc,
channel);
vsync_irq = priv->dispc_ops->mgr_get_vsync_irq(priv->dispc, channel);
if (enable) {
wait = omap_irq_wait_init(dev, vsync_irq, 1);
......@@ -190,7 +195,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
wait = omap_irq_wait_init(dev, vsync_irq, 2);
}
priv->dispc_ops->mgr_enable(channel, enable);
priv->dispc_ops->mgr_enable(priv->dispc, channel, enable);
omap_crtc->enabled = enable;
ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
......@@ -207,25 +212,28 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
}
static int omap_crtc_dss_enable(enum omap_channel channel)
static int omap_crtc_dss_enable(struct omap_drm_private *priv,
enum omap_channel channel)
{
struct omap_crtc *omap_crtc = omap_crtcs[channel];
struct omap_drm_private *priv = omap_crtc->base.dev->dev_private;
priv->dispc_ops->mgr_set_timings(omap_crtc->channel, &omap_crtc->vm);
priv->dispc_ops->mgr_set_timings(priv->dispc, omap_crtc->channel,
&omap_crtc->vm);
omap_crtc_set_enabled(&omap_crtc->base, true);
return 0;
}
static void omap_crtc_dss_disable(enum omap_channel channel)
static void omap_crtc_dss_disable(struct omap_drm_private *priv,
enum omap_channel channel)
{
struct omap_crtc *omap_crtc = omap_crtcs[channel];
omap_crtc_set_enabled(&omap_crtc->base, false);
}
static void omap_crtc_dss_set_timings(enum omap_channel channel,
static void omap_crtc_dss_set_timings(struct omap_drm_private *priv,
enum omap_channel channel,
const struct videomode *vm)
{
struct omap_crtc *omap_crtc = omap_crtcs[channel];
......@@ -233,25 +241,26 @@ static void omap_crtc_dss_set_timings(enum omap_channel channel,
omap_crtc->vm = *vm;
}
static void omap_crtc_dss_set_lcd_config(enum omap_channel channel,
static void omap_crtc_dss_set_lcd_config(struct omap_drm_private *priv,
enum omap_channel channel,
const struct dss_lcd_mgr_config *config)
{
struct omap_crtc *omap_crtc = omap_crtcs[channel];
struct omap_drm_private *priv = omap_crtc->base.dev->dev_private;
DBG("%s", omap_crtc->name);
priv->dispc_ops->mgr_set_lcd_config(omap_crtc->channel, config);
priv->dispc_ops->mgr_set_lcd_config(priv->dispc, omap_crtc->channel,
config);
}
static int omap_crtc_dss_register_framedone(
enum omap_channel channel,
struct omap_drm_private *priv, enum omap_channel channel,
void (*handler)(void *), void *data)
{
return 0;
}
static void omap_crtc_dss_unregister_framedone(
enum omap_channel channel,
struct omap_drm_private *priv, enum omap_channel channel,
void (*handler)(void *), void *data)
{
}
......@@ -272,7 +281,7 @@ static const struct dss_mgr_ops mgr_ops = {
* Setup, Flush and Page Flip
*/
void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus)
void omap_crtc_error_irq(struct drm_crtc *crtc, u32 irqstatus)
{
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
......@@ -297,7 +306,7 @@ void omap_crtc_vblank_irq(struct drm_crtc *crtc)
* If the dispc is busy we're racing the flush operation. Try again on
* the next vblank interrupt.
*/
if (priv->dispc_ops->mgr_go_busy(omap_crtc->channel)) {
if (priv->dispc_ops->mgr_go_busy(priv->dispc, omap_crtc->channel)) {
spin_unlock(&crtc->dev->event_lock);
return;
}
......@@ -334,7 +343,7 @@ static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc)
info.partial_alpha_enabled = false;
info.cpr_enable = false;
priv->dispc_ops->mgr_setup(omap_crtc->channel, &info);
priv->dispc_ops->mgr_setup(priv->dispc, omap_crtc->channel, &info);
}
/* -----------------------------------------------------------------------------
......@@ -492,7 +501,7 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc,
struct drm_plane_state *pri_state;
if (state->color_mgmt_changed && state->gamma_lut) {
uint length = state->gamma_lut->length /
unsigned int length = state->gamma_lut->length /
sizeof(struct drm_color_lut);
if (length < 2)
......@@ -526,7 +535,7 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
if (crtc->state->color_mgmt_changed) {
struct drm_color_lut *lut = NULL;
uint length = 0;
unsigned int length = 0;
if (crtc->state->gamma_lut) {
lut = (struct drm_color_lut *)
......@@ -534,7 +543,8 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
length = crtc->state->gamma_lut->length /
sizeof(*lut);
}
priv->dispc_ops->mgr_set_gamma(omap_crtc->channel, lut, length);
priv->dispc_ops->mgr_set_gamma(priv->dispc, omap_crtc->channel,
lut, length);
}
omap_crtc_write_crtc_properties(crtc);
......@@ -549,7 +559,7 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
WARN_ON(ret != 0);
spin_lock_irq(&crtc->dev->event_lock);
priv->dispc_ops->mgr_go(omap_crtc->channel);
priv->dispc_ops->mgr_go(priv->dispc, omap_crtc->channel);
omap_crtc_arm_event(crtc);
spin_unlock_irq(&crtc->dev->event_lock);
}
......@@ -557,7 +567,7 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
static int omap_crtc_atomic_set_property(struct drm_crtc *crtc,
struct drm_crtc_state *state,
struct drm_property *property,
uint64_t val)
u64 val)
{
struct omap_drm_private *priv = crtc->dev->dev_private;
struct drm_plane_state *plane_state;
......@@ -585,7 +595,7 @@ static int omap_crtc_atomic_set_property(struct drm_crtc *crtc,
static int omap_crtc_atomic_get_property(struct drm_crtc *crtc,
const struct drm_crtc_state *state,
struct drm_property *property,
uint64_t *val)
u64 *val)
{
struct omap_drm_private *priv = crtc->dev->dev_private;
struct omap_crtc_state *omap_state = to_omap_crtc_state(state);
......@@ -669,11 +679,11 @@ static const char *channel_names[] = {
[OMAP_DSS_CHANNEL_LCD3] = "lcd3",
};
void omap_crtc_pre_init(void)
void omap_crtc_pre_init(struct omap_drm_private *priv)
{
memset(omap_crtcs, 0, sizeof(omap_crtcs));
dss_install_mgr_ops(&mgr_ops);
dss_install_mgr_ops(&mgr_ops, priv);
}
void omap_crtc_pre_uninit(void)
......@@ -731,8 +741,8 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
* extracted with dispc_mgr_gamma_size(). If it returns 0
* gamma table is not supprted.
*/
if (priv->dispc_ops->mgr_gamma_size(channel)) {
uint gamma_lut_size = 256;
if (priv->dispc_ops->mgr_gamma_size(priv->dispc, channel)) {
unsigned int gamma_lut_size = 256;
drm_crtc_enable_color_mgmt(crtc, 0, false, gamma_lut_size);
drm_mode_crtc_set_gamma_size(crtc, gamma_lut_size);
......
......@@ -32,12 +32,12 @@ struct videomode;
struct videomode *omap_crtc_timings(struct drm_crtc *crtc);
enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
void omap_crtc_pre_init(void);
void omap_crtc_pre_init(struct omap_drm_private *priv);
void omap_crtc_pre_uninit(void);
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
struct drm_plane *plane, struct omap_dss_device *dssdev);
int omap_crtc_wait_pending(struct drm_crtc *crtc);
void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus);
void omap_crtc_error_irq(struct drm_crtc *crtc, u32 irqstatus);
void omap_crtc_vblank_irq(struct drm_crtc *crtc);
#endif /* __OMAPDRM_CRTC_H__ */
......@@ -102,10 +102,10 @@ struct pat_ctrl {
};
struct pat {
uint32_t next_pa;
u32 next_pa;
struct pat_area area;
struct pat_ctrl ctrl;
uint32_t data_pa;
u32 data_pa;
};
#define DMM_FIXED_RETRY_COUNT 1000
......@@ -129,7 +129,7 @@ struct dmm_txn {
void *engine_handle;
struct tcm *tcm;
uint8_t *current_va;
u8 *current_va;
dma_addr_t current_pa;
struct pat *last_pat;
......@@ -140,7 +140,7 @@ struct refill_engine {
struct dmm *dmm;
struct tcm *tcm;
uint8_t *refill_va;
u8 *refill_va;
dma_addr_t refill_pa;
/* only one trans per engine for now */
......@@ -154,7 +154,7 @@ struct refill_engine {
};
struct dmm_platform_data {
uint32_t cpu_cache_flags;
u32 cpu_cache_flags;
};
struct dmm {
......
......@@ -58,11 +58,11 @@ static DEFINE_SPINLOCK(list_lock);
}
static const struct {
uint32_t x_shft; /* unused X-bits (as part of bpp) */
uint32_t y_shft; /* unused Y-bits (as part of bpp) */
uint32_t cpp; /* bytes/chars per pixel */
uint32_t slot_w; /* width of each slot (in pixels) */
uint32_t slot_h; /* height of each slot (in pixels) */
u32 x_shft; /* unused X-bits (as part of bpp) */
u32 y_shft; /* unused Y-bits (as part of bpp) */
u32 cpp; /* bytes/chars per pixel */
u32 slot_w; /* width of each slot (in pixels) */
u32 slot_h; /* height of each slot (in pixels) */
} geom[TILFMT_NFORMATS] = {
[TILFMT_8BIT] = GEOM(0, 0, 1),
[TILFMT_16BIT] = GEOM(0, 1, 2),
......@@ -72,7 +72,7 @@ static const struct {
/* lookup table for registers w/ per-engine instances */
static const uint32_t reg[][4] = {
static const u32 reg[][4] = {
[PAT_STATUS] = {DMM_PAT_STATUS__0, DMM_PAT_STATUS__1,
DMM_PAT_STATUS__2, DMM_PAT_STATUS__3},
[PAT_DESCR] = {DMM_PAT_DESCR__0, DMM_PAT_DESCR__1,
......@@ -111,10 +111,10 @@ static void *alloc_dma(struct dmm_txn *txn, size_t sz, dma_addr_t *pa)
}
/* check status and spin until wait_mask comes true */
static int wait_status(struct refill_engine *engine, uint32_t wait_mask)
static int wait_status(struct refill_engine *engine, u32 wait_mask)
{
struct dmm *dmm = engine->dmm;
uint32_t r = 0, err, i;
u32 r = 0, err, i;
i = DMM_FIXED_RETRY_COUNT;
while (true) {
......@@ -158,7 +158,7 @@ static void release_engine(struct refill_engine *engine)
static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
{
struct dmm *dmm = arg;
uint32_t status = dmm_read(dmm, DMM_PAT_IRQSTATUS);
u32 status = dmm_read(dmm, DMM_PAT_IRQSTATUS);
int i;
/* ack IRQ */
......@@ -226,10 +226,10 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm)
* corresponding slot is cleared (ie. dummy_pa is programmed)
*/
static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
struct page **pages, uint32_t npages, uint32_t roll)
struct page **pages, u32 npages, u32 roll)
{
dma_addr_t pat_pa = 0, data_pa = 0;
uint32_t *data;
u32 *data;
struct pat *pat;
struct refill_engine *engine = txn->engine_handle;
int columns = (1 + area->x1 - area->x0);
......@@ -239,7 +239,7 @@ static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
pat = alloc_dma(txn, sizeof(*pat), &pat_pa);
if (txn->last_pat)
txn->last_pat->next_pa = (uint32_t)pat_pa;
txn->last_pat->next_pa = (u32)pat_pa;
pat->area = *area;
......@@ -330,7 +330,7 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
* DMM programming
*/
static int fill(struct tcm_area *area, struct page **pages,
uint32_t npages, uint32_t roll, bool wait)
u32 npages, u32 roll, bool wait)
{
int ret = 0;
struct tcm_area slice, area_s;
......@@ -378,7 +378,7 @@ static int fill(struct tcm_area *area, struct page **pages,
/* note: slots for which pages[i] == NULL are filled w/ dummy page
*/
int tiler_pin(struct tiler_block *block, struct page **pages,
uint32_t npages, uint32_t roll, bool wait)
u32 npages, u32 roll, bool wait)
{
int ret;
......@@ -398,8 +398,8 @@ int tiler_unpin(struct tiler_block *block)
/*
* Reserve/release
*/
struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, uint16_t w,
uint16_t h, uint16_t align)
struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, u16 w,
u16 h, u16 align)
{
struct tiler_block *block = kzalloc(sizeof(*block), GFP_KERNEL);
u32 min_align = 128;
......@@ -542,8 +542,8 @@ dma_addr_t tiler_ssptr(struct tiler_block *block)
block->area.p0.y * geom[block->fmt].slot_h);
}
dma_addr_t tiler_tsptr(struct tiler_block *block, uint32_t orient,
uint32_t x, uint32_t y)
dma_addr_t tiler_tsptr(struct tiler_block *block, u32 orient,
u32 x, u32 y)
{
struct tcm_pt *p = &block->area.p0;
BUG_ON(!validfmt(block->fmt));
......@@ -553,14 +553,14 @@ dma_addr_t tiler_tsptr(struct tiler_block *block, uint32_t orient,
(p->y * geom[block->fmt].slot_h) + y);
}
void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h)
void tiler_align(enum tiler_fmt fmt, u16 *w, u16 *h)
{
BUG_ON(!validfmt(fmt));
*w = round_up(*w, geom[fmt].slot_w);
*h = round_up(*h, geom[fmt].slot_h);
}
uint32_t tiler_stride(enum tiler_fmt fmt, uint32_t orient)
u32 tiler_stride(enum tiler_fmt fmt, u32 orient)
{
BUG_ON(!validfmt(fmt));
......@@ -570,19 +570,19 @@ uint32_t tiler_stride(enum tiler_fmt fmt, uint32_t orient)
return 1 << (CONT_WIDTH_BITS + geom[fmt].y_shft);
}
size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h)
size_t tiler_size(enum tiler_fmt fmt, u16 w, u16 h)
{
tiler_align(fmt, &w, &h);
return geom[fmt].cpp * w * h;
}
size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h)
size_t tiler_vsize(enum tiler_fmt fmt, u16 w, u16 h)
{
BUG_ON(!validfmt(fmt));
return round_up(geom[fmt].cpp * w, PAGE_SIZE) * h;
}
uint32_t tiler_get_cpu_cache_flags(void)
u32 tiler_get_cpu_cache_flags(void)
{
return omap_dmm->plat_data->cpu_cache_flags;
}
......
......@@ -88,30 +88,30 @@ int tiler_map_show(struct seq_file *s, void *arg);
/* pin/unpin */
int tiler_pin(struct tiler_block *block, struct page **pages,
uint32_t npages, uint32_t roll, bool wait);
u32 npages, u32 roll, bool wait);
int tiler_unpin(struct tiler_block *block);
/* reserve/release */
struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, uint16_t w, uint16_t h,
uint16_t align);
struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, u16 w, u16 h,
u16 align);
struct tiler_block *tiler_reserve_1d(size_t size);
int tiler_release(struct tiler_block *block);
/* utilities */
dma_addr_t tiler_ssptr(struct tiler_block *block);
dma_addr_t tiler_tsptr(struct tiler_block *block, uint32_t orient,
uint32_t x, uint32_t y);
uint32_t tiler_stride(enum tiler_fmt fmt, uint32_t orient);
size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h);
size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h);
void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h);
uint32_t tiler_get_cpu_cache_flags(void);
dma_addr_t tiler_tsptr(struct tiler_block *block, u32 orient,
u32 x, u32 y);
u32 tiler_stride(enum tiler_fmt fmt, u32 orient);
size_t tiler_size(enum tiler_fmt fmt, u16 w, u16 h);
size_t tiler_vsize(enum tiler_fmt fmt, u16 w, u16 h);
void tiler_align(enum tiler_fmt fmt, u16 *w, u16 *h);
u32 tiler_get_cpu_cache_flags(void);
bool dmm_is_available(void);
extern struct platform_driver omap_dmm_driver;
/* GEM bo flags -> tiler fmt */
static inline enum tiler_fmt gem2fmt(uint32_t flags)
static inline enum tiler_fmt gem2fmt(u32 flags)
{
switch (flags & OMAP_BO_TILED) {
case OMAP_BO_TILED_8:
......
......@@ -69,7 +69,7 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state)
struct drm_device *dev = old_state->dev;
struct omap_drm_private *priv = dev->dev_private;
priv->dispc_ops->runtime_get();
priv->dispc_ops->runtime_get(priv->dispc);
/* Apply the atomic update. */
drm_atomic_helper_commit_modeset_disables(dev, old_state);
......@@ -113,7 +113,7 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state)
drm_atomic_helper_cleanup_planes(dev, old_state);
priv->dispc_ops->runtime_put();
priv->dispc_ops->runtime_put(priv->dispc);
}
static const struct drm_mode_config_helper_funcs omap_mode_config_helper_funcs = {
......@@ -191,7 +191,7 @@ static int omap_connect_dssdevs(void)
static int omap_modeset_init_properties(struct drm_device *dev)
{
struct omap_drm_private *priv = dev->dev_private;
unsigned int num_planes = priv->dispc_ops->get_num_ovls();
unsigned int num_planes = priv->dispc_ops->get_num_ovls(priv->dispc);
priv->zorder_prop = drm_property_create_range(dev, 0, "zorder", 0,
num_planes - 1);
......@@ -205,8 +205,8 @@ static int omap_modeset_init(struct drm_device *dev)
{
struct omap_drm_private *priv = dev->dev_private;
struct omap_dss_device *dssdev = NULL;
int num_ovls = priv->dispc_ops->get_num_ovls();
int num_mgrs = priv->dispc_ops->get_num_mgrs();
int num_ovls = priv->dispc_ops->get_num_ovls(priv->dispc);
int num_mgrs = priv->dispc_ops->get_num_mgrs(priv->dispc);
int num_crtcs, crtc_idx, plane_idx;
int ret;
u32 plane_crtc_mask;
......@@ -310,11 +310,14 @@ static int omap_modeset_init(struct drm_device *dev)
dev->mode_config.min_width = 8;
dev->mode_config.min_height = 2;
/* note: eventually will need some cpu_is_omapXYZ() type stuff here
* to fill in these limits properly on different OMAP generations..
/*
* Note: these values are used for multiple independent things:
* connector mode filtering, buffer sizes, crtc sizes...
* Use big enough values here to cover all use cases, and do more
* specific checking in the respective code paths.
*/
dev->mode_config.max_width = 2048;
dev->mode_config.max_height = 2048;
dev->mode_config.max_width = 8192;
dev->mode_config.max_height = 8192;
dev->mode_config.funcs = &omap_mode_config_funcs;
dev->mode_config.helper_private = &omap_mode_config_helper_funcs;
......@@ -510,40 +513,26 @@ static const struct soc_device_attribute omapdrm_soc_devices[] = {
{ /* sentinel */ }
};
static int pdev_probe(struct platform_device *pdev)
static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
{
const struct soc_device_attribute *soc;
struct omap_drm_private *priv;
struct drm_device *ddev;
unsigned int i;
int ret;
DBG("%s", pdev->name);
DBG("%s", dev_name(dev));
if (omapdss_is_initialized() == false)
return -EPROBE_DEFER;
priv->dev = dev;
priv->dss = omapdss_get_dss();
priv->dispc = dispc_get_dispc(priv->dss);
priv->dispc_ops = dispc_get_ops(priv->dss);
ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (ret) {
dev_err(&pdev->dev, "Failed to set the DMA mask\n");
return ret;
}
omap_crtc_pre_init();
omap_crtc_pre_init(priv);
ret = omap_connect_dssdevs();
if (ret)
goto err_crtc_uninit;
/* Allocate and initialize the driver private structure. */
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
ret = -ENOMEM;
goto err_disconnect_dssdevs;
}
priv->dispc_ops = dispc_get_ops();
soc = soc_device_match(omapdrm_soc_devices);
priv->omaprev = soc ? (unsigned int)soc->data : 0;
priv->wq = alloc_ordered_workqueue("omapdrm", 0);
......@@ -552,39 +541,39 @@ static int pdev_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&priv->obj_list);
/* Allocate and initialize the DRM device. */
ddev = drm_dev_alloc(&omap_drm_driver, &pdev->dev);
ddev = drm_dev_alloc(&omap_drm_driver, priv->dev);
if (IS_ERR(ddev)) {
ret = PTR_ERR(ddev);
goto err_free_priv;
goto err_destroy_wq;
}
priv->ddev = ddev;
ddev->dev_private = priv;
platform_set_drvdata(pdev, ddev);
/* Get memory bandwidth limits */
if (priv->dispc_ops->get_memory_bandwidth_limit)
priv->max_bandwidth =
priv->dispc_ops->get_memory_bandwidth_limit();
priv->dispc_ops->get_memory_bandwidth_limit(priv->dispc);
omap_gem_init(ddev);
ret = omap_modeset_init(ddev);
if (ret) {
dev_err(&pdev->dev, "omap_modeset_init failed: ret=%d\n", ret);
dev_err(priv->dev, "omap_modeset_init failed: ret=%d\n", ret);
goto err_free_drm_dev;
}
/* Initialize vblank handling, start with all CRTCs disabled. */
ret = drm_vblank_init(ddev, priv->num_crtcs);
if (ret) {
dev_err(&pdev->dev, "could not init vblank\n");
dev_err(priv->dev, "could not init vblank\n");
goto err_cleanup_modeset;
}
for (i = 0; i < priv->num_crtcs; i++)
drm_crtc_vblank_off(priv->crtcs[i]);
priv->fbdev = omap_fbdev_init(ddev);
omap_fbdev_init(ddev);
drm_kms_helper_poll_init(ddev);
omap_modeset_enable_external_hpd();
......@@ -602,28 +591,25 @@ static int pdev_probe(struct platform_device *pdev)
err_cleanup_helpers:
omap_modeset_disable_external_hpd();
drm_kms_helper_poll_fini(ddev);
if (priv->fbdev)
omap_fbdev_free(ddev);
omap_fbdev_fini(ddev);
err_cleanup_modeset:
drm_mode_config_cleanup(ddev);
omap_drm_irq_uninstall(ddev);
err_free_drm_dev:
omap_gem_deinit(ddev);
drm_dev_unref(ddev);
err_free_priv:
err_destroy_wq:
destroy_workqueue(priv->wq);
kfree(priv);
err_disconnect_dssdevs:
omap_disconnect_dssdevs();
err_crtc_uninit:
omap_crtc_pre_uninit();
return ret;
}
static int pdev_remove(struct platform_device *pdev)
static void omapdrm_cleanup(struct omap_drm_private *priv)
{
struct drm_device *ddev = platform_get_drvdata(pdev);
struct omap_drm_private *priv = ddev->dev_private;
struct drm_device *ddev = priv->ddev;
DBG("");
......@@ -632,8 +618,7 @@ static int pdev_remove(struct platform_device *pdev)
omap_modeset_disable_external_hpd();
drm_kms_helper_poll_fini(ddev);
if (priv->fbdev)
omap_fbdev_free(ddev);
omap_fbdev_fini(ddev);
drm_atomic_helper_shutdown(ddev);
......@@ -645,10 +630,45 @@ static int pdev_remove(struct platform_device *pdev)
drm_dev_unref(ddev);
destroy_workqueue(priv->wq);
kfree(priv);
omap_disconnect_dssdevs();
omap_crtc_pre_uninit();
}
static int pdev_probe(struct platform_device *pdev)
{
struct omap_drm_private *priv;
int ret;
if (omapdss_is_initialized() == false)
return -EPROBE_DEFER;
ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (ret) {
dev_err(&pdev->dev, "Failed to set the DMA mask\n");
return ret;
}
/* Allocate and initialize the driver private structure. */
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
platform_set_drvdata(pdev, priv);
ret = omapdrm_init(priv, &pdev->dev);
if (ret < 0)
kfree(priv);
return ret;
}
static int pdev_remove(struct platform_device *pdev)
{
struct omap_drm_private *priv = platform_get_drvdata(pdev);
omapdrm_cleanup(priv);
kfree(priv);
return 0;
}
......@@ -692,7 +712,8 @@ static int omap_drm_resume_all_displays(void)
static int omap_drm_suspend(struct device *dev)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
struct omap_drm_private *priv = dev_get_drvdata(dev);
struct drm_device *drm_dev = priv->ddev;
drm_kms_helper_poll_disable(drm_dev);
......@@ -705,7 +726,8 @@ static int omap_drm_suspend(struct device *dev)
static int omap_drm_resume(struct device *dev)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
struct omap_drm_private *priv = dev_get_drvdata(dev);
struct drm_device *drm_dev = priv->ddev;
drm_modeset_lock_all(drm_dev);
omap_drm_resume_all_displays();
......
......@@ -46,8 +46,12 @@
struct omap_drm_usergart;
struct omap_drm_private {
uint32_t omaprev;
struct drm_device *ddev;
struct device *dev;
u32 omaprev;
struct dss_device *dss;
struct dispc_device *dispc;
const struct dispc_ops *dispc_ops;
unsigned int num_crtcs;
......@@ -81,7 +85,7 @@ struct omap_drm_private {
/* irq handling: */
spinlock_t wait_lock; /* protects the wait_list */
struct list_head wait_list; /* list of omap_irq_wait */
uint32_t irq_mask; /* enabled irqs in addition to wait_list */
u32 irq_mask; /* enabled irqs in addition to wait_list */
/* memory bandwidth limit if it is needed on the platform */
unsigned int max_bandwidth;
......
......@@ -52,8 +52,8 @@ static const u32 formats[] = {
/* per-plane info for the fb: */
struct plane {
struct drm_gem_object *bo;
uint32_t pitch;
uint32_t offset;
u32 pitch;
u32 offset;
dma_addr_t dma_addr;
};
......@@ -100,10 +100,10 @@ static const struct drm_framebuffer_funcs omap_framebuffer_funcs = {
.destroy = omap_framebuffer_destroy,
};
static uint32_t get_linear_addr(struct plane *plane,
static u32 get_linear_addr(struct plane *plane,
const struct drm_format_info *format, int n, int x, int y)
{
uint32_t offset;
u32 offset;
offset = plane->offset
+ (x * format->cpp[n] / (n == 0 ? 1 : format->hsub))
......@@ -121,9 +121,9 @@ bool omap_framebuffer_supports_rotation(struct drm_framebuffer *fb)
}
/* Note: DRM rotates counter-clockwise, TILER & DSS rotates clockwise */
static uint32_t drm_rotation_to_tiler(unsigned int drm_rot)
static u32 drm_rotation_to_tiler(unsigned int drm_rot)
{
uint32_t orient;
u32 orient;
switch (drm_rot & DRM_MODE_ROTATE_MASK) {
default:
......@@ -158,7 +158,7 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
const struct drm_format_info *format = omap_fb->format;
struct plane *plane = &omap_fb->planes[0];
uint32_t x, y, orient = 0;
u32 x, y, orient = 0;
info->fourcc = fb->format->format;
......@@ -177,8 +177,8 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
y = state->src_y >> 16;
if (omap_gem_flags(plane->bo) & OMAP_BO_TILED) {
uint32_t w = state->src_w >> 16;
uint32_t h = state->src_h >> 16;
u32 w = state->src_w >> 16;
u32 h = state->src_h >> 16;
orient = drm_rotation_to_tiler(state->rotation);
......
......@@ -80,15 +80,21 @@ static int omap_fbdev_pan_display(struct fb_var_screeninfo *var,
static struct fb_ops omap_fb_ops = {
.owner = THIS_MODULE,
DRM_FB_HELPER_DEFAULT_OPS,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_setcmap = drm_fb_helper_setcmap,
.fb_blank = drm_fb_helper_blank,
.fb_pan_display = omap_fbdev_pan_display,
.fb_debug_enter = drm_fb_helper_debug_enter,
.fb_debug_leave = drm_fb_helper_debug_leave,
.fb_ioctl = drm_fb_helper_ioctl,
.fb_read = drm_fb_helper_sys_read,
.fb_write = drm_fb_helper_sys_write,
.fb_fillrect = drm_fb_helper_sys_fillrect,
.fb_copyarea = drm_fb_helper_sys_copyarea,
.fb_imageblit = drm_fb_helper_sys_imageblit,
.fb_pan_display = omap_fbdev_pan_display,
};
static int omap_fbdev_create(struct drm_fb_helper *helper,
......@@ -188,7 +194,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
dev->mode_config.fb_base = dma_addr;
fbi->screen_base = omap_gem_vaddr(fbdev->bo);
fbi->screen_buffer = omap_gem_vaddr(fbdev->bo);
fbi->screen_size = fbdev->bo->size;
fbi->fix.smem_start = dma_addr;
fbi->fix.smem_len = fbdev->bo->size;
......@@ -236,13 +242,16 @@ static struct drm_fb_helper *get_fb(struct fb_info *fbi)
}
/* initialize fbdev helper */
struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
void omap_fbdev_init(struct drm_device *dev)
{
struct omap_drm_private *priv = dev->dev_private;
struct omap_fbdev *fbdev = NULL;
struct drm_fb_helper *helper;
int ret = 0;
if (!priv->num_crtcs || !priv->num_connectors)
return;
fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
if (!fbdev)
goto fail;
......@@ -254,10 +263,8 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
drm_fb_helper_prepare(dev, helper, &omap_fb_helper_funcs);
ret = drm_fb_helper_init(dev, helper, priv->num_connectors);
if (ret) {
dev_err(dev->dev, "could not init fbdev: ret=%d\n", ret);
if (ret)
goto fail;
}
ret = drm_fb_helper_single_add_all_connectors(helper);
if (ret)
......@@ -269,7 +276,7 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
priv->fbdev = helper;
return helper;
return;
fini:
drm_fb_helper_fini(helper);
......@@ -277,12 +284,9 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
kfree(fbdev);
dev_warn(dev->dev, "omap_fbdev_init failed\n");
/* well, limp along without an fbdev.. maybe X11 will work? */
return NULL;
}
void omap_fbdev_free(struct drm_device *dev)
void omap_fbdev_fini(struct drm_device *dev)
{
struct omap_drm_private *priv = dev->dev_private;
struct drm_fb_helper *helper = priv->fbdev;
......@@ -290,14 +294,18 @@ void omap_fbdev_free(struct drm_device *dev)
DBG();
if (!helper)
return;
drm_fb_helper_unregister_fbi(helper);
drm_fb_helper_fini(helper);
fbdev = to_omap_fbdev(priv->fbdev);
fbdev = to_omap_fbdev(helper);
/* unpin the GEM object pinned in omap_fbdev_create() */
omap_gem_unpin(fbdev->bo);
if (fbdev->bo)
omap_gem_unpin(fbdev->bo);
/* this will free the backing object */
if (fbdev->fb)
......
......@@ -24,14 +24,13 @@ struct drm_device;
struct drm_fb_helper;
#ifdef CONFIG_DRM_FBDEV_EMULATION
struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev);
void omap_fbdev_free(struct drm_device *dev);
void omap_fbdev_init(struct drm_device *dev);
void omap_fbdev_fini(struct drm_device *dev);
#else
static inline struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
static inline void omap_fbdev_init(struct drm_device *dev)
{
return NULL;
}
static inline void omap_fbdev_free(struct drm_device *dev)
static inline void omap_fbdev_fini(struct drm_device *dev)
{
}
#endif
......
......@@ -39,13 +39,13 @@ struct omap_gem_object {
struct list_head mm_list;
uint32_t flags;
u32 flags;
/** width/height for tiled formats (rounded up to slot boundaries) */
uint16_t width, height;
u16 width, height;
/** roll applied when mapping to DMM */
uint32_t roll;
u32 roll;
/**
* dma_addr contains the buffer DMA address. It is valid for
......@@ -73,7 +73,7 @@ struct omap_gem_object {
/**
* # of users of dma_addr
*/
uint32_t dma_addr_cnt;
u32 dma_addr_cnt;
/**
* If the buffer has been imported from a dmabuf the OMAP_DB_DMABUF flag
......@@ -137,7 +137,7 @@ struct omap_drm_usergart {
*/
/** get mmap offset */
static uint64_t mmap_offset(struct drm_gem_object *obj)
static u64 mmap_offset(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
int ret;
......@@ -331,14 +331,15 @@ static void omap_gem_detach_pages(struct drm_gem_object *obj)
}
/* get buffer flags */
uint32_t omap_gem_flags(struct drm_gem_object *obj)
u32 omap_gem_flags(struct drm_gem_object *obj)
{
return to_omap_bo(obj)->flags;
}
uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj)
u64 omap_gem_mmap_offset(struct drm_gem_object *obj)
{
uint64_t offset;
u64 offset;
mutex_lock(&obj->dev->struct_mutex);
offset = mmap_offset(obj);
mutex_unlock(&obj->dev->struct_mutex);
......@@ -649,7 +650,7 @@ int omap_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
* into user memory. We don't have to do much here at the moment.
*/
int omap_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
uint32_t handle, uint64_t *offset)
u32 handle, u64 *offset)
{
struct drm_gem_object *obj;
int ret = 0;
......@@ -675,10 +676,10 @@ int omap_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
*
* Call only from non-atomic contexts.
*/
int omap_gem_roll(struct drm_gem_object *obj, uint32_t roll)
int omap_gem_roll(struct drm_gem_object *obj, u32 roll)
{
struct omap_gem_object *omap_obj = to_omap_bo(obj);
uint32_t npages = obj->size >> PAGE_SHIFT;
u32 npages = obj->size >> PAGE_SHIFT;
int ret = 0;
if (roll > npages) {
......@@ -808,7 +809,7 @@ int omap_gem_pin(struct drm_gem_object *obj, dma_addr_t *dma_addr)
if (!is_contiguous(omap_obj) && priv->has_dmm) {
if (omap_obj->dma_addr_cnt == 0) {
struct page **pages;
uint32_t npages = obj->size >> PAGE_SHIFT;
u32 npages = obj->size >> PAGE_SHIFT;
enum tiler_fmt fmt = gem2fmt(omap_obj->flags);
struct tiler_block *block;
......@@ -904,7 +905,7 @@ void omap_gem_unpin(struct drm_gem_object *obj)
* specified orientation and x,y offset from top-left corner of buffer
* (only valid for tiled 2d buffers)
*/
int omap_gem_rotated_dma_addr(struct drm_gem_object *obj, uint32_t orient,
int omap_gem_rotated_dma_addr(struct drm_gem_object *obj, u32 orient,
int x, int y, dma_addr_t *dma_addr)
{
struct omap_gem_object *omap_obj = to_omap_bo(obj);
......@@ -921,7 +922,7 @@ int omap_gem_rotated_dma_addr(struct drm_gem_object *obj, uint32_t orient,
}
/* Get tiler stride for the buffer (only valid for 2d tiled buffers) */
int omap_gem_tiled_stride(struct drm_gem_object *obj, uint32_t orient)
int omap_gem_tiled_stride(struct drm_gem_object *obj, u32 orient)
{
struct omap_gem_object *omap_obj = to_omap_bo(obj);
int ret = -EINVAL;
......@@ -1003,7 +1004,8 @@ int omap_gem_resume(struct drm_device *dev)
list_for_each_entry(omap_obj, &priv->obj_list, mm_list) {
if (omap_obj->block) {
struct drm_gem_object *obj = &omap_obj->base;
uint32_t npages = obj->size >> PAGE_SHIFT;
u32 npages = obj->size >> PAGE_SHIFT;
WARN_ON(!omap_obj->pages); /* this can't happen */
ret = tiler_pin(omap_obj->block,
omap_obj->pages, npages,
......@@ -1027,7 +1029,7 @@ int omap_gem_resume(struct drm_device *dev)
void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
{
struct omap_gem_object *omap_obj = to_omap_bo(obj);
uint64_t off;
u64 off;
off = drm_vma_node_start(&obj->vma_node);
......@@ -1115,7 +1117,7 @@ void omap_gem_free_object(struct drm_gem_object *obj)
/* GEM buffer object constructor */
struct drm_gem_object *omap_gem_new(struct drm_device *dev,
union omap_gem_size gsize, uint32_t flags)
union omap_gem_size gsize, u32 flags)
{
struct omap_drm_private *priv = dev->dev_private;
struct omap_gem_object *omap_obj;
......@@ -1280,7 +1282,7 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
/* convenience method to construct a GEM buffer object, and userspace handle */
int omap_gem_new_handle(struct drm_device *dev, struct drm_file *file,
union omap_gem_size gsize, uint32_t flags, uint32_t *handle)
union omap_gem_size gsize, u32 flags, u32 *handle)
{
struct drm_gem_object *obj;
int ret;
......@@ -1327,7 +1329,8 @@ void omap_gem_init(struct drm_device *dev)
/* reserve 4k aligned/wide regions for userspace mappings: */
for (i = 0; i < ARRAY_SIZE(fmts); i++) {
uint16_t h = 1, w = PAGE_SIZE >> i;
u16 h = 1, w = PAGE_SIZE >> i;
tiler_align(fmts[i], &w, &h);
/* note: since each region is 1 4kb page wide, and minimum
* number of rows, the height ends up being the same as the
......
......@@ -53,17 +53,17 @@ void omap_gem_describe_objects(struct list_head *list, struct seq_file *m);
/* GEM Object Creation and Deletion */
struct drm_gem_object *omap_gem_new(struct drm_device *dev,
union omap_gem_size gsize, uint32_t flags);
union omap_gem_size gsize, u32 flags);
struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
struct sg_table *sgt);
int omap_gem_new_handle(struct drm_device *dev, struct drm_file *file,
union omap_gem_size gsize, uint32_t flags, uint32_t *handle);
union omap_gem_size gsize, u32 flags, u32 *handle);
void omap_gem_free_object(struct drm_gem_object *obj);
void *omap_gem_vaddr(struct drm_gem_object *obj);
/* Dumb Buffers Interface */
int omap_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
uint32_t handle, uint64_t *offset);
u32 handle, u64 *offset);
int omap_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
struct drm_mode_create_dumb *args);
......@@ -71,7 +71,7 @@ int omap_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
int omap_gem_mmap(struct file *filp, struct vm_area_struct *vma);
int omap_gem_mmap_obj(struct drm_gem_object *obj,
struct vm_area_struct *vma);
uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj);
u64 omap_gem_mmap_offset(struct drm_gem_object *obj);
size_t omap_gem_mmap_size(struct drm_gem_object *obj);
/* PRIME Interface */
......@@ -81,7 +81,7 @@ struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
struct dma_buf *buffer);
int omap_gem_fault(struct vm_fault *vmf);
int omap_gem_roll(struct drm_gem_object *obj, uint32_t roll);
int omap_gem_roll(struct drm_gem_object *obj, u32 roll);
void omap_gem_cpu_sync_page(struct drm_gem_object *obj, int pgoff);
void omap_gem_dma_sync_buffer(struct drm_gem_object *obj,
enum dma_data_direction dir);
......@@ -91,9 +91,9 @@ int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages,
bool remap);
int omap_gem_put_pages(struct drm_gem_object *obj);
uint32_t omap_gem_flags(struct drm_gem_object *obj);
int omap_gem_rotated_dma_addr(struct drm_gem_object *obj, uint32_t orient,
u32 omap_gem_flags(struct drm_gem_object *obj);
int omap_gem_rotated_dma_addr(struct drm_gem_object *obj, u32 orient,
int x, int y, dma_addr_t *dma_addr);
int omap_gem_tiled_stride(struct drm_gem_object *obj, uint32_t orient);
int omap_gem_tiled_stride(struct drm_gem_object *obj, u32 orient);
#endif /* __OMAPDRM_GEM_H__ */
......@@ -20,7 +20,7 @@
struct omap_irq_wait {
struct list_head node;
wait_queue_head_t wq;
uint32_t irqmask;
u32 irqmask;
int count;
};
......@@ -29,7 +29,7 @@ static void omap_irq_update(struct drm_device *dev)
{
struct omap_drm_private *priv = dev->dev_private;
struct omap_irq_wait *wait;
uint32_t irqmask = priv->irq_mask;
u32 irqmask = priv->irq_mask;
assert_spin_locked(&priv->wait_lock);
......@@ -38,7 +38,7 @@ static void omap_irq_update(struct drm_device *dev)
DBG("irqmask=%08x", irqmask);
priv->dispc_ops->write_irqenable(irqmask);
priv->dispc_ops->write_irqenable(priv->dispc, irqmask);
}
static void omap_irq_wait_handler(struct omap_irq_wait *wait)
......@@ -48,7 +48,7 @@ static void omap_irq_wait_handler(struct omap_irq_wait *wait)
}
struct omap_irq_wait * omap_irq_wait_init(struct drm_device *dev,
uint32_t irqmask, int count)
u32 irqmask, int count)
{
struct omap_drm_private *priv = dev->dev_private;
struct omap_irq_wait *wait = kzalloc(sizeof(*wait), GFP_KERNEL);
......@@ -108,7 +108,8 @@ int omap_irq_enable_vblank(struct drm_crtc *crtc)
DBG("dev=%p, crtc=%u", dev, channel);
spin_lock_irqsave(&priv->wait_lock, flags);
priv->irq_mask |= priv->dispc_ops->mgr_get_vsync_irq(channel);
priv->irq_mask |= priv->dispc_ops->mgr_get_vsync_irq(priv->dispc,
channel);
omap_irq_update(dev);
spin_unlock_irqrestore(&priv->wait_lock, flags);
......@@ -134,7 +135,8 @@ void omap_irq_disable_vblank(struct drm_crtc *crtc)
DBG("dev=%p, crtc=%u", dev, channel);
spin_lock_irqsave(&priv->wait_lock, flags);
priv->irq_mask &= ~priv->dispc_ops->mgr_get_vsync_irq(channel);
priv->irq_mask &= ~priv->dispc_ops->mgr_get_vsync_irq(priv->dispc,
channel);
omap_irq_update(dev);
spin_unlock_irqrestore(&priv->wait_lock, flags);
}
......@@ -198,9 +200,9 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
unsigned int id;
u32 irqstatus;
irqstatus = priv->dispc_ops->read_irqstatus();
priv->dispc_ops->clear_irqstatus(irqstatus);
priv->dispc_ops->read_irqstatus(); /* flush posted write */
irqstatus = priv->dispc_ops->read_irqstatus(priv->dispc);
priv->dispc_ops->clear_irqstatus(priv->dispc, irqstatus);
priv->dispc_ops->read_irqstatus(priv->dispc); /* flush posted write */
VERB("irqs: %08x", irqstatus);
......@@ -208,12 +210,12 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
struct drm_crtc *crtc = priv->crtcs[id];
enum omap_channel channel = omap_crtc_channel(crtc);
if (irqstatus & priv->dispc_ops->mgr_get_vsync_irq(channel)) {
if (irqstatus & priv->dispc_ops->mgr_get_vsync_irq(priv->dispc, channel)) {
drm_handle_vblank(dev, id);
omap_crtc_vblank_irq(crtc);
}
if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(channel))
if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(priv->dispc, channel))
omap_crtc_error_irq(crtc, irqstatus);
}
......@@ -247,7 +249,7 @@ static const u32 omap_underflow_irqs[] = {
int omap_drm_irq_install(struct drm_device *dev)
{
struct omap_drm_private *priv = dev->dev_private;
unsigned int num_mgrs = priv->dispc_ops->get_num_mgrs();
unsigned int num_mgrs = priv->dispc_ops->get_num_mgrs(priv->dispc);
unsigned int max_planes;
unsigned int i;
int ret;
......@@ -265,13 +267,13 @@ int omap_drm_irq_install(struct drm_device *dev)
}
for (i = 0; i < num_mgrs; ++i)
priv->irq_mask |= priv->dispc_ops->mgr_get_sync_lost_irq(i);
priv->irq_mask |= priv->dispc_ops->mgr_get_sync_lost_irq(priv->dispc, i);
priv->dispc_ops->runtime_get();
priv->dispc_ops->clear_irqstatus(0xffffffff);
priv->dispc_ops->runtime_put();
priv->dispc_ops->runtime_get(priv->dispc);
priv->dispc_ops->clear_irqstatus(priv->dispc, 0xffffffff);
priv->dispc_ops->runtime_put(priv->dispc);
ret = priv->dispc_ops->request_irq(omap_irq_handler, dev);
ret = priv->dispc_ops->request_irq(priv->dispc, omap_irq_handler, dev);
if (ret < 0)
return ret;
......@@ -289,5 +291,5 @@ void omap_drm_irq_uninstall(struct drm_device *dev)
dev->irq_enabled = false;
priv->dispc_ops->free_irq(dev);
priv->dispc_ops->free_irq(priv->dispc, dev);
}
......@@ -32,7 +32,7 @@ void omap_drm_irq_uninstall(struct drm_device *dev);
int omap_drm_irq_install(struct drm_device *dev);
struct omap_irq_wait *omap_irq_wait_init(struct drm_device *dev,
uint32_t irqmask, int count);
u32 irqmask, int count);
int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait,
unsigned long timeout);
......
......@@ -77,17 +77,17 @@ static void omap_plane_atomic_update(struct drm_plane *plane,
&info.paddr, &info.p_uv_addr);
/* and finally, update omapdss: */
ret = priv->dispc_ops->ovl_setup(omap_plane->id, &info,
ret = priv->dispc_ops->ovl_setup(priv->dispc, omap_plane->id, &info,
omap_crtc_timings(state->crtc), false,
omap_crtc_channel(state->crtc));
if (ret) {
dev_err(plane->dev->dev, "Failed to setup plane %s\n",
omap_plane->name);
priv->dispc_ops->ovl_enable(omap_plane->id, false);
priv->dispc_ops->ovl_enable(priv->dispc, omap_plane->id, false);
return;
}
priv->dispc_ops->ovl_enable(omap_plane->id, true);
priv->dispc_ops->ovl_enable(priv->dispc, omap_plane->id, true);
}
static void omap_plane_atomic_disable(struct drm_plane *plane,
......@@ -100,7 +100,7 @@ static void omap_plane_atomic_disable(struct drm_plane *plane,
plane->state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY
? 0 : omap_plane->id;
priv->dispc_ops->ovl_enable(omap_plane->id, false);
priv->dispc_ops->ovl_enable(priv->dispc, omap_plane->id, false);
}
static int omap_plane_atomic_check(struct drm_plane *plane,
......@@ -201,7 +201,7 @@ static void omap_plane_reset(struct drm_plane *plane)
static int omap_plane_atomic_set_property(struct drm_plane *plane,
struct drm_plane_state *state,
struct drm_property *property,
uint64_t val)
u64 val)
{
struct omap_drm_private *priv = plane->dev->dev_private;
......@@ -216,7 +216,7 @@ static int omap_plane_atomic_set_property(struct drm_plane *plane,
static int omap_plane_atomic_get_property(struct drm_plane *plane,
const struct drm_plane_state *state,
struct drm_property *property,
uint64_t *val)
u64 *val)
{
struct omap_drm_private *priv = plane->dev->dev_private;
......@@ -259,7 +259,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
u32 possible_crtcs)
{
struct omap_drm_private *priv = dev->dev_private;
unsigned int num_planes = priv->dispc_ops->get_num_ovls();
unsigned int num_planes = priv->dispc_ops->get_num_ovls(priv->dispc);
struct drm_plane *plane;
struct omap_plane *omap_plane;
enum omap_plane_id id;
......@@ -278,7 +278,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
if (!omap_plane)
return ERR_PTR(-ENOMEM);
formats = priv->dispc_ops->ovl_get_color_modes(id);
formats = priv->dispc_ops->ovl_get_color_modes(priv->dispc, id);
for (nformats = 0; formats[nformats]; ++nformats)
;
omap_plane->id = id;
......
......@@ -33,8 +33,8 @@ static unsigned long mask[8];
* map ptr to bitmap
* stride slots in a row
*/
static void free_slots(unsigned long pos, uint16_t w, uint16_t h,
unsigned long *map, uint16_t stride)
static void free_slots(unsigned long pos, u16 w, u16 h,
unsigned long *map, u16 stride)
{
int i;
......@@ -48,7 +48,7 @@ static void free_slots(unsigned long pos, uint16_t w, uint16_t h,
* map ptr to bitmap
* num_bits number of bits in bitmap
*/
static int r2l_b2t_1d(uint16_t w, unsigned long *pos, unsigned long *map,
static int r2l_b2t_1d(u16 w, unsigned long *pos, unsigned long *map,
size_t num_bits)
{
unsigned long search_count = 0;
......@@ -84,7 +84,7 @@ static int r2l_b2t_1d(uint16_t w, unsigned long *pos, unsigned long *map,
* num_bits = size of bitmap
* stride = bits in one row of container
*/
static int l2r_t2b(uint16_t w, uint16_t h, uint16_t a, int16_t offset,
static int l2r_t2b(u16 w, u16 h, u16 a, s16 offset,
unsigned long *pos, unsigned long slot_bytes,
unsigned long *map, size_t num_bits, size_t slot_stride)
{
......@@ -179,7 +179,7 @@ static s32 sita_reserve_1d(struct tcm *tcm, u32 num_slots,
}
static s32 sita_reserve_2d(struct tcm *tcm, u16 h, u16 w, u16 align,
int16_t offset, uint16_t slot_bytes,
s16 offset, u16 slot_bytes,
struct tcm_area *area)
{
unsigned long pos;
......@@ -208,7 +208,7 @@ static void sita_deinit(struct tcm *tcm)
static s32 sita_free(struct tcm *tcm, struct tcm_area *area)
{
unsigned long pos;
uint16_t w, h;
u16 w, h;
pos = area->p0.x + area->p0.y * tcm->width;
if (area->is2d) {
......
......@@ -65,7 +65,7 @@ struct tcm {
/* function table */
s32 (*reserve_2d)(struct tcm *tcm, u16 height, u16 width, u16 align,
int16_t offset, uint16_t slot_bytes,
s16 offset, u16 slot_bytes,
struct tcm_area *area);
s32 (*reserve_1d)(struct tcm *tcm, u32 slots, struct tcm_area *area);
s32 (*free)(struct tcm *tcm, struct tcm_area *area);
......@@ -129,7 +129,7 @@ static inline void tcm_deinit(struct tcm *tcm)
* allocation.
*/
static inline s32 tcm_reserve_2d(struct tcm *tcm, u16 width, u16 height,
u16 align, int16_t offset, uint16_t slot_bytes,
u16 align, s16 offset, u16 slot_bytes,
struct tcm_area *area)
{
/* perform rudimentary error checking */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment