2016-08-01 12:42:32 -04:00
/*
* Copyright 2013 Advanced Micro Devices , Inc .
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE COPYRIGHT HOLDER ( S ) OR AUTHOR ( S ) BE LIABLE FOR ANY CLAIM , DAMAGES OR
* OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE ,
* ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE .
*
*/
2017-04-24 13:50:21 +09:00
# include <drm/drmP.h>
2016-08-01 12:42:32 -04:00
# include "amdgpu.h"
# include "amdgpu_pm.h"
# include "amdgpu_dpm.h"
# include "amdgpu_atombios.h"
2017-01-24 18:00:57 -05:00
# include "sid.h"
2016-08-01 12:42:32 -04:00
# include "r600_dpm.h"
# include "si_dpm.h"
# include "atom.h"
# include "../include/pptable.h"
# include <linux/math64.h>
# include <linux/seq_file.h>
# include <linux/firmware.h>
# define MC_CG_ARB_FREQ_F0 0x0a
# define MC_CG_ARB_FREQ_F1 0x0b
# define MC_CG_ARB_FREQ_F2 0x0c
# define MC_CG_ARB_FREQ_F3 0x0d
# define SMC_RAM_END 0x20000
# define SCLK_MIN_DEEPSLEEP_FREQ 1350
/* sizeof(ATOM_PPLIB_EXTENDEDHEADER) */
# define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 12
# define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 14
# define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4 16
# define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5 18
# define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6 20
# define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7 22
# define BIOS_SCRATCH_4 0x5cd
MODULE_FIRMWARE ( " radeon/tahiti_smc.bin " ) ;
MODULE_FIRMWARE ( " radeon/pitcairn_smc.bin " ) ;
2016-08-01 16:05:47 -04:00
MODULE_FIRMWARE ( " radeon/pitcairn_k_smc.bin " ) ;
2016-08-01 12:42:32 -04:00
MODULE_FIRMWARE ( " radeon/verde_smc.bin " ) ;
2016-08-01 16:05:47 -04:00
MODULE_FIRMWARE ( " radeon/verde_k_smc.bin " ) ;
2016-08-01 12:42:32 -04:00
MODULE_FIRMWARE ( " radeon/oland_smc.bin " ) ;
2016-08-01 16:05:47 -04:00
MODULE_FIRMWARE ( " radeon/oland_k_smc.bin " ) ;
2016-08-01 12:42:32 -04:00
MODULE_FIRMWARE ( " radeon/hainan_smc.bin " ) ;
2016-08-01 16:05:47 -04:00
MODULE_FIRMWARE ( " radeon/hainan_k_smc.bin " ) ;
2017-01-17 15:06:58 -05:00
MODULE_FIRMWARE ( " radeon/banks_k_2_smc.bin " ) ;
2016-08-01 12:42:32 -04:00
union power_info {
struct _ATOM_POWERPLAY_INFO info ;
struct _ATOM_POWERPLAY_INFO_V2 info_2 ;
struct _ATOM_POWERPLAY_INFO_V3 info_3 ;
struct _ATOM_PPLIB_POWERPLAYTABLE pplib ;
struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2 ;
struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3 ;
struct _ATOM_PPLIB_POWERPLAYTABLE4 pplib4 ;
struct _ATOM_PPLIB_POWERPLAYTABLE5 pplib5 ;
} ;
union fan_info {
struct _ATOM_PPLIB_FANTABLE fan ;
struct _ATOM_PPLIB_FANTABLE2 fan2 ;
struct _ATOM_PPLIB_FANTABLE3 fan3 ;
} ;
union pplib_clock_info {
2016-09-06 09:45:43 -04:00
struct _ATOM_PPLIB_R600_CLOCK_INFO r600 ;
struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780 ;
struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen ;
struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo ;
struct _ATOM_PPLIB_SI_CLOCK_INFO si ;
2016-08-01 12:42:32 -04:00
} ;
2016-09-12 23:46:06 -04:00
static const u32 r600_utc [ R600_PM_NUMBER_OF_TC ] =
2016-08-01 12:42:32 -04:00
{
R600_UTC_DFLT_00 ,
R600_UTC_DFLT_01 ,
R600_UTC_DFLT_02 ,
R600_UTC_DFLT_03 ,
R600_UTC_DFLT_04 ,
R600_UTC_DFLT_05 ,
R600_UTC_DFLT_06 ,
R600_UTC_DFLT_07 ,
R600_UTC_DFLT_08 ,
R600_UTC_DFLT_09 ,
R600_UTC_DFLT_10 ,
R600_UTC_DFLT_11 ,
R600_UTC_DFLT_12 ,
R600_UTC_DFLT_13 ,
R600_UTC_DFLT_14 ,
} ;
2016-09-12 23:46:06 -04:00
static const u32 r600_dtc [ R600_PM_NUMBER_OF_TC ] =
2016-08-01 12:42:32 -04:00
{
R600_DTC_DFLT_00 ,
R600_DTC_DFLT_01 ,
R600_DTC_DFLT_02 ,
R600_DTC_DFLT_03 ,
R600_DTC_DFLT_04 ,
R600_DTC_DFLT_05 ,
R600_DTC_DFLT_06 ,
R600_DTC_DFLT_07 ,
R600_DTC_DFLT_08 ,
R600_DTC_DFLT_09 ,
R600_DTC_DFLT_10 ,
R600_DTC_DFLT_11 ,
R600_DTC_DFLT_12 ,
R600_DTC_DFLT_13 ,
R600_DTC_DFLT_14 ,
} ;
static const struct si_cac_config_reg cac_weights_tahiti [ ] =
{
{ 0x0 , 0x0000ffff , 0 , 0xc , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0x101 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0xc , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0x8fc , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0x95 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x34e , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x1a1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0xda , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0x46 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x208 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0xe7 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0x948 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x167 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x35 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x31 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0x18e , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg lcac_tahiti [ ] =
{
{ 0x143 , 0x0001fffe , 1 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x143 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x146 , 0x0001fffe , 1 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x146 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x149 , 0x0001fffe , 1 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x149 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14c , 0x0001fffe , 1 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x98 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x98 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9b , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9b , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9e , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9e , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x101 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x101 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x104 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x104 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x107 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x107 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10a , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10a , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10d , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10d , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8c , 0x0001fffe , 1 , 0x8 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8f , 0x0001fffe , 1 , 0x8 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x92 , 0x0001fffe , 1 , 0x8 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x92 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x95 , 0x0001fffe , 1 , 0x8 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x95 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14f , 0x0001fffe , 1 , 0x8 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x152 , 0x0001fffe , 1 , 0x8 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x152 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x155 , 0x0001fffe , 1 , 0x8 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x155 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x158 , 0x0001fffe , 1 , 0x8 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x158 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x110 , 0x0001fffe , 1 , 0x8 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x110 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x113 , 0x0001fffe , 1 , 0x8 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x113 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x116 , 0x0001fffe , 1 , 0x8 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x116 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x119 , 0x0001fffe , 1 , 0x8 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x119 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11c , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11f , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x122 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x122 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x125 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x125 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x128 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x128 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12b , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12b , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15b , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15b , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15e , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15e , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x161 , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x161 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x164 , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x164 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x167 , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x167 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16a , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16a , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16d , 0x0001fffe , 1 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16d , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x170 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x170 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x173 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x173 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x176 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x176 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x179 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x179 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17c , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17f , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg cac_override_tahiti [ ] =
{
{ 0xFFFFFFFF }
} ;
static const struct si_powertune_data powertune_data_tahiti =
{
( ( 1 < < 16 ) | 27027 ) ,
6 ,
0 ,
4 ,
95 ,
{
0UL ,
0UL ,
4521550UL ,
309631529UL ,
- 1270850L ,
4513710L ,
40
} ,
595000000UL ,
12 ,
{
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0
} ,
true
} ;
static const struct si_dte_data dte_data_tahiti =
{
{ 1159409 , 0 , 0 , 0 , 0 } ,
{ 777 , 0 , 0 , 0 , 0 } ,
2 ,
54000 ,
127000 ,
25 ,
2 ,
10 ,
13 ,
{ 27 , 31 , 35 , 39 , 43 , 47 , 54 , 61 , 67 , 74 , 81 , 88 , 95 , 0 , 0 , 0 } ,
{ 240888759 , 221057860 , 235370597 , 162287531 , 158510299 , 131423027 , 116673180 , 103067515 , 87941937 , 76209048 , 68209175 , 64090048 , 58301890 , 0 , 0 , 0 } ,
{ 12024 , 11189 , 11451 , 8411 , 7939 , 6666 , 5681 , 4905 , 4241 , 3720 , 3354 , 3122 , 2890 , 0 , 0 , 0 } ,
85 ,
false
} ;
2016-09-06 12:07:21 -04:00
#if 0
2016-08-01 12:42:32 -04:00
static const struct si_dte_data dte_data_tahiti_le =
{
{ 0x1E8480 , 0x7A1200 , 0x2160EC0 , 0x3938700 , 0 } ,
{ 0x7D , 0x7D , 0x4E4 , 0xB00 , 0 } ,
0x5 ,
0xAFC8 ,
0x64 ,
0x32 ,
1 ,
0 ,
0x10 ,
{ 0x78 , 0x7C , 0x82 , 0x88 , 0x8E , 0x94 , 0x9A , 0xA0 , 0xA6 , 0xAC , 0xB0 , 0xB4 , 0xB8 , 0xBC , 0xC0 , 0xC4 } ,
{ 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 , 0x3938700 } ,
{ 0x2AF8 , 0x2AF8 , 0x29BB , 0x27F9 , 0x2637 , 0x2475 , 0x22B3 , 0x20F1 , 0x1F2F , 0x1D6D , 0x1734 , 0x1414 , 0x10F4 , 0xDD4 , 0xAB4 , 0x794 } ,
85 ,
true
} ;
2016-09-06 12:07:21 -04:00
# endif
2016-08-01 12:42:32 -04:00
static const struct si_dte_data dte_data_tahiti_pro =
{
{ 0x1E8480 , 0x3D0900 , 0x989680 , 0x2625A00 , 0x0 } ,
{ 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
5 ,
45000 ,
100 ,
0xA ,
1 ,
0 ,
0x10 ,
{ 0x96 , 0xB4 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0x895440 , 0x3D0900 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 } ,
{ 0x7D0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
90 ,
true
} ;
static const struct si_dte_data dte_data_new_zealand =
{
{ 0x1E8480 , 0x3D0900 , 0x989680 , 0x2625A00 , 0 } ,
{ 0x29B , 0x3E9 , 0x537 , 0x7D2 , 0 } ,
0x5 ,
0xAFC8 ,
0x69 ,
0x32 ,
1 ,
0 ,
0x10 ,
{ 0x82 , 0xA0 , 0xB4 , 0xFE , 0xFE , 0xFE , 0xFE , 0xFE , 0xFE , 0xFE , 0xFE , 0xFE , 0xFE , 0xFE , 0xFE , 0xFE } ,
{ 0x895440 , 0x3D0900 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 } ,
{ 0xDAC , 0x1388 , 0x685 , 0x685 , 0x685 , 0x685 , 0x685 , 0x685 , 0x685 , 0x685 , 0x685 , 0x685 , 0x685 , 0x685 , 0x685 , 0x685 } ,
85 ,
true
} ;
static const struct si_dte_data dte_data_aruba_pro =
{
{ 0x1E8480 , 0x3D0900 , 0x989680 , 0x2625A00 , 0x0 } ,
{ 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
5 ,
45000 ,
100 ,
0xA ,
1 ,
0 ,
0x10 ,
{ 0x96 , 0xB4 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0x895440 , 0x3D0900 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 } ,
{ 0x1000 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
90 ,
true
} ;
static const struct si_dte_data dte_data_malta =
{
{ 0x1E8480 , 0x3D0900 , 0x989680 , 0x2625A00 , 0x0 } ,
{ 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
5 ,
45000 ,
100 ,
0xA ,
1 ,
0 ,
0x10 ,
{ 0x96 , 0xB4 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0x895440 , 0x3D0900 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 } ,
{ 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
90 ,
true
} ;
2016-09-12 23:46:06 -04:00
static const struct si_cac_config_reg cac_weights_pitcairn [ ] =
2016-08-01 12:42:32 -04:00
{
{ 0x0 , 0x0000ffff , 0 , 0x8a , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0x24d , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x19 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0x118 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0x76 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0xc11 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0x7f3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0x403 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x367 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x4c9 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0x45d , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0x36d , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x534 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0x5da , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0x880 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0x201 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0x9f , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x1f , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x5de , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x7b , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x13 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0xf9 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x66 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x13 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0x186 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg lcac_pitcairn [ ] =
{
{ 0x98 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x98 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x104 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x104 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x110 , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x110 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14f , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8c , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x143 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x143 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9b , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9b , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x107 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x107 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x113 , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x113 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x152 , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x152 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8f , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x146 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x146 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9e , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9e , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10a , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10a , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x116 , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x116 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x155 , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x155 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x92 , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x92 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x149 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x149 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x101 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x101 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10d , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10d , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x119 , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x119 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x158 , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x158 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x95 , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x95 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14c , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11c , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11f , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x122 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x122 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x125 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x125 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x128 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x128 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12b , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12b , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x164 , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x164 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x167 , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x167 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16a , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16a , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15e , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15e , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x161 , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x161 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15b , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15b , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16d , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16d , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x170 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x170 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x173 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x173 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x176 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x176 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x179 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x179 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17c , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17f , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg cac_override_pitcairn [ ] =
{
{ 0xFFFFFFFF }
} ;
static const struct si_powertune_data powertune_data_pitcairn =
{
( ( 1 < < 16 ) | 27027 ) ,
5 ,
0 ,
6 ,
100 ,
{
51600000UL ,
1800000UL ,
7194395UL ,
309631529UL ,
- 1270850L ,
4513710L ,
100
} ,
117830498UL ,
12 ,
{
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0
} ,
true
} ;
static const struct si_dte_data dte_data_pitcairn =
{
{ 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 } ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
0 ,
false
} ;
static const struct si_dte_data dte_data_curacao_xt =
{
{ 0x1E8480 , 0x3D0900 , 0x989680 , 0x2625A00 , 0x0 } ,
{ 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
5 ,
45000 ,
100 ,
0xA ,
1 ,
0 ,
0x10 ,
{ 0x96 , 0xB4 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0x895440 , 0x3D0900 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 } ,
{ 0x1D17 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
90 ,
true
} ;
static const struct si_dte_data dte_data_curacao_pro =
{
{ 0x1E8480 , 0x3D0900 , 0x989680 , 0x2625A00 , 0x0 } ,
{ 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
5 ,
45000 ,
100 ,
0xA ,
1 ,
0 ,
0x10 ,
{ 0x96 , 0xB4 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0x895440 , 0x3D0900 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 } ,
{ 0x1D17 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
90 ,
true
} ;
static const struct si_dte_data dte_data_neptune_xt =
{
{ 0x1E8480 , 0x3D0900 , 0x989680 , 0x2625A00 , 0x0 } ,
{ 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
5 ,
45000 ,
100 ,
0xA ,
1 ,
0 ,
0x10 ,
{ 0x96 , 0xB4 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0x895440 , 0x3D0900 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 } ,
{ 0x3A2F , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
90 ,
true
} ;
static const struct si_cac_config_reg cac_weights_chelsea_pro [ ] =
{
{ 0x0 , 0x0000ffff , 0 , 0x82 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x4F , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0x153 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0x52 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0x135 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x4F , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0x135 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0xAC , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0x118 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0xBE , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0x110 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x4CD , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x30 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0x37 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0x27 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0xC3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0x35 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0x28 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x26C , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0x3B2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0x99D , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0xA3F , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0xA , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0xA , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x15 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x34 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0x2BD , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x30 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x7A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0x100 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg cac_weights_chelsea_xt [ ] =
{
{ 0x0 , 0x0000ffff , 0 , 0x82 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x4F , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0x153 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0x52 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0x135 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x4F , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0x135 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0xAC , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0x118 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0xBE , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0x110 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x4CD , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x30 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0x37 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0x27 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0xC3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0x35 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0x28 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x26C , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0x3B2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0x99D , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0xA3F , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0xA , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0xA , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x15 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x34 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0x30A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x30 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x7A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0x100 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg cac_weights_heathrow [ ] =
{
{ 0x0 , 0x0000ffff , 0 , 0x82 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x4F , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0x153 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0x52 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0x135 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x4F , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0x135 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0xAC , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0x118 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0xBE , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0x110 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x4CD , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x30 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0x37 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0x27 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0xC3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0x35 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0x28 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x26C , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0x3B2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0x99D , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0xA3F , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0xA , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0xA , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x15 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x34 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0x362 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x30 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x7A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0x100 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg cac_weights_cape_verde_pro [ ] =
{
{ 0x0 , 0x0000ffff , 0 , 0x82 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x4F , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0x153 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0x52 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0x135 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x4F , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0x135 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0xAC , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0x118 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0xBE , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0x110 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x4CD , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x30 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0x37 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0x27 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0xC3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0x35 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0x28 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x26C , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0x3B2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0x99D , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0xA3F , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0xA , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0xA , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x15 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x34 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0x315 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x30 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x7A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0x100 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg cac_weights_cape_verde [ ] =
{
{ 0x0 , 0x0000ffff , 0 , 0x82 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x4F , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0x153 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0x52 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0x135 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x4F , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0x135 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0xAC , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0x118 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0xBE , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0x110 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x4CD , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x30 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0x37 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0x27 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0xC3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0x35 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0x28 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x26C , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0x3B2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0x99D , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0xA3F , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0xA , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0xA , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x15 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x34 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0x3BA , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x30 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x7A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0x100 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg lcac_cape_verde [ ] =
{
{ 0x98 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x98 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x104 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x104 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x110 , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x110 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14f , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8c , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x143 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x143 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9b , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9b , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x107 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x107 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x113 , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x113 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x152 , 0x0001fffe , 1 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x152 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8f , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x146 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x146 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11c , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11f , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x164 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x164 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x167 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x167 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16a , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16a , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15e , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15e , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x161 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x161 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15b , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15b , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16d , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16d , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x170 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x170 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x173 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x173 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x176 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x176 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x179 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x179 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17c , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17f , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg cac_override_cape_verde [ ] =
{
{ 0xFFFFFFFF }
} ;
static const struct si_powertune_data powertune_data_cape_verde =
{
( ( 1 < < 16 ) | 0x6993 ) ,
5 ,
0 ,
7 ,
105 ,
{
0UL ,
0UL ,
7194395UL ,
309631529UL ,
- 1270850L ,
4513710L ,
100
} ,
117830498UL ,
12 ,
{
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0
} ,
true
} ;
static const struct si_dte_data dte_data_cape_verde =
{
{ 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 } ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
0 ,
false
} ;
static const struct si_dte_data dte_data_venus_xtx =
{
{ 0x1E8480 , 0x3D0900 , 0x989680 , 0x2625A00 , 0x0 } ,
{ 0x71C , 0xAAB , 0xE39 , 0x11C7 , 0x0 } ,
5 ,
55000 ,
0x69 ,
0xA ,
1 ,
0 ,
0x3 ,
{ 0x96 , 0xB4 , 0xFF , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
{ 0x895440 , 0x3D0900 , 0x989680 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
{ 0xD6D8 , 0x88B8 , 0x1555 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
90 ,
true
} ;
static const struct si_dte_data dte_data_venus_xt =
{
{ 0x1E8480 , 0x3D0900 , 0x989680 , 0x2625A00 , 0x0 } ,
{ 0xBDA , 0x11C7 , 0x17B4 , 0x1DA1 , 0x0 } ,
5 ,
55000 ,
0x69 ,
0xA ,
1 ,
0 ,
0x3 ,
{ 0x96 , 0xB4 , 0xFF , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
{ 0x895440 , 0x3D0900 , 0x989680 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
{ 0xAFC8 , 0x88B8 , 0x238E , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
90 ,
true
} ;
static const struct si_dte_data dte_data_venus_pro =
{
{ 0x1E8480 , 0x3D0900 , 0x989680 , 0x2625A00 , 0x0 } ,
{ 0x11C7 , 0x1AAB , 0x238E , 0x2C72 , 0x0 } ,
5 ,
55000 ,
0x69 ,
0xA ,
1 ,
0 ,
0x3 ,
{ 0x96 , 0xB4 , 0xFF , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
{ 0x895440 , 0x3D0900 , 0x989680 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
{ 0x88B8 , 0x88B8 , 0x3555 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
90 ,
true
} ;
2016-09-12 23:46:06 -04:00
static const struct si_cac_config_reg cac_weights_oland [ ] =
2016-08-01 12:42:32 -04:00
{
{ 0x0 , 0x0000ffff , 0 , 0x82 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x4F , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0x153 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0x52 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0x135 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x4F , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0x135 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0xAC , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0x118 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0xBE , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0x110 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x4CD , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x30 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0x37 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0x27 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0xC3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0x35 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0x28 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x26C , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0x3B2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0x99D , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0xA3F , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0xA , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0xA , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x15 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x34 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0x3BA , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x30 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x7A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0x100 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg cac_weights_mars_pro [ ] =
{
{ 0x0 , 0x0000ffff , 0 , 0x43 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x29 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0xAF , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0x2A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0xA0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x29 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0xA0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0x59 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0x1A5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0x1D6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0x2A3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x8FD , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x76 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0x8A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0xA3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0x71 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0x36 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0xA6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x81 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0x3D2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0x27C , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0xA96 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0xB , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x15 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x7 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x36 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x10 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x10 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x32 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x7E , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0x280 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0x7 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0x3C , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0x203 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0xB4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg cac_weights_mars_xt [ ] =
{
{ 0x0 , 0x0000ffff , 0 , 0x43 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x29 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0xAF , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0x2A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0xA0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x29 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0xA0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0x59 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0x1A5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0x1D6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0x2A3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x8FD , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x76 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0x8A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0xA3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0x71 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0x36 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0xA6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x81 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0x3D2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0x27C , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0xA96 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0xB , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x15 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x7 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x36 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x10 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x10 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0x60 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x32 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x7E , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0x280 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0x7 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0x3C , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0x203 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0xB4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg cac_weights_oland_pro [ ] =
{
{ 0x0 , 0x0000ffff , 0 , 0x43 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x29 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0xAF , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0x2A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0xA0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x29 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0xA0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0x59 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0x1A5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0x1D6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0x2A3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x8FD , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x76 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0x8A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0xA3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0x71 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0x36 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0xA6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x81 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0x3D2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0x27C , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0xA96 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0xB , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x15 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x7 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x36 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x10 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x10 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0x90 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x32 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x7E , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0x280 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0x7 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0x3C , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0x203 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0xB4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg cac_weights_oland_xt [ ] =
{
{ 0x0 , 0x0000ffff , 0 , 0x43 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x29 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0xAF , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0x2A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0xA0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x29 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0xA0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0x59 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0x1A5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0x1D6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0x2A3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x8FD , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x76 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0x8A , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0xA3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0x71 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0x36 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0xA6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x81 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0x3D2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0x27C , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0xA96 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0x5 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0xB , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x15 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x7 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x36 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x10 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x10 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0x120 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x32 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x7E , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0x280 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0x7 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0x3C , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0x203 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0xB4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg lcac_oland [ ] =
{
{ 0x98 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x98 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x104 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x104 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x110 , 0x0001fffe , 1 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x110 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14f , 0x0001fffe , 1 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8c , 0x0001fffe , 1 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x143 , 0x0001fffe , 1 , 0x4 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x143 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11c , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11f , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x164 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x164 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x167 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x167 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16a , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16a , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15e , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15e , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x161 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x161 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15b , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15b , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16d , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16d , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x170 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x170 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x173 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x173 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x176 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x176 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x179 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x179 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17c , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17f , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg lcac_mars_pro [ ] =
{
{ 0x98 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x98 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x104 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x104 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x110 , 0x0001fffe , 1 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x110 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14f , 0x0001fffe , 1 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8c , 0x0001fffe , 1 , 0x6 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x143 , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x143 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11c , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11f , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x164 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x164 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x167 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x167 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16a , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16a , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15e , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15e , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x161 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x161 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15b , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15b , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16d , 0x0001fffe , 1 , 0x2 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16d , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x170 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x170 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x173 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x173 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x176 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x176 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x179 , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x179 , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17c , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17c , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17f , 0x0001fffe , 1 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17f , 0x00000001 , 0 , 0x1 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_cac_config_reg cac_override_oland [ ] =
{
{ 0xFFFFFFFF }
} ;
static const struct si_powertune_data powertune_data_oland =
{
( ( 1 < < 16 ) | 0x6993 ) ,
5 ,
0 ,
7 ,
105 ,
{
0UL ,
0UL ,
7194395UL ,
309631529UL ,
- 1270850L ,
4513710L ,
100
} ,
117830498UL ,
12 ,
{
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0
} ,
true
} ;
static const struct si_powertune_data powertune_data_mars_pro =
{
( ( 1 < < 16 ) | 0x6993 ) ,
5 ,
0 ,
7 ,
105 ,
{
0UL ,
0UL ,
7194395UL ,
309631529UL ,
- 1270850L ,
4513710L ,
100
} ,
117830498UL ,
12 ,
{
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0
} ,
true
} ;
static const struct si_dte_data dte_data_oland =
{
{ 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 } ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ,
0 ,
false
} ;
static const struct si_dte_data dte_data_mars_pro =
{
{ 0x1E8480 , 0x3D0900 , 0x989680 , 0x2625A00 , 0x0 } ,
{ 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
5 ,
55000 ,
105 ,
0xA ,
1 ,
0 ,
0x10 ,
{ 0x96 , 0xB4 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0x895440 , 0x3D0900 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 } ,
{ 0xF627 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
90 ,
true
} ;
static const struct si_dte_data dte_data_sun_xt =
{
{ 0x1E8480 , 0x3D0900 , 0x989680 , 0x2625A00 , 0x0 } ,
{ 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
5 ,
55000 ,
105 ,
0xA ,
1 ,
0 ,
0x10 ,
{ 0x96 , 0xB4 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ,
{ 0x895440 , 0x3D0900 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 , 0x989680 } ,
{ 0xD555 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
90 ,
true
} ;
static const struct si_cac_config_reg cac_weights_hainan [ ] =
{
{ 0x0 , 0x0000ffff , 0 , 0x2d9 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x0 , 0xffff0000 , 16 , 0x22b , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0x0000ffff , 0 , 0x21c , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1 , 0xffff0000 , 16 , 0x1dc , SISLANDS_CACCONFIG_CGIND } ,
{ 0x2 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0x0000ffff , 0 , 0x24e , SISLANDS_CACCONFIG_CGIND } ,
{ 0x3 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0x0000ffff , 0 , 0x35e , SISLANDS_CACCONFIG_CGIND } ,
{ 0x5 , 0xffff0000 , 16 , 0x1143 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0x0000ffff , 0 , 0xe17 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6 , 0xffff0000 , 16 , 0x441 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18f , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0x0000ffff , 0 , 0x28b , SISLANDS_CACCONFIG_CGIND } ,
{ 0x7 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x8 , 0xffff0000 , 16 , 0xabe , SISLANDS_CACCONFIG_CGIND } ,
{ 0x9 , 0x0000ffff , 0 , 0xf11 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xa , 0x0000ffff , 0 , 0x907 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0x0000ffff , 0 , 0xb45 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xb , 0xffff0000 , 16 , 0xd1e , SISLANDS_CACCONFIG_CGIND } ,
{ 0xc , 0x0000ffff , 0 , 0xa2c , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0x0000ffff , 0 , 0x62 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xd , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xe , 0x0000ffff , 0 , 0x1f3 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0x0000ffff , 0 , 0x42 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xf , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x10 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0x0000ffff , 0 , 0x709 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x11 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x12 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x13 , 0xffff0000 , 16 , 0x3a , SISLANDS_CACCONFIG_CGIND } ,
{ 0x14 , 0x0000ffff , 0 , 0x357 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0x0000ffff , 0 , 0x9f , SISLANDS_CACCONFIG_CGIND } ,
{ 0x15 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x4e , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0x0000ffff , 0 , 0x314 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x16 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x17 , 0x0000ffff , 0 , 0x6d , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x18 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0x0000ffff , 0 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x19 , 0xffff0000 , 16 , 0x0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1a , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1b , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1c , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1d , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1e , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x1f , 0xffff0000 , 16 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x20 , 0x0000ffff , 0 , 0 , SISLANDS_CACCONFIG_CGIND } ,
{ 0x6d , 0x0000ffff , 0 , 0x1b9 , SISLANDS_CACCONFIG_CGIND } ,
{ 0xFFFFFFFF }
} ;
static const struct si_powertune_data powertune_data_hainan =
{
( ( 1 < < 16 ) | 0x6993 ) ,
5 ,
0 ,
9 ,
105 ,
{
0UL ,
0UL ,
7194395UL ,
309631529UL ,
- 1270850L ,
4513710L ,
100
} ,
117830498UL ,
12 ,
{
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0
} ,
true
} ;
2016-09-12 23:46:06 -04:00
static struct rv7xx_power_info * rv770_get_pi ( struct amdgpu_device * adev ) ;
static struct evergreen_power_info * evergreen_get_pi ( struct amdgpu_device * adev ) ;
static struct ni_power_info * ni_get_pi ( struct amdgpu_device * adev ) ;
static struct si_ps * si_get_ps ( struct amdgpu_ps * rps ) ;
2016-08-01 12:42:32 -04:00
static int si_populate_voltage_value ( struct amdgpu_device * adev ,
const struct atom_voltage_table * table ,
u16 value , SISLANDS_SMC_VOLTAGE_VALUE * voltage ) ;
static int si_get_std_voltage_value ( struct amdgpu_device * adev ,
SISLANDS_SMC_VOLTAGE_VALUE * voltage ,
u16 * std_voltage ) ;
static int si_write_smc_soft_register ( struct amdgpu_device * adev ,
u16 reg_offset , u32 value ) ;
static int si_convert_power_level_to_smc ( struct amdgpu_device * adev ,
struct rv7xx_pl * pl ,
SISLANDS_SMC_HW_PERFORMANCE_LEVEL * level ) ;
static int si_calculate_sclk_params ( struct amdgpu_device * adev ,
u32 engine_clock ,
SISLANDS_SMC_SCLK_VALUE * sclk ) ;
static void si_thermal_start_smc_fan_control ( struct amdgpu_device * adev ) ;
static void si_fan_ctrl_set_default_mode ( struct amdgpu_device * adev ) ;
static void si_dpm_set_irq_funcs ( struct amdgpu_device * adev ) ;
static struct si_power_info * si_get_pi ( struct amdgpu_device * adev )
{
2016-09-06 09:45:43 -04:00
struct si_power_info * pi = adev - > pm . dpm . priv ;
return pi ;
2016-08-01 12:42:32 -04:00
}
static void si_calculate_leakage_for_v_and_t_formula ( const struct ni_leakage_coeffients * coeff ,
u16 v , s32 t , u32 ileakage , u32 * leakage )
{
s64 kt , kv , leakage_w , i_leakage , vddc ;
s64 temperature , t_slope , t_intercept , av , bv , t_ref ;
s64 tmp ;
i_leakage = div64_s64 ( drm_int2fixp ( ileakage ) , 100 ) ;
vddc = div64_s64 ( drm_int2fixp ( v ) , 1000 ) ;
temperature = div64_s64 ( drm_int2fixp ( t ) , 1000 ) ;
t_slope = div64_s64 ( drm_int2fixp ( coeff - > t_slope ) , 100000000 ) ;
t_intercept = div64_s64 ( drm_int2fixp ( coeff - > t_intercept ) , 100000000 ) ;
av = div64_s64 ( drm_int2fixp ( coeff - > av ) , 100000000 ) ;
bv = div64_s64 ( drm_int2fixp ( coeff - > bv ) , 100000000 ) ;
t_ref = drm_int2fixp ( coeff - > t_ref ) ;
tmp = drm_fixp_mul ( t_slope , vddc ) + t_intercept ;
kt = drm_fixp_exp ( drm_fixp_mul ( tmp , temperature ) ) ;
kt = drm_fixp_div ( kt , drm_fixp_exp ( drm_fixp_mul ( tmp , t_ref ) ) ) ;
kv = drm_fixp_mul ( av , drm_fixp_exp ( drm_fixp_mul ( bv , vddc ) ) ) ;
leakage_w = drm_fixp_mul ( drm_fixp_mul ( drm_fixp_mul ( i_leakage , kt ) , kv ) , vddc ) ;
* leakage = drm_fixp2int ( leakage_w * 1000 ) ;
}
static void si_calculate_leakage_for_v_and_t ( struct amdgpu_device * adev ,
const struct ni_leakage_coeffients * coeff ,
u16 v ,
s32 t ,
u32 i_leakage ,
u32 * leakage )
{
si_calculate_leakage_for_v_and_t_formula ( coeff , v , t , i_leakage , leakage ) ;
}
static void si_calculate_leakage_for_v_formula ( const struct ni_leakage_coeffients * coeff ,
const u32 fixed_kt , u16 v ,
u32 ileakage , u32 * leakage )
{
s64 kt , kv , leakage_w , i_leakage , vddc ;
i_leakage = div64_s64 ( drm_int2fixp ( ileakage ) , 100 ) ;
vddc = div64_s64 ( drm_int2fixp ( v ) , 1000 ) ;
kt = div64_s64 ( drm_int2fixp ( fixed_kt ) , 100000000 ) ;
kv = drm_fixp_mul ( div64_s64 ( drm_int2fixp ( coeff - > av ) , 100000000 ) ,
drm_fixp_exp ( drm_fixp_mul ( div64_s64 ( drm_int2fixp ( coeff - > bv ) , 100000000 ) , vddc ) ) ) ;
leakage_w = drm_fixp_mul ( drm_fixp_mul ( drm_fixp_mul ( i_leakage , kt ) , kv ) , vddc ) ;
* leakage = drm_fixp2int ( leakage_w * 1000 ) ;
}
static void si_calculate_leakage_for_v ( struct amdgpu_device * adev ,
const struct ni_leakage_coeffients * coeff ,
const u32 fixed_kt ,
u16 v ,
u32 i_leakage ,
u32 * leakage )
{
si_calculate_leakage_for_v_formula ( coeff , fixed_kt , v , i_leakage , leakage ) ;
}
static void si_update_dte_from_pl2 ( struct amdgpu_device * adev ,
struct si_dte_data * dte_data )
{
u32 p_limit1 = adev - > pm . dpm . tdp_limit ;
u32 p_limit2 = adev - > pm . dpm . near_tdp_limit ;
u32 k = dte_data - > k ;
u32 t_max = dte_data - > max_t ;
u32 t_split [ 5 ] = { 10 , 15 , 20 , 25 , 30 } ;
u32 t_0 = dte_data - > t0 ;
u32 i ;
if ( p_limit2 ! = 0 & & p_limit2 < = p_limit1 ) {
dte_data - > tdep_count = 3 ;
for ( i = 0 ; i < k ; i + + ) {
dte_data - > r [ i ] =
( t_split [ i ] * ( t_max - t_0 / ( u32 ) 1000 ) * ( 1 < < 14 ) ) /
( p_limit2 * ( u32 ) 100 ) ;
}
dte_data - > tdep_r [ 1 ] = dte_data - > r [ 4 ] * 2 ;
for ( i = 2 ; i < SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE ; i + + ) {
dte_data - > tdep_r [ i ] = dte_data - > r [ 4 ] ;
}
} else {
DRM_ERROR ( " Invalid PL2! DTE will not be updated. \n " ) ;
}
}
2016-09-12 23:46:06 -04:00
static struct rv7xx_power_info * rv770_get_pi ( struct amdgpu_device * adev )
2016-08-01 12:42:32 -04:00
{
2016-09-06 09:45:43 -04:00
struct rv7xx_power_info * pi = adev - > pm . dpm . priv ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
return pi ;
2016-08-01 12:42:32 -04:00
}
2016-09-12 23:46:06 -04:00
static struct ni_power_info * ni_get_pi ( struct amdgpu_device * adev )
2016-08-01 12:42:32 -04:00
{
2016-09-06 09:45:43 -04:00
struct ni_power_info * pi = adev - > pm . dpm . priv ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
return pi ;
2016-08-01 12:42:32 -04:00
}
2016-09-12 23:46:06 -04:00
static struct si_ps * si_get_ps ( struct amdgpu_ps * aps )
2016-08-01 12:42:32 -04:00
{
2016-09-06 09:45:43 -04:00
struct si_ps * ps = aps - > ps_priv ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
return ps ;
2016-08-01 12:42:32 -04:00
}
static void si_initialize_powertune_defaults ( struct amdgpu_device * adev )
{
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
bool update_dte_from_pl2 = false ;
if ( adev - > asic_type = = CHIP_TAHITI ) {
si_pi - > cac_weights = cac_weights_tahiti ;
si_pi - > lcac_config = lcac_tahiti ;
si_pi - > cac_override = cac_override_tahiti ;
si_pi - > powertune_data = & powertune_data_tahiti ;
si_pi - > dte_data = dte_data_tahiti ;
switch ( adev - > pdev - > device ) {
case 0x6798 :
si_pi - > dte_data . enable_dte_by_default = true ;
break ;
case 0x6799 :
si_pi - > dte_data = dte_data_new_zealand ;
break ;
case 0x6790 :
case 0x6791 :
case 0x6792 :
case 0x679E :
si_pi - > dte_data = dte_data_aruba_pro ;
update_dte_from_pl2 = true ;
break ;
case 0x679B :
si_pi - > dte_data = dte_data_malta ;
update_dte_from_pl2 = true ;
break ;
case 0x679A :
si_pi - > dte_data = dte_data_tahiti_pro ;
update_dte_from_pl2 = true ;
break ;
default :
if ( si_pi - > dte_data . enable_dte_by_default = = true )
DRM_ERROR ( " DTE is not enabled! \n " ) ;
break ;
}
} else if ( adev - > asic_type = = CHIP_PITCAIRN ) {
2016-09-06 09:44:47 -04:00
si_pi - > cac_weights = cac_weights_pitcairn ;
si_pi - > lcac_config = lcac_pitcairn ;
si_pi - > cac_override = cac_override_pitcairn ;
si_pi - > powertune_data = & powertune_data_pitcairn ;
2016-08-01 12:42:32 -04:00
switch ( adev - > pdev - > device ) {
case 0x6810 :
case 0x6818 :
si_pi - > dte_data = dte_data_curacao_xt ;
update_dte_from_pl2 = true ;
break ;
case 0x6819 :
case 0x6811 :
si_pi - > dte_data = dte_data_curacao_pro ;
update_dte_from_pl2 = true ;
break ;
case 0x6800 :
case 0x6806 :
si_pi - > dte_data = dte_data_neptune_xt ;
update_dte_from_pl2 = true ;
break ;
default :
si_pi - > dte_data = dte_data_pitcairn ;
break ;
}
} else if ( adev - > asic_type = = CHIP_VERDE ) {
si_pi - > lcac_config = lcac_cape_verde ;
si_pi - > cac_override = cac_override_cape_verde ;
si_pi - > powertune_data = & powertune_data_cape_verde ;
switch ( adev - > pdev - > device ) {
case 0x683B :
case 0x683F :
case 0x6829 :
case 0x6835 :
si_pi - > cac_weights = cac_weights_cape_verde_pro ;
si_pi - > dte_data = dte_data_cape_verde ;
break ;
case 0x682C :
si_pi - > cac_weights = cac_weights_cape_verde_pro ;
si_pi - > dte_data = dte_data_sun_xt ;
2017-07-12 15:52:26 +08:00
update_dte_from_pl2 = true ;
2016-08-01 12:42:32 -04:00
break ;
case 0x6825 :
case 0x6827 :
si_pi - > cac_weights = cac_weights_heathrow ;
si_pi - > dte_data = dte_data_cape_verde ;
break ;
case 0x6824 :
case 0x682D :
si_pi - > cac_weights = cac_weights_chelsea_xt ;
si_pi - > dte_data = dte_data_cape_verde ;
break ;
case 0x682F :
si_pi - > cac_weights = cac_weights_chelsea_pro ;
si_pi - > dte_data = dte_data_cape_verde ;
break ;
case 0x6820 :
si_pi - > cac_weights = cac_weights_heathrow ;
si_pi - > dte_data = dte_data_venus_xtx ;
break ;
case 0x6821 :
si_pi - > cac_weights = cac_weights_heathrow ;
si_pi - > dte_data = dte_data_venus_xt ;
break ;
case 0x6823 :
case 0x682B :
case 0x6822 :
case 0x682A :
si_pi - > cac_weights = cac_weights_chelsea_pro ;
si_pi - > dte_data = dte_data_venus_pro ;
break ;
default :
si_pi - > cac_weights = cac_weights_cape_verde ;
si_pi - > dte_data = dte_data_cape_verde ;
break ;
}
} else if ( adev - > asic_type = = CHIP_OLAND ) {
2016-09-06 09:44:47 -04:00
si_pi - > lcac_config = lcac_mars_pro ;
si_pi - > cac_override = cac_override_oland ;
si_pi - > powertune_data = & powertune_data_mars_pro ;
si_pi - > dte_data = dte_data_mars_pro ;
2016-08-01 12:42:32 -04:00
switch ( adev - > pdev - > device ) {
case 0x6601 :
case 0x6621 :
case 0x6603 :
case 0x6605 :
si_pi - > cac_weights = cac_weights_mars_pro ;
update_dte_from_pl2 = true ;
break ;
case 0x6600 :
case 0x6606 :
case 0x6620 :
case 0x6604 :
si_pi - > cac_weights = cac_weights_mars_xt ;
update_dte_from_pl2 = true ;
break ;
case 0x6611 :
case 0x6613 :
case 0x6608 :
si_pi - > cac_weights = cac_weights_oland_pro ;
update_dte_from_pl2 = true ;
break ;
case 0x6610 :
si_pi - > cac_weights = cac_weights_oland_xt ;
update_dte_from_pl2 = true ;
break ;
default :
si_pi - > cac_weights = cac_weights_oland ;
si_pi - > lcac_config = lcac_oland ;
si_pi - > cac_override = cac_override_oland ;
si_pi - > powertune_data = & powertune_data_oland ;
si_pi - > dte_data = dte_data_oland ;
break ;
}
} else if ( adev - > asic_type = = CHIP_HAINAN ) {
si_pi - > cac_weights = cac_weights_hainan ;
si_pi - > lcac_config = lcac_oland ;
si_pi - > cac_override = cac_override_oland ;
si_pi - > powertune_data = & powertune_data_hainan ;
si_pi - > dte_data = dte_data_sun_xt ;
update_dte_from_pl2 = true ;
} else {
DRM_ERROR ( " Unknown SI asic revision, failed to initialize PowerTune! \n " ) ;
return ;
}
ni_pi - > enable_power_containment = false ;
ni_pi - > enable_cac = false ;
ni_pi - > enable_sq_ramping = false ;
si_pi - > enable_dte = false ;
if ( si_pi - > powertune_data - > enable_powertune_by_default ) {
2016-09-06 09:45:43 -04:00
ni_pi - > enable_power_containment = true ;
2016-08-01 12:42:32 -04:00
ni_pi - > enable_cac = true ;
if ( si_pi - > dte_data . enable_dte_by_default ) {
si_pi - > enable_dte = true ;
if ( update_dte_from_pl2 )
si_update_dte_from_pl2 ( adev , & si_pi - > dte_data ) ;
}
ni_pi - > enable_sq_ramping = true ;
}
ni_pi - > driver_calculate_cac_leakage = true ;
ni_pi - > cac_configuration_required = true ;
if ( ni_pi - > cac_configuration_required ) {
ni_pi - > support_cac_long_term_average = true ;
si_pi - > dyn_powertune_data . l2_lta_window_size =
si_pi - > powertune_data - > l2_lta_window_size_default ;
si_pi - > dyn_powertune_data . lts_truncate =
si_pi - > powertune_data - > lts_truncate_default ;
} else {
ni_pi - > support_cac_long_term_average = false ;
si_pi - > dyn_powertune_data . l2_lta_window_size = 0 ;
si_pi - > dyn_powertune_data . lts_truncate = 0 ;
}
si_pi - > dyn_powertune_data . disable_uvd_powertune = false ;
}
static u32 si_get_smc_power_scaling_factor ( struct amdgpu_device * adev )
{
return 1 ;
}
static u32 si_calculate_cac_wintime ( struct amdgpu_device * adev )
{
u32 xclk ;
u32 wintime ;
u32 cac_window ;
u32 cac_window_size ;
xclk = amdgpu_asic_get_xclk ( adev ) ;
if ( xclk = = 0 )
return 0 ;
cac_window = RREG32 ( CG_CAC_CTRL ) & CAC_WINDOW_MASK ;
cac_window_size = ( ( cac_window & 0xFFFF0000 ) > > 16 ) * ( cac_window & 0x0000FFFF ) ;
wintime = ( cac_window_size * 100 ) / xclk ;
return wintime ;
}
static u32 si_scale_power_for_smc ( u32 power_in_watts , u32 scaling_factor )
{
return power_in_watts ;
}
static int si_calculate_adjusted_tdp_limits ( struct amdgpu_device * adev ,
bool adjust_polarity ,
u32 tdp_adjustment ,
u32 * tdp_limit ,
u32 * near_tdp_limit )
{
u32 adjustment_delta , max_tdp_limit ;
if ( tdp_adjustment > ( u32 ) adev - > pm . dpm . tdp_od_limit )
return - EINVAL ;
max_tdp_limit = ( ( 100 + 100 ) * adev - > pm . dpm . tdp_limit ) / 100 ;
if ( adjust_polarity ) {
* tdp_limit = ( ( 100 + tdp_adjustment ) * adev - > pm . dpm . tdp_limit ) / 100 ;
* near_tdp_limit = adev - > pm . dpm . near_tdp_limit_adjusted + ( * tdp_limit - adev - > pm . dpm . tdp_limit ) ;
} else {
* tdp_limit = ( ( 100 - tdp_adjustment ) * adev - > pm . dpm . tdp_limit ) / 100 ;
adjustment_delta = adev - > pm . dpm . tdp_limit - * tdp_limit ;
if ( adjustment_delta < adev - > pm . dpm . near_tdp_limit_adjusted )
* near_tdp_limit = adev - > pm . dpm . near_tdp_limit_adjusted - adjustment_delta ;
else
* near_tdp_limit = 0 ;
}
if ( ( * tdp_limit < = 0 ) | | ( * tdp_limit > max_tdp_limit ) )
return - EINVAL ;
if ( ( * near_tdp_limit < = 0 ) | | ( * near_tdp_limit > * tdp_limit ) )
return - EINVAL ;
return 0 ;
}
static int si_populate_smc_tdp_limits ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_state )
{
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
if ( ni_pi - > enable_power_containment ) {
SISLANDS_SMC_STATETABLE * smc_table = & si_pi - > smc_statetable ;
PP_SIslands_PAPMParameters * papm_parm ;
struct amdgpu_ppm_table * ppm = adev - > pm . dpm . dyn_state . ppm_table ;
u32 scaling_factor = si_get_smc_power_scaling_factor ( adev ) ;
u32 tdp_limit ;
u32 near_tdp_limit ;
int ret ;
if ( scaling_factor = = 0 )
return - EINVAL ;
memset ( smc_table , 0 , sizeof ( SISLANDS_SMC_STATETABLE ) ) ;
ret = si_calculate_adjusted_tdp_limits ( adev ,
false , /* ??? */
adev - > pm . dpm . tdp_adjustment ,
& tdp_limit ,
& near_tdp_limit ) ;
if ( ret )
return ret ;
smc_table - > dpm2Params . TDPLimit =
cpu_to_be32 ( si_scale_power_for_smc ( tdp_limit , scaling_factor ) * 1000 ) ;
smc_table - > dpm2Params . NearTDPLimit =
cpu_to_be32 ( si_scale_power_for_smc ( near_tdp_limit , scaling_factor ) * 1000 ) ;
smc_table - > dpm2Params . SafePowerLimit =
cpu_to_be32 ( si_scale_power_for_smc ( ( near_tdp_limit * SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT ) / 100 , scaling_factor ) * 1000 ) ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_copy_bytes_to_smc ( adev ,
( si_pi - > state_table_start + offsetof ( SISLANDS_SMC_STATETABLE , dpm2Params ) +
offsetof ( PP_SIslands_DPM2Parameters , TDPLimit ) ) ,
( u8 * ) ( & ( smc_table - > dpm2Params . TDPLimit ) ) ,
sizeof ( u32 ) * 3 ,
si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
if ( si_pi - > enable_ppm ) {
papm_parm = & si_pi - > papm_parm ;
memset ( papm_parm , 0 , sizeof ( PP_SIslands_PAPMParameters ) ) ;
papm_parm - > NearTDPLimitTherm = cpu_to_be32 ( ppm - > dgpu_tdp ) ;
papm_parm - > dGPU_T_Limit = cpu_to_be32 ( ppm - > tj_max ) ;
papm_parm - > dGPU_T_Warning = cpu_to_be32 ( 95 ) ;
papm_parm - > dGPU_T_Hysteresis = cpu_to_be32 ( 5 ) ;
papm_parm - > PlatformPowerLimit = 0xffffffff ;
papm_parm - > NearTDPLimitPAPM = 0xffffffff ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_copy_bytes_to_smc ( adev , si_pi - > papm_cfg_table_start ,
( u8 * ) papm_parm ,
sizeof ( PP_SIslands_PAPMParameters ) ,
si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
}
}
return 0 ;
}
static int si_populate_smc_tdp_limits_2 ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_state )
{
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
if ( ni_pi - > enable_power_containment ) {
SISLANDS_SMC_STATETABLE * smc_table = & si_pi - > smc_statetable ;
u32 scaling_factor = si_get_smc_power_scaling_factor ( adev ) ;
int ret ;
memset ( smc_table , 0 , sizeof ( SISLANDS_SMC_STATETABLE ) ) ;
smc_table - > dpm2Params . NearTDPLimit =
cpu_to_be32 ( si_scale_power_for_smc ( adev - > pm . dpm . near_tdp_limit_adjusted , scaling_factor ) * 1000 ) ;
smc_table - > dpm2Params . SafePowerLimit =
cpu_to_be32 ( si_scale_power_for_smc ( ( adev - > pm . dpm . near_tdp_limit_adjusted * SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT ) / 100 , scaling_factor ) * 1000 ) ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_copy_bytes_to_smc ( adev ,
( si_pi - > state_table_start +
offsetof ( SISLANDS_SMC_STATETABLE , dpm2Params ) +
offsetof ( PP_SIslands_DPM2Parameters , NearTDPLimit ) ) ,
( u8 * ) ( & ( smc_table - > dpm2Params . NearTDPLimit ) ) ,
sizeof ( u32 ) * 2 ,
si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
}
return 0 ;
}
static u16 si_calculate_power_efficiency_ratio ( struct amdgpu_device * adev ,
const u16 prev_std_vddc ,
const u16 curr_std_vddc )
{
u64 margin = ( u64 ) SISLANDS_DPM2_PWREFFICIENCYRATIO_MARGIN ;
u64 prev_vddc = ( u64 ) prev_std_vddc ;
u64 curr_vddc = ( u64 ) curr_std_vddc ;
u64 pwr_efficiency_ratio , n , d ;
if ( ( prev_vddc = = 0 ) | | ( curr_vddc = = 0 ) )
return 0 ;
n = div64_u64 ( ( u64 ) 1024 * curr_vddc * curr_vddc * ( ( u64 ) 1000 + margin ) , ( u64 ) 1000 ) ;
d = prev_vddc * prev_vddc ;
pwr_efficiency_ratio = div64_u64 ( n , d ) ;
if ( pwr_efficiency_ratio > ( u64 ) 0xFFFF )
return 0 ;
return ( u16 ) pwr_efficiency_ratio ;
}
static bool si_should_disable_uvd_powertune ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_state )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
if ( si_pi - > dyn_powertune_data . disable_uvd_powertune & &
amdgpu_state - > vclk & & amdgpu_state - > dclk )
return true ;
return false ;
}
struct evergreen_power_info * evergreen_get_pi ( struct amdgpu_device * adev )
{
struct evergreen_power_info * pi = adev - > pm . dpm . priv ;
return pi ;
}
static int si_populate_power_containment_values ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_state ,
SISLANDS_SMC_SWSTATE * smc_state )
{
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
struct si_ps * state = si_get_ps ( amdgpu_state ) ;
SISLANDS_SMC_VOLTAGE_VALUE vddc ;
u32 prev_sclk ;
u32 max_sclk ;
u32 min_sclk ;
u16 prev_std_vddc ;
u16 curr_std_vddc ;
int i ;
u16 pwr_efficiency_ratio ;
u8 max_ps_percent ;
bool disable_uvd_power_tune ;
int ret ;
if ( ni_pi - > enable_power_containment = = false )
return 0 ;
if ( state - > performance_level_count = = 0 )
return - EINVAL ;
if ( smc_state - > levelCount ! = state - > performance_level_count )
return - EINVAL ;
disable_uvd_power_tune = si_should_disable_uvd_powertune ( adev , amdgpu_state ) ;
smc_state - > levels [ 0 ] . dpm2 . MaxPS = 0 ;
smc_state - > levels [ 0 ] . dpm2 . NearTDPDec = 0 ;
smc_state - > levels [ 0 ] . dpm2 . AboveSafeInc = 0 ;
smc_state - > levels [ 0 ] . dpm2 . BelowSafeInc = 0 ;
smc_state - > levels [ 0 ] . dpm2 . PwrEfficiencyRatio = 0 ;
for ( i = 1 ; i < state - > performance_level_count ; i + + ) {
prev_sclk = state - > performance_levels [ i - 1 ] . sclk ;
max_sclk = state - > performance_levels [ i ] . sclk ;
if ( i = = 1 )
max_ps_percent = SISLANDS_DPM2_MAXPS_PERCENT_M ;
else
max_ps_percent = SISLANDS_DPM2_MAXPS_PERCENT_H ;
if ( prev_sclk > max_sclk )
return - EINVAL ;
if ( ( max_ps_percent = = 0 ) | |
( prev_sclk = = max_sclk ) | |
2016-09-06 09:45:43 -04:00
disable_uvd_power_tune )
2016-08-01 12:42:32 -04:00
min_sclk = max_sclk ;
2016-09-06 09:45:43 -04:00
else if ( i = = 1 )
2016-08-01 12:42:32 -04:00
min_sclk = prev_sclk ;
2016-09-06 09:45:43 -04:00
else
2016-08-01 12:42:32 -04:00
min_sclk = ( prev_sclk * ( u32 ) max_ps_percent ) / 100 ;
if ( min_sclk < state - > performance_levels [ 0 ] . sclk )
min_sclk = state - > performance_levels [ 0 ] . sclk ;
if ( min_sclk = = 0 )
return - EINVAL ;
ret = si_populate_voltage_value ( adev , & eg_pi - > vddc_voltage_table ,
state - > performance_levels [ i - 1 ] . vddc , & vddc ) ;
if ( ret )
return ret ;
ret = si_get_std_voltage_value ( adev , & vddc , & prev_std_vddc ) ;
if ( ret )
return ret ;
ret = si_populate_voltage_value ( adev , & eg_pi - > vddc_voltage_table ,
state - > performance_levels [ i ] . vddc , & vddc ) ;
if ( ret )
return ret ;
ret = si_get_std_voltage_value ( adev , & vddc , & curr_std_vddc ) ;
if ( ret )
return ret ;
pwr_efficiency_ratio = si_calculate_power_efficiency_ratio ( adev ,
prev_std_vddc , curr_std_vddc ) ;
smc_state - > levels [ i ] . dpm2 . MaxPS = ( u8 ) ( ( SISLANDS_DPM2_MAX_PULSE_SKIP * ( max_sclk - min_sclk ) ) / max_sclk ) ;
smc_state - > levels [ i ] . dpm2 . NearTDPDec = SISLANDS_DPM2_NEAR_TDP_DEC ;
smc_state - > levels [ i ] . dpm2 . AboveSafeInc = SISLANDS_DPM2_ABOVE_SAFE_INC ;
smc_state - > levels [ i ] . dpm2 . BelowSafeInc = SISLANDS_DPM2_BELOW_SAFE_INC ;
smc_state - > levels [ i ] . dpm2 . PwrEfficiencyRatio = cpu_to_be16 ( pwr_efficiency_ratio ) ;
}
return 0 ;
}
static int si_populate_sq_ramping_values ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_state ,
SISLANDS_SMC_SWSTATE * smc_state )
{
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
struct si_ps * state = si_get_ps ( amdgpu_state ) ;
u32 sq_power_throttle , sq_power_throttle2 ;
bool enable_sq_ramping = ni_pi - > enable_sq_ramping ;
int i ;
if ( state - > performance_level_count = = 0 )
return - EINVAL ;
if ( smc_state - > levelCount ! = state - > performance_level_count )
return - EINVAL ;
if ( adev - > pm . dpm . sq_ramping_threshold = = 0 )
return - EINVAL ;
if ( SISLANDS_DPM2_SQ_RAMP_MAX_POWER > ( MAX_POWER_MASK > > MAX_POWER_SHIFT ) )
enable_sq_ramping = false ;
if ( SISLANDS_DPM2_SQ_RAMP_MIN_POWER > ( MIN_POWER_MASK > > MIN_POWER_SHIFT ) )
enable_sq_ramping = false ;
if ( SISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA > ( MAX_POWER_DELTA_MASK > > MAX_POWER_DELTA_SHIFT ) )
enable_sq_ramping = false ;
if ( SISLANDS_DPM2_SQ_RAMP_STI_SIZE > ( STI_SIZE_MASK > > STI_SIZE_SHIFT ) )
enable_sq_ramping = false ;
if ( SISLANDS_DPM2_SQ_RAMP_LTI_RATIO > ( LTI_RATIO_MASK > > LTI_RATIO_SHIFT ) )
enable_sq_ramping = false ;
for ( i = 0 ; i < state - > performance_level_count ; i + + ) {
sq_power_throttle = 0 ;
sq_power_throttle2 = 0 ;
if ( ( state - > performance_levels [ i ] . sclk > = adev - > pm . dpm . sq_ramping_threshold ) & &
enable_sq_ramping ) {
sq_power_throttle | = MAX_POWER ( SISLANDS_DPM2_SQ_RAMP_MAX_POWER ) ;
sq_power_throttle | = MIN_POWER ( SISLANDS_DPM2_SQ_RAMP_MIN_POWER ) ;
sq_power_throttle2 | = MAX_POWER_DELTA ( SISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA ) ;
sq_power_throttle2 | = STI_SIZE ( SISLANDS_DPM2_SQ_RAMP_STI_SIZE ) ;
sq_power_throttle2 | = LTI_RATIO ( SISLANDS_DPM2_SQ_RAMP_LTI_RATIO ) ;
} else {
sq_power_throttle | = MAX_POWER_MASK | MIN_POWER_MASK ;
sq_power_throttle2 | = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK ;
}
smc_state - > levels [ i ] . SQPowerThrottle = cpu_to_be32 ( sq_power_throttle ) ;
smc_state - > levels [ i ] . SQPowerThrottle_2 = cpu_to_be32 ( sq_power_throttle2 ) ;
}
return 0 ;
}
static int si_enable_power_containment ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_new_state ,
bool enable )
{
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
PPSMC_Result smc_result ;
int ret = 0 ;
if ( ni_pi - > enable_power_containment ) {
if ( enable ) {
if ( ! si_should_disable_uvd_powertune ( adev , amdgpu_new_state ) ) {
2016-09-13 00:06:07 -04:00
smc_result = amdgpu_si_send_msg_to_smc ( adev , PPSMC_TDPClampingActive ) ;
2016-08-01 12:42:32 -04:00
if ( smc_result ! = PPSMC_Result_OK ) {
ret = - EINVAL ;
ni_pi - > pc_enabled = false ;
} else {
ni_pi - > pc_enabled = true ;
}
}
} else {
2016-09-13 00:06:07 -04:00
smc_result = amdgpu_si_send_msg_to_smc ( adev , PPSMC_TDPClampingInactive ) ;
2016-08-01 12:42:32 -04:00
if ( smc_result ! = PPSMC_Result_OK )
ret = - EINVAL ;
ni_pi - > pc_enabled = false ;
}
}
return ret ;
}
static int si_initialize_smc_dte_tables ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
int ret = 0 ;
struct si_dte_data * dte_data = & si_pi - > dte_data ;
Smc_SIslands_DTE_Configuration * dte_tables = NULL ;
u32 table_size ;
u8 tdep_count ;
u32 i ;
if ( dte_data = = NULL )
si_pi - > enable_dte = false ;
if ( si_pi - > enable_dte = = false )
return 0 ;
if ( dte_data - > k < = 0 )
return - EINVAL ;
dte_tables = kzalloc ( sizeof ( Smc_SIslands_DTE_Configuration ) , GFP_KERNEL ) ;
if ( dte_tables = = NULL ) {
si_pi - > enable_dte = false ;
return - ENOMEM ;
}
table_size = dte_data - > k ;
if ( table_size > SMC_SISLANDS_DTE_MAX_FILTER_STAGES )
table_size = SMC_SISLANDS_DTE_MAX_FILTER_STAGES ;
tdep_count = dte_data - > tdep_count ;
if ( tdep_count > SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE )
tdep_count = SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE ;
dte_tables - > K = cpu_to_be32 ( table_size ) ;
dte_tables - > T0 = cpu_to_be32 ( dte_data - > t0 ) ;
dte_tables - > MaxT = cpu_to_be32 ( dte_data - > max_t ) ;
dte_tables - > WindowSize = dte_data - > window_size ;
dte_tables - > temp_select = dte_data - > temp_select ;
dte_tables - > DTE_mode = dte_data - > dte_mode ;
dte_tables - > Tthreshold = cpu_to_be32 ( dte_data - > t_threshold ) ;
if ( tdep_count > 0 )
table_size - - ;
for ( i = 0 ; i < table_size ; i + + ) {
dte_tables - > tau [ i ] = cpu_to_be32 ( dte_data - > tau [ i ] ) ;
dte_tables - > R [ i ] = cpu_to_be32 ( dte_data - > r [ i ] ) ;
}
dte_tables - > Tdep_count = tdep_count ;
for ( i = 0 ; i < ( u32 ) tdep_count ; i + + ) {
dte_tables - > T_limits [ i ] = dte_data - > t_limits [ i ] ;
dte_tables - > Tdep_tau [ i ] = cpu_to_be32 ( dte_data - > tdep_tau [ i ] ) ;
dte_tables - > Tdep_R [ i ] = cpu_to_be32 ( dte_data - > tdep_r [ i ] ) ;
}
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_copy_bytes_to_smc ( adev , si_pi - > dte_table_start ,
( u8 * ) dte_tables ,
sizeof ( Smc_SIslands_DTE_Configuration ) ,
si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
kfree ( dte_tables ) ;
return ret ;
}
static int si_get_cac_std_voltage_max_min ( struct amdgpu_device * adev ,
u16 * max , u16 * min )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct amdgpu_cac_leakage_table * table =
& adev - > pm . dpm . dyn_state . cac_leakage_table ;
u32 i ;
u32 v0_loadline ;
if ( table = = NULL )
return - EINVAL ;
* max = 0 ;
* min = 0xFFFF ;
for ( i = 0 ; i < table - > count ; i + + ) {
if ( table - > entries [ i ] . vddc > * max )
* max = table - > entries [ i ] . vddc ;
if ( table - > entries [ i ] . vddc < * min )
* min = table - > entries [ i ] . vddc ;
}
if ( si_pi - > powertune_data - > lkge_lut_v0_percent > 100 )
return - EINVAL ;
v0_loadline = ( * min ) * ( 100 - si_pi - > powertune_data - > lkge_lut_v0_percent ) / 100 ;
if ( v0_loadline > 0xFFFFUL )
return - EINVAL ;
* min = ( u16 ) v0_loadline ;
if ( ( * min > * max ) | | ( * max = = 0 ) | | ( * min = = 0 ) )
return - EINVAL ;
return 0 ;
}
static u16 si_get_cac_std_voltage_step ( u16 max , u16 min )
{
return ( ( max - min ) + ( SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES - 1 ) ) /
SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES ;
}
static int si_init_dte_leakage_table ( struct amdgpu_device * adev ,
PP_SIslands_CacConfig * cac_tables ,
u16 vddc_max , u16 vddc_min , u16 vddc_step ,
u16 t0 , u16 t_step )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 leakage ;
unsigned int i , j ;
s32 t ;
u32 smc_leakage ;
u32 scaling_factor ;
u16 voltage ;
scaling_factor = si_get_smc_power_scaling_factor ( adev ) ;
for ( i = 0 ; i < SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES ; i + + ) {
t = ( 1000 * ( i * t_step + t0 ) ) ;
for ( j = 0 ; j < SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES ; j + + ) {
voltage = vddc_max - ( vddc_step * j ) ;
si_calculate_leakage_for_v_and_t ( adev ,
& si_pi - > powertune_data - > leakage_coefficients ,
voltage ,
t ,
si_pi - > dyn_powertune_data . cac_leakage ,
& leakage ) ;
smc_leakage = si_scale_power_for_smc ( leakage , scaling_factor ) / 4 ;
if ( smc_leakage > 0xFFFF )
smc_leakage = 0xFFFF ;
cac_tables - > cac_lkge_lut [ i ] [ SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES - 1 - j ] =
cpu_to_be16 ( ( u16 ) smc_leakage ) ;
}
}
return 0 ;
}
static int si_init_simplified_leakage_table ( struct amdgpu_device * adev ,
PP_SIslands_CacConfig * cac_tables ,
u16 vddc_max , u16 vddc_min , u16 vddc_step )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 leakage ;
unsigned int i , j ;
u32 smc_leakage ;
u32 scaling_factor ;
u16 voltage ;
scaling_factor = si_get_smc_power_scaling_factor ( adev ) ;
for ( j = 0 ; j < SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES ; j + + ) {
voltage = vddc_max - ( vddc_step * j ) ;
si_calculate_leakage_for_v ( adev ,
& si_pi - > powertune_data - > leakage_coefficients ,
si_pi - > powertune_data - > fixed_kt ,
voltage ,
si_pi - > dyn_powertune_data . cac_leakage ,
& leakage ) ;
smc_leakage = si_scale_power_for_smc ( leakage , scaling_factor ) / 4 ;
if ( smc_leakage > 0xFFFF )
smc_leakage = 0xFFFF ;
for ( i = 0 ; i < SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES ; i + + )
cac_tables - > cac_lkge_lut [ i ] [ SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES - 1 - j ] =
cpu_to_be16 ( ( u16 ) smc_leakage ) ;
}
return 0 ;
}
static int si_initialize_smc_cac_tables ( struct amdgpu_device * adev )
{
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
PP_SIslands_CacConfig * cac_tables = NULL ;
u16 vddc_max , vddc_min , vddc_step ;
u16 t0 , t_step ;
u32 load_line_slope , reg ;
int ret = 0 ;
u32 ticks_per_us = amdgpu_asic_get_xclk ( adev ) / 100 ;
if ( ni_pi - > enable_cac = = false )
return 0 ;
cac_tables = kzalloc ( sizeof ( PP_SIslands_CacConfig ) , GFP_KERNEL ) ;
if ( ! cac_tables )
return - ENOMEM ;
reg = RREG32 ( CG_CAC_CTRL ) & ~ CAC_WINDOW_MASK ;
reg | = CAC_WINDOW ( si_pi - > powertune_data - > cac_window ) ;
WREG32 ( CG_CAC_CTRL , reg ) ;
si_pi - > dyn_powertune_data . cac_leakage = adev - > pm . dpm . cac_leakage ;
si_pi - > dyn_powertune_data . dc_pwr_value =
si_pi - > powertune_data - > dc_cac [ NISLANDS_DCCAC_LEVEL_0 ] ;
si_pi - > dyn_powertune_data . wintime = si_calculate_cac_wintime ( adev ) ;
si_pi - > dyn_powertune_data . shift_n = si_pi - > powertune_data - > shift_n_default ;
si_pi - > dyn_powertune_data . leakage_minimum_temperature = 80 * 1000 ;
ret = si_get_cac_std_voltage_max_min ( adev , & vddc_max , & vddc_min ) ;
if ( ret )
goto done_free ;
vddc_step = si_get_cac_std_voltage_step ( vddc_max , vddc_min ) ;
vddc_min = vddc_max - ( vddc_step * ( SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES - 1 ) ) ;
t_step = 4 ;
t0 = 60 ;
if ( si_pi - > enable_dte | | ni_pi - > driver_calculate_cac_leakage )
ret = si_init_dte_leakage_table ( adev , cac_tables ,
vddc_max , vddc_min , vddc_step ,
t0 , t_step ) ;
else
ret = si_init_simplified_leakage_table ( adev , cac_tables ,
vddc_max , vddc_min , vddc_step ) ;
if ( ret )
goto done_free ;
load_line_slope = ( ( u32 ) adev - > pm . dpm . load_line_slope < < SMC_SISLANDS_SCALE_R ) / 100 ;
cac_tables - > l2numWin_TDP = cpu_to_be32 ( si_pi - > dyn_powertune_data . l2_lta_window_size ) ;
cac_tables - > lts_truncate_n = si_pi - > dyn_powertune_data . lts_truncate ;
cac_tables - > SHIFT_N = si_pi - > dyn_powertune_data . shift_n ;
cac_tables - > lkge_lut_V0 = cpu_to_be32 ( ( u32 ) vddc_min ) ;
cac_tables - > lkge_lut_Vstep = cpu_to_be32 ( ( u32 ) vddc_step ) ;
cac_tables - > R_LL = cpu_to_be32 ( load_line_slope ) ;
cac_tables - > WinTime = cpu_to_be32 ( si_pi - > dyn_powertune_data . wintime ) ;
cac_tables - > calculation_repeats = cpu_to_be32 ( 2 ) ;
cac_tables - > dc_cac = cpu_to_be32 ( 0 ) ;
cac_tables - > log2_PG_LKG_SCALE = 12 ;
cac_tables - > cac_temp = si_pi - > powertune_data - > operating_temp ;
cac_tables - > lkge_lut_T0 = cpu_to_be32 ( ( u32 ) t0 ) ;
cac_tables - > lkge_lut_Tstep = cpu_to_be32 ( ( u32 ) t_step ) ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_copy_bytes_to_smc ( adev , si_pi - > cac_table_start ,
( u8 * ) cac_tables ,
sizeof ( PP_SIslands_CacConfig ) ,
si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
goto done_free ;
ret = si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_ticks_per_us , ticks_per_us ) ;
done_free :
if ( ret ) {
ni_pi - > enable_cac = false ;
ni_pi - > enable_power_containment = false ;
}
kfree ( cac_tables ) ;
2016-09-07 08:42:41 -04:00
return ret ;
2016-08-01 12:42:32 -04:00
}
static int si_program_cac_config_registers ( struct amdgpu_device * adev ,
const struct si_cac_config_reg * cac_config_regs )
{
const struct si_cac_config_reg * config_regs = cac_config_regs ;
u32 data = 0 , offset ;
if ( ! config_regs )
return - EINVAL ;
while ( config_regs - > offset ! = 0xFFFFFFFF ) {
switch ( config_regs - > type ) {
case SISLANDS_CACCONFIG_CGIND :
offset = SMC_CG_IND_START + config_regs - > offset ;
if ( offset < SMC_CG_IND_END )
data = RREG32_SMC ( offset ) ;
break ;
default :
data = RREG32 ( config_regs - > offset ) ;
break ;
}
data & = ~ config_regs - > mask ;
data | = ( ( config_regs - > value < < config_regs - > shift ) & config_regs - > mask ) ;
switch ( config_regs - > type ) {
case SISLANDS_CACCONFIG_CGIND :
offset = SMC_CG_IND_START + config_regs - > offset ;
if ( offset < SMC_CG_IND_END )
WREG32_SMC ( offset , data ) ;
break ;
default :
WREG32 ( config_regs - > offset , data ) ;
break ;
}
config_regs + + ;
}
return 0 ;
}
static int si_initialize_hardware_cac_manager ( struct amdgpu_device * adev )
{
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
int ret ;
if ( ( ni_pi - > enable_cac = = false ) | |
( ni_pi - > cac_configuration_required = = false ) )
return 0 ;
ret = si_program_cac_config_registers ( adev , si_pi - > lcac_config ) ;
if ( ret )
return ret ;
ret = si_program_cac_config_registers ( adev , si_pi - > cac_override ) ;
if ( ret )
return ret ;
ret = si_program_cac_config_registers ( adev , si_pi - > cac_weights ) ;
if ( ret )
return ret ;
return 0 ;
}
static int si_enable_smc_cac ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_new_state ,
bool enable )
{
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
PPSMC_Result smc_result ;
int ret = 0 ;
if ( ni_pi - > enable_cac ) {
if ( enable ) {
if ( ! si_should_disable_uvd_powertune ( adev , amdgpu_new_state ) ) {
if ( ni_pi - > support_cac_long_term_average ) {
2016-09-13 00:06:07 -04:00
smc_result = amdgpu_si_send_msg_to_smc ( adev , PPSMC_CACLongTermAvgEnable ) ;
2016-08-01 12:42:32 -04:00
if ( smc_result ! = PPSMC_Result_OK )
ni_pi - > support_cac_long_term_average = false ;
}
2016-09-13 00:06:07 -04:00
smc_result = amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_EnableCac ) ;
2016-08-01 12:42:32 -04:00
if ( smc_result ! = PPSMC_Result_OK ) {
ret = - EINVAL ;
ni_pi - > cac_enabled = false ;
} else {
ni_pi - > cac_enabled = true ;
}
if ( si_pi - > enable_dte ) {
2016-09-13 00:06:07 -04:00
smc_result = amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_EnableDTE ) ;
2016-08-01 12:42:32 -04:00
if ( smc_result ! = PPSMC_Result_OK )
ret = - EINVAL ;
}
}
} else if ( ni_pi - > cac_enabled ) {
if ( si_pi - > enable_dte )
2016-09-13 00:06:07 -04:00
smc_result = amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_DisableDTE ) ;
2016-08-01 12:42:32 -04:00
2016-09-13 00:06:07 -04:00
smc_result = amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_DisableCac ) ;
2016-08-01 12:42:32 -04:00
ni_pi - > cac_enabled = false ;
if ( ni_pi - > support_cac_long_term_average )
2016-09-13 00:06:07 -04:00
smc_result = amdgpu_si_send_msg_to_smc ( adev , PPSMC_CACLongTermAvgDisable ) ;
2016-08-01 12:42:32 -04:00
}
}
return ret ;
}
static int si_init_smc_spll_table ( struct amdgpu_device * adev )
{
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
SMC_SISLANDS_SPLL_DIV_TABLE * spll_table ;
SISLANDS_SMC_SCLK_VALUE sclk_params ;
u32 fb_div , p_div ;
u32 clk_s , clk_v ;
u32 sclk = 0 ;
int ret = 0 ;
u32 tmp ;
int i ;
if ( si_pi - > spll_table_start = = 0 )
return - EINVAL ;
spll_table = kzalloc ( sizeof ( SMC_SISLANDS_SPLL_DIV_TABLE ) , GFP_KERNEL ) ;
if ( spll_table = = NULL )
return - ENOMEM ;
for ( i = 0 ; i < 256 ; i + + ) {
ret = si_calculate_sclk_params ( adev , sclk , & sclk_params ) ;
if ( ret )
break ;
p_div = ( sclk_params . vCG_SPLL_FUNC_CNTL & SPLL_PDIV_A_MASK ) > > SPLL_PDIV_A_SHIFT ;
fb_div = ( sclk_params . vCG_SPLL_FUNC_CNTL_3 & SPLL_FB_DIV_MASK ) > > SPLL_FB_DIV_SHIFT ;
clk_s = ( sclk_params . vCG_SPLL_SPREAD_SPECTRUM & CLK_S_MASK ) > > CLK_S_SHIFT ;
clk_v = ( sclk_params . vCG_SPLL_SPREAD_SPECTRUM_2 & CLK_V_MASK ) > > CLK_V_SHIFT ;
fb_div & = ~ 0x00001FFF ;
fb_div > > = 1 ;
clk_v > > = 6 ;
if ( p_div & ~ ( SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_MASK > > SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT ) )
ret = - EINVAL ;
if ( fb_div & ~ ( SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_MASK > > SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT ) )
ret = - EINVAL ;
if ( clk_s & ~ ( SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_MASK > > SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT ) )
ret = - EINVAL ;
if ( clk_v & ~ ( SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_MASK > > SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT ) )
ret = - EINVAL ;
if ( ret )
break ;
tmp = ( ( fb_div < < SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT ) & SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_MASK ) |
( ( p_div < < SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT ) & SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_MASK ) ;
spll_table - > freq [ i ] = cpu_to_be32 ( tmp ) ;
tmp = ( ( clk_v < < SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT ) & SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_MASK ) |
( ( clk_s < < SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT ) & SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_MASK ) ;
spll_table - > ss [ i ] = cpu_to_be32 ( tmp ) ;
sclk + = 512 ;
}
if ( ! ret )
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_copy_bytes_to_smc ( adev , si_pi - > spll_table_start ,
( u8 * ) spll_table ,
sizeof ( SMC_SISLANDS_SPLL_DIV_TABLE ) ,
si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
ni_pi - > enable_power_containment = false ;
kfree ( spll_table ) ;
return ret ;
}
static u16 si_get_lower_of_leakage_and_vce_voltage ( struct amdgpu_device * adev ,
u16 vce_voltage )
{
u16 highest_leakage = 0 ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
int i ;
for ( i = 0 ; i < si_pi - > leakage_voltage . count ; i + + ) {
if ( highest_leakage < si_pi - > leakage_voltage . entries [ i ] . voltage )
highest_leakage = si_pi - > leakage_voltage . entries [ i ] . voltage ;
}
if ( si_pi - > leakage_voltage . count & & ( highest_leakage < vce_voltage ) )
return highest_leakage ;
return vce_voltage ;
}
static int si_get_vce_clock_voltage ( struct amdgpu_device * adev ,
u32 evclk , u32 ecclk , u16 * voltage )
{
u32 i ;
int ret = - EINVAL ;
struct amdgpu_vce_clock_voltage_dependency_table * table =
& adev - > pm . dpm . dyn_state . vce_clock_voltage_dependency_table ;
if ( ( ( evclk = = 0 ) & & ( ecclk = = 0 ) ) | |
( table & & ( table - > count = = 0 ) ) ) {
* voltage = 0 ;
return 0 ;
}
for ( i = 0 ; i < table - > count ; i + + ) {
if ( ( evclk < = table - > entries [ i ] . evclk ) & &
( ecclk < = table - > entries [ i ] . ecclk ) ) {
* voltage = table - > entries [ i ] . v ;
ret = 0 ;
break ;
}
}
/* if no match return the highest voltage */
if ( ret )
* voltage = table - > entries [ table - > count - 1 ] . v ;
* voltage = si_get_lower_of_leakage_and_vce_voltage ( adev , * voltage ) ;
return ret ;
}
2017-09-06 15:27:59 +08:00
static bool si_dpm_vblank_too_short ( void * handle )
2016-08-01 12:42:32 -04:00
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-09-06 09:45:43 -04:00
u32 vblank_time = amdgpu_dpm_get_vblank_time ( adev ) ;
/* we never hit the non-gddr5 limit so disable it */
u32 switch_limit = adev - > mc . vram_type = = AMDGPU_VRAM_TYPE_GDDR5 ? 450 : 0 ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
if ( vblank_time < switch_limit )
return true ;
else
return false ;
2016-08-01 12:42:32 -04:00
}
static int ni_copy_and_switch_arb_sets ( struct amdgpu_device * adev ,
u32 arb_freq_src , u32 arb_freq_dest )
{
u32 mc_arb_dram_timing ;
u32 mc_arb_dram_timing2 ;
u32 burst_time ;
u32 mc_cg_config ;
switch ( arb_freq_src ) {
2016-09-06 09:45:43 -04:00
case MC_CG_ARB_FREQ_F0 :
2016-08-01 12:42:32 -04:00
mc_arb_dram_timing = RREG32 ( MC_ARB_DRAM_TIMING ) ;
mc_arb_dram_timing2 = RREG32 ( MC_ARB_DRAM_TIMING2 ) ;
burst_time = ( RREG32 ( MC_ARB_BURST_TIME ) & STATE0_MASK ) > > STATE0_SHIFT ;
break ;
2016-09-06 09:45:43 -04:00
case MC_CG_ARB_FREQ_F1 :
2016-08-01 12:42:32 -04:00
mc_arb_dram_timing = RREG32 ( MC_ARB_DRAM_TIMING_1 ) ;
mc_arb_dram_timing2 = RREG32 ( MC_ARB_DRAM_TIMING2_1 ) ;
burst_time = ( RREG32 ( MC_ARB_BURST_TIME ) & STATE1_MASK ) > > STATE1_SHIFT ;
break ;
2016-09-06 09:45:43 -04:00
case MC_CG_ARB_FREQ_F2 :
2016-08-01 12:42:32 -04:00
mc_arb_dram_timing = RREG32 ( MC_ARB_DRAM_TIMING_2 ) ;
mc_arb_dram_timing2 = RREG32 ( MC_ARB_DRAM_TIMING2_2 ) ;
burst_time = ( RREG32 ( MC_ARB_BURST_TIME ) & STATE2_MASK ) > > STATE2_SHIFT ;
break ;
2016-09-06 09:45:43 -04:00
case MC_CG_ARB_FREQ_F3 :
2016-08-01 12:42:32 -04:00
mc_arb_dram_timing = RREG32 ( MC_ARB_DRAM_TIMING_3 ) ;
mc_arb_dram_timing2 = RREG32 ( MC_ARB_DRAM_TIMING2_3 ) ;
burst_time = ( RREG32 ( MC_ARB_BURST_TIME ) & STATE3_MASK ) > > STATE3_SHIFT ;
break ;
2016-09-06 09:45:43 -04:00
default :
2016-08-01 12:42:32 -04:00
return - EINVAL ;
}
switch ( arb_freq_dest ) {
2016-09-06 09:45:43 -04:00
case MC_CG_ARB_FREQ_F0 :
2016-08-01 12:42:32 -04:00
WREG32 ( MC_ARB_DRAM_TIMING , mc_arb_dram_timing ) ;
WREG32 ( MC_ARB_DRAM_TIMING2 , mc_arb_dram_timing2 ) ;
WREG32_P ( MC_ARB_BURST_TIME , STATE0 ( burst_time ) , ~ STATE0_MASK ) ;
break ;
2016-09-06 09:45:43 -04:00
case MC_CG_ARB_FREQ_F1 :
2016-08-01 12:42:32 -04:00
WREG32 ( MC_ARB_DRAM_TIMING_1 , mc_arb_dram_timing ) ;
WREG32 ( MC_ARB_DRAM_TIMING2_1 , mc_arb_dram_timing2 ) ;
WREG32_P ( MC_ARB_BURST_TIME , STATE1 ( burst_time ) , ~ STATE1_MASK ) ;
break ;
2016-09-06 09:45:43 -04:00
case MC_CG_ARB_FREQ_F2 :
2016-08-01 12:42:32 -04:00
WREG32 ( MC_ARB_DRAM_TIMING_2 , mc_arb_dram_timing ) ;
WREG32 ( MC_ARB_DRAM_TIMING2_2 , mc_arb_dram_timing2 ) ;
WREG32_P ( MC_ARB_BURST_TIME , STATE2 ( burst_time ) , ~ STATE2_MASK ) ;
break ;
2016-09-06 09:45:43 -04:00
case MC_CG_ARB_FREQ_F3 :
2016-08-01 12:42:32 -04:00
WREG32 ( MC_ARB_DRAM_TIMING_3 , mc_arb_dram_timing ) ;
WREG32 ( MC_ARB_DRAM_TIMING2_3 , mc_arb_dram_timing2 ) ;
WREG32_P ( MC_ARB_BURST_TIME , STATE3 ( burst_time ) , ~ STATE3_MASK ) ;
break ;
default :
return - EINVAL ;
}
mc_cg_config = RREG32 ( MC_CG_CONFIG ) | 0x0000000F ;
WREG32 ( MC_CG_CONFIG , mc_cg_config ) ;
WREG32_P ( MC_ARB_CG , CG_ARB_REQ ( arb_freq_dest ) , ~ CG_ARB_REQ_MASK ) ;
return 0 ;
}
static void ni_update_current_ps ( struct amdgpu_device * adev ,
struct amdgpu_ps * rps )
{
2016-09-06 09:45:43 -04:00
struct si_ps * new_ps = si_get_ps ( rps ) ;
2016-08-01 12:42:32 -04:00
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
2016-09-06 09:45:43 -04:00
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
2016-08-01 12:42:32 -04:00
eg_pi - > current_rps = * rps ;
ni_pi - > current_ps = * new_ps ;
eg_pi - > current_rps . ps_priv = & ni_pi - > current_ps ;
2016-10-14 19:29:02 +08:00
adev - > pm . dpm . current_ps = & eg_pi - > current_rps ;
2016-08-01 12:42:32 -04:00
}
static void ni_update_requested_ps ( struct amdgpu_device * adev ,
struct amdgpu_ps * rps )
{
2016-09-06 09:45:43 -04:00
struct si_ps * new_ps = si_get_ps ( rps ) ;
2016-08-01 12:42:32 -04:00
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
2016-09-06 09:45:43 -04:00
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
2016-08-01 12:42:32 -04:00
eg_pi - > requested_rps = * rps ;
ni_pi - > requested_ps = * new_ps ;
eg_pi - > requested_rps . ps_priv = & ni_pi - > requested_ps ;
2016-10-14 19:29:02 +08:00
adev - > pm . dpm . requested_ps = & eg_pi - > requested_rps ;
2016-08-01 12:42:32 -04:00
}
static void ni_set_uvd_clock_before_set_eng_clock ( struct amdgpu_device * adev ,
struct amdgpu_ps * new_ps ,
struct amdgpu_ps * old_ps )
{
2016-09-06 09:45:43 -04:00
struct si_ps * new_state = si_get_ps ( new_ps ) ;
struct si_ps * current_state = si_get_ps ( old_ps ) ;
2016-08-01 12:42:32 -04:00
if ( ( new_ps - > vclk = = old_ps - > vclk ) & &
( new_ps - > dclk = = old_ps - > dclk ) )
return ;
if ( new_state - > performance_levels [ new_state - > performance_level_count - 1 ] . sclk > =
current_state - > performance_levels [ current_state - > performance_level_count - 1 ] . sclk )
return ;
amdgpu_asic_set_uvd_clocks ( adev , new_ps - > vclk , new_ps - > dclk ) ;
}
static void ni_set_uvd_clock_after_set_eng_clock ( struct amdgpu_device * adev ,
struct amdgpu_ps * new_ps ,
struct amdgpu_ps * old_ps )
{
2016-09-06 09:45:43 -04:00
struct si_ps * new_state = si_get_ps ( new_ps ) ;
struct si_ps * current_state = si_get_ps ( old_ps ) ;
2016-08-01 12:42:32 -04:00
if ( ( new_ps - > vclk = = old_ps - > vclk ) & &
( new_ps - > dclk = = old_ps - > dclk ) )
return ;
if ( new_state - > performance_levels [ new_state - > performance_level_count - 1 ] . sclk <
current_state - > performance_levels [ current_state - > performance_level_count - 1 ] . sclk )
return ;
amdgpu_asic_set_uvd_clocks ( adev , new_ps - > vclk , new_ps - > dclk ) ;
}
static u16 btc_find_voltage ( struct atom_voltage_table * table , u16 voltage )
{
2016-09-06 09:45:43 -04:00
unsigned int i ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
for ( i = 0 ; i < table - > count ; i + + )
if ( voltage < = table - > entries [ i ] . value )
return table - > entries [ i ] . value ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
return table - > entries [ table - > count - 1 ] . value ;
2016-08-01 12:42:32 -04:00
}
static u32 btc_find_valid_clock ( struct amdgpu_clock_array * clocks ,
2016-09-06 09:45:43 -04:00
u32 max_clock , u32 requested_clock )
2016-08-01 12:42:32 -04:00
{
2016-09-06 09:45:43 -04:00
unsigned int i ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
if ( ( clocks = = NULL ) | | ( clocks - > count = = 0 ) )
return ( requested_clock < max_clock ) ? requested_clock : max_clock ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
for ( i = 0 ; i < clocks - > count ; i + + ) {
if ( clocks - > values [ i ] > = requested_clock )
return ( clocks - > values [ i ] < max_clock ) ? clocks - > values [ i ] : max_clock ;
}
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
return ( clocks - > values [ clocks - > count - 1 ] < max_clock ) ?
clocks - > values [ clocks - > count - 1 ] : max_clock ;
2016-08-01 12:42:32 -04:00
}
static u32 btc_get_valid_mclk ( struct amdgpu_device * adev ,
2016-09-06 09:45:43 -04:00
u32 max_mclk , u32 requested_mclk )
2016-08-01 12:42:32 -04:00
{
2016-09-06 09:45:43 -04:00
return btc_find_valid_clock ( & adev - > pm . dpm . dyn_state . valid_mclk_values ,
max_mclk , requested_mclk ) ;
2016-08-01 12:42:32 -04:00
}
static u32 btc_get_valid_sclk ( struct amdgpu_device * adev ,
2016-09-06 09:45:43 -04:00
u32 max_sclk , u32 requested_sclk )
2016-08-01 12:42:32 -04:00
{
2016-09-06 09:45:43 -04:00
return btc_find_valid_clock ( & adev - > pm . dpm . dyn_state . valid_sclk_values ,
max_sclk , requested_sclk ) ;
2016-08-01 12:42:32 -04:00
}
2016-09-12 23:46:06 -04:00
static void btc_get_max_clock_from_voltage_dependency_table ( struct amdgpu_clock_voltage_dependency_table * table ,
u32 * max_clock )
2016-08-01 12:42:32 -04:00
{
2016-09-06 09:45:43 -04:00
u32 i , clock = 0 ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
if ( ( table = = NULL ) | | ( table - > count = = 0 ) ) {
* max_clock = clock ;
return ;
}
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
for ( i = 0 ; i < table - > count ; i + + ) {
if ( clock < table - > entries [ i ] . clk )
clock = table - > entries [ i ] . clk ;
}
* max_clock = clock ;
2016-08-01 12:42:32 -04:00
}
static void btc_apply_voltage_dependency_rules ( struct amdgpu_clock_voltage_dependency_table * table ,
2016-09-06 09:45:43 -04:00
u32 clock , u16 max_voltage , u16 * voltage )
2016-08-01 12:42:32 -04:00
{
2016-09-06 09:45:43 -04:00
u32 i ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
if ( ( table = = NULL ) | | ( table - > count = = 0 ) )
return ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
for ( i = 0 ; i < table - > count ; i + + ) {
if ( clock < = table - > entries [ i ] . clk ) {
if ( * voltage < table - > entries [ i ] . v )
* voltage = ( u16 ) ( ( table - > entries [ i ] . v < max_voltage ) ?
table - > entries [ i ] . v : max_voltage ) ;
return ;
}
}
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
* voltage = ( * voltage > max_voltage ) ? * voltage : max_voltage ;
2016-08-01 12:42:32 -04:00
}
static void btc_adjust_clock_combinations ( struct amdgpu_device * adev ,
2016-09-06 09:45:43 -04:00
const struct amdgpu_clock_and_voltage_limits * max_limits ,
struct rv7xx_pl * pl )
2016-08-01 12:42:32 -04:00
{
2016-09-06 09:45:43 -04:00
if ( ( pl - > mclk = = 0 ) | | ( pl - > sclk = = 0 ) )
return ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
if ( pl - > mclk = = pl - > sclk )
return ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
if ( pl - > mclk > pl - > sclk ) {
if ( ( ( pl - > mclk + ( pl - > sclk - 1 ) ) / pl - > sclk ) > adev - > pm . dpm . dyn_state . mclk_sclk_ratio )
pl - > sclk = btc_get_valid_sclk ( adev ,
max_limits - > sclk ,
( pl - > mclk +
( adev - > pm . dpm . dyn_state . mclk_sclk_ratio - 1 ) ) /
adev - > pm . dpm . dyn_state . mclk_sclk_ratio ) ;
} else {
if ( ( pl - > sclk - pl - > mclk ) > adev - > pm . dpm . dyn_state . sclk_mclk_delta )
pl - > mclk = btc_get_valid_mclk ( adev ,
max_limits - > mclk ,
pl - > sclk -
adev - > pm . dpm . dyn_state . sclk_mclk_delta ) ;
}
2016-08-01 12:42:32 -04:00
}
static void btc_apply_voltage_delta_rules ( struct amdgpu_device * adev ,
2016-09-06 09:45:43 -04:00
u16 max_vddc , u16 max_vddci ,
u16 * vddc , u16 * vddci )
{
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
u16 new_voltage ;
if ( ( 0 = = * vddc ) | | ( 0 = = * vddci ) )
return ;
if ( * vddc > * vddci ) {
if ( ( * vddc - * vddci ) > adev - > pm . dpm . dyn_state . vddc_vddci_delta ) {
new_voltage = btc_find_voltage ( & eg_pi - > vddci_voltage_table ,
( * vddc - adev - > pm . dpm . dyn_state . vddc_vddci_delta ) ) ;
* vddci = ( new_voltage < max_vddci ) ? new_voltage : max_vddci ;
}
} else {
if ( ( * vddci - * vddc ) > adev - > pm . dpm . dyn_state . vddc_vddci_delta ) {
new_voltage = btc_find_voltage ( & eg_pi - > vddc_voltage_table ,
( * vddci - adev - > pm . dpm . dyn_state . vddc_vddci_delta ) ) ;
* vddc = ( new_voltage < max_vddc ) ? new_voltage : max_vddc ;
}
}
2016-08-01 12:42:32 -04:00
}
static enum amdgpu_pcie_gen r600_get_pcie_gen_support ( struct amdgpu_device * adev ,
u32 sys_mask ,
enum amdgpu_pcie_gen asic_gen ,
enum amdgpu_pcie_gen default_gen )
{
switch ( asic_gen ) {
case AMDGPU_PCIE_GEN1 :
return AMDGPU_PCIE_GEN1 ;
case AMDGPU_PCIE_GEN2 :
return AMDGPU_PCIE_GEN2 ;
case AMDGPU_PCIE_GEN3 :
return AMDGPU_PCIE_GEN3 ;
default :
if ( ( sys_mask & DRM_PCIE_SPEED_80 ) & & ( default_gen = = AMDGPU_PCIE_GEN3 ) )
return AMDGPU_PCIE_GEN3 ;
else if ( ( sys_mask & DRM_PCIE_SPEED_50 ) & & ( default_gen = = AMDGPU_PCIE_GEN2 ) )
return AMDGPU_PCIE_GEN2 ;
else
return AMDGPU_PCIE_GEN1 ;
}
return AMDGPU_PCIE_GEN1 ;
}
static void r600_calculate_u_and_p ( u32 i , u32 r_c , u32 p_b ,
u32 * p , u32 * u )
{
u32 b_c = 0 ;
u32 i_c ;
u32 tmp ;
i_c = ( i * r_c ) / 100 ;
tmp = i_c > > p_b ;
while ( tmp ) {
b_c + + ;
tmp > > = 1 ;
}
* u = ( b_c + 1 ) / 2 ;
* p = i_c / ( 1 < < ( 2 * ( * u ) ) ) ;
}
static int r600_calculate_at ( u32 t , u32 h , u32 fh , u32 fl , u32 * tl , u32 * th )
{
u32 k , a , ah , al ;
u32 t1 ;
if ( ( fl = = 0 ) | | ( fh = = 0 ) | | ( fl > fh ) )
return - EINVAL ;
k = ( 100 * fh ) / fl ;
t1 = ( t * ( k - 100 ) ) ;
a = ( 1000 * ( 100 * h + t1 ) ) / ( 10000 + ( t1 / 100 ) ) ;
a = ( a + 5 ) / 10 ;
ah = ( ( a * t ) + 5000 ) / 10000 ;
al = a - ah ;
* th = t - ah ;
* tl = t + al ;
return 0 ;
}
static bool r600_is_uvd_state ( u32 class , u32 class2 )
{
if ( class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE )
return true ;
if ( class & ATOM_PPLIB_CLASSIFICATION_HD2STATE )
return true ;
if ( class & ATOM_PPLIB_CLASSIFICATION_HDSTATE )
return true ;
if ( class & ATOM_PPLIB_CLASSIFICATION_SDSTATE )
return true ;
if ( class2 & ATOM_PPLIB_CLASSIFICATION2_MVC )
return true ;
return false ;
}
static u8 rv770_get_memory_module_index ( struct amdgpu_device * adev )
{
return ( u8 ) ( ( RREG32 ( BIOS_SCRATCH_4 ) > > 16 ) & 0xff ) ;
}
static void rv770_get_max_vddc ( struct amdgpu_device * adev )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
u16 vddc ;
if ( amdgpu_atombios_get_max_vddc ( adev , 0 , 0 , & vddc ) )
pi - > max_vddc = 0 ;
else
pi - > max_vddc = vddc ;
}
static void rv770_get_engine_memory_ss ( struct amdgpu_device * adev )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct amdgpu_atom_ss ss ;
pi - > sclk_ss = amdgpu_atombios_get_asic_ss_info ( adev , & ss ,
ASIC_INTERNAL_ENGINE_SS , 0 ) ;
pi - > mclk_ss = amdgpu_atombios_get_asic_ss_info ( adev , & ss ,
ASIC_INTERNAL_MEMORY_SS , 0 ) ;
if ( pi - > sclk_ss | | pi - > mclk_ss )
pi - > dynamic_ss = true ;
else
pi - > dynamic_ss = false ;
}
static void si_apply_state_adjust_rules ( struct amdgpu_device * adev ,
struct amdgpu_ps * rps )
{
struct si_ps * ps = si_get_ps ( rps ) ;
struct amdgpu_clock_and_voltage_limits * max_limits ;
bool disable_mclk_switching = false ;
bool disable_sclk_switching = false ;
u32 mclk , sclk ;
u16 vddc , vddci , min_vce_voltage = 0 ;
u32 max_sclk_vddc , max_mclk_vddci , max_mclk_vddc ;
u32 max_sclk = 0 , max_mclk = 0 ;
int i ;
2017-01-24 16:59:35 -05:00
if ( adev - > asic_type = = CHIP_HAINAN ) {
2016-10-26 15:27:45 -04:00
if ( ( adev - > pdev - > revision = = 0x81 ) | |
( adev - > pdev - > revision = = 0x83 ) | |
( adev - > pdev - > revision = = 0xC3 ) | |
( adev - > pdev - > device = = 0x6664 ) | |
( adev - > pdev - > device = = 0x6665 ) | |
( adev - > pdev - > device = = 0x6667 ) ) {
max_sclk = 75000 ;
}
2017-03-14 19:24:19 -04:00
} else if ( adev - > asic_type = = CHIP_OLAND ) {
2017-03-15 21:13:25 -04:00
if ( ( adev - > pdev - > revision = = 0xC7 ) | |
( adev - > pdev - > revision = = 0x80 ) | |
( adev - > pdev - > revision = = 0x81 ) | |
( adev - > pdev - > revision = = 0x83 ) | |
( adev - > pdev - > revision = = 0x87 ) | |
( adev - > pdev - > device = = 0x6604 ) | |
( adev - > pdev - > device = = 0x6605 ) ) {
2017-03-14 19:24:19 -04:00
max_sclk = 75000 ;
}
2016-10-26 15:27:45 -04:00
}
2016-08-01 12:42:32 -04:00
if ( rps - > vce_active ) {
rps - > evclk = adev - > pm . dpm . vce_states [ adev - > pm . dpm . vce_level ] . evclk ;
rps - > ecclk = adev - > pm . dpm . vce_states [ adev - > pm . dpm . vce_level ] . ecclk ;
si_get_vce_clock_voltage ( adev , rps - > evclk , rps - > ecclk ,
& min_vce_voltage ) ;
} else {
rps - > evclk = 0 ;
rps - > ecclk = 0 ;
}
if ( ( adev - > pm . dpm . new_active_crtc_count > 1 ) | |
si_dpm_vblank_too_short ( adev ) )
disable_mclk_switching = true ;
if ( rps - > vclk | | rps - > dclk ) {
disable_mclk_switching = true ;
disable_sclk_switching = true ;
}
if ( adev - > pm . dpm . ac_power )
max_limits = & adev - > pm . dpm . dyn_state . max_clock_voltage_on_ac ;
else
max_limits = & adev - > pm . dpm . dyn_state . max_clock_voltage_on_dc ;
for ( i = ps - > performance_level_count - 2 ; i > = 0 ; i - - ) {
if ( ps - > performance_levels [ i ] . vddc > ps - > performance_levels [ i + 1 ] . vddc )
ps - > performance_levels [ i ] . vddc = ps - > performance_levels [ i + 1 ] . vddc ;
}
if ( adev - > pm . dpm . ac_power = = false ) {
for ( i = 0 ; i < ps - > performance_level_count ; i + + ) {
if ( ps - > performance_levels [ i ] . mclk > max_limits - > mclk )
ps - > performance_levels [ i ] . mclk = max_limits - > mclk ;
if ( ps - > performance_levels [ i ] . sclk > max_limits - > sclk )
ps - > performance_levels [ i ] . sclk = max_limits - > sclk ;
if ( ps - > performance_levels [ i ] . vddc > max_limits - > vddc )
ps - > performance_levels [ i ] . vddc = max_limits - > vddc ;
if ( ps - > performance_levels [ i ] . vddci > max_limits - > vddci )
ps - > performance_levels [ i ] . vddci = max_limits - > vddci ;
}
}
/* limit clocks to max supported clocks based on voltage dependency tables */
btc_get_max_clock_from_voltage_dependency_table ( & adev - > pm . dpm . dyn_state . vddc_dependency_on_sclk ,
& max_sclk_vddc ) ;
btc_get_max_clock_from_voltage_dependency_table ( & adev - > pm . dpm . dyn_state . vddci_dependency_on_mclk ,
& max_mclk_vddci ) ;
btc_get_max_clock_from_voltage_dependency_table ( & adev - > pm . dpm . dyn_state . vddc_dependency_on_mclk ,
& max_mclk_vddc ) ;
for ( i = 0 ; i < ps - > performance_level_count ; i + + ) {
if ( max_sclk_vddc ) {
if ( ps - > performance_levels [ i ] . sclk > max_sclk_vddc )
ps - > performance_levels [ i ] . sclk = max_sclk_vddc ;
}
if ( max_mclk_vddci ) {
if ( ps - > performance_levels [ i ] . mclk > max_mclk_vddci )
ps - > performance_levels [ i ] . mclk = max_mclk_vddci ;
}
if ( max_mclk_vddc ) {
if ( ps - > performance_levels [ i ] . mclk > max_mclk_vddc )
ps - > performance_levels [ i ] . mclk = max_mclk_vddc ;
}
if ( max_mclk ) {
if ( ps - > performance_levels [ i ] . mclk > max_mclk )
ps - > performance_levels [ i ] . mclk = max_mclk ;
}
if ( max_sclk ) {
if ( ps - > performance_levels [ i ] . sclk > max_sclk )
ps - > performance_levels [ i ] . sclk = max_sclk ;
}
}
/* XXX validate the min clocks required for display */
if ( disable_mclk_switching ) {
mclk = ps - > performance_levels [ ps - > performance_level_count - 1 ] . mclk ;
vddci = ps - > performance_levels [ ps - > performance_level_count - 1 ] . vddci ;
} else {
mclk = ps - > performance_levels [ 0 ] . mclk ;
vddci = ps - > performance_levels [ 0 ] . vddci ;
}
if ( disable_sclk_switching ) {
sclk = ps - > performance_levels [ ps - > performance_level_count - 1 ] . sclk ;
vddc = ps - > performance_levels [ ps - > performance_level_count - 1 ] . vddc ;
} else {
sclk = ps - > performance_levels [ 0 ] . sclk ;
vddc = ps - > performance_levels [ 0 ] . vddc ;
}
if ( rps - > vce_active ) {
if ( sclk < adev - > pm . dpm . vce_states [ adev - > pm . dpm . vce_level ] . sclk )
sclk = adev - > pm . dpm . vce_states [ adev - > pm . dpm . vce_level ] . sclk ;
if ( mclk < adev - > pm . dpm . vce_states [ adev - > pm . dpm . vce_level ] . mclk )
mclk = adev - > pm . dpm . vce_states [ adev - > pm . dpm . vce_level ] . mclk ;
}
/* adjusted low state */
ps - > performance_levels [ 0 ] . sclk = sclk ;
ps - > performance_levels [ 0 ] . mclk = mclk ;
ps - > performance_levels [ 0 ] . vddc = vddc ;
ps - > performance_levels [ 0 ] . vddci = vddci ;
if ( disable_sclk_switching ) {
sclk = ps - > performance_levels [ 0 ] . sclk ;
for ( i = 1 ; i < ps - > performance_level_count ; i + + ) {
if ( sclk < ps - > performance_levels [ i ] . sclk )
sclk = ps - > performance_levels [ i ] . sclk ;
}
for ( i = 0 ; i < ps - > performance_level_count ; i + + ) {
ps - > performance_levels [ i ] . sclk = sclk ;
ps - > performance_levels [ i ] . vddc = vddc ;
}
} else {
for ( i = 1 ; i < ps - > performance_level_count ; i + + ) {
if ( ps - > performance_levels [ i ] . sclk < ps - > performance_levels [ i - 1 ] . sclk )
ps - > performance_levels [ i ] . sclk = ps - > performance_levels [ i - 1 ] . sclk ;
if ( ps - > performance_levels [ i ] . vddc < ps - > performance_levels [ i - 1 ] . vddc )
ps - > performance_levels [ i ] . vddc = ps - > performance_levels [ i - 1 ] . vddc ;
}
}
if ( disable_mclk_switching ) {
mclk = ps - > performance_levels [ 0 ] . mclk ;
for ( i = 1 ; i < ps - > performance_level_count ; i + + ) {
if ( mclk < ps - > performance_levels [ i ] . mclk )
mclk = ps - > performance_levels [ i ] . mclk ;
}
for ( i = 0 ; i < ps - > performance_level_count ; i + + ) {
ps - > performance_levels [ i ] . mclk = mclk ;
ps - > performance_levels [ i ] . vddci = vddci ;
}
} else {
for ( i = 1 ; i < ps - > performance_level_count ; i + + ) {
if ( ps - > performance_levels [ i ] . mclk < ps - > performance_levels [ i - 1 ] . mclk )
ps - > performance_levels [ i ] . mclk = ps - > performance_levels [ i - 1 ] . mclk ;
if ( ps - > performance_levels [ i ] . vddci < ps - > performance_levels [ i - 1 ] . vddci )
ps - > performance_levels [ i ] . vddci = ps - > performance_levels [ i - 1 ] . vddci ;
}
}
2016-09-06 09:45:43 -04:00
for ( i = 0 ; i < ps - > performance_level_count ; i + + )
btc_adjust_clock_combinations ( adev , max_limits ,
& ps - > performance_levels [ i ] ) ;
2016-08-01 12:42:32 -04:00
for ( i = 0 ; i < ps - > performance_level_count ; i + + ) {
if ( ps - > performance_levels [ i ] . vddc < min_vce_voltage )
ps - > performance_levels [ i ] . vddc = min_vce_voltage ;
btc_apply_voltage_dependency_rules ( & adev - > pm . dpm . dyn_state . vddc_dependency_on_sclk ,
ps - > performance_levels [ i ] . sclk ,
max_limits - > vddc , & ps - > performance_levels [ i ] . vddc ) ;
btc_apply_voltage_dependency_rules ( & adev - > pm . dpm . dyn_state . vddci_dependency_on_mclk ,
ps - > performance_levels [ i ] . mclk ,
max_limits - > vddci , & ps - > performance_levels [ i ] . vddci ) ;
btc_apply_voltage_dependency_rules ( & adev - > pm . dpm . dyn_state . vddc_dependency_on_mclk ,
ps - > performance_levels [ i ] . mclk ,
max_limits - > vddc , & ps - > performance_levels [ i ] . vddc ) ;
btc_apply_voltage_dependency_rules ( & adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk ,
adev - > clock . current_dispclk ,
max_limits - > vddc , & ps - > performance_levels [ i ] . vddc ) ;
}
for ( i = 0 ; i < ps - > performance_level_count ; i + + ) {
btc_apply_voltage_delta_rules ( adev ,
max_limits - > vddc , max_limits - > vddci ,
& ps - > performance_levels [ i ] . vddc ,
& ps - > performance_levels [ i ] . vddci ) ;
}
ps - > dc_compatible = true ;
for ( i = 0 ; i < ps - > performance_level_count ; i + + ) {
if ( ps - > performance_levels [ i ] . vddc > adev - > pm . dpm . dyn_state . max_clock_voltage_on_dc . vddc )
ps - > dc_compatible = false ;
}
}
#if 0
static int si_read_smc_soft_register ( struct amdgpu_device * adev ,
u16 reg_offset , u32 * value )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
2016-09-13 00:06:07 -04:00
return amdgpu_si_read_smc_sram_dword ( adev ,
si_pi - > soft_regs_start + reg_offset , value ,
si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
}
# endif
static int si_write_smc_soft_register ( struct amdgpu_device * adev ,
u16 reg_offset , u32 value )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
2016-09-13 00:06:07 -04:00
return amdgpu_si_write_smc_sram_dword ( adev ,
si_pi - > soft_regs_start + reg_offset ,
value , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
}
static bool si_is_special_1gb_platform ( struct amdgpu_device * adev )
{
bool ret = false ;
u32 tmp , width , row , column , bank , density ;
bool is_memory_gddr5 , is_special ;
tmp = RREG32 ( MC_SEQ_MISC0 ) ;
is_memory_gddr5 = ( MC_SEQ_MISC0_GDDR5_VALUE = = ( ( tmp & MC_SEQ_MISC0_GDDR5_MASK ) > > MC_SEQ_MISC0_GDDR5_SHIFT ) ) ;
is_special = ( MC_SEQ_MISC0_REV_ID_VALUE = = ( ( tmp & MC_SEQ_MISC0_REV_ID_MASK ) > > MC_SEQ_MISC0_REV_ID_SHIFT ) )
& ( MC_SEQ_MISC0_VEN_ID_VALUE = = ( ( tmp & MC_SEQ_MISC0_VEN_ID_MASK ) > > MC_SEQ_MISC0_VEN_ID_SHIFT ) ) ;
WREG32 ( MC_SEQ_IO_DEBUG_INDEX , 0xb ) ;
width = ( ( RREG32 ( MC_SEQ_IO_DEBUG_DATA ) > > 1 ) & 1 ) ? 16 : 32 ;
tmp = RREG32 ( MC_ARB_RAMCFG ) ;
row = ( ( tmp & NOOFROWS_MASK ) > > NOOFROWS_SHIFT ) + 10 ;
column = ( ( tmp & NOOFCOLS_MASK ) > > NOOFCOLS_SHIFT ) + 8 ;
bank = ( ( tmp & NOOFBANK_MASK ) > > NOOFBANK_SHIFT ) + 2 ;
density = ( 1 < < ( row + column - 20 + bank ) ) * width ;
if ( ( adev - > pdev - > device = = 0x6819 ) & &
is_memory_gddr5 & & is_special & & ( density = = 0x400 ) )
ret = true ;
return ret ;
}
static void si_get_leakage_vddc ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u16 vddc , count = 0 ;
int i , ret ;
for ( i = 0 ; i < SISLANDS_MAX_LEAKAGE_COUNT ; i + + ) {
ret = amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx ( adev , & vddc , SISLANDS_LEAKAGE_INDEX0 + i ) ;
if ( ! ret & & ( vddc > 0 ) & & ( vddc ! = ( SISLANDS_LEAKAGE_INDEX0 + i ) ) ) {
si_pi - > leakage_voltage . entries [ count ] . voltage = vddc ;
si_pi - > leakage_voltage . entries [ count ] . leakage_index =
SISLANDS_LEAKAGE_INDEX0 + i ;
count + + ;
}
}
si_pi - > leakage_voltage . count = count ;
}
static int si_get_leakage_voltage_from_leakage_index ( struct amdgpu_device * adev ,
u32 index , u16 * leakage_voltage )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
int i ;
if ( leakage_voltage = = NULL )
return - EINVAL ;
if ( ( index & 0xff00 ) ! = 0xff00 )
return - EINVAL ;
if ( ( index & 0xff ) > SISLANDS_MAX_LEAKAGE_COUNT + 1 )
return - EINVAL ;
if ( index < SISLANDS_LEAKAGE_INDEX0 )
return - EINVAL ;
for ( i = 0 ; i < si_pi - > leakage_voltage . count ; i + + ) {
if ( si_pi - > leakage_voltage . entries [ i ] . leakage_index = = index ) {
* leakage_voltage = si_pi - > leakage_voltage . entries [ i ] . voltage ;
return 0 ;
}
}
return - EAGAIN ;
}
static void si_set_dpm_event_sources ( struct amdgpu_device * adev , u32 sources )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
bool want_thermal_protection ;
enum amdgpu_dpm_event_src dpm_event_src ;
switch ( sources ) {
case 0 :
default :
want_thermal_protection = false ;
2016-09-06 09:45:43 -04:00
break ;
2016-08-01 12:42:32 -04:00
case ( 1 < < AMDGPU_DPM_AUTO_THROTTLE_SRC_THERMAL ) :
want_thermal_protection = true ;
dpm_event_src = AMDGPU_DPM_EVENT_SRC_DIGITAL ;
break ;
case ( 1 < < AMDGPU_DPM_AUTO_THROTTLE_SRC_EXTERNAL ) :
want_thermal_protection = true ;
dpm_event_src = AMDGPU_DPM_EVENT_SRC_EXTERNAL ;
break ;
case ( ( 1 < < AMDGPU_DPM_AUTO_THROTTLE_SRC_EXTERNAL ) |
( 1 < < AMDGPU_DPM_AUTO_THROTTLE_SRC_THERMAL ) ) :
want_thermal_protection = true ;
dpm_event_src = AMDGPU_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL ;
break ;
}
if ( want_thermal_protection ) {
WREG32_P ( CG_THERMAL_CTRL , DPM_EVENT_SRC ( dpm_event_src ) , ~ DPM_EVENT_SRC_MASK ) ;
if ( pi - > thermal_protection )
WREG32_P ( GENERAL_PWRMGT , 0 , ~ THERMAL_PROTECTION_DIS ) ;
} else {
WREG32_P ( GENERAL_PWRMGT , THERMAL_PROTECTION_DIS , ~ THERMAL_PROTECTION_DIS ) ;
}
}
static void si_enable_auto_throttle_source ( struct amdgpu_device * adev ,
enum amdgpu_dpm_auto_throttle_src source ,
bool enable )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
if ( enable ) {
if ( ! ( pi - > active_auto_throttle_sources & ( 1 < < source ) ) ) {
pi - > active_auto_throttle_sources | = 1 < < source ;
si_set_dpm_event_sources ( adev , pi - > active_auto_throttle_sources ) ;
}
} else {
if ( pi - > active_auto_throttle_sources & ( 1 < < source ) ) {
pi - > active_auto_throttle_sources & = ~ ( 1 < < source ) ;
si_set_dpm_event_sources ( adev , pi - > active_auto_throttle_sources ) ;
}
}
}
static void si_start_dpm ( struct amdgpu_device * adev )
{
WREG32_P ( GENERAL_PWRMGT , GLOBAL_PWRMGT_EN , ~ GLOBAL_PWRMGT_EN ) ;
}
static void si_stop_dpm ( struct amdgpu_device * adev )
{
WREG32_P ( GENERAL_PWRMGT , 0 , ~ GLOBAL_PWRMGT_EN ) ;
}
static void si_enable_sclk_control ( struct amdgpu_device * adev , bool enable )
{
if ( enable )
WREG32_P ( SCLK_PWRMGT_CNTL , 0 , ~ SCLK_PWRMGT_OFF ) ;
else
WREG32_P ( SCLK_PWRMGT_CNTL , SCLK_PWRMGT_OFF , ~ SCLK_PWRMGT_OFF ) ;
}
#if 0
static int si_notify_hardware_of_thermal_state ( struct amdgpu_device * adev ,
u32 thermal_level )
{
PPSMC_Result ret ;
if ( thermal_level = = 0 ) {
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_EnableThermalInterrupt ) ;
2016-08-01 12:42:32 -04:00
if ( ret = = PPSMC_Result_OK )
return 0 ;
else
return - EINVAL ;
}
return 0 ;
}
static void si_notify_hardware_vpu_recovery_event ( struct amdgpu_device * adev )
{
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_tdr_is_about_to_happen , true ) ;
}
# endif
#if 0
static int si_notify_hw_of_powersource ( struct amdgpu_device * adev , bool ac_power )
{
if ( ac_power )
2016-09-13 00:06:07 -04:00
return ( amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_RunningOnAC ) = = PPSMC_Result_OK ) ?
2016-08-01 12:42:32 -04:00
0 : - EINVAL ;
return 0 ;
}
# endif
static PPSMC_Result si_send_msg_to_smc_with_parameter ( struct amdgpu_device * adev ,
PPSMC_Msg msg , u32 parameter )
{
WREG32 ( SMC_SCRATCH0 , parameter ) ;
2016-09-13 00:06:07 -04:00
return amdgpu_si_send_msg_to_smc ( adev , msg ) ;
2016-08-01 12:42:32 -04:00
}
static int si_restrict_performance_levels_before_switch ( struct amdgpu_device * adev )
{
2016-09-13 00:06:07 -04:00
if ( amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_NoForcedLevel ) ! = PPSMC_Result_OK )
2016-08-01 12:42:32 -04:00
return - EINVAL ;
return ( si_send_msg_to_smc_with_parameter ( adev , PPSMC_MSG_SetEnabledLevels , 1 ) = = PPSMC_Result_OK ) ?
0 : - EINVAL ;
}
2017-09-06 15:27:59 +08:00
static int si_dpm_force_performance_level ( void * handle ,
2016-12-23 14:39:41 +08:00
enum amd_dpm_forced_level level )
2016-08-01 12:42:32 -04:00
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-08-01 12:42:32 -04:00
struct amdgpu_ps * rps = adev - > pm . dpm . current_ps ;
struct si_ps * ps = si_get_ps ( rps ) ;
u32 levels = ps - > performance_level_count ;
2016-12-23 14:39:41 +08:00
if ( level = = AMD_DPM_FORCED_LEVEL_HIGH ) {
2016-08-01 12:42:32 -04:00
if ( si_send_msg_to_smc_with_parameter ( adev , PPSMC_MSG_SetEnabledLevels , levels ) ! = PPSMC_Result_OK )
return - EINVAL ;
if ( si_send_msg_to_smc_with_parameter ( adev , PPSMC_MSG_SetForcedLevels , 1 ) ! = PPSMC_Result_OK )
return - EINVAL ;
2016-12-23 14:39:41 +08:00
} else if ( level = = AMD_DPM_FORCED_LEVEL_LOW ) {
2016-08-01 12:42:32 -04:00
if ( si_send_msg_to_smc_with_parameter ( adev , PPSMC_MSG_SetForcedLevels , 0 ) ! = PPSMC_Result_OK )
return - EINVAL ;
if ( si_send_msg_to_smc_with_parameter ( adev , PPSMC_MSG_SetEnabledLevels , 1 ) ! = PPSMC_Result_OK )
return - EINVAL ;
2016-12-23 14:39:41 +08:00
} else if ( level = = AMD_DPM_FORCED_LEVEL_AUTO ) {
2016-08-01 12:42:32 -04:00
if ( si_send_msg_to_smc_with_parameter ( adev , PPSMC_MSG_SetForcedLevels , 0 ) ! = PPSMC_Result_OK )
return - EINVAL ;
if ( si_send_msg_to_smc_with_parameter ( adev , PPSMC_MSG_SetEnabledLevels , levels ) ! = PPSMC_Result_OK )
return - EINVAL ;
}
adev - > pm . dpm . forced_level = level ;
return 0 ;
}
#if 0
static int si_set_boot_state ( struct amdgpu_device * adev )
{
2016-09-13 00:06:07 -04:00
return ( amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_SwitchToInitialState ) = = PPSMC_Result_OK ) ?
2016-08-01 12:42:32 -04:00
0 : - EINVAL ;
}
# endif
static int si_set_sw_state ( struct amdgpu_device * adev )
{
2016-09-13 00:06:07 -04:00
return ( amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_SwitchToSwState ) = = PPSMC_Result_OK ) ?
2016-08-01 12:42:32 -04:00
0 : - EINVAL ;
}
static int si_halt_smc ( struct amdgpu_device * adev )
{
2016-09-13 00:06:07 -04:00
if ( amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_Halt ) ! = PPSMC_Result_OK )
2016-08-01 12:42:32 -04:00
return - EINVAL ;
2016-09-13 00:06:07 -04:00
return ( amdgpu_si_wait_for_smc_inactive ( adev ) = = PPSMC_Result_OK ) ?
2016-08-01 12:42:32 -04:00
0 : - EINVAL ;
}
static int si_resume_smc ( struct amdgpu_device * adev )
{
2016-09-13 00:06:07 -04:00
if ( amdgpu_si_send_msg_to_smc ( adev , PPSMC_FlushDataCache ) ! = PPSMC_Result_OK )
2016-08-01 12:42:32 -04:00
return - EINVAL ;
2016-09-13 00:06:07 -04:00
return ( amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_Resume ) = = PPSMC_Result_OK ) ?
2016-08-01 12:42:32 -04:00
0 : - EINVAL ;
}
static void si_dpm_start_smc ( struct amdgpu_device * adev )
{
2016-09-13 00:06:07 -04:00
amdgpu_si_program_jump_on_start ( adev ) ;
amdgpu_si_start_smc ( adev ) ;
amdgpu_si_smc_clock ( adev , true ) ;
2016-08-01 12:42:32 -04:00
}
static void si_dpm_stop_smc ( struct amdgpu_device * adev )
{
2016-09-13 00:06:07 -04:00
amdgpu_si_reset_smc ( adev ) ;
amdgpu_si_smc_clock ( adev , false ) ;
2016-08-01 12:42:32 -04:00
}
static int si_process_firmware_header ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 tmp ;
int ret ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_read_smc_sram_dword ( adev ,
SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
SISLANDS_SMC_FIRMWARE_HEADER_stateTable ,
& tmp , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
2016-09-06 09:45:43 -04:00
si_pi - > state_table_start = tmp ;
2016-08-01 12:42:32 -04:00
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_read_smc_sram_dword ( adev ,
SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
SISLANDS_SMC_FIRMWARE_HEADER_softRegisters ,
& tmp , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
si_pi - > soft_regs_start = tmp ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_read_smc_sram_dword ( adev ,
SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
SISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable ,
& tmp , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
si_pi - > mc_reg_table_start = tmp ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_read_smc_sram_dword ( adev ,
SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
SISLANDS_SMC_FIRMWARE_HEADER_fanTable ,
& tmp , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
si_pi - > fan_table_start = tmp ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_read_smc_sram_dword ( adev ,
SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
SISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable ,
& tmp , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
si_pi - > arb_table_start = tmp ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_read_smc_sram_dword ( adev ,
SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
SISLANDS_SMC_FIRMWARE_HEADER_CacConfigTable ,
& tmp , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
si_pi - > cac_table_start = tmp ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_read_smc_sram_dword ( adev ,
SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
SISLANDS_SMC_FIRMWARE_HEADER_DteConfiguration ,
& tmp , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
si_pi - > dte_table_start = tmp ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_read_smc_sram_dword ( adev ,
SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
SISLANDS_SMC_FIRMWARE_HEADER_spllTable ,
& tmp , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
si_pi - > spll_table_start = tmp ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_read_smc_sram_dword ( adev ,
SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
SISLANDS_SMC_FIRMWARE_HEADER_PAPMParameters ,
& tmp , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
si_pi - > papm_cfg_table_start = tmp ;
return ret ;
}
static void si_read_clock_registers ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
si_pi - > clock_registers . cg_spll_func_cntl = RREG32 ( CG_SPLL_FUNC_CNTL ) ;
si_pi - > clock_registers . cg_spll_func_cntl_2 = RREG32 ( CG_SPLL_FUNC_CNTL_2 ) ;
si_pi - > clock_registers . cg_spll_func_cntl_3 = RREG32 ( CG_SPLL_FUNC_CNTL_3 ) ;
si_pi - > clock_registers . cg_spll_func_cntl_4 = RREG32 ( CG_SPLL_FUNC_CNTL_4 ) ;
si_pi - > clock_registers . cg_spll_spread_spectrum = RREG32 ( CG_SPLL_SPREAD_SPECTRUM ) ;
si_pi - > clock_registers . cg_spll_spread_spectrum_2 = RREG32 ( CG_SPLL_SPREAD_SPECTRUM_2 ) ;
si_pi - > clock_registers . dll_cntl = RREG32 ( DLL_CNTL ) ;
si_pi - > clock_registers . mclk_pwrmgt_cntl = RREG32 ( MCLK_PWRMGT_CNTL ) ;
si_pi - > clock_registers . mpll_ad_func_cntl = RREG32 ( MPLL_AD_FUNC_CNTL ) ;
si_pi - > clock_registers . mpll_dq_func_cntl = RREG32 ( MPLL_DQ_FUNC_CNTL ) ;
si_pi - > clock_registers . mpll_func_cntl = RREG32 ( MPLL_FUNC_CNTL ) ;
si_pi - > clock_registers . mpll_func_cntl_1 = RREG32 ( MPLL_FUNC_CNTL_1 ) ;
si_pi - > clock_registers . mpll_func_cntl_2 = RREG32 ( MPLL_FUNC_CNTL_2 ) ;
si_pi - > clock_registers . mpll_ss1 = RREG32 ( MPLL_SS1 ) ;
si_pi - > clock_registers . mpll_ss2 = RREG32 ( MPLL_SS2 ) ;
}
static void si_enable_thermal_protection ( struct amdgpu_device * adev ,
bool enable )
{
if ( enable )
WREG32_P ( GENERAL_PWRMGT , 0 , ~ THERMAL_PROTECTION_DIS ) ;
else
WREG32_P ( GENERAL_PWRMGT , THERMAL_PROTECTION_DIS , ~ THERMAL_PROTECTION_DIS ) ;
}
static void si_enable_acpi_power_management ( struct amdgpu_device * adev )
{
WREG32_P ( GENERAL_PWRMGT , STATIC_PM_EN , ~ STATIC_PM_EN ) ;
}
#if 0
static int si_enter_ulp_state ( struct amdgpu_device * adev )
{
WREG32 ( SMC_MESSAGE_0 , PPSMC_MSG_SwitchToMinimumPower ) ;
udelay ( 25000 ) ;
return 0 ;
}
static int si_exit_ulp_state ( struct amdgpu_device * adev )
{
int i ;
WREG32 ( SMC_MESSAGE_0 , PPSMC_MSG_ResumeFromMinimumPower ) ;
udelay ( 7000 ) ;
for ( i = 0 ; i < adev - > usec_timeout ; i + + ) {
if ( RREG32 ( SMC_RESP_0 ) = = 1 )
break ;
udelay ( 1000 ) ;
}
return 0 ;
}
# endif
static int si_notify_smc_display_change ( struct amdgpu_device * adev ,
bool has_display )
{
PPSMC_Msg msg = has_display ?
PPSMC_MSG_HasDisplay : PPSMC_MSG_NoDisplay ;
2016-09-13 00:06:07 -04:00
return ( amdgpu_si_send_msg_to_smc ( adev , msg ) = = PPSMC_Result_OK ) ?
2016-08-01 12:42:32 -04:00
0 : - EINVAL ;
}
static void si_program_response_times ( struct amdgpu_device * adev )
{
u32 voltage_response_time , backbias_response_time , acpi_delay_time , vbi_time_out ;
u32 vddc_dly , acpi_dly , vbi_dly ;
u32 reference_clock ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_mvdd_chg_time , 1 ) ;
voltage_response_time = ( u32 ) adev - > pm . dpm . voltage_response_time ;
2016-09-06 09:45:43 -04:00
backbias_response_time = ( u32 ) adev - > pm . dpm . backbias_response_time ;
2016-08-01 12:42:32 -04:00
if ( voltage_response_time = = 0 )
voltage_response_time = 1000 ;
acpi_delay_time = 15000 ;
vbi_time_out = 100000 ;
reference_clock = amdgpu_asic_get_xclk ( adev ) ;
vddc_dly = ( voltage_response_time * reference_clock ) / 100 ;
acpi_dly = ( acpi_delay_time * reference_clock ) / 100 ;
vbi_dly = ( vbi_time_out * reference_clock ) / 100 ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_delay_vreg , vddc_dly ) ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_delay_acpi , acpi_dly ) ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_mclk_chg_timeout , vbi_dly ) ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_mc_block_delay , 0xAA ) ;
}
static void si_program_ds_registers ( struct amdgpu_device * adev )
{
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
u32 tmp ;
/* DEEP_SLEEP_CLK_SEL field should be 0x10 on tahiti A0 */
if ( adev - > asic_type = = CHIP_TAHITI & & adev - > rev_id = = 0x0 )
tmp = 0x10 ;
else
tmp = 0x1 ;
if ( eg_pi - > sclk_deep_sleep ) {
WREG32_P ( MISC_CLK_CNTL , DEEP_SLEEP_CLK_SEL ( tmp ) , ~ DEEP_SLEEP_CLK_SEL_MASK ) ;
WREG32_P ( CG_SPLL_AUTOSCALE_CNTL , AUTOSCALE_ON_SS_CLEAR ,
~ AUTOSCALE_ON_SS_CLEAR ) ;
}
}
static void si_program_display_gap ( struct amdgpu_device * adev )
{
u32 tmp , pipe ;
int i ;
tmp = RREG32 ( CG_DISPLAY_GAP_CNTL ) & ~ ( DISP1_GAP_MASK | DISP2_GAP_MASK ) ;
if ( adev - > pm . dpm . new_active_crtc_count > 0 )
tmp | = DISP1_GAP ( R600_PM_DISPLAY_GAP_VBLANK_OR_WM ) ;
else
tmp | = DISP1_GAP ( R600_PM_DISPLAY_GAP_IGNORE ) ;
if ( adev - > pm . dpm . new_active_crtc_count > 1 )
tmp | = DISP2_GAP ( R600_PM_DISPLAY_GAP_VBLANK_OR_WM ) ;
else
tmp | = DISP2_GAP ( R600_PM_DISPLAY_GAP_IGNORE ) ;
WREG32 ( CG_DISPLAY_GAP_CNTL , tmp ) ;
tmp = RREG32 ( DCCG_DISP_SLOW_SELECT_REG ) ;
pipe = ( tmp & DCCG_DISP1_SLOW_SELECT_MASK ) > > DCCG_DISP1_SLOW_SELECT_SHIFT ;
if ( ( adev - > pm . dpm . new_active_crtc_count > 0 ) & &
( ! ( adev - > pm . dpm . new_active_crtcs & ( 1 < < pipe ) ) ) ) {
/* find the first active crtc */
for ( i = 0 ; i < adev - > mode_info . num_crtc ; i + + ) {
if ( adev - > pm . dpm . new_active_crtcs & ( 1 < < i ) )
break ;
}
if ( i = = adev - > mode_info . num_crtc )
pipe = 0 ;
else
pipe = i ;
tmp & = ~ DCCG_DISP1_SLOW_SELECT_MASK ;
tmp | = DCCG_DISP1_SLOW_SELECT ( pipe ) ;
WREG32 ( DCCG_DISP_SLOW_SELECT_REG , tmp ) ;
}
/* Setting this to false forces the performance state to low if the crtcs are disabled.
* This can be a problem on PowerXpress systems or if you want to use the card
* for offscreen rendering or compute if there are no crtcs enabled .
*/
si_notify_smc_display_change ( adev , adev - > pm . dpm . new_active_crtc_count > 0 ) ;
}
static void si_enable_spread_spectrum ( struct amdgpu_device * adev , bool enable )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
if ( enable ) {
if ( pi - > sclk_ss )
WREG32_P ( GENERAL_PWRMGT , DYN_SPREAD_SPECTRUM_EN , ~ DYN_SPREAD_SPECTRUM_EN ) ;
} else {
WREG32_P ( CG_SPLL_SPREAD_SPECTRUM , 0 , ~ SSEN ) ;
WREG32_P ( GENERAL_PWRMGT , 0 , ~ DYN_SPREAD_SPECTRUM_EN ) ;
}
}
static void si_setup_bsp ( struct amdgpu_device * adev )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
u32 xclk = amdgpu_asic_get_xclk ( adev ) ;
r600_calculate_u_and_p ( pi - > asi ,
xclk ,
16 ,
& pi - > bsp ,
& pi - > bsu ) ;
r600_calculate_u_and_p ( pi - > pasi ,
xclk ,
16 ,
& pi - > pbsp ,
& pi - > pbsu ) ;
pi - > dsp = BSP ( pi - > bsp ) | BSU ( pi - > bsu ) ;
pi - > psp = BSP ( pi - > pbsp ) | BSU ( pi - > pbsu ) ;
WREG32 ( CG_BSP , pi - > dsp ) ;
}
static void si_program_git ( struct amdgpu_device * adev )
{
WREG32_P ( CG_GIT , CG_GICST ( R600_GICST_DFLT ) , ~ CG_GICST_MASK ) ;
}
static void si_program_tp ( struct amdgpu_device * adev )
{
int i ;
enum r600_td td = R600_TD_DFLT ;
for ( i = 0 ; i < R600_PM_NUMBER_OF_TC ; i + + )
WREG32 ( CG_FFCT_0 + i , ( UTC_0 ( r600_utc [ i ] ) | DTC_0 ( r600_dtc [ i ] ) ) ) ;
if ( td = = R600_TD_AUTO )
WREG32_P ( SCLK_PWRMGT_CNTL , 0 , ~ FIR_FORCE_TREND_SEL ) ;
else
WREG32_P ( SCLK_PWRMGT_CNTL , FIR_FORCE_TREND_SEL , ~ FIR_FORCE_TREND_SEL ) ;
if ( td = = R600_TD_UP )
WREG32_P ( SCLK_PWRMGT_CNTL , 0 , ~ FIR_TREND_MODE ) ;
if ( td = = R600_TD_DOWN )
WREG32_P ( SCLK_PWRMGT_CNTL , FIR_TREND_MODE , ~ FIR_TREND_MODE ) ;
}
static void si_program_tpp ( struct amdgpu_device * adev )
{
WREG32 ( CG_TPC , R600_TPC_DFLT ) ;
}
static void si_program_sstp ( struct amdgpu_device * adev )
{
WREG32 ( CG_SSP , ( SSTU ( R600_SSTU_DFLT ) | SST ( R600_SST_DFLT ) ) ) ;
}
static void si_enable_display_gap ( struct amdgpu_device * adev )
{
u32 tmp = RREG32 ( CG_DISPLAY_GAP_CNTL ) ;
tmp & = ~ ( DISP1_GAP_MASK | DISP2_GAP_MASK ) ;
tmp | = ( DISP1_GAP ( R600_PM_DISPLAY_GAP_IGNORE ) |
DISP2_GAP ( R600_PM_DISPLAY_GAP_IGNORE ) ) ;
tmp & = ~ ( DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK ) ;
tmp | = ( DISP1_GAP_MCHG ( R600_PM_DISPLAY_GAP_VBLANK ) |
DISP2_GAP_MCHG ( R600_PM_DISPLAY_GAP_IGNORE ) ) ;
WREG32 ( CG_DISPLAY_GAP_CNTL , tmp ) ;
}
static void si_program_vc ( struct amdgpu_device * adev )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
WREG32 ( CG_FTV , pi - > vrc ) ;
}
static void si_clear_vc ( struct amdgpu_device * adev )
{
WREG32 ( CG_FTV , 0 ) ;
}
2016-09-12 23:46:06 -04:00
static u8 si_get_ddr3_mclk_frequency_ratio ( u32 memory_clock )
2016-08-01 12:42:32 -04:00
{
u8 mc_para_index ;
if ( memory_clock < 10000 )
mc_para_index = 0 ;
else if ( memory_clock > = 80000 )
mc_para_index = 0x0f ;
else
mc_para_index = ( u8 ) ( ( memory_clock - 10000 ) / 5000 + 1 ) ;
return mc_para_index ;
}
2016-09-12 23:46:06 -04:00
static u8 si_get_mclk_frequency_ratio ( u32 memory_clock , bool strobe_mode )
2016-08-01 12:42:32 -04:00
{
u8 mc_para_index ;
if ( strobe_mode ) {
if ( memory_clock < 12500 )
mc_para_index = 0x00 ;
else if ( memory_clock > 47500 )
mc_para_index = 0x0f ;
else
mc_para_index = ( u8 ) ( ( memory_clock - 10000 ) / 2500 ) ;
} else {
if ( memory_clock < 65000 )
mc_para_index = 0x00 ;
else if ( memory_clock > 135000 )
mc_para_index = 0x0f ;
else
mc_para_index = ( u8 ) ( ( memory_clock - 60000 ) / 5000 ) ;
}
return mc_para_index ;
}
static u8 si_get_strobe_mode_settings ( struct amdgpu_device * adev , u32 mclk )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
bool strobe_mode = false ;
u8 result = 0 ;
if ( mclk < = pi - > mclk_strobe_mode_threshold )
strobe_mode = true ;
if ( adev - > mc . vram_type = = AMDGPU_VRAM_TYPE_GDDR5 )
result = si_get_mclk_frequency_ratio ( mclk , strobe_mode ) ;
else
result = si_get_ddr3_mclk_frequency_ratio ( mclk ) ;
if ( strobe_mode )
result | = SISLANDS_SMC_STROBE_ENABLE ;
return result ;
}
static int si_upload_firmware ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
2016-09-13 00:06:07 -04:00
amdgpu_si_reset_smc ( adev ) ;
amdgpu_si_smc_clock ( adev , false ) ;
2016-08-01 12:42:32 -04:00
2016-09-13 00:06:07 -04:00
return amdgpu_si_load_smc_ucode ( adev , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
}
static bool si_validate_phase_shedding_tables ( struct amdgpu_device * adev ,
const struct atom_voltage_table * table ,
const struct amdgpu_phase_shedding_limits_table * limits )
{
u32 data , num_bits , num_levels ;
if ( ( table = = NULL ) | | ( limits = = NULL ) )
return false ;
data = table - > mask_low ;
num_bits = hweight32 ( data ) ;
if ( num_bits = = 0 )
return false ;
num_levels = ( 1 < < num_bits ) ;
if ( table - > count ! = num_levels )
return false ;
if ( limits - > count ! = ( num_levels - 1 ) )
return false ;
return true ;
}
static void si_trim_voltage_table_to_fit_state_table ( struct amdgpu_device * adev ,
u32 max_voltage_steps ,
struct atom_voltage_table * voltage_table )
{
unsigned int i , diff ;
if ( voltage_table - > count < = max_voltage_steps )
return ;
diff = voltage_table - > count - max_voltage_steps ;
for ( i = 0 ; i < max_voltage_steps ; i + + )
voltage_table - > entries [ i ] = voltage_table - > entries [ i + diff ] ;
voltage_table - > count = max_voltage_steps ;
}
static int si_get_svi2_voltage_table ( struct amdgpu_device * adev ,
struct amdgpu_clock_voltage_dependency_table * voltage_dependency_table ,
struct atom_voltage_table * voltage_table )
{
u32 i ;
if ( voltage_dependency_table = = NULL )
return - EINVAL ;
voltage_table - > mask_low = 0 ;
voltage_table - > phase_delay = 0 ;
voltage_table - > count = voltage_dependency_table - > count ;
for ( i = 0 ; i < voltage_table - > count ; i + + ) {
voltage_table - > entries [ i ] . value = voltage_dependency_table - > entries [ i ] . v ;
voltage_table - > entries [ i ] . smio_low = 0 ;
}
return 0 ;
}
static int si_construct_voltage_tables ( struct amdgpu_device * adev )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
int ret ;
if ( pi - > voltage_control ) {
ret = amdgpu_atombios_get_voltage_table ( adev , VOLTAGE_TYPE_VDDC ,
VOLTAGE_OBJ_GPIO_LUT , & eg_pi - > vddc_voltage_table ) ;
if ( ret )
return ret ;
if ( eg_pi - > vddc_voltage_table . count > SISLANDS_MAX_NO_VREG_STEPS )
si_trim_voltage_table_to_fit_state_table ( adev ,
SISLANDS_MAX_NO_VREG_STEPS ,
& eg_pi - > vddc_voltage_table ) ;
} else if ( si_pi - > voltage_control_svi2 ) {
ret = si_get_svi2_voltage_table ( adev ,
& adev - > pm . dpm . dyn_state . vddc_dependency_on_mclk ,
& eg_pi - > vddc_voltage_table ) ;
if ( ret )
return ret ;
} else {
return - EINVAL ;
}
if ( eg_pi - > vddci_control ) {
ret = amdgpu_atombios_get_voltage_table ( adev , VOLTAGE_TYPE_VDDCI ,
VOLTAGE_OBJ_GPIO_LUT , & eg_pi - > vddci_voltage_table ) ;
if ( ret )
return ret ;
if ( eg_pi - > vddci_voltage_table . count > SISLANDS_MAX_NO_VREG_STEPS )
si_trim_voltage_table_to_fit_state_table ( adev ,
SISLANDS_MAX_NO_VREG_STEPS ,
& eg_pi - > vddci_voltage_table ) ;
}
if ( si_pi - > vddci_control_svi2 ) {
ret = si_get_svi2_voltage_table ( adev ,
& adev - > pm . dpm . dyn_state . vddci_dependency_on_mclk ,
& eg_pi - > vddci_voltage_table ) ;
if ( ret )
return ret ;
}
if ( pi - > mvdd_control ) {
ret = amdgpu_atombios_get_voltage_table ( adev , VOLTAGE_TYPE_MVDDC ,
VOLTAGE_OBJ_GPIO_LUT , & si_pi - > mvdd_voltage_table ) ;
if ( ret ) {
pi - > mvdd_control = false ;
return ret ;
}
if ( si_pi - > mvdd_voltage_table . count = = 0 ) {
pi - > mvdd_control = false ;
return - EINVAL ;
}
if ( si_pi - > mvdd_voltage_table . count > SISLANDS_MAX_NO_VREG_STEPS )
si_trim_voltage_table_to_fit_state_table ( adev ,
SISLANDS_MAX_NO_VREG_STEPS ,
& si_pi - > mvdd_voltage_table ) ;
}
if ( si_pi - > vddc_phase_shed_control ) {
ret = amdgpu_atombios_get_voltage_table ( adev , VOLTAGE_TYPE_VDDC ,
VOLTAGE_OBJ_PHASE_LUT , & si_pi - > vddc_phase_shed_table ) ;
if ( ret )
si_pi - > vddc_phase_shed_control = false ;
if ( ( si_pi - > vddc_phase_shed_table . count = = 0 ) | |
( si_pi - > vddc_phase_shed_table . count > SISLANDS_MAX_NO_VREG_STEPS ) )
si_pi - > vddc_phase_shed_control = false ;
}
return 0 ;
}
static void si_populate_smc_voltage_table ( struct amdgpu_device * adev ,
const struct atom_voltage_table * voltage_table ,
SISLANDS_SMC_STATETABLE * table )
{
unsigned int i ;
for ( i = 0 ; i < voltage_table - > count ; i + + )
table - > lowSMIO [ i ] | = cpu_to_be32 ( voltage_table - > entries [ i ] . smio_low ) ;
}
static int si_populate_smc_voltage_tables ( struct amdgpu_device * adev ,
SISLANDS_SMC_STATETABLE * table )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u8 i ;
if ( si_pi - > voltage_control_svi2 ) {
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc ,
si_pi - > svc_gpio_id ) ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd ,
si_pi - > svd_gpio_id ) ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_svi_rework_plat_type ,
2 ) ;
} else {
if ( eg_pi - > vddc_voltage_table . count ) {
si_populate_smc_voltage_table ( adev , & eg_pi - > vddc_voltage_table , table ) ;
table - > voltageMaskTable . lowMask [ SISLANDS_SMC_VOLTAGEMASK_VDDC ] =
cpu_to_be32 ( eg_pi - > vddc_voltage_table . mask_low ) ;
for ( i = 0 ; i < eg_pi - > vddc_voltage_table . count ; i + + ) {
if ( pi - > max_vddc_in_table < = eg_pi - > vddc_voltage_table . entries [ i ] . value ) {
table - > maxVDDCIndexInPPTable = i ;
break ;
}
}
}
if ( eg_pi - > vddci_voltage_table . count ) {
si_populate_smc_voltage_table ( adev , & eg_pi - > vddci_voltage_table , table ) ;
table - > voltageMaskTable . lowMask [ SISLANDS_SMC_VOLTAGEMASK_VDDCI ] =
cpu_to_be32 ( eg_pi - > vddci_voltage_table . mask_low ) ;
}
if ( si_pi - > mvdd_voltage_table . count ) {
si_populate_smc_voltage_table ( adev , & si_pi - > mvdd_voltage_table , table ) ;
table - > voltageMaskTable . lowMask [ SISLANDS_SMC_VOLTAGEMASK_MVDD ] =
cpu_to_be32 ( si_pi - > mvdd_voltage_table . mask_low ) ;
}
if ( si_pi - > vddc_phase_shed_control ) {
if ( si_validate_phase_shedding_tables ( adev , & si_pi - > vddc_phase_shed_table ,
& adev - > pm . dpm . dyn_state . phase_shedding_limits_table ) ) {
si_populate_smc_voltage_table ( adev , & si_pi - > vddc_phase_shed_table , table ) ;
2016-09-27 14:57:35 -04:00
table - > phaseMaskTable . lowMask [ SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING ] =
2016-08-01 12:42:32 -04:00
cpu_to_be32 ( si_pi - > vddc_phase_shed_table . mask_low ) ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_phase_shedding_delay ,
( u32 ) si_pi - > vddc_phase_shed_table . phase_delay ) ;
} else {
si_pi - > vddc_phase_shed_control = false ;
}
}
}
return 0 ;
}
static int si_populate_voltage_value ( struct amdgpu_device * adev ,
const struct atom_voltage_table * table ,
u16 value , SISLANDS_SMC_VOLTAGE_VALUE * voltage )
{
unsigned int i ;
for ( i = 0 ; i < table - > count ; i + + ) {
if ( value < = table - > entries [ i ] . value ) {
voltage - > index = ( u8 ) i ;
voltage - > value = cpu_to_be16 ( table - > entries [ i ] . value ) ;
break ;
}
}
if ( i > = table - > count )
return - EINVAL ;
return 0 ;
}
static int si_populate_mvdd_value ( struct amdgpu_device * adev , u32 mclk ,
SISLANDS_SMC_VOLTAGE_VALUE * voltage )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
if ( pi - > mvdd_control ) {
if ( mclk < = pi - > mvdd_split_frequency )
voltage - > index = 0 ;
else
voltage - > index = ( u8 ) ( si_pi - > mvdd_voltage_table . count ) - 1 ;
voltage - > value = cpu_to_be16 ( si_pi - > mvdd_voltage_table . entries [ voltage - > index ] . value ) ;
}
return 0 ;
}
static int si_get_std_voltage_value ( struct amdgpu_device * adev ,
SISLANDS_SMC_VOLTAGE_VALUE * voltage ,
u16 * std_voltage )
{
u16 v_index ;
bool voltage_found = false ;
* std_voltage = be16_to_cpu ( voltage - > value ) ;
if ( adev - > pm . dpm . dyn_state . cac_leakage_table . entries ) {
if ( adev - > pm . dpm . platform_caps & ATOM_PP_PLATFORM_CAP_NEW_CAC_VOLTAGE ) {
if ( adev - > pm . dpm . dyn_state . vddc_dependency_on_sclk . entries = = NULL )
return - EINVAL ;
for ( v_index = 0 ; ( u32 ) v_index < adev - > pm . dpm . dyn_state . vddc_dependency_on_sclk . count ; v_index + + ) {
if ( be16_to_cpu ( voltage - > value ) = =
( u16 ) adev - > pm . dpm . dyn_state . vddc_dependency_on_sclk . entries [ v_index ] . v ) {
voltage_found = true ;
if ( ( u32 ) v_index < adev - > pm . dpm . dyn_state . cac_leakage_table . count )
* std_voltage =
adev - > pm . dpm . dyn_state . cac_leakage_table . entries [ v_index ] . vddc ;
else
* std_voltage =
adev - > pm . dpm . dyn_state . cac_leakage_table . entries [ adev - > pm . dpm . dyn_state . cac_leakage_table . count - 1 ] . vddc ;
break ;
}
}
if ( ! voltage_found ) {
for ( v_index = 0 ; ( u32 ) v_index < adev - > pm . dpm . dyn_state . vddc_dependency_on_sclk . count ; v_index + + ) {
if ( be16_to_cpu ( voltage - > value ) < =
( u16 ) adev - > pm . dpm . dyn_state . vddc_dependency_on_sclk . entries [ v_index ] . v ) {
voltage_found = true ;
if ( ( u32 ) v_index < adev - > pm . dpm . dyn_state . cac_leakage_table . count )
* std_voltage =
adev - > pm . dpm . dyn_state . cac_leakage_table . entries [ v_index ] . vddc ;
else
* std_voltage =
adev - > pm . dpm . dyn_state . cac_leakage_table . entries [ adev - > pm . dpm . dyn_state . cac_leakage_table . count - 1 ] . vddc ;
break ;
}
}
}
} else {
if ( ( u32 ) voltage - > index < adev - > pm . dpm . dyn_state . cac_leakage_table . count )
* std_voltage = adev - > pm . dpm . dyn_state . cac_leakage_table . entries [ voltage - > index ] . vddc ;
}
}
return 0 ;
}
static int si_populate_std_voltage_value ( struct amdgpu_device * adev ,
u16 value , u8 index ,
SISLANDS_SMC_VOLTAGE_VALUE * voltage )
{
voltage - > index = index ;
voltage - > value = cpu_to_be16 ( value ) ;
return 0 ;
}
static int si_populate_phase_shedding_value ( struct amdgpu_device * adev ,
const struct amdgpu_phase_shedding_limits_table * limits ,
u16 voltage , u32 sclk , u32 mclk ,
SISLANDS_SMC_VOLTAGE_VALUE * smc_voltage )
{
unsigned int i ;
for ( i = 0 ; i < limits - > count ; i + + ) {
if ( ( voltage < = limits - > entries [ i ] . voltage ) & &
( sclk < = limits - > entries [ i ] . sclk ) & &
( mclk < = limits - > entries [ i ] . mclk ) )
break ;
}
smc_voltage - > phase_settings = ( u8 ) i ;
return 0 ;
}
static int si_init_arb_table_index ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 tmp ;
int ret ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_read_smc_sram_dword ( adev , si_pi - > arb_table_start ,
& tmp , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
tmp & = 0x00FFFFFF ;
tmp | = MC_CG_ARB_FREQ_F1 < < 24 ;
2016-09-13 00:06:07 -04:00
return amdgpu_si_write_smc_sram_dword ( adev , si_pi - > arb_table_start ,
tmp , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
}
static int si_initial_switch_from_arb_f0_to_f1 ( struct amdgpu_device * adev )
{
return ni_copy_and_switch_arb_sets ( adev , MC_CG_ARB_FREQ_F0 , MC_CG_ARB_FREQ_F1 ) ;
}
static int si_reset_to_default ( struct amdgpu_device * adev )
{
2016-09-13 00:06:07 -04:00
return ( amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_ResetToDefaults ) = = PPSMC_Result_OK ) ?
2016-08-01 12:42:32 -04:00
0 : - EINVAL ;
}
static int si_force_switch_to_arb_f0 ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 tmp ;
int ret ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_read_smc_sram_dword ( adev , si_pi - > arb_table_start ,
& tmp , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
tmp = ( tmp > > 24 ) & 0xff ;
if ( tmp = = MC_CG_ARB_FREQ_F0 )
return 0 ;
return ni_copy_and_switch_arb_sets ( adev , tmp , MC_CG_ARB_FREQ_F0 ) ;
}
static u32 si_calculate_memory_refresh_rate ( struct amdgpu_device * adev ,
u32 engine_clock )
{
u32 dram_rows ;
u32 dram_refresh_rate ;
u32 mc_arb_rfsh_rate ;
u32 tmp = ( RREG32 ( MC_ARB_RAMCFG ) & NOOFROWS_MASK ) > > NOOFROWS_SHIFT ;
if ( tmp > = 4 )
dram_rows = 16384 ;
else
dram_rows = 1 < < ( tmp + 10 ) ;
dram_refresh_rate = 1 < < ( ( RREG32 ( MC_SEQ_MISC0 ) & 0x3 ) + 3 ) ;
mc_arb_rfsh_rate = ( ( engine_clock * 10 ) * dram_refresh_rate / dram_rows - 32 ) / 64 ;
return mc_arb_rfsh_rate ;
}
static int si_populate_memory_timing_parameters ( struct amdgpu_device * adev ,
struct rv7xx_pl * pl ,
SMC_SIslands_MCArbDramTimingRegisterSet * arb_regs )
{
u32 dram_timing ;
u32 dram_timing2 ;
u32 burst_time ;
arb_regs - > mc_arb_rfsh_rate =
( u8 ) si_calculate_memory_refresh_rate ( adev , pl - > sclk ) ;
amdgpu_atombios_set_engine_dram_timings ( adev ,
pl - > sclk ,
2016-09-06 09:45:43 -04:00
pl - > mclk ) ;
2016-08-01 12:42:32 -04:00
dram_timing = RREG32 ( MC_ARB_DRAM_TIMING ) ;
dram_timing2 = RREG32 ( MC_ARB_DRAM_TIMING2 ) ;
burst_time = RREG32 ( MC_ARB_BURST_TIME ) & STATE0_MASK ;
arb_regs - > mc_arb_dram_timing = cpu_to_be32 ( dram_timing ) ;
arb_regs - > mc_arb_dram_timing2 = cpu_to_be32 ( dram_timing2 ) ;
arb_regs - > mc_arb_burst_time = ( u8 ) burst_time ;
return 0 ;
}
static int si_do_program_memory_timing_parameters ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_state ,
unsigned int first_arb_set )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct si_ps * state = si_get_ps ( amdgpu_state ) ;
SMC_SIslands_MCArbDramTimingRegisterSet arb_regs = { 0 } ;
int i , ret = 0 ;
for ( i = 0 ; i < state - > performance_level_count ; i + + ) {
ret = si_populate_memory_timing_parameters ( adev , & state - > performance_levels [ i ] , & arb_regs ) ;
if ( ret )
break ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_copy_bytes_to_smc ( adev ,
si_pi - > arb_table_start +
offsetof ( SMC_SIslands_MCArbDramTimingRegisters , data ) +
sizeof ( SMC_SIslands_MCArbDramTimingRegisterSet ) * ( first_arb_set + i ) ,
( u8 * ) & arb_regs ,
sizeof ( SMC_SIslands_MCArbDramTimingRegisterSet ) ,
si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
break ;
2016-09-06 09:45:43 -04:00
}
2016-08-01 12:42:32 -04:00
return ret ;
}
static int si_program_memory_timing_parameters ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_new_state )
{
return si_do_program_memory_timing_parameters ( adev , amdgpu_new_state ,
SISLANDS_DRIVER_STATE_ARB_INDEX ) ;
}
static int si_populate_initial_mvdd_value ( struct amdgpu_device * adev ,
struct SISLANDS_SMC_VOLTAGE_VALUE * voltage )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
if ( pi - > mvdd_control )
return si_populate_voltage_value ( adev , & si_pi - > mvdd_voltage_table ,
si_pi - > mvdd_bootup_value , voltage ) ;
return 0 ;
}
static int si_populate_smc_initial_state ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_initial_state ,
SISLANDS_SMC_STATETABLE * table )
{
struct si_ps * initial_state = si_get_ps ( amdgpu_initial_state ) ;
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 reg ;
int ret ;
table - > initialState . levels [ 0 ] . mclk . vDLL_CNTL =
cpu_to_be32 ( si_pi - > clock_registers . dll_cntl ) ;
table - > initialState . levels [ 0 ] . mclk . vMCLK_PWRMGT_CNTL =
cpu_to_be32 ( si_pi - > clock_registers . mclk_pwrmgt_cntl ) ;
table - > initialState . levels [ 0 ] . mclk . vMPLL_AD_FUNC_CNTL =
cpu_to_be32 ( si_pi - > clock_registers . mpll_ad_func_cntl ) ;
table - > initialState . levels [ 0 ] . mclk . vMPLL_DQ_FUNC_CNTL =
cpu_to_be32 ( si_pi - > clock_registers . mpll_dq_func_cntl ) ;
table - > initialState . levels [ 0 ] . mclk . vMPLL_FUNC_CNTL =
cpu_to_be32 ( si_pi - > clock_registers . mpll_func_cntl ) ;
table - > initialState . levels [ 0 ] . mclk . vMPLL_FUNC_CNTL_1 =
cpu_to_be32 ( si_pi - > clock_registers . mpll_func_cntl_1 ) ;
table - > initialState . levels [ 0 ] . mclk . vMPLL_FUNC_CNTL_2 =
cpu_to_be32 ( si_pi - > clock_registers . mpll_func_cntl_2 ) ;
table - > initialState . levels [ 0 ] . mclk . vMPLL_SS =
cpu_to_be32 ( si_pi - > clock_registers . mpll_ss1 ) ;
table - > initialState . levels [ 0 ] . mclk . vMPLL_SS2 =
cpu_to_be32 ( si_pi - > clock_registers . mpll_ss2 ) ;
table - > initialState . levels [ 0 ] . mclk . mclk_value =
cpu_to_be32 ( initial_state - > performance_levels [ 0 ] . mclk ) ;
table - > initialState . levels [ 0 ] . sclk . vCG_SPLL_FUNC_CNTL =
cpu_to_be32 ( si_pi - > clock_registers . cg_spll_func_cntl ) ;
table - > initialState . levels [ 0 ] . sclk . vCG_SPLL_FUNC_CNTL_2 =
cpu_to_be32 ( si_pi - > clock_registers . cg_spll_func_cntl_2 ) ;
table - > initialState . levels [ 0 ] . sclk . vCG_SPLL_FUNC_CNTL_3 =
cpu_to_be32 ( si_pi - > clock_registers . cg_spll_func_cntl_3 ) ;
table - > initialState . levels [ 0 ] . sclk . vCG_SPLL_FUNC_CNTL_4 =
cpu_to_be32 ( si_pi - > clock_registers . cg_spll_func_cntl_4 ) ;
table - > initialState . levels [ 0 ] . sclk . vCG_SPLL_SPREAD_SPECTRUM =
cpu_to_be32 ( si_pi - > clock_registers . cg_spll_spread_spectrum ) ;
table - > initialState . levels [ 0 ] . sclk . vCG_SPLL_SPREAD_SPECTRUM_2 =
cpu_to_be32 ( si_pi - > clock_registers . cg_spll_spread_spectrum_2 ) ;
table - > initialState . levels [ 0 ] . sclk . sclk_value =
cpu_to_be32 ( initial_state - > performance_levels [ 0 ] . sclk ) ;
table - > initialState . levels [ 0 ] . arbRefreshState =
SISLANDS_INITIAL_STATE_ARB_INDEX ;
table - > initialState . levels [ 0 ] . ACIndex = 0 ;
ret = si_populate_voltage_value ( adev , & eg_pi - > vddc_voltage_table ,
initial_state - > performance_levels [ 0 ] . vddc ,
& table - > initialState . levels [ 0 ] . vddc ) ;
if ( ! ret ) {
u16 std_vddc ;
ret = si_get_std_voltage_value ( adev ,
& table - > initialState . levels [ 0 ] . vddc ,
& std_vddc ) ;
if ( ! ret )
si_populate_std_voltage_value ( adev , std_vddc ,
table - > initialState . levels [ 0 ] . vddc . index ,
& table - > initialState . levels [ 0 ] . std_vddc ) ;
}
if ( eg_pi - > vddci_control )
si_populate_voltage_value ( adev ,
& eg_pi - > vddci_voltage_table ,
initial_state - > performance_levels [ 0 ] . vddci ,
& table - > initialState . levels [ 0 ] . vddci ) ;
if ( si_pi - > vddc_phase_shed_control )
si_populate_phase_shedding_value ( adev ,
& adev - > pm . dpm . dyn_state . phase_shedding_limits_table ,
initial_state - > performance_levels [ 0 ] . vddc ,
initial_state - > performance_levels [ 0 ] . sclk ,
initial_state - > performance_levels [ 0 ] . mclk ,
& table - > initialState . levels [ 0 ] . vddc ) ;
si_populate_initial_mvdd_value ( adev , & table - > initialState . levels [ 0 ] . mvdd ) ;
reg = CG_R ( 0xffff ) | CG_L ( 0 ) ;
table - > initialState . levels [ 0 ] . aT = cpu_to_be32 ( reg ) ;
table - > initialState . levels [ 0 ] . bSP = cpu_to_be32 ( pi - > dsp ) ;
table - > initialState . levels [ 0 ] . gen2PCIE = ( u8 ) si_pi - > boot_pcie_gen ;
if ( adev - > mc . vram_type = = AMDGPU_VRAM_TYPE_GDDR5 ) {
table - > initialState . levels [ 0 ] . strobeMode =
si_get_strobe_mode_settings ( adev ,
initial_state - > performance_levels [ 0 ] . mclk ) ;
if ( initial_state - > performance_levels [ 0 ] . mclk > pi - > mclk_edc_enable_threshold )
table - > initialState . levels [ 0 ] . mcFlags = SISLANDS_SMC_MC_EDC_RD_FLAG | SISLANDS_SMC_MC_EDC_WR_FLAG ;
else
table - > initialState . levels [ 0 ] . mcFlags = 0 ;
}
table - > initialState . levelCount = 1 ;
table - > initialState . flags | = PPSMC_SWSTATE_FLAG_DC ;
table - > initialState . levels [ 0 ] . dpm2 . MaxPS = 0 ;
table - > initialState . levels [ 0 ] . dpm2 . NearTDPDec = 0 ;
table - > initialState . levels [ 0 ] . dpm2 . AboveSafeInc = 0 ;
table - > initialState . levels [ 0 ] . dpm2 . BelowSafeInc = 0 ;
table - > initialState . levels [ 0 ] . dpm2 . PwrEfficiencyRatio = 0 ;
reg = MIN_POWER_MASK | MAX_POWER_MASK ;
table - > initialState . levels [ 0 ] . SQPowerThrottle = cpu_to_be32 ( reg ) ;
reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK ;
table - > initialState . levels [ 0 ] . SQPowerThrottle_2 = cpu_to_be32 ( reg ) ;
return 0 ;
}
static int si_populate_smc_acpi_state ( struct amdgpu_device * adev ,
SISLANDS_SMC_STATETABLE * table )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 spll_func_cntl = si_pi - > clock_registers . cg_spll_func_cntl ;
u32 spll_func_cntl_2 = si_pi - > clock_registers . cg_spll_func_cntl_2 ;
u32 spll_func_cntl_3 = si_pi - > clock_registers . cg_spll_func_cntl_3 ;
u32 spll_func_cntl_4 = si_pi - > clock_registers . cg_spll_func_cntl_4 ;
u32 dll_cntl = si_pi - > clock_registers . dll_cntl ;
u32 mclk_pwrmgt_cntl = si_pi - > clock_registers . mclk_pwrmgt_cntl ;
u32 mpll_ad_func_cntl = si_pi - > clock_registers . mpll_ad_func_cntl ;
u32 mpll_dq_func_cntl = si_pi - > clock_registers . mpll_dq_func_cntl ;
u32 mpll_func_cntl = si_pi - > clock_registers . mpll_func_cntl ;
u32 mpll_func_cntl_1 = si_pi - > clock_registers . mpll_func_cntl_1 ;
u32 mpll_func_cntl_2 = si_pi - > clock_registers . mpll_func_cntl_2 ;
u32 reg ;
int ret ;
table - > ACPIState = table - > initialState ;
table - > ACPIState . flags & = ~ PPSMC_SWSTATE_FLAG_DC ;
if ( pi - > acpi_vddc ) {
ret = si_populate_voltage_value ( adev , & eg_pi - > vddc_voltage_table ,
pi - > acpi_vddc , & table - > ACPIState . levels [ 0 ] . vddc ) ;
if ( ! ret ) {
u16 std_vddc ;
ret = si_get_std_voltage_value ( adev ,
& table - > ACPIState . levels [ 0 ] . vddc , & std_vddc ) ;
if ( ! ret )
si_populate_std_voltage_value ( adev , std_vddc ,
table - > ACPIState . levels [ 0 ] . vddc . index ,
& table - > ACPIState . levels [ 0 ] . std_vddc ) ;
}
table - > ACPIState . levels [ 0 ] . gen2PCIE = si_pi - > acpi_pcie_gen ;
if ( si_pi - > vddc_phase_shed_control ) {
si_populate_phase_shedding_value ( adev ,
& adev - > pm . dpm . dyn_state . phase_shedding_limits_table ,
pi - > acpi_vddc ,
0 ,
0 ,
& table - > ACPIState . levels [ 0 ] . vddc ) ;
}
} else {
ret = si_populate_voltage_value ( adev , & eg_pi - > vddc_voltage_table ,
pi - > min_vddc_in_table , & table - > ACPIState . levels [ 0 ] . vddc ) ;
if ( ! ret ) {
u16 std_vddc ;
ret = si_get_std_voltage_value ( adev ,
& table - > ACPIState . levels [ 0 ] . vddc , & std_vddc ) ;
if ( ! ret )
si_populate_std_voltage_value ( adev , std_vddc ,
table - > ACPIState . levels [ 0 ] . vddc . index ,
& table - > ACPIState . levels [ 0 ] . std_vddc ) ;
}
table - > ACPIState . levels [ 0 ] . gen2PCIE = ( u8 ) r600_get_pcie_gen_support ( adev ,
si_pi - > sys_pcie_mask ,
si_pi - > boot_pcie_gen ,
AMDGPU_PCIE_GEN1 ) ;
if ( si_pi - > vddc_phase_shed_control )
si_populate_phase_shedding_value ( adev ,
& adev - > pm . dpm . dyn_state . phase_shedding_limits_table ,
pi - > min_vddc_in_table ,
0 ,
0 ,
& table - > ACPIState . levels [ 0 ] . vddc ) ;
}
if ( pi - > acpi_vddc ) {
if ( eg_pi - > acpi_vddci )
si_populate_voltage_value ( adev , & eg_pi - > vddci_voltage_table ,
eg_pi - > acpi_vddci ,
& table - > ACPIState . levels [ 0 ] . vddci ) ;
}
mclk_pwrmgt_cntl | = MRDCK0_RESET | MRDCK1_RESET ;
mclk_pwrmgt_cntl & = ~ ( MRDCK0_PDNB | MRDCK1_PDNB ) ;
dll_cntl & = ~ ( MRDCK0_BYPASS | MRDCK1_BYPASS ) ;
spll_func_cntl_2 & = ~ SCLK_MUX_SEL_MASK ;
spll_func_cntl_2 | = SCLK_MUX_SEL ( 4 ) ;
table - > ACPIState . levels [ 0 ] . mclk . vDLL_CNTL =
cpu_to_be32 ( dll_cntl ) ;
table - > ACPIState . levels [ 0 ] . mclk . vMCLK_PWRMGT_CNTL =
cpu_to_be32 ( mclk_pwrmgt_cntl ) ;
table - > ACPIState . levels [ 0 ] . mclk . vMPLL_AD_FUNC_CNTL =
cpu_to_be32 ( mpll_ad_func_cntl ) ;
table - > ACPIState . levels [ 0 ] . mclk . vMPLL_DQ_FUNC_CNTL =
cpu_to_be32 ( mpll_dq_func_cntl ) ;
table - > ACPIState . levels [ 0 ] . mclk . vMPLL_FUNC_CNTL =
cpu_to_be32 ( mpll_func_cntl ) ;
table - > ACPIState . levels [ 0 ] . mclk . vMPLL_FUNC_CNTL_1 =
cpu_to_be32 ( mpll_func_cntl_1 ) ;
table - > ACPIState . levels [ 0 ] . mclk . vMPLL_FUNC_CNTL_2 =
cpu_to_be32 ( mpll_func_cntl_2 ) ;
table - > ACPIState . levels [ 0 ] . mclk . vMPLL_SS =
cpu_to_be32 ( si_pi - > clock_registers . mpll_ss1 ) ;
table - > ACPIState . levels [ 0 ] . mclk . vMPLL_SS2 =
cpu_to_be32 ( si_pi - > clock_registers . mpll_ss2 ) ;
table - > ACPIState . levels [ 0 ] . sclk . vCG_SPLL_FUNC_CNTL =
cpu_to_be32 ( spll_func_cntl ) ;
table - > ACPIState . levels [ 0 ] . sclk . vCG_SPLL_FUNC_CNTL_2 =
cpu_to_be32 ( spll_func_cntl_2 ) ;
table - > ACPIState . levels [ 0 ] . sclk . vCG_SPLL_FUNC_CNTL_3 =
cpu_to_be32 ( spll_func_cntl_3 ) ;
table - > ACPIState . levels [ 0 ] . sclk . vCG_SPLL_FUNC_CNTL_4 =
cpu_to_be32 ( spll_func_cntl_4 ) ;
table - > ACPIState . levels [ 0 ] . mclk . mclk_value = 0 ;
table - > ACPIState . levels [ 0 ] . sclk . sclk_value = 0 ;
si_populate_mvdd_value ( adev , 0 , & table - > ACPIState . levels [ 0 ] . mvdd ) ;
if ( eg_pi - > dynamic_ac_timing )
table - > ACPIState . levels [ 0 ] . ACIndex = 0 ;
table - > ACPIState . levels [ 0 ] . dpm2 . MaxPS = 0 ;
table - > ACPIState . levels [ 0 ] . dpm2 . NearTDPDec = 0 ;
table - > ACPIState . levels [ 0 ] . dpm2 . AboveSafeInc = 0 ;
table - > ACPIState . levels [ 0 ] . dpm2 . BelowSafeInc = 0 ;
table - > ACPIState . levels [ 0 ] . dpm2 . PwrEfficiencyRatio = 0 ;
reg = MIN_POWER_MASK | MAX_POWER_MASK ;
table - > ACPIState . levels [ 0 ] . SQPowerThrottle = cpu_to_be32 ( reg ) ;
reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK ;
table - > ACPIState . levels [ 0 ] . SQPowerThrottle_2 = cpu_to_be32 ( reg ) ;
return 0 ;
}
static int si_populate_ulv_state ( struct amdgpu_device * adev ,
SISLANDS_SMC_SWSTATE * state )
{
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct si_ulv_param * ulv = & si_pi - > ulv ;
u32 sclk_in_sr = 1350 ; /* ??? */
int ret ;
ret = si_convert_power_level_to_smc ( adev , & ulv - > pl ,
& state - > levels [ 0 ] ) ;
if ( ! ret ) {
if ( eg_pi - > sclk_deep_sleep ) {
if ( sclk_in_sr < = SCLK_MIN_DEEPSLEEP_FREQ )
state - > levels [ 0 ] . stateFlags | = PPSMC_STATEFLAG_DEEPSLEEP_BYPASS ;
else
state - > levels [ 0 ] . stateFlags | = PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE ;
}
if ( ulv - > one_pcie_lane_in_ulv )
state - > flags | = PPSMC_SWSTATE_FLAG_PCIE_X1 ;
state - > levels [ 0 ] . arbRefreshState = ( u8 ) ( SISLANDS_ULV_STATE_ARB_INDEX ) ;
state - > levels [ 0 ] . ACIndex = 1 ;
state - > levels [ 0 ] . std_vddc = state - > levels [ 0 ] . vddc ;
state - > levelCount = 1 ;
state - > flags | = PPSMC_SWSTATE_FLAG_DC ;
}
return ret ;
}
static int si_program_ulv_memory_timing_parameters ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct si_ulv_param * ulv = & si_pi - > ulv ;
SMC_SIslands_MCArbDramTimingRegisterSet arb_regs = { 0 } ;
int ret ;
ret = si_populate_memory_timing_parameters ( adev , & ulv - > pl ,
& arb_regs ) ;
if ( ret )
return ret ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_ulv_volt_change_delay ,
ulv - > volt_change_delay ) ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_copy_bytes_to_smc ( adev ,
si_pi - > arb_table_start +
offsetof ( SMC_SIslands_MCArbDramTimingRegisters , data ) +
sizeof ( SMC_SIslands_MCArbDramTimingRegisterSet ) * SISLANDS_ULV_STATE_ARB_INDEX ,
( u8 * ) & arb_regs ,
sizeof ( SMC_SIslands_MCArbDramTimingRegisterSet ) ,
si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
return ret ;
}
static void si_get_mvdd_configuration ( struct amdgpu_device * adev )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
pi - > mvdd_split_frequency = 30000 ;
}
static int si_init_smc_table ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct amdgpu_ps * amdgpu_boot_state = adev - > pm . dpm . boot_ps ;
const struct si_ulv_param * ulv = & si_pi - > ulv ;
SISLANDS_SMC_STATETABLE * table = & si_pi - > smc_statetable ;
int ret ;
u32 lane_width ;
u32 vr_hot_gpio ;
si_populate_smc_voltage_tables ( adev , table ) ;
switch ( adev - > pm . int_thermal_type ) {
case THERMAL_TYPE_SI :
case THERMAL_TYPE_EMC2103_WITH_INTERNAL :
table - > thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL ;
break ;
case THERMAL_TYPE_NONE :
table - > thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE ;
break ;
default :
table - > thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL ;
break ;
}
if ( adev - > pm . dpm . platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC )
table - > systemFlags | = PPSMC_SYSTEMFLAG_GPIO_DC ;
if ( adev - > pm . dpm . platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT ) {
if ( ( adev - > pdev - > device ! = 0x6818 ) & & ( adev - > pdev - > device ! = 0x6819 ) )
table - > systemFlags | = PPSMC_SYSTEMFLAG_REGULATOR_HOT ;
}
if ( adev - > pm . dpm . platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC )
table - > systemFlags | = PPSMC_SYSTEMFLAG_STEPVDDC ;
if ( adev - > mc . vram_type = = AMDGPU_VRAM_TYPE_GDDR5 )
table - > systemFlags | = PPSMC_SYSTEMFLAG_GDDR5 ;
if ( adev - > pm . dpm . platform_caps & ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY )
table - > extraFlags | = PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH ;
if ( adev - > pm . dpm . platform_caps & ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE ) {
table - > systemFlags | = PPSMC_SYSTEMFLAG_REGULATOR_HOT_PROG_GPIO ;
vr_hot_gpio = adev - > pm . dpm . backbias_response_time ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_vr_hot_gpio ,
vr_hot_gpio ) ;
}
ret = si_populate_smc_initial_state ( adev , amdgpu_boot_state , table ) ;
if ( ret )
return ret ;
ret = si_populate_smc_acpi_state ( adev , table ) ;
if ( ret )
return ret ;
table - > driverState = table - > initialState ;
ret = si_do_program_memory_timing_parameters ( adev , amdgpu_boot_state ,
SISLANDS_INITIAL_STATE_ARB_INDEX ) ;
if ( ret )
return ret ;
if ( ulv - > supported & & ulv - > pl . vddc ) {
ret = si_populate_ulv_state ( adev , & table - > ULVState ) ;
if ( ret )
return ret ;
ret = si_program_ulv_memory_timing_parameters ( adev ) ;
if ( ret )
return ret ;
WREG32 ( CG_ULV_CONTROL , ulv - > cg_ulv_control ) ;
WREG32 ( CG_ULV_PARAMETER , ulv - > cg_ulv_parameter ) ;
lane_width = amdgpu_get_pcie_lanes ( adev ) ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width , lane_width ) ;
} else {
table - > ULVState = table - > initialState ;
}
2016-09-13 00:06:07 -04:00
return amdgpu_si_copy_bytes_to_smc ( adev , si_pi - > state_table_start ,
( u8 * ) table , sizeof ( SISLANDS_SMC_STATETABLE ) ,
si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
}
static int si_calculate_sclk_params ( struct amdgpu_device * adev ,
u32 engine_clock ,
SISLANDS_SMC_SCLK_VALUE * sclk )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct atom_clock_dividers dividers ;
u32 spll_func_cntl = si_pi - > clock_registers . cg_spll_func_cntl ;
u32 spll_func_cntl_2 = si_pi - > clock_registers . cg_spll_func_cntl_2 ;
u32 spll_func_cntl_3 = si_pi - > clock_registers . cg_spll_func_cntl_3 ;
u32 spll_func_cntl_4 = si_pi - > clock_registers . cg_spll_func_cntl_4 ;
u32 cg_spll_spread_spectrum = si_pi - > clock_registers . cg_spll_spread_spectrum ;
u32 cg_spll_spread_spectrum_2 = si_pi - > clock_registers . cg_spll_spread_spectrum_2 ;
u64 tmp ;
u32 reference_clock = adev - > clock . spll . reference_freq ;
u32 reference_divider ;
u32 fbdiv ;
int ret ;
ret = amdgpu_atombios_get_clock_dividers ( adev , COMPUTE_ENGINE_PLL_PARAM ,
engine_clock , false , & dividers ) ;
if ( ret )
return ret ;
reference_divider = 1 + dividers . ref_div ;
tmp = ( u64 ) engine_clock * reference_divider * dividers . post_div * 16384 ;
do_div ( tmp , reference_clock ) ;
fbdiv = ( u32 ) tmp ;
spll_func_cntl & = ~ ( SPLL_PDIV_A_MASK | SPLL_REF_DIV_MASK ) ;
spll_func_cntl | = SPLL_REF_DIV ( dividers . ref_div ) ;
spll_func_cntl | = SPLL_PDIV_A ( dividers . post_div ) ;
spll_func_cntl_2 & = ~ SCLK_MUX_SEL_MASK ;
spll_func_cntl_2 | = SCLK_MUX_SEL ( 2 ) ;
2016-09-06 09:45:43 -04:00
spll_func_cntl_3 & = ~ SPLL_FB_DIV_MASK ;
spll_func_cntl_3 | = SPLL_FB_DIV ( fbdiv ) ;
spll_func_cntl_3 | = SPLL_DITHEN ;
2016-08-01 12:42:32 -04:00
if ( pi - > sclk_ss ) {
struct amdgpu_atom_ss ss ;
u32 vco_freq = engine_clock * dividers . post_div ;
if ( amdgpu_atombios_get_asic_ss_info ( adev , & ss ,
ASIC_INTERNAL_ENGINE_SS , vco_freq ) ) {
u32 clk_s = reference_clock * 5 / ( reference_divider * ss . rate ) ;
u32 clk_v = 4 * ss . percentage * fbdiv / ( clk_s * 10000 ) ;
cg_spll_spread_spectrum & = ~ CLK_S_MASK ;
cg_spll_spread_spectrum | = CLK_S ( clk_s ) ;
cg_spll_spread_spectrum | = SSEN ;
cg_spll_spread_spectrum_2 & = ~ CLK_V_MASK ;
cg_spll_spread_spectrum_2 | = CLK_V ( clk_v ) ;
}
}
sclk - > sclk_value = engine_clock ;
sclk - > vCG_SPLL_FUNC_CNTL = spll_func_cntl ;
sclk - > vCG_SPLL_FUNC_CNTL_2 = spll_func_cntl_2 ;
sclk - > vCG_SPLL_FUNC_CNTL_3 = spll_func_cntl_3 ;
sclk - > vCG_SPLL_FUNC_CNTL_4 = spll_func_cntl_4 ;
sclk - > vCG_SPLL_SPREAD_SPECTRUM = cg_spll_spread_spectrum ;
sclk - > vCG_SPLL_SPREAD_SPECTRUM_2 = cg_spll_spread_spectrum_2 ;
return 0 ;
}
static int si_populate_sclk_value ( struct amdgpu_device * adev ,
u32 engine_clock ,
SISLANDS_SMC_SCLK_VALUE * sclk )
{
SISLANDS_SMC_SCLK_VALUE sclk_tmp ;
int ret ;
ret = si_calculate_sclk_params ( adev , engine_clock , & sclk_tmp ) ;
if ( ! ret ) {
sclk - > sclk_value = cpu_to_be32 ( sclk_tmp . sclk_value ) ;
sclk - > vCG_SPLL_FUNC_CNTL = cpu_to_be32 ( sclk_tmp . vCG_SPLL_FUNC_CNTL ) ;
sclk - > vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32 ( sclk_tmp . vCG_SPLL_FUNC_CNTL_2 ) ;
sclk - > vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32 ( sclk_tmp . vCG_SPLL_FUNC_CNTL_3 ) ;
sclk - > vCG_SPLL_FUNC_CNTL_4 = cpu_to_be32 ( sclk_tmp . vCG_SPLL_FUNC_CNTL_4 ) ;
sclk - > vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32 ( sclk_tmp . vCG_SPLL_SPREAD_SPECTRUM ) ;
sclk - > vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32 ( sclk_tmp . vCG_SPLL_SPREAD_SPECTRUM_2 ) ;
}
return ret ;
}
static int si_populate_mclk_value ( struct amdgpu_device * adev ,
u32 engine_clock ,
u32 memory_clock ,
SISLANDS_SMC_MCLK_VALUE * mclk ,
bool strobe_mode ,
bool dll_state_on )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 dll_cntl = si_pi - > clock_registers . dll_cntl ;
u32 mclk_pwrmgt_cntl = si_pi - > clock_registers . mclk_pwrmgt_cntl ;
u32 mpll_ad_func_cntl = si_pi - > clock_registers . mpll_ad_func_cntl ;
u32 mpll_dq_func_cntl = si_pi - > clock_registers . mpll_dq_func_cntl ;
u32 mpll_func_cntl = si_pi - > clock_registers . mpll_func_cntl ;
u32 mpll_func_cntl_1 = si_pi - > clock_registers . mpll_func_cntl_1 ;
u32 mpll_func_cntl_2 = si_pi - > clock_registers . mpll_func_cntl_2 ;
u32 mpll_ss1 = si_pi - > clock_registers . mpll_ss1 ;
u32 mpll_ss2 = si_pi - > clock_registers . mpll_ss2 ;
struct atom_mpll_param mpll_param ;
int ret ;
ret = amdgpu_atombios_get_memory_pll_dividers ( adev , memory_clock , strobe_mode , & mpll_param ) ;
if ( ret )
return ret ;
mpll_func_cntl & = ~ BWCTRL_MASK ;
mpll_func_cntl | = BWCTRL ( mpll_param . bwcntl ) ;
mpll_func_cntl_1 & = ~ ( CLKF_MASK | CLKFRAC_MASK | VCO_MODE_MASK ) ;
mpll_func_cntl_1 | = CLKF ( mpll_param . clkf ) |
CLKFRAC ( mpll_param . clkfrac ) | VCO_MODE ( mpll_param . vco_mode ) ;
mpll_ad_func_cntl & = ~ YCLK_POST_DIV_MASK ;
mpll_ad_func_cntl | = YCLK_POST_DIV ( mpll_param . post_div ) ;
if ( adev - > mc . vram_type = = AMDGPU_VRAM_TYPE_GDDR5 ) {
mpll_dq_func_cntl & = ~ ( YCLK_SEL_MASK | YCLK_POST_DIV_MASK ) ;
mpll_dq_func_cntl | = YCLK_SEL ( mpll_param . yclk_sel ) |
YCLK_POST_DIV ( mpll_param . post_div ) ;
}
if ( pi - > mclk_ss ) {
struct amdgpu_atom_ss ss ;
u32 freq_nom ;
u32 tmp ;
u32 reference_clock = adev - > clock . mpll . reference_freq ;
if ( adev - > mc . vram_type = = AMDGPU_VRAM_TYPE_GDDR5 )
freq_nom = memory_clock * 4 ;
else
freq_nom = memory_clock * 2 ;
tmp = freq_nom / reference_clock ;
tmp = tmp * tmp ;
if ( amdgpu_atombios_get_asic_ss_info ( adev , & ss ,
2016-09-06 09:45:43 -04:00
ASIC_INTERNAL_MEMORY_SS , freq_nom ) ) {
2016-08-01 12:42:32 -04:00
u32 clks = reference_clock * 5 / ss . rate ;
u32 clkv = ( u32 ) ( ( ( ( 131 * ss . percentage * ss . rate ) / 100 ) * tmp ) / freq_nom ) ;
2016-09-06 09:45:43 -04:00
mpll_ss1 & = ~ CLKV_MASK ;
mpll_ss1 | = CLKV ( clkv ) ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
mpll_ss2 & = ~ CLKS_MASK ;
mpll_ss2 | = CLKS ( clks ) ;
2016-08-01 12:42:32 -04:00
}
}
mclk_pwrmgt_cntl & = ~ DLL_SPEED_MASK ;
mclk_pwrmgt_cntl | = DLL_SPEED ( mpll_param . dll_speed ) ;
if ( dll_state_on )
mclk_pwrmgt_cntl | = MRDCK0_PDNB | MRDCK1_PDNB ;
else
mclk_pwrmgt_cntl & = ~ ( MRDCK0_PDNB | MRDCK1_PDNB ) ;
mclk - > mclk_value = cpu_to_be32 ( memory_clock ) ;
mclk - > vMPLL_FUNC_CNTL = cpu_to_be32 ( mpll_func_cntl ) ;
mclk - > vMPLL_FUNC_CNTL_1 = cpu_to_be32 ( mpll_func_cntl_1 ) ;
mclk - > vMPLL_FUNC_CNTL_2 = cpu_to_be32 ( mpll_func_cntl_2 ) ;
mclk - > vMPLL_AD_FUNC_CNTL = cpu_to_be32 ( mpll_ad_func_cntl ) ;
mclk - > vMPLL_DQ_FUNC_CNTL = cpu_to_be32 ( mpll_dq_func_cntl ) ;
mclk - > vMCLK_PWRMGT_CNTL = cpu_to_be32 ( mclk_pwrmgt_cntl ) ;
mclk - > vDLL_CNTL = cpu_to_be32 ( dll_cntl ) ;
mclk - > vMPLL_SS = cpu_to_be32 ( mpll_ss1 ) ;
mclk - > vMPLL_SS2 = cpu_to_be32 ( mpll_ss2 ) ;
return 0 ;
}
static void si_populate_smc_sp ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_state ,
SISLANDS_SMC_SWSTATE * smc_state )
{
struct si_ps * ps = si_get_ps ( amdgpu_state ) ;
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
int i ;
for ( i = 0 ; i < ps - > performance_level_count - 1 ; i + + )
smc_state - > levels [ i ] . bSP = cpu_to_be32 ( pi - > dsp ) ;
smc_state - > levels [ ps - > performance_level_count - 1 ] . bSP =
cpu_to_be32 ( pi - > psp ) ;
}
static int si_convert_power_level_to_smc ( struct amdgpu_device * adev ,
struct rv7xx_pl * pl ,
SISLANDS_SMC_HW_PERFORMANCE_LEVEL * level )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
int ret ;
bool dll_state_on ;
u16 std_vddc ;
bool gmc_pg = false ;
if ( eg_pi - > pcie_performance_request & &
( si_pi - > force_pcie_gen ! = AMDGPU_PCIE_GEN_INVALID ) )
level - > gen2PCIE = ( u8 ) si_pi - > force_pcie_gen ;
else
level - > gen2PCIE = ( u8 ) pl - > pcie_gen ;
ret = si_populate_sclk_value ( adev , pl - > sclk , & level - > sclk ) ;
if ( ret )
return ret ;
level - > mcFlags = 0 ;
if ( pi - > mclk_stutter_mode_threshold & &
( pl - > mclk < = pi - > mclk_stutter_mode_threshold ) & &
! eg_pi - > uvd_enabled & &
( RREG32 ( DPG_PIPE_STUTTER_CONTROL ) & STUTTER_ENABLE ) & &
( adev - > pm . dpm . new_active_crtc_count < = 2 ) ) {
level - > mcFlags | = SISLANDS_SMC_MC_STUTTER_EN ;
if ( gmc_pg )
level - > mcFlags | = SISLANDS_SMC_MC_PG_EN ;
}
if ( adev - > mc . vram_type = = AMDGPU_VRAM_TYPE_GDDR5 ) {
if ( pl - > mclk > pi - > mclk_edc_enable_threshold )
level - > mcFlags | = SISLANDS_SMC_MC_EDC_RD_FLAG ;
if ( pl - > mclk > eg_pi - > mclk_edc_wr_enable_threshold )
level - > mcFlags | = SISLANDS_SMC_MC_EDC_WR_FLAG ;
level - > strobeMode = si_get_strobe_mode_settings ( adev , pl - > mclk ) ;
if ( level - > strobeMode & SISLANDS_SMC_STROBE_ENABLE ) {
if ( si_get_mclk_frequency_ratio ( pl - > mclk , true ) > =
( ( RREG32 ( MC_SEQ_MISC7 ) > > 16 ) & 0xf ) )
dll_state_on = ( ( RREG32 ( MC_SEQ_MISC5 ) > > 1 ) & 0x1 ) ? true : false ;
else
dll_state_on = ( ( RREG32 ( MC_SEQ_MISC6 ) > > 1 ) & 0x1 ) ? true : false ;
} else {
dll_state_on = false ;
}
} else {
level - > strobeMode = si_get_strobe_mode_settings ( adev ,
pl - > mclk ) ;
dll_state_on = ( ( RREG32 ( MC_SEQ_MISC5 ) > > 1 ) & 0x1 ) ? true : false ;
}
ret = si_populate_mclk_value ( adev ,
pl - > sclk ,
pl - > mclk ,
& level - > mclk ,
( level - > strobeMode & SISLANDS_SMC_STROBE_ENABLE ) ! = 0 , dll_state_on ) ;
if ( ret )
return ret ;
ret = si_populate_voltage_value ( adev ,
& eg_pi - > vddc_voltage_table ,
pl - > vddc , & level - > vddc ) ;
if ( ret )
return ret ;
ret = si_get_std_voltage_value ( adev , & level - > vddc , & std_vddc ) ;
if ( ret )
return ret ;
ret = si_populate_std_voltage_value ( adev , std_vddc ,
level - > vddc . index , & level - > std_vddc ) ;
if ( ret )
return ret ;
if ( eg_pi - > vddci_control ) {
ret = si_populate_voltage_value ( adev , & eg_pi - > vddci_voltage_table ,
pl - > vddci , & level - > vddci ) ;
if ( ret )
return ret ;
}
if ( si_pi - > vddc_phase_shed_control ) {
ret = si_populate_phase_shedding_value ( adev ,
& adev - > pm . dpm . dyn_state . phase_shedding_limits_table ,
pl - > vddc ,
pl - > sclk ,
pl - > mclk ,
& level - > vddc ) ;
if ( ret )
return ret ;
}
level - > MaxPoweredUpCU = si_pi - > max_cu ;
ret = si_populate_mvdd_value ( adev , pl - > mclk , & level - > mvdd ) ;
return ret ;
}
static int si_populate_smc_t ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_state ,
SISLANDS_SMC_SWSTATE * smc_state )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct si_ps * state = si_get_ps ( amdgpu_state ) ;
u32 a_t ;
u32 t_l , t_h ;
u32 high_bsp ;
int i , ret ;
if ( state - > performance_level_count > = 9 )
return - EINVAL ;
if ( state - > performance_level_count < 2 ) {
a_t = CG_R ( 0xffff ) | CG_L ( 0 ) ;
smc_state - > levels [ 0 ] . aT = cpu_to_be32 ( a_t ) ;
return 0 ;
}
smc_state - > levels [ 0 ] . aT = cpu_to_be32 ( 0 ) ;
for ( i = 0 ; i < = state - > performance_level_count - 2 ; i + + ) {
ret = r600_calculate_at (
( 50 / SISLANDS_MAX_HARDWARE_POWERLEVELS ) * 100 * ( i + 1 ) ,
100 * R600_AH_DFLT ,
state - > performance_levels [ i + 1 ] . sclk ,
state - > performance_levels [ i ] . sclk ,
& t_l ,
& t_h ) ;
if ( ret ) {
t_h = ( i + 1 ) * 1000 - 50 * R600_AH_DFLT ;
t_l = ( i + 1 ) * 1000 + 50 * R600_AH_DFLT ;
}
a_t = be32_to_cpu ( smc_state - > levels [ i ] . aT ) & ~ CG_R_MASK ;
a_t | = CG_R ( t_l * pi - > bsp / 20000 ) ;
smc_state - > levels [ i ] . aT = cpu_to_be32 ( a_t ) ;
high_bsp = ( i = = state - > performance_level_count - 2 ) ?
pi - > pbsp : pi - > bsp ;
a_t = CG_R ( 0xffff ) | CG_L ( t_h * high_bsp / 20000 ) ;
smc_state - > levels [ i + 1 ] . aT = cpu_to_be32 ( a_t ) ;
}
return 0 ;
}
static int si_disable_ulv ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct si_ulv_param * ulv = & si_pi - > ulv ;
if ( ulv - > supported )
2016-09-13 00:06:07 -04:00
return ( amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_DisableULV ) = = PPSMC_Result_OK ) ?
2016-08-01 12:42:32 -04:00
0 : - EINVAL ;
return 0 ;
}
static bool si_is_state_ulv_compatible ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_state )
{
const struct si_power_info * si_pi = si_get_pi ( adev ) ;
const struct si_ulv_param * ulv = & si_pi - > ulv ;
const struct si_ps * state = si_get_ps ( amdgpu_state ) ;
int i ;
if ( state - > performance_levels [ 0 ] . mclk ! = ulv - > pl . mclk )
return false ;
/* XXX validate against display requirements! */
for ( i = 0 ; i < adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . count ; i + + ) {
if ( adev - > clock . current_dispclk < =
adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries [ i ] . clk ) {
if ( ulv - > pl . vddc <
adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries [ i ] . v )
return false ;
}
}
if ( ( amdgpu_state - > vclk ! = 0 ) | | ( amdgpu_state - > dclk ! = 0 ) )
return false ;
return true ;
}
static int si_set_power_state_conditionally_enable_ulv ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_new_state )
{
const struct si_power_info * si_pi = si_get_pi ( adev ) ;
const struct si_ulv_param * ulv = & si_pi - > ulv ;
if ( ulv - > supported ) {
if ( si_is_state_ulv_compatible ( adev , amdgpu_new_state ) )
2016-09-13 00:06:07 -04:00
return ( amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_EnableULV ) = = PPSMC_Result_OK ) ?
2016-08-01 12:42:32 -04:00
0 : - EINVAL ;
}
return 0 ;
}
static int si_convert_power_state_to_smc ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_state ,
SISLANDS_SMC_SWSTATE * smc_state )
{
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct ni_power_info * ni_pi = ni_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct si_ps * state = si_get_ps ( amdgpu_state ) ;
int i , ret ;
u32 threshold ;
u32 sclk_in_sr = 1350 ; /* ??? */
if ( state - > performance_level_count > SISLANDS_MAX_HARDWARE_POWERLEVELS )
return - EINVAL ;
threshold = state - > performance_levels [ state - > performance_level_count - 1 ] . sclk * 100 / 100 ;
if ( amdgpu_state - > vclk & & amdgpu_state - > dclk ) {
eg_pi - > uvd_enabled = true ;
if ( eg_pi - > smu_uvd_hs )
smc_state - > flags | = PPSMC_SWSTATE_FLAG_UVD ;
} else {
eg_pi - > uvd_enabled = false ;
}
if ( state - > dc_compatible )
smc_state - > flags | = PPSMC_SWSTATE_FLAG_DC ;
smc_state - > levelCount = 0 ;
for ( i = 0 ; i < state - > performance_level_count ; i + + ) {
if ( eg_pi - > sclk_deep_sleep ) {
if ( ( i = = 0 ) | | si_pi - > sclk_deep_sleep_above_low ) {
if ( sclk_in_sr < = SCLK_MIN_DEEPSLEEP_FREQ )
smc_state - > levels [ i ] . stateFlags | = PPSMC_STATEFLAG_DEEPSLEEP_BYPASS ;
else
smc_state - > levels [ i ] . stateFlags | = PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE ;
}
}
ret = si_convert_power_level_to_smc ( adev , & state - > performance_levels [ i ] ,
& smc_state - > levels [ i ] ) ;
smc_state - > levels [ i ] . arbRefreshState =
( u8 ) ( SISLANDS_DRIVER_STATE_ARB_INDEX + i ) ;
if ( ret )
return ret ;
if ( ni_pi - > enable_power_containment )
smc_state - > levels [ i ] . displayWatermark =
( state - > performance_levels [ i ] . sclk < threshold ) ?
PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH ;
else
smc_state - > levels [ i ] . displayWatermark = ( i < 2 ) ?
PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH ;
if ( eg_pi - > dynamic_ac_timing )
smc_state - > levels [ i ] . ACIndex = SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i ;
else
smc_state - > levels [ i ] . ACIndex = 0 ;
smc_state - > levelCount + + ;
}
si_write_smc_soft_register ( adev ,
SI_SMC_SOFT_REGISTER_watermark_threshold ,
threshold / 512 ) ;
si_populate_smc_sp ( adev , amdgpu_state , smc_state ) ;
ret = si_populate_power_containment_values ( adev , amdgpu_state , smc_state ) ;
if ( ret )
ni_pi - > enable_power_containment = false ;
ret = si_populate_sq_ramping_values ( adev , amdgpu_state , smc_state ) ;
2016-09-06 09:45:43 -04:00
if ( ret )
2016-08-01 12:42:32 -04:00
ni_pi - > enable_sq_ramping = false ;
return si_populate_smc_t ( adev , amdgpu_state , smc_state ) ;
}
static int si_upload_sw_state ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_new_state )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct si_ps * new_state = si_get_ps ( amdgpu_new_state ) ;
int ret ;
u32 address = si_pi - > state_table_start +
offsetof ( SISLANDS_SMC_STATETABLE , driverState ) ;
u32 state_size = sizeof ( SISLANDS_SMC_SWSTATE ) +
( ( new_state - > performance_level_count - 1 ) *
sizeof ( SISLANDS_SMC_HW_PERFORMANCE_LEVEL ) ) ;
SISLANDS_SMC_SWSTATE * smc_state = & si_pi - > smc_statetable . driverState ;
memset ( smc_state , 0 , state_size ) ;
ret = si_convert_power_state_to_smc ( adev , amdgpu_new_state , smc_state ) ;
if ( ret )
return ret ;
2016-09-13 00:06:07 -04:00
return amdgpu_si_copy_bytes_to_smc ( adev , address , ( u8 * ) smc_state ,
state_size , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
}
static int si_upload_ulv_state ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct si_ulv_param * ulv = & si_pi - > ulv ;
int ret = 0 ;
if ( ulv - > supported & & ulv - > pl . vddc ) {
u32 address = si_pi - > state_table_start +
offsetof ( SISLANDS_SMC_STATETABLE , ULVState ) ;
SISLANDS_SMC_SWSTATE * smc_state = & si_pi - > smc_statetable . ULVState ;
u32 state_size = sizeof ( SISLANDS_SMC_SWSTATE ) ;
memset ( smc_state , 0 , state_size ) ;
ret = si_populate_ulv_state ( adev , smc_state ) ;
if ( ! ret )
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_copy_bytes_to_smc ( adev , address , ( u8 * ) smc_state ,
state_size , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
}
return ret ;
}
static int si_upload_smc_data ( struct amdgpu_device * adev )
{
struct amdgpu_crtc * amdgpu_crtc = NULL ;
int i ;
if ( adev - > pm . dpm . new_active_crtc_count = = 0 )
return 0 ;
for ( i = 0 ; i < adev - > mode_info . num_crtc ; i + + ) {
if ( adev - > pm . dpm . new_active_crtcs & ( 1 < < i ) ) {
amdgpu_crtc = adev - > mode_info . crtcs [ i ] ;
break ;
}
}
if ( amdgpu_crtc = = NULL )
return 0 ;
if ( amdgpu_crtc - > line_time < = 0 )
return 0 ;
if ( si_write_smc_soft_register ( adev ,
SI_SMC_SOFT_REGISTER_crtc_index ,
amdgpu_crtc - > crtc_id ) ! = PPSMC_Result_OK )
return 0 ;
if ( si_write_smc_soft_register ( adev ,
SI_SMC_SOFT_REGISTER_mclk_change_block_cp_min ,
amdgpu_crtc - > wm_high / amdgpu_crtc - > line_time ) ! = PPSMC_Result_OK )
return 0 ;
if ( si_write_smc_soft_register ( adev ,
SI_SMC_SOFT_REGISTER_mclk_change_block_cp_max ,
amdgpu_crtc - > wm_low / amdgpu_crtc - > line_time ) ! = PPSMC_Result_OK )
return 0 ;
return 0 ;
}
static int si_set_mc_special_registers ( struct amdgpu_device * adev ,
struct si_mc_reg_table * table )
{
u8 i , j , k ;
u32 temp_reg ;
for ( i = 0 , j = table - > last ; i < table - > last ; i + + ) {
if ( j > = SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE )
return - EINVAL ;
switch ( table - > mc_reg_address [ i ] . s1 ) {
case MC_SEQ_MISC1 :
temp_reg = RREG32 ( MC_PMG_CMD_EMRS ) ;
table - > mc_reg_address [ j ] . s1 = MC_PMG_CMD_EMRS ;
table - > mc_reg_address [ j ] . s0 = MC_SEQ_PMG_CMD_EMRS_LP ;
for ( k = 0 ; k < table - > num_entries ; k + + )
table - > mc_reg_table_entry [ k ] . mc_data [ j ] =
( ( temp_reg & 0xffff0000 ) ) |
( ( table - > mc_reg_table_entry [ k ] . mc_data [ i ] & 0xffff0000 ) > > 16 ) ;
j + + ;
if ( j > = SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE )
return - EINVAL ;
temp_reg = RREG32 ( MC_PMG_CMD_MRS ) ;
table - > mc_reg_address [ j ] . s1 = MC_PMG_CMD_MRS ;
table - > mc_reg_address [ j ] . s0 = MC_SEQ_PMG_CMD_MRS_LP ;
for ( k = 0 ; k < table - > num_entries ; k + + ) {
table - > mc_reg_table_entry [ k ] . mc_data [ j ] =
( temp_reg & 0xffff0000 ) |
( table - > mc_reg_table_entry [ k ] . mc_data [ i ] & 0x0000ffff ) ;
if ( adev - > mc . vram_type ! = AMDGPU_VRAM_TYPE_GDDR5 )
table - > mc_reg_table_entry [ k ] . mc_data [ j ] | = 0x100 ;
}
j + + ;
if ( j > = SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE )
return - EINVAL ;
if ( adev - > mc . vram_type ! = AMDGPU_VRAM_TYPE_GDDR5 ) {
table - > mc_reg_address [ j ] . s1 = MC_PMG_AUTO_CMD ;
table - > mc_reg_address [ j ] . s0 = MC_PMG_AUTO_CMD ;
for ( k = 0 ; k < table - > num_entries ; k + + )
table - > mc_reg_table_entry [ k ] . mc_data [ j ] =
( table - > mc_reg_table_entry [ k ] . mc_data [ i ] & 0xffff0000 ) > > 16 ;
j + + ;
if ( j > = SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE )
return - EINVAL ;
}
break ;
case MC_SEQ_RESERVE_M :
temp_reg = RREG32 ( MC_PMG_CMD_MRS1 ) ;
table - > mc_reg_address [ j ] . s1 = MC_PMG_CMD_MRS1 ;
table - > mc_reg_address [ j ] . s0 = MC_SEQ_PMG_CMD_MRS1_LP ;
for ( k = 0 ; k < table - > num_entries ; k + + )
table - > mc_reg_table_entry [ k ] . mc_data [ j ] =
( temp_reg & 0xffff0000 ) |
( table - > mc_reg_table_entry [ k ] . mc_data [ i ] & 0x0000ffff ) ;
j + + ;
if ( j > = SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE )
return - EINVAL ;
break ;
default :
break ;
}
}
table - > last = j ;
return 0 ;
}
static bool si_check_s0_mc_reg_index ( u16 in_reg , u16 * out_reg )
{
bool result = true ;
switch ( in_reg ) {
case MC_SEQ_RAS_TIMING :
* out_reg = MC_SEQ_RAS_TIMING_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_SEQ_CAS_TIMING :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_CAS_TIMING_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_SEQ_MISC_TIMING :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_MISC_TIMING_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_SEQ_MISC_TIMING2 :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_MISC_TIMING2_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_SEQ_RD_CTL_D0 :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_RD_CTL_D0_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_SEQ_RD_CTL_D1 :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_RD_CTL_D1_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_SEQ_WR_CTL_D0 :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_WR_CTL_D0_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_SEQ_WR_CTL_D1 :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_WR_CTL_D1_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_PMG_CMD_EMRS :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_PMG_CMD_EMRS_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_PMG_CMD_MRS :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_PMG_CMD_MRS_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_PMG_CMD_MRS1 :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_PMG_CMD_MRS1_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_SEQ_PMG_TIMING :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_PMG_TIMING_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_PMG_CMD_MRS2 :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_PMG_CMD_MRS2_LP ;
break ;
2016-09-06 09:45:43 -04:00
case MC_SEQ_WR_CTL_2 :
2016-08-01 12:42:32 -04:00
* out_reg = MC_SEQ_WR_CTL_2_LP ;
break ;
2016-09-06 09:45:43 -04:00
default :
2016-08-01 12:42:32 -04:00
result = false ;
break ;
}
return result ;
}
static void si_set_valid_flag ( struct si_mc_reg_table * table )
{
u8 i , j ;
for ( i = 0 ; i < table - > last ; i + + ) {
for ( j = 1 ; j < table - > num_entries ; j + + ) {
if ( table - > mc_reg_table_entry [ j - 1 ] . mc_data [ i ] ! = table - > mc_reg_table_entry [ j ] . mc_data [ i ] ) {
table - > valid_flag | = 1 < < i ;
break ;
}
}
}
}
static void si_set_s0_mc_reg_index ( struct si_mc_reg_table * table )
{
u32 i ;
u16 address ;
for ( i = 0 ; i < table - > last ; i + + )
table - > mc_reg_address [ i ] . s0 = si_check_s0_mc_reg_index ( table - > mc_reg_address [ i ] . s1 , & address ) ?
address : table - > mc_reg_address [ i ] . s1 ;
}
static int si_copy_vbios_mc_reg_table ( struct atom_mc_reg_table * table ,
struct si_mc_reg_table * si_table )
{
u8 i , j ;
if ( table - > last > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE )
return - EINVAL ;
if ( table - > num_entries > MAX_AC_TIMING_ENTRIES )
return - EINVAL ;
for ( i = 0 ; i < table - > last ; i + + )
si_table - > mc_reg_address [ i ] . s1 = table - > mc_reg_address [ i ] . s1 ;
si_table - > last = table - > last ;
for ( i = 0 ; i < table - > num_entries ; i + + ) {
si_table - > mc_reg_table_entry [ i ] . mclk_max =
table - > mc_reg_table_entry [ i ] . mclk_max ;
for ( j = 0 ; j < table - > last ; j + + ) {
si_table - > mc_reg_table_entry [ i ] . mc_data [ j ] =
table - > mc_reg_table_entry [ i ] . mc_data [ j ] ;
}
}
si_table - > num_entries = table - > num_entries ;
return 0 ;
}
static int si_initialize_mc_reg_table ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct atom_mc_reg_table * table ;
struct si_mc_reg_table * si_table = & si_pi - > mc_reg_table ;
u8 module_index = rv770_get_memory_module_index ( adev ) ;
int ret ;
table = kzalloc ( sizeof ( struct atom_mc_reg_table ) , GFP_KERNEL ) ;
if ( ! table )
return - ENOMEM ;
WREG32 ( MC_SEQ_RAS_TIMING_LP , RREG32 ( MC_SEQ_RAS_TIMING ) ) ;
WREG32 ( MC_SEQ_CAS_TIMING_LP , RREG32 ( MC_SEQ_CAS_TIMING ) ) ;
WREG32 ( MC_SEQ_MISC_TIMING_LP , RREG32 ( MC_SEQ_MISC_TIMING ) ) ;
WREG32 ( MC_SEQ_MISC_TIMING2_LP , RREG32 ( MC_SEQ_MISC_TIMING2 ) ) ;
WREG32 ( MC_SEQ_PMG_CMD_EMRS_LP , RREG32 ( MC_PMG_CMD_EMRS ) ) ;
WREG32 ( MC_SEQ_PMG_CMD_MRS_LP , RREG32 ( MC_PMG_CMD_MRS ) ) ;
WREG32 ( MC_SEQ_PMG_CMD_MRS1_LP , RREG32 ( MC_PMG_CMD_MRS1 ) ) ;
WREG32 ( MC_SEQ_WR_CTL_D0_LP , RREG32 ( MC_SEQ_WR_CTL_D0 ) ) ;
WREG32 ( MC_SEQ_WR_CTL_D1_LP , RREG32 ( MC_SEQ_WR_CTL_D1 ) ) ;
WREG32 ( MC_SEQ_RD_CTL_D0_LP , RREG32 ( MC_SEQ_RD_CTL_D0 ) ) ;
WREG32 ( MC_SEQ_RD_CTL_D1_LP , RREG32 ( MC_SEQ_RD_CTL_D1 ) ) ;
WREG32 ( MC_SEQ_PMG_TIMING_LP , RREG32 ( MC_SEQ_PMG_TIMING ) ) ;
WREG32 ( MC_SEQ_PMG_CMD_MRS2_LP , RREG32 ( MC_PMG_CMD_MRS2 ) ) ;
WREG32 ( MC_SEQ_WR_CTL_2_LP , RREG32 ( MC_SEQ_WR_CTL_2 ) ) ;
2016-09-06 09:45:43 -04:00
ret = amdgpu_atombios_init_mc_reg_table ( adev , module_index , table ) ;
if ( ret )
goto init_mc_done ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
ret = si_copy_vbios_mc_reg_table ( table , si_table ) ;
if ( ret )
goto init_mc_done ;
2016-08-01 12:42:32 -04:00
si_set_s0_mc_reg_index ( si_table ) ;
ret = si_set_mc_special_registers ( adev , si_table ) ;
2016-09-06 09:45:43 -04:00
if ( ret )
goto init_mc_done ;
2016-08-01 12:42:32 -04:00
si_set_valid_flag ( si_table ) ;
init_mc_done :
kfree ( table ) ;
return ret ;
}
static void si_populate_mc_reg_addresses ( struct amdgpu_device * adev ,
SMC_SIslands_MCRegisters * mc_reg_table )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 i , j ;
for ( i = 0 , j = 0 ; j < si_pi - > mc_reg_table . last ; j + + ) {
if ( si_pi - > mc_reg_table . valid_flag & ( 1 < < j ) ) {
if ( i > = SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE )
break ;
mc_reg_table - > address [ i ] . s0 =
cpu_to_be16 ( si_pi - > mc_reg_table . mc_reg_address [ j ] . s0 ) ;
mc_reg_table - > address [ i ] . s1 =
cpu_to_be16 ( si_pi - > mc_reg_table . mc_reg_address [ j ] . s1 ) ;
i + + ;
}
}
mc_reg_table - > last = ( u8 ) i ;
}
static void si_convert_mc_registers ( const struct si_mc_reg_entry * entry ,
SMC_SIslands_MCRegisterSet * data ,
u32 num_entries , u32 valid_flag )
{
u32 i , j ;
for ( i = 0 , j = 0 ; j < num_entries ; j + + ) {
if ( valid_flag & ( 1 < < j ) ) {
data - > value [ i ] = cpu_to_be32 ( entry - > mc_data [ j ] ) ;
i + + ;
}
}
}
static void si_convert_mc_reg_table_entry_to_smc ( struct amdgpu_device * adev ,
struct rv7xx_pl * pl ,
SMC_SIslands_MCRegisterSet * mc_reg_table_data )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 i = 0 ;
for ( i = 0 ; i < si_pi - > mc_reg_table . num_entries ; i + + ) {
if ( pl - > mclk < = si_pi - > mc_reg_table . mc_reg_table_entry [ i ] . mclk_max )
break ;
}
if ( ( i = = si_pi - > mc_reg_table . num_entries ) & & ( i > 0 ) )
- - i ;
si_convert_mc_registers ( & si_pi - > mc_reg_table . mc_reg_table_entry [ i ] ,
mc_reg_table_data , si_pi - > mc_reg_table . last ,
si_pi - > mc_reg_table . valid_flag ) ;
}
static void si_convert_mc_reg_table_to_smc ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_state ,
SMC_SIslands_MCRegisters * mc_reg_table )
{
2016-09-06 09:45:43 -04:00
struct si_ps * state = si_get_ps ( amdgpu_state ) ;
2016-08-01 12:42:32 -04:00
int i ;
for ( i = 0 ; i < state - > performance_level_count ; i + + ) {
si_convert_mc_reg_table_entry_to_smc ( adev ,
& state - > performance_levels [ i ] ,
& mc_reg_table - > data [ SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i ] ) ;
}
}
static int si_populate_mc_reg_table ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_boot_state )
{
struct si_ps * boot_state = si_get_ps ( amdgpu_boot_state ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct si_ulv_param * ulv = & si_pi - > ulv ;
SMC_SIslands_MCRegisters * smc_mc_reg_table = & si_pi - > smc_mc_reg_table ;
memset ( smc_mc_reg_table , 0 , sizeof ( SMC_SIslands_MCRegisters ) ) ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_seq_index , 1 ) ;
si_populate_mc_reg_addresses ( adev , smc_mc_reg_table ) ;
si_convert_mc_reg_table_entry_to_smc ( adev , & boot_state - > performance_levels [ 0 ] ,
& smc_mc_reg_table - > data [ SISLANDS_MCREGISTERTABLE_INITIAL_SLOT ] ) ;
si_convert_mc_registers ( & si_pi - > mc_reg_table . mc_reg_table_entry [ 0 ] ,
& smc_mc_reg_table - > data [ SISLANDS_MCREGISTERTABLE_ACPI_SLOT ] ,
si_pi - > mc_reg_table . last ,
si_pi - > mc_reg_table . valid_flag ) ;
if ( ulv - > supported & & ulv - > pl . vddc ! = 0 )
si_convert_mc_reg_table_entry_to_smc ( adev , & ulv - > pl ,
& smc_mc_reg_table - > data [ SISLANDS_MCREGISTERTABLE_ULV_SLOT ] ) ;
else
si_convert_mc_registers ( & si_pi - > mc_reg_table . mc_reg_table_entry [ 0 ] ,
& smc_mc_reg_table - > data [ SISLANDS_MCREGISTERTABLE_ULV_SLOT ] ,
si_pi - > mc_reg_table . last ,
si_pi - > mc_reg_table . valid_flag ) ;
si_convert_mc_reg_table_to_smc ( adev , amdgpu_boot_state , smc_mc_reg_table ) ;
2016-09-13 00:06:07 -04:00
return amdgpu_si_copy_bytes_to_smc ( adev , si_pi - > mc_reg_table_start ,
( u8 * ) smc_mc_reg_table ,
sizeof ( SMC_SIslands_MCRegisters ) , si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
}
static int si_upload_mc_reg_table ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_new_state )
{
2016-09-06 09:45:43 -04:00
struct si_ps * new_state = si_get_ps ( amdgpu_new_state ) ;
2016-08-01 12:42:32 -04:00
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 address = si_pi - > mc_reg_table_start +
offsetof ( SMC_SIslands_MCRegisters ,
data [ SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT ] ) ;
SMC_SIslands_MCRegisters * smc_mc_reg_table = & si_pi - > smc_mc_reg_table ;
memset ( smc_mc_reg_table , 0 , sizeof ( SMC_SIslands_MCRegisters ) ) ;
si_convert_mc_reg_table_to_smc ( adev , amdgpu_new_state , smc_mc_reg_table ) ;
2016-09-13 00:06:07 -04:00
return amdgpu_si_copy_bytes_to_smc ( adev , address ,
( u8 * ) & smc_mc_reg_table - > data [ SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT ] ,
sizeof ( SMC_SIslands_MCRegisterSet ) * new_state - > performance_level_count ,
si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
}
static void si_enable_voltage_control ( struct amdgpu_device * adev , bool enable )
{
2016-09-06 09:45:43 -04:00
if ( enable )
WREG32_P ( GENERAL_PWRMGT , VOLT_PWRMGT_EN , ~ VOLT_PWRMGT_EN ) ;
else
WREG32_P ( GENERAL_PWRMGT , 0 , ~ VOLT_PWRMGT_EN ) ;
2016-08-01 12:42:32 -04:00
}
static enum amdgpu_pcie_gen si_get_maximum_link_speed ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_state )
{
2016-09-06 09:45:43 -04:00
struct si_ps * state = si_get_ps ( amdgpu_state ) ;
2016-08-01 12:42:32 -04:00
int i ;
u16 pcie_speed , max_speed = 0 ;
for ( i = 0 ; i < state - > performance_level_count ; i + + ) {
pcie_speed = state - > performance_levels [ i ] . pcie_gen ;
if ( max_speed < pcie_speed )
max_speed = pcie_speed ;
}
return max_speed ;
}
static u16 si_get_current_pcie_speed ( struct amdgpu_device * adev )
{
u32 speed_cntl ;
speed_cntl = RREG32_PCIE_PORT ( PCIE_LC_SPEED_CNTL ) & LC_CURRENT_DATA_RATE_MASK ;
speed_cntl > > = LC_CURRENT_DATA_RATE_SHIFT ;
return ( u16 ) speed_cntl ;
}
static void si_request_link_speed_change_before_state_change ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_new_state ,
struct amdgpu_ps * amdgpu_current_state )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
enum amdgpu_pcie_gen target_link_speed = si_get_maximum_link_speed ( adev , amdgpu_new_state ) ;
enum amdgpu_pcie_gen current_link_speed ;
if ( si_pi - > force_pcie_gen = = AMDGPU_PCIE_GEN_INVALID )
current_link_speed = si_get_maximum_link_speed ( adev , amdgpu_current_state ) ;
else
current_link_speed = si_pi - > force_pcie_gen ;
si_pi - > force_pcie_gen = AMDGPU_PCIE_GEN_INVALID ;
si_pi - > pspp_notify_required = false ;
if ( target_link_speed > current_link_speed ) {
switch ( target_link_speed ) {
# if defined(CONFIG_ACPI)
case AMDGPU_PCIE_GEN3 :
if ( amdgpu_acpi_pcie_performance_request ( adev , PCIE_PERF_REQ_PECI_GEN3 , false ) = = 0 )
break ;
si_pi - > force_pcie_gen = AMDGPU_PCIE_GEN2 ;
if ( current_link_speed = = AMDGPU_PCIE_GEN2 )
break ;
case AMDGPU_PCIE_GEN2 :
if ( amdgpu_acpi_pcie_performance_request ( adev , PCIE_PERF_REQ_PECI_GEN2 , false ) = = 0 )
break ;
# endif
default :
si_pi - > force_pcie_gen = si_get_current_pcie_speed ( adev ) ;
break ;
}
} else {
if ( target_link_speed < current_link_speed )
si_pi - > pspp_notify_required = true ;
}
}
static void si_notify_link_speed_change_after_state_change ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_new_state ,
struct amdgpu_ps * amdgpu_current_state )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
enum amdgpu_pcie_gen target_link_speed = si_get_maximum_link_speed ( adev , amdgpu_new_state ) ;
u8 request ;
if ( si_pi - > pspp_notify_required ) {
if ( target_link_speed = = AMDGPU_PCIE_GEN3 )
request = PCIE_PERF_REQ_PECI_GEN3 ;
else if ( target_link_speed = = AMDGPU_PCIE_GEN2 )
request = PCIE_PERF_REQ_PECI_GEN2 ;
else
request = PCIE_PERF_REQ_PECI_GEN1 ;
if ( ( request = = PCIE_PERF_REQ_PECI_GEN1 ) & &
( si_get_current_pcie_speed ( adev ) > 0 ) )
return ;
# if defined(CONFIG_ACPI)
amdgpu_acpi_pcie_performance_request ( adev , request , false ) ;
# endif
}
}
#if 0
static int si_ds_request ( struct amdgpu_device * adev ,
bool ds_status_on , u32 count_write )
{
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
if ( eg_pi - > sclk_deep_sleep ) {
if ( ds_status_on )
2016-09-13 00:06:07 -04:00
return ( amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_CancelThrottleOVRDSCLKDS ) = =
2016-08-01 12:42:32 -04:00
PPSMC_Result_OK ) ?
0 : - EINVAL ;
else
2016-09-13 00:06:07 -04:00
return ( amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_ThrottleOVRDSCLKDS ) = =
2016-08-01 12:42:32 -04:00
PPSMC_Result_OK ) ? 0 : - EINVAL ;
}
return 0 ;
}
# endif
static void si_set_max_cu_value ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
if ( adev - > asic_type = = CHIP_VERDE ) {
switch ( adev - > pdev - > device ) {
case 0x6820 :
case 0x6825 :
case 0x6821 :
case 0x6823 :
case 0x6827 :
si_pi - > max_cu = 10 ;
break ;
case 0x682D :
case 0x6824 :
case 0x682F :
case 0x6826 :
si_pi - > max_cu = 8 ;
break ;
case 0x6828 :
case 0x6830 :
case 0x6831 :
case 0x6838 :
case 0x6839 :
case 0x683D :
si_pi - > max_cu = 10 ;
break ;
case 0x683B :
case 0x683F :
case 0x6829 :
si_pi - > max_cu = 8 ;
break ;
default :
si_pi - > max_cu = 0 ;
break ;
}
} else {
si_pi - > max_cu = 0 ;
}
}
static int si_patch_single_dependency_table_based_on_leakage ( struct amdgpu_device * adev ,
struct amdgpu_clock_voltage_dependency_table * table )
{
u32 i ;
int j ;
u16 leakage_voltage ;
if ( table ) {
for ( i = 0 ; i < table - > count ; i + + ) {
switch ( si_get_leakage_voltage_from_leakage_index ( adev ,
table - > entries [ i ] . v ,
& leakage_voltage ) ) {
case 0 :
table - > entries [ i ] . v = leakage_voltage ;
break ;
case - EAGAIN :
return - EINVAL ;
case - EINVAL :
default :
break ;
}
}
for ( j = ( table - > count - 2 ) ; j > = 0 ; j - - ) {
table - > entries [ j ] . v = ( table - > entries [ j ] . v < = table - > entries [ j + 1 ] . v ) ?
table - > entries [ j ] . v : table - > entries [ j + 1 ] . v ;
}
}
return 0 ;
}
static int si_patch_dependency_tables_based_on_leakage ( struct amdgpu_device * adev )
{
int ret = 0 ;
ret = si_patch_single_dependency_table_based_on_leakage ( adev ,
& adev - > pm . dpm . dyn_state . vddc_dependency_on_sclk ) ;
2016-09-07 08:42:41 -04:00
if ( ret )
DRM_ERROR ( " Could not patch vddc_on_sclk leakage table \n " ) ;
2016-08-01 12:42:32 -04:00
ret = si_patch_single_dependency_table_based_on_leakage ( adev ,
& adev - > pm . dpm . dyn_state . vddc_dependency_on_mclk ) ;
2016-09-07 08:42:41 -04:00
if ( ret )
DRM_ERROR ( " Could not patch vddc_on_mclk leakage table \n " ) ;
2016-08-01 12:42:32 -04:00
ret = si_patch_single_dependency_table_based_on_leakage ( adev ,
& adev - > pm . dpm . dyn_state . vddci_dependency_on_mclk ) ;
2016-09-07 08:42:41 -04:00
if ( ret )
DRM_ERROR ( " Could not patch vddci_on_mclk leakage table \n " ) ;
2016-08-01 12:42:32 -04:00
return ret ;
}
static void si_set_pcie_lane_width_in_smc ( struct amdgpu_device * adev ,
struct amdgpu_ps * amdgpu_new_state ,
struct amdgpu_ps * amdgpu_current_state )
{
u32 lane_width ;
u32 new_lane_width =
( amdgpu_new_state - > caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK ) > > ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT ;
u32 current_lane_width =
( amdgpu_current_state - > caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK ) > > ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT ;
if ( new_lane_width ! = current_lane_width ) {
amdgpu_set_pcie_lanes ( adev , new_lane_width ) ;
lane_width = amdgpu_get_pcie_lanes ( adev ) ;
si_write_smc_soft_register ( adev , SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width , lane_width ) ;
}
}
static void si_dpm_setup_asic ( struct amdgpu_device * adev )
{
si_read_clock_registers ( adev ) ;
si_enable_acpi_power_management ( adev ) ;
}
static int si_thermal_enable_alert ( struct amdgpu_device * adev ,
bool enable )
{
u32 thermal_int = RREG32 ( CG_THERMAL_INT ) ;
if ( enable ) {
PPSMC_Result result ;
thermal_int & = ~ ( THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW ) ;
WREG32 ( CG_THERMAL_INT , thermal_int ) ;
2016-09-13 00:06:07 -04:00
result = amdgpu_si_send_msg_to_smc ( adev , PPSMC_MSG_EnableThermalInterrupt ) ;
2016-08-01 12:42:32 -04:00
if ( result ! = PPSMC_Result_OK ) {
DRM_DEBUG_KMS ( " Could not enable thermal interrupts. \n " ) ;
return - EINVAL ;
}
} else {
thermal_int | = THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW ;
WREG32 ( CG_THERMAL_INT , thermal_int ) ;
}
return 0 ;
}
static int si_thermal_set_temperature_range ( struct amdgpu_device * adev ,
int min_temp , int max_temp )
{
int low_temp = 0 * 1000 ;
int high_temp = 255 * 1000 ;
if ( low_temp < min_temp )
low_temp = min_temp ;
if ( high_temp > max_temp )
high_temp = max_temp ;
if ( high_temp < low_temp ) {
DRM_ERROR ( " invalid thermal range: %d - %d \n " , low_temp , high_temp ) ;
return - EINVAL ;
}
WREG32_P ( CG_THERMAL_INT , DIG_THERM_INTH ( high_temp / 1000 ) , ~ DIG_THERM_INTH_MASK ) ;
WREG32_P ( CG_THERMAL_INT , DIG_THERM_INTL ( low_temp / 1000 ) , ~ DIG_THERM_INTL_MASK ) ;
WREG32_P ( CG_THERMAL_CTRL , DIG_THERM_DPM ( high_temp / 1000 ) , ~ DIG_THERM_DPM_MASK ) ;
adev - > pm . dpm . thermal . min_temp = low_temp ;
adev - > pm . dpm . thermal . max_temp = high_temp ;
return 0 ;
}
static void si_fan_ctrl_set_static_mode ( struct amdgpu_device * adev , u32 mode )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 tmp ;
if ( si_pi - > fan_ctrl_is_in_default_mode ) {
tmp = ( RREG32 ( CG_FDO_CTRL2 ) & FDO_PWM_MODE_MASK ) > > FDO_PWM_MODE_SHIFT ;
si_pi - > fan_ctrl_default_mode = tmp ;
tmp = ( RREG32 ( CG_FDO_CTRL2 ) & TMIN_MASK ) > > TMIN_SHIFT ;
si_pi - > t_min = tmp ;
si_pi - > fan_ctrl_is_in_default_mode = false ;
}
tmp = RREG32 ( CG_FDO_CTRL2 ) & ~ TMIN_MASK ;
tmp | = TMIN ( 0 ) ;
WREG32 ( CG_FDO_CTRL2 , tmp ) ;
tmp = RREG32 ( CG_FDO_CTRL2 ) & ~ FDO_PWM_MODE_MASK ;
tmp | = FDO_PWM_MODE ( mode ) ;
WREG32 ( CG_FDO_CTRL2 , tmp ) ;
}
static int si_thermal_setup_fan_table ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
PP_SIslands_FanTable fan_table = { FDO_MODE_HARDWARE } ;
u32 duty100 ;
u32 t_diff1 , t_diff2 , pwm_diff1 , pwm_diff2 ;
u16 fdo_min , slope1 , slope2 ;
u32 reference_clock , tmp ;
int ret ;
u64 tmp64 ;
if ( ! si_pi - > fan_table_start ) {
adev - > pm . dpm . fan . ucode_fan_control = false ;
return 0 ;
}
duty100 = ( RREG32 ( CG_FDO_CTRL1 ) & FMAX_DUTY100_MASK ) > > FMAX_DUTY100_SHIFT ;
if ( duty100 = = 0 ) {
adev - > pm . dpm . fan . ucode_fan_control = false ;
return 0 ;
}
tmp64 = ( u64 ) adev - > pm . dpm . fan . pwm_min * duty100 ;
do_div ( tmp64 , 10000 ) ;
fdo_min = ( u16 ) tmp64 ;
t_diff1 = adev - > pm . dpm . fan . t_med - adev - > pm . dpm . fan . t_min ;
t_diff2 = adev - > pm . dpm . fan . t_high - adev - > pm . dpm . fan . t_med ;
pwm_diff1 = adev - > pm . dpm . fan . pwm_med - adev - > pm . dpm . fan . pwm_min ;
pwm_diff2 = adev - > pm . dpm . fan . pwm_high - adev - > pm . dpm . fan . pwm_med ;
slope1 = ( u16 ) ( ( 50 + ( ( 16 * duty100 * pwm_diff1 ) / t_diff1 ) ) / 100 ) ;
slope2 = ( u16 ) ( ( 50 + ( ( 16 * duty100 * pwm_diff2 ) / t_diff2 ) ) / 100 ) ;
fan_table . temp_min = cpu_to_be16 ( ( 50 + adev - > pm . dpm . fan . t_min ) / 100 ) ;
fan_table . temp_med = cpu_to_be16 ( ( 50 + adev - > pm . dpm . fan . t_med ) / 100 ) ;
fan_table . temp_max = cpu_to_be16 ( ( 50 + adev - > pm . dpm . fan . t_max ) / 100 ) ;
fan_table . slope1 = cpu_to_be16 ( slope1 ) ;
fan_table . slope2 = cpu_to_be16 ( slope2 ) ;
fan_table . fdo_min = cpu_to_be16 ( fdo_min ) ;
fan_table . hys_down = cpu_to_be16 ( adev - > pm . dpm . fan . t_hyst ) ;
fan_table . hys_up = cpu_to_be16 ( 1 ) ;
fan_table . hys_slope = cpu_to_be16 ( 1 ) ;
fan_table . temp_resp_lim = cpu_to_be16 ( 5 ) ;
reference_clock = amdgpu_asic_get_xclk ( adev ) ;
fan_table . refresh_period = cpu_to_be32 ( ( adev - > pm . dpm . fan . cycle_delay *
reference_clock ) / 1600 ) ;
fan_table . fdo_max = cpu_to_be16 ( ( u16 ) duty100 ) ;
tmp = ( RREG32 ( CG_MULT_THERMAL_CTRL ) & TEMP_SEL_MASK ) > > TEMP_SEL_SHIFT ;
fan_table . temp_src = ( uint8_t ) tmp ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_copy_bytes_to_smc ( adev ,
si_pi - > fan_table_start ,
( u8 * ) ( & fan_table ) ,
sizeof ( fan_table ) ,
si_pi - > sram_end ) ;
2016-08-01 12:42:32 -04:00
if ( ret ) {
DRM_ERROR ( " Failed to load fan table to the SMC. " ) ;
adev - > pm . dpm . fan . ucode_fan_control = false ;
}
2016-09-07 08:42:41 -04:00
return ret ;
2016-08-01 12:42:32 -04:00
}
static int si_fan_ctrl_start_smc_fan_control ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
PPSMC_Result ret ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_send_msg_to_smc ( adev , PPSMC_StartFanControl ) ;
2016-08-01 12:42:32 -04:00
if ( ret = = PPSMC_Result_OK ) {
si_pi - > fan_is_controlled_by_smc = true ;
return 0 ;
} else {
return - EINVAL ;
}
}
static int si_fan_ctrl_stop_smc_fan_control ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
PPSMC_Result ret ;
2016-09-13 00:06:07 -04:00
ret = amdgpu_si_send_msg_to_smc ( adev , PPSMC_StopFanControl ) ;
2016-08-01 12:42:32 -04:00
if ( ret = = PPSMC_Result_OK ) {
si_pi - > fan_is_controlled_by_smc = false ;
return 0 ;
} else {
return - EINVAL ;
}
}
2017-09-06 15:27:59 +08:00
static int si_dpm_get_fan_speed_percent ( void * handle ,
2016-08-01 12:42:32 -04:00
u32 * speed )
{
u32 duty , duty100 ;
u64 tmp64 ;
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-08-01 12:42:32 -04:00
if ( adev - > pm . no_fan )
return - ENOENT ;
duty100 = ( RREG32 ( CG_FDO_CTRL1 ) & FMAX_DUTY100_MASK ) > > FMAX_DUTY100_SHIFT ;
duty = ( RREG32 ( CG_THERMAL_STATUS ) & FDO_PWM_DUTY_MASK ) > > FDO_PWM_DUTY_SHIFT ;
if ( duty100 = = 0 )
return - EINVAL ;
tmp64 = ( u64 ) duty * 100 ;
do_div ( tmp64 , duty100 ) ;
* speed = ( u32 ) tmp64 ;
if ( * speed > 100 )
* speed = 100 ;
return 0 ;
}
2017-09-06 15:27:59 +08:00
static int si_dpm_set_fan_speed_percent ( void * handle ,
2016-08-01 12:42:32 -04:00
u32 speed )
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-08-01 12:42:32 -04:00
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 tmp ;
u32 duty , duty100 ;
u64 tmp64 ;
if ( adev - > pm . no_fan )
return - ENOENT ;
if ( si_pi - > fan_is_controlled_by_smc )
return - EINVAL ;
if ( speed > 100 )
return - EINVAL ;
duty100 = ( RREG32 ( CG_FDO_CTRL1 ) & FMAX_DUTY100_MASK ) > > FMAX_DUTY100_SHIFT ;
if ( duty100 = = 0 )
return - EINVAL ;
tmp64 = ( u64 ) speed * duty100 ;
do_div ( tmp64 , 100 ) ;
duty = ( u32 ) tmp64 ;
tmp = RREG32 ( CG_FDO_CTRL0 ) & ~ FDO_STATIC_DUTY_MASK ;
tmp | = FDO_STATIC_DUTY ( duty ) ;
WREG32 ( CG_FDO_CTRL0 , tmp ) ;
return 0 ;
}
2017-09-06 15:27:59 +08:00
static void si_dpm_set_fan_control_mode ( void * handle , u32 mode )
2016-08-01 12:42:32 -04:00
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-08-01 12:42:32 -04:00
if ( mode ) {
/* stop auto-manage */
if ( adev - > pm . dpm . fan . ucode_fan_control )
si_fan_ctrl_stop_smc_fan_control ( adev ) ;
si_fan_ctrl_set_static_mode ( adev , mode ) ;
} else {
/* restart auto-manage */
if ( adev - > pm . dpm . fan . ucode_fan_control )
si_thermal_start_smc_fan_control ( adev ) ;
else
si_fan_ctrl_set_default_mode ( adev ) ;
}
}
2017-09-06 15:27:59 +08:00
static u32 si_dpm_get_fan_control_mode ( void * handle )
2016-08-01 12:42:32 -04:00
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-08-01 12:42:32 -04:00
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 tmp ;
if ( si_pi - > fan_is_controlled_by_smc )
return 0 ;
tmp = RREG32 ( CG_FDO_CTRL2 ) & FDO_PWM_MODE_MASK ;
return ( tmp > > FDO_PWM_MODE_SHIFT ) ;
}
#if 0
static int si_fan_ctrl_get_fan_speed_rpm ( struct amdgpu_device * adev ,
u32 * speed )
{
u32 tach_period ;
u32 xclk = amdgpu_asic_get_xclk ( adev ) ;
if ( adev - > pm . no_fan )
return - ENOENT ;
if ( adev - > pm . fan_pulses_per_revolution = = 0 )
return - ENOENT ;
tach_period = ( RREG32 ( CG_TACH_STATUS ) & TACH_PERIOD_MASK ) > > TACH_PERIOD_SHIFT ;
if ( tach_period = = 0 )
return - ENOENT ;
* speed = 60 * xclk * 10000 / tach_period ;
return 0 ;
}
static int si_fan_ctrl_set_fan_speed_rpm ( struct amdgpu_device * adev ,
u32 speed )
{
u32 tach_period , tmp ;
u32 xclk = amdgpu_asic_get_xclk ( adev ) ;
if ( adev - > pm . no_fan )
return - ENOENT ;
if ( adev - > pm . fan_pulses_per_revolution = = 0 )
return - ENOENT ;
if ( ( speed < adev - > pm . fan_min_rpm ) | |
( speed > adev - > pm . fan_max_rpm ) )
return - EINVAL ;
if ( adev - > pm . dpm . fan . ucode_fan_control )
si_fan_ctrl_stop_smc_fan_control ( adev ) ;
tach_period = 60 * xclk * 10000 / ( 8 * speed ) ;
tmp = RREG32 ( CG_TACH_CTRL ) & ~ TARGET_PERIOD_MASK ;
tmp | = TARGET_PERIOD ( tach_period ) ;
WREG32 ( CG_TACH_CTRL , tmp ) ;
si_fan_ctrl_set_static_mode ( adev , FDO_PWM_MODE_STATIC_RPM ) ;
return 0 ;
}
# endif
static void si_fan_ctrl_set_default_mode ( struct amdgpu_device * adev )
{
struct si_power_info * si_pi = si_get_pi ( adev ) ;
u32 tmp ;
if ( ! si_pi - > fan_ctrl_is_in_default_mode ) {
tmp = RREG32 ( CG_FDO_CTRL2 ) & ~ FDO_PWM_MODE_MASK ;
tmp | = FDO_PWM_MODE ( si_pi - > fan_ctrl_default_mode ) ;
WREG32 ( CG_FDO_CTRL2 , tmp ) ;
tmp = RREG32 ( CG_FDO_CTRL2 ) & ~ TMIN_MASK ;
tmp | = TMIN ( si_pi - > t_min ) ;
WREG32 ( CG_FDO_CTRL2 , tmp ) ;
si_pi - > fan_ctrl_is_in_default_mode = true ;
}
}
static void si_thermal_start_smc_fan_control ( struct amdgpu_device * adev )
{
if ( adev - > pm . dpm . fan . ucode_fan_control ) {
si_fan_ctrl_start_smc_fan_control ( adev ) ;
si_fan_ctrl_set_static_mode ( adev , FDO_PWM_MODE_STATIC ) ;
}
}
static void si_thermal_initialize ( struct amdgpu_device * adev )
{
u32 tmp ;
if ( adev - > pm . fan_pulses_per_revolution ) {
tmp = RREG32 ( CG_TACH_CTRL ) & ~ EDGE_PER_REV_MASK ;
tmp | = EDGE_PER_REV ( adev - > pm . fan_pulses_per_revolution - 1 ) ;
WREG32 ( CG_TACH_CTRL , tmp ) ;
}
tmp = RREG32 ( CG_FDO_CTRL2 ) & ~ TACH_PWM_RESP_RATE_MASK ;
tmp | = TACH_PWM_RESP_RATE ( 0x28 ) ;
WREG32 ( CG_FDO_CTRL2 , tmp ) ;
}
static int si_thermal_start_thermal_controller ( struct amdgpu_device * adev )
{
int ret ;
si_thermal_initialize ( adev ) ;
ret = si_thermal_set_temperature_range ( adev , R600_TEMP_RANGE_MIN , R600_TEMP_RANGE_MAX ) ;
if ( ret )
return ret ;
ret = si_thermal_enable_alert ( adev , true ) ;
if ( ret )
return ret ;
if ( adev - > pm . dpm . fan . ucode_fan_control ) {
ret = si_halt_smc ( adev ) ;
if ( ret )
return ret ;
ret = si_thermal_setup_fan_table ( adev ) ;
if ( ret )
return ret ;
ret = si_resume_smc ( adev ) ;
if ( ret )
return ret ;
si_thermal_start_smc_fan_control ( adev ) ;
}
return 0 ;
}
static void si_thermal_stop_thermal_controller ( struct amdgpu_device * adev )
{
if ( ! adev - > pm . no_fan ) {
si_fan_ctrl_set_default_mode ( adev ) ;
si_fan_ctrl_stop_smc_fan_control ( adev ) ;
}
}
static int si_dpm_enable ( struct amdgpu_device * adev )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct amdgpu_ps * boot_ps = adev - > pm . dpm . boot_ps ;
int ret ;
2016-09-13 00:06:07 -04:00
if ( amdgpu_si_is_smc_running ( adev ) )
2016-08-01 12:42:32 -04:00
return - EINVAL ;
if ( pi - > voltage_control | | si_pi - > voltage_control_svi2 )
si_enable_voltage_control ( adev , true ) ;
if ( pi - > mvdd_control )
si_get_mvdd_configuration ( adev ) ;
if ( pi - > voltage_control | | si_pi - > voltage_control_svi2 ) {
ret = si_construct_voltage_tables ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_construct_voltage_tables failed \n " ) ;
return ret ;
}
}
if ( eg_pi - > dynamic_ac_timing ) {
ret = si_initialize_mc_reg_table ( adev ) ;
if ( ret )
eg_pi - > dynamic_ac_timing = false ;
}
if ( pi - > dynamic_ss )
si_enable_spread_spectrum ( adev , true ) ;
if ( pi - > thermal_protection )
si_enable_thermal_protection ( adev , true ) ;
si_setup_bsp ( adev ) ;
si_program_git ( adev ) ;
si_program_tp ( adev ) ;
si_program_tpp ( adev ) ;
si_program_sstp ( adev ) ;
si_enable_display_gap ( adev ) ;
si_program_vc ( adev ) ;
ret = si_upload_firmware ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_upload_firmware failed \n " ) ;
return ret ;
}
ret = si_process_firmware_header ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_process_firmware_header failed \n " ) ;
return ret ;
}
ret = si_initial_switch_from_arb_f0_to_f1 ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_initial_switch_from_arb_f0_to_f1 failed \n " ) ;
return ret ;
}
ret = si_init_smc_table ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_init_smc_table failed \n " ) ;
return ret ;
}
ret = si_init_smc_spll_table ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_init_smc_spll_table failed \n " ) ;
return ret ;
}
ret = si_init_arb_table_index ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_init_arb_table_index failed \n " ) ;
return ret ;
}
if ( eg_pi - > dynamic_ac_timing ) {
ret = si_populate_mc_reg_table ( adev , boot_ps ) ;
if ( ret ) {
DRM_ERROR ( " si_populate_mc_reg_table failed \n " ) ;
return ret ;
}
}
ret = si_initialize_smc_cac_tables ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_initialize_smc_cac_tables failed \n " ) ;
return ret ;
}
ret = si_initialize_hardware_cac_manager ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_initialize_hardware_cac_manager failed \n " ) ;
return ret ;
}
ret = si_initialize_smc_dte_tables ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_initialize_smc_dte_tables failed \n " ) ;
return ret ;
}
ret = si_populate_smc_tdp_limits ( adev , boot_ps ) ;
if ( ret ) {
DRM_ERROR ( " si_populate_smc_tdp_limits failed \n " ) ;
return ret ;
}
ret = si_populate_smc_tdp_limits_2 ( adev , boot_ps ) ;
if ( ret ) {
DRM_ERROR ( " si_populate_smc_tdp_limits_2 failed \n " ) ;
return ret ;
}
si_program_response_times ( adev ) ;
si_program_ds_registers ( adev ) ;
si_dpm_start_smc ( adev ) ;
ret = si_notify_smc_display_change ( adev , false ) ;
if ( ret ) {
DRM_ERROR ( " si_notify_smc_display_change failed \n " ) ;
return ret ;
}
si_enable_sclk_control ( adev , true ) ;
si_start_dpm ( adev ) ;
si_enable_auto_throttle_source ( adev , AMDGPU_DPM_AUTO_THROTTLE_SRC_THERMAL , true ) ;
si_thermal_start_thermal_controller ( adev ) ;
ni_update_current_ps ( adev , boot_ps ) ;
return 0 ;
}
static int si_set_temperature_range ( struct amdgpu_device * adev )
{
int ret ;
ret = si_thermal_enable_alert ( adev , false ) ;
if ( ret )
return ret ;
ret = si_thermal_set_temperature_range ( adev , R600_TEMP_RANGE_MIN , R600_TEMP_RANGE_MAX ) ;
if ( ret )
return ret ;
ret = si_thermal_enable_alert ( adev , true ) ;
if ( ret )
return ret ;
return ret ;
}
static void si_dpm_disable ( struct amdgpu_device * adev )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct amdgpu_ps * boot_ps = adev - > pm . dpm . boot_ps ;
2016-09-13 00:06:07 -04:00
if ( ! amdgpu_si_is_smc_running ( adev ) )
2016-08-01 12:42:32 -04:00
return ;
si_thermal_stop_thermal_controller ( adev ) ;
si_disable_ulv ( adev ) ;
si_clear_vc ( adev ) ;
if ( pi - > thermal_protection )
si_enable_thermal_protection ( adev , false ) ;
si_enable_power_containment ( adev , boot_ps , false ) ;
si_enable_smc_cac ( adev , boot_ps , false ) ;
si_enable_spread_spectrum ( adev , false ) ;
si_enable_auto_throttle_source ( adev , AMDGPU_DPM_AUTO_THROTTLE_SRC_THERMAL , false ) ;
si_stop_dpm ( adev ) ;
si_reset_to_default ( adev ) ;
si_dpm_stop_smc ( adev ) ;
si_force_switch_to_arb_f0 ( adev ) ;
ni_update_current_ps ( adev , boot_ps ) ;
}
2017-09-06 15:27:59 +08:00
static int si_dpm_pre_set_power_state ( void * handle )
2016-08-01 12:42:32 -04:00
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-08-01 12:42:32 -04:00
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct amdgpu_ps requested_ps = * adev - > pm . dpm . requested_ps ;
struct amdgpu_ps * new_ps = & requested_ps ;
ni_update_requested_ps ( adev , new_ps ) ;
si_apply_state_adjust_rules ( adev , & eg_pi - > requested_rps ) ;
return 0 ;
}
static int si_power_control_set_level ( struct amdgpu_device * adev )
{
struct amdgpu_ps * new_ps = adev - > pm . dpm . requested_ps ;
int ret ;
ret = si_restrict_performance_levels_before_switch ( adev ) ;
if ( ret )
return ret ;
ret = si_halt_smc ( adev ) ;
if ( ret )
return ret ;
ret = si_populate_smc_tdp_limits ( adev , new_ps ) ;
if ( ret )
return ret ;
ret = si_populate_smc_tdp_limits_2 ( adev , new_ps ) ;
if ( ret )
return ret ;
ret = si_resume_smc ( adev ) ;
if ( ret )
return ret ;
ret = si_set_sw_state ( adev ) ;
if ( ret )
return ret ;
return 0 ;
}
2017-09-06 15:27:59 +08:00
static int si_dpm_set_power_state ( void * handle )
2016-08-01 12:42:32 -04:00
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-08-01 12:42:32 -04:00
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct amdgpu_ps * new_ps = & eg_pi - > requested_rps ;
struct amdgpu_ps * old_ps = & eg_pi - > current_rps ;
int ret ;
ret = si_disable_ulv ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_disable_ulv failed \n " ) ;
return ret ;
}
ret = si_restrict_performance_levels_before_switch ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_restrict_performance_levels_before_switch failed \n " ) ;
return ret ;
}
if ( eg_pi - > pcie_performance_request )
si_request_link_speed_change_before_state_change ( adev , new_ps , old_ps ) ;
ni_set_uvd_clock_before_set_eng_clock ( adev , new_ps , old_ps ) ;
ret = si_enable_power_containment ( adev , new_ps , false ) ;
if ( ret ) {
DRM_ERROR ( " si_enable_power_containment failed \n " ) ;
return ret ;
}
ret = si_enable_smc_cac ( adev , new_ps , false ) ;
if ( ret ) {
DRM_ERROR ( " si_enable_smc_cac failed \n " ) ;
return ret ;
}
ret = si_halt_smc ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_halt_smc failed \n " ) ;
return ret ;
}
ret = si_upload_sw_state ( adev , new_ps ) ;
if ( ret ) {
DRM_ERROR ( " si_upload_sw_state failed \n " ) ;
return ret ;
}
ret = si_upload_smc_data ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_upload_smc_data failed \n " ) ;
return ret ;
}
ret = si_upload_ulv_state ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_upload_ulv_state failed \n " ) ;
return ret ;
}
if ( eg_pi - > dynamic_ac_timing ) {
ret = si_upload_mc_reg_table ( adev , new_ps ) ;
if ( ret ) {
DRM_ERROR ( " si_upload_mc_reg_table failed \n " ) ;
return ret ;
}
}
ret = si_program_memory_timing_parameters ( adev , new_ps ) ;
if ( ret ) {
DRM_ERROR ( " si_program_memory_timing_parameters failed \n " ) ;
return ret ;
}
si_set_pcie_lane_width_in_smc ( adev , new_ps , old_ps ) ;
ret = si_resume_smc ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_resume_smc failed \n " ) ;
return ret ;
}
ret = si_set_sw_state ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_set_sw_state failed \n " ) ;
return ret ;
}
ni_set_uvd_clock_after_set_eng_clock ( adev , new_ps , old_ps ) ;
if ( eg_pi - > pcie_performance_request )
si_notify_link_speed_change_after_state_change ( adev , new_ps , old_ps ) ;
ret = si_set_power_state_conditionally_enable_ulv ( adev , new_ps ) ;
if ( ret ) {
DRM_ERROR ( " si_set_power_state_conditionally_enable_ulv failed \n " ) ;
return ret ;
}
ret = si_enable_smc_cac ( adev , new_ps , true ) ;
if ( ret ) {
DRM_ERROR ( " si_enable_smc_cac failed \n " ) ;
return ret ;
}
ret = si_enable_power_containment ( adev , new_ps , true ) ;
if ( ret ) {
DRM_ERROR ( " si_enable_power_containment failed \n " ) ;
return ret ;
}
ret = si_power_control_set_level ( adev ) ;
if ( ret ) {
DRM_ERROR ( " si_power_control_set_level failed \n " ) ;
return ret ;
}
return 0 ;
}
2017-09-06 15:27:59 +08:00
static void si_dpm_post_set_power_state ( void * handle )
2016-08-01 12:42:32 -04:00
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-08-01 12:42:32 -04:00
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct amdgpu_ps * new_ps = & eg_pi - > requested_rps ;
ni_update_current_ps ( adev , new_ps ) ;
}
#if 0
void si_dpm_reset_asic ( struct amdgpu_device * adev )
{
si_restrict_performance_levels_before_switch ( adev ) ;
si_disable_ulv ( adev ) ;
si_set_boot_state ( adev ) ;
}
# endif
2017-09-06 15:27:59 +08:00
static void si_dpm_display_configuration_changed ( void * handle )
2016-08-01 12:42:32 -04:00
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-08-01 12:42:32 -04:00
si_program_display_gap ( adev ) ;
}
static void si_parse_pplib_non_clock_info ( struct amdgpu_device * adev ,
struct amdgpu_ps * rps ,
struct _ATOM_PPLIB_NONCLOCK_INFO * non_clock_info ,
u8 table_rev )
{
rps - > caps = le32_to_cpu ( non_clock_info - > ulCapsAndSettings ) ;
rps - > class = le16_to_cpu ( non_clock_info - > usClassification ) ;
rps - > class2 = le16_to_cpu ( non_clock_info - > usClassification2 ) ;
if ( ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev ) {
rps - > vclk = le32_to_cpu ( non_clock_info - > ulVCLK ) ;
rps - > dclk = le32_to_cpu ( non_clock_info - > ulDCLK ) ;
} else if ( r600_is_uvd_state ( rps - > class , rps - > class2 ) ) {
rps - > vclk = RV770_DEFAULT_VCLK_FREQ ;
rps - > dclk = RV770_DEFAULT_DCLK_FREQ ;
} else {
rps - > vclk = 0 ;
rps - > dclk = 0 ;
}
if ( rps - > class & ATOM_PPLIB_CLASSIFICATION_BOOT )
adev - > pm . dpm . boot_ps = rps ;
if ( rps - > class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE )
adev - > pm . dpm . uvd_ps = rps ;
}
static void si_parse_pplib_clock_info ( struct amdgpu_device * adev ,
struct amdgpu_ps * rps , int index ,
union pplib_clock_info * clock_info )
{
struct rv7xx_power_info * pi = rv770_get_pi ( adev ) ;
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct si_power_info * si_pi = si_get_pi ( adev ) ;
struct si_ps * ps = si_get_ps ( rps ) ;
u16 leakage_voltage ;
struct rv7xx_pl * pl = & ps - > performance_levels [ index ] ;
int ret ;
ps - > performance_level_count = index + 1 ;
pl - > sclk = le16_to_cpu ( clock_info - > si . usEngineClockLow ) ;
pl - > sclk | = clock_info - > si . ucEngineClockHigh < < 16 ;
pl - > mclk = le16_to_cpu ( clock_info - > si . usMemoryClockLow ) ;
pl - > mclk | = clock_info - > si . ucMemoryClockHigh < < 16 ;
pl - > vddc = le16_to_cpu ( clock_info - > si . usVDDC ) ;
pl - > vddci = le16_to_cpu ( clock_info - > si . usVDDCI ) ;
pl - > flags = le32_to_cpu ( clock_info - > si . ulFlags ) ;
pl - > pcie_gen = r600_get_pcie_gen_support ( adev ,
si_pi - > sys_pcie_mask ,
si_pi - > boot_pcie_gen ,
clock_info - > si . ucPCIEGen ) ;
/* patch up vddc if necessary */
ret = si_get_leakage_voltage_from_leakage_index ( adev , pl - > vddc ,
& leakage_voltage ) ;
if ( ret = = 0 )
pl - > vddc = leakage_voltage ;
if ( rps - > class & ATOM_PPLIB_CLASSIFICATION_ACPI ) {
pi - > acpi_vddc = pl - > vddc ;
eg_pi - > acpi_vddci = pl - > vddci ;
si_pi - > acpi_pcie_gen = pl - > pcie_gen ;
}
if ( ( rps - > class2 & ATOM_PPLIB_CLASSIFICATION2_ULV ) & &
index = = 0 ) {
/* XXX disable for A0 tahiti */
si_pi - > ulv . supported = false ;
si_pi - > ulv . pl = * pl ;
si_pi - > ulv . one_pcie_lane_in_ulv = false ;
si_pi - > ulv . volt_change_delay = SISLANDS_ULVVOLTAGECHANGEDELAY_DFLT ;
si_pi - > ulv . cg_ulv_parameter = SISLANDS_CGULVPARAMETER_DFLT ;
si_pi - > ulv . cg_ulv_control = SISLANDS_CGULVCONTROL_DFLT ;
}
if ( pi - > min_vddc_in_table > pl - > vddc )
pi - > min_vddc_in_table = pl - > vddc ;
if ( pi - > max_vddc_in_table < pl - > vddc )
pi - > max_vddc_in_table = pl - > vddc ;
/* patch up boot state */
if ( rps - > class & ATOM_PPLIB_CLASSIFICATION_BOOT ) {
u16 vddc , vddci , mvdd ;
amdgpu_atombios_get_default_voltages ( adev , & vddc , & vddci , & mvdd ) ;
pl - > mclk = adev - > clock . default_mclk ;
pl - > sclk = adev - > clock . default_sclk ;
pl - > vddc = vddc ;
pl - > vddci = vddci ;
si_pi - > mvdd_bootup_value = mvdd ;
}
if ( ( rps - > class & ATOM_PPLIB_CLASSIFICATION_UI_MASK ) = =
ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE ) {
adev - > pm . dpm . dyn_state . max_clock_voltage_on_ac . sclk = pl - > sclk ;
adev - > pm . dpm . dyn_state . max_clock_voltage_on_ac . mclk = pl - > mclk ;
adev - > pm . dpm . dyn_state . max_clock_voltage_on_ac . vddc = pl - > vddc ;
adev - > pm . dpm . dyn_state . max_clock_voltage_on_ac . vddci = pl - > vddci ;
}
}
union pplib_power_state {
2016-09-06 09:45:43 -04:00
struct _ATOM_PPLIB_STATE v1 ;
struct _ATOM_PPLIB_STATE_V2 v2 ;
2016-08-01 12:42:32 -04:00
} ;
static int si_parse_power_table ( struct amdgpu_device * adev )
{
struct amdgpu_mode_info * mode_info = & adev - > mode_info ;
struct _ATOM_PPLIB_NONCLOCK_INFO * non_clock_info ;
union pplib_power_state * power_state ;
int i , j , k , non_clock_array_index , clock_array_index ;
union pplib_clock_info * clock_info ;
struct _StateArray * state_array ;
struct _ClockInfoArray * clock_info_array ;
struct _NonClockInfoArray * non_clock_info_array ;
union power_info * power_info ;
int index = GetIndexIntoMasterTable ( DATA , PowerPlayInfo ) ;
2016-09-06 09:45:43 -04:00
u16 data_offset ;
2016-08-01 12:42:32 -04:00
u8 frev , crev ;
u8 * power_state_offset ;
struct si_ps * ps ;
if ( ! amdgpu_atom_parse_data_header ( mode_info - > atom_context , index , NULL ,
& frev , & crev , & data_offset ) )
return - EINVAL ;
power_info = ( union power_info * ) ( mode_info - > atom_context - > bios + data_offset ) ;
amdgpu_add_thermal_controller ( adev ) ;
state_array = ( struct _StateArray * )
( mode_info - > atom_context - > bios + data_offset +
le16_to_cpu ( power_info - > pplib . usStateArrayOffset ) ) ;
clock_info_array = ( struct _ClockInfoArray * )
( mode_info - > atom_context - > bios + data_offset +
le16_to_cpu ( power_info - > pplib . usClockInfoArrayOffset ) ) ;
non_clock_info_array = ( struct _NonClockInfoArray * )
( mode_info - > atom_context - > bios + data_offset +
le16_to_cpu ( power_info - > pplib . usNonClockInfoArrayOffset ) ) ;
adev - > pm . dpm . ps = kzalloc ( sizeof ( struct amdgpu_ps ) *
state_array - > ucNumEntries , GFP_KERNEL ) ;
if ( ! adev - > pm . dpm . ps )
return - ENOMEM ;
power_state_offset = ( u8 * ) state_array - > states ;
for ( i = 0 ; i < state_array - > ucNumEntries ; i + + ) {
u8 * idx ;
power_state = ( union pplib_power_state * ) power_state_offset ;
non_clock_array_index = power_state - > v2 . nonClockInfoIndex ;
non_clock_info = ( struct _ATOM_PPLIB_NONCLOCK_INFO * )
& non_clock_info_array - > nonClockInfo [ non_clock_array_index ] ;
ps = kzalloc ( sizeof ( struct si_ps ) , GFP_KERNEL ) ;
if ( ps = = NULL ) {
kfree ( adev - > pm . dpm . ps ) ;
return - ENOMEM ;
}
adev - > pm . dpm . ps [ i ] . ps_priv = ps ;
si_parse_pplib_non_clock_info ( adev , & adev - > pm . dpm . ps [ i ] ,
non_clock_info ,
non_clock_info_array - > ucEntrySize ) ;
k = 0 ;
idx = ( u8 * ) & power_state - > v2 . clockInfoIndex [ 0 ] ;
for ( j = 0 ; j < power_state - > v2 . ucNumDPMLevels ; j + + ) {
clock_array_index = idx [ j ] ;
if ( clock_array_index > = clock_info_array - > ucNumEntries )
continue ;
if ( k > = SISLANDS_MAX_HARDWARE_POWERLEVELS )
break ;
clock_info = ( union pplib_clock_info * )
( ( u8 * ) & clock_info_array - > clockInfo [ 0 ] +
( clock_array_index * clock_info_array - > ucEntrySize ) ) ;
si_parse_pplib_clock_info ( adev ,
& adev - > pm . dpm . ps [ i ] , k ,
clock_info ) ;
k + + ;
}
power_state_offset + = 2 + power_state - > v2 . ucNumDPMLevels ;
}
adev - > pm . dpm . num_ps = state_array - > ucNumEntries ;
/* fill in the vce power states */
2016-10-12 15:38:56 +08:00
for ( i = 0 ; i < adev - > pm . dpm . num_of_vce_states ; i + + ) {
2016-08-01 12:42:32 -04:00
u32 sclk , mclk ;
clock_array_index = adev - > pm . dpm . vce_states [ i ] . clk_idx ;
clock_info = ( union pplib_clock_info * )
& clock_info_array - > clockInfo [ clock_array_index * clock_info_array - > ucEntrySize ] ;
sclk = le16_to_cpu ( clock_info - > si . usEngineClockLow ) ;
sclk | = clock_info - > si . ucEngineClockHigh < < 16 ;
mclk = le16_to_cpu ( clock_info - > si . usMemoryClockLow ) ;
mclk | = clock_info - > si . ucMemoryClockHigh < < 16 ;
adev - > pm . dpm . vce_states [ i ] . sclk = sclk ;
adev - > pm . dpm . vce_states [ i ] . mclk = mclk ;
}
return 0 ;
}
static int si_dpm_init ( struct amdgpu_device * adev )
{
struct rv7xx_power_info * pi ;
struct evergreen_power_info * eg_pi ;
struct ni_power_info * ni_pi ;
struct si_power_info * si_pi ;
struct atom_clock_dividers dividers ;
int ret ;
u32 mask ;
si_pi = kzalloc ( sizeof ( struct si_power_info ) , GFP_KERNEL ) ;
if ( si_pi = = NULL )
return - ENOMEM ;
adev - > pm . dpm . priv = si_pi ;
ni_pi = & si_pi - > ni ;
eg_pi = & ni_pi - > eg ;
pi = & eg_pi - > rv7xx ;
ret = drm_pcie_get_speed_cap_mask ( adev - > ddev , & mask ) ;
if ( ret )
si_pi - > sys_pcie_mask = 0 ;
else
si_pi - > sys_pcie_mask = mask ;
si_pi - > force_pcie_gen = AMDGPU_PCIE_GEN_INVALID ;
si_pi - > boot_pcie_gen = si_get_current_pcie_speed ( adev ) ;
si_set_max_cu_value ( adev ) ;
rv770_get_max_vddc ( adev ) ;
si_get_leakage_vddc ( adev ) ;
si_patch_dependency_tables_based_on_leakage ( adev ) ;
pi - > acpi_vddc = 0 ;
eg_pi - > acpi_vddci = 0 ;
pi - > min_vddc_in_table = 0 ;
pi - > max_vddc_in_table = 0 ;
ret = amdgpu_get_platform_caps ( adev ) ;
if ( ret )
return ret ;
ret = amdgpu_parse_extended_power_table ( adev ) ;
if ( ret )
return ret ;
ret = si_parse_power_table ( adev ) ;
if ( ret )
return ret ;
adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries =
kzalloc ( 4 * sizeof ( struct amdgpu_clock_voltage_dependency_entry ) , GFP_KERNEL ) ;
if ( ! adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries ) {
amdgpu_free_extended_power_table ( adev ) ;
return - ENOMEM ;
}
adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . count = 4 ;
adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries [ 0 ] . clk = 0 ;
adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries [ 0 ] . v = 0 ;
adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries [ 1 ] . clk = 36000 ;
adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries [ 1 ] . v = 720 ;
adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries [ 2 ] . clk = 54000 ;
adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries [ 2 ] . v = 810 ;
adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries [ 3 ] . clk = 72000 ;
adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries [ 3 ] . v = 900 ;
if ( adev - > pm . dpm . voltage_response_time = = 0 )
adev - > pm . dpm . voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT ;
if ( adev - > pm . dpm . backbias_response_time = = 0 )
adev - > pm . dpm . backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT ;
ret = amdgpu_atombios_get_clock_dividers ( adev , COMPUTE_ENGINE_PLL_PARAM ,
0 , false , & dividers ) ;
if ( ret )
pi - > ref_div = dividers . ref_div + 1 ;
else
pi - > ref_div = R600_REFERENCEDIVIDER_DFLT ;
eg_pi - > smu_uvd_hs = false ;
pi - > mclk_strobe_mode_threshold = 40000 ;
if ( si_is_special_1gb_platform ( adev ) )
pi - > mclk_stutter_mode_threshold = 0 ;
else
pi - > mclk_stutter_mode_threshold = pi - > mclk_strobe_mode_threshold ;
pi - > mclk_edc_enable_threshold = 40000 ;
eg_pi - > mclk_edc_wr_enable_threshold = 40000 ;
ni_pi - > mclk_rtt_mode_threshold = eg_pi - > mclk_edc_wr_enable_threshold ;
pi - > voltage_control =
amdgpu_atombios_is_voltage_gpio ( adev , SET_VOLTAGE_TYPE_ASIC_VDDC ,
VOLTAGE_OBJ_GPIO_LUT ) ;
if ( ! pi - > voltage_control ) {
si_pi - > voltage_control_svi2 =
amdgpu_atombios_is_voltage_gpio ( adev , SET_VOLTAGE_TYPE_ASIC_VDDC ,
VOLTAGE_OBJ_SVID2 ) ;
if ( si_pi - > voltage_control_svi2 )
amdgpu_atombios_get_svi2_info ( adev , SET_VOLTAGE_TYPE_ASIC_VDDC ,
& si_pi - > svd_gpio_id , & si_pi - > svc_gpio_id ) ;
}
pi - > mvdd_control =
amdgpu_atombios_is_voltage_gpio ( adev , SET_VOLTAGE_TYPE_ASIC_MVDDC ,
VOLTAGE_OBJ_GPIO_LUT ) ;
eg_pi - > vddci_control =
amdgpu_atombios_is_voltage_gpio ( adev , SET_VOLTAGE_TYPE_ASIC_VDDCI ,
VOLTAGE_OBJ_GPIO_LUT ) ;
if ( ! eg_pi - > vddci_control )
si_pi - > vddci_control_svi2 =
amdgpu_atombios_is_voltage_gpio ( adev , SET_VOLTAGE_TYPE_ASIC_VDDCI ,
VOLTAGE_OBJ_SVID2 ) ;
si_pi - > vddc_phase_shed_control =
amdgpu_atombios_is_voltage_gpio ( adev , SET_VOLTAGE_TYPE_ASIC_VDDC ,
VOLTAGE_OBJ_PHASE_LUT ) ;
rv770_get_engine_memory_ss ( adev ) ;
pi - > asi = RV770_ASI_DFLT ;
pi - > pasi = CYPRESS_HASI_DFLT ;
pi - > vrc = SISLANDS_VRC_DFLT ;
pi - > gfx_clock_gating = true ;
eg_pi - > sclk_deep_sleep = true ;
si_pi - > sclk_deep_sleep_above_low = false ;
if ( adev - > pm . int_thermal_type ! = THERMAL_TYPE_NONE )
pi - > thermal_protection = true ;
else
pi - > thermal_protection = false ;
eg_pi - > dynamic_ac_timing = true ;
eg_pi - > light_sleep = true ;
# if defined(CONFIG_ACPI)
eg_pi - > pcie_performance_request =
amdgpu_acpi_is_pcie_performance_request_supported ( adev ) ;
# else
eg_pi - > pcie_performance_request = false ;
# endif
si_pi - > sram_end = SMC_RAM_END ;
adev - > pm . dpm . dyn_state . mclk_sclk_ratio = 4 ;
adev - > pm . dpm . dyn_state . sclk_mclk_delta = 15000 ;
adev - > pm . dpm . dyn_state . vddc_vddci_delta = 200 ;
adev - > pm . dpm . dyn_state . valid_sclk_values . count = 0 ;
adev - > pm . dpm . dyn_state . valid_sclk_values . values = NULL ;
adev - > pm . dpm . dyn_state . valid_mclk_values . count = 0 ;
adev - > pm . dpm . dyn_state . valid_mclk_values . values = NULL ;
si_initialize_powertune_defaults ( adev ) ;
/* make sure dc limits are valid */
if ( ( adev - > pm . dpm . dyn_state . max_clock_voltage_on_dc . sclk = = 0 ) | |
( adev - > pm . dpm . dyn_state . max_clock_voltage_on_dc . mclk = = 0 ) )
adev - > pm . dpm . dyn_state . max_clock_voltage_on_dc =
adev - > pm . dpm . dyn_state . max_clock_voltage_on_ac ;
si_pi - > fan_ctrl_is_in_default_mode = true ;
return 0 ;
}
static void si_dpm_fini ( struct amdgpu_device * adev )
{
int i ;
2016-09-06 09:42:55 -04:00
if ( adev - > pm . dpm . ps )
for ( i = 0 ; i < adev - > pm . dpm . num_ps ; i + + )
kfree ( adev - > pm . dpm . ps [ i ] . ps_priv ) ;
2016-08-01 12:42:32 -04:00
kfree ( adev - > pm . dpm . ps ) ;
kfree ( adev - > pm . dpm . priv ) ;
kfree ( adev - > pm . dpm . dyn_state . vddc_dependency_on_dispclk . entries ) ;
amdgpu_free_extended_power_table ( adev ) ;
}
2017-09-06 15:27:59 +08:00
static void si_dpm_debugfs_print_current_performance_level ( void * handle ,
2016-08-01 12:42:32 -04:00
struct seq_file * m )
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-08-01 12:42:32 -04:00
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct amdgpu_ps * rps = & eg_pi - > current_rps ;
struct si_ps * ps = si_get_ps ( rps ) ;
struct rv7xx_pl * pl ;
u32 current_index =
( RREG32 ( TARGET_AND_CURRENT_PROFILE_INDEX ) & CURRENT_STATE_INDEX_MASK ) > >
CURRENT_STATE_INDEX_SHIFT ;
if ( current_index > = ps - > performance_level_count ) {
seq_printf ( m , " invalid dpm profile %d \n " , current_index ) ;
} else {
pl = & ps - > performance_levels [ current_index ] ;
seq_printf ( m , " uvd vclk: %d dclk: %d \n " , rps - > vclk , rps - > dclk ) ;
seq_printf ( m , " power level %d sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u \n " ,
current_index , pl - > sclk , pl - > mclk , pl - > vddc , pl - > vddci , pl - > pcie_gen + 1 ) ;
}
}
static int si_dpm_set_interrupt_state ( struct amdgpu_device * adev ,
struct amdgpu_irq_src * source ,
unsigned type ,
enum amdgpu_interrupt_state state )
{
u32 cg_thermal_int ;
switch ( type ) {
case AMDGPU_THERMAL_IRQ_LOW_TO_HIGH :
switch ( state ) {
case AMDGPU_IRQ_STATE_DISABLE :
cg_thermal_int = RREG32_SMC ( CG_THERMAL_INT ) ;
cg_thermal_int | = THERM_INT_MASK_HIGH ;
WREG32_SMC ( CG_THERMAL_INT , cg_thermal_int ) ;
break ;
case AMDGPU_IRQ_STATE_ENABLE :
cg_thermal_int = RREG32_SMC ( CG_THERMAL_INT ) ;
cg_thermal_int & = ~ THERM_INT_MASK_HIGH ;
WREG32_SMC ( CG_THERMAL_INT , cg_thermal_int ) ;
break ;
default :
break ;
}
break ;
case AMDGPU_THERMAL_IRQ_HIGH_TO_LOW :
switch ( state ) {
case AMDGPU_IRQ_STATE_DISABLE :
cg_thermal_int = RREG32_SMC ( CG_THERMAL_INT ) ;
cg_thermal_int | = THERM_INT_MASK_LOW ;
WREG32_SMC ( CG_THERMAL_INT , cg_thermal_int ) ;
break ;
case AMDGPU_IRQ_STATE_ENABLE :
cg_thermal_int = RREG32_SMC ( CG_THERMAL_INT ) ;
cg_thermal_int & = ~ THERM_INT_MASK_LOW ;
WREG32_SMC ( CG_THERMAL_INT , cg_thermal_int ) ;
break ;
default :
break ;
}
break ;
default :
break ;
}
return 0 ;
}
static int si_dpm_process_interrupt ( struct amdgpu_device * adev ,
2016-09-12 23:46:06 -04:00
struct amdgpu_irq_src * source ,
2016-08-01 12:42:32 -04:00
struct amdgpu_iv_entry * entry )
{
bool queue_thermal = false ;
if ( entry = = NULL )
return - EINVAL ;
switch ( entry - > src_id ) {
case 230 : /* thermal low to high */
DRM_DEBUG ( " IH: thermal low to high \n " ) ;
adev - > pm . dpm . thermal . high_to_low = false ;
queue_thermal = true ;
break ;
case 231 : /* thermal high to low */
DRM_DEBUG ( " IH: thermal high to low \n " ) ;
adev - > pm . dpm . thermal . high_to_low = true ;
queue_thermal = true ;
break ;
default :
break ;
}
if ( queue_thermal )
schedule_work ( & adev - > pm . dpm . thermal . work ) ;
return 0 ;
}
static int si_dpm_late_init ( void * handle )
{
int ret ;
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
if ( ! amdgpu_dpm )
return 0 ;
ret = si_set_temperature_range ( adev ) ;
if ( ret )
return ret ;
#if 0 //TODO ?
si_dpm_powergate_uvd ( adev , true ) ;
# endif
return 0 ;
}
/**
* si_dpm_init_microcode - load ucode images from disk
*
* @ adev : amdgpu_device pointer
*
* Use the firmware interface to load the ucode images into
* the driver ( not loaded into hw ) .
* Returns 0 on success , error on failure .
*/
static int si_dpm_init_microcode ( struct amdgpu_device * adev )
{
const char * chip_name ;
char fw_name [ 30 ] ;
int err ;
DRM_DEBUG ( " \n " ) ;
switch ( adev - > asic_type ) {
case CHIP_TAHITI :
chip_name = " tahiti " ;
break ;
case CHIP_PITCAIRN :
2016-12-15 13:43:59 +08:00
if ( ( adev - > pdev - > revision = = 0x81 ) & &
( ( adev - > pdev - > device = = 0x6810 ) | |
( adev - > pdev - > device = = 0x6811 ) ) )
2016-08-01 16:05:47 -04:00
chip_name = " pitcairn_k " ;
else
chip_name = " pitcairn " ;
2016-08-01 12:42:32 -04:00
break ;
case CHIP_VERDE :
2016-12-15 13:43:59 +08:00
if ( ( ( adev - > pdev - > device = = 0x6820 ) & &
( ( adev - > pdev - > revision = = 0x81 ) | |
( adev - > pdev - > revision = = 0x83 ) ) ) | |
( ( adev - > pdev - > device = = 0x6821 ) & &
( ( adev - > pdev - > revision = = 0x83 ) | |
( adev - > pdev - > revision = = 0x87 ) ) ) | |
( ( adev - > pdev - > revision = = 0x87 ) & &
( ( adev - > pdev - > device = = 0x6823 ) | |
( adev - > pdev - > device = = 0x682b ) ) ) )
2016-08-01 16:05:47 -04:00
chip_name = " verde_k " ;
else
chip_name = " verde " ;
2016-08-01 12:42:32 -04:00
break ;
case CHIP_OLAND :
2016-12-15 13:43:59 +08:00
if ( ( ( adev - > pdev - > revision = = 0x81 ) & &
( ( adev - > pdev - > device = = 0x6600 ) | |
( adev - > pdev - > device = = 0x6604 ) | |
( adev - > pdev - > device = = 0x6605 ) | |
( adev - > pdev - > device = = 0x6610 ) ) ) | |
( ( adev - > pdev - > revision = = 0x83 ) & &
( adev - > pdev - > device = = 0x6610 ) ) )
2016-08-01 16:05:47 -04:00
chip_name = " oland_k " ;
else
chip_name = " oland " ;
2016-08-01 12:42:32 -04:00
break ;
case CHIP_HAINAN :
2016-12-15 13:43:59 +08:00
if ( ( ( adev - > pdev - > revision = = 0x81 ) & &
( adev - > pdev - > device = = 0x6660 ) ) | |
( ( adev - > pdev - > revision = = 0x83 ) & &
( ( adev - > pdev - > device = = 0x6660 ) | |
( adev - > pdev - > device = = 0x6663 ) | |
( adev - > pdev - > device = = 0x6665 ) | |
2017-01-17 15:06:58 -05:00
( adev - > pdev - > device = = 0x6667 ) ) ) )
2016-08-01 16:05:47 -04:00
chip_name = " hainan_k " ;
2017-01-17 15:06:58 -05:00
else if ( ( adev - > pdev - > revision = = 0xc3 ) & &
( adev - > pdev - > device = = 0x6665 ) )
chip_name = " banks_k_2 " ;
2016-08-01 16:05:47 -04:00
else
chip_name = " hainan " ;
2016-08-01 12:42:32 -04:00
break ;
default : BUG ( ) ;
}
snprintf ( fw_name , sizeof ( fw_name ) , " radeon/%s_smc.bin " , chip_name ) ;
err = request_firmware ( & adev - > pm . fw , fw_name , adev - > dev ) ;
if ( err )
goto out ;
err = amdgpu_ucode_validate ( adev - > pm . fw ) ;
out :
if ( err ) {
2016-08-31 13:23:18 +08:00
DRM_ERROR ( " si_smc: Failed to load firmware. err = %d \" %s \" \n " ,
err , fw_name ) ;
2016-08-01 12:42:32 -04:00
release_firmware ( adev - > pm . fw ) ;
adev - > pm . fw = NULL ;
}
return err ;
}
static int si_dpm_sw_init ( void * handle )
{
int ret ;
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-03-29 18:28:50 -04:00
ret = amdgpu_irq_add_id ( adev , AMDGPU_IH_CLIENTID_LEGACY , 230 , & adev - > pm . dpm . thermal . irq ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
2016-03-29 18:28:50 -04:00
ret = amdgpu_irq_add_id ( adev , AMDGPU_IH_CLIENTID_LEGACY , 231 , & adev - > pm . dpm . thermal . irq ) ;
2016-08-01 12:42:32 -04:00
if ( ret )
return ret ;
/* default to balanced state */
adev - > pm . dpm . state = POWER_STATE_TYPE_BALANCED ;
adev - > pm . dpm . user_state = POWER_STATE_TYPE_BALANCED ;
2016-12-23 14:39:41 +08:00
adev - > pm . dpm . forced_level = AMD_DPM_FORCED_LEVEL_AUTO ;
2016-08-01 12:42:32 -04:00
adev - > pm . default_sclk = adev - > clock . default_sclk ;
adev - > pm . default_mclk = adev - > clock . default_mclk ;
adev - > pm . current_sclk = adev - > clock . default_sclk ;
adev - > pm . current_mclk = adev - > clock . default_mclk ;
adev - > pm . int_thermal_type = THERMAL_TYPE_NONE ;
if ( amdgpu_dpm = = 0 )
return 0 ;
ret = si_dpm_init_microcode ( adev ) ;
if ( ret )
return ret ;
INIT_WORK ( & adev - > pm . dpm . thermal . work , amdgpu_dpm_thermal_work_handler ) ;
mutex_lock ( & adev - > pm . mutex ) ;
ret = si_dpm_init ( adev ) ;
if ( ret )
goto dpm_failed ;
adev - > pm . dpm . current_ps = adev - > pm . dpm . requested_ps = adev - > pm . dpm . boot_ps ;
if ( amdgpu_dpm = = 1 )
amdgpu_pm_print_power_states ( adev ) ;
mutex_unlock ( & adev - > pm . mutex ) ;
DRM_INFO ( " amdgpu: dpm initialized \n " ) ;
return 0 ;
dpm_failed :
si_dpm_fini ( adev ) ;
mutex_unlock ( & adev - > pm . mutex ) ;
DRM_ERROR ( " amdgpu: dpm initialization failed \n " ) ;
return ret ;
}
static int si_dpm_sw_fini ( void * handle )
{
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-10-21 16:30:10 -04:00
flush_work ( & adev - > pm . dpm . thermal . work ) ;
2016-08-01 12:42:32 -04:00
mutex_lock ( & adev - > pm . mutex ) ;
si_dpm_fini ( adev ) ;
mutex_unlock ( & adev - > pm . mutex ) ;
return 0 ;
}
static int si_dpm_hw_init ( void * handle )
{
int ret ;
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
if ( ! amdgpu_dpm )
return 0 ;
mutex_lock ( & adev - > pm . mutex ) ;
si_dpm_setup_asic ( adev ) ;
ret = si_dpm_enable ( adev ) ;
if ( ret )
adev - > pm . dpm_enabled = false ;
else
adev - > pm . dpm_enabled = true ;
mutex_unlock ( & adev - > pm . mutex ) ;
return ret ;
}
static int si_dpm_hw_fini ( void * handle )
{
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
if ( adev - > pm . dpm_enabled ) {
mutex_lock ( & adev - > pm . mutex ) ;
si_dpm_disable ( adev ) ;
mutex_unlock ( & adev - > pm . mutex ) ;
}
return 0 ;
}
static int si_dpm_suspend ( void * handle )
{
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
if ( adev - > pm . dpm_enabled ) {
mutex_lock ( & adev - > pm . mutex ) ;
/* disable dpm */
si_dpm_disable ( adev ) ;
/* reset the power state */
adev - > pm . dpm . current_ps = adev - > pm . dpm . requested_ps = adev - > pm . dpm . boot_ps ;
mutex_unlock ( & adev - > pm . mutex ) ;
}
return 0 ;
}
static int si_dpm_resume ( void * handle )
{
int ret ;
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
if ( adev - > pm . dpm_enabled ) {
/* asic init will reset to the boot state */
mutex_lock ( & adev - > pm . mutex ) ;
si_dpm_setup_asic ( adev ) ;
ret = si_dpm_enable ( adev ) ;
if ( ret )
adev - > pm . dpm_enabled = false ;
else
adev - > pm . dpm_enabled = true ;
mutex_unlock ( & adev - > pm . mutex ) ;
if ( adev - > pm . dpm_enabled )
amdgpu_pm_compute_clocks ( adev ) ;
}
return 0 ;
}
static bool si_dpm_is_idle ( void * handle )
{
/* XXX */
return true ;
}
static int si_dpm_wait_for_idle ( void * handle )
{
/* XXX */
return 0 ;
}
static int si_dpm_soft_reset ( void * handle )
{
return 0 ;
}
static int si_dpm_set_clockgating_state ( void * handle ,
enum amd_clockgating_state state )
{
return 0 ;
}
static int si_dpm_set_powergating_state ( void * handle ,
enum amd_powergating_state state )
{
return 0 ;
}
/* get temperature in millidegrees */
2017-09-06 15:27:59 +08:00
static int si_dpm_get_temp ( void * handle )
2016-08-01 12:42:32 -04:00
{
u32 temp ;
int actual_temp = 0 ;
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-08-01 12:42:32 -04:00
temp = ( RREG32 ( CG_MULT_THERMAL_STATUS ) & CTF_TEMP_MASK ) > >
CTF_TEMP_SHIFT ;
if ( temp & 0x200 )
actual_temp = 255 ;
else
actual_temp = temp & 0x1ff ;
actual_temp = ( actual_temp * 1000 ) ;
return actual_temp ;
}
2017-09-06 15:27:59 +08:00
static u32 si_dpm_get_sclk ( void * handle , bool low )
2016-08-01 12:42:32 -04:00
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-09-06 09:45:43 -04:00
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct si_ps * requested_state = si_get_ps ( & eg_pi - > requested_rps ) ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
if ( low )
return requested_state - > performance_levels [ 0 ] . sclk ;
else
return requested_state - > performance_levels [ requested_state - > performance_level_count - 1 ] . sclk ;
2016-08-01 12:42:32 -04:00
}
2017-09-06 15:27:59 +08:00
static u32 si_dpm_get_mclk ( void * handle , bool low )
2016-08-01 12:42:32 -04:00
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-09-06 09:45:43 -04:00
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct si_ps * requested_state = si_get_ps ( & eg_pi - > requested_rps ) ;
2016-08-01 12:42:32 -04:00
2016-09-06 09:45:43 -04:00
if ( low )
return requested_state - > performance_levels [ 0 ] . mclk ;
else
return requested_state - > performance_levels [ requested_state - > performance_level_count - 1 ] . mclk ;
2016-08-01 12:42:32 -04:00
}
2017-09-06 15:27:59 +08:00
static void si_dpm_print_power_state ( void * handle ,
void * current_ps )
2016-09-06 09:45:43 -04:00
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
struct amdgpu_ps * rps = ( struct amdgpu_ps * ) current_ps ;
2016-09-06 09:45:43 -04:00
struct si_ps * ps = si_get_ps ( rps ) ;
struct rv7xx_pl * pl ;
int i ;
amdgpu_dpm_print_class_info ( rps - > class , rps - > class2 ) ;
amdgpu_dpm_print_cap_info ( rps - > caps ) ;
DRM_INFO ( " \t uvd vclk: %d dclk: %d \n " , rps - > vclk , rps - > dclk ) ;
for ( i = 0 ; i < ps - > performance_level_count ; i + + ) {
pl = & ps - > performance_levels [ i ] ;
if ( adev - > asic_type > = CHIP_TAHITI )
DRM_INFO ( " \t \t power level %d sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u \n " ,
2016-08-31 13:23:18 +08:00
i , pl - > sclk , pl - > mclk , pl - > vddc , pl - > vddci , pl - > pcie_gen + 1 ) ;
2016-09-06 09:45:43 -04:00
else
DRM_INFO ( " \t \t power level %d sclk: %u mclk: %u vddc: %u vddci: %u \n " ,
2016-08-31 13:23:18 +08:00
i , pl - > sclk , pl - > mclk , pl - > vddc , pl - > vddci ) ;
2016-09-06 09:45:43 -04:00
}
amdgpu_dpm_print_ps_status ( adev , rps ) ;
2016-08-01 12:42:32 -04:00
}
static int si_dpm_early_init ( void * handle )
{
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
si_dpm_set_irq_funcs ( adev ) ;
return 0 ;
}
2016-10-14 19:39:52 +08:00
static inline bool si_are_power_levels_equal ( const struct rv7xx_pl * si_cpl1 ,
const struct rv7xx_pl * si_cpl2 )
{
return ( ( si_cpl1 - > mclk = = si_cpl2 - > mclk ) & &
( si_cpl1 - > sclk = = si_cpl2 - > sclk ) & &
( si_cpl1 - > pcie_gen = = si_cpl2 - > pcie_gen ) & &
( si_cpl1 - > vddc = = si_cpl2 - > vddc ) & &
( si_cpl1 - > vddci = = si_cpl2 - > vddci ) ) ;
}
2017-09-06 15:27:59 +08:00
static int si_check_state_equal ( void * handle ,
void * current_ps ,
void * request_ps ,
2016-10-14 19:39:52 +08:00
bool * equal )
{
struct si_ps * si_cps ;
struct si_ps * si_rps ;
int i ;
2017-09-06 15:27:59 +08:00
struct amdgpu_ps * cps = ( struct amdgpu_ps * ) current_ps ;
struct amdgpu_ps * rps = ( struct amdgpu_ps * ) request_ps ;
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2016-10-14 19:39:52 +08:00
if ( adev = = NULL | | cps = = NULL | | rps = = NULL | | equal = = NULL )
return - EINVAL ;
2017-09-06 15:27:59 +08:00
si_cps = si_get_ps ( ( struct amdgpu_ps * ) cps ) ;
si_rps = si_get_ps ( ( struct amdgpu_ps * ) rps ) ;
2016-10-14 19:39:52 +08:00
if ( si_cps = = NULL ) {
printk ( " si_cps is NULL \n " ) ;
* equal = false ;
return 0 ;
}
if ( si_cps - > performance_level_count ! = si_rps - > performance_level_count ) {
* equal = false ;
return 0 ;
}
for ( i = 0 ; i < si_cps - > performance_level_count ; i + + ) {
if ( ! si_are_power_levels_equal ( & ( si_cps - > performance_levels [ i ] ) ,
& ( si_rps - > performance_levels [ i ] ) ) ) {
* equal = false ;
return 0 ;
}
}
/* If all performance levels are the same try to use the UVD clocks to break the tie.*/
* equal = ( ( cps - > vclk = = rps - > vclk ) & & ( cps - > dclk = = rps - > dclk ) ) ;
* equal & = ( ( cps - > evclk = = rps - > evclk ) & & ( cps - > ecclk = = rps - > ecclk ) ) ;
return 0 ;
}
2017-09-06 15:27:59 +08:00
static int si_dpm_read_sensor ( void * handle , int idx ,
2017-02-14 01:00:49 +01:00
void * value , int * size )
{
2017-09-06 15:27:59 +08:00
struct amdgpu_device * adev = ( struct amdgpu_device * ) handle ;
2017-02-14 01:00:49 +01:00
struct evergreen_power_info * eg_pi = evergreen_get_pi ( adev ) ;
struct amdgpu_ps * rps = & eg_pi - > current_rps ;
struct si_ps * ps = si_get_ps ( rps ) ;
uint32_t sclk , mclk ;
u32 pl_index =
( RREG32 ( TARGET_AND_CURRENT_PROFILE_INDEX ) & CURRENT_STATE_INDEX_MASK ) > >
CURRENT_STATE_INDEX_SHIFT ;
/* size must be at least 4 bytes for all sensors */
if ( * size < 4 )
return - EINVAL ;
switch ( idx ) {
case AMDGPU_PP_SENSOR_GFX_SCLK :
if ( pl_index < ps - > performance_level_count ) {
sclk = ps - > performance_levels [ pl_index ] . sclk ;
* ( ( uint32_t * ) value ) = sclk ;
* size = 4 ;
return 0 ;
}
return - EINVAL ;
case AMDGPU_PP_SENSOR_GFX_MCLK :
if ( pl_index < ps - > performance_level_count ) {
mclk = ps - > performance_levels [ pl_index ] . mclk ;
* ( ( uint32_t * ) value ) = mclk ;
* size = 4 ;
return 0 ;
}
return - EINVAL ;
case AMDGPU_PP_SENSOR_GPU_TEMP :
* ( ( uint32_t * ) value ) = si_dpm_get_temp ( adev ) ;
* size = 4 ;
return 0 ;
default :
return - EINVAL ;
}
}
2016-08-01 12:42:32 -04:00
const struct amd_ip_funcs si_dpm_ip_funcs = {
. name = " si_dpm " ,
. early_init = si_dpm_early_init ,
. late_init = si_dpm_late_init ,
. sw_init = si_dpm_sw_init ,
. sw_fini = si_dpm_sw_fini ,
. hw_init = si_dpm_hw_init ,
. hw_fini = si_dpm_hw_fini ,
. suspend = si_dpm_suspend ,
. resume = si_dpm_resume ,
. is_idle = si_dpm_is_idle ,
. wait_for_idle = si_dpm_wait_for_idle ,
. soft_reset = si_dpm_soft_reset ,
. set_clockgating_state = si_dpm_set_clockgating_state ,
. set_powergating_state = si_dpm_set_powergating_state ,
} ;
2017-09-06 18:43:52 +08:00
const struct amd_pm_funcs si_dpm_funcs = {
2016-08-01 12:42:32 -04:00
. get_temperature = & si_dpm_get_temp ,
. pre_set_power_state = & si_dpm_pre_set_power_state ,
. set_power_state = & si_dpm_set_power_state ,
. post_set_power_state = & si_dpm_post_set_power_state ,
. display_configuration_changed = & si_dpm_display_configuration_changed ,
. get_sclk = & si_dpm_get_sclk ,
. get_mclk = & si_dpm_get_mclk ,
. print_power_state = & si_dpm_print_power_state ,
. debugfs_print_current_performance_level = & si_dpm_debugfs_print_current_performance_level ,
. force_performance_level = & si_dpm_force_performance_level ,
. vblank_too_short = & si_dpm_vblank_too_short ,
. set_fan_control_mode = & si_dpm_set_fan_control_mode ,
. get_fan_control_mode = & si_dpm_get_fan_control_mode ,
. set_fan_speed_percent = & si_dpm_set_fan_speed_percent ,
. get_fan_speed_percent = & si_dpm_get_fan_speed_percent ,
2016-10-14 19:39:52 +08:00
. check_state_equal = & si_check_state_equal ,
2016-10-07 12:38:04 -04:00
. get_vce_clock_state = amdgpu_get_vce_clock_state ,
2017-02-14 01:00:49 +01:00
. read_sensor = & si_dpm_read_sensor ,
2016-08-01 12:42:32 -04:00
} ;
static const struct amdgpu_irq_src_funcs si_dpm_irq_funcs = {
. set = si_dpm_set_interrupt_state ,
. process = si_dpm_process_interrupt ,
} ;
static void si_dpm_set_irq_funcs ( struct amdgpu_device * adev )
{
adev - > pm . dpm . thermal . irq . num_types = AMDGPU_THERMAL_IRQ_LAST ;
adev - > pm . dpm . thermal . irq . funcs = & si_dpm_irq_funcs ;
}