Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2018 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  */
0023 #ifndef _SMU_HELPER_H_
0024 #define _SMU_HELPER_H_
0025 
0026 struct pp_atomctrl_voltage_table;
0027 struct pp_hwmgr;
0028 struct phm_ppt_v1_voltage_lookup_table;
0029 struct Watermarks_t;
0030 struct pp_wm_sets_with_clock_ranges_soc15;
0031 
0032 uint8_t convert_to_vid(uint16_t vddc);
0033 uint16_t convert_to_vddc(uint8_t vid);
0034 
0035 struct watermark_row_generic_t {
0036     uint16_t MinClock;
0037     uint16_t MaxClock;
0038     uint16_t MinUclk;
0039     uint16_t MaxUclk;
0040 
0041     uint8_t  WmSetting;
0042     uint8_t  Padding[3];
0043 };
0044 
0045 struct watermarks {
0046     struct watermark_row_generic_t WatermarkRow[2][4];
0047     uint32_t     padding[7];
0048 };
0049 
0050 int phm_copy_clock_limits_array(
0051     struct pp_hwmgr *hwmgr,
0052     uint32_t **pptable_info_array,
0053     const uint32_t *pptable_array,
0054     uint32_t power_saving_clock_count);
0055 
0056 int phm_copy_overdrive_settings_limits_array(
0057     struct pp_hwmgr *hwmgr,
0058     uint32_t **pptable_info_array,
0059     const uint32_t *pptable_array,
0060     uint32_t od_setting_count);
0061 
0062 extern int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr,
0063                     uint32_t index,
0064                     uint32_t value, uint32_t mask);
0065 extern int phm_wait_for_indirect_register_unequal(
0066                 struct pp_hwmgr *hwmgr,
0067                 uint32_t indirect_port, uint32_t index,
0068                 uint32_t value, uint32_t mask);
0069 
0070 
0071 extern bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr);
0072 extern bool phm_cf_want_vce_power_gating(struct pp_hwmgr *hwmgr);
0073 extern bool phm_cf_want_microcode_fan_ctrl(struct pp_hwmgr *hwmgr);
0074 
0075 extern int phm_trim_voltage_table(struct pp_atomctrl_voltage_table *vol_table);
0076 extern int phm_get_svi2_mvdd_voltage_table(struct pp_atomctrl_voltage_table *vol_table, phm_ppt_v1_clock_voltage_dependency_table *dep_table);
0077 extern int phm_get_svi2_vddci_voltage_table(struct pp_atomctrl_voltage_table *vol_table, phm_ppt_v1_clock_voltage_dependency_table *dep_table);
0078 extern int phm_get_svi2_vdd_voltage_table(struct pp_atomctrl_voltage_table *vol_table, phm_ppt_v1_voltage_lookup_table *lookup_table);
0079 extern void phm_trim_voltage_table_to_fit_state_table(uint32_t max_vol_steps, struct pp_atomctrl_voltage_table *vol_table);
0080 extern int phm_reset_single_dpm_table(void *table, uint32_t count, int max);
0081 extern void phm_setup_pcie_table_entry(void *table, uint32_t index, uint32_t pcie_gen, uint32_t pcie_lanes);
0082 extern int32_t phm_get_dpm_level_enable_mask_value(void *table);
0083 extern uint8_t phm_get_voltage_id(struct pp_atomctrl_voltage_table *voltage_table,
0084         uint32_t voltage);
0085 extern uint8_t phm_get_voltage_index(struct phm_ppt_v1_voltage_lookup_table *lookup_table, uint16_t voltage);
0086 extern uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, uint16_t vddci);
0087 extern int phm_find_boot_level(void *table, uint32_t value, uint32_t *boot_level);
0088 extern int phm_get_sclk_for_voltage_evv(struct pp_hwmgr *hwmgr, phm_ppt_v1_voltage_lookup_table *lookup_table,
0089                                 uint16_t virtual_voltage_id, int32_t *sclk);
0090 extern int phm_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr);
0091 extern uint32_t phm_get_lowest_enabled_level(struct pp_hwmgr *hwmgr, uint32_t mask);
0092 extern void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr);
0093 
0094 extern int phm_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type,
0095                 uint32_t sclk, uint16_t id, uint16_t *voltage);
0096 
0097 extern uint32_t phm_set_field_to_u32(u32 offset, u32 original_data, u32 field, u32 size);
0098 
0099 extern int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
0100                 uint32_t value, uint32_t mask);
0101 
0102 extern int phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
0103                 uint32_t indirect_port,
0104                 uint32_t index,
0105                 uint32_t value,
0106                 uint32_t mask);
0107 
0108 int phm_irq_process(struct amdgpu_device *adev,
0109                struct amdgpu_irq_src *source,
0110                struct amdgpu_iv_entry *entry);
0111 
0112 /*
0113  * Helper function to make sysfs_emit_at() happy. Align buf to
0114  * the current page boundary and record the offset.
0115  */
0116 static inline void phm_get_sysfs_buf(char **buf, int *offset)
0117 {
0118     if (!*buf || !offset)
0119         return;
0120 
0121     *offset = offset_in_page(*buf);
0122     *buf -= *offset;
0123 }
0124 
0125 int smu9_register_irq_handlers(struct pp_hwmgr *hwmgr);
0126 
0127 void *smu_atom_get_data_table(void *dev, uint32_t table, uint16_t *size,
0128                         uint8_t *frev, uint8_t *crev);
0129 
0130 int smu_get_voltage_dependency_table_ppt_v1(
0131     const struct phm_ppt_v1_clock_voltage_dependency_table *allowed_dep_table,
0132         struct phm_ppt_v1_clock_voltage_dependency_table *dep_table);
0133 
0134 int smu_set_watermarks_for_clocks_ranges(void *wt_table,
0135         struct dm_pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges);
0136 
0137 #define PHM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
0138 #define PHM_FIELD_MASK(reg, field) reg##__##field##_MASK
0139 
0140 #define PHM_SET_FIELD(origval, reg, field, fieldval)    \
0141     (((origval) & ~PHM_FIELD_MASK(reg, field)) |    \
0142      (PHM_FIELD_MASK(reg, field) & ((fieldval) << PHM_FIELD_SHIFT(reg, field))))
0143 
0144 #define PHM_GET_FIELD(value, reg, field)    \
0145     (((value) & PHM_FIELD_MASK(reg, field)) >>  \
0146      PHM_FIELD_SHIFT(reg, field))
0147 
0148 
0149 /* Operations on named fields. */
0150 
0151 #define PHM_READ_FIELD(device, reg, field)  \
0152     PHM_GET_FIELD(cgs_read_register(device, mm##reg), reg, field)
0153 
0154 #define PHM_READ_INDIRECT_FIELD(device, port, reg, field)   \
0155     PHM_GET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
0156             reg, field)
0157 
0158 #define PHM_READ_VFPF_INDIRECT_FIELD(device, port, reg, field)  \
0159     PHM_GET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
0160             reg, field)
0161 
0162 #define PHM_WRITE_FIELD(device, reg, field, fieldval)   \
0163     cgs_write_register(device, mm##reg, PHM_SET_FIELD(  \
0164                 cgs_read_register(device, mm##reg), reg, field, fieldval))
0165 
0166 #define PHM_WRITE_INDIRECT_FIELD(device, port, reg, field, fieldval)    \
0167     cgs_write_ind_register(device, port, ix##reg,   \
0168             PHM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
0169                 reg, field, fieldval))
0170 
0171 #define PHM_WRITE_VFPF_INDIRECT_FIELD(device, port, reg, field, fieldval)   \
0172     cgs_write_ind_register(device, port, ix##reg,   \
0173             PHM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
0174                 reg, field, fieldval))
0175 
0176 #define PHM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, index, value, mask)        \
0177        phm_wait_on_indirect_register(hwmgr, mm##port##_INDEX, index, value, mask)
0178 
0179 
0180 #define PHM_WAIT_INDIRECT_REGISTER(hwmgr, port, reg, value, mask)      \
0181        PHM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
0182 
0183 #define PHM_WAIT_INDIRECT_FIELD(hwmgr, port, reg, field, fieldval)  \
0184     PHM_WAIT_INDIRECT_REGISTER(hwmgr, port, reg, (fieldval) \
0185             << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
0186 
0187 #define PHM_WAIT_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, index, value, mask)    \
0188         phm_wait_for_indirect_register_unequal(hwmgr,                   \
0189                 mm##port##_INDEX, index, value, mask)
0190 
0191 #define PHM_WAIT_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, value, mask)    \
0192         PHM_WAIT_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
0193 
0194 #define PHM_WAIT_INDIRECT_FIELD_UNEQUAL(hwmgr, port, reg, field, fieldval)                          \
0195         PHM_WAIT_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, \
0196                 (fieldval) << PHM_FIELD_SHIFT(reg, field), \
0197                     PHM_FIELD_MASK(reg, field) )
0198 
0199 
0200 #define PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr,  \
0201                 port, index, value, mask)       \
0202     phm_wait_for_indirect_register_unequal(hwmgr,           \
0203         mm##port##_INDEX_11, index, value, mask)
0204 
0205 #define PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, value, mask)     \
0206         PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
0207 
0208 #define PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, port, reg, field, fieldval) \
0209     PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg,   \
0210         (fieldval) << PHM_FIELD_SHIFT(reg, field),      \
0211         PHM_FIELD_MASK(reg, field))
0212 
0213 
0214 #define PHM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr,      \
0215                 port, index, value, mask)       \
0216     phm_wait_on_indirect_register(hwmgr,                \
0217         mm##port##_INDEX_11, index, value, mask)
0218 
0219 #define PHM_WAIT_VFPF_INDIRECT_REGISTER(hwmgr, port, reg, value, mask) \
0220     PHM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
0221 
0222 #define PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, port, reg, field, fieldval) \
0223     PHM_WAIT_VFPF_INDIRECT_REGISTER(hwmgr, port, reg,       \
0224         (fieldval) << PHM_FIELD_SHIFT(reg, field),      \
0225         PHM_FIELD_MASK(reg, field))
0226 
0227 #define PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr,         \
0228                             index, value, mask) \
0229         phm_wait_for_register_unequal(hwmgr,            \
0230                     index, value, mask)
0231 
0232 #define PHM_WAIT_REGISTER_UNEQUAL(hwmgr, reg, value, mask)      \
0233     PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr,            \
0234                 mm##reg, value, mask)
0235 
0236 #define PHM_WAIT_FIELD_UNEQUAL(hwmgr, reg, field, fieldval)     \
0237     PHM_WAIT_REGISTER_UNEQUAL(hwmgr, reg,               \
0238         (fieldval) << PHM_FIELD_SHIFT(reg, field),      \
0239         PHM_FIELD_MASK(reg, field))
0240 
0241 #endif /* _SMU_HELPER_H_ */