Message ID | 20241204053634.1365491-1-fshao@chromium.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/mediatek: dp: Support flexible length of DP calibration data | expand |
Hi Fei, kernel test robot noticed the following build warnings: [auto build test WARNING on linus/master] [also build test WARNING on v6.13-rc1 next-20241203] [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#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Fei-Shao/drm-mediatek-dp-Support-flexible-length-of-DP-calibration-data/20241204-133854 base: linus/master patch link: https://lore.kernel.org/r/20241204053634.1365491-1-fshao%40chromium.org patch subject: [PATCH] drm/mediatek: dp: Support flexible length of DP calibration data config: mips-allyesconfig (https://download.01.org/0day-ci/archive/20241204/202412042020.FZmfgvza-lkp@intel.com/config) compiler: mips-linux-gcc (GCC) 14.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241204/202412042020.FZmfgvza-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202412042020.FZmfgvza-lkp@intel.com/ All warnings (new ones prefixed by >>): In file included from include/linux/device.h:15, from include/drm/display/drm_dp_aux_bus.h:13, from drivers/gpu/drm/mediatek/mtk_dp.c:7: drivers/gpu/drm/mediatek/mtk_dp.c: In function 'mtk_dp_get_calibration_data': >> drivers/gpu/drm/mediatek/mtk_dp.c:1181:34: warning: format '%lu' expects argument of type 'long unsigned int', but argument 4 has type 'size_t' {aka 'unsigned int'} [-Wformat=] 1181 | "Out-of-bound efuse data access, fmt idx = %d, buf len = %lu\n", | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:110:30: note: in definition of macro 'dev_printk_index_wrap' 110 | _p_func(dev, fmt, ##__VA_ARGS__); \ | ^~~ include/linux/dev_printk.h:156:61: note: in expansion of macro 'dev_fmt' 156 | dev_printk_index_wrap(_dev_warn, KERN_WARNING, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ drivers/gpu/drm/mediatek/mtk_dp.c:1180:25: note: in expansion of macro 'dev_warn' 1180 | dev_warn(mtk_dp->dev, | ^~~~~~~~ drivers/gpu/drm/mediatek/mtk_dp.c:1181:93: note: format string is defined here 1181 | "Out-of-bound efuse data access, fmt idx = %d, buf len = %lu\n", | ~~^ | | | long unsigned int | %u vim +1181 drivers/gpu/drm/mediatek/mtk_dp.c 1148 1149 static void mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp) 1150 { 1151 const struct mtk_dp_efuse_fmt *fmt; 1152 struct device *dev = mtk_dp->dev; 1153 struct nvmem_cell *cell; 1154 u32 *cal_data = mtk_dp->cal_data; 1155 u32 *buf; 1156 int i; 1157 size_t len; 1158 1159 cell = nvmem_cell_get(dev, "dp_calibration_data"); 1160 if (IS_ERR(cell)) { 1161 dev_warn(dev, "Failed to get nvmem cell dp_calibration_data\n"); 1162 goto use_default_val; 1163 } 1164 1165 buf = (u32 *)nvmem_cell_read(cell, &len); 1166 nvmem_cell_put(cell); 1167 1168 if (IS_ERR(buf)) { 1169 dev_warn(dev, "Failed to read nvmem_cell_read\n"); 1170 goto use_default_val; 1171 } 1172 1173 /* The cell length is in bytes. Convert it to be compatible with u32 buffer. */ 1174 len /= sizeof(u32); 1175 1176 for (i = 0; i < MTK_DP_CAL_MAX; i++) { 1177 fmt = &mtk_dp->data->efuse_fmt[i]; 1178 1179 if (fmt->idx >= len) { 1180 dev_warn(mtk_dp->dev, > 1181 "Out-of-bound efuse data access, fmt idx = %d, buf len = %lu\n", 1182 fmt->idx, len); 1183 kfree(buf); 1184 goto use_default_val; 1185 } 1186 1187 cal_data[i] = (buf[fmt->idx] >> fmt->shift) & fmt->mask; 1188 1189 if (cal_data[i] < fmt->min_val || cal_data[i] > fmt->max_val) { 1190 dev_warn(mtk_dp->dev, "Invalid efuse data, idx = %d\n", i); 1191 kfree(buf); 1192 goto use_default_val; 1193 } 1194 } 1195 kfree(buf); 1196 1197 return; 1198 1199 use_default_val: 1200 dev_warn(mtk_dp->dev, "Use default calibration data\n"); 1201 for (i = 0; i < MTK_DP_CAL_MAX; i++) 1202 cal_data[i] = mtk_dp->data->efuse_fmt[i].default_val; 1203 } 1204
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index 1cc916b16471..e9ff6fdfd6ee 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -1165,17 +1165,25 @@ static void mtk_dp_get_calibration_data(struct mtk_dp *mtk_dp) buf = (u32 *)nvmem_cell_read(cell, &len); nvmem_cell_put(cell); - if (IS_ERR(buf) || ((len / sizeof(u32)) != 4)) { + if (IS_ERR(buf)) { dev_warn(dev, "Failed to read nvmem_cell_read\n"); - - if (!IS_ERR(buf)) - kfree(buf); - goto use_default_val; } + /* The cell length is in bytes. Convert it to be compatible with u32 buffer. */ + len /= sizeof(u32); + for (i = 0; i < MTK_DP_CAL_MAX; i++) { fmt = &mtk_dp->data->efuse_fmt[i]; + + if (fmt->idx >= len) { + dev_warn(mtk_dp->dev, + "Out-of-bound efuse data access, fmt idx = %d, buf len = %lu\n", + fmt->idx, len); + kfree(buf); + goto use_default_val; + } + cal_data[i] = (buf[fmt->idx] >> fmt->shift) & fmt->mask; if (cal_data[i] < fmt->min_val || cal_data[i] > fmt->max_val) {
The DP calibration data is stored in nvmem cells, and the data layout is described in the `mtk_dp_efuse_fmt` arrays for each platform. There is no guarantee that the data is always a 4-length u32 buffer. For example, MT8188 has a data length of 3, preventing it from passing the preliminary check and undergoing calibration. Update the logic to support flexible data lengths. Specifically, we validate the length returned from `nvmem_cell_read()` against the platform-specific efuse format. If out-of-bound access is detected, fall back to the default calibration values. This likely indicates an error in either the efuse data length described in DT or the efuse format within the driver. Signed-off-by: Fei Shao <fshao@chromium.org> --- drivers/gpu/drm/mediatek/mtk_dp.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)