Lines Matching +full:lvds +full:- +full:4 +full:bits

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
28 #include <linux/bits.h>
32 #include <linux/media-bus-format.h>
65 #define REG_DSI_LANE_LEFT_RIGHT_PIXELS BIT(7) /* DSI85-only */
66 #define REG_DSI_LANE_DSI_CHANNEL_MODE_DUAL 0 /* DSI85-only */
67 #define REG_DSI_LANE_DSI_CHANNEL_MODE_2SINGLE BIT(6) /* DSI85-only */
77 /* LVDS registers */
82 #define REG_LVDS_FMT_LVDS_LINK_CFG BIT(4) /* 0:AB 1:A-only */
89 #define REG_LVDS_VCOM_CHB_LVDS_VOCM BIT(4)
95 #define REG_LVDS_LANE_CHB_REVERSE_LVDS BIT(4)
99 #define REG_LVDS_CM_CHA_LVDS_CM_ADJUST(n) (((n) & 0x3) << 4)
124 #define REG_IRQ_EN_CHA_COR_ECC_ERR_EN BIT(4)
132 #define REG_IRQ_STAT_CHA_COR_ECC_ERR BIT(4)
257 static const int lvds_vod_swing_data_table[2][4][2] = {
272 static const int lvds_vod_swing_clock_table[2][4][2] = {
297 return drm_bridge_attach(bridge->encoder, ctx->panel_bridge,
298 &ctx->bridge, flags);
305 if (!ctx->dsi)
308 ctx->dsi = NULL;
316 * 000 - 25 MHz <= LVDS_CLK < 37.5 MHz
317 * 001 - 37.5 MHz <= LVDS_CLK < 62.5 MHz
318 * 010 - 62.5 MHz <= LVDS_CLK < 87.5 MHz
319 * 011 - 87.5 MHz <= LVDS_CLK < 112.5 MHz
320 * 100 - 112.5 MHz <= LVDS_CLK < 137.5 MHz
321 * 101 - 137.5 MHz <= LVDS_CLK <= 154 MHz
328 int mode_clock = mode->clock;
330 if (ctx->lvds_dual_link)
333 return (mode_clock - 12500) / 25000;
341 * 0x00 through 0x07 - Reserved
342 * 0x08 - 40 <= DSI_CLK < 45 MHz
343 * 0x09 - 45 <= DSI_CLK < 50 MHz
345 * 0x63 - 495 <= DSI_CLK < 500 MHz
346 * 0x64 - 500 MHz
347 * 0x65 through 0xFF - Reserved
353 return DIV_ROUND_UP(clamp((unsigned int)mode->clock *
354 mipi_dsi_pixel_format_to_bpp(ctx->dsi->format) /
355 ctx->dsi->lanes / 2, 40000U, 500000U), 5000U);
360 /* The divider is (DSI_CLK / LVDS_CLK) - 1, which really is: */
361 unsigned int dsi_div = mipi_dsi_pixel_format_to_bpp(ctx->dsi->format);
363 dsi_div /= ctx->dsi->lanes;
365 if (!ctx->lvds_dual_link)
368 return dsi_div - 1;
373 struct drm_device *dev = sn65dsi83->bridge.dev;
390 if (!sn65dsi83->bridge.encoder->crtc) {
392 * No CRTC attached -> No CRTC active outputs to reset
400 dev_warn(sn65dsi83->dev, "reset the pipe\n");
402 err = drm_atomic_helper_reset_crtc(sn65dsi83->bridge.encoder->crtc, &ctx);
418 dev_err(ctx->dev, "reset pipe failed %pe\n", ERR_PTR(ret));
421 if (ctx->irq)
422 enable_irq(ctx->irq);
432 * - the bridge doesn't answer
433 * - the bridge signals an error
436 ret = regmap_read(ctx->regmap, REG_IRQ_STAT, &irq_stat);
444 if (ctx->irq)
445 disable_irq_nosync(ctx->irq);
447 schedule_work(&ctx->reset_work);
458 schedule_delayed_work(&ctx->monitor_work, msecs_to_jiffies(1000));
463 schedule_delayed_work(&ctx->monitor_work, msecs_to_jiffies(1000));
468 cancel_delayed_work_sync(&ctx->monitor_work);
487 ret = regulator_enable(ctx->vcc);
489 dev_err(ctx->dev, "Failed to enable vcc: %d\n", ret);
494 gpiod_set_value_cansleep(ctx->enable_gpio, 1);
497 /* Get the LVDS format from the bridge state. */
500 switch (bridge_state->output_bus_cfg.format) {
516 * LVDS bus pixel format, use SPWG24 default
521 dev_warn(ctx->dev,
522 "Unsupported LVDS bus format 0x%04x, please check output bridge driver. Falling back to SPWG24.\n",
523 bridge_state->output_bus_cfg.format);
532 bridge->encoder);
533 crtc = drm_atomic_get_new_connector_state(state, connector)->crtc;
535 mode = &crtc_state->adjusted_mode;
538 regmap_write(ctx->regmap, REG_RC_RESET, 0x00);
539 regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00);
542 regmap_write(ctx->regmap, REG_RC_LVDS_PLL,
545 regmap_write(ctx->regmap, REG_DSI_CLK,
547 regmap_write(ctx->regmap, REG_RC_DSI_CLK,
550 /* Set number of DSI lanes and LVDS link config. */
551 regmap_write(ctx->regmap, REG_DSI_LANE,
553 REG_DSI_LANE_CHA_DSI_LANES(~(ctx->dsi->lanes - 1)) |
554 /* CHB is DSI85-only, set to default on DSI83/DSI84 */
557 regmap_write(ctx->regmap, REG_DSI_EQ, 0x00);
560 val = (mode->flags & DRM_MODE_FLAG_NHSYNC ?
562 (mode->flags & DRM_MODE_FLAG_NVSYNC ?
564 val |= bridge_state->output_bus_cfg.flags & DRM_BUS_FLAG_DE_LOW ?
567 /* Set up bits-per-pixel, 18bpp or 24bpp. */
570 if (ctx->lvds_dual_link)
574 /* Set up LVDS format, JEIDA/Format 1 or SPWG/Format 2 */
577 if (ctx->lvds_dual_link)
581 /* Set up LVDS output config (DSI84,DSI85) */
582 if (!ctx->lvds_dual_link)
585 regmap_write(ctx->regmap, REG_LVDS_FMT, val);
586 regmap_write(ctx->regmap, REG_LVDS_VCOM,
587 REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) |
588 REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B]));
589 regmap_write(ctx->regmap, REG_LVDS_LANE,
590 (ctx->lvds_dual_link_even_odd_swap ?
592 (ctx->lvds_term_conf[CHANNEL_A] ?
594 (ctx->lvds_term_conf[CHANNEL_B] ?
596 regmap_write(ctx->regmap, REG_LVDS_CM, 0x00);
598 le16val = cpu_to_le16(mode->hdisplay);
599 regmap_bulk_write(ctx->regmap, REG_VID_CHA_ACTIVE_LINE_LENGTH_LOW,
601 le16val = cpu_to_le16(mode->vdisplay);
602 regmap_bulk_write(ctx->regmap, REG_VID_CHA_VERTICAL_DISPLAY_SIZE_LOW,
606 regmap_bulk_write(ctx->regmap, REG_VID_CHA_SYNC_DELAY_LOW, &le16val, 2);
607 le16val = cpu_to_le16(mode->hsync_end - mode->hsync_start);
608 regmap_bulk_write(ctx->regmap, REG_VID_CHA_HSYNC_PULSE_WIDTH_LOW,
610 le16val = cpu_to_le16(mode->vsync_end - mode->vsync_start);
611 regmap_bulk_write(ctx->regmap, REG_VID_CHA_VSYNC_PULSE_WIDTH_LOW,
613 regmap_write(ctx->regmap, REG_VID_CHA_HORIZONTAL_BACK_PORCH,
614 mode->htotal - mode->hsync_end);
615 regmap_write(ctx->regmap, REG_VID_CHA_VERTICAL_BACK_PORCH,
616 mode->vtotal - mode->vsync_end);
617 regmap_write(ctx->regmap, REG_VID_CHA_HORIZONTAL_FRONT_PORCH,
618 mode->hsync_start - mode->hdisplay);
619 regmap_write(ctx->regmap, REG_VID_CHA_VERTICAL_FRONT_PORCH,
620 mode->vsync_start - mode->vdisplay);
621 regmap_write(ctx->regmap, REG_VID_CHA_TEST_PATTERN, 0x00);
624 regmap_write(ctx->regmap, REG_RC_PLL_EN, REG_RC_PLL_EN_PLL_EN);
626 ret = regmap_read_poll_timeout(ctx->regmap, REG_RC_LVDS_PLL, pval,
630 dev_err(ctx->dev, "failed to lock PLL, ret=%i\n", ret);
632 regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00);
637 regmap_write(ctx->regmap, REG_RC_RESET, REG_RC_RESET_SOFT_RESET);
650 regmap_read(ctx->regmap, REG_IRQ_STAT, &pval);
651 regmap_write(ctx->regmap, REG_IRQ_STAT, pval);
655 regmap_read(ctx->regmap, REG_IRQ_STAT, &pval);
657 dev_err(ctx->dev, "Unexpected link status 0x%02x\n", pval);
659 if (ctx->irq) {
661 regmap_write(ctx->regmap, REG_IRQ_GLOBAL, REG_IRQ_GLOBAL_IRQ_EN);
662 regmap_write(ctx->regmap, REG_IRQ_EN, 0xff);
675 if (ctx->irq) {
677 regmap_write(ctx->regmap, REG_IRQ_EN, 0x0);
678 regmap_write(ctx->regmap, REG_IRQ_GLOBAL, 0x0);
685 gpiod_set_value_cansleep(ctx->enable_gpio, 0);
688 ret = regulator_disable(ctx->vcc);
690 dev_err(ctx->dev, "Failed to disable vcc: %d\n", ret);
692 regcache_mark_dirty(ctx->regmap);
700 /* LVDS output clock range 25..154 MHz */
701 if (mode->clock < 25000)
703 if (mode->clock > 154000)
728 /* This is the DSI-end bus format */
763 return -EINVAL;
768 struct device *dev = ctx->dev;
786 endpoint = of_graph_get_endpoint_by_regs(dev->of_node, endpoint_reg, -1);
788 of_property_read_u32(endpoint, "ti,lvds-termination-ohms", &lvds_term);
790 ctx->lvds_term_conf[channel] = OHM_100;
792 ctx->lvds_term_conf[channel] = OHM_200;
794 ret = -EINVAL;
798 ret_data = of_property_read_u32_array(endpoint, "ti,lvds-vod-swing-data-microvolt",
800 if (ret_data != 0 && ret_data != -EINVAL) {
805 ret_clock = of_property_read_u32_array(endpoint, "ti,lvds-vod-swing-clock-microvolt",
807 if (ret_clock != 0 && ret_clock != -EINVAL) {
813 if (ret_data == -EINVAL && ret_clock == -EINVAL)
819 lvds_vod_swing_clk, ctx->lvds_term_conf[channel]);
826 ctx->lvds_vod_swing_conf[channel] = lvds_vod_swing_conf;
836 struct device *dev = ctx->dev;
847 ctx->lvds_dual_link = false;
848 ctx->lvds_dual_link_even_odd_swap = false;
853 port2 = of_graph_get_port_by_id(dev->of_node, 2);
854 port3 = of_graph_get_port_by_id(dev->of_node, 3);
860 ctx->lvds_dual_link = true;
861 /* Odd pixels to LVDS Channel A, even pixels to B */
862 ctx->lvds_dual_link_even_odd_swap = false;
864 ctx->lvds_dual_link = true;
865 /* Even pixels to LVDS Channel A, odd pixels to B */
866 ctx->lvds_dual_link_even_odd_swap = true;
870 panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 2, 0);
874 ctx->panel_bridge = panel_bridge;
876 ctx->vcc = devm_regulator_get(dev, "vcc");
877 if (IS_ERR(ctx->vcc))
878 return dev_err_probe(dev, PTR_ERR(ctx->vcc),
886 struct device *dev = ctx->dev;
898 endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
899 dsi_lanes = drm_of_get_data_lanes_count(endpoint, 1, 4);
906 return -EPROBE_DEFER;
916 ctx->dsi = dsi;
918 dsi->lanes = dsi_lanes;
919 dsi->format = MIPI_DSI_FMT_RGB888;
920 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
944 struct device *dev = &client->dev;
951 return -ENOMEM;
953 ctx->dev = dev;
954 INIT_WORK(&ctx->reset_work, sn65dsi83_reset_work);
955 INIT_DELAYED_WORK(&ctx->monitor_work, sn65dsi83_monitor_work);
957 if (dev->of_node) {
961 model = id->driver_data;
965 ctx->enable_gpio = devm_gpiod_get_optional(ctx->dev, "enable",
967 if (IS_ERR(ctx->enable_gpio))
968 return dev_err_probe(dev, PTR_ERR(ctx->enable_gpio), "failed to get enable GPIO\n");
976 ctx->regmap = devm_regmap_init_i2c(client, &sn65dsi83_regmap_config);
977 if (IS_ERR(ctx->regmap))
978 return dev_err_probe(dev, PTR_ERR(ctx->regmap), "failed to get regmap\n");
980 if (client->irq) {
981 ctx->irq = client->irq;
982 ret = devm_request_threaded_irq(ctx->dev, ctx->irq, NULL, sn65dsi83_irq,
983 IRQF_ONESHOT, dev_name(ctx->dev), ctx);
991 ctx->bridge.funcs = &sn65dsi83_funcs;
992 ctx->bridge.of_node = dev->of_node;
993 ctx->bridge.pre_enable_prev_first = true;
994 ctx->bridge.type = DRM_MODE_CONNECTOR_LVDS;
995 drm_bridge_add(&ctx->bridge);
1006 drm_bridge_remove(&ctx->bridge);
1014 drm_bridge_remove(&ctx->bridge);
1043 MODULE_DESCRIPTION("TI SN65DSI83 DSI to LVDS bridge driver");