From: Yakir Yang Date: Sat, 16 Jul 2016 08:39:04 +0000 (+0800) Subject: CHROMIUM: drm: rockchip/dw_hdmi-rockchip: refactor the mode table X-Git-Tag: firefly_0821_release~2132 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=bc29e0086129311ec084975bc7fba85d3236f925;p=firefly-linux-kernel-4.4.55.git CHROMIUM: drm: rockchip/dw_hdmi-rockchip: refactor the mode table This cleanup will allow the following patch to implement slop easier. 25175000-40000000 and a few other ranges use the same settings. And the rest of the driver already snaps to the next highest frequency when it gets the settings. So this patch removes a lot of the duplicates. It should be a noop change. And frequencies within 0.1% should be close enough, let's redo rockchip hdmi to allow slop. Change-Id: Ic4865b2825de9b6c3b3e8d029066a8964e8ede6b Signed-off-by: Doug Anderson Signed-off-by: Alexandru M Stan Signed-off-by: Yakir Yang --- diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 69e6efb80433..23a610e4b31e 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -41,6 +41,55 @@ struct rockchip_hdmi { #define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x) +#define CLK_SLOP(clk) ((clk) / 1000) +#define CLK_PLUS_SLOP(clk) ((clk) + CLK_SLOP(clk)) + +static const int dw_hdmi_rates[] = { + 25176471, /* for 25.175 MHz, 0.006% off */ + 25200000, + 27000000, + 28320000, + 30240000, + 31500000, + 32000000, + 33750000, + 36000000, + 40000000, + 49500000, + 50000000, + 54000000, + 57290323, /* for 57.284 MHz, .011 % off */ + 65000000, + 68250000, + 71000000, + 72000000, + 73250000, + 74250000, + 74437500, /* for 74.44 MHz, .003% off */ + 75000000, + 78750000, + 78800000, + 79500000, + 83500000, + 85500000, + 88750000, + 97750000, + 101000000, + 106500000, + 108000000, + 115500000, + 118666667, /* for 118.68 MHz, .011% off */ + 119000000, + 121714286, /* for 121.75 MHz, .029% off */ + 135000000, + 136800000, /* for 136.75 MHz, .037% off */ + 146250000, + 148500000, + 154000000, + 162000000, + 297000000, +}; + static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { { 30666000, { @@ -190,19 +239,19 @@ static enum drm_mode_status dw_hdmi_rockchip_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg; int pclk = mode->clock * 1000; - bool valid = false; + int num_rates = ARRAY_SIZE(dw_hdmi_rates); int i; - for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) { - if (pclk == mpll_cfg[i].mpixelclock) { - valid = true; - break; - } + for (i = 0; i < num_rates; i++) { + int slop = CLK_SLOP(pclk); + + if ((pclk >= dw_hdmi_rates[i] - slop) && + (pclk <= dw_hdmi_rates[i] + slop)) + return MODE_OK; } - return (valid) ? MODE_OK : MODE_BAD; + return MODE_BAD; } static const struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = {