diff options
author | Ramalingam C <ramalingam.c@intel.com> | 2016-04-19 04:18:14 -0400 |
---|---|---|
committer | Jani Nikula <jani.nikula@intel.com> | 2016-05-23 04:21:06 -0400 |
commit | 4832aa16c4cdfc750e47c5752a32776f93b6448d (patch) | |
tree | 0ddebb75d8f0f3c5a0a3b08f046b378b0155784a /drivers/gpu | |
parent | 7045c3689f148a0c95f42bae8ef3eb2829ac7de9 (diff) |
drm/i915/bxt: Adjusting the error in horizontal timings retrieval
In BXT DSI there is no regs programmed with few horizontal timings
in Pixels but txbyteclkhs.. So retrieval process adds some
ROUND_UP ERRORS in the process of PIXELS<==>txbyteclkhs.
Actually here for the given adjusted_mode, we are calculating the
value programmed to the port and then back to the horizontal timing
param in pixels. This is the expected value at the end of get_config,
including roundup errors. And if that is same as retrieved value
from port, then retrieved (HW state) adjusted_mode's horizontal
timings are corrected to match with SW state to nullify the errors.
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1461053894-5058-2-git-send-email-ramalingam.c@intel.com
(cherry picked from commit 042ab0c3c40be1efcaad6b526173b5536fc6c3bf)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dsi.c | 97 |
1 files changed, 88 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index efa306bb19c9..366ad6c67ce4 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c | |||
@@ -46,6 +46,14 @@ static const struct { | |||
46 | }, | 46 | }, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | /* return pixels in terms of txbyteclkhs */ | ||
50 | static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count, | ||
51 | u16 burst_mode_ratio) | ||
52 | { | ||
53 | return DIV_ROUND_UP(DIV_ROUND_UP(pixels * bpp * burst_mode_ratio, | ||
54 | 8 * 100), lane_count); | ||
55 | } | ||
56 | |||
49 | /* return pixels equvalent to txbyteclkhs */ | 57 | /* return pixels equvalent to txbyteclkhs */ |
50 | static u16 pixels_from_txbyteclkhs(u16 clk_hs, int bpp, int lane_count, | 58 | static u16 pixels_from_txbyteclkhs(u16 clk_hs, int bpp, int lane_count, |
51 | u16 burst_mode_ratio) | 59 | u16 burst_mode_ratio) |
@@ -788,11 +796,19 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, | |||
788 | struct drm_i915_private *dev_priv = dev->dev_private; | 796 | struct drm_i915_private *dev_priv = dev->dev_private; |
789 | struct drm_display_mode *adjusted_mode = | 797 | struct drm_display_mode *adjusted_mode = |
790 | &pipe_config->base.adjusted_mode; | 798 | &pipe_config->base.adjusted_mode; |
799 | struct drm_display_mode *adjusted_mode_sw; | ||
800 | struct intel_crtc *intel_crtc; | ||
791 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | 801 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); |
792 | unsigned int lane_count = intel_dsi->lane_count; | 802 | unsigned int lane_count = intel_dsi->lane_count; |
793 | unsigned int bpp, fmt; | 803 | unsigned int bpp, fmt; |
794 | enum port port; | 804 | enum port port; |
795 | u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp; | 805 | u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp; |
806 | u16 hfp_sw, hsync_sw, hbp_sw; | ||
807 | u16 crtc_htotal_sw, crtc_hsync_start_sw, crtc_hsync_end_sw, | ||
808 | crtc_hblank_start_sw, crtc_hblank_end_sw; | ||
809 | |||
810 | intel_crtc = to_intel_crtc(encoder->base.crtc); | ||
811 | adjusted_mode_sw = &intel_crtc->config->base.adjusted_mode; | ||
796 | 812 | ||
797 | /* | 813 | /* |
798 | * Atleast one port is active as encoder->get_config called only if | 814 | * Atleast one port is active as encoder->get_config called only if |
@@ -856,8 +872,79 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, | |||
856 | adjusted_mode->crtc_vsync_end = vsync + adjusted_mode->crtc_vsync_start; | 872 | adjusted_mode->crtc_vsync_end = vsync + adjusted_mode->crtc_vsync_start; |
857 | adjusted_mode->crtc_vblank_start = adjusted_mode->crtc_vdisplay; | 873 | adjusted_mode->crtc_vblank_start = adjusted_mode->crtc_vdisplay; |
858 | adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vtotal; | 874 | adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vtotal; |
859 | } | ||
860 | 875 | ||
876 | /* | ||
877 | * In BXT DSI there is no regs programmed with few horizontal timings | ||
878 | * in Pixels but txbyteclkhs.. So retrieval process adds some | ||
879 | * ROUND_UP ERRORS in the process of PIXELS<==>txbyteclkhs. | ||
880 | * Actually here for the given adjusted_mode, we are calculating the | ||
881 | * value programmed to the port and then back to the horizontal timing | ||
882 | * param in pixels. This is the expected value, including roundup errors | ||
883 | * And if that is same as retrieved value from port, then | ||
884 | * (HW state) adjusted_mode's horizontal timings are corrected to | ||
885 | * match with SW state to nullify the errors. | ||
886 | */ | ||
887 | /* Calculating the value programmed to the Port register */ | ||
888 | hfp_sw = adjusted_mode_sw->crtc_hsync_start - | ||
889 | adjusted_mode_sw->crtc_hdisplay; | ||
890 | hsync_sw = adjusted_mode_sw->crtc_hsync_end - | ||
891 | adjusted_mode_sw->crtc_hsync_start; | ||
892 | hbp_sw = adjusted_mode_sw->crtc_htotal - | ||
893 | adjusted_mode_sw->crtc_hsync_end; | ||
894 | |||
895 | if (intel_dsi->dual_link) { | ||
896 | hfp_sw /= 2; | ||
897 | hsync_sw /= 2; | ||
898 | hbp_sw /= 2; | ||
899 | } | ||
900 | |||
901 | hfp_sw = txbyteclkhs(hfp_sw, bpp, lane_count, | ||
902 | intel_dsi->burst_mode_ratio); | ||
903 | hsync_sw = txbyteclkhs(hsync_sw, bpp, lane_count, | ||
904 | intel_dsi->burst_mode_ratio); | ||
905 | hbp_sw = txbyteclkhs(hbp_sw, bpp, lane_count, | ||
906 | intel_dsi->burst_mode_ratio); | ||
907 | |||
908 | /* Reverse calculating the adjusted mode parameters from port reg vals*/ | ||
909 | hfp_sw = pixels_from_txbyteclkhs(hfp_sw, bpp, lane_count, | ||
910 | intel_dsi->burst_mode_ratio); | ||
911 | hsync_sw = pixels_from_txbyteclkhs(hsync_sw, bpp, lane_count, | ||
912 | intel_dsi->burst_mode_ratio); | ||
913 | hbp_sw = pixels_from_txbyteclkhs(hbp_sw, bpp, lane_count, | ||
914 | intel_dsi->burst_mode_ratio); | ||
915 | |||
916 | if (intel_dsi->dual_link) { | ||
917 | hfp_sw *= 2; | ||
918 | hsync_sw *= 2; | ||
919 | hbp_sw *= 2; | ||
920 | } | ||
921 | |||
922 | crtc_htotal_sw = adjusted_mode_sw->crtc_hdisplay + hfp_sw + | ||
923 | hsync_sw + hbp_sw; | ||
924 | crtc_hsync_start_sw = hfp_sw + adjusted_mode_sw->crtc_hdisplay; | ||
925 | crtc_hsync_end_sw = hsync_sw + crtc_hsync_start_sw; | ||
926 | crtc_hblank_start_sw = adjusted_mode_sw->crtc_hdisplay; | ||
927 | crtc_hblank_end_sw = crtc_htotal_sw; | ||
928 | |||
929 | if (adjusted_mode->crtc_htotal == crtc_htotal_sw) | ||
930 | adjusted_mode->crtc_htotal = adjusted_mode_sw->crtc_htotal; | ||
931 | |||
932 | if (adjusted_mode->crtc_hsync_start == crtc_hsync_start_sw) | ||
933 | adjusted_mode->crtc_hsync_start = | ||
934 | adjusted_mode_sw->crtc_hsync_start; | ||
935 | |||
936 | if (adjusted_mode->crtc_hsync_end == crtc_hsync_end_sw) | ||
937 | adjusted_mode->crtc_hsync_end = | ||
938 | adjusted_mode_sw->crtc_hsync_end; | ||
939 | |||
940 | if (adjusted_mode->crtc_hblank_start == crtc_hblank_start_sw) | ||
941 | adjusted_mode->crtc_hblank_start = | ||
942 | adjusted_mode_sw->crtc_hblank_start; | ||
943 | |||
944 | if (adjusted_mode->crtc_hblank_end == crtc_hblank_end_sw) | ||
945 | adjusted_mode->crtc_hblank_end = | ||
946 | adjusted_mode_sw->crtc_hblank_end; | ||
947 | } | ||
861 | 948 | ||
862 | static void intel_dsi_get_config(struct intel_encoder *encoder, | 949 | static void intel_dsi_get_config(struct intel_encoder *encoder, |
863 | struct intel_crtc_state *pipe_config) | 950 | struct intel_crtc_state *pipe_config) |
@@ -921,14 +1008,6 @@ static u16 txclkesc(u32 divider, unsigned int us) | |||
921 | } | 1008 | } |
922 | } | 1009 | } |
923 | 1010 | ||
924 | /* return pixels in terms of txbyteclkhs */ | ||
925 | static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count, | ||
926 | u16 burst_mode_ratio) | ||
927 | { | ||
928 | return DIV_ROUND_UP(DIV_ROUND_UP(pixels * bpp * burst_mode_ratio, | ||
929 | 8 * 100), lane_count); | ||
930 | } | ||
931 | |||
932 | static void set_dsi_timings(struct drm_encoder *encoder, | 1011 | static void set_dsi_timings(struct drm_encoder *encoder, |
933 | const struct drm_display_mode *adjusted_mode) | 1012 | const struct drm_display_mode *adjusted_mode) |
934 | { | 1013 | { |