blob: dbcbd8b0efd984cc7ad5b692f763938298913c1a [file] [log] [blame]
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -07001/*
Sankeerth Billakanti4223e132019-03-08 12:09:59 +05302 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -07003 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#ifndef _DP_CATALOG_H_
16#define _DP_CATALOG_H_
17
Ajay Singh Parmar9c842d42017-09-21 13:02:05 -070018#include <drm/msm_drm.h>
19
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -070020#include "dp_parser.h"
21
22/* interrupts */
23#define DP_INTR_HPD BIT(0)
24#define DP_INTR_AUX_I2C_DONE BIT(3)
25#define DP_INTR_WRONG_ADDR BIT(6)
26#define DP_INTR_TIMEOUT BIT(9)
27#define DP_INTR_NACK_DEFER BIT(12)
28#define DP_INTR_WRONG_DATA_CNT BIT(15)
29#define DP_INTR_I2C_NACK BIT(18)
30#define DP_INTR_I2C_DEFER BIT(21)
31#define DP_INTR_PLL_UNLOCKED BIT(24)
32#define DP_INTR_AUX_ERROR BIT(27)
33
34#define DP_INTR_READY_FOR_VIDEO BIT(0)
35#define DP_INTR_IDLE_PATTERN_SENT BIT(3)
36#define DP_INTR_FRAME_END BIT(6)
37#define DP_INTR_CRC_UPDATED BIT(9)
38
Ajay Singh Parmar059d0e02017-09-13 11:37:40 -070039struct dp_catalog_hdr_data {
Ajay Singh Parmar7e724362017-11-05 00:06:30 -070040 u32 ext_header_byte0;
41 u32 ext_header_byte1;
42 u32 ext_header_byte2;
43 u32 ext_header_byte3;
44
Ajay Singh Parmar9c842d42017-09-21 13:02:05 -070045 u32 vsc_header_byte0;
46 u32 vsc_header_byte1;
47 u32 vsc_header_byte2;
48 u32 vsc_header_byte3;
49
50 u32 vscext_header_byte0;
51 u32 vscext_header_byte1;
52 u32 vscext_header_byte2;
53 u32 vscext_header_byte3;
Ajay Singh Parmar059d0e02017-09-13 11:37:40 -070054
55 u32 bpc;
56
57 u32 version;
58 u32 length;
Ajay Singh Parmar9c842d42017-09-21 13:02:05 -070059 u32 pixel_encoding;
60 u32 colorimetry;
61 u32 dynamic_range;
62 u32 content_type;
Ajay Singh Parmar059d0e02017-09-13 11:37:40 -070063
Ajay Singh Parmar9c842d42017-09-21 13:02:05 -070064 struct drm_msm_ext_hdr_metadata hdr_meta;
Ajay Singh Parmar059d0e02017-09-13 11:37:40 -070065};
66
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -070067struct dp_catalog_aux {
68 u32 data;
Padmanabhan Komanduru15e757d2017-05-24 04:07:31 -070069 u32 isr;
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -070070
71 u32 (*read_data)(struct dp_catalog_aux *aux);
72 int (*write_data)(struct dp_catalog_aux *aux);
73 int (*write_trans)(struct dp_catalog_aux *aux);
Tatenda Chipeperekwa1a43e702017-09-15 15:45:16 -070074 int (*clear_trans)(struct dp_catalog_aux *aux, bool read);
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -070075 void (*reset)(struct dp_catalog_aux *aux);
76 void (*enable)(struct dp_catalog_aux *aux, bool enable);
Padmanabhan Komanduru2e9914b2017-08-04 20:51:31 +053077 void (*update_aux_cfg)(struct dp_catalog_aux *aux,
78 struct dp_aux_cfg *cfg, enum dp_phy_aux_config_type type);
Padmanabhan Komanduru20a21db2017-07-10 16:58:59 +053079 void (*setup)(struct dp_catalog_aux *aux,
80 struct dp_aux_cfg *aux_cfg);
Padmanabhan Komanduru15e757d2017-05-24 04:07:31 -070081 void (*get_irq)(struct dp_catalog_aux *aux, bool cmd_busy);
Padmanabhan Komanduruf69e3572017-09-27 20:39:32 +053082 void (*clear_hw_interrupts)(struct dp_catalog_aux *aux);
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -070083};
84
85struct dp_catalog_ctrl {
86 u32 dp_tu;
87 u32 valid_boundary;
88 u32 valid_boundary2;
Padmanabhan Komanduru15e757d2017-05-24 04:07:31 -070089 u32 isr;
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -070090
91 void (*state_ctrl)(struct dp_catalog_ctrl *ctrl, u32 state);
92 void (*config_ctrl)(struct dp_catalog_ctrl *ctrl, u32 config);
93 void (*lane_mapping)(struct dp_catalog_ctrl *ctrl);
94 void (*mainlink_ctrl)(struct dp_catalog_ctrl *ctrl, bool enable);
95 void (*config_misc)(struct dp_catalog_ctrl *ctrl, u32 cc, u32 tb);
Aravind Venkateswaran7599a992017-08-10 14:17:57 -070096 void (*config_msa)(struct dp_catalog_ctrl *ctrl, u32 rate,
Sankeerth Billakanti4223e132019-03-08 12:09:59 +053097 u32 stream_rate_khz);
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -070098 void (*set_pattern)(struct dp_catalog_ctrl *ctrl, u32 pattern);
99 void (*reset)(struct dp_catalog_ctrl *ctrl);
Padmanabhan Komandurub6117bd2017-05-11 20:18:40 -0700100 void (*usb_reset)(struct dp_catalog_ctrl *ctrl, bool flip);
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -0700101 bool (*mainlink_ready)(struct dp_catalog_ctrl *ctrl);
102 void (*enable_irq)(struct dp_catalog_ctrl *ctrl, bool enable);
103 void (*hpd_config)(struct dp_catalog_ctrl *ctrl, bool enable);
104 void (*phy_reset)(struct dp_catalog_ctrl *ctrl);
105 void (*phy_lane_cfg)(struct dp_catalog_ctrl *ctrl, bool flipped,
106 u8 lane_cnt);
107 void (*update_vx_px)(struct dp_catalog_ctrl *ctrl, u8 v_level,
108 u8 p_level);
Padmanabhan Komanduru15e757d2017-05-24 04:07:31 -0700109 void (*get_interrupt)(struct dp_catalog_ctrl *ctrl);
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -0700110 void (*update_transfer_unit)(struct dp_catalog_ctrl *ctrl);
Tatenda Chipeperekwa39547362017-07-07 17:44:09 -0700111 u32 (*read_hdcp_status)(struct dp_catalog_ctrl *ctrl);
Tatenda Chipeperekwa8ce1d5f2017-08-07 18:44:21 -0700112 void (*send_phy_pattern)(struct dp_catalog_ctrl *ctrl,
113 u32 pattern);
114 u32 (*read_phy_pattern)(struct dp_catalog_ctrl *ctrl);
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -0700115};
116
Padmanabhan Komanduru62a01d02017-11-03 19:44:13 +0530117#define HEADER_BYTE_2_BIT 0
118#define PARITY_BYTE_2_BIT 8
119#define HEADER_BYTE_1_BIT 16
120#define PARITY_BYTE_1_BIT 24
121#define HEADER_BYTE_3_BIT 16
122#define PARITY_BYTE_3_BIT 24
123
Tatenda Chipeperekwa758dea02017-04-28 12:26:31 -0700124enum dp_catalog_audio_sdp_type {
125 DP_AUDIO_SDP_STREAM,
126 DP_AUDIO_SDP_TIMESTAMP,
127 DP_AUDIO_SDP_INFOFRAME,
128 DP_AUDIO_SDP_COPYMANAGEMENT,
129 DP_AUDIO_SDP_ISRC,
130 DP_AUDIO_SDP_MAX,
131};
132
133enum dp_catalog_audio_header_type {
134 DP_AUDIO_SDP_HEADER_1,
135 DP_AUDIO_SDP_HEADER_2,
136 DP_AUDIO_SDP_HEADER_3,
137 DP_AUDIO_SDP_HEADER_MAX,
138};
139
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -0700140struct dp_catalog_audio {
Tatenda Chipeperekwa758dea02017-04-28 12:26:31 -0700141 enum dp_catalog_audio_sdp_type sdp_type;
142 enum dp_catalog_audio_header_type sdp_header;
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -0700143 u32 data;
144
Tatenda Chipeperekwa758dea02017-04-28 12:26:31 -0700145 void (*init)(struct dp_catalog_audio *audio);
146 void (*enable)(struct dp_catalog_audio *audio);
147 void (*config_acr)(struct dp_catalog_audio *audio);
148 void (*config_sdp)(struct dp_catalog_audio *audio);
149 void (*set_header)(struct dp_catalog_audio *audio);
150 void (*get_header)(struct dp_catalog_audio *audio);
151 void (*safe_to_exit_level)(struct dp_catalog_audio *audio);
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -0700152};
153
154struct dp_catalog_panel {
155 u32 total;
156 u32 sync_start;
157 u32 width_blanking;
158 u32 dp_active;
Padmanabhan Komanduru62a01d02017-11-03 19:44:13 +0530159 u8 *spd_vendor_name;
160 u8 *spd_product_description;
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -0700161
Ajay Singh Parmar9c842d42017-09-21 13:02:05 -0700162 struct dp_catalog_hdr_data hdr_data;
163
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +0530164 /* TPG */
165 u32 hsync_period;
166 u32 vsync_period;
167 u32 display_v_start;
168 u32 display_v_end;
169 u32 v_sync_width;
170 u32 hsync_ctl;
171 u32 display_hctl;
172
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -0700173 int (*timing_cfg)(struct dp_catalog_panel *panel);
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800174 void (*config_hdr)(struct dp_catalog_panel *panel, bool en);
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +0530175 void (*tpg_config)(struct dp_catalog_panel *panel, bool enable);
Padmanabhan Komanduru62a01d02017-11-03 19:44:13 +0530176 void (*config_spd)(struct dp_catalog_panel *panel);
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -0700177};
178
179struct dp_catalog {
180 struct dp_catalog_aux aux;
181 struct dp_catalog_ctrl ctrl;
182 struct dp_catalog_audio audio;
183 struct dp_catalog_panel panel;
Samantha Tranb6a5cd82018-02-01 14:47:16 -0800184
185 void (*set_exe_mode)(struct dp_catalog *dp_catalog, char *mode);
186 int (*get_reg_dump)(struct dp_catalog *dp_catalog,
187 char *mode, u8 **out_buf, u32 *out_buf_len);
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -0700188};
189
Padmanabhan Komanduru62a01d02017-11-03 19:44:13 +0530190static inline u8 dp_ecc_get_g0_value(u8 data)
191{
192 u8 c[4];
193 u8 g[4];
194 u8 ret_data = 0;
195 u8 i;
196
197 for (i = 0; i < 4; i++)
198 c[i] = (data >> i) & 0x01;
199
200 g[0] = c[3];
201 g[1] = c[0] ^ c[3];
202 g[2] = c[1];
203 g[3] = c[2];
204
205 for (i = 0; i < 4; i++)
206 ret_data = ((g[i] & 0x01) << i) | ret_data;
207
208 return ret_data;
209}
210
211static inline u8 dp_ecc_get_g1_value(u8 data)
212{
213 u8 c[4];
214 u8 g[4];
215 u8 ret_data = 0;
216 u8 i;
217
218 for (i = 0; i < 4; i++)
219 c[i] = (data >> i) & 0x01;
220
221 g[0] = c[0] ^ c[3];
222 g[1] = c[0] ^ c[1] ^ c[3];
223 g[2] = c[1] ^ c[2];
224 g[3] = c[2] ^ c[3];
225
226 for (i = 0; i < 4; i++)
227 ret_data = ((g[i] & 0x01) << i) | ret_data;
228
229 return ret_data;
230}
231
232static inline u8 dp_header_get_parity(u32 data)
233{
234 u8 x0 = 0;
235 u8 x1 = 0;
236 u8 ci = 0;
237 u8 iData = 0;
238 u8 i = 0;
239 u8 parity_byte;
240 u8 num_byte = (data & 0xFF00) > 0 ? 8 : 2;
241
242 for (i = 0; i < num_byte; i++) {
243 iData = (data >> i*4) & 0xF;
244
245 ci = iData ^ x1;
246 x1 = x0 ^ dp_ecc_get_g1_value(ci);
247 x0 = dp_ecc_get_g0_value(ci);
248 }
249
250 parity_byte = x1 | (x0 << 4);
251
252 return parity_byte;
253}
254
Samantha Tranb6a5cd82018-02-01 14:47:16 -0800255struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser);
Ajay Singh Parmarbd3097f2017-03-29 15:04:13 -0700256void dp_catalog_put(struct dp_catalog *catalog);
257
258#endif /* _DP_CATALOG_H_ */