xref: /linux/drivers/gpu/drm/i915/display/intel_de.h (revision bba2c3615bd6cfee7456d1130f2e6b01b3f4e9ba)
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Copyright © 2019 Intel Corporation
4  */
5 
6 #ifndef __INTEL_DE_H__
7 #define __INTEL_DE_H__
8 
9 #include "intel_display_core.h"
10 #include "intel_dmc_wl.h"
11 #include "intel_dsb.h"
12 #include "intel_uncore.h"
13 #include "intel_uncore_trace.h"
14 
15 static inline struct intel_uncore *__to_uncore(struct intel_display *display)
16 {
17 	return to_intel_uncore(display->drm);
18 }
19 
20 u8 intel_de_read8(struct intel_display *display, intel_reg_t reg);
21 void intel_de_write8(struct intel_display *display, intel_reg_t reg, u8 val);
22 u16 intel_de_read16(struct intel_display *display, intel_reg_t reg);
23 
24 static inline u32
25 intel_de_read(struct intel_display *display, intel_reg_t reg)
26 {
27 	u32 val;
28 
29 	intel_dmc_wl_get(display, reg);
30 
31 	val = intel_uncore_read(__to_uncore(display), reg);
32 
33 	intel_dmc_wl_put(display, reg);
34 
35 	return val;
36 }
37 
38 static inline u64
39 intel_de_read64_2x32_volatile(struct intel_display *display,
40 			      intel_reg_t lower_reg, intel_reg_t upper_reg)
41 {
42 	u64 val;
43 
44 	intel_dmc_wl_get(display, lower_reg);
45 	intel_dmc_wl_get(display, upper_reg);
46 
47 	val = intel_uncore_read64_2x32(__to_uncore(display), lower_reg,
48 				       upper_reg);
49 
50 	intel_dmc_wl_put(display, upper_reg);
51 	intel_dmc_wl_put(display, lower_reg);
52 
53 	return val;
54 }
55 
56 static inline u64
57 intel_de_read64_2x32(struct intel_display *display, intel_reg_t reg)
58 {
59 	intel_reg_t upper_reg = _MMIO(intel_reg_offset(reg) + 4);
60 	u32 lower, upper;
61 
62 	lower = intel_de_read(display, reg);
63 	upper = intel_de_read(display, upper_reg);
64 
65 	return (u64)upper << 32 | lower;
66 }
67 
68 static inline void
69 intel_de_posting_read(struct intel_display *display, intel_reg_t reg)
70 {
71 	intel_dmc_wl_get(display, reg);
72 
73 	intel_uncore_posting_read(__to_uncore(display), reg);
74 
75 	intel_dmc_wl_put(display, reg);
76 }
77 
78 static inline void
79 intel_de_write(struct intel_display *display, intel_reg_t reg, u32 val)
80 {
81 	intel_dmc_wl_get(display, reg);
82 
83 	intel_uncore_write(__to_uncore(display), reg, val);
84 
85 	intel_dmc_wl_put(display, reg);
86 }
87 
88 static inline u32
89 intel_de_rmw(struct intel_display *display, intel_reg_t reg, u32 clear, u32 set)
90 {
91 	u32 val;
92 
93 	intel_dmc_wl_get(display, reg);
94 
95 	val = intel_uncore_rmw(__to_uncore(display), reg, clear, set);
96 
97 	intel_dmc_wl_put(display, reg);
98 
99 	return val;
100 }
101 
102 int intel_de_wait_us(struct intel_display *display, intel_reg_t reg,
103 		     u32 mask, u32 value, unsigned int timeout_us,
104 		     u32 *out_value);
105 int intel_de_wait_ms(struct intel_display *display, intel_reg_t reg,
106 		     u32 mask, u32 value, unsigned int timeout_ms,
107 		     u32 *out_value);
108 int intel_de_wait_fw_ms(struct intel_display *display, intel_reg_t reg,
109 			u32 mask, u32 value, unsigned int timeout_ms,
110 			u32 *out_value);
111 int intel_de_wait_fw_us_atomic(struct intel_display *display, intel_reg_t reg,
112 			       u32 mask, u32 value, unsigned int timeout_us,
113 			       u32 *out_value);
114 int intel_de_wait_for_set_us(struct intel_display *display, intel_reg_t reg,
115 			     u32 mask, unsigned int timeout_us);
116 int intel_de_wait_for_clear_us(struct intel_display *display, intel_reg_t reg,
117 			       u32 mask, unsigned int timeout_us);
118 int intel_de_wait_for_set_ms(struct intel_display *display, intel_reg_t reg,
119 			     u32 mask, unsigned int timeout_ms);
120 int intel_de_wait_for_clear_ms(struct intel_display *display, intel_reg_t reg,
121 			       u32 mask, unsigned int timeout_ms);
122 
123 /*
124  * Unlocked mmio-accessors, think carefully before using these.
125  *
126  * Certain architectures will die if the same cacheline is concurrently accessed
127  * by different clients (e.g. on Ivybridge). Access to registers should
128  * therefore generally be serialised, by either the dev_priv->uncore.lock or
129  * a more localised lock guarding all access to that bank of registers.
130  */
131 static inline u32
132 intel_de_read_fw(struct intel_display *display, intel_reg_t reg)
133 {
134 	u32 val;
135 
136 	val = intel_uncore_read_fw(__to_uncore(display), reg);
137 	trace_i915_reg_rw(false, reg, val, sizeof(val), true);
138 
139 	return val;
140 }
141 
142 static inline void
143 intel_de_write_fw(struct intel_display *display, intel_reg_t reg, u32 val)
144 {
145 	trace_i915_reg_rw(true, reg, val, sizeof(val), true);
146 	intel_uncore_write_fw(__to_uncore(display), reg, val);
147 }
148 
149 static inline u32
150 intel_de_rmw_fw(struct intel_display *display, intel_reg_t reg, u32 clear, u32 set)
151 {
152 	u32 old, val;
153 
154 	old = intel_de_read_fw(display, reg);
155 	val = (old & ~clear) | set;
156 	intel_de_write_fw(display, reg, val);
157 
158 	return old;
159 }
160 
161 static inline u32
162 intel_de_read_notrace(struct intel_display *display, intel_reg_t reg)
163 {
164 	return intel_uncore_read_notrace(__to_uncore(display), reg);
165 }
166 
167 static inline void
168 intel_de_write_notrace(struct intel_display *display, intel_reg_t reg, u32 val)
169 {
170 	intel_uncore_write_notrace(__to_uncore(display), reg, val);
171 }
172 
173 static __always_inline void
174 intel_de_write_dsb(struct intel_display *display, struct intel_dsb *dsb,
175 		   intel_reg_t reg, u32 val)
176 {
177 	if (dsb)
178 		intel_dsb_reg_write(dsb, reg, val);
179 	else
180 		intel_de_write_fw(display, reg, val);
181 }
182 
183 #endif /* __INTEL_DE_H__ */
184