.. | .. |
---|
23 | 23 | * |
---|
24 | 24 | */ |
---|
25 | 25 | |
---|
| 26 | +#include <linux/delay.h> |
---|
| 27 | +#include <linux/slab.h> |
---|
| 28 | + |
---|
26 | 29 | #include "dm_services.h" |
---|
27 | 30 | |
---|
28 | 31 | #include "dce/dce_11_0_d.h" |
---|
.. | .. |
---|
62 | 65 | } |
---|
63 | 66 | }; |
---|
64 | 67 | |
---|
65 | | -static const uint32_t dce11_one_lpt_channel_max_resolution = 2560 * 1600; |
---|
66 | | - |
---|
67 | | -enum fbc_idle_force { |
---|
68 | | - /* Bit 0 - Display registers updated */ |
---|
69 | | - FBC_IDLE_FORCE_DISPLAY_REGISTER_UPDATE = 0x00000001, |
---|
70 | | - |
---|
71 | | - /* Bit 2 - FBC_GRPH_COMP_EN register updated */ |
---|
72 | | - FBC_IDLE_FORCE_GRPH_COMP_EN = 0x00000002, |
---|
73 | | - /* Bit 3 - FBC_SRC_SEL register updated */ |
---|
74 | | - FBC_IDLE_FORCE_SRC_SEL_CHANGE = 0x00000004, |
---|
75 | | - /* Bit 4 - FBC_MIN_COMPRESSION register updated */ |
---|
76 | | - FBC_IDLE_FORCE_MIN_COMPRESSION_CHANGE = 0x00000008, |
---|
77 | | - /* Bit 5 - FBC_ALPHA_COMP_EN register updated */ |
---|
78 | | - FBC_IDLE_FORCE_ALPHA_COMP_EN = 0x00000010, |
---|
79 | | - /* Bit 6 - FBC_ZERO_ALPHA_CHUNK_SKIP_EN register updated */ |
---|
80 | | - FBC_IDLE_FORCE_ZERO_ALPHA_CHUNK_SKIP_EN = 0x00000020, |
---|
81 | | - /* Bit 7 - FBC_FORCE_COPY_TO_COMP_BUF register updated */ |
---|
82 | | - FBC_IDLE_FORCE_FORCE_COPY_TO_COMP_BUF = 0x00000040, |
---|
83 | | - |
---|
84 | | - /* Bit 24 - Memory write to region 0 defined by MC registers. */ |
---|
85 | | - FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION0 = 0x01000000, |
---|
86 | | - /* Bit 25 - Memory write to region 1 defined by MC registers */ |
---|
87 | | - FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION1 = 0x02000000, |
---|
88 | | - /* Bit 26 - Memory write to region 2 defined by MC registers */ |
---|
89 | | - FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION2 = 0x04000000, |
---|
90 | | - /* Bit 27 - Memory write to region 3 defined by MC registers. */ |
---|
91 | | - FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION3 = 0x08000000, |
---|
92 | | - |
---|
93 | | - /* Bit 28 - Memory write from any client other than MCIF */ |
---|
94 | | - FBC_IDLE_FORCE_MEMORY_WRITE_OTHER_THAN_MCIF = 0x10000000, |
---|
95 | | - /* Bit 29 - CG statics screen signal is inactive */ |
---|
96 | | - FBC_IDLE_FORCE_CG_STATIC_SCREEN_IS_INACTIVE = 0x20000000, |
---|
97 | | -}; |
---|
98 | | - |
---|
99 | | - |
---|
100 | 68 | static uint32_t align_to_chunks_number_per_line(uint32_t pixels) |
---|
101 | 69 | { |
---|
102 | 70 | return 256 * ((pixels + 255) / 256); |
---|
103 | 71 | } |
---|
104 | 72 | |
---|
105 | | -static void reset_lb_on_vblank(struct dc_context *ctx) |
---|
| 73 | +static void reset_lb_on_vblank(struct compressor *compressor, uint32_t crtc_inst) |
---|
106 | 74 | { |
---|
107 | | - uint32_t value, frame_count; |
---|
| 75 | + uint32_t value; |
---|
| 76 | + uint32_t frame_count; |
---|
| 77 | + uint32_t status_pos; |
---|
108 | 78 | uint32_t retry = 0; |
---|
109 | | - uint32_t status_pos = |
---|
110 | | - dm_read_reg(ctx, mmCRTC_STATUS_POSITION); |
---|
| 79 | + struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor); |
---|
| 80 | + |
---|
| 81 | + cp110->offsets = reg_offsets[crtc_inst]; |
---|
| 82 | + |
---|
| 83 | + status_pos = dm_read_reg(compressor->ctx, DCP_REG(mmCRTC_STATUS_POSITION)); |
---|
111 | 84 | |
---|
112 | 85 | |
---|
113 | 86 | /* Only if CRTC is enabled and counter is moving we wait for one frame. */ |
---|
114 | | - if (status_pos != dm_read_reg(ctx, mmCRTC_STATUS_POSITION)) { |
---|
| 87 | + if (status_pos != dm_read_reg(compressor->ctx, DCP_REG(mmCRTC_STATUS_POSITION))) { |
---|
115 | 88 | /* Resetting LB on VBlank */ |
---|
116 | | - value = dm_read_reg(ctx, mmLB_SYNC_RESET_SEL); |
---|
| 89 | + value = dm_read_reg(compressor->ctx, DCP_REG(mmLB_SYNC_RESET_SEL)); |
---|
117 | 90 | set_reg_field_value(value, 3, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL); |
---|
118 | 91 | set_reg_field_value(value, 1, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL2); |
---|
119 | | - dm_write_reg(ctx, mmLB_SYNC_RESET_SEL, value); |
---|
| 92 | + dm_write_reg(compressor->ctx, DCP_REG(mmLB_SYNC_RESET_SEL), value); |
---|
120 | 93 | |
---|
121 | | - frame_count = dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT); |
---|
| 94 | + frame_count = dm_read_reg(compressor->ctx, DCP_REG(mmCRTC_STATUS_FRAME_COUNT)); |
---|
122 | 95 | |
---|
123 | 96 | |
---|
124 | 97 | for (retry = 10000; retry > 0; retry--) { |
---|
125 | | - if (frame_count != dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT)) |
---|
| 98 | + if (frame_count != dm_read_reg(compressor->ctx, DCP_REG(mmCRTC_STATUS_FRAME_COUNT))) |
---|
126 | 99 | break; |
---|
127 | 100 | udelay(10); |
---|
128 | 101 | } |
---|
.. | .. |
---|
130 | 103 | dm_error("Frame count did not increase for 100ms.\n"); |
---|
131 | 104 | |
---|
132 | 105 | /* Resetting LB on VBlank */ |
---|
133 | | - value = dm_read_reg(ctx, mmLB_SYNC_RESET_SEL); |
---|
| 106 | + value = dm_read_reg(compressor->ctx, DCP_REG(mmLB_SYNC_RESET_SEL)); |
---|
134 | 107 | set_reg_field_value(value, 2, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL); |
---|
135 | 108 | set_reg_field_value(value, 0, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL2); |
---|
136 | | - dm_write_reg(ctx, mmLB_SYNC_RESET_SEL, value); |
---|
137 | | - |
---|
| 109 | + dm_write_reg(compressor->ctx, DCP_REG(mmLB_SYNC_RESET_SEL), value); |
---|
138 | 110 | } |
---|
139 | | - |
---|
140 | 111 | } |
---|
141 | 112 | |
---|
142 | 113 | static void wait_for_fbc_state_changed( |
---|
.. | .. |
---|
226 | 197 | uint32_t addr; |
---|
227 | 198 | uint32_t value, misc_value; |
---|
228 | 199 | |
---|
229 | | - |
---|
230 | 200 | addr = mmFBC_CNTL; |
---|
231 | 201 | value = dm_read_reg(compressor->ctx, addr); |
---|
232 | 202 | set_reg_field_value(value, 1, FBC_CNTL, FBC_GRPH_COMP_EN); |
---|
| 203 | + /* params->inst is valid HW CRTC instance start from 0 */ |
---|
233 | 204 | set_reg_field_value( |
---|
234 | 205 | value, |
---|
235 | 206 | params->inst, |
---|
.. | .. |
---|
238 | 209 | |
---|
239 | 210 | /* Keep track of enum controller_id FBC is attached to */ |
---|
240 | 211 | compressor->is_enabled = true; |
---|
241 | | - compressor->attached_inst = params->inst; |
---|
242 | | - cp110->offsets = reg_offsets[params->inst]; |
---|
| 212 | + /* attached_inst is SW CRTC instance start from 1 |
---|
| 213 | + * 0 = CONTROLLER_ID_UNDEFINED means not attached crtc |
---|
| 214 | + */ |
---|
| 215 | + compressor->attached_inst = params->inst + CONTROLLER_ID_D0; |
---|
243 | 216 | |
---|
244 | 217 | /* Toggle it as there is bug in HW */ |
---|
245 | 218 | set_reg_field_value(value, 0, FBC_CNTL, FBC_GRPH_COMP_EN); |
---|
.. | .. |
---|
268 | 241 | void dce110_compressor_disable_fbc(struct compressor *compressor) |
---|
269 | 242 | { |
---|
270 | 243 | struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor); |
---|
| 244 | + uint32_t crtc_inst = 0; |
---|
271 | 245 | |
---|
272 | 246 | if (compressor->options.bits.FBC_SUPPORT) { |
---|
273 | | - if (dce110_compressor_is_fbc_enabled_in_hw(compressor, NULL)) { |
---|
| 247 | + if (dce110_compressor_is_fbc_enabled_in_hw(compressor, &crtc_inst)) { |
---|
274 | 248 | uint32_t reg_data; |
---|
275 | 249 | /* Turn off compression */ |
---|
276 | 250 | reg_data = dm_read_reg(compressor->ctx, mmFBC_CNTL); |
---|
.. | .. |
---|
284 | 258 | wait_for_fbc_state_changed(cp110, false); |
---|
285 | 259 | } |
---|
286 | 260 | |
---|
287 | | - /* Sync line buffer - dce100/110 only*/ |
---|
288 | | - reset_lb_on_vblank(compressor->ctx); |
---|
| 261 | + /* Sync line buffer which fbc was attached to dce100/110 only */ |
---|
| 262 | + if (crtc_inst > CONTROLLER_ID_UNDEFINED && crtc_inst < CONTROLLER_ID_D3) |
---|
| 263 | + reset_lb_on_vblank(compressor, |
---|
| 264 | + crtc_inst - CONTROLLER_ID_D0); |
---|
289 | 265 | } |
---|
290 | 266 | } |
---|
291 | 267 | |
---|
.. | .. |
---|
327 | 303 | uint32_t fbc_pitch = 0; |
---|
328 | 304 | uint32_t compressed_surf_address_low_part = |
---|
329 | 305 | compressor->compr_surface_address.addr.low_part; |
---|
| 306 | + |
---|
| 307 | + cp110->offsets = reg_offsets[params->inst]; |
---|
330 | 308 | |
---|
331 | 309 | /* Clear content first. */ |
---|
332 | 310 | dm_write_reg( |
---|
.. | .. |
---|
410 | 388 | value = dm_read_reg(compressor->ctx, addr); |
---|
411 | 389 | set_reg_field_value( |
---|
412 | 390 | value, |
---|
413 | | - fbc_trigger | |
---|
414 | | - FBC_IDLE_FORCE_GRPH_COMP_EN | |
---|
415 | | - FBC_IDLE_FORCE_SRC_SEL_CHANGE | |
---|
416 | | - FBC_IDLE_FORCE_MIN_COMPRESSION_CHANGE | |
---|
417 | | - FBC_IDLE_FORCE_ALPHA_COMP_EN | |
---|
418 | | - FBC_IDLE_FORCE_ZERO_ALPHA_CHUNK_SKIP_EN | |
---|
419 | | - FBC_IDLE_FORCE_FORCE_COPY_TO_COMP_BUF, |
---|
| 391 | + fbc_trigger, |
---|
420 | 392 | FBC_IDLE_FORCE_CLEAR_MASK, |
---|
421 | 393 | FBC_IDLE_FORCE_CLEAR_MASK); |
---|
422 | 394 | dm_write_reg(compressor->ctx, addr, value); |
---|
.. | .. |
---|
549 | 521 | compressor->base.channel_interleave_size = 0; |
---|
550 | 522 | compressor->base.dram_channels_num = 0; |
---|
551 | 523 | compressor->base.lpt_channels_num = 0; |
---|
552 | | - compressor->base.attached_inst = 0; |
---|
| 524 | + compressor->base.attached_inst = CONTROLLER_ID_UNDEFINED; |
---|
553 | 525 | compressor->base.is_enabled = false; |
---|
554 | 526 | compressor->base.funcs = &dce110_compressor_funcs; |
---|
555 | 527 | |
---|