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

kernel test robot
2020-10-27T14:16:33Z

[-- 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 --]