linux/drivers/gpu/drm/radeon/kv_dpm.c
<<
>>
Prefs
   1/*
   2 * Copyright 2013 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 */
  23
  24#include "drmP.h"
  25#include "radeon.h"
  26#include "cikd.h"
  27#include "r600_dpm.h"
  28#include "kv_dpm.h"
  29#include "radeon_asic.h"
  30#include <linux/seq_file.h>
  31
  32#define KV_MAX_DEEPSLEEP_DIVIDER_ID     5
  33#define KV_MINIMUM_ENGINE_CLOCK         800
  34#define SMC_RAM_END                     0x40000
  35
  36static void kv_init_graphics_levels(struct radeon_device *rdev);
  37static int kv_calculate_ds_divider(struct radeon_device *rdev);
  38static int kv_calculate_nbps_level_settings(struct radeon_device *rdev);
  39static int kv_calculate_dpm_settings(struct radeon_device *rdev);
  40static void kv_enable_new_levels(struct radeon_device *rdev);
  41static void kv_program_nbps_index_settings(struct radeon_device *rdev,
  42                                           struct radeon_ps *new_rps);
  43static int kv_set_enabled_level(struct radeon_device *rdev, u32 level);
  44static int kv_set_enabled_levels(struct radeon_device *rdev);
  45static int kv_force_dpm_highest(struct radeon_device *rdev);
  46static int kv_force_dpm_lowest(struct radeon_device *rdev);
  47static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
  48                                        struct radeon_ps *new_rps,
  49                                        struct radeon_ps *old_rps);
  50static int kv_set_thermal_temperature_range(struct radeon_device *rdev,
  51                                            int min_temp, int max_temp);
  52static int kv_init_fps_limits(struct radeon_device *rdev);
  53
  54void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate);
  55static void kv_dpm_powergate_vce(struct radeon_device *rdev, bool gate);
  56static void kv_dpm_powergate_samu(struct radeon_device *rdev, bool gate);
  57static void kv_dpm_powergate_acp(struct radeon_device *rdev, bool gate);
  58
  59extern void cik_enter_rlc_safe_mode(struct radeon_device *rdev);
  60extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev);
  61extern void cik_update_cg(struct radeon_device *rdev,
  62                          u32 block, bool enable);
  63
  64static const struct kv_lcac_config_values sx_local_cac_cfg_kv[] =
  65{
  66        {  0,       4,        1    },
  67        {  1,       4,        1    },
  68        {  2,       5,        1    },
  69        {  3,       4,        2    },
  70        {  4,       1,        1    },
  71        {  5,       5,        2    },
  72        {  6,       6,        1    },
  73        {  7,       9,        2    },
  74        { 0xffffffff }
  75};
  76
  77static const struct kv_lcac_config_values mc0_local_cac_cfg_kv[] =
  78{
  79        {  0,       4,        1    },
  80        { 0xffffffff }
  81};
  82
  83static const struct kv_lcac_config_values mc1_local_cac_cfg_kv[] =
  84{
  85        {  0,       4,        1    },
  86        { 0xffffffff }
  87};
  88
  89static const struct kv_lcac_config_values mc2_local_cac_cfg_kv[] =
  90{
  91        {  0,       4,        1    },
  92        { 0xffffffff }
  93};
  94
  95static const struct kv_lcac_config_values mc3_local_cac_cfg_kv[] =
  96{
  97        {  0,       4,        1    },
  98        { 0xffffffff }
  99};
 100
 101static const struct kv_lcac_config_values cpl_local_cac_cfg_kv[] =
 102{
 103        {  0,       4,        1    },
 104        {  1,       4,        1    },
 105        {  2,       5,        1    },
 106        {  3,       4,        1    },
 107        {  4,       1,        1    },
 108        {  5,       5,        1    },
 109        {  6,       6,        1    },
 110        {  7,       9,        1    },
 111        {  8,       4,        1    },
 112        {  9,       2,        1    },
 113        {  10,      3,        1    },
 114        {  11,      6,        1    },
 115        {  12,      8,        2    },
 116        {  13,      1,        1    },
 117        {  14,      2,        1    },
 118        {  15,      3,        1    },
 119        {  16,      1,        1    },
 120        {  17,      4,        1    },
 121        {  18,      3,        1    },
 122        {  19,      1,        1    },
 123        {  20,      8,        1    },
 124        {  21,      5,        1    },
 125        {  22,      1,        1    },
 126        {  23,      1,        1    },
 127        {  24,      4,        1    },
 128        {  27,      6,        1    },
 129        {  28,      1,        1    },
 130        { 0xffffffff }
 131};
 132
 133static const struct kv_lcac_config_reg sx0_cac_config_reg[] =
 134{
 135        { 0xc0400d00, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
 136};
 137
 138static const struct kv_lcac_config_reg mc0_cac_config_reg[] =
 139{
 140        { 0xc0400d30, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
 141};
 142
 143static const struct kv_lcac_config_reg mc1_cac_config_reg[] =
 144{
 145        { 0xc0400d3c, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
 146};
 147
 148static const struct kv_lcac_config_reg mc2_cac_config_reg[] =
 149{
 150        { 0xc0400d48, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
 151};
 152
 153static const struct kv_lcac_config_reg mc3_cac_config_reg[] =
 154{
 155        { 0xc0400d54, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
 156};
 157
 158static const struct kv_lcac_config_reg cpl_cac_config_reg[] =
 159{
 160        { 0xc0400d80, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
 161};
 162
 163static const struct kv_pt_config_reg didt_config_kv[] =
 164{
 165        { 0x10, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 166        { 0x10, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
 167        { 0x10, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
 168        { 0x10, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
 169        { 0x11, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 170        { 0x11, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
 171        { 0x11, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
 172        { 0x11, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
 173        { 0x12, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 174        { 0x12, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
 175        { 0x12, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
 176        { 0x12, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
 177        { 0x2, 0x00003fff, 0, 0x4, KV_CONFIGREG_DIDT_IND },
 178        { 0x2, 0x03ff0000, 16, 0x80, KV_CONFIGREG_DIDT_IND },
 179        { 0x2, 0x78000000, 27, 0x3, KV_CONFIGREG_DIDT_IND },
 180        { 0x1, 0x0000ffff, 0, 0x3FFF, KV_CONFIGREG_DIDT_IND },
 181        { 0x1, 0xffff0000, 16, 0x3FFF, KV_CONFIGREG_DIDT_IND },
 182        { 0x0, 0x00000001, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 183        { 0x30, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 184        { 0x30, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
 185        { 0x30, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
 186        { 0x30, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
 187        { 0x31, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 188        { 0x31, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
 189        { 0x31, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
 190        { 0x31, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
 191        { 0x32, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 192        { 0x32, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
 193        { 0x32, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
 194        { 0x32, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
 195        { 0x22, 0x00003fff, 0, 0x4, KV_CONFIGREG_DIDT_IND },
 196        { 0x22, 0x03ff0000, 16, 0x80, KV_CONFIGREG_DIDT_IND },
 197        { 0x22, 0x78000000, 27, 0x3, KV_CONFIGREG_DIDT_IND },
 198        { 0x21, 0x0000ffff, 0, 0x3FFF, KV_CONFIGREG_DIDT_IND },
 199        { 0x21, 0xffff0000, 16, 0x3FFF, KV_CONFIGREG_DIDT_IND },
 200        { 0x20, 0x00000001, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 201        { 0x50, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 202        { 0x50, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
 203        { 0x50, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
 204        { 0x50, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
 205        { 0x51, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 206        { 0x51, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
 207        { 0x51, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
 208        { 0x51, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
 209        { 0x52, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 210        { 0x52, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
 211        { 0x52, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
 212        { 0x52, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
 213        { 0x42, 0x00003fff, 0, 0x4, KV_CONFIGREG_DIDT_IND },
 214        { 0x42, 0x03ff0000, 16, 0x80, KV_CONFIGREG_DIDT_IND },
 215        { 0x42, 0x78000000, 27, 0x3, KV_CONFIGREG_DIDT_IND },
 216        { 0x41, 0x0000ffff, 0, 0x3FFF, KV_CONFIGREG_DIDT_IND },
 217        { 0x41, 0xffff0000, 16, 0x3FFF, KV_CONFIGREG_DIDT_IND },
 218        { 0x40, 0x00000001, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 219        { 0x70, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 220        { 0x70, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
 221        { 0x70, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
 222        { 0x70, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
 223        { 0x71, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 224        { 0x71, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
 225        { 0x71, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
 226        { 0x71, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
 227        { 0x72, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 228        { 0x72, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
 229        { 0x72, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
 230        { 0x72, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
 231        { 0x62, 0x00003fff, 0, 0x4, KV_CONFIGREG_DIDT_IND },
 232        { 0x62, 0x03ff0000, 16, 0x80, KV_CONFIGREG_DIDT_IND },
 233        { 0x62, 0x78000000, 27, 0x3, KV_CONFIGREG_DIDT_IND },
 234        { 0x61, 0x0000ffff, 0, 0x3FFF, KV_CONFIGREG_DIDT_IND },
 235        { 0x61, 0xffff0000, 16, 0x3FFF, KV_CONFIGREG_DIDT_IND },
 236        { 0x60, 0x00000001, 0, 0x0, KV_CONFIGREG_DIDT_IND },
 237        { 0xFFFFFFFF }
 238};
 239
 240static struct kv_ps *kv_get_ps(struct radeon_ps *rps)
 241{
 242        struct kv_ps *ps = rps->ps_priv;
 243
 244        return ps;
 245}
 246
 247static struct kv_power_info *kv_get_pi(struct radeon_device *rdev)
 248{
 249        struct kv_power_info *pi = rdev->pm.dpm.priv;
 250
 251        return pi;
 252}
 253
 254#if 0
 255static void kv_program_local_cac_table(struct radeon_device *rdev,
 256                                       const struct kv_lcac_config_values *local_cac_table,
 257                                       const struct kv_lcac_config_reg *local_cac_reg)
 258{
 259        u32 i, count, data;
 260        const struct kv_lcac_config_values *values = local_cac_table;
 261
 262        while (values->block_id != 0xffffffff) {
 263                count = values->signal_id;
 264                for (i = 0; i < count; i++) {
 265                        data = ((values->block_id << local_cac_reg->block_shift) &
 266                                local_cac_reg->block_mask);
 267                        data |= ((i << local_cac_reg->signal_shift) &
 268                                 local_cac_reg->signal_mask);
 269                        data |= ((values->t << local_cac_reg->t_shift) &
 270                                 local_cac_reg->t_mask);
 271                        data |= ((1 << local_cac_reg->enable_shift) &
 272                                 local_cac_reg->enable_mask);
 273                        WREG32_SMC(local_cac_reg->cntl, data);
 274                }
 275                values++;
 276        }
 277}
 278#endif
 279
 280static int kv_program_pt_config_registers(struct radeon_device *rdev,
 281                                          const struct kv_pt_config_reg *cac_config_regs)
 282{
 283        const struct kv_pt_config_reg *config_regs = cac_config_regs;
 284        u32 data;
 285        u32 cache = 0;
 286
 287        if (config_regs == NULL)
 288                return -EINVAL;
 289
 290        while (config_regs->offset != 0xFFFFFFFF) {
 291                if (config_regs->type == KV_CONFIGREG_CACHE) {
 292                        cache |= ((config_regs->value << config_regs->shift) & config_regs->mask);
 293                } else {
 294                        switch (config_regs->type) {
 295                        case KV_CONFIGREG_SMC_IND:
 296                                data = RREG32_SMC(config_regs->offset);
 297                                break;
 298                        case KV_CONFIGREG_DIDT_IND:
 299                                data = RREG32_DIDT(config_regs->offset);
 300                                break;
 301                        default:
 302                                data = RREG32(config_regs->offset << 2);
 303                                break;
 304                        }
 305
 306                        data &= ~config_regs->mask;
 307                        data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
 308                        data |= cache;
 309                        cache = 0;
 310
 311                        switch (config_regs->type) {
 312                        case KV_CONFIGREG_SMC_IND:
 313                                WREG32_SMC(config_regs->offset, data);
 314                                break;
 315                        case KV_CONFIGREG_DIDT_IND:
 316                                WREG32_DIDT(config_regs->offset, data);
 317                                break;
 318                        default:
 319                                WREG32(config_regs->offset << 2, data);
 320                                break;
 321                        }
 322                }
 323                config_regs++;
 324        }
 325
 326        return 0;
 327}
 328
 329static void kv_do_enable_didt(struct radeon_device *rdev, bool enable)
 330{
 331        struct kv_power_info *pi = kv_get_pi(rdev);
 332        u32 data;
 333
 334        if (pi->caps_sq_ramping) {
 335                data = RREG32_DIDT(DIDT_SQ_CTRL0);
 336                if (enable)
 337                        data |= DIDT_CTRL_EN;
 338                else
 339                        data &= ~DIDT_CTRL_EN;
 340                WREG32_DIDT(DIDT_SQ_CTRL0, data);
 341        }
 342
 343        if (pi->caps_db_ramping) {
 344                data = RREG32_DIDT(DIDT_DB_CTRL0);
 345                if (enable)
 346                        data |= DIDT_CTRL_EN;
 347                else
 348                        data &= ~DIDT_CTRL_EN;
 349                WREG32_DIDT(DIDT_DB_CTRL0, data);
 350        }
 351
 352        if (pi->caps_td_ramping) {
 353                data = RREG32_DIDT(DIDT_TD_CTRL0);
 354                if (enable)
 355                        data |= DIDT_CTRL_EN;
 356                else
 357                        data &= ~DIDT_CTRL_EN;
 358                WREG32_DIDT(DIDT_TD_CTRL0, data);
 359        }
 360
 361        if (pi->caps_tcp_ramping) {
 362                data = RREG32_DIDT(DIDT_TCP_CTRL0);
 363                if (enable)
 364                        data |= DIDT_CTRL_EN;
 365                else
 366                        data &= ~DIDT_CTRL_EN;
 367                WREG32_DIDT(DIDT_TCP_CTRL0, data);
 368        }
 369}
 370
 371static int kv_enable_didt(struct radeon_device *rdev, bool enable)
 372{
 373        struct kv_power_info *pi = kv_get_pi(rdev);
 374        int ret;
 375
 376        if (pi->caps_sq_ramping ||
 377            pi->caps_db_ramping ||
 378            pi->caps_td_ramping ||
 379            pi->caps_tcp_ramping) {
 380                cik_enter_rlc_safe_mode(rdev);
 381
 382                if (enable) {
 383                        ret = kv_program_pt_config_registers(rdev, didt_config_kv);
 384                        if (ret) {
 385                                cik_exit_rlc_safe_mode(rdev);
 386                                return ret;
 387                        }
 388                }
 389
 390                kv_do_enable_didt(rdev, enable);
 391
 392                cik_exit_rlc_safe_mode(rdev);
 393        }
 394
 395        return 0;
 396}
 397
 398#if 0
 399static void kv_initialize_hardware_cac_manager(struct radeon_device *rdev)
 400{
 401        struct kv_power_info *pi = kv_get_pi(rdev);
 402
 403        if (pi->caps_cac) {
 404                WREG32_SMC(LCAC_SX0_OVR_SEL, 0);
 405                WREG32_SMC(LCAC_SX0_OVR_VAL, 0);
 406                kv_program_local_cac_table(rdev, sx_local_cac_cfg_kv, sx0_cac_config_reg);
 407
 408                WREG32_SMC(LCAC_MC0_OVR_SEL, 0);
 409                WREG32_SMC(LCAC_MC0_OVR_VAL, 0);
 410                kv_program_local_cac_table(rdev, mc0_local_cac_cfg_kv, mc0_cac_config_reg);
 411
 412                WREG32_SMC(LCAC_MC1_OVR_SEL, 0);
 413                WREG32_SMC(LCAC_MC1_OVR_VAL, 0);
 414                kv_program_local_cac_table(rdev, mc1_local_cac_cfg_kv, mc1_cac_config_reg);
 415
 416                WREG32_SMC(LCAC_MC2_OVR_SEL, 0);
 417                WREG32_SMC(LCAC_MC2_OVR_VAL, 0);
 418                kv_program_local_cac_table(rdev, mc2_local_cac_cfg_kv, mc2_cac_config_reg);
 419
 420                WREG32_SMC(LCAC_MC3_OVR_SEL, 0);
 421                WREG32_SMC(LCAC_MC3_OVR_VAL, 0);
 422                kv_program_local_cac_table(rdev, mc3_local_cac_cfg_kv, mc3_cac_config_reg);
 423
 424                WREG32_SMC(LCAC_CPL_OVR_SEL, 0);
 425                WREG32_SMC(LCAC_CPL_OVR_VAL, 0);
 426                kv_program_local_cac_table(rdev, cpl_local_cac_cfg_kv, cpl_cac_config_reg);
 427        }
 428}
 429#endif
 430
 431static int kv_enable_smc_cac(struct radeon_device *rdev, bool enable)
 432{
 433        struct kv_power_info *pi = kv_get_pi(rdev);
 434        int ret = 0;
 435
 436        if (pi->caps_cac) {
 437                if (enable) {
 438                        ret = kv_notify_message_to_smu(rdev, PPSMC_MSG_EnableCac);
 439                        if (ret)
 440                                pi->cac_enabled = false;
 441                        else
 442                                pi->cac_enabled = true;
 443                } else if (pi->cac_enabled) {
 444                        kv_notify_message_to_smu(rdev, PPSMC_MSG_DisableCac);
 445                        pi->cac_enabled = false;
 446                }
 447        }
 448
 449        return ret;
 450}
 451
 452static int kv_process_firmware_header(struct radeon_device *rdev)
 453{
 454        struct kv_power_info *pi = kv_get_pi(rdev);
 455        u32 tmp;
 456        int ret;
 457
 458        ret = kv_read_smc_sram_dword(rdev, SMU7_FIRMWARE_HEADER_LOCATION +
 459                                     offsetof(SMU7_Firmware_Header, DpmTable),
 460                                     &tmp, pi->sram_end);
 461
 462        if (ret == 0)
 463                pi->dpm_table_start = tmp;
 464
 465        ret = kv_read_smc_sram_dword(rdev, SMU7_FIRMWARE_HEADER_LOCATION +
 466                                     offsetof(SMU7_Firmware_Header, SoftRegisters),
 467                                     &tmp, pi->sram_end);
 468
 469        if (ret == 0)
 470                pi->soft_regs_start = tmp;
 471
 472        return ret;
 473}
 474
 475static int kv_enable_dpm_voltage_scaling(struct radeon_device *rdev)
 476{
 477        struct kv_power_info *pi = kv_get_pi(rdev);
 478        int ret;
 479
 480        pi->graphics_voltage_change_enable = 1;
 481
 482        ret = kv_copy_bytes_to_smc(rdev,
 483                                   pi->dpm_table_start +
 484                                   offsetof(SMU7_Fusion_DpmTable, GraphicsVoltageChangeEnable),
 485                                   &pi->graphics_voltage_change_enable,
 486                                   sizeof(u8), pi->sram_end);
 487
 488        return ret;
 489}
 490
 491static int kv_set_dpm_interval(struct radeon_device *rdev)
 492{
 493        struct kv_power_info *pi = kv_get_pi(rdev);
 494        int ret;
 495
 496        pi->graphics_interval = 1;
 497
 498        ret = kv_copy_bytes_to_smc(rdev,
 499                                   pi->dpm_table_start +
 500                                   offsetof(SMU7_Fusion_DpmTable, GraphicsInterval),
 501                                   &pi->graphics_interval,
 502                                   sizeof(u8), pi->sram_end);
 503
 504        return ret;
 505}
 506
 507static int kv_set_dpm_boot_state(struct radeon_device *rdev)
 508{
 509        struct kv_power_info *pi = kv_get_pi(rdev);
 510        int ret;
 511
 512        ret = kv_copy_bytes_to_smc(rdev,
 513                                   pi->dpm_table_start +
 514                                   offsetof(SMU7_Fusion_DpmTable, GraphicsBootLevel),
 515                                   &pi->graphics_boot_level,
 516                                   sizeof(u8), pi->sram_end);
 517
 518        return ret;
 519}
 520
 521static void kv_program_vc(struct radeon_device *rdev)
 522{
 523        WREG32_SMC(CG_FTV_0, 0x3FFFC100);
 524}
 525
 526static void kv_clear_vc(struct radeon_device *rdev)
 527{
 528        WREG32_SMC(CG_FTV_0, 0);
 529}
 530
 531static int kv_set_divider_value(struct radeon_device *rdev,
 532                                u32 index, u32 sclk)
 533{
 534        struct kv_power_info *pi = kv_get_pi(rdev);
 535        struct atom_clock_dividers dividers;
 536        int ret;
 537
 538        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
 539                                             sclk, false, &dividers);
 540        if (ret)
 541                return ret;
 542
 543        pi->graphics_level[index].SclkDid = (u8)dividers.post_div;
 544        pi->graphics_level[index].SclkFrequency = cpu_to_be32(sclk);
 545
 546        return 0;
 547}
 548
 549static u16 kv_convert_8bit_index_to_voltage(struct radeon_device *rdev,
 550                                            u16 voltage)
 551{
 552        return 6200 - (voltage * 25);
 553}
 554
 555static u16 kv_convert_2bit_index_to_voltage(struct radeon_device *rdev,
 556                                            u32 vid_2bit)
 557{
 558        struct kv_power_info *pi = kv_get_pi(rdev);
 559        u32 vid_8bit = sumo_convert_vid2_to_vid7(rdev,
 560                                                 &pi->sys_info.vid_mapping_table,
 561                                                 vid_2bit);
 562
 563        return kv_convert_8bit_index_to_voltage(rdev, (u16)vid_8bit);
 564}
 565
 566
 567static int kv_set_vid(struct radeon_device *rdev, u32 index, u32 vid)
 568{
 569        struct kv_power_info *pi = kv_get_pi(rdev);
 570
 571        pi->graphics_level[index].VoltageDownH = (u8)pi->voltage_drop_t;
 572        pi->graphics_level[index].MinVddNb =
 573                cpu_to_be32(kv_convert_2bit_index_to_voltage(rdev, vid));
 574
 575        return 0;
 576}
 577
 578static int kv_set_at(struct radeon_device *rdev, u32 index, u32 at)
 579{
 580        struct kv_power_info *pi = kv_get_pi(rdev);
 581
 582        pi->graphics_level[index].AT = cpu_to_be16((u16)at);
 583
 584        return 0;
 585}
 586
 587static void kv_dpm_power_level_enable(struct radeon_device *rdev,
 588                                      u32 index, bool enable)
 589{
 590        struct kv_power_info *pi = kv_get_pi(rdev);
 591
 592        pi->graphics_level[index].EnabledForActivity = enable ? 1 : 0;
 593}
 594
 595static void kv_start_dpm(struct radeon_device *rdev)
 596{
 597        u32 tmp = RREG32_SMC(GENERAL_PWRMGT);
 598
 599        tmp |= GLOBAL_PWRMGT_EN;
 600        WREG32_SMC(GENERAL_PWRMGT, tmp);
 601
 602        kv_smc_dpm_enable(rdev, true);
 603}
 604
 605static void kv_stop_dpm(struct radeon_device *rdev)
 606{
 607        kv_smc_dpm_enable(rdev, false);
 608}
 609
 610static void kv_start_am(struct radeon_device *rdev)
 611{
 612        u32 sclk_pwrmgt_cntl = RREG32_SMC(SCLK_PWRMGT_CNTL);
 613
 614        sclk_pwrmgt_cntl &= ~(RESET_SCLK_CNT | RESET_BUSY_CNT);
 615        sclk_pwrmgt_cntl |= DYNAMIC_PM_EN;
 616
 617        WREG32_SMC(SCLK_PWRMGT_CNTL, sclk_pwrmgt_cntl);
 618}
 619
 620static void kv_reset_am(struct radeon_device *rdev)
 621{
 622        u32 sclk_pwrmgt_cntl = RREG32_SMC(SCLK_PWRMGT_CNTL);
 623
 624        sclk_pwrmgt_cntl |= (RESET_SCLK_CNT | RESET_BUSY_CNT);
 625
 626        WREG32_SMC(SCLK_PWRMGT_CNTL, sclk_pwrmgt_cntl);
 627}
 628
 629static int kv_freeze_sclk_dpm(struct radeon_device *rdev, bool freeze)
 630{
 631        return kv_notify_message_to_smu(rdev, freeze ?
 632                                        PPSMC_MSG_SCLKDPM_FreezeLevel : PPSMC_MSG_SCLKDPM_UnfreezeLevel);
 633}
 634
 635static int kv_force_lowest_valid(struct radeon_device *rdev)
 636{
 637        return kv_force_dpm_lowest(rdev);
 638}
 639
 640static int kv_unforce_levels(struct radeon_device *rdev)
 641{
 642        if (rdev->family == CHIP_KABINI)
 643                return kv_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel);
 644        else
 645                return kv_set_enabled_levels(rdev);
 646}
 647
 648static int kv_update_sclk_t(struct radeon_device *rdev)
 649{
 650        struct kv_power_info *pi = kv_get_pi(rdev);
 651        u32 low_sclk_interrupt_t = 0;
 652        int ret = 0;
 653
 654        if (pi->caps_sclk_throttle_low_notification) {
 655                low_sclk_interrupt_t = cpu_to_be32(pi->low_sclk_interrupt_t);
 656
 657                ret = kv_copy_bytes_to_smc(rdev,
 658                                           pi->dpm_table_start +
 659                                           offsetof(SMU7_Fusion_DpmTable, LowSclkInterruptT),
 660                                           (u8 *)&low_sclk_interrupt_t,
 661                                           sizeof(u32), pi->sram_end);
 662        }
 663        return ret;
 664}
 665
 666static int kv_program_bootup_state(struct radeon_device *rdev)
 667{
 668        struct kv_power_info *pi = kv_get_pi(rdev);
 669        u32 i;
 670        struct radeon_clock_voltage_dependency_table *table =
 671                &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
 672
 673        if (table && table->count) {
 674                for (i = pi->graphics_dpm_level_count - 1; i > 0; i--) {
 675                        if (table->entries[i].clk == pi->boot_pl.sclk)
 676                                break;
 677                }
 678
 679                pi->graphics_boot_level = (u8)i;
 680                kv_dpm_power_level_enable(rdev, i, true);
 681        } else {
 682                struct sumo_sclk_voltage_mapping_table *table =
 683                        &pi->sys_info.sclk_voltage_mapping_table;
 684
 685                if (table->num_max_dpm_entries == 0)
 686                        return -EINVAL;
 687
 688                for (i = pi->graphics_dpm_level_count - 1; i > 0; i--) {
 689                        if (table->entries[i].sclk_frequency == pi->boot_pl.sclk)
 690                                break;
 691                }
 692
 693                pi->graphics_boot_level = (u8)i;
 694                kv_dpm_power_level_enable(rdev, i, true);
 695        }
 696        return 0;
 697}
 698
 699static int kv_enable_auto_thermal_throttling(struct radeon_device *rdev)
 700{
 701        struct kv_power_info *pi = kv_get_pi(rdev);
 702        int ret;
 703
 704        pi->graphics_therm_throttle_enable = 1;
 705
 706        ret = kv_copy_bytes_to_smc(rdev,
 707                                   pi->dpm_table_start +
 708                                   offsetof(SMU7_Fusion_DpmTable, GraphicsThermThrottleEnable),
 709                                   &pi->graphics_therm_throttle_enable,
 710                                   sizeof(u8), pi->sram_end);
 711
 712        return ret;
 713}
 714
 715static int kv_upload_dpm_settings(struct radeon_device *rdev)
 716{
 717        struct kv_power_info *pi = kv_get_pi(rdev);
 718        int ret;
 719
 720        ret = kv_copy_bytes_to_smc(rdev,
 721                                   pi->dpm_table_start +
 722                                   offsetof(SMU7_Fusion_DpmTable, GraphicsLevel),
 723                                   (u8 *)&pi->graphics_level,
 724                                   sizeof(SMU7_Fusion_GraphicsLevel) * SMU7_MAX_LEVELS_GRAPHICS,
 725                                   pi->sram_end);
 726
 727        if (ret)
 728                return ret;
 729
 730        ret = kv_copy_bytes_to_smc(rdev,
 731                                   pi->dpm_table_start +
 732                                   offsetof(SMU7_Fusion_DpmTable, GraphicsDpmLevelCount),
 733                                   &pi->graphics_dpm_level_count,
 734                                   sizeof(u8), pi->sram_end);
 735
 736        return ret;
 737}
 738
 739static u32 kv_get_clock_difference(u32 a, u32 b)
 740{
 741        return (a >= b) ? a - b : b - a;
 742}
 743
 744static u32 kv_get_clk_bypass(struct radeon_device *rdev, u32 clk)
 745{
 746        struct kv_power_info *pi = kv_get_pi(rdev);
 747        u32 value;
 748
 749        if (pi->caps_enable_dfs_bypass) {
 750                if (kv_get_clock_difference(clk, 40000) < 200)
 751                        value = 3;
 752                else if (kv_get_clock_difference(clk, 30000) < 200)
 753                        value = 2;
 754                else if (kv_get_clock_difference(clk, 20000) < 200)
 755                        value = 7;
 756                else if (kv_get_clock_difference(clk, 15000) < 200)
 757                        value = 6;
 758                else if (kv_get_clock_difference(clk, 10000) < 200)
 759                        value = 8;
 760                else
 761                        value = 0;
 762        } else {
 763                value = 0;
 764        }
 765
 766        return value;
 767}
 768
 769static int kv_populate_uvd_table(struct radeon_device *rdev)
 770{
 771        struct kv_power_info *pi = kv_get_pi(rdev);
 772        struct radeon_uvd_clock_voltage_dependency_table *table =
 773                &rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table;
 774        struct atom_clock_dividers dividers;
 775        int ret;
 776        u32 i;
 777
 778        if (table == NULL || table->count == 0)
 779                return 0;
 780
 781        pi->uvd_level_count = 0;
 782        for (i = 0; i < table->count; i++) {
 783                if (pi->high_voltage_t &&
 784                    (pi->high_voltage_t < table->entries[i].v))
 785                        break;
 786
 787                pi->uvd_level[i].VclkFrequency = cpu_to_be32(table->entries[i].vclk);
 788                pi->uvd_level[i].DclkFrequency = cpu_to_be32(table->entries[i].dclk);
 789                pi->uvd_level[i].MinVddNb = cpu_to_be16(table->entries[i].v);
 790
 791                pi->uvd_level[i].VClkBypassCntl =
 792                        (u8)kv_get_clk_bypass(rdev, table->entries[i].vclk);
 793                pi->uvd_level[i].DClkBypassCntl =
 794                        (u8)kv_get_clk_bypass(rdev, table->entries[i].dclk);
 795
 796                ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
 797                                                     table->entries[i].vclk, false, &dividers);
 798                if (ret)
 799                        return ret;
 800                pi->uvd_level[i].VclkDivider = (u8)dividers.post_div;
 801
 802                ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
 803                                                     table->entries[i].dclk, false, &dividers);
 804                if (ret)
 805                        return ret;
 806                pi->uvd_level[i].DclkDivider = (u8)dividers.post_div;
 807
 808                pi->uvd_level_count++;
 809        }
 810
 811        ret = kv_copy_bytes_to_smc(rdev,
 812                                   pi->dpm_table_start +
 813                                   offsetof(SMU7_Fusion_DpmTable, UvdLevelCount),
 814                                   (u8 *)&pi->uvd_level_count,
 815                                   sizeof(u8), pi->sram_end);
 816        if (ret)
 817                return ret;
 818
 819        pi->uvd_interval = 1;
 820
 821        ret = kv_copy_bytes_to_smc(rdev,
 822                                   pi->dpm_table_start +
 823                                   offsetof(SMU7_Fusion_DpmTable, UVDInterval),
 824                                   &pi->uvd_interval,
 825                                   sizeof(u8), pi->sram_end);
 826        if (ret)
 827                return ret;
 828
 829        ret = kv_copy_bytes_to_smc(rdev,
 830                                   pi->dpm_table_start +
 831                                   offsetof(SMU7_Fusion_DpmTable, UvdLevel),
 832                                   (u8 *)&pi->uvd_level,
 833                                   sizeof(SMU7_Fusion_UvdLevel) * SMU7_MAX_LEVELS_UVD,
 834                                   pi->sram_end);
 835
 836        return ret;
 837
 838}
 839
 840static int kv_populate_vce_table(struct radeon_device *rdev)
 841{
 842        struct kv_power_info *pi = kv_get_pi(rdev);
 843        int ret;
 844        u32 i;
 845        struct radeon_vce_clock_voltage_dependency_table *table =
 846                &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
 847        struct atom_clock_dividers dividers;
 848
 849        if (table == NULL || table->count == 0)
 850                return 0;
 851
 852        pi->vce_level_count = 0;
 853        for (i = 0; i < table->count; i++) {
 854                if (pi->high_voltage_t &&
 855                    pi->high_voltage_t < table->entries[i].v)
 856                        break;
 857
 858                pi->vce_level[i].Frequency = cpu_to_be32(table->entries[i].evclk);
 859                pi->vce_level[i].MinVoltage = cpu_to_be16(table->entries[i].v);
 860
 861                pi->vce_level[i].ClkBypassCntl =
 862                        (u8)kv_get_clk_bypass(rdev, table->entries[i].evclk);
 863
 864                ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
 865                                                     table->entries[i].evclk, false, &dividers);
 866                if (ret)
 867                        return ret;
 868                pi->vce_level[i].Divider = (u8)dividers.post_div;
 869
 870                pi->vce_level_count++;
 871        }
 872
 873        ret = kv_copy_bytes_to_smc(rdev,
 874                                   pi->dpm_table_start +
 875                                   offsetof(SMU7_Fusion_DpmTable, VceLevelCount),
 876                                   (u8 *)&pi->vce_level_count,
 877                                   sizeof(u8),
 878                                   pi->sram_end);
 879        if (ret)
 880                return ret;
 881
 882        pi->vce_interval = 1;
 883
 884        ret = kv_copy_bytes_to_smc(rdev,
 885                                   pi->dpm_table_start +
 886                                   offsetof(SMU7_Fusion_DpmTable, VCEInterval),
 887                                   (u8 *)&pi->vce_interval,
 888                                   sizeof(u8),
 889                                   pi->sram_end);
 890        if (ret)
 891                return ret;
 892
 893        ret = kv_copy_bytes_to_smc(rdev,
 894                                   pi->dpm_table_start +
 895                                   offsetof(SMU7_Fusion_DpmTable, VceLevel),
 896                                   (u8 *)&pi->vce_level,
 897                                   sizeof(SMU7_Fusion_ExtClkLevel) * SMU7_MAX_LEVELS_VCE,
 898                                   pi->sram_end);
 899
 900        return ret;
 901}
 902
 903static int kv_populate_samu_table(struct radeon_device *rdev)
 904{
 905        struct kv_power_info *pi = kv_get_pi(rdev);
 906        struct radeon_clock_voltage_dependency_table *table =
 907                &rdev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table;
 908        struct atom_clock_dividers dividers;
 909        int ret;
 910        u32 i;
 911
 912        if (table == NULL || table->count == 0)
 913                return 0;
 914
 915        pi->samu_level_count = 0;
 916        for (i = 0; i < table->count; i++) {
 917                if (pi->high_voltage_t &&
 918                    pi->high_voltage_t < table->entries[i].v)
 919                        break;
 920
 921                pi->samu_level[i].Frequency = cpu_to_be32(table->entries[i].clk);
 922                pi->samu_level[i].MinVoltage = cpu_to_be16(table->entries[i].v);
 923
 924                pi->samu_level[i].ClkBypassCntl =
 925                        (u8)kv_get_clk_bypass(rdev, table->entries[i].clk);
 926
 927                ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
 928                                                     table->entries[i].clk, false, &dividers);
 929                if (ret)
 930                        return ret;
 931                pi->samu_level[i].Divider = (u8)dividers.post_div;
 932
 933                pi->samu_level_count++;
 934        }
 935
 936        ret = kv_copy_bytes_to_smc(rdev,
 937                                   pi->dpm_table_start +
 938                                   offsetof(SMU7_Fusion_DpmTable, SamuLevelCount),
 939                                   (u8 *)&pi->samu_level_count,
 940                                   sizeof(u8),
 941                                   pi->sram_end);
 942        if (ret)
 943                return ret;
 944
 945        pi->samu_interval = 1;
 946
 947        ret = kv_copy_bytes_to_smc(rdev,
 948                                   pi->dpm_table_start +
 949                                   offsetof(SMU7_Fusion_DpmTable, SAMUInterval),
 950                                   (u8 *)&pi->samu_interval,
 951                                   sizeof(u8),
 952                                   pi->sram_end);
 953        if (ret)
 954                return ret;
 955
 956        ret = kv_copy_bytes_to_smc(rdev,
 957                                   pi->dpm_table_start +
 958                                   offsetof(SMU7_Fusion_DpmTable, SamuLevel),
 959                                   (u8 *)&pi->samu_level,
 960                                   sizeof(SMU7_Fusion_ExtClkLevel) * SMU7_MAX_LEVELS_SAMU,
 961                                   pi->sram_end);
 962        if (ret)
 963                return ret;
 964
 965        return ret;
 966}
 967
 968
 969static int kv_populate_acp_table(struct radeon_device *rdev)
 970{
 971        struct kv_power_info *pi = kv_get_pi(rdev);
 972        struct radeon_clock_voltage_dependency_table *table =
 973                &rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table;
 974        struct atom_clock_dividers dividers;
 975        int ret;
 976        u32 i;
 977
 978        if (table == NULL || table->count == 0)
 979                return 0;
 980
 981        pi->acp_level_count = 0;
 982        for (i = 0; i < table->count; i++) {
 983                pi->acp_level[i].Frequency = cpu_to_be32(table->entries[i].clk);
 984                pi->acp_level[i].MinVoltage = cpu_to_be16(table->entries[i].v);
 985
 986                ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
 987                                                     table->entries[i].clk, false, &dividers);
 988                if (ret)
 989                        return ret;
 990                pi->acp_level[i].Divider = (u8)dividers.post_div;
 991
 992                pi->acp_level_count++;
 993        }
 994
 995        ret = kv_copy_bytes_to_smc(rdev,
 996                                   pi->dpm_table_start +
 997                                   offsetof(SMU7_Fusion_DpmTable, AcpLevelCount),
 998                                   (u8 *)&pi->acp_level_count,
 999                                   sizeof(u8),
1000                                   pi->sram_end);
1001        if (ret)
1002                return ret;
1003
1004        pi->acp_interval = 1;
1005
1006        ret = kv_copy_bytes_to_smc(rdev,
1007                                   pi->dpm_table_start +
1008                                   offsetof(SMU7_Fusion_DpmTable, ACPInterval),
1009                                   (u8 *)&pi->acp_interval,
1010                                   sizeof(u8),
1011                                   pi->sram_end);
1012        if (ret)
1013                return ret;
1014
1015        ret = kv_copy_bytes_to_smc(rdev,
1016                                   pi->dpm_table_start +
1017                                   offsetof(SMU7_Fusion_DpmTable, AcpLevel),
1018                                   (u8 *)&pi->acp_level,
1019                                   sizeof(SMU7_Fusion_ExtClkLevel) * SMU7_MAX_LEVELS_ACP,
1020                                   pi->sram_end);
1021        if (ret)
1022                return ret;
1023
1024        return ret;
1025}
1026
1027static void kv_calculate_dfs_bypass_settings(struct radeon_device *rdev)
1028{
1029        struct kv_power_info *pi = kv_get_pi(rdev);
1030        u32 i;
1031        struct radeon_clock_voltage_dependency_table *table =
1032                &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
1033
1034        if (table && table->count) {
1035                for (i = 0; i < pi->graphics_dpm_level_count; i++) {
1036                        if (pi->caps_enable_dfs_bypass) {
1037                                if (kv_get_clock_difference(table->entries[i].clk, 40000) < 200)
1038                                        pi->graphics_level[i].ClkBypassCntl = 3;
1039                                else if (kv_get_clock_difference(table->entries[i].clk, 30000) < 200)
1040                                        pi->graphics_level[i].ClkBypassCntl = 2;
1041                                else if (kv_get_clock_difference(table->entries[i].clk, 26600) < 200)
1042                                        pi->graphics_level[i].ClkBypassCntl = 7;
1043                                else if (kv_get_clock_difference(table->entries[i].clk , 20000) < 200)
1044                                        pi->graphics_level[i].ClkBypassCntl = 6;
1045                                else if (kv_get_clock_difference(table->entries[i].clk , 10000) < 200)
1046                                        pi->graphics_level[i].ClkBypassCntl = 8;
1047                                else
1048                                        pi->graphics_level[i].ClkBypassCntl = 0;
1049                        } else {
1050                                pi->graphics_level[i].ClkBypassCntl = 0;
1051                        }
1052                }
1053        } else {
1054                struct sumo_sclk_voltage_mapping_table *table =
1055                        &pi->sys_info.sclk_voltage_mapping_table;
1056                for (i = 0; i < pi->graphics_dpm_level_count; i++) {
1057                        if (pi->caps_enable_dfs_bypass) {
1058                                if (kv_get_clock_difference(table->entries[i].sclk_frequency, 40000) < 200)
1059                                        pi->graphics_level[i].ClkBypassCntl = 3;
1060                                else if (kv_get_clock_difference(table->entries[i].sclk_frequency, 30000) < 200)
1061                                        pi->graphics_level[i].ClkBypassCntl = 2;
1062                                else if (kv_get_clock_difference(table->entries[i].sclk_frequency, 26600) < 200)
1063                                        pi->graphics_level[i].ClkBypassCntl = 7;
1064                                else if (kv_get_clock_difference(table->entries[i].sclk_frequency, 20000) < 200)
1065                                        pi->graphics_level[i].ClkBypassCntl = 6;
1066                                else if (kv_get_clock_difference(table->entries[i].sclk_frequency, 10000) < 200)
1067                                        pi->graphics_level[i].ClkBypassCntl = 8;
1068                                else
1069                                        pi->graphics_level[i].ClkBypassCntl = 0;
1070                        } else {
1071                                pi->graphics_level[i].ClkBypassCntl = 0;
1072                        }
1073                }
1074        }
1075}
1076
1077static int kv_enable_ulv(struct radeon_device *rdev, bool enable)
1078{
1079        return kv_notify_message_to_smu(rdev, enable ?
1080                                        PPSMC_MSG_EnableULV : PPSMC_MSG_DisableULV);
1081}
1082
1083static void kv_reset_acp_boot_level(struct radeon_device *rdev)
1084{
1085        struct kv_power_info *pi = kv_get_pi(rdev);
1086
1087        pi->acp_boot_level = 0xff;
1088}
1089
1090static void kv_update_current_ps(struct radeon_device *rdev,
1091                                 struct radeon_ps *rps)
1092{
1093        struct kv_ps *new_ps = kv_get_ps(rps);
1094        struct kv_power_info *pi = kv_get_pi(rdev);
1095
1096        pi->current_rps = *rps;
1097        pi->current_ps = *new_ps;
1098        pi->current_rps.ps_priv = &pi->current_ps;
1099}
1100
1101static void kv_update_requested_ps(struct radeon_device *rdev,
1102                                   struct radeon_ps *rps)
1103{
1104        struct kv_ps *new_ps = kv_get_ps(rps);
1105        struct kv_power_info *pi = kv_get_pi(rdev);
1106
1107        pi->requested_rps = *rps;
1108        pi->requested_ps = *new_ps;
1109        pi->requested_rps.ps_priv = &pi->requested_ps;
1110}
1111
1112void kv_dpm_enable_bapm(struct radeon_device *rdev, bool enable)
1113{
1114        struct kv_power_info *pi = kv_get_pi(rdev);
1115        int ret;
1116
1117        if (pi->bapm_enable) {
1118                ret = kv_smc_bapm_enable(rdev, enable);
1119                if (ret)
1120                        DRM_ERROR("kv_smc_bapm_enable failed\n");
1121        }
1122}
1123
1124int kv_dpm_enable(struct radeon_device *rdev)
1125{
1126        struct kv_power_info *pi = kv_get_pi(rdev);
1127        int ret;
1128
1129        cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
1130                             RADEON_CG_BLOCK_SDMA |
1131                             RADEON_CG_BLOCK_BIF |
1132                             RADEON_CG_BLOCK_HDP), false);
1133
1134        ret = kv_process_firmware_header(rdev);
1135        if (ret) {
1136                DRM_ERROR("kv_process_firmware_header failed\n");
1137                return ret;
1138        }
1139        kv_init_fps_limits(rdev);
1140        kv_init_graphics_levels(rdev);
1141        ret = kv_program_bootup_state(rdev);
1142        if (ret) {
1143                DRM_ERROR("kv_program_bootup_state failed\n");
1144                return ret;
1145        }
1146        kv_calculate_dfs_bypass_settings(rdev);
1147        ret = kv_upload_dpm_settings(rdev);
1148        if (ret) {
1149                DRM_ERROR("kv_upload_dpm_settings failed\n");
1150                return ret;
1151        }
1152        ret = kv_populate_uvd_table(rdev);
1153        if (ret) {
1154                DRM_ERROR("kv_populate_uvd_table failed\n");
1155                return ret;
1156        }
1157        ret = kv_populate_vce_table(rdev);
1158        if (ret) {
1159                DRM_ERROR("kv_populate_vce_table failed\n");
1160                return ret;
1161        }
1162        ret = kv_populate_samu_table(rdev);
1163        if (ret) {
1164                DRM_ERROR("kv_populate_samu_table failed\n");
1165                return ret;
1166        }
1167        ret = kv_populate_acp_table(rdev);
1168        if (ret) {
1169                DRM_ERROR("kv_populate_acp_table failed\n");
1170                return ret;
1171        }
1172        kv_program_vc(rdev);
1173#if 0
1174        kv_initialize_hardware_cac_manager(rdev);
1175#endif
1176        kv_start_am(rdev);
1177        if (pi->enable_auto_thermal_throttling) {
1178                ret = kv_enable_auto_thermal_throttling(rdev);
1179                if (ret) {
1180                        DRM_ERROR("kv_enable_auto_thermal_throttling failed\n");
1181                        return ret;
1182                }
1183        }
1184        ret = kv_enable_dpm_voltage_scaling(rdev);
1185        if (ret) {
1186                DRM_ERROR("kv_enable_dpm_voltage_scaling failed\n");
1187                return ret;
1188        }
1189        ret = kv_set_dpm_interval(rdev);
1190        if (ret) {
1191                DRM_ERROR("kv_set_dpm_interval failed\n");
1192                return ret;
1193        }
1194        ret = kv_set_dpm_boot_state(rdev);
1195        if (ret) {
1196                DRM_ERROR("kv_set_dpm_boot_state failed\n");
1197                return ret;
1198        }
1199        ret = kv_enable_ulv(rdev, true);
1200        if (ret) {
1201                DRM_ERROR("kv_enable_ulv failed\n");
1202                return ret;
1203        }
1204        kv_start_dpm(rdev);
1205        ret = kv_enable_didt(rdev, true);
1206        if (ret) {
1207                DRM_ERROR("kv_enable_didt failed\n");
1208                return ret;
1209        }
1210        ret = kv_enable_smc_cac(rdev, true);
1211        if (ret) {
1212                DRM_ERROR("kv_enable_smc_cac failed\n");
1213                return ret;
1214        }
1215
1216        kv_reset_acp_boot_level(rdev);
1217
1218        if (rdev->irq.installed &&
1219            r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
1220                ret = kv_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
1221                if (ret) {
1222                        DRM_ERROR("kv_set_thermal_temperature_range failed\n");
1223                        return ret;
1224                }
1225                rdev->irq.dpm_thermal = true;
1226                radeon_irq_set(rdev);
1227        }
1228
1229        ret = kv_smc_bapm_enable(rdev, false);
1230        if (ret) {
1231                DRM_ERROR("kv_smc_bapm_enable failed\n");
1232                return ret;
1233        }
1234
1235        /* powerdown unused blocks for now */
1236        kv_dpm_powergate_acp(rdev, true);
1237        kv_dpm_powergate_samu(rdev, true);
1238        kv_dpm_powergate_vce(rdev, true);
1239        kv_dpm_powergate_uvd(rdev, true);
1240
1241        cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
1242                             RADEON_CG_BLOCK_SDMA |
1243                             RADEON_CG_BLOCK_BIF |
1244                             RADEON_CG_BLOCK_HDP), true);
1245
1246        kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
1247
1248        return ret;
1249}
1250
1251void kv_dpm_disable(struct radeon_device *rdev)
1252{
1253        cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
1254                             RADEON_CG_BLOCK_SDMA |
1255                             RADEON_CG_BLOCK_BIF |
1256                             RADEON_CG_BLOCK_HDP), false);
1257
1258        kv_smc_bapm_enable(rdev, false);
1259
1260        /* powerup blocks */
1261        kv_dpm_powergate_acp(rdev, false);
1262        kv_dpm_powergate_samu(rdev, false);
1263        kv_dpm_powergate_vce(rdev, false);
1264        kv_dpm_powergate_uvd(rdev, false);
1265
1266        kv_enable_smc_cac(rdev, false);
1267        kv_enable_didt(rdev, false);
1268        kv_clear_vc(rdev);
1269        kv_stop_dpm(rdev);
1270        kv_enable_ulv(rdev, false);
1271        kv_reset_am(rdev);
1272
1273        kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
1274}
1275
1276#if 0
1277static int kv_write_smc_soft_register(struct radeon_device *rdev,
1278                                      u16 reg_offset, u32 value)
1279{
1280        struct kv_power_info *pi = kv_get_pi(rdev);
1281
1282        return kv_copy_bytes_to_smc(rdev, pi->soft_regs_start + reg_offset,
1283                                    (u8 *)&value, sizeof(u16), pi->sram_end);
1284}
1285
1286static int kv_read_smc_soft_register(struct radeon_device *rdev,
1287                                     u16 reg_offset, u32 *value)
1288{
1289        struct kv_power_info *pi = kv_get_pi(rdev);
1290
1291        return kv_read_smc_sram_dword(rdev, pi->soft_regs_start + reg_offset,
1292                                      value, pi->sram_end);
1293}
1294#endif
1295
1296static void kv_init_sclk_t(struct radeon_device *rdev)
1297{
1298        struct kv_power_info *pi = kv_get_pi(rdev);
1299
1300        pi->low_sclk_interrupt_t = 0;
1301}
1302
1303static int kv_init_fps_limits(struct radeon_device *rdev)
1304{
1305        struct kv_power_info *pi = kv_get_pi(rdev);
1306        int ret = 0;
1307
1308        if (pi->caps_fps) {
1309                u16 tmp;
1310
1311                tmp = 45;
1312                pi->fps_high_t = cpu_to_be16(tmp);
1313                ret = kv_copy_bytes_to_smc(rdev,
1314                                           pi->dpm_table_start +
1315                                           offsetof(SMU7_Fusion_DpmTable, FpsHighT),
1316                                           (u8 *)&pi->fps_high_t,
1317                                           sizeof(u16), pi->sram_end);
1318
1319                tmp = 30;
1320                pi->fps_low_t = cpu_to_be16(tmp);
1321
1322                ret = kv_copy_bytes_to_smc(rdev,
1323                                           pi->dpm_table_start +
1324                                           offsetof(SMU7_Fusion_DpmTable, FpsLowT),
1325                                           (u8 *)&pi->fps_low_t,
1326                                           sizeof(u16), pi->sram_end);
1327
1328        }
1329        return ret;
1330}
1331
1332static void kv_init_powergate_state(struct radeon_device *rdev)
1333{
1334        struct kv_power_info *pi = kv_get_pi(rdev);
1335
1336        pi->uvd_power_gated = false;
1337        pi->vce_power_gated = false;
1338        pi->samu_power_gated = false;
1339        pi->acp_power_gated = false;
1340
1341}
1342
1343static int kv_enable_uvd_dpm(struct radeon_device *rdev, bool enable)
1344{
1345        return kv_notify_message_to_smu(rdev, enable ?
1346                                        PPSMC_MSG_UVDDPM_Enable : PPSMC_MSG_UVDDPM_Disable);
1347}
1348
1349#if 0
1350static int kv_enable_vce_dpm(struct radeon_device *rdev, bool enable)
1351{
1352        return kv_notify_message_to_smu(rdev, enable ?
1353                                        PPSMC_MSG_VCEDPM_Enable : PPSMC_MSG_VCEDPM_Disable);
1354}
1355#endif
1356
1357static int kv_enable_samu_dpm(struct radeon_device *rdev, bool enable)
1358{
1359        return kv_notify_message_to_smu(rdev, enable ?
1360                                        PPSMC_MSG_SAMUDPM_Enable : PPSMC_MSG_SAMUDPM_Disable);
1361}
1362
1363static int kv_enable_acp_dpm(struct radeon_device *rdev, bool enable)
1364{
1365        return kv_notify_message_to_smu(rdev, enable ?
1366                                        PPSMC_MSG_ACPDPM_Enable : PPSMC_MSG_ACPDPM_Disable);
1367}
1368
1369static int kv_update_uvd_dpm(struct radeon_device *rdev, bool gate)
1370{
1371        struct kv_power_info *pi = kv_get_pi(rdev);
1372        struct radeon_uvd_clock_voltage_dependency_table *table =
1373                &rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table;
1374        int ret;
1375
1376        if (!gate) {
1377                if (!pi->caps_uvd_dpm || table->count || pi->caps_stable_p_state)
1378                        pi->uvd_boot_level = table->count - 1;
1379                else
1380                        pi->uvd_boot_level = 0;
1381
1382                ret = kv_copy_bytes_to_smc(rdev,
1383                                           pi->dpm_table_start +
1384                                           offsetof(SMU7_Fusion_DpmTable, UvdBootLevel),
1385                                           (uint8_t *)&pi->uvd_boot_level,
1386                                           sizeof(u8), pi->sram_end);
1387                if (ret)
1388                        return ret;
1389
1390                if (!pi->caps_uvd_dpm ||
1391                    pi->caps_stable_p_state)
1392                        kv_send_msg_to_smc_with_parameter(rdev,
1393                                                          PPSMC_MSG_UVDDPM_SetEnabledMask,
1394                                                          (1 << pi->uvd_boot_level));
1395        }
1396
1397        return kv_enable_uvd_dpm(rdev, !gate);
1398}
1399
1400#if 0
1401static u8 kv_get_vce_boot_level(struct radeon_device *rdev)
1402{
1403        u8 i;
1404        struct radeon_vce_clock_voltage_dependency_table *table =
1405                &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
1406
1407        for (i = 0; i < table->count; i++) {
1408                if (table->entries[i].evclk >= 0) /* XXX */
1409                        break;
1410        }
1411
1412        return i;
1413}
1414
1415static int kv_update_vce_dpm(struct radeon_device *rdev,
1416                             struct radeon_ps *radeon_new_state,
1417                             struct radeon_ps *radeon_current_state)
1418{
1419        struct kv_power_info *pi = kv_get_pi(rdev);
1420        struct radeon_vce_clock_voltage_dependency_table *table =
1421                &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
1422        int ret;
1423
1424        if (radeon_new_state->evclk > 0 && radeon_current_state->evclk == 0) {
1425                if (pi->caps_stable_p_state)
1426                        pi->vce_boot_level = table->count - 1;
1427                else
1428                        pi->vce_boot_level = kv_get_vce_boot_level(rdev);
1429
1430                ret = kv_copy_bytes_to_smc(rdev,
1431                                           pi->dpm_table_start +
1432                                           offsetof(SMU7_Fusion_DpmTable, VceBootLevel),
1433                                           (u8 *)&pi->vce_boot_level,
1434                                           sizeof(u8),
1435                                           pi->sram_end);
1436                if (ret)
1437                        return ret;
1438
1439                if (pi->caps_stable_p_state)
1440                        kv_send_msg_to_smc_with_parameter(rdev,
1441                                                          PPSMC_MSG_VCEDPM_SetEnabledMask,
1442                                                          (1 << pi->vce_boot_level));
1443
1444                kv_enable_vce_dpm(rdev, true);
1445        } else if (radeon_new_state->evclk == 0 && radeon_current_state->evclk > 0) {
1446                kv_enable_vce_dpm(rdev, false);
1447        }
1448
1449        return 0;
1450}
1451#endif
1452
1453static int kv_update_samu_dpm(struct radeon_device *rdev, bool gate)
1454{
1455        struct kv_power_info *pi = kv_get_pi(rdev);
1456        struct radeon_clock_voltage_dependency_table *table =
1457                &rdev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table;
1458        int ret;
1459
1460        if (!gate) {
1461                if (pi->caps_stable_p_state)
1462                        pi->samu_boot_level = table->count - 1;
1463                else
1464                        pi->samu_boot_level = 0;
1465
1466                ret = kv_copy_bytes_to_smc(rdev,
1467                                           pi->dpm_table_start +
1468                                           offsetof(SMU7_Fusion_DpmTable, SamuBootLevel),
1469                                           (u8 *)&pi->samu_boot_level,
1470                                           sizeof(u8),
1471                                           pi->sram_end);
1472                if (ret)
1473                        return ret;
1474
1475                if (pi->caps_stable_p_state)
1476                        kv_send_msg_to_smc_with_parameter(rdev,
1477                                                          PPSMC_MSG_SAMUDPM_SetEnabledMask,
1478                                                          (1 << pi->samu_boot_level));
1479        }
1480
1481        return kv_enable_samu_dpm(rdev, !gate);
1482}
1483
1484static u8 kv_get_acp_boot_level(struct radeon_device *rdev)
1485{
1486        u8 i;
1487        struct radeon_clock_voltage_dependency_table *table =
1488                &rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table;
1489
1490        for (i = 0; i < table->count; i++) {
1491                if (table->entries[i].clk >= 0) /* XXX */
1492                        break;
1493        }
1494
1495        if (i >= table->count)
1496                i = table->count - 1;
1497
1498        return i;
1499}
1500
1501static void kv_update_acp_boot_level(struct radeon_device *rdev)
1502{
1503        struct kv_power_info *pi = kv_get_pi(rdev);
1504        u8 acp_boot_level;
1505
1506        if (!pi->caps_stable_p_state) {
1507                acp_boot_level = kv_get_acp_boot_level(rdev);
1508                if (acp_boot_level != pi->acp_boot_level) {
1509                        pi->acp_boot_level = acp_boot_level;
1510                        kv_send_msg_to_smc_with_parameter(rdev,
1511                                                          PPSMC_MSG_ACPDPM_SetEnabledMask,
1512                                                          (1 << pi->acp_boot_level));
1513                }
1514        }
1515}
1516
1517static int kv_update_acp_dpm(struct radeon_device *rdev, bool gate)
1518{
1519        struct kv_power_info *pi = kv_get_pi(rdev);
1520        struct radeon_clock_voltage_dependency_table *table =
1521                &rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table;
1522        int ret;
1523
1524        if (!gate) {
1525                if (pi->caps_stable_p_state)
1526                        pi->acp_boot_level = table->count - 1;
1527                else
1528                        pi->acp_boot_level = kv_get_acp_boot_level(rdev);
1529
1530                ret = kv_copy_bytes_to_smc(rdev,
1531                                           pi->dpm_table_start +
1532                                           offsetof(SMU7_Fusion_DpmTable, AcpBootLevel),
1533                                           (u8 *)&pi->acp_boot_level,
1534                                           sizeof(u8),
1535                                           pi->sram_end);
1536                if (ret)
1537                        return ret;
1538
1539                if (pi->caps_stable_p_state)
1540                        kv_send_msg_to_smc_with_parameter(rdev,
1541                                                          PPSMC_MSG_ACPDPM_SetEnabledMask,
1542                                                          (1 << pi->acp_boot_level));
1543        }
1544
1545        return kv_enable_acp_dpm(rdev, !gate);
1546}
1547
1548void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate)
1549{
1550        struct kv_power_info *pi = kv_get_pi(rdev);
1551
1552        if (pi->uvd_power_gated == gate)
1553                return;
1554
1555        pi->uvd_power_gated = gate;
1556
1557        if (gate) {
1558                if (pi->caps_uvd_pg) {
1559                        uvd_v1_0_stop(rdev);
1560                        cik_update_cg(rdev, RADEON_CG_BLOCK_UVD, false);
1561                }
1562                kv_update_uvd_dpm(rdev, gate);
1563                if (pi->caps_uvd_pg)
1564                        kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerOFF);
1565        } else {
1566                if (pi->caps_uvd_pg) {
1567                        kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerON);
1568                        uvd_v4_2_resume(rdev);
1569                        uvd_v1_0_start(rdev);
1570                        cik_update_cg(rdev, RADEON_CG_BLOCK_UVD, true);
1571                }
1572                kv_update_uvd_dpm(rdev, gate);
1573        }
1574}
1575
1576static void kv_dpm_powergate_vce(struct radeon_device *rdev, bool gate)
1577{
1578        struct kv_power_info *pi = kv_get_pi(rdev);
1579
1580        if (pi->vce_power_gated == gate)
1581                return;
1582
1583        pi->vce_power_gated = gate;
1584
1585        if (gate) {
1586                if (pi->caps_vce_pg)
1587                        kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerOFF);
1588        } else {
1589                if (pi->caps_vce_pg)
1590                        kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerON);
1591        }
1592}
1593
1594static void kv_dpm_powergate_samu(struct radeon_device *rdev, bool gate)
1595{
1596        struct kv_power_info *pi = kv_get_pi(rdev);
1597
1598        if (pi->samu_power_gated == gate)
1599                return;
1600
1601        pi->samu_power_gated = gate;
1602
1603        if (gate) {
1604                kv_update_samu_dpm(rdev, true);
1605                if (pi->caps_samu_pg)
1606                        kv_notify_message_to_smu(rdev, PPSMC_MSG_SAMPowerOFF);
1607        } else {
1608                if (pi->caps_samu_pg)
1609                        kv_notify_message_to_smu(rdev, PPSMC_MSG_SAMPowerON);
1610                kv_update_samu_dpm(rdev, false);
1611        }
1612}
1613
1614static void kv_dpm_powergate_acp(struct radeon_device *rdev, bool gate)
1615{
1616        struct kv_power_info *pi = kv_get_pi(rdev);
1617
1618        if (pi->acp_power_gated == gate)
1619                return;
1620
1621        if (rdev->family == CHIP_KABINI)
1622                return;
1623
1624        pi->acp_power_gated = gate;
1625
1626        if (gate) {
1627                kv_update_acp_dpm(rdev, true);
1628                if (pi->caps_acp_pg)
1629                        kv_notify_message_to_smu(rdev, PPSMC_MSG_ACPPowerOFF);
1630        } else {
1631                if (pi->caps_acp_pg)
1632                        kv_notify_message_to_smu(rdev, PPSMC_MSG_ACPPowerON);
1633                kv_update_acp_dpm(rdev, false);
1634        }
1635}
1636
1637static void kv_set_valid_clock_range(struct radeon_device *rdev,
1638                                     struct radeon_ps *new_rps)
1639{
1640        struct kv_ps *new_ps = kv_get_ps(new_rps);
1641        struct kv_power_info *pi = kv_get_pi(rdev);
1642        u32 i;
1643        struct radeon_clock_voltage_dependency_table *table =
1644                &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
1645
1646        if (table && table->count) {
1647                for (i = 0; i < pi->graphics_dpm_level_count; i++) {
1648                        if ((table->entries[i].clk >= new_ps->levels[0].sclk) ||
1649                            (i == (pi->graphics_dpm_level_count - 1))) {
1650                                pi->lowest_valid = i;
1651                                break;
1652                        }
1653                }
1654
1655                for (i = pi->graphics_dpm_level_count - 1; i > 0; i--) {
1656                        if (table->entries[i].clk <= new_ps->levels[new_ps->num_levels - 1].sclk)
1657                                break;
1658                }
1659                pi->highest_valid = i;
1660
1661                if (pi->lowest_valid > pi->highest_valid) {
1662                        if ((new_ps->levels[0].sclk - table->entries[pi->highest_valid].clk) >
1663                            (table->entries[pi->lowest_valid].clk - new_ps->levels[new_ps->num_levels - 1].sclk))
1664                                pi->highest_valid = pi->lowest_valid;
1665                        else
1666                                pi->lowest_valid =  pi->highest_valid;
1667                }
1668        } else {
1669                struct sumo_sclk_voltage_mapping_table *table =
1670                        &pi->sys_info.sclk_voltage_mapping_table;
1671
1672                for (i = 0; i < (int)pi->graphics_dpm_level_count; i++) {
1673                        if (table->entries[i].sclk_frequency >= new_ps->levels[0].sclk ||
1674                            i == (int)(pi->graphics_dpm_level_count - 1)) {
1675                                pi->lowest_valid = i;
1676                                break;
1677                        }
1678                }
1679
1680                for (i = pi->graphics_dpm_level_count - 1; i > 0; i--) {
1681                        if (table->entries[i].sclk_frequency <=
1682                            new_ps->levels[new_ps->num_levels - 1].sclk)
1683                                break;
1684                }
1685                pi->highest_valid = i;
1686
1687                if (pi->lowest_valid > pi->highest_valid) {
1688                        if ((new_ps->levels[0].sclk -
1689                             table->entries[pi->highest_valid].sclk_frequency) >
1690                            (table->entries[pi->lowest_valid].sclk_frequency -
1691                             new_ps->levels[new_ps->num_levels -1].sclk))
1692                                pi->highest_valid = pi->lowest_valid;
1693                        else
1694                                pi->lowest_valid =  pi->highest_valid;
1695                }
1696        }
1697}
1698
1699static int kv_update_dfs_bypass_settings(struct radeon_device *rdev,
1700                                         struct radeon_ps *new_rps)
1701{
1702        struct kv_ps *new_ps = kv_get_ps(new_rps);
1703        struct kv_power_info *pi = kv_get_pi(rdev);
1704        int ret = 0;
1705        u8 clk_bypass_cntl;
1706
1707        if (pi->caps_enable_dfs_bypass) {
1708                clk_bypass_cntl = new_ps->need_dfs_bypass ?
1709                        pi->graphics_level[pi->graphics_boot_level].ClkBypassCntl : 0;
1710                ret = kv_copy_bytes_to_smc(rdev,
1711                                           (pi->dpm_table_start +
1712                                            offsetof(SMU7_Fusion_DpmTable, GraphicsLevel) +
1713                                            (pi->graphics_boot_level * sizeof(SMU7_Fusion_GraphicsLevel)) +
1714                                            offsetof(SMU7_Fusion_GraphicsLevel, ClkBypassCntl)),
1715                                           &clk_bypass_cntl,
1716                                           sizeof(u8), pi->sram_end);
1717        }
1718
1719        return ret;
1720}
1721
1722static int kv_enable_nb_dpm(struct radeon_device *rdev)
1723{
1724        struct kv_power_info *pi = kv_get_pi(rdev);
1725        int ret = 0;
1726
1727        if (pi->enable_nb_dpm && !pi->nb_dpm_enabled) {
1728                ret = kv_notify_message_to_smu(rdev, PPSMC_MSG_NBDPM_Enable);
1729                if (ret == 0)
1730                        pi->nb_dpm_enabled = true;
1731        }
1732
1733        return ret;
1734}
1735
1736int kv_dpm_force_performance_level(struct radeon_device *rdev,
1737                                   enum radeon_dpm_forced_level level)
1738{
1739        int ret;
1740
1741        if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
1742                ret = kv_force_dpm_highest(rdev);
1743                if (ret)
1744                        return ret;
1745        } else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
1746                ret = kv_force_dpm_lowest(rdev);
1747                if (ret)
1748                        return ret;
1749        } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) {
1750                ret = kv_unforce_levels(rdev);
1751                if (ret)
1752                        return ret;
1753        }
1754
1755        rdev->pm.dpm.forced_level = level;
1756
1757        return 0;
1758}
1759
1760int kv_dpm_pre_set_power_state(struct radeon_device *rdev)
1761{
1762        struct kv_power_info *pi = kv_get_pi(rdev);
1763        struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
1764        struct radeon_ps *new_ps = &requested_ps;
1765
1766        kv_update_requested_ps(rdev, new_ps);
1767
1768        kv_apply_state_adjust_rules(rdev,
1769                                    &pi->requested_rps,
1770                                    &pi->current_rps);
1771
1772        return 0;
1773}
1774
1775int kv_dpm_set_power_state(struct radeon_device *rdev)
1776{
1777        struct kv_power_info *pi = kv_get_pi(rdev);
1778        struct radeon_ps *new_ps = &pi->requested_rps;
1779        /*struct radeon_ps *old_ps = &pi->current_rps;*/
1780        int ret;
1781
1782        cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
1783                             RADEON_CG_BLOCK_SDMA |
1784                             RADEON_CG_BLOCK_BIF |
1785                             RADEON_CG_BLOCK_HDP), false);
1786
1787        if (pi->bapm_enable) {
1788                ret = kv_smc_bapm_enable(rdev, rdev->pm.dpm.ac_power);
1789                if (ret) {
1790                        DRM_ERROR("kv_smc_bapm_enable failed\n");
1791                        return ret;
1792                }
1793        }
1794
1795        if (rdev->family == CHIP_KABINI) {
1796                if (pi->enable_dpm) {
1797                        kv_set_valid_clock_range(rdev, new_ps);
1798                        kv_update_dfs_bypass_settings(rdev, new_ps);
1799                        ret = kv_calculate_ds_divider(rdev);
1800                        if (ret) {
1801                                DRM_ERROR("kv_calculate_ds_divider failed\n");
1802                                return ret;
1803                        }
1804                        kv_calculate_nbps_level_settings(rdev);
1805                        kv_calculate_dpm_settings(rdev);
1806                        kv_force_lowest_valid(rdev);
1807                        kv_enable_new_levels(rdev);
1808                        kv_upload_dpm_settings(rdev);
1809                        kv_program_nbps_index_settings(rdev, new_ps);
1810                        kv_unforce_levels(rdev);
1811                        kv_set_enabled_levels(rdev);
1812                        kv_force_lowest_valid(rdev);
1813                        kv_unforce_levels(rdev);
1814#if 0
1815                        ret = kv_update_vce_dpm(rdev, new_ps, old_ps);
1816                        if (ret) {
1817                                DRM_ERROR("kv_update_vce_dpm failed\n");
1818                                return ret;
1819                        }
1820#endif
1821                        kv_update_sclk_t(rdev);
1822                }
1823        } else {
1824                if (pi->enable_dpm) {
1825                        kv_set_valid_clock_range(rdev, new_ps);
1826                        kv_update_dfs_bypass_settings(rdev, new_ps);
1827                        ret = kv_calculate_ds_divider(rdev);
1828                        if (ret) {
1829                                DRM_ERROR("kv_calculate_ds_divider failed\n");
1830                                return ret;
1831                        }
1832                        kv_calculate_nbps_level_settings(rdev);
1833                        kv_calculate_dpm_settings(rdev);
1834                        kv_freeze_sclk_dpm(rdev, true);
1835                        kv_upload_dpm_settings(rdev);
1836                        kv_program_nbps_index_settings(rdev, new_ps);
1837                        kv_freeze_sclk_dpm(rdev, false);
1838                        kv_set_enabled_levels(rdev);
1839#if 0
1840                        ret = kv_update_vce_dpm(rdev, new_ps, old_ps);
1841                        if (ret) {
1842                                DRM_ERROR("kv_update_vce_dpm failed\n");
1843                                return ret;
1844                        }
1845#endif
1846                        kv_update_acp_boot_level(rdev);
1847                        kv_update_sclk_t(rdev);
1848                        kv_enable_nb_dpm(rdev);
1849                }
1850        }
1851
1852        cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
1853                             RADEON_CG_BLOCK_SDMA |
1854                             RADEON_CG_BLOCK_BIF |
1855                             RADEON_CG_BLOCK_HDP), true);
1856
1857        return 0;
1858}
1859
1860void kv_dpm_post_set_power_state(struct radeon_device *rdev)
1861{
1862        struct kv_power_info *pi = kv_get_pi(rdev);
1863        struct radeon_ps *new_ps = &pi->requested_rps;
1864
1865        kv_update_current_ps(rdev, new_ps);
1866}
1867
1868void kv_dpm_setup_asic(struct radeon_device *rdev)
1869{
1870        sumo_take_smu_control(rdev, true);
1871        kv_init_powergate_state(rdev);
1872        kv_init_sclk_t(rdev);
1873}
1874
1875void kv_dpm_reset_asic(struct radeon_device *rdev)
1876{
1877        struct kv_power_info *pi = kv_get_pi(rdev);
1878
1879        if (rdev->family == CHIP_KABINI) {
1880                kv_force_lowest_valid(rdev);
1881                kv_init_graphics_levels(rdev);
1882                kv_program_bootup_state(rdev);
1883                kv_upload_dpm_settings(rdev);
1884                kv_force_lowest_valid(rdev);
1885                kv_unforce_levels(rdev);
1886        } else {
1887                kv_init_graphics_levels(rdev);
1888                kv_program_bootup_state(rdev);
1889                kv_freeze_sclk_dpm(rdev, true);
1890                kv_upload_dpm_settings(rdev);
1891                kv_freeze_sclk_dpm(rdev, false);
1892                kv_set_enabled_level(rdev, pi->graphics_boot_level);
1893        }
1894}
1895
1896//XXX use sumo_dpm_display_configuration_changed
1897
1898static void kv_construct_max_power_limits_table(struct radeon_device *rdev,
1899                                                struct radeon_clock_and_voltage_limits *table)
1900{
1901        struct kv_power_info *pi = kv_get_pi(rdev);
1902
1903        if (pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries > 0) {
1904                int idx = pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries - 1;
1905                table->sclk =
1906                        pi->sys_info.sclk_voltage_mapping_table.entries[idx].sclk_frequency;
1907                table->vddc =
1908                        kv_convert_2bit_index_to_voltage(rdev,
1909                                                         pi->sys_info.sclk_voltage_mapping_table.entries[idx].vid_2bit);
1910        }
1911
1912        table->mclk = pi->sys_info.nbp_memory_clock[0];
1913}
1914
1915static void kv_patch_voltage_values(struct radeon_device *rdev)
1916{
1917        int i;
1918        struct radeon_uvd_clock_voltage_dependency_table *table =
1919                &rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table;
1920
1921        if (table->count) {
1922                for (i = 0; i < table->count; i++)
1923                        table->entries[i].v =
1924                                kv_convert_8bit_index_to_voltage(rdev,
1925                                                                 table->entries[i].v);
1926        }
1927
1928}
1929
1930static void kv_construct_boot_state(struct radeon_device *rdev)
1931{
1932        struct kv_power_info *pi = kv_get_pi(rdev);
1933
1934        pi->boot_pl.sclk = pi->sys_info.bootup_sclk;
1935        pi->boot_pl.vddc_index = pi->sys_info.bootup_nb_voltage_index;
1936        pi->boot_pl.ds_divider_index = 0;
1937        pi->boot_pl.ss_divider_index = 0;
1938        pi->boot_pl.allow_gnb_slow = 1;
1939        pi->boot_pl.force_nbp_state = 0;
1940        pi->boot_pl.display_wm = 0;
1941        pi->boot_pl.vce_wm = 0;
1942}
1943
1944static int kv_force_dpm_highest(struct radeon_device *rdev)
1945{
1946        int ret;
1947        u32 enable_mask, i;
1948
1949        ret = kv_dpm_get_enable_mask(rdev, &enable_mask);
1950        if (ret)
1951                return ret;
1952
1953        for (i = SMU7_MAX_LEVELS_GRAPHICS - 1; i > 0; i--) {
1954                if (enable_mask & (1 << i))
1955                        break;
1956        }
1957
1958        if (rdev->family == CHIP_KABINI)
1959                return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i);
1960        else
1961                return kv_set_enabled_level(rdev, i);
1962}
1963
1964static int kv_force_dpm_lowest(struct radeon_device *rdev)
1965{
1966        int ret;
1967        u32 enable_mask, i;
1968
1969        ret = kv_dpm_get_enable_mask(rdev, &enable_mask);
1970        if (ret)
1971                return ret;
1972
1973        for (i = 0; i < SMU7_MAX_LEVELS_GRAPHICS; i++) {
1974                if (enable_mask & (1 << i))
1975                        break;
1976        }
1977
1978        if (rdev->family == CHIP_KABINI)
1979                return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i);
1980        else
1981                return kv_set_enabled_level(rdev, i);
1982}
1983
1984static u8 kv_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
1985                                             u32 sclk, u32 min_sclk_in_sr)
1986{
1987        struct kv_power_info *pi = kv_get_pi(rdev);
1988        u32 i;
1989        u32 temp;
1990        u32 min = (min_sclk_in_sr > KV_MINIMUM_ENGINE_CLOCK) ?
1991                min_sclk_in_sr : KV_MINIMUM_ENGINE_CLOCK;
1992
1993        if (sclk < min)
1994                return 0;
1995
1996        if (!pi->caps_sclk_ds)
1997                return 0;
1998
1999        for (i = KV_MAX_DEEPSLEEP_DIVIDER_ID; i > 0; i--) {
2000                temp = sclk / sumo_get_sleep_divider_from_id(i);
2001                if (temp >= min)
2002                        break;
2003        }
2004
2005        return (u8)i;
2006}
2007
2008static int kv_get_high_voltage_limit(struct radeon_device *rdev, int *limit)
2009{
2010        struct kv_power_info *pi = kv_get_pi(rdev);
2011        struct radeon_clock_voltage_dependency_table *table =
2012                &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
2013        int i;
2014
2015        if (table && table->count) {
2016                for (i = table->count - 1; i >= 0; i--) {
2017                        if (pi->high_voltage_t &&
2018                            (kv_convert_8bit_index_to_voltage(rdev, table->entries[i].v) <=
2019                             pi->high_voltage_t)) {
2020                                *limit = i;
2021                                return 0;
2022                        }
2023                }
2024        } else {
2025                struct sumo_sclk_voltage_mapping_table *table =
2026                        &pi->sys_info.sclk_voltage_mapping_table;
2027
2028                for (i = table->num_max_dpm_entries - 1; i >= 0; i--) {
2029                        if (pi->high_voltage_t &&
2030                            (kv_convert_2bit_index_to_voltage(rdev, table->entries[i].vid_2bit) <=
2031                             pi->high_voltage_t)) {
2032                                *limit = i;
2033                                return 0;
2034                        }
2035                }
2036        }
2037
2038        *limit = 0;
2039        return 0;
2040}
2041
2042static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
2043                                        struct radeon_ps *new_rps,
2044                                        struct radeon_ps *old_rps)
2045{
2046        struct kv_ps *ps = kv_get_ps(new_rps);
2047        struct kv_power_info *pi = kv_get_pi(rdev);
2048        u32 min_sclk = 10000; /* ??? */
2049        u32 sclk, mclk = 0;
2050        int i, limit;
2051        bool force_high;
2052        struct radeon_clock_voltage_dependency_table *table =
2053                &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
2054        u32 stable_p_state_sclk = 0;
2055        struct radeon_clock_and_voltage_limits *max_limits =
2056                &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
2057
2058        mclk = max_limits->mclk;
2059        sclk = min_sclk;
2060
2061        if (pi->caps_stable_p_state) {
2062                stable_p_state_sclk = (max_limits->sclk * 75) / 100;
2063
2064                for (i = table->count - 1; i >= 0; i++) {
2065                        if (stable_p_state_sclk >= table->entries[i].clk) {
2066                                stable_p_state_sclk = table->entries[i].clk;
2067                                break;
2068                        }
2069                }
2070
2071                if (i > 0)
2072                        stable_p_state_sclk = table->entries[0].clk;
2073
2074                sclk = stable_p_state_sclk;
2075        }
2076
2077        ps->need_dfs_bypass = true;
2078
2079        for (i = 0; i < ps->num_levels; i++) {
2080                if (ps->levels[i].sclk < sclk)
2081                        ps->levels[i].sclk = sclk;
2082        }
2083
2084        if (table && table->count) {
2085                for (i = 0; i < ps->num_levels; i++) {
2086                        if (pi->high_voltage_t &&
2087                            (pi->high_voltage_t <
2088                             kv_convert_8bit_index_to_voltage(rdev, ps->levels[i].vddc_index))) {
2089                                kv_get_high_voltage_limit(rdev, &limit);
2090                                ps->levels[i].sclk = table->entries[limit].clk;
2091                        }
2092                }
2093        } else {
2094                struct sumo_sclk_voltage_mapping_table *table =
2095                        &pi->sys_info.sclk_voltage_mapping_table;
2096
2097                for (i = 0; i < ps->num_levels; i++) {
2098                        if (pi->high_voltage_t &&
2099                            (pi->high_voltage_t <
2100                             kv_convert_8bit_index_to_voltage(rdev, ps->levels[i].vddc_index))) {
2101                                kv_get_high_voltage_limit(rdev, &limit);
2102                                ps->levels[i].sclk = table->entries[limit].sclk_frequency;
2103                        }
2104                }
2105        }
2106
2107        if (pi->caps_stable_p_state) {
2108                for (i = 0; i < ps->num_levels; i++) {
2109                        ps->levels[i].sclk = stable_p_state_sclk;
2110                }
2111        }
2112
2113        pi->video_start = new_rps->dclk || new_rps->vclk;
2114
2115        if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
2116            ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)
2117                pi->battery_state = true;
2118        else
2119                pi->battery_state = false;
2120
2121        if (rdev->family == CHIP_KABINI) {
2122                ps->dpm0_pg_nb_ps_lo = 0x1;
2123                ps->dpm0_pg_nb_ps_hi = 0x0;
2124                ps->dpmx_nb_ps_lo = 0x1;
2125                ps->dpmx_nb_ps_hi = 0x0;
2126        } else {
2127                ps->dpm0_pg_nb_ps_lo = 0x3;
2128                ps->dpm0_pg_nb_ps_hi = 0x0;
2129                ps->dpmx_nb_ps_lo = 0x3;
2130                ps->dpmx_nb_ps_hi = 0x0;
2131
2132                if (pi->sys_info.nb_dpm_enable) {
2133                        force_high = (mclk >= pi->sys_info.nbp_memory_clock[3]) ||
2134                                pi->video_start || (rdev->pm.dpm.new_active_crtc_count >= 3) ||
2135                                pi->disable_nb_ps3_in_battery;
2136                        ps->dpm0_pg_nb_ps_lo = force_high ? 0x2 : 0x3;
2137                        ps->dpm0_pg_nb_ps_hi = 0x2;
2138                        ps->dpmx_nb_ps_lo = force_high ? 0x2 : 0x3;
2139                        ps->dpmx_nb_ps_hi = 0x2;
2140                }
2141        }
2142}
2143
2144static void kv_dpm_power_level_enabled_for_throttle(struct radeon_device *rdev,
2145                                                    u32 index, bool enable)
2146{
2147        struct kv_power_info *pi = kv_get_pi(rdev);
2148
2149        pi->graphics_level[index].EnabledForThrottle = enable ? 1 : 0;
2150}
2151
2152static int kv_calculate_ds_divider(struct radeon_device *rdev)
2153{
2154        struct kv_power_info *pi = kv_get_pi(rdev);
2155        u32 sclk_in_sr = 10000; /* ??? */
2156        u32 i;
2157
2158        if (pi->lowest_valid > pi->highest_valid)
2159                return -EINVAL;
2160
2161        for (i = pi->lowest_valid; i <= pi->highest_valid; i++) {
2162                pi->graphics_level[i].DeepSleepDivId =
2163                        kv_get_sleep_divider_id_from_clock(rdev,
2164                                                           be32_to_cpu(pi->graphics_level[i].SclkFrequency),
2165                                                           sclk_in_sr);
2166        }
2167        return 0;
2168}
2169
2170static int kv_calculate_nbps_level_settings(struct radeon_device *rdev)
2171{
2172        struct kv_power_info *pi = kv_get_pi(rdev);
2173        u32 i;
2174        bool force_high;
2175        struct radeon_clock_and_voltage_limits *max_limits =
2176                &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
2177        u32 mclk = max_limits->mclk;
2178
2179        if (pi->lowest_valid > pi->highest_valid)
2180                return -EINVAL;
2181
2182        if (rdev->family == CHIP_KABINI) {
2183                for (i = pi->lowest_valid; i <= pi->highest_valid; i++) {
2184                        pi->graphics_level[i].GnbSlow = 1;
2185                        pi->graphics_level[i].ForceNbPs1 = 0;
2186                        pi->graphics_level[i].UpH = 0;
2187                }
2188
2189                if (!pi->sys_info.nb_dpm_enable)
2190                        return 0;
2191
2192                force_high = ((mclk >= pi->sys_info.nbp_memory_clock[3]) ||
2193                              (rdev->pm.dpm.new_active_crtc_count >= 3) || pi->video_start);
2194
2195                if (force_high) {
2196                        for (i = pi->lowest_valid; i <= pi->highest_valid; i++)
2197                                pi->graphics_level[i].GnbSlow = 0;
2198                } else {
2199                        if (pi->battery_state)
2200                                pi->graphics_level[0].ForceNbPs1 = 1;
2201
2202                        pi->graphics_level[1].GnbSlow = 0;
2203                        pi->graphics_level[2].GnbSlow = 0;
2204                        pi->graphics_level[3].GnbSlow = 0;
2205                        pi->graphics_level[4].GnbSlow = 0;
2206                }
2207        } else {
2208                for (i = pi->lowest_valid; i <= pi->highest_valid; i++) {
2209                        pi->graphics_level[i].GnbSlow = 1;
2210                        pi->graphics_level[i].ForceNbPs1 = 0;
2211                        pi->graphics_level[i].UpH = 0;
2212                }
2213
2214                if (pi->sys_info.nb_dpm_enable && pi->battery_state) {
2215                        pi->graphics_level[pi->lowest_valid].UpH = 0x28;
2216                        pi->graphics_level[pi->lowest_valid].GnbSlow = 0;
2217                        if (pi->lowest_valid != pi->highest_valid)
2218                                pi->graphics_level[pi->lowest_valid].ForceNbPs1 = 1;
2219                }
2220        }
2221        return 0;
2222}
2223
2224static int kv_calculate_dpm_settings(struct radeon_device *rdev)
2225{
2226        struct kv_power_info *pi = kv_get_pi(rdev);
2227        u32 i;
2228
2229        if (pi->lowest_valid > pi->highest_valid)
2230                return -EINVAL;
2231
2232        for (i = pi->lowest_valid; i <= pi->highest_valid; i++)
2233                pi->graphics_level[i].DisplayWatermark = (i == pi->highest_valid) ? 1 : 0;
2234
2235        return 0;
2236}
2237
2238static void kv_init_graphics_levels(struct radeon_device *rdev)
2239{
2240        struct kv_power_info *pi = kv_get_pi(rdev);
2241        u32 i;
2242        struct radeon_clock_voltage_dependency_table *table =
2243                &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
2244
2245        if (table && table->count) {
2246                u32 vid_2bit;
2247
2248                pi->graphics_dpm_level_count = 0;
2249                for (i = 0; i < table->count; i++) {
2250                        if (pi->high_voltage_t &&
2251                            (pi->high_voltage_t <
2252                             kv_convert_8bit_index_to_voltage(rdev, table->entries[i].v)))
2253                                break;
2254
2255                        kv_set_divider_value(rdev, i, table->entries[i].clk);
2256                        vid_2bit = sumo_convert_vid7_to_vid2(rdev,
2257                                                             &pi->sys_info.vid_mapping_table,
2258                                                             table->entries[i].v);
2259                        kv_set_vid(rdev, i, vid_2bit);
2260                        kv_set_at(rdev, i, pi->at[i]);
2261                        kv_dpm_power_level_enabled_for_throttle(rdev, i, true);
2262                        pi->graphics_dpm_level_count++;
2263                }
2264        } else {
2265                struct sumo_sclk_voltage_mapping_table *table =
2266                        &pi->sys_info.sclk_voltage_mapping_table;
2267
2268                pi->graphics_dpm_level_count = 0;
2269                for (i = 0; i < table->num_max_dpm_entries; i++) {
2270                        if (pi->high_voltage_t &&
2271                            pi->high_voltage_t <
2272                            kv_convert_2bit_index_to_voltage(rdev, table->entries[i].vid_2bit))
2273                                break;
2274
2275                        kv_set_divider_value(rdev, i, table->entries[i].sclk_frequency);
2276                        kv_set_vid(rdev, i, table->entries[i].vid_2bit);
2277                        kv_set_at(rdev, i, pi->at[i]);
2278                        kv_dpm_power_level_enabled_for_throttle(rdev, i, true);
2279                        pi->graphics_dpm_level_count++;
2280                }
2281        }
2282
2283        for (i = 0; i < SMU7_MAX_LEVELS_GRAPHICS; i++)
2284                kv_dpm_power_level_enable(rdev, i, false);
2285}
2286
2287static void kv_enable_new_levels(struct radeon_device *rdev)
2288{
2289        struct kv_power_info *pi = kv_get_pi(rdev);
2290        u32 i;
2291
2292        for (i = 0; i < SMU7_MAX_LEVELS_GRAPHICS; i++) {
2293                if (i >= pi->lowest_valid && i <= pi->highest_valid)
2294                        kv_dpm_power_level_enable(rdev, i, true);
2295        }
2296}
2297
2298static int kv_set_enabled_level(struct radeon_device *rdev, u32 level)
2299{
2300        u32 new_mask = (1 << level);
2301
2302        return kv_send_msg_to_smc_with_parameter(rdev,
2303                                                 PPSMC_MSG_SCLKDPM_SetEnabledMask,
2304                                                 new_mask);
2305}
2306
2307static int kv_set_enabled_levels(struct radeon_device *rdev)
2308{
2309        struct kv_power_info *pi = kv_get_pi(rdev);
2310        u32 i, new_mask = 0;
2311
2312        for (i = pi->lowest_valid; i <= pi->highest_valid; i++)
2313                new_mask |= (1 << i);
2314
2315        return kv_send_msg_to_smc_with_parameter(rdev,
2316                                                 PPSMC_MSG_SCLKDPM_SetEnabledMask,
2317                                                 new_mask);
2318}
2319
2320static void kv_program_nbps_index_settings(struct radeon_device *rdev,
2321                                           struct radeon_ps *new_rps)
2322{
2323        struct kv_ps *new_ps = kv_get_ps(new_rps);
2324        struct kv_power_info *pi = kv_get_pi(rdev);
2325        u32 nbdpmconfig1;
2326
2327        if (rdev->family == CHIP_KABINI)
2328                return;
2329
2330        if (pi->sys_info.nb_dpm_enable) {
2331                nbdpmconfig1 = RREG32_SMC(NB_DPM_CONFIG_1);
2332                nbdpmconfig1 &= ~(Dpm0PgNbPsLo_MASK | Dpm0PgNbPsHi_MASK |
2333                                  DpmXNbPsLo_MASK | DpmXNbPsHi_MASK);
2334                nbdpmconfig1 |= (Dpm0PgNbPsLo(new_ps->dpm0_pg_nb_ps_lo) |
2335                                 Dpm0PgNbPsHi(new_ps->dpm0_pg_nb_ps_hi) |
2336                                 DpmXNbPsLo(new_ps->dpmx_nb_ps_lo) |
2337                                 DpmXNbPsHi(new_ps->dpmx_nb_ps_hi));
2338                WREG32_SMC(NB_DPM_CONFIG_1, nbdpmconfig1);
2339        }
2340}
2341
2342static int kv_set_thermal_temperature_range(struct radeon_device *rdev,
2343                                            int min_temp, int max_temp)
2344{
2345        int low_temp = 0 * 1000;
2346        int high_temp = 255 * 1000;
2347        u32 tmp;
2348
2349        if (low_temp < min_temp)
2350                low_temp = min_temp;
2351        if (high_temp > max_temp)
2352                high_temp = max_temp;
2353        if (high_temp < low_temp) {
2354                DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
2355                return -EINVAL;
2356        }
2357
2358        tmp = RREG32_SMC(CG_THERMAL_INT_CTRL);
2359        tmp &= ~(DIG_THERM_INTH_MASK | DIG_THERM_INTL_MASK);
2360        tmp |= (DIG_THERM_INTH(49 + (high_temp / 1000)) |
2361                DIG_THERM_INTL(49 + (low_temp / 1000)));
2362        WREG32_SMC(CG_THERMAL_INT_CTRL, tmp);
2363
2364        rdev->pm.dpm.thermal.min_temp = low_temp;
2365        rdev->pm.dpm.thermal.max_temp = high_temp;
2366
2367        return 0;
2368}
2369
2370union igp_info {
2371        struct _ATOM_INTEGRATED_SYSTEM_INFO info;
2372        struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
2373        struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 info_5;
2374        struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
2375        struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
2376        struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8;
2377};
2378
2379static int kv_parse_sys_info_table(struct radeon_device *rdev)
2380{
2381        struct kv_power_info *pi = kv_get_pi(rdev);
2382        struct radeon_mode_info *mode_info = &rdev->mode_info;
2383        int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
2384        union igp_info *igp_info;
2385        u8 frev, crev;
2386        u16 data_offset;
2387        int i;
2388
2389        if (atom_parse_data_header(mode_info->atom_context, index, NULL,
2390                                   &frev, &crev, &data_offset)) {
2391                igp_info = (union igp_info *)(mode_info->atom_context->bios +
2392                                              data_offset);
2393
2394                if (crev != 8) {
2395                        DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
2396                        return -EINVAL;
2397                }
2398                pi->sys_info.bootup_sclk = le32_to_cpu(igp_info->info_8.ulBootUpEngineClock);
2399                pi->sys_info.bootup_uma_clk = le32_to_cpu(igp_info->info_8.ulBootUpUMAClock);
2400                pi->sys_info.bootup_nb_voltage_index =
2401                        le16_to_cpu(igp_info->info_8.usBootUpNBVoltage);
2402                if (igp_info->info_8.ucHtcTmpLmt == 0)
2403                        pi->sys_info.htc_tmp_lmt = 203;
2404                else
2405                        pi->sys_info.htc_tmp_lmt = igp_info->info_8.ucHtcTmpLmt;
2406                if (igp_info->info_8.ucHtcHystLmt == 0)
2407                        pi->sys_info.htc_hyst_lmt = 5;
2408                else
2409                        pi->sys_info.htc_hyst_lmt = igp_info->info_8.ucHtcHystLmt;
2410                if (pi->sys_info.htc_tmp_lmt <= pi->sys_info.htc_hyst_lmt) {
2411                        DRM_ERROR("The htcTmpLmt should be larger than htcHystLmt.\n");
2412                }
2413
2414                if (le32_to_cpu(igp_info->info_8.ulSystemConfig) & (1 << 3))
2415                        pi->sys_info.nb_dpm_enable = true;
2416                else
2417                        pi->sys_info.nb_dpm_enable = false;
2418
2419                for (i = 0; i < KV_NUM_NBPSTATES; i++) {
2420                        pi->sys_info.nbp_memory_clock[i] =
2421                                le32_to_cpu(igp_info->info_8.ulNbpStateMemclkFreq[i]);
2422                        pi->sys_info.nbp_n_clock[i] =
2423                                le32_to_cpu(igp_info->info_8.ulNbpStateNClkFreq[i]);
2424                }
2425                if (le32_to_cpu(igp_info->info_8.ulGPUCapInfo) &
2426                    SYS_INFO_GPUCAPS__ENABEL_DFS_BYPASS)
2427                        pi->caps_enable_dfs_bypass = true;
2428
2429                sumo_construct_sclk_voltage_mapping_table(rdev,
2430                                                          &pi->sys_info.sclk_voltage_mapping_table,
2431                                                          igp_info->info_8.sAvail_SCLK);
2432
2433                sumo_construct_vid_mapping_table(rdev,
2434                                                 &pi->sys_info.vid_mapping_table,
2435                                                 igp_info->info_8.sAvail_SCLK);
2436
2437                kv_construct_max_power_limits_table(rdev,
2438                                                    &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac);
2439        }
2440        return 0;
2441}
2442
2443union power_info {
2444        struct _ATOM_POWERPLAY_INFO info;
2445        struct _ATOM_POWERPLAY_INFO_V2 info_2;
2446        struct _ATOM_POWERPLAY_INFO_V3 info_3;
2447        struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
2448        struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
2449        struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
2450};
2451
2452union pplib_clock_info {
2453        struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
2454        struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
2455        struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
2456        struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
2457};
2458
2459union pplib_power_state {
2460        struct _ATOM_PPLIB_STATE v1;
2461        struct _ATOM_PPLIB_STATE_V2 v2;
2462};
2463
2464static void kv_patch_boot_state(struct radeon_device *rdev,
2465                                struct kv_ps *ps)
2466{
2467        struct kv_power_info *pi = kv_get_pi(rdev);
2468
2469        ps->num_levels = 1;
2470        ps->levels[0] = pi->boot_pl;
2471}
2472
2473static void kv_parse_pplib_non_clock_info(struct radeon_device *rdev,
2474                                          struct radeon_ps *rps,
2475                                          struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
2476                                          u8 table_rev)
2477{
2478        struct kv_ps *ps = kv_get_ps(rps);
2479
2480        rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
2481        rps->class = le16_to_cpu(non_clock_info->usClassification);
2482        rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
2483
2484        if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
2485                rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
2486                rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
2487        } else {
2488                rps->vclk = 0;
2489                rps->dclk = 0;
2490        }
2491
2492        if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
2493                rdev->pm.dpm.boot_ps = rps;
2494                kv_patch_boot_state(rdev, ps);
2495        }
2496        if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
2497                rdev->pm.dpm.uvd_ps = rps;
2498}
2499
2500static void kv_parse_pplib_clock_info(struct radeon_device *rdev,
2501                                      struct radeon_ps *rps, int index,
2502                                        union pplib_clock_info *clock_info)
2503{
2504        struct kv_power_info *pi = kv_get_pi(rdev);
2505        struct kv_ps *ps = kv_get_ps(rps);
2506        struct kv_pl *pl = &ps->levels[index];
2507        u32 sclk;
2508
2509        sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
2510        sclk |= clock_info->sumo.ucEngineClockHigh << 16;
2511        pl->sclk = sclk;
2512        pl->vddc_index = clock_info->sumo.vddcIndex;
2513
2514        ps->num_levels = index + 1;
2515
2516        if (pi->caps_sclk_ds) {
2517                pl->ds_divider_index = 5;
2518                pl->ss_divider_index = 5;
2519        }
2520}
2521
2522static int kv_parse_power_table(struct radeon_device *rdev)
2523{
2524        struct radeon_mode_info *mode_info = &rdev->mode_info;
2525        struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
2526        union pplib_power_state *power_state;
2527        int i, j, k, non_clock_array_index, clock_array_index;
2528        union pplib_clock_info *clock_info;
2529        struct _StateArray *state_array;
2530        struct _ClockInfoArray *clock_info_array;
2531        struct _NonClockInfoArray *non_clock_info_array;
2532        union power_info *power_info;
2533        int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
2534        u16 data_offset;
2535        u8 frev, crev;
2536        u8 *power_state_offset;
2537        struct kv_ps *ps;
2538
2539        if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
2540                                   &frev, &crev, &data_offset))
2541                return -EINVAL;
2542        power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
2543
2544        state_array = (struct _StateArray *)
2545                (mode_info->atom_context->bios + data_offset +
2546                 le16_to_cpu(power_info->pplib.usStateArrayOffset));
2547        clock_info_array = (struct _ClockInfoArray *)
2548                (mode_info->atom_context->bios + data_offset +
2549                 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
2550        non_clock_info_array = (struct _NonClockInfoArray *)
2551                (mode_info->atom_context->bios + data_offset +
2552                 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
2553
2554        rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
2555                                  state_array->ucNumEntries, GFP_KERNEL);
2556        if (!rdev->pm.dpm.ps)
2557                return -ENOMEM;
2558        power_state_offset = (u8 *)state_array->states;
2559        rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
2560        rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
2561        rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
2562        for (i = 0; i < state_array->ucNumEntries; i++) {
2563                u8 *idx;
2564                power_state = (union pplib_power_state *)power_state_offset;
2565                non_clock_array_index = power_state->v2.nonClockInfoIndex;
2566                non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
2567                        &non_clock_info_array->nonClockInfo[non_clock_array_index];
2568                if (!rdev->pm.power_state[i].clock_info)
2569                        return -EINVAL;
2570                ps = kzalloc(sizeof(struct kv_ps), GFP_KERNEL);
2571                if (ps == NULL) {
2572                        kfree(rdev->pm.dpm.ps);
2573                        return -ENOMEM;
2574                }
2575                rdev->pm.dpm.ps[i].ps_priv = ps;
2576                k = 0;
2577                idx = (u8 *)&power_state->v2.clockInfoIndex[0];
2578                for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
2579                        clock_array_index = idx[j];
2580                        if (clock_array_index >= clock_info_array->ucNumEntries)
2581                                continue;
2582                        if (k >= SUMO_MAX_HARDWARE_POWERLEVELS)
2583                                break;
2584                        clock_info = (union pplib_clock_info *)
2585                                ((u8 *)&clock_info_array->clockInfo[0] +
2586                                 (clock_array_index * clock_info_array->ucEntrySize));
2587                        kv_parse_pplib_clock_info(rdev,
2588                                                  &rdev->pm.dpm.ps[i], k,
2589                                                  clock_info);
2590                        k++;
2591                }
2592                kv_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
2593                                              non_clock_info,
2594                                              non_clock_info_array->ucEntrySize);
2595                power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
2596        }
2597        rdev->pm.dpm.num_ps = state_array->ucNumEntries;
2598        return 0;
2599}
2600
2601int kv_dpm_init(struct radeon_device *rdev)
2602{
2603        struct kv_power_info *pi;
2604        int ret, i;
2605
2606        pi = kzalloc(sizeof(struct kv_power_info), GFP_KERNEL);
2607        if (pi == NULL)
2608                return -ENOMEM;
2609        rdev->pm.dpm.priv = pi;
2610
2611        ret = r600_parse_extended_power_table(rdev);
2612        if (ret)
2613                return ret;
2614
2615        for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++)
2616                pi->at[i] = TRINITY_AT_DFLT;
2617
2618        pi->sram_end = SMC_RAM_END;
2619
2620        if (rdev->family == CHIP_KABINI)
2621                pi->high_voltage_t = 4001;
2622
2623        pi->enable_nb_dpm = true;
2624
2625        pi->caps_power_containment = true;
2626        pi->caps_cac = true;
2627        pi->enable_didt = false;
2628        if (pi->enable_didt) {
2629                pi->caps_sq_ramping = true;
2630                pi->caps_db_ramping = true;
2631                pi->caps_td_ramping = true;
2632                pi->caps_tcp_ramping = true;
2633        }
2634
2635        pi->caps_sclk_ds = true;
2636        pi->enable_auto_thermal_throttling = true;
2637        pi->disable_nb_ps3_in_battery = false;
2638        pi->bapm_enable = false;
2639        pi->voltage_drop_t = 0;
2640        pi->caps_sclk_throttle_low_notification = false;
2641        pi->caps_fps = false; /* true? */
2642        pi->caps_uvd_pg = true;
2643        pi->caps_uvd_dpm = true;
2644        pi->caps_vce_pg = false;
2645        pi->caps_samu_pg = false;
2646        pi->caps_acp_pg = false;
2647        pi->caps_stable_p_state = false;
2648
2649        ret = kv_parse_sys_info_table(rdev);
2650        if (ret)
2651                return ret;
2652
2653        kv_patch_voltage_values(rdev);
2654        kv_construct_boot_state(rdev);
2655
2656        ret = kv_parse_power_table(rdev);
2657        if (ret)
2658                return ret;
2659
2660        pi->enable_dpm = true;
2661
2662        return 0;
2663}
2664
2665void kv_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
2666                                                    struct seq_file *m)
2667{
2668        struct kv_power_info *pi = kv_get_pi(rdev);
2669        u32 current_index =
2670                (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) & CURR_SCLK_INDEX_MASK) >>
2671                CURR_SCLK_INDEX_SHIFT;
2672        u32 sclk, tmp;
2673        u16 vddc;
2674
2675        if (current_index >= SMU__NUM_SCLK_DPM_STATE) {
2676                seq_printf(m, "invalid dpm profile %d\n", current_index);
2677        } else {
2678                sclk = be32_to_cpu(pi->graphics_level[current_index].SclkFrequency);
2679                tmp = (RREG32_SMC(SMU_VOLTAGE_STATUS) & SMU_VOLTAGE_CURRENT_LEVEL_MASK) >>
2680                        SMU_VOLTAGE_CURRENT_LEVEL_SHIFT;
2681                vddc = kv_convert_8bit_index_to_voltage(rdev, (u16)tmp);
2682                seq_printf(m, "power level %d    sclk: %u vddc: %u\n",
2683                           current_index, sclk, vddc);
2684        }
2685}
2686
2687void kv_dpm_print_power_state(struct radeon_device *rdev,
2688                              struct radeon_ps *rps)
2689{
2690        int i;
2691        struct kv_ps *ps = kv_get_ps(rps);
2692
2693        r600_dpm_print_class_info(rps->class, rps->class2);
2694        r600_dpm_print_cap_info(rps->caps);
2695        printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
2696        for (i = 0; i < ps->num_levels; i++) {
2697                struct kv_pl *pl = &ps->levels[i];
2698                printk("\t\tpower level %d    sclk: %u vddc: %u\n",
2699                       i, pl->sclk,
2700                       kv_convert_8bit_index_to_voltage(rdev, pl->vddc_index));
2701        }
2702        r600_dpm_print_ps_status(rdev, rps);
2703}
2704
2705void kv_dpm_fini(struct radeon_device *rdev)
2706{
2707        int i;
2708
2709        for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
2710                kfree(rdev->pm.dpm.ps[i].ps_priv);
2711        }
2712        kfree(rdev->pm.dpm.ps);
2713        kfree(rdev->pm.dpm.priv);
2714        r600_free_extended_power_table(rdev);
2715}
2716
2717void kv_dpm_display_configuration_changed(struct radeon_device *rdev)
2718{
2719
2720}
2721
2722u32 kv_dpm_get_sclk(struct radeon_device *rdev, bool low)
2723{
2724        struct kv_power_info *pi = kv_get_pi(rdev);
2725        struct kv_ps *requested_state = kv_get_ps(&pi->requested_rps);
2726
2727        if (low)
2728                return requested_state->levels[0].sclk;
2729        else
2730                return requested_state->levels[requested_state->num_levels - 1].sclk;
2731}
2732
2733u32 kv_dpm_get_mclk(struct radeon_device *rdev, bool low)
2734{
2735        struct kv_power_info *pi = kv_get_pi(rdev);
2736
2737        return pi->sys_info.bootup_uma_clk;
2738}
2739
2740