linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Add devcoredump support for DPU
@ 2020-10-22  5:01 Abhinav Kumar
  2020-10-22  5:01 ` [PATCH 1/4] drm: allow drm_atomic_print_state() to accept any drm_printer Abhinav Kumar
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Abhinav Kumar @ 2020-10-22  5:01 UTC (permalink / raw)
  To: dri-devel
  Cc: Abhinav Kumar, linux-arm-msm, freedreno, robdclark, seanpaul,
	swboyd, nganji, aravindh, tanmay, khsieh

This series adds support to use devcoredump for DPU driver. It introduces
the dpu_dbg module which assists in the capturing of register dumps during
error scenarios. When a display related error happens, the dpu_dbg module
captures all the relevant register dumps along with the snapshot of the drm
atomic state and triggers a devcoredump.

Abhinav Kumar (4):
  drm: allow drm_atomic_print_state() to accept any drm_printer
  disp/msm/dpu: add support to dump dpu registers
  drm/msm: register the base address with dpu_dbg module
  drm/msm/dpu: add dpu_dbg points across dpu driver

 drivers/gpu/drm/drm_atomic.c                  |  17 +-
 drivers/gpu/drm/drm_atomic_uapi.c             |   4 +-
 drivers/gpu/drm/drm_crtc_internal.h           |   4 +-
 drivers/gpu/drm/msm/Makefile                  |   2 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c       | 316 ++++++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h       | 273 +++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c  | 313 +++++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  12 +-
 .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  |   5 +-
 .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c  |   5 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |   4 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c    |   6 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c   |   7 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c   |   5 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c   |   6 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c   |   8 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c    |   7 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c       |  12 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h       |   4 +-
 drivers/gpu/drm/msm/dp/dp_catalog.c           |  12 +
 drivers/gpu/drm/msm/dp/dp_catalog.h           |   4 +
 drivers/gpu/drm/msm/dp/dp_display.c           |   2 +
 drivers/gpu/drm/msm/dsi/dsi_host.c            |  10 +-
 drivers/gpu/drm/msm/msm_drv.c                 |  30 +-
 drivers/gpu/drm/msm/msm_drv.h                 |   3 +-
 25 files changed, 1045 insertions(+), 26 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/4] drm: allow drm_atomic_print_state() to accept any drm_printer
  2020-10-22  5:01 [PATCH 0/4] Add devcoredump support for DPU Abhinav Kumar
@ 2020-10-22  5:01 ` Abhinav Kumar
  2020-10-22 10:10   ` kernel test robot
                     ` (2 more replies)
  2020-10-22  5:01 ` [PATCH 2/4] disp/msm/dpu: add support to dump dpu registers Abhinav Kumar
                   ` (2 subsequent siblings)
  3 siblings, 3 replies; 11+ messages in thread
From: Abhinav Kumar @ 2020-10-22  5:01 UTC (permalink / raw)
  To: dri-devel
  Cc: Abhinav Kumar, linux-arm-msm, freedreno, robdclark, seanpaul,
	swboyd, nganji, aravindh, tanmay, khsieh

Currently drm_atomic_print_state() internally allocates and uses a
drm_info printer. Allow it to accept any drm_printer type so that
the API can be leveraged even for taking drm snapshot.

Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
---
 drivers/gpu/drm/drm_atomic.c        | 17 ++++++++++++-----
 drivers/gpu/drm/drm_atomic_uapi.c   |  4 +++-
 drivers/gpu/drm/drm_crtc_internal.h |  4 +++-
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 58527f151984..e7079a5f439c 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2014 Red Hat
  * Copyright (C) 2014 Intel Corp.
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -1543,9 +1544,9 @@ int __drm_atomic_helper_set_config(struct drm_mode_set *set,
 }
 EXPORT_SYMBOL(__drm_atomic_helper_set_config);
 
-void drm_atomic_print_state(const struct drm_atomic_state *state)
+void drm_atomic_print_state(const struct drm_atomic_state *state,
+		struct drm_printer *p)
 {
-	struct drm_printer p = drm_info_printer(state->dev->dev);
 	struct drm_plane *plane;
 	struct drm_plane_state *plane_state;
 	struct drm_crtc *crtc;
@@ -1554,17 +1555,23 @@ void drm_atomic_print_state(const struct drm_atomic_state *state)
 	struct drm_connector_state *connector_state;
 	int i;
 
+	if (!p) {
+		DRM_ERROR("invalid drm printer\n");
+		return;
+	}
+
 	DRM_DEBUG_ATOMIC("checking %p\n", state);
 
 	for_each_new_plane_in_state(state, plane, plane_state, i)
-		drm_atomic_plane_print_state(&p, plane_state);
+		drm_atomic_plane_print_state(p, plane_state);
 
 	for_each_new_crtc_in_state(state, crtc, crtc_state, i)
-		drm_atomic_crtc_print_state(&p, crtc_state);
+		drm_atomic_crtc_print_state(p, crtc_state);
 
 	for_each_new_connector_in_state(state, connector, connector_state, i)
-		drm_atomic_connector_print_state(&p, connector_state);
+		drm_atomic_connector_print_state(p, connector_state);
 }
+EXPORT_SYMBOL(drm_atomic_print_state);
 
 static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p,
 			     bool take_locks)
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 25c269bc4681..d9ae86c92608 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -2,6 +2,7 @@
  * Copyright (C) 2014 Red Hat
  * Copyright (C) 2014 Intel Corp.
  * Copyright (C) 2018 Intel Corp.
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -1294,6 +1295,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
 	struct drm_out_fence_state *fence_state;
 	int ret = 0;
 	unsigned int i, j, num_fences;
+	struct drm_printer p = drm_info_printer(dev->dev);
 
 	/* disallow for drivers not supporting atomic: */
 	if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
@@ -1413,7 +1415,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
 		ret = drm_atomic_nonblocking_commit(state);
 	} else {
 		if (drm_debug_enabled(DRM_UT_STATE))
-			drm_atomic_print_state(state);
+			drm_atomic_print_state(state, &p);
 
 		ret = drm_atomic_commit(state);
 	}
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index da96b2f64d7e..d34215366936 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -5,6 +5,7 @@
  *   Jesse Barnes <jesse.barnes@intel.com>
  * Copyright © 2014 Intel Corporation
  *   Daniel Vetter <daniel.vetter@ffwll.ch>
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -233,7 +234,8 @@ int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
 int __drm_atomic_helper_set_config(struct drm_mode_set *set,
 				   struct drm_atomic_state *state);
 
-void drm_atomic_print_state(const struct drm_atomic_state *state);
+void drm_atomic_print_state(const struct drm_atomic_state *state,
+		struct drm_printer *p);
 
 /* drm_atomic_uapi.c */
 int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/4] disp/msm/dpu: add support to dump dpu registers
  2020-10-22  5:01 [PATCH 0/4] Add devcoredump support for DPU Abhinav Kumar
  2020-10-22  5:01 ` [PATCH 1/4] drm: allow drm_atomic_print_state() to accept any drm_printer Abhinav Kumar
@ 2020-10-22  5:01 ` Abhinav Kumar
  2020-10-22  8:29   ` kernel test robot
  2020-10-27 14:15   ` kernel test robot
  2020-10-22  5:01 ` [PATCH 3/4] drm/msm: register the base address with dpu_dbg module Abhinav Kumar
  2020-10-22  5:01 ` [PATCH 4/4] drm/msm/dpu: add dpu_dbg points across dpu driver Abhinav Kumar
  3 siblings, 2 replies; 11+ messages in thread
From: Abhinav Kumar @ 2020-10-22  5:01 UTC (permalink / raw)
  To: dri-devel
  Cc: Abhinav Kumar, linux-arm-msm, freedreno, robdclark, seanpaul,
	swboyd, nganji, aravindh, tanmay, khsieh

Add the dpu_dbg module which adds supports to dump dpu registers
which can be used in case of error conditions.

Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
---
 drivers/gpu/drm/msm/Makefile                  |   2 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c       | 316 ++++++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h       | 273 +++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c  | 313 +++++++++++++++++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |   4 +-
 drivers/gpu/drm/msm/msm_drv.c                 |   6 +-
 6 files changed, 912 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 340682cd0f32..96bd1398edac 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -54,6 +54,8 @@ msm-y := \
 	disp/dpu1/dpu_core_irq.o \
 	disp/dpu1/dpu_core_perf.o \
 	disp/dpu1/dpu_crtc.o \
+	disp/dpu1/dpu_dbg.o \
+	disp/dpu1/dpu_dbg_util.o \
 	disp/dpu1/dpu_encoder.o \
 	disp/dpu1/dpu_encoder_phys_cmd.o \
 	disp/dpu1/dpu_encoder_phys_vid.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c
