.. | .. |
---|
246 | 246 | struct phy *dcphy; |
---|
247 | 247 | union phy_configure_opts phy_opts; |
---|
248 | 248 | |
---|
| 249 | + bool disable_hold_mode; |
---|
| 250 | + bool auto_calc_mode; |
---|
249 | 251 | bool c_option; |
---|
250 | 252 | bool scrambling_en; |
---|
251 | 253 | unsigned int slice_width; |
---|
.. | .. |
---|
270 | 272 | u32 lanes; |
---|
271 | 273 | u32 format; |
---|
272 | 274 | unsigned long mode_flags; |
---|
273 | | - |
---|
| 275 | + u64 mipi_pixel_rate; |
---|
274 | 276 | const struct dw_mipi_dsi2_plat_data *pdata; |
---|
275 | 277 | struct rockchip_drm_sub_dev sub_dev; |
---|
276 | 278 | |
---|
.. | .. |
---|
609 | 611 | |
---|
610 | 612 | static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2) |
---|
611 | 613 | { |
---|
612 | | - struct drm_display_mode *mode = &dsi2->mode; |
---|
613 | 614 | u64 sys_clk = clk_get_rate(dsi2->sys_clk); |
---|
614 | | - u64 pixel_clk, ipi_clk, phy_hsclk; |
---|
| 615 | + u64 ipi_clk, phy_hsclk; |
---|
615 | 616 | u64 tmp; |
---|
616 | 617 | |
---|
617 | 618 | /* |
---|
.. | .. |
---|
625 | 626 | phy_hsclk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_hs_rate * MSEC_PER_SEC, 16); |
---|
626 | 627 | |
---|
627 | 628 | /* IPI_RATIO_MAN_CFG = PHY_HSTX_CLK / IPI_CLK */ |
---|
628 | | - pixel_clk = mode->crtc_clock * MSEC_PER_SEC; |
---|
629 | | - ipi_clk = pixel_clk / 4; |
---|
| 629 | + ipi_clk = dsi2->mipi_pixel_rate; |
---|
| 630 | + if (!sys_clk || !ipi_clk) |
---|
| 631 | + return; |
---|
630 | 632 | |
---|
631 | 633 | tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, ipi_clk); |
---|
632 | 634 | regmap_write(dsi2->regmap, DSI2_PHY_IPI_RATIO_MAN_CFG, |
---|
.. | .. |
---|
666 | 668 | { |
---|
667 | 669 | dw_mipi_dsi2_phy_mode_cfg(dsi2); |
---|
668 | 670 | dw_mipi_dsi2_phy_clk_mode_cfg(dsi2); |
---|
| 671 | + |
---|
| 672 | + if (dsi2->auto_calc_mode) |
---|
| 673 | + return; |
---|
| 674 | + |
---|
669 | 675 | dw_mipi_dsi2_phy_ratio_cfg(dsi2); |
---|
670 | 676 | dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(dsi2); |
---|
671 | 677 | |
---|
.. | .. |
---|
733 | 739 | regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, MAX_PIX_PKT(val)); |
---|
734 | 740 | |
---|
735 | 741 | dw_mipi_dsi2_ipi_color_coding_cfg(dsi2); |
---|
| 742 | + |
---|
| 743 | + if (dsi2->auto_calc_mode) |
---|
| 744 | + return; |
---|
736 | 745 | |
---|
737 | 746 | /* |
---|
738 | 747 | * if the controller is intended to operate in data stream mode, |
---|
.. | .. |
---|
807 | 816 | |
---|
808 | 817 | /* there may be some timeout registers may be configured if desired */ |
---|
809 | 818 | |
---|
810 | | - dw_mipi_dsi2_work_mode(dsi2, MANUAL_MODE_EN); |
---|
| 819 | + dw_mipi_dsi2_work_mode(dsi2, dsi2->auto_calc_mode ? 0 : MANUAL_MODE_EN); |
---|
811 | 820 | dw_mipi_dsi2_phy_init(dsi2); |
---|
812 | 821 | dw_mipi_dsi2_tx_option_set(dsi2); |
---|
813 | 822 | dw_mipi_dsi2_irq_enable(dsi2, 1); |
---|
.. | .. |
---|
830 | 839 | |
---|
831 | 840 | static void dw_mipi_dsi2_enable(struct dw_mipi_dsi2 *dsi2) |
---|
832 | 841 | { |
---|
| 842 | + u32 mode; |
---|
| 843 | + int ret; |
---|
| 844 | + |
---|
833 | 845 | dw_mipi_dsi2_ipi_set(dsi2); |
---|
| 846 | + |
---|
| 847 | + if (dsi2->auto_calc_mode) { |
---|
| 848 | + regmap_write(dsi2->regmap, DSI2_MODE_CTRL, AUTOCALC_MODE); |
---|
| 849 | + ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS, |
---|
| 850 | + mode, mode == IDLE_MODE, |
---|
| 851 | + 1000, MODE_STATUS_TIMEOUT_US); |
---|
| 852 | + if (ret < 0) |
---|
| 853 | + dev_err(dsi2->dev, "auto calculation training failed\n"); |
---|
| 854 | + } |
---|
834 | 855 | |
---|
835 | 856 | if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO) |
---|
836 | 857 | dw_mipi_dsi2_set_vid_mode(dsi2); |
---|
.. | .. |
---|
841 | 862 | dw_mipi_dsi2_enable(dsi2->slave); |
---|
842 | 863 | } |
---|
843 | 864 | |
---|
| 865 | +static void dw_mipi_dsi2_get_mipi_pixel_clk(struct dw_mipi_dsi2 *dsi2, |
---|
| 866 | + struct rockchip_crtc_state *s) |
---|
| 867 | +{ |
---|
| 868 | + struct drm_display_mode *mode = &dsi2->mode; |
---|
| 869 | + u8 k = dsi2->slave ? 2 : 1; |
---|
| 870 | + |
---|
| 871 | + /* 1.When MIPI works in uncompressed mode: |
---|
| 872 | + * (Video Timing Pixel Rate)/(4)=(MIPI Pixel ClockxK)=(dclk_out×K)=dclk_core |
---|
| 873 | + * 2.When MIPI works in compressed mode: |
---|
| 874 | + * MIPI Pixel Clock = cds_clk / 2 |
---|
| 875 | + * MIPI is configured as double channel display mode, K=2, otherwise K=1. |
---|
| 876 | + */ |
---|
| 877 | + if (dsi2->dsc_enable) { |
---|
| 878 | + dsi2->mipi_pixel_rate = s->dsc_cds_clk_rate / 2; |
---|
| 879 | + if (dsi2->slave) |
---|
| 880 | + dsi2->slave->mipi_pixel_rate = dsi2->mipi_pixel_rate; |
---|
| 881 | + |
---|
| 882 | + return; |
---|
| 883 | + } |
---|
| 884 | + |
---|
| 885 | + dsi2->mipi_pixel_rate = (mode->crtc_clock * MSEC_PER_SEC) / (4 * k); |
---|
| 886 | + if (dsi2->slave) |
---|
| 887 | + dsi2->slave->mipi_pixel_rate = dsi2->mipi_pixel_rate; |
---|
| 888 | +} |
---|
| 889 | + |
---|
844 | 890 | static int dw_mipi_dsi2_encoder_mode_set(struct dw_mipi_dsi2 *dsi2, |
---|
845 | 891 | struct drm_atomic_state *state) |
---|
846 | 892 | { |
---|
.. | .. |
---|
848 | 894 | struct drm_connector *connector; |
---|
849 | 895 | struct drm_connector_state *conn_state; |
---|
850 | 896 | struct drm_crtc_state *crtc_state; |
---|
| 897 | + struct rockchip_crtc_state *vcstate; |
---|
851 | 898 | const struct drm_display_mode *adjusted_mode; |
---|
852 | 899 | struct drm_display_mode *mode = &dsi2->mode; |
---|
853 | 900 | |
---|
.. | .. |
---|
865 | 912 | return -ENODEV; |
---|
866 | 913 | } |
---|
867 | 914 | |
---|
| 915 | + vcstate = to_rockchip_crtc_state(crtc_state); |
---|
868 | 916 | adjusted_mode = &crtc_state->adjusted_mode; |
---|
869 | 917 | drm_mode_copy(mode, adjusted_mode); |
---|
870 | 918 | |
---|
.. | .. |
---|
873 | 921 | |
---|
874 | 922 | if (dsi2->slave) |
---|
875 | 923 | drm_mode_copy(&dsi2->slave->mode, mode); |
---|
| 924 | + |
---|
| 925 | + dw_mipi_dsi2_get_mipi_pixel_clk(dsi2, vcstate); |
---|
876 | 926 | |
---|
877 | 927 | return 0; |
---|
878 | 928 | } |
---|
.. | .. |
---|
954 | 1004 | if (!(dsi2->mode_flags & MIPI_DSI_MODE_VIDEO)) { |
---|
955 | 1005 | s->output_flags |= ROCKCHIP_OUTPUT_MIPI_DS_MODE; |
---|
956 | 1006 | s->soft_te = dsi2->te_gpio ? true : false; |
---|
957 | | - s->hold_mode = true; |
---|
| 1007 | + s->hold_mode = dsi2->disable_hold_mode ? false : true; |
---|
958 | 1008 | } |
---|
959 | 1009 | |
---|
960 | 1010 | if (dsi2->slave) { |
---|
.. | .. |
---|
1164 | 1214 | dsi2->slave->master = dsi2; |
---|
1165 | 1215 | dsi2->lanes /= 2; |
---|
1166 | 1216 | |
---|
| 1217 | + dsi2->slave->auto_calc_mode = dsi2->auto_calc_mode; |
---|
1167 | 1218 | dsi2->slave->lanes = dsi2->lanes; |
---|
1168 | 1219 | dsi2->slave->channel = dsi2->channel; |
---|
1169 | 1220 | dsi2->slave->format = dsi2->format; |
---|
.. | .. |
---|
1639 | 1690 | dsi2->pdata = of_device_get_match_data(dev); |
---|
1640 | 1691 | platform_set_drvdata(pdev, dsi2); |
---|
1641 | 1692 | |
---|
| 1693 | + if (device_property_read_bool(dev, "auto-calculation-mode")) |
---|
| 1694 | + dsi2->auto_calc_mode = true; |
---|
| 1695 | + |
---|
| 1696 | + if (device_property_read_bool(dev, "disable-hold-mode")) |
---|
| 1697 | + dsi2->disable_hold_mode = true; |
---|
| 1698 | + |
---|
1642 | 1699 | if (device_property_read_bool(dev, "dual-connector-split")) { |
---|
1643 | 1700 | dsi2->dual_connector_split = true; |
---|
1644 | 1701 | |
---|