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 "atomfirmware.h"
31 
32 #define DMUB_RB_CMD_SIZE 64
33 #define DMUB_RB_MAX_ENTRY 128
34 #define DMUB_RB_SIZE (DMUB_RB_CMD_SIZE * DMUB_RB_MAX_ENTRY)
35 #define REG_SET_MASK 0xFFFF
36 
37 enum dmub_cmd_type {
38 	DMUB_CMD__NULL,
39 	DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE,
40 	DMUB_CMD__REG_SEQ_FIELD_UPDATE_SEQ,
41 	DMUB_CMD__REG_SEQ_BURST_WRITE,
42 	DMUB_CMD__REG_REG_WAIT,
43 	DMUB_CMD__DIGX_ENCODER_CONTROL,
44 	DMUB_CMD__SET_PIXEL_CLOCK,
45 	DMUB_CMD__ENABLE_DISP_POWER_GATING,
46 	DMUB_CMD__DPPHY_INIT,
47 	DMUB_CMD__DIG1_TRANSMITTER_CONTROL,
48 
49 	// PSR
50 	DMUB_CMD__PSR_ENABLE,
51 	DMUB_CMD__PSR_DISABLE,
52 	DMUB_CMD__PSR_COPY_SETTINGS,
53 	DMUB_CMD__PSR_SET_LEVEL,
54 };
55 
56 #pragma pack(push, 1)
57 
58 struct dmub_cmd_header {
59 	enum dmub_cmd_type type : 8;
60 	unsigned int reserved0 : 16;
61 	unsigned int payload_bytes : 6;  /* up to 60 bytes */
62 	unsigned int reserved : 2;
63 };
64 
65 /*
66  * Read modify write
67  *
68  * 60 payload bytes can hold up to 5 sets of read modify writes,
69  * each take 3 dwords.
70  *
71  * number of sequences = header.payload_bytes / sizeof(struct dmub_cmd_read_modify_write_sequence)
72  *
73  * modify_mask = 0xffff'ffff means all fields are going to be updated.  in this case
74  * command parser will skip the read and we can use modify_mask = 0xffff'ffff as reg write
75  */
76 struct dmub_cmd_read_modify_write_sequence {
77 	uint32_t addr;
78 	uint32_t modify_mask;
79 	uint32_t modify_value;
80 };
81 
82 #define DMUB_READ_MODIFY_WRITE_SEQ__MAX		5
83 struct dmub_rb_cmd_read_modify_write {
84 	struct dmub_cmd_header header;  // type = DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE
85 	struct dmub_cmd_read_modify_write_sequence seq[DMUB_READ_MODIFY_WRITE_SEQ__MAX];
86 };
87 
88 /*
89  * Update a register with specified masks and values sequeunce
90  *
91  * 60 payload bytes can hold address + up to 7 sets of mask/value combo, each take 2 dword
92  *
93  * number of field update sequence = (header.payload_bytes - sizeof(addr)) / sizeof(struct read_modify_write_sequence)
94  *
95  *
96  * USE CASE:
97  *   1. auto-increment register where additional read would update pointer and produce wrong result
98  *   2. toggle a bit without read in the middle
99  */
100 
101 struct dmub_cmd_reg_field_update_sequence {
102 	uint32_t modify_mask;  // 0xffff'ffff to skip initial read
103 	uint32_t modify_value;
104 };
105 
106 #define DMUB_REG_FIELD_UPDATE_SEQ__MAX		7
107 
108 struct dmub_rb_cmd_reg_field_update_sequence {
109 	struct dmub_cmd_header header;
110 	uint32_t addr;
111 	struct dmub_cmd_reg_field_update_sequence seq[DMUB_REG_FIELD_UPDATE_SEQ__MAX];
112 };
113 
114 
115 /*
116  * Burst write
117  *
118  * support use case such as writing out LUTs.
119  *
120  * 60 payload bytes can hold up to 14 values to write to given address
121  *
122  * number of payload = header.payload_bytes / sizeof(struct read_modify_write_sequence)
123  */
124 #define DMUB_BURST_WRITE_VALUES__MAX  14
125 struct dmub_rb_cmd_burst_write {
126 	struct dmub_cmd_header header;  // type = DMUB_CMD__REG_SEQ_BURST_WRITE
127 	uint32_t addr;
128 	uint32_t write_values[DMUB_BURST_WRITE_VALUES__MAX];
129 };
130 
131 
132 struct dmub_rb_cmd_common {
133 	struct dmub_cmd_header header;
134 	uint8_t cmd_buffer[DMUB_RB_CMD_SIZE - sizeof(struct dmub_cmd_header)];
135 };
136 
137 struct dmub_cmd_reg_wait_data {
138 	uint32_t addr;
139 	uint32_t mask;
140 	uint32_t condition_field_value;
141 	uint32_t time_out_us;
142 };
143 
144 struct dmub_rb_cmd_reg_wait {
145 	struct dmub_cmd_header header;
146 	struct dmub_cmd_reg_wait_data reg_wait;
147 };
148 
149 struct dmub_cmd_digx_encoder_control_data {
150 	union dig_encoder_control_parameters_v1_5 dig;
151 };
152 
153 struct dmub_rb_cmd_digx_encoder_control {
154 	struct dmub_cmd_header header;
155 	struct dmub_cmd_digx_encoder_control_data encoder_control;
156 };
157 
158 struct dmub_cmd_set_pixel_clock_data {
159 	struct set_pixel_clock_parameter_v1_7 clk;
160 };
161 
162 struct dmub_rb_cmd_set_pixel_clock {
163 	struct dmub_cmd_header header;
164 	struct dmub_cmd_set_pixel_clock_data pixel_clock;
165 };
166 
167 struct dmub_cmd_enable_disp_power_gating_data {
168 	struct enable_disp_power_gating_parameters_v2_1 pwr;
169 };
170 
171 struct dmub_rb_cmd_enable_disp_power_gating {
172 	struct dmub_cmd_header header;
173 	struct dmub_cmd_enable_disp_power_gating_data power_gating;
174 };
175 
176 struct dmub_cmd_dig1_transmitter_control_data {
177 	struct dig_transmitter_control_parameters_v1_6 dig;
178 };
179 
180 struct dmub_rb_cmd_dig1_transmitter_control {
181 	struct dmub_cmd_header header;
182 	struct dmub_cmd_dig1_transmitter_control_data transmitter_control;
183 };
184 
185 struct dmub_rb_cmd_dpphy_init {
186 	struct dmub_cmd_header header;
187 	uint8_t reserved[60];
188 };
189 
190 struct dmub_cmd_psr_copy_settings_data {
191 	uint32_t reg1;
192 	uint32_t reg2;
193 	uint32_t reg3;
194 };
195 
196 struct dmub_rb_cmd_psr_copy_settings {
197 	struct dmub_cmd_header header;
198 	struct dmub_cmd_psr_copy_settings_data psr_copy_settings_data;
199 };
200 
201 struct dmub_cmd_psr_set_level_data {
202 	uint16_t psr_level;
203 };
204 
205 struct dmub_rb_cmd_psr_set_level {
206 	struct dmub_cmd_header header;
207 	struct dmub_cmd_psr_set_level_data psr_set_level_data;
208 };
209 
210 struct dmub_rb_cmd_psr_disable {
211 	struct dmub_cmd_header header;
212 };
213 
214 struct dmub_rb_cmd_psr_enable {
215 	struct dmub_cmd_header header;
216 };
217 
218 struct dmub_cmd_psr_notify_vblank_data {
219 	uint32_t vblank_int; // Which vblank interrupt was triggered
220 };
221 
222 struct dmub_rb_cmd_notify_vblank {
223 	struct dmub_cmd_header header;
224 	struct dmub_cmd_psr_notify_vblank_data psr_notify_vblank_data;
225 };
226 
227 struct dmub_cmd_psr_notify_static_state_data {
228 	uint32_t ss_int;   // Which static screen interrupt was triggered
229 	uint32_t ss_enter; // Enter (1) or exit (0) static screen
230 };
231 
232 struct dmub_rb_cmd_psr_notify_static_state {
233 	struct dmub_cmd_header header;
234 	struct dmub_cmd_psr_notify_static_state_data psr_notify_static_state_data;
235 };
236 
237 union dmub_rb_cmd {
238 	struct dmub_rb_cmd_read_modify_write read_modify_write;
239 	struct dmub_rb_cmd_reg_field_update_sequence reg_field_update_seq;
240 	struct dmub_rb_cmd_burst_write burst_write;
241 	struct dmub_rb_cmd_reg_wait reg_wait;
242 	struct dmub_rb_cmd_common cmd_common;
243 	struct dmub_rb_cmd_digx_encoder_control digx_encoder_control;
244 	struct dmub_rb_cmd_set_pixel_clock set_pixel_clock;
245 	struct dmub_rb_cmd_enable_disp_power_gating enable_disp_power_gating;
246 	struct dmub_rb_cmd_dpphy_init dpphy_init;
247 	struct dmub_rb_cmd_dig1_transmitter_control dig1_transmitter_control;
248 	struct dmub_rb_cmd_psr_enable psr_enable;
249 	struct dmub_rb_cmd_psr_disable psr_disable;
250 	struct dmub_rb_cmd_psr_copy_settings psr_copy_settings;
251 	struct dmub_rb_cmd_psr_set_level psr_set_level;
252 };
253 
254 #pragma pack(pop)
255 
256 #endif /* _DMUB_CMD_H_ */
257