aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2017-06-13 05:02:10 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2017-08-23 05:22:09 -0400
commit0c43f1e02598d304d4cfb06187305445c8207675 (patch)
tree882a3af2f67b84292cfdff5db2961ab69219b865
parentbeea6214d1cc5bb08ce25ffe06b57fb948445bed (diff)
drm/omap: fix i886 work-around
7d267f068a8b4944d52e8b0ae4c8fcc1c1c5c5ba ("drm/omap: work-around for errata i886") changed how the PLL dividers and multipliers are calculated. While the new way should work fine for all the PLLs, it breaks omap5 PLLs. The issues seen are rather odd: seemed that the output clock rate is half of what we asked. It is unclear what's causing there issues. As a work-around this patch adds a "errata_i886" flag, which is set only for DRA7's PLLs, and the PLL setup is done according to that flag. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Tested-by: H. Nikolaus Schaller <hns@goldelico.com>
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.h3
-rw-r--r--drivers/gpu/drm/omapdrm/dss/pll.c29
-rw-r--r--drivers/gpu/drm/omapdrm/dss/video-pll.c2
3 files changed, 25 insertions, 9 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
index 085486024089..ed465572491e 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -185,6 +185,9 @@ struct dss_pll_hw {
185 bool has_freqsel; 185 bool has_freqsel;
186 bool has_selfreqdco; 186 bool has_selfreqdco;
187 bool has_refsel; 187 bool has_refsel;
188
189 /* DRA7 errata i886: use high N & M to avoid jitter */
190 bool errata_i886;
188}; 191};
189 192
190struct dss_pll { 193struct dss_pll {
diff --git a/drivers/gpu/drm/omapdrm/dss/pll.c b/drivers/gpu/drm/omapdrm/dss/pll.c
index 5e221302768b..9d9d9d42009b 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,
215 dss_pll_calc_func func, void *data) 215 dss_pll_calc_func func, void *data)
216{ 216{
217 const struct dss_pll_hw *hw = pll->hw; 217 const struct dss_pll_hw *hw = pll->hw;
218 int n, n_min, n_max; 218 int n, n_start, n_stop, n_inc;
219 int m, m_min, m_max; 219 int m, m_start, m_stop, m_inc;
220 unsigned long fint, clkdco; 220 unsigned long fint, clkdco;
221 unsigned long pll_hw_max; 221 unsigned long pll_hw_max;
222 unsigned long fint_hw_min, fint_hw_max; 222 unsigned long fint_hw_min, fint_hw_max;
@@ -226,22 +226,33 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
226 fint_hw_min = hw->fint_min; 226 fint_hw_min = hw->fint_min;
227 fint_hw_max = hw->fint_max; 227 fint_hw_max = hw->fint_max;
228 228
229 n_min = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul); 229 n_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
230 n_max = min((unsigned)(clkin / fint_hw_min), hw->n_max); 230 n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max);
231 n_inc = 1;
232
233 if (hw->errata_i886) {
234 swap(n_start, n_stop);
235 n_inc = -1;
236 }
231 237
232 pll_max = pll_max ? pll_max : ULONG_MAX; 238 pll_max = pll_max ? pll_max : ULONG_MAX;
233 239
234 /* Try to find high N & M to avoid jitter (DRA7 errata i886) */ 240 for (n = n_start; n != n_stop; n += n_inc) {
235 for (n = n_max; n >= n_min; --n) {
236 fint = clkin / n; 241 fint = clkin / n;
237 242
238 m_min = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2), 243 m_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
239 1ul); 244 1ul);
240 m_max = min3((unsigned)(pll_max / fint / 2), 245 m_stop = min3((unsigned)(pll_max / fint / 2),
241 (unsigned)(pll_hw_max / fint / 2), 246 (unsigned)(pll_hw_max / fint / 2),
242 hw->m_max); 247 hw->m_max);
248 m_inc = 1;
249
250 if (hw->errata_i886) {
251 swap(m_start, m_stop);
252 m_inc = -1;
253 }
243 254
244 for (m = m_max; m >= m_min; --m) { 255 for (m = m_start; m != m_stop; m += m_inc) {
245 clkdco = 2 * m * fint; 256 clkdco = 2 * m * fint;
246 257
247 if (func(n, m, fint, clkdco, data)) 258 if (func(n, m, fint, clkdco, data))
diff --git a/drivers/gpu/drm/omapdrm/dss/video-pll.c b/drivers/gpu/drm/omapdrm/dss/video-pll.c
index f7ea02a88b1a..38a239cc5e04 100644
--- a/drivers/gpu/drm/omapdrm/dss/video-pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/video-pll.c
@@ -130,6 +130,8 @@ static const struct dss_pll_hw dss_dra7_video_pll_hw = {
130 .mX_lsb[3] = 5, 130 .mX_lsb[3] = 5,
131 131
132 .has_refsel = true, 132 .has_refsel = true,
133
134 .errata_i886 = true,
133}; 135};
134 136
135struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id, 137struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id,