summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/omapdrm
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2016-01-05 12:43:13 +0300
committerTomi Valkeinen <tomi.valkeinen@ti.com>2017-04-03 12:36:40 +0300
commit7d267f068a8b4944d52e8b0ae4c8fcc1c1c5c5ba (patch)
tree1e275a4708c319c008b2d5349cbdefc80236733d /drivers/gpu/drm/omapdrm
parent320d8c3d38739fa8e31a076b86cbdafcf8897d5e (diff)
downloadlinux-7d267f068a8b4944d52e8b0ae4c8fcc1c1c5c5ba.tar.xz
drm/omap: work-around for errata i886
DRA7 errata i886 (FPDLink PLL Unlocks With Certain SoC PLL M/N Values) says that FPDLink is sensitive to jitter on the vout clock, and that low PLL M and N values result in more jitter than high M and N values. This patch implements a workaround for the problem by changing the PLL setup to search for clocks starting from high M and N values, instead of low values. This should not cause any functional change, and only reduces the jitter. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm')
-rw-r--r--drivers/gpu/drm/omapdrm/dss/pll.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/pll.c b/drivers/gpu/drm/omapdrm/dss/pll.c
index 0a76c89cdc2e..5e221302768b 100644
--- a/drivers/gpu/drm/omapdrm/dss/pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/pll.c
@@ -215,8 +215,8 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
dss_pll_calc_func func, void *data)
{
const struct dss_pll_hw *hw = pll->hw;
- int n, n_start, n_stop;
- int m, m_start, m_stop;
+ int n, n_min, n_max;
+ int m, m_min, m_max;
unsigned long fint, clkdco;
unsigned long pll_hw_max;
unsigned long fint_hw_min, fint_hw_max;
@@ -226,21 +226,22 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
fint_hw_min = hw->fint_min;
fint_hw_max = hw->fint_max;
- n_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
- n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max);
+ n_min = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
+ n_max = min((unsigned)(clkin / fint_hw_min), hw->n_max);
pll_max = pll_max ? pll_max : ULONG_MAX;
- for (n = n_start; n <= n_stop; ++n) {
+ /* Try to find high N & M to avoid jitter (DRA7 errata i886) */
+ for (n = n_max; n >= n_min; --n) {
fint = clkin / n;
- m_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
+ m_min = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
1ul);
- m_stop = min3((unsigned)(pll_max / fint / 2),
+ m_max = min3((unsigned)(pll_max / fint / 2),
(unsigned)(pll_hw_max / fint / 2),
hw->m_max);
- for (m = m_start; m <= m_stop; ++m) {
+ for (m = m_max; m >= m_min; --m) {
clkdco = 2 * m * fint;
if (func(n, m, fint, clkdco, data))