Merge remote branch 'korg/drm-radeon-next' into drm-linus
* korg/drm-radeon-next: drm/radeon/kms: add definitions for v4 power tables drm/radeon/kms: never combine LVDS with another encoder drm/radeon/kms: Check module arguments to be valid V2 drm/radeon/kms: Avoid crash when trying to cleanup uninitialized structure drm/radeon/kms: add cvt mode if we only have lvds w/h and no edid (v4) drm/radeon/kms: add 3DC compression support drm/radeon/kms: allow rendering while no colorbuffer is set on r300 drm/radeon/kms: enable memory clock reading on legacy (V2) drm/radeon/kms: prevent parallel AtomBIOS calls drm/radeon/kms: set proper default tv standard drm/radeon/kms: fix legacy rmx drm/radeon/kms/atom: fill in proper defines for digital setup
This commit is contained in:
commit
d94a5108f7
21 changed files with 459 additions and 61 deletions
|
@ -58,6 +58,7 @@ typedef struct {
|
|||
} atom_exec_context;
|
||||
|
||||
int atom_debug = 0;
|
||||
static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
|
||||
void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);
|
||||
|
||||
static uint32_t atom_arg_mask[8] =
|
||||
|
@ -573,7 +574,7 @@ static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg)
|
|||
else
|
||||
SDEBUG(" table: %d\n", idx);
|
||||
if (U16(ctx->ctx->cmd_table + 4 + 2 * idx))
|
||||
atom_execute_table(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
|
||||
atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
|
||||
}
|
||||
|
||||
static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg)
|
||||
|
@ -1040,7 +1041,7 @@ static struct {
|
|||
atom_op_shr, ATOM_ARG_MC}, {
|
||||
atom_op_debug, 0},};
|
||||
|
||||
void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
|
||||
static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
|
||||
{
|
||||
int base = CU16(ctx->cmd_table + 4 + 2 * index);
|
||||
int len, ws, ps, ptr;
|
||||
|
@ -1092,6 +1093,13 @@ void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
|
|||
kfree(ectx.ws);
|
||||
}
|
||||
|
||||
void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
|
||||
{
|
||||
mutex_lock(&ctx->mutex);
|
||||
atom_execute_table_locked(ctx, index, params);
|
||||
mutex_unlock(&ctx->mutex);
|
||||
}
|
||||
|
||||
static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 };
|
||||
|
||||
static void atom_index_iio(struct atom_context *ctx, int base)
|
||||
|
|
|
@ -120,6 +120,7 @@ struct card_info {
|
|||
|
||||
struct atom_context {
|
||||
struct card_info *card;
|
||||
struct mutex mutex;
|
||||
void *bios;
|
||||
uint32_t cmd_table, data_table;
|
||||
uint16_t *iio;
|
||||
|
|
|
@ -4690,6 +4690,205 @@ typedef struct _ATOM_POWERPLAY_INFO_V3 {
|
|||
ATOM_POWERMODE_INFO_V3 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK];
|
||||
} ATOM_POWERPLAY_INFO_V3;
|
||||
|
||||
/* New PPlib */
|
||||
/**************************************************************************/
|
||||
typedef struct _ATOM_PPLIB_THERMALCONTROLLER
|
||||
|
||||
{
|
||||
UCHAR ucType; // one of ATOM_PP_THERMALCONTROLLER_*
|
||||
UCHAR ucI2cLine; // as interpreted by DAL I2C
|
||||
UCHAR ucI2cAddress;
|
||||
UCHAR ucFanParameters; // Fan Control Parameters.
|
||||
UCHAR ucFanMinRPM; // Fan Minimum RPM (hundreds) -- for display purposes only.
|
||||
UCHAR ucFanMaxRPM; // Fan Maximum RPM (hundreds) -- for display purposes only.
|
||||
UCHAR ucReserved; // ----
|
||||
UCHAR ucFlags; // to be defined
|
||||
} ATOM_PPLIB_THERMALCONTROLLER;
|
||||
|
||||
#define ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK 0x0f
|
||||
#define ATOM_PP_FANPARAMETERS_NOFAN 0x80 // No fan is connected to this controller.
|
||||
|
||||
#define ATOM_PP_THERMALCONTROLLER_NONE 0
|
||||
#define ATOM_PP_THERMALCONTROLLER_LM63 1 // Not used by PPLib
|
||||
#define ATOM_PP_THERMALCONTROLLER_ADM1032 2 // Not used by PPLib
|
||||
#define ATOM_PP_THERMALCONTROLLER_ADM1030 3 // Not used by PPLib
|
||||
#define ATOM_PP_THERMALCONTROLLER_MUA6649 4 // Not used by PPLib
|
||||
#define ATOM_PP_THERMALCONTROLLER_LM64 5
|
||||
#define ATOM_PP_THERMALCONTROLLER_F75375 6 // Not used by PPLib
|
||||
#define ATOM_PP_THERMALCONTROLLER_RV6xx 7
|
||||
#define ATOM_PP_THERMALCONTROLLER_RV770 8
|
||||
#define ATOM_PP_THERMALCONTROLLER_ADT7473 9
|
||||
|
||||
typedef struct _ATOM_PPLIB_STATE
|
||||
{
|
||||
UCHAR ucNonClockStateIndex;
|
||||
UCHAR ucClockStateIndices[1]; // variable-sized
|
||||
} ATOM_PPLIB_STATE;
|
||||
|
||||
//// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps
|
||||
#define ATOM_PP_PLATFORM_CAP_BACKBIAS 1
|
||||
#define ATOM_PP_PLATFORM_CAP_POWERPLAY 2
|
||||
#define ATOM_PP_PLATFORM_CAP_SBIOSPOWERSOURCE 4
|
||||
#define ATOM_PP_PLATFORM_CAP_ASPM_L0s 8
|
||||
#define ATOM_PP_PLATFORM_CAP_ASPM_L1 16
|
||||
#define ATOM_PP_PLATFORM_CAP_HARDWAREDC 32
|
||||
#define ATOM_PP_PLATFORM_CAP_GEMINIPRIMARY 64
|
||||
#define ATOM_PP_PLATFORM_CAP_STEPVDDC 128
|
||||
#define ATOM_PP_PLATFORM_CAP_VOLTAGECONTROL 256
|
||||
#define ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL 512
|
||||
#define ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1 1024
|
||||
#define ATOM_PP_PLATFORM_CAP_HTLINKCONTROL 2048
|
||||
|
||||
typedef struct _ATOM_PPLIB_POWERPLAYTABLE
|
||||
{
|
||||
ATOM_COMMON_TABLE_HEADER sHeader;
|
||||
|
||||
UCHAR ucDataRevision;
|
||||
|
||||
UCHAR ucNumStates;
|
||||
UCHAR ucStateEntrySize;
|
||||
UCHAR ucClockInfoSize;
|
||||
UCHAR ucNonClockSize;
|
||||
|
||||
// offset from start of this table to array of ucNumStates ATOM_PPLIB_STATE structures
|
||||
USHORT usStateArrayOffset;
|
||||
|
||||
// offset from start of this table to array of ASIC-specific structures,
|
||||
// currently ATOM_PPLIB_CLOCK_INFO.
|
||||
USHORT usClockInfoArrayOffset;
|
||||
|
||||
// offset from start of this table to array of ATOM_PPLIB_NONCLOCK_INFO
|
||||
USHORT usNonClockInfoArrayOffset;
|
||||
|
||||
USHORT usBackbiasTime; // in microseconds
|
||||
USHORT usVoltageTime; // in microseconds
|
||||
USHORT usTableSize; //the size of this structure, or the extended structure
|
||||
|
||||
ULONG ulPlatformCaps; // See ATOM_PPLIB_CAPS_*
|
||||
|
||||
ATOM_PPLIB_THERMALCONTROLLER sThermalController;
|
||||
|
||||
USHORT usBootClockInfoOffset;
|
||||
USHORT usBootNonClockInfoOffset;
|
||||
|
||||
} ATOM_PPLIB_POWERPLAYTABLE;
|
||||
|
||||
//// ATOM_PPLIB_NONCLOCK_INFO::usClassification
|
||||
#define ATOM_PPLIB_CLASSIFICATION_UI_MASK 0x0007
|
||||
#define ATOM_PPLIB_CLASSIFICATION_UI_SHIFT 0
|
||||
#define ATOM_PPLIB_CLASSIFICATION_UI_NONE 0
|
||||
#define ATOM_PPLIB_CLASSIFICATION_UI_BATTERY 1
|
||||
#define ATOM_PPLIB_CLASSIFICATION_UI_BALANCED 3
|
||||
#define ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE 5
|
||||
// 2, 4, 6, 7 are reserved
|
||||
|
||||
#define ATOM_PPLIB_CLASSIFICATION_BOOT 0x0008
|
||||
#define ATOM_PPLIB_CLASSIFICATION_THERMAL 0x0010
|
||||
#define ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE 0x0020
|
||||
#define ATOM_PPLIB_CLASSIFICATION_REST 0x0040
|
||||
#define ATOM_PPLIB_CLASSIFICATION_FORCED 0x0080
|
||||
#define ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE 0x0100
|
||||
#define ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE 0x0200
|
||||
#define ATOM_PPLIB_CLASSIFICATION_UVDSTATE 0x0400
|
||||
#define ATOM_PPLIB_CLASSIFICATION_3DLOW 0x0800
|
||||
#define ATOM_PPLIB_CLASSIFICATION_ACPI 0x1000
|
||||
// remaining 3 bits are reserved
|
||||
|
||||
//// ATOM_PPLIB_NONCLOCK_INFO::ulCapsAndSettings
|
||||
#define ATOM_PPLIB_SINGLE_DISPLAY_ONLY 0x00000001
|
||||
#define ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK 0x00000002
|
||||
|
||||
// 0 is 2.5Gb/s, 1 is 5Gb/s
|
||||
#define ATOM_PPLIB_PCIE_LINK_SPEED_MASK 0x00000004
|
||||
#define ATOM_PPLIB_PCIE_LINK_SPEED_SHIFT 2
|
||||
|
||||
// lanes - 1: 1, 2, 4, 8, 12, 16 permitted by PCIE spec
|
||||
#define ATOM_PPLIB_PCIE_LINK_WIDTH_MASK 0x000000F8
|
||||
#define ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT 3
|
||||
|
||||
// lookup into reduced refresh-rate table
|
||||
#define ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_MASK 0x00000F00
|
||||
#define ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_SHIFT 8
|
||||
|
||||
#define ATOM_PPLIB_LIMITED_REFRESHRATE_UNLIMITED 0
|
||||
#define ATOM_PPLIB_LIMITED_REFRESHRATE_50HZ 1
|
||||
// 2-15 TBD as needed.
|
||||
|
||||
#define ATOM_PPLIB_SOFTWARE_DISABLE_LOADBALANCING 0x00001000
|
||||
#define ATOM_PPLIB_SOFTWARE_ENABLE_SLEEP_FOR_TIMESTAMPS 0x00002000
|
||||
#define ATOM_PPLIB_ENABLE_VARIBRIGHT 0x00008000
|
||||
|
||||
#define ATOM_PPLIB_DISALLOW_ON_DC 0x00004000
|
||||
|
||||
// Contained in an array starting at the offset
|
||||
// in ATOM_PPLIB_POWERPLAYTABLE::usNonClockInfoArrayOffset.
|
||||
// referenced from ATOM_PPLIB_STATE_INFO::ucNonClockStateIndex
|
||||
typedef struct _ATOM_PPLIB_NONCLOCK_INFO
|
||||
{
|
||||
USHORT usClassification;
|
||||
UCHAR ucMinTemperature;
|
||||
UCHAR ucMaxTemperature;
|
||||
ULONG ulCapsAndSettings;
|
||||
UCHAR ucRequiredPower;
|
||||
UCHAR ucUnused1[3];
|
||||
} ATOM_PPLIB_NONCLOCK_INFO;
|
||||
|
||||
// Contained in an array starting at the offset
|
||||
// in ATOM_PPLIB_POWERPLAYTABLE::usClockInfoArrayOffset.
|
||||
// referenced from ATOM_PPLIB_STATE::ucClockStateIndices
|
||||
typedef struct _ATOM_PPLIB_R600_CLOCK_INFO
|
||||
{
|
||||
USHORT usEngineClockLow;
|
||||
UCHAR ucEngineClockHigh;
|
||||
|
||||
USHORT usMemoryClockLow;
|
||||
UCHAR ucMemoryClockHigh;
|
||||
|
||||
USHORT usVDDC;
|
||||
USHORT usUnused1;
|
||||
USHORT usUnused2;
|
||||
|
||||
ULONG ulFlags; // ATOM_PPLIB_R600_FLAGS_*
|
||||
|
||||
} ATOM_PPLIB_R600_CLOCK_INFO;
|
||||
|
||||
// ulFlags in ATOM_PPLIB_R600_CLOCK_INFO
|
||||
#define ATOM_PPLIB_R600_FLAGS_PCIEGEN2 1
|
||||
#define ATOM_PPLIB_R600_FLAGS_UVDSAFE 2
|
||||
#define ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE 4
|
||||
#define ATOM_PPLIB_R600_FLAGS_MEMORY_ODT_OFF 8
|
||||
#define ATOM_PPLIB_R600_FLAGS_MEMORY_DLL_OFF 16
|
||||
|
||||
typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO
|
||||
|
||||
{
|
||||
USHORT usLowEngineClockLow; // Low Engine clock in MHz (the same way as on the R600).
|
||||
UCHAR ucLowEngineClockHigh;
|
||||
USHORT usHighEngineClockLow; // High Engine clock in MHz.
|
||||
UCHAR ucHighEngineClockHigh;
|
||||
USHORT usMemoryClockLow; // For now one of the ATOM_PPLIB_RS780_SPMCLK_XXXX constants.
|
||||
UCHAR ucMemoryClockHigh; // Currentyl unused.
|
||||
UCHAR ucPadding; // For proper alignment and size.
|
||||
USHORT usVDDC; // For the 780, use: None, Low, High, Variable
|
||||
UCHAR ucMaxHTLinkWidth; // From SBIOS - {2, 4, 8, 16}
|
||||
UCHAR ucMinHTLinkWidth; // From SBIOS - {2, 4, 8, 16}. Effective only if CDLW enabled. Minimum down stream width could be bigger as display BW requriement.
|
||||
USHORT usHTLinkFreq; // See definition ATOM_PPLIB_RS780_HTLINKFREQ_xxx or in MHz(>=200).
|
||||
ULONG ulFlags;
|
||||
} ATOM_PPLIB_RS780_CLOCK_INFO;
|
||||
|
||||
#define ATOM_PPLIB_RS780_VOLTAGE_NONE 0
|
||||
#define ATOM_PPLIB_RS780_VOLTAGE_LOW 1
|
||||
#define ATOM_PPLIB_RS780_VOLTAGE_HIGH 2
|
||||
#define ATOM_PPLIB_RS780_VOLTAGE_VARIABLE 3
|
||||
|
||||
#define ATOM_PPLIB_RS780_SPMCLK_NONE 0 // We cannot change the side port memory clock, leave it as it is.
|
||||
#define ATOM_PPLIB_RS780_SPMCLK_LOW 1
|
||||
#define ATOM_PPLIB_RS780_SPMCLK_HIGH 2
|
||||
|
||||
#define ATOM_PPLIB_RS780_HTLINKFREQ_NONE 0
|
||||
#define ATOM_PPLIB_RS780_HTLINKFREQ_LOW 1
|
||||
#define ATOM_PPLIB_RS780_HTLINKFREQ_HIGH 2
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
/* Following definitions are for compatiblity issue in different SW components. */
|
||||
|
|
|
@ -2881,6 +2881,10 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
|
|||
|
||||
for (i = 0; i < track->num_cb; i++) {
|
||||
if (track->cb[i].robj == NULL) {
|
||||
if (!(track->fastfill || track->color_channel_mask ||
|
||||
track->blend_read_enable)) {
|
||||
continue;
|
||||
}
|
||||
DRM_ERROR("[drm] No buffer for color buffer %d !\n", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -67,13 +67,15 @@ struct r100_cs_track {
|
|||
unsigned immd_dwords;
|
||||
unsigned num_arrays;
|
||||
unsigned max_indx;
|
||||
unsigned color_channel_mask;
|
||||
struct r100_cs_track_array arrays[11];
|
||||
struct r100_cs_track_cb cb[R300_MAX_CB];
|
||||
struct r100_cs_track_cb zb;
|
||||
struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE];
|
||||
bool z_enabled;
|
||||
bool separate_cube;
|
||||
|
||||
bool fastfill;
|
||||
bool blend_read_enable;
|
||||
};
|
||||
|
||||
int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track);
|
||||
|
|
|
@ -887,6 +887,14 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
track->textures[i].cpp = 1;
|
||||
track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
|
||||
break;
|
||||
case R300_TX_FORMAT_ATI2N:
|
||||
if (p->rdev->family < CHIP_R420) {
|
||||
DRM_ERROR("Invalid texture format %u\n",
|
||||
(idx_value & 0x1F));
|
||||
return -EINVAL;
|
||||
}
|
||||
/* The same rules apply as for DXT3/5. */
|
||||
/* Pass through. */
|
||||
case R300_TX_FORMAT_DXT3:
|
||||
case R300_TX_FORMAT_DXT5:
|
||||
track->textures[i].cpp = 1;
|
||||
|
@ -951,6 +959,16 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
track->textures[i].width_11 = tmp;
|
||||
tmp = ((idx_value >> 16) & 1) << 11;
|
||||
track->textures[i].height_11 = tmp;
|
||||
|
||||
/* ATI1N */
|
||||
if (idx_value & (1 << 14)) {
|
||||
/* The same rules apply as for DXT1. */
|
||||
track->textures[i].compress_format =
|
||||
R100_TRACK_COMP_DXT1;
|
||||
}
|
||||
} else if (idx_value & (1 << 14)) {
|
||||
DRM_ERROR("Forbidden bit TXFORMAT_MSB\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case 0x4480:
|
||||
|
@ -992,6 +1010,18 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
}
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
break;
|
||||
case 0x4e0c:
|
||||
/* RB3D_COLOR_CHANNEL_MASK */
|
||||
track->color_channel_mask = idx_value;
|
||||
break;
|
||||
case 0x4d1c:
|
||||
/* ZB_BW_CNTL */
|
||||
track->fastfill = !!(idx_value & (1 << 2));
|
||||
break;
|
||||
case 0x4e04:
|
||||
/* RB3D_BLENDCNTL */
|
||||
track->blend_read_enable = !!(idx_value & (1 << 2));
|
||||
break;
|
||||
case 0x4be8:
|
||||
/* valid register only on RV530 */
|
||||
if (p->rdev->family == CHIP_RV530)
|
||||
|
|
|
@ -900,6 +900,7 @@
|
|||
# define R300_TX_FORMAT_FL_I32 0x1B
|
||||
# define R300_TX_FORMAT_FL_I32A32 0x1C
|
||||
# define R300_TX_FORMAT_FL_R32G32B32A32 0x1D
|
||||
# define R300_TX_FORMAT_ATI2N 0x1F
|
||||
/* alpha modes, convenience mostly */
|
||||
/* if you have alpha, pick constant appropriate to the
|
||||
number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */
|
||||
|
|
|
@ -162,6 +162,7 @@ struct radeon_fence_driver {
|
|||
struct list_head created;
|
||||
struct list_head emited;
|
||||
struct list_head signaled;
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
struct radeon_fence {
|
||||
|
@ -202,8 +203,9 @@ struct radeon_surface_reg {
|
|||
struct radeon_mman {
|
||||
struct ttm_bo_global_ref bo_global_ref;
|
||||
struct ttm_global_reference mem_global_ref;
|
||||
bool mem_global_referenced;
|
||||
struct ttm_bo_device bdev;
|
||||
bool mem_global_referenced;
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
struct radeon_bo {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
*/
|
||||
uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev);
|
||||
void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock);
|
||||
uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev);
|
||||
void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
|
||||
|
||||
uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev);
|
||||
|
@ -106,7 +107,7 @@ static struct radeon_asic r100_asic = {
|
|||
.copy = &r100_copy_blit,
|
||||
.get_engine_clock = &radeon_legacy_get_engine_clock,
|
||||
.set_engine_clock = &radeon_legacy_set_engine_clock,
|
||||
.get_memory_clock = NULL,
|
||||
.get_memory_clock = &radeon_legacy_get_memory_clock,
|
||||
.set_memory_clock = NULL,
|
||||
.set_pcie_lanes = NULL,
|
||||
.set_clock_gating = &radeon_legacy_set_clock_gating,
|
||||
|
@ -166,7 +167,7 @@ static struct radeon_asic r300_asic = {
|
|||
.copy = &r100_copy_blit,
|
||||
.get_engine_clock = &radeon_legacy_get_engine_clock,
|
||||
.set_engine_clock = &radeon_legacy_set_engine_clock,
|
||||
.get_memory_clock = NULL,
|
||||
.get_memory_clock = &radeon_legacy_get_memory_clock,
|
||||
.set_memory_clock = NULL,
|
||||
.set_pcie_lanes = &rv370_set_pcie_lanes,
|
||||
.set_clock_gating = &radeon_legacy_set_clock_gating,
|
||||
|
@ -259,7 +260,7 @@ static struct radeon_asic rs400_asic = {
|
|||
.copy = &r100_copy_blit,
|
||||
.get_engine_clock = &radeon_legacy_get_engine_clock,
|
||||
.set_engine_clock = &radeon_legacy_set_engine_clock,
|
||||
.get_memory_clock = NULL,
|
||||
.get_memory_clock = &radeon_legacy_get_memory_clock,
|
||||
.set_memory_clock = NULL,
|
||||
.set_pcie_lanes = NULL,
|
||||
.set_clock_gating = &radeon_legacy_set_clock_gating,
|
||||
|
|
|
@ -745,8 +745,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
|
|||
else
|
||||
radeon_add_legacy_encoder(dev,
|
||||
radeon_get_encoder_id(dev,
|
||||
(1 <<
|
||||
i),
|
||||
(1 << i),
|
||||
dac),
|
||||
(1 << i));
|
||||
}
|
||||
|
@ -758,32 +757,30 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
|
|||
if (bios_connectors[j].valid && (i != j)) {
|
||||
if (bios_connectors[i].line_mux ==
|
||||
bios_connectors[j].line_mux) {
|
||||
if (((bios_connectors[i].
|
||||
devices &
|
||||
(ATOM_DEVICE_DFP_SUPPORT))
|
||||
&& (bios_connectors[j].
|
||||
devices &
|
||||
(ATOM_DEVICE_CRT_SUPPORT)))
|
||||
||
|
||||
((bios_connectors[j].
|
||||
devices &
|
||||
(ATOM_DEVICE_DFP_SUPPORT))
|
||||
&& (bios_connectors[i].
|
||||
devices &
|
||||
(ATOM_DEVICE_CRT_SUPPORT)))) {
|
||||
bios_connectors[i].
|
||||
devices |=
|
||||
bios_connectors[j].
|
||||
devices;
|
||||
bios_connectors[i].
|
||||
connector_type =
|
||||
DRM_MODE_CONNECTOR_DVII;
|
||||
if (bios_connectors[j].devices &
|
||||
(ATOM_DEVICE_DFP_SUPPORT))
|
||||
/* make sure not to combine LVDS */
|
||||
if (bios_connectors[i].devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||
bios_connectors[i].line_mux = 53;
|
||||
bios_connectors[i].ddc_bus.valid = false;
|
||||
continue;
|
||||
}
|
||||
if (bios_connectors[j].devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||
bios_connectors[j].line_mux = 53;
|
||||
bios_connectors[j].ddc_bus.valid = false;
|
||||
continue;
|
||||
}
|
||||
/* combine analog and digital for DVI-I */
|
||||
if (((bios_connectors[i].devices & (ATOM_DEVICE_DFP_SUPPORT)) &&
|
||||
(bios_connectors[j].devices & (ATOM_DEVICE_CRT_SUPPORT))) ||
|
||||
((bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT)) &&
|
||||
(bios_connectors[i].devices & (ATOM_DEVICE_CRT_SUPPORT)))) {
|
||||
bios_connectors[i].devices |=
|
||||
bios_connectors[j].devices;
|
||||
bios_connectors[i].connector_type =
|
||||
DRM_MODE_CONNECTOR_DVII;
|
||||
if (bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT))
|
||||
bios_connectors[i].hpd =
|
||||
bios_connectors[j].hpd;
|
||||
bios_connectors[j].
|
||||
valid = false;
|
||||
bios_connectors[j].valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1234,6 +1231,61 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
|
|||
return true;
|
||||
}
|
||||
|
||||
enum radeon_tv_std
|
||||
radeon_atombios_get_tv_info(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_mode_info *mode_info = &rdev->mode_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);
|
||||
uint16_t data_offset;
|
||||
uint8_t frev, crev;
|
||||
struct _ATOM_ANALOG_TV_INFO *tv_info;
|
||||
enum radeon_tv_std tv_std = TV_STD_NTSC;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
|
||||
|
||||
tv_info = (struct _ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
switch (tv_info->ucTV_BootUpDefaultStandard) {
|
||||
case ATOM_TV_NTSC:
|
||||
tv_std = TV_STD_NTSC;
|
||||
DRM_INFO("Default TV standard: NTSC\n");
|
||||
break;
|
||||
case ATOM_TV_NTSCJ:
|
||||
tv_std = TV_STD_NTSC_J;
|
||||
DRM_INFO("Default TV standard: NTSC-J\n");
|
||||
break;
|
||||
case ATOM_TV_PAL:
|
||||
tv_std = TV_STD_PAL;
|
||||
DRM_INFO("Default TV standard: PAL\n");
|
||||
break;
|
||||
case ATOM_TV_PALM:
|
||||
tv_std = TV_STD_PAL_M;
|
||||
DRM_INFO("Default TV standard: PAL-M\n");
|
||||
break;
|
||||
case ATOM_TV_PALN:
|
||||
tv_std = TV_STD_PAL_N;
|
||||
DRM_INFO("Default TV standard: PAL-N\n");
|
||||
break;
|
||||
case ATOM_TV_PALCN:
|
||||
tv_std = TV_STD_PAL_CN;
|
||||
DRM_INFO("Default TV standard: PAL-CN\n");
|
||||
break;
|
||||
case ATOM_TV_PAL60:
|
||||
tv_std = TV_STD_PAL_60;
|
||||
DRM_INFO("Default TV standard: PAL-60\n");
|
||||
break;
|
||||
case ATOM_TV_SECAM:
|
||||
tv_std = TV_STD_SECAM;
|
||||
DRM_INFO("Default TV standard: SECAM\n");
|
||||
break;
|
||||
default:
|
||||
tv_std = TV_STD_NTSC;
|
||||
DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
|
||||
break;
|
||||
}
|
||||
return tv_std;
|
||||
}
|
||||
|
||||
struct radeon_encoder_tv_dac *
|
||||
radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
|
||||
{
|
||||
|
@ -1269,6 +1321,7 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
|
|||
dac = dac_info->ucDAC2_NTSC_DAC_Adjustment;
|
||||
tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
|
||||
|
||||
tv_dac->tv_std = radeon_atombios_get_tv_info(rdev);
|
||||
}
|
||||
return tv_dac;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev)
|
|||
}
|
||||
|
||||
/* 10 khz */
|
||||
static uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev)
|
||||
uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_pll *mpll = &rdev->clock.mpll;
|
||||
uint32_t fb_div, ref_div, post_div, mclk;
|
||||
|
|
|
@ -634,11 +634,10 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
|
|||
return p_dac;
|
||||
}
|
||||
|
||||
static enum radeon_tv_std
|
||||
radeon_combios_get_tv_info(struct radeon_encoder *encoder)
|
||||
enum radeon_tv_std
|
||||
radeon_combios_get_tv_info(struct radeon_device *rdev)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct drm_device *dev = rdev->ddev;
|
||||
uint16_t tv_info;
|
||||
enum radeon_tv_std tv_std = TV_STD_NTSC;
|
||||
|
||||
|
@ -779,7 +778,7 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
|
|||
tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
|
||||
found = 1;
|
||||
}
|
||||
tv_dac->tv_std = radeon_combios_get_tv_info(encoder);
|
||||
tv_dac->tv_std = radeon_combios_get_tv_info(rdev);
|
||||
}
|
||||
if (!found) {
|
||||
/* then check CRT table */
|
||||
|
|
|
@ -208,6 +208,18 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode
|
|||
drm_mode_set_name(mode);
|
||||
|
||||
DRM_DEBUG("Adding native panel mode %s\n", mode->name);
|
||||
} else if (native_mode->hdisplay != 0 &&
|
||||
native_mode->vdisplay != 0) {
|
||||
/* mac laptops without an edid */
|
||||
/* Note that this is not necessarily the exact panel mode,
|
||||
* but an approximation based on the cvt formula. For these
|
||||
* systems we should ideally read the mode info out of the
|
||||
* registers or add a mode table, but this works and is much
|
||||
* simpler.
|
||||
*/
|
||||
mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false);
|
||||
mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
|
||||
DRM_DEBUG("Adding cvt approximation of native panel mode %s\n", mode->name);
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
@ -1171,7 +1183,7 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
1);
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.tv_std_property,
|
||||
1);
|
||||
radeon_atombios_get_tv_info(rdev));
|
||||
}
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
|
@ -1315,7 +1327,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
1);
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.tv_std_property,
|
||||
1);
|
||||
radeon_combios_get_tv_info(rdev));
|
||||
}
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
|
|
|
@ -391,6 +391,12 @@ int radeon_asic_init(struct radeon_device *rdev)
|
|||
/* FIXME: not supported yet */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
rdev->asic->get_memory_clock = NULL;
|
||||
rdev->asic->set_memory_clock = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -481,6 +487,7 @@ int radeon_atombios_init(struct radeon_device *rdev)
|
|||
atom_card_info->pll_write = cail_pll_write;
|
||||
|
||||
rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios);
|
||||
mutex_init(&rdev->mode_info.atom_context->mutex);
|
||||
radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
|
||||
atom_allocate_fb_scratch(rdev->mode_info.atom_context);
|
||||
return 0;
|
||||
|
@ -539,9 +546,72 @@ void radeon_agp_disable(struct radeon_device *rdev)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Radeon device.
|
||||
*/
|
||||
void radeon_check_arguments(struct radeon_device *rdev)
|
||||
{
|
||||
/* vramlimit must be a power of two */
|
||||
switch (radeon_vram_limit) {
|
||||
case 0:
|
||||
case 4:
|
||||
case 8:
|
||||
case 16:
|
||||
case 32:
|
||||
case 64:
|
||||
case 128:
|
||||
case 256:
|
||||
case 512:
|
||||
case 1024:
|
||||
case 2048:
|
||||
case 4096:
|
||||
break;
|
||||
default:
|
||||
dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n",
|
||||
radeon_vram_limit);
|
||||
radeon_vram_limit = 0;
|
||||
break;
|
||||
}
|
||||
radeon_vram_limit = radeon_vram_limit << 20;
|
||||
/* gtt size must be power of two and greater or equal to 32M */
|
||||
switch (radeon_gart_size) {
|
||||
case 4:
|
||||
case 8:
|
||||
case 16:
|
||||
dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n",
|
||||
radeon_gart_size);
|
||||
radeon_gart_size = 512;
|
||||
break;
|
||||
case 32:
|
||||
case 64:
|
||||
case 128:
|
||||
case 256:
|
||||
case 512:
|
||||
case 1024:
|
||||
case 2048:
|
||||
case 4096:
|
||||
break;
|
||||
default:
|
||||
dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n",
|
||||
radeon_gart_size);
|
||||
radeon_gart_size = 512;
|
||||
break;
|
||||
}
|
||||
rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
|
||||
/* AGP mode can only be -1, 1, 2, 4, 8 */
|
||||
switch (radeon_agpmode) {
|
||||
case -1:
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
break;
|
||||
default:
|
||||
dev_warn(rdev->dev, "invalid AGP mode %d (valid mode: "
|
||||
"-1, 0, 1, 2, 4, 8)\n", radeon_agpmode);
|
||||
radeon_agpmode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int radeon_device_init(struct radeon_device *rdev,
|
||||
struct drm_device *ddev,
|
||||
struct pci_dev *pdev,
|
||||
|
@ -580,9 +650,9 @@ int radeon_device_init(struct radeon_device *rdev,
|
|||
|
||||
/* Set asic functions */
|
||||
r = radeon_asic_init(rdev);
|
||||
if (r) {
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
radeon_check_arguments(rdev);
|
||||
|
||||
if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) {
|
||||
radeon_agp_disable(rdev);
|
||||
|
|
|
@ -739,7 +739,7 @@ static struct drm_prop_enum_list radeon_tv_std_enum_list[] =
|
|||
{ TV_STD_SECAM, "secam" },
|
||||
};
|
||||
|
||||
int radeon_modeset_create_props(struct radeon_device *rdev)
|
||||
static int radeon_modeset_create_props(struct radeon_device *rdev)
|
||||
{
|
||||
int i, sz;
|
||||
|
||||
|
|
|
@ -233,6 +233,8 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
|
|||
if (!ASIC_IS_AVIVO(rdev)) {
|
||||
adjusted_mode->hdisplay = mode->hdisplay;
|
||||
adjusted_mode->vdisplay = mode->vdisplay;
|
||||
adjusted_mode->crtc_hdisplay = mode->hdisplay;
|
||||
adjusted_mode->crtc_vdisplay = mode->vdisplay;
|
||||
}
|
||||
adjusted_mode->base.id = mode_id;
|
||||
}
|
||||
|
@ -495,9 +497,9 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
|
|||
args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
|
||||
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
|
||||
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||
if (dig->lvds_misc & (1 << 0))
|
||||
if (dig->lvds_misc & ATOM_PANEL_MISC_DUAL)
|
||||
args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
|
||||
if (dig->lvds_misc & (1 << 1))
|
||||
if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB)
|
||||
args.v1.ucMisc |= (1 << 1);
|
||||
} else {
|
||||
if (dig_connector->linkb)
|
||||
|
@ -524,18 +526,18 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
|
|||
args.v2.ucTemporal = 0;
|
||||
args.v2.ucFRC = 0;
|
||||
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||
if (dig->lvds_misc & (1 << 0))
|
||||
if (dig->lvds_misc & ATOM_PANEL_MISC_DUAL)
|
||||
args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
|
||||
if (dig->lvds_misc & (1 << 5)) {
|
||||
if (dig->lvds_misc & ATOM_PANEL_MISC_SPATIAL) {
|
||||
args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;
|
||||
if (dig->lvds_misc & (1 << 1))
|
||||
if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB)
|
||||
args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;
|
||||
}
|
||||
if (dig->lvds_misc & (1 << 6)) {
|
||||
if (dig->lvds_misc & ATOM_PANEL_MISC_TEMPORAL) {
|
||||
args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;
|
||||
if (dig->lvds_misc & (1 << 1))
|
||||
if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB)
|
||||
args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
|
||||
if (((dig->lvds_misc >> 2) & 0x3) == 2)
|
||||
if (((dig->lvds_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2)
|
||||
args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -324,7 +324,7 @@ int radeon_fence_driver_init(struct radeon_device *rdev)
|
|||
write_lock_irqsave(&rdev->fence_drv.lock, irq_flags);
|
||||
r = radeon_scratch_get(rdev, &rdev->fence_drv.scratch_reg);
|
||||
if (r) {
|
||||
DRM_ERROR("Fence failed to get a scratch register.");
|
||||
dev_err(rdev->dev, "fence failed to get scratch register\n");
|
||||
write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
|
||||
return r;
|
||||
}
|
||||
|
@ -335,9 +335,10 @@ int radeon_fence_driver_init(struct radeon_device *rdev)
|
|||
INIT_LIST_HEAD(&rdev->fence_drv.signaled);
|
||||
rdev->fence_drv.count_timeout = 0;
|
||||
init_waitqueue_head(&rdev->fence_drv.queue);
|
||||
rdev->fence_drv.initialized = true;
|
||||
write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
|
||||
if (radeon_debugfs_fence_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for fence !\n");
|
||||
dev_err(rdev->dev, "fence debugfs file creation failed\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -346,11 +347,13 @@ void radeon_fence_driver_fini(struct radeon_device *rdev)
|
|||
{
|
||||
unsigned long irq_flags;
|
||||
|
||||
if (!rdev->fence_drv.initialized)
|
||||
return;
|
||||
wake_up_all(&rdev->fence_drv.queue);
|
||||
write_lock_irqsave(&rdev->fence_drv.lock, irq_flags);
|
||||
radeon_scratch_free(rdev, rdev->fence_drv.scratch_reg);
|
||||
write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
|
||||
DRM_INFO("radeon: fence finalized\n");
|
||||
rdev->fence_drv.initialized = false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,8 +43,7 @@ static void radeon_overscan_setup(struct drm_crtc *crtc,
|
|||
}
|
||||
|
||||
static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
@ -1059,7 +1058,7 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc,
|
|||
radeon_set_pll(crtc, adjusted_mode);
|
||||
radeon_overscan_setup(crtc, adjusted_mode);
|
||||
if (radeon_crtc->crtc_id == 0) {
|
||||
radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode);
|
||||
radeon_legacy_rmx_mode_set(crtc, adjusted_mode);
|
||||
} else {
|
||||
if (radeon_crtc->rmx_type != RMX_OFF) {
|
||||
/* FIXME: only first crtc has rmx what should we
|
||||
|
|
|
@ -207,6 +207,8 @@ static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder,
|
|||
*adjusted_mode = *native_mode;
|
||||
adjusted_mode->hdisplay = mode->hdisplay;
|
||||
adjusted_mode->vdisplay = mode->vdisplay;
|
||||
adjusted_mode->crtc_hdisplay = mode->hdisplay;
|
||||
adjusted_mode->crtc_vdisplay = mode->vdisplay;
|
||||
adjusted_mode->base.id = mode_id;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ enum radeon_tv_std {
|
|||
TV_STD_SCART_PAL,
|
||||
TV_STD_SECAM,
|
||||
TV_STD_PAL_CN,
|
||||
TV_STD_PAL_N,
|
||||
};
|
||||
|
||||
/* radeon gpio-based i2c
|
||||
|
@ -395,6 +396,11 @@ struct radeon_framebuffer {
|
|||
struct drm_gem_object *obj;
|
||||
};
|
||||
|
||||
extern enum radeon_tv_std
|
||||
radeon_combios_get_tv_info(struct radeon_device *rdev);
|
||||
extern enum radeon_tv_std
|
||||
radeon_atombios_get_tv_info(struct radeon_device *rdev);
|
||||
|
||||
extern void radeon_connector_hotplug(struct drm_connector *connector);
|
||||
extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
|
||||
extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
|
||||
|
|
|
@ -494,6 +494,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
|
|||
DRM_ERROR("failed initializing buffer object driver(%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
rdev->mman.initialized = true;
|
||||
r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM,
|
||||
rdev->mc.real_vram_size >> PAGE_SHIFT);
|
||||
if (r) {
|
||||
|
@ -541,6 +542,8 @@ void radeon_ttm_fini(struct radeon_device *rdev)
|
|||
{
|
||||
int r;
|
||||
|
||||
if (!rdev->mman.initialized)
|
||||
return;
|
||||
if (rdev->stollen_vga_memory) {
|
||||
r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
|
||||
if (r == 0) {
|
||||
|
@ -554,6 +557,7 @@ void radeon_ttm_fini(struct radeon_device *rdev)
|
|||
ttm_bo_device_release(&rdev->mman.bdev);
|
||||
radeon_gart_fini(rdev);
|
||||
radeon_ttm_global_fini(rdev);
|
||||
rdev->mman.initialized = false;
|
||||
DRM_INFO("radeon: ttm finalized\n");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue