summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
diff options
context:
space:
mode:
authorHeiko Stuebner <heiko.stuebner@theobroma-systems.com>2019-12-09 17:31:25 +0300
committerHeiko Stuebner <heiko@sntech.de>2019-12-16 14:01:58 +0300
commit25ed8aeb9c396475f48c13abdaf76a2e6e6b117b (patch)
tree3b07ba676283a90be8de4b141f1188f7f855dd4f /drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
parent2156873f08c7893811f34177aa923ab1ea486591 (diff)
downloadlinux-25ed8aeb9c396475f48c13abdaf76a2e6e6b117b.tar.xz
drm/bridge/synopsys: dsi: driver-specific configuration of phy timings
The timing values for dw-dsi are often dependent on the used display and according to Philippe Cornu will most likely also depend on the used phy technology in the soc-specific implementation. To solve this and allow specific implementations to define them as needed add a new get_timing callback to phy_ops and call this from the dphy_timing function to retrieve the necessary values for the specific mode. Right now this handles the hs2lp + lp2hs where Rockchip SoCs need handling according to the phy speed, while STM seems to be ok with static values. changes in v5: - rebase on 5.5-rc1 - merge into px30 dsi series to prevent ordering conflicts changes in v4: - rebase to make it directly fit on top of drm-misc-next after all changes in v3: - check existence of phy_ops->get_timing in __dw_mipi_dsi_probe() - emit actual error when get_timing() call fails - add tags from Philippe and Yannick changes in v2: - add driver-specific handling, don't force all bridge users to use the same timings, as suggested by Philippe Suggested-by: Philippe Cornu <philippe.cornu@st.com> Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> Reviewed-by: Philippe Cornu <philippe.cornu@st.com> Tested-by: Yannick Fertre <yannick.fertre@st.com> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191209143130.4553-2-heiko@sntech.de
Diffstat (limited to 'drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c')
-rw-r--r--drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 5f23cf702cb4..b41d86ee9e17 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -559,9 +559,87 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
return 0;
}
+struct hstt {
+ unsigned int maxfreq;
+ struct dw_mipi_dsi_dphy_timing timing;
+};
+
+#define HSTT(_maxfreq, _c_lp2hs, _c_hs2lp, _d_lp2hs, _d_hs2lp) \
+{ \
+ .maxfreq = _maxfreq, \
+ .timing = { \
+ .clk_lp2hs = _c_lp2hs, \
+ .clk_hs2lp = _c_hs2lp, \
+ .data_lp2hs = _d_lp2hs, \
+ .data_hs2lp = _d_hs2lp, \
+ } \
+}
+
+/* Table A-3 High-Speed Transition Times */
+struct hstt hstt_table[] = {
+ HSTT( 90, 32, 20, 26, 13),
+ HSTT( 100, 35, 23, 28, 14),
+ HSTT( 110, 32, 22, 26, 13),
+ HSTT( 130, 31, 20, 27, 13),
+ HSTT( 140, 33, 22, 26, 14),
+ HSTT( 150, 33, 21, 26, 14),
+ HSTT( 170, 32, 20, 27, 13),
+ HSTT( 180, 36, 23, 30, 15),
+ HSTT( 200, 40, 22, 33, 15),
+ HSTT( 220, 40, 22, 33, 15),
+ HSTT( 240, 44, 24, 36, 16),
+ HSTT( 250, 48, 24, 38, 17),
+ HSTT( 270, 48, 24, 38, 17),
+ HSTT( 300, 50, 27, 41, 18),
+ HSTT( 330, 56, 28, 45, 18),
+ HSTT( 360, 59, 28, 48, 19),
+ HSTT( 400, 61, 30, 50, 20),
+ HSTT( 450, 67, 31, 55, 21),
+ HSTT( 500, 73, 31, 59, 22),
+ HSTT( 550, 79, 36, 63, 24),
+ HSTT( 600, 83, 37, 68, 25),
+ HSTT( 650, 90, 38, 73, 27),
+ HSTT( 700, 95, 40, 77, 28),
+ HSTT( 750, 102, 40, 84, 28),
+ HSTT( 800, 106, 42, 87, 30),
+ HSTT( 850, 113, 44, 93, 31),
+ HSTT( 900, 118, 47, 98, 32),
+ HSTT( 950, 124, 47, 102, 34),
+ HSTT(1000, 130, 49, 107, 35),
+ HSTT(1050, 135, 51, 111, 37),
+ HSTT(1100, 139, 51, 114, 38),
+ HSTT(1150, 146, 54, 120, 40),
+ HSTT(1200, 153, 57, 125, 41),
+ HSTT(1250, 158, 58, 130, 42),
+ HSTT(1300, 163, 58, 135, 44),
+ HSTT(1350, 168, 60, 140, 45),
+ HSTT(1400, 172, 64, 144, 47),
+ HSTT(1450, 176, 65, 148, 48),
+ HSTT(1500, 181, 66, 153, 50)
+};
+
+static int
+dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
+ struct dw_mipi_dsi_dphy_timing *timing)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(hstt_table); i++)
+ if (lane_mbps < hstt_table[i].maxfreq)
+ break;
+
+ if (i == ARRAY_SIZE(hstt_table))
+ i--;
+
+ *timing = hstt_table[i].timing;
+
+ return 0;
+}
+
static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_rockchip_phy_ops = {
.init = dw_mipi_dsi_phy_init,
.get_lane_mbps = dw_mipi_dsi_get_lane_mbps,
+ .get_timing = dw_mipi_dsi_phy_get_timing,
};
static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi,