summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/exynos
diff options
context:
space:
mode:
authorJoonas Lahtinen <joonas.lahtinen@linux.intel.com>2022-04-12 11:28:42 +0300
committerJoonas Lahtinen <joonas.lahtinen@linux.intel.com>2022-04-12 11:28:42 +0300
commitc16c8bfa09d5f318c1bd65698d058d3739970c24 (patch)
treea3ac5a1cad695c93d698cfff0b7629fd1a2ff79c /drivers/gpu/drm/exynos
parent8e7e5c077cd57ee9a36d58c65f07257dc49a88d5 (diff)
parentb85ffe47c4ec172214a38b7e7087c60582c488f0 (diff)
Merge drm/drm-next into drm-intel-gt-next
Pull in TTM changes needed for DG2 CCS enabling from Ram. Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm/exynos')
-rw-r--r--drivers/gpu/drm/exynos/exynos7_drm_decon.c12
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dsi.c247
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimc.c13
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c55
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gsc.c10
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_mic.c22
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c14
8 files changed, 150 insertions, 231 deletions
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 12571ac45540..c04264f70ad1 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -678,7 +678,6 @@ static int decon_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct decon_context *ctx;
struct device_node *i80_if_timings;
- struct resource *res;
int ret;
if (!dev->of_node)
@@ -728,16 +727,11 @@ static int decon_probe(struct platform_device *pdev)
goto err_iounmap;
}
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
- ctx->i80_if ? "lcd_sys" : "vsync");
- if (!res) {
- dev_err(dev, "irq request failed.\n");
- ret = -ENXIO;
+ ret = platform_get_irq_byname(pdev, ctx->i80_if ? "lcd_sys" : "vsync");
+ if (ret < 0)
goto err_iounmap;
- }
- ret = devm_request_irq(dev, res->start, decon_irq_handler,
- 0, "drm_decon", ctx);
+ ret = devm_request_irq(dev, ret, decon_irq_handler, 0, "drm_decon", ctx);
if (ret) {
dev_err(dev, "irq request failed.\n");
goto err_iounmap;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index c68498497c0b..424ea23eec32 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -212,11 +212,6 @@ static struct exynos_drm_driver_info exynos_drm_drivers[] = {
}
};
-static int compare_dev(struct device *dev, void *data)
-{
- return dev == (struct device *)data;
-}
-
static struct component_match *exynos_drm_match_add(struct device *dev)
{
struct component_match *match = NULL;
@@ -234,8 +229,7 @@ static struct component_match *exynos_drm_match_add(struct device *dev)
if (!(info->flags & DRM_FIMC_DEVICE) ||
exynos_drm_check_fimc_device(d) == 0)
- component_match_add(dev, &match,
- compare_dev, d);
+ component_match_add(dev, &match, component_compare_dev, d);
p = d;
}
put_device(p);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index b7d0a4aead0a..f067c86b0b12 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -24,9 +24,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
-#include <drm/drm_fb_helper.h>
#include <drm/drm_mipi_dsi.h>
-#include <drm/drm_panel.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
@@ -253,9 +251,7 @@ struct exynos_dsi_driver_data {
struct exynos_dsi {
struct drm_encoder encoder;
struct mipi_dsi_host dsi_host;
- struct drm_connector connector;
- struct drm_panel *panel;
- struct list_head bridge_chain;
+ struct drm_bridge bridge;
struct drm_bridge *out_bridge;
struct device *dev;
struct drm_display_mode mode;
@@ -285,11 +281,10 @@ struct exynos_dsi {
};
#define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
-#define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
-static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e)
+static inline struct exynos_dsi *bridge_to_dsi(struct drm_bridge *b)
{
- return container_of(e, struct exynos_dsi, encoder);
+ return container_of(b, struct exynos_dsi, bridge);
}
enum reg_idx {
@@ -1335,8 +1330,10 @@ static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi,
int ret;
int te_gpio_irq;
- dsi->te_gpio = devm_gpiod_get_optional(dsi->dev, "te", GPIOD_IN);
- if (IS_ERR(dsi->te_gpio)) {
+ dsi->te_gpio = gpiod_get_optional(panel, "te", GPIOD_IN);
+ if (!dsi->te_gpio) {
+ return 0;
+ } else if (IS_ERR(dsi->te_gpio)) {
dev_err(dsi->dev, "gpio request failed with %ld\n",
PTR_ERR(dsi->te_gpio));
return PTR_ERR(dsi->te_gpio);
@@ -1363,10 +1360,10 @@ static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi)
}
}
-static void exynos_dsi_enable(struct drm_encoder *encoder)
+static void exynos_dsi_atomic_pre_enable(struct drm_bridge *bridge,
+ struct drm_bridge_state *old_bridge_state)
{
- struct exynos_dsi *dsi = encoder_to_dsi(encoder);
- struct drm_bridge *iter;
+ struct exynos_dsi *dsi = bridge_to_dsi(bridge);
int ret;
if (dsi->state & DSIM_STATE_ENABLED)
@@ -1379,151 +1376,70 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
}
dsi->state |= DSIM_STATE_ENABLED;
+}
- if (dsi->panel) {
- ret = drm_panel_prepare(dsi->panel);
- if (ret < 0)
- goto err_put_sync;
- } else {
- list_for_each_entry_reverse(iter, &dsi->bridge_chain,
- chain_node) {
- if (iter->funcs->pre_enable)
- iter->funcs->pre_enable(iter);
- }
- }
+static void exynos_dsi_atomic_enable(struct drm_bridge *bridge,
+ struct drm_bridge_state *old_bridge_state)
+{
+ struct exynos_dsi *dsi = bridge_to_dsi(bridge);
exynos_dsi_set_display_mode(dsi);
exynos_dsi_set_display_enable(dsi, true);
- if (dsi->panel) {
- ret = drm_panel_enable(dsi->panel);
- if (ret < 0)
- goto err_display_disable;
- } else {
- list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
- if (iter->funcs->enable)
- iter->funcs->enable(iter);
- }
- }
-
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
- return;
-
-err_display_disable:
- exynos_dsi_set_display_enable(dsi, false);
- drm_panel_unprepare(dsi->panel);
-err_put_sync:
- dsi->state &= ~DSIM_STATE_ENABLED;
- pm_runtime_put(dsi->dev);
+ return;
}
-static void exynos_dsi_disable(struct drm_encoder *encoder)
+static void exynos_dsi_atomic_disable(struct drm_bridge *bridge,
+ struct drm_bridge_state *old_bridge_state)
{
- struct exynos_dsi *dsi = encoder_to_dsi(encoder);
- struct drm_bridge *iter;
+ struct exynos_dsi *dsi = bridge_to_dsi(bridge);
if (!(dsi->state & DSIM_STATE_ENABLED))
return;
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
+}
- drm_panel_disable(dsi->panel);
-
- list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
- if (iter->funcs->disable)
- iter->funcs->disable(iter);
- }
+static void exynos_dsi_atomic_post_disable(struct drm_bridge *bridge,
+ struct drm_bridge_state *old_bridge_state)
+{
+ struct exynos_dsi *dsi = bridge_to_dsi(bridge);
exynos_dsi_set_display_enable(dsi, false);
- drm_panel_unprepare(dsi->panel);
-
- list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
- if (iter->funcs->post_disable)
- iter->funcs->post_disable(iter);
- }
dsi->state &= ~DSIM_STATE_ENABLED;
pm_runtime_put_sync(dsi->dev);
}
-static void exynos_dsi_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static void exynos_dsi_mode_set(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ const struct drm_display_mode *adjusted_mode)
{
- struct exynos_dsi *dsi = encoder_to_dsi(encoder);
+ struct exynos_dsi *dsi = bridge_to_dsi(bridge);
drm_mode_copy(&dsi->mode, adjusted_mode);
}
-static enum drm_connector_status
-exynos_dsi_detect(struct drm_connector *connector, bool force)
-{
- return connector->status;
-}
-
-static void exynos_dsi_connector_destroy(struct drm_connector *connector)
-{
- drm_connector_unregister(connector);
- drm_connector_cleanup(connector);
- connector->dev = NULL;
-}
-
-static const struct drm_connector_funcs exynos_dsi_connector_funcs = {
- .detect = exynos_dsi_detect,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .destroy = exynos_dsi_connector_destroy,
- .reset = drm_atomic_helper_connector_reset,
- .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int exynos_dsi_get_modes(struct drm_connector *connector)
-{
- struct exynos_dsi *dsi = connector_to_dsi(connector);
-
- if (dsi->panel)
- return drm_panel_get_modes(dsi->panel, connector);
-
- return 0;
-}
-
-static const struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
- .get_modes = exynos_dsi_get_modes,
-};
-
-static int exynos_dsi_create_connector(struct drm_encoder *encoder)
+static int exynos_dsi_attach(struct drm_bridge *bridge,
+ enum drm_bridge_attach_flags flags)
{
- struct exynos_dsi *dsi = encoder_to_dsi(encoder);
- struct drm_connector *connector = &dsi->connector;
- struct drm_device *drm = encoder->dev;
- int ret;
-
- connector->polled = DRM_CONNECTOR_POLL_HPD;
+ struct exynos_dsi *dsi = bridge_to_dsi(bridge);
- ret = drm_connector_init(drm, connector, &exynos_dsi_connector_funcs,
- DRM_MODE_CONNECTOR_DSI);
- if (ret) {
- DRM_DEV_ERROR(dsi->dev,
- "Failed to initialize connector with drm\n");
- return ret;
- }
-
- connector->status = connector_status_disconnected;
- drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs);
- drm_connector_attach_encoder(connector, encoder);
- if (!drm->registered)
- return 0;
-
- connector->funcs->reset(connector);
- drm_connector_register(connector);
- return 0;
+ return drm_bridge_attach(bridge->encoder, dsi->out_bridge, NULL, flags);
}
-static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
- .enable = exynos_dsi_enable,
- .disable = exynos_dsi_disable,
- .mode_set = exynos_dsi_mode_set,
+static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+ .atomic_reset = drm_atomic_helper_bridge_reset,
+ .atomic_pre_enable = exynos_dsi_atomic_pre_enable,
+ .atomic_enable = exynos_dsi_atomic_enable,
+ .atomic_disable = exynos_dsi_atomic_disable,
+ .atomic_post_disable = exynos_dsi_atomic_post_disable,
+ .mode_set = exynos_dsi_mode_set,
+ .attach = exynos_dsi_attach,
};
MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
@@ -1532,33 +1448,24 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
struct mipi_dsi_device *device)
{
struct exynos_dsi *dsi = host_to_dsi(host);
+ struct device *dev = dsi->dev;
struct drm_encoder *encoder = &dsi->encoder;
struct drm_device *drm = encoder->dev;
- struct drm_bridge *out_bridge;
-
- out_bridge = of_drm_find_bridge(device->dev.of_node);
- if (out_bridge) {
- drm_bridge_attach(encoder, out_bridge, NULL, 0);
- dsi->out_bridge = out_bridge;
- list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
- } else {
- int ret = exynos_dsi_create_connector(encoder);
-
- if (ret) {
- DRM_DEV_ERROR(dsi->dev,
- "failed to create connector ret = %d\n",
- ret);
- drm_encoder_cleanup(encoder);
- return ret;
- }
+ int ret;
- dsi->panel = of_drm_find_panel(device->dev.of_node);
- if (IS_ERR(dsi->panel))
- dsi->panel = NULL;
- else
- dsi->connector.status = connector_status_connected;
+ dsi->out_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
+ if (IS_ERR(dsi->out_bridge)) {
+ ret = PTR_ERR(dsi->out_bridge);
+ DRM_DEV_ERROR(dev, "failed to find the bridge: %d\n", ret);
+ return ret;
}
+ DRM_DEV_INFO(dev, "Attached %s device\n", device->name);
+
+ drm_bridge_add(&dsi->bridge);
+
+ drm_bridge_attach(encoder, &dsi->bridge, NULL, 0);
+
/*
* This is a temporary solution and should be made by more generic way.
*
@@ -1566,7 +1473,7 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
* TE interrupt handler.
*/
if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
- int ret = exynos_dsi_register_te_irq(dsi, &device->dev);
+ ret = exynos_dsi_register_te_irq(dsi, &device->dev);
if (ret)
return ret;
}
@@ -1593,24 +1500,17 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
struct exynos_dsi *dsi = host_to_dsi(host);
struct drm_device *drm = dsi->encoder.dev;
- if (dsi->panel) {
- mutex_lock(&drm->mode_config.mutex);
- exynos_dsi_disable(&dsi->encoder);
- dsi->panel = NULL;
- dsi->connector.status = connector_status_disconnected;
- mutex_unlock(&drm->mode_config.mutex);
- } else {
- if (dsi->out_bridge->funcs->detach)
- dsi->out_bridge->funcs->detach(dsi->out_bridge);
- dsi->out_bridge = NULL;
- INIT_LIST_HEAD(&dsi->bridge_chain);
- }
+ if (dsi->out_bridge->funcs->detach)
+ dsi->out_bridge->funcs->detach(dsi->out_bridge);
+ dsi->out_bridge = NULL;
if (drm->mode_config.poll_enabled)
drm_kms_helper_hotplug_event(drm);
exynos_dsi_unregister_te_irq(dsi);
+ drm_bridge_remove(&dsi->bridge);
+
return 0;
}
@@ -1660,11 +1560,6 @@ static int exynos_dsi_of_read_u32(const struct device_node *np,
return ret;
}
-enum {
- DSI_PORT_IN,
- DSI_PORT_OUT
-};
-
static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
{
struct device *dev = dsi->dev;
@@ -1695,26 +1590,14 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
struct exynos_dsi *dsi = dev_get_drvdata(dev);
struct drm_encoder *encoder = &dsi->encoder;
struct drm_device *drm_dev = data;
- struct device_node *in_bridge_node;
- struct drm_bridge *in_bridge;
int ret;
drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
- drm_encoder_helper_add(encoder, &exynos_dsi_encoder_helper_funcs);
-
ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_LCD);
if (ret < 0)
return ret;
- in_bridge_node = of_graph_get_remote_node(dev->of_node, DSI_PORT_IN, 0);
- if (in_bridge_node) {
- in_bridge = of_drm_find_bridge(in_bridge_node);
- if (in_bridge)
- drm_bridge_attach(encoder, in_bridge, NULL, 0);
- of_node_put(in_bridge_node);
- }
-
return mipi_dsi_host_register(&dsi->dsi_host);
}
@@ -1722,9 +1605,8 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master,
void *data)
{
struct exynos_dsi *dsi = dev_get_drvdata(dev);
- struct drm_encoder *encoder = &dsi->encoder;
- exynos_dsi_disable(encoder);
+ exynos_dsi_atomic_disable(&dsi->bridge, NULL);
mipi_dsi_host_unregister(&dsi->dsi_host);
}
@@ -1747,7 +1629,6 @@ static int exynos_dsi_probe(struct platform_device *pdev)
init_completion(&dsi->completed);
spin_lock_init(&dsi->transfer_lock);
INIT_LIST_HEAD(&dsi->transfer_list);
- INIT_LIST_HEAD(&dsi->bridge_chain);
dsi->dsi_host.ops = &exynos_dsi_ops;
dsi->dsi_host.dev = dev;
@@ -1815,6 +1696,10 @@ static int exynos_dsi_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
+ dsi->bridge.funcs = &exynos_dsi_bridge_funcs;
+ dsi->bridge.of_node = dev->of_node;
+ dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
+
ret = component_add(dev, &exynos_dsi_component_ops);
if (ret)
goto err_disable_runtime;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
index 023f54ee61a8..0ee32e4b1e43 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
@@ -1267,7 +1267,6 @@ static int fimc_probe(struct platform_device *pdev)
struct exynos_drm_ipp_formats *formats;
struct device *dev = &pdev->dev;
struct fimc_context *ctx;
- struct resource *res;
int ret;
int i, j, num_limits, num_formats;
@@ -1330,14 +1329,12 @@ static int fimc_probe(struct platform_device *pdev)
return PTR_ERR(ctx->regs);
/* resource irq */
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(dev, "failed to request irq resource.\n");
- return -ENOENT;
- }
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0)
+ return ret;
- ret = devm_request_irq(dev, res->start, fimc_irq_handler,
- 0, dev_name(dev), ctx);
+ ret = devm_request_irq(dev, ret, fimc_irq_handler,
+ 0, dev_name(dev), ctx);
if (ret < 0) {
dev_err(dev, "failed to request irq.\n");
return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index c735e53939d8..d5720fab510c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -109,6 +109,7 @@ struct fimd_driver_data {
unsigned int has_dp_clk:1;
unsigned int has_hw_trigger:1;
unsigned int has_trigger_per_te:1;
+ unsigned int has_bgr_support:1;
};
static struct fimd_driver_data s3c64xx_fimd_driver_data = {
@@ -138,6 +139,7 @@ static struct fimd_driver_data exynos4_fimd_driver_data = {
.lcdblk_bypass_shift = 1,
.has_shadowcon = 1,
.has_vtsel = 1,
+ .has_bgr_support = 1,
};
static struct fimd_driver_data exynos5_fimd_driver_data = {
@@ -149,6 +151,7 @@ static struct fimd_driver_data exynos5_fimd_driver_data = {
.has_vidoutcon = 1,
.has_vtsel = 1,
.has_dp_clk = 1,
+ .has_bgr_support = 1,
};
static struct fimd_driver_data exynos5420_fimd_driver_data = {
@@ -162,6 +165,7 @@ static struct fimd_driver_data exynos5420_fimd_driver_data = {
.has_vtsel = 1,
.has_mic_bypass = 1,
.has_dp_clk = 1,
+ .has_bgr_support = 1,
};
struct fimd_context {
@@ -226,6 +230,18 @@ static const uint32_t fimd_formats[] = {
DRM_FORMAT_ARGB8888,
};
+static const uint32_t fimd_extended_formats[] = {
+ DRM_FORMAT_C8,
+ DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_XBGR1555,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_BGR565,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_ABGR8888,
+};
+
static const unsigned int capabilities[WINDOWS_NR] = {
0,
EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
@@ -673,21 +689,25 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
val |= WINCONx_BYTSWP;
break;
case DRM_FORMAT_XRGB1555:
+ case DRM_FORMAT_XBGR1555:
val |= WINCON0_BPPMODE_16BPP_1555;
val |= WINCONx_HAWSWP;
val |= WINCONx_BURSTLEN_16WORD;
break;
case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_BGR565:
val |= WINCON0_BPPMODE_16BPP_565;
val |= WINCONx_HAWSWP;
val |= WINCONx_BURSTLEN_16WORD;
break;
case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
val |= WINCON0_BPPMODE_24BPP_888;
val |= WINCONx_WSWP;
val |= WINCONx_BURSTLEN_16WORD;
break;
case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_ABGR8888:
default:
val |= WINCON1_BPPMODE_25BPP_A1888;
val |= WINCONx_WSWP;
@@ -695,6 +715,18 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
break;
}
+ switch (pixel_format) {
+ case DRM_FORMAT_XBGR1555:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_BGR565:
+ writel(WIN_RGB_ORDER_REVERSE, ctx->regs + WIN_RGB_ORDER(win));
+ break;
+ default:
+ writel(WIN_RGB_ORDER_FORWARD, ctx->regs + WIN_RGB_ORDER(win));
+ break;
+ }
+
/*
* Setting dma-burst to 16Word causes permanent tearing for very small
* buffers, e.g. cursor buffer. Burst Mode switching which based on
@@ -1074,8 +1106,14 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
ctx->drm_dev = drm_dev;
for (i = 0; i < WINDOWS_NR; i++) {
- ctx->configs[i].pixel_formats = fimd_formats;
- ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats);
+ if (ctx->driver_data->has_bgr_support) {
+ ctx->configs[i].pixel_formats = fimd_extended_formats;
+ ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_extended_formats);
+ } else {
+ ctx->configs[i].pixel_formats = fimd_formats;
+ ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats);
+ }
+
ctx->configs[i].zpos = i;
ctx->configs[i].type = fimd_win_types[i];
ctx->configs[i].capabilities = capabilities[i];
@@ -1133,7 +1171,6 @@ static int fimd_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct fimd_context *ctx;
struct device_node *i80_if_timings;
- struct resource *res;
int ret;
if (!dev->of_node)
@@ -1206,15 +1243,11 @@ static int fimd_probe(struct platform_device *pdev)
if (IS_ERR(ctx->regs))
return PTR_ERR(ctx->regs);
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
- ctx->i80_if ? "lcd_sys" : "vsync");
- if (!res) {
- dev_err(dev, "irq request failed.\n");
- return -ENXIO;
- }
+ ret = platform_get_irq_byname(pdev, ctx->i80_if ? "lcd_sys" : "vsync");
+ if (ret < 0)
+ return ret;
- ret = devm_request_irq(dev, res->start, fimd_irq_handler,
- 0, "drm_fimd", ctx);
+ ret = devm_request_irq(dev, ret, fimd_irq_handler, 0, "drm_fimd", ctx);
if (ret) {
dev_err(dev, "irq request failed.\n");
return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index 166a80262896..964dceb28c1e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -1220,7 +1220,6 @@ static int gsc_probe(struct platform_device *pdev)
struct gsc_driverdata *driver_data;
struct exynos_drm_ipp_formats *formats;
struct gsc_context *ctx;
- struct resource *res;
int num_formats, ret, i, j;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
@@ -1275,13 +1274,10 @@ static int gsc_probe(struct platform_device *pdev)
return PTR_ERR(ctx->regs);
/* resource irq */
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(dev, "failed to request irq resource.\n");
- return -ENOENT;
- }
+ ctx->irq = platform_get_irq(pdev, 0);
+ if (ctx->irq < 0)
+ return ctx->irq;
- ctx->irq = res->start;
ret = devm_request_irq(dev, ctx->irq, gsc_irq_handler, 0,
dev_name(dev), ctx);
if (ret < 0) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
index 32672bf8ae4a..9e06f8e2a863 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
@@ -102,6 +102,7 @@ struct exynos_mic {
struct videomode vm;
struct drm_encoder *encoder;
struct drm_bridge bridge;
+ struct drm_bridge *next_bridge;
bool enabled;
};
@@ -298,12 +299,22 @@ unlock:
static void mic_enable(struct drm_bridge *bridge) { }
+static int mic_attach(struct drm_bridge *bridge,
+ enum drm_bridge_attach_flags flags)
+{
+ struct exynos_mic *mic = bridge->driver_private;
+
+ return drm_bridge_attach(bridge->encoder, mic->next_bridge,
+ &mic->bridge, flags);
+}
+
static const struct drm_bridge_funcs mic_bridge_funcs = {
.disable = mic_disable,
.post_disable = mic_post_disable,
.mode_set = mic_mode_set,
.pre_enable = mic_pre_enable,
.enable = mic_enable,
+ .attach = mic_attach,
};
static int exynos_mic_bind(struct device *dev, struct device *master,
@@ -377,6 +388,7 @@ static int exynos_mic_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct exynos_mic *mic;
+ struct device_node *remote;
struct resource res;
int ret, i;
@@ -420,6 +432,16 @@ static int exynos_mic_probe(struct platform_device *pdev)
}
}
+ remote = of_graph_get_remote_node(dev->of_node, 1, 0);
+ mic->next_bridge = of_drm_find_bridge(remote);
+ if (IS_ERR(mic->next_bridge)) {
+ DRM_DEV_ERROR(dev, "mic: Failed to find next bridge\n");
+ ret = PTR_ERR(mic->next_bridge);
+ goto err;
+ }
+
+ of_node_put(remote);
+
platform_set_drvdata(pdev, mic);
mic->bridge.funcs = &mic_bridge_funcs;
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 41c54f1f60bc..e5204be86093 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -809,19 +809,17 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx)
return -ENXIO;
}
- res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_IRQ, 0);
- if (res == NULL) {
- dev_err(dev, "get interrupt resource failed.\n");
- return -ENXIO;
- }
+ ret = platform_get_irq(mixer_ctx->pdev, 0);
+ if (ret < 0)
+ return ret;
+ mixer_ctx->irq = ret;
- ret = devm_request_irq(dev, res->start, mixer_irq_handler,
- 0, "drm_mixer", mixer_ctx);
+ ret = devm_request_irq(dev, mixer_ctx->irq, mixer_irq_handler,
+ 0, "drm_mixer", mixer_ctx);
if (ret) {
dev_err(dev, "request interrupt failed.\n");
return ret;
}
- mixer_ctx->irq = res->start;
return 0;
}