linux/drivers/gpu/drm/amd/amdgpu/soc15_common.h
<<
>>
Prefs
   1/*
   2 * Copyright 2016 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#ifndef __SOC15_COMMON_H__
  25#define __SOC15_COMMON_H__
  26
  27/* Register Access Macros */
  28#define SOC15_REG_OFFSET(ip, inst, reg) (adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)
  29
  30#define WREG32_FIELD15(ip, idx, reg, field, val)        \
  31        WREG32(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg,  \
  32        (RREG32(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg) \
  33        & ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field))
  34
  35#define RREG32_SOC15(ip, inst, reg) \
  36        RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)
  37
  38#define RREG32_SOC15_NO_KIQ(ip, inst, reg) \
  39        RREG32_NO_KIQ(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)
  40
  41#define RREG32_SOC15_OFFSET(ip, inst, reg, offset) \
  42        RREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset)
  43
  44#define WREG32_SOC15(ip, inst, reg, value) \
  45        WREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg), value)
  46
  47#define WREG32_SOC15_NO_KIQ(ip, inst, reg, value) \
  48        WREG32_NO_KIQ((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg), value)
  49
  50#define WREG32_SOC15_OFFSET(ip, inst, reg, offset, value) \
  51        WREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, value)
  52
  53#define SOC15_WAIT_ON_RREG(ip, inst, reg, expected_value, mask) \
  54({      int ret = 0;                                            \
  55        do {                                                    \
  56                uint32_t old_ = 0;                              \
  57                uint32_t tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \
  58                uint32_t loop = adev->usec_timeout;             \
  59                ret = 0;                                        \
  60                while ((tmp_ & (mask)) != (expected_value)) {   \
  61                        if (old_ != tmp_) {                     \
  62                                loop = adev->usec_timeout;      \
  63                                old_ = tmp_;                    \
  64                        } else                                  \
  65                                udelay(1);                      \
  66                        tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \
  67                        loop--;                                 \
  68                        if (!loop) {                            \
  69                                DRM_WARN("Register(%d) [%s] failed to reach value 0x%08x != 0x%08x\n", \
  70                                          inst, #reg, (unsigned)expected_value, (unsigned)(tmp_ & (mask))); \
  71                                ret = -ETIMEDOUT;               \
  72                                break;                          \
  73                        }                                       \
  74                }                                               \
  75        } while (0);                                            \
  76        ret;                                                    \
  77})
  78
  79#define WREG32_RLC(reg, value) \
  80        do { \
  81                if (adev->gfx.rlc.funcs->rlcg_wreg) \
  82                        adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, value, 0); \
  83                else \
  84                        WREG32(reg, value);     \
  85        } while (0)
  86
  87#define WREG32_RLC_EX(prefix, reg, value) \
  88        do {                                                    \
  89                if (amdgpu_sriov_fullaccess(adev)) {    \
  90                        uint32_t i = 0; \
  91                        uint32_t retries = 50000;       \
  92                        uint32_t r0 = adev->reg_offset[GC_HWIP][0][prefix##SCRATCH_REG0_BASE_IDX] + prefix##SCRATCH_REG0;       \
  93                        uint32_t r1 = adev->reg_offset[GC_HWIP][0][prefix##SCRATCH_REG1_BASE_IDX] + prefix##SCRATCH_REG1;       \
  94                        uint32_t spare_int = adev->reg_offset[GC_HWIP][0][prefix##RLC_SPARE_INT_BASE_IDX] + prefix##RLC_SPARE_INT;      \
  95                        WREG32(r0, value);      \
  96                        WREG32(r1, (reg | 0x80000000)); \
  97                        WREG32(spare_int, 0x1); \
  98                        for (i = 0; i < retries; i++) { \
  99                                u32 tmp = RREG32(r1);   \
 100                                if (!(tmp & 0x80000000))        \
 101                                        break;  \
 102                                udelay(10);     \
 103                        }       \
 104                        if (i >= retries)       \
 105                                pr_err("timeout: rlcg program reg:0x%05x failed !\n", reg);     \
 106                } else {        \
 107                        WREG32(reg, value); \
 108                }       \
 109        } while (0)
 110
 111#define WREG32_SOC15_RLC_SHADOW(ip, inst, reg, value) \
 112        WREG32_RLC((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg), value)
 113
 114#define RREG32_RLC(reg) \
 115        (adev->gfx.rlc.funcs->rlcg_rreg ? \
 116                adev->gfx.rlc.funcs->rlcg_rreg(adev, reg, 0) : RREG32(reg))
 117
 118#define WREG32_RLC_NO_KIQ(reg, value) \
 119        do { \
 120                if (adev->gfx.rlc.funcs->rlcg_wreg) \
 121                        adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, value, AMDGPU_REGS_NO_KIQ); \
 122                else \
 123                        WREG32_NO_KIQ(reg, value);      \
 124        } while (0)
 125
 126#define RREG32_RLC_NO_KIQ(reg) \
 127        (adev->gfx.rlc.funcs->rlcg_rreg ? \
 128                adev->gfx.rlc.funcs->rlcg_rreg(adev, reg, AMDGPU_REGS_NO_KIQ) : RREG32_NO_KIQ(reg))
 129
 130#define WREG32_SOC15_RLC_SHADOW_EX(prefix, ip, inst, reg, value) \
 131        do {                                                    \
 132                uint32_t target_reg = adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg;\
 133                if (amdgpu_sriov_fullaccess(adev)) {    \
 134                        uint32_t r2 = adev->reg_offset[GC_HWIP][0][prefix##SCRATCH_REG1_BASE_IDX] + prefix##SCRATCH_REG2;       \
 135                        uint32_t r3 = adev->reg_offset[GC_HWIP][0][prefix##SCRATCH_REG1_BASE_IDX] + prefix##SCRATCH_REG3;       \
 136                        uint32_t grbm_cntl = adev->reg_offset[GC_HWIP][0][prefix##GRBM_GFX_CNTL_BASE_IDX] + prefix##GRBM_GFX_CNTL;   \
 137                        uint32_t grbm_idx = adev->reg_offset[GC_HWIP][0][prefix##GRBM_GFX_INDEX_BASE_IDX] + prefix##GRBM_GFX_INDEX;   \
 138                        if (target_reg == grbm_cntl) \
 139                                WREG32(r2, value);      \
 140                        else if (target_reg == grbm_idx) \
 141                                WREG32(r3, value);      \
 142                        WREG32(target_reg, value);      \
 143                } else {        \
 144                        WREG32(target_reg, value); \
 145                }       \
 146        } while (0)
 147
 148#define RREG32_SOC15_RLC(ip, inst, reg) \
 149        RREG32_RLC(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)
 150
 151#define WREG32_SOC15_RLC(ip, inst, reg, value) \
 152        do {                                                    \
 153                uint32_t target_reg = adev->reg_offset[ip##_HWIP][0][reg##_BASE_IDX] + reg;\
 154                WREG32_RLC(target_reg, value); \
 155        } while (0)
 156
 157#define WREG32_SOC15_RLC_EX(prefix, ip, inst, reg, value) \
 158        do {                                                    \
 159                        uint32_t target_reg = adev->reg_offset[GC_HWIP][0][reg##_BASE_IDX] + reg;\
 160                        WREG32_RLC_EX(prefix, target_reg, value); \
 161        } while (0)
 162
 163#define WREG32_FIELD15_RLC(ip, idx, reg, field, val)   \
 164        WREG32_RLC((adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg), \
 165        (RREG32_RLC(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg) \
 166        & ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field))
 167
 168#define WREG32_SOC15_OFFSET_RLC(ip, inst, reg, offset, value) \
 169        WREG32_RLC(((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset), value)
 170
 171#define RREG32_SOC15_OFFSET_RLC(ip, inst, reg, offset) \
 172        RREG32_RLC(((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset))
 173
 174#endif
 175