Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/panel: otm8009a: Switch to mipi_dsi_multi_context helpers

Update the driver to use the non-deprecated mipi_dsi_*_multi()
helpers, as recommended in Documentation/gpu/todo.rst. The multi
variants provide proper error accumulation and handle the required
DCS NOP insertions, which suits the OTM8009A command sequences.

Refactor otm8009a_dcs_write_buf() and the dcs_write_seq/dcs_write_cmd_at
macros to take a mipi_dsi_multi_context pointer, passing it through
from callers. This ensures consistent error handling throughout the
driver.

Replace all mdelay() and msleep() calls within DSI command sequences
with mipi_dsi_msleep() for proper error accumulation.

The init, disable, and backlight update paths now return dsi_ctx.accum_err,
ensuring errors are propagated to callers.

Signed-off-by: Amin GATTOUT <amin.gattout@gmail.com>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patch.msgid.link/20251213142421.6762-1-amin.gattout@gmail.com

authored by

Amin GATTOUT and committed by
Neil Armstrong
4855f260 ac488854

+70 -105
+70 -105
drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
··· 109 109 return container_of(panel, struct otm8009a, panel); 110 110 } 111 111 112 - static void otm8009a_dcs_write_buf(struct otm8009a *ctx, const void *data, 113 - size_t len) 114 - { 115 - struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 116 - 117 - if (mipi_dsi_dcs_write_buffer(dsi, data, len) < 0) 118 - dev_warn(ctx->dev, "mipi dsi dcs write buffer failed\n"); 119 - } 120 - 121 - #define dcs_write_seq(ctx, seq...) \ 122 - ({ \ 123 - static const u8 d[] = { seq }; \ 124 - otm8009a_dcs_write_buf(ctx, d, ARRAY_SIZE(d)); \ 125 - }) 126 - 127 112 #define dcs_write_cmd_at(ctx, cmd, seq...) \ 128 113 ({ \ 129 - dcs_write_seq(ctx, MCS_ADRSFT, (cmd) & 0xFF); \ 130 - dcs_write_seq(ctx, (cmd) >> 8, seq); \ 114 + mipi_dsi_dcs_write_seq_multi(ctx, MCS_ADRSFT, (cmd) & 0xFF); \ 115 + mipi_dsi_dcs_write_seq_multi(ctx, (cmd) >> 8, seq); \ 131 116 }) 132 117 133 118 static int otm8009a_init_sequence(struct otm8009a *ctx) 134 119 { 135 120 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 136 - int ret; 121 + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 137 122 138 123 /* Enter CMD2 */ 139 - dcs_write_cmd_at(ctx, MCS_CMD2_ENA1, 0x80, 0x09, 0x01); 124 + dcs_write_cmd_at(&dsi_ctx, MCS_CMD2_ENA1, 0x80, 0x09, 0x01); 140 125 141 126 /* Enter Orise Command2 */ 142 - dcs_write_cmd_at(ctx, MCS_CMD2_ENA2, 0x80, 0x09); 127 + dcs_write_cmd_at(&dsi_ctx, MCS_CMD2_ENA2, 0x80, 0x09); 143 128 144 - dcs_write_cmd_at(ctx, MCS_SD_PCH_CTRL, 0x30); 145 - mdelay(10); 129 + dcs_write_cmd_at(&dsi_ctx, MCS_SD_PCH_CTRL, 0x30); 130 + mipi_dsi_msleep(&dsi_ctx, 10); 146 131 147 - dcs_write_cmd_at(ctx, MCS_NO_DOC1, 0x40); 148 - mdelay(10); 132 + dcs_write_cmd_at(&dsi_ctx, MCS_NO_DOC1, 0x40); 133 + mipi_dsi_msleep(&dsi_ctx, 10); 149 134 150 - dcs_write_cmd_at(ctx, MCS_PWR_CTRL4 + 1, 0xA9); 151 - dcs_write_cmd_at(ctx, MCS_PWR_CTRL2 + 1, 0x34); 152 - dcs_write_cmd_at(ctx, MCS_P_DRV_M, 0x50); 153 - dcs_write_cmd_at(ctx, MCS_VCOMDC, 0x4E); 154 - dcs_write_cmd_at(ctx, MCS_OSC_ADJ, 0x66); /* 65Hz */ 155 - dcs_write_cmd_at(ctx, MCS_PWR_CTRL2 + 2, 0x01); 156 - dcs_write_cmd_at(ctx, MCS_PWR_CTRL2 + 5, 0x34); 157 - dcs_write_cmd_at(ctx, MCS_PWR_CTRL2 + 4, 0x33); 158 - dcs_write_cmd_at(ctx, MCS_GVDDSET, 0x79, 0x79); 159 - dcs_write_cmd_at(ctx, MCS_SD_CTRL + 1, 0x1B); 160 - dcs_write_cmd_at(ctx, MCS_PWR_CTRL1 + 2, 0x83); 161 - dcs_write_cmd_at(ctx, MCS_SD_PCH_CTRL + 1, 0x83); 162 - dcs_write_cmd_at(ctx, MCS_RGB_VID_SET, 0x0E); 163 - dcs_write_cmd_at(ctx, MCS_PANSET, 0x00, 0x01); 135 + dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL4 + 1, 0xA9); 136 + dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL2 + 1, 0x34); 137 + dcs_write_cmd_at(&dsi_ctx, MCS_P_DRV_M, 0x50); 138 + dcs_write_cmd_at(&dsi_ctx, MCS_VCOMDC, 0x4E); 139 + dcs_write_cmd_at(&dsi_ctx, MCS_OSC_ADJ, 0x66); /* 65Hz */ 140 + dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL2 + 2, 0x01); 141 + dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL2 + 5, 0x34); 142 + dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL2 + 4, 0x33); 143 + dcs_write_cmd_at(&dsi_ctx, MCS_GVDDSET, 0x79, 0x79); 144 + dcs_write_cmd_at(&dsi_ctx, MCS_SD_CTRL + 1, 0x1B); 145 + dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL1 + 2, 0x83); 146 + dcs_write_cmd_at(&dsi_ctx, MCS_SD_PCH_CTRL + 1, 0x83); 147 + dcs_write_cmd_at(&dsi_ctx, MCS_RGB_VID_SET, 0x0E); 148 + dcs_write_cmd_at(&dsi_ctx, MCS_PANSET, 0x00, 0x01); 164 149 165 - dcs_write_cmd_at(ctx, MCS_GOAVST, 0x85, 0x01, 0x00, 0x84, 0x01, 0x00); 166 - dcs_write_cmd_at(ctx, MCS_GOACLKA1, 0x18, 0x04, 0x03, 0x39, 0x00, 0x00, 150 + dcs_write_cmd_at(&dsi_ctx, MCS_GOAVST, 0x85, 0x01, 0x00, 0x84, 0x01, 0x00); 151 + dcs_write_cmd_at(&dsi_ctx, MCS_GOACLKA1, 0x18, 0x04, 0x03, 0x39, 0x00, 0x00, 167 152 0x00, 0x18, 0x03, 0x03, 0x3A, 0x00, 0x00, 0x00); 168 - dcs_write_cmd_at(ctx, MCS_GOACLKA3, 0x18, 0x02, 0x03, 0x3B, 0x00, 0x00, 153 + dcs_write_cmd_at(&dsi_ctx, MCS_GOACLKA3, 0x18, 0x02, 0x03, 0x3B, 0x00, 0x00, 169 154 0x00, 0x18, 0x01, 0x03, 0x3C, 0x00, 0x00, 0x00); 170 - dcs_write_cmd_at(ctx, MCS_GOAECLK, 0x01, 0x01, 0x20, 0x20, 0x00, 0x00, 155 + dcs_write_cmd_at(&dsi_ctx, MCS_GOAECLK, 0x01, 0x01, 0x20, 0x20, 0x00, 0x00, 171 156 0x01, 0x02, 0x00, 0x00); 172 157 173 - dcs_write_cmd_at(ctx, MCS_NO_DOC2, 0x00); 158 + dcs_write_cmd_at(&dsi_ctx, MCS_NO_DOC2, 0x00); 174 159 175 - dcs_write_cmd_at(ctx, MCS_PANCTRLSET1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 176 - dcs_write_cmd_at(ctx, MCS_PANCTRLSET2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160 + dcs_write_cmd_at(&dsi_ctx, MCS_PANCTRLSET1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 161 + dcs_write_cmd_at(&dsi_ctx, MCS_PANCTRLSET2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177 162 0, 0, 0, 0, 0); 178 - dcs_write_cmd_at(ctx, MCS_PANCTRLSET3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163 + dcs_write_cmd_at(&dsi_ctx, MCS_PANCTRLSET3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179 164 0, 0, 0, 0, 0); 180 - dcs_write_cmd_at(ctx, MCS_PANCTRLSET4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 181 - dcs_write_cmd_at(ctx, MCS_PANCTRLSET5, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 165 + dcs_write_cmd_at(&dsi_ctx, MCS_PANCTRLSET4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 166 + dcs_write_cmd_at(&dsi_ctx, MCS_PANCTRLSET5, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 182 167 0, 0, 0, 0, 0); 183 - dcs_write_cmd_at(ctx, MCS_PANCTRLSET6, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 168 + dcs_write_cmd_at(&dsi_ctx, MCS_PANCTRLSET6, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 184 169 4, 0, 0, 0, 0); 185 - dcs_write_cmd_at(ctx, MCS_PANCTRLSET7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 186 - dcs_write_cmd_at(ctx, MCS_PANCTRLSET8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 170 + dcs_write_cmd_at(&dsi_ctx, MCS_PANCTRLSET7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 171 + dcs_write_cmd_at(&dsi_ctx, MCS_PANCTRLSET8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 187 172 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); 188 173 189 - dcs_write_cmd_at(ctx, MCS_PANU2D1, 0x00, 0x26, 0x09, 0x0B, 0x01, 0x25, 174 + dcs_write_cmd_at(&dsi_ctx, MCS_PANU2D1, 0x00, 0x26, 0x09, 0x0B, 0x01, 0x25, 190 175 0x00, 0x00, 0x00, 0x00); 191 - dcs_write_cmd_at(ctx, MCS_PANU2D2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 176 + dcs_write_cmd_at(&dsi_ctx, MCS_PANU2D2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 192 177 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x0A, 0x0C, 0x02); 193 - dcs_write_cmd_at(ctx, MCS_PANU2D3, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 178 + dcs_write_cmd_at(&dsi_ctx, MCS_PANU2D3, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 194 179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 195 - dcs_write_cmd_at(ctx, MCS_PAND2U1, 0x00, 0x25, 0x0C, 0x0A, 0x02, 0x26, 180 + dcs_write_cmd_at(&dsi_ctx, MCS_PAND2U1, 0x00, 0x25, 0x0C, 0x0A, 0x02, 0x26, 196 181 0x00, 0x00, 0x00, 0x00); 197 - dcs_write_cmd_at(ctx, MCS_PAND2U2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 182 + dcs_write_cmd_at(&dsi_ctx, MCS_PAND2U2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 198 183 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x0B, 0x09, 0x01); 199 - dcs_write_cmd_at(ctx, MCS_PAND2U3, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 184 + dcs_write_cmd_at(&dsi_ctx, MCS_PAND2U3, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 200 185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 201 186 202 - dcs_write_cmd_at(ctx, MCS_PWR_CTRL1 + 1, 0x66); 187 + dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL1 + 1, 0x66); 203 188 204 - dcs_write_cmd_at(ctx, MCS_NO_DOC3, 0x06); 189 + dcs_write_cmd_at(&dsi_ctx, MCS_NO_DOC3, 0x06); 205 190 206 - dcs_write_cmd_at(ctx, MCS_GMCT2_2P, 0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10, 191 + dcs_write_cmd_at(&dsi_ctx, MCS_GMCT2_2P, 0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10, 207 192 0x0B, 0x0A, 0x04, 0x07, 0x0B, 0x08, 0x0F, 0x10, 0x0A, 208 193 0x01); 209 - dcs_write_cmd_at(ctx, MCS_GMCT2_2N, 0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10, 194 + dcs_write_cmd_at(&dsi_ctx, MCS_GMCT2_2N, 0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10, 210 195 0x0B, 0x0A, 0x04, 0x07, 0x0B, 0x08, 0x0F, 0x10, 0x0A, 211 196 0x01); 212 197 213 198 /* Exit CMD2 */ 214 - dcs_write_cmd_at(ctx, MCS_CMD2_ENA1, 0xFF, 0xFF, 0xFF); 199 + dcs_write_cmd_at(&dsi_ctx, MCS_CMD2_ENA1, 0xFF, 0xFF, 0xFF); 215 200 216 - ret = mipi_dsi_dcs_nop(dsi); 217 - if (ret) 218 - return ret; 201 + mipi_dsi_dcs_nop_multi(&dsi_ctx); 219 202 220 - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 221 - if (ret) 222 - return ret; 223 - 224 - /* Wait for sleep out exit */ 225 - mdelay(120); 203 + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); 204 + mipi_dsi_msleep(&dsi_ctx, 120); 226 205 227 206 /* Default portrait 480x800 rgb24 */ 228 - dcs_write_seq(ctx, MIPI_DCS_SET_ADDRESS_MODE, 0x00); 207 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_SET_ADDRESS_MODE, 0x00); 229 208 230 - ret = mipi_dsi_dcs_set_column_address(dsi, 0, OTM8009A_HDISPLAY - 1); 231 - if (ret) 232 - return ret; 209 + mipi_dsi_dcs_set_column_address_multi(&dsi_ctx, 0, OTM8009A_HDISPLAY - 1); 233 210 234 - ret = mipi_dsi_dcs_set_page_address(dsi, 0, OTM8009A_VDISPLAY - 1); 235 - if (ret) 236 - return ret; 211 + mipi_dsi_dcs_set_page_address_multi(&dsi_ctx, 0, OTM8009A_VDISPLAY - 1); 237 212 238 213 /* See otm8009a driver documentation for pixel format descriptions */ 239 - ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT | 214 + mipi_dsi_dcs_set_pixel_format_multi(&dsi_ctx, MIPI_DCS_PIXEL_FMT_24BIT | 240 215 MIPI_DCS_PIXEL_FMT_24BIT << 4); 241 - if (ret) 242 - return ret; 243 216 244 217 /* Disable CABC feature */ 245 - dcs_write_seq(ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x00); 218 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x00); 246 219 247 - ret = mipi_dsi_dcs_set_display_on(dsi); 248 - if (ret) 249 - return ret; 220 + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); 250 221 251 - ret = mipi_dsi_dcs_nop(dsi); 252 - if (ret) 253 - return ret; 222 + mipi_dsi_dcs_nop_multi(&dsi_ctx); 254 223 255 224 /* Send Command GRAM memory write (no parameters) */ 256 - dcs_write_seq(ctx, MIPI_DCS_WRITE_MEMORY_START); 225 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_MEMORY_START); 257 226 258 227 /* Wait a short while to let the panel be ready before the 1st frame */ 259 - mdelay(10); 228 + mipi_dsi_msleep(&dsi_ctx, 10); 260 229 261 - return 0; 230 + return dsi_ctx.accum_err; 262 231 } 263 232 264 233 static int otm8009a_disable(struct drm_panel *panel) 265 234 { 266 235 struct otm8009a *ctx = panel_to_otm8009a(panel); 267 236 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 268 - int ret; 237 + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 269 238 270 239 backlight_disable(ctx->bl_dev); 271 240 272 - ret = mipi_dsi_dcs_set_display_off(dsi); 273 - if (ret) 274 - return ret; 241 + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); 242 + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); 243 + mipi_dsi_msleep(&dsi_ctx, 120); 275 244 276 - ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 277 - if (ret) 278 - return ret; 279 - 280 - msleep(120); 281 - 282 - return 0; 245 + return dsi_ctx.accum_err; 283 246 } 284 247 285 248 static int otm8009a_unprepare(struct drm_panel *panel) ··· 346 383 static int otm8009a_backlight_update_status(struct backlight_device *bd) 347 384 { 348 385 struct otm8009a *ctx = bl_get_data(bd); 386 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 387 + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; 349 388 u8 data[2]; 350 389 351 390 if (!ctx->prepared) { ··· 362 397 */ 363 398 data[0] = MIPI_DCS_SET_DISPLAY_BRIGHTNESS; 364 399 data[1] = bd->props.brightness; 365 - otm8009a_dcs_write_buf(ctx, data, ARRAY_SIZE(data)); 400 + mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, data, ARRAY_SIZE(data)); 366 401 367 402 /* set Brightness Control & Backlight on */ 368 403 data[1] = 0x24; ··· 374 409 375 410 /* Update Brightness Control & Backlight */ 376 411 data[0] = MIPI_DCS_WRITE_CONTROL_DISPLAY; 377 - otm8009a_dcs_write_buf(ctx, data, ARRAY_SIZE(data)); 412 + mipi_dsi_dcs_write_buffer_multi(&dsi_ctx, data, ARRAY_SIZE(data)); 378 413 379 - return 0; 414 + return dsi_ctx.accum_err; 380 415 } 381 416 382 417 static const struct backlight_ops otm8009a_backlight_ops = {