drm/armada: remove non-component support

Now that the transition of TDA998x to the component helpers is complete,
remove the non-componentised support from the Armada DRM driver.  All
outputs are expected to use the component helpers from now on.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
Russell King 2015-06-06 21:46:53 +01:00
parent 64291f7db5
commit 0fb2970b4b
9 changed files with 17 additions and 462 deletions

View File

@ -14,12 +14,3 @@ config DRM_ARMADA
This driver provides no built-in acceleration; acceleration is This driver provides no built-in acceleration; acceleration is
performed by other IP found on the SoC. This driver provides performed by other IP found on the SoC. This driver provides
kernel mode setting and buffer management to userspace. kernel mode setting and buffer management to userspace.
config DRM_ARMADA_TDA1998X
bool "Support TDA1998X HDMI output"
depends on DRM_ARMADA != n
depends on I2C && DRM_I2C_NXP_TDA998X = y
default y
help
Support the TDA1998x HDMI output device found on the Solid-Run
CuBox.

View File

@ -1,6 +1,5 @@
armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \ armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
armada_gem.o armada_output.o armada_overlay.o \ armada_gem.o armada_overlay.o
armada_slave.o
armada-y += armada_510.o armada-y += armada_510.o
armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o

View File

@ -1044,7 +1044,7 @@ static int armada_drm_crtc_create_properties(struct drm_device *dev)
return 0; return 0;
} }
int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
struct resource *res, int irq, const struct armada_variant *variant, struct resource *res, int irq, const struct armada_variant *variant,
struct device_node *port) struct device_node *port)
{ {

View File

@ -75,10 +75,6 @@ struct armada_crtc {
}; };
#define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc) #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
struct device_node;
int armada_drm_crtc_create(struct drm_device *, struct device *,
struct resource *, int, const struct armada_variant *,
struct device_node *);
void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int); void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int); void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
void armada_drm_crtc_disable_irq(struct armada_crtc *, u32); void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);

View File

