diff options
author | Furquan Shaikh <furquan@google.com> | 2013-07-22 16:18:31 -0700 |
---|---|---|
committer | Patrick Georgi <patrick@georgi-clan.de> | 2013-12-21 08:04:10 +0100 |
commit | 6b19071ffb89dbb68196b7f3b088d87d4fad9e80 (patch) | |
tree | cb68ceaff1796a7798288eba1f6472154642b76a /src/drivers/intel/gma/intel_dp.c | |
parent | 3d9b5a29317b9df63698abbcf743ff4d15b2892a (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/intel/gma/intel_dp.c')
-rw-r--r-- | src/drivers/intel/gma/intel_dp.c | 58 |
1 files changed, 36 insertions, 22 deletions
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. */ |