summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorFurquan Shaikh <furquan@google.com>2013-07-22 16:18:31 -0700
committerPatrick Georgi <patrick@georgi-clan.de>2013-12-21 08:04:10 +0100
commit6b19071ffb89dbb68196b7f3b088d87d4fad9e80 (patch)
treecb68ceaff1796a7798288eba1f6472154642b76a /src/drivers
parent3d9b5a29317b9df63698abbcf743ff4d15b2892a (diff)
FUI: Fill in link_m and link_n values
... based on the EDID detailed timing values for pixel_clock and link_clock. Two undocumented registers 0x6f040 and 0x6f044 correspond to link_m and link_n respectively. Other two undocumented registers 0x6f030 and 0x6f034 correspond to data_m and data_n respectively. Calculations are based on the intel_link_compute_m_n from linux kernel. Currently, the value for 0x6f030 does not come up right with our calculations. Hence, set to hard-coded value. Change-Id: I40ff411729d0a61759164c3c1098504973f9cf5e Reviewed-on: https://gerrit.chromium.org/gerrit/62915 Reviewed-by: Ronald G. Minnich <rminnich@chromium.org> Tested-by: Furquan Shaikh <furquan@chromium.org> Commit-Queue: Furquan Shaikh <furquan@chromium.org> Reviewed-on: http://review.coreboot.org/4381 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/intel/gma/i915.h14
-rw-r--r--src/drivers/intel/gma/i915_reg.h4
-rw-r--r--src/drivers/intel/gma/intel_dp.c58
3 files changed, 54 insertions, 22 deletions
diff --git a/src/drivers/intel/gma/i915.h b/src/drivers/intel/gma/i915.h
index e976f912cc..62fe0230e6 100644
--- a/src/drivers/intel/gma/i915.h
+++ b/src/drivers/intel/gma/i915.h
@@ -65,6 +65,14 @@ void io_i915_write32(unsigned long val, unsigned long addr);
#define DP_LINK_CONFIGURATION_SIZE 9
+struct intel_dp_m_n {
+ uint32_t tu;
+ uint32_t gmch_m;
+ uint32_t gmch_n;
+ uint32_t link_m;
+ uint32_t link_n;
+};
+
struct intel_dp {
int gen; // 6 for link, 7 for wtm2
int has_pch_split; // 1 for link and wtm2
@@ -134,6 +142,7 @@ struct intel_dp {
u32 pfa_ctl;
u32 pipesrc;
u32 stride;
+ struct intel_dp_m_n m_n;
};
/* we may yet need these. */
@@ -183,3 +192,8 @@ void intel_dp_wait_reg(unsigned long addr,
void intel_dp_wait_panel_power_control(unsigned long val);
+void intel_dp_compute_m_n(unsigned int bits_per_pixel,
+ unsigned int nlanes,
+ unsigned int pixel_clock,
+ unsigned int link_clock,
+ struct intel_dp_m_n *m_n);
diff --git a/src/drivers/intel/gma/i915_reg.h b/src/drivers/intel/gma/i915_reg.h
index d947f1af79..27a3d2b7da 100644
--- a/src/drivers/intel/gma/i915_reg.h
+++ b/src/drivers/intel/gma/i915_reg.h
@@ -3321,6 +3321,10 @@
#define _PIPEA_DATA_M1 0x60030
#define TU_SIZE(x) (((x)-1) << 25) /* default size 64 */
#define TU_SIZE_MASK 0x7e000000
+
+#define DATA_LINK_M_N_MASK (0xffffff)
+#define DATA_LINK_N_MAX (0x800000)
+
#define PIPE_DATA_M1_OFFSET 0
#define _PIPEA_DATA_N1 0x60034
#define PIPE_DATA_N1_OFFSET 0
diff --git a/src/drivers/intel/gma/intel_dp.c b/src/drivers/intel/gma/intel_dp.c
index 8097c6aca5..0def7717ac 100644
--- a/src/drivers/intel/gma/intel_dp.c
+++ b/src/drivers/intel/gma/intel_dp.c
@@ -393,37 +393,51 @@ intel_dp_i2c_init(struct intel_dp *intel_dp)
return ret;
}
-struct intel_dp_m_n {
- uint32_t tu;
- uint32_t gmch_m;
- uint32_t gmch_n;
- uint32_t link_m;
- uint32_t link_n;
-};
-
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;
*den >>= 1;
}
}
-static void
-intel_dp_compute_m_n(int bpp,
- int nlanes,
- int pixel_clock,
- int link_clock,
- struct intel_dp_m_n *m_n)
+unsigned int roundup_power_of_two(unsigned int n);
+
+unsigned int roundup_power_of_two(unsigned int n)
+{
+ n--;
+ n |= n >> 1;
+ n |= n >> 2;
+ n |= n >> 4;
+ n |= n >> 8;
+ n |= n >> 16;
+ n++;
+ return n;
+}
+
+static void compute_m_n(unsigned int m, unsigned int n,
+ unsigned int *ret_m, unsigned int *ret_n)
+{
+ *ret_n = MIN(roundup_power_of_two(n), DATA_LINK_N_MAX);
+ *ret_m = ( (unsigned long long)m * *ret_n) / n;
+ intel_reduce_m_n_ratio(ret_m, ret_n);
+}
+
+void intel_dp_compute_m_n(unsigned int bits_per_pixel,
+ unsigned int nlanes,
+ unsigned int pixel_clock,
+ unsigned int link_clock,
+ struct intel_dp_m_n *m_n)
{
m_n->tu = 64;
- m_n->gmch_m = (pixel_clock * bpp) >> 3;
- m_n->gmch_n = link_clock * nlanes;
- intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
- m_n->link_m = pixel_clock;
- m_n->link_n = link_clock;
- intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
+
+ compute_m_n(bits_per_pixel * pixel_clock,
+ link_clock * nlanes * 8,
+ &m_n->gmch_m, &m_n->gmch_n);
+
+ compute_m_n(pixel_clock, link_clock,
+ &m_n->link_m, &m_n->link_n);
}
/* not sure. */