root/drivers/gpu/drm/radeon/rv770_smc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rv770_set_smc_sram_address
  2. rv770_copy_bytes_to_smc
  3. rv770_program_interrupt_vectors
  4. rv770_start_smc
  5. rv770_reset_smc
  6. rv770_stop_smc_clock
  7. rv770_start_smc_clock
  8. rv770_is_smc_running
  9. rv770_send_msg_to_smc
  10. rv770_wait_for_smc_inactive
  11. rv770_clear_smc_sram
  12. rv770_load_smc_ucode
  13. rv770_read_smc_sram_dword
  14. rv770_write_smc_sram_dword

   1 /*
   2  * Copyright 2011 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  * Authors: Alex Deucher
  23  */
  24 
  25 #include <linux/firmware.h>
  26 
  27 #include "radeon.h"
  28 #include "rv770d.h"
  29 #include "rv770_dpm.h"
  30 #include "rv770_smc.h"
  31 #include "atom.h"
  32 #include "radeon_ucode.h"
  33 
  34 #define FIRST_SMC_INT_VECT_REG 0xFFD8
  35 #define FIRST_INT_VECT_S19     0xFFC0
  36 
  37 static const u8 rv770_smc_int_vectors[] =
  38 {
  39         0x08, 0x10, 0x08, 0x10,
  40         0x08, 0x10, 0x08, 0x10,
  41         0x08, 0x10, 0x08, 0x10,
  42         0x08, 0x10, 0x08, 0x10,
  43         0x08, 0x10, 0x08, 0x10,
  44         0x08, 0x10, 0x08, 0x10,
  45         0x08, 0x10, 0x08, 0x10,
  46         0x08, 0x10, 0x08, 0x10,
  47         0x08, 0x10, 0x08, 0x10,
  48         0x08, 0x10, 0x08, 0x10,
  49         0x08, 0x10, 0x08, 0x10,
  50         0x08, 0x10, 0x08, 0x10,
  51         0x08, 0x10, 0x0C, 0xD7,
  52         0x08, 0x2B, 0x08, 0x10,
  53         0x03, 0x51, 0x03, 0x51,
  54         0x03, 0x51, 0x03, 0x51
  55 };
  56 
  57 static const u8 rv730_smc_int_vectors[] =
  58 {
  59         0x08, 0x15, 0x08, 0x15,
  60         0x08, 0x15, 0x08, 0x15,
  61         0x08, 0x15, 0x08, 0x15,
  62         0x08, 0x15, 0x08, 0x15,
  63         0x08, 0x15, 0x08, 0x15,
  64         0x08, 0x15, 0x08, 0x15,
  65         0x08, 0x15, 0x08, 0x15,
  66         0x08, 0x15, 0x08, 0x15,
  67         0x08, 0x15, 0x08, 0x15,
  68         0x08, 0x15, 0x08, 0x15,
  69         0x08, 0x15, 0x08, 0x15,
  70         0x08, 0x15, 0x08, 0x15,
  71         0x08, 0x15, 0x0C, 0xBB,
  72         0x08, 0x30, 0x08, 0x15,
  73         0x03, 0x56, 0x03, 0x56,
  74         0x03, 0x56, 0x03, 0x56
  75 };
  76 
  77 static const u8 rv710_smc_int_vectors[] =
  78 {
  79         0x08, 0x04, 0x08, 0x04,
  80         0x08, 0x04, 0x08, 0x04,
  81         0x08, 0x04, 0x08, 0x04,
  82         0x08, 0x04, 0x08, 0x04,
  83         0x08, 0x04, 0x08, 0x04,
  84         0x08, 0x04, 0x08, 0x04,
  85         0x08, 0x04, 0x08, 0x04,
  86         0x08, 0x04, 0x08, 0x04,
  87         0x08, 0x04, 0x08, 0x04,
  88         0x08, 0x04, 0x08, 0x04,
  89         0x08, 0x04, 0x08, 0x04,
  90         0x08, 0x04, 0x08, 0x04,
  91         0x08, 0x04, 0x0C, 0xCB,
  92         0x08, 0x1F, 0x08, 0x04,
  93         0x03, 0x51, 0x03, 0x51,
  94         0x03, 0x51, 0x03, 0x51
  95 };
  96 
  97 static const u8 rv740_smc_int_vectors[] =
  98 {
  99         0x08, 0x10, 0x08, 0x10,
 100         0x08, 0x10, 0x08, 0x10,
 101         0x08, 0x10, 0x08, 0x10,
 102         0x08, 0x10, 0x08, 0x10,
 103         0x08, 0x10, 0x08, 0x10,
 104         0x08, 0x10, 0x08, 0x10,
 105         0x08, 0x10, 0x08, 0x10,
 106         0x08, 0x10, 0x08, 0x10,
 107         0x08, 0x10, 0x08, 0x10,
 108         0x08, 0x10, 0x08, 0x10,
 109         0x08, 0x10, 0x08, 0x10,
 110         0x08, 0x10, 0x08, 0x10,
 111         0x08, 0x10, 0x0C, 0xD7,
 112         0x08, 0x2B, 0x08, 0x10,
 113         0x03, 0x51, 0x03, 0x51,
 114         0x03, 0x51, 0x03, 0x51
 115 };
 116 
 117 static const u8 cedar_smc_int_vectors[] =
 118 {
 119         0x0B, 0x05, 0x0B, 0x05,
 120         0x0B, 0x05, 0x0B, 0x05,
 121         0x0B, 0x05, 0x0B, 0x05,
 122         0x0B, 0x05, 0x0B, 0x05,
 123         0x0B, 0x05, 0x0B, 0x05,
 124         0x0B, 0x05, 0x0B, 0x05,
 125         0x0B, 0x05, 0x0B, 0x05,
 126         0x0B, 0x05, 0x0B, 0x05,
 127         0x0B, 0x05, 0x0B, 0x05,
 128         0x0B, 0x05, 0x0B, 0x05,
 129         0x0B, 0x05, 0x0B, 0x05,
 130         0x0B, 0x05, 0x0B, 0x05,
 131         0x0B, 0x05, 0x11, 0x8B,
 132         0x0B, 0x20, 0x0B, 0x05,
 133         0x04, 0xF6, 0x04, 0xF6,
 134         0x04, 0xF6, 0x04, 0xF6
 135 };
 136 
 137 static const u8 redwood_smc_int_vectors[] =
 138 {
 139         0x0B, 0x05, 0x0B, 0x05,
 140         0x0B, 0x05, 0x0B, 0x05,
 141         0x0B, 0x05, 0x0B, 0x05,
 142         0x0B, 0x05, 0x0B, 0x05,
 143         0x0B, 0x05, 0x0B, 0x05,
 144         0x0B, 0x05, 0x0B, 0x05,
 145         0x0B, 0x05, 0x0B, 0x05,
 146         0x0B, 0x05, 0x0B, 0x05,
 147         0x0B, 0x05, 0x0B, 0x05,
 148         0x0B, 0x05, 0x0B, 0x05,
 149         0x0B, 0x05, 0x0B, 0x05,
 150         0x0B, 0x05, 0x0B, 0x05,
 151         0x0B, 0x05, 0x11, 0x8B,
 152         0x0B, 0x20, 0x0B, 0x05,
 153         0x04, 0xF6, 0x04, 0xF6,
 154         0x04, 0xF6, 0x04, 0xF6
 155 };
 156 
 157 static const u8 juniper_smc_int_vectors[] =
 158 {
 159         0x0B, 0x05, 0x0B, 0x05,
 160         0x0B, 0x05, 0x0B, 0x05,
 161         0x0B, 0x05, 0x0B, 0x05,
 162         0x0B, 0x05, 0x0B, 0x05,
 163         0x0B, 0x05, 0x0B, 0x05,
 164         0x0B, 0x05, 0x0B, 0x05,
 165         0x0B, 0x05, 0x0B, 0x05,
 166         0x0B, 0x05, 0x0B, 0x05,
 167         0x0B, 0x05, 0x0B, 0x05,
 168         0x0B, 0x05, 0x0B, 0x05,
 169         0x0B, 0x05, 0x0B, 0x05,
 170         0x0B, 0x05, 0x0B, 0x05,
 171         0x0B, 0x05, 0x11, 0x8B,
 172         0x0B, 0x20, 0x0B, 0x05,
 173         0x04, 0xF6, 0x04, 0xF6,
 174         0x04, 0xF6, 0x04, 0xF6
 175 };
 176 
 177 static const u8 cypress_smc_int_vectors[] =
 178 {
 179         0x0B, 0x05, 0x0B, 0x05,
 180         0x0B, 0x05, 0x0B, 0x05,
 181         0x0B, 0x05, 0x0B, 0x05,
 182         0x0B, 0x05, 0x0B, 0x05,
 183         0x0B, 0x05, 0x0B, 0x05,
 184         0x0B, 0x05, 0x0B, 0x05,
 185         0x0B, 0x05, 0x0B, 0x05,
 186         0x0B, 0x05, 0x0B, 0x05,
 187         0x0B, 0x05, 0x0B, 0x05,
 188         0x0B, 0x05, 0x0B, 0x05,
 189         0x0B, 0x05, 0x0B, 0x05,
 190         0x0B, 0x05, 0x0B, 0x05,
 191         0x0B, 0x05, 0x11, 0x8B,
 192         0x0B, 0x20, 0x0B, 0x05,
 193         0x04, 0xF6, 0x04, 0xF6,
 194         0x04, 0xF6, 0x04, 0xF6
 195 };
 196 
 197 static const u8 barts_smc_int_vectors[] =
 198 {
 199         0x0C, 0x14, 0x0C, 0x14,
 200         0x0C, 0x14, 0x0C, 0x14,
 201         0x0C, 0x14, 0x0C, 0x14,
 202         0x0C, 0x14, 0x0C, 0x14,
 203         0x0C, 0x14, 0x0C, 0x14,
 204         0x0C, 0x14, 0x0C, 0x14,
 205         0x0C, 0x14, 0x0C, 0x14,
 206         0x0C, 0x14, 0x0C, 0x14,
 207         0x0C, 0x14, 0x0C, 0x14,
 208         0x0C, 0x14, 0x0C, 0x14,
 209         0x0C, 0x14, 0x0C, 0x14,
 210         0x0C, 0x14, 0x0C, 0x14,
 211         0x0C, 0x14, 0x12, 0xAA,
 212         0x0C, 0x2F, 0x15, 0xF6,
 213         0x15, 0xF6, 0x05, 0x0A,
 214         0x05, 0x0A, 0x05, 0x0A
 215 };
 216 
 217 static const u8 turks_smc_int_vectors[] =
 218 {
 219         0x0C, 0x14, 0x0C, 0x14,
 220         0x0C, 0x14, 0x0C, 0x14,
 221         0x0C, 0x14, 0x0C, 0x14,
 222         0x0C, 0x14, 0x0C, 0x14,
 223         0x0C, 0x14, 0x0C, 0x14,
 224         0x0C, 0x14, 0x0C, 0x14,
 225         0x0C, 0x14, 0x0C, 0x14,
 226         0x0C, 0x14, 0x0C, 0x14,
 227         0x0C, 0x14, 0x0C, 0x14,
 228         0x0C, 0x14, 0x0C, 0x14,
 229         0x0C, 0x14, 0x0C, 0x14,
 230         0x0C, 0x14, 0x0C, 0x14,
 231         0x0C, 0x14, 0x12, 0xAA,
 232         0x0C, 0x2F, 0x15, 0xF6,
 233         0x15, 0xF6, 0x05, 0x0A,
 234         0x05, 0x0A, 0x05, 0x0A
 235 };
 236 
 237 static const u8 caicos_smc_int_vectors[] =
 238 {
 239         0x0C, 0x14, 0x0C, 0x14,
 240         0x0C, 0x14, 0x0C, 0x14,
 241         0x0C, 0x14, 0x0C, 0x14,
 242         0x0C, 0x14, 0x0C, 0x14,
 243         0x0C, 0x14, 0x0C, 0x14,
 244         0x0C, 0x14, 0x0C, 0x14,
 245         0x0C, 0x14, 0x0C, 0x14,
 246         0x0C, 0x14, 0x0C, 0x14,
 247         0x0C, 0x14, 0x0C, 0x14,
 248         0x0C, 0x14, 0x0C, 0x14,
 249         0x0C, 0x14, 0x0C, 0x14,
 250         0x0C, 0x14, 0x0C, 0x14,
 251         0x0C, 0x14, 0x12, 0xAA,
 252         0x0C, 0x2F, 0x15, 0xF6,
 253         0x15, 0xF6, 0x05, 0x0A,
 254         0x05, 0x0A, 0x05, 0x0A
 255 };
 256 
 257 static const u8 cayman_smc_int_vectors[] =
 258 {
 259         0x12, 0x05, 0x12, 0x05,
 260         0x12, 0x05, 0x12, 0x05,
 261         0x12, 0x05, 0x12, 0x05,
 262         0x12, 0x05, 0x12, 0x05,
 263         0x12, 0x05, 0x12, 0x05,
 264         0x12, 0x05, 0x12, 0x05,
 265         0x12, 0x05, 0x12, 0x05,
 266         0x12, 0x05, 0x12, 0x05,
 267         0x12, 0x05, 0x12, 0x05,
 268         0x12, 0x05, 0x12, 0x05,
 269         0x12, 0x05, 0x12, 0x05,
 270         0x12, 0x05, 0x12, 0x05,
 271         0x12, 0x05, 0x18, 0xEA,
 272         0x12, 0x20, 0x1C, 0x34,
 273         0x1C, 0x34, 0x08, 0x72,
 274         0x08, 0x72, 0x08, 0x72
 275 };
 276 
 277 static int rv770_set_smc_sram_address(struct radeon_device *rdev,
 278                                       u16 smc_address, u16 limit)
 279 {
 280         u32 addr;
 281 
 282         if (smc_address & 3)
 283                 return -EINVAL;
 284         if ((smc_address + 3) > limit)
 285                 return -EINVAL;
 286 
 287         addr = smc_address;
 288         addr |= SMC_SRAM_AUTO_INC_DIS;
 289 
 290         WREG32(SMC_SRAM_ADDR, addr);
 291 
 292         return 0;
 293 }
 294 
 295 int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
 296                             u16 smc_start_address, const u8 *src,
 297                             u16 byte_count, u16 limit)
 298 {
 299         unsigned long flags;
 300         u32 data, original_data, extra_shift;
 301         u16 addr;
 302         int ret = 0;
 303 
 304         if (smc_start_address & 3)
 305                 return -EINVAL;
 306         if ((smc_start_address + byte_count) > limit)
 307                 return -EINVAL;
 308 
 309         addr = smc_start_address;
 310 
 311         spin_lock_irqsave(&rdev->smc_idx_lock, flags);
 312         while (byte_count >= 4) {
 313                 /* SMC address space is BE */
 314                 data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
 315 
 316                 ret = rv770_set_smc_sram_address(rdev, addr, limit);
 317                 if (ret)
 318                         goto done;
 319 
 320                 WREG32(SMC_SRAM_DATA, data);
 321 
 322                 src += 4;
 323                 byte_count -= 4;
 324                 addr += 4;
 325         }
 326 
 327         /* RMW for final bytes */
 328         if (byte_count > 0) {
 329                 data = 0;
 330 
 331                 ret = rv770_set_smc_sram_address(rdev, addr, limit);
 332                 if (ret)
 333                         goto done;
 334 
 335                 original_data = RREG32(SMC_SRAM_DATA);
 336 
 337                 extra_shift = 8 * (4 - byte_count);
 338 
 339                 while (byte_count > 0) {
 340                         /* SMC address space is BE */
 341                         data = (data << 8) + *src++;
 342                         byte_count--;
 343                 }
 344 
 345                 data <<= extra_shift;
 346 
 347                 data |= (original_data & ~((~0UL) << extra_shift));
 348 
 349                 ret = rv770_set_smc_sram_address(rdev, addr, limit);
 350                 if (ret)
 351                         goto done;
 352 
 353                 WREG32(SMC_SRAM_DATA, data);
 354         }
 355 
 356 done:
 357         spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
 358 
 359         return ret;
 360 }
 361 
 362 static int rv770_program_interrupt_vectors(struct radeon_device *rdev,
 363                                            u32 smc_first_vector, const u8 *src,
 364                                            u32 byte_count)
 365 {
 366         u32 tmp, i;
 367 
 368         if (byte_count % 4)
 369                 return -EINVAL;
 370 
 371         if (smc_first_vector < FIRST_SMC_INT_VECT_REG) {
 372                 tmp = FIRST_SMC_INT_VECT_REG - smc_first_vector;
 373 
 374                 if (tmp > byte_count)
 375                         return 0;
 376 
 377                 byte_count -= tmp;
 378                 src += tmp;
 379                 smc_first_vector = FIRST_SMC_INT_VECT_REG;
 380         }
 381 
 382         for (i = 0; i < byte_count; i += 4) {
 383                 /* SMC address space is BE */
 384                 tmp = (src[i] << 24) | (src[i + 1] << 16) | (src[i + 2] << 8) | src[i + 3];
 385 
 386                 WREG32(SMC_ISR_FFD8_FFDB + i, tmp);
 387         }
 388 
 389         return 0;
 390 }
 391 
 392 void rv770_start_smc(struct radeon_device *rdev)
 393 {
 394         WREG32_P(SMC_IO, SMC_RST_N, ~SMC_RST_N);
 395 }
 396 
 397 void rv770_reset_smc(struct radeon_device *rdev)
 398 {
 399         WREG32_P(SMC_IO, 0, ~SMC_RST_N);
 400 }
 401 
 402 void rv770_stop_smc_clock(struct radeon_device *rdev)
 403 {
 404         WREG32_P(SMC_IO, 0, ~SMC_CLK_EN);
 405 }
 406 
 407 void rv770_start_smc_clock(struct radeon_device *rdev)
 408 {
 409         WREG32_P(SMC_IO, SMC_CLK_EN, ~SMC_CLK_EN);
 410 }
 411 
 412 bool rv770_is_smc_running(struct radeon_device *rdev)
 413 {
 414         u32 tmp;
 415 
 416         tmp = RREG32(SMC_IO);
 417 
 418         if ((tmp & SMC_RST_N) && (tmp & SMC_CLK_EN))
 419                 return true;
 420         else
 421                 return false;
 422 }
 423 
 424 PPSMC_Result rv770_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg)
 425 {
 426         u32 tmp;
 427         int i;
 428         PPSMC_Result result;
 429 
 430         if (!rv770_is_smc_running(rdev))
 431                 return PPSMC_Result_Failed;
 432 
 433         WREG32_P(SMC_MSG, HOST_SMC_MSG(msg), ~HOST_SMC_MSG_MASK);
 434 
 435         for (i = 0; i < rdev->usec_timeout; i++) {
 436                 tmp = RREG32(SMC_MSG) & HOST_SMC_RESP_MASK;
 437                 tmp >>= HOST_SMC_RESP_SHIFT;
 438                 if (tmp != 0)
 439                         break;
 440                 udelay(1);
 441         }
 442 
 443         tmp = RREG32(SMC_MSG) & HOST_SMC_RESP_MASK;
 444         tmp >>= HOST_SMC_RESP_SHIFT;
 445 
 446         result = (PPSMC_Result)tmp;
 447         return result;
 448 }
 449 
 450 PPSMC_Result rv770_wait_for_smc_inactive(struct radeon_device *rdev)
 451 {
 452         int i;
 453         PPSMC_Result result = PPSMC_Result_OK;
 454 
 455         if (!rv770_is_smc_running(rdev))
 456                 return result;
 457 
 458         for (i = 0; i < rdev->usec_timeout; i++) {
 459                 if (RREG32(SMC_IO) & SMC_STOP_MODE)
 460                         break;
 461                 udelay(1);
 462         }
 463 
 464         return result;
 465 }
 466 
 467 static void rv770_clear_smc_sram(struct radeon_device *rdev, u16 limit)
 468 {
 469         unsigned long flags;
 470         u16 i;
 471 
 472         spin_lock_irqsave(&rdev->smc_idx_lock, flags);
 473         for (i = 0;  i < limit; i += 4) {
 474                 rv770_set_smc_sram_address(rdev, i, limit);
 475                 WREG32(SMC_SRAM_DATA, 0);
 476         }
 477         spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
 478 }
 479 
 480 int rv770_load_smc_ucode(struct radeon_device *rdev,
 481                          u16 limit)
 482 {
 483         int ret;
 484         const u8 *int_vect;
 485         u16 int_vect_start_address;
 486         u16 int_vect_size;
 487         const u8 *ucode_data;
 488         u16 ucode_start_address;
 489         u16 ucode_size;
 490 
 491         if (!rdev->smc_fw)
 492                 return -EINVAL;
 493 
 494         rv770_clear_smc_sram(rdev, limit);
 495 
 496         switch (rdev->family) {
 497         case CHIP_RV770:
 498                 ucode_start_address = RV770_SMC_UCODE_START;
 499                 ucode_size = RV770_SMC_UCODE_SIZE;
 500                 int_vect = (const u8 *)&rv770_smc_int_vectors;
 501                 int_vect_start_address = RV770_SMC_INT_VECTOR_START;
 502                 int_vect_size = RV770_SMC_INT_VECTOR_SIZE;
 503                 break;
 504         case CHIP_RV730:
 505                 ucode_start_address = RV730_SMC_UCODE_START;
 506                 ucode_size = RV730_SMC_UCODE_SIZE;
 507                 int_vect = (const u8 *)&rv730_smc_int_vectors;
 508                 int_vect_start_address = RV730_SMC_INT_VECTOR_START;
 509                 int_vect_size = RV730_SMC_INT_VECTOR_SIZE;
 510                 break;
 511         case CHIP_RV710:
 512                 ucode_start_address = RV710_SMC_UCODE_START;
 513                 ucode_size = RV710_SMC_UCODE_SIZE;
 514                 int_vect = (const u8 *)&rv710_smc_int_vectors;
 515                 int_vect_start_address = RV710_SMC_INT_VECTOR_START;
 516                 int_vect_size = RV710_SMC_INT_VECTOR_SIZE;
 517                 break;
 518         case CHIP_RV740:
 519                 ucode_start_address = RV740_SMC_UCODE_START;
 520                 ucode_size = RV740_SMC_UCODE_SIZE;
 521                 int_vect = (const u8 *)&rv740_smc_int_vectors;
 522                 int_vect_start_address = RV740_SMC_INT_VECTOR_START;
 523                 int_vect_size = RV740_SMC_INT_VECTOR_SIZE;
 524                 break;
 525         case CHIP_CEDAR:
 526                 ucode_start_address = CEDAR_SMC_UCODE_START;
 527                 ucode_size = CEDAR_SMC_UCODE_SIZE;
 528                 int_vect = (const u8 *)&cedar_smc_int_vectors;
 529                 int_vect_start_address = CEDAR_SMC_INT_VECTOR_START;
 530                 int_vect_size = CEDAR_SMC_INT_VECTOR_SIZE;
 531                 break;
 532         case CHIP_REDWOOD:
 533                 ucode_start_address = REDWOOD_SMC_UCODE_START;
 534                 ucode_size = REDWOOD_SMC_UCODE_SIZE;
 535                 int_vect = (const u8 *)&redwood_smc_int_vectors;
 536                 int_vect_start_address = REDWOOD_SMC_INT_VECTOR_START;
 537                 int_vect_size = REDWOOD_SMC_INT_VECTOR_SIZE;
 538                 break;
 539         case CHIP_JUNIPER:
 540                 ucode_start_address = JUNIPER_SMC_UCODE_START;
 541                 ucode_size = JUNIPER_SMC_UCODE_SIZE;
 542                 int_vect = (const u8 *)&juniper_smc_int_vectors;
 543                 int_vect_start_address = JUNIPER_SMC_INT_VECTOR_START;
 544                 int_vect_size = JUNIPER_SMC_INT_VECTOR_SIZE;
 545                 break;
 546         case CHIP_CYPRESS:
 547         case CHIP_HEMLOCK:
 548                 ucode_start_address = CYPRESS_SMC_UCODE_START;
 549                 ucode_size = CYPRESS_SMC_UCODE_SIZE;
 550                 int_vect = (const u8 *)&cypress_smc_int_vectors;
 551                 int_vect_start_address = CYPRESS_SMC_INT_VECTOR_START;
 552                 int_vect_size = CYPRESS_SMC_INT_VECTOR_SIZE;
 553                 break;
 554         case CHIP_BARTS:
 555                 ucode_start_address = BARTS_SMC_UCODE_START;
 556                 ucode_size = BARTS_SMC_UCODE_SIZE;
 557                 int_vect = (const u8 *)&barts_smc_int_vectors;
 558                 int_vect_start_address = BARTS_SMC_INT_VECTOR_START;
 559                 int_vect_size = BARTS_SMC_INT_VECTOR_SIZE;
 560                 break;
 561         case CHIP_TURKS:
 562                 ucode_start_address = TURKS_SMC_UCODE_START;
 563                 ucode_size = TURKS_SMC_UCODE_SIZE;
 564                 int_vect = (const u8 *)&turks_smc_int_vectors;
 565                 int_vect_start_address = TURKS_SMC_INT_VECTOR_START;
 566                 int_vect_size = TURKS_SMC_INT_VECTOR_SIZE;
 567                 break;
 568         case CHIP_CAICOS:
 569                 ucode_start_address = CAICOS_SMC_UCODE_START;
 570                 ucode_size = CAICOS_SMC_UCODE_SIZE;
 571                 int_vect = (const u8 *)&caicos_smc_int_vectors;
 572                 int_vect_start_address = CAICOS_SMC_INT_VECTOR_START;
 573                 int_vect_size = CAICOS_SMC_INT_VECTOR_SIZE;
 574                 break;
 575         case CHIP_CAYMAN:
 576                 ucode_start_address = CAYMAN_SMC_UCODE_START;
 577                 ucode_size = CAYMAN_SMC_UCODE_SIZE;
 578                 int_vect = (const u8 *)&cayman_smc_int_vectors;
 579                 int_vect_start_address = CAYMAN_SMC_INT_VECTOR_START;
 580                 int_vect_size = CAYMAN_SMC_INT_VECTOR_SIZE;
 581                 break;
 582         default:
 583                 DRM_ERROR("unknown asic in smc ucode loader\n");
 584                 BUG();
 585         }
 586 
 587         /* load the ucode */
 588         ucode_data = (const u8 *)rdev->smc_fw->data;
 589         ret = rv770_copy_bytes_to_smc(rdev, ucode_start_address,
 590                                       ucode_data, ucode_size, limit);
 591         if (ret)
 592                 return ret;
 593 
 594         /* set up the int vectors */
 595         ret = rv770_program_interrupt_vectors(rdev, int_vect_start_address,
 596                                               int_vect, int_vect_size);
 597         if (ret)
 598                 return ret;
 599 
 600         return 0;
 601 }
 602 
 603 int rv770_read_smc_sram_dword(struct radeon_device *rdev,
 604                               u16 smc_address, u32 *value, u16 limit)
 605 {
 606         unsigned long flags;
 607         int ret;
 608 
 609         spin_lock_irqsave(&rdev->smc_idx_lock, flags);
 610         ret = rv770_set_smc_sram_address(rdev, smc_address, limit);
 611         if (ret == 0)
 612                 *value = RREG32(SMC_SRAM_DATA);
 613         spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
 614 
 615         return ret;
 616 }
 617 
 618 int rv770_write_smc_sram_dword(struct radeon_device *rdev,
 619                                u16 smc_address, u32 value, u16 limit)
 620 {
 621         unsigned long flags;
 622         int ret;
 623 
 624         spin_lock_irqsave(&rdev->smc_idx_lock, flags);
 625         ret = rv770_set_smc_sram_address(rdev, smc_address, limit);
 626         if (ret == 0)
 627                 WREG32(SMC_SRAM_DATA, value);
 628         spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
 629 
 630         return ret;
 631 }

/* [<][>][^][v][top][bottom][index][help] */