1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include "dm_services.h"
27#include "dc.h"
28#include "core_types.h"
29#include "dce112_hw_sequencer.h"
30
31#include "dce110/dce110_hw_sequencer.h"
32
33
34#include "dce/dce_11_2_d.h"
35#include "dce/dce_11_2_sh_mask.h"
36
37struct dce112_hw_seq_reg_offsets {
38 uint32_t crtc;
39};
40
41
42static const struct dce112_hw_seq_reg_offsets reg_offsets[] = {
43{
44 .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
45},
46{
47 .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
48},
49{
50 .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
51},
52{
53 .crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
54},
55{
56 .crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
57},
58{
59 .crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
60}
61};
62#define HW_REG_CRTC(reg, id)\
63 (reg + reg_offsets[id].crtc)
64
65
66
67
68
69static void dce112_init_pte(struct dc_context *ctx)
70{
71 uint32_t addr;
72 uint32_t value = 0;
73 uint32_t chunk_int = 0;
74 uint32_t chunk_mul = 0;
75
76 addr = mmDVMM_PTE_REQ;
77 value = dm_read_reg(ctx, addr);
78
79 chunk_int = get_reg_field_value(
80 value,
81 DVMM_PTE_REQ,
82 HFLIP_PTEREQ_PER_CHUNK_INT);
83
84 chunk_mul = get_reg_field_value(
85 value,
86 DVMM_PTE_REQ,
87 HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
88
89 if (chunk_int != 0x4 || chunk_mul != 0x4) {
90
91 set_reg_field_value(
92 value,
93 255,
94 DVMM_PTE_REQ,
95 MAX_PTEREQ_TO_ISSUE);
96
97 set_reg_field_value(
98 value,
99 4,
100 DVMM_PTE_REQ,
101 HFLIP_PTEREQ_PER_CHUNK_INT);
102
103 set_reg_field_value(
104 value,
105 4,
106 DVMM_PTE_REQ,
107 HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
108
109 dm_write_reg(ctx, addr, value);
110 }
111}
112
113static bool dce112_enable_display_power_gating(
114 struct dc *dc,
115 uint8_t controller_id,
116 struct dc_bios *dcb,
117 enum pipe_gating_control power_gating)
118{
119 enum bp_result bp_result = BP_RESULT_OK;
120 enum bp_pipe_control_action cntl;
121 struct dc_context *ctx = dc->ctx;
122
123 if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
124 return true;
125
126 if (power_gating == PIPE_GATING_CONTROL_INIT)
127 cntl = ASIC_PIPE_INIT;
128 else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
129 cntl = ASIC_PIPE_ENABLE;
130 else
131 cntl = ASIC_PIPE_DISABLE;
132
133 if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0){
134
135 bp_result = dcb->funcs->enable_disp_power_gating(
136 dcb, controller_id + 1, cntl);
137
138
139
140
141 dm_write_reg(ctx,
142 HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id),
143 0);
144 }
145
146 if (power_gating != PIPE_GATING_CONTROL_ENABLE)
147 dce112_init_pte(ctx);
148
149 if (bp_result == BP_RESULT_OK)
150 return true;
151 else
152 return false;
153}
154
155void dce112_hw_sequencer_construct(struct dc *dc)
156{
157
158
159
160 dce110_hw_sequencer_construct(dc);
161 dc->hwss.enable_display_power_gating = dce112_enable_display_power_gating;
162}
163
164