Commit 8e9c4038 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel into drm-next

Just a few important fixes for 3.10. 3 regression fixes, plus rectified
Haswell overclock support (the old code was correct, only docs confusing)
and improved DP data m/n selection.

* 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel:
  drm/i915: correct the calculation of first_pd_entry_in_global_pt
  Revert "drm/i915: Don't overclock on Haswell"
  drm/i915: Make data/link N value power of two
  drm/i915: avoid full modeset when changing the color range properties
  drm/i915: Fall back to bit banging mode for DVO transmitter detection
parents 8b1f3dc8 43b27290
...@@ -233,8 +233,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ...@@ -233,8 +233,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
/* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024
* entries. For aliasing ppgtt support we just steal them at the end for * entries. For aliasing ppgtt support we just steal them at the end for
* now. */ * now. */
first_pd_entry_in_global_pt = first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt);
gtt_total_entries(dev_priv->gtt) - I915_PPGTT_PD_ENTRIES;
ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES; ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES;
ppgtt->enable = gen6_ppgtt_enable; ppgtt->enable = gen6_ppgtt_enable;
......
...@@ -2652,14 +2652,14 @@ ...@@ -2652,14 +2652,14 @@
#define _PIPEB_GMCH_DATA_M 0x71050 #define _PIPEB_GMCH_DATA_M 0x71050
/* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */ /* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */
#define PIPE_GMCH_DATA_M_TU_SIZE_MASK (0x3f << 25) #define TU_SIZE(x) (((x)-1) << 25) /* default size 64 */
#define PIPE_GMCH_DATA_M_TU_SIZE_SHIFT 25 #define TU_SIZE_MASK (0x3f << 25)
#define PIPE_GMCH_DATA_M_MASK (0xffffff) #define DATA_LINK_M_N_MASK (0xffffff)
#define DATA_LINK_N_MAX (0x800000)
#define _PIPEA_GMCH_DATA_N 0x70054 #define _PIPEA_GMCH_DATA_N 0x70054
#define _PIPEB_GMCH_DATA_N 0x71054 #define _PIPEB_GMCH_DATA_N 0x71054
#define PIPE_GMCH_DATA_N_MASK (0xffffff)
/* /*
* Computing Link M and N values for the Display Port link * Computing Link M and N values for the Display Port link
...@@ -2674,11 +2674,9 @@ ...@@ -2674,11 +2674,9 @@
#define _PIPEA_DP_LINK_M 0x70060 #define _PIPEA_DP_LINK_M 0x70060
#define _PIPEB_DP_LINK_M 0x71060 #define _PIPEB_DP_LINK_M 0x71060
#define PIPEA_DP_LINK_M_MASK (0xffffff)
#define _PIPEA_DP_LINK_N 0x70064 #define _PIPEA_DP_LINK_N 0x70064
#define _PIPEB_DP_LINK_N 0x71064 #define _PIPEB_DP_LINK_N 0x71064
#define PIPEA_DP_LINK_N_MASK (0xffffff)
#define PIPE_GMCH_DATA_M(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_M, _PIPEB_GMCH_DATA_M) #define PIPE_GMCH_DATA_M(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_M, _PIPEB_GMCH_DATA_M)
#define PIPE_GMCH_DATA_N(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_N, _PIPEB_GMCH_DATA_N) #define PIPE_GMCH_DATA_N(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_N, _PIPEB_GMCH_DATA_N)
...@@ -3404,8 +3402,6 @@ ...@@ -3404,8 +3402,6 @@
#define _PIPEA_DATA_M1 (dev_priv->info->display_mmio_offset + 0x60030) #define _PIPEA_DATA_M1 (dev_priv->info->display_mmio_offset + 0x60030)
#define TU_SIZE(x) (((x)-1) << 25) /* default size 64 */
#define TU_SIZE_MASK 0x7e000000
#define PIPE_DATA_M1_OFFSET 0 #define PIPE_DATA_M1_OFFSET 0
#define _PIPEA_DATA_N1 (dev_priv->info->display_mmio_offset + 0x60034) #define _PIPEA_DATA_N1 (dev_priv->info->display_mmio_offset + 0x60034)
#define PIPE_DATA_N1_OFFSET 0 #define PIPE_DATA_N1_OFFSET 0
......
...@@ -4084,26 +4084,36 @@ static int i830_get_display_clock_speed(struct drm_device *dev) ...@@ -4084,26 +4084,36 @@ static int i830_get_display_clock_speed(struct drm_device *dev)
} }
static void static void
intel_reduce_ratio(uint32_t *num, uint32_t *den) intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den)
{ {
while (*num > 0xffffff || *den > 0xffffff) { while (*num > DATA_LINK_M_N_MASK ||
*den > DATA_LINK_M_N_MASK) {
*num >>= 1; *num >>= 1;
*den >>= 1; *den >>= 1;
} }
} }
static void compute_m_n(unsigned int m, unsigned int n,
uint32_t *ret_m, uint32_t *ret_n)
{
*ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX);
*ret_m = div_u64((uint64_t) m * *ret_n, n);
intel_reduce_m_n_ratio(ret_m, ret_n);
}
void void
intel_link_compute_m_n(int bits_per_pixel, int nlanes, intel_link_compute_m_n(int bits_per_pixel, int nlanes,
int pixel_clock, int link_clock, int pixel_clock, int link_clock,
struct intel_link_m_n *m_n) struct intel_link_m_n *m_n)
{ {
m_n->tu = 64; m_n->tu = 64;
m_n->gmch_m = bits_per_pixel * pixel_clock;
m_n->gmch_n = link_clock * nlanes * 8; compute_m_n(bits_per_pixel * pixel_clock,
intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); link_clock * nlanes * 8,
m_n->link_m = pixel_clock; &m_n->gmch_m, &m_n->gmch_n);
m_n->link_n = link_clock;
intel_reduce_ratio(&m_n->link_m, &m_n->link_n); compute_m_n(pixel_clock, link_clock,
&m_n->link_m, &m_n->link_n);
} }
static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
......
...@@ -2428,6 +2428,9 @@ intel_dp_set_property(struct drm_connector *connector, ...@@ -2428,6 +2428,9 @@ intel_dp_set_property(struct drm_connector *connector,
} }
if (property == dev_priv->broadcast_rgb_property) { if (property == dev_priv->broadcast_rgb_property) {
bool old_auto = intel_dp->color_range_auto;
uint32_t old_range = intel_dp->color_range;
switch (val) { switch (val) {
case INTEL_BROADCAST_RGB_AUTO: case INTEL_BROADCAST_RGB_AUTO:
intel_dp->color_range_auto = true; intel_dp->color_range_auto = true;
...@@ -2443,6 +2446,11 @@ intel_dp_set_property(struct drm_connector *connector, ...@@ -2443,6 +2446,11 @@ intel_dp_set_property(struct drm_connector *connector,
default: default:
return -EINVAL; return -EINVAL;
} }
if (old_auto == intel_dp->color_range_auto &&
old_range == intel_dp->color_range)
return 0;
goto done; goto done;
} }
......
...@@ -448,6 +448,7 @@ void intel_dvo_init(struct drm_device *dev) ...@@ -448,6 +448,7 @@ void intel_dvo_init(struct drm_device *dev)
const struct intel_dvo_device *dvo = &intel_dvo_devices[i]; const struct intel_dvo_device *dvo = &intel_dvo_devices[i];
struct i2c_adapter *i2c; struct i2c_adapter *i2c;
int gpio; int gpio;
bool dvoinit;
/* Allow the I2C driver info to specify the GPIO to be used in /* Allow the I2C driver info to specify the GPIO to be used in
* special cases, but otherwise default to what's defined * special cases, but otherwise default to what's defined
...@@ -467,7 +468,17 @@ void intel_dvo_init(struct drm_device *dev) ...@@ -467,7 +468,17 @@ void intel_dvo_init(struct drm_device *dev)
i2c = intel_gmbus_get_adapter(dev_priv, gpio); i2c = intel_gmbus_get_adapter(dev_priv, gpio);
intel_dvo->dev = *dvo; intel_dvo->dev = *dvo;
if (!dvo->dev_ops->init(&intel_dvo->dev, i2c))
/* GMBUS NAK handling seems to be unstable, hence let the
* transmitter detection run in bit banging mode for now.
*/
intel_gmbus_force_bit(i2c, true);
dvoinit = dvo->dev_ops->init(&intel_dvo->dev, i2c);
intel_gmbus_force_bit(i2c, false);
if (!dvoinit)
continue; continue;
intel_encoder->type = INTEL_OUTPUT_DVO; intel_encoder->type = INTEL_OUTPUT_DVO;
......
...@@ -920,6 +920,9 @@ intel_hdmi_set_property(struct drm_connector *connector, ...@@ -920,6 +920,9 @@ intel_hdmi_set_property(struct drm_connector *connector,
} }
if (property == dev_priv->broadcast_rgb_property) { if (property == dev_priv->broadcast_rgb_property) {
bool old_auto = intel_hdmi->color_range_auto;
uint32_t old_range = intel_hdmi->color_range;
switch (val) { switch (val) {
case INTEL_BROADCAST_RGB_AUTO: case INTEL_BROADCAST_RGB_AUTO:
intel_hdmi->color_range_auto = true; intel_hdmi->color_range_auto = true;
...@@ -935,6 +938,11 @@ intel_hdmi_set_property(struct drm_connector *connector, ...@@ -935,6 +938,11 @@ intel_hdmi_set_property(struct drm_connector *connector,
default: default:
return -EINVAL; return -EINVAL;
} }
if (old_auto == intel_hdmi->color_range_auto &&
old_range == intel_hdmi->color_range)
return 0;
goto done; goto done;
} }
......
...@@ -2639,7 +2639,7 @@ static void gen6_enable_rps(struct drm_device *dev) ...@@ -2639,7 +2639,7 @@ static void gen6_enable_rps(struct drm_device *dev)
(IS_HASWELL(dev) ? GEN7_RP_DOWN_IDLE_AVG : GEN6_RP_DOWN_IDLE_CONT)); (IS_HASWELL(dev) ? GEN7_RP_DOWN_IDLE_AVG : GEN6_RP_DOWN_IDLE_CONT));
ret = sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_MIN_FREQ_TABLE, 0); ret = sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_MIN_FREQ_TABLE, 0);
if (!ret && (IS_GEN6(dev) || IS_IVYBRIDGE(dev))) { if (!ret) {
pcu_mbox = 0; pcu_mbox = 0;
ret = sandybridge_pcode_read(dev_priv, GEN6_READ_OC_PARAMS, &pcu_mbox); ret = sandybridge_pcode_read(dev_priv, GEN6_READ_OC_PARAMS, &pcu_mbox);
if (!ret && (pcu_mbox & (1<<31))) { /* OC supported */ if (!ret && (pcu_mbox & (1<<31))) { /* OC supported */
......
...@@ -1930,6 +1930,9 @@ intel_sdvo_set_property(struct drm_connector *connector, ...@@ -1930,6 +1930,9 @@ intel_sdvo_set_property(struct drm_connector *connector,
} }
if (property == dev_priv->broadcast_rgb_property) { if (property == dev_priv->broadcast_rgb_property) {
bool old_auto = intel_sdvo->color_range_auto;
uint32_t old_range = intel_sdvo->color_range;
switch (val) { switch (val) {
case INTEL_BROADCAST_RGB_AUTO: case INTEL_BROADCAST_RGB_AUTO:
intel_sdvo->color_range_auto = true; intel_sdvo->color_range_auto = true;
...@@ -1947,6 +1950,11 @@ intel_sdvo_set_property(struct drm_connector *connector, ...@@ -1947,6 +1950,11 @@ intel_sdvo_set_property(struct drm_connector *connector,
default: default:
return -EINVAL; return -EINVAL;
} }
if (old_auto == intel_sdvo->color_range_auto &&
old_range == intel_sdvo->color_range)
return 0;
goto done; goto done;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment