Commit 3273fc63 authored by Neil Armstrong's avatar Neil Armstrong

drm/meson: Make DMT timings parameters and pixel clock generic

Remove the modes timings tables for DMT modes and calculate the HW
paremeters from the modes timings.

Switch the DMT modes pixel clock calculation out of the static frequency
list to a generic calculation from a range of possible PLL dividers.

This patch is an intermediate step towards usage of the Common Clock
Framwework for PLL setup, by reworking the code to have common
sel_pll() function called by the CEA (HDMI) freq setup and the generic
DMT frequencies setup, we should be able to simply call clk_set_rate()
on the PLL clock handle in a near future.

The CEA (HDMI) and CVBS modes needs very specific clock paths that CCF will
never be able to determine by itself, so there is still some work to do for
a full handoff to CCF handling the clocks.

This setup permits setting non-CEA modes like :
- 1600x900-60Hz
- 1280x1024-75Hz
- 1280x1024-60Hz
- 1440x900-60Hz
- 1366x768-60Hz
- 1280x800-60Hz
- 1152x864-75Hz
- 1024x768-75Hz
- 1024x768-70Hz
- 1024x768-60Hz
- 832x624-75Hz
- 800x600-75Hz
- 800x600-72Hz
- 800x600-60Hz
- 640x480-75Hz
- 640x480-73Hz
- 640x480-67Hz
Signed-off-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
Acked-by: default avatarJerome Brunet <jbrunet@baylibre.com>
[narmstrong: fixed trivial checkpatch issues]
Link: https://patchwork.freedesktop.org/patch/msgid/1531726814-14638-1-git-send-email-narmstrong@baylibre.com
parent 620eec75
...@@ -329,6 +329,12 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, ...@@ -329,6 +329,12 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
vclk_freq = mode->clock; vclk_freq = mode->clock;
if (!vic) {
meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, vclk_freq,
vclk_freq, vclk_freq, false);
return;
}
if (mode->flags & DRM_MODE_FLAG_DBLCLK) if (mode->flags & DRM_MODE_FLAG_DBLCLK)
vclk_freq *= 2; vclk_freq *= 2;
...@@ -542,10 +548,12 @@ static enum drm_mode_status ...@@ -542,10 +548,12 @@ static enum drm_mode_status
dw_hdmi_mode_valid(struct drm_connector *connector, dw_hdmi_mode_valid(struct drm_connector *connector,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
struct meson_drm *priv = connector->dev->dev_private;
unsigned int vclk_freq; unsigned int vclk_freq;
unsigned int venc_freq; unsigned int venc_freq;
unsigned int hdmi_freq; unsigned int hdmi_freq;
int vic = drm_match_cea_mode(mode); int vic = drm_match_cea_mode(mode);
enum drm_mode_status status;
DRM_DEBUG_DRIVER("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n", DRM_DEBUG_DRIVER("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n",
mode->base.id, mode->name, mode->vrefresh, mode->clock, mode->base.id, mode->name, mode->vrefresh, mode->clock,
...@@ -556,8 +564,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector, ...@@ -556,8 +564,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
/* Check against non-VIC supported modes */ /* Check against non-VIC supported modes */
if (!vic) { if (!vic) {
if (!meson_venc_hdmi_supported_mode(mode)) status = meson_venc_hdmi_supported_mode(mode);
return MODE_BAD; if (status != MODE_OK)
return status;
return meson_vclk_dmt_supported_freq(priv, mode->clock);
/* Check against supported VIC modes */ /* Check against supported VIC modes */
} else if (!meson_venc_hdmi_supported_vic(vic)) } else if (!meson_venc_hdmi_supported_vic(vic))
return MODE_BAD; return MODE_BAD;
...@@ -583,16 +594,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector, ...@@ -583,16 +594,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__, dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__,
vclk_freq, venc_freq, hdmi_freq); vclk_freq, venc_freq, hdmi_freq);
/* Finally filter by configurable vclk frequencies */ /* Finally filter by configurable vclk frequencies for VIC modes */
switch (vclk_freq) { switch (vclk_freq) {
case 25175:
case 40000:
case 54000: case 54000:
case 65000:
case 74250: case 74250:
case 108000:
case 148500: case 148500:
case 162000:
case 297000: case 297000:
case 594000: case 594000:
return MODE_OK; return MODE_OK;
......
This diff is collapsed.
...@@ -24,11 +24,15 @@ ...@@ -24,11 +24,15 @@
enum { enum {
MESON_VCLK_TARGET_CVBS = 0, MESON_VCLK_TARGET_CVBS = 0,
MESON_VCLK_TARGET_HDMI = 1, MESON_VCLK_TARGET_HDMI = 1,
MESON_VCLK_TARGET_DMT = 2,
}; };
/* 27MHz is the CVBS Pixel Clock */ /* 27MHz is the CVBS Pixel Clock */
#define MESON_VCLK_CVBS 27000 #define MESON_VCLK_CVBS 27000
enum drm_mode_status
meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq);
void meson_vclk_setup(struct meson_drm *priv, unsigned int target, void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
unsigned int vclk_freq, unsigned int venc_freq, unsigned int vclk_freq, unsigned int venc_freq,
unsigned int dac_freq, bool hdmi_use_enci); unsigned int dac_freq, bool hdmi_use_enci);
......
This diff is collapsed.
...@@ -58,7 +58,8 @@ struct meson_cvbs_enci_mode { ...@@ -58,7 +58,8 @@ struct meson_cvbs_enci_mode {
}; };
/* HDMI Clock parameters */ /* HDMI Clock parameters */
bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode); enum drm_mode_status
meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode);
bool meson_venc_hdmi_supported_vic(int vic); bool meson_venc_hdmi_supported_vic(int vic);
bool meson_venc_hdmi_venc_repeat(int vic); bool meson_venc_hdmi_venc_repeat(int vic);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment