1 /*
2  * Copyright 2019 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 #ifndef _DMUB_CMD_H_
27 #define _DMUB_CMD_H_
28 
29 #include "dmub_types.h"
30 #include "dmub_cmd_dal.h"
31 #include "dmub_cmd_vbios.h"
32 #include "atomfirmware.h"
33 
34 #define DMUB_RB_CMD_SIZE 64
35 #define DMUB_RB_MAX_ENTRY 128
36 #define DMUB_RB_SIZE (DMUB_RB_CMD_SIZE * DMUB_RB_MAX_ENTRY)
37 #define REG_SET_MASK 0xFFFF
38 
39 
40 /*
41  * Command IDs should be treated as stable ABI.
42  * Do not reuse or modify IDs.
43  */
44 
45 enum dmub_cmd_type {
46 	DMUB_CMD__NULL = 0,
47 	DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE = 1,
48 	DMUB_CMD__REG_SEQ_FIELD_UPDATE_SEQ = 2,
49 	DMUB_CMD__REG_SEQ_BURST_WRITE = 3,
50 	DMUB_CMD__REG_REG_WAIT = 4,
51 	DMUB_CMD__PLAT_54186_WA = 5,
52 	DMUB_CMD__PSR = 64,
53 	DMUB_CMD__VBIOS = 128,
54 };
55 
56 #pragma pack(push, 1)
57 
58 struct dmub_cmd_header {
59 	unsigned int type : 8;
60 	unsigned int sub_type : 8;
61 	unsigned int reserved0 : 8;
62 	unsigned int payload_bytes : 6;  /* up to 60 bytes */
63 	unsigned int reserved1 : 2;
64 };
65 
66 /*
67  * Read modify write
68  *
69  * 60 payload bytes can hold up to 5 sets of read modify writes,
70  * each take 3 dwords.
71  *
72  * number of sequences = header.payload_bytes / sizeof(struct dmub_cmd_read_modify_write_sequence)
73  *
74  * modify_mask = 0xffff'ffff means all fields are going to be updated.  in this case
75  * command parser will skip the read and we can use modify_mask = 0xffff'ffff as reg write
76  */
77 struct dmub_cmd_read_modify_write_sequence {
78 	uint32_t addr;
79 	uint32_t modify_mask;
80 	uint32_t modify_value;
81 };
82 
83 #define DMUB_READ_MODIFY_WRITE_SEQ__MAX		5
84 struct dmub_rb_cmd_read_modify_write {
85 	struct dmub_cmd_header header;  // type = DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE
86 	struct dmub_cmd_read_modify_write_sequence seq[DMUB_READ_MODIFY_WRITE_SEQ__MAX];
87 };
88 
89 /*
90  * Update a register with specified masks and values sequeunce
91  *
92  * 60 payload bytes can hold address + up to 7 sets of mask/value combo, each take 2 dword
93  *
94  * number of field update sequence = (header.payload_bytes - sizeof(addr)) / sizeof(struct read_modify_write_sequence)
95  *
96  *
97  * USE CASE:
98  *   1. auto-increment register where additional read would update pointer and produce wrong result
99  *   2. toggle a bit without read in the middle
100  */
101 
102 struct dmub_cmd_reg_field_update_sequence {
103 	uint32_t modify_mask;  // 0xffff'ffff to skip initial read
104 	uint32_t modify_value;
105 };
106 
107 #define DMUB_REG_FIELD_UPDATE_SEQ__MAX		7
108 
109 struct dmub_rb_cmd_reg_field_update_sequence {
110 	struct dmub_cmd_header header;
111 	uint32_t addr;
112 	struct dmub_cmd_reg_field_update_sequence seq[DMUB_REG_FIELD_UPDATE_SEQ__MAX];
113 };
114 
115 
116 /*
117  * Burst write
118  *
119  * support use case such as writing out LUTs.
120  *
121  * 60 payload bytes can hold up to 14 values to write to given address
122  *
123  * number of payload = header.payload_bytes / sizeof(struct read_modify_write_sequence)
124  */
125 #define DMUB_BURST_WRITE_VALUES__MAX  14
126 struct dmub_rb_cmd_burst_write {
127 	struct dmub_cmd_header header;  // type = DMUB_CMD__REG_SEQ_BURST_WRITE
128 	uint32_t addr;
129 	uint32_t write_values[DMUB_BURST_WRITE_VALUES__MAX];
130 };
131 
132 
133 struct dmub_rb_cmd_common {
134 	struct dmub_cmd_header header;
135 	uint8_t cmd_buffer[DMUB_RB_CMD_SIZE - sizeof(struct dmub_cmd_header)];
136 };
137 
138 struct dmub_cmd_reg_wait_data {
139 	uint32_t addr;
140 	uint32_t mask;
141 	uint32_t condition_field_value;
142 	uint32_t time_out_us;
143 };
144 
145 struct dmub_rb_cmd_reg_wait {
146 	struct dmub_cmd_header header;
147 	struct dmub_cmd_reg_wait_data reg_wait;
148 };
149 
150 #ifndef PHYSICAL_ADDRESS_LOC
151 #define PHYSICAL_ADDRESS_LOC union large_integer
152 #endif
153 
154 struct dmub_cmd_PLAT_54186_wa {
155 	uint32_t DCSURF_SURFACE_CONTROL;
156 	uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH;
157 	uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS;
158 	uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C;
159 	uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_C;
160 	struct {
161 		uint8_t hubp_inst : 4;
162 		uint8_t tmz_surface : 1;
163 		uint8_t immediate :1;
164 		uint8_t vmid : 4;
165 		uint8_t grph_stereo : 1;
166 		uint32_t reserved : 21;
167 	} flip_params;
168 	uint32_t reserved[9];
169 };
170 
171 struct dmub_rb_cmd_PLAT_54186_wa {
172 	struct dmub_cmd_header header;
173 	struct dmub_cmd_PLAT_54186_wa flip;
174 };
175 
176 struct dmub_cmd_digx_encoder_control_data {
177 	union dig_encoder_control_parameters_v1_5 dig;
178 };
179 
180 struct dmub_rb_cmd_digx_encoder_control {
181 	struct dmub_cmd_header header;
182 	struct dmub_cmd_digx_encoder_control_data encoder_control;
183 };
184 
185 struct dmub_cmd_set_pixel_clock_data {
186 	struct set_pixel_clock_parameter_v1_7 clk;
187 };
188 
189 struct dmub_rb_cmd_set_pixel_clock {
190 	struct dmub_cmd_header header;
191 	struct dmub_cmd_set_pixel_clock_data pixel_clock;
192 };
193 
194 struct dmub_cmd_enable_disp_power_gating_data {
195 	struct enable_disp_power_gating_parameters_v2_1 pwr;
196 };
197 
198 struct dmub_rb_cmd_enable_disp_power_gating {
199 	struct dmub_cmd_header header;
200 	struct dmub_cmd_enable_disp_power_gating_data power_gating;
201 };
202 
203 struct dmub_cmd_dig1_transmitter_control_data {
204 	struct dig_transmitter_control_parameters_v1_6 dig;
205 };
206 
207 struct dmub_rb_cmd_dig1_transmitter_control {
208 	struct dmub_cmd_header header;
209 	struct dmub_cmd_dig1_transmitter_control_data transmitter_control;
210 };
211 
212 struct dmub_rb_cmd_dpphy_init {
213 	struct dmub_cmd_header header;
214 	uint8_t reserved[60];
215 };
216 
217 struct dmub_cmd_psr_copy_settings_data {
218 	uint16_t psr_level;
219 	uint8_t hubp_inst;
220 	uint8_t dpp_inst;
221 	uint8_t mpcc_inst;
222 	uint8_t opp_inst;
223 	uint8_t otg_inst;
224 	uint8_t digfe_inst;
225 	uint8_t digbe_inst;
226 	uint8_t dpphy_inst;
227 	uint8_t aux_inst;
228 	uint8_t hyst_frames;
229 	uint8_t hyst_lines;
230 	uint8_t phy_num;
231 	uint8_t phy_type;
232 	uint8_t aux_repeat;
233 	uint8_t smu_optimizations_en;
234 	uint8_t skip_wait_for_pll_lock;
235 	uint8_t frame_delay;
236 	uint8_t smu_phy_id;
237 	uint8_t num_of_controllers;
238 	uint8_t link_rate;
239 	uint8_t frame_cap_ind;
240 };
241 
242 struct dmub_rb_cmd_psr_copy_settings {
243 	struct dmub_cmd_header header;
244 	struct dmub_cmd_psr_copy_settings_data psr_copy_settings_data;
245 };
246 
247 struct dmub_cmd_psr_set_level_data {
248 	uint16_t psr_level;
249 };
250 
251 struct dmub_rb_cmd_psr_set_level {
252 	struct dmub_cmd_header header;
253 	struct dmub_cmd_psr_set_level_data psr_set_level_data;
254 };
255 
256 struct dmub_rb_cmd_psr_enable {
257 	struct dmub_cmd_header header;
258 };
259 
260 struct dmub_cmd_psr_setup_data {
261 	enum psr_version version; // PSR version 1 or 2
262 };
263 
264 struct dmub_rb_cmd_psr_setup {
265 	struct dmub_cmd_header header;
266 	struct dmub_cmd_psr_setup_data psr_setup_data;
267 };
268 
269 union dmub_rb_cmd {
270 	struct dmub_rb_cmd_read_modify_write read_modify_write;
271 	struct dmub_rb_cmd_reg_field_update_sequence reg_field_update_seq;
272 	struct dmub_rb_cmd_burst_write burst_write;
273 	struct dmub_rb_cmd_reg_wait reg_wait;
274 	struct dmub_rb_cmd_common cmd_common;
275 	struct dmub_rb_cmd_digx_encoder_control digx_encoder_control;
276 	struct dmub_rb_cmd_set_pixel_clock set_pixel_clock;
277 	struct dmub_rb_cmd_enable_disp_power_gating enable_disp_power_gating;
278 	struct dmub_rb_cmd_dpphy_init dpphy_init;
279 	struct dmub_rb_cmd_dig1_transmitter_control dig1_transmitter_control;
280 	struct dmub_rb_cmd_psr_enable psr_enable;
281 	struct dmub_rb_cmd_psr_copy_settings psr_copy_settings;
282 	struct dmub_rb_cmd_psr_set_level psr_set_level;
283 	struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa;
284 	struct dmub_rb_cmd_psr_setup psr_setup;
285 };
286 
287 #pragma pack(pop)
288 
289 #endif /* _DMUB_CMD_H_ */
290