2015-05-18 Daniel Stone daniel@fooishbar.org:
Hi,
On Monday, May 18, 2015, Gustavo Padovan gustavo@padovan.org wrote:
Hi Tobias,
2015-05-15 Tobias Jakobi <tjakobi@math.uni-bielefeld.de javascript:;>:
I did another run with drm.debug=0xff and also tried to figure out where
the
div-by-zero comes from.
The only division I see is in fimd_calc_clkdiv() (which is called by fimd_commit()). So it looks like 'ideal_clk' is zero when calling DIV_ROUND_UP().
'htotal' and 'vtotal' can't be zero, since this is checked early in fimd_commit(). So 'vrefresh' has to be zero. Maybe this helps?
What is is the output when you run with this patch:
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 12ab80c..f5d215d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -310,6 +310,8 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx, unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh; u32 clkdiv;
DRM_DEBUG_KMS("vrefresh %d\n", mode->vrefresh);
if (ctx->i80_if) { /* * The frame done interrupt should be occurred prior to the
@@ -328,6 +330,7 @@ static bool fimd_mode_fixup(struct exynos_drm_crtc *crtc, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) {
DRM_DEBUG_KMS("vrefresh %d\n", adjusted_mode->vrefresh); if (adjusted_mode->vrefresh == 0) adjusted_mode->vrefresh = FIMD_DEFAULT_FRAMERATE;
vrefresh can legitimately be zero, which makes this FIMD_DEFAULT_FRAMERATE assignment problematic rather than harmless.
If it's zero, you can find a vrefresh value with drm_mode_vrefresh, which will calculate it for you.
So better try this. Ideally fimd_mode_fixup should go away too, I'll do a proper patch once we know this works.
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 12ab80c..363353b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -307,9 +307,17 @@ static void fimd_iommu_detach_devices(struct fimd_context *ctx) static u32 fimd_calc_clkdiv(struct fimd_context *ctx, const struct drm_display_mode *mode) { - unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh; + unsigned long ideal_clk; + int vrefresh; u32 clkdiv;
+ if (mode->vrefresh == 0) + vrefresh = drm_mode_vrefresh(mode); + else + vrefresh = mode->vrefresh; + + ideal_clk = mode->htotal * mode->vtotal * vrefresh; + if (ctx->i80_if) { /* * The frame done interrupt should be occurred prior to the