| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2011 Freescale Semiconductor, Inc. |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 5 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 6 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 7 | | - * (at your option) any later version. |
|---|
| 8 | 4 | */ |
|---|
| 9 | 5 | |
|---|
| 10 | 6 | #ifndef __DW_HDMI__ |
|---|
| 11 | 7 | #define __DW_HDMI__ |
|---|
| 12 | 8 | |
|---|
| 13 | | -#include <drm/drmP.h> |
|---|
| 9 | +#include <drm/drm_property.h> |
|---|
| 10 | +#include <drm/drm_crtc.h> |
|---|
| 14 | 11 | #include <sound/hdmi-codec.h> |
|---|
| 12 | +#include <media/cec.h> |
|---|
| 15 | 13 | |
|---|
| 14 | +struct drm_display_info; |
|---|
| 15 | +struct drm_display_mode; |
|---|
| 16 | +struct drm_encoder; |
|---|
| 16 | 17 | struct dw_hdmi; |
|---|
| 18 | +struct dw_hdmi_qp; |
|---|
| 19 | +struct platform_device; |
|---|
| 17 | 20 | |
|---|
| 18 | 21 | /** |
|---|
| 19 | 22 | * DOC: Supported input formats and encodings |
|---|
| .. | .. |
|---|
| 76 | 79 | * +----------------------+----------------------------------+------------------------------+ |
|---|
| 77 | 80 | */ |
|---|
| 78 | 81 | |
|---|
| 82 | +#define SUPPORT_HDMI_ALLM BIT(1) |
|---|
| 83 | + |
|---|
| 79 | 84 | enum { |
|---|
| 80 | 85 | DW_HDMI_RES_8, |
|---|
| 81 | 86 | DW_HDMI_RES_10, |
|---|
| .. | .. |
|---|
| 91 | 96 | DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY = 0xf2, |
|---|
| 92 | 97 | DW_HDMI_PHY_DWC_HDMI20_TX_PHY = 0xf3, |
|---|
| 93 | 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; |
|---|
| 94 | 106 | }; |
|---|
| 95 | 107 | |
|---|
| 96 | 108 | struct dw_hdmi_audio_tmds_n { |
|---|
| .. | .. |
|---|
| 120 | 132 | u16 vlev_ctr; /* voltage level control */ |
|---|
| 121 | 133 | }; |
|---|
| 122 | 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 | + |
|---|
| 123 | 145 | struct dw_hdmi_phy_ops { |
|---|
| 124 | 146 | int (*init)(struct dw_hdmi *hdmi, void *data, |
|---|
| 125 | | - struct drm_display_mode *mode); |
|---|
| 147 | + const struct drm_display_info *display, |
|---|
| 148 | + const struct drm_display_mode *mode); |
|---|
| 126 | 149 | void (*disable)(struct dw_hdmi *hdmi, void *data); |
|---|
| 127 | 150 | enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data); |
|---|
| 128 | 151 | void (*update_hpd)(struct dw_hdmi *hdmi, void *data, |
|---|
| .. | .. |
|---|
| 130 | 153 | void (*setup_hpd)(struct dw_hdmi *hdmi, void *data); |
|---|
| 131 | 154 | }; |
|---|
| 132 | 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 | + |
|---|
| 133 | 169 | struct dw_hdmi_property_ops { |
|---|
| 134 | 170 | void (*attach_properties)(struct drm_connector *connector, |
|---|
| 135 | 171 | unsigned int color, int version, |
|---|
| 136 | | - void *data); |
|---|
| 172 | + void *data, bool allm_en); |
|---|
| 137 | 173 | void (*destroy_properties)(struct drm_connector *connector, |
|---|
| 138 | 174 | void *data); |
|---|
| 139 | 175 | int (*set_property)(struct drm_connector *connector, |
|---|
| .. | .. |
|---|
| 150 | 186 | |
|---|
| 151 | 187 | struct dw_hdmi_plat_data { |
|---|
| 152 | 188 | struct regmap *regm; |
|---|
| 153 | | - enum drm_mode_status (*mode_valid)(struct drm_connector *connector, |
|---|
| 154 | | - const struct drm_display_mode *mode); |
|---|
| 189 | + |
|---|
| 155 | 190 | unsigned long input_bus_format; |
|---|
| 156 | 191 | unsigned long input_bus_encoding; |
|---|
| 192 | + unsigned int max_tmdsclk; |
|---|
| 193 | + int id; |
|---|
| 194 | + bool use_drm_infoframe; |
|---|
| 157 | 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); |
|---|
| 158 | 210 | |
|---|
| 159 | 211 | /* Vendor PHY support */ |
|---|
| 160 | 212 | const struct dw_hdmi_phy_ops *phy_ops; |
|---|
| 213 | + const struct dw_hdmi_qp_phy_ops *qp_phy_ops; |
|---|
| 161 | 214 | const char *phy_name; |
|---|
| 162 | 215 | void *phy_data; |
|---|
| 163 | 216 | unsigned int phy_force_vendor; |
|---|
| 164 | | - const struct dw_hdmi_audio_tmds_n *tmds_n_table; |
|---|
| 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; |
|---|
| 165 | 224 | |
|---|
| 166 | 225 | /* Synopsys PHY support */ |
|---|
| 167 | 226 | const struct dw_hdmi_mpll_config *mpll_cfg; |
|---|
| 168 | 227 | const struct dw_hdmi_mpll_config *mpll_cfg_420; |
|---|
| 169 | 228 | const struct dw_hdmi_curr_ctrl *cur_ctr; |
|---|
| 170 | 229 | const struct dw_hdmi_phy_config *phy_config; |
|---|
| 171 | | - int (*configure_phy)(struct dw_hdmi *hdmi, |
|---|
| 172 | | - const struct dw_hdmi_plat_data *pdata, |
|---|
| 230 | + int (*configure_phy)(struct dw_hdmi *hdmi, void *data, |
|---|
| 173 | 231 | unsigned long mpixelclock); |
|---|
| 174 | 232 | |
|---|
| 175 | 233 | unsigned long (*get_input_bus_format)(void *data); |
|---|
| .. | .. |
|---|
| 180 | 238 | struct drm_property *(*get_hdr_property)(void *data); |
|---|
| 181 | 239 | struct drm_property_blob *(*get_hdr_blob)(void *data); |
|---|
| 182 | 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_hdcp_status)(void *data, u8 status); |
|---|
| 248 | + void (*set_hdcp2_enable)(void *data, bool enable); |
|---|
| 249 | + void (*set_grf_cfg)(void *data); |
|---|
| 250 | + u64 (*get_grf_color_fmt)(void *data); |
|---|
| 251 | + void (*convert_to_split_mode)(struct drm_display_mode *mode); |
|---|
| 252 | + void (*convert_to_origin_mode)(struct drm_display_mode *mode); |
|---|
| 253 | + int (*dclk_set)(void *data, bool enable, int vp_id); |
|---|
| 254 | + int (*link_clk_set)(void *data, bool enable); |
|---|
| 255 | + int (*get_vp_id)(struct drm_crtc_state *crtc_state); |
|---|
| 183 | 256 | void (*update_color_format)(struct drm_connector_state *conn_state, void *data); |
|---|
| 184 | 257 | bool (*check_hdr_color_change)(struct drm_connector_state *conn_state, void *data); |
|---|
| 185 | 258 | void (*set_prev_bus_format)(void *data, unsigned long bus_format); |
|---|
| 259 | + int (*get_colorimetry)(void *data, struct edid *edid); |
|---|
| 186 | 260 | void (*set_ddc_io)(void *data, bool enable); |
|---|
| 187 | | - int (*dclk_set)(void *data, bool enable, int vp_id); |
|---|
| 261 | + void (*set_hdcp14_mem)(void *data, bool enable); |
|---|
| 188 | 262 | |
|---|
| 189 | 263 | /* Vendor Property support */ |
|---|
| 190 | 264 | const struct dw_hdmi_property_ops *property_ops; |
|---|
| 191 | 265 | struct drm_connector *connector; |
|---|
| 266 | + struct drm_bridge *bridge; |
|---|
| 267 | +}; |
|---|
| 268 | + |
|---|
| 269 | +struct dw_hdmi_cec_wake_ops { |
|---|
| 270 | + void (*hpd_wake_up)(struct platform_device *pdev); |
|---|
| 192 | 271 | }; |
|---|
| 193 | 272 | |
|---|
| 194 | 273 | struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, |
|---|
| .. | .. |
|---|
| 198 | 277 | struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev, |
|---|
| 199 | 278 | struct drm_encoder *encoder, |
|---|
| 200 | 279 | struct dw_hdmi_plat_data *plat_data); |
|---|
| 201 | | -void dw_hdmi_suspend(struct device *dev, struct dw_hdmi *hdmi); |
|---|
| 202 | | -void dw_hdmi_resume(struct device *dev, struct dw_hdmi *hdmi); |
|---|
| 280 | + |
|---|
| 281 | +void dw_hdmi_suspend(struct dw_hdmi *hdmi); |
|---|
| 282 | +void dw_hdmi_resume(struct dw_hdmi *hdmi); |
|---|
| 203 | 283 | |
|---|
| 204 | 284 | void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense); |
|---|
| 205 | 285 | |
|---|
| 206 | 286 | int dw_hdmi_set_plugged_cb(struct dw_hdmi *hdmi, hdmi_codec_plugged_cb fn, |
|---|
| 207 | 287 | struct device *codec_dev); |
|---|
| 208 | 288 | void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate); |
|---|
| 289 | +void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt); |
|---|
| 290 | +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8 *channel_status); |
|---|
| 291 | +void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int ca); |
|---|
| 209 | 292 | void dw_hdmi_audio_enable(struct dw_hdmi *hdmi); |
|---|
| 210 | 293 | void dw_hdmi_audio_disable(struct dw_hdmi *hdmi); |
|---|
| 211 | | -void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi); |
|---|
| 294 | +void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi, |
|---|
| 295 | + const struct drm_display_info *display); |
|---|
| 212 | 296 | |
|---|
| 213 | 297 | /* PHY configuration */ |
|---|
| 214 | 298 | void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address); |
|---|
| .. | .. |
|---|
| 228 | 312 | void dw_hdmi_set_output_type(struct dw_hdmi *hdmi, u64 val); |
|---|
| 229 | 313 | bool dw_hdmi_get_output_whether_hdmi(struct dw_hdmi *hdmi); |
|---|
| 230 | 314 | int dw_hdmi_get_output_type_cap(struct dw_hdmi *hdmi); |
|---|
| 315 | +void dw_hdmi_set_cec_adap(struct dw_hdmi *hdmi, struct cec_adapter *adap); |
|---|
| 316 | +void dw_hdmi_qp_set_allm_enable(struct dw_hdmi_qp *hdmi_qp, bool enable); |
|---|
| 317 | + |
|---|
| 318 | +void dw_hdmi_qp_unbind(struct dw_hdmi_qp *hdmi); |
|---|
| 319 | +struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, |
|---|
| 320 | + struct drm_encoder *encoder, |
|---|
| 321 | + struct dw_hdmi_plat_data *plat_data); |
|---|
| 322 | +void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi); |
|---|
| 323 | +void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi); |
|---|
| 324 | +void dw_hdmi_qp_cec_set_hpd(struct dw_hdmi_qp *hdmi, bool plug_in, bool change); |
|---|
| 325 | +void dw_hdmi_qp_set_cec_adap(struct dw_hdmi_qp *hdmi, struct cec_adapter *adap); |
|---|
| 326 | +int dw_hdmi_qp_set_earc(struct dw_hdmi_qp *hdmi); |
|---|
| 327 | +void dw_hdmi_qp_set_sample_rate(struct dw_hdmi_qp *hdmi, unsigned int rate); |
|---|
| 328 | +void dw_hdmi_qp_set_channel_count(struct dw_hdmi_qp *hdmi, unsigned int cnt); |
|---|
| 329 | +void dw_hdmi_qp_set_channel_status(struct dw_hdmi_qp *hdmi, u8 *channel_status, |
|---|
| 330 | + bool ref2stream); |
|---|
| 331 | +void dw_hdmi_qp_set_channel_allocation(struct dw_hdmi_qp *hdmi, unsigned int ca); |
|---|
| 332 | +void dw_hdmi_qp_set_audio_interface(struct dw_hdmi_qp *hdmi, |
|---|
| 333 | + struct hdmi_codec_daifmt *fmt, |
|---|
| 334 | + struct hdmi_codec_params *hparms); |
|---|
| 335 | +void dw_hdmi_qp_set_audio_infoframe(struct dw_hdmi_qp *hdmi, |
|---|
| 336 | + struct hdmi_codec_params *hparms); |
|---|
| 337 | +void dw_hdmi_qp_audio_enable(struct dw_hdmi_qp *hdmi); |
|---|
| 338 | +void dw_hdmi_qp_audio_disable(struct dw_hdmi_qp *hdmi); |
|---|
| 339 | +int dw_hdmi_qp_set_plugged_cb(struct dw_hdmi_qp *hdmi, hdmi_codec_plugged_cb fn, |
|---|
| 340 | + struct device *codec_dev); |
|---|
| 341 | +void dw_hdmi_qp_set_output_type(struct dw_hdmi_qp *hdmi, u64 val); |
|---|
| 342 | +bool dw_hdmi_qp_get_output_whether_hdmi(struct dw_hdmi_qp *hdmi); |
|---|
| 343 | +int dw_hdmi_qp_get_output_type_cap(struct dw_hdmi_qp *hdmi); |
|---|
| 231 | 344 | void dw_hdmi_set_hpd_wake(struct dw_hdmi *hdmi); |
|---|
| 345 | +void dw_hdmi_cec_wake_ops_register(struct dw_hdmi *hdmi, |
|---|
| 346 | + const struct dw_hdmi_cec_wake_ops *cec_ops); |
|---|
| 232 | 347 | |
|---|
| 233 | 348 | #endif /* __IMX_HDMI_H__ */ |
|---|