0001
0002
0003
0004
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;
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;
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
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
0157
0158
0159
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
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
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
0287 hdmi_writeb(hdmi, HDMI_DEEP_COLOR_MODE, 0x22);
0288
0289
0290
0291
0292
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
0346 hdmi_modb(hdmi, HDMI_VIDEO_CTRL2, HDMI_VIDEO_AUDIO_DISABLE_MASK,
0347 HDMI_AUDIO_DISABLE | HDMI_VIDEO_DISABLE);
0348
0349
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
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
0378
0379
0380
0381
0382 rk3066_hdmi_i2c_init(hdmi);
0383
0384
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
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
0560
0561
0562
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
0637
0638
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
0652 hdmi_writeb(hdmi, HDMI_EDID_FIFO_ADDR, 0x00);
0653
0654
0655 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr);
0656
0657
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
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
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
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 { },
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 };