Received: by 2002:a5b:505:0:0:0:0:0 with SMTP id o5csp198252ybp; Thu, 3 Oct 2019 12:12:15 -0700 (PDT) X-Google-Smtp-Source: APXvYqy8Qr/VPJkhyuBiLXHh1+u0OsOfc1FQ9wkNoamZpurzfO1Th71j1mZKGY90vxs4pIos+a99 X-Received: by 2002:aa7:d38e:: with SMTP id x14mr11485508edq.102.1570129935380; Thu, 03 Oct 2019 12:12:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570129935; cv=none; d=google.com; s=arc-20160816; b=vt7wUNwgWLRJZOYTCcR3ORT1J29YdzVuTu2wUQNB06Y++kV7pQa3pdyrqnYfIpp0SQ DjbCo9Zuf74y4n+OD8ShzO3k2o7gQZWm+wREN0UtV6QwI6467I886oJHVSVagLwtWWp0 9eZmVMb2EwkU+tXr+YBolzcghDNhmyjRJgQsBQO2g+nP21YLmQFi7n8huks5A0YQl8pH jkNfSh/NvsXWceRBJO76hsw+hpG6C14PAK+Sef3zjGiS1cRJxaaP0MS6Mywk+iKo9JPd H/pWuxmJxxH9xr4C1zD/7no5k2STh1ls2ivtQt6NpB9h5xgLX8Wqmp24K8mWEQb4BpHb eXxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=SMux9srIAI9knq9rYMeJgiDQW4HVbC+Jk/8BjWLwEQc=; b=sUfyALcL/5yE8P0nZfVoAx4HlueNqRJ+SJg0V3diZNM+Xp2xjkQsKenPJ9ORHrXo35 LzV/Te+/k6M14KN8Gx/Cq1P52L/Rtu1wzCQX9trJHzEShenyA5bJCNXuDD1e3OgAbOgd izB0KPclBMMhFJI8CCjd+aUhKC4w4ONxXtQWai1BaPDRRQ41hWont5eC1t1NcxiZ4dOm kUmMRMpkiBAW+/BP/1hG8v0fF1O9jE+TcDA5qmKXuhhctDBQecKuGEahButgZvVG7NCh 2q/HxDKXrrUb7YG7FE+W8oJEoAKZQzKJBB/xNc6nLPm3hMsPhW8K0S+iDL72/+28vpG6 Si4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=ghSRkX0v; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a36si2243996edf.123.2019.10.03.12.11.50; Thu, 03 Oct 2019 12:12:15 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=ghSRkX0v; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730392AbfJCSsb (ORCPT + 99 others); Thu, 3 Oct 2019 14:48:31 -0400 Received: from mail-pg1-f196.google.com ([209.85.215.196]:34352 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726677AbfJCSsb (ORCPT ); Thu, 3 Oct 2019 14:48:31 -0400 Received: by mail-pg1-f196.google.com with SMTP id y35so2316201pgl.1 for ; Thu, 03 Oct 2019 11:48:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=SMux9srIAI9knq9rYMeJgiDQW4HVbC+Jk/8BjWLwEQc=; b=ghSRkX0vFVvr9BDMmtqVMBlVFlkNHVD4hFZa9FpY6l1ITk9pwLi08wkKZwW0TON0d4 4KIsbvAJigEs7jQnKga+xiPXIx1DEqmD3CT5CN0LFYf1WPn1pbKLRFUV4tY1nhc2f+Mo vssad7sA++XuthkMymk6sWA1G2zDrMr8u9U7I= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=SMux9srIAI9knq9rYMeJgiDQW4HVbC+Jk/8BjWLwEQc=; b=AjJA+9Nz+rwOQXHAHNuqilikS2Dxf3G588FitDS12GE3pr0hD44RSpTujSddnlAPSr xpQz5UVzSGuYAT1McutrfUMxa1ygt71Mg9Fe73XYrh3f8QowsZSKG92xR2AgoffbBIgW 1mckqg3uXeY8+jJUsSlJ42k/WoC58nLV3Gjg5fot/UWLD1so+oS4IsI6YLSwwdRwlBsk /IXa3J9zeZSIDu/XgMJBJwdyJScDYR9rxOl+3XwECwLd9/TFyLQbnVaYszDCqWhyACXg oX6+7qvmZ9f0OFhj8Mu5uWdkONyfNdbzhZQf/XirzmqwR+zyAKTD5SXo13MC5N12iUCs ABcA== X-Gm-Message-State: APjAAAXYKqj8abZJw6xSBfNHSPpzErF8y47Kbp8FTtVdOBN1ZIbftiYg 26GoygQxLvLudjoNo676pUJk1g== X-Received: by 2002:a63:4754:: with SMTP id w20mr11328229pgk.134.1570128509058; Thu, 03 Oct 2019 11:48:29 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:1:24fa:e766:52c9:e3b2]) by smtp.gmail.com with ESMTPSA id k93sm6590355pjh.3.2019.10.03.11.48.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Oct 2019 11:48:28 -0700 (PDT) From: Douglas Anderson To: heiko@sntech.de Cc: ryandcase@chromium.org, mka@chromium.org, seanpaul@chromium.org, tfiga@chromium.org, Douglas Anderson , Sandy Huang , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-rockchip@lists.infradead.org, David Airlie , linux-arm-kernel@lists.infradead.org, Daniel Vetter Subject: [PATCH v2] drm/rockchip: Round up _before_ giving to the clock framework Date: Thu, 3 Oct 2019 11:47:30 -0700 Message-Id: <20191003114726.v2.1.Ib233b3e706cf6317858384264d5b0ed35657456e@changeid> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org I'm embarassed to say that even though I've touched vop_crtc_mode_fixup() twice and I swear I tested it, there's still a stupid glaring bug in it. Specifically, on veyron_minnie (with all the latest display timings) we want to be setting our pixel clock to 66,666,666.67 Hz and we tell userspace that's what we set, but we're actually choosing 66,000,000 Hz. This is confirmed by looking at the clock tree. The problem is that in drm_display_mode_from_videomode() we convert from Hz to kHz with: dmode->clock = vm->pixelclock / 1000; ...and drm_display_mode_from_videomode() is called from panel-simple when we have an "override_mode" like we do on veyron_minnie. See commit 123643e5c40a ("ARM: dts: rockchip: Specify rk3288-veyron-minnie's display timings"). ...so when the device tree specifies a clock of 66666667 for the panel then DRM translates that to 66666000. The clock framework will always pick a clock that is _lower_ than the one requested, so it will refuse to pick 66666667 and we'll end up at 66000000. While we could try to fix drm_display_mode_from_videomode() to round to the nearest kHz and it would fix our problem, it wouldn't help if the clock we actually needed was 60,000,001 Hz. We could alternatively have DRM always round up, but maybe this would break someone else who already baked in the assumption that DRM rounds down. Specifically note that clock drivers are not consistent about whether they round up or round down when you call clk_set_rate(). We know how Rockchip's clock driver works, but (for instance) you can see that on most Qualcomm clocks the default is clk_rcg2_ops which rounds up. Let's solve this by just adding 999 Hz before calling clk_round_rate(). This should be safe and work everywhere. As discussed in more detail in comments in the commit, Rockchip's PLLs are configured in a way that there shouldn't be another PLL setting that is only a few kHz off so we won't get mixed up. NOTE: if this is picked to stable, it's probably easiest to first pick commit 527e4ca3b6d1 ("drm/rockchip: Base adjustments of the mode based on prev adjustments") which shouldn't hurt in stable. Fixes: b59b8de31497 ("drm/rockchip: return a true clock rate to adjusted_mode") Signed-off-by: Douglas Anderson Reviewed-by: Sean Paul --- Changes in v2: - Beefed up the commit message (Sean). drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 37 +++++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 613404f86668..84e3decb17b1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1040,10 +1040,41 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *adjusted_mode) { struct vop *vop = to_vop(crtc); + unsigned long rate; - adjusted_mode->clock = - DIV_ROUND_UP(clk_round_rate(vop->dclk, - adjusted_mode->clock * 1000), 1000); + /* + * Clock craziness. + * + * Key points: + * + * - DRM works in in kHz. + * - Clock framework works in Hz. + * - Rockchip's clock driver picks the clock rate that is the + * same _OR LOWER_ than the one requested. + * + * Action plan: + * + * 1. When DRM gives us a mode, we should add 999 Hz to it. That way + * if the clock we need is 60000001 Hz (~60 MHz) and DRM tells us to + * make 60000 kHz then the clock framework will actually give us + * the right clock. + * + * NOTE: if the PLL (maybe through a divider) could actually make + * a clock rate 999 Hz higher instead of the one we want then this + * could be a problem. Unfortunately there's not much we can do + * since it's baked into DRM to use kHz. It shouldn't matter in + * practice since Rockchip PLLs are controlled by tables and + * even if there is a divider in the middle I wouldn't expect PLL + * rates in the table that are just a few kHz different. + * + * 2. Get the clock framework to round the rate for us to tell us + * what it will actually make. + * + * 3. Store the rounded up rate so that we don't need to worry about + * this in the actual clk_set_rate(). + */ + rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000 + 999); + adjusted_mode->clock = DIV_ROUND_UP(rate, 1000); return true; } -- 2.23.0.444.g18eeb5a265-goog