]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - drivers/gpu/drm/amd/display/dc/dc_helper.c
drm/amd/dc: Add dc display driver (v2)
[mirror_ubuntu-jammy-kernel.git] / drivers / gpu / drm / amd / display / dc / dc_helper.c
1 /*
2 * dc_helper.c
3 *
4 * Created on: Aug 30, 2016
5 * Author: agrodzov
6 */
7 #include "dm_services.h"
8 #include <stdarg.h>
9
10 uint32_t generic_reg_update_ex(const struct dc_context *ctx,
11 uint32_t addr, uint32_t reg_val, int n,
12 uint8_t shift1, uint32_t mask1, uint32_t field_value1,
13 ...)
14 {
15 uint32_t shift, mask, field_value;
16 int i = 1;
17
18 va_list ap;
19 va_start(ap, field_value1);
20
21 reg_val = set_reg_field_value_ex(reg_val, field_value1, mask1, shift1);
22
23 while (i < n) {
24 shift = va_arg(ap, uint32_t);
25 mask = va_arg(ap, uint32_t);
26 field_value = va_arg(ap, uint32_t);
27
28 reg_val = set_reg_field_value_ex(reg_val, field_value, mask, shift);
29 i++;
30 }
31
32 dm_write_reg(ctx, addr, reg_val);
33 va_end(ap);
34
35 return reg_val;
36 }
37
38 uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr,
39 uint8_t shift, uint32_t mask, uint32_t *field_value)
40 {
41 uint32_t reg_val = dm_read_reg(ctx, addr);
42 *field_value = get_reg_field_value_ex(reg_val, mask, shift);
43 return reg_val;
44 }
45
46 uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr,
47 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
48 uint8_t shift2, uint32_t mask2, uint32_t *field_value2)
49 {
50 uint32_t reg_val = dm_read_reg(ctx, addr);
51 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
52 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
53 return reg_val;
54 }
55
56 uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr,
57 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
58 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
59 uint8_t shift3, uint32_t mask3, uint32_t *field_value3)
60 {
61 uint32_t reg_val = dm_read_reg(ctx, addr);
62 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
63 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
64 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
65 return reg_val;
66 }
67
68 uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr,
69 uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
70 uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
71 uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
72 uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
73 uint8_t shift5, uint32_t mask5, uint32_t *field_value5)
74 {
75 uint32_t reg_val = dm_read_reg(ctx, addr);
76 *field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
77 *field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
78 *field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
79 *field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
80 *field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
81 return reg_val;
82 }
83
84 /* note: va version of this is pretty bad idea, since there is a output parameter pass by pointer
85 * compiler won't be able to check for size match and is prone to stack corruption type of bugs
86
87 uint32_t generic_reg_get(const struct dc_context *ctx,
88 uint32_t addr, int n, ...)
89 {
90 uint32_t shift, mask;
91 uint32_t *field_value;
92 uint32_t reg_val;
93 int i = 0;
94
95 reg_val = dm_read_reg(ctx, addr);
96
97 va_list ap;
98 va_start(ap, n);
99
100 while (i < n) {
101 shift = va_arg(ap, uint32_t);
102 mask = va_arg(ap, uint32_t);
103 field_value = va_arg(ap, uint32_t *);
104
105 *field_value = get_reg_field_value_ex(reg_val, mask, shift);
106 i++;
107 }
108
109 va_end(ap);
110
111 return reg_val;
112 }
113 */
114
115 uint32_t generic_reg_wait(const struct dc_context *ctx,
116 uint32_t addr, uint32_t shift, uint32_t mask, uint32_t condition_value,
117 unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
118 const char *func_name)
119 {
120 uint32_t field_value;
121 uint32_t reg_val;
122 int i;
123
124 for (i = 0; i <= time_out_num_tries; i++) {
125 if (i) {
126 if (0 < delay_between_poll_us && delay_between_poll_us < 1000)
127 udelay(delay_between_poll_us);
128
129 if (delay_between_poll_us > 1000)
130 msleep(delay_between_poll_us/1000);
131 }
132
133 reg_val = dm_read_reg(ctx, addr);
134
135 field_value = get_reg_field_value_ex(reg_val, mask, shift);
136
137 if (field_value == condition_value)
138 return reg_val;
139 }
140
141 DC_ERR("REG_WAIT timeout %dus * %d tries - %s",
142 delay_between_poll_us, time_out_num_tries, func_name);
143 return reg_val;
144 }