new file mode 100644
index 000000000000..6703e1555194
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2009-2020, The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include "dpu_dbg.h"
+#include "dpu_hw_catalog.h"
+
+/* global dpu debug base structure */
+static struct dpu_dbg_base dpu_dbg;
+
+
+#ifdef CONFIG_DEV_COREDUMP
+static ssize_t dpu_devcoredump_read(char *buffer, loff_t offset,
+		size_t count, void *data, size_t datalen)
+{
+	struct drm_print_iterator iter;
+	struct drm_printer p;
+
+	iter.data = buffer;
+	iter.offset = 0;
+	iter.start = offset;
+	iter.remain = count;
+
+	p = drm_coredump_printer(&iter);
+
+	drm_printf(&p, "---\n");
+
+	drm_printf(&p, "module: " KBUILD_MODNAME "\n");
+	drm_printf(&p, "dpu devcoredump\n");
+	drm_printf(&p, "timestamp %lld\n", ktime_to_ns(dpu_dbg.timestamp));
+
+	dpu_dbg.dpu_dbg_printer = &p;
+	dpu_dbg.enable_reg_dump = DPU_DBG_DUMP_IN_COREDUMP;
+
+	drm_printf(&p, "===================dpu regs================\n");
+
+	_dpu_dump_array(&dpu_dbg, dpu_dbg.req_dump_blks,
+		ARRAY_SIZE(dpu_dbg.req_dump_blks),
+		dpu_dbg.work_panic, "evtlog_workitem",
+		dpu_dbg.dump_all);
+
+	drm_printf(&p, "===================dpu drm state================\n");
+
+	if (dpu_dbg.atomic_state)
+		drm_atomic_print_state(dpu_dbg.atomic_state,
+				&p);
+
+	return count - iter.remain;
+}
+
+static void dpu_devcoredump_free(void *data)
+{
+	if (dpu_dbg.atomic_state) {
+		drm_atomic_state_put(dpu_dbg.atomic_state);
+		dpu_dbg.atomic_state = NULL;
+	}
+	dpu_dbg.coredump_pending = false;
+}
+
+static void dpu_devcoredump_capture_state(void)
+{
+	struct drm_device *ddev;
+	struct drm_modeset_acquire_ctx ctx;
+
+	dpu_dbg.timestamp = ktime_get();
+
+	ddev = dpu_dbg.drm_dev;
+
+	drm_modeset_acquire_init(&ctx, 0);
+
+	while (drm_modeset_lock_all_ctx(ddev, &ctx) != 0)
+		drm_modeset_backoff(&ctx);
+
+	dpu_dbg.atomic_state = drm_atomic_helper_duplicate_state(ddev,
+			&ctx);
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+}
+#else
+static void dpu_devcoredump_capture_state(void)
+{
+}
+#endif /* CONFIG_DEV_COREDUMP */
+
+/**
+ * _dpu_dump_work - deferred dump work function
+ * @work: work structure
+ */
+static void _dpu_dump_work(struct kthread_work *work)
+{
+	/* reset the enable_reg_dump to default before every dump */
+	dpu_dbg.enable_reg_dump = DEFAULT_REGDUMP;
+
+	_dpu_dump_array(&dpu_dbg, dpu_dbg.req_dump_blks,
+		ARRAY_SIZE(dpu_dbg.req_dump_blks),
+		dpu_dbg.work_panic, "evtlog_workitem",
+		dpu_dbg.dump_all);
+
+	dpu_devcoredump_capture_state();
+
+#ifdef CONFIG_DEV_COREDUMP
+	if (dpu_dbg.enable_reg_dump & DPU_DBG_DUMP_IN_MEM) {
+		dev_coredumpm(dpu_dbg.dev, THIS_MODULE, &dpu_dbg, 0, GFP_KERNEL,
+				dpu_devcoredump_read, dpu_devcoredump_free);
+		dpu_dbg.coredump_pending = true;
+	}
+#endif
+}
+
+void dpu_dbg_dump(enum dpu_dbg_dump_context dump_mode, const char *name, ...)
+{
+	int i, index = 0;
+	bool do_panic = false;
+	bool dump_all = false;
+	va_list args;
+	char *blk_name = NULL;
+	struct dpu_dbg_reg_base *blk_base = NULL;
+	struct dpu_dbg_reg_base **blk_arr;
+	u32 blk_len;
+
+	/*
+	 * if there is a coredump pending return immediately till dump
+	 * if read by userspace or timeout happens
+	 */
+	if (((dpu_dbg.enable_reg_dump == DPU_DBG_DUMP_IN_MEM) ||
+		 (dpu_dbg.enable_reg_dump == DPU_DBG_DUMP_IN_COREDUMP)) &&
+		dpu_dbg.coredump_pending) {
+		pr_debug("coredump is pending read\n");
+		return;
+	}
+
+	blk_arr = &dpu_dbg.req_dump_blks[0];
+	blk_len = ARRAY_SIZE(dpu_dbg.req_dump_blks);
+
+	memset(dpu_dbg.req_dump_blks, 0,
+			sizeof(dpu_dbg.req_dump_blks));
+	dpu_dbg.dump_all = false;
+	dpu_dbg.dump_mode = dump_mode;
+
+	va_start(args, name);
+	i = 0;
+	while ((blk_name = va_arg(args, char*))) {
+
+		if (IS_ERR_OR_NULL(blk_name))
+			break;
+
+		blk_base = _dpu_dump_get_blk_addr(&dpu_dbg, blk_name);
+		if (blk_base) {
+			if (index < blk_len) {
+				blk_arr[index] = blk_base;
+				index++;
+			} else {
+				pr_err("insufficient space to dump %s\n",
+						blk_name);
+			}
+		}
+
+		if (!strcmp(blk_name, "all"))
+			dump_all = true;
+
+		if (!strcmp(blk_name, "panic"))
+			do_panic = true;
+
+	}
+	va_end(args);
+
+	dpu_dbg.work_panic = do_panic;
+	dpu_dbg.dump_all = dump_all;
+
+	kthread_queue_work(dpu_dbg.dump_worker,
+			&dpu_dbg.dump_work);
+
+}
+
+int dpu_dbg_init(struct device *dev)
+{
+	if (!dev) {
+		pr_err("invalid params\n");
+		return -EINVAL;
+	}
+
+	mutex_init(&dpu_dbg.mutex);
+	INIT_LIST_HEAD(&dpu_dbg.reg_base_list);
+	dpu_dbg.dev = dev;
+
+	dpu_dbg.work_panic = false;
+	dpu_dbg.enable_reg_dump = DEFAULT_REGDUMP;
+
+	dpu_dbg.dump_worker = kthread_create_worker(0, "%s", "dpu_dbg");
+	if (IS_ERR(dpu_dbg.dump_worker))
+		dev_err(dev, "failed to create dpu dbg task\n");
+
+	kthread_init_work(&dpu_dbg.dump_work, _dpu_dump_work);
+
+	pr_info("dump:%d\n", dpu_dbg.enable_reg_dump);
+
+	return 0;
+}
+
+void dpu_dbg_register_drm_dev(struct drm_device *ddev)
+{
+	dpu_dbg.drm_dev = ddev;
+}
+
+static void dpu_dbg_reg_base_destroy(void)
+{
+	struct dpu_dbg_reg_range *range_node, *range_tmp;
+	struct dpu_dbg_reg_base *blk_base, *blk_tmp;
+	struct dpu_dbg_base *dbg_base = &dpu_dbg;
+
+	/* if the dbg init failed or was never called */
+	if (!dbg_base || !dpu_dbg.dev)
+		return;
+
+	list_for_each_entry_safe(blk_base, blk_tmp, &dbg_base->reg_base_list,
+							reg_base_head) {
+		list_for_each_entry_safe(range_node, range_tmp,
+				&blk_base->sub_range_list, head) {
+			list_del(&range_node->head);
+			kfree(range_node);
+		}
+		list_del(&blk_base->reg_base_head);
+		kfree(blk_base);
+	}
+}
+
+/**
+ * dpu_dbg_destroy - destroy dpu debug facilities
+ */
+void dpu_dbg_destroy(void)
+{
+	if (dpu_dbg.dump_worker)
+		kthread_destroy_worker(dpu_dbg.dump_worker);
+	dpu_dbg_reg_base_destroy();
+	mutex_destroy(&dpu_dbg.mutex);
+}
+
+int dpu_dbg_reg_register_base(const char *name, void __iomem *base,
+		size_t max_offset)
+{
+	struct dpu_dbg_base *dbg_base = &dpu_dbg;
+	struct dpu_dbg_reg_base *reg_base;
+
+	if (!name || !strlen(name)) {
+		pr_err("no debug name provided\n");
+		return -EINVAL;
+	}
+
+	reg_base = kzalloc(sizeof(*reg_base), GFP_KERNEL);
+	if (!reg_base)
+		return -ENOMEM;
+
+	strlcpy(reg_base->name, name, sizeof(reg_base->name));
+	reg_base->base = base;
+	reg_base->max_offset = max_offset;
+	reg_base->off = 0;
+	reg_base->cnt = DEFAULT_BASE_REG_CNT;
+	reg_base->reg_dump = NULL;
+
+	/* Initialize list to make sure check for null list will be valid */
+	INIT_LIST_HEAD(&reg_base->sub_range_list);
+
+	pr_debug("%s base: %pK max_offset 0x%zX\n", reg_base->name,
+			reg_base->base, reg_base->max_offset);
+
+	list_add(&reg_base->reg_base_head, &dbg_base->reg_base_list);
+
+	return 0;
+}
+
+void dpu_dbg_reg_register_dump_range(const char *base_name,
+		const char *range_name, u32 offset_start, u32 offset_end,
+		uint32_t xin_id)
+{
+	struct dpu_dbg_reg_base *reg_base;
+	struct dpu_dbg_reg_range *range;
+
+	reg_base = _dpu_dump_get_blk_addr(&dpu_dbg, base_name);
+	if (!reg_base) {
+		pr_err("error: for range %s unable to locate base %s\n",
+				range_name, base_name);
+		return;
+	}
+
+	if (!range_name || strlen(range_name) == 0) {
+		pr_err("%pS: bad range name, base_name %s, offset_start 0x%X, end 0x%X\n",
+				__builtin_return_address(0), base_name,
+				offset_start, offset_end);
+		return;
+	}
+
+	if (offset_end - offset_start < REG_DUMP_ALIGN ||
+			offset_start > offset_end) {
+		pr_err("%pS: bad range, base_name %s, range_name %s, offset_start 0x%X, end 0x%X\n",
+				__builtin_return_address(0), base_name,
+				range_name, offset_start, offset_end);
+		return;
+	}
+
+	range = kzalloc(sizeof(*range), GFP_KERNEL);
+	if (!range)
+		return;
+
+	strlcpy(range->range_name, range_name, sizeof(range->range_name));
+	range->offset.start = offset_start;
+	range->offset.end = offset_end;
+	range->xin_id = xin_id;
+	list_add_tail(&range->head, &reg_base->sub_range_list);
+
+	pr_debug("base %s, range %s, start 0x%X, end 0x%X\n",
+			base_name, range->range_name,
+			range->offset.start, range->offset.end);
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h
new file mode 100644
index 000000000000..2cea13288cef
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h
@@ -0,0 +1,273 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef DPU_DBG_H_
+#define DPU_DBG_H_
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_device.h>
+#include "../../../drm_crtc_internal.h"
+#include <drm/drm_print.h>
+#include <drm/drm_atomic.h>
+#include <linux/debugfs.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/ktime.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/dma-buf.h>
+#include <linux/slab.h>
+#include <linux/list_sort.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/kthread.h>
+#include <linux/devcoredump.h>
+#include <stdarg.h>
+
+#define DPU_DBG_DUMP_DATA_LIMITER (NULL)
+
+enum dpu_dbg_dump_flag {
+	DPU_DBG_DUMP_IN_LOG = BIT(0),
+	DPU_DBG_DUMP_IN_MEM = BIT(1),
+	DPU_DBG_DUMP_IN_COREDUMP = BIT(2),
+};
+
+enum dpu_dbg_dump_context {
+	DPU_DBG_DUMP_PROC_CTX,
+	DPU_DBG_DUMP_CLK_ENABLED_CTX,
+};
+
+#define DPU_DBG_BASE_MAX		10
+
+#define DEFAULT_PANIC		0
+#define DEFAULT_REGDUMP		DPU_DBG_DUMP_IN_MEM
+#define DEFAULT_BASE_REG_CNT	DEFAULT_MDSS_HW_BLOCK_SIZE
+#define ROW_BYTES		16
+#define RANGE_NAME_LEN		40
+#define REG_BASE_NAME_LEN	80
+
+/* print debug ranges in groups of 4 u32s */
+#define REG_DUMP_ALIGN		16
+
+/**
+ * struct dpu_dbg_reg_offset - tracking for start and end of region
+ * @start: start offset
+ * @start: end offset
+ */
+struct dpu_dbg_reg_offset {
+	u32 start;
+	u32 end;
+};
+
+/**
+ * struct dpu_dbg_reg_range - register dumping named sub-range
+ * @head: head of this node
+ * @reg_dump: address for the mem dump
+ * @range_name: name of this range
+ * @offset: offsets for range to dump
+ * @xin_id: client xin id
+ */
+struct dpu_dbg_reg_range {
+	struct list_head head;
+	u32 *reg_dump;
+	char range_name[RANGE_NAME_LEN];
+	struct dpu_dbg_reg_offset offset;
+	uint32_t xin_id;
+};
+
+/**
+ * struct dpu_dbg_reg_base - register region base.
+ *	may sub-ranges: sub-ranges are used for dumping
+ *	or may not have sub-ranges: dumping is base -> max_offset
+ * @reg_base_head: head of this node
+ * @sub_range_list: head to the list with dump ranges
+ * @name: register base name
+ * @base: base pointer
+ * @off: cached offset of region for manual register dumping
+ * @cnt: cached range of region for manual register dumping
+ * @max_offset: length of region
+ * @buf: buffer used for manual register dumping
+ * @buf_len:  buffer length used for manual register dumping
+ * @reg_dump: address for the mem dump if no ranges used
+ * @cb: callback for external dump function, null if not defined
+ * @cb_ptr: private pointer to callback function
+ */
+struct dpu_dbg_reg_base {
+	struct list_head reg_base_head;
+	struct list_head sub_range_list;
+	char name[REG_BASE_NAME_LEN];
+	void __iomem *base;
+	size_t off;
+	size_t cnt;
+	size_t max_offset;
+	char *buf;
+	size_t buf_len;
+	u32 *reg_dump;
+	void (*cb)(void *ptr);
+	void *cb_ptr;
+};
+
+/**
+ * struct dpu_dbg_base - global sde debug base structure
+ * @evtlog: event log instance
+ * @reg_base_list: list of register dumping regions
+ * @dev: device pointer
+ * @drm_dev: drm device pointer
+ * @mutex: mutex to serialize access to serialze dumps, debugfs access
+ * @req_dump_blks: list of blocks requested for dumping
+ * @work_panic: panic after dump if internal user passed "panic" special region
+ * @enable_reg_dump: whether to dump registers into memory, kernel log, or both
+ * @dump_all: dump all entries in register dump
+ * @coredump_pending: coredump is pending read from userspace
+ * @atomic_state: atomic state duplicated at the time of the error
+ * @dump_worker: kworker thread which runs the dump work
+ * @dump_work: kwork which dumps the registers and drm state
+ * @timestamp: timestamp at which the coredump was captured
+ * @dpu_dbg_printer: drm printer handle used to take drm snapshot
+ * @dump_mode: decides whether the data is dumped in memory or logs
+ */
+struct dpu_dbg_base {
+	struct list_head reg_base_list;
+	struct device *dev;
+	struct drm_device *drm_dev;
+	struct mutex mutex;
+
+	struct dpu_dbg_reg_base *req_dump_blks[DPU_DBG_BASE_MAX];
+
+	bool work_panic;
+	u32 enable_reg_dump;
+
+	bool dump_all;
+	bool coredump_pending;
+
+	struct drm_atomic_state *atomic_state;
+
+	struct kthread_worker *dump_worker;
+	struct kthread_work dump_work;
+	ktime_t timestamp;
+
+	struct drm_printer *dpu_dbg_printer;
+
+	enum dpu_dbg_dump_context dump_mode;
+};
+
+struct dpu_dbg_power_ctrl {
+	void *handle;
+	void *client;
+	int (*enable_fn)(void *handle, void *client, bool enable);
+};
+
+
+/**
+ * DPU_DBG_DUMP - trigger dumping of all dpu_dbg facilities
+ * @va_args:	list of named register dump ranges and regions to dump, as
+ *		registered previously through dpu_dbg_reg_register_base and
+ *		dpu_dbg_reg_register_dump_range.
+ *		Including the special name "panic" will trigger a panic after
+ *		the dumping work has completed.
+ */
+#define DPU_DBG_DUMP(...) dpu_dbg_dump(DPU_DBG_DUMP_PROC_CTX, __func__, \
+		##__VA_ARGS__, DPU_DBG_DUMP_DATA_LIMITER)
+
+/**
+ * DPU_DBG_DUMP_CLK_EN - trigger dumping of all dpu_dbg facilities, without clk
+ * @va_args:	list of named register dump ranges and regions to dump, as
+ *		registered previously through dpu_dbg_reg_register_base and
+ *		dpu_dbg_reg_register_dump_range.
+ *		Including the special name "panic" will trigger a panic after
+ *		the dumping work has completed.
+ */
+#define DPU_DBG_DUMP_CLK_EN(...) dpu_dbg_dump(DPU_DBG_DUMP_CLK_ENABLED_CTX, \
+		__func__, ##__VA_ARGS__, DPU_DBG_DUMP_DATA_LIMITER)
+
+/**
+ * dpu_dbg_init - initialize global sde debug facilities: evtlog, regdump
+ * @dev:		device handle
+ * Returns:		0 or -ERROR
+ */
+int dpu_dbg_init(struct device *dev);
+
+/**
+ * dpu_dbg_register_drm_dev - register a drm device with the dpu dbg module
+ * @ddev:		drm device hangle
+ * Returns:		void
+ */
+void dpu_dbg_register_drm_dev(struct drm_device *ddev);
+
+/**
+ * dpu_dbg_destroy - destroy the global sde debug facilities
+ * Returns:	none
+ */
+void dpu_dbg_destroy(void);
+
+/**
+ * dpu_dbg_dump - trigger dumping of all dpu_dbg facilities
+ * @queue_work:	whether to queue the dumping work to the work_struct
+ * @name:	string indicating origin of dump
+ * @va_args:	list of named register dump ranges and regions to dump, as
+ *		registered previously through dpu_dbg_reg_register_base and
+ *		dpu_dbg_reg_register_dump_range.
+ *		Including the special name "panic" will trigger a panic after
+ *		the dumping work has completed.
+ * Returns:	none
+ */
+void dpu_dbg_dump(enum dpu_dbg_dump_context mode, const char *name, ...);
+
+/**
+ * dpu_dbg_reg_register_base - register a hw register address section for later
+ *	dumping. call this before calling dpu_dbg_reg_register_dump_range
+ *	to be able to specify sub-ranges within the base hw range.
+ * @name:	name of base region
+ * @base:	base pointer of region
+ * @max_offset:	length of region
+ * Returns:	0 or -ERROR
+ */
+int dpu_dbg_reg_register_base(const char *name, void __iomem *base,
+		size_t max_offset);
+
+/**
+ * dpu_dbg_reg_register_dump_range - register a hw register sub-region for
+ *	later register dumping associated with base specified by
+ *	dpu_dbg_reg_register_base
+ * @base_name:		name of base region
+ * @range_name:		name of sub-range within base region
+ * @offset_start:	sub-range's start offset from base's base pointer
+ * @offset_end:		sub-range's end offset from base's base pointer
+ * @xin_id:		xin id
+ * Returns:		none
+ */
+void dpu_dbg_reg_register_dump_range(const char *base_name,
+		const char *range_name, u32 offset_start, u32 offset_end,
+		uint32_t xin_id);
+
+/**
+ * dpu_dbg_set_sde_top_offset - set the target specific offset from mdss base
+ *	address of the top registers. Used for accessing debug bus controls.
+ * @blk_off: offset from mdss base of the top block
+ */
+void dpu_dbg_set_sde_top_offset(u32 blk_off);
+
+/**
+ * _dpu_dump_array - dump array of register bases
+ * @blk_arr: array of register base pointers
+ * @len: length of blk_arr
+ * @do_panic: whether to trigger a panic after dumping
+ * @name: string indicating origin of dump
+ * @dump_all: dump all regs
+ */
+void _dpu_dump_array(struct dpu_dbg_base *dbg_base,
+		struct dpu_dbg_reg_base *blk_arr[],
+		u32 len, bool do_panic, const char *name, bool dump_all);
+
+/**
+ * _dpu_dump_get_blk_addr - retrieve register block address by name
+ * @blk_name: register blk name
+ * @Return: register blk base, or NULL
+ */
+struct dpu_dbg_reg_base *_dpu_dump_get_blk_addr(struct dpu_dbg_base *dbg_base,
+		const char *blk_name);
+
+#endif /* DPU_DBG_H_ */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c
new file mode 100644
index 000000000000..a54bea108020
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c
@@ -0,0 +1,313 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include "dpu_dbg.h"
+#include "dpu_hw_catalog.h"
+
+/**
+ * _sde_power_check - check if power needs to enabled
+ * @dump_mode: to check if power need to be enabled
+ * Return: true if success; false otherwise
+ */
+static inline bool _dpu_power_check(enum dpu_dbg_dump_context dump_mode)
+{
+	return (dump_mode == DPU_DBG_DUMP_CLK_ENABLED_CTX) ? false : true;
+}
+
+/**
+ * _dpu_dump_reg - helper function for dumping rotator register set content
+ * @dump_name: register set name
+ * @reg_dump_flag: dumping flag controlling in-log/memory dump location
+ * @base_addr: starting address of io region for calculating offsets to print
+ * @addr: starting address offset for dumping
+ * @len_bytes: range of the register set
+ * @dump_mem: output buffer for memory dump location option
+ * @from_isr: whether being called from isr context
+ */
+static void _dpu_dump_reg(struct dpu_dbg_base *dbg_base,
+		const char *dump_name, u32 reg_dump_flag,
+		char *base_addr, char *addr, size_t len_bytes, u32 **dump_mem)
+{
+	u32 in_log, in_mem, len_align, len_padded, in_dump;
+	u32 *dump_addr = NULL;
+	char *end_addr;
+	int i;
+	int rc;
+
+	if (!len_bytes)
+		return;
+
+	in_log = (reg_dump_flag & DPU_DBG_DUMP_IN_LOG);
+	in_mem = (reg_dump_flag & DPU_DBG_DUMP_IN_MEM);
+	in_dump = (reg_dump_flag & DPU_DBG_DUMP_IN_COREDUMP);
+
+	pr_debug("%s: reg_dump_flag=%d in_log=%d in_mem=%d\n",
+		dump_name, reg_dump_flag, in_log, in_mem);
+
+	if (!in_log && !in_mem && !in_dump)
+		return;
+
+	if (in_log)
+		dev_info(dbg_base->dev, "%s: start_offset 0x%lx len 0x%zx\n",
+				dump_name, (unsigned long)(addr - base_addr),
+					len_bytes);
+
+	len_align = (len_bytes + REG_DUMP_ALIGN - 1) / REG_DUMP_ALIGN;
+	len_padded = len_align * REG_DUMP_ALIGN;
+	end_addr = addr + len_bytes;
+
+	if (in_mem || in_dump) {
+		if (dump_mem && !(*dump_mem))
+			*dump_mem = devm_kzalloc(dbg_base->dev, len_padded,
+					GFP_KERNEL);
+
+		if (dump_mem && *dump_mem) {
+			dump_addr = *dump_mem;
+			dev_info(dbg_base->dev,
+				"%s: start_addr:0x%pK len:0x%x reg_offset=0x%lx\n",
+				dump_name, dump_addr, len_padded,
+				(unsigned long)(addr - base_addr));
+			if (in_dump)
+				drm_printf(dbg_base->dpu_dbg_printer,
+						"%s: start_addr:0x%pK len:0x%x reg_offset=0x%lx\n",
+						dump_name, dump_addr,
+						len_padded,
+						(unsigned long)(addr -
+						base_addr));
+		} else {
+			in_mem = 0;
+			pr_err("dump_mem: kzalloc fails!\n");
+		}
+	}
+
+	if (_dpu_power_check(dbg_base->dump_mode)) {
+		rc = pm_runtime_get_sync(dbg_base->dev);
+		if (rc < 0) {
+			pr_err("failed to enable power %d\n", rc);
+			return;
+		}
+	}
+
+	for (i = 0; i < len_align; i++) {
+		u32 x0, x4, x8, xc;
+
+		if (in_log || in_mem) {
+			x0 = (addr < end_addr) ? readl_relaxed(addr + 0x0) : 0;
+			x4 = (addr + 0x4 < end_addr) ? readl_relaxed(addr +
+					0x4) : 0;
+			x8 = (addr + 0x8 < end_addr) ? readl_relaxed(addr +
+					0x8) : 0;
+			xc = (addr + 0xc < end_addr) ? readl_relaxed(addr +
+					0xc) : 0;
+		}
+
+		if (in_log)
+			dev_info(dbg_base->dev,
+					"0x%lx : %08x %08x %08x %08x\n",
+					(unsigned long)(addr - base_addr),
+					x0, x4, x8, xc);
+
+		if (dump_addr && in_mem) {
+			dump_addr[i * 4] = x0;
+			dump_addr[i * 4 + 1] = x4;
+			dump_addr[i * 4 + 2] = x8;
+			dump_addr[i * 4 + 3] = xc;
+		}
+
+		if (in_dump) {
+			drm_printf(dbg_base->dpu_dbg_printer,
+					"0x%lx : %08x %08x %08x %08x\n",
+					(unsigned long)(addr - base_addr),
+					dump_addr[i * 4],
+					dump_addr[i * 4 + 1],
+					dump_addr[i * 4 + 2],
+					dump_addr[i * 4 + 3]);
+
+		}
+
+		addr += REG_DUMP_ALIGN;
+	}
+
+	if (_dpu_power_check(dbg_base->dump_mode))
+		pm_runtime_put_sync(dbg_base->dev);
+}
+
+/**
+ * _dpu_dbg_get_dump_range - helper to retrieve dump length for a range node
+ * @range_node: range node to dump
+ * @max_offset: max offset of the register base
+ * @Return: length
+ */
+static u32 _dpu_dbg_get_dump_range(struct dpu_dbg_reg_offset *range_node,
+		size_t max_offset)
+{
+	u32 length = 0;
+
+	if (range_node->start == 0 && range_node->end == 0) {
+		length = max_offset;
+	} else if (range_node->start < max_offset) {
+		if (range_node->end > max_offset)
+			length = max_offset - range_node->start;
+		else if (range_node->start < range_node->end)
+			length = range_node->end - range_node->start;
+	}
+
+	return length;
+}
+
+static int _dpu_dump_reg_range_cmp(void *priv, struct list_head *a,
+		struct list_head *b)
+{
+	struct dpu_dbg_reg_range *ar, *br;
+
+	if (!a || !b)
+		return 0;
+
+	ar = container_of(a, struct dpu_dbg_reg_range, head);
+	br = container_of(b, struct dpu_dbg_reg_range, head);
+
+	return ar->offset.start - br->offset.start;
+}
+
+/**
+ * _dpu_dump_reg_by_ranges - dump ranges or full range of the register blk base
+ * @dbg: register blk base structure
+ * @reg_dump_flag: dump target, memory, kernel log, or both
+ */
+static void _dpu_dump_reg_by_ranges(struct dpu_dbg_base *dbg_base,
+		struct dpu_dbg_reg_base *dbg,
+		u32 reg_dump_flag)
+{
+	char *addr;
+	size_t len;
+	struct dpu_dbg_reg_range *range_node;
+
+	if (!dbg || !(dbg->base || dbg->cb)) {
+		pr_err("dbg base is null!\n");
+		return;
+	}
+
+	dev_info(dbg_base->dev, "%s:=========%s DUMP=========\n", __func__,
+			dbg->name);
+
+	if (reg_dump_flag & DPU_DBG_DUMP_IN_COREDUMP)
+		drm_printf(dbg_base->dpu_dbg_printer,
+				"%s:=========%s DUMP=========\n",
+				__func__, dbg->name);
+
+	if (dbg->cb) {
+		dbg->cb(dbg->cb_ptr);
+	/* If there is a list to dump the registers by ranges, use the ranges */
+	} else if (!list_empty(&dbg->sub_range_list)) {
+		/* sort the list by start address first */
+		list_sort(NULL, &dbg->sub_range_list, _dpu_dump_reg_range_cmp);
+		list_for_each_entry(range_node, &dbg->sub_range_list, head) {
+			len = _dpu_dbg_get_dump_range(&range_node->offset,
+				dbg->max_offset);
+			addr = dbg->base + range_node->offset.start;
+
+			pr_debug("%s: range_base=0x%pK start=0x%x end=0x%x\n",
+				range_node->range_name,
+				addr, range_node->offset.start,
+				range_node->offset.end);
+
+			_dpu_dump_reg(dbg_base, range_node->range_name,
+					reg_dump_flag,
+					dbg->base, addr, len,
+					&range_node->reg_dump);
+		}
+	} else {
+		/* If there is no list to dump ranges, dump all registers */
+		dev_info(dbg_base->dev,
+				"Ranges not found, will dump full registers\n");
+		dev_info(dbg_base->dev, "base:0x%pK len:0x%zx\n", dbg->base,
+				dbg->max_offset);
+		addr = dbg->base;
+		len = dbg->max_offset;
+		_dpu_dump_reg(dbg_base, dbg->name, reg_dump_flag,
+				dbg->base, addr, len,
+				&dbg->reg_dump);
+	}
+}
+
+/**
+ * _dpu_dump_reg_by_blk - dump a named register base region
+ * @blk_name: register blk name
+ */
+static void _dpu_dump_reg_by_blk(struct dpu_dbg_base *dbg_base,
+		const char *blk_name)
+{
+	struct dpu_dbg_reg_base *blk_base;
+
+	if (!dbg_base)
+		return;
+
+	list_for_each_entry(blk_base, &dbg_base->reg_base_list, reg_base_head) {
+		if (strlen(blk_base->name) &&
+			!strcmp(blk_base->name, blk_name)) {
+			_dpu_dump_reg_by_ranges(dbg_base, blk_base,
+				dbg_base->enable_reg_dump);
+			break;
+		}
+	}
+}
+
+/**
+ * _dpu_dump_reg_all - dump all register regions
+ */
+static void _dpu_dump_reg_all(struct dpu_dbg_base *dbg_base)
+{
+	struct dpu_dbg_reg_base *blk_base;
+
+	if (!dbg_base)
+		return;
+
+	list_for_each_entry(blk_base, &dbg_base->reg_base_list, reg_base_head) {
+
+		if (!strlen(blk_base->name))
+			continue;
+
+		_dpu_dump_reg_by_blk(dbg_base, blk_base->name);
+	}
+}
+
+struct dpu_dbg_reg_base *_dpu_dump_get_blk_addr(struct dpu_dbg_base *dbg_base,
+		const char *blk_name)
+{
+	struct dpu_dbg_reg_base *blk_base;
+
+	list_for_each_entry(blk_base, &dbg_base->reg_base_list, reg_base_head)
+		if (strlen(blk_base->name) && !strcmp(blk_base->name, blk_name))
+			return blk_base;
+
+	return NULL;
+}
+
+void _dpu_dump_array(struct dpu_dbg_base *dbg_base,
+		struct dpu_dbg_reg_base *blk_arr[],
+		u32 len, bool do_panic, const char *name, bool dump_all)
+{
+	int i;
+
+	mutex_lock(&dbg_base->mutex);
+
+	if (dump_all || !blk_arr || !len) {
+		_dpu_dump_reg_all(dbg_base);
+	} else {
+		for (i = 0; i < len; i++) {
+			if (blk_arr[i] != NULL)
+				_dpu_dump_reg_by_ranges(dbg_base,
+						blk_arr[i],
+						dbg_base->enable_reg_dump);
+		}
+	}
+
+	if (do_panic)
+		panic(name);
+
+	mutex_unlock(&dbg_base->mutex);
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 3544af1a45c5..b2ab22be4c55 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
  */
 
 #ifndef _DPU_HW_CATALOG_H
@@ -52,6 +52,8 @@
 
 
 #define DPU_HW_BLK_NAME_LEN	16
+/* default size of valid register space for MDSS_HW block (offset 0) */
+#define DEFAULT_MDSS_HW_BLOCK_SIZE 0x5C
 
 #define MAX_IMG_WIDTH 0x3fff
 #define MAX_IMG_HEIGHT 0x3fff
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 49685571dc0e..f6fb0187388f 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved.
  * Copyright (C) 2013 Red Hat
  * Author: Rob Clark <robdclark@gmail.com>
  */
@@ -17,6 +17,7 @@
 #include <drm/drm_prime.h>
 #include <drm/drm_of.h>
 #include <drm/drm_vblank.h>
+#include "dpu_dbg.h"
 
 #include "msm_drv.h"
 #include "msm_debugfs.h"
@@ -268,6 +269,8 @@ static int msm_drm_uninit(struct device *dev)
 		msm_fbdev_free(ddev);
 #endif
 
+	dpu_dbg_destroy();
+
 	drm_mode_config_cleanup(ddev);
 
 	pm_runtime_get_sync(dev);
@@ -1303,6 +1306,7 @@ static int msm_pdev_probe(struct platform_device *pdev)
 
 fail:
 	of_platform_depopulate(&pdev->dev);
+	dpu_dbg_destroy();
 	return ret;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/4] drm/msm: register the base address with dpu_dbg module
  2020-10-22  5:01 [PATCH 0/4] Add devcoredump support for DPU Abhinav Kumar
  2020-10-22  5:01 ` [PATCH 1/4] drm: allow drm_atomic_print_state() to accept any drm_printer Abhinav Kumar
  2020-10-22  5:01 ` [PATCH 2/4] disp/msm/dpu: add support to dump dpu registers Abhinav Kumar
@ 2020-10-22  5:01 ` Abhinav Kumar
  2020-10-22  5:01 ` [PATCH 4/4] drm/msm/dpu: add dpu_dbg points across dpu driver Abhinav Kumar
  3 siblings, 0 replies; 11+ messages in thread
From: Abhinav Kumar @ 2020-10-22  5:01 UTC (permalink / raw)
  To: dri-devel
  Cc: Abhinav Kumar, linux-arm-msm, freedreno, robdclark, seanpaul,
	swboyd, nganji, aravindh, tanmay, khsieh

Register the base address of various dpu sub-modules with the
dpu_dbg module so that it can be dumped out during error scenarios.

Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c       |  4 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c    |  6 ++++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c   |  7 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c   |  5 +++-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c   |  6 ++++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c   |  8 +++++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c    |  7 ++++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c       | 12 +++++++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h       |  4 ++-
 drivers/gpu/drm/msm/dp/dp_catalog.c           | 12 +++++++++
 drivers/gpu/drm/msm/dp/dp_catalog.h           |  4 +++
 drivers/gpu/drm/msm/dp/dp_display.c           |  2 ++
 drivers/gpu/drm/msm/dsi/dsi_host.c            | 10 ++++++-
 drivers/gpu/drm/msm/msm_drv.c                 | 26 ++++++++++++++++++-
 drivers/gpu/drm/msm/msm_drv.h                 |  3 ++-
 15 files changed, 101 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c
index 6703e1555194..62f49e60a4ca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c
@@ -263,7 +263,7 @@ int dpu_dbg_reg_register_base(const char *name, void __iomem *base,
 	/* Initialize list to make sure check for null list will be valid */
 	INIT_LIST_HEAD(&reg_base->sub_range_list);
 
-	pr_debug("%s base: %pK max_offset 0x%zX\n", reg_base->name,
+	pr_info("%s base: %pK max_offset 0x%zX\n", reg_base->name,
 			reg_base->base, reg_base->max_offset);
 
 	list_add(&reg_base->reg_base_head, &dbg_base->reg_base_list);
@@ -310,7 +310,7 @@ void dpu_dbg_reg_register_dump_range(const char *base_name,
 	range->xin_id = xin_id;
 	list_add_tail(&range->head, &reg_base->sub_range_list);
 
-	pr_debug("base %s, range %s, start 0x%X, end 0x%X\n",
+	pr_info("base_name %s, range_name %s, start 0x%X, end 0x%X\n",
 			base_name, range->range_name,
 			range->offset.start, range->offset.end);
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 758c355b4fd8..3a827ea96723 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
  */
 
 #include <linux/delay.h>
@@ -7,6 +7,7 @@
 #include "dpu_hw_ctl.h"
 #include "dpu_kms.h"
 #include "dpu_trace.h"
+#include "dpu_dbg.h"
 
 #define   CTL_LAYER(lm)                 \
 	(((lm) == LM_5) ? (0x024) : (((lm) - LM_0) * 0x004))
@@ -588,6 +589,9 @@ struct dpu_hw_ctl *dpu_hw_ctl_init(enum dpu_ctl idx,
 
 	dpu_hw_blk_init(&c->base, DPU_HW_BLK_CTL, idx, &dpu_hw_ops);
 
+	dpu_dbg_reg_register_dump_range(DPU_DBG_NAME, cfg->name, c->hw.blk_off,
+			c->hw.blk_off + c->hw.length, c->hw.xin_id);
+
 	return c;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c
index a7a24539921f..ee9ae02f5e7f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
  */
 
 #include "dpu_hwio.h"
@@ -7,7 +7,7 @@
 #include "dpu_hw_lm.h"
 #include "dpu_hw_dspp.h"
 #include "dpu_kms.h"
-
+#include "dpu_dbg.h"
 
 /* DSPP_PCC */
 #define PCC_EN BIT(0)
@@ -115,6 +115,9 @@ struct dpu_hw_dspp *dpu_hw_dspp_init(enum dpu_dspp idx,
 
 	dpu_hw_blk_init(&c->base, DPU_HW_BLK_DSPP, idx, &dpu_hw_ops);
 
+	dpu_dbg_reg_register_dump_range(DPU_DBG_NAME, cfg->name, c->hw.blk_off,
+			c->hw.blk_off + c->hw.length, c->hw.xin_id);
+
 	return c;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index 6f0f54588124..d8198d4d42bc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -1,11 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
  */
 
 #include "dpu_hwio.h"
 #include "dpu_hw_catalog.h"
 #include "dpu_hw_intf.h"
 #include "dpu_kms.h"
+#include "dpu_dbg.h"
 
 #define INTF_TIMING_ENGINE_EN           0x000
 #define INTF_CONFIG                     0x004
@@ -319,6 +320,8 @@ struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx,
 
 	dpu_hw_blk_init(&c->base, DPU_HW_BLK_INTF, idx, &dpu_hw_ops);
 
+	dpu_dbg_reg_register_dump_range(DPU_DBG_NAME, cfg->name, c->hw.blk_off,
+			c->hw.blk_off + c->hw.length, c->hw.xin_id);
 	return c;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
index bea4ab5c58c5..0dc6d161e890 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
  */
 
 #include <linux/iopoll.h>
@@ -10,6 +10,7 @@
 #include "dpu_hw_pingpong.h"
 #include "dpu_kms.h"
 #include "dpu_trace.h"
+#include "dpu_dbg.h"
 
 #define PP_TEAR_CHECK_EN                0x000
 #define PP_SYNC_CONFIG_VSYNC            0x004
@@ -260,6 +261,9 @@ struct dpu_hw_pingpong *dpu_hw_pingpong_init(enum dpu_pingpong idx,
 
 	dpu_hw_blk_init(&c->base, DPU_HW_BLK_PINGPONG, idx, &dpu_hw_ops);
 
+	dpu_dbg_reg_register_dump_range(DPU_DBG_NAME, cfg->name, c->hw.blk_off,
+			c->hw.blk_off + c->hw.length, c->hw.xin_id);
+
 	return c;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index c940b69435e1..873fc828538d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
  */
 
 #include "dpu_hwio.h"
@@ -7,6 +7,7 @@
 #include "dpu_hw_lm.h"
 #include "dpu_hw_sspp.h"
 #include "dpu_kms.h"
+#include "dpu_dbg.h"
 
 #define DPU_FETCH_CONFIG_RESET_VALUE   0x00000087
 
@@ -736,6 +737,11 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
 
 	dpu_hw_blk_init(&hw_pipe->base, DPU_HW_BLK_SSPP, idx, &dpu_hw_ops);
 
+	dpu_dbg_reg_register_dump_range(DPU_DBG_NAME, cfg->name,
+			hw_pipe->hw.blk_off,
+			hw_pipe->hw.blk_off + hw_pipe->hw.length,
+			hw_pipe->hw.xin_id);
+
 	return hw_pipe;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
index 01b76766a9a8..f042471815cc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
@@ -1,11 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
  */
 
 #include "dpu_hwio.h"
 #include "dpu_hw_catalog.h"
 #include "dpu_hw_top.h"
 #include "dpu_kms.h"
+#include "dpu_dbg.h"
 
 #define SSPP_SPARE                        0x28
 
@@ -326,6 +327,10 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(enum dpu_mdp idx,
 
 	dpu_hw_blk_init(&mdp->base, DPU_HW_BLK_TOP, idx, &dpu_hw_ops);
 
+	dpu_dbg_reg_register_dump_range(DPU_DBG_NAME, cfg->name,
+			mdp->hw.blk_off, mdp->hw.blk_off + mdp->hw.length,
+			mdp->hw.xin_id);
+
 	return mdp;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index d93c44f6996d..dc64e032d82f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, 2020 The Linux Foundation. All rights reserved.
  * Copyright (C) 2013 Red Hat
  * Author: Rob Clark <robdclark@gmail.com>
  */
@@ -27,6 +27,7 @@
 #include "dpu_encoder.h"
 #include "dpu_plane.h"
 #include "dpu_crtc.h"
+#include "dpu_dbg.h"
 
 #define CREATE_TRACE_POINTS
 #include "dpu_trace.h"
@@ -908,7 +909,14 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 		dpu_kms->mmio = NULL;
 		goto error;
 	}
-	DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
+
+	dpu_kms->mmio_len = msm_iomap_size(dpu_kms->pdev, "mdp");
+
+	DRM_DEBUG("mapped dpu address space @%pK len = 0x%lx\n",
+			dpu_kms->mmio, dpu_kms->mmio_len);
+
+	dpu_dbg_reg_register_base(DPU_DBG_NAME,
+			dpu_kms->mmio, dpu_kms->mmio_len);
 
 	dpu_kms->vbif[VBIF_RT] = msm_ioremap(dpu_kms->pdev, "vbif", "vbif");
 	if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 1c0e4c0c9ffb..a478b40868dd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
  * Copyright (C) 2013 Red Hat
  * Author: Rob Clark <robdclark@gmail.com>
  */
@@ -103,6 +103,8 @@ struct dpu_kms {
 	/* io/register spaces: */
 	void __iomem *mmio, *vbif[VBIF_MAX], *reg_dma;
 
+	unsigned long mmio_len;
+
 	struct regulator *vdd;
 	struct regulator *mmagic;
 	struct regulator *venus;
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index b15b4ce4ba35..efde98a3d9ab 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -63,6 +63,18 @@ struct dp_catalog_private {
 	u8 aux_lut_cfg_index[PHY_AUX_CFG_MAX];
 };
 
+void dp_catalog_register_dbg_base(struct dp_catalog *dp_catalog)
+{
+	char dbg_name[32];
+	struct dp_catalog_private *catalog = container_of(dp_catalog,
+			struct dp_catalog_private, dp_catalog);
+
+	snprintf(dbg_name, 32, "dp_ctrl");
+
+	dpu_dbg_reg_register_base(dbg_name, catalog->io->dp_controller.base,
+			catalog->io->dp_controller.len);
+}
+
 static inline u32 dp_read_aux(struct dp_catalog_private *catalog, u32 offset)
 {
 	offset += MSM_DP_CONTROLLER_AUX_OFFSET;
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 4b7666f1fe6f..af48590913e3 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -9,6 +9,7 @@
 #include <drm/drm_modes.h>
 
 #include "dp_parser.h"
+#include "dpu_dbg.h"
 
 /* interrupts */
 #define DP_INTR_HPD		BIT(0)
@@ -71,6 +72,9 @@ struct dp_catalog {
 	u32 audio_data;
 };
 
+/* Debug module */
+void dp_catalog_register_dbg_base(struct dp_catalog *dp_catalog);
+
 /* AUX APIs */
 u32 dp_catalog_aux_read_data(struct dp_catalog *dp_catalog);
 int dp_catalog_aux_write_data(struct dp_catalog *dp_catalog);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index e175aa3fd3a9..4a5735564be2 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -230,6 +230,8 @@ static int dp_display_bind(struct device *dev, struct device *master,
 	if (rc)
 		DRM_ERROR("Audio registration Dp failed\n");
 
+	dp_catalog_register_dbg_base(dp->catalog);
+
 end:
 	return rc;
 }
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index b17ac6c27554..97c04d31f289 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, 2020 The Linux Foundation. All rights reserved.
  */
 
 #include <linux/clk.h>
@@ -26,6 +26,8 @@
 #include "sfpb.xml.h"
 #include "dsi_cfg.h"
 #include "msm_kms.h"
+#include "dpu_dbg.h"
+#include "msm_drv.h"
 
 #define DSI_RESET_TOGGLE_DELAY_MS 20
 
@@ -1823,6 +1825,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
 	struct msm_dsi_host *msm_host = NULL;
 	struct platform_device *pdev = msm_dsi->pdev;
 	int ret;
+	char dbg_name[32];
 
 	msm_host = devm_kzalloc(&pdev->dev, sizeof(*msm_host), GFP_KERNEL);
 	if (!msm_host) {
@@ -1912,6 +1915,11 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
 
 	msm_dsi->id = msm_host->id;
 
+	snprintf(dbg_name, 32, "dsi%d_ctrl",
+			msm_host->id);
+	dpu_dbg_reg_register_base(dbg_name, msm_host->ctrl_base,
+			msm_iomap_size(pdev, "dsi_ctrl"));
+
 	DBG("Dsi Host %d initialized", msm_host->id);
 	return 0;
 
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index f6fb0187388f..df505a3d53e8 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -17,8 +17,8 @@
 #include <drm/drm_prime.h>
 #include <drm/drm_of.h>
 #include <drm/drm_vblank.h>
-#include "dpu_dbg.h"
 
+#include "dpu_dbg.h"
 #include "msm_drv.h"
 #include "msm_debugfs.h"
 #include "msm_fence.h"
@@ -166,6 +166,24 @@ void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name,
 	return _msm_ioremap(pdev, name, dbgname, true);
 }
 
+unsigned long msm_iomap_size(struct platform_device *pdev, const char *name)
+{
+	struct resource *res;
+
+	if (name)
+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
+	else
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!res) {
+		dev_dbg(&pdev->dev, "failed to get memory resource: %s\n",
+				name);
+		return 0;
+	}
+
+	return resource_size(res);
+}
+
 void msm_writel(u32 data, void __iomem *addr)
 {
 	if (reglog)
@@ -535,6 +553,8 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	if (ret)
 		goto err_msm_uninit;
 
+	dpu_dbg_register_drm_dev(ddev);
+
 	drm_mode_config_reset(ddev);
 
 #ifdef CONFIG_DRM_FBDEV_EMULATION
@@ -1282,6 +1302,10 @@ static int msm_pdev_probe(struct platform_device *pdev)
 	int ret;
 
 	if (get_mdp_ver(pdev)) {
+		ret = dpu_dbg_init(&pdev->dev);
+		if (ret)
+			pr_err("dpu_dbg_init failed ret = %d\n", ret);
+
 		ret = add_display_components(&pdev->dev, &match);
 		if (ret)
 			return ret;
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index b9dd8f8f4887..211161bdce2f 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved.
  * Copyright (C) 2013 Red Hat
  * Author: Rob Clark <robdclark@gmail.com>
  */
@@ -476,6 +476,7 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
 		const char *dbgname);
 void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name,
 		const char *dbgname);
+unsigned long msm_iomap_size(struct platform_device *pdev, const char *name);
 void msm_writel(u32 data, void __iomem *addr);
 u32 msm_readl(const void __iomem *addr);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/4] drm/msm/dpu: add dpu_dbg points across dpu driver
  2020-10-22  5:01 [PATCH 0/4] Add devcoredump support for DPU Abhinav Kumar
                   ` (2 preceding siblings ...)
  2020-10-22  5:01 ` [PATCH 3/4] drm/msm: register the base address with dpu_dbg module Abhinav Kumar
@ 2020-10-22  5:01 ` Abhinav Kumar
  3 siblings, 0 replies; 11+ messages in thread
From: Abhinav Kumar @ 2020-10-22  5:01 UTC (permalink / raw)
  To: dri-devel
  Cc: Abhinav Kumar, linux-arm-msm, freedreno, robdclark, seanpaul,
	swboyd, nganji, aravindh, tanmay, khsieh

Add dpu_dbg points across dpu driver to trigger dumps when critical
errors are hit.

Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c          | 12 ++++++++++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c |  5 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c |  5 ++++-
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index f7f5c258b553..a2ee1af73c9f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, 2020 The Linux Foundation. All rights reserved.
  * Copyright (C) 2013 Red Hat
  * Author: Rob Clark <robdclark@gmail.com>
  */
@@ -26,6 +26,7 @@
 #include "dpu_crtc.h"
 #include "dpu_trace.h"
 #include "dpu_core_irq.h"
+#include "dpu_dbg.h"
 
 #define DPU_DEBUG_ENC(e, fmt, ...) DPU_DEBUG("enc%d " fmt,\
 		(e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
@@ -1313,6 +1314,11 @@ static void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
 
 	DPU_ATRACE_BEGIN("encoder_underrun_callback");
 	atomic_inc(&phy_enc->underrun_cnt);
+
+	/* trigger dump only on the first underrun */
+	if (atomic_read(&phy_enc->underrun_cnt) == 1)
+		DPU_DBG_DUMP("all");
+
 	trace_dpu_enc_underrun_cb(DRMID(drm_enc),
 				  atomic_read(&phy_enc->underrun_cnt));
 	DPU_ATRACE_END("encoder_underrun_callback");
@@ -1553,8 +1559,10 @@ static void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc)
 		      ctl->idx);
 
 	rc = ctl->ops.reset(ctl);
-	if (rc)
+	if (rc) {
 		DPU_ERROR_ENC(dpu_enc, "ctl %d reset failure\n",  ctl->idx);
+		DPU_DBG_DUMP("all");
+	}
 
 	phys_enc->enable_state = DPU_ENC_ENABLED;
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index 8493d68ad841..58f79557b560 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
  */
 
 #define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
@@ -9,6 +9,7 @@
 #include "dpu_core_irq.h"
 #include "dpu_formats.h"
 #include "dpu_trace.h"
+#include "dpu_dbg.h"
 
 #define DPU_DEBUG_CMDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
 		(e) && (e)->base.parent ? \
@@ -213,7 +214,7 @@ static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
 			  phys_enc->hw_ctl->idx - CTL_0,
 			  cmd_enc->pp_timeout_report_cnt,
 			  atomic_read(&phys_enc->pending_kickoff_cnt));
-
+		DPU_DBG_DUMP("all");
 		dpu_encoder_helper_unregister_irq(phys_enc, INTR_IDX_RDPTR);
 	}
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 805e059b50b7..46c5320150fa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
  */
 
 #define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
@@ -8,6 +8,7 @@
 #include "dpu_core_irq.h"
 #include "dpu_formats.h"
 #include "dpu_trace.h"
+#include "dpu_dbg.h"
 
 #define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
 		(e) && (e)->parent ? \
@@ -467,6 +468,7 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
 		"update pending flush ctl %d flush_mask 0%x intf_mask 0x%x\n",
 		ctl->idx - CTL_0, flush_mask, intf_flush_mask);
 
+	atomic_set(&phys_enc->underrun_cnt, 0);
 
 	/* ctl_flush & timing engine enable will be triggered by framework */
 	if (phys_enc->enable_state == DPU_ENC_DISABLED)
@@ -549,6 +551,7 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff(
 	if (rc) {
 		DPU_ERROR_VIDENC(phys_enc, "ctl %d reset failure: %d\n",
 				ctl->idx, rc);
+		DPU_DBG_DUMP("all");
 		dpu_encoder_helper_unregister_irq(phys_enc, INTR_IDX_VSYNC);
 	}
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] disp/msm/dpu: add support to dump dpu registers
  2020-10-22  5:01 ` [PATCH 2/4] disp/msm/dpu: add support to dump dpu registers Abhinav Kumar
@ 2020-10-22  8:29   ` kernel test robot
  2020-10-27 14:15   ` kernel test robot
  1 sibling, 0 replies; 11+ messages in thread
From: kernel test robot @ 2020-10-22  8:29 UTC (permalink / raw)
  To: Abhinav Kumar, dri-devel
  Cc: kbuild-all, linux-arm-msm, Abhinav Kumar, swboyd, khsieh,
	seanpaul, tanmay, aravindh, freedreno

[-- Attachment #1: Type: text/plain, Size: 3831 bytes --]

Hi Abhinav,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-exynos/exynos-drm-next]
[also build test WARNING on drm-intel/for-linux-next tegra-drm/drm/tegra/for-next drm-tip/drm-tip linus/master v5.9 next-20201022]
[cannot apply to drm/drm-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Abhinav-Kumar/Add-devcoredump-support-for-DPU/20201022-130507
base:   https://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git exynos-drm-next
config: arm-defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/a7e6907c303a46ea8422fc3c414c22fdfb45d49f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Abhinav-Kumar/Add-devcoredump-support-for-DPU/20201022-130507
        git checkout a7e6907c303a46ea8422fc3c414c22fdfb45d49f
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c: In function 'dpu_dbg_dump':
>> drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c:115:6: warning: variable 'i' set but not used [-Wunused-but-set-variable]
     115 |  int i, index = 0;
         |      ^

vim +/i +115 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c

   112	
   113	void dpu_dbg_dump(enum dpu_dbg_dump_context dump_mode, const char *name, ...)
   114	{
 > 115		int i, index = 0;
   116		bool do_panic = false;
   117		bool dump_all = false;
   118		va_list args;
   119		char *blk_name = NULL;
   120		struct dpu_dbg_reg_base *blk_base = NULL;
   121		struct dpu_dbg_reg_base **blk_arr;
   122		u32 blk_len;
   123	
   124		/*
   125		 * if there is a coredump pending return immediately till dump
   126		 * if read by userspace or timeout happens
   127		 */
   128		if (((dpu_dbg.enable_reg_dump == DPU_DBG_DUMP_IN_MEM) ||
   129			 (dpu_dbg.enable_reg_dump == DPU_DBG_DUMP_IN_COREDUMP)) &&
   130			dpu_dbg.coredump_pending) {
   131			pr_debug("coredump is pending read\n");
   132			return;
   133		}
   134	
   135		blk_arr = &dpu_dbg.req_dump_blks[0];
   136		blk_len = ARRAY_SIZE(dpu_dbg.req_dump_blks);
   137	
   138		memset(dpu_dbg.req_dump_blks, 0,
   139				sizeof(dpu_dbg.req_dump_blks));
   140		dpu_dbg.dump_all = false;
   141		dpu_dbg.dump_mode = dump_mode;
   142	
   143		va_start(args, name);
   144		i = 0;
   145		while ((blk_name = va_arg(args, char*))) {
   146	
   147			if (IS_ERR_OR_NULL(blk_name))
   148				break;
   149	
   150			blk_base = _dpu_dump_get_blk_addr(&dpu_dbg, blk_name);
   151			if (blk_base) {
   152				if (index < blk_len) {
   153					blk_arr[index] = blk_base;
   154					index++;
   155				} else {
   156					pr_err("insufficient space to dump %s\n",
   157							blk_name);
   158				}
   159			}
   160	
   161			if (!strcmp(blk_name, "all"))
   162				dump_all = true;
   163	
   164			if (!strcmp(blk_name, "panic"))
   165				do_panic = true;
   166	
   167		}
   168		va_end(args);
   169	
   170		dpu_dbg.work_panic = do_panic;
   171		dpu_dbg.dump_all = dump_all;
   172	
   173		kthread_queue_work(dpu_dbg.dump_worker,
   174				&dpu_dbg.dump_work);
   175	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 53087 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] drm: allow drm_atomic_print_state() to accept any drm_printer
  2020-10-22  5:01 ` [PATCH 1/4] drm: allow drm_atomic_print_state() to accept any drm_printer Abhinav Kumar
@ 2020-10-22 10:10   ` kernel test robot
  2020-10-22 10:38   ` Daniel Vetter
  2020-10-27  7:14   ` kernel test robot
  2 siblings, 0 replies; 11+ messages in thread
From: kernel test robot @ 2020-10-22 10:10 UTC (permalink / raw)
  To: Abhinav Kumar, dri-devel
  Cc: kbuild-all, linux-arm-msm, Abhinav Kumar, swboyd, khsieh,
	seanpaul, tanmay, aravindh, freedreno

[-- Attachment #1: Type: text/plain, Size: 2757 bytes --]

Hi Abhinav,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-exynos/exynos-drm-next]
[also build test WARNING on drm-intel/for-linux-next tegra-drm/drm/tegra/for-next drm-tip/drm-tip linus/master v5.9 next-20201022]
[cannot apply to drm/drm-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Abhinav-Kumar/Add-devcoredump-support-for-DPU/20201022-130507
base:   https://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git exynos-drm-next
config: microblaze-randconfig-r003-20201022 (attached as .config)
compiler: microblaze-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/76add8f28420cad0b0d2977abed6e031ef307f32
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Abhinav-Kumar/Add-devcoredump-support-for-DPU/20201022-130507
        git checkout 76add8f28420cad0b0d2977abed6e031ef307f32
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=microblaze 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/selftests/test-drm_framebuffer.c:12:
>> drivers/gpu/drm/selftests/../drm_crtc_internal.h:238:10: warning: 'struct drm_printer' declared inside parameter list will not be visible outside of this definition or declaration
     238 |   struct drm_printer *p);
         |          ^~~~~~~~~~~
   drivers/gpu/drm/selftests/test-drm_framebuffer.c: In function 'execute_drm_mode_fb_cmd2':
   drivers/gpu/drm/selftests/test-drm_framebuffer.c:333:26: warning: variable 'fb' set but not used [-Wunused-but-set-variable]
     333 |  struct drm_framebuffer *fb;
         |                          ^~

vim +238 drivers/gpu/drm/selftests/../drm_crtc_internal.h

   231	
   232	int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
   233					      struct drm_plane_state *plane_state);
   234	int __drm_atomic_helper_set_config(struct drm_mode_set *set,
   235					   struct drm_atomic_state *state);
   236	
   237	void drm_atomic_print_state(const struct drm_atomic_state *state,
 > 238			struct drm_printer *p);
   239	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 29070 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] drm: allow drm_atomic_print_state() to accept any drm_printer
  2020-10-22  5:01 ` [PATCH 1/4] drm: allow drm_atomic_print_state() to accept any drm_printer Abhinav Kumar
  2020-10-22 10:10   ` kernel test robot
@ 2020-10-22 10:38   ` Daniel Vetter
  2020-10-30  1:12     ` abhinavk
  2020-10-27  7:14   ` kernel test robot
  2 siblings, 1 reply; 11+ messages in thread
From: Daniel Vetter @ 2020-10-22 10:38 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: dri-devel, linux-arm-msm, swboyd, khsieh, seanpaul, tanmay,
	aravindh, freedreno

On Wed, Oct 21, 2020 at 10:01:45PM -0700, Abhinav Kumar wrote:
> Currently drm_atomic_print_state() internally allocates and uses a
> drm_info printer. Allow it to accept any drm_printer type so that
> the API can be leveraged even for taking drm snapshot.
> 
> Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
> ---
>  drivers/gpu/drm/drm_atomic.c        | 17 ++++++++++++-----
>  drivers/gpu/drm/drm_atomic_uapi.c   |  4 +++-
>  drivers/gpu/drm/drm_crtc_internal.h |  4 +++-
>  3 files changed, 18 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 58527f151984..e7079a5f439c 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -1,6 +1,7 @@
>  /*
>   * Copyright (C) 2014 Red Hat
>   * Copyright (C) 2014 Intel Corp.
> + * Copyright (c) 2020, The Linux Foundation. All rights reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining a
>   * copy of this software and associated documentation files (the "Software"),
> @@ -1543,9 +1544,9 @@ int __drm_atomic_helper_set_config(struct drm_mode_set *set,
>  }
>  EXPORT_SYMBOL(__drm_atomic_helper_set_config);
>  
> -void drm_atomic_print_state(const struct drm_atomic_state *state)
> +void drm_atomic_print_state(const struct drm_atomic_state *state,
> +		struct drm_printer *p)

Please add a nice kerneldoc for this newly exported function. Specifically
this kerneldoc needs to include a warning that state updates after call
drm_atomic_state_helper_commit_hw_done() is unsafe to print using this
function, because it looks at the new state objects. Only the old state
structures will stay like this.

So maybe rename the function to say print_new_state() to make this
completely clear. That way we can eventually add a print_old_state() when
needed.

Otherwise I think this makes sense, and nicely avoids the locking issue of
looking at ->state pointers without the right locking.
-Daniel

>  {
> -	struct drm_printer p = drm_info_printer(state->dev->dev);
>  	struct drm_plane *plane;
>  	struct drm_plane_state *plane_state;
>  	struct drm_crtc *crtc;
> @@ -1554,17 +1555,23 @@ void drm_atomic_print_state(const struct drm_atomic_state *state)
>  	struct drm_connector_state *connector_state;
>  	int i;
>  
> +	if (!p) {
> +		DRM_ERROR("invalid drm printer\n");
> +		return;
> +	}
> +
>  	DRM_DEBUG_ATOMIC("checking %p\n", state);
>  
>  	for_each_new_plane_in_state(state, plane, plane_state, i)
> -		drm_atomic_plane_print_state(&p, plane_state);
> +		drm_atomic_plane_print_state(p, plane_state);
>  
>  	for_each_new_crtc_in_state(state, crtc, crtc_state, i)
> -		drm_atomic_crtc_print_state(&p, crtc_state);
> +		drm_atomic_crtc_print_state(p, crtc_state);
>  
>  	for_each_new_connector_in_state(state, connector, connector_state, i)
> -		drm_atomic_connector_print_state(&p, connector_state);
> +		drm_atomic_connector_print_state(p, connector_state);
>  }
> +EXPORT_SYMBOL(drm_atomic_print_state);
>  
>  static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p,
>  			     bool take_locks)
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index 25c269bc4681..d9ae86c92608 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -2,6 +2,7 @@
>   * Copyright (C) 2014 Red Hat
>   * Copyright (C) 2014 Intel Corp.
>   * Copyright (C) 2018 Intel Corp.
> + * Copyright (c) 2020, The Linux Foundation. All rights reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining a
>   * copy of this software and associated documentation files (the "Software"),
> @@ -1294,6 +1295,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
>  	struct drm_out_fence_state *fence_state;
>  	int ret = 0;
>  	unsigned int i, j, num_fences;
> +	struct drm_printer p = drm_info_printer(dev->dev);
>  
>  	/* disallow for drivers not supporting atomic: */
>  	if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
> @@ -1413,7 +1415,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
>  		ret = drm_atomic_nonblocking_commit(state);
>  	} else {
>  		if (drm_debug_enabled(DRM_UT_STATE))
> -			drm_atomic_print_state(state);
> +			drm_atomic_print_state(state, &p);
>  
>  		ret = drm_atomic_commit(state);
>  	}
> diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
> index da96b2f64d7e..d34215366936 100644
> --- a/drivers/gpu/drm/drm_crtc_internal.h
> +++ b/drivers/gpu/drm/drm_crtc_internal.h
> @@ -5,6 +5,7 @@
>   *   Jesse Barnes <jesse.barnes@intel.com>
>   * Copyright © 2014 Intel Corporation
>   *   Daniel Vetter <daniel.vetter@ffwll.ch>
> + * Copyright (c) 2020, The Linux Foundation. All rights reserved.
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining a
>   * copy of this software and associated documentation files (the "Software"),
> @@ -233,7 +234,8 @@ int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
>  int __drm_atomic_helper_set_config(struct drm_mode_set *set,
>  				   struct drm_atomic_state *state);
>  
> -void drm_atomic_print_state(const struct drm_atomic_state *state);
> +void drm_atomic_print_state(const struct drm_atomic_state *state,
> +		struct drm_printer *p);
>  
>  /* drm_atomic_uapi.c */
>  int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] drm: allow drm_atomic_print_state() to accept any drm_printer
  2020-10-22  5:01 ` [PATCH 1/4] drm: allow drm_atomic_print_state() to accept any drm_printer Abhinav Kumar
  2020-10-22 10:10   ` kernel test robot
  2020-10-22 10:38   ` Daniel Vetter
@ 2020-10-27  7:14   ` kernel test robot
  2 siblings, 0 replies; 11+ messages in thread
From: kernel test robot @ 2020-10-27  7:14 UTC (permalink / raw)
  To: Abhinav Kumar, dri-devel
  Cc: kbuild-all, clang-built-linux, linux-arm-msm, Abhinav Kumar,
	swboyd, khsieh, seanpaul, tanmay, aravindh, freedreno

[-- Attachment #1: Type: text/plain, Size: 2632 bytes --]

Hi Abhinav,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-exynos/exynos-drm-next]
[also build test WARNING on drm-intel/for-linux-next tegra-drm/drm/tegra/for-next drm-tip/drm-tip linus/master v5.10-rc1 next-20201026]
[cannot apply to drm/drm-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Abhinav-Kumar/Add-devcoredump-support-for-DPU/20201022-130507
base:   https://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git exynos-drm-next
config: mips-randconfig-r014-20201026 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project f2c25c70791de95d2466e09b5b58fc37f6ccd7a4)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install mips cross compiling tool for clang build
        # apt-get install binutils-mips-linux-gnu
        # https://github.com/0day-ci/linux/commit/76add8f28420cad0b0d2977abed6e031ef307f32
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Abhinav-Kumar/Add-devcoredump-support-for-DPU/20201022-130507
        git checkout 76add8f28420cad0b0d2977abed6e031ef307f32
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=mips 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/selftests/test-drm_framebuffer.c:12:
>> drivers/gpu/drm/selftests/../drm_crtc_internal.h:238:10: warning: declaration of 'struct drm_printer' will not be visible outside of this function [-Wvisibility]
                   struct drm_printer *p);
                          ^
   1 warning generated.

vim +238 drivers/gpu/drm/selftests/../drm_crtc_internal.h

   231	
   232	int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
   233					      struct drm_plane_state *plane_state);
   234	int __drm_atomic_helper_set_config(struct drm_mode_set *set,
   235					   struct drm_atomic_state *state);
   236	
   237	void drm_atomic_print_state(const struct drm_atomic_state *state,
 > 238			struct drm_printer *p);
   239	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 31484 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] disp/msm/dpu: add support to dump dpu registers
  2020-10-22  5:01 ` [PATCH 2/4] disp/msm/dpu: add support to dump dpu registers Abhinav Kumar
  2020-10-22  8:29   ` kernel test robot
@ 2020-10-27 14:15   ` kernel test robot
  1 sibling, 0 replies; 11+ messages in thread
From: kernel test robot @ 2020-10-27 14:15 UTC (permalink / raw)
  To: Abhinav Kumar, dri-devel
  Cc: kbuild-all, linux-arm-msm, Abhinav Kumar, swboyd, khsieh,
	seanpaul, tanmay, aravindh, freedreno

[-- Attachment #1: Type: text/plain, Size: 12523 bytes --]

Hi Abhinav,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-exynos/exynos-drm-next]
[also build test WARNING on drm-intel/for-linux-next tegra-drm/drm/tegra/for-next drm-tip/drm-tip linus/master v5.10-rc1 next-20201027]
[cannot apply to drm/drm-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Abhinav-Kumar/Add-devcoredump-support-for-DPU/20201022-130507
base:   https://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git exynos-drm-next
config: arm64-randconfig-s032-20201026 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.3-56-gc09e8239-dirty
        # https://github.com/0day-ci/linux/commit/a7e6907c303a46ea8422fc3c414c22fdfb45d49f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Abhinav-Kumar/Add-devcoredump-support-for-DPU/20201022-130507
        git checkout a7e6907c303a46ea8422fc3c414c22fdfb45d49f
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


"sparse warnings: (new ones prefixed by >>)"
>> drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:99:50: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got char * @@
>> drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:99:50: sparse:     expected void const volatile [noderef] __iomem *addr
>> drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:99:50: sparse:     got char *
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:100:56: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got char * @@
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:100:56: sparse:     expected void const volatile [noderef] __iomem *addr
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:100:56: sparse:     got char *
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:102:56: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got char * @@
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:102:56: sparse:     expected void const volatile [noderef] __iomem *addr
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:102:56: sparse:     got char *
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:104:56: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got char * @@
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:104:56: sparse:     expected void const volatile [noderef] __iomem *addr
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:104:56: sparse:     got char *
>> drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:211:30: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected char *addr @@     got void [noderef] __iomem * @@
>> drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:211:30: sparse:     expected char *addr
>> drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:211:30: sparse:     got void [noderef] __iomem *
>> drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:220:44: sparse: sparse: incorrect type in argument 4 (different address spaces) @@     expected char *base_addr @@     got void [noderef] __iomem *base @@
>> drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:220:44: sparse:     expected char *base_addr
>> drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:220:44: sparse:     got void [noderef] __iomem *base
>> drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:229:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected char *addr @@     got void [noderef] __iomem *base @@
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:229:22: sparse:     expected char *addr
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:229:22: sparse:     got void [noderef] __iomem *base
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:232:36: sparse: sparse: incorrect type in argument 4 (different address spaces) @@     expected char *base_addr @@     got void [noderef] __iomem *base @@
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:232:36: sparse:     expected char *base_addr
   drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c:232:36: sparse:     got void [noderef] __iomem *base

vim +99 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg_util.c

    20	
    21	/**
    22	 * _dpu_dump_reg - helper function for dumping rotator register set content
    23	 * @dump_name: register set name
    24	 * @reg_dump_flag: dumping flag controlling in-log/memory dump location
    25	 * @base_addr: starting address of io region for calculating offsets to print
    26	 * @addr: starting address offset for dumping
    27	 * @len_bytes: range of the register set
    28	 * @dump_mem: output buffer for memory dump location option
    29	 * @from_isr: whether being called from isr context
    30	 */
    31	static void _dpu_dump_reg(struct dpu_dbg_base *dbg_base,
    32			const char *dump_name, u32 reg_dump_flag,
    33			char *base_addr, char *addr, size_t len_bytes, u32 **dump_mem)
    34	{
    35		u32 in_log, in_mem, len_align, len_padded, in_dump;
    36		u32 *dump_addr = NULL;
    37		char *end_addr;
    38		int i;
    39		int rc;
    40	
    41		if (!len_bytes)
    42			return;
    43	
    44		in_log = (reg_dump_flag & DPU_DBG_DUMP_IN_LOG);
    45		in_mem = (reg_dump_flag & DPU_DBG_DUMP_IN_MEM);
    46		in_dump = (reg_dump_flag & DPU_DBG_DUMP_IN_COREDUMP);
    47	
    48		pr_debug("%s: reg_dump_flag=%d in_log=%d in_mem=%d\n",
    49			dump_name, reg_dump_flag, in_log, in_mem);
    50	
    51		if (!in_log && !in_mem && !in_dump)
    52			return;
    53	
    54		if (in_log)
    55			dev_info(dbg_base->dev, "%s: start_offset 0x%lx len 0x%zx\n",
    56					dump_name, (unsigned long)(addr - base_addr),
    57						len_bytes);
    58	
    59		len_align = (len_bytes + REG_DUMP_ALIGN - 1) / REG_DUMP_ALIGN;
    60		len_padded = len_align * REG_DUMP_ALIGN;
    61		end_addr = addr + len_bytes;
    62	
    63		if (in_mem || in_dump) {
    64			if (dump_mem && !(*dump_mem))
    65				*dump_mem = devm_kzalloc(dbg_base->dev, len_padded,
    66						GFP_KERNEL);
    67	
    68			if (dump_mem && *dump_mem) {
    69				dump_addr = *dump_mem;
    70				dev_info(dbg_base->dev,
    71					"%s: start_addr:0x%pK len:0x%x reg_offset=0x%lx\n",
    72					dump_name, dump_addr, len_padded,
    73					(unsigned long)(addr - base_addr));
    74				if (in_dump)
    75					drm_printf(dbg_base->dpu_dbg_printer,
    76							"%s: start_addr:0x%pK len:0x%x reg_offset=0x%lx\n",
    77							dump_name, dump_addr,
    78							len_padded,
    79							(unsigned long)(addr -
    80							base_addr));
    81			} else {
    82				in_mem = 0;
    83				pr_err("dump_mem: kzalloc fails!\n");
    84			}
    85		}
    86	
    87		if (_dpu_power_check(dbg_base->dump_mode)) {
    88			rc = pm_runtime_get_sync(dbg_base->dev);
    89			if (rc < 0) {
    90				pr_err("failed to enable power %d\n", rc);
    91				return;
    92			}
    93		}
    94	
    95		for (i = 0; i < len_align; i++) {
    96			u32 x0, x4, x8, xc;
    97	
    98			if (in_log || in_mem) {
  > 99				x0 = (addr < end_addr) ? readl_relaxed(addr + 0x0) : 0;
   100				x4 = (addr + 0x4 < end_addr) ? readl_relaxed(addr +
   101						0x4) : 0;
   102				x8 = (addr + 0x8 < end_addr) ? readl_relaxed(addr +
   103						0x8) : 0;
   104				xc = (addr + 0xc < end_addr) ? readl_relaxed(addr +
   105						0xc) : 0;
   106			}
   107	
   108			if (in_log)
   109				dev_info(dbg_base->dev,
   110						"0x%lx : %08x %08x %08x %08x\n",
   111						(unsigned long)(addr - base_addr),
   112						x0, x4, x8, xc);
   113	
   114			if (dump_addr && in_mem) {
   115				dump_addr[i * 4] = x0;
   116				dump_addr[i * 4 + 1] = x4;
   117				dump_addr[i * 4 + 2] = x8;
   118				dump_addr[i * 4 + 3] = xc;
   119			}
   120	
   121			if (in_dump) {
   122				drm_printf(dbg_base->dpu_dbg_printer,
   123						"0x%lx : %08x %08x %08x %08x\n",
   124						(unsigned long)(addr - base_addr),
   125						dump_addr[i * 4],
   126						dump_addr[i * 4 + 1],
   127						dump_addr[i * 4 + 2],
   128						dump_addr[i * 4 + 3]);
   129	
   130			}
   131	
   132			addr += REG_DUMP_ALIGN;
   133		}
   134	
   135		if (_dpu_power_check(dbg_base->dump_mode))
   136			pm_runtime_put_sync(dbg_base->dev);
   137	}
   138	
   139	/**
   140	 * _dpu_dbg_get_dump_range - helper to retrieve dump length for a range node
   141	 * @range_node: range node to dump
   142	 * @max_offset: max offset of the register base
   143	 * @Return: length
   144	 */
   145	static u32 _dpu_dbg_get_dump_range(struct dpu_dbg_reg_offset *range_node,
   146			size_t max_offset)
   147	{
   148		u32 length = 0;
   149	
   150		if (range_node->start == 0 && range_node->end == 0) {
   151			length = max_offset;
   152		} else if (range_node->start < max_offset) {
   153			if (range_node->end > max_offset)
   154				length = max_offset - range_node->start;
   155			else if (range_node->start < range_node->end)
   156				length = range_node->end - range_node->start;
   157		}
   158	
   159		return length;
   160	}
   161	
   162	static int _dpu_dump_reg_range_cmp(void *priv, struct list_head *a,
   163			struct list_head *b)
   164	{
   165		struct dpu_dbg_reg_range *ar, *br;
   166	
   167		if (!a || !b)
   168			return 0;
   169	
   170		ar = container_of(a, struct dpu_dbg_reg_range, head);
   171		br = container_of(b, struct dpu_dbg_reg_range, head);
   172	
   173		return ar->offset.start - br->offset.start;
   174	}
   175	
   176	/**
   177	 * _dpu_dump_reg_by_ranges - dump ranges or full range of the register blk base
   178	 * @dbg: register blk base structure
   179	 * @reg_dump_flag: dump target, memory, kernel log, or both
   180	 */
   181	static void _dpu_dump_reg_by_ranges(struct dpu_dbg_base *dbg_base,
   182			struct dpu_dbg_reg_base *dbg,
   183			u32 reg_dump_flag)
   184	{
   185		char *addr;
   186		size_t len;
   187		struct dpu_dbg_reg_range *range_node;
   188	
   189		if (!dbg || !(dbg->base || dbg->cb)) {
   190			pr_err("dbg base is null!\n");
   191			return;
   192		}
   193	
   194		dev_info(dbg_base->dev, "%s:=========%s DUMP=========\n", __func__,
   195				dbg->name);
   196	
   197		if (reg_dump_flag & DPU_DBG_DUMP_IN_COREDUMP)
   198			drm_printf(dbg_base->dpu_dbg_printer,
   199					"%s:=========%s DUMP=========\n",
   200					__func__, dbg->name);
   201	
   202		if (dbg->cb) {
   203			dbg->cb(dbg->cb_ptr);
   204		/* If there is a list to dump the registers by ranges, use the ranges */
   205		} else if (!list_empty(&dbg->sub_range_list)) {
   206			/* sort the list by start address first */
   207			list_sort(NULL, &dbg->sub_range_list, _dpu_dump_reg_range_cmp);
   208			list_for_each_entry(range_node, &dbg->sub_range_list, head) {
   209				len = _dpu_dbg_get_dump_range(&range_node->offset,
   210					dbg->max_offset);
 > 211				addr = dbg->base + range_node->offset.start;
   212	
   213				pr_debug("%s: range_base=0x%pK start=0x%x end=0x%x\n",
   214					range_node->range_name,
   215					addr, range_node->offset.start,
   216					range_node->offset.end);
   217	
   218				_dpu_dump_reg(dbg_base, range_node->range_name,
   219						reg_dump_flag,
 > 220						dbg->base, addr, len,
   221						&range_node->reg_dump);
   222			}
   223		} else {
   224			/* If there is no list to dump ranges, dump all registers */
   225			dev_info(dbg_base->dev,
   226					"Ranges not found, will dump full registers\n");
   227			dev_info(dbg_base->dev, "base:0x%pK len:0x%zx\n", dbg->base,
   228					dbg->max_offset);
 > 229			addr = dbg->base;
   230			len = dbg->max_offset;
   231			_dpu_dump_reg(dbg_base, dbg->name, reg_dump_flag,
   232					dbg->base, addr, len,
   233					&dbg->reg_dump);
   234		}
   235	}
   236	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 35412 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] drm: allow drm_atomic_print_state() to accept any drm_printer
  2020-10-22 10:38   ` Daniel Vetter
@ 2020-10-30  1:12     ` abhinavk
  0 siblings, 0 replies; 11+ messages in thread
From: abhinavk @ 2020-10-30  1:12 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: dri-devel, linux-arm-msm, swboyd, khsieh, seanpaul, tanmay,
	aravindh, freedreno

Hi Daniel

On 2020-10-22 03:38, Daniel Vetter wrote:
> On Wed, Oct 21, 2020 at 10:01:45PM -0700, Abhinav Kumar wrote:
>> Currently drm_atomic_print_state() internally allocates and uses a
>> drm_info printer. Allow it to accept any drm_printer type so that
>> the API can be leveraged even for taking drm snapshot.
>> 
>> Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
>> ---
>>  drivers/gpu/drm/drm_atomic.c        | 17 ++++++++++++-----
>>  drivers/gpu/drm/drm_atomic_uapi.c   |  4 +++-
>>  drivers/gpu/drm/drm_crtc_internal.h |  4 +++-
>>  3 files changed, 18 insertions(+), 7 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/drm_atomic.c 
>> b/drivers/gpu/drm/drm_atomic.c
>> index 58527f151984..e7079a5f439c 100644
>> --- a/drivers/gpu/drm/drm_atomic.c
>> +++ b/drivers/gpu/drm/drm_atomic.c
>> @@ -1,6 +1,7 @@
>>  /*
>>   * Copyright (C) 2014 Red Hat
>>   * Copyright (C) 2014 Intel Corp.
>> + * Copyright (c) 2020, The Linux Foundation. All rights reserved.
>>   *
>>   * Permission is hereby granted, free of charge, to any person 
>> obtaining a
>>   * copy of this software and associated documentation files (the 
>> "Software"),
>> @@ -1543,9 +1544,9 @@ int __drm_atomic_helper_set_config(struct 
>> drm_mode_set *set,
>>  }
>>  EXPORT_SYMBOL(__drm_atomic_helper_set_config);
>> 
>> -void drm_atomic_print_state(const struct drm_atomic_state *state)
>> +void drm_atomic_print_state(const struct drm_atomic_state *state,
>> +		struct drm_printer *p)
> 
> Please add a nice kerneldoc for this newly exported function. 
> Specifically
> this kerneldoc needs to include a warning that state updates after call
> drm_atomic_state_helper_commit_hw_done() is unsafe to print using this
> function, because it looks at the new state objects. Only the old state
> structures will stay like this.
> 
> So maybe rename the function to say print_new_state() to make this
> completely clear. That way we can eventually add a print_old_state() 
> when
> needed.
> 
> Otherwise I think this makes sense, and nicely avoids the locking issue 
> of
> looking at ->state pointers without the right locking.
> -Daniel
> 

Thanks for the review, I have addressed these comments and posted a V2.
-Abhinav

>>  {
>> -	struct drm_printer p = drm_info_printer(state->dev->dev);
>>  	struct drm_plane *plane;
>>  	struct drm_plane_state *plane_state;
>>  	struct drm_crtc *crtc;
>> @@ -1554,17 +1555,23 @@ void drm_atomic_print_state(const struct 
>> drm_atomic_state *state)
>>  	struct drm_connector_state *connector_state;
>>  	int i;
>> 
>> +	if (!p) {
>> +		DRM_ERROR("invalid drm printer\n");
>> +		return;
>> +	}
>> +
>>  	DRM_DEBUG_ATOMIC("checking %p\n", state);
>> 
>>  	for_each_new_plane_in_state(state, plane, plane_state, i)
>> -		drm_atomic_plane_print_state(&p, plane_state);
>> +		drm_atomic_plane_print_state(p, plane_state);
>> 
>>  	for_each_new_crtc_in_state(state, crtc, crtc_state, i)
>> -		drm_atomic_crtc_print_state(&p, crtc_state);
>> +		drm_atomic_crtc_print_state(p, crtc_state);
>> 
>>  	for_each_new_connector_in_state(state, connector, connector_state, 
>> i)
>> -		drm_atomic_connector_print_state(&p, connector_state);
>> +		drm_atomic_connector_print_state(p, connector_state);
>>  }
>> +EXPORT_SYMBOL(drm_atomic_print_state);
>> 
>>  static void __drm_state_dump(struct drm_device *dev, struct 
>> drm_printer *p,
>>  			     bool take_locks)
>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
>> b/drivers/gpu/drm/drm_atomic_uapi.c
>> index 25c269bc4681..d9ae86c92608 100644
>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
>> @@ -2,6 +2,7 @@
>>   * Copyright (C) 2014 Red Hat
>>   * Copyright (C) 2014 Intel Corp.
>>   * Copyright (C) 2018 Intel Corp.
>> + * Copyright (c) 2020, The Linux Foundation. All rights reserved.
>>   *
>>   * Permission is hereby granted, free of charge, to any person 
>> obtaining a
>>   * copy of this software and associated documentation files (the 
>> "Software"),
>> @@ -1294,6 +1295,7 @@ int drm_mode_atomic_ioctl(struct drm_device 
>> *dev,
>>  	struct drm_out_fence_state *fence_state;
>>  	int ret = 0;
>>  	unsigned int i, j, num_fences;
>> +	struct drm_printer p = drm_info_printer(dev->dev);
>> 
>>  	/* disallow for drivers not supporting atomic: */
>>  	if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
>> @@ -1413,7 +1415,7 @@ int drm_mode_atomic_ioctl(struct drm_device 
>> *dev,
>>  		ret = drm_atomic_nonblocking_commit(state);
>>  	} else {
>>  		if (drm_debug_enabled(DRM_UT_STATE))
>> -			drm_atomic_print_state(state);
>> +			drm_atomic_print_state(state, &p);
>> 
>>  		ret = drm_atomic_commit(state);
>>  	}
>> diff --git a/drivers/gpu/drm/drm_crtc_internal.h 
>> b/drivers/gpu/drm/drm_crtc_internal.h
>> index da96b2f64d7e..d34215366936 100644
>> --- a/drivers/gpu/drm/drm_crtc_internal.h
>> +++ b/drivers/gpu/drm/drm_crtc_internal.h
>> @@ -5,6 +5,7 @@
>>   *   Jesse Barnes <jesse.barnes@intel.com>
>>   * Copyright © 2014 Intel Corporation
>>   *   Daniel Vetter <daniel.vetter@ffwll.ch>
>> + * Copyright (c) 2020, The Linux Foundation. All rights reserved.
>>   *
>>   * Permission is hereby granted, free of charge, to any person 
>> obtaining a
>>   * copy of this software and associated documentation files (the 
>> "Software"),
>> @@ -233,7 +234,8 @@ int __drm_atomic_helper_disable_plane(struct 
>> drm_plane *plane,
>>  int __drm_atomic_helper_set_config(struct drm_mode_set *set,
>>  				   struct drm_atomic_state *state);
>> 
>> -void drm_atomic_print_state(const struct drm_atomic_state *state);
>> +void drm_atomic_print_state(const struct drm_atomic_state *state,
>> +		struct drm_printer *p);
>> 
>>  /* drm_atomic_uapi.c */
>>  int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
>> --
>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
>> Forum,
>> a Linux Foundation Collaborative Project
>> 
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-10-30  1:12 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-22  5:01 [PATCH 0/4] Add devcoredump support for DPU Abhinav Kumar
2020-10-22  5:01 ` [PATCH 1/4] drm: allow drm_atomic_print_state() to accept any drm_printer Abhinav Kumar
2020-10-22 10:10   ` kernel test robot
2020-10-22 10:38   ` Daniel Vetter
2020-10-30  1:12     ` abhinavk
2020-10-27  7:14   ` kernel test robot
2020-10-22  5:01 ` [PATCH 2/4] disp/msm/dpu: add support to dump dpu registers Abhinav Kumar
2020-10-22  8:29   ` kernel test robot
2020-10-27 14:15   ` kernel test robot
2020-10-22  5:01 ` [PATCH 3/4] drm/msm: register the base address with dpu_dbg module Abhinav Kumar
2020-10-22  5:01 ` [PATCH 4/4] drm/msm/dpu: add dpu_dbg points across dpu driver Abhinav Kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).