Lines Matching +full:en +full:- +full:active +full:- +full:lanes

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com
26 /* Global (16-bit addressable) */
43 /* Debug (16-bit addressable) */
49 /* TX PHY (32-bit addressable) */
61 /* TX PPI (32-bit addressable) */
77 /* TX CTRL (32-bit addressable) */
98 /* DSITX CTRL (16-bit addressable) */
149 u32 dsi_lanes; /* number of DSI Lanes */
173 int ret = priv->error; in tc358768_clear_error()
175 priv->error = 0; in tc358768_clear_error()
185 if (priv->error) in tc358768_write()
188 /* 16-bit register? */ in tc358768_write()
192 priv->error = regmap_bulk_write(priv->regmap, reg, &tmpval, count); in tc358768_write()
199 if (priv->error) in tc358768_read()
202 /* 16-bit register? */ in tc358768_read()
208 priv->error = regmap_bulk_read(priv->regmap, reg, val, count); in tc358768_read()
237 if (priv->enabled) in tc358768_hw_enable()
240 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies); in tc358768_hw_enable()
242 dev_err(priv->dev, "error enabling regulators (%d)\n", ret); in tc358768_hw_enable()
244 if (priv->reset_gpio) in tc358768_hw_enable()
248 * The RESX is active low (GPIO_ACTIVE_LOW). in tc358768_hw_enable()
251 gpiod_set_value_cansleep(priv->reset_gpio, 0); in tc358768_hw_enable()
256 priv->enabled = true; in tc358768_hw_enable()
263 if (!priv->enabled) in tc358768_hw_disable()
267 * The RESX is active low (GPIO_ACTIVE_LOW). in tc358768_hw_disable()
270 gpiod_set_value_cansleep(priv->reset_gpio, 1); in tc358768_hw_disable()
272 ret = regulator_bulk_disable(ARRAY_SIZE(priv->supplies), in tc358768_hw_disable()
273 priv->supplies); in tc358768_hw_disable()
275 dev_err(priv->dev, "error disabling regulators (%d)\n", ret); in tc358768_hw_disable()
277 priv->enabled = false; in tc358768_hw_disable()
282 return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->pd_lines); in tc358768_pll_to_pclk()
287 return (u32)div_u64((u64)pclk * priv->pd_lines, priv->dsi_lanes); in tc358768_pclk_to_pll()
305 target_pll = tc358768_pclk_to_pll(priv, mode->clock * 1000); in tc358768_calc_pll()
314 return -EINVAL; in tc358768_calc_pll()
316 frs = i - 1; in tc358768_calc_pll()
317 max_pll = frs_limits[i - 1]; in tc358768_calc_pll()
320 refclk = clk_get_rate(priv->refclk); in tc358768_calc_pll()
339 diff = max(pll, target_pll) - min(pll, target_pll); in tc358768_calc_pll()
354 dev_err(priv->dev, "could not find suitable PLL setup\n"); in tc358768_calc_pll()
355 return -EINVAL; in tc358768_calc_pll()
362 priv->fbd = best_fbd; in tc358768_calc_pll()
363 priv->prd = best_prd; in tc358768_calc_pll()
364 priv->frs = frs; in tc358768_calc_pll()
365 priv->dsiclk = best_pll / 2; in tc358768_calc_pll()
379 if (dev->lanes > 4) { in tc358768_dsi_host_attach()
380 dev_err(priv->dev, "unsupported number of data lanes(%u)\n", in tc358768_dsi_host_attach()
381 dev->lanes); in tc358768_dsi_host_attach()
382 return -EINVAL; in tc358768_dsi_host_attach()
389 if (!(dev->mode_flags & MIPI_DSI_MODE_VIDEO)) { in tc358768_dsi_host_attach()
390 dev_err(priv->dev, "Only MIPI_DSI_MODE_VIDEO is supported\n"); in tc358768_dsi_host_attach()
391 return -ENOTSUPP; in tc358768_dsi_host_attach()
398 if (dev->format != MIPI_DSI_FMT_RGB888) { in tc358768_dsi_host_attach()
399 dev_warn(priv->dev, "Only MIPI_DSI_FMT_RGB888 tested!\n"); in tc358768_dsi_host_attach()
400 return -ENOTSUPP; in tc358768_dsi_host_attach()
403 ret = drm_of_find_panel_or_bridge(host->dev->of_node, 1, 0, &panel, in tc358768_dsi_host_attach()
415 priv->output.dev = dev; in tc358768_dsi_host_attach()
416 priv->output.bridge = bridge; in tc358768_dsi_host_attach()
417 priv->output.panel = panel; in tc358768_dsi_host_attach()
419 priv->dsi_lanes = dev->lanes; in tc358768_dsi_host_attach()
422 ret = -EINVAL; in tc358768_dsi_host_attach()
423 ep = of_graph_get_endpoint_by_regs(host->dev->of_node, 0, 0); in tc358768_dsi_host_attach()
425 ret = of_property_read_u32(ep, "data-lines", &priv->pd_lines); in tc358768_dsi_host_attach()
431 priv->pd_lines = mipi_dsi_pixel_format_to_bpp(dev->format); in tc358768_dsi_host_attach()
433 drm_bridge_add(&priv->bridge); in tc358768_dsi_host_attach()
443 drm_bridge_remove(&priv->bridge); in tc358768_dsi_host_detach()
444 if (priv->output.panel) in tc358768_dsi_host_detach()
445 drm_panel_bridge_remove(priv->output.bridge); in tc358768_dsi_host_detach()
457 if (!priv->enabled) { in tc358768_dsi_host_transfer()
458 dev_err(priv->dev, "Bridge is not enabled\n"); in tc358768_dsi_host_transfer()
459 return -ENODEV; in tc358768_dsi_host_transfer()
462 if (msg->rx_len) { in tc358768_dsi_host_transfer()
463 dev_warn(priv->dev, "MIPI rx is not supported\n"); in tc358768_dsi_host_transfer()
464 return -ENOTSUPP; in tc358768_dsi_host_transfer()
467 if (msg->tx_len > 8) { in tc358768_dsi_host_transfer()
468 dev_warn(priv->dev, "Maximum 8 byte MIPI tx is supported\n"); in tc358768_dsi_host_transfer()
469 return -ENOTSUPP; in tc358768_dsi_host_transfer()
476 if (mipi_dsi_packet_format_is_short(msg->type)) { in tc358768_dsi_host_transfer()
503 dev_warn(priv->dev, "Software disable failed: %d\n", ret); in tc358768_dsi_host_transfer()
521 if (!drm_core_check_feature(bridge->dev, DRIVER_ATOMIC)) { in tc358768_bridge_attach()
522 dev_err(priv->dev, "needs atomic updates support\n"); in tc358768_bridge_attach()
523 return -ENOTSUPP; in tc358768_bridge_attach()
526 return drm_bridge_attach(bridge->encoder, priv->output.bridge, bridge, in tc358768_bridge_attach()
562 dev_warn(priv->dev, "Software disable failed: %d\n", ret); in tc358768_bridge_disable()
580 dev_err(priv->dev, "PLL calculation failed: %d\n", ret); in tc358768_setup_pll()
584 fbd = priv->fbd; in tc358768_setup_pll()
585 prd = priv->prd; in tc358768_setup_pll()
586 frs = priv->frs; in tc358768_setup_pll()
588 dev_dbg(priv->dev, "PLL: refclk %lu, fbd %u, prd %u, frs %u\n", in tc358768_setup_pll()
589 clk_get_rate(priv->refclk), fbd, prd, frs); in tc358768_setup_pll()
590 dev_dbg(priv->dev, "PLL: pll_clk: %u, DSIClk %u, DSIByteClk %u\n", in tc358768_setup_pll()
591 priv->dsiclk * 2, priv->dsiclk, priv->dsiclk / 4); in tc358768_setup_pll()
592 dev_dbg(priv->dev, "PLL: pclk %u (panel: %u)\n", in tc358768_setup_pll()
593 tc358768_pll_to_pclk(priv, priv->dsiclk * 2), in tc358768_setup_pll()
594 mode->clock * 1000); in tc358768_setup_pll()
599 /* FRS[11:10] LBWS[9:8] CKEN[4] RESETB[1] EN[0] */ in tc358768_setup_pll()
606 /* FRS[11:10] LBWS[9:8] CKEN[4] PLL_CKEN[4] RESETB[1] EN[0] */ in tc358768_setup_pll()
627 struct mipi_dsi_device *dsi_dev = priv->output.dev; in tc358768_bridge_pre_enable()
638 dev_err(priv->dev, "Software reset failed: %d\n", ret); in tc358768_bridge_pre_enable()
643 mode = &bridge->encoder->crtc->state->adjusted_mode; in tc358768_bridge_pre_enable()
646 dev_err(priv->dev, "PLL setup failed: %d\n", ret); in tc358768_bridge_pre_enable()
651 dsiclk = priv->dsiclk; in tc358768_bridge_pre_enable()
656 switch (dsi_dev->format) { in tc358768_bridge_pre_enable()
659 hact = mode->hdisplay * 3; in tc358768_bridge_pre_enable()
664 hact = mode->hdisplay * 3; in tc358768_bridge_pre_enable()
670 hact = mode->hdisplay * 18 / 8; in tc358768_bridge_pre_enable()
676 hact = mode->hdisplay * 2; in tc358768_bridge_pre_enable()
680 dev_err(priv->dev, "Invalid data format (%u)\n", in tc358768_bridge_pre_enable()
681 dsi_dev->format); in tc358768_bridge_pre_enable()
692 /* Enable D-PHY (HiZ->LP11) */ in tc358768_bridge_pre_enable()
694 /* Enable lanes */ in tc358768_bridge_pre_enable()
695 for (i = 0; i < dsi_dev->lanes; i++) in tc358768_bridge_pre_enable()
704 dev_dbg(priv->dev, "dsiclk_nsk: %u\n", dsiclk_nsk); in tc358768_bridge_pre_enable()
705 dev_dbg(priv->dev, "ui_nsk: %u\n", ui_nsk); in tc358768_bridge_pre_enable()
706 dev_dbg(priv->dev, "dsibclk_nsk: %u\n", dsibclk_nsk); in tc358768_bridge_pre_enable()
707 dev_dbg(priv->dev, "phy_delay_nsk: %u\n", phy_delay_nsk); in tc358768_bridge_pre_enable()
709 /* LP11 > 100us for D-PHY Rx Init */ in tc358768_bridge_pre_enable()
710 val = tc358768_ns_to_cnt(100 * 1000, dsibclk_nsk) - 1; in tc358768_bridge_pre_enable()
711 dev_dbg(priv->dev, "LINEINITCNT: 0x%x\n", val); in tc358768_bridge_pre_enable()
715 val = tc358768_ns_to_cnt(50, dsibclk_nsk) - 1; in tc358768_bridge_pre_enable()
717 dev_dbg(priv->dev, "LPTXTIMECNT: 0x%x\n", val); in tc358768_bridge_pre_enable()
721 val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1; in tc358768_bridge_pre_enable()
725 val |= (val2 - tc358768_to_ns(phy_delay_nsk - dsibclk_nsk)) << 8; in tc358768_bridge_pre_enable()
726 dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val); in tc358768_bridge_pre_enable()
731 val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 5; in tc358768_bridge_pre_enable()
732 dev_dbg(priv->dev, "TCLK_TRAILCNT: 0x%x\n", val); in tc358768_bridge_pre_enable()
737 val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1; in tc358768_bridge_pre_enable()
739 val2 = tc358768_ns_to_cnt(145 - tc358768_to_ns(ui_nsk), dsibclk_nsk); in tc358768_bridge_pre_enable()
740 val |= (val2 - tc358768_to_ns(phy_delay_nsk)) << 8; in tc358768_bridge_pre_enable()
741 dev_dbg(priv->dev, "THS_HEADERCNT: 0x%x\n", val); in tc358768_bridge_pre_enable()
746 val = val / (lptxcnt + 1) - 1; in tc358768_bridge_pre_enable()
747 dev_dbg(priv->dev, "TWAKEUP: 0x%x\n", val); in tc358768_bridge_pre_enable()
752 dsibclk_nsk) - 3; in tc358768_bridge_pre_enable()
753 dev_dbg(priv->dev, "TCLK_POSTCNT: 0x%x\n", val); in tc358768_bridge_pre_enable()
758 dsibclk_nsk) - 5; in tc358768_bridge_pre_enable()
759 dev_dbg(priv->dev, "THS_TRAILCNT: 0x%x\n", val); in tc358768_bridge_pre_enable()
763 for (i = 0; i < dsi_dev->lanes; i++) in tc358768_bridge_pre_enable()
767 if (!(dsi_dev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) in tc358768_bridge_pre_enable()
772 val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1; in tc358768_bridge_pre_enable()
774 dsibclk_nsk) - 2; in tc358768_bridge_pre_enable()
776 dev_dbg(priv->dev, "BTACNTRL1: 0x%x\n", val); in tc358768_bridge_pre_enable()
787 mode->vtotal - mode->vsync_start); in tc358768_bridge_pre_enable()
791 tc358768_write(priv, TC358768_DSI_VACT, mode->vdisplay); in tc358768_bridge_pre_enable()
794 val = (u32)div_u64((mode->htotal - mode->hsync_start) * in tc358768_bridge_pre_enable()
795 ((u64)priv->dsiclk / 4) * priv->dsi_lanes, in tc358768_bridge_pre_enable()
796 mode->clock * 1000); in tc358768_bridge_pre_enable()
804 if (!(mode->flags & DRM_MODE_FLAG_NVSYNC)) in tc358768_bridge_pre_enable()
807 if (mode->flags & DRM_MODE_FLAG_PHSYNC) in tc358768_bridge_pre_enable()
820 val |= (dsi_dev->lanes - 1) << 1; in tc358768_bridge_pre_enable()
822 if (!(dsi_dev->mode_flags & MIPI_DSI_MODE_LPM)) in tc358768_bridge_pre_enable()
825 if (!(dsi_dev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) in tc358768_bridge_pre_enable()
828 if (dsi_dev->mode_flags & MIPI_DSI_MODE_EOT_PACKET) in tc358768_bridge_pre_enable()
839 dev_err(priv->dev, "Bridge pre_enable failed: %d\n", ret); in tc358768_bridge_pre_enable()
850 if (!priv->enabled) { in tc358768_bridge_enable()
851 dev_err(priv->dev, "Bridge is not enabled\n"); in tc358768_bridge_enable()
863 dev_err(priv->dev, "Bridge enable failed: %d\n", ret); in tc358768_bridge_enable()
962 for (i = 0; i < ARRAY_SIZE(priv->supplies); ++i) in tc358768_get_regulators()
963 priv->supplies[i].supply = tc358768_supplies[i]; in tc358768_get_regulators()
965 ret = devm_regulator_bulk_get(priv->dev, ARRAY_SIZE(priv->supplies), in tc358768_get_regulators()
966 priv->supplies); in tc358768_get_regulators()
968 dev_err(priv->dev, "failed to get regulators: %d\n", ret); in tc358768_get_regulators()
977 struct device *dev = &client->dev; in tc358768_i2c_probe()
978 struct device_node *np = dev->of_node; in tc358768_i2c_probe()
982 return -ENODEV; in tc358768_i2c_probe()
986 return -ENOMEM; in tc358768_i2c_probe()
989 priv->dev = dev; in tc358768_i2c_probe()
995 priv->refclk = devm_clk_get(dev, "refclk"); in tc358768_i2c_probe()
996 if (IS_ERR(priv->refclk)) in tc358768_i2c_probe()
997 return PTR_ERR(priv->refclk); in tc358768_i2c_probe()
1000 * RESX is low active, to disable tc358768 initially (keep in reset) in tc358768_i2c_probe()
1004 priv->reset_gpio = devm_gpiod_get_optional(dev, "reset", in tc358768_i2c_probe()
1006 if (IS_ERR(priv->reset_gpio)) in tc358768_i2c_probe()
1007 return PTR_ERR(priv->reset_gpio); in tc358768_i2c_probe()
1009 priv->regmap = devm_regmap_init_i2c(client, &tc358768_regmap_config); in tc358768_i2c_probe()
1010 if (IS_ERR(priv->regmap)) { in tc358768_i2c_probe()
1012 return PTR_ERR(priv->regmap); in tc358768_i2c_probe()
1015 priv->dsi_host.dev = dev; in tc358768_i2c_probe()
1016 priv->dsi_host.ops = &tc358768_dsi_host_ops; in tc358768_i2c_probe()
1018 priv->bridge.funcs = &tc358768_bridge_funcs; in tc358768_i2c_probe()
1019 priv->bridge.timings = &default_tc358768_timings; in tc358768_i2c_probe()
1020 priv->bridge.of_node = np; in tc358768_i2c_probe()
1024 return mipi_dsi_host_register(&priv->dsi_host); in tc358768_i2c_probe()
1031 mipi_dsi_host_unregister(&priv->dsi_host); in tc358768_i2c_remove()