#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, {
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 = {