0001
0002
0003
0004
0005
0006
0007 #include <drm/drm_crtc.h>
0008 #include <drm/drm_probe_helper.h>
0009
0010 #include "mdp4_kms.h"
0011
0012 struct mdp4_dtv_encoder {
0013 struct drm_encoder base;
0014 struct clk *hdmi_clk;
0015 struct clk *mdp_clk;
0016 unsigned long int pixclock;
0017 bool enabled;
0018 uint32_t bsc;
0019 };
0020 #define to_mdp4_dtv_encoder(x) container_of(x, struct mdp4_dtv_encoder, base)
0021
0022 static struct mdp4_kms *get_kms(struct drm_encoder *encoder)
0023 {
0024 struct msm_drm_private *priv = encoder->dev->dev_private;
0025 return to_mdp4_kms(to_mdp_kms(priv->kms));
0026 }
0027
0028 static void mdp4_dtv_encoder_destroy(struct drm_encoder *encoder)
0029 {
0030 struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
0031 drm_encoder_cleanup(encoder);
0032 kfree(mdp4_dtv_encoder);
0033 }
0034
0035 static const struct drm_encoder_funcs mdp4_dtv_encoder_funcs = {
0036 .destroy = mdp4_dtv_encoder_destroy,
0037 };
0038
0039 static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder,
0040 struct drm_display_mode *mode,
0041 struct drm_display_mode *adjusted_mode)
0042 {
0043 struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
0044 struct mdp4_kms *mdp4_kms = get_kms(encoder);
0045 uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol;
0046 uint32_t display_v_start, display_v_end;
0047 uint32_t hsync_start_x, hsync_end_x;
0048
0049 mode = adjusted_mode;
0050
0051 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
0052
0053 mdp4_dtv_encoder->pixclock = mode->clock * 1000;
0054
0055 DBG("pixclock=%lu", mdp4_dtv_encoder->pixclock);
0056
0057 ctrl_pol = 0;
0058 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
0059 ctrl_pol |= MDP4_DTV_CTRL_POLARITY_HSYNC_LOW;
0060 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
0061 ctrl_pol |= MDP4_DTV_CTRL_POLARITY_VSYNC_LOW;
0062
0063
0064 dtv_hsync_skew = 0;
0065
0066 hsync_start_x = (mode->htotal - mode->hsync_start);
0067 hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1;
0068
0069 vsync_period = mode->vtotal * mode->htotal;
0070 vsync_len = (mode->vsync_end - mode->vsync_start) * mode->htotal;
0071 display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + dtv_hsync_skew;
0072 display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + dtv_hsync_skew - 1;
0073
0074 mdp4_write(mdp4_kms, REG_MDP4_DTV_HSYNC_CTRL,
0075 MDP4_DTV_HSYNC_CTRL_PULSEW(mode->hsync_end - mode->hsync_start) |
0076 MDP4_DTV_HSYNC_CTRL_PERIOD(mode->htotal));
0077 mdp4_write(mdp4_kms, REG_MDP4_DTV_VSYNC_PERIOD, vsync_period);
0078 mdp4_write(mdp4_kms, REG_MDP4_DTV_VSYNC_LEN, vsync_len);
0079 mdp4_write(mdp4_kms, REG_MDP4_DTV_DISPLAY_HCTRL,
0080 MDP4_DTV_DISPLAY_HCTRL_START(hsync_start_x) |
0081 MDP4_DTV_DISPLAY_HCTRL_END(hsync_end_x));
0082 mdp4_write(mdp4_kms, REG_MDP4_DTV_DISPLAY_VSTART, display_v_start);
0083 mdp4_write(mdp4_kms, REG_MDP4_DTV_DISPLAY_VEND, display_v_end);
0084 mdp4_write(mdp4_kms, REG_MDP4_DTV_BORDER_CLR, 0);
0085 mdp4_write(mdp4_kms, REG_MDP4_DTV_UNDERFLOW_CLR,
0086 MDP4_DTV_UNDERFLOW_CLR_ENABLE_RECOVERY |
0087 MDP4_DTV_UNDERFLOW_CLR_COLOR(0xff));
0088 mdp4_write(mdp4_kms, REG_MDP4_DTV_HSYNC_SKEW, dtv_hsync_skew);
0089 mdp4_write(mdp4_kms, REG_MDP4_DTV_CTRL_POLARITY, ctrl_pol);
0090 mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_HCTL,
0091 MDP4_DTV_ACTIVE_HCTL_START(0) |
0092 MDP4_DTV_ACTIVE_HCTL_END(0));
0093 mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_VSTART, 0);
0094 mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_VEND, 0);
0095 }
0096
0097 static void mdp4_dtv_encoder_disable(struct drm_encoder *encoder)
0098 {
0099 struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
0100 struct mdp4_kms *mdp4_kms = get_kms(encoder);
0101
0102 if (WARN_ON(!mdp4_dtv_encoder->enabled))
0103 return;
0104
0105 mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0);
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115 mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_EXTERNAL_VSYNC);
0116
0117 clk_disable_unprepare(mdp4_dtv_encoder->hdmi_clk);
0118 clk_disable_unprepare(mdp4_dtv_encoder->mdp_clk);
0119
0120 mdp4_dtv_encoder->enabled = false;
0121 }
0122
0123 static void mdp4_dtv_encoder_enable(struct drm_encoder *encoder)
0124 {
0125 struct drm_device *dev = encoder->dev;
0126 struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
0127 struct mdp4_kms *mdp4_kms = get_kms(encoder);
0128 unsigned long pc = mdp4_dtv_encoder->pixclock;
0129 int ret;
0130
0131 if (WARN_ON(mdp4_dtv_encoder->enabled))
0132 return;
0133
0134 mdp4_crtc_set_config(encoder->crtc,
0135 MDP4_DMA_CONFIG_R_BPC(BPC8) |
0136 MDP4_DMA_CONFIG_G_BPC(BPC8) |
0137 MDP4_DMA_CONFIG_B_BPC(BPC8) |
0138 MDP4_DMA_CONFIG_PACK(0x21));
0139 mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 1);
0140
0141 DBG("setting mdp_clk=%lu", pc);
0142
0143 ret = clk_set_rate(mdp4_dtv_encoder->mdp_clk, pc);
0144 if (ret)
0145 DRM_DEV_ERROR(dev->dev, "failed to set mdp_clk to %lu: %d\n",
0146 pc, ret);
0147
0148 ret = clk_prepare_enable(mdp4_dtv_encoder->mdp_clk);
0149 if (ret)
0150 DRM_DEV_ERROR(dev->dev, "failed to enabled mdp_clk: %d\n", ret);
0151
0152 ret = clk_prepare_enable(mdp4_dtv_encoder->hdmi_clk);
0153 if (ret)
0154 DRM_DEV_ERROR(dev->dev, "failed to enable hdmi_clk: %d\n", ret);
0155
0156 mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 1);
0157
0158 mdp4_dtv_encoder->enabled = true;
0159 }
0160
0161 static const struct drm_encoder_helper_funcs mdp4_dtv_encoder_helper_funcs = {
0162 .mode_set = mdp4_dtv_encoder_mode_set,
0163 .enable = mdp4_dtv_encoder_enable,
0164 .disable = mdp4_dtv_encoder_disable,
0165 };
0166
0167 long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate)
0168 {
0169 struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
0170 return clk_round_rate(mdp4_dtv_encoder->mdp_clk, rate);
0171 }
0172
0173
0174 struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev)
0175 {
0176 struct drm_encoder *encoder = NULL;
0177 struct mdp4_dtv_encoder *mdp4_dtv_encoder;
0178 int ret;
0179
0180 mdp4_dtv_encoder = kzalloc(sizeof(*mdp4_dtv_encoder), GFP_KERNEL);
0181 if (!mdp4_dtv_encoder) {
0182 ret = -ENOMEM;
0183 goto fail;
0184 }
0185
0186 encoder = &mdp4_dtv_encoder->base;
0187
0188 drm_encoder_init(dev, encoder, &mdp4_dtv_encoder_funcs,
0189 DRM_MODE_ENCODER_TMDS, NULL);
0190 drm_encoder_helper_add(encoder, &mdp4_dtv_encoder_helper_funcs);
0191
0192 mdp4_dtv_encoder->hdmi_clk = devm_clk_get(dev->dev, "hdmi_clk");
0193 if (IS_ERR(mdp4_dtv_encoder->hdmi_clk)) {
0194 DRM_DEV_ERROR(dev->dev, "failed to get hdmi_clk\n");
0195 ret = PTR_ERR(mdp4_dtv_encoder->hdmi_clk);
0196 goto fail;
0197 }
0198
0199 mdp4_dtv_encoder->mdp_clk = devm_clk_get(dev->dev, "tv_clk");
0200 if (IS_ERR(mdp4_dtv_encoder->mdp_clk)) {
0201 DRM_DEV_ERROR(dev->dev, "failed to get tv_clk\n");
0202 ret = PTR_ERR(mdp4_dtv_encoder->mdp_clk);
0203 goto fail;
0204 }
0205
0206 return encoder;
0207
0208 fail:
0209 if (encoder)
0210 mdp4_dtv_encoder_destroy(encoder);
0211
0212 return ERR_PTR(ret);
0213 }