Merge tag 'linux-watchdog-5.11-rc1' of git://www.linux-watchdog.org/linux-watchdog
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / dcn30 / dcn30_vpg.c
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 }