1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
/*
* edid.h: tegra edid function declarations.
*
* Copyright (C) 2010 Google, Inc.
* Author: Erik Gilling <konkers@android.com>
*
* Copyright (c) 2011-2019, NVIDIA CORPORATION. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __DRIVERS_VIDEO_TEGRA_DC_EDID_H
#define __DRIVERS_VIDEO_TEGRA_DC_EDID_H
#include "edid_disp_id_ext.h"
#include <linux/i2c.h>
#include <linux/wait.h>
#include "dc.h"
#include <uapi/video/tegra_dc_ext.h>
#define TEGRA_DC_Y420_30 1 /* YCbCr 4:2:0 deep color 30bpp */
#define TEGRA_DC_Y420_36 2 /* YCbCr 4:2:0 deep color 36bpp */
#define TEGRA_DC_Y420_48 4 /* YCbCr 4:2:0 deep color 48bpp */
#define TEGRA_DC_Y420_MASK (TEGRA_DC_Y420_30 | \
TEGRA_DC_Y420_36 | TEGRA_DC_Y420_48)
#define TEGRA_DC_Y422_30 8 /* YCbCr 4:2:2 deep color 30bpp */
#define TEGRA_DC_Y422_36 16 /* YCbCr 4:2:2 deep color 36bpp */
#define TEGRA_DC_Y422_48 32 /* YCbCr 4:2:2 deep color 48bpp */
#define TEGRA_DC_Y422_MASK (TEGRA_DC_Y422_30 | \
TEGRA_DC_Y422_36 | TEGRA_DC_Y422_48)
#define TEGRA_DC_Y444_30 64 /* YCbCr 4:4:4 deep color 30bpp */
#define TEGRA_DC_Y444_36 128 /* YCbCr 4:4:4 deep color 36bpp */
#define TEGRA_DC_Y444_48 256 /* YCbCr 4:4:4 deep color 48bpp */
#define TEGRA_DC_Y444_MASK (TEGRA_DC_Y444_30 | \
TEGRA_DC_Y444_36 | TEGRA_DC_Y444_48)
#define TEGRA_DC_RGB_30 512 /* RGB 4:4:4 deep color 30bpp */
#define TEGRA_DC_RGB_36 1024 /* RGB 4:4:4 deep color 36bpp */
#define TEGRA_DC_RGB_48 2048 /* RGB 4:4:4 deep color 48bpp */
#define TEGRA_DC_RGB_MASK (TEGRA_DC_RGB_30 | \
TEGRA_DC_RGB_36 | TEGRA_DC_RGB_48)
#define TEGRA_DC_MASK (TEGRA_DC_Y420_MASK | \
TEGRA_DC_Y422_MASK | TEGRA_DC_Y444_MASK | \
TEGRA_DC_RGB_MASK)
#define TEGRA_EDID_MAX_RETRY 5
#define TEGRA_EDID_MIN_RETRY_DELAY_US 200
#define TEGRA_EDID_MAX_RETRY_DELAY_US (TEGRA_EDID_MIN_RETRY_DELAY_US + 200)
enum {
CEA_DATA_BLOCK_RSVD0,
CEA_DATA_BLOCK_AUDIO,
CEA_DATA_BLOCK_VIDEO,
CEA_DATA_BLOCK_VENDOR,
CEA_DATA_BLOCK_SPEAKER_ALLOC,
CEA_DATA_BLOCK_VESA_DISP_TRANS_CHAR,
CEA_DATA_BLOCK_RSVD1,
CEA_DATA_BLOCK_EXT,
CEA_DATA_BLOCK_MAX_CNT,
};
enum {
/* video blocks */
CEA_DATA_BLOCK_EXT_VCDB = 0, /* video capability data block */
CEA_DATA_BLOCK_EXT_VSVDB = 1, /* vendor specific video data block */
CEA_DATA_BLOCK_EXT_VESA_DDDB = 2, /* VESA display device data block */
CEA_DATA_BLOCK_EXT_VESA_VTBE = 3, /* VESA video timing block ext */
CEA_DATA_BLOCK_EXT_HDMI_VDB = 4, /* rsvd for HDMI video data block */
CEA_DATA_BLOCK_EXT_CDB = 5, /* colorimetry data block */
CEA_DATA_BLOCK_EXT_HDR = 6, /* HDR data block */
/* 7-12 rsvd for other video related blocks */
CEA_DATA_BLOCK_EXT_VFPDB = 13, /* video format preference data block */
CEA_DATA_BLOCK_EXT_Y420VDB = 14, /* YCbCr 4:2:0 video data block */
CEA_DATA_BLOCK_EXT_Y420CMDB = 15, /* YCbCr 4:2:0 cap map data block */
/* audio blocks */
CEA_DATA_BLOCK_EXT_CEA_MAF = 16, /* rsvd CEA misc audio fields */
CEA_DATA_BLOCK_EXT_VSADB = 17, /* vendor specific audio data block */
CEA_DATA_BLOCK_EXT_HDMI_ADB = 18, /* rsvd HDMI audio data block */
/* 19-31 rsvd for other audio related blocks */
CEA_DATA_BLOCK_EXT_IDB = 32, /* infoframe data block */
/* 33-255 rsvd */
};
#define ELD_MAX_MNL 16
#define ELD_MAX_SAD 16
#define ELD_MAX_SAD_BYTES (ELD_MAX_SAD * 3)
struct tegra_edid_pvt;
#define EDID_BYTES_PER_BLOCK 128
#define EDID_BASE_HEADER_SIZE 8
static const unsigned char edid_base_header[EDID_BASE_HEADER_SIZE] = {
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
};
typedef int (*i2c_transfer_func_t)(struct tegra_dc *dc, struct i2c_msg *msgs,
int num);
struct tegra_dc_i2c_ops {
i2c_transfer_func_t i2c_transfer;
};
enum {
EDID_SRC_PANEL,
EDID_SRC_DT,
};
/* Flag panel edid checksum is corrupted.
* SW fixes checksum before passing on the
* edid block to parser. For now just represent checksum
* corruption on any of the edid blocks.
*/
#define EDID_ERRORS_CHECKSUM_CORRUPTED 0x01
/* Flag edid read failed after all retries. */
#define EDID_ERRORS_READ_FAILED 0x02
/* Flag fallback edid is in use. */
#define EDID_ERRORS_USING_FALLBACK 0x04
#define TEGRA_EDID_QUIRK_NONE (0)
/* TV doesn't support YUV420, but declares support */
#define TEGRA_EDID_QUIRK_NO_YUV (1 << 0)
/* TV needs us to delay HDCP by a few seconds */
#define TEGRA_EDID_QUIRK_DELAY_HDCP (1 << 1)
/* TVs that blank screen if we try to do HDCP at all */
#define TEGRA_EDID_QUIRK_NO_HDCP (1 << 2)
/* Denon 2313 doesn't support YUV422, but declares support for it */
#define TEGRA_EDID_QUIRK_NO_YUV_422 (1 << 3)
/* TVs that send HPD bounce upto 4 seconds */
#define TEGRA_EDID_QUIRK_HPD_BOUNCE (1 << 4)
/* TVs supports only CEA modes */
#define TEGRA_EDID_QUIRK_ONLY_CEA (1 << 5)
struct tegra_edid {
struct tegra_edid_pvt *data;
struct mutex lock;
struct tegra_dc_i2c_ops i2c_ops;
struct tegra_dc *dc;
/* Bitmap to flag EDID reading / parsing error conditions. */
u8 errors;
};
/*
* ELD: EDID Like Data
*/
struct tegra_edid_hdmi_eld {
u8 baseline_len;
u8 eld_ver;
u8 cea_edid_ver;
char monitor_name[ELD_MAX_MNL + 1];
u8 mnl;
u8 manufacture_id[2];
u8 product_id[2];
u8 port_id[8];
u8 support_hdcp;
u8 support_ai;
u8 conn_type;
u8 aud_synch_delay;
u8 spk_alloc;
u8 sad_count;
u8 sad[ELD_MAX_SAD_BYTES];
};
struct tegra_edid *tegra_edid_create(struct tegra_dc *dc,
i2c_transfer_func_t func);
void tegra_edid_destroy(struct tegra_edid *edid);
int tegra_edid_get_monspecs(struct tegra_edid *edid,
struct fb_monspecs *specs);
u16 tegra_edid_get_cd_flag(struct tegra_edid *edid);
u16 tegra_edid_get_ex_hdr_cap(struct tegra_edid *edid);
int tegra_edid_get_ex_hdr_cap_info(struct tegra_edid *edid,
struct tegra_dc_ext_hdr_caps *hdr_cap_info);
bool tegra_edid_is_rgb_quantization_selectable(struct tegra_edid *edid);
bool tegra_edid_is_yuv_quantization_selectable(struct tegra_edid *edid);
int tegra_edid_get_ex_quant_cap_info(struct tegra_edid *edid,
struct tegra_dc_ext_quant_caps *hdr_quant_info);
u16 tegra_edid_get_max_clk_rate(struct tegra_edid *edid);
bool tegra_edid_is_scdc_present(struct tegra_edid *edid);
bool tegra_edid_is_420db_present(struct tegra_edid *edid);
bool tegra_edid_is_hfvsdb_present(struct tegra_edid *edid);
bool tegra_edid_support_yuv422(struct tegra_edid *edid);
bool tegra_edid_support_yuv444(struct tegra_edid *edid);
u16 tegra_edid_get_ex_colorimetry(struct tegra_edid *edid);
int tegra_edid_get_eld(struct tegra_edid *edid, struct tegra_edid_hdmi_eld *elddata);
u32 tegra_edid_get_quirks(struct tegra_edid *edid);
u32 tegra_edid_lookup_quirks(const char *manufacturer, u32 model,
const char *monitor_name);
struct tegra_dc_edid *tegra_edid_get_data(struct tegra_edid *edid);
void tegra_edid_put_data(struct tegra_dc_edid *data);
int tegra_dc_edid_blob(struct tegra_dc *dc, struct i2c_msg *msgs, int num);
int tegra_edid_underscan_supported(struct tegra_edid *edid);
int tegra_edid_i2c_divide_rate(struct tegra_edid *edid);
int tegra_edid_i2c_adap_change_rate(struct i2c_adapter *i2c_adap, int rate);
int tegra_edid_read_block(struct tegra_edid *edid, int block, u8 *data);
int tegra_edid_audio_supported(struct tegra_edid *edid);
bool tegra_edid_is_vrr_capable(struct tegra_edid *edid);
int tegra_edid_get_source_physical_address(struct tegra_edid *edid, u8 *phy_address);
int tegra_edid_disp_id_ext_block_parse(const u8 *section,
struct fb_monspecs *specs,
struct tegra_edid_pvt *edid_pvt);
#endif
|