Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
0004  *    Zheng Yang <zhengyang@rock-chips.com>
0005  */
0006 
0007 #include <drm/drm_edid.h>
0008 #include <drm/drm_of.h>
0009 #include <drm/drm_probe_helper.h>
0010 #include <drm/drm_simple_kms_helper.h>
0011 
0012 #include <linux/clk.h>
0013 #include <linux/mfd/syscon.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/regmap.h>
0016 
0017 #include "rk3066_hdmi.h"
0018 
0019 #include "rockchip_drm_drv.h"
0020 #include "rockchip_drm_vop.h"
0021 
0022 #define DEFAULT_PLLA_RATE 30000000
0023 
0024 struct hdmi_data_info {
0025     int vic; /* The CEA Video ID (VIC) of the current drm display mode. */
0026     unsigned int enc_out_format;
0027     unsigned int colorimetry;
0028 };
0029 
0030 struct rk3066_hdmi_i2c {
0031     struct i2c_adapter adap;
0032 
0033     u8 ddc_addr;
0034     u8 segment_addr;
0035     u8 stat;
0036 
0037     struct mutex i2c_lock; /* For i2c operation. */
0038     struct completion cmpltn;
0039 };
0040 
0041 struct rk3066_hdmi {
0042     struct device *dev;
0043     struct drm_device *drm_dev;
0044     struct regmap *grf_regmap;
0045     int irq;
0046     struct clk *hclk;
0047     void __iomem *regs;
0048 
0049     struct drm_connector connector;
0050     struct rockchip_encoder encoder;
0051 
0052     struct rk3066_hdmi_i2c *i2c;
0053     struct i2c_adapter *ddc;
0054 
0055     unsigned int tmdsclk;
0056 
0057     struct hdmi_data_info hdmi_data;
0058     struct drm_display_mode previous_mode;
0059 };
0060 
0061 static struct rk3066_hdmi *encoder_to_rk3066_hdmi(struct drm_encoder *encoder)
0062 {
0063     struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
0064 
0065     return container_of(rkencoder, struct rk3066_hdmi, encoder);
0066 }
0067 
0068 static struct rk3066_hdmi *connector_to_rk3066_hdmi(struct drm_connector *connector)
0069 {
0070     return container_of(connector, struct rk3066_hdmi, connector);
0071 }
0072 
0073 static inline u8 hdmi_readb(struct rk3066_hdmi *hdmi, u16 offset)
0074 {
0075     return readl_relaxed(hdmi->regs + offset);
0076 }
0077 
0078 static inline void hdmi_writeb(struct rk3066_hdmi *hdmi, u16 offset, u32 val)
0079 {
0080     writel_relaxed(val, hdmi->regs + offset);
0081 }
0082 
0083 static inline void hdmi_modb(struct rk3066_hdmi *hdmi, u16 offset,
0084                  u32 msk, u32 val)
0085 {
0086     u8 temp = hdmi_readb(hdmi, offset) & ~msk;
0087 
0088     temp |= val & msk;
0089     hdmi_writeb(hdmi, offset, temp);
0090 }
0091 
0092 static void rk3066_hdmi_i2c_init(struct rk3066_hdmi *hdmi)
0093 {
0094     int ddc_bus_freq;
0095 
0096     ddc_bus_freq = (hdmi->tmdsclk >> 2) / HDMI_SCL_RATE;
0097 
0098     hdmi_writeb(hdmi, HDMI_DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
0099     hdmi_writeb(hdmi, HDMI_DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
0100 
0101     /* Clear the EDID interrupt flag and mute the interrupt. */
0102     hdmi_modb(hdmi, HDMI_INTR_MASK1, HDMI_INTR_EDID_MASK, 0);
0103     hdmi_writeb(hdmi, HDMI_INTR_STATUS1, HDMI_INTR_EDID_MASK);
0104 }
0105 
0106 static inline u8 rk3066_hdmi_get_power_mode(struct rk3066_hdmi *hdmi)
0107 {
0108     return hdmi_readb(hdmi, HDMI_SYS_CTRL) & HDMI_SYS_POWER_MODE_MASK;
0109 }
0110 
0111 static void rk3066_hdmi_set_power_mode(struct rk3066_hdmi *hdmi, int mode)
0112 {
0113     u8 current_mode, next_mode;
0114     u8 i = 0;
0115 
0116     current_mode = rk3066_hdmi_get_power_mode(hdmi);
0117 
0118     DRM_DEV_DEBUG(hdmi->dev, "mode         :%d\n", mode);
0119     DRM_DEV_DEBUG(hdmi->dev, "current_mode :%d\n", current_mode);
0120 
0121     if (current_mode == mode)
0122         return;
0123 
0124     do {
0125         if (current_mode > mode) {
0126             next_mode = current_mode / 2;
0127         } else {
0128             if (current_mode < HDMI_SYS_POWER_MODE_A)
0129                 next_mode = HDMI_SYS_POWER_MODE_A;
0130             else
0131                 next_mode = current_mode * 2;
0132         }
0133 
0134         DRM_DEV_DEBUG(hdmi->dev, "%d: next_mode :%d\n", i, next_mode);
0135 
0136         if (next_mode != HDMI_SYS_POWER_MODE_D) {
0137             hdmi_modb(hdmi, HDMI_SYS_CTRL,
0138                   HDMI_SYS_POWER_MODE_MASK, next_mode);
0139         } else {
0140             hdmi_writeb(hdmi, HDMI_SYS_CTRL,
0141                     HDMI_SYS_POWER_MODE_D |
0142                     HDMI_SYS_PLL_RESET_MASK);
0143             usleep_range(90, 100);
0144             hdmi_writeb(hdmi, HDMI_SYS_CTRL,
0145                     HDMI_SYS_POWER_MODE_D |
0146                     HDMI_SYS_PLLB_RESET);
0147             usleep_range(90, 100);
0148             hdmi_writeb(hdmi, HDMI_SYS_CTRL,
0149                     HDMI_SYS_POWER_MODE_D);
0150         }
0151         current_mode = next_mode;
0152         i = i + 1;
0153     } while ((next_mode != mode) && (i < 5));
0154 
0155     /*
0156      * When the IP controller isn't configured with accurate video timing,
0157      * DDC_CLK should be equal to the PLLA frequency, which is 30MHz,
0158      * so we need to init the TMDS rate to the PCLK rate and reconfigure
0159      * the DDC clock.
0160      */
0161     if (mode < HDMI_SYS_POWER_MODE_D)
0162         hdmi->tmdsclk = DEFAULT_PLLA_RATE;
0163 }
0164 
0165 static int
0166 rk3066_hdmi_upload_frame(struct rk3066_hdmi *hdmi, int setup_rc,
0167              union hdmi_infoframe *frame, u32 frame_index,
0168              u32 mask, u32 disable, u32 enable)
0169 {
0170     if (mask)
0171         hdmi_modb(hdmi, HDMI_CP_AUTO_SEND_CTRL, mask, disable);
0172 
0173     hdmi_writeb(hdmi, HDMI_CP_BUF_INDEX, frame_index);
0174 
0175     if (setup_rc >= 0) {
0176         u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
0177         ssize_t rc, i;
0178 
0179         rc = hdmi_infoframe_pack(frame, packed_frame,
0180                      sizeof(packed_frame));
0181         if (rc < 0)
0182             return rc;
0183 
0184         for (i = 0; i < rc; i++)
0185             hdmi_writeb(hdmi, HDMI_CP_BUF_ACC_HB0 + i * 4,
0186                     packed_frame[i]);
0187 
0188         if (mask)
0189             hdmi_modb(hdmi, HDMI_CP_AUTO_SEND_CTRL, mask, enable);
0190     }
0191 
0192     return setup_rc;
0193 }
0194 
0195 static int rk3066_hdmi_config_avi(struct rk3066_hdmi *hdmi,
0196                   struct drm_display_mode *mode)
0197 {
0198     union hdmi_infoframe frame;
0199     int rc;
0200 
0201     rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
0202                               &hdmi->connector, mode);
0203 
0204     if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
0205         frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
0206     else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422)
0207         frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
0208     else
0209         frame.avi.colorspace = HDMI_COLORSPACE_RGB;
0210 
0211     frame.avi.colorimetry = hdmi->hdmi_data.colorimetry;
0212     frame.avi.scan_mode = HDMI_SCAN_MODE_NONE;
0213 
0214     return rk3066_hdmi_upload_frame(hdmi, rc, &frame,
0215                     HDMI_INFOFRAME_AVI, 0, 0, 0);
0216 }
0217 
0218 static int rk3066_hdmi_config_video_timing(struct rk3066_hdmi *hdmi,
0219                        struct drm_display_mode *mode)
0220 {
0221     int value, vsync_offset;
0222 
0223     /* Set the details for the external polarity and interlace mode. */
0224     value = HDMI_EXT_VIDEO_SET_EN;
0225     value |= mode->flags & DRM_MODE_FLAG_PHSYNC ?
0226          HDMI_VIDEO_HSYNC_ACTIVE_HIGH : HDMI_VIDEO_HSYNC_ACTIVE_LOW;
0227     value |= mode->flags & DRM_MODE_FLAG_PVSYNC ?
0228          HDMI_VIDEO_VSYNC_ACTIVE_HIGH : HDMI_VIDEO_VSYNC_ACTIVE_LOW;
0229     value |= mode->flags & DRM_MODE_FLAG_INTERLACE ?
0230          HDMI_VIDEO_MODE_INTERLACE : HDMI_VIDEO_MODE_PROGRESSIVE;
0231 
0232     if (hdmi->hdmi_data.vic == 2 || hdmi->hdmi_data.vic == 3)
0233         vsync_offset = 6;
0234     else
0235         vsync_offset = 0;
0236 
0237     value |= vsync_offset << HDMI_VIDEO_VSYNC_OFFSET_SHIFT;
0238     hdmi_writeb(hdmi, HDMI_EXT_VIDEO_PARA, value);
0239 
0240     /* Set the details for the external video timing. */
0241     value = mode->htotal;
0242     hdmi_writeb(hdmi, HDMI_EXT_HTOTAL_L, value & 0xFF);
0243     hdmi_writeb(hdmi, HDMI_EXT_HTOTAL_H, (value >> 8) & 0xFF);
0244 
0245     value = mode->htotal - mode->hdisplay;
0246     hdmi_writeb(hdmi, HDMI_EXT_HBLANK_L, value & 0xFF);
0247     hdmi_writeb(hdmi, HDMI_EXT_HBLANK_H, (value >> 8) & 0xFF);
0248 
0249     value = mode->htotal - mode->hsync_start;
0250     hdmi_writeb(hdmi, HDMI_EXT_HDELAY_L, value & 0xFF);
0251     hdmi_writeb(hdmi, HDMI_EXT_HDELAY_H, (value >> 8) & 0xFF);
0252 
0253     value = mode->hsync_end - mode->hsync_start;
0254     hdmi_writeb(hdmi, HDMI_EXT_HDURATION_L, value & 0xFF);
0255     hdmi_writeb(hdmi, HDMI_EXT_HDURATION_H, (value >> 8) & 0xFF);
0256 
0257     value = mode->vtotal;
0258     hdmi_writeb(hdmi, HDMI_EXT_VTOTAL_L, value & 0xFF);
0259     hdmi_writeb(hdmi, HDMI_EXT_VTOTAL_H, (value >> 8) & 0xFF);
0260 
0261     value = mode->vtotal - mode->vdisplay;
0262     hdmi_writeb(hdmi, HDMI_EXT_VBLANK_L, value & 0xFF);
0263 
0264     value = mode->vtotal - mode->vsync_start + vsync_offset;
0265     hdmi_writeb(hdmi, HDMI_EXT_VDELAY, value & 0xFF);
0266 
0267     value = mode->vsync_end - mode->vsync_start;
0268     hdmi_writeb(hdmi, HDMI_EXT_VDURATION, value & 0xFF);
0269 
0270     return 0;
0271 }
0272 
0273 static void
0274 rk3066_hdmi_phy_write(struct rk3066_hdmi *hdmi, u16 offset, u8 value)
0275 {
0276     hdmi_writeb(hdmi, offset, value);
0277     hdmi_modb(hdmi, HDMI_SYS_CTRL,
0278           HDMI_SYS_PLL_RESET_MASK, HDMI_SYS_PLL_RESET);
0279     usleep_range(90, 100);
0280     hdmi_modb(hdmi, HDMI_SYS_CTRL, HDMI_SYS_PLL_RESET_MASK, 0);
0281     usleep_range(900, 1000);
0282 }
0283 
0284 static void rk3066_hdmi_config_phy(struct rk3066_hdmi *hdmi)
0285 {
0286     /* TMDS uses the same frequency as dclk. */
0287     hdmi_writeb(hdmi, HDMI_DEEP_COLOR_MODE, 0x22);
0288 
0289     /*
0290      * The semi-public documentation does not describe the hdmi registers
0291      * used by the function rk3066_hdmi_phy_write(), so we keep using
0292      * these magic values for now.
0293      */
0294     if (hdmi->tmdsclk > 100000000) {
0295         rk3066_hdmi_phy_write(hdmi, 0x158, 0x0E);
0296         rk3066_hdmi_phy_write(hdmi, 0x15c, 0x00);
0297         rk3066_hdmi_phy_write(hdmi, 0x160, 0x60);
0298         rk3066_hdmi_phy_write(hdmi, 0x164, 0x00);
0299         rk3066_hdmi_phy_write(hdmi, 0x168, 0xDA);
0300         rk3066_hdmi_phy_write(hdmi, 0x16c, 0xA1);
0301         rk3066_hdmi_phy_write(hdmi, 0x170, 0x0e);
0302         rk3066_hdmi_phy_write(hdmi, 0x174, 0x22);
0303         rk3066_hdmi_phy_write(hdmi, 0x178, 0x00);
0304     } else if (hdmi->tmdsclk > 50000000) {
0305         rk3066_hdmi_phy_write(hdmi, 0x158, 0x06);
0306         rk3066_hdmi_phy_write(hdmi, 0x15c, 0x00);
0307         rk3066_hdmi_phy_write(hdmi, 0x160, 0x60);
0308         rk3066_hdmi_phy_write(hdmi, 0x164, 0x00);
0309         rk3066_hdmi_phy_write(hdmi, 0x168, 0xCA);
0310         rk3066_hdmi_phy_write(hdmi, 0x16c, 0xA3);
0311         rk3066_hdmi_phy_write(hdmi, 0x170, 0x0e);
0312         rk3066_hdmi_phy_write(hdmi, 0x174, 0x20);
0313         rk3066_hdmi_phy_write(hdmi, 0x178, 0x00);
0314     } else {
0315         rk3066_hdmi_phy_write(hdmi, 0x158, 0x02);
0316         rk3066_hdmi_phy_write(hdmi, 0x15c, 0x00);
0317         rk3066_hdmi_phy_write(hdmi, 0x160, 0x60);
0318         rk3066_hdmi_phy_write(hdmi, 0x164, 0x00);
0319         rk3066_hdmi_phy_write(hdmi, 0x168, 0xC2);
0320         rk3066_hdmi_phy_write(hdmi, 0x16c, 0xA2);
0321         rk3066_hdmi_phy_write(hdmi, 0x170, 0x0e);
0322         rk3066_hdmi_phy_write(hdmi, 0x174, 0x20);
0323         rk3066_hdmi_phy_write(hdmi, 0x178, 0x00);
0324     }
0325 }
0326 
0327 static int rk3066_hdmi_setup(struct rk3066_hdmi *hdmi,
0328                  struct drm_display_mode *mode)
0329 {
0330     struct drm_display_info *display = &hdmi->connector.display_info;
0331 
0332     hdmi->hdmi_data.vic = drm_match_cea_mode(mode);
0333     hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB;
0334 
0335     if (hdmi->hdmi_data.vic == 6 || hdmi->hdmi_data.vic == 7 ||
0336         hdmi->hdmi_data.vic == 21 || hdmi->hdmi_data.vic == 22 ||
0337         hdmi->hdmi_data.vic == 2 || hdmi->hdmi_data.vic == 3 ||
0338         hdmi->hdmi_data.vic == 17 || hdmi->hdmi_data.vic == 18)
0339         hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
0340     else
0341         hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
0342 
0343     hdmi->tmdsclk = mode->clock * 1000;
0344 
0345     /* Mute video and audio output. */
0346     hdmi_modb(hdmi, HDMI_VIDEO_CTRL2, HDMI_VIDEO_AUDIO_DISABLE_MASK,
0347           HDMI_AUDIO_DISABLE | HDMI_VIDEO_DISABLE);
0348 
0349     /* Set power state to mode B. */
0350     if (rk3066_hdmi_get_power_mode(hdmi) != HDMI_SYS_POWER_MODE_B)
0351         rk3066_hdmi_set_power_mode(hdmi, HDMI_SYS_POWER_MODE_B);
0352 
0353     /* Input video mode is RGB 24 bit. Use external data enable signal. */
0354     hdmi_modb(hdmi, HDMI_AV_CTRL1,
0355           HDMI_VIDEO_DE_MASK, HDMI_VIDEO_EXTERNAL_DE);
0356     hdmi_writeb(hdmi, HDMI_VIDEO_CTRL1,
0357             HDMI_VIDEO_OUTPUT_RGB444 |
0358             HDMI_VIDEO_INPUT_DATA_DEPTH_8BIT |
0359             HDMI_VIDEO_INPUT_COLOR_RGB);
0360     hdmi_writeb(hdmi, HDMI_DEEP_COLOR_MODE, 0x20);
0361 
0362     rk3066_hdmi_config_video_timing(hdmi, mode);
0363 
0364     if (display->is_hdmi) {
0365         hdmi_modb(hdmi, HDMI_HDCP_CTRL, HDMI_VIDEO_MODE_MASK,
0366               HDMI_VIDEO_MODE_HDMI);
0367         rk3066_hdmi_config_avi(hdmi, mode);
0368     } else {
0369         hdmi_modb(hdmi, HDMI_HDCP_CTRL, HDMI_VIDEO_MODE_MASK, 0);
0370     }
0371 
0372     rk3066_hdmi_config_phy(hdmi);
0373 
0374     rk3066_hdmi_set_power_mode(hdmi, HDMI_SYS_POWER_MODE_E);
0375 
0376     /*
0377      * When the IP controller is configured with accurate video
0378      * timing, the TMDS clock source should be switched to
0379      * DCLK_LCDC, so we need to init the TMDS rate to the pixel mode
0380      * clock rate and reconfigure the DDC clock.
0381      */
0382     rk3066_hdmi_i2c_init(hdmi);
0383 
0384     /* Unmute video output. */
0385     hdmi_modb(hdmi, HDMI_VIDEO_CTRL2,
0386           HDMI_VIDEO_AUDIO_DISABLE_MASK, HDMI_AUDIO_DISABLE);
0387     return 0;
0388 }
0389 
0390 static void
0391 rk3066_hdmi_encoder_mode_set(struct drm_encoder *encoder,
0392                  struct drm_display_mode *mode,
0393                  struct drm_display_mode *adj_mode)
0394 {
0395     struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder);
0396 
0397     /* Store the display mode for plugin/DPMS poweron events. */
0398     memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
0399 }
0400 
0401 static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder)
0402 {
0403     struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder);
0404     int mux, val;
0405 
0406     mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
0407     if (mux)
0408         val = (HDMI_VIDEO_SEL << 16) | HDMI_VIDEO_SEL;
0409     else
0410         val = HDMI_VIDEO_SEL << 16;
0411 
0412     regmap_write(hdmi->grf_regmap, GRF_SOC_CON0, val);
0413 
0414     DRM_DEV_DEBUG(hdmi->dev, "hdmi encoder enable select: vop%s\n",
0415               (mux) ? "1" : "0");
0416 
0417     rk3066_hdmi_setup(hdmi, &hdmi->previous_mode);
0418 }
0419 
0420 static void rk3066_hdmi_encoder_disable(struct drm_encoder *encoder)
0421 {
0422     struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder);
0423 
0424     DRM_DEV_DEBUG(hdmi->dev, "hdmi encoder disable\n");
0425 
0426     if (rk3066_hdmi_get_power_mode(hdmi) == HDMI_SYS_POWER_MODE_E) {
0427         hdmi_writeb(hdmi, HDMI_VIDEO_CTRL2,
0428                 HDMI_VIDEO_AUDIO_DISABLE_MASK);
0429         hdmi_modb(hdmi, HDMI_VIDEO_CTRL2,
0430               HDMI_AUDIO_CP_LOGIC_RESET_MASK,
0431               HDMI_AUDIO_CP_LOGIC_RESET);
0432         usleep_range(500, 510);
0433     }
0434     rk3066_hdmi_set_power_mode(hdmi, HDMI_SYS_POWER_MODE_A);
0435 }
0436 
0437 static bool
0438 rk3066_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
0439                    const struct drm_display_mode *mode,
0440                    struct drm_display_mode *adj_mode)
0441 {
0442     return true;
0443 }
0444 
0445 static int
0446 rk3066_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
0447                  struct drm_crtc_state *crtc_state,
0448                  struct drm_connector_state *conn_state)
0449 {
0450     struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
0451 
0452     s->output_mode = ROCKCHIP_OUT_MODE_P888;
0453     s->output_type = DRM_MODE_CONNECTOR_HDMIA;
0454 
0455     return 0;
0456 }
0457 
0458 static const
0459 struct drm_encoder_helper_funcs rk3066_hdmi_encoder_helper_funcs = {
0460     .enable       = rk3066_hdmi_encoder_enable,
0461     .disable      = rk3066_hdmi_encoder_disable,
0462     .mode_fixup   = rk3066_hdmi_encoder_mode_fixup,
0463     .mode_set     = rk3066_hdmi_encoder_mode_set,
0464     .atomic_check = rk3066_hdmi_encoder_atomic_check,
0465 };
0466 
0467 static enum drm_connector_status
0468 rk3066_hdmi_connector_detect(struct drm_connector *connector, bool force)
0469 {
0470     struct rk3066_hdmi *hdmi = connector_to_rk3066_hdmi(connector);
0471 
0472     return (hdmi_readb(hdmi, HDMI_HPG_MENS_STA) & HDMI_HPG_IN_STATUS_HIGH) ?
0473         connector_status_connected : connector_status_disconnected;
0474 }
0475 
0476 static int rk3066_hdmi_connector_get_modes(struct drm_connector *connector)
0477 {
0478     struct rk3066_hdmi *hdmi = connector_to_rk3066_hdmi(connector);
0479     struct edid *edid;
0480     int ret = 0;
0481 
0482     if (!hdmi->ddc)
0483         return 0;
0484 
0485     edid = drm_get_edid(connector, hdmi->ddc);
0486     if (edid) {
0487         drm_connector_update_edid_property(connector, edid);
0488         ret = drm_add_edid_modes(connector, edid);
0489         kfree(edid);
0490     }
0491 
0492     return ret;
0493 }
0494 
0495 static enum drm_mode_status
0496 rk3066_hdmi_connector_mode_valid(struct drm_connector *connector,
0497                  struct drm_display_mode *mode)
0498 {
0499     u32 vic = drm_match_cea_mode(mode);
0500 
0501     if (vic > 1)
0502         return MODE_OK;
0503     else
0504         return MODE_BAD;
0505 }
0506 
0507 static struct drm_encoder *
0508 rk3066_hdmi_connector_best_encoder(struct drm_connector *connector)
0509 {
0510     struct rk3066_hdmi *hdmi = connector_to_rk3066_hdmi(connector);
0511 
0512     return &hdmi->encoder.encoder;
0513 }
0514 
0515 static int
0516 rk3066_hdmi_probe_single_connector_modes(struct drm_connector *connector,
0517                      uint32_t maxX, uint32_t maxY)
0518 {
0519     if (maxX > 1920)
0520         maxX = 1920;
0521     if (maxY > 1080)
0522         maxY = 1080;
0523 
0524     return drm_helper_probe_single_connector_modes(connector, maxX, maxY);
0525 }
0526 
0527 static void rk3066_hdmi_connector_destroy(struct drm_connector *connector)
0528 {
0529     drm_connector_unregister(connector);
0530     drm_connector_cleanup(connector);
0531 }
0532 
0533 static const struct drm_connector_funcs rk3066_hdmi_connector_funcs = {
0534     .fill_modes = rk3066_hdmi_probe_single_connector_modes,
0535     .detect = rk3066_hdmi_connector_detect,
0536     .destroy = rk3066_hdmi_connector_destroy,
0537     .reset = drm_atomic_helper_connector_reset,
0538     .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
0539     .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
0540 };
0541 
0542 static const
0543 struct drm_connector_helper_funcs rk3066_hdmi_connector_helper_funcs = {
0544     .get_modes = rk3066_hdmi_connector_get_modes,
0545     .mode_valid = rk3066_hdmi_connector_mode_valid,
0546     .best_encoder = rk3066_hdmi_connector_best_encoder,
0547 };
0548 
0549 static int
0550 rk3066_hdmi_register(struct drm_device *drm, struct rk3066_hdmi *hdmi)
0551 {
0552     struct drm_encoder *encoder = &hdmi->encoder.encoder;
0553     struct device *dev = hdmi->dev;
0554 
0555     encoder->possible_crtcs =
0556         drm_of_find_possible_crtcs(drm, dev->of_node);
0557 
0558     /*
0559      * If we failed to find the CRTC(s) which this encoder is
0560      * supposed to be connected to, it's because the CRTC has
0561      * not been registered yet.  Defer probing, and hope that
0562      * the required CRTC is added later.
0563      */
0564     if (encoder->possible_crtcs == 0)
0565         return -EPROBE_DEFER;
0566 
0567     drm_encoder_helper_add(encoder, &rk3066_hdmi_encoder_helper_funcs);
0568     drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
0569 
0570     hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
0571 
0572     drm_connector_helper_add(&hdmi->connector,
0573                  &rk3066_hdmi_connector_helper_funcs);
0574     drm_connector_init_with_ddc(drm, &hdmi->connector,
0575                     &rk3066_hdmi_connector_funcs,
0576                     DRM_MODE_CONNECTOR_HDMIA,
0577                     hdmi->ddc);
0578 
0579     drm_connector_attach_encoder(&hdmi->connector, encoder);
0580 
0581     return 0;
0582 }
0583 
0584 static irqreturn_t rk3066_hdmi_hardirq(int irq, void *dev_id)
0585 {
0586     struct rk3066_hdmi *hdmi = dev_id;
0587     irqreturn_t ret = IRQ_NONE;
0588     u8 interrupt;
0589 
0590     if (rk3066_hdmi_get_power_mode(hdmi) == HDMI_SYS_POWER_MODE_A)
0591         hdmi_writeb(hdmi, HDMI_SYS_CTRL, HDMI_SYS_POWER_MODE_B);
0592 
0593     interrupt = hdmi_readb(hdmi, HDMI_INTR_STATUS1);
0594     if (interrupt)
0595         hdmi_writeb(hdmi, HDMI_INTR_STATUS1, interrupt);
0596 
0597     if (interrupt & HDMI_INTR_EDID_MASK) {
0598         hdmi->i2c->stat = interrupt;
0599         complete(&hdmi->i2c->cmpltn);
0600     }
0601 
0602     if (interrupt & (HDMI_INTR_HOTPLUG | HDMI_INTR_MSENS))
0603         ret = IRQ_WAKE_THREAD;
0604 
0605     return ret;
0606 }
0607 
0608 static irqreturn_t rk3066_hdmi_irq(int irq, void *dev_id)
0609 {
0610     struct rk3066_hdmi *hdmi = dev_id;
0611 
0612     drm_helper_hpd_irq_event(hdmi->connector.dev);
0613 
0614     return IRQ_HANDLED;
0615 }
0616 
0617 static int rk3066_hdmi_i2c_read(struct rk3066_hdmi *hdmi, struct i2c_msg *msgs)
0618 {
0619     int length = msgs->len;
0620     u8 *buf = msgs->buf;
0621     int ret;
0622 
0623     ret = wait_for_completion_timeout(&hdmi->i2c->cmpltn, HZ / 10);
0624     if (!ret || hdmi->i2c->stat & HDMI_INTR_EDID_ERR)
0625         return -EAGAIN;
0626 
0627     while (length--)
0628         *buf++ = hdmi_readb(hdmi, HDMI_DDC_READ_FIFO_ADDR);
0629 
0630     return 0;
0631 }
0632 
0633 static int rk3066_hdmi_i2c_write(struct rk3066_hdmi *hdmi, struct i2c_msg *msgs)
0634 {
0635     /*
0636      * The DDC module only supports read EDID message, so
0637      * we assume that each word write to this i2c adapter
0638      * should be the offset of the EDID word address.
0639      */
0640     if (msgs->len != 1 ||
0641         (msgs->addr != DDC_ADDR && msgs->addr != DDC_SEGMENT_ADDR))
0642         return -EINVAL;
0643 
0644     reinit_completion(&hdmi->i2c->cmpltn);
0645 
0646     if (msgs->addr == DDC_SEGMENT_ADDR)
0647         hdmi->i2c->segment_addr = msgs->buf[0];
0648     if (msgs->addr == DDC_ADDR)
0649         hdmi->i2c->ddc_addr = msgs->buf[0];
0650 
0651     /* Set edid fifo first address. */
0652     hdmi_writeb(hdmi, HDMI_EDID_FIFO_ADDR, 0x00);
0653 
0654     /* Set edid word address 0x00/0x80. */
0655     hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr);
0656 
0657     /* Set edid segment pointer. */
0658     hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr);
0659 
0660     return 0;
0661 }
0662 
0663 static int rk3066_hdmi_i2c_xfer(struct i2c_adapter *adap,
0664                 struct i2c_msg *msgs, int num)
0665 {
0666     struct rk3066_hdmi *hdmi = i2c_get_adapdata(adap);
0667     struct rk3066_hdmi_i2c *i2c = hdmi->i2c;
0668     int i, ret = 0;
0669 
0670     mutex_lock(&i2c->i2c_lock);
0671 
0672     rk3066_hdmi_i2c_init(hdmi);
0673 
0674     /* Unmute HDMI EDID interrupt. */
0675     hdmi_modb(hdmi, HDMI_INTR_MASK1,
0676           HDMI_INTR_EDID_MASK, HDMI_INTR_EDID_MASK);
0677     i2c->stat = 0;
0678 
0679     for (i = 0; i < num; i++) {
0680         DRM_DEV_DEBUG(hdmi->dev,
0681                   "xfer: num: %d/%d, len: %d, flags: %#x\n",
0682                   i + 1, num, msgs[i].len, msgs[i].flags);
0683 
0684         if (msgs[i].flags & I2C_M_RD)
0685             ret = rk3066_hdmi_i2c_read(hdmi, &msgs[i]);
0686         else
0687             ret = rk3066_hdmi_i2c_write(hdmi, &msgs[i]);
0688 
0689         if (ret < 0)
0690             break;
0691     }
0692 
0693     if (!ret)
0694         ret = num;
0695 
0696     /* Mute HDMI EDID interrupt. */
0697     hdmi_modb(hdmi, HDMI_INTR_MASK1, HDMI_INTR_EDID_MASK, 0);
0698 
0699     mutex_unlock(&i2c->i2c_lock);
0700 
0701     return ret;
0702 }
0703 
0704 static u32 rk3066_hdmi_i2c_func(struct i2c_adapter *adapter)
0705 {
0706     return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
0707 }
0708 
0709 static const struct i2c_algorithm rk3066_hdmi_algorithm = {
0710     .master_xfer   = rk3066_hdmi_i2c_xfer,
0711     .functionality = rk3066_hdmi_i2c_func,
0712 };
0713 
0714 static struct i2c_adapter *rk3066_hdmi_i2c_adapter(struct rk3066_hdmi *hdmi)
0715 {
0716     struct i2c_adapter *adap;
0717     struct rk3066_hdmi_i2c *i2c;
0718     int ret;
0719 
0720     i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
0721     if (!i2c)
0722         return ERR_PTR(-ENOMEM);
0723 
0724     mutex_init(&i2c->i2c_lock);
0725     init_completion(&i2c->cmpltn);
0726 
0727     adap = &i2c->adap;
0728     adap->class = I2C_CLASS_DDC;
0729     adap->owner = THIS_MODULE;
0730     adap->dev.parent = hdmi->dev;
0731     adap->dev.of_node = hdmi->dev->of_node;
0732     adap->algo = &rk3066_hdmi_algorithm;
0733     strlcpy(adap->name, "RK3066 HDMI", sizeof(adap->name));
0734     i2c_set_adapdata(adap, hdmi);
0735 
0736     ret = i2c_add_adapter(adap);
0737     if (ret) {
0738         DRM_DEV_ERROR(hdmi->dev, "cannot add %s I2C adapter\n",
0739                   adap->name);
0740         devm_kfree(hdmi->dev, i2c);
0741         return ERR_PTR(ret);
0742     }
0743 
0744     hdmi->i2c = i2c;
0745 
0746     DRM_DEV_DEBUG(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
0747 
0748     return adap;
0749 }
0750 
0751 static int rk3066_hdmi_bind(struct device *dev, struct device *master,
0752                 void *data)
0753 {
0754     struct platform_device *pdev = to_platform_device(dev);
0755     struct drm_device *drm = data;
0756     struct rk3066_hdmi *hdmi;
0757     int irq;
0758     int ret;
0759 
0760     hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
0761     if (!hdmi)
0762         return -ENOMEM;
0763 
0764     hdmi->dev = dev;
0765     hdmi->drm_dev = drm;
0766     hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
0767     if (IS_ERR(hdmi->regs))
0768         return PTR_ERR(hdmi->regs);
0769 
0770     irq = platform_get_irq(pdev, 0);
0771     if (irq < 0)
0772         return irq;
0773 
0774     hdmi->hclk = devm_clk_get(dev, "hclk");
0775     if (IS_ERR(hdmi->hclk)) {
0776         DRM_DEV_ERROR(dev, "unable to get HDMI hclk clock\n");
0777         return PTR_ERR(hdmi->hclk);
0778     }
0779 
0780     ret = clk_prepare_enable(hdmi->hclk);
0781     if (ret) {
0782         DRM_DEV_ERROR(dev, "cannot enable HDMI hclk clock: %d\n", ret);
0783         return ret;
0784     }
0785 
0786     hdmi->grf_regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
0787                                "rockchip,grf");
0788     if (IS_ERR(hdmi->grf_regmap)) {
0789         DRM_DEV_ERROR(dev, "unable to get rockchip,grf\n");
0790         ret = PTR_ERR(hdmi->grf_regmap);
0791         goto err_disable_hclk;
0792     }
0793 
0794     /* internal hclk = hdmi_hclk / 25 */
0795     hdmi_writeb(hdmi, HDMI_INTERNAL_CLK_DIVIDER, 25);
0796 
0797     hdmi->ddc = rk3066_hdmi_i2c_adapter(hdmi);
0798     if (IS_ERR(hdmi->ddc)) {
0799         ret = PTR_ERR(hdmi->ddc);
0800         hdmi->ddc = NULL;
0801         goto err_disable_hclk;
0802     }
0803 
0804     rk3066_hdmi_set_power_mode(hdmi, HDMI_SYS_POWER_MODE_B);
0805     usleep_range(999, 1000);
0806     hdmi_writeb(hdmi, HDMI_INTR_MASK1, HDMI_INTR_HOTPLUG);
0807     hdmi_writeb(hdmi, HDMI_INTR_MASK2, 0);
0808     hdmi_writeb(hdmi, HDMI_INTR_MASK3, 0);
0809     hdmi_writeb(hdmi, HDMI_INTR_MASK4, 0);
0810     rk3066_hdmi_set_power_mode(hdmi, HDMI_SYS_POWER_MODE_A);
0811 
0812     ret = rk3066_hdmi_register(drm, hdmi);
0813     if (ret)
0814         goto err_disable_i2c;
0815 
0816     dev_set_drvdata(dev, hdmi);
0817 
0818     ret = devm_request_threaded_irq(dev, irq, rk3066_hdmi_hardirq,
0819                     rk3066_hdmi_irq, IRQF_SHARED,
0820                     dev_name(dev), hdmi);
0821     if (ret) {
0822         DRM_DEV_ERROR(dev, "failed to request hdmi irq: %d\n", ret);
0823         goto err_cleanup_hdmi;
0824     }
0825 
0826     return 0;
0827 
0828 err_cleanup_hdmi:
0829     hdmi->connector.funcs->destroy(&hdmi->connector);
0830     hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder);
0831 err_disable_i2c:
0832     i2c_put_adapter(hdmi->ddc);
0833 err_disable_hclk:
0834     clk_disable_unprepare(hdmi->hclk);
0835 
0836     return ret;
0837 }
0838 
0839 static void rk3066_hdmi_unbind(struct device *dev, struct device *master,
0840                    void *data)
0841 {
0842     struct rk3066_hdmi *hdmi = dev_get_drvdata(dev);
0843 
0844     hdmi->connector.funcs->destroy(&hdmi->connector);
0845     hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder);
0846 
0847     i2c_put_adapter(hdmi->ddc);
0848     clk_disable_unprepare(hdmi->hclk);
0849 }
0850 
0851 static const struct component_ops rk3066_hdmi_ops = {
0852     .bind   = rk3066_hdmi_bind,
0853     .unbind = rk3066_hdmi_unbind,
0854 };
0855 
0856 static int rk3066_hdmi_probe(struct platform_device *pdev)
0857 {
0858     return component_add(&pdev->dev, &rk3066_hdmi_ops);
0859 }
0860 
0861 static int rk3066_hdmi_remove(struct platform_device *pdev)
0862 {
0863     component_del(&pdev->dev, &rk3066_hdmi_ops);
0864 
0865     return 0;
0866 }
0867 
0868 static const struct of_device_id rk3066_hdmi_dt_ids[] = {
0869     { .compatible = "rockchip,rk3066-hdmi" },
0870     { /* sentinel */ },
0871 };
0872 MODULE_DEVICE_TABLE(of, rk3066_hdmi_dt_ids);
0873 
0874 struct platform_driver rk3066_hdmi_driver = {
0875     .probe  = rk3066_hdmi_probe,
0876     .remove = rk3066_hdmi_remove,
0877     .driver = {
0878         .name = "rockchip-rk3066-hdmi",
0879         .of_match_table = rk3066_hdmi_dt_ids,
0880     },
0881 };