summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/arm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/arm')
-rw-r--r--drivers/gpu/drm/arm/Kconfig9
-rw-r--r--drivers/gpu/drm/arm/display/Kconfig4
-rw-r--r--drivers/gpu/drm/arm/display/include/malidp_utils.h2
-rw-r--r--drivers/gpu/drm/arm/display/komeda/Makefile4
-rw-r--r--drivers/gpu/drm/arm/display/komeda/d71/d71_component.c14
-rw-r--r--drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c6
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c5
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_crtc.c86
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_dev.c10
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_drv.c82
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c16
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h1
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_kms.c69
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_kms.h9
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c7
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c37
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_plane.c25
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c11
-rw-r--r--drivers/gpu/drm/arm/hdlcd_crtc.c61
-rw-r--r--drivers/gpu/drm/arm/hdlcd_drv.c246
-rw-r--r--drivers/gpu/drm/arm/hdlcd_drv.h3
-rw-r--r--drivers/gpu/drm/arm/malidp_crtc.c15
-rw-r--r--drivers/gpu/drm/arm/malidp_drv.c120
-rw-r--r--drivers/gpu/drm/arm/malidp_drv.h2
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.c10
-rw-r--r--drivers/gpu/drm/arm/malidp_mw.c28
-rw-r--r--drivers/gpu/drm/arm/malidp_planes.c91
-rw-r--r--drivers/gpu/drm/arm/malidp_regs.h2
28 files changed, 495 insertions, 480 deletions
diff --git a/drivers/gpu/drm/arm/Kconfig b/drivers/gpu/drm/arm/Kconfig
index 3a9e966e0e78..ed3ed617c688 100644
--- a/drivers/gpu/drm/arm/Kconfig
+++ b/drivers/gpu/drm/arm/Kconfig
@@ -1,12 +1,15 @@
# SPDX-License-Identifier: GPL-2.0
menu "ARM devices"
+ depends on DRM
config DRM_HDLCD
tristate "ARM HDLCD"
depends on DRM && OF && (ARM || ARM64 || COMPILE_TEST)
depends on COMMON_CLK
+ select DRM_CLIENT_SELECTION
select DRM_KMS_HELPER
- select DRM_KMS_CMA_HELPER
+ select DRM_GEM_DMA_HELPER
+ select DRM_BRIDGE # for TDA998x
help
Choose this option if you have an ARM High Definition Colour LCD
controller.
@@ -26,9 +29,9 @@ config DRM_MALI_DISPLAY
tristate "ARM Mali Display Processor"
depends on DRM && OF && (ARM || ARM64 || COMPILE_TEST)
depends on COMMON_CLK
+ select DRM_CLIENT_SELECTION
select DRM_KMS_HELPER
- select DRM_KMS_CMA_HELPER
- select DRM_GEM_CMA_HELPER
+ select DRM_GEM_DMA_HELPER
select VIDEOMODE_HELPERS
help
Choose this option if you want to compile the ARM Mali Display
diff --git a/drivers/gpu/drm/arm/display/Kconfig b/drivers/gpu/drm/arm/display/Kconfig
index cec0639e3aa1..415c10a6374b 100644
--- a/drivers/gpu/drm/arm/display/Kconfig
+++ b/drivers/gpu/drm/arm/display/Kconfig
@@ -3,9 +3,9 @@ config DRM_KOMEDA
tristate "ARM Komeda display driver"
depends on DRM && OF
depends on COMMON_CLK
+ select DRM_CLIENT_SELECTION
select DRM_KMS_HELPER
- select DRM_KMS_CMA_HELPER
- select DRM_GEM_CMA_HELPER
+ select DRM_GEM_DMA_HELPER
select VIDEOMODE_HELPERS
help
Choose this option if you want to compile the ARM Komeda display
diff --git a/drivers/gpu/drm/arm/display/include/malidp_utils.h b/drivers/gpu/drm/arm/display/include/malidp_utils.h
index 49a1d7f3539c..9f83baac6ed8 100644
--- a/drivers/gpu/drm/arm/display/include/malidp_utils.h
+++ b/drivers/gpu/drm/arm/display/include/malidp_utils.h
@@ -35,7 +35,7 @@ static inline void set_range(struct malidp_range *rg, u32 start, u32 end)
rg->end = end;
}
-static inline bool in_range(struct malidp_range *rg, u32 v)
+static inline bool malidp_in_range(struct malidp_range *rg, u32 v)
{
return (v >= rg->start) && (v <= rg->end);
}
diff --git a/drivers/gpu/drm/arm/display/komeda/Makefile b/drivers/gpu/drm/arm/display/komeda/Makefile
index 1931a7fa1a14..cf5287fcbbc2 100644
--- a/drivers/gpu/drm/arm/display/komeda/Makefile
+++ b/drivers/gpu/drm/arm/display/komeda/Makefile
@@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
ccflags-y := \
- -I $(srctree)/$(src)/../include \
- -I $(srctree)/$(src)
+ -I $(src)/../include \
+ -I $(src)
komeda-y := \
komeda_drv.o \
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 8a02ade369db..67e5d3b4190f 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -4,6 +4,8 @@
* Author: James.Qian.Wang <james.qian.wang@arm.com>
*
*/
+
+#include <linux/seq_file.h>
#include "d71_dev.h"
#include "komeda_kms.h"
#include "malidp_io.h"
@@ -1078,11 +1080,11 @@ static void d71_improc_update(struct komeda_component *c,
mask |= IPS_CTRL_YUV | IPS_CTRL_CHD422 | IPS_CTRL_CHD420;
/* config color format */
- if (st->color_format == DRM_COLOR_FORMAT_YCRCB420)
+ if (st->color_format == DRM_COLOR_FORMAT_YCBCR420)
ctrl |= IPS_CTRL_YUV | IPS_CTRL_CHD422 | IPS_CTRL_CHD420;
- else if (st->color_format == DRM_COLOR_FORMAT_YCRCB422)
+ else if (st->color_format == DRM_COLOR_FORMAT_YCBCR422)
ctrl |= IPS_CTRL_YUV | IPS_CTRL_CHD422;
- else if (st->color_format == DRM_COLOR_FORMAT_YCRCB444)
+ else if (st->color_format == DRM_COLOR_FORMAT_YCBCR444)
ctrl |= IPS_CTRL_YUV;
malidp_write32_mask(reg, BLK_CONTROL, mask, ctrl);
@@ -1144,11 +1146,11 @@ static int d71_improc_init(struct d71_dev *d71,
improc = to_improc(c);
improc->supported_color_depths = BIT(8) | BIT(10);
improc->supported_color_formats = DRM_COLOR_FORMAT_RGB444 |
- DRM_COLOR_FORMAT_YCRCB444 |
- DRM_COLOR_FORMAT_YCRCB422;
+ DRM_COLOR_FORMAT_YCBCR444 |
+ DRM_COLOR_FORMAT_YCBCR422;
value = malidp_read32(reg, BLK_INFO);
if (value & IPS_INFO_CHD420)
- improc->supported_color_formats |= DRM_COLOR_FORMAT_YCRCB420;
+ improc->supported_color_formats |= DRM_COLOR_FORMAT_YCBCR420;
improc->supports_csc = true;
improc->supports_gamma = true;
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 00fa56c29b3e..80973975bfdb 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -5,6 +5,7 @@
*
*/
+#include <drm/drm_blend.h>
#include <drm/drm_print.h>
#include "d71_dev.h"
#include "malidp_io.h"
@@ -309,8 +310,7 @@ static int d71_reset(struct d71_dev *d71)
u32 __iomem *gcu = d71->gcu_addr;
int ret;
- malidp_write32_mask(gcu, BLK_CONTROL,
- GCU_CONTROL_SRST, GCU_CONTROL_SRST);
+ malidp_write32(gcu, BLK_CONTROL, GCU_CONTROL_SRST);
ret = dp_wait_cond(!(malidp_read32(gcu, BLK_CONTROL) & GCU_CONTROL_SRST),
100, 1000, 10000);
@@ -521,7 +521,7 @@ static struct komeda_format_caps d71_format_caps_table[] = {
{__HW_ID(5, 1), DRM_FORMAT_YUYV, RICH, Rot_ALL_H_V, LYT_NM, AFB_TH}, /* afbc */
{__HW_ID(5, 2), DRM_FORMAT_YUYV, RICH, Flip_H_V, 0, 0},
{__HW_ID(5, 3), DRM_FORMAT_UYVY, RICH, Flip_H_V, 0, 0},
- {__HW_ID(5, 6), DRM_FORMAT_NV12, RICH, Flip_H_V, 0, 0},
+ {__HW_ID(5, 6), DRM_FORMAT_NV12, RICH_WB, Flip_H_V, 0, 0},
{__HW_ID(5, 6), DRM_FORMAT_YUV420_8BIT, RICH, Rot_ALL_H_V, LYT_NM, AFB_TH}, /* afbc */
{__HW_ID(5, 7), DRM_FORMAT_YUV420, RICH, Flip_H_V, 0, 0},
/* YUV 10bit*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
index d8e449e6ebda..50cb8f7ee6b2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
@@ -72,11 +72,6 @@ struct gamma_curve_sector {
u32 segment_width;
};
-struct gamma_curve_segment {
- u32 start;
- u32 end;
-};
-
static struct gamma_curve_sector sector_tbl[] = {
{ 0, 4, 4 },
{ 16, 4, 4 },
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 59172acb9738..5a66948ffd24 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -5,15 +5,16 @@
*
*/
#include <linux/clk.h>
+#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/spinlock.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_plane_helper.h>
#include <drm/drm_print.h>
#include <drm/drm_vblank.h>
+#include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_bridge.h>
#include "komeda_dev.h"
#include "komeda_kms.h"
@@ -110,6 +111,7 @@ komeda_crtc_atomic_check(struct drm_crtc *crtc,
static int
komeda_crtc_prepare(struct komeda_crtc *kcrtc)
{
+ struct drm_device *drm = kcrtc->base.dev;
struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
struct komeda_pipeline *master = kcrtc->master;
struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(kcrtc->base.state);
@@ -127,8 +129,8 @@ komeda_crtc_prepare(struct komeda_crtc *kcrtc)
err = mdev->funcs->change_opmode(mdev, new_mode);
if (err) {
- DRM_ERROR("failed to change opmode: 0x%x -> 0x%x.\n,",
- mdev->dpmode, new_mode);
+ drm_err(drm, "failed to change opmode: 0x%x -> 0x%x.\n,",
+ mdev->dpmode, new_mode);
goto unlock;
}
@@ -141,18 +143,18 @@ komeda_crtc_prepare(struct komeda_crtc *kcrtc)
if (new_mode != KOMEDA_MODE_DUAL_DISP) {
err = clk_set_rate(mdev->aclk, komeda_crtc_get_aclk(kcrtc_st));
if (err)
- DRM_ERROR("failed to set aclk.\n");
+ drm_err(drm, "failed to set aclk.\n");
err = clk_prepare_enable(mdev->aclk);
if (err)
- DRM_ERROR("failed to enable aclk.\n");
+ drm_err(drm, "failed to enable aclk.\n");
}
err = clk_set_rate(master->pxlclk, mode->crtc_clock * 1000);
if (err)
- DRM_ERROR("failed to set pxlclk for pipe%d\n", master->id);
+ drm_err(drm, "failed to set pxlclk for pipe%d\n", master->id);
err = clk_prepare_enable(master->pxlclk);
if (err)
- DRM_ERROR("failed to enable pxl clk for pipe%d.\n", master->id);
+ drm_err(drm, "failed to enable pxl clk for pipe%d.\n", master->id);
unlock:
mutex_unlock(&mdev->lock);
@@ -163,6 +165,7 @@ unlock:
static int
komeda_crtc_unprepare(struct komeda_crtc *kcrtc)
{
+ struct drm_device *drm = kcrtc->base.dev;
struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
struct komeda_pipeline *master = kcrtc->master;
u32 new_mode;
@@ -179,8 +182,8 @@ komeda_crtc_unprepare(struct komeda_crtc *kcrtc)
err = mdev->funcs->change_opmode(mdev, new_mode);
if (err) {
- DRM_ERROR("failed to change opmode: 0x%x -> 0x%x.\n,",
- mdev->dpmode, new_mode);
+ drm_err(drm, "failed to change opmode: 0x%x -> 0x%x.\n,",
+ mdev->dpmode, new_mode);
goto unlock;
}
@@ -199,6 +202,7 @@ unlock:
void komeda_crtc_handle_event(struct komeda_crtc *kcrtc,
struct komeda_events *evts)
{
+ struct drm_device *drm = kcrtc->base.dev;
struct drm_crtc *crtc = &kcrtc->base;
u32 events = evts->pipes[kcrtc->master->id];
@@ -211,7 +215,7 @@ void komeda_crtc_handle_event(struct komeda_crtc *kcrtc,
if (wb_conn)
drm_writeback_signal_completion(&wb_conn->base, 0);
else
- DRM_WARN("CRTC[%d]: EOW happen but no wb_connector.\n",
+ drm_warn(drm, "CRTC[%d]: EOW happen but no wb_connector.\n",
drm_crtc_index(&kcrtc->base));
}
/* will handle it together with the write back support */
@@ -235,7 +239,7 @@ void komeda_crtc_handle_event(struct komeda_crtc *kcrtc,
crtc->state->event = NULL;
drm_crtc_send_vblank_event(crtc, event);
} else {
- DRM_WARN("CRTC[%d]: FLIP happen but no pending commit.\n",
+ drm_warn(drm, "CRTC[%d]: FLIP happened but no pending commit.\n",
drm_crtc_index(&kcrtc->base));
}
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
@@ -286,7 +290,7 @@ komeda_crtc_atomic_enable(struct drm_crtc *crtc,
komeda_crtc_do_flush(crtc, old);
}
-static void
+void
komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
struct completion *input_flip_done)
{
@@ -294,7 +298,6 @@ komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
struct komeda_dev *mdev = kcrtc->master->mdev;
struct completion *flip_done;
struct completion temp;
- int timeout;
/* if caller doesn't send a flip_done, use a private flip_done */
if (input_flip_done) {
@@ -308,9 +311,8 @@ komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
mdev->funcs->flush(mdev, kcrtc->master->id, 0);
/* wait the flip take affect.*/
- timeout = wait_for_completion_timeout(flip_done, HZ);
- if (timeout == 0) {
- DRM_ERROR("wait pipe%d flip done timeout\n", kcrtc->master->id);
+ if (wait_for_completion_timeout(flip_done, HZ) == 0) {
+ drm_err(drm, "wait pipe%d flip done timeout\n", kcrtc->master->id);
if (!input_flip_done) {
unsigned long flags;
@@ -563,6 +565,7 @@ static const struct drm_crtc_funcs komeda_crtc_funcs = {
int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
struct komeda_dev *mdev)
{
+ struct drm_device *drm = &kms->base;
struct komeda_crtc *crtc;
struct komeda_pipeline *master;
char str[16];
@@ -582,7 +585,7 @@ int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
else
sprintf(str, "None");
- DRM_INFO("CRTC-%d: master(pipe-%d) slave(%s).\n",
+ drm_info(drm, "CRTC-%d: master(pipe-%d) slave(%s).\n",
kms->n_crtcs, master->id, str);
kms->n_crtcs++;
@@ -610,13 +613,38 @@ get_crtc_primary(struct komeda_kms_dev *kms, struct komeda_crtc *crtc)
return NULL;
}
+static int komeda_attach_bridge(struct device *dev,
+ struct komeda_pipeline *pipe,
+ struct drm_encoder *encoder)
+{
+ struct drm_device *drm = encoder->dev;
+ struct drm_bridge *bridge;
+ int err;
+
+ bridge = devm_drm_of_get_bridge(dev, pipe->of_node,
+ KOMEDA_OF_PORT_OUTPUT, 0);
+ if (IS_ERR(bridge))
+ return dev_err_probe(dev, PTR_ERR(bridge), "remote bridge not found for pipe: %s\n",
+ of_node_full_name(pipe->of_node));
+
+ err = drm_bridge_attach(encoder, bridge, NULL, 0);
+ if (err)
+ drm_err(drm, "bridge_attach() failed for pipe: %s\n",
+ of_node_full_name(pipe->of_node));
+
+ return err;
+}
+
static int komeda_crtc_add(struct komeda_kms_dev *kms,
struct komeda_crtc *kcrtc)
{
struct drm_crtc *crtc = &kcrtc->base;
+ struct drm_device *base = &kms->base;
+ struct komeda_pipeline *pipe = kcrtc->master;
+ struct drm_encoder *encoder = &kcrtc->encoder;
int err;
- err = drm_crtc_init_with_planes(&kms->base, crtc,
+ err = drm_crtc_init_with_planes(base, crtc,
get_crtc_primary(kms, kcrtc), NULL,
&komeda_crtc_funcs, NULL);
if (err)
@@ -624,11 +652,27 @@ static int komeda_crtc_add(struct komeda_kms_dev *kms,
drm_crtc_helper_add(crtc, &komeda_crtc_helper_funcs);
- crtc->port = kcrtc->master->of_output_port;
+ crtc->port = pipe->of_output_port;
+
+ /* Construct an encoder for each pipeline and attach it to the remote
+ * bridge
+ */
+ kcrtc->encoder.possible_crtcs = drm_crtc_mask(crtc);
+ err = drm_simple_encoder_init(base, encoder, DRM_MODE_ENCODER_TMDS);
+ if (err)
+ return err;
+
+ if (pipe->of_output_links[0]) {
+ err = komeda_attach_bridge(base->dev, pipe, encoder);
+ if (err)
+ return err;
+ }
drm_crtc_enable_color_mgmt(crtc, 0, true, KOMEDA_COLOR_LUT_SIZE);
- return err;
+ komeda_pipeline_dump(pipe);
+
+ return 0;
}
int komeda_kms_add_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index cc7664c95a54..5ba62e637a61 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -6,16 +6,14 @@
*/
#include <linux/io.h>
#include <linux/iommu.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/dma-mapping.h>
-#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/seq_file.h>
-#endif
#include <drm/drm_print.h>
@@ -43,7 +41,6 @@ static int komeda_register_show(struct seq_file *sf, void *x)
DEFINE_SHOW_ATTRIBUTE(komeda_register);
-#ifdef CONFIG_DEBUG_FS
static void komeda_debugfs_init(struct komeda_dev *mdev)
{
if (!debugfs_initialized())
@@ -55,7 +52,6 @@ static void komeda_debugfs_init(struct komeda_dev *mdev)
debugfs_create_x16("err_verbosity", 0664, mdev->debugfs_root,
&mdev->err_verbosity);
}
-#endif
static ssize_t
core_id_show(struct device *dev, struct device_attribute *attr, char *buf)
@@ -265,9 +261,7 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
mdev->err_verbosity = KOMEDA_DEV_PRINT_ERR_EVENTS;
-#ifdef CONFIG_DEBUG_FS
komeda_debugfs_init(mdev);
-#endif
return mdev;
@@ -286,9 +280,7 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
sysfs_remove_group(&dev->kobj, &komeda_sysfs_attr_group);
-#ifdef CONFIG_DEBUG_FS
debugfs_remove_recursive(mdev->debugfs_root);
-#endif
if (mdev->aclk)
clk_prepare_enable(mdev->aclk);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
index e7933930a657..358c1512b087 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
@@ -6,9 +6,11 @@
*/
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
-#include <linux/component.h>
#include <linux/pm_runtime.h>
+#include <drm/clients/drm_client_setup.h>
+#include <drm/drm_module.h>
#include <drm/drm_of.h>
#include "komeda_dev.h"
#include "komeda_kms.h"
@@ -25,13 +27,11 @@ struct komeda_dev *dev_to_mdev(struct device *dev)
return mdrv ? mdrv->mdev : NULL;
}
-static void komeda_unbind(struct device *dev)
+static void komeda_platform_remove(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct komeda_drv *mdrv = dev_get_drvdata(dev);
- if (!mdrv)
- return;
-
komeda_kms_detach(mdrv->kms);
if (pm_runtime_enabled(dev))
@@ -45,11 +45,24 @@ static void komeda_unbind(struct device *dev)
devm_kfree(dev, mdrv);
}
-static int komeda_bind(struct device *dev)
+static void komeda_platform_shutdown(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct komeda_drv *mdrv = dev_get_drvdata(dev);
+
+ komeda_kms_shutdown(mdrv->kms);
+}
+
+static int komeda_platform_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct komeda_drv *mdrv;
int err;
+ err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
+ if (err)
+ return dev_err_probe(dev, err, "DMA mask error\n");
+
mdrv = devm_kzalloc(dev, sizeof(*mdrv), GFP_KERNEL);
if (!mdrv)
return -ENOMEM;
@@ -71,6 +84,7 @@ static int komeda_bind(struct device *dev)
}
dev_set_drvdata(dev, mdrv);
+ drm_client_setup(&mdrv->kms->base, NULL);
return 0;
@@ -87,57 +101,6 @@ free_mdrv:
return err;
}
-static const struct component_master_ops komeda_master_ops = {
- .bind = komeda_bind,
- .unbind = komeda_unbind,
-};
-
-static int compare_of(struct device *dev, void *data)
-{
- return dev->of_node == data;
-}
-
-static void komeda_add_slave(struct device *master,
- struct component_match **match,
- struct device_node *np,
- u32 port, u32 endpoint)
-{
- struct device_node *remote;
-
- remote = of_graph_get_remote_node(np, port, endpoint);
- if (remote) {
- drm_of_component_match_add(master, match, compare_of, remote);
- of_node_put(remote);
- }
-}
-
-static int komeda_platform_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct component_match *match = NULL;
- struct device_node *child;
-
- if (!dev->of_node)
- return -ENODEV;
-
- for_each_available_child_of_node(dev->of_node, child) {
- if (of_node_cmp(child->name, "pipeline") != 0)
- continue;
-
- /* add connector */
- komeda_add_slave(dev, &match, child, KOMEDA_OF_PORT_OUTPUT, 0);
- komeda_add_slave(dev, &match, child, KOMEDA_OF_PORT_OUTPUT, 1);
- }
-
- return component_master_add_with_match(dev, &komeda_master_ops, match);
-}
-
-static int komeda_platform_remove(struct platform_device *pdev)
-{
- component_master_del(&pdev->dev, &komeda_master_ops);
- return 0;
-}
-
static const struct of_device_id komeda_of_match[] = {
{ .compatible = "arm,mali-d71", .data = d71_identify, },
{ .compatible = "arm,mali-d32", .data = d71_identify, },
@@ -190,7 +153,8 @@ static const struct dev_pm_ops komeda_pm_ops = {
static struct platform_driver komeda_platform_driver = {
.probe = komeda_platform_probe,
- .remove = komeda_platform_remove,
+ .remove = komeda_platform_remove,
+ .shutdown = komeda_platform_shutdown,
.driver = {
.name = "komeda",
.of_match_table = komeda_of_match,
@@ -198,7 +162,7 @@ static struct platform_driver komeda_platform_driver = {
},
};
-module_platform_driver(komeda_platform_driver);
+drm_module_platform_driver(komeda_platform_driver);
MODULE_AUTHOR("James.Qian.Wang <james.qian.wang@arm.com>");
MODULE_DESCRIPTION("Komeda KMS driver");
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 3c372d2deb0a..3ca461eb0a24 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -5,10 +5,11 @@
*
*/
#include <drm/drm_device.h>
-#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_gem.h>
-#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_print.h>
#include "komeda_framebuffer.h"
#include "komeda_dev.h"
@@ -137,7 +138,7 @@ komeda_fb_none_afbc_size_check(struct komeda_dev *mdev, struct komeda_fb *kfb,
}
min_size = komeda_fb_get_pixel_addr(kfb, 0, fb->height, i)
- - to_drm_gem_cma_obj(obj)->paddr;
+ - to_drm_gem_dma_obj(obj)->dma_addr;
if (obj->size < min_size) {
DRM_DEBUG_KMS("The fb->obj[%d] size: 0x%zx lower than the minimum requirement: 0x%llx.\n",
i, obj->size, min_size);
@@ -157,6 +158,7 @@ komeda_fb_none_afbc_size_check(struct komeda_dev *mdev, struct komeda_fb *kfb,
struct drm_framebuffer *
komeda_fb_create(struct drm_device *dev, struct drm_file *file,
+ const struct drm_format_info *info,
const struct drm_mode_fb_cmd2 *mode_cmd)
{
struct komeda_dev *mdev = dev->dev_private;
@@ -177,7 +179,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file *file,
return ERR_PTR(-EINVAL);
}
- drm_helper_mode_fill_fb_struct(dev, &kfb->base, mode_cmd);
+ drm_helper_mode_fill_fb_struct(dev, &kfb->base, info, mode_cmd);
if (kfb->base.modifier)
ret = komeda_fb_afbc_size_check(kfb, file, mode_cmd);
@@ -239,7 +241,7 @@ dma_addr_t
komeda_fb_get_pixel_addr(struct komeda_fb *kfb, int x, int y, int plane)
{
struct drm_framebuffer *fb = &kfb->base;
- const struct drm_gem_cma_object *obj;
+ const struct drm_gem_dma_object *obj;
u32 offset, plane_x, plane_y, block_w, block_sz;
if (plane >= fb->format->num_planes) {
@@ -247,7 +249,7 @@ komeda_fb_get_pixel_addr(struct komeda_fb *kfb, int x, int y, int plane)
return -EINVAL;
}
- obj = drm_fb_cma_get_gem_obj(fb, plane);
+ obj = drm_fb_dma_get_gem_obj(fb, plane);
offset = fb->offsets[plane];
if (!fb->modifier) {
@@ -260,7 +262,7 @@ komeda_fb_get_pixel_addr(struct komeda_fb *kfb, int x, int y, int plane)
+ plane_y * fb->pitches[plane];
}
- return obj->paddr + offset;
+ return obj->dma_addr + offset;
}
/* if the fb can be supported by a specific layer */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h
index c61ca98a3a63..02b2b8ae482a 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h
@@ -37,6 +37,7 @@ struct komeda_fb {
struct drm_framebuffer *
komeda_fb_create(struct drm_device *dev, struct drm_file *file,
+ const struct drm_format_info *info,
const struct drm_mode_fb_cmd2 *mode_cmd);
int komeda_fb_check_src_coords(const struct komeda_fb *kfb,
u32 src_x, u32 src_y, u32 src_w, u32 src_h);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
index ff45f23f3d56..6ed504099188 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
@@ -4,16 +4,14 @@
* Author: James.Qian.Wang <james.qian.wang@arm.com>
*
*/
-#include <linux/component.h>
#include <linux/interrupt.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fb_helper.h>
-#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fbdev_dma.h>
+#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
-#include <drm/drm_irq.h>
#include <drm/drm_managed.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
@@ -22,9 +20,9 @@
#include "komeda_framebuffer.h"
#include "komeda_kms.h"
-DEFINE_DRM_GEM_CMA_FOPS(komeda_cma_fops);
+DEFINE_DRM_GEM_DMA_FOPS(komeda_cma_fops);
-static int komeda_gem_cma_dumb_create(struct drm_file *file,
+static int komeda_gem_dma_dumb_create(struct drm_file *file,
struct drm_device *dev,
struct drm_mode_create_dumb *args)
{
@@ -33,7 +31,7 @@ static int komeda_gem_cma_dumb_create(struct drm_file *file,
args->pitch = ALIGN(pitch, mdev->chip.bus_width);
- return drm_gem_cma_dumb_create_internal(file, dev, args);
+ return drm_gem_dma_dumb_create_internal(file, dev, args);
}
static irqreturn_t komeda_kms_irq_handler(int irq, void *data)
@@ -60,16 +58,34 @@ static irqreturn_t komeda_kms_irq_handler(int irq, void *data)
static const struct drm_driver komeda_kms_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
- .lastclose = drm_fb_helper_lastclose,
- DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(komeda_gem_cma_dumb_create),
+ DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(komeda_gem_dma_dumb_create),
+ DRM_FBDEV_DMA_DRIVER_OPS,
.fops = &komeda_cma_fops,
.name = "komeda",
.desc = "Arm Komeda Display Processor driver",
- .date = "20181101",
.major = 0,
.minor = 1,
};
+static void komeda_kms_atomic_commit_hw_done(struct drm_atomic_state *state)
+{
+ struct drm_device *dev = state->dev;
+ struct komeda_kms_dev *kms = to_kdev(dev);
+ int i;
+
+ for (i = 0; i < kms->n_crtcs; i++) {
+ struct komeda_crtc *kcrtc = &kms->crtcs[i];
+
+ if (kcrtc->base.state->active) {
+ struct completion *flip_done = NULL;
+ if (kcrtc->base.state->event)
+ flip_done = kcrtc->base.state->event->base.completion;
+ komeda_crtc_flush_and_wait_for_flip_done(kcrtc, flip_done);
+ }
+ }
+ drm_atomic_helper_commit_hw_done(state);
+}
+
static void komeda_kms_commit_tail(struct drm_atomic_state *old_state)
{
struct drm_device *dev = old_state->dev;
@@ -82,7 +98,7 @@ static void komeda_kms_commit_tail(struct drm_atomic_state *old_state)
drm_atomic_helper_commit_modeset_enables(dev, old_state);
- drm_atomic_helper_commit_hw_done(old_state);
+ komeda_kms_atomic_commit_hw_done(old_state);
drm_atomic_helper_wait_for_flip_done(dev, old_state);
@@ -145,6 +161,7 @@ static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc,
struct drm_plane *plane;
struct list_head zorder_list;
int order = 0, err;
+ u32 slave_zpos = 0;
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n",
crtc->base.id, crtc->name);
@@ -184,10 +201,13 @@ static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc,
plane_st->zpos, plane_st->normalized_zpos);
/* calculate max slave zorder */
- if (has_bit(drm_plane_index(plane), kcrtc->slave_planes))
+ if (has_bit(drm_plane_index(plane), kcrtc->slave_planes)) {
+ slave_zpos = plane_st->normalized_zpos;
+ if (to_kplane_st(plane_st)->layer_split)
+ slave_zpos++;
kcrtc_st->max_slave_zorder =
- max(plane_st->normalized_zpos,
- kcrtc_st->max_slave_zorder);
+ max(slave_zpos, kcrtc_st->max_slave_zorder);
+ }
}
crtc_st->zpos_changed = true;
@@ -289,19 +309,13 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
if (err)
goto cleanup_mode_config;
- err = component_bind_all(mdev->dev, kms);
- if (err)
- goto cleanup_mode_config;
-
drm_mode_config_reset(drm);
err = devm_request_irq(drm->dev, mdev->irq,
komeda_kms_irq_handler, IRQF_SHARED,
drm->driver->name, drm);
if (err)
- goto free_component_binding;
-
- drm->irq_enabled = true;
+ goto cleanup_mode_config;
drm_kms_helper_poll_init(drm);
@@ -313,9 +327,6 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
free_interrupts:
drm_kms_helper_poll_fini(drm);
- drm->irq_enabled = false;
-free_component_binding:
- component_unbind_all(mdev->dev, drm);
cleanup_mode_config:
drm_mode_config_cleanup(drm);
komeda_kms_cleanup_private_objs(kms);
@@ -326,14 +337,18 @@ cleanup_mode_config:
void komeda_kms_detach(struct komeda_kms_dev *kms)
{
struct drm_device *drm = &kms->base;
- struct komeda_dev *mdev = drm->dev_private;
drm_dev_unregister(drm);
drm_kms_helper_poll_fini(drm);
drm_atomic_helper_shutdown(drm);
- drm->irq_enabled = false;
- component_unbind_all(mdev->dev, drm);
drm_mode_config_cleanup(drm);
komeda_kms_cleanup_private_objs(kms);
drm->dev_private = NULL;
}
+
+void komeda_kms_shutdown(struct komeda_kms_dev *kms)
+{
+ struct drm_device *drm = &kms->base;
+
+ drm_atomic_helper_shutdown(drm);
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index 456f3c435719..83e61c4080c2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -10,7 +10,7 @@
#include <linux/list.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
-#include <drm/drm_crtc_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_device.h>
#include <drm/drm_writeback.h>
#include <drm/drm_print.h>
@@ -84,6 +84,9 @@ struct komeda_crtc {
/** @disable_done: this flip_done is for tracing the disable */
struct completion *disable_done;
+
+ /** @encoder: encoder at the end of the pipeline */
+ struct drm_encoder encoder;
};
/**
@@ -182,8 +185,12 @@ void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms);
void komeda_crtc_handle_event(struct komeda_crtc *kcrtc,
struct komeda_events *evts);
+void komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
+ struct completion *input_flip_done);
struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev);
void komeda_kms_detach(struct komeda_kms_dev *kms);
+void komeda_kms_shutdown(struct komeda_kms_dev *kms);
+void komeda_pipeline_dump(struct komeda_pipeline *pipe);
#endif /*_KOMEDA_KMS_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
index 06c595378dda..81e244f0c0ca 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
@@ -4,9 +4,13 @@
* Author: James.Qian.Wang <james.qian.wang@arm.com>
*
*/
+#include <linux/of.h>
+#include <linux/seq_file.h>
+
#include <drm/drm_print.h>
#include "komeda_dev.h"
+#include "komeda_kms.h"
#include "komeda_pipeline.h"
/** komeda_pipeline_add - Add a pipeline to &komeda_dev */
@@ -244,7 +248,7 @@ static void komeda_component_dump(struct komeda_component *c)
c->max_active_outputs, c->supported_outputs);
}
-static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
+void komeda_pipeline_dump(struct komeda_pipeline *pipe)
{
struct komeda_component *c;
int id;
@@ -348,7 +352,6 @@ int komeda_assemble_pipelines(struct komeda_dev *mdev)
pipe = mdev->pipelines[i];
komeda_pipeline_assemble(pipe);
- komeda_pipeline_dump(pipe);
}
return 0;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index e672b9cffee3..f4e76b46ca32 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -259,7 +259,7 @@ komeda_component_get_avail_scaler(struct komeda_component *c,
u32 avail_scalers;
pipe_st = komeda_pipeline_get_state(c->pipeline, state);
- if (!pipe_st)
+ if (IS_ERR_OR_NULL(pipe_st))
return NULL;
avail_scalers = (pipe_st->active_comps & KOMEDA_PIPELINE_SCALERS) ^
@@ -305,12 +305,12 @@ komeda_layer_check_cfg(struct komeda_layer *layer,
if (komeda_fb_check_src_coords(kfb, src_x, src_y, src_w, src_h))
return -EINVAL;
- if (!in_range(&layer->hsize_in, src_w)) {
+ if (!malidp_in_range(&layer->hsize_in, src_w)) {
DRM_DEBUG_ATOMIC("invalidate src_w %d.\n", src_w);
return -EINVAL;
}
- if (!in_range(&layer->vsize_in, src_h)) {
+ if (!malidp_in_range(&layer->vsize_in, src_h)) {
DRM_DEBUG_ATOMIC("invalidate src_h %d.\n", src_h);
return -EINVAL;
}
@@ -452,14 +452,14 @@ komeda_scaler_check_cfg(struct komeda_scaler *scaler,
hsize_out = dflow->out_w;
vsize_out = dflow->out_h;
- if (!in_range(&scaler->hsize, hsize_in) ||
- !in_range(&scaler->hsize, hsize_out)) {
+ if (!malidp_in_range(&scaler->hsize, hsize_in) ||
+ !malidp_in_range(&scaler->hsize, hsize_out)) {
DRM_DEBUG_ATOMIC("Invalid horizontal sizes");
return -EINVAL;
}
- if (!in_range(&scaler->vsize, vsize_in) ||
- !in_range(&scaler->vsize, vsize_out)) {
+ if (!malidp_in_range(&scaler->vsize, vsize_in) ||
+ !malidp_in_range(&scaler->vsize, vsize_out)) {
DRM_DEBUG_ATOMIC("Invalid vertical sizes");
return -EINVAL;
}
@@ -574,13 +574,13 @@ komeda_splitter_validate(struct komeda_splitter *splitter,
return -EINVAL;
}
- if (!in_range(&splitter->hsize, dflow->in_w)) {
+ if (!malidp_in_range(&splitter->hsize, dflow->in_w)) {
DRM_DEBUG_ATOMIC("split in_w:%d is out of the acceptable range.\n",
dflow->in_w);
return -EINVAL;
}
- if (!in_range(&splitter->vsize, dflow->in_h)) {
+ if (!malidp_in_range(&splitter->vsize, dflow->in_h)) {
DRM_DEBUG_ATOMIC("split in_h: %d exceeds the acceptable range.\n",
dflow->in_h);
return -EINVAL;
@@ -624,13 +624,13 @@ komeda_merger_validate(struct komeda_merger *merger,
return -EINVAL;
}
- if (!in_range(&merger->hsize_merged, output->out_w)) {
+ if (!malidp_in_range(&merger->hsize_merged, output->out_w)) {
DRM_DEBUG_ATOMIC("merged_w: %d is out of the accepted range.\n",
output->out_w);
return -EINVAL;
}
- if (!in_range(&merger->vsize_merged, output->out_h)) {
+ if (!malidp_in_range(&merger->vsize_merged, output->out_h)) {
DRM_DEBUG_ATOMIC("merged_h: %d is out of the accepted range.\n",
output->out_h);
return -EINVAL;
@@ -866,8 +866,8 @@ void komeda_complete_data_flow_cfg(struct komeda_layer *layer,
* input/output range.
*/
if (dflow->en_scaling && scaler)
- dflow->en_split = !in_range(&scaler->hsize, dflow->in_w) ||
- !in_range(&scaler->hsize, dflow->out_w);
+ dflow->en_split = !malidp_in_range(&scaler->hsize, dflow->in_w) ||
+ !malidp_in_range(&scaler->hsize, dflow->out_w);
}
static bool merger_is_available(struct komeda_pipeline *pipe,
@@ -1223,7 +1223,7 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
return 0;
}
-static void
+static int
komeda_pipeline_unbound_components(struct komeda_pipeline *pipe,
struct komeda_pipeline_state *new)
{
@@ -1243,8 +1243,12 @@ komeda_pipeline_unbound_components(struct komeda_pipeline *pipe,
c = komeda_pipeline_get_component(pipe, id);
c_st = komeda_component_get_state_and_set_user(c,
drm_st, NULL, new->crtc);
+ if (PTR_ERR(c_st) == -EDEADLK)
+ return -EDEADLK;
WARN_ON(IS_ERR(c_st));
}
+
+ return 0;
}
/* release unclaimed pipeline resource */
@@ -1266,12 +1270,11 @@ int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
if (WARN_ON(IS_ERR_OR_NULL(st)))
return -EINVAL;
- komeda_pipeline_unbound_components(pipe, st);
+ return komeda_pipeline_unbound_components(pipe, st);
- return 0;
}
-/* Since standalong disabled components must be disabled separately and in the
+/* Since standalone disabled components must be disabled separately and in the
* last, So a complete disable operation may needs to call pipeline_disable
* twice (two phase disabling).
* Phase 1: disable the common components, flush it.
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index d63d83800a8a..c20ff72f0ae5 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -6,7 +6,7 @@
*/
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
-#include <drm/drm_plane_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_print.h>
#include "komeda_dev.h"
#include "komeda_kms.h"
@@ -135,7 +135,6 @@ static void komeda_plane_destroy(struct drm_plane *plane)
static void komeda_plane_reset(struct drm_plane *plane)
{
struct komeda_plane_state *state;
- struct komeda_plane *kplane = to_kplane(plane);
if (plane->state)
__drm_atomic_helper_plane_destroy_state(plane->state);
@@ -144,16 +143,8 @@ static void komeda_plane_reset(struct drm_plane *plane)
plane->state = NULL;
state = kzalloc(sizeof(*state), GFP_KERNEL);
- if (state) {
- state->base.rotation = DRM_MODE_ROTATE_0;
- state->base.pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
- state->base.alpha = DRM_BLEND_ALPHA_OPAQUE;
- state->base.zpos = kplane->layer->base.id;
- state->base.color_encoding = DRM_COLOR_YCBCR_BT601;
- state->base.color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
- plane->state = &state->base;
- plane->state->plane = plane;
- }
+ if (state)
+ __drm_atomic_helper_plane_reset(plane, &state->base);
}
static struct drm_plane_state *
@@ -265,6 +256,10 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl,
layer->layer_type, &n_formats);
+ if (!formats) {
+ kfree(kplane);
+ return -ENOMEM;
+ }
err = drm_universal_plane_init(&kms->base, plane,
get_possible_crtcs(kms, c->pipeline),
@@ -275,8 +270,10 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
komeda_put_fourcc_list(formats);
- if (err)
- goto cleanup;
+ if (err) {
+ kfree(kplane);
+ return err;
+ }
drm_plane_helper_add(plane, &komeda_plane_helper_funcs);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index e465cc4879c9..875cdbff18c9 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -4,6 +4,7 @@
* Author: James.Qian.Wang <james.qian.wang@arm.com>
*
*/
+#include <drm/drm_framebuffer.h>
#include "komeda_dev.h"
#include "komeda_kms.h"
@@ -87,7 +88,7 @@ komeda_wb_connector_get_modes(struct drm_connector *connector)
static enum drm_mode_status
komeda_wb_connector_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
+ const struct drm_display_mode *mode)
{
struct drm_device *dev = connector->dev;
struct drm_mode_config *mode_config = &dev->mode_config;
@@ -155,16 +156,20 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms,
kwb_conn->wb_layer = kcrtc->master->wb_layer;
wb_conn = &kwb_conn->base;
- wb_conn->encoder.possible_crtcs = BIT(drm_crtc_index(&kcrtc->base));
formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl,
kwb_conn->wb_layer->layer_type,
&n_formats);
+ if (!formats) {
+ kfree(kwb_conn);
+ return -ENOMEM;
+ }
err = drm_writeback_connector_init(&kms->base, wb_conn,
&komeda_wb_connector_funcs,
&komeda_wb_encoder_helper_funcs,
- formats, n_formats);
+ formats, n_formats,
+ BIT(drm_crtc_index(&kcrtc->base)));
komeda_put_fourcc_list(formats);
if (err) {
kfree(kwb_conn);
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index 7adb065169e9..4b4a08cb396d 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -11,18 +11,18 @@
#include <linux/clk.h>
#include <linux/of_graph.h>
-#include <linux/platform_data/simplefb.h>
+#include <video/pixel_format.h>
#include <video/videomode.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
-#include <drm/drm_fb_cma_helper.h>
-#include <drm/drm_fb_helper.h>
-#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fb_dma_helper.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_of.h>
-#include <drm/drm_plane_helper.h>
+#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
@@ -74,7 +74,17 @@ static const struct drm_crtc_funcs hdlcd_crtc_funcs = {
.disable_vblank = hdlcd_crtc_disable_vblank,
};
-static struct simplefb_format supported_formats[] = SIMPLEFB_FORMATS;
+static const struct {
+ u32 fourcc;
+ struct pixel_format pixel;
+} supported_formats[] = {
+ { DRM_FORMAT_RGB565, PIXEL_FORMAT_RGB565 },
+ { DRM_FORMAT_XRGB1555, PIXEL_FORMAT_XRGB1555 },
+ { DRM_FORMAT_RGB888, PIXEL_FORMAT_RGB888 },
+ { DRM_FORMAT_XRGB8888, PIXEL_FORMAT_XRGB8888 },
+ { DRM_FORMAT_XBGR8888, PIXEL_FORMAT_XBGR8888 },
+ { DRM_FORMAT_XRGB2101010, PIXEL_FORMAT_XRGB2101010},
+};
/*
* Setup the HDLCD registers for decoding the pixels out of the framebuffer
@@ -84,15 +94,12 @@ static int hdlcd_set_pxl_fmt(struct drm_crtc *crtc)
unsigned int btpp;
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
const struct drm_framebuffer *fb = crtc->primary->state->fb;
- uint32_t pixel_format;
- struct simplefb_format *format = NULL;
+ const struct pixel_format *format = NULL;
int i;
- pixel_format = fb->format->format;
-
for (i = 0; i < ARRAY_SIZE(supported_formats); i++) {
- if (supported_formats[i].fourcc == pixel_format)
- format = &supported_formats[i];
+ if (supported_formats[i].fourcc == fb->format->format)
+ format = &supported_formats[i].pixel;
}
if (WARN_ON(!format))
@@ -251,8 +258,8 @@ static int hdlcd_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
return drm_atomic_helper_check_plane_state(new_plane_state,
crtc_state,
- DRM_PLANE_HELPER_NO_SCALING,
- DRM_PLANE_HELPER_NO_SCALING,
+ DRM_PLANE_NO_SCALING,
+ DRM_PLANE_NO_SCALING,
false, true);
}
@@ -273,9 +280,9 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane,
return;
dest_h = drm_rect_height(&new_plane_state->dst);
- scanout_start = drm_fb_cma_get_gem_addr(fb, new_plane_state, 0);
+ scanout_start = drm_fb_dma_get_gem_addr(fb, new_plane_state, 0);
- hdlcd = plane->dev->dev_private;
+ hdlcd = drm_to_hdlcd_priv(plane->dev);
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, fb->pitches[0]);
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, fb->pitches[0]);
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, dest_h - 1);
@@ -290,7 +297,6 @@ static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = {
static const struct drm_plane_funcs hdlcd_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
- .destroy = drm_plane_cleanup,
.reset = drm_atomic_helper_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -298,24 +304,19 @@ static const struct drm_plane_funcs hdlcd_plane_funcs = {
static struct drm_plane *hdlcd_plane_init(struct drm_device *drm)
{
- struct hdlcd_drm_private *hdlcd = drm->dev_private;
+ struct hdlcd_drm_private *hdlcd = drm_to_hdlcd_priv(drm);
struct drm_plane *plane = NULL;
u32 formats[ARRAY_SIZE(supported_formats)], i;
- int ret;
-
- plane = devm_kzalloc(drm->dev, sizeof(*plane), GFP_KERNEL);
- if (!plane)
- return ERR_PTR(-ENOMEM);
for (i = 0; i < ARRAY_SIZE(supported_formats); i++)
formats[i] = supported_formats[i].fourcc;
- ret = drm_universal_plane_init(drm, plane, 0xff, &hdlcd_plane_funcs,
- formats, ARRAY_SIZE(formats),
- NULL,
- DRM_PLANE_TYPE_PRIMARY, NULL);
- if (ret)
- return ERR_PTR(ret);
+ plane = drmm_universal_plane_alloc(drm, struct drm_plane, dev, 0xff,
+ &hdlcd_plane_funcs,
+ formats, ARRAY_SIZE(formats),
+ NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
+ if (IS_ERR(plane))
+ return plane;
drm_plane_helper_add(plane, &hdlcd_plane_helper_funcs);
hdlcd->plane = plane;
@@ -325,7 +326,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm)
int hdlcd_setup_crtc(struct drm_device *drm)
{
- struct hdlcd_drm_private *hdlcd = drm->dev_private;
+ struct hdlcd_drm_private *hdlcd = drm_to_hdlcd_priv(drm);
struct drm_plane *primary;
int ret;
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 81ae92390736..81d45f2dd6a7 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -9,6 +9,7 @@
* ARM HDLCD Driver
*/
+#include <linux/aperture.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/clk.h>
@@ -21,28 +22,86 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <drm/clients/drm_client_setup.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_debugfs.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fb_cma_helper.h>
-#include <drm/drm_fb_helper.h>
-#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fbdev_dma.h>
+#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
-#include <drm/drm_irq.h>
#include <drm/drm_modeset_helper.h>
+#include <drm/drm_module.h>
#include <drm/drm_of.h>
+#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
#include "hdlcd_drv.h"
#include "hdlcd_regs.h"
+static irqreturn_t hdlcd_irq(int irq, void *arg)
+{
+ struct hdlcd_drm_private *hdlcd = arg;
+ unsigned long irq_status;
+
+ irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
+
+#ifdef CONFIG_DEBUG_FS
+ if (irq_status & HDLCD_INTERRUPT_UNDERRUN)
+ atomic_inc(&hdlcd->buffer_underrun_count);
+
+ if (irq_status & HDLCD_INTERRUPT_DMA_END)
+ atomic_inc(&hdlcd->dma_end_count);
+
+ if (irq_status & HDLCD_INTERRUPT_BUS_ERROR)
+ atomic_inc(&hdlcd->bus_error_count);
+
+ if (irq_status & HDLCD_INTERRUPT_VSYNC)
+ atomic_inc(&hdlcd->vsync_count);
+
+#endif
+ if (irq_status & HDLCD_INTERRUPT_VSYNC)
+ drm_crtc_handle_vblank(&hdlcd->crtc);
+
+ /* acknowledge interrupt(s) */
+ hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
+
+ return IRQ_HANDLED;
+}
+
+static int hdlcd_irq_install(struct hdlcd_drm_private *hdlcd)
+{
+ int ret;
+
+ /* Ensure interrupts are disabled */
+ hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);
+ hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0);
+
+ ret = request_irq(hdlcd->irq, hdlcd_irq, 0, "hdlcd", hdlcd);
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_DEBUG_FS
+ /* enable debug interrupts */
+ hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, HDLCD_DEBUG_INT_MASK);
+#endif
+
+ return 0;
+}
+
+static void hdlcd_irq_uninstall(struct hdlcd_drm_private *hdlcd)
+{
+ /* disable all the interrupts that we might have enabled */
+ hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);
+
+ free_irq(hdlcd->irq, hdlcd);
+}
+
static int hdlcd_load(struct drm_device *drm, unsigned long flags)
{
- struct hdlcd_drm_private *hdlcd = drm->dev_private;
+ struct hdlcd_drm_private *hdlcd = drm_to_hdlcd_priv(drm);
struct platform_device *pdev = to_platform_device(drm->dev);
- struct resource *res;
u32 version;
int ret;
@@ -57,8 +116,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
atomic_set(&hdlcd->dma_end_count, 0);
#endif
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- hdlcd->mmio = devm_ioremap_resource(drm->dev, res);
+ hdlcd->mmio = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(hdlcd->mmio)) {
DRM_ERROR("failed to map control registers area\n");
ret = PTR_ERR(hdlcd->mmio);
@@ -90,7 +148,12 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
goto setup_fail;
}
- ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0)
+ goto irq_fail;
+ hdlcd->irq = ret;
+
+ ret = hdlcd_irq_install(hdlcd);
if (ret < 0) {
DRM_ERROR("failed to install IRQ handler\n");
goto irq_fail;
@@ -112,92 +175,29 @@ static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = {
.atomic_commit = drm_atomic_helper_commit,
};
-static void hdlcd_setup_mode_config(struct drm_device *drm)
+static int hdlcd_setup_mode_config(struct drm_device *drm)
{
- drm_mode_config_init(drm);
+ int ret;
+
+ ret = drmm_mode_config_init(drm);
+ if (ret)
+ return ret;
+
drm->mode_config.min_width = 0;
drm->mode_config.min_height = 0;
drm->mode_config.max_width = HDLCD_MAX_XRES;
drm->mode_config.max_height = HDLCD_MAX_YRES;
drm->mode_config.funcs = &hdlcd_mode_config_funcs;
-}
-
-static irqreturn_t hdlcd_irq(int irq, void *arg)
-{
- struct drm_device *drm = arg;
- struct hdlcd_drm_private *hdlcd = drm->dev_private;
- unsigned long irq_status;
- irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
-
-#ifdef CONFIG_DEBUG_FS
- if (irq_status & HDLCD_INTERRUPT_UNDERRUN)
- atomic_inc(&hdlcd->buffer_underrun_count);
-
- if (irq_status & HDLCD_INTERRUPT_DMA_END)
- atomic_inc(&hdlcd->dma_end_count);
-
- if (irq_status & HDLCD_INTERRUPT_BUS_ERROR)
- atomic_inc(&hdlcd->bus_error_count);
-
- if (irq_status & HDLCD_INTERRUPT_VSYNC)
- atomic_inc(&hdlcd->vsync_count);
-
-#endif
- if (irq_status & HDLCD_INTERRUPT_VSYNC)
- drm_crtc_handle_vblank(&hdlcd->crtc);
-
- /* acknowledge interrupt(s) */
- hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
-
- return IRQ_HANDLED;
-}
-
-static void hdlcd_irq_preinstall(struct drm_device *drm)
-{
- struct hdlcd_drm_private *hdlcd = drm->dev_private;
- /* Ensure interrupts are disabled */
- hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);
- hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0);
-}
-
-static int hdlcd_irq_postinstall(struct drm_device *drm)
-{
-#ifdef CONFIG_DEBUG_FS
- struct hdlcd_drm_private *hdlcd = drm->dev_private;
- unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
-
- /* enable debug interrupts */
- irq_mask |= HDLCD_DEBUG_INT_MASK;
-
- hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
-#endif
return 0;
}
-static void hdlcd_irq_uninstall(struct drm_device *drm)
-{
- struct hdlcd_drm_private *hdlcd = drm->dev_private;
- /* disable all the interrupts that we might have enabled */
- unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
-
-#ifdef CONFIG_DEBUG_FS
- /* disable debug interrupts */
- irq_mask &= ~HDLCD_DEBUG_INT_MASK;
-#endif
-
- /* disable vsync interrupts */
- irq_mask &= ~HDLCD_INTERRUPT_VSYNC;
-
- hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
-}
-
#ifdef CONFIG_DEBUG_FS
static int hdlcd_show_underrun_count(struct seq_file *m, void *arg)
{
- struct drm_info_node *node = (struct drm_info_node *)m->private;
- struct drm_device *drm = node->minor->dev;
- struct hdlcd_drm_private *hdlcd = drm->dev_private;
+ struct drm_debugfs_entry *entry = m->private;
+ struct drm_device *drm = entry->dev;
+ struct hdlcd_drm_private *hdlcd = drm_to_hdlcd_priv(drm);
seq_printf(m, "underrun : %d\n", atomic_read(&hdlcd->buffer_underrun_count));
seq_printf(m, "dma_end : %d\n", atomic_read(&hdlcd->dma_end_count));
@@ -208,9 +208,9 @@ static int hdlcd_show_underrun_count(struct seq_file *m, void *arg)
static int hdlcd_show_pxlclock(struct seq_file *m, void *arg)
{
- struct drm_info_node *node = (struct drm_info_node *)m->private;
- struct drm_device *drm = node->minor->dev;
- struct hdlcd_drm_private *hdlcd = drm->dev_private;
+ struct drm_debugfs_entry *entry = m->private;
+ struct drm_device *drm = entry->dev;
+ struct hdlcd_drm_private *hdlcd = drm_to_hdlcd_priv(drm);
unsigned long clkrate = clk_get_rate(hdlcd->clk);
unsigned long mode_clock = hdlcd->crtc.mode.crtc_clock * 1000;
@@ -219,35 +219,21 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void *arg)
return 0;
}
-static struct drm_info_list hdlcd_debugfs_list[] = {
+static struct drm_debugfs_info hdlcd_debugfs_list[] = {
{ "interrupt_count", hdlcd_show_underrun_count, 0 },
{ "clocks", hdlcd_show_pxlclock, 0 },
};
-
-static void hdlcd_debugfs_init(struct drm_minor *minor)
-{
- drm_debugfs_create_files(hdlcd_debugfs_list,
- ARRAY_SIZE(hdlcd_debugfs_list),
- minor->debugfs_root, minor);
-}
#endif
-DEFINE_DRM_GEM_CMA_FOPS(fops);
+DEFINE_DRM_GEM_DMA_FOPS(fops);
static const struct drm_driver hdlcd_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
- .irq_handler = hdlcd_irq,
- .irq_preinstall = hdlcd_irq_preinstall,
- .irq_postinstall = hdlcd_irq_postinstall,
- .irq_uninstall = hdlcd_irq_uninstall,
- DRM_GEM_CMA_DRIVER_OPS,
-#ifdef CONFIG_DEBUG_FS
- .debugfs_init = hdlcd_debugfs_init,
-#endif
+ DRM_GEM_DMA_DRIVER_OPS,
+ DRM_FBDEV_DMA_DRIVER_OPS,
.fops = &fops,
.name = "hdlcd",
.desc = "ARM HDLCD Controller DRM",
- .date = "20151021",
.major = 1,
.minor = 0,
};
@@ -258,18 +244,18 @@ static int hdlcd_drm_bind(struct device *dev)
struct hdlcd_drm_private *hdlcd;
int ret;
- hdlcd = devm_kzalloc(dev, sizeof(*hdlcd), GFP_KERNEL);
- if (!hdlcd)
- return -ENOMEM;
+ hdlcd = devm_drm_dev_alloc(dev, &hdlcd_driver, typeof(*hdlcd), base);
+ if (IS_ERR(hdlcd))
+ return PTR_ERR(hdlcd);
- drm = drm_dev_alloc(&hdlcd_driver, dev);
- if (IS_ERR(drm))
- return PTR_ERR(drm);
+ drm = &hdlcd->base;
- drm->dev_private = hdlcd;
dev_set_drvdata(dev, drm);
- hdlcd_setup_mode_config(drm);
+ ret = hdlcd_setup_mode_config(drm);
+ if (ret)
+ goto err_free;
+
ret = hdlcd_load(drm, 0);
if (ret)
goto err_free;
@@ -295,14 +281,27 @@ static int hdlcd_drm_bind(struct device *dev)
goto err_vblank;
}
+ /*
+ * If EFI left us running, take over from simple framebuffer
+ * drivers. Read HDLCD_REG_COMMAND to see if we are enabled.
+ */
+ if (hdlcd_read(hdlcd, HDLCD_REG_COMMAND)) {
+ hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
+ aperture_remove_all_conflicting_devices(hdlcd_driver.name);
+ }
+
drm_mode_config_reset(drm);
drm_kms_helper_poll_init(drm);
+#ifdef CONFIG_DEBUG_FS
+ drm_debugfs_add_files(drm, hdlcd_debugfs_list, ARRAY_SIZE(hdlcd_debugfs_list));
+#endif
+
ret = drm_dev_register(drm, 0);
if (ret)
goto err_register;
- drm_fbdev_generic_setup(drm, 32);
+ drm_client_setup(drm, NULL);
return 0;
@@ -316,20 +315,17 @@ err_pm_active:
err_unload:
of_node_put(hdlcd->crtc.port);
hdlcd->crtc.port = NULL;
- drm_irq_uninstall(drm);
+ hdlcd_irq_uninstall(hdlcd);
of_reserved_mem_device_release(drm->dev);
err_free:
- drm_mode_config_cleanup(drm);
dev_set_drvdata(dev, NULL);
- drm_dev_put(drm);
-
return ret;
}
static void hdlcd_drm_unbind(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
- struct hdlcd_drm_private *hdlcd = drm->dev_private;
+ struct hdlcd_drm_private *hdlcd = drm_to_hdlcd_priv(drm);
drm_dev_unregister(drm);
drm_kms_helper_poll_fini(drm);
@@ -338,15 +334,12 @@ static void hdlcd_drm_unbind(struct device *dev)
hdlcd->crtc.port = NULL;
pm_runtime_get_sync(dev);
drm_atomic_helper_shutdown(drm);
- drm_irq_uninstall(drm);
+ hdlcd_irq_uninstall(hdlcd);
pm_runtime_put(dev);
if (pm_runtime_enabled(dev))
pm_runtime_disable(dev);
of_reserved_mem_device_release(dev);
- drm_mode_config_cleanup(drm);
- drm->dev_private = NULL;
dev_set_drvdata(dev, NULL);
- drm_dev_put(drm);
}
static const struct component_master_ops hdlcd_master_ops = {
@@ -376,10 +369,14 @@ static int hdlcd_probe(struct platform_device *pdev)
match);
}
-static int hdlcd_remove(struct platform_device *pdev)
+static void hdlcd_remove(struct platform_device *pdev)
{
component_master_del(&pdev->dev, &hdlcd_master_ops);
- return 0;
+}
+
+static void hdlcd_shutdown(struct platform_device *pdev)
+{
+ drm_atomic_helper_shutdown(platform_get_drvdata(pdev));
}
static const struct of_device_id hdlcd_of_match[] = {
@@ -409,6 +406,7 @@ static SIMPLE_DEV_PM_OPS(hdlcd_pm_ops, hdlcd_pm_suspend, hdlcd_pm_resume);
static struct platform_driver hdlcd_platform_driver = {
.probe = hdlcd_probe,
.remove = hdlcd_remove,
+ .shutdown = hdlcd_shutdown,
.driver = {
.name = "hdlcd",
.pm = &hdlcd_pm_ops,
@@ -416,7 +414,7 @@ static struct platform_driver hdlcd_platform_driver = {
},
};
-module_platform_driver(hdlcd_platform_driver);
+drm_module_platform_driver(hdlcd_platform_driver);
MODULE_AUTHOR("Liviu Dudau");
MODULE_DESCRIPTION("ARM HDLCD DRM driver");
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h
index fd438d177b64..f1c1da2ac2db 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.h
+++ b/drivers/gpu/drm/arm/hdlcd_drv.h
@@ -7,10 +7,12 @@
#define __HDLCD_DRV_H__
struct hdlcd_drm_private {
+ struct drm_device base;
void __iomem *mmio;
struct clk *clk;
struct drm_crtc crtc;
struct drm_plane *plane;
+ unsigned int irq;
#ifdef CONFIG_DEBUG_FS
atomic_t buffer_underrun_count;
atomic_t bus_error_count;
@@ -19,6 +21,7 @@ struct hdlcd_drm_private {
#endif
};
+#define drm_to_hdlcd_priv(x) container_of(x, struct hdlcd_drm_private, base)
#define crtc_to_hdlcd_priv(x) container_of(x, struct hdlcd_drm_private, crtc)
static inline void hdlcd_write(struct hdlcd_drm_private *hdlcd,
diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c
index 494075ddbef6..d72c22dcf685 100644
--- a/drivers/gpu/drm/arm/malidp_crtc.c
+++ b/drivers/gpu/drm/arm/malidp_crtc.c
@@ -14,6 +14,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
+#include <drm/drm_framebuffer.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
@@ -220,7 +221,7 @@ static int malidp_crtc_atomic_check_ctm(struct drm_crtc *crtc,
/*
* The size of the ctm is checked in
- * drm_atomic_replace_property_blob_from_id.
+ * drm_property_replace_blob_from_id.
*/
ctm = (struct drm_color_ctm *)state->ctm->data;
for (i = 0; i < ARRAY_SIZE(ctm->matrix); ++i) {
@@ -487,7 +488,10 @@ static void malidp_crtc_reset(struct drm_crtc *crtc)
if (crtc->state)
malidp_crtc_destroy_state(crtc, crtc->state);
- __drm_atomic_helper_crtc_reset(crtc, &state->base);
+ if (state)
+ __drm_atomic_helper_crtc_reset(crtc, &state->base);
+ else
+ __drm_atomic_helper_crtc_reset(crtc, NULL);
}
static int malidp_crtc_enable_vblank(struct drm_crtc *crtc)
@@ -510,7 +514,6 @@ static void malidp_crtc_disable_vblank(struct drm_crtc *crtc)
}
static const struct drm_crtc_funcs malidp_crtc_funcs = {
- .destroy = drm_crtc_cleanup,
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
.reset = malidp_crtc_reset,
@@ -522,7 +525,7 @@ static const struct drm_crtc_funcs malidp_crtc_funcs = {
int malidp_crtc_init(struct drm_device *drm)
{
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct drm_plane *primary = NULL, *plane;
int ret;
@@ -544,8 +547,8 @@ int malidp_crtc_init(struct drm_device *drm)
return -EINVAL;
}
- ret = drm_crtc_init_with_planes(drm, &malidp->crtc, primary, NULL,
- &malidp_crtc_funcs, NULL);
+ ret = drmm_crtc_init_with_planes(drm, &malidp->crtc, primary, NULL,
+ &malidp_crtc_funcs, NULL);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index de59f3302516..b765f6c9eea4 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -12,20 +12,24 @@
#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/debugfs.h>
+#include <drm/clients/drm_client_setup.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fb_cma_helper.h>
-#include <drm/drm_fb_helper.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_fourcc.h>
-#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
#include <drm/drm_modeset_helper.h>
+#include <drm/drm_module.h>
#include <drm/drm_of.h>
+#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
@@ -168,7 +172,7 @@ static void malidp_atomic_commit_se_config(struct drm_crtc *crtc,
*/
static int malidp_set_and_wait_config_valid(struct drm_device *drm)
{
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
int ret;
@@ -189,7 +193,7 @@ static int malidp_set_and_wait_config_valid(struct drm_device *drm)
static void malidp_atomic_commit_hw_done(struct drm_atomic_state *state)
{
struct drm_device *drm = state->dev;
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
int loop = 5;
malidp->event = malidp->crtc.state->event;
@@ -230,7 +234,7 @@ static void malidp_atomic_commit_hw_done(struct drm_atomic_state *state)
static void malidp_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *drm = state->dev;
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state;
int i;
@@ -303,10 +307,10 @@ malidp_verify_afbc_framebuffer_caps(struct drm_device *dev,
static bool
malidp_verify_afbc_framebuffer_size(struct drm_device *dev,
struct drm_file *file,
+ const struct drm_format_info *info,
const struct drm_mode_fb_cmd2 *mode_cmd)
{
int n_superblocks = 0;
- const struct drm_format_info *info;
struct drm_gem_object *objs = NULL;
u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
u32 afbc_superblock_width = 0, afbc_size = 0;
@@ -322,8 +326,6 @@ malidp_verify_afbc_framebuffer_size(struct drm_device *dev,
return false;
}
- info = drm_get_format_info(dev, mode_cmd);
-
n_superblocks = (mode_cmd->width / afbc_superblock_width) *
(mode_cmd->height / afbc_superblock_height);
@@ -363,24 +365,26 @@ malidp_verify_afbc_framebuffer_size(struct drm_device *dev,
static bool
malidp_verify_afbc_framebuffer(struct drm_device *dev, struct drm_file *file,
+ const struct drm_format_info *info,
const struct drm_mode_fb_cmd2 *mode_cmd)
{
if (malidp_verify_afbc_framebuffer_caps(dev, mode_cmd))
- return malidp_verify_afbc_framebuffer_size(dev, file, mode_cmd);
+ return malidp_verify_afbc_framebuffer_size(dev, file, info, mode_cmd);
return false;
}
static struct drm_framebuffer *
malidp_fb_create(struct drm_device *dev, struct drm_file *file,
+ const struct drm_format_info *info,
const struct drm_mode_fb_cmd2 *mode_cmd)
{
if (mode_cmd->modifier[0]) {
- if (!malidp_verify_afbc_framebuffer(dev, file, mode_cmd))
+ if (!malidp_verify_afbc_framebuffer(dev, file, info, mode_cmd))
return ERR_PTR(-EINVAL);
}
- return drm_gem_fb_create(dev, file, mode_cmd);
+ return drm_gem_fb_create(dev, file, info, mode_cmd);
}
static const struct drm_mode_config_funcs malidp_mode_config_funcs = {
@@ -392,10 +396,12 @@ static const struct drm_mode_config_funcs malidp_mode_config_funcs = {
static int malidp_init(struct drm_device *drm)
{
int ret;
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
- drm_mode_config_init(drm);
+ ret = drmm_mode_config_init(drm);
+ if (ret)
+ goto out;
drm->mode_config.min_width = hwdev->min_line_size;
drm->mode_config.min_height = hwdev->min_line_size;
@@ -406,29 +412,21 @@ static int malidp_init(struct drm_device *drm)
ret = malidp_crtc_init(drm);
if (ret)
- goto crtc_fail;
+ goto out;
ret = malidp_mw_connector_init(drm);
if (ret)
- goto crtc_fail;
-
- return 0;
+ goto out;
-crtc_fail:
- drm_mode_config_cleanup(drm);
+out:
return ret;
}
-static void malidp_fini(struct drm_device *drm)
-{
- drm_mode_config_cleanup(drm);
-}
-
static int malidp_irq_init(struct platform_device *pdev)
{
int irq_de, irq_se, ret = 0;
struct drm_device *drm = dev_get_drvdata(&pdev->dev);
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
/* fetch the interrupts from DT */
@@ -456,19 +454,19 @@ static int malidp_irq_init(struct platform_device *pdev)
return 0;
}
-DEFINE_DRM_GEM_CMA_FOPS(fops);
+DEFINE_DRM_GEM_DMA_FOPS(fops);
static int malidp_dumb_create(struct drm_file *file_priv,
struct drm_device *drm,
struct drm_mode_create_dumb *args)
{
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
/* allocate for the worst case scenario, i.e. rotated buffers */
u8 alignment = malidp_hw_get_pitch_align(malidp->dev, 1);
args->pitch = ALIGN(DIV_ROUND_UP(args->width * args->bpp, 8), alignment);
- return drm_gem_cma_dumb_create_internal(file_priv, drm, args);
+ return drm_gem_dma_dumb_create_internal(file_priv, drm, args);
}
#ifdef CONFIG_DEBUG_FS
@@ -508,7 +506,7 @@ static void malidp_error_stats_dump(const char *prefix,
static int malidp_show_stats(struct seq_file *m, void *arg)
{
struct drm_device *drm = m->private;
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
unsigned long irqflags;
struct malidp_error_stats de_errors, se_errors;
@@ -531,7 +529,7 @@ static ssize_t malidp_debugfs_write(struct file *file, const char __user *ubuf,
{
struct seq_file *m = file->private_data;
struct drm_device *drm = m->private;
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
unsigned long irqflags;
spin_lock_irqsave(&malidp->errors_lock, irqflags);
@@ -552,7 +550,7 @@ static const struct file_operations malidp_debugfs_fops = {
static void malidp_debugfs_init(struct drm_minor *minor)
{
- struct malidp_drm *malidp = minor->dev->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(minor->dev);
malidp_error_stats_init(&malidp->de_errors);
malidp_error_stats_init(&malidp->se_errors);
@@ -565,14 +563,14 @@ static void malidp_debugfs_init(struct drm_minor *minor)
static const struct drm_driver malidp_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
- DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(malidp_dumb_create),
+ DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(malidp_dumb_create),
+ DRM_FBDEV_DMA_DRIVER_OPS,
#ifdef CONFIG_DEBUG_FS
.debugfs_init = malidp_debugfs_init,
#endif
.fops = &fops,
.name = "mali-dp",
.desc = "ARM Mali Display Processor driver",
- .date = "20160106",
.major = 1,
.minor = 0,
};
@@ -652,9 +650,9 @@ static ssize_t core_id_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct drm_device *drm = dev_get_drvdata(dev);
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
- return snprintf(buf, PAGE_SIZE, "%08x\n", malidp->core_id);
+ return sysfs_emit(buf, "%08x\n", malidp->core_id);
}
static DEVICE_ATTR_RO(core_id);
@@ -670,7 +668,7 @@ ATTRIBUTE_GROUPS(mali_dp);
static int malidp_runtime_pm_suspend(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
/* we can only suspend if the hardware is in config mode */
@@ -689,7 +687,7 @@ static int malidp_runtime_pm_suspend(struct device *dev)
static int malidp_runtime_pm_resume(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
clk_prepare_enable(hwdev->pclk);
@@ -716,19 +714,20 @@ static int malidp_bind(struct device *dev)
int ret = 0, i;
u32 version, out_depth = 0;
- malidp = devm_kzalloc(dev, sizeof(*malidp), GFP_KERNEL);
- if (!malidp)
- return -ENOMEM;
+ malidp = devm_drm_dev_alloc(dev, &malidp_driver, typeof(*malidp), base);
+ if (IS_ERR(malidp))
+ return PTR_ERR(malidp);
- hwdev = devm_kzalloc(dev, sizeof(*hwdev), GFP_KERNEL);
+ drm = &malidp->base;
+
+ hwdev = drmm_kzalloc(drm, sizeof(*hwdev), GFP_KERNEL);
if (!hwdev)
return -ENOMEM;
hwdev->hw = (struct malidp_hw *)of_device_get_match_data(dev);
malidp->dev = hwdev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- hwdev->regs = devm_ioremap_resource(dev, res);
+ hwdev->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(hwdev->regs))
return PTR_ERR(hwdev->regs);
@@ -753,13 +752,6 @@ static int malidp_bind(struct device *dev)
if (ret && ret != -ENODEV)
return ret;
- drm = drm_dev_alloc(&malidp_driver, dev);
- if (IS_ERR(drm)) {
- ret = PTR_ERR(drm);
- goto alloc_fail;
- }
-
- drm->dev_private = malidp;
dev_set_drvdata(dev, drm);
/* Enable power management */
@@ -847,8 +839,6 @@ static int malidp_bind(struct device *dev)
if (ret < 0)
goto irq_init_fail;
- drm->irq_enabled = true;
-
ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
if (ret < 0) {
DRM_ERROR("failed to initialise vblank\n");
@@ -864,7 +854,7 @@ static int malidp_bind(struct device *dev)
if (ret)
goto register_fail;
- drm_fbdev_generic_setup(drm, 32);
+ drm_client_setup(drm, NULL);
return 0;
@@ -874,24 +864,19 @@ register_fail:
vblank_fail:
malidp_se_irq_fini(hwdev);
malidp_de_irq_fini(hwdev);
- drm->irq_enabled = false;
irq_init_fail:
drm_atomic_helper_shutdown(drm);
component_unbind_all(dev, drm);
bind_fail:
of_node_put(malidp->crtc.port);
malidp->crtc.port = NULL;
- malidp_fini(drm);
query_hw_fail:
pm_runtime_put(dev);
if (pm_runtime_enabled(dev))
pm_runtime_disable(dev);
else
malidp_runtime_pm_suspend(dev);
- drm->dev_private = NULL;
dev_set_drvdata(dev, NULL);
- drm_dev_put(drm);
-alloc_fail:
of_reserved_mem_device_release(dev);
return ret;
@@ -900,7 +885,7 @@ alloc_fail:
static void malidp_unbind(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
drm_dev_unregister(drm);
@@ -909,19 +894,15 @@ static void malidp_unbind(struct device *dev)
drm_atomic_helper_shutdown(drm);
malidp_se_irq_fini(hwdev);
malidp_de_irq_fini(hwdev);
- drm->irq_enabled = false;
component_unbind_all(dev, drm);
of_node_put(malidp->crtc.port);
malidp->crtc.port = NULL;
- malidp_fini(drm);
pm_runtime_put(dev);
if (pm_runtime_enabled(dev))
pm_runtime_disable(dev);
else
malidp_runtime_pm_suspend(dev);
- drm->dev_private = NULL;
dev_set_drvdata(dev, NULL);
- drm_dev_put(drm);
of_reserved_mem_device_release(dev);
}
@@ -957,10 +938,14 @@ static int malidp_platform_probe(struct platform_device *pdev)
match);
}
-static int malidp_platform_remove(struct platform_device *pdev)
+static void malidp_platform_remove(struct platform_device *pdev)
{
component_master_del(&pdev->dev, &malidp_master_ops);
- return 0;
+}
+
+static void malidp_platform_shutdown(struct platform_device *pdev)
+{
+ drm_atomic_helper_shutdown(platform_get_drvdata(pdev));
}
static int __maybe_unused malidp_pm_suspend(struct device *dev)
@@ -1004,6 +989,7 @@ static const struct dev_pm_ops malidp_pm_ops = {
static struct platform_driver malidp_platform_driver = {
.probe = malidp_platform_probe,
.remove = malidp_platform_remove,
+ .shutdown = malidp_platform_shutdown,
.driver = {
.name = "mali-dp",
.pm = &malidp_pm_ops,
@@ -1012,7 +998,7 @@ static struct platform_driver malidp_platform_driver = {
},
};
-module_platform_driver(malidp_platform_driver);
+drm_module_platform_driver(malidp_platform_driver);
MODULE_AUTHOR("Liviu Dudau <Liviu.Dudau@arm.com>");
MODULE_DESCRIPTION("ARM Mali DP DRM driver");
diff --git a/drivers/gpu/drm/arm/malidp_drv.h b/drivers/gpu/drm/arm/malidp_drv.h
index cdfddfabf2d1..bc0387876dea 100644
--- a/drivers/gpu/drm/arm/malidp_drv.h
+++ b/drivers/gpu/drm/arm/malidp_drv.h
@@ -29,6 +29,7 @@ struct malidp_error_stats {
};
struct malidp_drm {
+ struct drm_device base;
struct malidp_hw_device *dev;
struct drm_crtc crtc;
struct drm_writeback_connector mw_connector;
@@ -44,6 +45,7 @@ struct malidp_drm {
#endif
};
+#define drm_to_malidp(x) container_of(x, struct malidp_drm, base)
#define crtc_to_malidp_device(x) container_of(x, struct malidp_drm, crtc)
struct malidp_plane {
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index e9de542f9b7c..9b845d3f34e1 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -1168,7 +1168,7 @@ static void malidp_hw_clear_irq(struct malidp_hw_device *hwdev, u8 block, u32 ir
static irqreturn_t malidp_de_irq(int irq, void *arg)
{
struct drm_device *drm = arg;
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev;
struct malidp_hw *hw;
const struct malidp_irq_map *de;
@@ -1226,7 +1226,7 @@ static irqreturn_t malidp_de_irq(int irq, void *arg)
static irqreturn_t malidp_de_irq_thread_handler(int irq, void *arg)
{
struct drm_device *drm = arg;
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
wake_up(&malidp->wq);
@@ -1252,7 +1252,7 @@ void malidp_de_irq_hw_init(struct malidp_hw_device *hwdev)
int malidp_de_irq_init(struct drm_device *drm, int irq)
{
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
int ret;
@@ -1286,7 +1286,7 @@ void malidp_de_irq_fini(struct malidp_hw_device *hwdev)
static irqreturn_t malidp_se_irq(int irq, void *arg)
{
struct drm_device *drm = arg;
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
struct malidp_hw *hw = hwdev->hw;
const struct malidp_irq_map *se = &hw->map.se_irq_map;
@@ -1363,7 +1363,7 @@ static irqreturn_t malidp_se_irq_thread_handler(int irq, void *arg)
int malidp_se_irq_init(struct drm_device *drm, int irq)
{
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
int ret;
diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c
index f5847a79dd7e..47733c85d271 100644
--- a/drivers/gpu/drm/arm/malidp_mw.c
+++ b/drivers/gpu/drm/arm/malidp_mw.c
@@ -9,9 +9,12 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
-#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_fourcc.h>
-#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_dma_helper.h>
+#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_writeback.h>
@@ -41,7 +44,7 @@ static int malidp_mw_connector_get_modes(struct drm_connector *connector)
static enum drm_mode_status
malidp_mw_connector_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
+ const struct drm_display_mode *mode)
{
struct drm_device *dev = connector->dev;
struct drm_mode_config *mode_config = &dev->mode_config;
@@ -70,7 +73,10 @@ static void malidp_mw_connector_reset(struct drm_connector *connector)
__drm_atomic_helper_connector_destroy_state(connector->state);
kfree(connector->state);
- __drm_atomic_helper_connector_reset(connector, &mw_state->base);
+ connector->state = NULL;
+
+ if (mw_state)
+ __drm_atomic_helper_connector_reset(connector, &mw_state->base);
}
static enum drm_connector_status
@@ -127,7 +133,7 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_connector_state *conn_state)
{
struct malidp_mw_connector_state *mw_state = to_mw_state(conn_state);
- struct malidp_drm *malidp = encoder->dev->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(encoder->dev);
struct drm_framebuffer *fb;
int i, n_planes;
@@ -158,7 +164,7 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
n_planes = fb->format->num_planes;
for (i = 0; i < n_planes; i++) {
- struct drm_gem_cma_object *obj = drm_fb_cma_get_gem_obj(fb, i);
+ struct drm_gem_dma_object *obj = drm_fb_dma_get_gem_obj(fb, i);
/* memory write buffers are never rotated */
u8 alignment = malidp_hw_get_pitch_align(malidp->dev, 0);
@@ -168,7 +174,7 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
return -EINVAL;
}
mw_state->pitches[i] = fb->pitches[i];
- mw_state->addrs[i] = obj->paddr + fb->offsets[i];
+ mw_state->addrs[i] = obj->dma_addr + fb->offsets[i];
}
mw_state->n_planes = n_planes;
@@ -205,14 +211,13 @@ static u32 *get_writeback_formats(struct malidp_drm *malidp, int *n_formats)
int malidp_mw_connector_init(struct drm_device *drm)
{
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
u32 *formats;
int ret, n_formats;
if (!malidp->dev->hw->enable_memwrite)
return 0;
- malidp->mw_connector.encoder.possible_crtcs = 1 << drm_crtc_index(&malidp->crtc);
drm_connector_helper_add(&malidp->mw_connector.base,
&malidp_mw_connector_helper_funcs);
@@ -223,7 +228,8 @@ int malidp_mw_connector_init(struct drm_device *drm)
ret = drm_writeback_connector_init(drm, &malidp->mw_connector,
&malidp_mw_connector_funcs,
&malidp_mw_encoder_helper_funcs,
- formats, n_formats);
+ formats, n_formats,
+ 1 << drm_crtc_index(&malidp->crtc));
kfree(formats);
if (ret)
return ret;
@@ -234,7 +240,7 @@ int malidp_mw_connector_init(struct drm_device *drm)
void malidp_mw_atomic_commit(struct drm_device *drm,
struct drm_atomic_state *old_state)
{
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
struct drm_writeback_connector *mw_conn = &malidp->mw_connector;
struct drm_connector_state *conn_state = mw_conn->base.state;
struct malidp_hw_device *hwdev = malidp->dev;
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index 8c2ab3d653b7..f1a5014bcfa1 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -11,12 +11,13 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_fourcc.h>
-#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
-#include <drm/drm_plane_helper.h>
#include <drm/drm_print.h>
#include "malidp_hw.h"
@@ -67,14 +68,6 @@
/* readahead for partial-frame prefetch */
#define MALIDP_MMU_PREFETCH_READAHEAD 8
-static void malidp_de_plane_destroy(struct drm_plane *plane)
-{
- struct malidp_plane *mp = to_malidp_plane(plane);
-
- drm_plane_cleanup(plane);
- kfree(mp);
-}
-
/*
* Replicate what the default ->reset hook does: free the state pointer and
* allocate a new empty object. We just need enough space to store
@@ -150,7 +143,7 @@ bool malidp_format_mod_supported(struct drm_device *drm,
{
const struct drm_format_info *info;
const u64 *modifiers;
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
const struct malidp_hw_regmap *map = &malidp->dev->hw->map;
if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID))
@@ -165,8 +158,8 @@ bool malidp_format_mod_supported(struct drm_device *drm,
return !malidp_hw_format_is_afbc_only(format);
}
- if ((modifier >> 56) != DRM_FORMAT_MOD_VENDOR_ARM) {
- DRM_ERROR("Unknown modifier (not Arm)\n");
+ if (!fourcc_mod_is_vendor(modifier, ARM)) {
+ DRM_DEBUG_KMS("Unknown modifier (not Arm)\n");
return false;
}
@@ -259,7 +252,6 @@ static bool malidp_format_mod_supported_per_plane(struct drm_plane *plane,
static const struct drm_plane_funcs malidp_de_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
- .destroy = malidp_de_plane_destroy,
.reset = malidp_plane_reset,
.atomic_duplicate_state = malidp_duplicate_plane_state,
.atomic_destroy_state = malidp_destroy_plane_state,
@@ -271,7 +263,7 @@ static int malidp_se_check_scaling(struct malidp_plane *mp,
struct drm_plane_state *state)
{
struct drm_crtc_state *crtc_state =
- drm_atomic_get_existing_crtc_state(state->state, state->crtc);
+ drm_atomic_get_new_crtc_state(state->state, state->crtc);
struct malidp_crtc_state *mc;
u32 src_w, src_h;
int ret;
@@ -310,17 +302,13 @@ static int malidp_se_check_scaling(struct malidp_plane *mp,
static u32 malidp_get_pgsize_bitmap(struct malidp_plane *mp)
{
- u32 pgsize_bitmap = 0;
-
- if (iommu_present(&platform_bus_type)) {
- struct iommu_domain *mmu_dom =
- iommu_get_domain_for_dev(mp->base.dev->dev);
+ struct iommu_domain *mmu_dom;
- if (mmu_dom)
- pgsize_bitmap = mmu_dom->pgsize_bitmap;
- }
+ mmu_dom = iommu_get_domain_for_dev(mp->base.dev->dev);
+ if (mmu_dom)
+ return mmu_dom->pgsize_bitmap;
- return pgsize_bitmap;
+ return 0;
}
/*
@@ -336,33 +324,33 @@ static bool malidp_check_pages_threshold(struct malidp_plane_state *ms,
for (i = 0; i < ms->n_planes; i++) {
struct drm_gem_object *obj;
- struct drm_gem_cma_object *cma_obj;
+ struct drm_gem_dma_object *dma_obj;
struct sg_table *sgt;
struct scatterlist *sgl;
obj = drm_gem_fb_get_obj(ms->base.fb, i);
- cma_obj = to_drm_gem_cma_obj(obj);
+ dma_obj = to_drm_gem_dma_obj(obj);
- if (cma_obj->sgt)
- sgt = cma_obj->sgt;
+ if (dma_obj->sgt)
+ sgt = dma_obj->sgt;
else
sgt = obj->funcs->get_sg_table(obj);
- if (!sgt)
+ if (IS_ERR(sgt))
return false;
sgl = sgt->sgl;
while (sgl) {
if (sgl->length < pgsize) {
- if (!cma_obj->sgt)
+ if (!dma_obj->sgt)
kfree(sgt);
return false;
}
sgl = sg_next(sgl);
}
- if (!cma_obj->sgt)
+ if (!dma_obj->sgt)
kfree(sgt);
}
@@ -717,7 +705,7 @@ static void malidp_set_plane_base_addr(struct drm_framebuffer *fb,
struct malidp_plane *mp,
int plane_index)
{
- dma_addr_t paddr;
+ dma_addr_t dma_addr;
u16 ptr;
struct drm_plane *plane = &mp->base;
bool afbc = fb->modifier ? true : false;
@@ -725,27 +713,27 @@ static void malidp_set_plane_base_addr(struct drm_framebuffer *fb,
ptr = mp->layer->ptr + (plane_index << 4);
/*
- * drm_fb_cma_get_gem_addr() alters the physical base address of the
+ * drm_fb_dma_get_gem_addr() alters the physical base address of the
* framebuffer as per the plane's src_x, src_y co-ordinates (ie to
* take care of source cropping).
* For AFBC, this is not needed as the cropping is handled by _AD_CROP_H
* and _AD_CROP_V registers.
*/
if (!afbc) {
- paddr = drm_fb_cma_get_gem_addr(fb, plane->state,
- plane_index);
+ dma_addr = drm_fb_dma_get_gem_addr(fb, plane->state,
+ plane_index);
} else {
- struct drm_gem_cma_object *obj;
+ struct drm_gem_dma_object *obj;
- obj = drm_fb_cma_get_gem_obj(fb, plane_index);
+ obj = drm_fb_dma_get_gem_obj(fb, plane_index);
if (WARN_ON(!obj))
return;
- paddr = obj->paddr;
+ dma_addr = obj->dma_addr;
}
- malidp_hw_write(mp->hwdev, lower_32_bits(paddr), ptr);
- malidp_hw_write(mp->hwdev, upper_32_bits(paddr), ptr + 4);
+ malidp_hw_write(mp->hwdev, lower_32_bits(dma_addr), ptr);
+ malidp_hw_write(mp->hwdev, upper_32_bits(dma_addr), ptr + 4);
}
static void malidp_de_set_plane_afbc(struct drm_plane *plane)
@@ -934,7 +922,7 @@ static const uint64_t linear_only_modifiers[] = {
int malidp_de_planes_init(struct drm_device *drm)
{
- struct malidp_drm *malidp = drm->dev_private;
+ struct malidp_drm *malidp = drm_to_malidp(drm);
const struct malidp_hw_regmap *map = &malidp->dev->hw->map;
struct malidp_plane *plane = NULL;
enum drm_plane_type plane_type;
@@ -975,12 +963,6 @@ int malidp_de_planes_init(struct drm_device *drm)
for (i = 0; i < map->n_layers; i++) {
u8 id = map->layers[i].id;
- plane = kzalloc(sizeof(*plane), GFP_KERNEL);
- if (!plane) {
- ret = -ENOMEM;
- goto cleanup;
- }
-
/* build the list of DRM supported formats based on the map */
for (n = 0, j = 0; j < map->n_pixel_formats; j++) {
if ((map->pixel_formats[j].layer & id) == id)
@@ -993,13 +975,14 @@ int malidp_de_planes_init(struct drm_device *drm)
/*
* All the layers except smart layer supports AFBC modifiers.
*/
- ret = drm_universal_plane_init(drm, &plane->base, crtcs,
- &malidp_de_plane_funcs, formats, n,
- (id == DE_SMART) ? linear_only_modifiers : modifiers,
- plane_type, NULL);
-
- if (ret < 0)
+ plane = drmm_universal_plane_alloc(drm, struct malidp_plane, base,
+ crtcs, &malidp_de_plane_funcs, formats, n,
+ (id == DE_SMART) ? linear_only_modifiers :
+ modifiers, plane_type, NULL);
+ if (IS_ERR(plane)) {
+ ret = PTR_ERR(plane);
goto cleanup;
+ }
drm_plane_helper_add(&plane->base,
&malidp_de_plane_helper_funcs);
diff --git a/drivers/gpu/drm/arm/malidp_regs.h b/drivers/gpu/drm/arm/malidp_regs.h
index 514c50dcb74d..3bc16db70ddb 100644
--- a/drivers/gpu/drm/arm/malidp_regs.h
+++ b/drivers/gpu/drm/arm/malidp_regs.h
@@ -145,7 +145,7 @@
#define MALIDP_SE_COEFFTAB_DATA_MASK 0x3fff
#define MALIDP_SE_SET_COEFFTAB_DATA(x) \
((x) & MALIDP_SE_COEFFTAB_DATA_MASK)
-/* Enhance coeffents reigster offset */
+/* Enhance coefficients register offset */
#define MALIDP_SE_IMAGE_ENH 0x3C
/* ENH_LIMITS offset 0x0 */
#define MALIDP_SE_ENH_LOW_LEVEL 24