/drivers/video/drm/drm_crtc.c |
---|
886,9 → 886,6 |
total_objects += dev->mode_config.num_connector; |
total_objects += dev->mode_config.num_encoder; |
if (total_objects == 0) |
return -EINVAL; |
group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL); |
if (!group->id_list) |
return -ENOMEM; |
/drivers/video/drm/drm_edid.c |
---|
184,9 → 184,9 |
bad: |
if (raw_edid) { |
DRM_ERROR("Raw EDID:\n"); |
printk(KERN_ERR "Raw EDID:\n"); |
// print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH); |
// printk("\n"); |
printk(KERN_ERR "\n"); |
} |
return 0; |
} |
258,6 → 258,17 |
return ret == 2 ? 0 : -1; |
} |
static bool drm_edid_is_zero(u8 *in_edid, int length) |
{ |
int i; |
u32 *raw_edid = (u32 *)in_edid; |
for (i = 0; i < length / 4; i++) |
if (*(raw_edid + i) != 0) |
return false; |
return true; |
} |
static u8 * |
drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) |
{ |
274,7 → 285,11 |
goto out; |
if (drm_edid_block_valid(block)) |
break; |
if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) { |
connector->null_edid_counter++; |
goto carp; |
} |
} |
if (i == 4) |
goto carp; |
/drivers/video/drm/drm_fb_helper.c |
---|
924,7 → 924,7 |
/* clean out all the encoder/crtc combos */ |
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
// encoder->crtc = NULL; |
encoder->crtc = NULL; |
} |
crtcs = kcalloc(dev->mode_config.num_connector, |
/drivers/video/drm/radeon/Makefile |
---|
55,20 → 55,23 |
radeon_device.c \ |
evergreen.c \ |
evergreen_blit_shaders.c \ |
cayman_blit_shaders.c \ |
radeon_clocks.c \ |
radeon_i2c.c \ |
atom.c \ |
ni.c \ |
radeon_gem.c \ |
radeon_atombios.c \ |
radeon_agp.c \ |
radeon_asic.c \ |
radeon_atombios.c \ |
radeon_bios.c \ |
radeon_combios.c \ |
radeon_connectors.c \ |
atombios_crtc.c \ |
atombios_dp.c \ |
radeon_encoders.c \ |
radeon_connectors.c \ |
radeon_bios.c \ |
radeon_combios.c \ |
radeon_fence.c \ |
radeon_gem.c \ |
radeon_i2c.c \ |
radeon_irq_kms.c \ |
radeon_legacy_crtc.c \ |
radeon_legacy_encoders.c \ |
radeon_legacy_tv.c \ |
/drivers/video/drm/radeon/Makefile.lto |
---|
55,20 → 55,23 |
radeon_device.c \ |
evergreen.c \ |
evergreen_blit_shaders.c \ |
cayman_blit_shaders.c \ |
radeon_clocks.c \ |
radeon_i2c.c \ |
atom.c \ |
ni.c \ |
radeon_gem.c \ |
radeon_atombios.c \ |
radeon_agp.c \ |
radeon_asic.c \ |
radeon_atombios.c \ |
radeon_bios.c \ |
radeon_combios.c \ |
radeon_connectors.c \ |
atombios_crtc.c \ |
atombios_dp.c \ |
radeon_encoders.c \ |
radeon_connectors.c \ |
radeon_bios.c \ |
radeon_combios.c \ |
radeon_fence.c \ |
radeon_gem.c \ |
radeon_i2c.c \ |
radeon_irq_kms.c \ |
radeon_legacy_crtc.c \ |
radeon_legacy_encoders.c \ |
radeon_legacy_tv.c \ |
/drivers/video/drm/radeon/cayman_blit_shaders.c |
---|
0,0 → 1,373 |
/* |
* Copyright 2010 Advanced Micro Devices, Inc. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
* |
* Authors: |
* Alex Deucher <alexander.deucher@amd.com> |
*/ |
#include <linux/types.h> |
#include <linux/kernel.h> |
/* |
* evergreen cards need to use the 3D engine to blit data which requires |
* quite a bit of hw state setup. Rather than pull the whole 3D driver |
* (which normally generates the 3D state) into the DRM, we opt to use |
* statically generated state tables. The regsiter state and shaders |
* were hand generated to support blitting functionality. See the 3D |
* driver or documentation for descriptions of the registers and |
* shader instructions. |
*/ |
const u32 cayman_default_state[] = |
{ |
0xc0066900, |
0x00000000, |
0x00000060, /* DB_RENDER_CONTROL */ |
0x00000000, /* DB_COUNT_CONTROL */ |
0x00000000, /* DB_DEPTH_VIEW */ |
0x0000002a, /* DB_RENDER_OVERRIDE */ |
0x00000000, /* DB_RENDER_OVERRIDE2 */ |
0x00000000, /* DB_HTILE_DATA_BASE */ |
0xc0026900, |
0x0000000a, |
0x00000000, /* DB_STENCIL_CLEAR */ |
0x00000000, /* DB_DEPTH_CLEAR */ |
0xc0036900, |
0x0000000f, |
0x00000000, /* DB_DEPTH_INFO */ |
0x00000000, /* DB_Z_INFO */ |
0x00000000, /* DB_STENCIL_INFO */ |
0xc0016900, |
0x00000080, |
0x00000000, /* PA_SC_WINDOW_OFFSET */ |
0xc00d6900, |
0x00000083, |
0x0000ffff, /* PA_SC_CLIPRECT_RULE */ |
0x00000000, /* PA_SC_CLIPRECT_0_TL */ |
0x20002000, /* PA_SC_CLIPRECT_0_BR */ |
0x00000000, |
0x20002000, |
0x00000000, |
0x20002000, |
0x00000000, |
0x20002000, |
0xaaaaaaaa, /* PA_SC_EDGERULE */ |
0x00000000, /* PA_SU_HARDWARE_SCREEN_OFFSET */ |
0x0000000f, /* CB_TARGET_MASK */ |
0x0000000f, /* CB_SHADER_MASK */ |
0xc0226900, |
0x00000094, |
0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ |
0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x80000000, |
0x20002000, |
0x00000000, /* PA_SC_VPORT_ZMIN_0 */ |
0x3f800000, /* PA_SC_VPORT_ZMAX_0 */ |
0xc0016900, |
0x000000d4, |
0x00000000, /* SX_MISC */ |
0xc0026900, |
0x000000d9, |
0x00000000, /* CP_RINGID */ |
0x00000000, /* CP_VMID */ |
0xc0096900, |
0x00000100, |
0x00ffffff, /* VGT_MAX_VTX_INDX */ |
0x00000000, /* VGT_MIN_VTX_INDX */ |
0x00000000, /* VGT_INDX_OFFSET */ |
0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ |
0x00000000, /* SX_ALPHA_TEST_CONTROL */ |
0x00000000, /* CB_BLEND_RED */ |
0x00000000, /* CB_BLEND_GREEN */ |
0x00000000, /* CB_BLEND_BLUE */ |
0x00000000, /* CB_BLEND_ALPHA */ |
0xc0016900, |
0x00000187, |
0x00000100, /* SPI_VS_OUT_ID_0 */ |
0xc0026900, |
0x00000191, |
0x00000100, /* SPI_PS_INPUT_CNTL_0 */ |
0x00000101, /* SPI_PS_INPUT_CNTL_1 */ |
0xc0016900, |
0x000001b1, |
0x00000000, /* SPI_VS_OUT_CONFIG */ |
0xc0106900, |
0x000001b3, |
0x20000001, /* SPI_PS_IN_CONTROL_0 */ |
0x00000000, /* SPI_PS_IN_CONTROL_1 */ |
0x00000000, /* SPI_INTERP_CONTROL_0 */ |
0x00000000, /* SPI_INPUT_Z */ |
0x00000000, /* SPI_FOG_CNTL */ |
0x00100000, /* SPI_BARYC_CNTL */ |
0x00000000, /* SPI_PS_IN_CONTROL_2 */ |
0x00000000, /* SPI_COMPUTE_INPUT_CNTL */ |
0x00000000, /* SPI_COMPUTE_NUM_THREAD_X */ |
0x00000000, /* SPI_COMPUTE_NUM_THREAD_Y */ |
0x00000000, /* SPI_COMPUTE_NUM_THREAD_Z */ |
0x00000000, /* SPI_GPR_MGMT */ |
0x00000000, /* SPI_LDS_MGMT */ |
0x00000000, /* SPI_STACK_MGMT */ |
0x00000000, /* SPI_WAVE_MGMT_1 */ |
0x00000000, /* SPI_WAVE_MGMT_2 */ |
0xc0016900, |
0x000001e0, |
0x00000000, /* CB_BLEND0_CONTROL */ |
0xc00e6900, |
0x00000200, |
0x00000000, /* DB_DEPTH_CONTROL */ |
0x00000000, /* DB_EQAA */ |
0x00cc0010, /* CB_COLOR_CONTROL */ |
0x00000210, /* DB_SHADER_CONTROL */ |
0x00010000, /* PA_CL_CLIP_CNTL */ |
0x00000004, /* PA_SU_SC_MODE_CNTL */ |
0x00000100, /* PA_CL_VTE_CNTL */ |
0x00000000, /* PA_CL_VS_OUT_CNTL */ |
0x00000000, /* PA_CL_NANINF_CNTL */ |
0x00000000, /* PA_SU_LINE_STIPPLE_CNTL */ |
0x00000000, /* PA_SU_LINE_STIPPLE_SCALE */ |
0x00000000, /* PA_SU_PRIM_FILTER_CNTL */ |
0x00000000, /* */ |
0x00000000, /* */ |
0xc0026900, |
0x00000229, |
0x00000000, /* SQ_PGM_START_FS */ |
0x00000000, |
0xc0016900, |
0x0000023b, |
0x00000000, /* SQ_LDS_ALLOC_PS */ |
0xc0066900, |
0x00000240, |
0x00000000, /* SQ_ESGS_RING_ITEMSIZE */ |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0xc0046900, |
0x00000247, |
0x00000000, /* SQ_GS_VERT_ITEMSIZE */ |
0x00000000, |
0x00000000, |
0x00000000, |
0xc0116900, |
0x00000280, |
0x00000000, /* PA_SU_POINT_SIZE */ |
0x00000000, /* PA_SU_POINT_MINMAX */ |
0x00000008, /* PA_SU_LINE_CNTL */ |
0x00000000, /* PA_SC_LINE_STIPPLE */ |
0x00000000, /* VGT_OUTPUT_PATH_CNTL */ |
0x00000000, /* VGT_HOS_CNTL */ |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, /* VGT_GS_MODE */ |
0xc0026900, |
0x00000292, |
0x00000000, /* PA_SC_MODE_CNTL_0 */ |
0x00000000, /* PA_SC_MODE_CNTL_1 */ |
0xc0016900, |
0x000002a1, |
0x00000000, /* VGT_PRIMITIVEID_EN */ |
0xc0016900, |
0x000002a5, |
0x00000000, /* VGT_MULTI_PRIM_IB_RESET_EN */ |
0xc0026900, |
0x000002a8, |
0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ |
0x00000000, |
0xc0026900, |
0x000002ad, |
0x00000000, /* VGT_REUSE_OFF */ |
0x00000000, |
0xc0016900, |
0x000002d5, |
0x00000000, /* VGT_SHADER_STAGES_EN */ |
0xc0016900, |
0x000002dc, |
0x0000aa00, /* DB_ALPHA_TO_MASK */ |
0xc0066900, |
0x000002de, |
0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0xc0026900, |
0x000002e5, |
0x00000000, /* VGT_STRMOUT_CONFIG */ |
0x00000000, |
0xc01b6900, |
0x000002f5, |
0x76543210, /* PA_SC_CENTROID_PRIORITY_0 */ |
0xfedcba98, /* PA_SC_CENTROID_PRIORITY_1 */ |
0x00000000, /* PA_SC_LINE_CNTL */ |
0x00000000, /* PA_SC_AA_CONFIG */ |
0x00000005, /* PA_SU_VTX_CNTL */ |
0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ |
0x3f800000, /* PA_CL_GB_VERT_DISC_ADJ */ |
0x3f800000, /* PA_CL_GB_HORZ_CLIP_ADJ */ |
0x3f800000, /* PA_CL_GB_HORZ_DISC_ADJ */ |
0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */ |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0x00000000, |
0xffffffff, /* PA_SC_AA_MASK_X0Y0_X1Y0 */ |
0xffffffff, |
0xc0026900, |
0x00000316, |
0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */ |
0x00000010, /* */ |
}; |
const u32 cayman_vs[] = |
{ |
0x00000004, |
0x80400400, |
0x0000a03c, |
0x95000688, |
0x00004000, |
0x15000688, |
0x00000000, |
0x88000000, |
0x04000000, |
0x67961001, |
#ifdef __BIG_ENDIAN |
0x00020000, |
#else |
0x00000000, |
#endif |
0x00000000, |
0x04000000, |
0x67961000, |
#ifdef __BIG_ENDIAN |
0x00020008, |
#else |
0x00000008, |
#endif |
0x00000000, |
}; |
const u32 cayman_ps[] = |
{ |
0x00000004, |
0xa00c0000, |
0x00000008, |
0x80400000, |
0x00000000, |
0x95000688, |
0x00000000, |
0x88000000, |
0x00380400, |
0x00146b10, |
0x00380000, |
0x20146b10, |
0x00380400, |
0x40146b00, |
0x80380000, |
0x60146b00, |
0x00000010, |
0x000d1000, |
0xb0800000, |
0x00000000, |
}; |
const u32 cayman_ps_size = ARRAY_SIZE(cayman_ps); |
const u32 cayman_vs_size = ARRAY_SIZE(cayman_vs); |
const u32 cayman_default_size = ARRAY_SIZE(cayman_default_state); |
/drivers/video/drm/radeon/cayman_blit_shaders.h |
---|
0,0 → 1,35 |
/* |
* Copyright 2010 Advanced Micro Devices, Inc. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
* |
*/ |
#ifndef CAYMAN_BLIT_SHADERS_H |
#define CAYMAN_BLIT_SHADERS_H |
extern const u32 cayman_ps[]; |
extern const u32 cayman_vs[]; |
extern const u32 cayman_default_state[]; |
extern const u32 cayman_ps_size, cayman_vs_size; |
extern const u32 cayman_default_size; |
#endif |
/drivers/video/drm/radeon/evergreen.c |
---|
281,7 → 281,6 |
} |
} |
#if 0 |
void evergreen_hpd_init(struct radeon_device *rdev) |
{ |
struct drm_device *dev = rdev->ddev; |
320,10 → 319,12 |
break; |
} |
} |
if (rdev->irq.installed) |
evergreen_irq_set(rdev); |
// if (rdev->irq.installed) |
// evergreen_irq_set(rdev); |
} |
#if 0 |
void evergreen_hpd_fini(struct radeon_device *rdev) |
{ |
struct drm_device *dev = rdev->ddev; |
2240,6 → 2241,9 |
/* Get VRAM informations */ |
rdev->mc.vram_is_ddr = true; |
if (rdev->flags & RADEON_IS_IGP) |
tmp = RREG32(FUS_MC_ARB_RAMCFG); |
else |
tmp = RREG32(MC_ARB_RAMCFG); |
if (tmp & CHANSIZE_OVERRIDE) { |
chansize = 16; |
/drivers/video/drm/radeon/evergreend.h |
---|
466,7 → 466,7 |
#define IH_RB_WPTR_ADDR_LO 0x3e14 |
#define IH_CNTL 0x3e18 |
# define ENABLE_INTR (1 << 0) |
# define IH_MC_SWAP(x) ((x) << 2) |
# define IH_MC_SWAP(x) ((x) << 1) |
# define IH_MC_SWAP_NONE 0 |
# define IH_MC_SWAP_16BIT 1 |
# define IH_MC_SWAP_32BIT 2 |
547,7 → 547,7 |
# define LB_D5_VBLANK_INTERRUPT (1 << 3) |
# define DC_HPD5_INTERRUPT (1 << 17) |
# define DC_HPD5_RX_INTERRUPT (1 << 18) |
#define DISP_INTERRUPT_STATUS_CONTINUE5 0x6050 |
#define DISP_INTERRUPT_STATUS_CONTINUE5 0x6150 |
# define LB_D6_VLINE_INTERRUPT (1 << 2) |
# define LB_D6_VBLANK_INTERRUPT (1 << 3) |
# define DC_HPD6_INTERRUPT (1 << 17) |
/drivers/video/drm/radeon/fwblob.asm |
---|
114,11 → 114,29 |
dd SUMOME_START |
dd (SUMOME_END - SUMOME_START) |
dd FIRMWARE_SUMO2_ME |
dd SUMO2ME_START |
dd (SUMO2ME_END - SUMO2ME_START) |
macro ni_code [arg] |
{ |
dd FIRMWARE_#arg#_ME |
dd arg#ME_START |
dd (arg#ME_END - arg#ME_START) |
dd FIRMWARE_#arg#_PFP |
dd arg#PFP_START |
dd (arg#PFP_END - arg#PFP_START) |
dd FIRMWARE_#arg#_MC |
dd arg#MC_START |
dd (arg#MC_END - arg#MC_START) |
} |
ni_code BARTS, TURKS, CAICOS, CAYMAN |
dd FIRMWARE_RV610_PFP |
dd RV610PFP_START |
dd (RV610PFP_END - RV610PFP_START) |
180,6 → 198,9 |
dd SUMO2PFP_START |
dd (SUMO2PFP_END - SUMO2PFP_START) |
dd FIRMWARE_BARTS_PFP |
dd BARTSPFP_START |
dd (BARTSPFP_END - BARTSPFP_START) |
dd FIRMWARE_R600_RLC |
206,10 → 227,15 |
dd JUNIPERRLC_START |
dd (JUNIPERRLC_END - JUNIPERRLC_START) |
dd FIRMWARE_BTC_RLC |
dd BTCRLC_START |
dd (BTCRLC_END - BTCRLC_START) |
dd FIRMWARE_SUMO_RLC |
dd SUMORLC_START |
dd (SUMORLC_END - SUMORLC_START) |
___end_builtin_fw: |
223,7 → 249,6 |
FIRMWARE_RS690_CP db 'radeon/RS690_cp.bin',0 |
FIRMWARE_RS780_ME db 'radeon/RS780_me.bin',0 |
FIRMWARE_RS780_PFP db 'radeon/RS780_pfp.bin',0 |
FIRMWARE_R600_ME db 'radeon/RV600_me.bin',0 |
FIRMWARE_RV610_ME db 'radeon/RV610_me.bin',0 |
234,6 → 259,7 |
FIRMWARE_RV710_ME db 'radeon/RV710_me.bin',0 |
FIRMWARE_RV730_ME db 'radeon/RV730_me.bin',0 |
FIRMWARE_RV770_ME db 'radeon/RV770_me.bin',0 |
FIRMWARE_CYPRESS_ME db 'radeon/CYPRESS_me.bin',0 |
FIRMWARE_REDWOOD_ME db 'radeon/REDWOOD_me.bin',0 |
FIRMWARE_CEDAR_ME db 'radeon/CEDAR_me.bin',0 |
242,7 → 268,13 |
FIRMWARE_SUMO_ME db 'radeon/SUMO_me.bin',0 |
FIRMWARE_SUMO2_ME db 'radeon/SUMO2_me.bin',0 |
FIRMWARE_BARTS_ME db 'radeon/BARTS_me.bin',0 |
FIRMWARE_TURKS_ME db 'radeon/TURKS_me.bin',0 |
FIRMWARE_CAICOS_ME db 'radeon/CAICOS_me.bin',0 |
FIRMWARE_CAYMAN_ME db 'radeon/CAYMAN_me.bin',0 |
FIRMWARE_RS780_PFP db 'radeon/RS780_pfp.bin',0 |
FIRMWARE_R600_PFP db 'radeon/R600_pfp.bin',0 |
FIRMWARE_RV610_PFP db 'radeon/RV610_pfp.bin',0 |
FIRMWARE_RV620_PFP db 'radeon/RV620_pfp.bin',0 |
252,6 → 284,7 |
FIRMWARE_RV710_PFP db 'radeon/RV710_pfp.bin',0 |
FIRMWARE_RV730_PFP db 'radeon/RV730_pfp.bin',0 |
FIRMWARE_RV770_PFP db 'radeon/RV770_pfp.bin',0 |
FIRMWARE_CYPRESS_PFP db 'radeon/CYPRESS_pfp.bin',0 |
FIRMWARE_REDWOOD_PFP db 'radeon/REDWOOD_pfp.bin',0 |
FIRMWARE_CEDAR_PFP db 'radeon/CEDAR_pfp.bin',0 |
260,7 → 293,12 |
FIRMWARE_SUMO_PFP db 'radeon/SUMO_pfp.bin',0 |
FIRMWARE_SUMO2_PFP db 'radeon/SUMO2_pfp.bin',0 |
FIRMWARE_BARTS_PFP db 'radeon/BARTS_pfp.bin',0 |
FIRMWARE_TURKS_PFP db 'radeon/TURKS_pfp.bin',0 |
FIRMWARE_CAICOS_PFP db 'radeon/CAICOS_pfp.bin',0 |
FIRMWARE_CAYMAN_PFP db 'radeon/CAYMAN_pfp.bin',0 |
FIRMWARE_R600_RLC db 'radeon/R600_rlc.bin',0 |
FIRMWARE_R700_RLC db 'radeon/R700_rlc.bin',0 |
FIRMWARE_CYPRESS_RLC db 'radeon/CYPRESS_rlc.bin',0 |
268,8 → 306,16 |
FIRMWARE_CEDAR_RLC db 'radeon/CEDAR_rlc.bin',0 |
FIRMWARE_JUNIPER_RLC db 'radeon/JUNIPER_rlc.bin',0 |
FIRMWARE_SUMO_RLC db 'radeon/SUMO_rlc.bin',0 |
FIRMWARE_BTC_RLC db 'radeon/BTC_rlc.bin',0 |
FIRMWARE_CAYMAN_RLC db 'radeon/CAYMAN_rlc.bin',0 |
FIRMWARE_BARTS_MC db 'radeon/BARTS_mc.bin',0 |
FIRMWARE_TURKS_MC db 'radeon/TURKS_mc.bin',0 |
FIRMWARE_CAICOS_MC db 'radeon/CAICOS_mc.bin',0 |
FIRMWARE_CAYMAN_MC db 'radeon/CAYMAN_mc.bin',0 |
align 16 |
R100CP_START: |
file 'firmware/R100_cp.bin' |
396,8 → 442,28 |
file 'firmware/SUMO2_me.bin' |
SUMO2ME_END: |
align 16 |
BARTSME_START: |
file 'firmware/BARTS_me.bin' |
BARTSME_END: |
align 16 |
TURKSME_START: |
file 'firmware/TURKS_me.bin' |
TURKSME_END: |
align 16 |
CAICOSME_START: |
file 'firmware/CAICOS_me.bin' |
CAICOSME_END: |
align 16 |
CAYMANME_START: |
file 'firmware/CAYMAN_me.bin' |
CAYMANME_END: |
align 16 |
RV610PFP_START: |
file 'firmware/RV610_pfp.bin' |
RV610PFP_END: |
476,9 → 542,27 |
file 'firmware/SUMO2_pfp.bin' |
SUMO2PFP_END: |
align 16 |
BARTSPFP_START: |
file 'firmware/BARTS_pfp.bin' |
BARTSPFP_END: |
align 16 |
TURKSPFP_START: |
file 'firmware/TURKS_pfp.bin' |
TURKSPFP_END: |
align 16 |
CAICOSPFP_START: |
file 'firmware/CAICOS_pfp.bin' |
CAICOSPFP_END: |
align 16 |
CAYMANPFP_START: |
file 'firmware/CAYMAN_pfp.bin' |
CAYMANPFP_END: |
align 16 |
R600RLC_START: |
file 'firmware/R600_rlc.bin' |
R600RLC_END: |
512,3 → 596,34 |
SUMORLC_START: |
file 'firmware/SUMO_rlc.bin' |
SUMORLC_END: |
align 16 |
BTCRLC_START: |
file 'firmware/BTC_rlc.bin' |
BTCRLC_END: |
align 16 |
CAYMANRLC_START: |
file 'firmware/CAYMAN_rlc.bin' |
CAYMANRLC_END: |
align 16 |
BARTSMC_START: |
file 'firmware/BARTS_mc.bin' |
BARTSMC_END: |
align 16 |
TURKSMC_START: |
file 'firmware/TURKS_mc.bin' |
TURKSMC_END: |
align 16 |
CAICOSMC_START: |
file 'firmware/CAICOS_mc.bin' |
CAICOSMC_END: |
align 16 |
CAYMANMC_START: |
file 'firmware/CAYMAN_mc.bin' |
CAYMANMC_END: |
/drivers/video/drm/radeon/ni.c |
---|
31,7 → 31,7 |
#include "nid.h" |
#include "atom.h" |
#include "ni_reg.h" |
//#include "cayman_blit_shaders.h" |
#include "cayman_blit_shaders.h" |
extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); |
extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save); |
389,7 → 389,6 |
return err; |
} |
#if 0 |
/* |
* Core functions |
*/ |
1029,12 → 1028,6 |
} |
} |
void cayman_pcie_gart_fini(struct radeon_device *rdev) |
{ |
cayman_pcie_gart_disable(rdev); |
radeon_gart_table_vram_free(rdev); |
radeon_gart_fini(rdev); |
} |
/* |
* CP. |
1044,7 → 1037,6 |
if (enable) |
WREG32(CP_ME_CNTL, 0); |
else { |
radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); |
WREG32(SCRATCH_UMSK, 0); |
} |
1142,12 → 1134,8 |
return 0; |
} |
static void cayman_cp_fini(struct radeon_device *rdev) |
{ |
cayman_cp_enable(rdev, false); |
radeon_ring_fini(rdev); |
} |
int cayman_cp_resume(struct radeon_device *rdev) |
{ |
u32 tmp; |
1388,26 → 1376,10 |
return r; |
cayman_gpu_init(rdev); |
r = evergreen_blit_init(rdev); |
if (r) { |
evergreen_blit_fini(rdev); |
rdev->asic->copy = NULL; |
dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); |
} |
/* allocate wb buffer */ |
r = radeon_wb_init(rdev); |
if (r) |
return r; |
/* Enable IRQ */ |
r = r600_irq_init(rdev); |
if (r) { |
DRM_ERROR("radeon: IH init failed (%d).\n", r); |
radeon_irq_kms_fini(rdev); |
return r; |
} |
evergreen_irq_set(rdev); |
r = radeon_ring_init(rdev, rdev->cp.ring_size); |
if (r) |
1422,54 → 1394,10 |
return 0; |
} |
int cayman_resume(struct radeon_device *rdev) |
{ |
int r; |
/* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, |
* posting will perform necessary task to bring back GPU into good |
* shape. |
*/ |
/* post card */ |
atom_asic_init(rdev->mode_info.atom_context); |
r = cayman_startup(rdev); |
if (r) { |
DRM_ERROR("cayman startup failed on resume\n"); |
return r; |
} |
r = r600_ib_test(rdev); |
if (r) { |
DRM_ERROR("radeon: failled testing IB (%d).\n", r); |
return r; |
} |
return r; |
} |
int cayman_suspend(struct radeon_device *rdev) |
{ |
int r; |
/* FIXME: we should wait for ring to be empty */ |
cayman_cp_enable(rdev, false); |
rdev->cp.ready = false; |
evergreen_irq_suspend(rdev); |
radeon_wb_disable(rdev); |
cayman_pcie_gart_disable(rdev); |
/* unpin shaders bo */ |
r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); |
if (likely(r == 0)) { |
radeon_bo_unpin(rdev->r600_blit.shader_obj); |
radeon_bo_unreserve(rdev->r600_blit.shader_obj); |
} |
return 0; |
} |
/* Plan is to move initialization in that function and use |
* helper function so that radeon_device_init pretty much |
* do nothing more than calling asic specific function. This |
1514,9 → 1442,6 |
/* Initialize clocks */ |
radeon_get_clock_info(rdev->ddev); |
/* Fence driver */ |
r = radeon_fence_driver_init(rdev); |
if (r) |
return r; |
/* initialize memory controller */ |
r = evergreen_mc_init(rdev); |
if (r) |
1526,15 → 1451,10 |
if (r) |
return r; |
r = radeon_irq_kms_init(rdev); |
if (r) |
return r; |
rdev->cp.ring_obj = NULL; |
r600_ring_init(rdev, 1024 * 1024); |
rdev->ih.ring_obj = NULL; |
r600_ih_ring_init(rdev, 64 * 1024); |
r = r600_pcie_gart_init(rdev); |
if (r) |
1544,25 → 1464,10 |
r = cayman_startup(rdev); |
if (r) { |
dev_err(rdev->dev, "disabling GPU acceleration\n"); |
cayman_cp_fini(rdev); |
r600_irq_fini(rdev); |
radeon_wb_fini(rdev); |
radeon_irq_kms_fini(rdev); |
cayman_pcie_gart_fini(rdev); |
rdev->accel_working = false; |
} |
if (rdev->accel_working) { |
r = radeon_ib_pool_init(rdev); |
if (r) { |
DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r); |
rdev->accel_working = false; |
} |
r = r600_ib_test(rdev); |
if (r) { |
DRM_ERROR("radeon: failed testing IB (%d).\n", r); |
rdev->accel_working = false; |
} |
} |
/* Don't start up if the MC ucode is missing. |
* The default clocks and voltages before the MC ucode |
1576,19 → 1481,3 |
return 0; |
} |
void cayman_fini(struct radeon_device *rdev) |
{ |
evergreen_blit_fini(rdev); |
cayman_cp_fini(rdev); |
r600_irq_fini(rdev); |
radeon_wb_fini(rdev); |
radeon_irq_kms_fini(rdev); |
cayman_pcie_gart_fini(rdev); |
radeon_gem_fini(rdev); |
radeon_fence_driver_fini(rdev); |
radeon_bo_fini(rdev); |
radeon_atombios_fini(rdev); |
kfree(rdev->bios); |
rdev->bios = NULL; |
} |
#endif |
/drivers/video/drm/radeon/nid.h |
---|
320,7 → 320,7 |
#define CGTS_USER_TCC_DISABLE 0x914C |
#define TCC_DISABLE_MASK 0xFFFF0000 |
#define TCC_DISABLE_SHIFT 16 |
#define CGTS_SM_CTRL_REG 0x915C |
#define CGTS_SM_CTRL_REG 0x9150 |
#define OVERRIDE (1 << 21) |
#define TA_CNTL_AUX 0x9508 |
/drivers/video/drm/radeon/pci.c |
---|
208,7 → 208,7 |
irq = PciRead8(dev->bus, dev->devfn, PCI_INTERRUPT_PIN); |
dev->pin = irq; |
if (irq) |
PciRead8(dev->bus, dev->devfn, PCI_INTERRUPT_LINE); |
irq = PciRead8(dev->bus, dev->devfn, PCI_INTERRUPT_LINE); |
dev->irq = irq; |
}; |
/drivers/video/drm/radeon/r100.c |
---|
3551,9 → 3551,6 |
if (r) { |
/* Somethings want wront with the accel init stop accel */ |
dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
// r100_cp_fini(rdev); |
// r100_wb_fini(rdev); |
// r100_ib_fini(rdev); |
if (rdev->flags & RADEON_IS_PCI) |
r100_pci_gart_fini(rdev); |
rdev->accel_working = false; |
/drivers/video/drm/radeon/r600.c |
---|
289,28 → 289,28 |
switch (radeon_connector->hpd.hpd) { |
case RADEON_HPD_1: |
WREG32(DC_HPD1_CONTROL, tmp); |
// rdev->irq.hpd[0] = true; |
rdev->irq.hpd[0] = true; |
break; |
case RADEON_HPD_2: |
WREG32(DC_HPD2_CONTROL, tmp); |
// rdev->irq.hpd[1] = true; |
rdev->irq.hpd[1] = true; |
break; |
case RADEON_HPD_3: |
WREG32(DC_HPD3_CONTROL, tmp); |
// rdev->irq.hpd[2] = true; |
rdev->irq.hpd[2] = true; |
break; |
case RADEON_HPD_4: |
WREG32(DC_HPD4_CONTROL, tmp); |
// rdev->irq.hpd[3] = true; |
rdev->irq.hpd[3] = true; |
break; |
/* DCE 3.2 */ |
case RADEON_HPD_5: |
WREG32(DC_HPD5_CONTROL, tmp); |
// rdev->irq.hpd[4] = true; |
rdev->irq.hpd[4] = true; |
break; |
case RADEON_HPD_6: |
WREG32(DC_HPD6_CONTROL, tmp); |
// rdev->irq.hpd[5] = true; |
rdev->irq.hpd[5] = true; |
break; |
default: |
break; |
322,15 → 322,15 |
switch (radeon_connector->hpd.hpd) { |
case RADEON_HPD_1: |
WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); |
// rdev->irq.hpd[0] = true; |
rdev->irq.hpd[0] = true; |
break; |
case RADEON_HPD_2: |
WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN); |
// rdev->irq.hpd[1] = true; |
rdev->irq.hpd[1] = true; |
break; |
case RADEON_HPD_3: |
WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN); |
// rdev->irq.hpd[2] = true; |
rdev->irq.hpd[2] = true; |
break; |
default: |
break; |
337,8 → 337,8 |
} |
} |
} |
// if (rdev->irq.installed) |
// r600_irq_set(rdev); |
if (rdev->irq.installed) |
r600_irq_set(rdev); |
} |
void r600_hpd_fini(struct radeon_device *rdev) |
352,28 → 352,28 |
switch (radeon_connector->hpd.hpd) { |
case RADEON_HPD_1: |
WREG32(DC_HPD1_CONTROL, 0); |
// rdev->irq.hpd[0] = false; |
rdev->irq.hpd[0] = false; |
break; |
case RADEON_HPD_2: |
WREG32(DC_HPD2_CONTROL, 0); |
// rdev->irq.hpd[1] = false; |
rdev->irq.hpd[1] = false; |
break; |
case RADEON_HPD_3: |
WREG32(DC_HPD3_CONTROL, 0); |
// rdev->irq.hpd[2] = false; |
rdev->irq.hpd[2] = false; |
break; |
case RADEON_HPD_4: |
WREG32(DC_HPD4_CONTROL, 0); |
// rdev->irq.hpd[3] = false; |
rdev->irq.hpd[3] = false; |
break; |
/* DCE 3.2 */ |
case RADEON_HPD_5: |
WREG32(DC_HPD5_CONTROL, 0); |
// rdev->irq.hpd[4] = false; |
rdev->irq.hpd[4] = false; |
break; |
case RADEON_HPD_6: |
WREG32(DC_HPD6_CONTROL, 0); |
// rdev->irq.hpd[5] = false; |
rdev->irq.hpd[5] = false; |
break; |
default: |
break; |
385,15 → 385,15 |
switch (radeon_connector->hpd.hpd) { |
case RADEON_HPD_1: |
WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0); |
// rdev->irq.hpd[0] = false; |
rdev->irq.hpd[0] = false; |
break; |
case RADEON_HPD_2: |
WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0); |
// rdev->irq.hpd[1] = false; |
rdev->irq.hpd[1] = false; |
break; |
case RADEON_HPD_3: |
WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0); |
// rdev->irq.hpd[2] = false; |
rdev->irq.hpd[2] = false; |
break; |
default: |
break; |
1955,9 → 1955,9 |
DRM_ERROR("Failed to register debugfs file for mc !\n"); |
} |
/* This don't do much */ |
// r = radeon_gem_init(rdev); |
// if (r) |
// return r; |
r = radeon_gem_init(rdev); |
if (r) |
return r; |
/* Read BIOS */ |
if (!radeon_get_bios(rdev)) { |
if (ASIC_IS_AVIVO(rdev)) |
1987,9 → 1987,9 |
/* Initialize clocks */ |
radeon_get_clock_info(rdev->ddev); |
/* Fence driver */ |
// r = radeon_fence_driver_init(rdev); |
// if (r) |
// return r; |
r = radeon_fence_driver_init(rdev); |
if (r) |
return r; |
if (rdev->flags & RADEON_IS_AGP) { |
r = radeon_agp_init(rdev); |
if (r) |
2003,15 → 2003,15 |
if (r) |
return r; |
// r = radeon_irq_kms_init(rdev); |
// if (r) |
// return r; |
r = radeon_irq_kms_init(rdev); |
if (r) |
return r; |
rdev->cp.ring_obj = NULL; |
r600_ring_init(rdev, 1024 * 1024); |
// rdev->ih.ring_obj = NULL; |
// r600_ih_ring_init(rdev, 64 * 1024); |
rdev->ih.ring_obj = NULL; |
r600_ih_ring_init(rdev, 64 * 1024); |
r = r600_pcie_gart_init(rdev); |
if (r) |
2039,9 → 2039,268 |
// rdev->accel_working = false; |
// } |
} |
if (r) |
return r; /* TODO error handling */ |
return 0; |
} |
/* |
* CS stuff |
*/ |
void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
{ |
/* FIXME: implement */ |
radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
radeon_ring_write(rdev, |
#ifdef __BIG_ENDIAN |
(2 << 0) | |
#endif |
(ib->gpu_addr & 0xFFFFFFFC)); |
radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); |
radeon_ring_write(rdev, ib->length_dw); |
} |
int r600_ib_test(struct radeon_device *rdev) |
{ |
struct radeon_ib *ib; |
uint32_t scratch; |
uint32_t tmp = 0; |
unsigned i; |
int r; |
r = radeon_scratch_get(rdev, &scratch); |
if (r) { |
DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r); |
return r; |
} |
WREG32(scratch, 0xCAFEDEAD); |
r = radeon_ib_get(rdev, &ib); |
if (r) { |
DRM_ERROR("radeon: failed to get ib (%d).\n", r); |
return r; |
} |
ib->ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1); |
ib->ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); |
ib->ptr[2] = 0xDEADBEEF; |
ib->ptr[3] = PACKET2(0); |
ib->ptr[4] = PACKET2(0); |
ib->ptr[5] = PACKET2(0); |
ib->ptr[6] = PACKET2(0); |
ib->ptr[7] = PACKET2(0); |
ib->ptr[8] = PACKET2(0); |
ib->ptr[9] = PACKET2(0); |
ib->ptr[10] = PACKET2(0); |
ib->ptr[11] = PACKET2(0); |
ib->ptr[12] = PACKET2(0); |
ib->ptr[13] = PACKET2(0); |
ib->ptr[14] = PACKET2(0); |
ib->ptr[15] = PACKET2(0); |
ib->length_dw = 16; |
r = radeon_ib_schedule(rdev, ib); |
if (r) { |
radeon_scratch_free(rdev, scratch); |
radeon_ib_free(rdev, &ib); |
DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); |
return r; |
} |
r = radeon_fence_wait(ib->fence, false); |
if (r) { |
DRM_ERROR("radeon: fence wait failed (%d).\n", r); |
return r; |
} |
for (i = 0; i < rdev->usec_timeout; i++) { |
tmp = RREG32(scratch); |
if (tmp == 0xDEADBEEF) |
break; |
DRM_UDELAY(1); |
} |
if (i < rdev->usec_timeout) { |
DRM_INFO("ib test succeeded in %u usecs\n", i); |
} else { |
DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", |
scratch, tmp); |
r = -EINVAL; |
} |
radeon_scratch_free(rdev, scratch); |
radeon_ib_free(rdev, &ib); |
return r; |
} |
/* |
* Interrupts |
* |
* Interrupts use a ring buffer on r6xx/r7xx hardware. It works pretty |
* the same as the CP ring buffer, but in reverse. Rather than the CPU |
* writing to the ring and the GPU consuming, the GPU writes to the ring |
* and host consumes. As the host irq handler processes interrupts, it |
* increments the rptr. When the rptr catches up with the wptr, all the |
* current interrupts have been processed. |
*/ |
void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size) |
{ |
u32 rb_bufsz; |
/* Align ring size */ |
rb_bufsz = drm_order(ring_size / 4); |
ring_size = (1 << rb_bufsz) * 4; |
rdev->ih.ring_size = ring_size; |
rdev->ih.ptr_mask = rdev->ih.ring_size - 1; |
rdev->ih.rptr = 0; |
} |
static int r600_ih_ring_alloc(struct radeon_device *rdev) |
{ |
int r; |
/* Allocate ring buffer */ |
if (rdev->ih.ring_obj == NULL) { |
r = radeon_bo_create(rdev, rdev->ih.ring_size, |
PAGE_SIZE, true, |
RADEON_GEM_DOMAIN_GTT, |
&rdev->ih.ring_obj); |
if (r) { |
DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r); |
return r; |
} |
r = radeon_bo_reserve(rdev->ih.ring_obj, false); |
if (unlikely(r != 0)) |
return r; |
r = radeon_bo_pin(rdev->ih.ring_obj, |
RADEON_GEM_DOMAIN_GTT, |
&rdev->ih.gpu_addr); |
if (r) { |
radeon_bo_unreserve(rdev->ih.ring_obj); |
DRM_ERROR("radeon: failed to pin ih ring buffer (%d).\n", r); |
return r; |
} |
r = radeon_bo_kmap(rdev->ih.ring_obj, |
(void **)&rdev->ih.ring); |
radeon_bo_unreserve(rdev->ih.ring_obj); |
if (r) { |
DRM_ERROR("radeon: failed to map ih ring buffer (%d).\n", r); |
return r; |
} |
} |
return 0; |
} |
static void r600_ih_ring_fini(struct radeon_device *rdev) |
{ |
int r; |
if (rdev->ih.ring_obj) { |
r = radeon_bo_reserve(rdev->ih.ring_obj, false); |
if (likely(r == 0)) { |
radeon_bo_kunmap(rdev->ih.ring_obj); |
radeon_bo_unpin(rdev->ih.ring_obj); |
radeon_bo_unreserve(rdev->ih.ring_obj); |
} |
radeon_bo_unref(&rdev->ih.ring_obj); |
rdev->ih.ring = NULL; |
rdev->ih.ring_obj = NULL; |
} |
} |
void r600_rlc_stop(struct radeon_device *rdev) |
{ |
if ((rdev->family >= CHIP_RV770) && |
(rdev->family <= CHIP_RV740)) { |
/* r7xx asics need to soft reset RLC before halting */ |
WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC); |
RREG32(SRBM_SOFT_RESET); |
udelay(15000); |
WREG32(SRBM_SOFT_RESET, 0); |
RREG32(SRBM_SOFT_RESET); |
} |
WREG32(RLC_CNTL, 0); |
} |
static void r600_rlc_start(struct radeon_device *rdev) |
{ |
WREG32(RLC_CNTL, RLC_ENABLE); |
} |
static int r600_rlc_init(struct radeon_device *rdev) |
{ |
u32 i; |
const __be32 *fw_data; |
if (!rdev->rlc_fw) |
return -EINVAL; |
r600_rlc_stop(rdev); |
WREG32(RLC_HB_BASE, 0); |
WREG32(RLC_HB_CNTL, 0); |
WREG32(RLC_HB_RPTR, 0); |
WREG32(RLC_HB_WPTR, 0); |
if (rdev->family <= CHIP_CAICOS) { |
WREG32(RLC_HB_WPTR_LSB_ADDR, 0); |
WREG32(RLC_HB_WPTR_MSB_ADDR, 0); |
} |
WREG32(RLC_MC_CNTL, 0); |
WREG32(RLC_UCODE_CNTL, 0); |
fw_data = (const __be32 *)rdev->rlc_fw->data; |
if (rdev->family >= CHIP_CAYMAN) { |
for (i = 0; i < CAYMAN_RLC_UCODE_SIZE; i++) { |
WREG32(RLC_UCODE_ADDR, i); |
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); |
} |
} else if (rdev->family >= CHIP_CEDAR) { |
for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) { |
WREG32(RLC_UCODE_ADDR, i); |
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); |
} |
} else if (rdev->family >= CHIP_RV770) { |
for (i = 0; i < R700_RLC_UCODE_SIZE; i++) { |
WREG32(RLC_UCODE_ADDR, i); |
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); |
} |
} else { |
for (i = 0; i < RLC_UCODE_SIZE; i++) { |
WREG32(RLC_UCODE_ADDR, i); |
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); |
} |
} |
WREG32(RLC_UCODE_ADDR, 0); |
r600_rlc_start(rdev); |
return 0; |
} |
static void r600_enable_interrupts(struct radeon_device *rdev) |
{ |
u32 ih_cntl = RREG32(IH_CNTL); |
u32 ih_rb_cntl = RREG32(IH_RB_CNTL); |
ih_cntl |= ENABLE_INTR; |
ih_rb_cntl |= IH_RB_ENABLE; |
WREG32(IH_CNTL, ih_cntl); |
WREG32(IH_RB_CNTL, ih_rb_cntl); |
rdev->ih.enabled = true; |
} |
void r600_disable_interrupts(struct radeon_device *rdev) |
{ |
u32 ih_rb_cntl = RREG32(IH_RB_CNTL); |
u32 ih_cntl = RREG32(IH_CNTL); |
ih_rb_cntl &= ~IH_RB_ENABLE; |
ih_cntl &= ~ENABLE_INTR; |
WREG32(IH_RB_CNTL, ih_rb_cntl); |
WREG32(IH_CNTL, ih_cntl); |
/* set rptr, wptr to 0 */ |
WREG32(IH_RB_RPTR, 0); |
WREG32(IH_RB_WPTR, 0); |
rdev->ih.enabled = false; |
rdev->ih.wptr = 0; |
rdev->ih.rptr = 0; |
} |
static void r600_disable_interrupt_state(struct radeon_device *rdev) |
{ |
u32 tmp; |
2080,13 → 2339,524 |
} |
} |
int r600_irq_init(struct radeon_device *rdev) |
{ |
int ret = 0; |
int rb_bufsz; |
u32 interrupt_cntl, ih_cntl, ih_rb_cntl; |
/* allocate ring */ |
ret = r600_ih_ring_alloc(rdev); |
if (ret) |
return ret; |
/* disable irqs */ |
r600_disable_interrupts(rdev); |
/* init rlc */ |
ret = r600_rlc_init(rdev); |
if (ret) { |
r600_ih_ring_fini(rdev); |
return ret; |
} |
/* setup interrupt control */ |
/* set dummy read address to ring address */ |
WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8); |
interrupt_cntl = RREG32(INTERRUPT_CNTL); |
/* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi |
* IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN |
*/ |
interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE; |
/* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */ |
interrupt_cntl &= ~IH_REQ_NONSNOOP_EN; |
WREG32(INTERRUPT_CNTL, interrupt_cntl); |
WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8); |
rb_bufsz = drm_order(rdev->ih.ring_size / 4); |
ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE | |
IH_WPTR_OVERFLOW_CLEAR | |
(rb_bufsz << 1)); |
if (rdev->wb.enabled) |
ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE; |
/* set the writeback address whether it's enabled or not */ |
WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC); |
WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF); |
WREG32(IH_RB_CNTL, ih_rb_cntl); |
/* set rptr, wptr to 0 */ |
WREG32(IH_RB_RPTR, 0); |
WREG32(IH_RB_WPTR, 0); |
/* Default settings for IH_CNTL (disabled at first) */ |
ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10); |
/* RPTR_REARM only works if msi's are enabled */ |
if (rdev->msi_enabled) |
ih_cntl |= RPTR_REARM; |
#ifdef __BIG_ENDIAN |
ih_cntl |= IH_MC_SWAP(IH_MC_SWAP_32BIT); |
#endif |
WREG32(IH_CNTL, ih_cntl); |
/* force the active interrupt state to all disabled */ |
if (rdev->family >= CHIP_CEDAR) |
evergreen_disable_interrupt_state(rdev); |
else |
r600_disable_interrupt_state(rdev); |
/* enable irqs */ |
r600_enable_interrupts(rdev); |
return ret; |
} |
int r600_irq_set(struct radeon_device *rdev) |
{ |
u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; |
u32 mode_int = 0; |
u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; |
u32 grbm_int_cntl = 0; |
u32 hdmi1, hdmi2; |
u32 d1grph = 0, d2grph = 0; |
ENTER(); |
if (!rdev->irq.installed) { |
WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
return -EINVAL; |
} |
/* don't enable anything if the ih is disabled */ |
if (!rdev->ih.enabled) { |
r600_disable_interrupts(rdev); |
/* force the active interrupt state to all disabled */ |
r600_disable_interrupt_state(rdev); |
return 0; |
} |
hdmi1 = RREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL) & ~R600_HDMI_INT_EN; |
if (ASIC_IS_DCE3(rdev)) { |
hdmi2 = RREG32(R600_HDMI_BLOCK3 + R600_HDMI_CNTL) & ~R600_HDMI_INT_EN; |
hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; |
hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; |
hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; |
hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; |
if (ASIC_IS_DCE32(rdev)) { |
hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; |
hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; |
} |
} else { |
hdmi2 = RREG32(R600_HDMI_BLOCK2 + R600_HDMI_CNTL) & ~R600_HDMI_INT_EN; |
hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN; |
hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN; |
hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN; |
} |
if (rdev->irq.sw_int) { |
DRM_DEBUG("r600_irq_set: sw int\n"); |
cp_int_cntl |= RB_INT_ENABLE; |
cp_int_cntl |= TIME_STAMP_INT_ENABLE; |
} |
if (rdev->irq.crtc_vblank_int[0] || |
rdev->irq.pflip[0]) { |
DRM_DEBUG("r600_irq_set: vblank 0\n"); |
mode_int |= D1MODE_VBLANK_INT_MASK; |
} |
if (rdev->irq.crtc_vblank_int[1] || |
rdev->irq.pflip[1]) { |
DRM_DEBUG("r600_irq_set: vblank 1\n"); |
mode_int |= D2MODE_VBLANK_INT_MASK; |
} |
if (rdev->irq.hpd[0]) { |
DRM_DEBUG("r600_irq_set: hpd 1\n"); |
hpd1 |= DC_HPDx_INT_EN; |
} |
if (rdev->irq.hpd[1]) { |
DRM_DEBUG("r600_irq_set: hpd 2\n"); |
hpd2 |= DC_HPDx_INT_EN; |
} |
if (rdev->irq.hpd[2]) { |
DRM_DEBUG("r600_irq_set: hpd 3\n"); |
hpd3 |= DC_HPDx_INT_EN; |
} |
if (rdev->irq.hpd[3]) { |
DRM_DEBUG("r600_irq_set: hpd 4\n"); |
hpd4 |= DC_HPDx_INT_EN; |
} |
if (rdev->irq.hpd[4]) { |
DRM_DEBUG("r600_irq_set: hpd 5\n"); |
hpd5 |= DC_HPDx_INT_EN; |
} |
if (rdev->irq.hpd[5]) { |
DRM_DEBUG("r600_irq_set: hpd 6\n"); |
hpd6 |= DC_HPDx_INT_EN; |
} |
if (rdev->irq.hdmi[0]) { |
DRM_DEBUG("r600_irq_set: hdmi 1\n"); |
hdmi1 |= R600_HDMI_INT_EN; |
} |
if (rdev->irq.hdmi[1]) { |
DRM_DEBUG("r600_irq_set: hdmi 2\n"); |
hdmi2 |= R600_HDMI_INT_EN; |
} |
if (rdev->irq.gui_idle) { |
DRM_DEBUG("gui idle\n"); |
grbm_int_cntl |= GUI_IDLE_INT_ENABLE; |
} |
WREG32(CP_INT_CNTL, cp_int_cntl); |
WREG32(DxMODE_INT_MASK, mode_int); |
WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph); |
WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph); |
WREG32(GRBM_INT_CNTL, grbm_int_cntl); |
WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); |
if (ASIC_IS_DCE3(rdev)) { |
WREG32(R600_HDMI_BLOCK3 + R600_HDMI_CNTL, hdmi2); |
WREG32(DC_HPD1_INT_CONTROL, hpd1); |
WREG32(DC_HPD2_INT_CONTROL, hpd2); |
WREG32(DC_HPD3_INT_CONTROL, hpd3); |
WREG32(DC_HPD4_INT_CONTROL, hpd4); |
if (ASIC_IS_DCE32(rdev)) { |
WREG32(DC_HPD5_INT_CONTROL, hpd5); |
WREG32(DC_HPD6_INT_CONTROL, hpd6); |
} |
} else { |
WREG32(R600_HDMI_BLOCK2 + R600_HDMI_CNTL, hdmi2); |
WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); |
WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); |
WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3); |
} |
LEAVE(); |
return 0; |
} |
static inline void r600_irq_ack(struct radeon_device *rdev) |
{ |
u32 tmp; |
if (ASIC_IS_DCE3(rdev)) { |
rdev->irq.stat_regs.r600.disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); |
rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); |
rdev->irq.stat_regs.r600.disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); |
} else { |
rdev->irq.stat_regs.r600.disp_int = RREG32(DISP_INTERRUPT_STATUS); |
rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); |
rdev->irq.stat_regs.r600.disp_int_cont2 = 0; |
} |
rdev->irq.stat_regs.r600.d1grph_int = RREG32(D1GRPH_INTERRUPT_STATUS); |
rdev->irq.stat_regs.r600.d2grph_int = RREG32(D2GRPH_INTERRUPT_STATUS); |
if (rdev->irq.stat_regs.r600.d1grph_int & DxGRPH_PFLIP_INT_OCCURRED) |
WREG32(D1GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR); |
if (rdev->irq.stat_regs.r600.d2grph_int & DxGRPH_PFLIP_INT_OCCURRED) |
WREG32(D2GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR); |
if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) |
WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); |
if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) |
WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); |
if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) |
WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); |
if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) |
WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); |
if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { |
if (ASIC_IS_DCE3(rdev)) { |
tmp = RREG32(DC_HPD1_INT_CONTROL); |
tmp |= DC_HPDx_INT_ACK; |
WREG32(DC_HPD1_INT_CONTROL, tmp); |
} else { |
tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL); |
tmp |= DC_HPDx_INT_ACK; |
WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); |
} |
} |
if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { |
if (ASIC_IS_DCE3(rdev)) { |
tmp = RREG32(DC_HPD2_INT_CONTROL); |
tmp |= DC_HPDx_INT_ACK; |
WREG32(DC_HPD2_INT_CONTROL, tmp); |
} else { |
tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL); |
tmp |= DC_HPDx_INT_ACK; |
WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); |
} |
} |
if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { |
if (ASIC_IS_DCE3(rdev)) { |
tmp = RREG32(DC_HPD3_INT_CONTROL); |
tmp |= DC_HPDx_INT_ACK; |
WREG32(DC_HPD3_INT_CONTROL, tmp); |
} else { |
tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL); |
tmp |= DC_HPDx_INT_ACK; |
WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); |
} |
} |
if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { |
tmp = RREG32(DC_HPD4_INT_CONTROL); |
tmp |= DC_HPDx_INT_ACK; |
WREG32(DC_HPD4_INT_CONTROL, tmp); |
} |
if (ASIC_IS_DCE32(rdev)) { |
if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { |
tmp = RREG32(DC_HPD5_INT_CONTROL); |
tmp |= DC_HPDx_INT_ACK; |
WREG32(DC_HPD5_INT_CONTROL, tmp); |
} |
if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { |
tmp = RREG32(DC_HPD5_INT_CONTROL); |
tmp |= DC_HPDx_INT_ACK; |
WREG32(DC_HPD6_INT_CONTROL, tmp); |
} |
} |
if (RREG32(R600_HDMI_BLOCK1 + R600_HDMI_STATUS) & R600_HDMI_INT_PENDING) { |
WREG32_P(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, R600_HDMI_INT_ACK, ~R600_HDMI_INT_ACK); |
} |
if (ASIC_IS_DCE3(rdev)) { |
if (RREG32(R600_HDMI_BLOCK3 + R600_HDMI_STATUS) & R600_HDMI_INT_PENDING) { |
WREG32_P(R600_HDMI_BLOCK3 + R600_HDMI_CNTL, R600_HDMI_INT_ACK, ~R600_HDMI_INT_ACK); |
} |
} else { |
if (RREG32(R600_HDMI_BLOCK2 + R600_HDMI_STATUS) & R600_HDMI_INT_PENDING) { |
WREG32_P(R600_HDMI_BLOCK2 + R600_HDMI_CNTL, R600_HDMI_INT_ACK, ~R600_HDMI_INT_ACK); |
} |
} |
} |
static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) |
{ |
u32 wptr, tmp; |
if (rdev->wb.enabled) |
wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); |
else |
wptr = RREG32(IH_RB_WPTR); |
if (wptr & RB_OVERFLOW) { |
/* When a ring buffer overflow happen start parsing interrupt |
* from the last not overwritten vector (wptr + 16). Hopefully |
* this should allow us to catchup. |
*/ |
dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", |
wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); |
rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; |
tmp = RREG32(IH_RB_CNTL); |
tmp |= IH_WPTR_OVERFLOW_CLEAR; |
WREG32(IH_RB_CNTL, tmp); |
} |
return (wptr & rdev->ih.ptr_mask); |
} |
/* r600 IV Ring |
* Each IV ring entry is 128 bits: |
* [7:0] - interrupt source id |
* [31:8] - reserved |
* [59:32] - interrupt source data |
* [127:60] - reserved |
* |
* The basic interrupt vector entries |
* are decoded as follows: |
* src_id src_data description |
* 1 0 D1 Vblank |
* 1 1 D1 Vline |
* 5 0 D2 Vblank |
* 5 1 D2 Vline |
* 19 0 FP Hot plug detection A |
* 19 1 FP Hot plug detection B |
* 19 2 DAC A auto-detection |
* 19 3 DAC B auto-detection |
* 21 4 HDMI block A |
* 21 5 HDMI block B |
* 176 - CP_INT RB |
* 177 - CP_INT IB1 |
* 178 - CP_INT IB2 |
* 181 - EOP Interrupt |
* 233 - GUI Idle |
* |
* Note, these are based on r600 and may need to be |
* adjusted or added to on newer asics |
*/ |
int r600_irq_process(struct radeon_device *rdev) |
{ |
u32 wptr; |
u32 rptr; |
u32 src_id, src_data; |
u32 ring_index; |
unsigned long flags; |
bool queue_hotplug = false; |
if (!rdev->ih.enabled || rdev->shutdown) |
return IRQ_NONE; |
wptr = r600_get_ih_wptr(rdev); |
rptr = rdev->ih.rptr; |
DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); |
spin_lock_irqsave(&rdev->ih.lock, flags); |
if (rptr == wptr) { |
spin_unlock_irqrestore(&rdev->ih.lock, flags); |
return IRQ_NONE; |
} |
restart_ih: |
/* display interrupts */ |
r600_irq_ack(rdev); |
rdev->ih.wptr = wptr; |
while (rptr != wptr) { |
/* wptr/rptr are in bytes! */ |
ring_index = rptr / 4; |
src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; |
src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; |
switch (src_id) { |
case 1: /* D1 vblank/vline */ |
switch (src_data) { |
case 0: /* D1 vblank */ |
if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) { |
if (rdev->irq.crtc_vblank_int[0]) { |
// drm_handle_vblank(rdev->ddev, 0); |
rdev->pm.vblank_sync = true; |
// wake_up(&rdev->irq.vblank_queue); |
} |
// if (rdev->irq.pflip[0]) |
// radeon_crtc_handle_flip(rdev, 0); |
rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; |
DRM_DEBUG("IH: D1 vblank\n"); |
} |
break; |
case 1: /* D1 vline */ |
if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) { |
rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT; |
DRM_DEBUG("IH: D1 vline\n"); |
} |
break; |
default: |
DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
break; |
} |
break; |
case 5: /* D2 vblank/vline */ |
switch (src_data) { |
case 0: /* D2 vblank */ |
if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) { |
if (rdev->irq.crtc_vblank_int[1]) { |
// drm_handle_vblank(rdev->ddev, 1); |
rdev->pm.vblank_sync = true; |
// wake_up(&rdev->irq.vblank_queue); |
} |
// if (rdev->irq.pflip[1]) |
// radeon_crtc_handle_flip(rdev, 1); |
rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; |
DRM_DEBUG("IH: D2 vblank\n"); |
} |
break; |
case 1: /* D1 vline */ |
if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) { |
rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT; |
DRM_DEBUG("IH: D2 vline\n"); |
} |
break; |
default: |
DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
break; |
} |
break; |
case 19: /* HPD/DAC hotplug */ |
switch (src_data) { |
case 0: |
if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { |
rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT; |
queue_hotplug = true; |
DRM_DEBUG("IH: HPD1\n"); |
} |
break; |
case 1: |
if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { |
rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT; |
queue_hotplug = true; |
DRM_DEBUG("IH: HPD2\n"); |
} |
break; |
case 4: |
if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { |
rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT; |
queue_hotplug = true; |
DRM_DEBUG("IH: HPD3\n"); |
} |
break; |
case 5: |
if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { |
rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT; |
queue_hotplug = true; |
DRM_DEBUG("IH: HPD4\n"); |
} |
break; |
case 10: |
if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { |
rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT; |
queue_hotplug = true; |
DRM_DEBUG("IH: HPD5\n"); |
} |
break; |
case 12: |
if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { |
rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT; |
queue_hotplug = true; |
DRM_DEBUG("IH: HPD6\n"); |
} |
break; |
default: |
DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
break; |
} |
break; |
case 21: /* HDMI */ |
DRM_DEBUG("IH: HDMI: 0x%x\n", src_data); |
// r600_audio_schedule_polling(rdev); |
break; |
case 176: /* CP_INT in ring buffer */ |
case 177: /* CP_INT in IB1 */ |
case 178: /* CP_INT in IB2 */ |
DRM_DEBUG("IH: CP int: 0x%08x\n", src_data); |
// radeon_fence_process(rdev); |
break; |
case 181: /* CP EOP event */ |
DRM_DEBUG("IH: CP EOP\n"); |
// radeon_fence_process(rdev); |
break; |
case 233: /* GUI IDLE */ |
DRM_DEBUG("IH: GUI idle\n"); |
rdev->pm.gui_idle = true; |
// wake_up(&rdev->irq.idle_queue); |
break; |
default: |
DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
break; |
} |
/* wptr/rptr are in bytes! */ |
rptr += 16; |
rptr &= rdev->ih.ptr_mask; |
} |
/* make sure wptr hasn't changed while processing */ |
wptr = r600_get_ih_wptr(rdev); |
if (wptr != rdev->ih.wptr) |
goto restart_ih; |
// if (queue_hotplug) |
// schedule_work(&rdev->hotplug_work); |
rdev->ih.rptr = rptr; |
WREG32(IH_RB_RPTR, rdev->ih.rptr); |
spin_unlock_irqrestore(&rdev->ih.lock, flags); |
return IRQ_HANDLED; |
} |
/* |
* Debugfs info |
*/ |
/drivers/video/drm/radeon/r600d.h |
---|
536,7 → 536,7 |
#define IH_RB_WPTR_ADDR_LO 0x3e14 |
#define IH_CNTL 0x3e18 |
# define ENABLE_INTR (1 << 0) |
# define IH_MC_SWAP(x) ((x) << 2) |
# define IH_MC_SWAP(x) ((x) << 1) |
# define IH_MC_SWAP_NONE 0 |
# define IH_MC_SWAP_16BIT 1 |
# define IH_MC_SWAP_32BIT 2 |
/drivers/video/drm/radeon/radeon.h |
---|
70,7 → 70,7 |
#include <ttm/ttm_placement.h> |
#include <ttm/ttm_module.h> |
#include <linux/irqreturn.h> |
#include <pci.h> |
#include <errno-base.h> |
263,6 → 263,7 |
void radeon_combios_get_power_modes(struct radeon_device *rdev); |
void radeon_atombios_get_power_modes(struct radeon_device *rdev); |
void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type); |
int radeon_atom_get_max_vddc(struct radeon_device *rdev, u16 *voltage); |
void rs690_pm_info(struct radeon_device *rdev); |
extern int rv6xx_get_temp(struct radeon_device *rdev); |
extern int rv770_get_temp(struct radeon_device *rdev); |
375,6 → 376,15 |
uint64_t *gpu_addr); |
void radeon_gem_object_unpin(struct drm_gem_object *obj); |
int radeon_mode_dumb_create(struct drm_file *file_priv, |
struct drm_device *dev, |
struct drm_mode_create_dumb *args); |
int radeon_mode_dumb_mmap(struct drm_file *filp, |
struct drm_device *dev, |
uint32_t handle, uint64_t *offset_p); |
int radeon_mode_dumb_destroy(struct drm_file *file_priv, |
struct drm_device *dev, |
uint32_t handle); |
/* |
* GART structures, functions & helpers |
524,6 → 534,8 |
void radeon_irq_kms_fini(struct radeon_device *rdev); |
void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev); |
void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev); |
void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc); |
void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc); |
/* |
* CP & ring. |
638,7 → 650,7 |
struct radeon_cs_parser { |
struct device *dev; |
struct radeon_device *rdev; |
// struct drm_file *filp; |
struct drm_file *filp; |
/* chunks */ |
unsigned nchunks; |
struct radeon_cs_chunk *chunks; |
1229,8 → 1241,7 |
struct r600_blit r600_blit; |
struct r700_vram_scratch vram_scratch; |
int msi_enabled; /* msi enabled */ |
// struct r600_ih ih; /* r6/700 interrupt ring */ |
// struct workqueue_struct *wq; |
struct r600_ih ih; /* r6/700 interrupt ring */ |
// struct work_struct hotplug_work; |
int num_crtc; /* number of crtcs */ |
struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ |
1310,6 → 1321,7 |
#define RREG16(reg) readw(((void __iomem *)rdev->rmmio) + (reg)) |
#define WREG16(reg, v) writew(v, ((void __iomem *)rdev->rmmio) + (reg)) |
#define RREG32(reg) r100_mm_rreg(rdev, (reg)) |
#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg))) |
#define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) |
#define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) |
#define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) |
/drivers/video/drm/radeon/radeon_asic.c |
---|
518,8 → 518,8 |
.gart_set_page = &rs600_gart_set_page, |
.ring_test = &r600_ring_test, |
// .ring_ib_execute = &r600_ring_ib_execute, |
// .irq_set = &r600_irq_set, |
// .irq_process = &r600_irq_process, |
.irq_set = &r600_irq_set, |
.irq_process = &r600_irq_process, |
.fence_ring_emit = &r600_fence_ring_emit, |
// .cs_parse = &r600_cs_parse, |
// .copy_blit = &r600_copy_blit, |
555,8 → 555,8 |
.gart_set_page = &rs600_gart_set_page, |
.ring_test = &r600_ring_test, |
// .ring_ib_execute = &r600_ring_ib_execute, |
// .irq_set = &r600_irq_set, |
// .irq_process = &r600_irq_process, |
.irq_set = &r600_irq_set, |
.irq_process = &r600_irq_process, |
.fence_ring_emit = &r600_fence_ring_emit, |
// .cs_parse = &r600_cs_parse, |
// .copy_blit = &r600_copy_blit, |
589,9 → 589,9 |
.gart_tlb_flush = &r600_pcie_gart_tlb_flush, |
.gart_set_page = &rs600_gart_set_page, |
.ring_test = &r600_ring_test, |
// .ring_ib_execute = &r600_ring_ib_execute, |
// .irq_set = &r600_irq_set, |
// .irq_process = &r600_irq_process, |
.ring_ib_execute = &r600_ring_ib_execute, |
.irq_set = &r600_irq_set, |
.irq_process = &r600_irq_process, |
.fence_ring_emit = &r600_fence_ring_emit, |
// .cs_parse = &r600_cs_parse, |
// .copy_blit = &r600_copy_blit, |
706,26 → 706,24 |
.set_surface_reg = r600_set_surface_reg, |
.clear_surface_reg = r600_clear_surface_reg, |
.bandwidth_update = &evergreen_bandwidth_update, |
.hpd_init = &evergreen_hpd_init, |
.hpd_sense = &evergreen_hpd_sense, |
}; |
#if 0 |
static struct radeon_asic cayman_asic = { |
.init = &cayman_init, |
.fini = &cayman_fini, |
.suspend = &cayman_suspend, |
.resume = &cayman_resume, |
// .fini = &evergreen_fini, |
// .suspend = &evergreen_suspend, |
// .resume = &evergreen_resume, |
.cp_commit = &r600_cp_commit, |
.gpu_is_lockup = &cayman_gpu_is_lockup, |
.asic_reset = &cayman_asic_reset, |
.vga_set_state = &r600_vga_set_state, |
.gart_tlb_flush = &cayman_pcie_gart_tlb_flush, |
.gart_set_page = &rs600_gart_set_page, |
.ring_test = &r600_ring_test, |
.ring_ib_execute = &evergreen_ring_ib_execute, |
.irq_set = &evergreen_irq_set, |
.irq_process = &evergreen_irq_process, |
.get_vblank_counter = &evergreen_get_vblank_counter, |
// .ring_ib_execute = &r600_ring_ib_execute, |
// .irq_set = &r600_irq_set, |
// .irq_process = &r600_irq_process, |
.fence_ring_emit = &r600_fence_ring_emit, |
// .cs_parse = &r600_cs_parse, |
// .copy_blit = &r600_copy_blit, |
735,22 → 733,13 |
.set_engine_clock = &radeon_atom_set_engine_clock, |
.get_memory_clock = &radeon_atom_get_memory_clock, |
.set_memory_clock = &radeon_atom_set_memory_clock, |
.get_pcie_lanes = NULL, |
.set_pcie_lanes = NULL, |
.set_clock_gating = NULL, |
.set_surface_reg = r600_set_surface_reg, |
.clear_surface_reg = r600_clear_surface_reg, |
.bandwidth_update = &evergreen_bandwidth_update, |
.gui_idle = &r600_gui_idle, |
.pm_misc = &evergreen_pm_misc, |
.pm_prepare = &evergreen_pm_prepare, |
.pm_finish = &evergreen_pm_finish, |
.pm_init_profile = &r600_pm_init_profile, |
.pm_get_dynpm_state = &r600_pm_get_dynpm_state, |
.pre_page_flip = &evergreen_pre_page_flip, |
.page_flip = &evergreen_page_flip, |
.post_page_flip = &evergreen_post_page_flip, |
}; |
#endif |
int radeon_asic_init(struct radeon_device *rdev) |
{ |
863,7 → 852,11 |
rdev->num_crtc = 6; |
rdev->asic = &btc_asic; |
break; |
case CHIP_CAYMAN: |
rdev->asic = &cayman_asic; |
/* set num crtcs */ |
rdev->num_crtc = 6; |
break; |
default: |
/* FIXME: not supported yet */ |
return -EINVAL; |
/drivers/video/drm/radeon/radeon_bios.c |
---|
105,7 → 105,7 |
static bool radeon_atrm_get_bios(struct radeon_device *rdev) |
{ |
int ret; |
int size = 64 * 1024; |
int size = 256 * 1024; |
int i; |
if (!radeon_atrm_supported(rdev->pdev)) |
/drivers/video/drm/radeon/radeon_device.c |
---|
197,6 → 197,93 |
} |
} |
void radeon_wb_disable(struct radeon_device *rdev) |
{ |
int r; |
if (rdev->wb.wb_obj) { |
r = radeon_bo_reserve(rdev->wb.wb_obj, false); |
if (unlikely(r != 0)) |
return; |
radeon_bo_kunmap(rdev->wb.wb_obj); |
radeon_bo_unpin(rdev->wb.wb_obj); |
radeon_bo_unreserve(rdev->wb.wb_obj); |
} |
rdev->wb.enabled = false; |
} |
void radeon_wb_fini(struct radeon_device *rdev) |
{ |
radeon_wb_disable(rdev); |
if (rdev->wb.wb_obj) { |
radeon_bo_unref(&rdev->wb.wb_obj); |
rdev->wb.wb = NULL; |
rdev->wb.wb_obj = NULL; |
} |
} |
int radeon_wb_init(struct radeon_device *rdev) |
{ |
int r; |
if (rdev->wb.wb_obj == NULL) { |
r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, |
RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj); |
if (r) { |
dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); |
return r; |
} |
} |
r = radeon_bo_reserve(rdev->wb.wb_obj, false); |
if (unlikely(r != 0)) { |
radeon_wb_fini(rdev); |
return r; |
} |
r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, |
&rdev->wb.gpu_addr); |
if (r) { |
radeon_bo_unreserve(rdev->wb.wb_obj); |
dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r); |
radeon_wb_fini(rdev); |
return r; |
} |
r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); |
radeon_bo_unreserve(rdev->wb.wb_obj); |
if (r) { |
dev_warn(rdev->dev, "(%d) map WB bo failed\n", r); |
radeon_wb_fini(rdev); |
return r; |
} |
/* clear wb memory */ |
memset((char *)rdev->wb.wb, 0, RADEON_GPU_PAGE_SIZE); |
/* disable event_write fences */ |
rdev->wb.use_event = false; |
/* disabled via module param */ |
if (radeon_no_wb == 1) |
rdev->wb.enabled = false; |
else { |
/* often unreliable on AGP */ |
// if (rdev->flags & RADEON_IS_AGP) { |
// rdev->wb.enabled = false; |
// } else { |
rdev->wb.enabled = true; |
/* event_write fences are only available on r600+ */ |
if (rdev->family >= CHIP_R600) |
rdev->wb.use_event = true; |
// } |
} |
/* always use writeback/events on NI */ |
if (ASIC_IS_DCE5(rdev)) { |
rdev->wb.enabled = true; |
rdev->wb.use_event = true; |
} |
dev_info(rdev->dev, "WB %sabled\n", rdev->wb.enabled ? "en" : "dis"); |
return 0; |
} |
/** |
* radeon_vram_location - try to find VRAM location |
* @rdev: radeon device structure holding all necessary informations |
/drivers/video/drm/radeon/radeon_display.c |
---|
453,9 → 453,8 |
if (ret) { |
radeon_setup_encoder_clones(dev); |
radeon_print_display_setup(dev); |
// list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) |
// radeon_ddc_dump(drm_connector); |
list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) |
radeon_ddc_dump(drm_connector); |
} |
return ret; |
/drivers/video/drm/radeon/radeon_fence.c |
---|
30,7 → 30,7 |
*/ |
#include <linux/seq_file.h> |
#include <asm/atomic.h> |
#include <linux/wait.h> |
//#include <linux/wait.h> |
#include <linux/list.h> |
#include <linux/kref.h> |
#include <linux/slab.h> |
39,6 → 39,35 |
#include "radeon_reg.h" |
#include "radeon.h" |
static void radeon_fence_write(struct radeon_device *rdev, u32 seq) |
{ |
if (rdev->wb.enabled) { |
u32 scratch_index; |
if (rdev->wb.use_event) |
scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
else |
scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
rdev->wb.wb[scratch_index/4] = cpu_to_le32(seq);; |
} else |
WREG32(rdev->fence_drv.scratch_reg, seq); |
} |
static u32 radeon_fence_read(struct radeon_device *rdev) |
{ |
u32 seq; |
if (rdev->wb.enabled) { |
u32 scratch_index; |
if (rdev->wb.use_event) |
scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
else |
scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]); |
} else |
seq = RREG32(rdev->fence_drv.scratch_reg); |
return seq; |
} |
int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) |
{ |
unsigned long irq_flags; |
49,15 → 78,15 |
return 0; |
} |
fence->seq = atomic_add_return(1, &rdev->fence_drv.seq); |
if (!rdev->cp.ready) { |
if (!rdev->cp.ready) |
/* FIXME: cp is not running assume everythings is done right |
* away |
*/ |
WREG32(rdev->fence_drv.scratch_reg, fence->seq); |
} else |
radeon_fence_write(rdev, fence->seq); |
else |
radeon_fence_ring_emit(rdev, fence); |
trace_radeon_fence_emit(rdev->ddev, fence->seq); |
// trace_radeon_fence_emit(rdev->ddev, fence->seq); |
fence->emited = true; |
list_move_tail(&fence->list, &rdev->fence_drv.emited); |
write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
72,19 → 101,12 |
bool wake = false; |
unsigned long cjiffies; |
if (rdev->wb.enabled) { |
u32 scratch_index; |
if (rdev->wb.use_event) |
scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
else |
scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]); |
} else |
seq = RREG32(rdev->fence_drv.scratch_reg); |
#if 0 |
seq = radeon_fence_read(rdev); |
if (seq != rdev->fence_drv.last_seq) { |
rdev->fence_drv.last_seq = seq; |
rdev->fence_drv.last_jiffies = jiffies; |
rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; |
// rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; |
} else { |
cjiffies = jiffies; |
if (time_after(cjiffies, rdev->fence_drv.last_jiffies)) { |
126,6 → 148,7 |
} while (i != &rdev->fence_drv.emited); |
wake = true; |
} |
#endif |
return wake; |
} |
150,7 → 173,7 |
if ((*fence) == NULL) { |
return -ENOMEM; |
} |
kref_init(&((*fence)->kref)); |
// kref_init(&((*fence)->kref)); |
(*fence)->rdev = rdev; |
(*fence)->emited = false; |
(*fence)->signaled = false; |
208,11 → 231,13 |
if (radeon_fence_signaled(fence)) { |
return 0; |
} |
#if 0 |
timeout = rdev->fence_drv.last_timeout; |
retry: |
/* save current sequence used to check for GPU lockup */ |
seq = rdev->fence_drv.last_seq; |
trace_radeon_fence_wait_begin(rdev->ddev, seq); |
// trace_radeon_fence_wait_begin(rdev->ddev, seq); |
if (intr) { |
radeon_irq_kms_sw_irq_get(rdev); |
r = wait_event_interruptible_timeout(rdev->fence_drv.queue, |
227,7 → 252,7 |
radeon_fence_signaled(fence), timeout); |
radeon_irq_kms_sw_irq_put(rdev); |
} |
trace_radeon_fence_wait_end(rdev->ddev, seq); |
// trace_radeon_fence_wait_end(rdev->ddev, seq); |
if (unlikely(!radeon_fence_signaled(fence))) { |
/* we were interrupted for some reason and fence isn't |
* isn't signaled yet, resume wait |
250,19 → 275,21 |
r = radeon_gpu_reset(rdev); |
if (r) |
return r; |
WREG32(rdev->fence_drv.scratch_reg, fence->seq); |
radeon_fence_write(rdev, fence->seq); |
rdev->gpu_lockup = false; |
} |
timeout = RADEON_FENCE_JIFFIES_TIMEOUT; |
// timeout = RADEON_FENCE_JIFFIES_TIMEOUT; |
write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); |
rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; |
rdev->fence_drv.last_jiffies = jiffies; |
// rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; |
// rdev->fence_drv.last_jiffies = jiffies; |
write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
goto retry; |
} |
#endif |
return 0; |
} |
#if 0 |
int radeon_fence_wait_next(struct radeon_device *rdev) |
{ |
unsigned long irq_flags; |
315,16 → 342,16 |
return fence; |
} |
#endif |
void radeon_fence_unref(struct radeon_fence **fence) |
{ |
struct radeon_fence *tmp = *fence; |
*fence = NULL; |
if (tmp) { |
kref_put(&tmp->kref, radeon_fence_destroy); |
} |
} |
#if 0 |
void radeon_fence_process(struct radeon_device *rdev) |
{ |
unsigned long irq_flags; |
338,6 → 365,8 |
} |
} |
#endif |
int radeon_fence_driver_init(struct radeon_device *rdev) |
{ |
unsigned long irq_flags; |
350,34 → 379,18 |
write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
return r; |
} |
WREG32(rdev->fence_drv.scratch_reg, 0); |
radeon_fence_write(rdev, 0); |
atomic_set(&rdev->fence_drv.seq, 0); |
INIT_LIST_HEAD(&rdev->fence_drv.created); |
INIT_LIST_HEAD(&rdev->fence_drv.emited); |
INIT_LIST_HEAD(&rdev->fence_drv.signaled); |
init_waitqueue_head(&rdev->fence_drv.queue); |
// 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)) { |
dev_err(rdev->dev, "fence debugfs file creation failed\n"); |
} |
return 0; |
} |
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); |
rdev->fence_drv.initialized = false; |
} |
/* |
* Fence debugfs |
*/ |
390,7 → 403,7 |
struct radeon_fence *fence; |
seq_printf(m, "Last signaled fence 0x%08X\n", |
RREG32(rdev->fence_drv.scratch_reg)); |
radeon_fence_read(rdev)); |
if (!list_empty(&rdev->fence_drv.emited)) { |
fence = list_entry(rdev->fence_drv.emited.prev, |
struct radeon_fence, list); |
/drivers/video/drm/radeon/radeon_irq_kms.c |
---|
0,0 → 1,225 |
/* |
* Copyright 2008 Advanced Micro Devices, Inc. |
* Copyright 2008 Red Hat Inc. |
* Copyright 2009 Jerome Glisse. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
* OTHER DEALINGS IN THE SOFTWARE. |
* |
* Authors: Dave Airlie |
* Alex Deucher |
* Jerome Glisse |
*/ |
#include "drmP.h" |
#include "drm_crtc_helper.h" |
#include "radeon_drm.h" |
#include "radeon_reg.h" |
#include "radeon.h" |
#include "atom.h" |
static struct radeon_device *main_device; |
#if 0 |
irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) |
{ |
struct drm_device *dev = (struct drm_device *) arg; |
struct radeon_device *rdev = dev->dev_private; |
return radeon_irq_process(rdev); |
} |
/* |
* Handle hotplug events outside the interrupt handler proper. |
*/ |
static void radeon_hotplug_work_func(struct work_struct *work) |
{ |
struct radeon_device *rdev = container_of(work, struct radeon_device, |
hotplug_work); |
struct drm_device *dev = rdev->ddev; |
struct drm_mode_config *mode_config = &dev->mode_config; |
struct drm_connector *connector; |
if (mode_config->num_connector) { |
list_for_each_entry(connector, &mode_config->connector_list, head) |
radeon_connector_hotplug(connector); |
} |
/* Just fire off a uevent and let userspace tell us what to do */ |
drm_helper_hpd_irq_event(dev); |
} |
void radeon_driver_irq_uninstall_kms(struct drm_device *dev) |
{ |
struct radeon_device *rdev = dev->dev_private; |
unsigned i; |
if (rdev == NULL) { |
return; |
} |
/* Disable *all* interrupts */ |
rdev->irq.sw_int = false; |
rdev->irq.gui_idle = false; |
for (i = 0; i < rdev->num_crtc; i++) |
rdev->irq.crtc_vblank_int[i] = false; |
for (i = 0; i < 6; i++) { |
rdev->irq.hpd[i] = false; |
rdev->irq.pflip[i] = false; |
} |
radeon_irq_set(rdev); |
} |
#endif |
void irq_handler_kms() |
{ |
dbgprintf("%s\n",__FUNCTION__); |
radeon_irq_process(main_device); |
} |
static void radeon_irq_preinstall(struct radeon_device *rdev) |
{ |
unsigned i; |
/* Disable *all* interrupts */ |
rdev->irq.sw_int = false; |
rdev->irq.gui_idle = false; |
for (i = 0; i < rdev->num_crtc; i++) |
rdev->irq.crtc_vblank_int[i] = false; |
for (i = 0; i < 6; i++) { |
rdev->irq.hpd[i] = false; |
rdev->irq.pflip[i] = false; |
} |
radeon_irq_set(rdev); |
/* Clear bits */ |
radeon_irq_process(rdev); |
} |
int radeon_driver_irq_postinstall(struct radeon_device *rdev) |
{ |
// struct radeon_device *rdev = dev->dev_private; |
// dev->max_vblank_count = 0x001fffff; |
rdev->irq.sw_int = true; |
radeon_irq_set(rdev); |
return 0; |
} |
int radeon_irq_kms_init(struct radeon_device *rdev) |
{ |
int i; |
int irq_line; |
int r = 0; |
ENTER(); |
// INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); |
spin_lock_init(&rdev->irq.sw_lock); |
for (i = 0; i < rdev->num_crtc; i++) |
spin_lock_init(&rdev->irq.pflip_lock[i]); |
// r = drm_vblank_init(rdev->ddev, rdev->num_crtc); |
// if (r) { |
// return r; |
// } |
rdev->msi_enabled = 0; |
rdev->irq.installed = true; |
main_device = rdev; |
radeon_irq_preinstall(rdev); |
irq_line = rdev->pdev->irq; |
dbgprintf("%s install irq %d\n", __FUNCTION__, irq_line); |
AttachIntHandler(irq_line, irq_handler_kms, 2); |
// r = drm_irq_install(rdev->ddev); |
r = radeon_driver_irq_postinstall(rdev); |
if (r) { |
rdev->irq.installed = false; |
LEAVE(); |
return r; |
} |
DRM_INFO("radeon: irq initialized.\n"); |
return 0; |
} |
void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev) |
{ |
unsigned long irqflags; |
spin_lock_irqsave(&rdev->irq.sw_lock, irqflags); |
if (rdev->ddev->irq_enabled && (++rdev->irq.sw_refcount == 1)) { |
rdev->irq.sw_int = true; |
radeon_irq_set(rdev); |
} |
spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); |
} |
void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev) |
{ |
unsigned long irqflags; |
spin_lock_irqsave(&rdev->irq.sw_lock, irqflags); |
BUG_ON(rdev->ddev->irq_enabled && rdev->irq.sw_refcount <= 0); |
if (rdev->ddev->irq_enabled && (--rdev->irq.sw_refcount == 0)) { |
rdev->irq.sw_int = false; |
radeon_irq_set(rdev); |
} |
spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); |
} |
#if 0 |
void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc) |
{ |
unsigned long irqflags; |
if (crtc < 0 || crtc >= rdev->num_crtc) |
return; |
spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); |
if (rdev->ddev->irq_enabled && (++rdev->irq.pflip_refcount[crtc] == 1)) { |
rdev->irq.pflip[crtc] = true; |
radeon_irq_set(rdev); |
} |
spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); |
} |
void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) |
{ |
unsigned long irqflags; |
if (crtc < 0 || crtc >= rdev->num_crtc) |
return; |
spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); |
BUG_ON(rdev->ddev->irq_enabled && rdev->irq.pflip_refcount[crtc] <= 0); |
if (rdev->ddev->irq_enabled && (--rdev->irq.pflip_refcount[crtc] == 0)) { |
rdev->irq.pflip[crtc] = false; |
radeon_irq_set(rdev); |
} |
spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); |
} |
#endif |
/drivers/video/drm/radeon/radeon_ring.c |
---|
38,9 → 38,6 |
/* |
* IB. |
*/ |
#if 0 |
int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib) |
{ |
struct radeon_fence *fence; |
74,20 → 71,20 |
} |
rdev->ib_pool.head_id = (nib->idx + 1) & (RADEON_IB_POOL_SIZE - 1); |
nib->free = false; |
if (nib->fence) { |
mutex_unlock(&rdev->ib_pool.mutex); |
r = radeon_fence_wait(nib->fence, false); |
if (r) { |
dev_err(rdev->dev, "error waiting fence of IB(%u:0x%016lX:%u)\n", |
nib->idx, (unsigned long)nib->gpu_addr, nib->length_dw); |
mutex_lock(&rdev->ib_pool.mutex); |
nib->free = true; |
mutex_unlock(&rdev->ib_pool.mutex); |
radeon_fence_unref(&fence); |
return r; |
} |
mutex_lock(&rdev->ib_pool.mutex); |
} |
// if (nib->fence) { |
// mutex_unlock(&rdev->ib_pool.mutex); |
// r = radeon_fence_wait(nib->fence, false); |
// if (r) { |
// dev_err(rdev->dev, "error waiting fence of IB(%u:0x%016lX:%u)\n", |
// nib->idx, (unsigned long)nib->gpu_addr, nib->length_dw); |
// mutex_lock(&rdev->ib_pool.mutex); |
// nib->free = true; |
// mutex_unlock(&rdev->ib_pool.mutex); |
// radeon_fence_unref(&fence); |
// return r; |
// } |
// mutex_lock(&rdev->ib_pool.mutex); |
// } |
radeon_fence_unref(&nib->fence); |
nib->fence = fence; |
nib->length_dw = 0; |
136,7 → 133,6 |
radeon_ring_unlock_commit(rdev); |
return 0; |
} |
#endif |
int radeon_ib_pool_init(struct radeon_device *rdev) |
{ |
/drivers/video/drm/radeon/radeon_trace.h |
---|
0,0 → 1,82 |
#if !defined(_RADEON_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) |
#define _RADEON_TRACE_H_ |
#include <linux/stringify.h> |
#include <linux/types.h> |
#include <linux/tracepoint.h> |
#include <drm/drmP.h> |
#undef TRACE_SYSTEM |
#define TRACE_SYSTEM radeon |
#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) |
#define TRACE_INCLUDE_FILE radeon_trace |
TRACE_EVENT(radeon_bo_create, |
TP_PROTO(struct radeon_bo *bo), |
TP_ARGS(bo), |
TP_STRUCT__entry( |
__field(struct radeon_bo *, bo) |
__field(u32, pages) |
), |
TP_fast_assign( |
__entry->bo = bo; |
__entry->pages = bo->tbo.num_pages; |
), |
TP_printk("bo=%p, pages=%u", __entry->bo, __entry->pages) |
); |
DECLARE_EVENT_CLASS(radeon_fence_request, |
TP_PROTO(struct drm_device *dev, u32 seqno), |
TP_ARGS(dev, seqno), |
TP_STRUCT__entry( |
__field(u32, dev) |
__field(u32, seqno) |
), |
TP_fast_assign( |
__entry->dev = dev->primary->index; |
__entry->seqno = seqno; |
), |
TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) |
); |
DEFINE_EVENT(radeon_fence_request, radeon_fence_emit, |
TP_PROTO(struct drm_device *dev, u32 seqno), |
TP_ARGS(dev, seqno) |
); |
DEFINE_EVENT(radeon_fence_request, radeon_fence_retire, |
TP_PROTO(struct drm_device *dev, u32 seqno), |
TP_ARGS(dev, seqno) |
); |
DEFINE_EVENT(radeon_fence_request, radeon_fence_wait_begin, |
TP_PROTO(struct drm_device *dev, u32 seqno), |
TP_ARGS(dev, seqno) |
); |
DEFINE_EVENT(radeon_fence_request, radeon_fence_wait_end, |
TP_PROTO(struct drm_device *dev, u32 seqno), |
TP_ARGS(dev, seqno) |
); |
#endif |
/* This part must be outside protection */ |
#undef TRACE_INCLUDE_PATH |
#define TRACE_INCLUDE_PATH . |
#include <trace/define_trace.h> |
/drivers/video/drm/radeon/rdisplay.c |
---|
79,12 → 79,16 |
__DestroyObject(cursor); |
}; |
static void radeon_show_cursor() |
{ |
struct radeon_device *rdev = (struct radeon_device *)rdisplay->ddev->dev_private; |
if (ASIC_IS_AVIVO(rdev)) { |
if (ASIC_IS_DCE4(rdev)) { |
WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL); |
WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | |
EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); |
} else if (ASIC_IS_AVIVO(rdev)) { |
WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL); |
WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | |
(AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); |
109,8 → 113,17 |
rdisplay->cursor = cursor; |
gpu_addr = radeon_bo_gpu_offset(cursor->robj); |
if (ASIC_IS_AVIVO(rdev)) |
if (ASIC_IS_DCE4(rdev)) |
{ |
WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH, 0); |
WREG32(EVERGREEN_CUR_SURFACE_ADDRESS, gpu_addr); |
} |
else if (ASIC_IS_AVIVO(rdev)) |
{ |
if (rdev->family >= CHIP_RV770) |
WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, 0); |
WREG32(AVIVO_D1CUR_SURFACE_ADDRESS, gpu_addr); |
} |
else { |
WREG32(RADEON_CUR_OFFSET, gpu_addr - rdev->mc.vram_start); |
} |
126,7 → 139,14 |
uint32_t cur_lock; |
if (ASIC_IS_AVIVO(rdev)) { |
if (ASIC_IS_DCE4(rdev)) { |
cur_lock = RREG32(EVERGREEN_CUR_UPDATE); |
if (lock) |
cur_lock |= EVERGREEN_CURSOR_UPDATE_LOCK; |
else |
cur_lock &= ~EVERGREEN_CURSOR_UPDATE_LOCK; |
WREG32(EVERGREEN_CUR_UPDATE, cur_lock); |
} else if (ASIC_IS_AVIVO(rdev)) { |
cur_lock = RREG32(AVIVO_D1CUR_UPDATE); |
if (lock) |
cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK; |
151,12 → 171,15 |
int hot_x = cursor->hot_x; |
int hot_y = cursor->hot_y; |
int w = 32; |
radeon_lock_cursor(true); |
if (ASIC_IS_AVIVO(rdev)) |
{ |
int w = 32; |
if (ASIC_IS_DCE4(rdev)) { |
WREG32(EVERGREEN_CUR_POSITION,(x << 16) | y); |
WREG32(EVERGREEN_CUR_HOT_SPOT, (hot_x << 16) | hot_y); |
WREG32(EVERGREEN_CUR_SIZE, ((w - 1) << 16) | 31); |
} else if (ASIC_IS_AVIVO(rdev)) { |
WREG32(AVIVO_D1CUR_POSITION, (x << 16) | y); |
WREG32(AVIVO_D1CUR_HOT_SPOT, (hot_x << 16) | hot_y); |
WREG32(AVIVO_D1CUR_SIZE, ((w - 1) << 16) | 31); |
/drivers/video/drm/radeon/rdisplay_kms.c |
---|
30,7 → 30,11 |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
struct radeon_device *rdev = crtc->dev->dev_private; |
if (ASIC_IS_AVIVO(rdev)) { |
if (ASIC_IS_DCE4(rdev)) { |
WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | |
EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); |
} else if (ASIC_IS_AVIVO(rdev)) { |
WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | |
(AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); |
58,7 → 62,14 |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
uint32_t cur_lock; |
if (ASIC_IS_AVIVO(rdev)) { |
if (ASIC_IS_DCE4(rdev)) { |
cur_lock = RREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset); |
if (lock) |
cur_lock |= EVERGREEN_CURSOR_UPDATE_LOCK; |
else |
cur_lock &= ~EVERGREEN_CURSOR_UPDATE_LOCK; |
WREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock); |
} else if (ASIC_IS_AVIVO(rdev)) { |
cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset); |
if (lock) |
cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK; |
90,8 → 101,16 |
rdisplay->cursor = cursor; |
gpu_addr = radeon_bo_gpu_offset(cursor->robj); |
if (ASIC_IS_AVIVO(rdev)) |
if (ASIC_IS_DCE4(rdev)) { |
WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, |
0); |
WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
gpu_addr); |
} else if (ASIC_IS_AVIVO(rdev)) { |
if (rdev->family >= CHIP_RV770) |
WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, 0); |
WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr); |
} |
else { |
radeon_crtc->legacy_cursor_offset = gpu_addr - rdev->mc.vram_start; |
/* offset is from DISP(2)_BASE_ADDRESS */ |
110,44 → 129,18 |
int hot_x = cursor->hot_x; |
int hot_y = cursor->hot_y; |
int w = 32; |
radeon_lock_cursor_kms(crtc, true); |
if (ASIC_IS_AVIVO(rdev)) |
{ |
int w = 32; |
int i = 0; |
struct drm_crtc *crtc_p; |
/* avivo cursor are offset into the total surface */ |
// x += crtc->x; |
// y += crtc->y; |
// DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); |
#if 0 |
/* avivo cursor image can't end on 128 pixel boundry or |
* go past the end of the frame if both crtcs are enabled |
*/ |
list_for_each_entry(crtc_p, &crtc->dev->mode_config.crtc_list, head) { |
if (crtc_p->enabled) |
i++; |
} |
if (i > 1) { |
int cursor_end, frame_end; |
cursor_end = x + w; |
frame_end = crtc->x + crtc->mode.crtc_hdisplay; |
if (cursor_end >= frame_end) { |
w = w - (cursor_end - frame_end); |
if (!(frame_end & 0x7f)) |
w--; |
} else { |
if (!(cursor_end & 0x7f)) |
w--; |
} |
if (w <= 0) |
w = 1; |
} |
#endif |
if (ASIC_IS_DCE4(rdev)) { |
WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, |
(x << 16) | y); |
WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, |
(hot_x << 16) | hot_y); |
WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset, |
((w - 1) << 16) | 31); |
} else if (ASIC_IS_AVIVO(rdev)) { |
WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, |
(x << 16) | y); |
WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset, |
/drivers/video/drm/radeon/rv770.c |
---|
498,6 → 498,12 |
else |
tcp_chan_steer = 0x00fac688; |
/* RV770 CE has special chremap setup */ |
if (rdev->pdev->device == 0x944e) { |
tcp_chan_steer = 0x00b08b08; |
mc_shared_chremap = 0x00b08b08; |
} |
WREG32(TCP_CHAN_STEER, tcp_chan_steer); |
WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); |
} |
1082,6 → 1088,20 |
if (r) |
return r; |
rv770_gpu_init(rdev); |
/* allocate wb buffer */ |
r = radeon_wb_init(rdev); |
if (r) |
return r; |
/* Enable IRQ */ |
r = r600_irq_init(rdev); |
if (r) { |
DRM_ERROR("radeon: IH init failed (%d).\n", r); |
// radeon_irq_kms_fini(rdev); |
return r; |
} |
r600_irq_set(rdev); |
r = radeon_ring_init(rdev, rdev->cp.ring_size); |
if (r) |
return r; |
1111,6 → 1131,10 |
{ |
int r; |
/* This don't do much */ |
r = radeon_gem_init(rdev); |
if (r) |
return r; |
/* Read BIOS */ |
if (!radeon_get_bios(rdev)) { |
if (ASIC_IS_AVIVO(rdev)) |
1140,9 → 1164,9 |
/* Initialize clocks */ |
radeon_get_clock_info(rdev->ddev); |
/* Fence driver */ |
// r = radeon_fence_driver_init(rdev); |
// if (r) |
// return r; |
r = radeon_fence_driver_init(rdev); |
if (r) |
return r; |
/* initialize AGP */ |
if (rdev->flags & RADEON_IS_AGP) { |
r = radeon_agp_init(rdev); |
1157,10 → 1181,15 |
if (r) |
return r; |
r = radeon_irq_kms_init(rdev); |
if (r) |
return r; |
rdev->cp.ring_obj = NULL; |
r600_ring_init(rdev, 1024 * 1024); |
rdev->ih.ring_obj = NULL; |
r600_ih_ring_init(rdev, 64 * 1024); |
r = r600_pcie_gart_init(rdev); |
if (r) |
1170,23 → 1199,22 |
r = rv770_startup(rdev); |
if (r) { |
dev_err(rdev->dev, "disabling GPU acceleration\n"); |
rv770_pcie_gart_fini(rdev); |
rdev->accel_working = false; |
} |
if (rdev->accel_working) { |
// r = radeon_ib_pool_init(rdev); |
// if (r) { |
// dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
// rdev->accel_working = false; |
// } else { |
// r = r600_ib_test(rdev); |
// if (r) { |
// dev_err(rdev->dev, "IB test failed (%d).\n", r); |
// rdev->accel_working = false; |
// } |
// } |
r = radeon_ib_pool_init(rdev); |
if (r) { |
dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
rdev->accel_working = false; |
} else { |
r = r600_ib_test(rdev); |
if (r) { |
dev_err(rdev->dev, "IB test failed (%d).\n", r); |
rdev->accel_working = false; |
} |
} |
} |
return 0; |
} |