aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@bootlin.com>2019-01-21 10:45:51 -0500
committerMaxime Ripard <maxime.ripard@bootlin.com>2019-02-07 03:41:27 -0500
commit4dad3e7f12f702980f42033cf8f93525f95d8db9 (patch)
tree417ec958925cd95b7ab4989eb66323d8c00837ab
parent5d134abf9530de2f453a2a5c97d5e165bcc95b83 (diff)
drm/bridge: cdns: Separate DSI and D-PHY configuration
The current configuration of the DSI bridge and its associated D-PHY is intertwined. In order to ease the future conversion to the phy framework for the D-PHY part, let's split the configuration in two. Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com> Link: https://patchwork.freedesktop.org/patch/msgid/0b3bea44e05745b65c23af7926ca546bc80a1bcc.1548085432.git-series.maxime.ripard@bootlin.com
-rw-r--r--drivers/gpu/drm/bridge/cdns-dsi.c101
1 files changed, 73 insertions, 28 deletions
diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cdns-dsi.c
index 924abe82ea3c..0f5bb3dca828 100644
--- a/drivers/gpu/drm/bridge/cdns-dsi.c
+++ b/drivers/gpu/drm/bridge/cdns-dsi.c
@@ -547,6 +547,15 @@ bridge_to_cdns_dsi_input(struct drm_bridge *bridge)
547 return container_of(bridge, struct cdns_dsi_input, bridge); 547 return container_of(bridge, struct cdns_dsi_input, bridge);
548} 548}
549 549
550static unsigned int mode_to_dpi_hfp(const struct drm_display_mode *mode,
551 bool mode_valid_check)
552{
553 if (mode_valid_check)
554 return mode->hsync_start - mode->hdisplay;
555
556 return mode->crtc_hsync_start - mode->crtc_hdisplay;
557}
558
550static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, 559static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
551 struct cdns_dphy_cfg *cfg, 560 struct cdns_dphy_cfg *cfg,
552 unsigned int dpi_htotal, 561 unsigned int dpi_htotal,
@@ -733,14 +742,12 @@ static unsigned int dpi_to_dsi_timing(unsigned int dpi_timing,
733static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, 742static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi,
734 const struct drm_display_mode *mode, 743 const struct drm_display_mode *mode,
735 struct cdns_dsi_cfg *dsi_cfg, 744 struct cdns_dsi_cfg *dsi_cfg,
736 struct cdns_dphy_cfg *dphy_cfg,
737 bool mode_valid_check) 745 bool mode_valid_check)
738{ 746{
739 unsigned long dsi_htotal = 0, dsi_hss_hsa_hse_hbp = 0;
740 struct cdns_dsi_output *output = &dsi->output; 747 struct cdns_dsi_output *output = &dsi->output;
741 unsigned int dsi_hfp_ext = 0, dpi_hfp, tmp; 748 unsigned int tmp;
742 bool sync_pulse = false; 749 bool sync_pulse = false;
743 int bpp, nlanes, ret; 750 int bpp, nlanes;
744 751
745 memset(dsi_cfg, 0, sizeof(*dsi_cfg)); 752 memset(dsi_cfg, 0, sizeof(*dsi_cfg));
746 753
@@ -759,8 +766,6 @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi,
759 mode->crtc_hsync_end : mode->crtc_hsync_start); 766 mode->crtc_hsync_end : mode->crtc_hsync_start);
760 767
761 dsi_cfg->hbp = dpi_to_dsi_timing(tmp, bpp, DSI_HBP_FRAME_OVERHEAD); 768 dsi_cfg->hbp = dpi_to_dsi_timing(tmp, bpp, DSI_HBP_FRAME_OVERHEAD);
762 dsi_htotal += dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD;
763 dsi_hss_hsa_hse_hbp += dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD;
764 769
765 if (sync_pulse) { 770 if (sync_pulse) {
766 if (mode_valid_check) 771 if (mode_valid_check)
@@ -770,49 +775,91 @@ static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi,
770 775
771 dsi_cfg->hsa = dpi_to_dsi_timing(tmp, bpp, 776 dsi_cfg->hsa = dpi_to_dsi_timing(tmp, bpp,
772 DSI_HSA_FRAME_OVERHEAD); 777 DSI_HSA_FRAME_OVERHEAD);
773 dsi_htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD;
774 dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD;
775 } 778 }
776 779
777 dsi_cfg->hact = dpi_to_dsi_timing(mode_valid_check ? 780 dsi_cfg->hact = dpi_to_dsi_timing(mode_valid_check ?
778 mode->hdisplay : mode->crtc_hdisplay, 781 mode->hdisplay : mode->crtc_hdisplay,
779 bpp, 0); 782 bpp, 0);
780 dsi_htotal += dsi_cfg->hact; 783 dsi_cfg->hfp = dpi_to_dsi_timing(mode_to_dpi_hfp(mode, mode_valid_check),
784 bpp, DSI_HFP_FRAME_OVERHEAD);
781 785
782 if (mode_valid_check) 786 return 0;
783 dpi_hfp = mode->hsync_start - mode->hdisplay; 787}
784 else 788
785 dpi_hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; 789static int cdns_dphy_validate(struct cdns_dsi *dsi,
790 struct cdns_dsi_cfg *dsi_cfg,
791 struct cdns_dphy_cfg *dphy_cfg,
792 const struct drm_display_mode *mode,
793 bool mode_valid_check)
794{
795 struct cdns_dsi_output *output = &dsi->output;
796 unsigned long dsi_htotal;
797 unsigned int dsi_hfp_ext = 0;
798
799 int ret;
800
801 dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD;
802 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
803 dsi_htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD;
786 804
787 dsi_cfg->hfp = dpi_to_dsi_timing(dpi_hfp, bpp, DSI_HFP_FRAME_OVERHEAD); 805 dsi_htotal += dsi_cfg->hact;
788 dsi_htotal += dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD; 806 dsi_htotal += dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD;
789 807
790 if (mode_valid_check) 808 if (mode_valid_check)
791 ret = cdns_dsi_get_dphy_pll_cfg(dsi->dphy, dphy_cfg, 809 ret = cdns_dsi_get_dphy_pll_cfg(dsi->dphy, dphy_cfg,
792 mode->htotal, bpp, 810 mode->htotal,
811 mipi_dsi_pixel_format_to_bpp(output->dev->format),
793 mode->clock * 1000, 812 mode->clock * 1000,
794 dsi_htotal, nlanes, 813 dsi_htotal,
814 output->dev->lanes,
795 &dsi_hfp_ext); 815 &dsi_hfp_ext);
796 else 816 else
797 ret = cdns_dsi_get_dphy_pll_cfg(dsi->dphy, dphy_cfg, 817 ret = cdns_dsi_get_dphy_pll_cfg(dsi->dphy, dphy_cfg,
798 mode->crtc_htotal, bpp, 818 mode->crtc_htotal,
819 mipi_dsi_pixel_format_to_bpp(output->dev->format),
799 mode->crtc_clock * 1000, 820 mode->crtc_clock * 1000,
800 dsi_htotal, nlanes, 821 dsi_htotal,
822 output->dev->lanes,
801 &dsi_hfp_ext); 823 &dsi_hfp_ext);
802
803 if (ret) 824 if (ret)
804 return ret; 825 return ret;
805 826
806 dsi_cfg->hfp += dsi_hfp_ext; 827 dsi_cfg->hfp += dsi_hfp_ext;
807 dsi_htotal += dsi_hfp_ext; 828 dsi_cfg->htotal = dsi_htotal + dsi_hfp_ext;
808 dsi_cfg->htotal = dsi_htotal; 829
830 return 0;
831}
832
833static int cdns_dsi_check_conf(struct cdns_dsi *dsi,
834 const struct drm_display_mode *mode,
835 struct cdns_dsi_cfg *dsi_cfg,
836 struct cdns_dphy_cfg *dphy_cfg,
837 bool mode_valid_check)
838{
839 struct cdns_dsi_output *output = &dsi->output;
840 unsigned long dsi_hss_hsa_hse_hbp;
841 unsigned int nlanes = output->dev->lanes;
842 int ret;
843
844 ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg, mode_valid_check);
845 if (ret)
846 return ret;
847
848 ret = cdns_dphy_validate(dsi, dsi_cfg, dphy_cfg, mode, mode_valid_check);
849 if (ret)
850 return ret;
851
852 dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD;
853 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
854 dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD;
809 855
810 /* 856 /*
811 * Make sure DPI(HFP) > DSI(HSS+HSA+HSE+HBP) to guarantee that the FIFO 857 * Make sure DPI(HFP) > DSI(HSS+HSA+HSE+HBP) to guarantee that the FIFO
812 * is empty before we start a receiving a new line on the DPI 858 * is empty before we start a receiving a new line on the DPI
813 * interface. 859 * interface.
814 */ 860 */
815 if ((u64)dphy_cfg->lane_bps * dpi_hfp * nlanes < 861 if ((u64)dphy_cfg->lane_bps *
862 mode_to_dpi_hfp(mode, mode_valid_check) * nlanes <
816 (u64)dsi_hss_hsa_hse_hbp * 863 (u64)dsi_hss_hsa_hse_hbp *
817 (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000) 864 (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000)
818 return -EINVAL; 865 return -EINVAL;
@@ -844,7 +891,7 @@ cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
844 struct cdns_dsi_output *output = &dsi->output; 891 struct cdns_dsi_output *output = &dsi->output;
845 struct cdns_dphy_cfg dphy_cfg; 892 struct cdns_dphy_cfg dphy_cfg;
846 struct cdns_dsi_cfg dsi_cfg; 893 struct cdns_dsi_cfg dsi_cfg;
847 int bpp, nlanes, ret; 894 int bpp, ret;
848 895
849 /* 896 /*
850 * VFP_DSI should be less than VFP_DPI and VFP_DSI should be at 897 * VFP_DSI should be less than VFP_DPI and VFP_DSI should be at
@@ -862,11 +909,9 @@ cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
862 if ((mode->hdisplay * bpp) % 32) 909 if ((mode->hdisplay * bpp) % 32)
863 return MODE_H_ILLEGAL; 910 return MODE_H_ILLEGAL;
864 911
865 nlanes = output->dev->lanes; 912 ret = cdns_dsi_check_conf(dsi, mode, &dsi_cfg, &dphy_cfg, true);
866
867 ret = cdns_dsi_mode2cfg(dsi, mode, &dsi_cfg, &dphy_cfg, true);
868 if (ret) 913 if (ret)
869 return MODE_CLOCK_RANGE; 914 return MODE_BAD;
870 915
871 return MODE_OK; 916 return MODE_OK;
872} 917}
@@ -992,7 +1037,7 @@ static void cdns_dsi_bridge_enable(struct drm_bridge *bridge)
992 bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format); 1037 bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format);
993 nlanes = output->dev->lanes; 1038 nlanes = output->dev->lanes;
994 1039
995 WARN_ON_ONCE(cdns_dsi_mode2cfg(dsi, mode, &dsi_cfg, &dphy_cfg, false)); 1040 WARN_ON_ONCE(cdns_dsi_check_conf(dsi, mode, &dsi_cfg, &dphy_cfg, false));
996 1041
997 cdns_dsi_hs_init(dsi, &dphy_cfg); 1042 cdns_dsi_hs_init(dsi, &dphy_cfg);
998 cdns_dsi_init_link(dsi); 1043 cdns_dsi_init_link(dsi);