Loading drivers/gpu/drm/i915/intel_display.c +59 −13 Original line number Diff line number Diff line Loading @@ -2709,27 +2709,19 @@ fdi_reduce_ratio(u32 *num, u32 *den) } } #define DATA_N 0x800000 #define LINK_N 0x80000 static void ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, int link_clock, struct fdi_m_n *m_n) { u64 temp; m_n->tu = 64; /* default size */ temp = (u64) DATA_N * pixel_clock; temp = div_u64(temp, link_clock); m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes); m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */ m_n->gmch_n = DATA_N; /* BUG_ON(pixel_clock > INT_MAX / 36); */ m_n->gmch_m = bits_per_pixel * pixel_clock; m_n->gmch_n = link_clock * nlanes * 8; fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); temp = (u64) LINK_N * pixel_clock; m_n->link_m = div_u64(temp, link_clock); m_n->link_n = LINK_N; m_n->link_m = pixel_clock; m_n->link_n = link_clock; fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); } Loading Loading @@ -3713,6 +3705,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* FDI link */ if (HAS_PCH_SPLIT(dev)) { int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); int lane = 0, link_bw, bpp; /* CPU eDP doesn't require FDI link, so just set DP M/N according to current link config */ Loading Loading @@ -3796,6 +3789,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, intel_crtc->fdi_lanes = lane; if (pixel_multiplier > 1) link_bw *= pixel_multiplier; ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); } Loading Loading @@ -5263,6 +5258,55 @@ static const struct drm_crtc_funcs intel_crtc_funcs = { .page_flip = intel_crtc_page_flip, }; static void intel_sanitize_modesetting(struct drm_device *dev, int pipe, int plane) { struct drm_i915_private *dev_priv = dev->dev_private; u32 reg, val; if (HAS_PCH_SPLIT(dev)) return; /* Who knows what state these registers were left in by the BIOS or * grub? * * If we leave the registers in a conflicting state (e.g. with the * display plane reading from the other pipe than the one we intend * to use) then when we attempt to teardown the active mode, we will * not disable the pipes and planes in the correct order -- leaving * a plane reading from a disabled pipe and possibly leading to * undefined behaviour. */ reg = DSPCNTR(plane); val = I915_READ(reg); if ((val & DISPLAY_PLANE_ENABLE) == 0) return; if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe) return; /* This display plane is active and attached to the other CPU pipe. */ pipe = !pipe; /* Disable the plane and wait for it to stop reading from the pipe. */ I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); intel_flush_display_plane(dev, plane); if (IS_GEN2(dev)) intel_wait_for_vblank(dev, pipe); if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) return; /* Switch off the pipe. */ reg = PIPECONF(pipe); val = I915_READ(reg); if (val & PIPECONF_ENABLE) { I915_WRITE(reg, val & ~PIPECONF_ENABLE); intel_wait_for_pipe_off(dev, pipe); } } static void intel_crtc_init(struct drm_device *dev, int pipe) { Loading Loading @@ -5314,6 +5358,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, (unsigned long)intel_crtc); intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); } int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, Loading Loading
drivers/gpu/drm/i915/intel_display.c +59 −13 Original line number Diff line number Diff line Loading @@ -2709,27 +2709,19 @@ fdi_reduce_ratio(u32 *num, u32 *den) } } #define DATA_N 0x800000 #define LINK_N 0x80000 static void ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, int link_clock, struct fdi_m_n *m_n) { u64 temp; m_n->tu = 64; /* default size */ temp = (u64) DATA_N * pixel_clock; temp = div_u64(temp, link_clock); m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes); m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */ m_n->gmch_n = DATA_N; /* BUG_ON(pixel_clock > INT_MAX / 36); */ m_n->gmch_m = bits_per_pixel * pixel_clock; m_n->gmch_n = link_clock * nlanes * 8; fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); temp = (u64) LINK_N * pixel_clock; m_n->link_m = div_u64(temp, link_clock); m_n->link_n = LINK_N; m_n->link_m = pixel_clock; m_n->link_n = link_clock; fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); } Loading Loading @@ -3713,6 +3705,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* FDI link */ if (HAS_PCH_SPLIT(dev)) { int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); int lane = 0, link_bw, bpp; /* CPU eDP doesn't require FDI link, so just set DP M/N according to current link config */ Loading Loading @@ -3796,6 +3789,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, intel_crtc->fdi_lanes = lane; if (pixel_multiplier > 1) link_bw *= pixel_multiplier; ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); } Loading Loading @@ -5263,6 +5258,55 @@ static const struct drm_crtc_funcs intel_crtc_funcs = { .page_flip = intel_crtc_page_flip, }; static void intel_sanitize_modesetting(struct drm_device *dev, int pipe, int plane) { struct drm_i915_private *dev_priv = dev->dev_private; u32 reg, val; if (HAS_PCH_SPLIT(dev)) return; /* Who knows what state these registers were left in by the BIOS or * grub? * * If we leave the registers in a conflicting state (e.g. with the * display plane reading from the other pipe than the one we intend * to use) then when we attempt to teardown the active mode, we will * not disable the pipes and planes in the correct order -- leaving * a plane reading from a disabled pipe and possibly leading to * undefined behaviour. */ reg = DSPCNTR(plane); val = I915_READ(reg); if ((val & DISPLAY_PLANE_ENABLE) == 0) return; if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe) return; /* This display plane is active and attached to the other CPU pipe. */ pipe = !pipe; /* Disable the plane and wait for it to stop reading from the pipe. */ I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); intel_flush_display_plane(dev, plane); if (IS_GEN2(dev)) intel_wait_for_vblank(dev, pipe); if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) return; /* Switch off the pipe. */ reg = PIPECONF(pipe); val = I915_READ(reg); if (val & PIPECONF_ENABLE) { I915_WRITE(reg, val & ~PIPECONF_ENABLE); intel_wait_for_pipe_off(dev, pipe); } } static void intel_crtc_init(struct drm_device *dev, int pipe) { Loading Loading @@ -5314,6 +5358,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, (unsigned long)intel_crtc); intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); } int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, Loading