@ -18,47 +18,6 @@
#include <drm/armada_drm.h> #include <drm/armada_drm.h>
#include "armada_ioctlP.h" #include "armada_ioctlP.h"
#ifdef CONFIG_DRM_ARMADA_TDA1998X
#include <drm/i2c/tda998x.h>
#include "armada_slave.h"
static struct tda998x_encoder_params params = {
/* With 0x24, there is no translation between vp_out and int_vp
FB LCD out Pins VIP Int Vp
R:23:16 R:7:0 VPC7:0 7:0 7:0[R]
G:15:8 G:15:8 VPB7:0 23:16 23:16[G]
B:7:0 B:23:16 VPA7:0 15:8 15:8[B]
*/
.swap_a = 2,
.swap_b = 3,
.swap_c = 4,
.swap_d = 5,
.swap_e = 0,
.swap_f = 1,
.audio_cfg = BIT(2),
.audio_frame[1] = 1,
.audio_format = AFMT_SPDIF,
.audio_sample_rate = 44100,
};
static const struct armada_drm_slave_config tda19988_config = {
.i2c_adapter_id = 0,
.crtcs = 1 << 0, /* Only LCD0 at the moment */
.polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT,
.interlace_allowed = true,
.info = {
.type = "tda998x",
.addr = 0x70,
.platform_data = &params,
},
};
#endif
static bool is_componentized(struct device *dev)
{
return dev->of_node || dev->platform_data;
}
static void armada_drm_unref_work(struct work_struct *work) static void armada_drm_unref_work(struct work_struct *work)
{ {
struct armada_private *priv = struct armada_private *priv =
@ -91,16 +50,11 @@ void armada_drm_queue_unref_work(struct drm_device *dev,
static int armada_drm_load(struct drm_device *dev, unsigned long flags) static int armada_drm_load(struct drm_device *dev, unsigned long flags)
{ {
const struct platform_device_id *id;
const struct armada_variant *variant;
struct armada_private *priv; struct armada_private *priv;
struct resource *res[ARRAY_SIZE(priv->dcrtc)];
struct resource *mem = NULL; struct resource *mem = NULL;
int ret, n, i; int ret, n;
memset(res, 0, sizeof(res)); for (n = 0; ; n++) {
for (n = i = 0; ; n++) {
struct resource *r = platform_get_resource(dev->platformdev, struct resource *r = platform_get_resource(dev->platformdev,
IORESOURCE_MEM, n); IORESOURCE_MEM, n);
if (!r) if (!r)
@ -109,8 +63,6 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
/* Resources above 64K are graphics memory */ /* Resources above 64K are graphics memory */
if (resource_size(r) > SZ_64K) if (resource_size(r) > SZ_64K)
mem = r; mem = r;
else if (i < ARRAY_SIZE(priv->dcrtc))
res[i++] = r;
else else
return -EINVAL; return -EINVAL;
} }
@ -131,13 +83,6 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
platform_set_drvdata(dev->platformdev, dev); platform_set_drvdata(dev->platformdev, dev);
dev->dev_private = priv; dev->dev_private = priv;
/* Get the implementation specific driver data. */
id = platform_get_device_id(dev->platformdev);
if (!id)
return -ENXIO;
variant = (const struct armada_variant *)id->driver_data;
INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work); INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
INIT_KFIFO(priv->fb_unref); INIT_KFIFO(priv->fb_unref);
@ -157,34 +102,9 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
dev->mode_config.funcs = &armada_drm_mode_config_funcs; dev->mode_config.funcs = &armada_drm_mode_config_funcs;
drm_mm_init(&priv->linear, mem->start, resource_size(mem)); drm_mm_init(&priv->linear, mem->start, resource_size(mem));
/* Create all LCD controllers */ ret = component_bind_all(dev->dev, dev);
for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) { if (ret)
int irq; goto err_kms;
if (!res[n])
break;
irq = platform_get_irq(dev->platformdev, n);
if (irq < 0)
goto err_kms;
ret = armada_drm_crtc_create(dev, dev->dev, res[n], irq,
variant, NULL);
if (ret)
goto err_kms;
}
if (is_componentized(dev->dev)) {
ret = component_bind_all(dev->dev, dev);
if (ret)
goto err_kms;
} else {
#ifdef CONFIG_DRM_ARMADA_TDA1998X
ret = armada_drm_connector_slave_create(dev, &tda19988_config);
if (ret)
goto err_kms;
#endif
}
ret = drm_vblank_init(dev, dev->mode_config.num_crtc); ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
if (ret) if (ret)
@ -202,8 +122,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
return 0; return 0;
err_comp: err_comp:
if (is_componentized(dev->dev)) component_unbind_all(dev->dev, dev);
component_unbind_all(dev->dev, dev);
err_kms: err_kms:
drm_mode_config_cleanup(dev); drm_mode_config_cleanup(dev);
drm_mm_takedown(&priv->linear); drm_mm_takedown(&priv->linear);
@ -219,8 +138,7 @@ static int armada_drm_unload(struct drm_device *dev)
drm_kms_helper_poll_fini(dev); drm_kms_helper_poll_fini(dev);
armada_fbdev_fini(dev); armada_fbdev_fini(dev);
if (is_componentized(dev->dev)) component_unbind_all(dev->dev, dev);
component_unbind_all(dev->dev, dev);
drm_mode_config_cleanup(dev); drm_mode_config_cleanup(dev);
drm_mm_takedown(&priv->linear); drm_mm_takedown(&priv->linear);
@ -435,37 +353,28 @@ static const struct component_master_ops armada_master_ops = {
static int armada_drm_probe(struct platform_device *pdev) static int armada_drm_probe(struct platform_device *pdev)
{ {
if (is_componentized(&pdev->dev)) { struct component_match *match = NULL;
struct component_match *match = NULL; int ret;
int ret;
ret = armada_drm_find_components(&pdev->dev, &match); ret = armada_drm_find_components(&pdev->dev, &match);
if (ret < 0) if (ret < 0)
return ret; return ret;
return component_master_add_with_match(&pdev->dev, return component_master_add_with_match(&pdev->dev, &armada_master_ops,
&armada_master_ops, match); match);
} else {
return drm_platform_init(&armada_drm_driver, pdev);
}
} }
static int armada_drm_remove(struct platform_device *pdev) static int armada_drm_remove(struct platform_device *pdev)
{ {
if (is_componentized(&pdev->dev)) component_master_del(&pdev->dev, &armada_master_ops);
component_master_del(&pdev->dev, &armada_master_ops);
else
drm_put_dev(platform_get_drvdata(pdev));
return 0; return 0;
} }
static const struct platform_device_id armada_drm_platform_ids[] = { static const struct platform_device_id armada_drm_platform_ids[] = {
{ {
.name = "armada-drm", .name = "armada-drm",
.driver_data = (unsigned long)&armada510_ops,
}, { }, {
.name = "armada-510-drm", .name = "armada-510-drm",
.driver_data = (unsigned long)&armada510_ops,
}, },
{ }, { },
}; };

View File

@ -1,142 +0,0 @@
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder_slave.h>
#include "armada_output.h"
#include "armada_drm.h"
struct armada_connector {
struct drm_connector conn;
const struct armada_output_type *type;
};
#define drm_to_armada_conn(c) container_of(c, struct armada_connector, conn)
struct drm_encoder *armada_drm_connector_encoder(struct drm_connector *conn)
{
struct drm_encoder *enc = conn->encoder;
return enc ? enc : drm_encoder_find(conn->dev, conn->encoder_ids[0]);
}
static enum drm_connector_status armada_drm_connector_detect(
struct drm_connector *conn, bool force)
{
struct armada_connector *dconn = drm_to_armada_conn(conn);
enum drm_connector_status status = connector_status_disconnected;
if (dconn->type->detect) {
status = dconn->type->detect(conn, force);
} else {
struct drm_encoder *enc = armada_drm_connector_encoder(conn);
if (enc)
status = encoder_helper_funcs(enc)->detect(enc, conn);
}
return status;
}
static void armada_drm_connector_destroy(struct drm_connector *conn)
{
struct armada_connector *dconn = drm_to_armada_conn(conn);
drm_connector_unregister(conn);
drm_connector_cleanup(conn);
kfree(dconn);
}
static int armada_drm_connector_set_property(struct drm_connector *conn,
struct drm_property *property, uint64_t value)
{
struct armada_connector *dconn = drm_to_armada_conn(conn);
if (!dconn->type->set_property)
return -EINVAL;
return dconn->type->set_property(conn, property, value);
}
static const struct drm_connector_funcs armada_drm_conn_funcs = {
.dpms = drm_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = armada_drm_connector_detect,
.destroy = armada_drm_connector_destroy,
.set_property = armada_drm_connector_set_property,
};
/* Shouldn't this be a generic helper function? */
int armada_drm_slave_encoder_mode_valid(struct drm_connector *conn,
struct drm_display_mode *mode)
{
struct drm_encoder *encoder = armada_drm_connector_encoder(conn);
int valid = MODE_BAD;
if (encoder) {
struct drm_encoder_slave *slave = to_encoder_slave(encoder);
valid = slave->slave_funcs->mode_valid(encoder, mode);
}
return valid;
}
int armada_drm_slave_encoder_set_property(struct drm_connector *conn,
struct drm_property *property, uint64_t value)
{
struct drm_encoder *encoder = armada_drm_connector_encoder(conn);
int rc = -EINVAL;
if (encoder) {
struct drm_encoder_slave *slave = to_encoder_slave(encoder);
rc = slave->slave_funcs->set_property(encoder, conn, property,
value);
}
return rc;
}
int armada_output_create(struct drm_device *dev,
const struct armada_output_type *type, const void *data)
{
struct armada_connector *dconn;
int ret;
dconn = kzalloc(sizeof(*dconn), GFP_KERNEL);
if (!dconn)
return -ENOMEM;
dconn->type = type;
ret = drm_connector_init(dev, &dconn->conn, &armada_drm_conn_funcs,
type->connector_type);
if (ret) {
DRM_ERROR("unable to init connector\n");
goto err_destroy_dconn;
}
ret = type->create(&dconn->conn, data);
if (ret)
goto err_conn;
ret = drm_connector_register(&dconn->conn);
if (ret)
goto err_sysfs;
return 0;
err_sysfs:
if (dconn->conn.encoder)
dconn->conn.encoder->funcs->destroy(dconn->conn.encoder);
err_conn:
drm_connector_cleanup(&dconn->conn);
err_destroy_dconn:
kfree(dconn);
return ret;
}

View File

@ -1,33 +0,0 @@
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef ARMADA_CONNETOR_H
#define ARMADA_CONNETOR_H
#define encoder_helper_funcs(encoder) \
((const struct drm_encoder_helper_funcs *)encoder->helper_private)
struct armada_output_type {
int connector_type;
enum drm_connector_status (*detect)(struct drm_connector *, bool);
int (*create)(struct drm_connector *, const void *);
int (*set_property)(struct drm_connector *, struct drm_property *,
uint64_t);
};
struct drm_encoder *armada_drm_connector_encoder(struct drm_connector *conn);
int armada_drm_slave_encoder_mode_valid(struct drm_connector *conn,
struct drm_display_mode *mode);
int armada_drm_slave_encoder_set_property(struct drm_connector *conn,
struct drm_property *property, uint64_t value);
int armada_output_create(struct drm_device *dev,
const struct armada_output_type *type, const void *data);
#endif

View File

@ -1,139 +0,0 @@
/*
* Copyright (C) 2012 Russell King
* Rewritten from the dovefb driver, and Armada510 manuals.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder_slave.h>
#include "armada_drm.h"
#include "armada_output.h"
#include "armada_slave.h"
static int armada_drm_slave_get_modes(struct drm_connector *conn)
{
struct drm_encoder *enc = armada_drm_connector_encoder(conn);
int count = 0;
if (enc) {
struct drm_encoder_slave *slave = to_encoder_slave(enc);
count = slave->slave_funcs->get_modes(enc, conn);
}
return count;
}
static void armada_drm_slave_destroy(struct drm_encoder *enc)
{
struct drm_encoder_slave *slave = to_encoder_slave(enc);
struct i2c_client *client = drm_i2c_encoder_get_client(enc);
if (slave->slave_funcs)
slave->slave_funcs->destroy(enc);
if (client)
i2c_put_adapter(client->adapter);
drm_encoder_cleanup(&slave->base);
kfree(slave);
}
static const struct drm_encoder_funcs armada_drm_slave_encoder_funcs = {
.destroy = armada_drm_slave_destroy,
};
static const struct drm_connector_helper_funcs armada_drm_slave_helper_funcs = {
.get_modes = armada_drm_slave_get_modes,
.mode_valid = armada_drm_slave_encoder_mode_valid,
.best_encoder = armada_drm_connector_encoder,
};
static const struct drm_encoder_helper_funcs drm_slave_encoder_helpers = {
.dpms = drm_i2c_encoder_dpms,
.save = drm_i2c_encoder_save,
.restore = drm_i2c_encoder_restore,
.mode_fixup = drm_i2c_encoder_mode_fixup,
.prepare = drm_i2c_encoder_prepare,
.commit = drm_i2c_encoder_commit,
.mode_set = drm_i2c_encoder_mode_set,
.detect = drm_i2c_encoder_detect,
};
static int
armada_drm_conn_slave_create(struct drm_connector *conn, const void *data)
{
const struct armada_drm_slave_config *config = data;
struct drm_encoder_slave *slave;
struct i2c_adapter *adap;
int ret;
conn->interlace_allowed = config->interlace_allowed;
conn->doublescan_allowed = config->doublescan_allowed;
conn->polled = config->polled;
drm_connector_helper_add(conn, &armada_drm_slave_helper_funcs);
slave = kzalloc(sizeof(*slave), GFP_KERNEL);
if (!slave)
return -ENOMEM;
slave->base.possible_crtcs = config->crtcs;
adap = i2c_get_adapter(config->i2c_adapter_id);
if (!adap) {
kfree(slave);
return -EPROBE_DEFER;
}
ret = drm_encoder_init(conn->dev, &slave->base,
&armada_drm_slave_encoder_funcs,
DRM_MODE_ENCODER_TMDS);
if (ret) {
DRM_ERROR("unable to init encoder\n");
i2c_put_adapter(adap);
kfree(slave);
return ret;
}
ret = drm_i2c_encoder_init(conn->dev, slave, adap, &config->info);
i2c_put_adapter(adap);
if (ret) {
DRM_ERROR("unable to init encoder slave\n");
armada_drm_slave_destroy(&slave->base);
return ret;
}
drm_encoder_helper_add(&slave->base, &drm_slave_encoder_helpers);
ret = slave->slave_funcs->create_resources(&slave->base, conn);
if (ret) {
armada_drm_slave_destroy(&slave->base);
return ret;
}
ret = drm_mode_connector_attach_encoder(conn, &slave->base);
if (ret) {
armada_drm_slave_destroy(&slave->base);
return ret;
}
conn->encoder = &slave->base;
return ret;
}
static const struct armada_output_type armada_drm_conn_slave = {
.connector_type = DRM_MODE_CONNECTOR_HDMIA,
.create = armada_drm_conn_slave_create,
.set_property = armada_drm_slave_encoder_set_property,
};
int armada_drm_connector_slave_create(struct drm_device *dev,
const struct armada_drm_slave_config *config)
{
return armada_output_create(dev, &armada_drm_conn_slave, config);
}

View File

@ -1,26 +0,0 @@
/*
* Copyright (C) 2012 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef ARMADA_SLAVE_H
#define ARMADA_SLAVE_H
#include <linux/i2c.h>
#include <drm/drmP.h>
struct armada_drm_slave_config {
int i2c_adapter_id;
uint32_t crtcs;
uint8_t polled;
bool interlace_allowed;
bool doublescan_allowed;
struct i2c_board_info info;
};
int armada_drm_connector_slave_create(struct drm_device *dev,
const struct armada_drm_slave_config *);
#endif