File drivers/gpu/alga/amd/atombios/tables/pp.h changed (mode: 100644) (index 541cfd7..0093dbb) |
... |
... |
struct pp_thermal_ctrler { |
67 |
67 |
#define PP_PLATFORM_CAPS_HW_DC BIT(5) |
#define PP_PLATFORM_CAPS_HW_DC BIT(5) |
68 |
68 |
#define PP_PLATFORM_CAPS_GEMINI_PRIMARY BIT(6) |
#define PP_PLATFORM_CAPS_GEMINI_PRIMARY BIT(6) |
69 |
69 |
#define PP_PLATFORM_CAPS_STEP_VDDC BIT(7) |
#define PP_PLATFORM_CAPS_STEP_VDDC BIT(7) |
70 |
|
/* XXX:should not be used, use voltage_info table */ |
|
71 |
|
#define PP_PLATFORM_CAPS_VOLTAGE_CTL BIT(8) |
|
|
70 |
|
/* XXX:should not be used, use volt_info tbl */ |
|
71 |
|
#define PP_PLATFORM_CAPS_VOLT_CTL BIT(8) |
72 |
72 |
#define PP_PLATFORM_CAPS_SIDEPORT_CTL BIT(9) |
#define PP_PLATFORM_CAPS_SIDEPORT_CTL BIT(9) |
73 |
73 |
#define PP_PLATFORM_CAPS_TURNOFFPLL_ASPML1 BIT(10) |
#define PP_PLATFORM_CAPS_TURNOFFPLL_ASPML1 BIT(10) |
74 |
74 |
#define PP_PLATFORM_CAPS_HTLINK_CTL BIT(11) |
#define PP_PLATFORM_CAPS_HTLINK_CTL BIT(11) |
75 |
|
/* XXX:should not be used, use voltage_info table */ |
|
|
75 |
|
/* XXX:should not be used, use volt_info tbl */ |
76 |
76 |
#define PP_PLATFORM_CAPS_MVDD_CTL BIT(12) |
#define PP_PLATFORM_CAPS_MVDD_CTL BIT(12) |
77 |
77 |
/* ho to boot state on alerts (e.g. on an AC->DC transition) */ |
/* ho to boot state on alerts (e.g. on an AC->DC transition) */ |
78 |
78 |
#define PP_PLATFORM_CAPS_GOTO_BOOT_ON_ALERT BIT(13) |
#define PP_PLATFORM_CAPS_GOTO_BOOT_ON_ALERT BIT(13) |
|
... |
... |
struct pp_thermal_ctrler { |
80 |
80 |
#define _PP_PLATFORM_CAPS_DONT_WAIT_FOR_VBLANK_ON_ALERT BIT(14) |
#define _PP_PLATFORM_CAPS_DONT_WAIT_FOR_VBLANK_ON_ALERT BIT(14) |
81 |
81 |
/* |
/* |
82 |
82 |
* does the driver control vddci independently from vddc |
* does the driver control vddci independently from vddc |
83 |
|
* XXX:should not be used, use voltage_info table |
|
|
83 |
|
* XXX:should not be used, use volt_info tbl |
84 |
84 |
*/ |
*/ |
85 |
85 |
#define PP_PLATFORM_CAPS_VDDCI_CTL BIT(15) |
#define PP_PLATFORM_CAPS_VDDCI_CTL BIT(15) |
86 |
86 |
/* enable the 'regulator hot' feature */ |
/* enable the 'regulator hot' feature */ |
87 |
87 |
#define PP_PLATFORM_CAPS_REGULATOR_HOT BIT(16) |
#define PP_PLATFORM_CAPS_REGULATOR_HOT BIT(16) |
88 |
88 |
/* does the driver supports baco state */ |
/* does the driver supports baco state */ |
89 |
89 |
#define PP_PLATFORM_CAPS_BACO BIT(17) |
#define PP_PLATFORM_CAPS_BACO BIT(17) |
90 |
|
/* does the driver supports new cac voltage table */ |
|
91 |
|
#define PP_PLATFORM_CAPS_NEW_CAC_VOLTAGE BIT(18) |
|
|
90 |
|
/* does the driver supports new cac volt tbl */ |
|
91 |
|
#define PP_PLATFORM_CAPS_NEW_CAC_VOLT BIT(18) |
92 |
92 |
/* does the driver supports revert gpio5 polarity */ |
/* does the driver supports revert gpio5 polarity */ |
93 |
93 |
#define PP_PLATFORM_CAPS_REVERT_GPIO5_POLARITY BIT(19) |
#define PP_PLATFORM_CAPS_REVERT_GPIO5_POLARITY BIT(19) |
94 |
94 |
/* does the driver supports thermal2gpio17 */ |
/* does the driver supports thermal2gpio17 */ |
|
... |
... |
struct pp0 { |
114 |
114 |
__le16 desc_array_of; |
__le16 desc_array_of; |
115 |
115 |
|
|
116 |
116 |
__le16 back_bias_time; /* microseconds */ |
__le16 back_bias_time; /* microseconds */ |
117 |
|
__le16 voltage_time; /* microseconds */ |
|
|
117 |
|
__le16 volt_time; /* microseconds */ |
118 |
118 |
__le16 tbl_sz; /* used to selection proper revision */ |
__le16 tbl_sz; /* used to selection proper revision */ |
119 |
119 |
|
|
120 |
120 |
__le32 platform_caps; |
__le32 platform_caps; |
|
... |
... |
struct pp2 { |
138 |
138 |
} __packed; |
} __packed; |
139 |
139 |
|
|
140 |
140 |
/*----------------------------------------------------------------------------*/ |
/*----------------------------------------------------------------------------*/ |
141 |
|
struct voltage_on_clk_dep_tbl_entry { |
|
|
141 |
|
struct volt_on_clk_dep_tbl_entry { |
142 |
142 |
__le16 clk_low; |
__le16 clk_low; |
143 |
143 |
u8 clk_hi; |
u8 clk_hi; |
144 |
|
__le16 voltage_id; /* mV units or lkge idx */ |
|
|
144 |
|
__le16 volt_id; /* mV units or lkge idx */ |
145 |
145 |
} __packed; |
} __packed; |
146 |
146 |
|
|
147 |
|
struct voltage_on_clk_dep_tbl { |
|
|
147 |
|
struct volt_on_clk_dep_tbl { |
148 |
148 |
u8 entries_n; |
u8 entries_n; |
149 |
|
struct voltage_on_clk_dep_tbl_entry entries[]; |
|
|
149 |
|
struct volt_on_clk_dep_tbl_entry entries[]; |
150 |
150 |
} __packed; |
} __packed; |
151 |
151 |
|
|
152 |
152 |
struct vddc_phase_shed_limits_tbl_entry { |
struct vddc_phase_shed_limits_tbl_entry { |
153 |
|
__le16 voltage_mv; /* mV units only */ |
|
|
153 |
|
__le16 volt_mv; /* mV units only */ |
154 |
154 |
__le16 sclk_low; |
__le16 sclk_low; |
155 |
155 |
u8 sclk_hi; |
u8 sclk_hi; |
156 |
156 |
__le16 mclk_low; |
__le16 mclk_low; |
|
... |
... |
struct pp3 { |
168 |
168 |
__le16 vddc_dep_on_sclk_tbl_of; |
__le16 vddc_dep_on_sclk_tbl_of; |
169 |
169 |
__le16 vddci_dep_on_mclk_tbl_of; |
__le16 vddci_dep_on_mclk_tbl_of; |
170 |
170 |
__le16 vddc_dep_on_mclk_tbl_of; |
__le16 vddc_dep_on_mclk_tbl_of; |
171 |
|
__le16 clk_voltage_max_on_dc_tbl_of; |
|
|
171 |
|
__le16 clk_volt_max_on_dc_tbl_of; |
172 |
172 |
__le16 vddc_phase_shed_limits_tbl_of; |
__le16 vddc_phase_shed_limits_tbl_of; |
173 |
173 |
__le16 mvdd_dep_on_mclk_tbl_of; |
__le16 mvdd_dep_on_mclk_tbl_of; |
174 |
174 |
} __packed; |
} __packed; |
|
... |
... |
struct cac_lkge_tbl_entry { |
179 |
179 |
/* |
/* |
180 |
180 |
* We use this field for the "fake" standardized vddc for |
* We use this field for the "fake" standardized vddc for |
181 |
181 |
* power calculations. For ci and newer, we use this as the |
* power calculations. For ci and newer, we use this as the |
182 |
|
* real vddc value. In CI we read it as std_voltage_hi_sidd. |
|
|
182 |
|
* real vddc value. In CI we read it as std_volt_hi_sidd. |
183 |
183 |
*/ |
*/ |
184 |
184 |
__le16 vddc_mv; |
__le16 vddc_mv; |
185 |
185 |
/* |
/* |
186 |
186 |
* For ci and newer we use this as the "fake" standardized |
* For ci and newer we use this as the "fake" standardized |
187 |
|
* vddc value. In ci we read it as std_voltage_lo_sidd. |
|
|
187 |
|
* vddc value. In ci we read it as std_volt_lo_sidd. |
188 |
188 |
*/ |
*/ |
189 |
189 |
__le32 lkge; |
__le32 lkge; |
190 |
190 |
} __packed; |
} __packed; |
|
... |
... |
struct pp_clk_array { |
298 |
298 |
/*----------------------------------------------------------------------------*/ |
/*----------------------------------------------------------------------------*/ |
299 |
299 |
|
|
300 |
300 |
/*----------------------------------------------------------------------------*/ |
/*----------------------------------------------------------------------------*/ |
301 |
|
#define VOLTAGE_TYPE_VDDC 1 |
|
302 |
|
#define VOLTAGE_TYPE_MVDDC 2 |
|
303 |
|
#define VOLTAGE_TYPE_MVDDQ 3 |
|
304 |
|
#define VOLTAGE_TYPE_VDDCI 4 |
|
305 |
|
|
|
306 |
|
#define VOLTAGE_ACTION_SET 0 |
|
307 |
|
#define VOLTAGE_ACTION_INIT_REGULATOR 3 |
|
308 |
|
#define VOLTAGE_ACTION_SET_PHASE 4 |
|
309 |
|
#define VOLTAGE_ACTION_GET 6/* get from virtual voltage id */ |
|
310 |
|
struct voltage_params { |
|
|
301 |
|
#define VOLT_TYPE_VDDC 1 |
|
302 |
|
#define VOLT_TYPE_MVDDC 2 |
|
303 |
|
#define VOLT_TYPE_MVDDQ 3 |
|
304 |
|
#define VOLT_TYPE_VDDCI 4 |
|
305 |
|
|
|
306 |
|
#define VOLT_ACTION_SET 0 |
|
307 |
|
#define VOLT_ACTION_INIT_REGULATOR 3 |
|
308 |
|
#define VOLT_ACTION_SET_PHASE 4 |
|
309 |
|
#define VOLT_ACTION_GET 6/* get from virtual volt id */ |
|
310 |
|
struct volt_params { |
311 |
311 |
u8 type; |
u8 type; |
312 |
312 |
u8 action; |
u8 action; |
313 |
313 |
__le16 lvl; |
__le16 lvl; |
File drivers/gpu/alga/amd/atombios/vm.c changed (mode: 100644) (index 8d4f24f..734f29e) |
17 |
17 |
#include "tables/atb.h" |
#include "tables/atb.h" |
18 |
18 |
#include "tables/cmd.h" |
#include "tables/cmd.h" |
19 |
19 |
#include "tables/data.h" |
#include "tables/data.h" |
20 |
|
#include "tables/voltage_info.h" |
|
|
20 |
|
#include "tables/volt_info.h" |
21 |
21 |
#include "tables/i2c.h" |
#include "tables/i2c.h" |
22 |
22 |
#include "tables/pp.h" |
#include "tables/pp.h" |
23 |
23 |
|
|
|
26 |
26 |
|
|
27 |
27 |
#define DONT_HAVE_X_CTL 0 |
#define DONT_HAVE_X_CTL 0 |
28 |
28 |
#define HAVE_X_CTL 1 |
#define HAVE_X_CTL 1 |
29 |
|
static long have_x_ctl(struct atombios *atb, u8 voltage_type, u8 voltage_mode) |
|
|
29 |
|
static long have_x_ctl(struct atombios *atb, u8 volt_type, u8 volt_mode) |
30 |
30 |
{ |
{ |
31 |
31 |
u16 of; |
u16 of; |
32 |
32 |
struct master_data_tbl *data_tbl; |
struct master_data_tbl *data_tbl; |
33 |
|
struct voltage_info *info; |
|
|
33 |
|
struct volt_info *info; |
34 |
34 |
long r; |
long r; |
35 |
35 |
u16 tbl_sz; |
u16 tbl_sz; |
36 |
36 |
u8 *tbl_start; |
u8 *tbl_start; |
|
... |
... |
static long have_x_ctl(struct atombios *atb, u8 voltage_type, u8 voltage_mode) |
40 |
40 |
of = get_unaligned_le16(&atb->hdr->master_data_tbl_of); |
of = get_unaligned_le16(&atb->hdr->master_data_tbl_of); |
41 |
41 |
data_tbl = atb->adev.rom + of; |
data_tbl = atb->adev.rom + of; |
42 |
42 |
|
|
43 |
|
of = get_unaligned_le16(&data_tbl->list.voltage_info); |
|
|
43 |
|
of = get_unaligned_le16(&data_tbl->list.volt_info); |
44 |
44 |
info = atb->adev.rom + of; |
info = atb->adev.rom + of; |
45 |
45 |
|
|
46 |
|
dev_info(atb->adev.dev, "atombios:voltage_info (0x%04x) revision " |
|
47 |
|
"%u.%u\n", of, info->hdr.tbl_fmt_rev, |
|
48 |
|
info->hdr.tbl_content_rev); |
|
|
46 |
|
dev_info(atb->adev.dev, "atombios:volt_info (0x%04x) revision %u.%u\n", |
|
47 |
|
of, info->hdr.tbl_fmt_rev, info->hdr.tbl_content_rev); |
49 |
48 |
if (info->hdr.tbl_fmt_rev != 3 && info->hdr.tbl_content_rev != 1) { |
if (info->hdr.tbl_fmt_rev != 3 && info->hdr.tbl_content_rev != 1) { |
50 |
|
dev_err(atb->adev.dev, "atombios:voltage_info revision not supported"); |
|
|
49 |
|
dev_err(atb->adev.dev, "atombios:volt_info revision not supported"); |
51 |
50 |
r = -ATB_ERR; |
r = -ATB_ERR; |
52 |
51 |
goto unlock_mutex; |
goto unlock_mutex; |
53 |
52 |
} |
} |
54 |
53 |
|
|
55 |
54 |
/* |
/* |
56 |
55 |
* We have vddc control, if there is a gpio to control vddc. We get this |
* We have vddc control, if there is a gpio to control vddc. We get this |
57 |
|
* piece of information parsing the voltage info, looking for the |
|
58 |
|
* definition of a gpio control voltage object for vddc. |
|
|
56 |
|
* piece of information parsing the volt info, looking for the |
|
57 |
|
* definition of a gpio control volt object for vddc. |
59 |
58 |
*/ |
*/ |
60 |
59 |
tbl_start = (u8*)info; |
tbl_start = (u8*)info; |
61 |
60 |
tbl_sz = get_unaligned_le16(&info->hdr.sz); |
tbl_sz = get_unaligned_le16(&info->hdr.sz); |
62 |
|
of = offsetof(struct voltage_info, objs[0]); |
|
|
61 |
|
of = offsetof(struct volt_info, objs[0]); |
63 |
62 |
|
|
64 |
63 |
while (of < tbl_sz) { |
while (of < tbl_sz) { |
65 |
|
struct voltage_info_obj_hdr *obj_hdr; |
|
|
64 |
|
struct volt_info_obj_hdr *obj_hdr; |
66 |
65 |
|
|
67 |
|
obj_hdr = (struct voltage_info_obj_hdr*)(tbl_start + of); |
|
|
66 |
|
obj_hdr = (struct volt_info_obj_hdr*)(tbl_start + of); |
68 |
67 |
|
|
69 |
|
if (obj_hdr->type == voltage_type |
|
70 |
|
&& obj_hdr->mode == voltage_mode) { |
|
|
68 |
|
if (obj_hdr->type == volt_type |
|
69 |
|
&& obj_hdr->mode == volt_mode) { |
71 |
70 |
r = HAVE_X_CTL; |
r = HAVE_X_CTL; |
72 |
71 |
goto unlock_mutex; |
goto unlock_mutex; |
73 |
72 |
} |
} |
|
... |
... |
long atb_have_vddc_ctl(struct atombios *atb) |
86 |
85 |
{ |
{ |
87 |
86 |
long r; |
long r; |
88 |
87 |
|
|
89 |
|
r = have_x_ctl(atb, VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_GPIO_LUT); |
|
|
88 |
|
r = have_x_ctl(atb, VOLT_TYPE_VDDC, VOLT_OBJ_GPIO_LUT); |
90 |
89 |
switch (r) { |
switch (r) { |
91 |
90 |
case HAVE_X_CTL: |
case HAVE_X_CTL: |
92 |
91 |
r = ATB_HAVE_VDDC_CTL; |
r = ATB_HAVE_VDDC_CTL; |
|
... |
... |
long atb_have_mvddc_ctl(struct atombios *atb) |
103 |
102 |
{ |
{ |
104 |
103 |
long r; |
long r; |
105 |
104 |
|
|
106 |
|
r = have_x_ctl(atb, VOLTAGE_TYPE_MVDDC, VOLTAGE_OBJ_GPIO_LUT); |
|
|
105 |
|
r = have_x_ctl(atb, VOLT_TYPE_MVDDC, VOLT_OBJ_GPIO_LUT); |
107 |
106 |
switch (r) { |
switch (r) { |
108 |
107 |
case HAVE_X_CTL: |
case HAVE_X_CTL: |
109 |
108 |
r = ATB_HAVE_MVDDC_CTL; |
r = ATB_HAVE_MVDDC_CTL; |
|
... |
... |
long atb_have_vddci_ctl(struct atombios *atb) |
120 |
119 |
{ |
{ |
121 |
120 |
long r; |
long r; |
122 |
121 |
|
|
123 |
|
r = have_x_ctl(atb, VOLTAGE_TYPE_VDDCI, VOLTAGE_OBJ_GPIO_LUT); |
|
|
122 |
|
r = have_x_ctl(atb, VOLT_TYPE_VDDCI, VOLT_OBJ_GPIO_LUT); |
124 |
123 |
switch (r) { |
switch (r) { |
125 |
124 |
case HAVE_X_CTL: |
case HAVE_X_CTL: |
126 |
125 |
r = ATB_HAVE_VDDCI_CTL; |
r = ATB_HAVE_VDDCI_CTL; |
|
... |
... |
long atb_have_vddc_phase_shed_ctl(struct atombios *atb) |
137 |
136 |
{ |
{ |
138 |
137 |
long r; |
long r; |
139 |
138 |
|
|
140 |
|
r = have_x_ctl(atb, VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_GPIO_PHASE_SHED_LUT); |
|
|
139 |
|
r = have_x_ctl(atb, VOLT_TYPE_VDDC, VOLT_OBJ_GPIO_PHASE_SHED_LUT); |
141 |
140 |
switch (r) { |
switch (r) { |
142 |
141 |
case HAVE_X_CTL: |
case HAVE_X_CTL: |
143 |
142 |
r = ATB_HAVE_VDDC_PHASE_SHED_CTL; |
r = ATB_HAVE_VDDC_PHASE_SHED_CTL; |
|
... |
... |
long atb_have_vddc_phase_shed_ctl(struct atombios *atb) |
150 |
149 |
} |
} |
151 |
150 |
EXPORT_SYMBOL_GPL(atb_have_vddc_phase_shed_ctl); |
EXPORT_SYMBOL_GPL(atb_have_vddc_phase_shed_ctl); |
152 |
151 |
|
|
153 |
|
static long voltage_info_obj_gpio_parse(struct atombios *atb, |
|
154 |
|
struct voltage_info_obj_gpio *obj_gpio, |
|
155 |
|
struct atb_voltage_tbl *tbl) |
|
|
152 |
|
static long volt_info_obj_gpio_parse(struct atombios *atb, |
|
153 |
|
struct volt_info_obj_gpio *obj_gpio, |
|
154 |
|
struct atb_volt_tbl *tbl) |
156 |
155 |
{ |
{ |
157 |
156 |
u8 i; |
u8 i; |
158 |
157 |
|
|
159 |
|
if (obj_gpio->lut_entries_n > ATB_VOLTAGE_TBL_ENTRIES_N_MAX) { |
|
160 |
|
dev_err(atb->adev.dev, "atombios:voltage_info_obj_gpio has too many entries\n"); |
|
|
158 |
|
if (obj_gpio->lut_entries_n > ATB_VOLT_TBL_ENTRIES_N_MAX) { |
|
159 |
|
dev_err(atb->adev.dev, "atombios:volt_info_obj_gpio has too many entries\n"); |
161 |
160 |
return -ATB_ERR; |
return -ATB_ERR; |
162 |
161 |
} |
} |
163 |
162 |
|
|
|
... |
... |
static long voltage_info_obj_gpio_parse(struct atombios *atb, |
166 |
165 |
tbl->mask_low = get_unaligned_le32(&obj_gpio->gpio_mask); |
tbl->mask_low = get_unaligned_le32(&obj_gpio->gpio_mask); |
167 |
166 |
|
|
168 |
167 |
for (i = 0; i < obj_gpio->lut_entries_n; ++i) { |
for (i = 0; i < obj_gpio->lut_entries_n; ++i) { |
169 |
|
struct voltage_info_obj_gpio_lut_entry *entry; |
|
|
168 |
|
struct volt_info_obj_gpio_lut_entry *entry; |
170 |
169 |
|
|
171 |
170 |
entry = &obj_gpio->lut_entries[i]; |
entry = &obj_gpio->lut_entries[i]; |
172 |
|
tbl->entries[i].val_mv = get_unaligned_le16( |
|
173 |
|
&entry->voltage_val); |
|
174 |
|
tbl->entries[i].smio_low = get_unaligned_le32( |
|
175 |
|
&entry->voltage_id); |
|
|
171 |
|
tbl->entries[i].val_mv = get_unaligned_le16(&entry->volt_val); |
|
172 |
|
tbl->entries[i].smio_low = get_unaligned_le32(&entry->volt_id); |
176 |
173 |
} |
} |
177 |
174 |
return 0; |
return 0; |
178 |
175 |
} |
} |
179 |
176 |
|
|
180 |
|
static long x_gpio_tbl_get(struct atombios *atb, struct atb_voltage_tbl *tbl, |
|
181 |
|
u8 voltage_type, u8 voltage_mode) |
|
|
177 |
|
static long x_gpio_tbl_get(struct atombios *atb, struct atb_volt_tbl *tbl, |
|
178 |
|
u8 volt_type, u8 volt_mode) |
182 |
179 |
{ |
{ |
183 |
180 |
u16 of; |
u16 of; |
184 |
181 |
struct master_data_tbl *data_tbl; |
struct master_data_tbl *data_tbl; |
185 |
|
struct voltage_info *info; |
|
|
182 |
|
struct volt_info *info; |
186 |
183 |
long r; |
long r; |
187 |
184 |
u16 tbl_sz; |
u16 tbl_sz; |
188 |
185 |
u8 *tbl_start; |
u8 *tbl_start; |
|
... |
... |
static long x_gpio_tbl_get(struct atombios *atb, struct atb_voltage_tbl *tbl, |
192 |
189 |
of = get_unaligned_le16(&atb->hdr->master_data_tbl_of); |
of = get_unaligned_le16(&atb->hdr->master_data_tbl_of); |
193 |
190 |
data_tbl = atb->adev.rom + of; |
data_tbl = atb->adev.rom + of; |
194 |
191 |
|
|
195 |
|
of = get_unaligned_le16(&data_tbl->list.voltage_info); |
|
|
192 |
|
of = get_unaligned_le16(&data_tbl->list.volt_info); |
196 |
193 |
info = atb->adev.rom + of; |
info = atb->adev.rom + of; |
197 |
194 |
|
|
198 |
|
dev_info(atb->adev.dev, "atombios:voltage_info (0x%04x) revision " |
|
199 |
|
"%u.%u\n", of, info->hdr.tbl_fmt_rev, |
|
200 |
|
info->hdr.tbl_content_rev); |
|
|
195 |
|
dev_info(atb->adev.dev, "atombios:volt_info (0x%04x) revision %u.%u\n", |
|
196 |
|
of, info->hdr.tbl_fmt_rev, info->hdr.tbl_content_rev); |
201 |
197 |
if (info->hdr.tbl_fmt_rev != 3 && info->hdr.tbl_content_rev != 1) { |
if (info->hdr.tbl_fmt_rev != 3 && info->hdr.tbl_content_rev != 1) { |
202 |
|
dev_err(atb->adev.dev, "atombios:voltage_info revision not supported"); |
|
|
198 |
|
dev_err(atb->adev.dev, "atombios:volt_info revision not supported"); |
203 |
199 |
r = -ATB_ERR; |
r = -ATB_ERR; |
204 |
200 |
goto unlock_mutex; |
goto unlock_mutex; |
205 |
201 |
} |
} |
206 |
202 |
|
|
207 |
203 |
/* |
/* |
208 |
204 |
* We have vddc control, if there is a gpio to control vddc. We get this |
* We have vddc control, if there is a gpio to control vddc. We get this |
209 |
|
* piece of information parsing the voltage info, looking for the |
|
210 |
|
* definition of a gpio control voltage object for vddc. |
|
|
205 |
|
* piece of information parsing the volt info, looking for the |
|
206 |
|
* definition of a gpio control volt object for vddc. |
211 |
207 |
*/ |
*/ |
212 |
208 |
tbl_start = (u8*)info; |
tbl_start = (u8*)info; |
213 |
209 |
tbl_sz = get_unaligned_le16(&info->hdr.sz); |
tbl_sz = get_unaligned_le16(&info->hdr.sz); |
214 |
|
of = offsetof(struct voltage_info, objs[0]); |
|
|
210 |
|
of = offsetof(struct volt_info, objs[0]); |
215 |
211 |
|
|
216 |
212 |
memset(tbl, 0, sizeof(*tbl)); |
memset(tbl, 0, sizeof(*tbl)); |
217 |
213 |
r = 0; |
r = 0; |
218 |
214 |
|
|
219 |
215 |
while (of < tbl_sz) { |
while (of < tbl_sz) { |
220 |
|
struct voltage_info_obj_hdr *obj_hdr; |
|
|
216 |
|
struct volt_info_obj_hdr *obj_hdr; |
221 |
217 |
|
|
222 |
|
obj_hdr = (struct voltage_info_obj_hdr*)(tbl_start + of); |
|
|
218 |
|
obj_hdr = (struct volt_info_obj_hdr*)(tbl_start + of); |
223 |
219 |
|
|
224 |
|
if (obj_hdr->type == voltage_type |
|
225 |
|
&& obj_hdr->mode == voltage_mode) { |
|
226 |
|
struct voltage_info_obj_gpio *obj_gpio; |
|
|
220 |
|
if (obj_hdr->type == volt_type |
|
221 |
|
&& obj_hdr->mode == volt_mode) { |
|
222 |
|
struct volt_info_obj_gpio *obj_gpio; |
227 |
223 |
|
|
228 |
|
obj_gpio = (struct voltage_info_obj_gpio*)obj_hdr; |
|
229 |
|
r = voltage_info_obj_gpio_parse(atb, obj_gpio, tbl); |
|
|
224 |
|
obj_gpio = (struct volt_info_obj_gpio*)obj_hdr; |
|
225 |
|
r = volt_info_obj_gpio_parse(atb, obj_gpio, tbl); |
230 |
226 |
goto unlock_mutex; |
goto unlock_mutex; |
231 |
227 |
} |
} |
232 |
228 |
|
|
|
... |
... |
unlock_mutex: |
238 |
234 |
return r; |
return r; |
239 |
235 |
} |
} |
240 |
236 |
|
|
241 |
|
long atb_vddc_tbl_get(struct atombios *atb, struct atb_voltage_tbl *tbl) |
|
|
237 |
|
long atb_vddc_tbl_get(struct atombios *atb, struct atb_volt_tbl *tbl) |
242 |
238 |
{ |
{ |
243 |
|
return x_gpio_tbl_get(atb, tbl, VOLTAGE_TYPE_VDDC, |
|
244 |
|
VOLTAGE_OBJ_GPIO_LUT); |
|
|
239 |
|
return x_gpio_tbl_get(atb, tbl, VOLT_TYPE_VDDC, VOLT_OBJ_GPIO_LUT); |
245 |
240 |
} |
} |
246 |
241 |
EXPORT_SYMBOL_GPL(atb_vddc_tbl_get); |
EXPORT_SYMBOL_GPL(atb_vddc_tbl_get); |
247 |
242 |
|
|
248 |
|
long atb_vddci_tbl_get(struct atombios *atb, struct atb_voltage_tbl *tbl) |
|
|
243 |
|
long atb_vddci_tbl_get(struct atombios *atb, struct atb_volt_tbl *tbl) |
249 |
244 |
{ |
{ |
250 |
|
return x_gpio_tbl_get(atb, tbl, VOLTAGE_TYPE_VDDCI, |
|
251 |
|
VOLTAGE_OBJ_GPIO_LUT); |
|
|
245 |
|
return x_gpio_tbl_get(atb, tbl, VOLT_TYPE_VDDCI, VOLT_OBJ_GPIO_LUT); |
252 |
246 |
} |
} |
253 |
247 |
EXPORT_SYMBOL_GPL(atb_vddci_tbl_get); |
EXPORT_SYMBOL_GPL(atb_vddci_tbl_get); |
254 |
248 |
|
|
255 |
|
long atb_mvddc_tbl_get(struct atombios *atb, struct atb_voltage_tbl *tbl) |
|
|
249 |
|
long atb_mvddc_tbl_get(struct atombios *atb, struct atb_volt_tbl *tbl) |
256 |
250 |
{ |
{ |
257 |
|
return x_gpio_tbl_get(atb, tbl, VOLTAGE_TYPE_MVDDC, |
|
258 |
|
VOLTAGE_OBJ_GPIO_LUT); |
|
|
251 |
|
return x_gpio_tbl_get(atb, tbl, VOLT_TYPE_MVDDC, VOLT_OBJ_GPIO_LUT); |
259 |
252 |
} |
} |
260 |
253 |
EXPORT_SYMBOL_GPL(atb_mvddc_tbl_get); |
EXPORT_SYMBOL_GPL(atb_mvddc_tbl_get); |
261 |
254 |
|
|
262 |
|
long atb_vddc_phase_shed_tbl_get(struct atombios *atb, |
|
263 |
|
struct atb_voltage_tbl *tbl) |
|
|
255 |
|
long atb_vddc_phase_shed_tbl_get(struct atombios *atb, struct atb_volt_tbl *tbl) |
264 |
256 |
{ |
{ |
265 |
|
return x_gpio_tbl_get(atb, tbl, VOLTAGE_TYPE_VDDC, |
|
266 |
|
VOLTAGE_OBJ_GPIO_PHASE_SHED_LUT); |
|
|
257 |
|
return x_gpio_tbl_get(atb, tbl, VOLT_TYPE_VDDC, |
|
258 |
|
VOLT_OBJ_GPIO_PHASE_SHED_LUT); |
267 |
259 |
} |
} |
268 |
260 |
EXPORT_SYMBOL_GPL(atb_vddc_phase_shed_tbl_get); |
EXPORT_SYMBOL_GPL(atb_vddc_phase_shed_tbl_get); |
269 |
261 |
|
|
270 |
|
long voltage_get(struct atombios *atb, u8 type, u16 lkge_idx, u16 *mv) |
|
|
262 |
|
long volt_get(struct atombios *atb, u8 type, u16 lkge_idx, u16 *mv) |
271 |
263 |
{ |
{ |
272 |
264 |
u16 of; |
u16 of; |
273 |
265 |
struct master_cmd_tbl *cmd_tbl; |
struct master_cmd_tbl *cmd_tbl; |
274 |
|
struct common_cmd_tbl_hdr *voltage; |
|
275 |
|
struct voltage_params *ps; |
|
|
266 |
|
struct common_cmd_tbl_hdr *volt; |
|
267 |
|
struct volt_params *ps; |
276 |
268 |
long r; |
long r; |
277 |
269 |
|
|
278 |
270 |
of = get_unaligned_le16(&atb->hdr->master_cmd_tbl_of); |
of = get_unaligned_le16(&atb->hdr->master_cmd_tbl_of); |
279 |
271 |
cmd_tbl = atb->adev.rom + of; |
cmd_tbl = atb->adev.rom + of; |
280 |
|
of = get_unaligned_le16(&cmd_tbl->list.voltage); |
|
281 |
|
|
|
282 |
|
voltage = atb->adev.rom + of; |
|
283 |
|
dev_info(atb->adev.dev, "atombios:voltage (0x%04x) revision %u.%u\n", |
|
284 |
|
of, voltage->hdr.tbl_fmt_rev,voltage->hdr.tbl_content_rev); |
|
285 |
|
if (voltage->hdr.tbl_fmt_rev != 1 |
|
286 |
|
|| voltage->hdr.tbl_content_rev != 3) { |
|
287 |
|
dev_err(atb->adev.dev, "atombios:voltage revision not supported"); |
|
|
272 |
|
of = get_unaligned_le16(&cmd_tbl->list.volt); |
|
273 |
|
|
|
274 |
|
volt = atb->adev.rom + of; |
|
275 |
|
dev_info(atb->adev.dev, "atombios:volt (0x%04x) revision %u.%u\n", |
|
276 |
|
of, volt->hdr.tbl_fmt_rev,volt->hdr.tbl_content_rev); |
|
277 |
|
if (volt->hdr.tbl_fmt_rev != 1 || volt->hdr.tbl_content_rev != 3) { |
|
278 |
|
dev_err(atb->adev.dev, "atombios:volt revision not supported"); |
288 |
279 |
r = -ATB_ERR; |
r = -ATB_ERR; |
289 |
280 |
goto exit; |
goto exit; |
290 |
281 |
} |
} |
|
... |
... |
long voltage_get(struct atombios *atb, u8 type, u16 lkge_idx, u16 *mv) |
296 |
287 |
r = -ATB_ERR; |
r = -ATB_ERR; |
297 |
288 |
goto exit; |
goto exit; |
298 |
289 |
} |
} |
299 |
|
ps = (struct voltage_params *)atb->g_ctx.ps_top; |
|
|
290 |
|
ps = (struct volt_params *)atb->g_ctx.ps_top; |
300 |
291 |
ps->type = type; |
ps->type = type; |
301 |
|
ps->action = VOLTAGE_ACTION_GET; |
|
|
292 |
|
ps->action = VOLT_ACTION_GET; |
302 |
293 |
put_unaligned_le16(lkge_idx, &ps->lvl); |
put_unaligned_le16(lkge_idx, &ps->lvl); |
303 |
294 |
|
|
304 |
295 |
atb->g_ctx.fb_wnd = 0; |
atb->g_ctx.fb_wnd = 0; |
|
... |
... |
exit: |
316 |
307 |
return r; |
return r; |
317 |
308 |
} |
} |
318 |
309 |
|
|
319 |
|
long atb_voltage_get(struct atombios *atb, u8 type, u16 lkge_idx, u16 *lvl) |
|
|
310 |
|
long atb_volt_get(struct atombios *atb, u8 type, u16 lkge_idx, u16 *lvl) |
320 |
311 |
{ |
{ |
321 |
312 |
long r; |
long r; |
322 |
313 |
|
|
323 |
314 |
mutex_lock(&atb->mutex); |
mutex_lock(&atb->mutex); |
324 |
315 |
|
|
325 |
|
r = voltage_get(atb, type, lkge_idx, lvl); |
|
|
316 |
|
r = volt_get(atb, type, lkge_idx, lvl); |
326 |
317 |
|
|
327 |
318 |
mutex_unlock(&atb->mutex); |
mutex_unlock(&atb->mutex); |
328 |
319 |
return r; |
return r; |
329 |
320 |
} |
} |
330 |
|
EXPORT_SYMBOL_GPL(atb_voltage_get); |
|
|
321 |
|
EXPORT_SYMBOL_GPL(atb_volt_get); |
331 |
322 |
|
|
332 |
|
long atb_voltage_set(struct atombios *atb, u8 type, u16 lvl) |
|
|
323 |
|
long atb_volt_set(struct atombios *atb, u8 type, u16 lvl) |
333 |
324 |
{ |
{ |
334 |
325 |
u16 of; |
u16 of; |
335 |
326 |
struct master_cmd_tbl *cmd_tbl; |
struct master_cmd_tbl *cmd_tbl; |
336 |
|
struct common_cmd_tbl_hdr *voltage; |
|
337 |
|
struct voltage_params *ps; |
|
|
327 |
|
struct common_cmd_tbl_hdr *volt; |
|
328 |
|
struct volt_params *ps; |
338 |
329 |
long r; |
long r; |
339 |
330 |
|
|
340 |
331 |
mutex_lock(&atb->mutex); |
mutex_lock(&atb->mutex); |
341 |
332 |
|
|
342 |
333 |
of = get_unaligned_le16(&atb->hdr->master_cmd_tbl_of); |
of = get_unaligned_le16(&atb->hdr->master_cmd_tbl_of); |
343 |
334 |
cmd_tbl = atb->adev.rom + of; |
cmd_tbl = atb->adev.rom + of; |
344 |
|
of = get_unaligned_le16(&cmd_tbl->list.voltage); |
|
345 |
|
|
|
346 |
|
voltage = atb->adev.rom + of; |
|
347 |
|
dev_info(atb->adev.dev, "atombios:voltage (0x%04x) revision %u.%u\n", |
|
348 |
|
of, voltage->hdr.tbl_fmt_rev,voltage->hdr.tbl_content_rev); |
|
349 |
|
if (voltage->hdr.tbl_fmt_rev != 1 |
|
350 |
|
|| voltage->hdr.tbl_content_rev != 3) { |
|
351 |
|
dev_err(atb->adev.dev, "atombios:voltage revision not supported"); |
|
|
335 |
|
of = get_unaligned_le16(&cmd_tbl->list.volt); |
|
336 |
|
|
|
337 |
|
volt = atb->adev.rom + of; |
|
338 |
|
dev_info(atb->adev.dev, "atombios:volt (0x%04x) revision %u.%u\n", |
|
339 |
|
of, volt->hdr.tbl_fmt_rev, volt->hdr.tbl_content_rev); |
|
340 |
|
if (volt->hdr.tbl_fmt_rev != 1 || volt->hdr.tbl_content_rev != 3) { |
|
341 |
|
dev_err(atb->adev.dev, "atombios:volt revision not supported"); |
352 |
342 |
r = -ATB_ERR; |
r = -ATB_ERR; |
353 |
343 |
goto unlock_mutex; |
goto unlock_mutex; |
354 |
344 |
} |
} |
|
... |
... |
long atb_voltage_set(struct atombios *atb, u8 type, u16 lvl) |
360 |
350 |
r = -ATB_ERR; |
r = -ATB_ERR; |
361 |
351 |
goto unlock_mutex; |
goto unlock_mutex; |
362 |
352 |
} |
} |
363 |
|
ps = (struct voltage_params *)atb->g_ctx.ps_top; |
|
|
353 |
|
ps = (struct volt_params *)atb->g_ctx.ps_top; |
364 |
354 |
ps->type = type; |
ps->type = type; |
365 |
|
ps->action = VOLTAGE_ACTION_SET; |
|
|
355 |
|
ps->action = VOLT_ACTION_SET; |
366 |
356 |
put_unaligned_le16(lvl, &ps->lvl); |
put_unaligned_le16(lvl, &ps->lvl); |
367 |
357 |
|
|
368 |
358 |
atb->g_ctx.fb_wnd = 0; |
atb->g_ctx.fb_wnd = 0; |
|
... |
... |
unlock_mutex: |
376 |
366 |
mutex_unlock(&atb->mutex); |
mutex_unlock(&atb->mutex); |
377 |
367 |
return r; |
return r; |
378 |
368 |
} |
} |
379 |
|
EXPORT_SYMBOL_GPL(atb_voltage_set); |
|
|
369 |
|
EXPORT_SYMBOL_GPL(atb_volt_set); |
380 |
370 |
|
|
381 |
|
static long voltage_on_clk_dep_tbl_parse(struct atombios *atb, |
|
382 |
|
struct voltage_on_clk_dep_tbl *src, |
|
383 |
|
struct atb_voltage_on_clk_dep_tbl *dst) |
|
|
371 |
|
static long volt_on_clk_dep_tbl_parse(struct atombios *atb, |
|
372 |
|
struct atb_volt_on_clk_dep_tbl *dst, |
|
373 |
|
struct volt_on_clk_dep_tbl *src) |
384 |
374 |
{ |
{ |
385 |
375 |
u8 i; |
u8 i; |
386 |
376 |
|
|
|
... |
... |
static long voltage_on_clk_dep_tbl_parse(struct atombios *atb, |
396 |
386 |
dst->entries[i].clk = |
dst->entries[i].clk = |
397 |
387 |
get_unaligned_le16(&src->entries[i].clk_low) |
get_unaligned_le16(&src->entries[i].clk_low) |
398 |
388 |
| (src->entries[i].clk_hi << 16); |
| (src->entries[i].clk_hi << 16); |
399 |
|
dst->entries[i].voltage_id = get_unaligned_le16( |
|
400 |
|
&src->entries[i].voltage_id); |
|
|
389 |
|
dst->entries[i].volt_id = get_unaligned_le16( |
|
390 |
|
&src->entries[i].volt_id); |
401 |
391 |
} |
} |
402 |
392 |
return 0; |
return 0; |
403 |
393 |
} |
} |
404 |
394 |
|
|
405 |
395 |
long atb_vddc_dep_on_sclk_tbl_get(struct atombios *atb, |
long atb_vddc_dep_on_sclk_tbl_get(struct atombios *atb, |
406 |
|
struct atb_voltage_on_clk_dep_tbl *tbl) |
|
|
396 |
|
struct atb_volt_on_clk_dep_tbl *tbl) |
407 |
397 |
{ |
{ |
408 |
398 |
u16 of; |
u16 of; |
409 |
399 |
u16 pp_of; |
u16 pp_of; |
|
... |
... |
long atb_vddc_dep_on_sclk_tbl_get(struct atombios *atb, |
412 |
402 |
long r; |
long r; |
413 |
403 |
u16 tbl_sz; |
u16 tbl_sz; |
414 |
404 |
u16 vddc_dep_on_sclk_tbl_of; |
u16 vddc_dep_on_sclk_tbl_of; |
415 |
|
struct voltage_on_clk_dep_tbl *src_dep_tbl; |
|
|
405 |
|
struct volt_on_clk_dep_tbl *src_dep_tbl; |
416 |
406 |
|
|
417 |
407 |
mutex_lock(&atb->mutex); |
mutex_lock(&atb->mutex); |
418 |
408 |
|
|
|
... |
... |
long atb_vddc_dep_on_sclk_tbl_get(struct atombios *atb, |
448 |
438 |
if (vddc_dep_on_sclk_tbl_of) { |
if (vddc_dep_on_sclk_tbl_of) { |
449 |
439 |
src_dep_tbl = atb->adev.rom + pp_of + vddc_dep_on_sclk_tbl_of; |
src_dep_tbl = atb->adev.rom + pp_of + vddc_dep_on_sclk_tbl_of; |
450 |
440 |
|
|
451 |
|
r = voltage_on_clk_dep_tbl_parse(atb, src_dep_tbl, tbl); |
|
|
441 |
|
r = volt_on_clk_dep_tbl_parse(atb, tbl, src_dep_tbl); |
452 |
442 |
} |
} |
453 |
443 |
|
|
454 |
444 |
unlock_mutex: |
unlock_mutex: |
|
... |
... |
static long vddc_phase_shed_limits_tbl_parse(struct atombios *atb, |
607 |
597 |
|
|
608 |
598 |
for (i = 0; i < dst->entries_n; ++i) { |
for (i = 0; i < dst->entries_n; ++i) { |
609 |
599 |
dst->entries[i].vddc_mv = get_unaligned_le16( |
dst->entries[i].vddc_mv = get_unaligned_le16( |
610 |
|
&src->entries[i].voltage_mv); |
|
|
600 |
|
&src->entries[i].volt_mv); |
611 |
601 |
dst->entries[i].sclk = |
dst->entries[i].sclk = |
612 |
602 |
get_unaligned_le16(&src->entries[i].sclk_low) |
get_unaligned_le16(&src->entries[i].sclk_low) |
613 |
603 |
| (src->entries[i].sclk_hi << 16); |
| (src->entries[i].sclk_hi << 16); |
File drivers/gpu/alga/amd/si/dyn_pm/ctx.c changed (mode: 100644) (index 11ffca2..367206a) |
39 |
39 |
#include "private.h" |
#include "private.h" |
40 |
40 |
|
|
41 |
41 |
#ifdef CONFIG_ALGA_AMD_SI_DYN_PM_LOG |
#ifdef CONFIG_ALGA_AMD_SI_DYN_PM_LOG |
42 |
|
#include "smc_voltage.h" |
|
|
42 |
|
#include "smc_volt.h" |
43 |
43 |
static void atb_pp_state_dump(struct atb_pp_state *s, char *name) |
static void atb_pp_state_dump(struct atb_pp_state *s, char *name) |
44 |
44 |
{ |
{ |
45 |
45 |
u8 lvl_idx; |
u8 lvl_idx; |
|
... |
... |
static void atb_pp_state_dump(struct atb_pp_state *s, char *name) |
59 |
59 |
} |
} |
60 |
60 |
} |
} |
61 |
61 |
|
|
62 |
|
static void atb_voltage_on_clk_dep_tbl_dump( |
|
63 |
|
struct atb_voltage_on_clk_dep_tbl *tbl) |
|
|
62 |
|
static void atb_volt_on_clk_dep_tbl_dump(struct atb_volt_on_clk_dep_tbl *tbl) |
64 |
63 |
{ |
{ |
65 |
64 |
u8 entry_idx; |
u8 entry_idx; |
66 |
65 |
for (entry_idx = 0; entry_idx < tbl->entries_n; ++entry_idx) { |
for (entry_idx = 0; entry_idx < tbl->entries_n; ++entry_idx) { |
67 |
|
struct atb_voltage_on_clk_dep *step; |
|
|
66 |
|
struct atb_volt_on_clk_dep *step; |
68 |
67 |
|
|
69 |
68 |
step = &tbl->entries[entry_idx]; |
step = &tbl->entries[entry_idx]; |
70 |
|
if (IS_VDDC_LKGE_IDX(step->voltage_id)) { |
|
|
69 |
|
if (IS_VDDC_LKGE_IDX(step->volt_id)) { |
71 |
70 |
LOG("vddc_dep_on_sclk[%u]:clk=%ukHz voltage=0x%04x(leakage index)", |
LOG("vddc_dep_on_sclk[%u]:clk=%ukHz voltage=0x%04x(leakage index)", |
72 |
|
entry_idx, step->clk * 10, step->voltage_id); |
|
|
71 |
|
entry_idx, step->clk * 10, step->volt_id); |
73 |
72 |
} else { |
} else { |
74 |
73 |
LOG("vddc_dep_on_sclk[%u]:clk=%ukHz voltage=%umV", |
LOG("vddc_dep_on_sclk[%u]:clk=%ukHz voltage=%umV", |
75 |
|
entry_idx, step->clk * 10, step->voltage_id); |
|
|
74 |
|
entry_idx, step->clk * 10, step->volt_id); |
76 |
75 |
} |
} |
77 |
76 |
} |
} |
78 |
77 |
} |
} |
|
... |
... |
static void atb_vddc_phase_shed_limits_tbl_dump( |
103 |
102 |
} |
} |
104 |
103 |
} |
} |
105 |
104 |
|
|
106 |
|
static void atb_voltage_tbl_dump(struct atb_voltage_tbl *tbl, char *name) |
|
|
105 |
|
static void atb_volt_tbl_dump(struct atb_volt_tbl *tbl, char *name) |
107 |
106 |
{ |
{ |
108 |
107 |
u8 entry_idx; |
u8 entry_idx; |
109 |
108 |
|
|
110 |
|
LOG("atb_voltage_%s:phase_delay=%u mask_low=0x%08x", name, |
|
|
109 |
|
LOG("atb_volt_%s:phase_delay=%u mask_low=0x%08x", name, |
111 |
110 |
tbl->phase_delay, tbl->mask_low); |
tbl->phase_delay, tbl->mask_low); |
112 |
111 |
for (entry_idx = 0; entry_idx < tbl->entries_n; ++entry_idx) { |
for (entry_idx = 0; entry_idx < tbl->entries_n; ++entry_idx) { |
113 |
|
struct atb_voltage_tbl_entry *entry; |
|
|
112 |
|
struct atb_volt_tbl_entry *entry; |
114 |
113 |
|
|
115 |
114 |
entry = &tbl->entries[entry_idx]; |
entry = &tbl->entries[entry_idx]; |
116 |
|
LOG("atb_voltage_%s[%u]:smio_low=0x%08x val_mv=%u", |
|
|
115 |
|
LOG("atb_volt_%s[%u]:smio_low=0x%08x val_mv=%u", |
117 |
116 |
name, entry_idx, entry->smio_low, entry->val_mv); |
name, entry_idx, entry->smio_low, entry->val_mv); |
118 |
117 |
} |
} |
119 |
118 |
} |
} |
120 |
119 |
#else |
#else |
121 |
120 |
static void atb_pp_state_dump(struct atb_pp_state *s, char *name){} |
static void atb_pp_state_dump(struct atb_pp_state *s, char *name){} |
122 |
|
static void atb_voltage_on_clk_dep_tbl_dump( |
|
123 |
|
struct atb_voltage_on_clk_dep_tbl *tbl){} |
|
|
121 |
|
static void atb_volt_on_clk_dep_tbl_dump( |
|
122 |
|
struct atb_volt_on_clk_dep_tbl *tbl){} |
124 |
123 |
static void atb_cac_lkge_tbl_dump(struct atb_cac_lkge_tbl *tbl){} |
static void atb_cac_lkge_tbl_dump(struct atb_cac_lkge_tbl *tbl){} |
125 |
124 |
static void atb_vddc_phase_shed_limits_tbl_dump( |
static void atb_vddc_phase_shed_limits_tbl_dump( |
126 |
125 |
struct atb_vddc_phase_shed_limits_tbl *tbl){} |
struct atb_vddc_phase_shed_limits_tbl *tbl){} |
127 |
|
static void atb_voltage_tbl_dump(struct atb_voltage_tbl *tbl, char *name){} |
|
|
126 |
|
static void atb_volt_tbl_dump(struct atb_volt_tbl *tbl, char *name){} |
128 |
127 |
#endif |
#endif |
129 |
128 |
|
|
130 |
|
static long voltages_ctl_caps_get(struct ctx *ctx) |
|
|
129 |
|
static long volts_ctl_caps_get(struct ctx *ctx) |
131 |
130 |
{ |
{ |
132 |
131 |
struct dev_drv_data *dd; |
struct dev_drv_data *dd; |
133 |
132 |
long r; |
long r; |
|
... |
... |
static long voltages_ctl_caps_get(struct ctx *ctx) |
141 |
140 |
return -SI_ERR; |
return -SI_ERR; |
142 |
141 |
} else if (r == ATB_HAVE_VDDC_CTL) { |
} else if (r == ATB_HAVE_VDDC_CTL) { |
143 |
142 |
LOG("vddc control supported"); |
LOG("vddc control supported"); |
144 |
|
ctx->voltage_caps |= VOLTAGE_CAPS_VDDC_CTL_ENA; |
|
|
143 |
|
ctx->volt_caps |= VOLT_CAPS_VDDC_CTL_ENA; |
145 |
144 |
} else if (r == ATB_DONT_HAVE_VDDC_CTL) { |
} else if (r == ATB_DONT_HAVE_VDDC_CTL) { |
146 |
145 |
LOG("vddc control unsupported"); |
LOG("vddc control unsupported"); |
147 |
146 |
return 0; /* XXX:master switch */ |
return 0; /* XXX:master switch */ |
|
... |
... |
static long voltages_ctl_caps_get(struct ctx *ctx) |
155 |
154 |
return -SI_ERR; |
return -SI_ERR; |
156 |
155 |
} else if (r == ATB_HAVE_MVDDC_CTL) { |
} else if (r == ATB_HAVE_MVDDC_CTL) { |
157 |
156 |
LOG("mvdd control supported"); |
LOG("mvdd control supported"); |
158 |
|
ctx->voltage_caps |= VOLTAGE_CAPS_MVDD_CTL_ENA; |
|
|
157 |
|
ctx->volt_caps |= VOLT_CAPS_MVDD_CTL_ENA; |
159 |
158 |
} else if (r == ATB_DONT_HAVE_MVDDC_CTL) { |
} else if (r == ATB_DONT_HAVE_MVDDC_CTL) { |
160 |
159 |
LOG("mvdd control unsupported"); |
LOG("mvdd control unsupported"); |
161 |
160 |
} |
} |
|
... |
... |
static long voltages_ctl_caps_get(struct ctx *ctx) |
168 |
167 |
return -SI_ERR; |
return -SI_ERR; |
169 |
168 |
} else if (r == ATB_HAVE_VDDCI_CTL) { |
} else if (r == ATB_HAVE_VDDCI_CTL) { |
170 |
169 |
LOG("vddci control supported"); |
LOG("vddci control supported"); |
171 |
|
ctx->voltage_caps |= VOLTAGE_CAPS_VDDCI_CTL_ENA; |
|
|
170 |
|
ctx->volt_caps |= VOLT_CAPS_VDDCI_CTL_ENA; |
172 |
171 |
} else if (r == ATB_DONT_HAVE_VDDCI_CTL) { |
} else if (r == ATB_DONT_HAVE_VDDCI_CTL) { |
173 |
172 |
LOG("vddci control unsupported"); |
LOG("vddci control unsupported"); |
174 |
173 |
} |
} |
|
... |
... |
static long voltages_ctl_caps_get(struct ctx *ctx) |
181 |
180 |
return -SI_ERR; |
return -SI_ERR; |
182 |
181 |
} else if (r == ATB_HAVE_VDDC_PHASE_SHED_CTL) { |
} else if (r == ATB_HAVE_VDDC_PHASE_SHED_CTL) { |
183 |
182 |
LOG("vddc phase shedding supported"); |
LOG("vddc phase shedding supported"); |
184 |
|
ctx->voltage_caps |= VOLTAGE_CAPS_VDDC_PHASE_SHED_CTL_ENA; |
|
|
183 |
|
ctx->volt_caps |= VOLT_CAPS_VDDC_PHASE_SHED_CTL_ENA; |
185 |
184 |
} else if (r == ATB_DONT_HAVE_VDDC_PHASE_SHED_CTL) { |
} else if (r == ATB_DONT_HAVE_VDDC_PHASE_SHED_CTL) { |
186 |
185 |
LOG("vddc phase shedding unsupported"); |
LOG("vddc phase shedding unsupported"); |
187 |
186 |
} |
} |
|
... |
... |
long ctx_init(struct pci_dev *dev, struct ctx *ctx) |
508 |
507 |
} |
} |
509 |
508 |
LOG("powerplay platform capabilities is 0x%08x", ctx->platform_caps); |
LOG("powerplay platform capabilities is 0x%08x", ctx->platform_caps); |
510 |
509 |
|
|
511 |
|
r = voltages_ctl_caps_get(ctx); |
|
|
510 |
|
r = volts_ctl_caps_get(ctx); |
512 |
511 |
if (r == -SI_ERR) |
if (r == -SI_ERR) |
513 |
512 |
goto err; |
goto err; |
514 |
513 |
|
|
|
... |
... |
long ctx_init(struct pci_dev *dev, struct ctx *ctx) |
544 |
543 |
ctx->misc_caps |= MISC_CAPS_VRAM_IS_GDDR5; |
ctx->misc_caps |= MISC_CAPS_VRAM_IS_GDDR5; |
545 |
544 |
} |
} |
546 |
545 |
|
|
547 |
|
if (ctx->voltage_caps & VOLTAGE_CAPS_VDDC_CTL_ENA) { |
|
|
546 |
|
if (ctx->volt_caps & VOLT_CAPS_VDDC_CTL_ENA) { |
548 |
547 |
r = atb_vddc_tbl_get(dd->atb, &ctx->atb_vddc_tbl); |
r = atb_vddc_tbl_get(dd->atb, &ctx->atb_vddc_tbl); |
549 |
548 |
if (r == -ATB_ERR) { |
if (r == -ATB_ERR) { |
550 |
549 |
dev_err(&dev->dev, "dyn_pm:unable to fetch the vddc voltage table\n"); |
dev_err(&dev->dev, "dyn_pm:unable to fetch the vddc voltage table\n"); |
551 |
550 |
goto err; |
goto err; |
552 |
551 |
} |
} |
553 |
|
atb_voltage_tbl_dump(&ctx->atb_vddc_tbl, "vddc"); |
|
|
552 |
|
atb_volt_tbl_dump(&ctx->atb_vddc_tbl, "vddc"); |
554 |
553 |
} |
} |
555 |
554 |
|
|
556 |
|
if (ctx->voltage_caps & VOLTAGE_CAPS_MVDD_CTL_ENA) { |
|
|
555 |
|
if (ctx->volt_caps & VOLT_CAPS_MVDD_CTL_ENA) { |
557 |
556 |
r = atb_mvddc_tbl_get(dd->atb, &ctx->atb_mvddc_tbl); |
r = atb_mvddc_tbl_get(dd->atb, &ctx->atb_mvddc_tbl); |
558 |
557 |
if (r == -ATB_ERR) { |
if (r == -ATB_ERR) { |
559 |
558 |
dev_err(&dev->dev, "dyn_pm:unable to fetch the mvddc voltage table\n"); |
dev_err(&dev->dev, "dyn_pm:unable to fetch the mvddc voltage table\n"); |
560 |
559 |
goto err; |
goto err; |
561 |
560 |
} |
} |
562 |
|
atb_voltage_tbl_dump(&ctx->atb_mvddc_tbl, "mvddc"); |
|
|
561 |
|
atb_volt_tbl_dump(&ctx->atb_mvddc_tbl, "mvddc"); |
563 |
562 |
} |
} |
564 |
563 |
|
|
565 |
|
if (ctx->voltage_caps & VOLTAGE_CAPS_VDDCI_CTL_ENA) { |
|
|
564 |
|
if (ctx->volt_caps & VOLT_CAPS_VDDCI_CTL_ENA) { |
566 |
565 |
r = atb_vddci_tbl_get(dd->atb, &ctx->atb_vddci_tbl); |
r = atb_vddci_tbl_get(dd->atb, &ctx->atb_vddci_tbl); |
567 |
566 |
if (r == -ATB_ERR) { |
if (r == -ATB_ERR) { |
568 |
567 |
dev_err(&dev->dev, "dyn_pm:unable to fetch the vddci voltage table\n"); |
dev_err(&dev->dev, "dyn_pm:unable to fetch the vddci voltage table\n"); |
569 |
568 |
goto err; |
goto err; |
570 |
569 |
} |
} |
571 |
|
atb_voltage_tbl_dump(&ctx->atb_vddci_tbl, "vddci"); |
|
|
570 |
|
atb_volt_tbl_dump(&ctx->atb_vddci_tbl, "vddci"); |
572 |
571 |
} |
} |
573 |
572 |
|
|
574 |
|
if (ctx->voltage_caps & VOLTAGE_CAPS_VDDC_PHASE_SHED_CTL_ENA) { |
|
|
573 |
|
if (ctx->volt_caps & VOLT_CAPS_VDDC_PHASE_SHED_CTL_ENA) { |
575 |
574 |
r = atb_vddc_phase_shed_tbl_get(dd->atb, &ctx->atb_vddc_phase_shed_tbl); |
r = atb_vddc_phase_shed_tbl_get(dd->atb, &ctx->atb_vddc_phase_shed_tbl); |
576 |
575 |
if (r == -ATB_ERR) { |
if (r == -ATB_ERR) { |
577 |
576 |
dev_err(&dev->dev, "dyn_pm:unable to fetch the vddc phase shedding table\n"); |
dev_err(&dev->dev, "dyn_pm:unable to fetch the vddc phase shedding table\n"); |
578 |
577 |
goto err; |
goto err; |
579 |
578 |
} |
} |
580 |
|
atb_voltage_tbl_dump(&ctx->atb_vddc_phase_shed_tbl, |
|
|
579 |
|
atb_volt_tbl_dump(&ctx->atb_vddc_phase_shed_tbl, |
581 |
580 |
"vddc_phase_shed"); |
"vddc_phase_shed"); |
582 |
581 |
|
|
583 |
582 |
r = atb_vddc_phase_shed_limits_tbl_get(dd->atb, |
r = atb_vddc_phase_shed_limits_tbl_get(dd->atb, |
|
... |
... |
long ctx_init(struct pci_dev *dev, struct ctx *ctx) |
591 |
590 |
|
|
592 |
591 |
} |
} |
593 |
592 |
|
|
594 |
|
if (ctx->platform_caps & ATB_PP_PLATFORM_CAPS_NEW_CAC_VOLTAGE) { |
|
|
593 |
|
if (ctx->platform_caps & ATB_PP_PLATFORM_CAPS_NEW_CAC_VOLT) { |
595 |
594 |
r = atb_vddc_dep_on_sclk_tbl_get(dd->atb, |
r = atb_vddc_dep_on_sclk_tbl_get(dd->atb, |
596 |
595 |
&ctx->atb_vddc_dep_on_sclk_tbl); |
&ctx->atb_vddc_dep_on_sclk_tbl); |
597 |
596 |
if (r == -ATB_ERR) { |
if (r == -ATB_ERR) { |
598 |
597 |
dev_err(&dev->dev, "dyn_pm:unable to fetch the vddc on sclk dependency table\n"); |
dev_err(&dev->dev, "dyn_pm:unable to fetch the vddc on sclk dependency table\n"); |
599 |
598 |
goto err_free_vddc_phase_shed_limits_tbl_entries; |
goto err_free_vddc_phase_shed_limits_tbl_entries; |
600 |
599 |
} |
} |
601 |
|
atb_voltage_on_clk_dep_tbl_dump(&ctx->atb_vddc_dep_on_sclk_tbl); |
|
|
600 |
|
atb_volt_on_clk_dep_tbl_dump(&ctx->atb_vddc_dep_on_sclk_tbl); |
602 |
601 |
} |
} |
603 |
602 |
|
|
604 |
603 |
r = atb_cac_lkge_tbl_get(dd->atb, &ctx->atb_cac_lkge_tbl); |
r = atb_cac_lkge_tbl_get(dd->atb, &ctx->atb_cac_lkge_tbl); |
|
... |
... |
err_free_cac_lkge_tbl_entries: |
662 |
661 |
if (ctx->atb_cac_lkge_tbl.entries_n) |
if (ctx->atb_cac_lkge_tbl.entries_n) |
663 |
662 |
kfree(ctx->atb_cac_lkge_tbl.entries); |
kfree(ctx->atb_cac_lkge_tbl.entries); |
664 |
663 |
err_free_vddc_dep_on_sclk_tbl_entries: |
err_free_vddc_dep_on_sclk_tbl_entries: |
665 |
|
if (ctx->platform_caps & ATB_PP_PLATFORM_CAPS_NEW_CAC_VOLTAGE) |
|
|
664 |
|
if (ctx->platform_caps & ATB_PP_PLATFORM_CAPS_NEW_CAC_VOLT) |
666 |
665 |
if (ctx->atb_cac_lkge_tbl.entries_n) |
if (ctx->atb_cac_lkge_tbl.entries_n) |
667 |
666 |
kfree(ctx->atb_cac_lkge_tbl.entries); |
kfree(ctx->atb_cac_lkge_tbl.entries); |
668 |
667 |
err_free_vddc_phase_shed_limits_tbl_entries: |
err_free_vddc_phase_shed_limits_tbl_entries: |
|
... |
... |
void ctx_free(struct ctx *ctx) |
676 |
675 |
{ |
{ |
677 |
676 |
if (ctx->atb_cac_lkge_tbl.entries_n) |
if (ctx->atb_cac_lkge_tbl.entries_n) |
678 |
677 |
kfree(ctx->atb_cac_lkge_tbl.entries); |
kfree(ctx->atb_cac_lkge_tbl.entries); |
679 |
|
if (ctx->platform_caps & ATB_PP_PLATFORM_CAPS_NEW_CAC_VOLTAGE) |
|
|
678 |
|
if (ctx->platform_caps & ATB_PP_PLATFORM_CAPS_NEW_CAC_VOLT) |
680 |
679 |
if (ctx->atb_vddc_dep_on_sclk_tbl.entries_n) |
if (ctx->atb_vddc_dep_on_sclk_tbl.entries_n) |
681 |
680 |
kfree(ctx->atb_vddc_dep_on_sclk_tbl.entries); |
kfree(ctx->atb_vddc_dep_on_sclk_tbl.entries); |
682 |
681 |
if (ctx->atb_vddc_phase_shed_limits_tbl.entries_n) |
if (ctx->atb_vddc_phase_shed_limits_tbl.entries_n) |
File drivers/gpu/alga/amd/si/dyn_pm/smc_state_tbl.c changed (mode: 100644) (index 567c730..8f5773d) |
... |
... |
static void smc_vddc_tbl_init(struct ctx *ctx, |
59 |
59 |
} |
} |
60 |
60 |
|
|
61 |
61 |
put_unaligned_be32(ctx->atb_vddc_tbl.mask_low, |
put_unaligned_be32(ctx->atb_vddc_tbl.mask_low, |
62 |
|
&smc_state_tbl->voltage_mask_tbl.mask_low[ |
|
63 |
|
SMC_VOLTAGE_MASK_VDDC]); |
|
|
62 |
|
&smc_state_tbl->volt_mask_tbl.mask_low[ |
|
63 |
|
SMC_VOLT_MASK_VDDC]); |
64 |
64 |
|
|
65 |
65 |
/* |
/* |
66 |
66 |
* The smc needs to know which step has the highest vddc output. |
* The smc needs to know which step has the highest vddc output. |
|
... |
... |
static void smc_mvdd_tbl_init(struct ctx *ctx, |
97 |
97 |
} |
} |
98 |
98 |
|
|
99 |
99 |
put_unaligned_be32(ctx->atb_mvddc_tbl.mask_low, |
put_unaligned_be32(ctx->atb_mvddc_tbl.mask_low, |
100 |
|
&smc_state_tbl->voltage_mask_tbl.mask_low[ |
|
101 |
|
SMC_VOLTAGE_MASK_MVDD]); |
|
|
100 |
|
&smc_state_tbl->volt_mask_tbl.mask_low[ |
|
101 |
|
SMC_VOLT_MASK_MVDD]); |
102 |
102 |
} |
} |
103 |
103 |
|
|
104 |
104 |
static void smc_vddci_tbl_init(struct ctx *ctx, |
static void smc_vddci_tbl_init(struct ctx *ctx, |
|
... |
... |
static void smc_vddci_tbl_init(struct ctx *ctx, |
120 |
120 |
} |
} |
121 |
121 |
|
|
122 |
122 |
put_unaligned_be32(ctx->atb_vddci_tbl.mask_low, |
put_unaligned_be32(ctx->atb_vddci_tbl.mask_low, |
123 |
|
&smc_state_tbl->voltage_mask_tbl.mask_low[ |
|
124 |
|
SMC_VOLTAGE_MASK_VDDCI]); |
|
|
123 |
|
&smc_state_tbl->volt_mask_tbl.mask_low[ |
|
124 |
|
SMC_VOLT_MASK_VDDCI]); |
125 |
125 |
} |
} |
126 |
126 |
|
|
127 |
127 |
static void smc_vddc_phase_shed_tbl_init(struct ctx *ctx, |
static void smc_vddc_phase_shed_tbl_init(struct ctx *ctx, |
|
... |
... |
static void smc_vddc_phase_shed_tbl_init(struct ctx *ctx, |
137 |
137 |
for (i = 0; i < ctx->atb_vddc_phase_shed_tbl.entries_n; ++i) { |
for (i = 0; i < ctx->atb_vddc_phase_shed_tbl.entries_n; ++i) { |
138 |
138 |
u32 smio_low; |
u32 smio_low; |
139 |
139 |
|
|
140 |
|
/* phase shedding params share smio_low with voltage levels */ |
|
|
140 |
|
/* phase shed params share smio_low with volt lvls */ |
141 |
141 |
smio_low = get_unaligned_be32(&smc_state_tbl->smio_low[i]); |
smio_low = get_unaligned_be32(&smc_state_tbl->smio_low[i]); |
142 |
142 |
smio_low |= ctx->atb_vddc_phase_shed_tbl.entries[i].smio_low; |
smio_low |= ctx->atb_vddc_phase_shed_tbl.entries[i].smio_low; |
143 |
143 |
put_unaligned_be32(smio_low, &smc_state_tbl->smio_low[i]); |
put_unaligned_be32(smio_low, &smc_state_tbl->smio_low[i]); |
|
... |
... |
static void smc_vddc_phase_shed_tbl_init(struct ctx *ctx, |
145 |
145 |
|
|
146 |
146 |
put_unaligned_be32(ctx->atb_vddc_phase_shed_tbl.mask_low, |
put_unaligned_be32(ctx->atb_vddc_phase_shed_tbl.mask_low, |
147 |
147 |
&smc_state_tbl->phase_mask_tbl.mask_low[ |
&smc_state_tbl->phase_mask_tbl.mask_low[ |
148 |
|
SMC_VOLTAGE_MASK_VDDC]); |
|
|
148 |
|
SMC_VOLT_MASK_VDDC]); |
149 |
149 |
} |
} |
150 |
150 |
|
|
151 |
151 |
/* |
/* |
152 |
|
* A voltage level step is a n-upplet of vddc/mvdd/vddci. Each voltage |
|
153 |
|
* (vddc/mvdd/vddci) have a bit mask stored in voltage_mask_tbl. Then all gpio |
|
154 |
|
* values needed to program a voltage level are stored in smio_low, and that |
|
|
152 |
|
* A volt lvl step is a n-upplet of vddc/mvdd/vddci. Each volt |
|
153 |
|
* (vddc/mvdd/vddci) have a bit mask stored in volt_mask_tbl. Then all gpio |
|
154 |
|
* values needed to program a volt lvl are stored in smio_low, and that |
155 |
155 |
* based on the previous mask. |
* based on the previous mask. |
156 |
|
* Idem for phase shedding step, except the gpio mask is stored in |
|
157 |
|
* phase_mask_tbl. smio_low masks are shared with the voltage levels, then |
|
|
156 |
|
* Idem for phase shed step, except the gpio mask is stored in |
|
157 |
|
* phase_mask_tbl. smio_low masks are shared with the volt lvls, then |
158 |
158 |
* must work together. |
* must work together. |
159 |
|
* The mV values are stored in smc level tables. |
|
|
159 |
|
* The mV values are stored in smc lvl tbls. |
160 |
160 |
*/ |
*/ |
161 |
|
static void smc_voltage_tbls_init(struct ctx *ctx, |
|
|
161 |
|
static void smc_volt_tbls_init(struct ctx *ctx, |
162 |
162 |
struct smc_state_tbl *smc_state_tbl) |
struct smc_state_tbl *smc_state_tbl) |
163 |
163 |
{ |
{ |
164 |
|
if (ctx->voltage_caps & VOLTAGE_CAPS_VDDC_CTL_ENA) |
|
|
164 |
|
if (ctx->volt_caps & VOLT_CAPS_VDDC_CTL_ENA) |
165 |
165 |
smc_vddc_tbl_init(ctx, smc_state_tbl); |
smc_vddc_tbl_init(ctx, smc_state_tbl); |
166 |
166 |
|
|
167 |
|
if (ctx->voltage_caps & VOLTAGE_CAPS_MVDD_CTL_ENA) |
|
|
167 |
|
if (ctx->volt_caps & VOLT_CAPS_MVDD_CTL_ENA) |
168 |
168 |
smc_mvdd_tbl_init(ctx, smc_state_tbl); |
smc_mvdd_tbl_init(ctx, smc_state_tbl); |
169 |
169 |
|
|
170 |
|
if (ctx->voltage_caps & VOLTAGE_CAPS_VDDCI_CTL_ENA) |
|
|
170 |
|
if (ctx->volt_caps & VOLT_CAPS_VDDCI_CTL_ENA) |
171 |
171 |
smc_vddci_tbl_init(ctx, smc_state_tbl); |
smc_vddci_tbl_init(ctx, smc_state_tbl); |
172 |
172 |
|
|
173 |
|
if (ctx->voltage_caps & VOLTAGE_CAPS_VDDC_PHASE_SHED_CTL_ENA) |
|
|
173 |
|
if (ctx->volt_caps & VOLT_CAPS_VDDC_PHASE_SHED_CTL_ENA) |
174 |
174 |
smc_vddc_phase_shed_tbl_init(ctx, smc_state_tbl); |
smc_vddc_phase_shed_tbl_init(ctx, smc_state_tbl); |
175 |
175 |
} |
} |
176 |
176 |
|
|
|
... |
... |
long smc_state_tbl_init(struct ctx *ctx, struct smc_state_tbl *tbl) |
178 |
178 |
{ |
{ |
179 |
179 |
long r; |
long r; |
180 |
180 |
|
|
181 |
|
smc_voltage_tbls_init(ctx, tbl); |
|
|
181 |
|
smc_volt_tbls_init(ctx, tbl); |
182 |
182 |
|
|
183 |
183 |
if (ctx->state & STATE_THERMAL_PROTECTION_ENA) |
if (ctx->state & STATE_THERMAL_PROTECTION_ENA) |
184 |
184 |
tbl->thermal_protection_type = |
tbl->thermal_protection_type = |
File drivers/gpu/alga/amd/si/dyn_pm/smc_volt.c renamed from drivers/gpu/alga/amd/si/dyn_pm/smc_voltage.c (similarity 77%) (mode: 100644) (index 6b42cc9..39f0498) |
34 |
34 |
|
|
35 |
35 |
#include "ctx.h" |
#include "ctx.h" |
36 |
36 |
#include "private.h" |
#include "private.h" |
37 |
|
#include "smc_voltage.h" |
|
|
37 |
|
#include "smc_volt.h" |
38 |
38 |
|
|
39 |
|
static long voltage_step_idx(struct atb_voltage_tbl *tbl, u16 val_mv) |
|
|
39 |
|
static long volt_step_idx(struct atb_volt_tbl *tbl, u16 val_mv) |
40 |
40 |
{ |
{ |
41 |
41 |
u8 step; |
u8 step; |
42 |
42 |
|
|
|
... |
... |
static long voltage_step_idx(struct atb_voltage_tbl *tbl, u16 val_mv) |
51 |
51 |
return 0; |
return 0; |
52 |
52 |
} |
} |
53 |
53 |
|
|
54 |
|
long smc_voltage_vddc_set_from_atb_id(struct ctx *ctx, struct smc_voltage *vddc, |
|
|
54 |
|
long smc_volt_vddc_set_from_atb_id(struct ctx *ctx, struct smc_volt *vddc, |
55 |
55 |
u32 vddc_id) |
u32 vddc_id) |
56 |
56 |
{ |
{ |
57 |
57 |
u16 vddc_mv; /* vddc in mV units, not lkge index */ |
u16 vddc_mv; /* vddc in mV units, not lkge index */ |
|
... |
... |
long smc_voltage_vddc_set_from_atb_id(struct ctx *ctx, struct smc_voltage *vddc, |
62 |
62 |
|
|
63 |
63 |
dd = pci_get_drvdata(ctx->dev); |
dd = pci_get_drvdata(ctx->dev); |
64 |
64 |
|
|
65 |
|
r = atb_voltage_get(dd->atb, ATB_VOLTAGE_TYPE_VDDC, vddc_id, |
|
|
65 |
|
r = atb_volt_get(dd->atb, ATB_VOLT_TYPE_VDDC, vddc_id, |
66 |
66 |
&vddc_mv); |
&vddc_mv); |
67 |
67 |
if (r == -ATB_ERR) { |
if (r == -ATB_ERR) { |
68 |
68 |
dev_err(&ctx->dev->dev, "dyn_pm:unable to find vddc mV value for leakage index 0x%04x\n", |
dev_err(&ctx->dev->dev, "dyn_pm:unable to find vddc mV value for leakage index 0x%04x\n", |
|
... |
... |
long smc_voltage_vddc_set_from_atb_id(struct ctx *ctx, struct smc_voltage *vddc, |
73 |
73 |
} else |
} else |
74 |
74 |
vddc_mv = vddc_id; |
vddc_mv = vddc_id; |
75 |
75 |
|
|
76 |
|
r = voltage_step_idx(&ctx->atb_vddc_tbl, vddc_mv); |
|
|
76 |
|
r = volt_step_idx(&ctx->atb_vddc_tbl, vddc_mv); |
77 |
77 |
if (r == -SI_ERR) { |
if (r == -SI_ERR) { |
78 |
78 |
dev_err(&ctx->dev->dev, "dyn_pm:unable to find powerfull enough vddc in atombios voltage table\n"); |
dev_err(&ctx->dev->dev, "dyn_pm:unable to find powerfull enough vddc in atombios voltage table\n"); |
79 |
79 |
return -SI_ERR; |
return -SI_ERR; |
|
... |
... |
long smc_voltage_vddc_set_from_atb_id(struct ctx *ctx, struct smc_voltage *vddc, |
84 |
84 |
return 0; |
return 0; |
85 |
85 |
} |
} |
86 |
86 |
|
|
87 |
|
static long mv_set_from_atb(struct ctx *ctx, struct smc_voltage *voltage, |
|
88 |
|
struct atb_voltage_tbl *atb_voltage_tbl, u32 voltage_mv) |
|
|
87 |
|
static long mv_set_from_atb(struct ctx *ctx, struct smc_volt *volt, |
|
88 |
|
struct atb_volt_tbl *atb_volt_tbl, u32 volt_mv) |
89 |
89 |
{ |
{ |
90 |
90 |
long r; |
long r; |
91 |
91 |
|
|
92 |
|
r = voltage_step_idx(atb_voltage_tbl, voltage_mv); |
|
|
92 |
|
r = volt_step_idx(atb_volt_tbl, volt_mv); |
93 |
93 |
if (r == -SI_ERR) { |
if (r == -SI_ERR) { |
94 |
94 |
dev_err(&ctx->dev->dev, "dyn_pm:unable to find emergency powerfull enough voltage in atombios voltage table\n"); |
dev_err(&ctx->dev->dev, "dyn_pm:unable to find emergency powerfull enough voltage in atombios voltage table\n"); |
95 |
95 |
return -SI_ERR; |
return -SI_ERR; |
96 |
96 |
} |
} |
97 |
97 |
|
|
98 |
|
voltage->step_idx = (u8)r; |
|
99 |
|
put_unaligned_be16(atb_voltage_tbl->entries[r].val_mv, &voltage->val); |
|
|
98 |
|
volt->step_idx = (u8)r; |
|
99 |
|
put_unaligned_be16(atb_volt_tbl->entries[r].val_mv, &volt->val); |
100 |
100 |
return 0; |
return 0; |
101 |
101 |
} |
} |
102 |
102 |
|
|
103 |
|
long smc_voltage_vddc_set_from_atb_mv(struct ctx *ctx, struct smc_voltage *vddc, |
|
|
103 |
|
long smc_volt_vddc_set_from_atb_mv(struct ctx *ctx, struct smc_volt *vddc, |
104 |
104 |
u32 vddc_mv) |
u32 vddc_mv) |
105 |
105 |
{ |
{ |
106 |
106 |
return mv_set_from_atb(ctx, vddc, &ctx->atb_vddc_tbl, vddc_mv); |
return mv_set_from_atb(ctx, vddc, &ctx->atb_vddc_tbl, vddc_mv); |
107 |
107 |
} |
} |
108 |
108 |
|
|
109 |
|
long smc_voltage_vddci_set_from_atb_mv(struct ctx *ctx, |
|
110 |
|
struct smc_voltage *vddci, u32 vddci_mv) |
|
|
109 |
|
long smc_volt_vddci_set_from_atb_mv(struct ctx *ctx, struct smc_volt *vddci, |
|
110 |
|
u32 vddci_mv) |
111 |
111 |
{ |
{ |
112 |
112 |
return mv_set_from_atb(ctx, vddci, &ctx->atb_vddci_tbl, vddci_mv); |
return mv_set_from_atb(ctx, vddci, &ctx->atb_vddci_tbl, vddci_mv); |
113 |
113 |
} |
} |
114 |
114 |
|
|
115 |
115 |
/* only used by the initial state */ |
/* only used by the initial state */ |
116 |
|
long smc_voltage_mvdd_set_from_atb_mv(struct ctx *ctx, |
|
117 |
|
struct smc_voltage *mvdd, u32 mvdd_mv) |
|
|
116 |
|
long smc_volt_mvdd_set_from_atb_mv(struct ctx *ctx, struct smc_volt *mvdd, |
|
117 |
|
u32 mvdd_mv) |
118 |
118 |
{ |
{ |
119 |
119 |
return mv_set_from_atb(ctx, mvdd, &ctx->atb_mvddc_tbl, mvdd_mv); |
return mv_set_from_atb(ctx, mvdd, &ctx->atb_mvddc_tbl, mvdd_mv); |
120 |
120 |
} |
} |
121 |
121 |
|
|
122 |
122 |
#define MVDD_SPLIT_FREQ 30000 /* 10 kHz units */ |
#define MVDD_SPLIT_FREQ 30000 /* 10 kHz units */ |
123 |
|
void smc_voltage_mvdd_set_from_atb_mem_clk(struct ctx *ctx, |
|
124 |
|
struct smc_voltage *mvdd, u32 mem_clk) |
|
|
123 |
|
void smc_volt_mvdd_set_from_atb_mem_clk(struct ctx *ctx, struct smc_volt *mvdd, |
|
124 |
|
u32 mem_clk) |
125 |
125 |
{ |
{ |
126 |
126 |
u8 idx; |
u8 idx; |
127 |
127 |
|
|
128 |
128 |
if (mem_clk < MVDD_SPLIT_FREQ) |
if (mem_clk < MVDD_SPLIT_FREQ) |
129 |
129 |
idx = 0; |
idx = 0; |
130 |
130 |
else |
else |
131 |
|
/* use the highest voltage in atb table */ |
|
|
131 |
|
/* use the highest volt in atb tbl */ |
132 |
132 |
idx = ctx->atb_mvddc_tbl.entries_n - 1; |
idx = ctx->atb_mvddc_tbl.entries_n - 1; |
133 |
133 |
|
|
134 |
134 |
mvdd->step_idx = idx; |
mvdd->step_idx = idx; |
|
... |
... |
void smc_voltage_mvdd_set_from_atb_mem_clk(struct ctx *ctx, |
136 |
136 |
} |
} |
137 |
137 |
|
|
138 |
138 |
static void std_vddc_from_old_cac_lkge_tbl(struct ctx *ctx, |
static void std_vddc_from_old_cac_lkge_tbl(struct ctx *ctx, |
139 |
|
struct smc_voltage *std_vddc, struct smc_voltage *vddc) |
|
|
139 |
|
struct smc_volt *std_vddc, struct smc_volt *vddc) |
140 |
140 |
{ |
{ |
141 |
141 |
LOG("computing std_vddc from old cac table"); |
LOG("computing std_vddc from old cac table"); |
142 |
142 |
|
|
|
... |
... |
static void std_vddc_from_old_cac_lkge_tbl(struct ctx *ctx, |
152 |
152 |
} |
} |
153 |
153 |
|
|
154 |
154 |
static void std_vddc_from_new_cac_lkge_entry(struct ctx *ctx, |
static void std_vddc_from_new_cac_lkge_entry(struct ctx *ctx, |
155 |
|
struct smc_voltage *std_vddc, u8 vddc_step_idx, u8 dep_tbl_idx) |
|
|
155 |
|
struct smc_volt *std_vddc, u8 vddc_step_idx, u8 dep_tbl_idx) |
156 |
156 |
{ |
{ |
157 |
157 |
if (dep_tbl_idx < ctx->atb_cac_lkge_tbl.entries_n) { |
if (dep_tbl_idx < ctx->atb_cac_lkge_tbl.entries_n) { |
158 |
158 |
put_unaligned_be16( |
put_unaligned_be16( |
|
... |
... |
static void std_vddc_from_new_cac_lkge_entry(struct ctx *ctx, |
175 |
175 |
} |
} |
176 |
176 |
|
|
177 |
177 |
static void std_vddc_from_new_cac_lkge_tbl(struct ctx *ctx, |
static void std_vddc_from_new_cac_lkge_tbl(struct ctx *ctx, |
178 |
|
struct smc_voltage *std_vddc, struct smc_voltage *vddc) |
|
|
178 |
|
struct smc_volt *std_vddc, struct smc_volt *vddc) |
179 |
179 |
{ |
{ |
180 |
180 |
u8 dep_tbl_idx; |
u8 dep_tbl_idx; |
181 |
181 |
long r; |
long r; |
|
... |
... |
static void std_vddc_from_new_cac_lkge_tbl(struct ctx *ctx, |
195 |
195 |
u16 dep_vddc_mv; |
u16 dep_vddc_mv; |
196 |
196 |
|
|
197 |
197 |
dep_vddc_id = ctx->atb_vddc_dep_on_sclk_tbl.entries[dep_tbl_idx] |
dep_vddc_id = ctx->atb_vddc_dep_on_sclk_tbl.entries[dep_tbl_idx] |
198 |
|
.voltage_id; |
|
|
198 |
|
.volt_id; |
199 |
199 |
|
|
200 |
200 |
if (IS_VDDC_LKGE_IDX(dep_vddc_id)) { |
if (IS_VDDC_LKGE_IDX(dep_vddc_id)) { |
201 |
201 |
struct dev_drv_data *dd; |
struct dev_drv_data *dd; |
202 |
202 |
|
|
203 |
203 |
dd = pci_get_drvdata(ctx->dev); |
dd = pci_get_drvdata(ctx->dev); |
204 |
204 |
|
|
205 |
|
r = atb_voltage_get(dd->atb, ATB_VOLTAGE_TYPE_VDDC, |
|
|
205 |
|
r = atb_volt_get(dd->atb, ATB_VOLT_TYPE_VDDC, |
206 |
206 |
dep_vddc_id, &dep_vddc_mv); |
dep_vddc_id, &dep_vddc_mv); |
207 |
207 |
if (r == -ATB_ERR) { |
if (r == -ATB_ERR) { |
208 |
208 |
dev_err(&ctx->dev->dev, "dyn_pm:unable to convert a leakage index in vddc on engine clock dependency table\n"); |
dev_err(&ctx->dev->dev, "dyn_pm:unable to convert a leakage index in vddc on engine clock dependency table\n"); |
|
... |
... |
static void std_vddc_from_new_cac_lkge_tbl(struct ctx *ctx, |
221 |
221 |
} |
} |
222 |
222 |
|
|
223 |
223 |
/* |
/* |
224 |
|
* Will try to find an approximate match: The table is from low voltage |
|
225 |
|
* to high voltage, then try to find a voltage step which will provide |
|
226 |
|
* a bit more voltage than the targetted vddc. |
|
|
224 |
|
* Will try to find an approximate match: The tbl is from low volt to |
|
225 |
|
* high volt, then try to find a volt step which will provide a bit |
|
226 |
|
* more volt than the targetted vddc. |
227 |
227 |
*/ |
*/ |
228 |
228 |
for (dep_tbl_idx = 0; |
for (dep_tbl_idx = 0; |
229 |
229 |
dep_tbl_idx < ctx->atb_vddc_dep_on_sclk_tbl.entries_n; |
dep_tbl_idx < ctx->atb_vddc_dep_on_sclk_tbl.entries_n; |
|
... |
... |
static void std_vddc_from_new_cac_lkge_tbl(struct ctx *ctx, |
232 |
232 |
u16 dep_vddc_mv; |
u16 dep_vddc_mv; |
233 |
233 |
|
|
234 |
234 |
dep_vddc_id = ctx->atb_vddc_dep_on_sclk_tbl.entries[dep_tbl_idx] |
dep_vddc_id = ctx->atb_vddc_dep_on_sclk_tbl.entries[dep_tbl_idx] |
235 |
|
.voltage_id; |
|
|
235 |
|
.volt_id; |
236 |
236 |
|
|
237 |
237 |
if (IS_VDDC_LKGE_IDX(dep_vddc_id)) { |
if (IS_VDDC_LKGE_IDX(dep_vddc_id)) { |
238 |
238 |
struct dev_drv_data *dd; |
struct dev_drv_data *dd; |
239 |
239 |
|
|
240 |
240 |
dd = pci_get_drvdata(ctx->dev); |
dd = pci_get_drvdata(ctx->dev); |
241 |
241 |
|
|
242 |
|
r = atb_voltage_get(dd->atb, ATB_VOLTAGE_TYPE_VDDC, |
|
|
242 |
|
r = atb_volt_get(dd->atb, ATB_VOLT_TYPE_VDDC, |
243 |
243 |
dep_vddc_id, &dep_vddc_mv); |
dep_vddc_id, &dep_vddc_mv); |
244 |
244 |
if (r == -ATB_ERR) { |
if (r == -ATB_ERR) { |
245 |
245 |
dev_err(&ctx->dev->dev, "dyn_pm:unable to convert a leakage index in vddc on engine clock dependency table\n"); |
dev_err(&ctx->dev->dev, "dyn_pm:unable to convert a leakage index in vddc on engine clock dependency table\n"); |
|
... |
... |
exit_set_std_vddc_to_vddc: |
267 |
267 |
} |
} |
268 |
268 |
|
|
269 |
269 |
/* will put vddc in std_vddc if it encounters errors */ |
/* will put vddc in std_vddc if it encounters errors */ |
270 |
|
void smc_voltage_std_vddc_compute(struct ctx *ctx, struct smc_voltage *std_vddc, |
|
271 |
|
struct smc_voltage *vddc) |
|
|
270 |
|
void smc_volt_std_vddc_compute(struct ctx *ctx, struct smc_volt *std_vddc, |
|
271 |
|
struct smc_volt *vddc) |
272 |
272 |
{ |
{ |
273 |
273 |
LOG("computing std_vddc"); |
LOG("computing std_vddc"); |
274 |
274 |
|
|
|
... |
... |
void smc_voltage_std_vddc_compute(struct ctx *ctx, struct smc_voltage *std_vddc, |
277 |
277 |
return; |
return; |
278 |
278 |
} |
} |
279 |
279 |
|
|
280 |
|
if (ctx->platform_caps & ATB_PP_PLATFORM_CAPS_NEW_CAC_VOLTAGE) |
|
|
280 |
|
if (ctx->platform_caps & ATB_PP_PLATFORM_CAPS_NEW_CAC_VOLT) |
281 |
281 |
std_vddc_from_new_cac_lkge_tbl(ctx, std_vddc, vddc); |
std_vddc_from_new_cac_lkge_tbl(ctx, std_vddc, vddc); |
282 |
282 |
else |
else |
283 |
283 |
std_vddc_from_old_cac_lkge_tbl(ctx, std_vddc, vddc); |
std_vddc_from_old_cac_lkge_tbl(ctx, std_vddc, vddc); |