1 /*
2  * Copyright 2020 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 
27 #include "dc_bios_types.h"
28 #include "dcn30_vpg.h"
29 #include "reg_helper.h"
30 
31 #define DC_LOGGER \
32 		vpg3->base.ctx->logger
33 
34 #define REG(reg)\
35 	(vpg3->regs->reg)
36 
37 #undef FN
38 #define FN(reg_name, field_name) \
39 	vpg3->vpg_shift->field_name, vpg3->vpg_mask->field_name
40 
41 
42 #define CTX \
43 	vpg3->base.ctx
44 
45 
46 static void vpg3_update_generic_info_packet(
47 	struct vpg *vpg,
48 	uint32_t packet_index,
49 	const struct dc_info_packet *info_packet)
50 {
51 	struct dcn30_vpg *vpg3 = DCN30_VPG_FROM_VPG(vpg);
52 	uint32_t i;
53 
54 	/* TODOFPGA Figure out a proper number for max_retries polling for lock
55 	 * use 50 for now.
56 	 */
57 	uint32_t max_retries = 50;
58 
59 	if (packet_index > 14)
60 		ASSERT(0);
61 
62 	/* poll dig_update_lock is not locked -> asic internal signal
63 	 * assume otg master lock will unlock it
64 	 */
65 	/* REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS,
66 	 * 		0, 10, max_retries);
67 	 */
68 
69 	/* TODO: Check if this is required */
70 	/* check if HW reading GSP memory */
71 	REG_WAIT(VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_OCCURED,
72 			0, 10, max_retries);
73 
74 	/* HW does is not reading GSP memory not reading too long ->
75 	 * something wrong. clear GPS memory access and notify?
76 	 * hw SW is writing to GSP memory
77 	 */
78 	REG_UPDATE(VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_CLR, 1);
79 
80 	/* choose which generic packet to use */
81 	REG_UPDATE(VPG_GENERIC_PACKET_ACCESS_CTRL,
82 			VPG_GENERIC_DATA_INDEX, packet_index*9);
83 
84 	/* write generic packet header
85 	 * (4th byte is for GENERIC0 only)
86 	 */
87 	REG_SET_4(VPG_GENERIC_PACKET_DATA, 0,
88 			VPG_GENERIC_DATA_BYTE0, info_packet->hb0,
89 			VPG_GENERIC_DATA_BYTE1, info_packet->hb1,
90 			VPG_GENERIC_DATA_BYTE2, info_packet->hb2,
91 			VPG_GENERIC_DATA_BYTE3, info_packet->hb3);
92 
93 	/* write generic packet contents
94 	 * (we never use last 4 bytes)
95 	 * there are 8 (0-7) mmDIG0_AFMT_GENERIC0_x registers
96 	 */
97 	{
98 		const uint32_t *content =
99 			(const uint32_t *) &info_packet->sb[0];
100 
101 		for (i = 0; i < 8; i++) {
102 			REG_WRITE(VPG_GENERIC_PACKET_DATA, *content++);
103 		}
104 	}
105 
106 	/* atomically update double-buffered GENERIC0 registers in immediate mode
107 	 * (update at next block_update when block_update_lock == 0).
108 	 */
109 	switch (packet_index) {
110 	case 0:
111 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
112 				VPG_GENERIC0_IMMEDIATE_UPDATE, 1);
113 		break;
114 	case 1:
115 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
116 				VPG_GENERIC1_IMMEDIATE_UPDATE, 1);
117 		break;
118 	case 2:
119 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
120 				VPG_GENERIC2_IMMEDIATE_UPDATE, 1);
121 		break;
122 	case 3:
123 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
124 				VPG_GENERIC3_IMMEDIATE_UPDATE, 1);
125 		break;
126 	case 4:
127 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
128 				VPG_GENERIC4_IMMEDIATE_UPDATE, 1);
129 		break;
130 	case 5:
131 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
132 				VPG_GENERIC5_IMMEDIATE_UPDATE, 1);
133 		break;
134 	case 6:
135 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
136 				VPG_GENERIC6_IMMEDIATE_UPDATE, 1);
137 		break;
138 	case 7:
139 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
140 				VPG_GENERIC7_IMMEDIATE_UPDATE, 1);
141 		break;
142 	case 8:
143 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
144 				VPG_GENERIC8_IMMEDIATE_UPDATE, 1);
145 		break;
146 	case 9:
147 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
148 				VPG_GENERIC9_IMMEDIATE_UPDATE, 1);
149 		break;
150 	case 10:
151 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
152 				VPG_GENERIC10_IMMEDIATE_UPDATE, 1);
153 		break;
154 	case 11:
155 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
156 				VPG_GENERIC11_IMMEDIATE_UPDATE, 1);
157 		break;
158 	case 12:
159 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
160 				VPG_GENERIC12_IMMEDIATE_UPDATE, 1);
161 		break;
162 	case 13:
163 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
164 				VPG_GENERIC13_IMMEDIATE_UPDATE, 1);
165 		break;
166 	case 14:
167 		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
168 				VPG_GENERIC14_IMMEDIATE_UPDATE, 1);
169 		break;
170 	default:
171 		break;
172 	}
173 }
174 
175 static struct vpg_funcs dcn30_vpg_funcs = {
176 	.update_generic_info_packet	= vpg3_update_generic_info_packet,
177 };
178 
179 void vpg3_construct(struct dcn30_vpg *vpg3,
180 	struct dc_context *ctx,
181 	uint32_t inst,
182 	const struct dcn30_vpg_registers *vpg_regs,
183 	const struct dcn30_vpg_shift *vpg_shift,
184 	const struct dcn30_vpg_mask *vpg_mask)
185 {
186 	vpg3->base.ctx = ctx;
187 
188 	vpg3->base.inst = inst;
189 	vpg3->base.funcs = &dcn30_vpg_funcs;
190 
191 	vpg3->regs = vpg_regs;
192 	vpg3->vpg_shift = vpg_shift;
193 	vpg3->vpg_mask = vpg_mask;
194 }
195