Lines Matching +full:dual +full:- +full:dsi +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0
6 * - SN65DSI83
7 * = 1x Single-link DSI ~ 1x Single-link LVDS
8 * - Supported
9 * - Single-link LVDS mode tested
10 * - SN65DSI84
11 * = 1x Single-link DSI ~ 2x Single-link or 1x Dual-link LVDS
12 * - Supported
13 * - Dual-link LVDS mode tested
14 * - 2x Single-link LVDS mode unsupported
16 * - SN65DSI85
17 * = 2x Single-link or 1x Dual-link DSI ~ 2x Single-link or 1x Dual-link LVDS
18 * - Unsupported
59 /* DSI registers */
61 #define REG_DSI_LANE_LEFT_RIGHT_PIXELS BIT(7) /* DSI85-only */
62 #define REG_DSI_LANE_DSI_CHANNEL_MODE_DUAL 0 /* DSI85-only */
63 #define REG_DSI_LANE_DSI_CHANNEL_MODE_2SINGLE BIT(6) /* DSI85-only */
78 #define REG_LVDS_FMT_LVDS_LINK_CFG BIT(4) /* 0:AB 1:A-only */
143 struct mipi_dsi_device *dsi; member
248 struct device *dev = ctx->dev; in sn65dsi83_attach()
249 struct mipi_dsi_device *dsi; in sn65dsi83_attach() local
259 host = of_find_mipi_dsi_host_by_node(ctx->host_node); in sn65dsi83_attach()
261 dev_err(dev, "failed to find dsi host\n"); in sn65dsi83_attach()
262 return -EPROBE_DEFER; in sn65dsi83_attach()
265 dsi = mipi_dsi_device_register_full(host, &info); in sn65dsi83_attach()
266 if (IS_ERR(dsi)) { in sn65dsi83_attach()
267 return dev_err_probe(dev, PTR_ERR(dsi), in sn65dsi83_attach()
268 "failed to create dsi device\n"); in sn65dsi83_attach()
271 ctx->dsi = dsi; in sn65dsi83_attach()
273 dsi->lanes = ctx->dsi_lanes; in sn65dsi83_attach()
274 dsi->format = MIPI_DSI_FMT_RGB888; in sn65dsi83_attach()
275 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST; in sn65dsi83_attach()
277 ret = mipi_dsi_attach(dsi); in sn65dsi83_attach()
279 dev_err(dev, "failed to attach dsi to host\n"); in sn65dsi83_attach()
283 return drm_bridge_attach(bridge->encoder, ctx->panel_bridge, in sn65dsi83_attach()
284 &ctx->bridge, flags); in sn65dsi83_attach()
287 mipi_dsi_device_unregister(dsi); in sn65dsi83_attach()
300 regcache_mark_dirty(ctx->regmap); in sn65dsi83_atomic_pre_enable()
301 gpiod_set_value(ctx->enable_gpio, 0); in sn65dsi83_atomic_pre_enable()
303 gpiod_set_value(ctx->enable_gpio, 1); in sn65dsi83_atomic_pre_enable()
308 const struct drm_display_mode *mode) in sn65dsi83_get_lvds_range() argument
312 * 000 - 25 MHz <= LVDS_CLK < 37.5 MHz in sn65dsi83_get_lvds_range()
313 * 001 - 37.5 MHz <= LVDS_CLK < 62.5 MHz in sn65dsi83_get_lvds_range()
314 * 010 - 62.5 MHz <= LVDS_CLK < 87.5 MHz in sn65dsi83_get_lvds_range()
315 * 011 - 87.5 MHz <= LVDS_CLK < 112.5 MHz in sn65dsi83_get_lvds_range()
316 * 100 - 112.5 MHz <= LVDS_CLK < 137.5 MHz in sn65dsi83_get_lvds_range()
317 * 101 - 137.5 MHz <= LVDS_CLK <= 154 MHz in sn65dsi83_get_lvds_range()
324 int mode_clock = mode->clock; in sn65dsi83_get_lvds_range()
326 if (ctx->lvds_dual_link) in sn65dsi83_get_lvds_range()
329 return (mode_clock - 12500) / 25000; in sn65dsi83_get_lvds_range()
333 const struct drm_display_mode *mode) in sn65dsi83_get_dsi_range() argument
337 * 0x00 through 0x07 - Reserved in sn65dsi83_get_dsi_range()
338 * 0x08 - 40 <= DSI_CLK < 45 MHz in sn65dsi83_get_dsi_range()
339 * 0x09 - 45 <= DSI_CLK < 50 MHz in sn65dsi83_get_dsi_range()
341 * 0x63 - 495 <= DSI_CLK < 500 MHz in sn65dsi83_get_dsi_range()
342 * 0x64 - 500 MHz in sn65dsi83_get_dsi_range()
343 * 0x65 through 0xFF - Reserved in sn65dsi83_get_dsi_range()
344 * which is DSI clock in 5 MHz steps, clamped to 40..500 MHz. in sn65dsi83_get_dsi_range()
345 * The DSI clock are calculated as: in sn65dsi83_get_dsi_range()
346 * DSI_CLK = mode clock * bpp / dsi_data_lanes / 2 in sn65dsi83_get_dsi_range()
349 return DIV_ROUND_UP(clamp((unsigned int)mode->clock * in sn65dsi83_get_dsi_range()
350 mipi_dsi_pixel_format_to_bpp(ctx->dsi->format) / in sn65dsi83_get_dsi_range()
351 ctx->dsi_lanes / 2, 40000U, 500000U), 5000U); in sn65dsi83_get_dsi_range()
356 /* The divider is (DSI_CLK / LVDS_CLK) - 1, which really is: */ in sn65dsi83_get_dsi_div()
357 unsigned int dsi_div = mipi_dsi_pixel_format_to_bpp(ctx->dsi->format); in sn65dsi83_get_dsi_div()
359 dsi_div /= ctx->dsi_lanes; in sn65dsi83_get_dsi_div()
361 if (!ctx->lvds_dual_link) in sn65dsi83_get_dsi_div()
364 return dsi_div - 1; in sn65dsi83_get_dsi_div()
371 struct drm_atomic_state *state = old_bridge_state->base.state; in sn65dsi83_atomic_enable()
374 const struct drm_display_mode *mode; in sn65dsi83_atomic_enable() local
387 switch (bridge_state->output_bus_cfg.format) { in sn65dsi83_atomic_enable()
408 dev_warn(ctx->dev, in sn65dsi83_atomic_enable()
410 bridge_state->output_bus_cfg.format); in sn65dsi83_atomic_enable()
415 * Retrieve the CRTC adjusted mode. This requires a little dance to go in sn65dsi83_atomic_enable()
419 bridge->encoder); in sn65dsi83_atomic_enable()
420 crtc = drm_atomic_get_new_connector_state(state, connector)->crtc; in sn65dsi83_atomic_enable()
422 mode = &crtc_state->adjusted_mode; in sn65dsi83_atomic_enable()
425 regmap_write(ctx->regmap, REG_RC_RESET, 0x00); in sn65dsi83_atomic_enable()
426 regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00); in sn65dsi83_atomic_enable()
428 /* Reference clock derived from DSI link clock. */ in sn65dsi83_atomic_enable()
429 regmap_write(ctx->regmap, REG_RC_LVDS_PLL, in sn65dsi83_atomic_enable()
430 REG_RC_LVDS_PLL_LVDS_CLK_RANGE(sn65dsi83_get_lvds_range(ctx, mode)) | in sn65dsi83_atomic_enable()
432 regmap_write(ctx->regmap, REG_DSI_CLK, in sn65dsi83_atomic_enable()
433 REG_DSI_CLK_CHA_DSI_CLK_RANGE(sn65dsi83_get_dsi_range(ctx, mode))); in sn65dsi83_atomic_enable()
434 regmap_write(ctx->regmap, REG_RC_DSI_CLK, in sn65dsi83_atomic_enable()
437 /* Set number of DSI lanes and LVDS link config. */ in sn65dsi83_atomic_enable()
438 regmap_write(ctx->regmap, REG_DSI_LANE, in sn65dsi83_atomic_enable()
440 REG_DSI_LANE_CHA_DSI_LANES(~(ctx->dsi_lanes - 1)) | in sn65dsi83_atomic_enable()
441 /* CHB is DSI85-only, set to default on DSI83/DSI84 */ in sn65dsi83_atomic_enable()
444 regmap_write(ctx->regmap, REG_DSI_EQ, 0x00); in sn65dsi83_atomic_enable()
447 val = (mode->flags & DRM_MODE_FLAG_NHSYNC ? in sn65dsi83_atomic_enable()
449 (mode->flags & DRM_MODE_FLAG_NVSYNC ? in sn65dsi83_atomic_enable()
452 /* Set up bits-per-pixel, 18bpp or 24bpp. */ in sn65dsi83_atomic_enable()
455 if (ctx->lvds_dual_link) in sn65dsi83_atomic_enable()
462 if (ctx->lvds_dual_link) in sn65dsi83_atomic_enable()
467 if (!ctx->lvds_dual_link) in sn65dsi83_atomic_enable()
470 regmap_write(ctx->regmap, REG_LVDS_FMT, val); in sn65dsi83_atomic_enable()
471 regmap_write(ctx->regmap, REG_LVDS_VCOM, 0x05); in sn65dsi83_atomic_enable()
472 regmap_write(ctx->regmap, REG_LVDS_LANE, in sn65dsi83_atomic_enable()
473 (ctx->lvds_dual_link_even_odd_swap ? in sn65dsi83_atomic_enable()
477 regmap_write(ctx->regmap, REG_LVDS_CM, 0x00); in sn65dsi83_atomic_enable()
479 le16val = cpu_to_le16(mode->hdisplay); in sn65dsi83_atomic_enable()
480 regmap_bulk_write(ctx->regmap, REG_VID_CHA_ACTIVE_LINE_LENGTH_LOW, in sn65dsi83_atomic_enable()
482 le16val = cpu_to_le16(mode->vdisplay); in sn65dsi83_atomic_enable()
483 regmap_bulk_write(ctx->regmap, REG_VID_CHA_VERTICAL_DISPLAY_SIZE_LOW, in sn65dsi83_atomic_enable()
487 regmap_bulk_write(ctx->regmap, REG_VID_CHA_SYNC_DELAY_LOW, &le16val, 2); in sn65dsi83_atomic_enable()
488 le16val = cpu_to_le16(mode->hsync_end - mode->hsync_start); in sn65dsi83_atomic_enable()
489 regmap_bulk_write(ctx->regmap, REG_VID_CHA_HSYNC_PULSE_WIDTH_LOW, in sn65dsi83_atomic_enable()
491 le16val = cpu_to_le16(mode->vsync_end - mode->vsync_start); in sn65dsi83_atomic_enable()
492 regmap_bulk_write(ctx->regmap, REG_VID_CHA_VSYNC_PULSE_WIDTH_LOW, in sn65dsi83_atomic_enable()
494 regmap_write(ctx->regmap, REG_VID_CHA_HORIZONTAL_BACK_PORCH, in sn65dsi83_atomic_enable()
495 mode->htotal - mode->hsync_end); in sn65dsi83_atomic_enable()
496 regmap_write(ctx->regmap, REG_VID_CHA_VERTICAL_BACK_PORCH, in sn65dsi83_atomic_enable()
497 mode->vtotal - mode->vsync_end); in sn65dsi83_atomic_enable()
498 regmap_write(ctx->regmap, REG_VID_CHA_HORIZONTAL_FRONT_PORCH, in sn65dsi83_atomic_enable()
499 mode->hsync_start - mode->hdisplay); in sn65dsi83_atomic_enable()
500 regmap_write(ctx->regmap, REG_VID_CHA_VERTICAL_FRONT_PORCH, in sn65dsi83_atomic_enable()
501 mode->vsync_start - mode->vdisplay); in sn65dsi83_atomic_enable()
502 regmap_write(ctx->regmap, REG_VID_CHA_TEST_PATTERN, 0x00); in sn65dsi83_atomic_enable()
505 regmap_write(ctx->regmap, REG_RC_PLL_EN, REG_RC_PLL_EN_PLL_EN); in sn65dsi83_atomic_enable()
507 ret = regmap_read_poll_timeout(ctx->regmap, REG_RC_LVDS_PLL, pval, in sn65dsi83_atomic_enable()
511 dev_err(ctx->dev, "failed to lock PLL, ret=%i\n", ret); in sn65dsi83_atomic_enable()
513 regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00); in sn65dsi83_atomic_enable()
518 regmap_write(ctx->regmap, REG_RC_RESET, REG_RC_RESET_SOFT_RESET); in sn65dsi83_atomic_enable()
521 regmap_read(ctx->regmap, REG_IRQ_STAT, &pval); in sn65dsi83_atomic_enable()
522 regmap_write(ctx->regmap, REG_IRQ_STAT, pval); in sn65dsi83_atomic_enable()
531 regmap_write(ctx->regmap, REG_RC_RESET, 0x00); in sn65dsi83_atomic_disable()
532 regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00); in sn65dsi83_atomic_disable()
541 gpiod_set_value(ctx->enable_gpio, 0); in sn65dsi83_atomic_post_disable()
547 const struct drm_display_mode *mode) in sn65dsi83_mode_valid() argument
550 if (mode->clock < 25000) in sn65dsi83_mode_valid()
552 if (mode->clock > 154000) in sn65dsi83_mode_valid()
577 /* This is the DSI-end bus format */ in sn65dsi83_atomic_get_input_bus_fmts()
601 struct device *dev = ctx->dev; in sn65dsi83_parse_dt()
606 endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); in sn65dsi83_parse_dt()
607 ctx->dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); in sn65dsi83_parse_dt()
608 ctx->host_node = of_graph_get_remote_port_parent(endpoint); in sn65dsi83_parse_dt()
611 if (ctx->dsi_lanes < 0 || ctx->dsi_lanes > 4) in sn65dsi83_parse_dt()
612 return -EINVAL; in sn65dsi83_parse_dt()
613 if (!ctx->host_node) in sn65dsi83_parse_dt()
614 return -ENODEV; in sn65dsi83_parse_dt()
616 ctx->lvds_dual_link = false; in sn65dsi83_parse_dt()
617 ctx->lvds_dual_link_even_odd_swap = false; in sn65dsi83_parse_dt()
622 port2 = of_graph_get_port_by_id(dev->of_node, 2); in sn65dsi83_parse_dt()
623 port3 = of_graph_get_port_by_id(dev->of_node, 3); in sn65dsi83_parse_dt()
629 ctx->lvds_dual_link = true; in sn65dsi83_parse_dt()
631 ctx->lvds_dual_link_even_odd_swap = false; in sn65dsi83_parse_dt()
633 ctx->lvds_dual_link = true; in sn65dsi83_parse_dt()
635 ctx->lvds_dual_link_even_odd_swap = true; in sn65dsi83_parse_dt()
639 ret = drm_of_find_panel_or_bridge(dev->of_node, 2, 0, &panel, &panel_bridge); in sn65dsi83_parse_dt()
648 ctx->panel_bridge = panel_bridge; in sn65dsi83_parse_dt()
656 struct device *dev = &client->dev; in sn65dsi83_probe()
663 return -ENOMEM; in sn65dsi83_probe()
665 ctx->dev = dev; in sn65dsi83_probe()
667 if (dev->of_node) { in sn65dsi83_probe()
671 model = id->driver_data; in sn65dsi83_probe()
674 ctx->enable_gpio = devm_gpiod_get(ctx->dev, "enable", GPIOD_OUT_LOW); in sn65dsi83_probe()
675 if (IS_ERR(ctx->enable_gpio)) in sn65dsi83_probe()
676 return PTR_ERR(ctx->enable_gpio); in sn65dsi83_probe()
682 ctx->regmap = devm_regmap_init_i2c(client, &sn65dsi83_regmap_config); in sn65dsi83_probe()
683 if (IS_ERR(ctx->regmap)) in sn65dsi83_probe()
684 return PTR_ERR(ctx->regmap); in sn65dsi83_probe()
689 ctx->bridge.funcs = &sn65dsi83_funcs; in sn65dsi83_probe()
690 ctx->bridge.of_node = dev->of_node; in sn65dsi83_probe()
691 drm_bridge_add(&ctx->bridge); in sn65dsi83_probe()
700 mipi_dsi_detach(ctx->dsi); in sn65dsi83_remove()
701 mipi_dsi_device_unregister(ctx->dsi); in sn65dsi83_remove()
702 drm_bridge_remove(&ctx->bridge); in sn65dsi83_remove()
703 of_node_put(ctx->host_node); in sn65dsi83_remove()
734 MODULE_DESCRIPTION("TI SN65DSI83 DSI to LVDS bridge driver");