[Freedreno] [PATCH 2/4] disp/msm/dpu: add support to dump dpu registers

kernel test robot lkp at intel.com
Tue Oct 27 14:15:24 UTC 2020


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 at 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 35412 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/freedreno/attachments/20201027/c2b2d1ab/attachment-0001.gz>


More information about the Freedreno mailing list