1830 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2014 MediaTek Inc.4 * Author: Jie Qiu <jie.qiu@mediatek.com>5 */6 7#include <linux/arm-smccc.h>8#include <linux/clk.h>9#include <linux/delay.h>10#include <linux/hdmi.h>11#include <linux/i2c.h>12#include <linux/io.h>13#include <linux/kernel.h>14#include <linux/mfd/syscon.h>15#include <linux/module.h>16#include <linux/mutex.h>17#include <linux/of_platform.h>18#include <linux/of.h>19#include <linux/of_graph.h>20#include <linux/phy/phy.h>21#include <linux/platform_device.h>22#include <linux/regmap.h>23 24#include <sound/hdmi-codec.h>25 26#include <drm/drm_atomic_helper.h>27#include <drm/drm_bridge.h>28#include <drm/drm_crtc.h>29#include <drm/drm_edid.h>30#include <drm/drm_print.h>31#include <drm/drm_probe_helper.h>32 33#include "mtk_cec.h"34#include "mtk_hdmi.h"35#include "mtk_hdmi_regs.h"36 37#define NCTS_BYTES 738 39enum mtk_hdmi_clk_id {40 MTK_HDMI_CLK_HDMI_PIXEL,41 MTK_HDMI_CLK_HDMI_PLL,42 MTK_HDMI_CLK_AUD_BCLK,43 MTK_HDMI_CLK_AUD_SPDIF,44 MTK_HDMI_CLK_COUNT45};46 47enum hdmi_aud_input_type {48 HDMI_AUD_INPUT_I2S = 0,49 HDMI_AUD_INPUT_SPDIF,50};51 52enum hdmi_aud_i2s_fmt {53 HDMI_I2S_MODE_RJT_24BIT = 0,54 HDMI_I2S_MODE_RJT_16BIT,55 HDMI_I2S_MODE_LJT_24BIT,56 HDMI_I2S_MODE_LJT_16BIT,57 HDMI_I2S_MODE_I2S_24BIT,58 HDMI_I2S_MODE_I2S_16BIT59};60 61enum hdmi_aud_mclk {62 HDMI_AUD_MCLK_128FS,63 HDMI_AUD_MCLK_192FS,64 HDMI_AUD_MCLK_256FS,65 HDMI_AUD_MCLK_384FS,66 HDMI_AUD_MCLK_512FS,67 HDMI_AUD_MCLK_768FS,68 HDMI_AUD_MCLK_1152FS,69};70 71enum hdmi_aud_channel_type {72 HDMI_AUD_CHAN_TYPE_1_0 = 0,73 HDMI_AUD_CHAN_TYPE_1_1,74 HDMI_AUD_CHAN_TYPE_2_0,75 HDMI_AUD_CHAN_TYPE_2_1,76 HDMI_AUD_CHAN_TYPE_3_0,77 HDMI_AUD_CHAN_TYPE_3_1,78 HDMI_AUD_CHAN_TYPE_4_0,79 HDMI_AUD_CHAN_TYPE_4_1,80 HDMI_AUD_CHAN_TYPE_5_0,81 HDMI_AUD_CHAN_TYPE_5_1,82 HDMI_AUD_CHAN_TYPE_6_0,83 HDMI_AUD_CHAN_TYPE_6_1,84 HDMI_AUD_CHAN_TYPE_7_0,85 HDMI_AUD_CHAN_TYPE_7_1,86 HDMI_AUD_CHAN_TYPE_3_0_LRS,87 HDMI_AUD_CHAN_TYPE_3_1_LRS,88 HDMI_AUD_CHAN_TYPE_4_0_CLRS,89 HDMI_AUD_CHAN_TYPE_4_1_CLRS,90 HDMI_AUD_CHAN_TYPE_6_1_CS,91 HDMI_AUD_CHAN_TYPE_6_1_CH,92 HDMI_AUD_CHAN_TYPE_6_1_OH,93 HDMI_AUD_CHAN_TYPE_6_1_CHR,94 HDMI_AUD_CHAN_TYPE_7_1_LH_RH,95 HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR,96 HDMI_AUD_CHAN_TYPE_7_1_LC_RC,97 HDMI_AUD_CHAN_TYPE_7_1_LW_RW,98 HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD,99 HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS,100 HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS,101 HDMI_AUD_CHAN_TYPE_7_1_CS_CH,102 HDMI_AUD_CHAN_TYPE_7_1_CS_OH,103 HDMI_AUD_CHAN_TYPE_7_1_CS_CHR,104 HDMI_AUD_CHAN_TYPE_7_1_CH_OH,105 HDMI_AUD_CHAN_TYPE_7_1_CH_CHR,106 HDMI_AUD_CHAN_TYPE_7_1_OH_CHR,107 HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR,108 HDMI_AUD_CHAN_TYPE_6_0_CS,109 HDMI_AUD_CHAN_TYPE_6_0_CH,110 HDMI_AUD_CHAN_TYPE_6_0_OH,111 HDMI_AUD_CHAN_TYPE_6_0_CHR,112 HDMI_AUD_CHAN_TYPE_7_0_LH_RH,113 HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR,114 HDMI_AUD_CHAN_TYPE_7_0_LC_RC,115 HDMI_AUD_CHAN_TYPE_7_0_LW_RW,116 HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD,117 HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS,118 HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS,119 HDMI_AUD_CHAN_TYPE_7_0_CS_CH,120 HDMI_AUD_CHAN_TYPE_7_0_CS_OH,121 HDMI_AUD_CHAN_TYPE_7_0_CS_CHR,122 HDMI_AUD_CHAN_TYPE_7_0_CH_OH,123 HDMI_AUD_CHAN_TYPE_7_0_CH_CHR,124 HDMI_AUD_CHAN_TYPE_7_0_OH_CHR,125 HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR,126 HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS,127 HDMI_AUD_CHAN_TYPE_UNKNOWN = 0xFF128};129 130enum hdmi_aud_channel_swap_type {131 HDMI_AUD_SWAP_LR,132 HDMI_AUD_SWAP_LFE_CC,133 HDMI_AUD_SWAP_LSRS,134 HDMI_AUD_SWAP_RLS_RRS,135 HDMI_AUD_SWAP_LR_STATUS,136};137 138struct hdmi_audio_param {139 enum hdmi_audio_coding_type aud_codec;140 enum hdmi_audio_sample_size aud_sampe_size;141 enum hdmi_aud_input_type aud_input_type;142 enum hdmi_aud_i2s_fmt aud_i2s_fmt;143 enum hdmi_aud_mclk aud_mclk;144 enum hdmi_aud_channel_type aud_input_chan_type;145 struct hdmi_codec_params codec_params;146};147 148struct mtk_hdmi_conf {149 bool tz_disabled;150 bool cea_modes_only;151 unsigned long max_mode_clock;152};153 154struct mtk_hdmi {155 struct drm_bridge bridge;156 struct drm_bridge *next_bridge;157 struct drm_connector *curr_conn;/* current connector (only valid when 'enabled') */158 struct device *dev;159 const struct mtk_hdmi_conf *conf;160 struct phy *phy;161 struct device *cec_dev;162 struct i2c_adapter *ddc_adpt;163 struct clk *clk[MTK_HDMI_CLK_COUNT];164 struct drm_display_mode mode;165 bool dvi_mode;166 u32 min_clock;167 u32 max_clock;168 u32 max_hdisplay;169 u32 max_vdisplay;170 u32 ibias;171 u32 ibias_up;172 struct regmap *sys_regmap;173 unsigned int sys_offset;174 void __iomem *regs;175 enum hdmi_colorspace csp;176 struct hdmi_audio_param aud_param;177 bool audio_enable;178 bool powered;179 bool enabled;180 hdmi_codec_plugged_cb plugged_cb;181 struct device *codec_dev;182 struct mutex update_plugged_status_lock;183};184 185static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)186{187 return container_of(b, struct mtk_hdmi, bridge);188}189 190static u32 mtk_hdmi_read(struct mtk_hdmi *hdmi, u32 offset)191{192 return readl(hdmi->regs + offset);193}194 195static void mtk_hdmi_write(struct mtk_hdmi *hdmi, u32 offset, u32 val)196{197 writel(val, hdmi->regs + offset);198}199 200static void mtk_hdmi_clear_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits)201{202 void __iomem *reg = hdmi->regs + offset;203 u32 tmp;204 205 tmp = readl(reg);206 tmp &= ~bits;207 writel(tmp, reg);208}209 210static void mtk_hdmi_set_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits)211{212 void __iomem *reg = hdmi->regs + offset;213 u32 tmp;214 215 tmp = readl(reg);216 tmp |= bits;217 writel(tmp, reg);218}219 220static void mtk_hdmi_mask(struct mtk_hdmi *hdmi, u32 offset, u32 val, u32 mask)221{222 void __iomem *reg = hdmi->regs + offset;223 u32 tmp;224 225 tmp = readl(reg);226 tmp = (tmp & ~mask) | (val & mask);227 writel(tmp, reg);228}229 230static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black)231{232 mtk_hdmi_mask(hdmi, VIDEO_CFG_4, black ? GEN_RGB : NORMAL_PATH,233 VIDEO_SOURCE_SEL);234}235 236static void mtk_hdmi_hw_make_reg_writable(struct mtk_hdmi *hdmi, bool enable)237{238 struct arm_smccc_res res;239 240 /*241 * MT8173 HDMI hardware has an output control bit to enable/disable HDMI242 * output. This bit can only be controlled in ARM supervisor mode.243 * The ARM trusted firmware provides an API for the HDMI driver to set244 * this control bit to enable HDMI output in supervisor mode.245 */246 if (hdmi->conf && hdmi->conf->tz_disabled)247 regmap_update_bits(hdmi->sys_regmap,248 hdmi->sys_offset + HDMI_SYS_CFG20,249 0x80008005, enable ? 0x80000005 : 0x8000);250 else251 arm_smccc_smc(MTK_SIP_SET_AUTHORIZED_SECURE_REG, 0x14000904,252 0x80000000, 0, 0, 0, 0, 0, &res);253 254 regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG20,255 HDMI_PCLK_FREE_RUN, enable ? HDMI_PCLK_FREE_RUN : 0);256 regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG1C,257 HDMI_ON | ANLG_ON, enable ? (HDMI_ON | ANLG_ON) : 0);258}259 260static void mtk_hdmi_hw_1p4_version_enable(struct mtk_hdmi *hdmi, bool enable)261{262 regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG20,263 HDMI2P0_EN, enable ? 0 : HDMI2P0_EN);264}265 266static void mtk_hdmi_hw_aud_mute(struct mtk_hdmi *hdmi)267{268 mtk_hdmi_set_bits(hdmi, GRL_AUDIO_CFG, AUDIO_ZERO);269}270 271static void mtk_hdmi_hw_aud_unmute(struct mtk_hdmi *hdmi)272{273 mtk_hdmi_clear_bits(hdmi, GRL_AUDIO_CFG, AUDIO_ZERO);274}275 276static void mtk_hdmi_hw_reset(struct mtk_hdmi *hdmi)277{278 regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG1C,279 HDMI_RST, HDMI_RST);280 regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG1C,281 HDMI_RST, 0);282 mtk_hdmi_clear_bits(hdmi, GRL_CFG3, CFG3_CONTROL_PACKET_DELAY);283 regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG1C,284 ANLG_ON, ANLG_ON);285}286 287static void mtk_hdmi_hw_enable_notice(struct mtk_hdmi *hdmi, bool enable_notice)288{289 mtk_hdmi_mask(hdmi, GRL_CFG2, enable_notice ? CFG2_NOTICE_EN : 0,290 CFG2_NOTICE_EN);291}292 293static void mtk_hdmi_hw_write_int_mask(struct mtk_hdmi *hdmi, u32 int_mask)294{295 mtk_hdmi_write(hdmi, GRL_INT_MASK, int_mask);296}297 298static void mtk_hdmi_hw_enable_dvi_mode(struct mtk_hdmi *hdmi, bool enable)299{300 mtk_hdmi_mask(hdmi, GRL_CFG1, enable ? CFG1_DVI : 0, CFG1_DVI);301}302 303static void mtk_hdmi_hw_send_info_frame(struct mtk_hdmi *hdmi, u8 *buffer,304 u8 len)305{306 u32 ctrl_reg = GRL_CTRL;307 int i;308 u8 *frame_data;309 enum hdmi_infoframe_type frame_type;310 u8 frame_ver;311 u8 frame_len;312 u8 checksum;313 int ctrl_frame_en = 0;314 315 frame_type = *buffer++;316 frame_ver = *buffer++;317 frame_len = *buffer++;318 checksum = *buffer++;319 frame_data = buffer;320 321 dev_dbg(hdmi->dev,322 "frame_type:0x%x,frame_ver:0x%x,frame_len:0x%x,checksum:0x%x\n",323 frame_type, frame_ver, frame_len, checksum);324 325 switch (frame_type) {326 case HDMI_INFOFRAME_TYPE_AVI:327 ctrl_frame_en = CTRL_AVI_EN;328 ctrl_reg = GRL_CTRL;329 break;330 case HDMI_INFOFRAME_TYPE_SPD:331 ctrl_frame_en = CTRL_SPD_EN;332 ctrl_reg = GRL_CTRL;333 break;334 case HDMI_INFOFRAME_TYPE_AUDIO:335 ctrl_frame_en = CTRL_AUDIO_EN;336 ctrl_reg = GRL_CTRL;337 break;338 case HDMI_INFOFRAME_TYPE_VENDOR:339 ctrl_frame_en = VS_EN;340 ctrl_reg = GRL_ACP_ISRC_CTRL;341 break;342 default:343 dev_err(hdmi->dev, "Unknown infoframe type %d\n", frame_type);344 return;345 }346 mtk_hdmi_clear_bits(hdmi, ctrl_reg, ctrl_frame_en);347 mtk_hdmi_write(hdmi, GRL_INFOFRM_TYPE, frame_type);348 mtk_hdmi_write(hdmi, GRL_INFOFRM_VER, frame_ver);349 mtk_hdmi_write(hdmi, GRL_INFOFRM_LNG, frame_len);350 351 mtk_hdmi_write(hdmi, GRL_IFM_PORT, checksum);352 for (i = 0; i < frame_len; i++)353 mtk_hdmi_write(hdmi, GRL_IFM_PORT, frame_data[i]);354 355 mtk_hdmi_set_bits(hdmi, ctrl_reg, ctrl_frame_en);356}357 358static void mtk_hdmi_hw_send_aud_packet(struct mtk_hdmi *hdmi, bool enable)359{360 mtk_hdmi_mask(hdmi, GRL_SHIFT_R2, enable ? 0 : AUDIO_PACKET_OFF,361 AUDIO_PACKET_OFF);362}363 364static void mtk_hdmi_hw_config_sys(struct mtk_hdmi *hdmi)365{366 regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG20,367 HDMI_OUT_FIFO_EN | MHL_MODE_ON, 0);368 usleep_range(2000, 4000);369 regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG20,370 HDMI_OUT_FIFO_EN | MHL_MODE_ON, HDMI_OUT_FIFO_EN);371}372 373static void mtk_hdmi_hw_set_deep_color_mode(struct mtk_hdmi *hdmi)374{375 regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG20,376 DEEP_COLOR_MODE_MASK | DEEP_COLOR_EN,377 COLOR_8BIT_MODE);378}379 380static void mtk_hdmi_hw_send_av_mute(struct mtk_hdmi *hdmi)381{382 mtk_hdmi_clear_bits(hdmi, GRL_CFG4, CTRL_AVMUTE);383 usleep_range(2000, 4000);384 mtk_hdmi_set_bits(hdmi, GRL_CFG4, CTRL_AVMUTE);385}386 387static void mtk_hdmi_hw_send_av_unmute(struct mtk_hdmi *hdmi)388{389 mtk_hdmi_mask(hdmi, GRL_CFG4, CFG4_AV_UNMUTE_EN,390 CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET);391 usleep_range(2000, 4000);392 mtk_hdmi_mask(hdmi, GRL_CFG4, CFG4_AV_UNMUTE_SET,393 CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET);394}395 396static void mtk_hdmi_hw_ncts_enable(struct mtk_hdmi *hdmi, bool on)397{398 mtk_hdmi_mask(hdmi, GRL_CTS_CTRL, on ? 0 : CTS_CTRL_SOFT,399 CTS_CTRL_SOFT);400}401 402static void mtk_hdmi_hw_ncts_auto_write_enable(struct mtk_hdmi *hdmi,403 bool enable)404{405 mtk_hdmi_mask(hdmi, GRL_CTS_CTRL, enable ? NCTS_WRI_ANYTIME : 0,406 NCTS_WRI_ANYTIME);407}408 409static void mtk_hdmi_hw_msic_setting(struct mtk_hdmi *hdmi,410 struct drm_display_mode *mode)411{412 mtk_hdmi_clear_bits(hdmi, GRL_CFG4, CFG4_MHL_MODE);413 414 if (mode->flags & DRM_MODE_FLAG_INTERLACE &&415 mode->clock == 74250 &&416 mode->vdisplay == 1080)417 mtk_hdmi_clear_bits(hdmi, GRL_CFG2, CFG2_MHL_DE_SEL);418 else419 mtk_hdmi_set_bits(hdmi, GRL_CFG2, CFG2_MHL_DE_SEL);420}421 422static void mtk_hdmi_hw_aud_set_channel_swap(struct mtk_hdmi *hdmi,423 enum hdmi_aud_channel_swap_type swap)424{425 u8 swap_bit;426 427 switch (swap) {428 case HDMI_AUD_SWAP_LR:429 swap_bit = LR_SWAP;430 break;431 case HDMI_AUD_SWAP_LFE_CC:432 swap_bit = LFE_CC_SWAP;433 break;434 case HDMI_AUD_SWAP_LSRS:435 swap_bit = LSRS_SWAP;436 break;437 case HDMI_AUD_SWAP_RLS_RRS:438 swap_bit = RLS_RRS_SWAP;439 break;440 case HDMI_AUD_SWAP_LR_STATUS:441 swap_bit = LR_STATUS_SWAP;442 break;443 default:444 swap_bit = LFE_CC_SWAP;445 break;446 }447 mtk_hdmi_mask(hdmi, GRL_CH_SWAP, swap_bit, 0xff);448}449 450static void mtk_hdmi_hw_aud_set_bit_num(struct mtk_hdmi *hdmi,451 enum hdmi_audio_sample_size bit_num)452{453 u32 val;454 455 switch (bit_num) {456 case HDMI_AUDIO_SAMPLE_SIZE_16:457 val = AOUT_16BIT;458 break;459 case HDMI_AUDIO_SAMPLE_SIZE_20:460 val = AOUT_20BIT;461 break;462 case HDMI_AUDIO_SAMPLE_SIZE_24:463 case HDMI_AUDIO_SAMPLE_SIZE_STREAM:464 val = AOUT_24BIT;465 break;466 }467 468 mtk_hdmi_mask(hdmi, GRL_AOUT_CFG, val, AOUT_BNUM_SEL_MASK);469}470 471static void mtk_hdmi_hw_aud_set_i2s_fmt(struct mtk_hdmi *hdmi,472 enum hdmi_aud_i2s_fmt i2s_fmt)473{474 u32 val;475 476 val = mtk_hdmi_read(hdmi, GRL_CFG0);477 val &= ~(CFG0_W_LENGTH_MASK | CFG0_I2S_MODE_MASK);478 479 switch (i2s_fmt) {480 case HDMI_I2S_MODE_RJT_24BIT:481 val |= CFG0_I2S_MODE_RTJ | CFG0_W_LENGTH_24BIT;482 break;483 case HDMI_I2S_MODE_RJT_16BIT:484 val |= CFG0_I2S_MODE_RTJ | CFG0_W_LENGTH_16BIT;485 break;486 case HDMI_I2S_MODE_LJT_24BIT:487 default:488 val |= CFG0_I2S_MODE_LTJ | CFG0_W_LENGTH_24BIT;489 break;490 case HDMI_I2S_MODE_LJT_16BIT:491 val |= CFG0_I2S_MODE_LTJ | CFG0_W_LENGTH_16BIT;492 break;493 case HDMI_I2S_MODE_I2S_24BIT:494 val |= CFG0_I2S_MODE_I2S | CFG0_W_LENGTH_24BIT;495 break;496 case HDMI_I2S_MODE_I2S_16BIT:497 val |= CFG0_I2S_MODE_I2S | CFG0_W_LENGTH_16BIT;498 break;499 }500 mtk_hdmi_write(hdmi, GRL_CFG0, val);501}502 503static void mtk_hdmi_hw_audio_config(struct mtk_hdmi *hdmi, bool dst)504{505 const u8 mask = HIGH_BIT_RATE | DST_NORMAL_DOUBLE | SACD_DST | DSD_SEL;506 u8 val;507 508 /* Disable high bitrate, set DST packet normal/double */509 mtk_hdmi_clear_bits(hdmi, GRL_AOUT_CFG, HIGH_BIT_RATE_PACKET_ALIGN);510 511 if (dst)512 val = DST_NORMAL_DOUBLE | SACD_DST;513 else514 val = 0;515 516 mtk_hdmi_mask(hdmi, GRL_AUDIO_CFG, val, mask);517}518 519static void mtk_hdmi_hw_aud_set_i2s_chan_num(struct mtk_hdmi *hdmi,520 enum hdmi_aud_channel_type channel_type,521 u8 channel_count)522{523 unsigned int ch_switch;524 u8 i2s_uv;525 526 ch_switch = CH_SWITCH(7, 7) | CH_SWITCH(6, 6) |527 CH_SWITCH(5, 5) | CH_SWITCH(4, 4) |528 CH_SWITCH(3, 3) | CH_SWITCH(1, 2) |529 CH_SWITCH(2, 1) | CH_SWITCH(0, 0);530 531 if (channel_count == 2) {532 i2s_uv = I2S_UV_CH_EN(0);533 } else if (channel_count == 3 || channel_count == 4) {534 if (channel_count == 4 &&535 (channel_type == HDMI_AUD_CHAN_TYPE_3_0_LRS ||536 channel_type == HDMI_AUD_CHAN_TYPE_4_0))537 i2s_uv = I2S_UV_CH_EN(2) | I2S_UV_CH_EN(0);538 else539 i2s_uv = I2S_UV_CH_EN(3) | I2S_UV_CH_EN(2);540 } else if (channel_count == 6 || channel_count == 5) {541 if (channel_count == 6 &&542 channel_type != HDMI_AUD_CHAN_TYPE_5_1 &&543 channel_type != HDMI_AUD_CHAN_TYPE_4_1_CLRS) {544 i2s_uv = I2S_UV_CH_EN(3) | I2S_UV_CH_EN(2) |545 I2S_UV_CH_EN(1) | I2S_UV_CH_EN(0);546 } else {547 i2s_uv = I2S_UV_CH_EN(2) | I2S_UV_CH_EN(1) |548 I2S_UV_CH_EN(0);549 }550 } else if (channel_count == 8 || channel_count == 7) {551 i2s_uv = I2S_UV_CH_EN(3) | I2S_UV_CH_EN(2) |552 I2S_UV_CH_EN(1) | I2S_UV_CH_EN(0);553 } else {554 i2s_uv = I2S_UV_CH_EN(0);555 }556 557 mtk_hdmi_write(hdmi, GRL_CH_SW0, ch_switch & 0xff);558 mtk_hdmi_write(hdmi, GRL_CH_SW1, (ch_switch >> 8) & 0xff);559 mtk_hdmi_write(hdmi, GRL_CH_SW2, (ch_switch >> 16) & 0xff);560 mtk_hdmi_write(hdmi, GRL_I2S_UV, i2s_uv);561}562 563static void mtk_hdmi_hw_aud_set_input_type(struct mtk_hdmi *hdmi,564 enum hdmi_aud_input_type input_type)565{566 u32 val;567 568 val = mtk_hdmi_read(hdmi, GRL_CFG1);569 if (input_type == HDMI_AUD_INPUT_I2S &&570 (val & CFG1_SPDIF) == CFG1_SPDIF) {571 val &= ~CFG1_SPDIF;572 } else if (input_type == HDMI_AUD_INPUT_SPDIF &&573 (val & CFG1_SPDIF) == 0) {574 val |= CFG1_SPDIF;575 }576 mtk_hdmi_write(hdmi, GRL_CFG1, val);577}578 579static void mtk_hdmi_hw_aud_set_channel_status(struct mtk_hdmi *hdmi,580 u8 *channel_status)581{582 int i;583 584 for (i = 0; i < 5; i++) {585 mtk_hdmi_write(hdmi, GRL_I2S_C_STA0 + i * 4, channel_status[i]);586 mtk_hdmi_write(hdmi, GRL_L_STATUS_0 + i * 4, channel_status[i]);587 mtk_hdmi_write(hdmi, GRL_R_STATUS_0 + i * 4, channel_status[i]);588 }589 for (; i < 24; i++) {590 mtk_hdmi_write(hdmi, GRL_L_STATUS_0 + i * 4, 0);591 mtk_hdmi_write(hdmi, GRL_R_STATUS_0 + i * 4, 0);592 }593}594 595static void mtk_hdmi_hw_aud_src_reenable(struct mtk_hdmi *hdmi)596{597 u32 val;598 599 val = mtk_hdmi_read(hdmi, GRL_MIX_CTRL);600 if (val & MIX_CTRL_SRC_EN) {601 val &= ~MIX_CTRL_SRC_EN;602 mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val);603 usleep_range(255, 512);604 val |= MIX_CTRL_SRC_EN;605 mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val);606 }607}608 609static void mtk_hdmi_hw_aud_src_disable(struct mtk_hdmi *hdmi)610{611 u32 val;612 613 val = mtk_hdmi_read(hdmi, GRL_MIX_CTRL);614 val &= ~MIX_CTRL_SRC_EN;615 mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val);616 mtk_hdmi_write(hdmi, GRL_SHIFT_L1, 0x00);617}618 619static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi,620 enum hdmi_aud_mclk mclk)621{622 u32 val;623 624 val = mtk_hdmi_read(hdmi, GRL_CFG5);625 val &= CFG5_CD_RATIO_MASK;626 627 switch (mclk) {628 case HDMI_AUD_MCLK_128FS:629 val |= CFG5_FS128;630 break;631 case HDMI_AUD_MCLK_256FS:632 val |= CFG5_FS256;633 break;634 case HDMI_AUD_MCLK_384FS:635 val |= CFG5_FS384;636 break;637 case HDMI_AUD_MCLK_512FS:638 val |= CFG5_FS512;639 break;640 case HDMI_AUD_MCLK_768FS:641 val |= CFG5_FS768;642 break;643 default:644 val |= CFG5_FS256;645 break;646 }647 mtk_hdmi_write(hdmi, GRL_CFG5, val);648}649 650struct hdmi_acr_n {651 unsigned int clock;652 unsigned int n[3];653};654 655/* Recommended N values from HDMI specification, tables 7-1 to 7-3 */656static const struct hdmi_acr_n hdmi_rec_n_table[] = {657 /* Clock, N: 32kHz 44.1kHz 48kHz */658 { 25175, { 4576, 7007, 6864 } },659 { 74176, { 11648, 17836, 11648 } },660 { 148352, { 11648, 8918, 5824 } },661 { 296703, { 5824, 4459, 5824 } },662 { 297000, { 3072, 4704, 5120 } },663 { 0, { 4096, 6272, 6144 } }, /* all other TMDS clocks */664};665 666/**667 * hdmi_recommended_n() - Return N value recommended by HDMI specification668 * @freq: audio sample rate in Hz669 * @clock: rounded TMDS clock in kHz670 */671static unsigned int hdmi_recommended_n(unsigned int freq, unsigned int clock)672{673 const struct hdmi_acr_n *recommended;674 unsigned int i;675 676 for (i = 0; i < ARRAY_SIZE(hdmi_rec_n_table) - 1; i++) {677 if (clock == hdmi_rec_n_table[i].clock)678 break;679 }680 recommended = hdmi_rec_n_table + i;681 682 switch (freq) {683 case 32000:684 return recommended->n[0];685 case 44100:686 return recommended->n[1];687 case 48000:688 return recommended->n[2];689 case 88200:690 return recommended->n[1] * 2;691 case 96000:692 return recommended->n[2] * 2;693 case 176400:694 return recommended->n[1] * 4;695 case 192000:696 return recommended->n[2] * 4;697 default:698 return (128 * freq) / 1000;699 }700}701 702static unsigned int hdmi_mode_clock_to_hz(unsigned int clock)703{704 switch (clock) {705 case 25175:706 return 25174825; /* 25.2/1.001 MHz */707 case 74176:708 return 74175824; /* 74.25/1.001 MHz */709 case 148352:710 return 148351648; /* 148.5/1.001 MHz */711 case 296703:712 return 296703297; /* 297/1.001 MHz */713 default:714 return clock * 1000;715 }716}717 718static unsigned int hdmi_expected_cts(unsigned int audio_sample_rate,719 unsigned int tmds_clock, unsigned int n)720{721 return DIV_ROUND_CLOSEST_ULL((u64)hdmi_mode_clock_to_hz(tmds_clock) * n,722 128 * audio_sample_rate);723}724 725static void do_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, unsigned int n,726 unsigned int cts)727{728 unsigned char val[NCTS_BYTES];729 int i;730 731 mtk_hdmi_write(hdmi, GRL_NCTS, 0);732 mtk_hdmi_write(hdmi, GRL_NCTS, 0);733 mtk_hdmi_write(hdmi, GRL_NCTS, 0);734 memset(val, 0, sizeof(val));735 736 val[0] = (cts >> 24) & 0xff;737 val[1] = (cts >> 16) & 0xff;738 val[2] = (cts >> 8) & 0xff;739 val[3] = cts & 0xff;740 741 val[4] = (n >> 16) & 0xff;742 val[5] = (n >> 8) & 0xff;743 val[6] = n & 0xff;744 745 for (i = 0; i < NCTS_BYTES; i++)746 mtk_hdmi_write(hdmi, GRL_NCTS, val[i]);747}748 749static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi,750 unsigned int sample_rate,751 unsigned int clock)752{753 unsigned int n, cts;754 755 n = hdmi_recommended_n(sample_rate, clock);756 cts = hdmi_expected_cts(sample_rate, clock, n);757 758 dev_dbg(hdmi->dev, "%s: sample_rate=%u, clock=%d, cts=%u, n=%u\n",759 __func__, sample_rate, clock, n, cts);760 761 mtk_hdmi_mask(hdmi, DUMMY_304, AUDIO_I2S_NCTS_SEL_64,762 AUDIO_I2S_NCTS_SEL);763 do_hdmi_hw_aud_set_ncts(hdmi, n, cts);764}765 766static u8 mtk_hdmi_aud_get_chnl_count(enum hdmi_aud_channel_type channel_type)767{768 switch (channel_type) {769 case HDMI_AUD_CHAN_TYPE_1_0:770 case HDMI_AUD_CHAN_TYPE_1_1:771 case HDMI_AUD_CHAN_TYPE_2_0:772 return 2;773 case HDMI_AUD_CHAN_TYPE_2_1:774 case HDMI_AUD_CHAN_TYPE_3_0:775 return 3;776 case HDMI_AUD_CHAN_TYPE_3_1:777 case HDMI_AUD_CHAN_TYPE_4_0:778 case HDMI_AUD_CHAN_TYPE_3_0_LRS:779 return 4;780 case HDMI_AUD_CHAN_TYPE_4_1:781 case HDMI_AUD_CHAN_TYPE_5_0:782 case HDMI_AUD_CHAN_TYPE_3_1_LRS:783 case HDMI_AUD_CHAN_TYPE_4_0_CLRS:784 return 5;785 case HDMI_AUD_CHAN_TYPE_5_1:786 case HDMI_AUD_CHAN_TYPE_6_0:787 case HDMI_AUD_CHAN_TYPE_4_1_CLRS:788 case HDMI_AUD_CHAN_TYPE_6_0_CS:789 case HDMI_AUD_CHAN_TYPE_6_0_CH:790 case HDMI_AUD_CHAN_TYPE_6_0_OH:791 case HDMI_AUD_CHAN_TYPE_6_0_CHR:792 return 6;793 case HDMI_AUD_CHAN_TYPE_6_1:794 case HDMI_AUD_CHAN_TYPE_6_1_CS:795 case HDMI_AUD_CHAN_TYPE_6_1_CH:796 case HDMI_AUD_CHAN_TYPE_6_1_OH:797 case HDMI_AUD_CHAN_TYPE_6_1_CHR:798 case HDMI_AUD_CHAN_TYPE_7_0:799 case HDMI_AUD_CHAN_TYPE_7_0_LH_RH:800 case HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR:801 case HDMI_AUD_CHAN_TYPE_7_0_LC_RC:802 case HDMI_AUD_CHAN_TYPE_7_0_LW_RW:803 case HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD:804 case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS:805 case HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS:806 case HDMI_AUD_CHAN_TYPE_7_0_CS_CH:807 case HDMI_AUD_CHAN_TYPE_7_0_CS_OH:808 case HDMI_AUD_CHAN_TYPE_7_0_CS_CHR:809 case HDMI_AUD_CHAN_TYPE_7_0_CH_OH:810 case HDMI_AUD_CHAN_TYPE_7_0_CH_CHR:811 case HDMI_AUD_CHAN_TYPE_7_0_OH_CHR:812 case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR:813 case HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS:814 return 7;815 case HDMI_AUD_CHAN_TYPE_7_1:816 case HDMI_AUD_CHAN_TYPE_7_1_LH_RH:817 case HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR:818 case HDMI_AUD_CHAN_TYPE_7_1_LC_RC:819 case HDMI_AUD_CHAN_TYPE_7_1_LW_RW:820 case HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD:821 case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS:822 case HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS:823 case HDMI_AUD_CHAN_TYPE_7_1_CS_CH:824 case HDMI_AUD_CHAN_TYPE_7_1_CS_OH:825 case HDMI_AUD_CHAN_TYPE_7_1_CS_CHR:826 case HDMI_AUD_CHAN_TYPE_7_1_CH_OH:827 case HDMI_AUD_CHAN_TYPE_7_1_CH_CHR:828 case HDMI_AUD_CHAN_TYPE_7_1_OH_CHR:829 case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR:830 return 8;831 default:832 return 2;833 }834}835 836static int mtk_hdmi_video_change_vpll(struct mtk_hdmi *hdmi, u32 clock)837{838 unsigned long rate;839 int ret;840 841 /* The DPI driver already should have set TVDPLL to the correct rate */842 ret = clk_set_rate(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL], clock);843 if (ret) {844 dev_err(hdmi->dev, "Failed to set PLL to %u Hz: %d\n", clock,845 ret);846 return ret;847 }848 849 rate = clk_get_rate(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]);850 851 if (DIV_ROUND_CLOSEST(rate, 1000) != DIV_ROUND_CLOSEST(clock, 1000))852 dev_warn(hdmi->dev, "Want PLL %u Hz, got %lu Hz\n", clock,853 rate);854 else855 dev_dbg(hdmi->dev, "Want PLL %u Hz, got %lu Hz\n", clock, rate);856 857 mtk_hdmi_hw_config_sys(hdmi);858 mtk_hdmi_hw_set_deep_color_mode(hdmi);859 return 0;860}861 862static void mtk_hdmi_video_set_display_mode(struct mtk_hdmi *hdmi,863 struct drm_display_mode *mode)864{865 mtk_hdmi_hw_reset(hdmi);866 mtk_hdmi_hw_enable_notice(hdmi, true);867 mtk_hdmi_hw_write_int_mask(hdmi, 0xff);868 mtk_hdmi_hw_enable_dvi_mode(hdmi, hdmi->dvi_mode);869 mtk_hdmi_hw_ncts_auto_write_enable(hdmi, true);870 871 mtk_hdmi_hw_msic_setting(hdmi, mode);872}873 874 875static void mtk_hdmi_aud_set_input(struct mtk_hdmi *hdmi)876{877 enum hdmi_aud_channel_type chan_type;878 u8 chan_count;879 bool dst;880 881 mtk_hdmi_hw_aud_set_channel_swap(hdmi, HDMI_AUD_SWAP_LFE_CC);882 mtk_hdmi_set_bits(hdmi, GRL_MIX_CTRL, MIX_CTRL_FLAT);883 884 if (hdmi->aud_param.aud_input_type == HDMI_AUD_INPUT_SPDIF &&885 hdmi->aud_param.aud_codec == HDMI_AUDIO_CODING_TYPE_DST) {886 mtk_hdmi_hw_aud_set_bit_num(hdmi, HDMI_AUDIO_SAMPLE_SIZE_24);887 } else if (hdmi->aud_param.aud_i2s_fmt == HDMI_I2S_MODE_LJT_24BIT) {888 hdmi->aud_param.aud_i2s_fmt = HDMI_I2S_MODE_LJT_16BIT;889 }890 891 mtk_hdmi_hw_aud_set_i2s_fmt(hdmi, hdmi->aud_param.aud_i2s_fmt);892 mtk_hdmi_hw_aud_set_bit_num(hdmi, HDMI_AUDIO_SAMPLE_SIZE_24);893 894 dst = ((hdmi->aud_param.aud_input_type == HDMI_AUD_INPUT_SPDIF) &&895 (hdmi->aud_param.aud_codec == HDMI_AUDIO_CODING_TYPE_DST));896 mtk_hdmi_hw_audio_config(hdmi, dst);897 898 if (hdmi->aud_param.aud_input_type == HDMI_AUD_INPUT_SPDIF)899 chan_type = HDMI_AUD_CHAN_TYPE_2_0;900 else901 chan_type = hdmi->aud_param.aud_input_chan_type;902 chan_count = mtk_hdmi_aud_get_chnl_count(chan_type);903 mtk_hdmi_hw_aud_set_i2s_chan_num(hdmi, chan_type, chan_count);904 mtk_hdmi_hw_aud_set_input_type(hdmi, hdmi->aud_param.aud_input_type);905}906 907static int mtk_hdmi_aud_set_src(struct mtk_hdmi *hdmi,908 struct drm_display_mode *display_mode)909{910 unsigned int sample_rate = hdmi->aud_param.codec_params.sample_rate;911 912 mtk_hdmi_hw_ncts_enable(hdmi, false);913 mtk_hdmi_hw_aud_src_disable(hdmi);914 mtk_hdmi_clear_bits(hdmi, GRL_CFG2, CFG2_ACLK_INV);915 916 if (hdmi->aud_param.aud_input_type == HDMI_AUD_INPUT_I2S) {917 switch (sample_rate) {918 case 32000:919 case 44100:920 case 48000:921 case 88200:922 case 96000:923 break;924 default:925 return -EINVAL;926 }927 mtk_hdmi_hw_aud_set_mclk(hdmi, hdmi->aud_param.aud_mclk);928 } else {929 switch (sample_rate) {930 case 32000:931 case 44100:932 case 48000:933 break;934 default:935 return -EINVAL;936 }937 mtk_hdmi_hw_aud_set_mclk(hdmi, HDMI_AUD_MCLK_128FS);938 }939 940 mtk_hdmi_hw_aud_set_ncts(hdmi, sample_rate, display_mode->clock);941 942 mtk_hdmi_hw_aud_src_reenable(hdmi);943 return 0;944}945 946static int mtk_hdmi_aud_output_config(struct mtk_hdmi *hdmi,947 struct drm_display_mode *display_mode)948{949 mtk_hdmi_hw_aud_mute(hdmi);950 mtk_hdmi_hw_send_aud_packet(hdmi, false);951 952 mtk_hdmi_aud_set_input(hdmi);953 mtk_hdmi_aud_set_src(hdmi, display_mode);954 mtk_hdmi_hw_aud_set_channel_status(hdmi,955 hdmi->aud_param.codec_params.iec.status);956 957 usleep_range(50, 100);958 959 mtk_hdmi_hw_ncts_enable(hdmi, true);960 mtk_hdmi_hw_send_aud_packet(hdmi, true);961 mtk_hdmi_hw_aud_unmute(hdmi);962 return 0;963}964 965static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi,966 struct drm_display_mode *mode)967{968 struct hdmi_avi_infoframe frame;969 u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];970 ssize_t err;971 972 err = drm_hdmi_avi_infoframe_from_display_mode(&frame,973 hdmi->curr_conn, mode);974 if (err < 0) {975 dev_err(hdmi->dev,976 "Failed to get AVI infoframe from mode: %zd\n", err);977 return err;978 }979 980 err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));981 if (err < 0) {982 dev_err(hdmi->dev, "Failed to pack AVI infoframe: %zd\n", err);983 return err;984 }985 986 mtk_hdmi_hw_send_info_frame(hdmi, buffer, sizeof(buffer));987 return 0;988}989 990static int mtk_hdmi_setup_spd_infoframe(struct mtk_hdmi *hdmi,991 const char *vendor,992 const char *product)993{994 struct hdmi_spd_infoframe frame;995 u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_SPD_INFOFRAME_SIZE];996 ssize_t err;997 998 err = hdmi_spd_infoframe_init(&frame, vendor, product);999 if (err < 0) {1000 dev_err(hdmi->dev, "Failed to initialize SPD infoframe: %zd\n",1001 err);1002 return err;1003 }1004 1005 err = hdmi_spd_infoframe_pack(&frame, buffer, sizeof(buffer));1006 if (err < 0) {1007 dev_err(hdmi->dev, "Failed to pack SDP infoframe: %zd\n", err);1008 return err;1009 }1010 1011 mtk_hdmi_hw_send_info_frame(hdmi, buffer, sizeof(buffer));1012 return 0;1013}1014 1015static int mtk_hdmi_setup_audio_infoframe(struct mtk_hdmi *hdmi)1016{1017 struct hdmi_audio_infoframe frame;1018 u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];1019 ssize_t err;1020 1021 err = hdmi_audio_infoframe_init(&frame);1022 if (err < 0) {1023 dev_err(hdmi->dev, "Failed to setup audio infoframe: %zd\n",1024 err);1025 return err;1026 }1027 1028 frame.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;1029 frame.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;1030 frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;1031 frame.channels = mtk_hdmi_aud_get_chnl_count(1032 hdmi->aud_param.aud_input_chan_type);1033 1034 err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));1035 if (err < 0) {1036 dev_err(hdmi->dev, "Failed to pack audio infoframe: %zd\n",1037 err);1038 return err;1039 }1040 1041 mtk_hdmi_hw_send_info_frame(hdmi, buffer, sizeof(buffer));1042 return 0;1043}1044 1045static int mtk_hdmi_setup_vendor_specific_infoframe(struct mtk_hdmi *hdmi,1046 struct drm_display_mode *mode)1047{1048 struct hdmi_vendor_infoframe frame;1049 u8 buffer[10];1050 ssize_t err;1051 1052 err = drm_hdmi_vendor_infoframe_from_display_mode(&frame,1053 hdmi->curr_conn, mode);1054 if (err) {1055 dev_err(hdmi->dev,1056 "Failed to get vendor infoframe from mode: %zd\n", err);1057 return err;1058 }1059 1060 err = hdmi_vendor_infoframe_pack(&frame, buffer, sizeof(buffer));1061 if (err < 0) {1062 dev_err(hdmi->dev, "Failed to pack vendor infoframe: %zd\n",1063 err);1064 return err;1065 }1066 1067 mtk_hdmi_hw_send_info_frame(hdmi, buffer, sizeof(buffer));1068 return 0;1069}1070 1071static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)1072{1073 struct hdmi_audio_param *aud_param = &hdmi->aud_param;1074 1075 hdmi->csp = HDMI_COLORSPACE_RGB;1076 aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;1077 aud_param->aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;1078 aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;1079 aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;1080 aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;1081 aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;1082 1083 return 0;1084}1085 1086static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi)1087{1088 mtk_hdmi_hw_send_aud_packet(hdmi, true);1089 hdmi->audio_enable = true;1090}1091 1092static void mtk_hdmi_audio_disable(struct mtk_hdmi *hdmi)1093{1094 mtk_hdmi_hw_send_aud_packet(hdmi, false);1095 hdmi->audio_enable = false;1096}1097 1098static int mtk_hdmi_audio_set_param(struct mtk_hdmi *hdmi,1099 struct hdmi_audio_param *param)1100{1101 if (!hdmi->audio_enable) {1102 dev_err(hdmi->dev, "hdmi audio is in disable state!\n");1103 return -EINVAL;1104 }1105 dev_dbg(hdmi->dev, "codec:%d, input:%d, channel:%d, fs:%d\n",1106 param->aud_codec, param->aud_input_type,1107 param->aud_input_chan_type, param->codec_params.sample_rate);1108 memcpy(&hdmi->aud_param, param, sizeof(*param));1109 return mtk_hdmi_aud_output_config(hdmi, &hdmi->mode);1110}1111 1112static int mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi,1113 struct drm_display_mode *mode)1114{1115 int ret;1116 1117 mtk_hdmi_hw_vid_black(hdmi, true);1118 mtk_hdmi_hw_aud_mute(hdmi);1119 mtk_hdmi_hw_send_av_mute(hdmi);1120 phy_power_off(hdmi->phy);1121 1122 ret = mtk_hdmi_video_change_vpll(hdmi,1123 mode->clock * 1000);1124 if (ret) {1125 dev_err(hdmi->dev, "Failed to set vpll: %d\n", ret);1126 return ret;1127 }1128 mtk_hdmi_video_set_display_mode(hdmi, mode);1129 1130 phy_power_on(hdmi->phy);1131 mtk_hdmi_aud_output_config(hdmi, mode);1132 1133 mtk_hdmi_hw_vid_black(hdmi, false);1134 mtk_hdmi_hw_aud_unmute(hdmi);1135 mtk_hdmi_hw_send_av_unmute(hdmi);1136 1137 return 0;1138}1139 1140static const char * const mtk_hdmi_clk_names[MTK_HDMI_CLK_COUNT] = {1141 [MTK_HDMI_CLK_HDMI_PIXEL] = "pixel",1142 [MTK_HDMI_CLK_HDMI_PLL] = "pll",1143 [MTK_HDMI_CLK_AUD_BCLK] = "bclk",1144 [MTK_HDMI_CLK_AUD_SPDIF] = "spdif",1145};1146 1147static int mtk_hdmi_get_all_clk(struct mtk_hdmi *hdmi,1148 struct device_node *np)1149{1150 int i;1151 1152 for (i = 0; i < ARRAY_SIZE(mtk_hdmi_clk_names); i++) {1153 hdmi->clk[i] = of_clk_get_by_name(np,1154 mtk_hdmi_clk_names[i]);1155 if (IS_ERR(hdmi->clk[i]))1156 return PTR_ERR(hdmi->clk[i]);1157 }1158 return 0;1159}1160 1161static int mtk_hdmi_clk_enable_audio(struct mtk_hdmi *hdmi)1162{1163 int ret;1164 1165 ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]);1166 if (ret)1167 return ret;1168 1169 ret = clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_AUD_SPDIF]);1170 if (ret)1171 goto err;1172 1173 return 0;1174err:1175 clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]);1176 return ret;1177}1178 1179static void mtk_hdmi_clk_disable_audio(struct mtk_hdmi *hdmi)1180{1181 clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_BCLK]);1182 clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_SPDIF]);1183}1184 1185static enum drm_connector_status1186mtk_hdmi_update_plugged_status(struct mtk_hdmi *hdmi)1187{1188 bool connected;1189 1190 mutex_lock(&hdmi->update_plugged_status_lock);1191 connected = mtk_cec_hpd_high(hdmi->cec_dev);1192 if (hdmi->plugged_cb && hdmi->codec_dev)1193 hdmi->plugged_cb(hdmi->codec_dev, connected);1194 mutex_unlock(&hdmi->update_plugged_status_lock);1195 1196 return connected ?1197 connector_status_connected : connector_status_disconnected;1198}1199 1200static enum drm_connector_status mtk_hdmi_detect(struct mtk_hdmi *hdmi)1201{1202 return mtk_hdmi_update_plugged_status(hdmi);1203}1204 1205static enum drm_mode_status1206mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge,1207 const struct drm_display_info *info,1208 const struct drm_display_mode *mode)1209{1210 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);1211 1212 dev_dbg(hdmi->dev, "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",1213 mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),1214 !!(mode->flags & DRM_MODE_FLAG_INTERLACE), mode->clock * 1000);1215 1216 if (hdmi->conf) {1217 if (hdmi->conf->cea_modes_only && !drm_match_cea_mode(mode))1218 return MODE_BAD;1219 1220 if (hdmi->conf->max_mode_clock &&1221 mode->clock > hdmi->conf->max_mode_clock)1222 return MODE_CLOCK_HIGH;1223 }1224 1225 if (mode->clock < 27000)1226 return MODE_CLOCK_LOW;1227 if (mode->clock > 297000)1228 return MODE_CLOCK_HIGH;1229 1230 return drm_mode_validate_size(mode, 0x1fff, 0x1fff);1231}1232 1233static void mtk_hdmi_hpd_event(bool hpd, struct device *dev)1234{1235 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);1236 1237 if (hdmi && hdmi->bridge.encoder && hdmi->bridge.encoder->dev) {1238 static enum drm_connector_status status;1239 1240 status = mtk_hdmi_detect(hdmi);1241 drm_helper_hpd_irq_event(hdmi->bridge.encoder->dev);1242 drm_bridge_hpd_notify(&hdmi->bridge, status);1243 }1244}1245 1246/*1247 * Bridge callbacks1248 */1249 1250static enum drm_connector_status mtk_hdmi_bridge_detect(struct drm_bridge *bridge)1251{1252 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);1253 1254 return mtk_hdmi_detect(hdmi);1255}1256 1257static const struct drm_edid *mtk_hdmi_bridge_edid_read(struct drm_bridge *bridge,1258 struct drm_connector *connector)1259{1260 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);1261 const struct drm_edid *drm_edid;1262 1263 if (!hdmi->ddc_adpt)1264 return NULL;1265 drm_edid = drm_edid_read_ddc(connector, hdmi->ddc_adpt);1266 if (drm_edid) {1267 /*1268 * FIXME: This should use !connector->display_info.has_audio (or1269 * !connector->display_info.is_hdmi) from a path that has read1270 * the EDID and called drm_edid_connector_update().1271 */1272 const struct edid *edid = drm_edid_raw(drm_edid);1273 1274 hdmi->dvi_mode = !drm_detect_monitor_audio(edid);1275 }1276 1277 return drm_edid;1278}1279 1280static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge,1281 enum drm_bridge_attach_flags flags)1282{1283 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);1284 int ret;1285 1286 if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {1287 DRM_ERROR("%s: The flag DRM_BRIDGE_ATTACH_NO_CONNECTOR must be supplied\n",1288 __func__);1289 return -EINVAL;1290 }1291 1292 if (hdmi->next_bridge) {1293 ret = drm_bridge_attach(bridge->encoder, hdmi->next_bridge,1294 bridge, flags);1295 if (ret)1296 return ret;1297 }1298 1299 mtk_cec_set_hpd_event(hdmi->cec_dev, mtk_hdmi_hpd_event, hdmi->dev);1300 1301 return 0;1302}1303 1304static bool mtk_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,1305 const struct drm_display_mode *mode,1306 struct drm_display_mode *adjusted_mode)1307{1308 return true;1309}1310 1311static void mtk_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,1312 struct drm_bridge_state *old_bridge_state)1313{1314 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);1315 1316 if (!hdmi->enabled)1317 return;1318 1319 phy_power_off(hdmi->phy);1320 clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_HDMI_PIXEL]);1321 clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]);1322 1323 hdmi->curr_conn = NULL;1324 1325 hdmi->enabled = false;1326}1327 1328static void mtk_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,1329 struct drm_bridge_state *old_state)1330{1331 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);1332 1333 if (!hdmi->powered)1334 return;1335 1336 mtk_hdmi_hw_1p4_version_enable(hdmi, true);1337 mtk_hdmi_hw_make_reg_writable(hdmi, false);1338 1339 hdmi->powered = false;1340}1341 1342static void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge,1343 const struct drm_display_mode *mode,1344 const struct drm_display_mode *adjusted_mode)1345{1346 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);1347 1348 dev_dbg(hdmi->dev, "cur info: name:%s, hdisplay:%d\n",1349 adjusted_mode->name, adjusted_mode->hdisplay);1350 dev_dbg(hdmi->dev, "hsync_start:%d,hsync_end:%d, htotal:%d",1351 adjusted_mode->hsync_start, adjusted_mode->hsync_end,1352 adjusted_mode->htotal);1353 dev_dbg(hdmi->dev, "hskew:%d, vdisplay:%d\n",1354 adjusted_mode->hskew, adjusted_mode->vdisplay);1355 dev_dbg(hdmi->dev, "vsync_start:%d, vsync_end:%d, vtotal:%d",1356 adjusted_mode->vsync_start, adjusted_mode->vsync_end,1357 adjusted_mode->vtotal);1358 dev_dbg(hdmi->dev, "vscan:%d, flag:%d\n",1359 adjusted_mode->vscan, adjusted_mode->flags);1360 1361 drm_mode_copy(&hdmi->mode, adjusted_mode);1362}1363 1364static void mtk_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge,1365 struct drm_bridge_state *old_state)1366{1367 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);1368 1369 mtk_hdmi_hw_make_reg_writable(hdmi, true);1370 mtk_hdmi_hw_1p4_version_enable(hdmi, true);1371 1372 hdmi->powered = true;1373}1374 1375static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi,1376 struct drm_display_mode *mode)1377{1378 mtk_hdmi_setup_audio_infoframe(hdmi);1379 mtk_hdmi_setup_avi_infoframe(hdmi, mode);1380 mtk_hdmi_setup_spd_infoframe(hdmi, "mediatek", "On-chip HDMI");1381 if (mode->flags & DRM_MODE_FLAG_3D_MASK)1382 mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode);1383}1384 1385static void mtk_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,1386 struct drm_bridge_state *old_state)1387{1388 struct drm_atomic_state *state = old_state->base.state;1389 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);1390 1391 /* Retrieve the connector through the atomic state. */1392 hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state,1393 bridge->encoder);1394 1395 mtk_hdmi_output_set_display_mode(hdmi, &hdmi->mode);1396 clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]);1397 clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PIXEL]);1398 phy_power_on(hdmi->phy);1399 mtk_hdmi_send_infoframe(hdmi, &hdmi->mode);1400 1401 hdmi->enabled = true;1402}1403 1404static const struct drm_bridge_funcs mtk_hdmi_bridge_funcs = {1405 .mode_valid = mtk_hdmi_bridge_mode_valid,1406 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,1407 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,1408 .atomic_reset = drm_atomic_helper_bridge_reset,1409 .attach = mtk_hdmi_bridge_attach,1410 .mode_fixup = mtk_hdmi_bridge_mode_fixup,1411 .atomic_disable = mtk_hdmi_bridge_atomic_disable,1412 .atomic_post_disable = mtk_hdmi_bridge_atomic_post_disable,1413 .mode_set = mtk_hdmi_bridge_mode_set,1414 .atomic_pre_enable = mtk_hdmi_bridge_atomic_pre_enable,1415 .atomic_enable = mtk_hdmi_bridge_atomic_enable,1416 .detect = mtk_hdmi_bridge_detect,1417 .edid_read = mtk_hdmi_bridge_edid_read,1418};1419 1420static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,1421 struct platform_device *pdev)1422{1423 struct device *dev = &pdev->dev;1424 struct device_node *np = dev->of_node;1425 struct device_node *cec_np, *remote, *i2c_np;1426 struct platform_device *cec_pdev;1427 struct regmap *regmap;1428 struct resource *mem;1429 int ret;1430 1431 ret = mtk_hdmi_get_all_clk(hdmi, np);1432 if (ret) {1433 if (ret != -EPROBE_DEFER)1434 dev_err(dev, "Failed to get clocks: %d\n", ret);1435 1436 return ret;1437 }1438 1439 /* The CEC module handles HDMI hotplug detection */1440 cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec");1441 if (!cec_np) {1442 dev_err(dev, "Failed to find CEC node\n");1443 return -EINVAL;1444 }1445 1446 cec_pdev = of_find_device_by_node(cec_np);1447 if (!cec_pdev) {1448 dev_err(hdmi->dev, "Waiting for CEC device %pOF\n",1449 cec_np);1450 of_node_put(cec_np);1451 return -EPROBE_DEFER;1452 }1453 of_node_put(cec_np);1454 hdmi->cec_dev = &cec_pdev->dev;1455 1456 /*1457 * The mediatek,syscon-hdmi property contains a phandle link to the1458 * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG1459 * registers it contains.1460 */1461 regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi");1462 ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1,1463 &hdmi->sys_offset);1464 if (IS_ERR(regmap))1465 ret = PTR_ERR(regmap);1466 if (ret) {1467 dev_err(dev,1468 "Failed to get system configuration registers: %d\n",1469 ret);1470 goto put_device;1471 }1472 hdmi->sys_regmap = regmap;1473 1474 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);1475 hdmi->regs = devm_ioremap_resource(dev, mem);1476 if (IS_ERR(hdmi->regs)) {1477 ret = PTR_ERR(hdmi->regs);1478 goto put_device;1479 }1480 1481 remote = of_graph_get_remote_node(np, 1, 0);1482 if (!remote) {1483 ret = -EINVAL;1484 goto put_device;1485 }1486 1487 if (!of_device_is_compatible(remote, "hdmi-connector")) {1488 hdmi->next_bridge = of_drm_find_bridge(remote);1489 if (!hdmi->next_bridge) {1490 dev_err(dev, "Waiting for external bridge\n");1491 of_node_put(remote);1492 ret = -EPROBE_DEFER;1493 goto put_device;1494 }1495 }1496 1497 i2c_np = of_parse_phandle(remote, "ddc-i2c-bus", 0);1498 if (!i2c_np) {1499 dev_err(dev, "Failed to find ddc-i2c-bus node in %pOF\n",1500 remote);1501 of_node_put(remote);1502 ret = -EINVAL;1503 goto put_device;1504 }1505 of_node_put(remote);1506 1507 hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);1508 of_node_put(i2c_np);1509 if (!hdmi->ddc_adpt) {1510 dev_err(dev, "Failed to get ddc i2c adapter by node\n");1511 ret = -EINVAL;1512 goto put_device;1513 }1514 1515 return 0;1516put_device:1517 put_device(hdmi->cec_dev);1518 return ret;1519}1520 1521/*1522 * HDMI audio codec callbacks1523 */1524 1525static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,1526 struct hdmi_codec_daifmt *daifmt,1527 struct hdmi_codec_params *params)1528{1529 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);1530 struct hdmi_audio_param hdmi_params;1531 unsigned int chan = params->cea.channels;1532 1533 dev_dbg(hdmi->dev, "%s: %u Hz, %d bit, %d channels\n", __func__,1534 params->sample_rate, params->sample_width, chan);1535 1536 if (!hdmi->bridge.encoder)1537 return -ENODEV;1538 1539 switch (chan) {1540 case 2:1541 hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;1542 break;1543 case 4:1544 hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0;1545 break;1546 case 6:1547 hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1;1548 break;1549 case 8:1550 hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1;1551 break;1552 default:1553 dev_err(hdmi->dev, "channel[%d] not supported!\n", chan);1554 return -EINVAL;1555 }1556 1557 switch (params->sample_rate) {1558 case 32000:1559 case 44100:1560 case 48000:1561 case 88200:1562 case 96000:1563 case 176400:1564 case 192000:1565 break;1566 default:1567 dev_err(hdmi->dev, "rate[%d] not supported!\n",1568 params->sample_rate);1569 return -EINVAL;1570 }1571 1572 switch (daifmt->fmt) {1573 case HDMI_I2S:1574 hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;1575 hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;1576 hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;1577 hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;1578 hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;1579 break;1580 case HDMI_SPDIF:1581 hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;1582 hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;1583 hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;1584 break;1585 default:1586 dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__,1587 daifmt->fmt);1588 return -EINVAL;1589 }1590 1591 memcpy(&hdmi_params.codec_params, params,1592 sizeof(hdmi_params.codec_params));1593 1594 mtk_hdmi_audio_set_param(hdmi, &hdmi_params);1595 1596 return 0;1597}1598 1599static int mtk_hdmi_audio_startup(struct device *dev, void *data)1600{1601 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);1602 1603 mtk_hdmi_audio_enable(hdmi);1604 1605 return 0;1606}1607 1608static void mtk_hdmi_audio_shutdown(struct device *dev, void *data)1609{1610 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);1611 1612 mtk_hdmi_audio_disable(hdmi);1613}1614 1615static int1616mtk_hdmi_audio_mute(struct device *dev, void *data,1617 bool enable, int direction)1618{1619 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);1620 1621 if (enable)1622 mtk_hdmi_hw_aud_mute(hdmi);1623 else1624 mtk_hdmi_hw_aud_unmute(hdmi);1625 1626 return 0;1627}1628 1629static int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size_t len)1630{1631 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);1632 1633 if (hdmi->enabled)1634 memcpy(buf, hdmi->curr_conn->eld, min(sizeof(hdmi->curr_conn->eld), len));1635 else1636 memset(buf, 0, len);1637 return 0;1638}1639 1640static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data,1641 hdmi_codec_plugged_cb fn,1642 struct device *codec_dev)1643{1644 struct mtk_hdmi *hdmi = data;1645 1646 mutex_lock(&hdmi->update_plugged_status_lock);1647 hdmi->plugged_cb = fn;1648 hdmi->codec_dev = codec_dev;1649 mutex_unlock(&hdmi->update_plugged_status_lock);1650 1651 mtk_hdmi_update_plugged_status(hdmi);1652 1653 return 0;1654}1655 1656static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = {1657 .hw_params = mtk_hdmi_audio_hw_params,1658 .audio_startup = mtk_hdmi_audio_startup,1659 .audio_shutdown = mtk_hdmi_audio_shutdown,1660 .mute_stream = mtk_hdmi_audio_mute,1661 .get_eld = mtk_hdmi_audio_get_eld,1662 .hook_plugged_cb = mtk_hdmi_audio_hook_plugged_cb,1663 .no_capture_mute = 1,1664};1665 1666static int mtk_hdmi_register_audio_driver(struct device *dev)1667{1668 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);1669 struct hdmi_codec_pdata codec_data = {1670 .ops = &mtk_hdmi_audio_codec_ops,1671 .max_i2s_channels = 2,1672 .i2s = 1,1673 .data = hdmi,1674 };1675 struct platform_device *pdev;1676 1677 pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,1678 PLATFORM_DEVID_AUTO, &codec_data,1679 sizeof(codec_data));1680 if (IS_ERR(pdev))1681 return PTR_ERR(pdev);1682 1683 DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);1684 return 0;1685}1686 1687static int mtk_hdmi_probe(struct platform_device *pdev)1688{1689 struct mtk_hdmi *hdmi;1690 struct device *dev = &pdev->dev;1691 int ret;1692 1693 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);1694 if (!hdmi)1695 return -ENOMEM;1696 1697 hdmi->dev = dev;1698 hdmi->conf = of_device_get_match_data(dev);1699 1700 ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev);1701 if (ret)1702 return ret;1703 1704 hdmi->phy = devm_phy_get(dev, "hdmi");1705 if (IS_ERR(hdmi->phy))1706 return dev_err_probe(dev, PTR_ERR(hdmi->phy),1707 "Failed to get HDMI PHY\n");1708 1709 mutex_init(&hdmi->update_plugged_status_lock);1710 platform_set_drvdata(pdev, hdmi);1711 1712 ret = mtk_hdmi_output_init(hdmi);1713 if (ret)1714 return dev_err_probe(dev, ret,1715 "Failed to initialize hdmi output\n");1716 1717 ret = mtk_hdmi_register_audio_driver(dev);1718 if (ret)1719 return dev_err_probe(dev, ret,1720 "Failed to register audio driver\n");1721 1722 hdmi->bridge.funcs = &mtk_hdmi_bridge_funcs;1723 hdmi->bridge.of_node = pdev->dev.of_node;1724 hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID1725 | DRM_BRIDGE_OP_HPD;1726 hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;1727 drm_bridge_add(&hdmi->bridge);1728 1729 ret = mtk_hdmi_clk_enable_audio(hdmi);1730 if (ret) {1731 drm_bridge_remove(&hdmi->bridge);1732 return dev_err_probe(dev, ret,1733 "Failed to enable audio clocks\n");1734 }1735 1736 return 0;1737}1738 1739static void mtk_hdmi_remove(struct platform_device *pdev)1740{1741 struct mtk_hdmi *hdmi = platform_get_drvdata(pdev);1742 1743 drm_bridge_remove(&hdmi->bridge);1744 mtk_hdmi_clk_disable_audio(hdmi);1745}1746 1747#ifdef CONFIG_PM_SLEEP1748static int mtk_hdmi_suspend(struct device *dev)1749{1750 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);1751 1752 mtk_hdmi_clk_disable_audio(hdmi);1753 1754 return 0;1755}1756 1757static int mtk_hdmi_resume(struct device *dev)1758{1759 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);1760 int ret = 0;1761 1762 ret = mtk_hdmi_clk_enable_audio(hdmi);1763 if (ret) {1764 dev_err(dev, "hdmi resume failed!\n");1765 return ret;1766 }1767 1768 return 0;1769}1770#endif1771static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops,1772 mtk_hdmi_suspend, mtk_hdmi_resume);1773 1774static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 = {1775 .tz_disabled = true,1776};1777 1778static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8167 = {1779 .max_mode_clock = 148500,1780 .cea_modes_only = true,1781};1782 1783static const struct of_device_id mtk_hdmi_of_ids[] = {1784 { .compatible = "mediatek,mt2701-hdmi",1785 .data = &mtk_hdmi_conf_mt2701,1786 },1787 { .compatible = "mediatek,mt8167-hdmi",1788 .data = &mtk_hdmi_conf_mt8167,1789 },1790 { .compatible = "mediatek,mt8173-hdmi",1791 },1792 {}1793};1794MODULE_DEVICE_TABLE(of, mtk_hdmi_of_ids);1795 1796static struct platform_driver mtk_hdmi_driver = {1797 .probe = mtk_hdmi_probe,1798 .remove_new = mtk_hdmi_remove,1799 .driver = {1800 .name = "mediatek-drm-hdmi",1801 .of_match_table = mtk_hdmi_of_ids,1802 .pm = &mtk_hdmi_pm_ops,1803 },1804};1805 1806static struct platform_driver * const mtk_hdmi_drivers[] = {1807 &mtk_hdmi_ddc_driver,1808 &mtk_cec_driver,1809 &mtk_hdmi_driver,1810};1811 1812static int __init mtk_hdmitx_init(void)1813{1814 return platform_register_drivers(mtk_hdmi_drivers,1815 ARRAY_SIZE(mtk_hdmi_drivers));1816}1817 1818static void __exit mtk_hdmitx_exit(void)1819{1820 platform_unregister_drivers(mtk_hdmi_drivers,1821 ARRAY_SIZE(mtk_hdmi_drivers));1822}1823 1824module_init(mtk_hdmitx_init);1825module_exit(mtk_hdmitx_exit);1826 1827MODULE_AUTHOR("Jie Qiu <jie.qiu@mediatek.com>");1828MODULE_DESCRIPTION("MediaTek HDMI Driver");1829MODULE_LICENSE("GPL v2");1830