LCOV - code coverage report
Current view: top level - dev/pci/drm/radeon - rv770_smc.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 144 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13