1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Copyright (C) 2011 Freescale Semiconductor, Inc. 4 */ 5 6 #ifndef __DW_HDMI__ 7 #define __DW_HDMI__ 8 9 #include <drm/drm_property.h> 10 #include <drm/drm_crtc.h> 11 #include <sound/hdmi-codec.h> 12 #include <media/cec.h> 13 14 struct drm_display_info; 15 struct drm_display_mode; 16 struct drm_encoder; 17 struct dw_hdmi; 18 struct dw_hdmi_qp; 19 struct platform_device; 20 21 /** 22 * DOC: Supported input formats and encodings 23 * 24 * Depending on the Hardware configuration of the Controller IP, it supports 25 * a subset of the following input formats and encodings on its internal 26 * 48bit bus. 27 * 28 * +----------------------+----------------------------------+------------------------------+ 29 * | Format Name | Format Code | Encodings | 30 * +----------------------+----------------------------------+------------------------------+ 31 * | RGB 4:4:4 8bit | ``MEDIA_BUS_FMT_RGB888_1X24`` | ``V4L2_YCBCR_ENC_DEFAULT`` | 32 * +----------------------+----------------------------------+------------------------------+ 33 * | RGB 4:4:4 10bits | ``MEDIA_BUS_FMT_RGB101010_1X30`` | ``V4L2_YCBCR_ENC_DEFAULT`` | 34 * +----------------------+----------------------------------+------------------------------+ 35 * | RGB 4:4:4 12bits | ``MEDIA_BUS_FMT_RGB121212_1X36`` | ``V4L2_YCBCR_ENC_DEFAULT`` | 36 * +----------------------+----------------------------------+------------------------------+ 37 * | RGB 4:4:4 16bits | ``MEDIA_BUS_FMT_RGB161616_1X48`` | ``V4L2_YCBCR_ENC_DEFAULT`` | 38 * +----------------------+----------------------------------+------------------------------+ 39 * | YCbCr 4:4:4 8bit | ``MEDIA_BUS_FMT_YUV8_1X24`` | ``V4L2_YCBCR_ENC_601`` | 40 * | | | or ``V4L2_YCBCR_ENC_709`` | 41 * | | | or ``V4L2_YCBCR_ENC_XV601`` | 42 * | | | or ``V4L2_YCBCR_ENC_XV709`` | 43 * +----------------------+----------------------------------+------------------------------+ 44 * | YCbCr 4:4:4 10bits | ``MEDIA_BUS_FMT_YUV10_1X30`` | ``V4L2_YCBCR_ENC_601`` | 45 * | | | or ``V4L2_YCBCR_ENC_709`` | 46 * | | | or ``V4L2_YCBCR_ENC_XV601`` | 47 * | | | or ``V4L2_YCBCR_ENC_XV709`` | 48 * +----------------------+----------------------------------+------------------------------+ 49 * | YCbCr 4:4:4 12bits | ``MEDIA_BUS_FMT_YUV12_1X36`` | ``V4L2_YCBCR_ENC_601`` | 50 * | | | or ``V4L2_YCBCR_ENC_709`` | 51 * | | | or ``V4L2_YCBCR_ENC_XV601`` | 52 * | | | or ``V4L2_YCBCR_ENC_XV709`` | 53 * +----------------------+----------------------------------+------------------------------+ 54 * | YCbCr 4:4:4 16bits | ``MEDIA_BUS_FMT_YUV16_1X48`` | ``V4L2_YCBCR_ENC_601`` | 55 * | | | or ``V4L2_YCBCR_ENC_709`` | 56 * | | | or ``V4L2_YCBCR_ENC_XV601`` | 57 * | | | or ``V4L2_YCBCR_ENC_XV709`` | 58 * +----------------------+----------------------------------+------------------------------+ 59 * | YCbCr 4:2:2 8bit | ``MEDIA_BUS_FMT_UYVY8_1X16`` | ``V4L2_YCBCR_ENC_601`` | 60 * | | | or ``V4L2_YCBCR_ENC_709`` | 61 * +----------------------+----------------------------------+------------------------------+ 62 * | YCbCr 4:2:2 10bits | ``MEDIA_BUS_FMT_UYVY10_1X20`` | ``V4L2_YCBCR_ENC_601`` | 63 * | | | or ``V4L2_YCBCR_ENC_709`` | 64 * +----------------------+----------------------------------+------------------------------+ 65 * | YCbCr 4:2:2 12bits | ``MEDIA_BUS_FMT_UYVY12_1X24`` | ``V4L2_YCBCR_ENC_601`` | 66 * | | | or ``V4L2_YCBCR_ENC_709`` | 67 * +----------------------+----------------------------------+------------------------------+ 68 * | YCbCr 4:2:0 8bit | ``MEDIA_BUS_FMT_UYYVYY8_0_5X24`` | ``V4L2_YCBCR_ENC_601`` | 69 * | | | or ``V4L2_YCBCR_ENC_709`` | 70 * +----------------------+----------------------------------+------------------------------+ 71 * | YCbCr 4:2:0 10bits | ``MEDIA_BUS_FMT_UYYVYY10_0_5X30``| ``V4L2_YCBCR_ENC_601`` | 72 * | | | or ``V4L2_YCBCR_ENC_709`` | 73 * +----------------------+----------------------------------+------------------------------+ 74 * | YCbCr 4:2:0 12bits | ``MEDIA_BUS_FMT_UYYVYY12_0_5X36``| ``V4L2_YCBCR_ENC_601`` | 75 * | | | or ``V4L2_YCBCR_ENC_709`` | 76 * +----------------------+----------------------------------+------------------------------+ 77 * | YCbCr 4:2:0 16bits | ``MEDIA_BUS_FMT_UYYVYY16_0_5X48``| ``V4L2_YCBCR_ENC_601`` | 78 * | | | or ``V4L2_YCBCR_ENC_709`` | 79 * +----------------------+----------------------------------+------------------------------+ 80 */ 81 82 #define SUPPORT_HDMI_ALLM BIT(1) 83 84 enum { 85 DW_HDMI_RES_8, 86 DW_HDMI_RES_10, 87 DW_HDMI_RES_12, 88 DW_HDMI_RES_MAX, 89 }; 90 91 enum dw_hdmi_phy_type { 92 DW_HDMI_PHY_DWC_HDMI_TX_PHY = 0x00, 93 DW_HDMI_PHY_DWC_MHL_PHY_HEAC = 0xb2, 94 DW_HDMI_PHY_DWC_MHL_PHY = 0xc2, 95 DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC = 0xe2, 96 DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY = 0xf2, 97 DW_HDMI_PHY_DWC_HDMI20_TX_PHY = 0xf3, 98 DW_HDMI_PHY_VENDOR_PHY = 0xfe, 99 }; 100 101 struct dw_hdmi_audio_frl_n { 102 unsigned int r_bit; 103 unsigned int n_32k; 104 unsigned int n_44k1; 105 unsigned int n_48k; 106 }; 107 108 struct dw_hdmi_audio_tmds_n { 109 unsigned long tmds; 110 unsigned int n_32k; 111 unsigned int n_44k1; 112 unsigned int n_48k; 113 }; 114 115 struct dw_hdmi_mpll_config { 116 unsigned long mpixelclock; 117 struct { 118 u16 cpce; 119 u16 gmp; 120 } res[DW_HDMI_RES_MAX]; 121 }; 122 123 struct dw_hdmi_curr_ctrl { 124 unsigned long mpixelclock; 125 u16 curr[DW_HDMI_RES_MAX]; 126 }; 127 128 struct dw_hdmi_phy_config { 129 unsigned long mpixelclock; 130 u16 sym_ctr; /*clock symbol and transmitter control*/ 131 u16 term; /*transmission termination value*/ 132 u16 vlev_ctr; /* voltage level control */ 133 }; 134 135 struct dw_hdmi_link_config { 136 bool dsc_mode; 137 bool frl_mode; 138 int frl_lanes; 139 int rate_per_lane; 140 int hcactive; 141 u8 add_func; 142 u8 pps_payload[128]; 143 }; 144 145 struct dw_hdmi_phy_ops { 146 int (*init)(struct dw_hdmi *hdmi, void *data, 147 const struct drm_display_info *display, 148 const struct drm_display_mode *mode); 149 void (*disable)(struct dw_hdmi *hdmi, void *data); 150 enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data); 151 void (*update_hpd)(struct dw_hdmi *hdmi, void *data, 152 bool force, bool disabled, bool rxsense); 153 void (*setup_hpd)(struct dw_hdmi *hdmi, void *data); 154 }; 155 156 struct dw_hdmi_qp_phy_ops { 157 int (*init)(struct dw_hdmi_qp *hdmi, void *data, 158 struct drm_display_mode *mode); 159 void (*disable)(struct dw_hdmi_qp *hdmi, void *data); 160 enum drm_connector_status (*read_hpd)(struct dw_hdmi_qp *hdmi, 161 void *data); 162 void (*update_hpd)(struct dw_hdmi_qp *hdmi, void *data, 163 bool force, bool disabled, bool rxsense); 164 void (*setup_hpd)(struct dw_hdmi_qp *hdmi, void *data); 165 void (*set_mode)(struct dw_hdmi_qp *dw_hdmi, void *data, 166 u32 mode_mask, bool enable); 167 }; 168 169 struct dw_hdmi_property_ops { 170 void (*attach_properties)(struct drm_connector *connector, 171 unsigned int color, int version, 172 void *data, bool allm_en); 173 void (*destroy_properties)(struct drm_connector *connector, 174 void *data); 175 int (*set_property)(struct drm_connector *connector, 176 struct drm_connector_state *state, 177 struct drm_property *property, 178 u64 val, 179 void *data); 180 int (*get_property)(struct drm_connector *connector, 181 const struct drm_connector_state *state, 182 struct drm_property *property, 183 u64 *val, 184 void *data); 185 }; 186 187 struct dw_hdmi_plat_data { 188 struct regmap *regm; 189 190 unsigned long input_bus_format; 191 unsigned long input_bus_encoding; 192 unsigned int max_tmdsclk; 193 int id; 194 bool use_drm_infoframe; 195 bool ycbcr_420_allowed; 196 bool unsupported_yuv_input; 197 bool unsupported_deep_color; 198 bool is_hdmi_qp; 199 200 /* 201 * Private data passed to all the .mode_valid() and .configure_phy() 202 * callback functions. 203 */ 204 void *priv_data; 205 206 /* Platform-specific mode validation (optional). */ 207 enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data, 208 const struct drm_display_info *info, 209 const struct drm_display_mode *mode); 210 211 /* Vendor PHY support */ 212 const struct dw_hdmi_phy_ops *phy_ops; 213 const struct dw_hdmi_qp_phy_ops *qp_phy_ops; 214 const char *phy_name; 215 void *phy_data; 216 unsigned int phy_force_vendor; 217 const struct dw_hdmi_audio_tmds_n *tmds_n_table; 218 219 /* split mode */ 220 bool split_mode; 221 bool first_screen; 222 struct dw_hdmi_qp *left; 223 struct dw_hdmi_qp *right; 224 225 /* Synopsys PHY support */ 226 const struct dw_hdmi_mpll_config *mpll_cfg; 227 const struct dw_hdmi_mpll_config *mpll_cfg_420; 228 const struct dw_hdmi_curr_ctrl *cur_ctr; 229 const struct dw_hdmi_phy_config *phy_config; 230 int (*configure_phy)(struct dw_hdmi *hdmi, void *data, 231 unsigned long mpixelclock); 232 233 unsigned long (*get_input_bus_format)(void *data); 234 unsigned long (*get_output_bus_format)(void *data); 235 unsigned long (*get_enc_in_encoding)(void *data); 236 unsigned long (*get_enc_out_encoding)(void *data); 237 unsigned long (*get_quant_range)(void *data); 238 struct drm_property *(*get_hdr_property)(void *data); 239 struct drm_property_blob *(*get_hdr_blob)(void *data); 240 bool (*get_color_changed)(void *data); 241 int (*get_yuv422_format)(struct drm_connector *connector, 242 struct edid *edid); 243 int (*get_edid_dsc_info)(void *data, struct edid *edid); 244 int (*get_next_hdr_data)(void *data, struct edid *edid, 245 struct drm_connector *connector); 246 struct dw_hdmi_link_config *(*get_link_cfg)(void *data); 247 void (*set_grf_cfg)(void *data); 248 u64 (*get_grf_color_fmt)(void *data); 249 void (*convert_to_split_mode)(struct drm_display_mode *mode); 250 void (*convert_to_origin_mode)(struct drm_display_mode *mode); 251 int (*dclk_set)(void *data, bool enable, int vp_id); 252 int (*link_clk_set)(void *data, bool enable); 253 int (*get_vp_id)(struct drm_crtc_state *crtc_state); 254 void (*update_color_format)(struct drm_connector_state *conn_state, void *data); 255 bool (*check_hdr_color_change)(struct drm_connector_state *conn_state, void *data); 256 void (*set_prev_bus_format)(void *data, unsigned long bus_format); 257 int (*get_colorimetry)(void *data, struct edid *edid); 258 void (*set_ddc_io)(void *data, bool enable); 259 260 /* Vendor Property support */ 261 const struct dw_hdmi_property_ops *property_ops; 262 struct drm_connector *connector; 263 }; 264 265 struct dw_hdmi_cec_wake_ops { 266 void (*hpd_wake_up)(struct platform_device *pdev); 267 }; 268 269 struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, 270 const struct dw_hdmi_plat_data *plat_data); 271 void dw_hdmi_remove(struct dw_hdmi *hdmi); 272 void dw_hdmi_unbind(struct dw_hdmi *hdmi); 273 struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev, 274 struct drm_encoder *encoder, 275 struct dw_hdmi_plat_data *plat_data); 276 277 void dw_hdmi_suspend(struct dw_hdmi *hdmi); 278 void dw_hdmi_resume(struct dw_hdmi *hdmi); 279 280 void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense); 281 282 int dw_hdmi_set_plugged_cb(struct dw_hdmi *hdmi, hdmi_codec_plugged_cb fn, 283 struct device *codec_dev); 284 void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate); 285 void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt); 286 void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8 *channel_status); 287 void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int ca); 288 void dw_hdmi_audio_enable(struct dw_hdmi *hdmi); 289 void dw_hdmi_audio_disable(struct dw_hdmi *hdmi); 290 void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi, 291 const struct drm_display_info *display); 292 293 /* PHY configuration */ 294 void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address); 295 void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, 296 unsigned char addr); 297 298 void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable); 299 void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable); 300 void dw_hdmi_phy_reset(struct dw_hdmi *hdmi); 301 302 enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, 303 void *data); 304 void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, 305 bool force, bool disabled, bool rxsense); 306 void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data); 307 void dw_hdmi_set_quant_range(struct dw_hdmi *hdmi); 308 void dw_hdmi_set_output_type(struct dw_hdmi *hdmi, u64 val); 309 bool dw_hdmi_get_output_whether_hdmi(struct dw_hdmi *hdmi); 310 int dw_hdmi_get_output_type_cap(struct dw_hdmi *hdmi); 311 void dw_hdmi_set_cec_adap(struct dw_hdmi *hdmi, struct cec_adapter *adap); 312 void dw_hdmi_qp_set_allm_enable(struct dw_hdmi_qp *hdmi_qp, bool enable); 313 314 void dw_hdmi_qp_unbind(struct dw_hdmi_qp *hdmi); 315 struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, 316 struct drm_encoder *encoder, 317 struct dw_hdmi_plat_data *plat_data); 318 void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi); 319 void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi); 320 void dw_hdmi_qp_cec_set_hpd(struct dw_hdmi_qp *hdmi, bool plug_in, bool change); 321 void dw_hdmi_qp_set_cec_adap(struct dw_hdmi_qp *hdmi, struct cec_adapter *adap); 322 int dw_hdmi_qp_set_earc(struct dw_hdmi_qp *hdmi); 323 void dw_hdmi_qp_set_sample_rate(struct dw_hdmi_qp *hdmi, unsigned int rate); 324 void dw_hdmi_qp_set_channel_count(struct dw_hdmi_qp *hdmi, unsigned int cnt); 325 void dw_hdmi_qp_set_channel_status(struct dw_hdmi_qp *hdmi, u8 *channel_status, 326 bool ref2stream); 327 void dw_hdmi_qp_set_channel_allocation(struct dw_hdmi_qp *hdmi, unsigned int ca); 328 void dw_hdmi_qp_set_audio_interface(struct dw_hdmi_qp *hdmi, 329 struct hdmi_codec_daifmt *fmt, 330 struct hdmi_codec_params *hparms); 331 void dw_hdmi_qp_set_audio_infoframe(struct dw_hdmi_qp *hdmi, 332 struct hdmi_codec_params *hparms); 333 void dw_hdmi_qp_audio_enable(struct dw_hdmi_qp *hdmi); 334 void dw_hdmi_qp_audio_disable(struct dw_hdmi_qp *hdmi); 335 int dw_hdmi_qp_set_plugged_cb(struct dw_hdmi_qp *hdmi, hdmi_codec_plugged_cb fn, 336 struct device *codec_dev); 337 void dw_hdmi_qp_set_output_type(struct dw_hdmi_qp *hdmi, u64 val); 338 bool dw_hdmi_qp_get_output_whether_hdmi(struct dw_hdmi_qp *hdmi); 339 int dw_hdmi_qp_get_output_type_cap(struct dw_hdmi_qp *hdmi); 340 void dw_hdmi_set_hpd_wake(struct dw_hdmi *hdmi); 341 void dw_hdmi_cec_wake_ops_register(struct dw_hdmi *hdmi, 342 const struct dw_hdmi_cec_wake_ops *cec_ops); 343 344 #endif /* __IMX_HDMI_H__ */ 345