diff options
Diffstat (limited to 'drivers/gpu/drm/radeon')
61 files changed, 6830 insertions, 2134 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 09a28923f46e..feb52eee4314 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -49,7 +49,7 @@ radeon-y += radeon_device.o radeon_kms.o \ | |||
49 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ | 49 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ |
50 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ | 50 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ |
51 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ | 51 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ |
52 | r600_blit_kms.o | 52 | r600_blit_kms.o radeon_pm.o atombios_dp.o |
53 | 53 | ||
54 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 54 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
55 | 55 | ||
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 901befe03da2..6578d19dff93 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -107,6 +107,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
107 | base += 3; | 107 | base += 3; |
108 | break; | 108 | break; |
109 | case ATOM_IIO_WRITE: | 109 | case ATOM_IIO_WRITE: |
110 | (void)ctx->card->reg_read(ctx->card, CU16(base + 1)); | ||
110 | ctx->card->reg_write(ctx->card, CU16(base + 1), temp); | 111 | ctx->card->reg_write(ctx->card, CU16(base + 1), temp); |
111 | base += 3; | 112 | base += 3; |
112 | break; | 113 | break; |
@@ -262,10 +263,10 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, | |||
262 | case ATOM_ARG_FB: | 263 | case ATOM_ARG_FB: |
263 | idx = U8(*ptr); | 264 | idx = U8(*ptr); |
264 | (*ptr)++; | 265 | (*ptr)++; |
266 | val = gctx->scratch[((gctx->fb_base + idx) / 4)]; | ||
265 | if (print) | 267 | if (print) |
266 | DEBUG("FB[0x%02X]", idx); | 268 | DEBUG("FB[0x%02X]", idx); |
267 | printk(KERN_INFO "FB access is not implemented.\n"); | 269 | break; |
268 | return 0; | ||
269 | case ATOM_ARG_IMM: | 270 | case ATOM_ARG_IMM: |
270 | switch (align) { | 271 | switch (align) { |
271 | case ATOM_SRC_DWORD: | 272 | case ATOM_SRC_DWORD: |
@@ -487,9 +488,9 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr, | |||
487 | case ATOM_ARG_FB: | 488 | case ATOM_ARG_FB: |
488 | idx = U8(*ptr); | 489 | idx = U8(*ptr); |
489 | (*ptr)++; | 490 | (*ptr)++; |
491 | gctx->scratch[((gctx->fb_base + idx) / 4)] = val; | ||
490 | DEBUG("FB[0x%02X]", idx); | 492 | DEBUG("FB[0x%02X]", idx); |
491 | printk(KERN_INFO "FB access is not implemented.\n"); | 493 | break; |
492 | return; | ||
493 | case ATOM_ARG_PLL: | 494 | case ATOM_ARG_PLL: |
494 | idx = U8(*ptr); | 495 | idx = U8(*ptr); |
495 | (*ptr)++; | 496 | (*ptr)++; |
@@ -1213,3 +1214,28 @@ void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev, | |||
1213 | *crev = CU8(idx + 3); | 1214 | *crev = CU8(idx + 3); |
1214 | return; | 1215 | return; |
1215 | } | 1216 | } |
1217 | |||
1218 | int atom_allocate_fb_scratch(struct atom_context *ctx) | ||
1219 | { | ||
1220 | int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware); | ||
1221 | uint16_t data_offset; | ||
1222 | int usage_bytes; | ||
1223 | struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; | ||
1224 | |||
1225 | atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset); | ||
1226 | |||
1227 | firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); | ||
1228 | |||
1229 | DRM_DEBUG("atom firmware requested %08x %dkb\n", | ||
1230 | firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware, | ||
1231 | firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb); | ||
1232 | |||
1233 | usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; | ||
1234 | if (usage_bytes == 0) | ||
1235 | usage_bytes = 20 * 1024; | ||
1236 | /* allocate some scratch memory */ | ||
1237 | ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL); | ||
1238 | if (!ctx->scratch) | ||
1239 | return -ENOMEM; | ||
1240 | return 0; | ||
1241 | } | ||
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index e6eb38f2bcae..6671848e5ea1 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h | |||
@@ -132,6 +132,7 @@ struct atom_context { | |||
132 | uint8_t shift; | 132 | uint8_t shift; |
133 | int cs_equal, cs_above; | 133 | int cs_equal, cs_above; |
134 | int io_mode; | 134 | int io_mode; |
135 | uint32_t *scratch; | ||
135 | }; | 136 | }; |
136 | 137 | ||
137 | extern int atom_debug; | 138 | extern int atom_debug; |
@@ -142,6 +143,7 @@ int atom_asic_init(struct atom_context *); | |||
142 | void atom_destroy(struct atom_context *); | 143 | void atom_destroy(struct atom_context *); |
143 | void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); | 144 | void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); |
144 | void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev); | 145 | void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev); |
146 | int atom_allocate_fb_scratch(struct atom_context *ctx); | ||
145 | #include "atom-types.h" | 147 | #include "atom-types.h" |
146 | #include "atombios.h" | 148 | #include "atombios.h" |
147 | #include "ObjectID.h" | 149 | #include "ObjectID.h" |
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 5d402086bc47..5f48515c77a7 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h | |||
@@ -1141,7 +1141,7 @@ typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS { | |||
1141 | /* ucTableFormatRevision=1,ucTableContentRevision=2 */ | 1141 | /* ucTableFormatRevision=1,ucTableContentRevision=2 */ |
1142 | typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2 { | 1142 | typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2 { |
1143 | USHORT usPixelClock; /* in 10KHz; for bios convenient */ | 1143 | USHORT usPixelClock; /* in 10KHz; for bios convenient */ |
1144 | UCHAR ucMisc; /* see PANEL_ENCODER_MISC_xx defintions below */ | 1144 | UCHAR ucMisc; /* see PANEL_ENCODER_MISC_xx definitions below */ |
1145 | UCHAR ucAction; /* 0: turn off encoder */ | 1145 | UCHAR ucAction; /* 0: turn off encoder */ |
1146 | /* 1: setup and turn on encoder */ | 1146 | /* 1: setup and turn on encoder */ |
1147 | UCHAR ucTruncate; /* bit0=0: Disable truncate */ | 1147 | UCHAR ucTruncate; /* bit0=0: Disable truncate */ |
@@ -1424,7 +1424,7 @@ typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO { | |||
1424 | /* Structures used in FirmwareInfoTable */ | 1424 | /* Structures used in FirmwareInfoTable */ |
1425 | /****************************************************************************/ | 1425 | /****************************************************************************/ |
1426 | 1426 | ||
1427 | /* usBIOSCapability Defintion: */ | 1427 | /* usBIOSCapability Definition: */ |
1428 | /* Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; */ | 1428 | /* Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; */ |
1429 | /* Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; */ | 1429 | /* Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; */ |
1430 | /* Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; */ | 1430 | /* Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; */ |
@@ -2314,7 +2314,7 @@ typedef struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT { | |||
2314 | UCHAR ucSS_Step; | 2314 | UCHAR ucSS_Step; |
2315 | UCHAR ucSS_Delay; | 2315 | UCHAR ucSS_Delay; |
2316 | UCHAR ucSS_Id; | 2316 | UCHAR ucSS_Id; |
2317 | UCHAR ucRecommandedRef_Div; | 2317 | UCHAR ucRecommendedRef_Div; |
2318 | UCHAR ucSS_Range; /* it was reserved for V11 */ | 2318 | UCHAR ucSS_Range; /* it was reserved for V11 */ |
2319 | } ATOM_SPREAD_SPECTRUM_ASSIGNMENT; | 2319 | } ATOM_SPREAD_SPECTRUM_ASSIGNMENT; |
2320 | 2320 | ||
@@ -2386,7 +2386,7 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2 { | |||
2386 | } ATOM_ANALOG_TV_INFO_V1_2; | 2386 | } ATOM_ANALOG_TV_INFO_V1_2; |
2387 | 2387 | ||
2388 | /**************************************************************************/ | 2388 | /**************************************************************************/ |
2389 | /* VRAM usage and their defintions */ | 2389 | /* VRAM usage and their definitions */ |
2390 | 2390 | ||
2391 | /* One chunk of VRAM used by Bios are for HWICON surfaces,EDID data. */ | 2391 | /* One chunk of VRAM used by Bios are for HWICON surfaces,EDID data. */ |
2392 | /* Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below. */ | 2392 | /* Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below. */ |
@@ -2680,7 +2680,7 @@ typedef struct _ATOM_I2C_RECORD { | |||
2680 | typedef struct _ATOM_HPD_INT_RECORD { | 2680 | typedef struct _ATOM_HPD_INT_RECORD { |
2681 | ATOM_COMMON_RECORD_HEADER sheader; | 2681 | ATOM_COMMON_RECORD_HEADER sheader; |
2682 | UCHAR ucHPDIntGPIOID; /* Corresponding block in GPIO_PIN_INFO table gives the pin info */ | 2682 | UCHAR ucHPDIntGPIOID; /* Corresponding block in GPIO_PIN_INFO table gives the pin info */ |
2683 | UCHAR ucPluggged_PinState; | 2683 | UCHAR ucPlugged_PinState; |
2684 | } ATOM_HPD_INT_RECORD; | 2684 | } ATOM_HPD_INT_RECORD; |
2685 | 2685 | ||
2686 | typedef struct _ATOM_OUTPUT_PROTECTION_RECORD { | 2686 | typedef struct _ATOM_OUTPUT_PROTECTION_RECORD { |
@@ -3046,7 +3046,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { | |||
3046 | #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC 2 | 3046 | #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC 2 |
3047 | #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3 | 3047 | #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3 |
3048 | 3048 | ||
3049 | /* Byte aligned defintion for BIOS usage */ | 3049 | /* Byte aligned definition for BIOS usage */ |
3050 | #define ATOM_S0_CRT1_MONOb0 0x01 | 3050 | #define ATOM_S0_CRT1_MONOb0 0x01 |
3051 | #define ATOM_S0_CRT1_COLORb0 0x02 | 3051 | #define ATOM_S0_CRT1_COLORb0 0x02 |
3052 | #define ATOM_S0_CRT1_MASKb0 (ATOM_S0_CRT1_MONOb0+ATOM_S0_CRT1_COLORb0) | 3052 | #define ATOM_S0_CRT1_MASKb0 (ATOM_S0_CRT1_MONOb0+ATOM_S0_CRT1_COLORb0) |
@@ -3131,7 +3131,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { | |||
3131 | #define ATOM_S2_DISPLAY_ROTATION_DEGREE_SHIFT 30 | 3131 | #define ATOM_S2_DISPLAY_ROTATION_DEGREE_SHIFT 30 |
3132 | #define ATOM_S2_DISPLAY_ROTATION_ANGLE_MASK 0xC0000000L | 3132 | #define ATOM_S2_DISPLAY_ROTATION_ANGLE_MASK 0xC0000000L |
3133 | 3133 | ||
3134 | /* Byte aligned defintion for BIOS usage */ | 3134 | /* Byte aligned definition for BIOS usage */ |
3135 | #define ATOM_S2_TV1_STANDARD_MASKb0 0x0F | 3135 | #define ATOM_S2_TV1_STANDARD_MASKb0 0x0F |
3136 | #define ATOM_S2_CURRENT_BL_LEVEL_MASKb1 0xFF | 3136 | #define ATOM_S2_CURRENT_BL_LEVEL_MASKb1 0xFF |
3137 | #define ATOM_S2_CRT1_DPMS_STATEb2 0x01 | 3137 | #define ATOM_S2_CRT1_DPMS_STATEb2 0x01 |
@@ -3190,7 +3190,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { | |||
3190 | #define ATOM_S3_ALLOW_FAST_PWR_SWITCH 0x40000000L | 3190 | #define ATOM_S3_ALLOW_FAST_PWR_SWITCH 0x40000000L |
3191 | #define ATOM_S3_RQST_GPU_USE_MIN_PWR 0x80000000L | 3191 | #define ATOM_S3_RQST_GPU_USE_MIN_PWR 0x80000000L |
3192 | 3192 | ||
3193 | /* Byte aligned defintion for BIOS usage */ | 3193 | /* Byte aligned definition for BIOS usage */ |
3194 | #define ATOM_S3_CRT1_ACTIVEb0 0x01 | 3194 | #define ATOM_S3_CRT1_ACTIVEb0 0x01 |
3195 | #define ATOM_S3_LCD1_ACTIVEb0 0x02 | 3195 | #define ATOM_S3_LCD1_ACTIVEb0 0x02 |
3196 | #define ATOM_S3_TV1_ACTIVEb0 0x04 | 3196 | #define ATOM_S3_TV1_ACTIVEb0 0x04 |
@@ -3230,7 +3230,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { | |||
3230 | #define ATOM_S4_LCD1_REFRESH_MASK 0x0000FF00L | 3230 | #define ATOM_S4_LCD1_REFRESH_MASK 0x0000FF00L |
3231 | #define ATOM_S4_LCD1_REFRESH_SHIFT 8 | 3231 | #define ATOM_S4_LCD1_REFRESH_SHIFT 8 |
3232 | 3232 | ||
3233 | /* Byte aligned defintion for BIOS usage */ | 3233 | /* Byte aligned definition for BIOS usage */ |
3234 | #define ATOM_S4_LCD1_PANEL_ID_MASKb0 0x0FF | 3234 | #define ATOM_S4_LCD1_PANEL_ID_MASKb0 0x0FF |
3235 | #define ATOM_S4_LCD1_REFRESH_MASKb1 ATOM_S4_LCD1_PANEL_ID_MASKb0 | 3235 | #define ATOM_S4_LCD1_REFRESH_MASKb1 ATOM_S4_LCD1_PANEL_ID_MASKb0 |
3236 | #define ATOM_S4_VRAM_INFO_MASKb2 ATOM_S4_LCD1_PANEL_ID_MASKb0 | 3236 | #define ATOM_S4_VRAM_INFO_MASKb2 ATOM_S4_LCD1_PANEL_ID_MASKb0 |
@@ -3310,7 +3310,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO { | |||
3310 | #define ATOM_S6_VRI_BRIGHTNESS_CHANGE 0x40000000L | 3310 | #define ATOM_S6_VRI_BRIGHTNESS_CHANGE 0x40000000L |
3311 | #define ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK 0x80000000L | 3311 | #define ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK 0x80000000L |
3312 | 3312 | ||
3313 | /* Byte aligned defintion for BIOS usage */ | 3313 | /* Byte aligned definition for BIOS usage */ |
3314 | #define ATOM_S6_DEVICE_CHANGEb0 0x01 | 3314 | #define ATOM_S6_DEVICE_CHANGEb0 0x01 |
3315 | #define ATOM_S6_SCALER_CHANGEb0 0x02 | 3315 | #define ATOM_S6_SCALER_CHANGEb0 0x02 |
3316 | #define ATOM_S6_LID_CHANGEb0 0x04 | 3316 | #define ATOM_S6_LID_CHANGEb0 0x04 |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 14fa9701aeb3..260fcf59f00c 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -31,10 +31,6 @@ | |||
31 | #include "atom.h" | 31 | #include "atom.h" |
32 | #include "atom-bits.h" | 32 | #include "atom-bits.h" |
33 | 33 | ||
34 | /* evil but including atombios.h is much worse */ | ||
35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | ||
36 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, | ||
37 | int32_t *pixel_clock); | ||
38 | static void atombios_overscan_setup(struct drm_crtc *crtc, | 34 | static void atombios_overscan_setup(struct drm_crtc *crtc, |
39 | struct drm_display_mode *mode, | 35 | struct drm_display_mode *mode, |
40 | struct drm_display_mode *adjusted_mode) | 36 | struct drm_display_mode *adjusted_mode) |
@@ -245,84 +241,172 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
245 | { | 241 | { |
246 | struct drm_device *dev = crtc->dev; | 242 | struct drm_device *dev = crtc->dev; |
247 | struct radeon_device *rdev = dev->dev_private; | 243 | struct radeon_device *rdev = dev->dev_private; |
244 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
248 | 245 | ||
249 | switch (mode) { | 246 | switch (mode) { |
250 | case DRM_MODE_DPMS_ON: | 247 | case DRM_MODE_DPMS_ON: |
248 | atombios_enable_crtc(crtc, 1); | ||
251 | if (ASIC_IS_DCE3(rdev)) | 249 | if (ASIC_IS_DCE3(rdev)) |
252 | atombios_enable_crtc_memreq(crtc, 1); | 250 | atombios_enable_crtc_memreq(crtc, 1); |
253 | atombios_enable_crtc(crtc, 1); | ||
254 | atombios_blank_crtc(crtc, 0); | 251 | atombios_blank_crtc(crtc, 0); |
252 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); | ||
253 | radeon_crtc_load_lut(crtc); | ||
255 | break; | 254 | break; |
256 | case DRM_MODE_DPMS_STANDBY: | 255 | case DRM_MODE_DPMS_STANDBY: |
257 | case DRM_MODE_DPMS_SUSPEND: | 256 | case DRM_MODE_DPMS_SUSPEND: |
258 | case DRM_MODE_DPMS_OFF: | 257 | case DRM_MODE_DPMS_OFF: |
258 | drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); | ||
259 | atombios_blank_crtc(crtc, 1); | 259 | atombios_blank_crtc(crtc, 1); |
260 | atombios_enable_crtc(crtc, 0); | ||
261 | if (ASIC_IS_DCE3(rdev)) | 260 | if (ASIC_IS_DCE3(rdev)) |
262 | atombios_enable_crtc_memreq(crtc, 0); | 261 | atombios_enable_crtc_memreq(crtc, 0); |
262 | atombios_enable_crtc(crtc, 0); | ||
263 | break; | 263 | break; |
264 | } | 264 | } |
265 | |||
266 | if (mode != DRM_MODE_DPMS_OFF) { | ||
267 | radeon_crtc_load_lut(crtc); | ||
268 | } | ||
269 | } | 265 | } |
270 | 266 | ||
271 | static void | 267 | static void |
272 | atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, | 268 | atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, |
273 | SET_CRTC_USING_DTD_TIMING_PARAMETERS * crtc_param) | 269 | struct drm_display_mode *mode) |
274 | { | 270 | { |
271 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
275 | struct drm_device *dev = crtc->dev; | 272 | struct drm_device *dev = crtc->dev; |
276 | struct radeon_device *rdev = dev->dev_private; | 273 | struct radeon_device *rdev = dev->dev_private; |
277 | SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param; | 274 | SET_CRTC_USING_DTD_TIMING_PARAMETERS args; |
278 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming); | 275 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming); |
276 | u16 misc = 0; | ||
279 | 277 | ||
280 | conv_param.usH_Size = cpu_to_le16(crtc_param->usH_Size); | 278 | memset(&args, 0, sizeof(args)); |
281 | conv_param.usH_Blanking_Time = | 279 | args.usH_Size = cpu_to_le16(mode->crtc_hdisplay); |
282 | cpu_to_le16(crtc_param->usH_Blanking_Time); | 280 | args.usH_Blanking_Time = |
283 | conv_param.usV_Size = cpu_to_le16(crtc_param->usV_Size); | 281 | cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay); |
284 | conv_param.usV_Blanking_Time = | 282 | args.usV_Size = cpu_to_le16(mode->crtc_vdisplay); |
285 | cpu_to_le16(crtc_param->usV_Blanking_Time); | 283 | args.usV_Blanking_Time = |
286 | conv_param.usH_SyncOffset = cpu_to_le16(crtc_param->usH_SyncOffset); | 284 | cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay); |
287 | conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); | 285 | args.usH_SyncOffset = |
288 | conv_param.usV_SyncOffset = cpu_to_le16(crtc_param->usV_SyncOffset); | 286 | cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay); |
289 | conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth); | 287 | args.usH_SyncWidth = |
290 | conv_param.susModeMiscInfo.usAccess = | 288 | cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); |
291 | cpu_to_le16(crtc_param->susModeMiscInfo.usAccess); | 289 | args.usV_SyncOffset = |
292 | conv_param.ucCRTC = crtc_param->ucCRTC; | 290 | cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay); |
291 | args.usV_SyncWidth = | ||
292 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); | ||
293 | /*args.ucH_Border = mode->hborder;*/ | ||
294 | /*args.ucV_Border = mode->vborder;*/ | ||
295 | |||
296 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
297 | misc |= ATOM_VSYNC_POLARITY; | ||
298 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
299 | misc |= ATOM_HSYNC_POLARITY; | ||
300 | if (mode->flags & DRM_MODE_FLAG_CSYNC) | ||
301 | misc |= ATOM_COMPOSITESYNC; | ||
302 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
303 | misc |= ATOM_INTERLACE; | ||
304 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
305 | misc |= ATOM_DOUBLE_CLOCK_MODE; | ||
306 | |||
307 | args.susModeMiscInfo.usAccess = cpu_to_le16(misc); | ||
308 | args.ucCRTC = radeon_crtc->crtc_id; | ||
293 | 309 | ||
294 | printk("executing set crtc dtd timing\n"); | 310 | printk("executing set crtc dtd timing\n"); |
295 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param); | 311 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
296 | } | 312 | } |
297 | 313 | ||
298 | void atombios_crtc_set_timing(struct drm_crtc *crtc, | 314 | static void atombios_crtc_set_timing(struct drm_crtc *crtc, |
299 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION * | 315 | struct drm_display_mode *mode) |
300 | crtc_param) | ||
301 | { | 316 | { |
317 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
302 | struct drm_device *dev = crtc->dev; | 318 | struct drm_device *dev = crtc->dev; |
303 | struct radeon_device *rdev = dev->dev_private; | 319 | struct radeon_device *rdev = dev->dev_private; |
304 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param; | 320 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args; |
305 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); | 321 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); |
322 | u16 misc = 0; | ||
306 | 323 | ||
307 | conv_param.usH_Total = cpu_to_le16(crtc_param->usH_Total); | 324 | memset(&args, 0, sizeof(args)); |
308 | conv_param.usH_Disp = cpu_to_le16(crtc_param->usH_Disp); | 325 | args.usH_Total = cpu_to_le16(mode->crtc_htotal); |
309 | conv_param.usH_SyncStart = cpu_to_le16(crtc_param->usH_SyncStart); | 326 | args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay); |
310 | conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); | 327 | args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start); |
311 | conv_param.usV_Total = cpu_to_le16(crtc_param->usV_Total); | 328 | args.usH_SyncWidth = |
312 | conv_param.usV_Disp = cpu_to_le16(crtc_param->usV_Disp); | 329 | cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); |
313 | conv_param.usV_SyncStart = cpu_to_le16(crtc_param->usV_SyncStart); | 330 | args.usV_Total = cpu_to_le16(mode->crtc_vtotal); |
314 | conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth); | 331 | args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay); |
315 | conv_param.susModeMiscInfo.usAccess = | 332 | args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start); |
316 | cpu_to_le16(crtc_param->susModeMiscInfo.usAccess); | 333 | args.usV_SyncWidth = |
317 | conv_param.ucCRTC = crtc_param->ucCRTC; | 334 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); |
318 | conv_param.ucOverscanRight = crtc_param->ucOverscanRight; | 335 | |
319 | conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft; | 336 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
320 | conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom; | 337 | misc |= ATOM_VSYNC_POLARITY; |
321 | conv_param.ucOverscanTop = crtc_param->ucOverscanTop; | 338 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) |
322 | conv_param.ucReserved = crtc_param->ucReserved; | 339 | misc |= ATOM_HSYNC_POLARITY; |
340 | if (mode->flags & DRM_MODE_FLAG_CSYNC) | ||
341 | misc |= ATOM_COMPOSITESYNC; | ||
342 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
343 | misc |= ATOM_INTERLACE; | ||
344 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
345 | misc |= ATOM_DOUBLE_CLOCK_MODE; | ||
346 | |||
347 | args.susModeMiscInfo.usAccess = cpu_to_le16(misc); | ||
348 | args.ucCRTC = radeon_crtc->crtc_id; | ||
323 | 349 | ||
324 | printk("executing set crtc timing\n"); | 350 | printk("executing set crtc timing\n"); |
325 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param); | 351 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
352 | } | ||
353 | |||
354 | static void atombios_set_ss(struct drm_crtc *crtc, int enable) | ||
355 | { | ||
356 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
357 | struct drm_device *dev = crtc->dev; | ||
358 | struct radeon_device *rdev = dev->dev_private; | ||
359 | struct drm_encoder *encoder = NULL; | ||
360 | struct radeon_encoder *radeon_encoder = NULL; | ||
361 | struct radeon_encoder_atom_dig *dig = NULL; | ||
362 | int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); | ||
363 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION args; | ||
364 | ENABLE_LVDS_SS_PARAMETERS legacy_args; | ||
365 | uint16_t percentage = 0; | ||
366 | uint8_t type = 0, step = 0, delay = 0, range = 0; | ||
367 | |||
368 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
369 | if (encoder->crtc == crtc) { | ||
370 | radeon_encoder = to_radeon_encoder(encoder); | ||
371 | /* only enable spread spectrum on LVDS */ | ||
372 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
373 | dig = radeon_encoder->enc_priv; | ||
374 | if (dig && dig->ss) { | ||
375 | percentage = dig->ss->percentage; | ||
376 | type = dig->ss->type; | ||
377 | step = dig->ss->step; | ||
378 | delay = dig->ss->delay; | ||
379 | range = dig->ss->range; | ||
380 | } else if (enable) | ||
381 | return; | ||
382 | } else if (enable) | ||
383 | return; | ||
384 | break; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | if (!radeon_encoder) | ||
389 | return; | ||
390 | |||
391 | if (ASIC_IS_AVIVO(rdev)) { | ||
392 | memset(&args, 0, sizeof(args)); | ||
393 | args.usSpreadSpectrumPercentage = cpu_to_le16(percentage); | ||
394 | args.ucSpreadSpectrumType = type; | ||
395 | args.ucSpreadSpectrumStep = step; | ||
396 | args.ucSpreadSpectrumDelay = delay; | ||
397 | args.ucSpreadSpectrumRange = range; | ||
398 | args.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; | ||
399 | args.ucEnable = enable; | ||
400 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
401 | } else { | ||
402 | memset(&legacy_args, 0, sizeof(legacy_args)); | ||
403 | legacy_args.usSpreadSpectrumPercentage = cpu_to_le16(percentage); | ||
404 | legacy_args.ucSpreadSpectrumType = type; | ||
405 | legacy_args.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2; | ||
406 | legacy_args.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4; | ||
407 | legacy_args.ucEnable = enable; | ||
408 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&legacy_args); | ||
409 | } | ||
326 | } | 410 | } |
327 | 411 | ||
328 | void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | 412 | void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) |
@@ -333,12 +417,13 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
333 | struct drm_encoder *encoder = NULL; | 417 | struct drm_encoder *encoder = NULL; |
334 | struct radeon_encoder *radeon_encoder = NULL; | 418 | struct radeon_encoder *radeon_encoder = NULL; |
335 | uint8_t frev, crev; | 419 | uint8_t frev, crev; |
336 | int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); | 420 | int index; |
337 | SET_PIXEL_CLOCK_PS_ALLOCATION args; | 421 | SET_PIXEL_CLOCK_PS_ALLOCATION args; |
338 | PIXEL_CLOCK_PARAMETERS *spc1_ptr; | 422 | PIXEL_CLOCK_PARAMETERS *spc1_ptr; |
339 | PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr; | 423 | PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr; |
340 | PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; | 424 | PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; |
341 | uint32_t sclock = mode->clock; | 425 | uint32_t pll_clock = mode->clock; |
426 | uint32_t adjusted_clock; | ||
342 | uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; | 427 | uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; |
343 | struct radeon_pll *pll; | 428 | struct radeon_pll *pll; |
344 | int pll_flags = 0; | 429 | int pll_flags = 0; |
@@ -346,8 +431,6 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
346 | memset(&args, 0, sizeof(args)); | 431 | memset(&args, 0, sizeof(args)); |
347 | 432 | ||
348 | if (ASIC_IS_AVIVO(rdev)) { | 433 | if (ASIC_IS_AVIVO(rdev)) { |
349 | uint32_t ss_cntl; | ||
350 | |||
351 | if ((rdev->family == CHIP_RS600) || | 434 | if ((rdev->family == CHIP_RS600) || |
352 | (rdev->family == CHIP_RS690) || | 435 | (rdev->family == CHIP_RS690) || |
353 | (rdev->family == CHIP_RS740)) | 436 | (rdev->family == CHIP_RS740)) |
@@ -358,15 +441,6 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
358 | pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; | 441 | pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
359 | else | 442 | else |
360 | pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 443 | pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
361 | |||
362 | /* disable spread spectrum clocking for now -- thanks Hedy Lamarr */ | ||
363 | if (radeon_crtc->crtc_id == 0) { | ||
364 | ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); | ||
365 | WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl & ~1); | ||
366 | } else { | ||
367 | ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL); | ||
368 | WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl & ~1); | ||
369 | } | ||
370 | } else { | 444 | } else { |
371 | pll_flags |= RADEON_PLL_LEGACY; | 445 | pll_flags |= RADEON_PLL_LEGACY; |
372 | 446 | ||
@@ -383,9 +457,8 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
383 | if (encoder->encoder_type != | 457 | if (encoder->encoder_type != |
384 | DRM_MODE_ENCODER_DAC) | 458 | DRM_MODE_ENCODER_DAC) |
385 | pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; | 459 | pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; |
386 | if (!ASIC_IS_AVIVO(rdev) | 460 | if (encoder->encoder_type == |
387 | && (encoder->encoder_type == | 461 | DRM_MODE_ENCODER_LVDS) |
388 | DRM_MODE_ENCODER_LVDS)) | ||
389 | pll_flags |= RADEON_PLL_USE_REF_DIV; | 462 | pll_flags |= RADEON_PLL_USE_REF_DIV; |
390 | } | 463 | } |
391 | radeon_encoder = to_radeon_encoder(encoder); | 464 | radeon_encoder = to_radeon_encoder(encoder); |
@@ -393,14 +466,53 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
393 | } | 466 | } |
394 | } | 467 | } |
395 | 468 | ||
469 | /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock | ||
470 | * accordingly based on the encoder/transmitter to work around | ||
471 | * special hw requirements. | ||
472 | */ | ||
473 | if (ASIC_IS_DCE3(rdev)) { | ||
474 | ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_args; | ||
475 | |||
476 | if (!encoder) | ||
477 | return; | ||
478 | |||
479 | memset(&adjust_pll_args, 0, sizeof(adjust_pll_args)); | ||
480 | adjust_pll_args.usPixelClock = cpu_to_le16(mode->clock / 10); | ||
481 | adjust_pll_args.ucTransmitterID = radeon_encoder->encoder_id; | ||
482 | adjust_pll_args.ucEncodeMode = atombios_get_encoder_mode(encoder); | ||
483 | |||
484 | index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); | ||
485 | atom_execute_table(rdev->mode_info.atom_context, | ||
486 | index, (uint32_t *)&adjust_pll_args); | ||
487 | adjusted_clock = le16_to_cpu(adjust_pll_args.usPixelClock) * 10; | ||
488 | } else { | ||
489 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | ||
490 | if (ASIC_IS_AVIVO(rdev) && | ||
491 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)) | ||
492 | adjusted_clock = mode->clock * 2; | ||
493 | else | ||
494 | adjusted_clock = mode->clock; | ||
495 | } | ||
496 | |||
396 | if (radeon_crtc->crtc_id == 0) | 497 | if (radeon_crtc->crtc_id == 0) |
397 | pll = &rdev->clock.p1pll; | 498 | pll = &rdev->clock.p1pll; |
398 | else | 499 | else |
399 | pll = &rdev->clock.p2pll; | 500 | pll = &rdev->clock.p2pll; |
400 | 501 | ||
401 | radeon_compute_pll(pll, mode->clock, &sclock, &fb_div, &frac_fb_div, | 502 | if (ASIC_IS_AVIVO(rdev)) { |
402 | &ref_div, &post_div, pll_flags); | 503 | if (radeon_new_pll) |
403 | 504 | radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, | |
505 | &fb_div, &frac_fb_div, | ||
506 | &ref_div, &post_div, pll_flags); | ||
507 | else | ||
508 | radeon_compute_pll(pll, adjusted_clock, &pll_clock, | ||
509 | &fb_div, &frac_fb_div, | ||
510 | &ref_div, &post_div, pll_flags); | ||
511 | } else | ||
512 | radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | ||
513 | &ref_div, &post_div, pll_flags); | ||
514 | |||
515 | index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); | ||
404 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, | 516 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, |
405 | &crev); | 517 | &crev); |
406 | 518 | ||
@@ -409,7 +521,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
409 | switch (crev) { | 521 | switch (crev) { |
410 | case 1: | 522 | case 1: |
411 | spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput; | 523 | spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput; |
412 | spc1_ptr->usPixelClock = cpu_to_le16(sclock); | 524 | spc1_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); |
413 | spc1_ptr->usRefDiv = cpu_to_le16(ref_div); | 525 | spc1_ptr->usRefDiv = cpu_to_le16(ref_div); |
414 | spc1_ptr->usFbDiv = cpu_to_le16(fb_div); | 526 | spc1_ptr->usFbDiv = cpu_to_le16(fb_div); |
415 | spc1_ptr->ucFracFbDiv = frac_fb_div; | 527 | spc1_ptr->ucFracFbDiv = frac_fb_div; |
@@ -422,7 +534,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
422 | case 2: | 534 | case 2: |
423 | spc2_ptr = | 535 | spc2_ptr = |
424 | (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput; | 536 | (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput; |
425 | spc2_ptr->usPixelClock = cpu_to_le16(sclock); | 537 | spc2_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); |
426 | spc2_ptr->usRefDiv = cpu_to_le16(ref_div); | 538 | spc2_ptr->usRefDiv = cpu_to_le16(ref_div); |
427 | spc2_ptr->usFbDiv = cpu_to_le16(fb_div); | 539 | spc2_ptr->usFbDiv = cpu_to_le16(fb_div); |
428 | spc2_ptr->ucFracFbDiv = frac_fb_div; | 540 | spc2_ptr->ucFracFbDiv = frac_fb_div; |
@@ -437,7 +549,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
437 | return; | 549 | return; |
438 | spc3_ptr = | 550 | spc3_ptr = |
439 | (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput; | 551 | (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput; |
440 | spc3_ptr->usPixelClock = cpu_to_le16(sclock); | 552 | spc3_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); |
441 | spc3_ptr->usRefDiv = cpu_to_le16(ref_div); | 553 | spc3_ptr->usRefDiv = cpu_to_le16(ref_div); |
442 | spc3_ptr->usFbDiv = cpu_to_le16(fb_div); | 554 | spc3_ptr->usFbDiv = cpu_to_le16(fb_div); |
443 | spc3_ptr->ucFracFbDiv = frac_fb_div; | 555 | spc3_ptr->ucFracFbDiv = frac_fb_div; |
@@ -471,21 +583,32 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
471 | struct radeon_device *rdev = dev->dev_private; | 583 | struct radeon_device *rdev = dev->dev_private; |
472 | struct radeon_framebuffer *radeon_fb; | 584 | struct radeon_framebuffer *radeon_fb; |
473 | struct drm_gem_object *obj; | 585 | struct drm_gem_object *obj; |
474 | struct drm_radeon_gem_object *obj_priv; | 586 | struct radeon_bo *rbo; |
475 | uint64_t fb_location; | 587 | uint64_t fb_location; |
476 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; | 588 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; |
589 | int r; | ||
477 | 590 | ||
478 | if (!crtc->fb) | 591 | /* no fb bound */ |
479 | return -EINVAL; | 592 | if (!crtc->fb) { |
593 | DRM_DEBUG("No FB bound\n"); | ||
594 | return 0; | ||
595 | } | ||
480 | 596 | ||
481 | radeon_fb = to_radeon_framebuffer(crtc->fb); | 597 | radeon_fb = to_radeon_framebuffer(crtc->fb); |
482 | 598 | ||
599 | /* Pin framebuffer & get tilling informations */ | ||
483 | obj = radeon_fb->obj; | 600 | obj = radeon_fb->obj; |
484 | obj_priv = obj->driver_private; | 601 | rbo = obj->driver_private; |
485 | 602 | r = radeon_bo_reserve(rbo, false); | |
486 | if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &fb_location)) { | 603 | if (unlikely(r != 0)) |
604 | return r; | ||
605 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); | ||
606 | if (unlikely(r != 0)) { | ||
607 | radeon_bo_unreserve(rbo); | ||
487 | return -EINVAL; | 608 | return -EINVAL; |
488 | } | 609 | } |
610 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); | ||
611 | radeon_bo_unreserve(rbo); | ||
489 | 612 | ||
490 | switch (crtc->fb->bits_per_pixel) { | 613 | switch (crtc->fb->bits_per_pixel) { |
491 | case 8: | 614 | case 8: |
@@ -515,8 +638,6 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
515 | return -EINVAL; | 638 | return -EINVAL; |
516 | } | 639 | } |
517 | 640 | ||
518 | radeon_object_get_tiling_flags(obj->driver_private, | ||
519 | &tiling_flags, NULL); | ||
520 | if (tiling_flags & RADEON_TILING_MACRO) | 641 | if (tiling_flags & RADEON_TILING_MACRO) |
521 | fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE; | 642 | fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE; |
522 | 643 | ||
@@ -527,6 +648,16 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
527 | WREG32(AVIVO_D1VGA_CONTROL, 0); | 648 | WREG32(AVIVO_D1VGA_CONTROL, 0); |
528 | else | 649 | else |
529 | WREG32(AVIVO_D2VGA_CONTROL, 0); | 650 | WREG32(AVIVO_D2VGA_CONTROL, 0); |
651 | |||
652 | if (rdev->family >= CHIP_RV770) { | ||
653 | if (radeon_crtc->crtc_id) { | ||
654 | WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); | ||
655 | WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); | ||
656 | } else { | ||
657 | WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); | ||
658 | WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); | ||
659 | } | ||
660 | } | ||
530 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | 661 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
531 | (u32) fb_location); | 662 | (u32) fb_location); |
532 | WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + | 663 | WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + |
@@ -561,8 +692,17 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
561 | 692 | ||
562 | if (old_fb && old_fb != crtc->fb) { | 693 | if (old_fb && old_fb != crtc->fb) { |
563 | radeon_fb = to_radeon_framebuffer(old_fb); | 694 | radeon_fb = to_radeon_framebuffer(old_fb); |
564 | radeon_gem_object_unpin(radeon_fb->obj); | 695 | rbo = radeon_fb->obj->driver_private; |
696 | r = radeon_bo_reserve(rbo, false); | ||
697 | if (unlikely(r != 0)) | ||
698 | return r; | ||
699 | radeon_bo_unpin(rbo); | ||
700 | radeon_bo_unreserve(rbo); | ||
565 | } | 701 | } |
702 | |||
703 | /* Bytes per pixel may have changed */ | ||
704 | radeon_bandwidth_update(rdev); | ||
705 | |||
566 | return 0; | 706 | return 0; |
567 | } | 707 | } |
568 | 708 | ||
@@ -574,134 +714,24 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
574 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 714 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
575 | struct drm_device *dev = crtc->dev; | 715 | struct drm_device *dev = crtc->dev; |
576 | struct radeon_device *rdev = dev->dev_private; | 716 | struct radeon_device *rdev = dev->dev_private; |
577 | struct drm_encoder *encoder; | ||
578 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; | ||
579 | int need_tv_timings = 0; | ||
580 | bool ret; | ||
581 | 717 | ||
582 | /* TODO color tiling */ | 718 | /* TODO color tiling */ |
583 | memset(&crtc_timing, 0, sizeof(crtc_timing)); | ||
584 | |||
585 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
586 | /* find tv std */ | ||
587 | if (encoder->crtc == crtc) { | ||
588 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
589 | |||
590 | if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { | ||
591 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; | ||
592 | if (tv_dac) { | ||
593 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
594 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
595 | tv_dac->tv_std == TV_STD_PAL_M) | ||
596 | need_tv_timings = 1; | ||
597 | else | ||
598 | need_tv_timings = 2; | ||
599 | break; | ||
600 | } | ||
601 | } | ||
602 | } | ||
603 | } | ||
604 | |||
605 | crtc_timing.ucCRTC = radeon_crtc->crtc_id; | ||
606 | if (need_tv_timings) { | ||
607 | ret = radeon_atom_get_tv_timings(rdev, need_tv_timings - 1, | ||
608 | &crtc_timing, &adjusted_mode->clock); | ||
609 | if (ret == false) | ||
610 | need_tv_timings = 0; | ||
611 | } | ||
612 | |||
613 | if (!need_tv_timings) { | ||
614 | crtc_timing.usH_Total = adjusted_mode->crtc_htotal; | ||
615 | crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay; | ||
616 | crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start; | ||
617 | crtc_timing.usH_SyncWidth = | ||
618 | adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; | ||
619 | |||
620 | crtc_timing.usV_Total = adjusted_mode->crtc_vtotal; | ||
621 | crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay; | ||
622 | crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start; | ||
623 | crtc_timing.usV_SyncWidth = | ||
624 | adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; | ||
625 | |||
626 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
627 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; | ||
628 | |||
629 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
630 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; | ||
631 | |||
632 | if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) | ||
633 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC; | ||
634 | |||
635 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
636 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE; | ||
637 | |||
638 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
639 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE; | ||
640 | } | ||
641 | 719 | ||
720 | atombios_set_ss(crtc, 0); | ||
642 | atombios_crtc_set_pll(crtc, adjusted_mode); | 721 | atombios_crtc_set_pll(crtc, adjusted_mode); |
643 | atombios_crtc_set_timing(crtc, &crtc_timing); | 722 | atombios_set_ss(crtc, 1); |
723 | atombios_crtc_set_timing(crtc, adjusted_mode); | ||
644 | 724 | ||
645 | if (ASIC_IS_AVIVO(rdev)) | 725 | if (ASIC_IS_AVIVO(rdev)) |
646 | atombios_crtc_set_base(crtc, x, y, old_fb); | 726 | atombios_crtc_set_base(crtc, x, y, old_fb); |
647 | else { | 727 | else { |
648 | if (radeon_crtc->crtc_id == 0) { | 728 | if (radeon_crtc->crtc_id == 0) |
649 | SET_CRTC_USING_DTD_TIMING_PARAMETERS crtc_dtd_timing; | 729 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
650 | memset(&crtc_dtd_timing, 0, sizeof(crtc_dtd_timing)); | ||
651 | |||
652 | /* setup FP shadow regs on R4xx */ | ||
653 | crtc_dtd_timing.ucCRTC = radeon_crtc->crtc_id; | ||
654 | crtc_dtd_timing.usH_Size = adjusted_mode->crtc_hdisplay; | ||
655 | crtc_dtd_timing.usV_Size = adjusted_mode->crtc_vdisplay; | ||
656 | crtc_dtd_timing.usH_Blanking_Time = | ||
657 | adjusted_mode->crtc_hblank_end - | ||
658 | adjusted_mode->crtc_hdisplay; | ||
659 | crtc_dtd_timing.usV_Blanking_Time = | ||
660 | adjusted_mode->crtc_vblank_end - | ||
661 | adjusted_mode->crtc_vdisplay; | ||
662 | crtc_dtd_timing.usH_SyncOffset = | ||
663 | adjusted_mode->crtc_hsync_start - | ||
664 | adjusted_mode->crtc_hdisplay; | ||
665 | crtc_dtd_timing.usV_SyncOffset = | ||
666 | adjusted_mode->crtc_vsync_start - | ||
667 | adjusted_mode->crtc_vdisplay; | ||
668 | crtc_dtd_timing.usH_SyncWidth = | ||
669 | adjusted_mode->crtc_hsync_end - | ||
670 | adjusted_mode->crtc_hsync_start; | ||
671 | crtc_dtd_timing.usV_SyncWidth = | ||
672 | adjusted_mode->crtc_vsync_end - | ||
673 | adjusted_mode->crtc_vsync_start; | ||
674 | /* crtc_dtd_timing.ucH_Border = adjusted_mode->crtc_hborder; */ | ||
675 | /* crtc_dtd_timing.ucV_Border = adjusted_mode->crtc_vborder; */ | ||
676 | |||
677 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
678 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
679 | ATOM_VSYNC_POLARITY; | ||
680 | |||
681 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
682 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
683 | ATOM_HSYNC_POLARITY; | ||
684 | |||
685 | if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) | ||
686 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
687 | ATOM_COMPOSITESYNC; | ||
688 | |||
689 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
690 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
691 | ATOM_INTERLACE; | ||
692 | |||
693 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
694 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
695 | ATOM_DOUBLE_CLOCK_MODE; | ||
696 | |||
697 | atombios_set_crtc_dtd_timing(crtc, &crtc_dtd_timing); | ||
698 | } | ||
699 | radeon_crtc_set_base(crtc, x, y, old_fb); | 730 | radeon_crtc_set_base(crtc, x, y, old_fb); |
700 | radeon_legacy_atom_set_surface(crtc); | 731 | radeon_legacy_atom_set_surface(crtc); |
701 | } | 732 | } |
702 | atombios_overscan_setup(crtc, mode, adjusted_mode); | 733 | atombios_overscan_setup(crtc, mode, adjusted_mode); |
703 | atombios_scaler_setup(crtc); | 734 | atombios_scaler_setup(crtc); |
704 | radeon_bandwidth_update(rdev); | ||
705 | return 0; | 735 | return 0; |
706 | } | 736 | } |
707 | 737 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c new file mode 100644 index 000000000000..0d63c4436e7c --- /dev/null +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -0,0 +1,790 @@ | |||
1 | /* | ||
2 | * Copyright 2007-8 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2008 Red Hat Inc. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the "Software"), | ||
7 | * to deal in the Software without restriction, including without limitation | ||
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
10 | * Software is furnished to do so, subject to the following conditions: | ||
11 | * | ||
12 | * The above copyright notice and this permission notice shall be included in | ||
13 | * all copies or substantial portions of the Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
21 | * OTHER DEALINGS IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: Dave Airlie | ||
24 | * Alex Deucher | ||
25 | */ | ||
26 | #include "drmP.h" | ||
27 | #include "radeon_drm.h" | ||
28 | #include "radeon.h" | ||
29 | |||
30 | #include "atom.h" | ||
31 | #include "atom-bits.h" | ||
32 | #include "drm_dp_helper.h" | ||
33 | |||
34 | /* move these to drm_dp_helper.c/h */ | ||
35 | #define DP_LINK_CONFIGURATION_SIZE 9 | ||
36 | #define DP_LINK_STATUS_SIZE 6 | ||
37 | #define DP_DPCD_SIZE 8 | ||
38 | |||
39 | static char *voltage_names[] = { | ||
40 | "0.4V", "0.6V", "0.8V", "1.2V" | ||
41 | }; | ||
42 | static char *pre_emph_names[] = { | ||
43 | "0dB", "3.5dB", "6dB", "9.5dB" | ||
44 | }; | ||
45 | |||
46 | static const int dp_clocks[] = { | ||
47 | 54000, /* 1 lane, 1.62 Ghz */ | ||
48 | 90000, /* 1 lane, 2.70 Ghz */ | ||
49 | 108000, /* 2 lane, 1.62 Ghz */ | ||
50 | 180000, /* 2 lane, 2.70 Ghz */ | ||
51 | 216000, /* 4 lane, 1.62 Ghz */ | ||
52 | 360000, /* 4 lane, 2.70 Ghz */ | ||
53 | }; | ||
54 | |||
55 | static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int); | ||
56 | |||
57 | /* common helper functions */ | ||
58 | static int dp_lanes_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock) | ||
59 | { | ||
60 | int i; | ||
61 | u8 max_link_bw; | ||
62 | u8 max_lane_count; | ||
63 | |||
64 | if (!dpcd) | ||
65 | return 0; | ||
66 | |||
67 | max_link_bw = dpcd[DP_MAX_LINK_RATE]; | ||
68 | max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK; | ||
69 | |||
70 | switch (max_link_bw) { | ||
71 | case DP_LINK_BW_1_62: | ||
72 | default: | ||
73 | for (i = 0; i < num_dp_clocks; i++) { | ||
74 | if (i % 2) | ||
75 | continue; | ||
76 | switch (max_lane_count) { | ||
77 | case 1: | ||
78 | if (i > 1) | ||
79 | return 0; | ||
80 | break; | ||
81 | case 2: | ||
82 | if (i > 3) | ||
83 | return 0; | ||
84 | break; | ||
85 | case 4: | ||
86 | default: | ||
87 | break; | ||
88 | } | ||
89 | if (dp_clocks[i] > mode_clock) { | ||
90 | if (i < 2) | ||
91 | return 1; | ||
92 | else if (i < 4) | ||
93 | return 2; | ||
94 | else | ||
95 | return 4; | ||
96 | } | ||
97 | } | ||
98 | break; | ||
99 | case DP_LINK_BW_2_7: | ||
100 | for (i = 0; i < num_dp_clocks; i++) { | ||
101 | switch (max_lane_count) { | ||
102 | case 1: | ||
103 | if (i > 1) | ||
104 | return 0; | ||
105 | break; | ||
106 | case 2: | ||
107 | if (i > 3) | ||
108 | return 0; | ||
109 | break; | ||
110 | case 4: | ||
111 | default: | ||
112 | break; | ||
113 | } | ||
114 | if (dp_clocks[i] > mode_clock) { | ||
115 | if (i < 2) | ||
116 | return 1; | ||
117 | else if (i < 4) | ||
118 | return 2; | ||
119 | else | ||
120 | return 4; | ||
121 | } | ||
122 | } | ||
123 | break; | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int dp_link_clock_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock) | ||
130 | { | ||
131 | int i; | ||
132 | u8 max_link_bw; | ||
133 | u8 max_lane_count; | ||
134 | |||
135 | if (!dpcd) | ||
136 | return 0; | ||
137 | |||
138 | max_link_bw = dpcd[DP_MAX_LINK_RATE]; | ||
139 | max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK; | ||
140 | |||
141 | switch (max_link_bw) { | ||
142 | case DP_LINK_BW_1_62: | ||
143 | default: | ||
144 | for (i = 0; i < num_dp_clocks; i++) { | ||
145 | if (i % 2) | ||
146 | continue; | ||
147 | switch (max_lane_count) { | ||
148 | case 1: | ||
149 | if (i > 1) | ||
150 | return 0; | ||
151 | break; | ||
152 | case 2: | ||
153 | if (i > 3) | ||
154 | return 0; | ||
155 | break; | ||
156 | case 4: | ||
157 | default: | ||
158 | break; | ||
159 | } | ||
160 | if (dp_clocks[i] > mode_clock) | ||
161 | return 162000; | ||
162 | } | ||
163 | break; | ||
164 | case DP_LINK_BW_2_7: | ||
165 | for (i = 0; i < num_dp_clocks; i++) { | ||
166 | switch (max_lane_count) { | ||
167 | case 1: | ||
168 | if (i > 1) | ||
169 | return 0; | ||
170 | break; | ||
171 | case 2: | ||
172 | if (i > 3) | ||
173 | return 0; | ||
174 | break; | ||
175 | case 4: | ||
176 | default: | ||
177 | break; | ||
178 | } | ||
179 | if (dp_clocks[i] > mode_clock) | ||
180 | return (i % 2) ? 270000 : 162000; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | int dp_mode_valid(u8 dpcd[DP_DPCD_SIZE], int mode_clock) | ||
188 | { | ||
189 | int lanes = dp_lanes_for_mode_clock(dpcd, mode_clock); | ||
190 | int bw = dp_lanes_for_mode_clock(dpcd, mode_clock); | ||
191 | |||
192 | if ((lanes == 0) || (bw == 0)) | ||
193 | return MODE_CLOCK_HIGH; | ||
194 | |||
195 | return MODE_OK; | ||
196 | } | ||
197 | |||
198 | static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r) | ||
199 | { | ||
200 | return link_status[r - DP_LANE0_1_STATUS]; | ||
201 | } | ||
202 | |||
203 | static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE], | ||
204 | int lane) | ||
205 | { | ||
206 | int i = DP_LANE0_1_STATUS + (lane >> 1); | ||
207 | int s = (lane & 1) * 4; | ||
208 | u8 l = dp_link_status(link_status, i); | ||
209 | return (l >> s) & 0xf; | ||
210 | } | ||
211 | |||
212 | static bool dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE], | ||
213 | int lane_count) | ||
214 | { | ||
215 | int lane; | ||
216 | u8 lane_status; | ||
217 | |||
218 | for (lane = 0; lane < lane_count; lane++) { | ||
219 | lane_status = dp_get_lane_status(link_status, lane); | ||
220 | if ((lane_status & DP_LANE_CR_DONE) == 0) | ||
221 | return false; | ||
222 | } | ||
223 | return true; | ||
224 | } | ||
225 | |||
226 | static bool dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE], | ||
227 | int lane_count) | ||
228 | { | ||
229 | u8 lane_align; | ||
230 | u8 lane_status; | ||
231 | int lane; | ||
232 | |||
233 | lane_align = dp_link_status(link_status, | ||
234 | DP_LANE_ALIGN_STATUS_UPDATED); | ||
235 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) | ||
236 | return false; | ||
237 | for (lane = 0; lane < lane_count; lane++) { | ||
238 | lane_status = dp_get_lane_status(link_status, lane); | ||
239 | if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS) | ||
240 | return false; | ||
241 | } | ||
242 | return true; | ||
243 | } | ||
244 | |||
245 | static u8 dp_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
246 | int lane) | ||
247 | |||
248 | { | ||
249 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
250 | int s = ((lane & 1) ? | ||
251 | DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : | ||
252 | DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); | ||
253 | u8 l = dp_link_status(link_status, i); | ||
254 | |||
255 | return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; | ||
256 | } | ||
257 | |||
258 | static u8 dp_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
259 | int lane) | ||
260 | { | ||
261 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
262 | int s = ((lane & 1) ? | ||
263 | DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : | ||
264 | DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); | ||
265 | u8 l = dp_link_status(link_status, i); | ||
266 | |||
267 | return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; | ||
268 | } | ||
269 | |||
270 | /* XXX fix me -- chip specific */ | ||
271 | #define DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_1200 | ||
272 | static u8 dp_pre_emphasis_max(u8 voltage_swing) | ||
273 | { | ||
274 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { | ||
275 | case DP_TRAIN_VOLTAGE_SWING_400: | ||
276 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
277 | case DP_TRAIN_VOLTAGE_SWING_600: | ||
278 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
279 | case DP_TRAIN_VOLTAGE_SWING_800: | ||
280 | return DP_TRAIN_PRE_EMPHASIS_3_5; | ||
281 | case DP_TRAIN_VOLTAGE_SWING_1200: | ||
282 | default: | ||
283 | return DP_TRAIN_PRE_EMPHASIS_0; | ||
284 | } | ||
285 | } | ||
286 | |||
287 | static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], | ||
288 | int lane_count, | ||
289 | u8 train_set[4]) | ||
290 | { | ||
291 | u8 v = 0; | ||
292 | u8 p = 0; | ||
293 | int lane; | ||
294 | |||
295 | for (lane = 0; lane < lane_count; lane++) { | ||
296 | u8 this_v = dp_get_adjust_request_voltage(link_status, lane); | ||
297 | u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane); | ||
298 | |||
299 | DRM_DEBUG("requested signal parameters: lane %d voltage %s pre_emph %s\n", | ||
300 | lane, | ||
301 | voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT], | ||
302 | pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); | ||
303 | |||
304 | if (this_v > v) | ||
305 | v = this_v; | ||
306 | if (this_p > p) | ||
307 | p = this_p; | ||
308 | } | ||
309 | |||
310 | if (v >= DP_VOLTAGE_MAX) | ||
311 | v = DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED; | ||
312 | |||
313 | if (p >= dp_pre_emphasis_max(v)) | ||
314 | p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | ||
315 | |||
316 | DRM_DEBUG("using signal parameters: voltage %s pre_emph %s\n", | ||
317 | voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT], | ||
318 | pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); | ||
319 | |||
320 | for (lane = 0; lane < 4; lane++) | ||
321 | train_set[lane] = v | p; | ||
322 | } | ||
323 | |||
324 | |||
325 | /* radeon aux chan functions */ | ||
326 | bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, | ||
327 | int num_bytes, u8 *read_byte, | ||
328 | u8 read_buf_len, u8 delay) | ||
329 | { | ||
330 | struct drm_device *dev = chan->dev; | ||
331 | struct radeon_device *rdev = dev->dev_private; | ||
332 | PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args; | ||
333 | int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); | ||
334 | unsigned char *base; | ||
335 | |||
336 | memset(&args, 0, sizeof(args)); | ||
337 | |||
338 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; | ||
339 | |||
340 | memcpy(base, req_bytes, num_bytes); | ||
341 | |||
342 | args.lpAuxRequest = 0; | ||
343 | args.lpDataOut = 16; | ||
344 | args.ucDataOutLen = 0; | ||
345 | args.ucChannelID = chan->rec.i2c_id; | ||
346 | args.ucDelay = delay / 10; | ||
347 | |||
348 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
349 | |||
350 | if (args.ucReplyStatus) { | ||
351 | DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n", | ||
352 | req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], | ||
353 | chan->rec.i2c_id, args.ucReplyStatus); | ||
354 | return false; | ||
355 | } | ||
356 | |||
357 | if (args.ucDataOutLen && read_byte && read_buf_len) { | ||
358 | if (read_buf_len < args.ucDataOutLen) { | ||
359 | DRM_ERROR("Buffer to small for return answer %d %d\n", | ||
360 | read_buf_len, args.ucDataOutLen); | ||
361 | return false; | ||
362 | } | ||
363 | { | ||
364 | int len = min(read_buf_len, args.ucDataOutLen); | ||
365 | memcpy(read_byte, base + 16, len); | ||
366 | } | ||
367 | } | ||
368 | return true; | ||
369 | } | ||
370 | |||
371 | bool radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, uint16_t address, | ||
372 | uint8_t send_bytes, uint8_t *send) | ||
373 | { | ||
374 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
375 | u8 msg[20]; | ||
376 | u8 msg_len, dp_msg_len; | ||
377 | bool ret; | ||
378 | |||
379 | dp_msg_len = 4; | ||
380 | msg[0] = address; | ||
381 | msg[1] = address >> 8; | ||
382 | msg[2] = AUX_NATIVE_WRITE << 4; | ||
383 | dp_msg_len += send_bytes; | ||
384 | msg[3] = (dp_msg_len << 4) | (send_bytes - 1); | ||
385 | |||
386 | if (send_bytes > 16) | ||
387 | return false; | ||
388 | |||
389 | memcpy(&msg[4], send, send_bytes); | ||
390 | msg_len = 4 + send_bytes; | ||
391 | ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, NULL, 0, 0); | ||
392 | return ret; | ||
393 | } | ||
394 | |||
395 | bool radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, uint16_t address, | ||
396 | uint8_t delay, uint8_t expected_bytes, | ||
397 | uint8_t *read_p) | ||
398 | { | ||
399 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
400 | u8 msg[20]; | ||
401 | u8 msg_len, dp_msg_len; | ||
402 | bool ret = false; | ||
403 | msg_len = 4; | ||
404 | dp_msg_len = 4; | ||
405 | msg[0] = address; | ||
406 | msg[1] = address >> 8; | ||
407 | msg[2] = AUX_NATIVE_READ << 4; | ||
408 | msg[3] = (dp_msg_len) << 4; | ||
409 | msg[3] |= expected_bytes - 1; | ||
410 | |||
411 | ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, read_p, expected_bytes, delay); | ||
412 | return ret; | ||
413 | } | ||
414 | |||
415 | /* radeon dp functions */ | ||
416 | static u8 radeon_dp_encoder_service(struct radeon_device *rdev, int action, int dp_clock, | ||
417 | uint8_t ucconfig, uint8_t lane_num) | ||
418 | { | ||
419 | DP_ENCODER_SERVICE_PARAMETERS args; | ||
420 | int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService); | ||
421 | |||
422 | memset(&args, 0, sizeof(args)); | ||
423 | args.ucLinkClock = dp_clock / 10; | ||
424 | args.ucConfig = ucconfig; | ||
425 | args.ucAction = action; | ||
426 | args.ucLaneNum = lane_num; | ||
427 | args.ucStatus = 0; | ||
428 | |||
429 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
430 | return args.ucStatus; | ||
431 | } | ||
432 | |||
433 | u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector) | ||
434 | { | ||
435 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
436 | struct drm_device *dev = radeon_connector->base.dev; | ||
437 | struct radeon_device *rdev = dev->dev_private; | ||
438 | |||
439 | return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0, | ||
440 | dig_connector->dp_i2c_bus->rec.i2c_id, 0); | ||
441 | } | ||
442 | |||
443 | bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) | ||
444 | { | ||
445 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
446 | u8 msg[25]; | ||
447 | int ret; | ||
448 | |||
449 | ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, 0, 8, msg); | ||
450 | if (ret) { | ||
451 | memcpy(dig_connector->dpcd, msg, 8); | ||
452 | { | ||
453 | int i; | ||
454 | DRM_DEBUG("DPCD: "); | ||
455 | for (i = 0; i < 8; i++) | ||
456 | DRM_DEBUG("%02x ", msg[i]); | ||
457 | DRM_DEBUG("\n"); | ||
458 | } | ||
459 | return true; | ||
460 | } | ||
461 | dig_connector->dpcd[0] = 0; | ||
462 | return false; | ||
463 | } | ||
464 | |||
465 | void radeon_dp_set_link_config(struct drm_connector *connector, | ||
466 | struct drm_display_mode *mode) | ||
467 | { | ||
468 | struct radeon_connector *radeon_connector; | ||
469 | struct radeon_connector_atom_dig *dig_connector; | ||
470 | |||
471 | if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) | ||
472 | return; | ||
473 | |||
474 | radeon_connector = to_radeon_connector(connector); | ||
475 | if (!radeon_connector->con_priv) | ||
476 | return; | ||
477 | dig_connector = radeon_connector->con_priv; | ||
478 | |||
479 | dig_connector->dp_clock = | ||
480 | dp_link_clock_for_mode_clock(dig_connector->dpcd, mode->clock); | ||
481 | dig_connector->dp_lane_count = | ||
482 | dp_lanes_for_mode_clock(dig_connector->dpcd, mode->clock); | ||
483 | } | ||
484 | |||
485 | int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, | ||
486 | struct drm_display_mode *mode) | ||
487 | { | ||
488 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
489 | |||
490 | return dp_mode_valid(dig_connector->dpcd, mode->clock); | ||
491 | } | ||
492 | |||
493 | static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector, | ||
494 | u8 link_status[DP_LINK_STATUS_SIZE]) | ||
495 | { | ||
496 | int ret; | ||
497 | ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, 100, | ||
498 | DP_LINK_STATUS_SIZE, link_status); | ||
499 | if (!ret) { | ||
500 | DRM_ERROR("displayport link status failed\n"); | ||
501 | return false; | ||
502 | } | ||
503 | |||
504 | DRM_DEBUG("link status %02x %02x %02x %02x %02x %02x\n", | ||
505 | link_status[0], link_status[1], link_status[2], | ||
506 | link_status[3], link_status[4], link_status[5]); | ||
507 | return true; | ||
508 | } | ||
509 | |||
510 | bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) | ||
511 | { | ||
512 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
513 | u8 link_status[DP_LINK_STATUS_SIZE]; | ||
514 | |||
515 | if (!atom_dp_get_link_status(radeon_connector, link_status)) | ||
516 | return false; | ||
517 | if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count)) | ||
518 | return false; | ||
519 | return true; | ||
520 | } | ||
521 | |||
522 | static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state) | ||
523 | { | ||
524 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
525 | |||
526 | if (dig_connector->dpcd[0] >= 0x11) { | ||
527 | radeon_dp_aux_native_write(radeon_connector, DP_SET_POWER, 1, | ||
528 | &power_state); | ||
529 | } | ||
530 | } | ||
531 | |||
532 | static void dp_set_downspread(struct radeon_connector *radeon_connector, u8 downspread) | ||
533 | { | ||
534 | radeon_dp_aux_native_write(radeon_connector, DP_DOWNSPREAD_CTRL, 1, | ||
535 | &downspread); | ||
536 | } | ||
537 | |||
538 | static void dp_set_link_bw_lanes(struct radeon_connector *radeon_connector, | ||
539 | u8 link_configuration[DP_LINK_CONFIGURATION_SIZE]) | ||
540 | { | ||
541 | radeon_dp_aux_native_write(radeon_connector, DP_LINK_BW_SET, 2, | ||
542 | link_configuration); | ||
543 | } | ||
544 | |||
545 | static void dp_update_dpvs_emph(struct radeon_connector *radeon_connector, | ||
546 | struct drm_encoder *encoder, | ||
547 | u8 train_set[4]) | ||
548 | { | ||
549 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | ||
550 | int i; | ||
551 | |||
552 | for (i = 0; i < dig_connector->dp_lane_count; i++) | ||
553 | atombios_dig_transmitter_setup(encoder, | ||
554 | ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH, | ||
555 | i, train_set[i]); | ||
556 | |||
557 | radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_LANE0_SET, | ||
558 | dig_connector->dp_lane_count, train_set); | ||
559 | } | ||
560 | |||
561 | static void dp_set_training(struct radeon_connector *radeon_connector, | ||
562 | u8 training) | ||
563 | { | ||
564 | radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_PATTERN_SET, | ||
565 | 1, &training); | ||
566 | } | ||
567 | |||
568 | void dp_link_train(struct drm_encoder *encoder, | ||
569 | struct drm_connector *connector) | ||
570 | { | ||
571 | struct drm_device *dev = encoder->dev; | ||
572 | struct radeon_device *rdev = dev->dev_private; | ||
573 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
574 | struct radeon_encoder_atom_dig *dig; | ||
575 | struct radeon_connector *radeon_connector; | ||
576 | struct radeon_connector_atom_dig *dig_connector; | ||
577 | int enc_id = 0; | ||
578 | bool clock_recovery, channel_eq; | ||
579 | u8 link_status[DP_LINK_STATUS_SIZE]; | ||
580 | u8 link_configuration[DP_LINK_CONFIGURATION_SIZE]; | ||
581 | u8 tries, voltage; | ||
582 | u8 train_set[4]; | ||
583 | int i; | ||
584 | |||
585 | if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) | ||
586 | return; | ||
587 | |||
588 | if (!radeon_encoder->enc_priv) | ||
589 | return; | ||
590 | dig = radeon_encoder->enc_priv; | ||
591 | |||
592 | radeon_connector = to_radeon_connector(connector); | ||
593 | if (!radeon_connector->con_priv) | ||
594 | return; | ||
595 | dig_connector = radeon_connector->con_priv; | ||
596 | |||
597 | if (ASIC_IS_DCE32(rdev)) { | ||
598 | if (dig->dig_block) | ||
599 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; | ||
600 | else | ||
601 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; | ||
602 | if (dig_connector->linkb) | ||
603 | enc_id |= ATOM_DP_CONFIG_LINK_B; | ||
604 | else | ||
605 | enc_id |= ATOM_DP_CONFIG_LINK_A; | ||
606 | } else { | ||
607 | if (dig_connector->linkb) | ||
608 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER | ATOM_DP_CONFIG_LINK_B; | ||
609 | else | ||
610 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER | ATOM_DP_CONFIG_LINK_A; | ||
611 | } | ||
612 | |||
613 | memset(link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | ||
614 | if (dig_connector->dp_clock == 270000) | ||
615 | link_configuration[0] = DP_LINK_BW_2_7; | ||
616 | else | ||
617 | link_configuration[0] = DP_LINK_BW_1_62; | ||
618 | link_configuration[1] = dig_connector->dp_lane_count; | ||
619 | if (dig_connector->dpcd[0] >= 0x11) | ||
620 | link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | ||
621 | |||
622 | /* power up the sink */ | ||
623 | dp_set_power(radeon_connector, DP_SET_POWER_D0); | ||
624 | /* disable the training pattern on the sink */ | ||
625 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE); | ||
626 | /* set link bw and lanes on the sink */ | ||
627 | dp_set_link_bw_lanes(radeon_connector, link_configuration); | ||
628 | /* disable downspread on the sink */ | ||
629 | dp_set_downspread(radeon_connector, 0); | ||
630 | /* start training on the source */ | ||
631 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START, | ||
632 | dig_connector->dp_clock, enc_id, 0); | ||
633 | /* set training pattern 1 on the source */ | ||
634 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, | ||
635 | dig_connector->dp_clock, enc_id, 0); | ||
636 | |||
637 | /* set initial vs/emph */ | ||
638 | memset(train_set, 0, 4); | ||
639 | udelay(400); | ||
640 | /* set training pattern 1 on the sink */ | ||
641 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_1); | ||
642 | |||
643 | dp_update_dpvs_emph(radeon_connector, encoder, train_set); | ||
644 | |||
645 | /* clock recovery loop */ | ||
646 | clock_recovery = false; | ||
647 | tries = 0; | ||
648 | voltage = 0xff; | ||
649 | for (;;) { | ||
650 | udelay(100); | ||
651 | if (!atom_dp_get_link_status(radeon_connector, link_status)) | ||
652 | break; | ||
653 | |||
654 | if (dp_clock_recovery_ok(link_status, dig_connector->dp_lane_count)) { | ||
655 | clock_recovery = true; | ||
656 | break; | ||
657 | } | ||
658 | |||
659 | for (i = 0; i < dig_connector->dp_lane_count; i++) { | ||
660 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | ||
661 | break; | ||
662 | } | ||
663 | if (i == dig_connector->dp_lane_count) { | ||
664 | DRM_ERROR("clock recovery reached max voltage\n"); | ||
665 | break; | ||
666 | } | ||
667 | |||
668 | if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { | ||
669 | ++tries; | ||
670 | if (tries == 5) { | ||
671 | DRM_ERROR("clock recovery tried 5 times\n"); | ||
672 | break; | ||
673 | } | ||
674 | } else | ||
675 | tries = 0; | ||
676 | |||
677 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
678 | |||
679 | /* Compute new train_set as requested by sink */ | ||
680 | dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set); | ||
681 | dp_update_dpvs_emph(radeon_connector, encoder, train_set); | ||
682 | } | ||
683 | if (!clock_recovery) | ||
684 | DRM_ERROR("clock recovery failed\n"); | ||
685 | else | ||
686 | DRM_DEBUG("clock recovery at voltage %d pre-emphasis %d\n", | ||
687 | train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, | ||
688 | (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >> | ||
689 | DP_TRAIN_PRE_EMPHASIS_SHIFT); | ||
690 | |||
691 | |||
692 | /* set training pattern 2 on the sink */ | ||
693 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2); | ||
694 | /* set training pattern 2 on the source */ | ||
695 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, | ||
696 | dig_connector->dp_clock, enc_id, 1); | ||
697 | |||
698 | /* channel equalization loop */ | ||
699 | tries = 0; | ||
700 | channel_eq = false; | ||
701 | for (;;) { | ||
702 | udelay(400); | ||
703 | if (!atom_dp_get_link_status(radeon_connector, link_status)) | ||
704 | break; | ||
705 | |||
706 | if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count)) { | ||
707 | channel_eq = true; | ||
708 | break; | ||
709 | } | ||
710 | |||
711 | /* Try 5 times */ | ||
712 | if (tries > 5) { | ||
713 | DRM_ERROR("channel eq failed: 5 tries\n"); | ||
714 | break; | ||
715 | } | ||
716 | |||
717 | /* Compute new train_set as requested by sink */ | ||
718 | dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set); | ||
719 | dp_update_dpvs_emph(radeon_connector, encoder, train_set); | ||
720 | |||
721 | tries++; | ||
722 | } | ||
723 | |||
724 | if (!channel_eq) | ||
725 | DRM_ERROR("channel eq failed\n"); | ||
726 | else | ||
727 | DRM_DEBUG("channel eq at voltage %d pre-emphasis %d\n", | ||
728 | train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, | ||
729 | (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) | ||
730 | >> DP_TRAIN_PRE_EMPHASIS_SHIFT); | ||
731 | |||
732 | /* disable the training pattern on the sink */ | ||
733 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE); | ||
734 | |||
735 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, | ||
736 | dig_connector->dp_clock, enc_id, 0); | ||
737 | } | ||
738 | |||
739 | int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | ||
740 | uint8_t write_byte, uint8_t *read_byte) | ||
741 | { | ||
742 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
743 | struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter; | ||
744 | int ret = 0; | ||
745 | uint16_t address = algo_data->address; | ||
746 | uint8_t msg[5]; | ||
747 | uint8_t reply[2]; | ||
748 | int msg_len, dp_msg_len; | ||
749 | int reply_bytes; | ||
750 | |||
751 | /* Set up the command byte */ | ||
752 | if (mode & MODE_I2C_READ) | ||
753 | msg[2] = AUX_I2C_READ << 4; | ||
754 | else | ||
755 | msg[2] = AUX_I2C_WRITE << 4; | ||
756 | |||
757 | if (!(mode & MODE_I2C_STOP)) | ||
758 | msg[2] |= AUX_I2C_MOT << 4; | ||
759 | |||
760 | msg[0] = address; | ||
761 | msg[1] = address >> 8; | ||
762 | |||
763 | reply_bytes = 1; | ||
764 | |||
765 | msg_len = 4; | ||
766 | dp_msg_len = 3; | ||
767 | switch (mode) { | ||
768 | case MODE_I2C_WRITE: | ||
769 | msg[4] = write_byte; | ||
770 | msg_len++; | ||
771 | dp_msg_len += 2; | ||
772 | break; | ||
773 | case MODE_I2C_READ: | ||
774 | dp_msg_len += 1; | ||
775 | break; | ||
776 | default: | ||
777 | break; | ||
778 | } | ||
779 | |||
780 | msg[3] = (dp_msg_len) << 4; | ||
781 | ret = radeon_process_aux_ch(auxch, msg, msg_len, reply, reply_bytes, 0); | ||
782 | |||
783 | if (ret) { | ||
784 | if (read_byte) | ||
785 | *read_byte = reply[0]; | ||
786 | return reply_bytes; | ||
787 | } | ||
788 | return -EREMOTEIO; | ||
789 | } | ||
790 | |||
diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c index fb211e585dea..0d79577c1576 100644 --- a/drivers/gpu/drm/radeon/mkregtable.c +++ b/drivers/gpu/drm/radeon/mkregtable.c | |||
@@ -561,7 +561,7 @@ struct table { | |||
561 | char *gpu_prefix; | 561 | char *gpu_prefix; |
562 | }; | 562 | }; |
563 | 563 | ||
564 | struct offset *offset_new(unsigned o) | 564 | static struct offset *offset_new(unsigned o) |
565 | { | 565 | { |
566 | struct offset *offset; | 566 | struct offset *offset; |
567 | 567 | ||
@@ -573,12 +573,12 @@ struct offset *offset_new(unsigned o) | |||
573 | return offset; | 573 | return offset; |
574 | } | 574 | } |
575 | 575 | ||
576 | void table_offset_add(struct table *t, struct offset *offset) | 576 | static void table_offset_add(struct table *t, struct offset *offset) |
577 | { | 577 | { |
578 | list_add_tail(&offset->list, &t->offsets); | 578 | list_add_tail(&offset->list, &t->offsets); |
579 | } | 579 | } |
580 | 580 | ||
581 | void table_init(struct table *t) | 581 | static void table_init(struct table *t) |
582 | { | 582 | { |
583 | INIT_LIST_HEAD(&t->offsets); | 583 | INIT_LIST_HEAD(&t->offsets); |
584 | t->offset_max = 0; | 584 | t->offset_max = 0; |
@@ -586,7 +586,7 @@ void table_init(struct table *t) | |||
586 | t->table = NULL; | 586 | t->table = NULL; |
587 | } | 587 | } |
588 | 588 | ||
589 | void table_print(struct table *t) | 589 | static void table_print(struct table *t) |
590 | { | 590 | { |
591 | unsigned nlloop, i, j, n, c, id; | 591 | unsigned nlloop, i, j, n, c, id; |
592 | 592 | ||
@@ -611,7 +611,7 @@ void table_print(struct table *t) | |||
611 | printf("};\n"); | 611 | printf("};\n"); |
612 | } | 612 | } |
613 | 613 | ||
614 | int table_build(struct table *t) | 614 | static int table_build(struct table *t) |
615 | { | 615 | { |
616 | struct offset *offset; | 616 | struct offset *offset; |
617 | unsigned i, m; | 617 | unsigned i, m; |
@@ -631,7 +631,7 @@ int table_build(struct table *t) | |||
631 | } | 631 | } |
632 | 632 | ||
633 | static char gpu_name[10]; | 633 | static char gpu_name[10]; |
634 | int parser_auth(struct table *t, const char *filename) | 634 | static int parser_auth(struct table *t, const char *filename) |
635 | { | 635 | { |
636 | FILE *file; | 636 | FILE *file; |
637 | regex_t mask_rex; | 637 | regex_t mask_rex; |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 161094c07d94..824cc6480a06 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -65,6 +65,95 @@ MODULE_FIRMWARE(FIRMWARE_R520); | |||
65 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 | 65 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
66 | */ | 66 | */ |
67 | 67 | ||
68 | /* hpd for digital panel detect/disconnect */ | ||
69 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | ||
70 | { | ||
71 | bool connected = false; | ||
72 | |||
73 | switch (hpd) { | ||
74 | case RADEON_HPD_1: | ||
75 | if (RREG32(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE) | ||
76 | connected = true; | ||
77 | break; | ||
78 | case RADEON_HPD_2: | ||
79 | if (RREG32(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE) | ||
80 | connected = true; | ||
81 | break; | ||
82 | default: | ||
83 | break; | ||
84 | } | ||
85 | return connected; | ||
86 | } | ||
87 | |||
88 | void r100_hpd_set_polarity(struct radeon_device *rdev, | ||
89 | enum radeon_hpd_id hpd) | ||
90 | { | ||
91 | u32 tmp; | ||
92 | bool connected = r100_hpd_sense(rdev, hpd); | ||
93 | |||
94 | switch (hpd) { | ||
95 | case RADEON_HPD_1: | ||
96 | tmp = RREG32(RADEON_FP_GEN_CNTL); | ||
97 | if (connected) | ||
98 | tmp &= ~RADEON_FP_DETECT_INT_POL; | ||
99 | else | ||
100 | tmp |= RADEON_FP_DETECT_INT_POL; | ||
101 | WREG32(RADEON_FP_GEN_CNTL, tmp); | ||
102 | break; | ||
103 | case RADEON_HPD_2: | ||
104 | tmp = RREG32(RADEON_FP2_GEN_CNTL); | ||
105 | if (connected) | ||
106 | tmp &= ~RADEON_FP2_DETECT_INT_POL; | ||
107 | else | ||
108 | tmp |= RADEON_FP2_DETECT_INT_POL; | ||
109 | WREG32(RADEON_FP2_GEN_CNTL, tmp); | ||
110 | break; | ||
111 | default: | ||
112 | break; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | void r100_hpd_init(struct radeon_device *rdev) | ||
117 | { | ||
118 | struct drm_device *dev = rdev->ddev; | ||
119 | struct drm_connector *connector; | ||
120 | |||
121 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
122 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
123 | switch (radeon_connector->hpd.hpd) { | ||
124 | case RADEON_HPD_1: | ||
125 | rdev->irq.hpd[0] = true; | ||
126 | break; | ||
127 | case RADEON_HPD_2: | ||
128 | rdev->irq.hpd[1] = true; | ||
129 | break; | ||
130 | default: | ||
131 | break; | ||
132 | } | ||
133 | } | ||
134 | r100_irq_set(rdev); | ||
135 | } | ||
136 | |||
137 | void r100_hpd_fini(struct radeon_device *rdev) | ||
138 | { | ||
139 | struct drm_device *dev = rdev->ddev; | ||
140 | struct drm_connector *connector; | ||
141 | |||
142 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
143 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
144 | switch (radeon_connector->hpd.hpd) { | ||
145 | case RADEON_HPD_1: | ||
146 | rdev->irq.hpd[0] = false; | ||
147 | break; | ||
148 | case RADEON_HPD_2: | ||
149 | rdev->irq.hpd[1] = false; | ||
150 | break; | ||
151 | default: | ||
152 | break; | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
68 | /* | 157 | /* |
69 | * PCI GART | 158 | * PCI GART |
70 | */ | 159 | */ |
@@ -94,6 +183,15 @@ int r100_pci_gart_init(struct radeon_device *rdev) | |||
94 | return radeon_gart_table_ram_alloc(rdev); | 183 | return radeon_gart_table_ram_alloc(rdev); |
95 | } | 184 | } |
96 | 185 | ||
186 | /* required on r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ | ||
187 | void r100_enable_bm(struct radeon_device *rdev) | ||
188 | { | ||
189 | uint32_t tmp; | ||
190 | /* Enable bus mastering */ | ||
191 | tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; | ||
192 | WREG32(RADEON_BUS_CNTL, tmp); | ||
193 | } | ||
194 | |||
97 | int r100_pci_gart_enable(struct radeon_device *rdev) | 195 | int r100_pci_gart_enable(struct radeon_device *rdev) |
98 | { | 196 | { |
99 | uint32_t tmp; | 197 | uint32_t tmp; |
@@ -105,9 +203,6 @@ int r100_pci_gart_enable(struct radeon_device *rdev) | |||
105 | WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location); | 203 | WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location); |
106 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; | 204 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; |
107 | WREG32(RADEON_AIC_HI_ADDR, tmp); | 205 | WREG32(RADEON_AIC_HI_ADDR, tmp); |
108 | /* Enable bus mastering */ | ||
109 | tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; | ||
110 | WREG32(RADEON_BUS_CNTL, tmp); | ||
111 | /* set PCI GART page-table base address */ | 206 | /* set PCI GART page-table base address */ |
112 | WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr); | 207 | WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr); |
113 | tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN; | 208 | tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN; |
@@ -157,6 +252,12 @@ int r100_irq_set(struct radeon_device *rdev) | |||
157 | if (rdev->irq.crtc_vblank_int[1]) { | 252 | if (rdev->irq.crtc_vblank_int[1]) { |
158 | tmp |= RADEON_CRTC2_VBLANK_MASK; | 253 | tmp |= RADEON_CRTC2_VBLANK_MASK; |
159 | } | 254 | } |
255 | if (rdev->irq.hpd[0]) { | ||
256 | tmp |= RADEON_FP_DETECT_MASK; | ||
257 | } | ||
258 | if (rdev->irq.hpd[1]) { | ||
259 | tmp |= RADEON_FP2_DETECT_MASK; | ||
260 | } | ||
160 | WREG32(RADEON_GEN_INT_CNTL, tmp); | 261 | WREG32(RADEON_GEN_INT_CNTL, tmp); |
161 | return 0; | 262 | return 0; |
162 | } | 263 | } |
@@ -175,8 +276,9 @@ void r100_irq_disable(struct radeon_device *rdev) | |||
175 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) | 276 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) |
176 | { | 277 | { |
177 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); | 278 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); |
178 | uint32_t irq_mask = RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT | | 279 | uint32_t irq_mask = RADEON_SW_INT_TEST | |
179 | RADEON_CRTC2_VBLANK_STAT; | 280 | RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | |
281 | RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; | ||
180 | 282 | ||
181 | if (irqs) { | 283 | if (irqs) { |
182 | WREG32(RADEON_GEN_INT_STATUS, irqs); | 284 | WREG32(RADEON_GEN_INT_STATUS, irqs); |
@@ -186,7 +288,8 @@ static inline uint32_t r100_irq_ack(struct radeon_device *rdev) | |||
186 | 288 | ||
187 | int r100_irq_process(struct radeon_device *rdev) | 289 | int r100_irq_process(struct radeon_device *rdev) |
188 | { | 290 | { |
189 | uint32_t status; | 291 | uint32_t status, msi_rearm; |
292 | bool queue_hotplug = false; | ||
190 | 293 | ||
191 | status = r100_irq_ack(rdev); | 294 | status = r100_irq_ack(rdev); |
192 | if (!status) { | 295 | if (!status) { |
@@ -207,8 +310,33 @@ int r100_irq_process(struct radeon_device *rdev) | |||
207 | if (status & RADEON_CRTC2_VBLANK_STAT) { | 310 | if (status & RADEON_CRTC2_VBLANK_STAT) { |
208 | drm_handle_vblank(rdev->ddev, 1); | 311 | drm_handle_vblank(rdev->ddev, 1); |
209 | } | 312 | } |
313 | if (status & RADEON_FP_DETECT_STAT) { | ||
314 | queue_hotplug = true; | ||
315 | DRM_DEBUG("HPD1\n"); | ||
316 | } | ||
317 | if (status & RADEON_FP2_DETECT_STAT) { | ||
318 | queue_hotplug = true; | ||
319 | DRM_DEBUG("HPD2\n"); | ||
320 | } | ||
210 | status = r100_irq_ack(rdev); | 321 | status = r100_irq_ack(rdev); |
211 | } | 322 | } |
323 | if (queue_hotplug) | ||
324 | queue_work(rdev->wq, &rdev->hotplug_work); | ||
325 | if (rdev->msi_enabled) { | ||
326 | switch (rdev->family) { | ||
327 | case CHIP_RS400: | ||
328 | case CHIP_RS480: | ||
329 | msi_rearm = RREG32(RADEON_AIC_CNTL) & ~RS400_MSI_REARM; | ||
330 | WREG32(RADEON_AIC_CNTL, msi_rearm); | ||
331 | WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM); | ||
332 | break; | ||
333 | default: | ||
334 | msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; | ||
335 | WREG32(RADEON_MSI_REARM_EN, msi_rearm); | ||
336 | WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); | ||
337 | break; | ||
338 | } | ||
339 | } | ||
212 | return IRQ_HANDLED; | 340 | return IRQ_HANDLED; |
213 | } | 341 | } |
214 | 342 | ||
@@ -240,24 +368,27 @@ int r100_wb_init(struct radeon_device *rdev) | |||
240 | int r; | 368 | int r; |
241 | 369 | ||
242 | if (rdev->wb.wb_obj == NULL) { | 370 | if (rdev->wb.wb_obj == NULL) { |
243 | r = radeon_object_create(rdev, NULL, 4096, | 371 | r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true, |
244 | true, | 372 | RADEON_GEM_DOMAIN_GTT, |
245 | RADEON_GEM_DOMAIN_GTT, | 373 | &rdev->wb.wb_obj); |
246 | false, &rdev->wb.wb_obj); | ||
247 | if (r) { | 374 | if (r) { |
248 | DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r); | 375 | dev_err(rdev->dev, "(%d) create WB buffer failed\n", r); |
249 | return r; | 376 | return r; |
250 | } | 377 | } |
251 | r = radeon_object_pin(rdev->wb.wb_obj, | 378 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); |
252 | RADEON_GEM_DOMAIN_GTT, | 379 | if (unlikely(r != 0)) |
253 | &rdev->wb.gpu_addr); | 380 | return r; |
381 | r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, | ||
382 | &rdev->wb.gpu_addr); | ||
254 | if (r) { | 383 | if (r) { |
255 | DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r); | 384 | dev_err(rdev->dev, "(%d) pin WB buffer failed\n", r); |
385 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
256 | return r; | 386 | return r; |
257 | } | 387 | } |
258 | r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); | 388 | r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); |
389 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
259 | if (r) { | 390 | if (r) { |
260 | DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r); | 391 | dev_err(rdev->dev, "(%d) map WB buffer failed\n", r); |
261 | return r; | 392 | return r; |
262 | } | 393 | } |
263 | } | 394 | } |
@@ -275,11 +406,19 @@ void r100_wb_disable(struct radeon_device *rdev) | |||
275 | 406 | ||
276 | void r100_wb_fini(struct radeon_device *rdev) | 407 | void r100_wb_fini(struct radeon_device *rdev) |
277 | { | 408 | { |
409 | int r; | ||
410 | |||
278 | r100_wb_disable(rdev); | 411 | r100_wb_disable(rdev); |
279 | if (rdev->wb.wb_obj) { | 412 | if (rdev->wb.wb_obj) { |
280 | radeon_object_kunmap(rdev->wb.wb_obj); | 413 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); |
281 | radeon_object_unpin(rdev->wb.wb_obj); | 414 | if (unlikely(r != 0)) { |
282 | radeon_object_unref(&rdev->wb.wb_obj); | 415 | dev_err(rdev->dev, "(%d) can't finish WB\n", r); |
416 | return; | ||
417 | } | ||
418 | radeon_bo_kunmap(rdev->wb.wb_obj); | ||
419 | radeon_bo_unpin(rdev->wb.wb_obj); | ||
420 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
421 | radeon_bo_unref(&rdev->wb.wb_obj); | ||
283 | rdev->wb.wb = NULL; | 422 | rdev->wb.wb = NULL; |
284 | rdev->wb.wb_obj = NULL; | 423 | rdev->wb.wb_obj = NULL; |
285 | } | 424 | } |
@@ -563,19 +702,19 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) | |||
563 | indirect1_start = 16; | 702 | indirect1_start = 16; |
564 | /* cp setup */ | 703 | /* cp setup */ |
565 | WREG32(0x718, pre_write_timer | (pre_write_limit << 28)); | 704 | WREG32(0x718, pre_write_timer | (pre_write_limit << 28)); |
566 | WREG32(RADEON_CP_RB_CNTL, | 705 | tmp = (REG_SET(RADEON_RB_BUFSZ, rb_bufsz) | |
567 | #ifdef __BIG_ENDIAN | ||
568 | RADEON_BUF_SWAP_32BIT | | ||
569 | #endif | ||
570 | REG_SET(RADEON_RB_BUFSZ, rb_bufsz) | | ||
571 | REG_SET(RADEON_RB_BLKSZ, rb_blksz) | | 706 | REG_SET(RADEON_RB_BLKSZ, rb_blksz) | |
572 | REG_SET(RADEON_MAX_FETCH, max_fetch) | | 707 | REG_SET(RADEON_MAX_FETCH, max_fetch) | |
573 | RADEON_RB_NO_UPDATE); | 708 | RADEON_RB_NO_UPDATE); |
709 | #ifdef __BIG_ENDIAN | ||
710 | tmp |= RADEON_BUF_SWAP_32BIT; | ||
711 | #endif | ||
712 | WREG32(RADEON_CP_RB_CNTL, tmp); | ||
713 | |||
574 | /* Set ring address */ | 714 | /* Set ring address */ |
575 | DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr); | 715 | DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr); |
576 | WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr); | 716 | WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr); |
577 | /* Force read & write ptr to 0 */ | 717 | /* Force read & write ptr to 0 */ |
578 | tmp = RREG32(RADEON_CP_RB_CNTL); | ||
579 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); | 718 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); |
580 | WREG32(RADEON_CP_RB_RPTR_WR, 0); | 719 | WREG32(RADEON_CP_RB_RPTR_WR, 0); |
581 | WREG32(RADEON_CP_RB_WPTR, 0); | 720 | WREG32(RADEON_CP_RB_WPTR, 0); |
@@ -1273,17 +1412,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1273 | 1412 | ||
1274 | int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, | 1413 | int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, |
1275 | struct radeon_cs_packet *pkt, | 1414 | struct radeon_cs_packet *pkt, |
1276 | struct radeon_object *robj) | 1415 | struct radeon_bo *robj) |
1277 | { | 1416 | { |
1278 | unsigned idx; | 1417 | unsigned idx; |
1279 | u32 value; | 1418 | u32 value; |
1280 | idx = pkt->idx + 1; | 1419 | idx = pkt->idx + 1; |
1281 | value = radeon_get_ib_value(p, idx + 2); | 1420 | value = radeon_get_ib_value(p, idx + 2); |
1282 | if ((value + 1) > radeon_object_size(robj)) { | 1421 | if ((value + 1) > radeon_bo_size(robj)) { |
1283 | DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER " | 1422 | DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER " |
1284 | "(need %u have %lu) !\n", | 1423 | "(need %u have %lu) !\n", |
1285 | value + 1, | 1424 | value + 1, |
1286 | radeon_object_size(robj)); | 1425 | radeon_bo_size(robj)); |
1287 | return -EINVAL; | 1426 | return -EINVAL; |
1288 | } | 1427 | } |
1289 | return 0; | 1428 | return 0; |
@@ -1568,6 +1707,14 @@ void r100_gpu_init(struct radeon_device *rdev) | |||
1568 | r100_hdp_reset(rdev); | 1707 | r100_hdp_reset(rdev); |
1569 | } | 1708 | } |
1570 | 1709 | ||
1710 | void r100_hdp_flush(struct radeon_device *rdev) | ||
1711 | { | ||
1712 | u32 tmp; | ||
1713 | tmp = RREG32(RADEON_HOST_PATH_CNTL); | ||
1714 | tmp |= RADEON_HDP_READ_BUFFER_INVALIDATE; | ||
1715 | WREG32(RADEON_HOST_PATH_CNTL, tmp); | ||
1716 | } | ||
1717 | |||
1571 | void r100_hdp_reset(struct radeon_device *rdev) | 1718 | void r100_hdp_reset(struct radeon_device *rdev) |
1572 | { | 1719 | { |
1573 | uint32_t tmp; | 1720 | uint32_t tmp; |
@@ -1635,6 +1782,17 @@ int r100_gpu_reset(struct radeon_device *rdev) | |||
1635 | return 0; | 1782 | return 0; |
1636 | } | 1783 | } |
1637 | 1784 | ||
1785 | void r100_set_common_regs(struct radeon_device *rdev) | ||
1786 | { | ||
1787 | /* set these so they don't interfere with anything */ | ||
1788 | WREG32(RADEON_OV0_SCALE_CNTL, 0); | ||
1789 | WREG32(RADEON_SUBPIC_CNTL, 0); | ||
1790 | WREG32(RADEON_VIPH_CONTROL, 0); | ||
1791 | WREG32(RADEON_I2C_CNTL_1, 0); | ||
1792 | WREG32(RADEON_DVI_I2C_CNTL_1, 0); | ||
1793 | WREG32(RADEON_CAP0_TRIG_CNTL, 0); | ||
1794 | WREG32(RADEON_CAP1_TRIG_CNTL, 0); | ||
1795 | } | ||
1638 | 1796 | ||
1639 | /* | 1797 | /* |
1640 | * VRAM info | 1798 | * VRAM info |
@@ -2364,7 +2522,7 @@ void r100_bandwidth_update(struct radeon_device *rdev) | |||
2364 | /* | 2522 | /* |
2365 | Find the total latency for the display data. | 2523 | Find the total latency for the display data. |
2366 | */ | 2524 | */ |
2367 | disp_latency_overhead.full = rfixed_const(80); | 2525 | disp_latency_overhead.full = rfixed_const(8); |
2368 | disp_latency_overhead.full = rfixed_div(disp_latency_overhead, sclk_ff); | 2526 | disp_latency_overhead.full = rfixed_div(disp_latency_overhead, sclk_ff); |
2369 | mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full; | 2527 | mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full; |
2370 | mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full; | 2528 | mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full; |
@@ -2562,8 +2720,11 @@ void r100_bandwidth_update(struct radeon_device *rdev) | |||
2562 | static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t) | 2720 | static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t) |
2563 | { | 2721 | { |
2564 | DRM_ERROR("pitch %d\n", t->pitch); | 2722 | DRM_ERROR("pitch %d\n", t->pitch); |
2723 | DRM_ERROR("use_pitch %d\n", t->use_pitch); | ||
2565 | DRM_ERROR("width %d\n", t->width); | 2724 | DRM_ERROR("width %d\n", t->width); |
2725 | DRM_ERROR("width_11 %d\n", t->width_11); | ||
2566 | DRM_ERROR("height %d\n", t->height); | 2726 | DRM_ERROR("height %d\n", t->height); |
2727 | DRM_ERROR("height_11 %d\n", t->height_11); | ||
2567 | DRM_ERROR("num levels %d\n", t->num_levels); | 2728 | DRM_ERROR("num levels %d\n", t->num_levels); |
2568 | DRM_ERROR("depth %d\n", t->txdepth); | 2729 | DRM_ERROR("depth %d\n", t->txdepth); |
2569 | DRM_ERROR("bpp %d\n", t->cpp); | 2730 | DRM_ERROR("bpp %d\n", t->cpp); |
@@ -2576,7 +2737,7 @@ static int r100_cs_track_cube(struct radeon_device *rdev, | |||
2576 | struct r100_cs_track *track, unsigned idx) | 2737 | struct r100_cs_track *track, unsigned idx) |
2577 | { | 2738 | { |
2578 | unsigned face, w, h; | 2739 | unsigned face, w, h; |
2579 | struct radeon_object *cube_robj; | 2740 | struct radeon_bo *cube_robj; |
2580 | unsigned long size; | 2741 | unsigned long size; |
2581 | 2742 | ||
2582 | for (face = 0; face < 5; face++) { | 2743 | for (face = 0; face < 5; face++) { |
@@ -2589,9 +2750,9 @@ static int r100_cs_track_cube(struct radeon_device *rdev, | |||
2589 | 2750 | ||
2590 | size += track->textures[idx].cube_info[face].offset; | 2751 | size += track->textures[idx].cube_info[face].offset; |
2591 | 2752 | ||
2592 | if (size > radeon_object_size(cube_robj)) { | 2753 | if (size > radeon_bo_size(cube_robj)) { |
2593 | DRM_ERROR("Cube texture offset greater than object size %lu %lu\n", | 2754 | DRM_ERROR("Cube texture offset greater than object size %lu %lu\n", |
2594 | size, radeon_object_size(cube_robj)); | 2755 | size, radeon_bo_size(cube_robj)); |
2595 | r100_cs_track_texture_print(&track->textures[idx]); | 2756 | r100_cs_track_texture_print(&track->textures[idx]); |
2596 | return -1; | 2757 | return -1; |
2597 | } | 2758 | } |
@@ -2602,7 +2763,7 @@ static int r100_cs_track_cube(struct radeon_device *rdev, | |||
2602 | static int r100_cs_track_texture_check(struct radeon_device *rdev, | 2763 | static int r100_cs_track_texture_check(struct radeon_device *rdev, |
2603 | struct r100_cs_track *track) | 2764 | struct r100_cs_track *track) |
2604 | { | 2765 | { |
2605 | struct radeon_object *robj; | 2766 | struct radeon_bo *robj; |
2606 | unsigned long size; | 2767 | unsigned long size; |
2607 | unsigned u, i, w, h; | 2768 | unsigned u, i, w, h; |
2608 | int ret; | 2769 | int ret; |
@@ -2623,15 +2784,17 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev, | |||
2623 | else | 2784 | else |
2624 | w = track->textures[u].pitch / (1 << i); | 2785 | w = track->textures[u].pitch / (1 << i); |
2625 | } else { | 2786 | } else { |
2626 | w = track->textures[u].width / (1 << i); | 2787 | w = track->textures[u].width; |
2627 | if (rdev->family >= CHIP_RV515) | 2788 | if (rdev->family >= CHIP_RV515) |
2628 | w |= track->textures[u].width_11; | 2789 | w |= track->textures[u].width_11; |
2790 | w = w / (1 << i); | ||
2629 | if (track->textures[u].roundup_w) | 2791 | if (track->textures[u].roundup_w) |
2630 | w = roundup_pow_of_two(w); | 2792 | w = roundup_pow_of_two(w); |
2631 | } | 2793 | } |
2632 | h = track->textures[u].height / (1 << i); | 2794 | h = track->textures[u].height; |
2633 | if (rdev->family >= CHIP_RV515) | 2795 | if (rdev->family >= CHIP_RV515) |
2634 | h |= track->textures[u].height_11; | 2796 | h |= track->textures[u].height_11; |
2797 | h = h / (1 << i); | ||
2635 | if (track->textures[u].roundup_h) | 2798 | if (track->textures[u].roundup_h) |
2636 | h = roundup_pow_of_two(h); | 2799 | h = roundup_pow_of_two(h); |
2637 | size += w * h; | 2800 | size += w * h; |
@@ -2656,9 +2819,9 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev, | |||
2656 | "%u\n", track->textures[u].tex_coord_type, u); | 2819 | "%u\n", track->textures[u].tex_coord_type, u); |
2657 | return -EINVAL; | 2820 | return -EINVAL; |
2658 | } | 2821 | } |
2659 | if (size > radeon_object_size(robj)) { | 2822 | if (size > radeon_bo_size(robj)) { |
2660 | DRM_ERROR("Texture of unit %u needs %lu bytes but is " | 2823 | DRM_ERROR("Texture of unit %u needs %lu bytes but is " |
2661 | "%lu\n", u, size, radeon_object_size(robj)); | 2824 | "%lu\n", u, size, radeon_bo_size(robj)); |
2662 | r100_cs_track_texture_print(&track->textures[u]); | 2825 | r100_cs_track_texture_print(&track->textures[u]); |
2663 | return -EINVAL; | 2826 | return -EINVAL; |
2664 | } | 2827 | } |
@@ -2680,10 +2843,10 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
2680 | } | 2843 | } |
2681 | size = track->cb[i].pitch * track->cb[i].cpp * track->maxy; | 2844 | size = track->cb[i].pitch * track->cb[i].cpp * track->maxy; |
2682 | size += track->cb[i].offset; | 2845 | size += track->cb[i].offset; |
2683 | if (size > radeon_object_size(track->cb[i].robj)) { | 2846 | if (size > radeon_bo_size(track->cb[i].robj)) { |
2684 | DRM_ERROR("[drm] Buffer too small for color buffer %d " | 2847 | DRM_ERROR("[drm] Buffer too small for color buffer %d " |
2685 | "(need %lu have %lu) !\n", i, size, | 2848 | "(need %lu have %lu) !\n", i, size, |
2686 | radeon_object_size(track->cb[i].robj)); | 2849 | radeon_bo_size(track->cb[i].robj)); |
2687 | DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n", | 2850 | DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n", |
2688 | i, track->cb[i].pitch, track->cb[i].cpp, | 2851 | i, track->cb[i].pitch, track->cb[i].cpp, |
2689 | track->cb[i].offset, track->maxy); | 2852 | track->cb[i].offset, track->maxy); |
@@ -2697,10 +2860,10 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
2697 | } | 2860 | } |
2698 | size = track->zb.pitch * track->zb.cpp * track->maxy; | 2861 | size = track->zb.pitch * track->zb.cpp * track->maxy; |
2699 | size += track->zb.offset; | 2862 | size += track->zb.offset; |
2700 | if (size > radeon_object_size(track->zb.robj)) { | 2863 | if (size > radeon_bo_size(track->zb.robj)) { |
2701 | DRM_ERROR("[drm] Buffer too small for z buffer " | 2864 | DRM_ERROR("[drm] Buffer too small for z buffer " |
2702 | "(need %lu have %lu) !\n", size, | 2865 | "(need %lu have %lu) !\n", size, |
2703 | radeon_object_size(track->zb.robj)); | 2866 | radeon_bo_size(track->zb.robj)); |
2704 | DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n", | 2867 | DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n", |
2705 | track->zb.pitch, track->zb.cpp, | 2868 | track->zb.pitch, track->zb.cpp, |
2706 | track->zb.offset, track->maxy); | 2869 | track->zb.offset, track->maxy); |
@@ -2718,11 +2881,12 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
2718 | "bound\n", prim_walk, i); | 2881 | "bound\n", prim_walk, i); |
2719 | return -EINVAL; | 2882 | return -EINVAL; |
2720 | } | 2883 | } |
2721 | if (size > radeon_object_size(track->arrays[i].robj)) { | 2884 | if (size > radeon_bo_size(track->arrays[i].robj)) { |
2722 | DRM_ERROR("(PW %u) Vertex array %u need %lu dwords " | 2885 | dev_err(rdev->dev, "(PW %u) Vertex array %u " |
2723 | "have %lu dwords\n", prim_walk, i, | 2886 | "need %lu dwords have %lu dwords\n", |
2724 | size >> 2, | 2887 | prim_walk, i, size >> 2, |
2725 | radeon_object_size(track->arrays[i].robj) >> 2); | 2888 | radeon_bo_size(track->arrays[i].robj) |
2889 | >> 2); | ||
2726 | DRM_ERROR("Max indices %u\n", track->max_indx); | 2890 | DRM_ERROR("Max indices %u\n", track->max_indx); |
2727 | return -EINVAL; | 2891 | return -EINVAL; |
2728 | } | 2892 | } |
@@ -2736,10 +2900,12 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
2736 | "bound\n", prim_walk, i); | 2900 | "bound\n", prim_walk, i); |
2737 | return -EINVAL; | 2901 | return -EINVAL; |
2738 | } | 2902 | } |
2739 | if (size > radeon_object_size(track->arrays[i].robj)) { | 2903 | if (size > radeon_bo_size(track->arrays[i].robj)) { |
2740 | DRM_ERROR("(PW %u) Vertex array %u need %lu dwords " | 2904 | dev_err(rdev->dev, "(PW %u) Vertex array %u " |
2741 | "have %lu dwords\n", prim_walk, i, size >> 2, | 2905 | "need %lu dwords have %lu dwords\n", |
2742 | radeon_object_size(track->arrays[i].robj) >> 2); | 2906 | prim_walk, i, size >> 2, |
2907 | radeon_bo_size(track->arrays[i].robj) | ||
2908 | >> 2); | ||
2743 | return -EINVAL; | 2909 | return -EINVAL; |
2744 | } | 2910 | } |
2745 | } | 2911 | } |
@@ -3081,6 +3247,9 @@ static int r100_startup(struct radeon_device *rdev) | |||
3081 | { | 3247 | { |
3082 | int r; | 3248 | int r; |
3083 | 3249 | ||
3250 | /* set common regs */ | ||
3251 | r100_set_common_regs(rdev); | ||
3252 | /* program mc */ | ||
3084 | r100_mc_program(rdev); | 3253 | r100_mc_program(rdev); |
3085 | /* Resume clock */ | 3254 | /* Resume clock */ |
3086 | r100_clock_startup(rdev); | 3255 | r100_clock_startup(rdev); |
@@ -3088,13 +3257,13 @@ static int r100_startup(struct radeon_device *rdev) | |||
3088 | r100_gpu_init(rdev); | 3257 | r100_gpu_init(rdev); |
3089 | /* Initialize GART (initialize after TTM so we can allocate | 3258 | /* Initialize GART (initialize after TTM so we can allocate |
3090 | * memory through TTM but finalize after TTM) */ | 3259 | * memory through TTM but finalize after TTM) */ |
3260 | r100_enable_bm(rdev); | ||
3091 | if (rdev->flags & RADEON_IS_PCI) { | 3261 | if (rdev->flags & RADEON_IS_PCI) { |
3092 | r = r100_pci_gart_enable(rdev); | 3262 | r = r100_pci_gart_enable(rdev); |
3093 | if (r) | 3263 | if (r) |
3094 | return r; | 3264 | return r; |
3095 | } | 3265 | } |
3096 | /* Enable IRQ */ | 3266 | /* Enable IRQ */ |
3097 | rdev->irq.sw_int = true; | ||
3098 | r100_irq_set(rdev); | 3267 | r100_irq_set(rdev); |
3099 | /* 1M ring buffer */ | 3268 | /* 1M ring buffer */ |
3100 | r = r100_cp_init(rdev, 1024 * 1024); | 3269 | r = r100_cp_init(rdev, 1024 * 1024); |
@@ -3130,6 +3299,8 @@ int r100_resume(struct radeon_device *rdev) | |||
3130 | radeon_combios_asic_init(rdev->ddev); | 3299 | radeon_combios_asic_init(rdev->ddev); |
3131 | /* Resume clock after posting */ | 3300 | /* Resume clock after posting */ |
3132 | r100_clock_startup(rdev); | 3301 | r100_clock_startup(rdev); |
3302 | /* Initialize surface registers */ | ||
3303 | radeon_surface_init(rdev); | ||
3133 | return r100_startup(rdev); | 3304 | return r100_startup(rdev); |
3134 | } | 3305 | } |
3135 | 3306 | ||
@@ -3154,7 +3325,7 @@ void r100_fini(struct radeon_device *rdev) | |||
3154 | r100_pci_gart_fini(rdev); | 3325 | r100_pci_gart_fini(rdev); |
3155 | radeon_irq_kms_fini(rdev); | 3326 | radeon_irq_kms_fini(rdev); |
3156 | radeon_fence_driver_fini(rdev); | 3327 | radeon_fence_driver_fini(rdev); |
3157 | radeon_object_fini(rdev); | 3328 | radeon_bo_fini(rdev); |
3158 | radeon_atombios_fini(rdev); | 3329 | radeon_atombios_fini(rdev); |
3159 | kfree(rdev->bios); | 3330 | kfree(rdev->bios); |
3160 | rdev->bios = NULL; | 3331 | rdev->bios = NULL; |
@@ -3222,10 +3393,8 @@ int r100_init(struct radeon_device *rdev) | |||
3222 | RREG32(R_0007C0_CP_STAT)); | 3393 | RREG32(R_0007C0_CP_STAT)); |
3223 | } | 3394 | } |
3224 | /* check if cards are posted or not */ | 3395 | /* check if cards are posted or not */ |
3225 | if (!radeon_card_posted(rdev) && rdev->bios) { | 3396 | if (radeon_boot_test_post_card(rdev) == false) |
3226 | DRM_INFO("GPU not posted. posting now...\n"); | 3397 | return -EINVAL; |
3227 | radeon_combios_asic_init(rdev->ddev); | ||
3228 | } | ||
3229 | /* Set asic errata */ | 3398 | /* Set asic errata */ |
3230 | r100_errata(rdev); | 3399 | r100_errata(rdev); |
3231 | /* Initialize clocks */ | 3400 | /* Initialize clocks */ |
@@ -3244,7 +3413,7 @@ int r100_init(struct radeon_device *rdev) | |||
3244 | if (r) | 3413 | if (r) |
3245 | return r; | 3414 | return r; |
3246 | /* Memory manager */ | 3415 | /* Memory manager */ |
3247 | r = radeon_object_init(rdev); | 3416 | r = radeon_bo_init(rdev); |
3248 | if (r) | 3417 | if (r) |
3249 | return r; | 3418 | return r; |
3250 | if (rdev->flags & RADEON_IS_PCI) { | 3419 | if (rdev->flags & RADEON_IS_PCI) { |
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index 0daf0d76a891..ca50903dd2bb 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h | |||
@@ -10,26 +10,26 @@ | |||
10 | * CS functions | 10 | * CS functions |
11 | */ | 11 | */ |
12 | struct r100_cs_track_cb { | 12 | struct r100_cs_track_cb { |
13 | struct radeon_object *robj; | 13 | struct radeon_bo *robj; |
14 | unsigned pitch; | 14 | unsigned pitch; |
15 | unsigned cpp; | 15 | unsigned cpp; |
16 | unsigned offset; | 16 | unsigned offset; |
17 | }; | 17 | }; |
18 | 18 | ||
19 | struct r100_cs_track_array { | 19 | struct r100_cs_track_array { |
20 | struct radeon_object *robj; | 20 | struct radeon_bo *robj; |
21 | unsigned esize; | 21 | unsigned esize; |
22 | }; | 22 | }; |
23 | 23 | ||
24 | struct r100_cs_cube_info { | 24 | struct r100_cs_cube_info { |
25 | struct radeon_object *robj; | 25 | struct radeon_bo *robj; |
26 | unsigned offset; | 26 | unsigned offset; |
27 | unsigned width; | 27 | unsigned width; |
28 | unsigned height; | 28 | unsigned height; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | struct r100_cs_track_texture { | 31 | struct r100_cs_track_texture { |
32 | struct radeon_object *robj; | 32 | struct radeon_bo *robj; |
33 | struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */ | 33 | struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */ |
34 | unsigned pitch; | 34 | unsigned pitch; |
35 | unsigned width; | 35 | unsigned width; |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index e08c4a8974ca..83378c39d0e3 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -113,7 +113,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev) | |||
113 | tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; | 113 | tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; |
114 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); | 114 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); |
115 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_location); | 115 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_location); |
116 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 4096; | 116 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - RADEON_GPU_PAGE_SIZE; |
117 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp); | 117 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp); |
118 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0); | 118 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0); |
119 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0); | 119 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0); |
@@ -137,14 +137,19 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev) | |||
137 | 137 | ||
138 | void rv370_pcie_gart_disable(struct radeon_device *rdev) | 138 | void rv370_pcie_gart_disable(struct radeon_device *rdev) |
139 | { | 139 | { |
140 | uint32_t tmp; | 140 | u32 tmp; |
141 | int r; | ||
141 | 142 | ||
142 | tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); | 143 | tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); |
143 | tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; | 144 | tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; |
144 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); | 145 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); |
145 | if (rdev->gart.table.vram.robj) { | 146 | if (rdev->gart.table.vram.robj) { |
146 | radeon_object_kunmap(rdev->gart.table.vram.robj); | 147 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); |
147 | radeon_object_unpin(rdev->gart.table.vram.robj); | 148 | if (likely(r == 0)) { |
149 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
150 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
151 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
152 | } | ||
148 | } | 153 | } |
149 | } | 154 | } |
150 | 155 | ||
@@ -1181,6 +1186,9 @@ static int r300_startup(struct radeon_device *rdev) | |||
1181 | { | 1186 | { |
1182 | int r; | 1187 | int r; |
1183 | 1188 | ||
1189 | /* set common regs */ | ||
1190 | r100_set_common_regs(rdev); | ||
1191 | /* program mc */ | ||
1184 | r300_mc_program(rdev); | 1192 | r300_mc_program(rdev); |
1185 | /* Resume clock */ | 1193 | /* Resume clock */ |
1186 | r300_clock_startup(rdev); | 1194 | r300_clock_startup(rdev); |
@@ -1193,13 +1201,18 @@ static int r300_startup(struct radeon_device *rdev) | |||
1193 | if (r) | 1201 | if (r) |
1194 | return r; | 1202 | return r; |
1195 | } | 1203 | } |
1204 | |||
1205 | if (rdev->family == CHIP_R300 || | ||
1206 | rdev->family == CHIP_R350 || | ||
1207 | rdev->family == CHIP_RV350) | ||
1208 | r100_enable_bm(rdev); | ||
1209 | |||
1196 | if (rdev->flags & RADEON_IS_PCI) { | 1210 | if (rdev->flags & RADEON_IS_PCI) { |
1197 | r = r100_pci_gart_enable(rdev); | 1211 | r = r100_pci_gart_enable(rdev); |
1198 | if (r) | 1212 | if (r) |
1199 | return r; | 1213 | return r; |
1200 | } | 1214 | } |
1201 | /* Enable IRQ */ | 1215 | /* Enable IRQ */ |
1202 | rdev->irq.sw_int = true; | ||
1203 | r100_irq_set(rdev); | 1216 | r100_irq_set(rdev); |
1204 | /* 1M ring buffer */ | 1217 | /* 1M ring buffer */ |
1205 | r = r100_cp_init(rdev, 1024 * 1024); | 1218 | r = r100_cp_init(rdev, 1024 * 1024); |
@@ -1237,6 +1250,8 @@ int r300_resume(struct radeon_device *rdev) | |||
1237 | radeon_combios_asic_init(rdev->ddev); | 1250 | radeon_combios_asic_init(rdev->ddev); |
1238 | /* Resume clock after posting */ | 1251 | /* Resume clock after posting */ |
1239 | r300_clock_startup(rdev); | 1252 | r300_clock_startup(rdev); |
1253 | /* Initialize surface registers */ | ||
1254 | radeon_surface_init(rdev); | ||
1240 | return r300_startup(rdev); | 1255 | return r300_startup(rdev); |
1241 | } | 1256 | } |
1242 | 1257 | ||
@@ -1265,7 +1280,7 @@ void r300_fini(struct radeon_device *rdev) | |||
1265 | r100_pci_gart_fini(rdev); | 1280 | r100_pci_gart_fini(rdev); |
1266 | radeon_irq_kms_fini(rdev); | 1281 | radeon_irq_kms_fini(rdev); |
1267 | radeon_fence_driver_fini(rdev); | 1282 | radeon_fence_driver_fini(rdev); |
1268 | radeon_object_fini(rdev); | 1283 | radeon_bo_fini(rdev); |
1269 | radeon_atombios_fini(rdev); | 1284 | radeon_atombios_fini(rdev); |
1270 | kfree(rdev->bios); | 1285 | kfree(rdev->bios); |
1271 | rdev->bios = NULL; | 1286 | rdev->bios = NULL; |
@@ -1303,10 +1318,8 @@ int r300_init(struct radeon_device *rdev) | |||
1303 | RREG32(R_0007C0_CP_STAT)); | 1318 | RREG32(R_0007C0_CP_STAT)); |
1304 | } | 1319 | } |
1305 | /* check if cards are posted or not */ | 1320 | /* check if cards are posted or not */ |
1306 | if (!radeon_card_posted(rdev) && rdev->bios) { | 1321 | if (radeon_boot_test_post_card(rdev) == false) |
1307 | DRM_INFO("GPU not posted. posting now...\n"); | 1322 | return -EINVAL; |
1308 | radeon_combios_asic_init(rdev->ddev); | ||
1309 | } | ||
1310 | /* Set asic errata */ | 1323 | /* Set asic errata */ |
1311 | r300_errata(rdev); | 1324 | r300_errata(rdev); |
1312 | /* Initialize clocks */ | 1325 | /* Initialize clocks */ |
@@ -1325,7 +1338,7 @@ int r300_init(struct radeon_device *rdev) | |||
1325 | if (r) | 1338 | if (r) |
1326 | return r; | 1339 | return r; |
1327 | /* Memory manager */ | 1340 | /* Memory manager */ |
1328 | r = radeon_object_init(rdev); | 1341 | r = radeon_bo_init(rdev); |
1329 | if (r) | 1342 | if (r) |
1330 | return r; | 1343 | return r; |
1331 | if (rdev->flags & RADEON_IS_PCIE) { | 1344 | if (rdev->flags & RADEON_IS_PCIE) { |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 5c7fe52de30e..c05a7270cf0c 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -169,6 +169,9 @@ static int r420_startup(struct radeon_device *rdev) | |||
169 | { | 169 | { |
170 | int r; | 170 | int r; |
171 | 171 | ||
172 | /* set common regs */ | ||
173 | r100_set_common_regs(rdev); | ||
174 | /* program mc */ | ||
172 | r300_mc_program(rdev); | 175 | r300_mc_program(rdev); |
173 | /* Resume clock */ | 176 | /* Resume clock */ |
174 | r420_clock_resume(rdev); | 177 | r420_clock_resume(rdev); |
@@ -186,7 +189,6 @@ static int r420_startup(struct radeon_device *rdev) | |||
186 | } | 189 | } |
187 | r420_pipes_init(rdev); | 190 | r420_pipes_init(rdev); |
188 | /* Enable IRQ */ | 191 | /* Enable IRQ */ |
189 | rdev->irq.sw_int = true; | ||
190 | r100_irq_set(rdev); | 192 | r100_irq_set(rdev); |
191 | /* 1M ring buffer */ | 193 | /* 1M ring buffer */ |
192 | r = r100_cp_init(rdev, 1024 * 1024); | 194 | r = r100_cp_init(rdev, 1024 * 1024); |
@@ -229,7 +231,8 @@ int r420_resume(struct radeon_device *rdev) | |||
229 | } | 231 | } |
230 | /* Resume clock after posting */ | 232 | /* Resume clock after posting */ |
231 | r420_clock_resume(rdev); | 233 | r420_clock_resume(rdev); |
232 | 234 | /* Initialize surface registers */ | |
235 | radeon_surface_init(rdev); | ||
233 | return r420_startup(rdev); | 236 | return r420_startup(rdev); |
234 | } | 237 | } |
235 | 238 | ||
@@ -258,7 +261,7 @@ void r420_fini(struct radeon_device *rdev) | |||
258 | radeon_agp_fini(rdev); | 261 | radeon_agp_fini(rdev); |
259 | radeon_irq_kms_fini(rdev); | 262 | radeon_irq_kms_fini(rdev); |
260 | radeon_fence_driver_fini(rdev); | 263 | radeon_fence_driver_fini(rdev); |
261 | radeon_object_fini(rdev); | 264 | radeon_bo_fini(rdev); |
262 | if (rdev->is_atom_bios) { | 265 | if (rdev->is_atom_bios) { |
263 | radeon_atombios_fini(rdev); | 266 | radeon_atombios_fini(rdev); |
264 | } else { | 267 | } else { |
@@ -301,16 +304,13 @@ int r420_init(struct radeon_device *rdev) | |||
301 | RREG32(R_0007C0_CP_STAT)); | 304 | RREG32(R_0007C0_CP_STAT)); |
302 | } | 305 | } |
303 | /* check if cards are posted or not */ | 306 | /* check if cards are posted or not */ |
304 | if (!radeon_card_posted(rdev) && rdev->bios) { | 307 | if (radeon_boot_test_post_card(rdev) == false) |
305 | DRM_INFO("GPU not posted. posting now...\n"); | 308 | return -EINVAL; |
306 | if (rdev->is_atom_bios) { | 309 | |
307 | atom_asic_init(rdev->mode_info.atom_context); | ||
308 | } else { | ||
309 | radeon_combios_asic_init(rdev->ddev); | ||
310 | } | ||
311 | } | ||
312 | /* Initialize clocks */ | 310 | /* Initialize clocks */ |
313 | radeon_get_clock_info(rdev->ddev); | 311 | radeon_get_clock_info(rdev->ddev); |
312 | /* Initialize power management */ | ||
313 | radeon_pm_init(rdev); | ||
314 | /* Get vram informations */ | 314 | /* Get vram informations */ |
315 | r300_vram_info(rdev); | 315 | r300_vram_info(rdev); |
316 | /* Initialize memory controller (also test AGP) */ | 316 | /* Initialize memory controller (also test AGP) */ |
@@ -329,10 +329,13 @@ int r420_init(struct radeon_device *rdev) | |||
329 | return r; | 329 | return r; |
330 | } | 330 | } |
331 | /* Memory manager */ | 331 | /* Memory manager */ |
332 | r = radeon_object_init(rdev); | 332 | r = radeon_bo_init(rdev); |
333 | if (r) { | 333 | if (r) { |
334 | return r; | 334 | return r; |
335 | } | 335 | } |
336 | if (rdev->family == CHIP_R420) | ||
337 | r100_enable_bm(rdev); | ||
338 | |||
336 | if (rdev->flags & RADEON_IS_PCIE) { | 339 | if (rdev->flags & RADEON_IS_PCIE) { |
337 | r = rv370_pcie_gart_init(rdev); | 340 | r = rv370_pcie_gart_init(rdev); |
338 | if (r) | 341 | if (r) |
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index 868add6e166d..74ad89bdf2b5 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h | |||
@@ -384,9 +384,16 @@ | |||
384 | # define AVIVO_D1GRPH_TILED (1 << 20) | 384 | # define AVIVO_D1GRPH_TILED (1 << 20) |
385 | # define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21) | 385 | # define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21) |
386 | 386 | ||
387 | /* The R7xx *_HIGH surface regs are backwards; the D1 regs are in the D2 | ||
388 | * block and vice versa. This applies to GRPH, CUR, etc. | ||
389 | */ | ||
387 | #define AVIVO_D1GRPH_LUT_SEL 0x6108 | 390 | #define AVIVO_D1GRPH_LUT_SEL 0x6108 |
388 | #define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 | 391 | #define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 |
392 | #define R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914 | ||
393 | #define R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114 | ||
389 | #define AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 | 394 | #define AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 |
395 | #define R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x691c | ||
396 | #define R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x611c | ||
390 | #define AVIVO_D1GRPH_PITCH 0x6120 | 397 | #define AVIVO_D1GRPH_PITCH 0x6120 |
391 | #define AVIVO_D1GRPH_SURFACE_OFFSET_X 0x6124 | 398 | #define AVIVO_D1GRPH_SURFACE_OFFSET_X 0x6124 |
392 | #define AVIVO_D1GRPH_SURFACE_OFFSET_Y 0x6128 | 399 | #define AVIVO_D1GRPH_SURFACE_OFFSET_Y 0x6128 |
@@ -404,6 +411,8 @@ | |||
404 | # define AVIVO_D1CURSOR_MODE_MASK (3 << 8) | 411 | # define AVIVO_D1CURSOR_MODE_MASK (3 << 8) |
405 | # define AVIVO_D1CURSOR_MODE_24BPP 2 | 412 | # define AVIVO_D1CURSOR_MODE_24BPP 2 |
406 | #define AVIVO_D1CUR_SURFACE_ADDRESS 0x6408 | 413 | #define AVIVO_D1CUR_SURFACE_ADDRESS 0x6408 |
414 | #define R700_D1CUR_SURFACE_ADDRESS_HIGH 0x6c0c | ||
415 | #define R700_D2CUR_SURFACE_ADDRESS_HIGH 0x640c | ||
407 | #define AVIVO_D1CUR_SIZE 0x6410 | 416 | #define AVIVO_D1CUR_SIZE 0x6410 |
408 | #define AVIVO_D1CUR_POSITION 0x6414 | 417 | #define AVIVO_D1CUR_POSITION 0x6414 |
409 | #define AVIVO_D1CUR_HOT_SPOT 0x6418 | 418 | #define AVIVO_D1CUR_HOT_SPOT 0x6418 |
@@ -707,6 +716,8 @@ | |||
707 | 716 | ||
708 | #define AVIVO_DVOA_BIT_DEPTH_CONTROL 0x7988 | 717 | #define AVIVO_DVOA_BIT_DEPTH_CONTROL 0x7988 |
709 | 718 | ||
719 | #define AVIVO_DC_GPIO_HPD_A 0x7e94 | ||
720 | |||
710 | #define AVIVO_GPIO_0 0x7e30 | 721 | #define AVIVO_GPIO_0 0x7e30 |
711 | #define AVIVO_GPIO_1 0x7e40 | 722 | #define AVIVO_GPIO_1 0x7e40 |
712 | #define AVIVO_GPIO_2 0x7e50 | 723 | #define AVIVO_GPIO_2 0x7e50 |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index a555b7b19b48..0f3843b6dac7 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -185,7 +185,6 @@ static int r520_startup(struct radeon_device *rdev) | |||
185 | return r; | 185 | return r; |
186 | } | 186 | } |
187 | /* Enable IRQ */ | 187 | /* Enable IRQ */ |
188 | rdev->irq.sw_int = true; | ||
189 | rs600_irq_set(rdev); | 188 | rs600_irq_set(rdev); |
190 | /* 1M ring buffer */ | 189 | /* 1M ring buffer */ |
191 | r = r100_cp_init(rdev, 1024 * 1024); | 190 | r = r100_cp_init(rdev, 1024 * 1024); |
@@ -221,6 +220,8 @@ int r520_resume(struct radeon_device *rdev) | |||
221 | atom_asic_init(rdev->mode_info.atom_context); | 220 | atom_asic_init(rdev->mode_info.atom_context); |
222 | /* Resume clock after posting */ | 221 | /* Resume clock after posting */ |
223 | rv515_clock_startup(rdev); | 222 | rv515_clock_startup(rdev); |
223 | /* Initialize surface registers */ | ||
224 | radeon_surface_init(rdev); | ||
224 | return r520_startup(rdev); | 225 | return r520_startup(rdev); |
225 | } | 226 | } |
226 | 227 | ||
@@ -254,12 +255,17 @@ int r520_init(struct radeon_device *rdev) | |||
254 | RREG32(R_0007C0_CP_STAT)); | 255 | RREG32(R_0007C0_CP_STAT)); |
255 | } | 256 | } |
256 | /* check if cards are posted or not */ | 257 | /* check if cards are posted or not */ |
258 | if (radeon_boot_test_post_card(rdev) == false) | ||
259 | return -EINVAL; | ||
260 | |||
257 | if (!radeon_card_posted(rdev) && rdev->bios) { | 261 | if (!radeon_card_posted(rdev) && rdev->bios) { |
258 | DRM_INFO("GPU not posted. posting now...\n"); | 262 | DRM_INFO("GPU not posted. posting now...\n"); |
259 | atom_asic_init(rdev->mode_info.atom_context); | 263 | atom_asic_init(rdev->mode_info.atom_context); |
260 | } | 264 | } |
261 | /* Initialize clocks */ | 265 | /* Initialize clocks */ |
262 | radeon_get_clock_info(rdev->ddev); | 266 | radeon_get_clock_info(rdev->ddev); |
267 | /* Initialize power management */ | ||
268 | radeon_pm_init(rdev); | ||
263 | /* Get vram informations */ | 269 | /* Get vram informations */ |
264 | r520_vram_info(rdev); | 270 | r520_vram_info(rdev); |
265 | /* Initialize memory controller (also test AGP) */ | 271 | /* Initialize memory controller (also test AGP) */ |
@@ -275,7 +281,7 @@ int r520_init(struct radeon_device *rdev) | |||
275 | if (r) | 281 | if (r) |
276 | return r; | 282 | return r; |
277 | /* Memory manager */ | 283 | /* Memory manager */ |
278 | r = radeon_object_init(rdev); | 284 | r = radeon_bo_init(rdev); |
279 | if (r) | 285 | if (r) |
280 | return r; | 286 | return r; |
281 | r = rv370_pcie_gart_init(rdev); | 287 | r = rv370_pcie_gart_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 609719490ec2..36656bd110bf 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -38,8 +38,10 @@ | |||
38 | 38 | ||
39 | #define PFP_UCODE_SIZE 576 | 39 | #define PFP_UCODE_SIZE 576 |
40 | #define PM4_UCODE_SIZE 1792 | 40 | #define PM4_UCODE_SIZE 1792 |
41 | #define RLC_UCODE_SIZE 768 | ||
41 | #define R700_PFP_UCODE_SIZE 848 | 42 | #define R700_PFP_UCODE_SIZE 848 |
42 | #define R700_PM4_UCODE_SIZE 1360 | 43 | #define R700_PM4_UCODE_SIZE 1360 |
44 | #define R700_RLC_UCODE_SIZE 1024 | ||
43 | 45 | ||
44 | /* Firmware Names */ | 46 | /* Firmware Names */ |
45 | MODULE_FIRMWARE("radeon/R600_pfp.bin"); | 47 | MODULE_FIRMWARE("radeon/R600_pfp.bin"); |
@@ -62,6 +64,8 @@ MODULE_FIRMWARE("radeon/RV730_pfp.bin"); | |||
62 | MODULE_FIRMWARE("radeon/RV730_me.bin"); | 64 | MODULE_FIRMWARE("radeon/RV730_me.bin"); |
63 | MODULE_FIRMWARE("radeon/RV710_pfp.bin"); | 65 | MODULE_FIRMWARE("radeon/RV710_pfp.bin"); |
64 | MODULE_FIRMWARE("radeon/RV710_me.bin"); | 66 | MODULE_FIRMWARE("radeon/RV710_me.bin"); |
67 | MODULE_FIRMWARE("radeon/R600_rlc.bin"); | ||
68 | MODULE_FIRMWARE("radeon/R700_rlc.bin"); | ||
65 | 69 | ||
66 | int r600_debugfs_mc_info_init(struct radeon_device *rdev); | 70 | int r600_debugfs_mc_info_init(struct radeon_device *rdev); |
67 | 71 | ||
@@ -70,6 +74,281 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev); | |||
70 | void r600_gpu_init(struct radeon_device *rdev); | 74 | void r600_gpu_init(struct radeon_device *rdev); |
71 | void r600_fini(struct radeon_device *rdev); | 75 | void r600_fini(struct radeon_device *rdev); |
72 | 76 | ||
77 | /* hpd for digital panel detect/disconnect */ | ||
78 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | ||
79 | { | ||
80 | bool connected = false; | ||
81 | |||
82 | if (ASIC_IS_DCE3(rdev)) { | ||
83 | switch (hpd) { | ||
84 | case RADEON_HPD_1: | ||
85 | if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE) | ||
86 | connected = true; | ||
87 | break; | ||
88 | case RADEON_HPD_2: | ||
89 | if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE) | ||
90 | connected = true; | ||
91 | break; | ||
92 | case RADEON_HPD_3: | ||
93 | if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE) | ||
94 | connected = true; | ||
95 | break; | ||
96 | case RADEON_HPD_4: | ||
97 | if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE) | ||
98 | connected = true; | ||
99 | break; | ||
100 | /* DCE 3.2 */ | ||
101 | case RADEON_HPD_5: | ||
102 | if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE) | ||
103 | connected = true; | ||
104 | break; | ||
105 | case RADEON_HPD_6: | ||
106 | if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE) | ||
107 | connected = true; | ||
108 | break; | ||
109 | default: | ||
110 | break; | ||
111 | } | ||
112 | } else { | ||
113 | switch (hpd) { | ||
114 | case RADEON_HPD_1: | ||
115 | if (RREG32(DC_HOT_PLUG_DETECT1_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) | ||
116 | connected = true; | ||
117 | break; | ||
118 | case RADEON_HPD_2: | ||
119 | if (RREG32(DC_HOT_PLUG_DETECT2_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) | ||
120 | connected = true; | ||
121 | break; | ||
122 | case RADEON_HPD_3: | ||
123 | if (RREG32(DC_HOT_PLUG_DETECT3_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) | ||
124 | connected = true; | ||
125 | break; | ||
126 | default: | ||
127 | break; | ||
128 | } | ||
129 | } | ||
130 | return connected; | ||
131 | } | ||
132 | |||
133 | void r600_hpd_set_polarity(struct radeon_device *rdev, | ||
134 | enum radeon_hpd_id hpd) | ||
135 | { | ||
136 | u32 tmp; | ||
137 | bool connected = r600_hpd_sense(rdev, hpd); | ||
138 | |||
139 | if (ASIC_IS_DCE3(rdev)) { | ||
140 | switch (hpd) { | ||
141 | case RADEON_HPD_1: | ||
142 | tmp = RREG32(DC_HPD1_INT_CONTROL); | ||
143 | if (connected) | ||
144 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
145 | else | ||
146 | tmp |= DC_HPDx_INT_POLARITY; | ||
147 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
148 | break; | ||
149 | case RADEON_HPD_2: | ||
150 | tmp = RREG32(DC_HPD2_INT_CONTROL); | ||
151 | if (connected) | ||
152 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
153 | else | ||
154 | tmp |= DC_HPDx_INT_POLARITY; | ||
155 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
156 | break; | ||
157 | case RADEON_HPD_3: | ||
158 | tmp = RREG32(DC_HPD3_INT_CONTROL); | ||
159 | if (connected) | ||
160 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
161 | else | ||
162 | tmp |= DC_HPDx_INT_POLARITY; | ||
163 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
164 | break; | ||
165 | case RADEON_HPD_4: | ||
166 | tmp = RREG32(DC_HPD4_INT_CONTROL); | ||
167 | if (connected) | ||
168 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
169 | else | ||
170 | tmp |= DC_HPDx_INT_POLARITY; | ||
171 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
172 | break; | ||
173 | case RADEON_HPD_5: | ||
174 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
175 | if (connected) | ||
176 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
177 | else | ||
178 | tmp |= DC_HPDx_INT_POLARITY; | ||
179 | WREG32(DC_HPD5_INT_CONTROL, tmp); | ||
180 | break; | ||
181 | /* DCE 3.2 */ | ||
182 | case RADEON_HPD_6: | ||
183 | tmp = RREG32(DC_HPD6_INT_CONTROL); | ||
184 | if (connected) | ||
185 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
186 | else | ||
187 | tmp |= DC_HPDx_INT_POLARITY; | ||
188 | WREG32(DC_HPD6_INT_CONTROL, tmp); | ||
189 | break; | ||
190 | default: | ||
191 | break; | ||
192 | } | ||
193 | } else { | ||
194 | switch (hpd) { | ||
195 | case RADEON_HPD_1: | ||
196 | tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
197 | if (connected) | ||
198 | tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
199 | else | ||
200 | tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
201 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
202 | break; | ||
203 | case RADEON_HPD_2: | ||
204 | tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
205 | if (connected) | ||
206 | tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
207 | else | ||
208 | tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
209 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
210 | break; | ||
211 | case RADEON_HPD_3: | ||
212 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL); | ||
213 | if (connected) | ||
214 | tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
215 | else | ||
216 | tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
217 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | ||
218 | break; | ||
219 | default: | ||
220 | break; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
225 | void r600_hpd_init(struct radeon_device *rdev) | ||
226 | { | ||
227 | struct drm_device *dev = rdev->ddev; | ||
228 | struct drm_connector *connector; | ||
229 | |||
230 | if (ASIC_IS_DCE3(rdev)) { | ||
231 | u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); | ||
232 | if (ASIC_IS_DCE32(rdev)) | ||
233 | tmp |= DC_HPDx_EN; | ||
234 | |||
235 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
236 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
237 | switch (radeon_connector->hpd.hpd) { | ||
238 | case RADEON_HPD_1: | ||
239 | WREG32(DC_HPD1_CONTROL, tmp); | ||
240 | rdev->irq.hpd[0] = true; | ||
241 | break; | ||
242 | case RADEON_HPD_2: | ||
243 | WREG32(DC_HPD2_CONTROL, tmp); | ||
244 | rdev->irq.hpd[1] = true; | ||
245 | break; | ||
246 | case RADEON_HPD_3: | ||
247 | WREG32(DC_HPD3_CONTROL, tmp); | ||
248 | rdev->irq.hpd[2] = true; | ||
249 | break; | ||
250 | case RADEON_HPD_4: | ||
251 | WREG32(DC_HPD4_CONTROL, tmp); | ||
252 | rdev->irq.hpd[3] = true; | ||
253 | break; | ||
254 | /* DCE 3.2 */ | ||
255 | case RADEON_HPD_5: | ||
256 | WREG32(DC_HPD5_CONTROL, tmp); | ||
257 | rdev->irq.hpd[4] = true; | ||
258 | break; | ||
259 | case RADEON_HPD_6: | ||
260 | WREG32(DC_HPD6_CONTROL, tmp); | ||
261 | rdev->irq.hpd[5] = true; | ||
262 | break; | ||
263 | default: | ||
264 | break; | ||
265 | } | ||
266 | } | ||
267 | } else { | ||
268 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
269 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
270 | switch (radeon_connector->hpd.hpd) { | ||
271 | case RADEON_HPD_1: | ||
272 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); | ||
273 | rdev->irq.hpd[0] = true; | ||
274 | break; | ||
275 | case RADEON_HPD_2: | ||
276 | WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN); | ||
277 | rdev->irq.hpd[1] = true; | ||
278 | break; | ||
279 | case RADEON_HPD_3: | ||
280 | WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN); | ||
281 | rdev->irq.hpd[2] = true; | ||
282 | break; | ||
283 | default: | ||
284 | break; | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | r600_irq_set(rdev); | ||
289 | } | ||
290 | |||
291 | void r600_hpd_fini(struct radeon_device *rdev) | ||
292 | { | ||
293 | struct drm_device *dev = rdev->ddev; | ||
294 | struct drm_connector *connector; | ||
295 | |||
296 | if (ASIC_IS_DCE3(rdev)) { | ||
297 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
298 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
299 | switch (radeon_connector->hpd.hpd) { | ||
300 | case RADEON_HPD_1: | ||
301 | WREG32(DC_HPD1_CONTROL, 0); | ||
302 | rdev->irq.hpd[0] = false; | ||
303 | break; | ||
304 | case RADEON_HPD_2: | ||
305 | WREG32(DC_HPD2_CONTROL, 0); | ||
306 | rdev->irq.hpd[1] = false; | ||
307 | break; | ||
308 | case RADEON_HPD_3: | ||
309 | WREG32(DC_HPD3_CONTROL, 0); | ||
310 | rdev->irq.hpd[2] = false; | ||
311 | break; | ||
312 | case RADEON_HPD_4: | ||
313 | WREG32(DC_HPD4_CONTROL, 0); | ||
314 | rdev->irq.hpd[3] = false; | ||
315 | break; | ||
316 | /* DCE 3.2 */ | ||
317 | case RADEON_HPD_5: | ||
318 | WREG32(DC_HPD5_CONTROL, 0); | ||
319 | rdev->irq.hpd[4] = false; | ||
320 | break; | ||
321 | case RADEON_HPD_6: | ||
322 | WREG32(DC_HPD6_CONTROL, 0); | ||
323 | rdev->irq.hpd[5] = false; | ||
324 | break; | ||
325 | default: | ||
326 | break; | ||
327 | } | ||
328 | } | ||
329 | } else { | ||
330 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
331 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
332 | switch (radeon_connector->hpd.hpd) { | ||
333 | case RADEON_HPD_1: | ||
334 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0); | ||
335 | rdev->irq.hpd[0] = false; | ||
336 | break; | ||
337 | case RADEON_HPD_2: | ||
338 | WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0); | ||
339 | rdev->irq.hpd[1] = false; | ||
340 | break; | ||
341 | case RADEON_HPD_3: | ||
342 | WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0); | ||
343 | rdev->irq.hpd[2] = false; | ||
344 | break; | ||
345 | default: | ||
346 | break; | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | } | ||
351 | |||
73 | /* | 352 | /* |
74 | * R600 PCIE GART | 353 | * R600 PCIE GART |
75 | */ | 354 | */ |
@@ -180,7 +459,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev) | |||
180 | void r600_pcie_gart_disable(struct radeon_device *rdev) | 459 | void r600_pcie_gart_disable(struct radeon_device *rdev) |
181 | { | 460 | { |
182 | u32 tmp; | 461 | u32 tmp; |
183 | int i; | 462 | int i, r; |
184 | 463 | ||
185 | /* Disable all tables */ | 464 | /* Disable all tables */ |
186 | for (i = 0; i < 7; i++) | 465 | for (i = 0; i < 7; i++) |
@@ -208,8 +487,12 @@ void r600_pcie_gart_disable(struct radeon_device *rdev) | |||
208 | WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); | 487 | WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); |
209 | WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); | 488 | WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); |
210 | if (rdev->gart.table.vram.robj) { | 489 | if (rdev->gart.table.vram.robj) { |
211 | radeon_object_kunmap(rdev->gart.table.vram.robj); | 490 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); |
212 | radeon_object_unpin(rdev->gart.table.vram.robj); | 491 | if (likely(r == 0)) { |
492 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
493 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
494 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
495 | } | ||
213 | } | 496 | } |
214 | } | 497 | } |
215 | 498 | ||
@@ -339,11 +622,10 @@ int r600_mc_init(struct radeon_device *rdev) | |||
339 | { | 622 | { |
340 | fixed20_12 a; | 623 | fixed20_12 a; |
341 | u32 tmp; | 624 | u32 tmp; |
342 | int chansize; | 625 | int chansize, numchan; |
343 | int r; | 626 | int r; |
344 | 627 | ||
345 | /* Get VRAM informations */ | 628 | /* Get VRAM informations */ |
346 | rdev->mc.vram_width = 128; | ||
347 | rdev->mc.vram_is_ddr = true; | 629 | rdev->mc.vram_is_ddr = true; |
348 | tmp = RREG32(RAMCFG); | 630 | tmp = RREG32(RAMCFG); |
349 | if (tmp & CHANSIZE_OVERRIDE) { | 631 | if (tmp & CHANSIZE_OVERRIDE) { |
@@ -353,17 +635,23 @@ int r600_mc_init(struct radeon_device *rdev) | |||
353 | } else { | 635 | } else { |
354 | chansize = 32; | 636 | chansize = 32; |
355 | } | 637 | } |
356 | if (rdev->family == CHIP_R600) { | 638 | tmp = RREG32(CHMAP); |
357 | rdev->mc.vram_width = 8 * chansize; | 639 | switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { |
358 | } else if (rdev->family == CHIP_RV670) { | 640 | case 0: |
359 | rdev->mc.vram_width = 4 * chansize; | 641 | default: |
360 | } else if ((rdev->family == CHIP_RV610) || | 642 | numchan = 1; |
361 | (rdev->family == CHIP_RV620)) { | 643 | break; |
362 | rdev->mc.vram_width = chansize; | 644 | case 1: |
363 | } else if ((rdev->family == CHIP_RV630) || | 645 | numchan = 2; |
364 | (rdev->family == CHIP_RV635)) { | 646 | break; |
365 | rdev->mc.vram_width = 2 * chansize; | 647 | case 2: |
648 | numchan = 4; | ||
649 | break; | ||
650 | case 3: | ||
651 | numchan = 8; | ||
652 | break; | ||
366 | } | 653 | } |
654 | rdev->mc.vram_width = numchan * chansize; | ||
367 | /* Could aper size report 0 ? */ | 655 | /* Could aper size report 0 ? */ |
368 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 656 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); |
369 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 657 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); |
@@ -389,11 +677,11 @@ int r600_mc_init(struct radeon_device *rdev) | |||
389 | * AGP so that GPU can catch out of VRAM/AGP access | 677 | * AGP so that GPU can catch out of VRAM/AGP access |
390 | */ | 678 | */ |
391 | if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { | 679 | if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { |
392 | /* Enought place before */ | 680 | /* Enough place before */ |
393 | rdev->mc.vram_location = rdev->mc.gtt_location - | 681 | rdev->mc.vram_location = rdev->mc.gtt_location - |
394 | rdev->mc.mc_vram_size; | 682 | rdev->mc.mc_vram_size; |
395 | } else if (tmp > rdev->mc.mc_vram_size) { | 683 | } else if (tmp > rdev->mc.mc_vram_size) { |
396 | /* Enought place after */ | 684 | /* Enough place after */ |
397 | rdev->mc.vram_location = rdev->mc.gtt_location + | 685 | rdev->mc.vram_location = rdev->mc.gtt_location + |
398 | rdev->mc.gtt_size; | 686 | rdev->mc.gtt_size; |
399 | } else { | 687 | } else { |
@@ -404,35 +692,29 @@ int r600_mc_init(struct radeon_device *rdev) | |||
404 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | 692 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; |
405 | } | 693 | } |
406 | } else { | 694 | } else { |
407 | if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) { | 695 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
408 | rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) & | 696 | rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) & |
409 | 0xFFFF) << 24; | 697 | 0xFFFF) << 24; |
410 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | 698 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size; |
411 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size; | 699 | if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) { |
412 | if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) { | 700 | /* Enough place after vram */ |
413 | /* Enough place after vram */ | 701 | rdev->mc.gtt_location = tmp; |
414 | rdev->mc.gtt_location = tmp; | 702 | } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) { |
415 | } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) { | 703 | /* Enough place before vram */ |
416 | /* Enough place before vram */ | 704 | rdev->mc.gtt_location = 0; |
705 | } else { | ||
706 | /* Not enough place after or before shrink | ||
707 | * gart size | ||
708 | */ | ||
709 | if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) { | ||
417 | rdev->mc.gtt_location = 0; | 710 | rdev->mc.gtt_location = 0; |
711 | rdev->mc.gtt_size = rdev->mc.vram_location; | ||
418 | } else { | 712 | } else { |
419 | /* Not enough place after or before shrink | 713 | rdev->mc.gtt_location = tmp; |
420 | * gart size | 714 | rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp; |
421 | */ | ||
422 | if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) { | ||
423 | rdev->mc.gtt_location = 0; | ||
424 | rdev->mc.gtt_size = rdev->mc.vram_location; | ||
425 | } else { | ||
426 | rdev->mc.gtt_location = tmp; | ||
427 | rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp; | ||
428 | } | ||
429 | } | 715 | } |
430 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
431 | } else { | ||
432 | rdev->mc.vram_location = 0x00000000UL; | ||
433 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
434 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
435 | } | 716 | } |
717 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
436 | } | 718 | } |
437 | rdev->mc.vram_start = rdev->mc.vram_location; | 719 | rdev->mc.vram_start = rdev->mc.vram_location; |
438 | rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; | 720 | rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; |
@@ -859,7 +1141,8 @@ void r600_gpu_init(struct radeon_device *rdev) | |||
859 | ((rdev->family) == CHIP_RV630) || | 1141 | ((rdev->family) == CHIP_RV630) || |
860 | ((rdev->family) == CHIP_RV610) || | 1142 | ((rdev->family) == CHIP_RV610) || |
861 | ((rdev->family) == CHIP_RV620) || | 1143 | ((rdev->family) == CHIP_RV620) || |
862 | ((rdev->family) == CHIP_RS780)) { | 1144 | ((rdev->family) == CHIP_RS780) || |
1145 | ((rdev->family) == CHIP_RS880)) { | ||
863 | WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE); | 1146 | WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE); |
864 | } else { | 1147 | } else { |
865 | WREG32(DB_DEBUG, 0); | 1148 | WREG32(DB_DEBUG, 0); |
@@ -876,7 +1159,8 @@ void r600_gpu_init(struct radeon_device *rdev) | |||
876 | tmp = RREG32(SQ_MS_FIFO_SIZES); | 1159 | tmp = RREG32(SQ_MS_FIFO_SIZES); |
877 | if (((rdev->family) == CHIP_RV610) || | 1160 | if (((rdev->family) == CHIP_RV610) || |
878 | ((rdev->family) == CHIP_RV620) || | 1161 | ((rdev->family) == CHIP_RV620) || |
879 | ((rdev->family) == CHIP_RS780)) { | 1162 | ((rdev->family) == CHIP_RS780) || |
1163 | ((rdev->family) == CHIP_RS880)) { | ||
880 | tmp = (CACHE_FIFO_SIZE(0xa) | | 1164 | tmp = (CACHE_FIFO_SIZE(0xa) | |
881 | FETCH_FIFO_HIWATER(0xa) | | 1165 | FETCH_FIFO_HIWATER(0xa) | |
882 | DONE_FIFO_HIWATER(0xe0) | | 1166 | DONE_FIFO_HIWATER(0xe0) | |
@@ -919,7 +1203,8 @@ void r600_gpu_init(struct radeon_device *rdev) | |||
919 | NUM_ES_STACK_ENTRIES(0)); | 1203 | NUM_ES_STACK_ENTRIES(0)); |
920 | } else if (((rdev->family) == CHIP_RV610) || | 1204 | } else if (((rdev->family) == CHIP_RV610) || |
921 | ((rdev->family) == CHIP_RV620) || | 1205 | ((rdev->family) == CHIP_RV620) || |
922 | ((rdev->family) == CHIP_RS780)) { | 1206 | ((rdev->family) == CHIP_RS780) || |
1207 | ((rdev->family) == CHIP_RS880)) { | ||
923 | /* no vertex cache */ | 1208 | /* no vertex cache */ |
924 | sq_config &= ~VC_ENABLE; | 1209 | sq_config &= ~VC_ENABLE; |
925 | 1210 | ||
@@ -976,7 +1261,8 @@ void r600_gpu_init(struct radeon_device *rdev) | |||
976 | 1261 | ||
977 | if (((rdev->family) == CHIP_RV610) || | 1262 | if (((rdev->family) == CHIP_RV610) || |
978 | ((rdev->family) == CHIP_RV620) || | 1263 | ((rdev->family) == CHIP_RV620) || |
979 | ((rdev->family) == CHIP_RS780)) { | 1264 | ((rdev->family) == CHIP_RS780) || |
1265 | ((rdev->family) == CHIP_RS880)) { | ||
980 | WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY)); | 1266 | WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY)); |
981 | } else { | 1267 | } else { |
982 | WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC)); | 1268 | WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC)); |
@@ -1002,8 +1288,9 @@ void r600_gpu_init(struct radeon_device *rdev) | |||
1002 | tmp = rdev->config.r600.max_pipes * 16; | 1288 | tmp = rdev->config.r600.max_pipes * 16; |
1003 | switch (rdev->family) { | 1289 | switch (rdev->family) { |
1004 | case CHIP_RV610: | 1290 | case CHIP_RV610: |
1005 | case CHIP_RS780: | ||
1006 | case CHIP_RV620: | 1291 | case CHIP_RV620: |
1292 | case CHIP_RS780: | ||
1293 | case CHIP_RS880: | ||
1007 | tmp += 32; | 1294 | tmp += 32; |
1008 | break; | 1295 | break; |
1009 | case CHIP_RV670: | 1296 | case CHIP_RV670: |
@@ -1044,8 +1331,9 @@ void r600_gpu_init(struct radeon_device *rdev) | |||
1044 | 1331 | ||
1045 | switch (rdev->family) { | 1332 | switch (rdev->family) { |
1046 | case CHIP_RV610: | 1333 | case CHIP_RV610: |
1047 | case CHIP_RS780: | ||
1048 | case CHIP_RV620: | 1334 | case CHIP_RV620: |
1335 | case CHIP_RS780: | ||
1336 | case CHIP_RS880: | ||
1049 | tmp = TC_L2_SIZE(8); | 1337 | tmp = TC_L2_SIZE(8); |
1050 | break; | 1338 | break; |
1051 | case CHIP_RV630: | 1339 | case CHIP_RV630: |
@@ -1096,6 +1384,10 @@ void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) | |||
1096 | (void)RREG32(PCIE_PORT_DATA); | 1384 | (void)RREG32(PCIE_PORT_DATA); |
1097 | } | 1385 | } |
1098 | 1386 | ||
1387 | void r600_hdp_flush(struct radeon_device *rdev) | ||
1388 | { | ||
1389 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
1390 | } | ||
1099 | 1391 | ||
1100 | /* | 1392 | /* |
1101 | * CP & Ring | 1393 | * CP & Ring |
@@ -1105,11 +1397,12 @@ void r600_cp_stop(struct radeon_device *rdev) | |||
1105 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); | 1397 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); |
1106 | } | 1398 | } |
1107 | 1399 | ||
1108 | int r600_cp_init_microcode(struct radeon_device *rdev) | 1400 | int r600_init_microcode(struct radeon_device *rdev) |
1109 | { | 1401 | { |
1110 | struct platform_device *pdev; | 1402 | struct platform_device *pdev; |
1111 | const char *chip_name; | 1403 | const char *chip_name; |
1112 | size_t pfp_req_size, me_req_size; | 1404 | const char *rlc_chip_name; |
1405 | size_t pfp_req_size, me_req_size, rlc_req_size; | ||
1113 | char fw_name[30]; | 1406 | char fw_name[30]; |
1114 | int err; | 1407 | int err; |
1115 | 1408 | ||
@@ -1123,30 +1416,62 @@ int r600_cp_init_microcode(struct radeon_device *rdev) | |||
1123 | } | 1416 | } |
1124 | 1417 | ||
1125 | switch (rdev->family) { | 1418 | switch (rdev->family) { |
1126 | case CHIP_R600: chip_name = "R600"; break; | 1419 | case CHIP_R600: |
1127 | case CHIP_RV610: chip_name = "RV610"; break; | 1420 | chip_name = "R600"; |
1128 | case CHIP_RV630: chip_name = "RV630"; break; | 1421 | rlc_chip_name = "R600"; |
1129 | case CHIP_RV620: chip_name = "RV620"; break; | 1422 | break; |
1130 | case CHIP_RV635: chip_name = "RV635"; break; | 1423 | case CHIP_RV610: |
1131 | case CHIP_RV670: chip_name = "RV670"; break; | 1424 | chip_name = "RV610"; |
1425 | rlc_chip_name = "R600"; | ||
1426 | break; | ||
1427 | case CHIP_RV630: | ||
1428 | chip_name = "RV630"; | ||
1429 | rlc_chip_name = "R600"; | ||
1430 | break; | ||
1431 | case CHIP_RV620: | ||
1432 | chip_name = "RV620"; | ||
1433 | rlc_chip_name = "R600"; | ||
1434 | break; | ||
1435 | case CHIP_RV635: | ||
1436 | chip_name = "RV635"; | ||
1437 | rlc_chip_name = "R600"; | ||
1438 | break; | ||
1439 | case CHIP_RV670: | ||
1440 | chip_name = "RV670"; | ||
1441 | rlc_chip_name = "R600"; | ||
1442 | break; | ||
1132 | case CHIP_RS780: | 1443 | case CHIP_RS780: |
1133 | case CHIP_RS880: chip_name = "RS780"; break; | 1444 | case CHIP_RS880: |
1134 | case CHIP_RV770: chip_name = "RV770"; break; | 1445 | chip_name = "RS780"; |
1446 | rlc_chip_name = "R600"; | ||
1447 | break; | ||
1448 | case CHIP_RV770: | ||
1449 | chip_name = "RV770"; | ||
1450 | rlc_chip_name = "R700"; | ||
1451 | break; | ||
1135 | case CHIP_RV730: | 1452 | case CHIP_RV730: |
1136 | case CHIP_RV740: chip_name = "RV730"; break; | 1453 | case CHIP_RV740: |
1137 | case CHIP_RV710: chip_name = "RV710"; break; | 1454 | chip_name = "RV730"; |
1455 | rlc_chip_name = "R700"; | ||
1456 | break; | ||
1457 | case CHIP_RV710: | ||
1458 | chip_name = "RV710"; | ||
1459 | rlc_chip_name = "R700"; | ||
1460 | break; | ||
1138 | default: BUG(); | 1461 | default: BUG(); |
1139 | } | 1462 | } |
1140 | 1463 | ||
1141 | if (rdev->family >= CHIP_RV770) { | 1464 | if (rdev->family >= CHIP_RV770) { |
1142 | pfp_req_size = R700_PFP_UCODE_SIZE * 4; | 1465 | pfp_req_size = R700_PFP_UCODE_SIZE * 4; |
1143 | me_req_size = R700_PM4_UCODE_SIZE * 4; | 1466 | me_req_size = R700_PM4_UCODE_SIZE * 4; |
1467 | rlc_req_size = R700_RLC_UCODE_SIZE * 4; | ||
1144 | } else { | 1468 | } else { |
1145 | pfp_req_size = PFP_UCODE_SIZE * 4; | 1469 | pfp_req_size = PFP_UCODE_SIZE * 4; |
1146 | me_req_size = PM4_UCODE_SIZE * 12; | 1470 | me_req_size = PM4_UCODE_SIZE * 12; |
1471 | rlc_req_size = RLC_UCODE_SIZE * 4; | ||
1147 | } | 1472 | } |
1148 | 1473 | ||
1149 | DRM_INFO("Loading %s CP Microcode\n", chip_name); | 1474 | DRM_INFO("Loading %s Microcode\n", chip_name); |
1150 | 1475 | ||
1151 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); | 1476 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); |
1152 | err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); | 1477 | err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); |
@@ -1170,6 +1495,18 @@ int r600_cp_init_microcode(struct radeon_device *rdev) | |||
1170 | rdev->me_fw->size, fw_name); | 1495 | rdev->me_fw->size, fw_name); |
1171 | err = -EINVAL; | 1496 | err = -EINVAL; |
1172 | } | 1497 | } |
1498 | |||
1499 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name); | ||
1500 | err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev); | ||
1501 | if (err) | ||
1502 | goto out; | ||
1503 | if (rdev->rlc_fw->size != rlc_req_size) { | ||
1504 | printk(KERN_ERR | ||
1505 | "r600_rlc: Bogus length %zu in firmware \"%s\"\n", | ||
1506 | rdev->rlc_fw->size, fw_name); | ||
1507 | err = -EINVAL; | ||
1508 | } | ||
1509 | |||
1173 | out: | 1510 | out: |
1174 | platform_device_unregister(pdev); | 1511 | platform_device_unregister(pdev); |
1175 | 1512 | ||
@@ -1182,6 +1519,8 @@ out: | |||
1182 | rdev->pfp_fw = NULL; | 1519 | rdev->pfp_fw = NULL; |
1183 | release_firmware(rdev->me_fw); | 1520 | release_firmware(rdev->me_fw); |
1184 | rdev->me_fw = NULL; | 1521 | rdev->me_fw = NULL; |
1522 | release_firmware(rdev->rlc_fw); | ||
1523 | rdev->rlc_fw = NULL; | ||
1185 | } | 1524 | } |
1186 | return err; | 1525 | return err; |
1187 | } | 1526 | } |
@@ -1267,19 +1606,17 @@ int r600_cp_resume(struct radeon_device *rdev) | |||
1267 | 1606 | ||
1268 | /* Set ring buffer size */ | 1607 | /* Set ring buffer size */ |
1269 | rb_bufsz = drm_order(rdev->cp.ring_size / 8); | 1608 | rb_bufsz = drm_order(rdev->cp.ring_size / 8); |
1609 | tmp = RB_NO_UPDATE | (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; | ||
1270 | #ifdef __BIG_ENDIAN | 1610 | #ifdef __BIG_ENDIAN |
1271 | WREG32(CP_RB_CNTL, BUF_SWAP_32BIT | RB_NO_UPDATE | | 1611 | tmp |= BUF_SWAP_32BIT; |
1272 | (drm_order(4096/8) << 8) | rb_bufsz); | ||
1273 | #else | ||
1274 | WREG32(CP_RB_CNTL, RB_NO_UPDATE | (drm_order(4096/8) << 8) | rb_bufsz); | ||
1275 | #endif | 1612 | #endif |
1613 | WREG32(CP_RB_CNTL, tmp); | ||
1276 | WREG32(CP_SEM_WAIT_TIMER, 0x4); | 1614 | WREG32(CP_SEM_WAIT_TIMER, 0x4); |
1277 | 1615 | ||
1278 | /* Set the write pointer delay */ | 1616 | /* Set the write pointer delay */ |
1279 | WREG32(CP_RB_WPTR_DELAY, 0); | 1617 | WREG32(CP_RB_WPTR_DELAY, 0); |
1280 | 1618 | ||
1281 | /* Initialize the ring buffer's read and write pointers */ | 1619 | /* Initialize the ring buffer's read and write pointers */ |
1282 | tmp = RREG32(CP_RB_CNTL); | ||
1283 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); | 1620 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); |
1284 | WREG32(CP_RB_RPTR_WR, 0); | 1621 | WREG32(CP_RB_RPTR_WR, 0); |
1285 | WREG32(CP_RB_WPTR, 0); | 1622 | WREG32(CP_RB_WPTR, 0); |
@@ -1378,10 +1715,16 @@ int r600_ring_test(struct radeon_device *rdev) | |||
1378 | 1715 | ||
1379 | void r600_wb_disable(struct radeon_device *rdev) | 1716 | void r600_wb_disable(struct radeon_device *rdev) |
1380 | { | 1717 | { |
1718 | int r; | ||
1719 | |||
1381 | WREG32(SCRATCH_UMSK, 0); | 1720 | WREG32(SCRATCH_UMSK, 0); |
1382 | if (rdev->wb.wb_obj) { | 1721 | if (rdev->wb.wb_obj) { |
1383 | radeon_object_kunmap(rdev->wb.wb_obj); | 1722 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); |
1384 | radeon_object_unpin(rdev->wb.wb_obj); | 1723 | if (unlikely(r != 0)) |
1724 | return; | ||
1725 | radeon_bo_kunmap(rdev->wb.wb_obj); | ||
1726 | radeon_bo_unpin(rdev->wb.wb_obj); | ||
1727 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
1385 | } | 1728 | } |
1386 | } | 1729 | } |
1387 | 1730 | ||
@@ -1389,7 +1732,7 @@ void r600_wb_fini(struct radeon_device *rdev) | |||
1389 | { | 1732 | { |
1390 | r600_wb_disable(rdev); | 1733 | r600_wb_disable(rdev); |
1391 | if (rdev->wb.wb_obj) { | 1734 | if (rdev->wb.wb_obj) { |
1392 | radeon_object_unref(&rdev->wb.wb_obj); | 1735 | radeon_bo_unref(&rdev->wb.wb_obj); |
1393 | rdev->wb.wb = NULL; | 1736 | rdev->wb.wb = NULL; |
1394 | rdev->wb.wb_obj = NULL; | 1737 | rdev->wb.wb_obj = NULL; |
1395 | } | 1738 | } |
@@ -1400,22 +1743,29 @@ int r600_wb_enable(struct radeon_device *rdev) | |||
1400 | int r; | 1743 | int r; |
1401 | 1744 | ||
1402 | if (rdev->wb.wb_obj == NULL) { | 1745 | if (rdev->wb.wb_obj == NULL) { |
1403 | r = radeon_object_create(rdev, NULL, 4096, true, | 1746 | r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true, |
1404 | RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj); | 1747 | RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj); |
1405 | if (r) { | 1748 | if (r) { |
1406 | dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r); | 1749 | dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); |
1750 | return r; | ||
1751 | } | ||
1752 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); | ||
1753 | if (unlikely(r != 0)) { | ||
1754 | r600_wb_fini(rdev); | ||
1407 | return r; | 1755 | return r; |
1408 | } | 1756 | } |
1409 | r = radeon_object_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, | 1757 | r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, |
1410 | &rdev->wb.gpu_addr); | 1758 | &rdev->wb.gpu_addr); |
1411 | if (r) { | 1759 | if (r) { |
1412 | dev_warn(rdev->dev, "failed to pin WB buffer (%d).\n", r); | 1760 | radeon_bo_unreserve(rdev->wb.wb_obj); |
1761 | dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r); | ||
1413 | r600_wb_fini(rdev); | 1762 | r600_wb_fini(rdev); |
1414 | return r; | 1763 | return r; |
1415 | } | 1764 | } |
1416 | r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); | 1765 | r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); |
1766 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
1417 | if (r) { | 1767 | if (r) { |
1418 | dev_warn(rdev->dev, "failed to map WB buffer (%d).\n", r); | 1768 | dev_warn(rdev->dev, "(%d) map WB bo failed\n", r); |
1419 | r600_wb_fini(rdev); | 1769 | r600_wb_fini(rdev); |
1420 | return r; | 1770 | return r; |
1421 | } | 1771 | } |
@@ -1430,10 +1780,14 @@ int r600_wb_enable(struct radeon_device *rdev) | |||
1430 | void r600_fence_ring_emit(struct radeon_device *rdev, | 1780 | void r600_fence_ring_emit(struct radeon_device *rdev, |
1431 | struct radeon_fence *fence) | 1781 | struct radeon_fence *fence) |
1432 | { | 1782 | { |
1783 | /* Also consider EVENT_WRITE_EOP. it handles the interrupts + timestamps + events */ | ||
1433 | /* Emit fence sequence & fire IRQ */ | 1784 | /* Emit fence sequence & fire IRQ */ |
1434 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 1785 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
1435 | radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | 1786 | radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); |
1436 | radeon_ring_write(rdev, fence->seq); | 1787 | radeon_ring_write(rdev, fence->seq); |
1788 | /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ | ||
1789 | radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); | ||
1790 | radeon_ring_write(rdev, RB_INT_STAT); | ||
1437 | } | 1791 | } |
1438 | 1792 | ||
1439 | int r600_copy_dma(struct radeon_device *rdev, | 1793 | int r600_copy_dma(struct radeon_device *rdev, |
@@ -1450,24 +1804,12 @@ int r600_copy_blit(struct radeon_device *rdev, | |||
1450 | uint64_t src_offset, uint64_t dst_offset, | 1804 | uint64_t src_offset, uint64_t dst_offset, |
1451 | unsigned num_pages, struct radeon_fence *fence) | 1805 | unsigned num_pages, struct radeon_fence *fence) |
1452 | { | 1806 | { |
1453 | r600_blit_prepare_copy(rdev, num_pages * 4096); | 1807 | r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); |
1454 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * 4096); | 1808 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); |
1455 | r600_blit_done_copy(rdev, fence); | 1809 | r600_blit_done_copy(rdev, fence); |
1456 | return 0; | 1810 | return 0; |
1457 | } | 1811 | } |
1458 | 1812 | ||
1459 | int r600_irq_process(struct radeon_device *rdev) | ||
1460 | { | ||
1461 | /* FIXME: implement */ | ||
1462 | return 0; | ||
1463 | } | ||
1464 | |||
1465 | int r600_irq_set(struct radeon_device *rdev) | ||
1466 | { | ||
1467 | /* FIXME: implement */ | ||
1468 | return 0; | ||
1469 | } | ||
1470 | |||
1471 | int r600_set_surface_reg(struct radeon_device *rdev, int reg, | 1813 | int r600_set_surface_reg(struct radeon_device *rdev, int reg, |
1472 | uint32_t tiling_flags, uint32_t pitch, | 1814 | uint32_t tiling_flags, uint32_t pitch, |
1473 | uint32_t offset, uint32_t obj_size) | 1815 | uint32_t offset, uint32_t obj_size) |
@@ -1503,6 +1845,14 @@ int r600_startup(struct radeon_device *rdev) | |||
1503 | { | 1845 | { |
1504 | int r; | 1846 | int r; |
1505 | 1847 | ||
1848 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | ||
1849 | r = r600_init_microcode(rdev); | ||
1850 | if (r) { | ||
1851 | DRM_ERROR("Failed to load firmware!\n"); | ||
1852 | return r; | ||
1853 | } | ||
1854 | } | ||
1855 | |||
1506 | r600_mc_program(rdev); | 1856 | r600_mc_program(rdev); |
1507 | if (rdev->flags & RADEON_IS_AGP) { | 1857 | if (rdev->flags & RADEON_IS_AGP) { |
1508 | r600_agp_enable(rdev); | 1858 | r600_agp_enable(rdev); |
@@ -1513,12 +1863,25 @@ int r600_startup(struct radeon_device *rdev) | |||
1513 | } | 1863 | } |
1514 | r600_gpu_init(rdev); | 1864 | r600_gpu_init(rdev); |
1515 | 1865 | ||
1516 | r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | 1866 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); |
1517 | &rdev->r600_blit.shader_gpu_addr); | 1867 | if (unlikely(r != 0)) |
1868 | return r; | ||
1869 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
1870 | &rdev->r600_blit.shader_gpu_addr); | ||
1871 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
1872 | if (r) { | ||
1873 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); | ||
1874 | return r; | ||
1875 | } | ||
1876 | |||
1877 | /* Enable IRQ */ | ||
1878 | r = r600_irq_init(rdev); | ||
1518 | if (r) { | 1879 | if (r) { |
1519 | DRM_ERROR("failed to pin blit object %d\n", r); | 1880 | DRM_ERROR("radeon: IH init failed (%d).\n", r); |
1881 | radeon_irq_kms_fini(rdev); | ||
1520 | return r; | 1882 | return r; |
1521 | } | 1883 | } |
1884 | r600_irq_set(rdev); | ||
1522 | 1885 | ||
1523 | r = radeon_ring_init(rdev, rdev->cp.ring_size); | 1886 | r = radeon_ring_init(rdev, rdev->cp.ring_size); |
1524 | if (r) | 1887 | if (r) |
@@ -1580,13 +1943,19 @@ int r600_resume(struct radeon_device *rdev) | |||
1580 | 1943 | ||
1581 | int r600_suspend(struct radeon_device *rdev) | 1944 | int r600_suspend(struct radeon_device *rdev) |
1582 | { | 1945 | { |
1946 | int r; | ||
1947 | |||
1583 | /* FIXME: we should wait for ring to be empty */ | 1948 | /* FIXME: we should wait for ring to be empty */ |
1584 | r600_cp_stop(rdev); | 1949 | r600_cp_stop(rdev); |
1585 | rdev->cp.ready = false; | 1950 | rdev->cp.ready = false; |
1586 | r600_wb_disable(rdev); | 1951 | r600_wb_disable(rdev); |
1587 | r600_pcie_gart_disable(rdev); | 1952 | r600_pcie_gart_disable(rdev); |
1588 | /* unpin shaders bo */ | 1953 | /* unpin shaders bo */ |
1589 | radeon_object_unpin(rdev->r600_blit.shader_obj); | 1954 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); |
1955 | if (unlikely(r != 0)) | ||
1956 | return r; | ||
1957 | radeon_bo_unpin(rdev->r600_blit.shader_obj); | ||
1958 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
1590 | return 0; | 1959 | return 0; |
1591 | } | 1960 | } |
1592 | 1961 | ||
@@ -1624,7 +1993,11 @@ int r600_init(struct radeon_device *rdev) | |||
1624 | if (r) | 1993 | if (r) |
1625 | return r; | 1994 | return r; |
1626 | /* Post card if necessary */ | 1995 | /* Post card if necessary */ |
1627 | if (!r600_card_posted(rdev) && rdev->bios) { | 1996 | if (!r600_card_posted(rdev)) { |
1997 | if (!rdev->bios) { | ||
1998 | dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); | ||
1999 | return -EINVAL; | ||
2000 | } | ||
1628 | DRM_INFO("GPU not posted. posting now...\n"); | 2001 | DRM_INFO("GPU not posted. posting now...\n"); |
1629 | atom_asic_init(rdev->mode_info.atom_context); | 2002 | atom_asic_init(rdev->mode_info.atom_context); |
1630 | } | 2003 | } |
@@ -1632,10 +2005,13 @@ int r600_init(struct radeon_device *rdev) | |||
1632 | r600_scratch_init(rdev); | 2005 | r600_scratch_init(rdev); |
1633 | /* Initialize surface registers */ | 2006 | /* Initialize surface registers */ |
1634 | radeon_surface_init(rdev); | 2007 | radeon_surface_init(rdev); |
2008 | /* Initialize clocks */ | ||
1635 | radeon_get_clock_info(rdev->ddev); | 2009 | radeon_get_clock_info(rdev->ddev); |
1636 | r = radeon_clocks_init(rdev); | 2010 | r = radeon_clocks_init(rdev); |
1637 | if (r) | 2011 | if (r) |
1638 | return r; | 2012 | return r; |
2013 | /* Initialize power management */ | ||
2014 | radeon_pm_init(rdev); | ||
1639 | /* Fence driver */ | 2015 | /* Fence driver */ |
1640 | r = radeon_fence_driver_init(rdev); | 2016 | r = radeon_fence_driver_init(rdev); |
1641 | if (r) | 2017 | if (r) |
@@ -1644,31 +2020,31 @@ int r600_init(struct radeon_device *rdev) | |||
1644 | if (r) | 2020 | if (r) |
1645 | return r; | 2021 | return r; |
1646 | /* Memory manager */ | 2022 | /* Memory manager */ |
1647 | r = radeon_object_init(rdev); | 2023 | r = radeon_bo_init(rdev); |
1648 | if (r) | 2024 | if (r) |
1649 | return r; | 2025 | return r; |
2026 | |||
2027 | r = radeon_irq_kms_init(rdev); | ||
2028 | if (r) | ||
2029 | return r; | ||
2030 | |||
1650 | rdev->cp.ring_obj = NULL; | 2031 | rdev->cp.ring_obj = NULL; |
1651 | r600_ring_init(rdev, 1024 * 1024); | 2032 | r600_ring_init(rdev, 1024 * 1024); |
1652 | 2033 | ||
1653 | if (!rdev->me_fw || !rdev->pfp_fw) { | 2034 | rdev->ih.ring_obj = NULL; |
1654 | r = r600_cp_init_microcode(rdev); | 2035 | r600_ih_ring_init(rdev, 64 * 1024); |
1655 | if (r) { | ||
1656 | DRM_ERROR("Failed to load firmware!\n"); | ||
1657 | return r; | ||
1658 | } | ||
1659 | } | ||
1660 | 2036 | ||
1661 | r = r600_pcie_gart_init(rdev); | 2037 | r = r600_pcie_gart_init(rdev); |
1662 | if (r) | 2038 | if (r) |
1663 | return r; | 2039 | return r; |
1664 | 2040 | ||
1665 | rdev->accel_working = true; | ||
1666 | r = r600_blit_init(rdev); | 2041 | r = r600_blit_init(rdev); |
1667 | if (r) { | 2042 | if (r) { |
1668 | DRM_ERROR("radeon: failled blitter (%d).\n", r); | 2043 | DRM_ERROR("radeon: failed blitter (%d).\n", r); |
1669 | return r; | 2044 | return r; |
1670 | } | 2045 | } |
1671 | 2046 | ||
2047 | rdev->accel_working = true; | ||
1672 | r = r600_startup(rdev); | 2048 | r = r600_startup(rdev); |
1673 | if (r) { | 2049 | if (r) { |
1674 | r600_suspend(rdev); | 2050 | r600_suspend(rdev); |
@@ -1680,12 +2056,12 @@ int r600_init(struct radeon_device *rdev) | |||
1680 | if (rdev->accel_working) { | 2056 | if (rdev->accel_working) { |
1681 | r = radeon_ib_pool_init(rdev); | 2057 | r = radeon_ib_pool_init(rdev); |
1682 | if (r) { | 2058 | if (r) { |
1683 | DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); | 2059 | DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r); |
1684 | rdev->accel_working = false; | 2060 | rdev->accel_working = false; |
1685 | } | 2061 | } |
1686 | r = r600_ib_test(rdev); | 2062 | r = r600_ib_test(rdev); |
1687 | if (r) { | 2063 | if (r) { |
1688 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | 2064 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); |
1689 | rdev->accel_working = false; | 2065 | rdev->accel_working = false; |
1690 | } | 2066 | } |
1691 | } | 2067 | } |
@@ -1698,6 +2074,8 @@ void r600_fini(struct radeon_device *rdev) | |||
1698 | r600_suspend(rdev); | 2074 | r600_suspend(rdev); |
1699 | 2075 | ||
1700 | r600_blit_fini(rdev); | 2076 | r600_blit_fini(rdev); |
2077 | r600_irq_fini(rdev); | ||
2078 | radeon_irq_kms_fini(rdev); | ||
1701 | radeon_ring_fini(rdev); | 2079 | radeon_ring_fini(rdev); |
1702 | r600_wb_fini(rdev); | 2080 | r600_wb_fini(rdev); |
1703 | r600_pcie_gart_fini(rdev); | 2081 | r600_pcie_gart_fini(rdev); |
@@ -1706,7 +2084,7 @@ void r600_fini(struct radeon_device *rdev) | |||
1706 | radeon_clocks_fini(rdev); | 2084 | radeon_clocks_fini(rdev); |
1707 | if (rdev->flags & RADEON_IS_AGP) | 2085 | if (rdev->flags & RADEON_IS_AGP) |
1708 | radeon_agp_fini(rdev); | 2086 | radeon_agp_fini(rdev); |
1709 | radeon_object_fini(rdev); | 2087 | radeon_bo_fini(rdev); |
1710 | radeon_atombios_fini(rdev); | 2088 | radeon_atombios_fini(rdev); |
1711 | kfree(rdev->bios); | 2089 | kfree(rdev->bios); |
1712 | rdev->bios = NULL; | 2090 | rdev->bios = NULL; |
@@ -1792,8 +2170,657 @@ int r600_ib_test(struct radeon_device *rdev) | |||
1792 | return r; | 2170 | return r; |
1793 | } | 2171 | } |
1794 | 2172 | ||
2173 | /* | ||
2174 | * Interrupts | ||
2175 | * | ||
2176 | * Interrupts use a ring buffer on r6xx/r7xx hardware. It works pretty | ||
2177 | * the same as the CP ring buffer, but in reverse. Rather than the CPU | ||
2178 | * writing to the ring and the GPU consuming, the GPU writes to the ring | ||
2179 | * and host consumes. As the host irq handler processes interrupts, it | ||
2180 | * increments the rptr. When the rptr catches up with the wptr, all the | ||
2181 | * current interrupts have been processed. | ||
2182 | */ | ||
2183 | |||
2184 | void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size) | ||
2185 | { | ||
2186 | u32 rb_bufsz; | ||
2187 | |||
2188 | /* Align ring size */ | ||
2189 | rb_bufsz = drm_order(ring_size / 4); | ||
2190 | ring_size = (1 << rb_bufsz) * 4; | ||
2191 | rdev->ih.ring_size = ring_size; | ||
2192 | rdev->ih.align_mask = 4 - 1; | ||
2193 | } | ||
2194 | |||
2195 | static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size) | ||
2196 | { | ||
2197 | int r; | ||
2198 | |||
2199 | rdev->ih.ring_size = ring_size; | ||
2200 | /* Allocate ring buffer */ | ||
2201 | if (rdev->ih.ring_obj == NULL) { | ||
2202 | r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size, | ||
2203 | true, | ||
2204 | RADEON_GEM_DOMAIN_GTT, | ||
2205 | &rdev->ih.ring_obj); | ||
2206 | if (r) { | ||
2207 | DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r); | ||
2208 | return r; | ||
2209 | } | ||
2210 | r = radeon_bo_reserve(rdev->ih.ring_obj, false); | ||
2211 | if (unlikely(r != 0)) | ||
2212 | return r; | ||
2213 | r = radeon_bo_pin(rdev->ih.ring_obj, | ||
2214 | RADEON_GEM_DOMAIN_GTT, | ||
2215 | &rdev->ih.gpu_addr); | ||
2216 | if (r) { | ||
2217 | radeon_bo_unreserve(rdev->ih.ring_obj); | ||
2218 | DRM_ERROR("radeon: failed to pin ih ring buffer (%d).\n", r); | ||
2219 | return r; | ||
2220 | } | ||
2221 | r = radeon_bo_kmap(rdev->ih.ring_obj, | ||
2222 | (void **)&rdev->ih.ring); | ||
2223 | radeon_bo_unreserve(rdev->ih.ring_obj); | ||
2224 | if (r) { | ||
2225 | DRM_ERROR("radeon: failed to map ih ring buffer (%d).\n", r); | ||
2226 | return r; | ||
2227 | } | ||
2228 | } | ||
2229 | rdev->ih.ptr_mask = (rdev->cp.ring_size / 4) - 1; | ||
2230 | rdev->ih.rptr = 0; | ||
2231 | |||
2232 | return 0; | ||
2233 | } | ||
2234 | |||
2235 | static void r600_ih_ring_fini(struct radeon_device *rdev) | ||
2236 | { | ||
2237 | int r; | ||
2238 | if (rdev->ih.ring_obj) { | ||
2239 | r = radeon_bo_reserve(rdev->ih.ring_obj, false); | ||
2240 | if (likely(r == 0)) { | ||
2241 | radeon_bo_kunmap(rdev->ih.ring_obj); | ||
2242 | radeon_bo_unpin(rdev->ih.ring_obj); | ||
2243 | radeon_bo_unreserve(rdev->ih.ring_obj); | ||
2244 | } | ||
2245 | radeon_bo_unref(&rdev->ih.ring_obj); | ||
2246 | rdev->ih.ring = NULL; | ||
2247 | rdev->ih.ring_obj = NULL; | ||
2248 | } | ||
2249 | } | ||
2250 | |||
2251 | static void r600_rlc_stop(struct radeon_device *rdev) | ||
2252 | { | ||
2253 | |||
2254 | if (rdev->family >= CHIP_RV770) { | ||
2255 | /* r7xx asics need to soft reset RLC before halting */ | ||
2256 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC); | ||
2257 | RREG32(SRBM_SOFT_RESET); | ||
2258 | udelay(15000); | ||
2259 | WREG32(SRBM_SOFT_RESET, 0); | ||
2260 | RREG32(SRBM_SOFT_RESET); | ||
2261 | } | ||
2262 | |||
2263 | WREG32(RLC_CNTL, 0); | ||
2264 | } | ||
2265 | |||
2266 | static void r600_rlc_start(struct radeon_device *rdev) | ||
2267 | { | ||
2268 | WREG32(RLC_CNTL, RLC_ENABLE); | ||
2269 | } | ||
2270 | |||
2271 | static int r600_rlc_init(struct radeon_device *rdev) | ||
2272 | { | ||
2273 | u32 i; | ||
2274 | const __be32 *fw_data; | ||
2275 | |||
2276 | if (!rdev->rlc_fw) | ||
2277 | return -EINVAL; | ||
2278 | |||
2279 | r600_rlc_stop(rdev); | ||
2280 | |||
2281 | WREG32(RLC_HB_BASE, 0); | ||
2282 | WREG32(RLC_HB_CNTL, 0); | ||
2283 | WREG32(RLC_HB_RPTR, 0); | ||
2284 | WREG32(RLC_HB_WPTR, 0); | ||
2285 | WREG32(RLC_HB_WPTR_LSB_ADDR, 0); | ||
2286 | WREG32(RLC_HB_WPTR_MSB_ADDR, 0); | ||
2287 | WREG32(RLC_MC_CNTL, 0); | ||
2288 | WREG32(RLC_UCODE_CNTL, 0); | ||
2289 | |||
2290 | fw_data = (const __be32 *)rdev->rlc_fw->data; | ||
2291 | if (rdev->family >= CHIP_RV770) { | ||
2292 | for (i = 0; i < R700_RLC_UCODE_SIZE; i++) { | ||
2293 | WREG32(RLC_UCODE_ADDR, i); | ||
2294 | WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); | ||
2295 | } | ||
2296 | } else { | ||
2297 | for (i = 0; i < RLC_UCODE_SIZE; i++) { | ||
2298 | WREG32(RLC_UCODE_ADDR, i); | ||
2299 | WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); | ||
2300 | } | ||
2301 | } | ||
2302 | WREG32(RLC_UCODE_ADDR, 0); | ||
2303 | |||
2304 | r600_rlc_start(rdev); | ||
2305 | |||
2306 | return 0; | ||
2307 | } | ||
2308 | |||
2309 | static void r600_enable_interrupts(struct radeon_device *rdev) | ||
2310 | { | ||
2311 | u32 ih_cntl = RREG32(IH_CNTL); | ||
2312 | u32 ih_rb_cntl = RREG32(IH_RB_CNTL); | ||
2313 | |||
2314 | ih_cntl |= ENABLE_INTR; | ||
2315 | ih_rb_cntl |= IH_RB_ENABLE; | ||
2316 | WREG32(IH_CNTL, ih_cntl); | ||
2317 | WREG32(IH_RB_CNTL, ih_rb_cntl); | ||
2318 | rdev->ih.enabled = true; | ||
2319 | } | ||
2320 | |||
2321 | static void r600_disable_interrupts(struct radeon_device *rdev) | ||
2322 | { | ||
2323 | u32 ih_rb_cntl = RREG32(IH_RB_CNTL); | ||
2324 | u32 ih_cntl = RREG32(IH_CNTL); | ||
2325 | |||
2326 | ih_rb_cntl &= ~IH_RB_ENABLE; | ||
2327 | ih_cntl &= ~ENABLE_INTR; | ||
2328 | WREG32(IH_RB_CNTL, ih_rb_cntl); | ||
2329 | WREG32(IH_CNTL, ih_cntl); | ||
2330 | /* set rptr, wptr to 0 */ | ||
2331 | WREG32(IH_RB_RPTR, 0); | ||
2332 | WREG32(IH_RB_WPTR, 0); | ||
2333 | rdev->ih.enabled = false; | ||
2334 | rdev->ih.wptr = 0; | ||
2335 | rdev->ih.rptr = 0; | ||
2336 | } | ||
2337 | |||
2338 | static void r600_disable_interrupt_state(struct radeon_device *rdev) | ||
2339 | { | ||
2340 | u32 tmp; | ||
2341 | |||
2342 | WREG32(CP_INT_CNTL, 0); | ||
2343 | WREG32(GRBM_INT_CNTL, 0); | ||
2344 | WREG32(DxMODE_INT_MASK, 0); | ||
2345 | if (ASIC_IS_DCE3(rdev)) { | ||
2346 | WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); | ||
2347 | WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); | ||
2348 | tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2349 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
2350 | tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2351 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
2352 | tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2353 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
2354 | tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2355 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
2356 | if (ASIC_IS_DCE32(rdev)) { | ||
2357 | tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2358 | WREG32(DC_HPD5_INT_CONTROL, 0); | ||
2359 | tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2360 | WREG32(DC_HPD6_INT_CONTROL, 0); | ||
2361 | } | ||
2362 | } else { | ||
2363 | WREG32(DACA_AUTODETECT_INT_CONTROL, 0); | ||
2364 | WREG32(DACB_AUTODETECT_INT_CONTROL, 0); | ||
2365 | tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
2366 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0); | ||
2367 | tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
2368 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0); | ||
2369 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
2370 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0); | ||
2371 | } | ||
2372 | } | ||
2373 | |||
2374 | int r600_irq_init(struct radeon_device *rdev) | ||
2375 | { | ||
2376 | int ret = 0; | ||
2377 | int rb_bufsz; | ||
2378 | u32 interrupt_cntl, ih_cntl, ih_rb_cntl; | ||
2379 | |||
2380 | /* allocate ring */ | ||
2381 | ret = r600_ih_ring_alloc(rdev, rdev->ih.ring_size); | ||
2382 | if (ret) | ||
2383 | return ret; | ||
2384 | |||
2385 | /* disable irqs */ | ||
2386 | r600_disable_interrupts(rdev); | ||
2387 | |||
2388 | /* init rlc */ | ||
2389 | ret = r600_rlc_init(rdev); | ||
2390 | if (ret) { | ||
2391 | r600_ih_ring_fini(rdev); | ||
2392 | return ret; | ||
2393 | } | ||
2394 | |||
2395 | /* setup interrupt control */ | ||
2396 | /* set dummy read address to ring address */ | ||
2397 | WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8); | ||
2398 | interrupt_cntl = RREG32(INTERRUPT_CNTL); | ||
2399 | /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi | ||
2400 | * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN | ||
2401 | */ | ||
2402 | interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE; | ||
2403 | /* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */ | ||
2404 | interrupt_cntl &= ~IH_REQ_NONSNOOP_EN; | ||
2405 | WREG32(INTERRUPT_CNTL, interrupt_cntl); | ||
2406 | |||
2407 | WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8); | ||
2408 | rb_bufsz = drm_order(rdev->ih.ring_size / 4); | ||
2409 | |||
2410 | ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE | | ||
2411 | IH_WPTR_OVERFLOW_CLEAR | | ||
2412 | (rb_bufsz << 1)); | ||
2413 | /* WPTR writeback, not yet */ | ||
2414 | /*ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;*/ | ||
2415 | WREG32(IH_RB_WPTR_ADDR_LO, 0); | ||
2416 | WREG32(IH_RB_WPTR_ADDR_HI, 0); | ||
2417 | |||
2418 | WREG32(IH_RB_CNTL, ih_rb_cntl); | ||
2419 | |||
2420 | /* set rptr, wptr to 0 */ | ||
2421 | WREG32(IH_RB_RPTR, 0); | ||
2422 | WREG32(IH_RB_WPTR, 0); | ||
2423 | |||
2424 | /* Default settings for IH_CNTL (disabled at first) */ | ||
2425 | ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10); | ||
2426 | /* RPTR_REARM only works if msi's are enabled */ | ||
2427 | if (rdev->msi_enabled) | ||
2428 | ih_cntl |= RPTR_REARM; | ||
2429 | |||
2430 | #ifdef __BIG_ENDIAN | ||
2431 | ih_cntl |= IH_MC_SWAP(IH_MC_SWAP_32BIT); | ||
2432 | #endif | ||
2433 | WREG32(IH_CNTL, ih_cntl); | ||
2434 | |||
2435 | /* force the active interrupt state to all disabled */ | ||
2436 | r600_disable_interrupt_state(rdev); | ||
2437 | |||
2438 | /* enable irqs */ | ||
2439 | r600_enable_interrupts(rdev); | ||
2440 | |||
2441 | return ret; | ||
2442 | } | ||
2443 | |||
2444 | void r600_irq_fini(struct radeon_device *rdev) | ||
2445 | { | ||
2446 | r600_disable_interrupts(rdev); | ||
2447 | r600_rlc_stop(rdev); | ||
2448 | r600_ih_ring_fini(rdev); | ||
2449 | } | ||
2450 | |||
2451 | int r600_irq_set(struct radeon_device *rdev) | ||
2452 | { | ||
2453 | u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; | ||
2454 | u32 mode_int = 0; | ||
2455 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; | ||
2456 | |||
2457 | /* don't enable anything if the ih is disabled */ | ||
2458 | if (!rdev->ih.enabled) | ||
2459 | return 0; | ||
2460 | |||
2461 | if (ASIC_IS_DCE3(rdev)) { | ||
2462 | hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2463 | hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2464 | hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2465 | hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2466 | if (ASIC_IS_DCE32(rdev)) { | ||
2467 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2468 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2469 | } | ||
2470 | } else { | ||
2471 | hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2472 | hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2473 | hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2474 | } | ||
2475 | |||
2476 | if (rdev->irq.sw_int) { | ||
2477 | DRM_DEBUG("r600_irq_set: sw int\n"); | ||
2478 | cp_int_cntl |= RB_INT_ENABLE; | ||
2479 | } | ||
2480 | if (rdev->irq.crtc_vblank_int[0]) { | ||
2481 | DRM_DEBUG("r600_irq_set: vblank 0\n"); | ||
2482 | mode_int |= D1MODE_VBLANK_INT_MASK; | ||
2483 | } | ||
2484 | if (rdev->irq.crtc_vblank_int[1]) { | ||
2485 | DRM_DEBUG("r600_irq_set: vblank 1\n"); | ||
2486 | mode_int |= D2MODE_VBLANK_INT_MASK; | ||
2487 | } | ||
2488 | if (rdev->irq.hpd[0]) { | ||
2489 | DRM_DEBUG("r600_irq_set: hpd 1\n"); | ||
2490 | hpd1 |= DC_HPDx_INT_EN; | ||
2491 | } | ||
2492 | if (rdev->irq.hpd[1]) { | ||
2493 | DRM_DEBUG("r600_irq_set: hpd 2\n"); | ||
2494 | hpd2 |= DC_HPDx_INT_EN; | ||
2495 | } | ||
2496 | if (rdev->irq.hpd[2]) { | ||
2497 | DRM_DEBUG("r600_irq_set: hpd 3\n"); | ||
2498 | hpd3 |= DC_HPDx_INT_EN; | ||
2499 | } | ||
2500 | if (rdev->irq.hpd[3]) { | ||
2501 | DRM_DEBUG("r600_irq_set: hpd 4\n"); | ||
2502 | hpd4 |= DC_HPDx_INT_EN; | ||
2503 | } | ||
2504 | if (rdev->irq.hpd[4]) { | ||
2505 | DRM_DEBUG("r600_irq_set: hpd 5\n"); | ||
2506 | hpd5 |= DC_HPDx_INT_EN; | ||
2507 | } | ||
2508 | if (rdev->irq.hpd[5]) { | ||
2509 | DRM_DEBUG("r600_irq_set: hpd 6\n"); | ||
2510 | hpd6 |= DC_HPDx_INT_EN; | ||
2511 | } | ||
2512 | |||
2513 | WREG32(CP_INT_CNTL, cp_int_cntl); | ||
2514 | WREG32(DxMODE_INT_MASK, mode_int); | ||
2515 | if (ASIC_IS_DCE3(rdev)) { | ||
2516 | WREG32(DC_HPD1_INT_CONTROL, hpd1); | ||
2517 | WREG32(DC_HPD2_INT_CONTROL, hpd2); | ||
2518 | WREG32(DC_HPD3_INT_CONTROL, hpd3); | ||
2519 | WREG32(DC_HPD4_INT_CONTROL, hpd4); | ||
2520 | if (ASIC_IS_DCE32(rdev)) { | ||
2521 | WREG32(DC_HPD5_INT_CONTROL, hpd5); | ||
2522 | WREG32(DC_HPD6_INT_CONTROL, hpd6); | ||
2523 | } | ||
2524 | } else { | ||
2525 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); | ||
2526 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); | ||
2527 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3); | ||
2528 | } | ||
2529 | |||
2530 | return 0; | ||
2531 | } | ||
2532 | |||
2533 | static inline void r600_irq_ack(struct radeon_device *rdev, | ||
2534 | u32 *disp_int, | ||
2535 | u32 *disp_int_cont, | ||
2536 | u32 *disp_int_cont2) | ||
2537 | { | ||
2538 | u32 tmp; | ||
1795 | 2539 | ||
2540 | if (ASIC_IS_DCE3(rdev)) { | ||
2541 | *disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); | ||
2542 | *disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); | ||
2543 | *disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); | ||
2544 | } else { | ||
2545 | *disp_int = RREG32(DISP_INTERRUPT_STATUS); | ||
2546 | *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); | ||
2547 | *disp_int_cont2 = 0; | ||
2548 | } | ||
2549 | |||
2550 | if (*disp_int & LB_D1_VBLANK_INTERRUPT) | ||
2551 | WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | ||
2552 | if (*disp_int & LB_D1_VLINE_INTERRUPT) | ||
2553 | WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | ||
2554 | if (*disp_int & LB_D2_VBLANK_INTERRUPT) | ||
2555 | WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | ||
2556 | if (*disp_int & LB_D2_VLINE_INTERRUPT) | ||
2557 | WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | ||
2558 | if (*disp_int & DC_HPD1_INTERRUPT) { | ||
2559 | if (ASIC_IS_DCE3(rdev)) { | ||
2560 | tmp = RREG32(DC_HPD1_INT_CONTROL); | ||
2561 | tmp |= DC_HPDx_INT_ACK; | ||
2562 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
2563 | } else { | ||
2564 | tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
2565 | tmp |= DC_HPDx_INT_ACK; | ||
2566 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
2567 | } | ||
2568 | } | ||
2569 | if (*disp_int & DC_HPD2_INTERRUPT) { | ||
2570 | if (ASIC_IS_DCE3(rdev)) { | ||
2571 | tmp = RREG32(DC_HPD2_INT_CONTROL); | ||
2572 | tmp |= DC_HPDx_INT_ACK; | ||
2573 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
2574 | } else { | ||
2575 | tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
2576 | tmp |= DC_HPDx_INT_ACK; | ||
2577 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
2578 | } | ||
2579 | } | ||
2580 | if (*disp_int_cont & DC_HPD3_INTERRUPT) { | ||
2581 | if (ASIC_IS_DCE3(rdev)) { | ||
2582 | tmp = RREG32(DC_HPD3_INT_CONTROL); | ||
2583 | tmp |= DC_HPDx_INT_ACK; | ||
2584 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
2585 | } else { | ||
2586 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL); | ||
2587 | tmp |= DC_HPDx_INT_ACK; | ||
2588 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | ||
2589 | } | ||
2590 | } | ||
2591 | if (*disp_int_cont & DC_HPD4_INTERRUPT) { | ||
2592 | tmp = RREG32(DC_HPD4_INT_CONTROL); | ||
2593 | tmp |= DC_HPDx_INT_ACK; | ||
2594 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
2595 | } | ||
2596 | if (ASIC_IS_DCE32(rdev)) { | ||
2597 | if (*disp_int_cont2 & DC_HPD5_INTERRUPT) { | ||
2598 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
2599 | tmp |= DC_HPDx_INT_ACK; | ||
2600 | WREG32(DC_HPD5_INT_CONTROL, tmp); | ||
2601 | } | ||
2602 | if (*disp_int_cont2 & DC_HPD6_INTERRUPT) { | ||
2603 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
2604 | tmp |= DC_HPDx_INT_ACK; | ||
2605 | WREG32(DC_HPD6_INT_CONTROL, tmp); | ||
2606 | } | ||
2607 | } | ||
2608 | } | ||
1796 | 2609 | ||
2610 | void r600_irq_disable(struct radeon_device *rdev) | ||
2611 | { | ||
2612 | u32 disp_int, disp_int_cont, disp_int_cont2; | ||
2613 | |||
2614 | r600_disable_interrupts(rdev); | ||
2615 | /* Wait and acknowledge irq */ | ||
2616 | mdelay(1); | ||
2617 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); | ||
2618 | r600_disable_interrupt_state(rdev); | ||
2619 | } | ||
2620 | |||
2621 | static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) | ||
2622 | { | ||
2623 | u32 wptr, tmp; | ||
2624 | |||
2625 | /* XXX use writeback */ | ||
2626 | wptr = RREG32(IH_RB_WPTR); | ||
2627 | |||
2628 | if (wptr & RB_OVERFLOW) { | ||
2629 | WARN_ON(1); | ||
2630 | /* XXX deal with overflow */ | ||
2631 | DRM_ERROR("IH RB overflow\n"); | ||
2632 | tmp = RREG32(IH_RB_CNTL); | ||
2633 | tmp |= IH_WPTR_OVERFLOW_CLEAR; | ||
2634 | WREG32(IH_RB_CNTL, tmp); | ||
2635 | } | ||
2636 | wptr = wptr & WPTR_OFFSET_MASK; | ||
2637 | |||
2638 | return wptr; | ||
2639 | } | ||
2640 | |||
2641 | /* r600 IV Ring | ||
2642 | * Each IV ring entry is 128 bits: | ||
2643 | * [7:0] - interrupt source id | ||
2644 | * [31:8] - reserved | ||
2645 | * [59:32] - interrupt source data | ||
2646 | * [127:60] - reserved | ||
2647 | * | ||
2648 | * The basic interrupt vector entries | ||
2649 | * are decoded as follows: | ||
2650 | * src_id src_data description | ||
2651 | * 1 0 D1 Vblank | ||
2652 | * 1 1 D1 Vline | ||
2653 | * 5 0 D2 Vblank | ||
2654 | * 5 1 D2 Vline | ||
2655 | * 19 0 FP Hot plug detection A | ||
2656 | * 19 1 FP Hot plug detection B | ||
2657 | * 19 2 DAC A auto-detection | ||
2658 | * 19 3 DAC B auto-detection | ||
2659 | * 176 - CP_INT RB | ||
2660 | * 177 - CP_INT IB1 | ||
2661 | * 178 - CP_INT IB2 | ||
2662 | * 181 - EOP Interrupt | ||
2663 | * 233 - GUI Idle | ||
2664 | * | ||
2665 | * Note, these are based on r600 and may need to be | ||
2666 | * adjusted or added to on newer asics | ||
2667 | */ | ||
2668 | |||
2669 | int r600_irq_process(struct radeon_device *rdev) | ||
2670 | { | ||
2671 | u32 wptr = r600_get_ih_wptr(rdev); | ||
2672 | u32 rptr = rdev->ih.rptr; | ||
2673 | u32 src_id, src_data; | ||
2674 | u32 last_entry = rdev->ih.ring_size - 16; | ||
2675 | u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; | ||
2676 | unsigned long flags; | ||
2677 | bool queue_hotplug = false; | ||
2678 | |||
2679 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | ||
2680 | |||
2681 | spin_lock_irqsave(&rdev->ih.lock, flags); | ||
2682 | |||
2683 | if (rptr == wptr) { | ||
2684 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | ||
2685 | return IRQ_NONE; | ||
2686 | } | ||
2687 | if (rdev->shutdown) { | ||
2688 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | ||
2689 | return IRQ_NONE; | ||
2690 | } | ||
2691 | |||
2692 | restart_ih: | ||
2693 | /* display interrupts */ | ||
2694 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); | ||
2695 | |||
2696 | rdev->ih.wptr = wptr; | ||
2697 | while (rptr != wptr) { | ||
2698 | /* wptr/rptr are in bytes! */ | ||
2699 | ring_index = rptr / 4; | ||
2700 | src_id = rdev->ih.ring[ring_index] & 0xff; | ||
2701 | src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff; | ||
2702 | |||
2703 | switch (src_id) { | ||
2704 | case 1: /* D1 vblank/vline */ | ||
2705 | switch (src_data) { | ||
2706 | case 0: /* D1 vblank */ | ||
2707 | if (disp_int & LB_D1_VBLANK_INTERRUPT) { | ||
2708 | drm_handle_vblank(rdev->ddev, 0); | ||
2709 | disp_int &= ~LB_D1_VBLANK_INTERRUPT; | ||
2710 | DRM_DEBUG("IH: D1 vblank\n"); | ||
2711 | } | ||
2712 | break; | ||
2713 | case 1: /* D1 vline */ | ||
2714 | if (disp_int & LB_D1_VLINE_INTERRUPT) { | ||
2715 | disp_int &= ~LB_D1_VLINE_INTERRUPT; | ||
2716 | DRM_DEBUG("IH: D1 vline\n"); | ||
2717 | } | ||
2718 | break; | ||
2719 | default: | ||
2720 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | ||
2721 | break; | ||
2722 | } | ||
2723 | break; | ||
2724 | case 5: /* D2 vblank/vline */ | ||
2725 | switch (src_data) { | ||
2726 | case 0: /* D2 vblank */ | ||
2727 | if (disp_int & LB_D2_VBLANK_INTERRUPT) { | ||
2728 | drm_handle_vblank(rdev->ddev, 1); | ||
2729 | disp_int &= ~LB_D2_VBLANK_INTERRUPT; | ||
2730 | DRM_DEBUG("IH: D2 vblank\n"); | ||
2731 | } | ||
2732 | break; | ||
2733 | case 1: /* D1 vline */ | ||
2734 | if (disp_int & LB_D2_VLINE_INTERRUPT) { | ||
2735 | disp_int &= ~LB_D2_VLINE_INTERRUPT; | ||
2736 | DRM_DEBUG("IH: D2 vline\n"); | ||
2737 | } | ||
2738 | break; | ||
2739 | default: | ||
2740 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | ||
2741 | break; | ||
2742 | } | ||
2743 | break; | ||
2744 | case 19: /* HPD/DAC hotplug */ | ||
2745 | switch (src_data) { | ||
2746 | case 0: | ||
2747 | if (disp_int & DC_HPD1_INTERRUPT) { | ||
2748 | disp_int &= ~DC_HPD1_INTERRUPT; | ||
2749 | queue_hotplug = true; | ||
2750 | DRM_DEBUG("IH: HPD1\n"); | ||
2751 | } | ||
2752 | break; | ||
2753 | case 1: | ||
2754 | if (disp_int & DC_HPD2_INTERRUPT) { | ||
2755 | disp_int &= ~DC_HPD2_INTERRUPT; | ||
2756 | queue_hotplug = true; | ||
2757 | DRM_DEBUG("IH: HPD2\n"); | ||
2758 | } | ||
2759 | break; | ||
2760 | case 4: | ||
2761 | if (disp_int_cont & DC_HPD3_INTERRUPT) { | ||
2762 | disp_int_cont &= ~DC_HPD3_INTERRUPT; | ||
2763 | queue_hotplug = true; | ||
2764 | DRM_DEBUG("IH: HPD3\n"); | ||
2765 | } | ||
2766 | break; | ||
2767 | case 5: | ||
2768 | if (disp_int_cont & DC_HPD4_INTERRUPT) { | ||
2769 | disp_int_cont &= ~DC_HPD4_INTERRUPT; | ||
2770 | queue_hotplug = true; | ||
2771 | DRM_DEBUG("IH: HPD4\n"); | ||
2772 | } | ||
2773 | break; | ||
2774 | case 10: | ||
2775 | if (disp_int_cont2 & DC_HPD5_INTERRUPT) { | ||
2776 | disp_int_cont &= ~DC_HPD5_INTERRUPT; | ||
2777 | queue_hotplug = true; | ||
2778 | DRM_DEBUG("IH: HPD5\n"); | ||
2779 | } | ||
2780 | break; | ||
2781 | case 12: | ||
2782 | if (disp_int_cont2 & DC_HPD6_INTERRUPT) { | ||
2783 | disp_int_cont &= ~DC_HPD6_INTERRUPT; | ||
2784 | queue_hotplug = true; | ||
2785 | DRM_DEBUG("IH: HPD6\n"); | ||
2786 | } | ||
2787 | break; | ||
2788 | default: | ||
2789 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | ||
2790 | break; | ||
2791 | } | ||
2792 | break; | ||
2793 | case 176: /* CP_INT in ring buffer */ | ||
2794 | case 177: /* CP_INT in IB1 */ | ||
2795 | case 178: /* CP_INT in IB2 */ | ||
2796 | DRM_DEBUG("IH: CP int: 0x%08x\n", src_data); | ||
2797 | radeon_fence_process(rdev); | ||
2798 | break; | ||
2799 | case 181: /* CP EOP event */ | ||
2800 | DRM_DEBUG("IH: CP EOP\n"); | ||
2801 | break; | ||
2802 | default: | ||
2803 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | ||
2804 | break; | ||
2805 | } | ||
2806 | |||
2807 | /* wptr/rptr are in bytes! */ | ||
2808 | if (rptr == last_entry) | ||
2809 | rptr = 0; | ||
2810 | else | ||
2811 | rptr += 16; | ||
2812 | } | ||
2813 | /* make sure wptr hasn't changed while processing */ | ||
2814 | wptr = r600_get_ih_wptr(rdev); | ||
2815 | if (wptr != rdev->ih.wptr) | ||
2816 | goto restart_ih; | ||
2817 | if (queue_hotplug) | ||
2818 | queue_work(rdev->wq, &rdev->hotplug_work); | ||
2819 | rdev->ih.rptr = rptr; | ||
2820 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | ||
2821 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | ||
2822 | return IRQ_HANDLED; | ||
2823 | } | ||
1797 | 2824 | ||
1798 | /* | 2825 | /* |
1799 | * Debugfs info | 2826 | * Debugfs info |
@@ -1805,21 +2832,21 @@ static int r600_debugfs_cp_ring_info(struct seq_file *m, void *data) | |||
1805 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 2832 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
1806 | struct drm_device *dev = node->minor->dev; | 2833 | struct drm_device *dev = node->minor->dev; |
1807 | struct radeon_device *rdev = dev->dev_private; | 2834 | struct radeon_device *rdev = dev->dev_private; |
1808 | uint32_t rdp, wdp; | ||
1809 | unsigned count, i, j; | 2835 | unsigned count, i, j; |
1810 | 2836 | ||
1811 | radeon_ring_free_size(rdev); | 2837 | radeon_ring_free_size(rdev); |
1812 | rdp = RREG32(CP_RB_RPTR); | 2838 | count = (rdev->cp.ring_size / 4) - rdev->cp.ring_free_dw; |
1813 | wdp = RREG32(CP_RB_WPTR); | ||
1814 | count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask; | ||
1815 | seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT)); | 2839 | seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT)); |
1816 | seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp); | 2840 | seq_printf(m, "CP_RB_WPTR 0x%08x\n", RREG32(CP_RB_WPTR)); |
1817 | seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp); | 2841 | seq_printf(m, "CP_RB_RPTR 0x%08x\n", RREG32(CP_RB_RPTR)); |
2842 | seq_printf(m, "driver's copy of the CP_RB_WPTR 0x%08x\n", rdev->cp.wptr); | ||
2843 | seq_printf(m, "driver's copy of the CP_RB_RPTR 0x%08x\n", rdev->cp.rptr); | ||
1818 | seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw); | 2844 | seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw); |
1819 | seq_printf(m, "%u dwords in ring\n", count); | 2845 | seq_printf(m, "%u dwords in ring\n", count); |
2846 | i = rdev->cp.rptr; | ||
1820 | for (j = 0; j <= count; j++) { | 2847 | for (j = 0; j <= count; j++) { |
1821 | i = (rdp + j) & rdev->cp.ptr_mask; | ||
1822 | seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]); | 2848 | seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]); |
2849 | i = (i + 1) & rdev->cp.ptr_mask; | ||
1823 | } | 2850 | } |
1824 | return 0; | 2851 | return 0; |
1825 | } | 2852 | } |
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c index dec501081608..5ea432347589 100644 --- a/drivers/gpu/drm/radeon/r600_blit.c +++ b/drivers/gpu/drm/radeon/r600_blit.c | |||
@@ -582,6 +582,8 @@ r600_blit_copy(struct drm_device *dev, | |||
582 | u64 vb_addr; | 582 | u64 vb_addr; |
583 | u32 *vb; | 583 | u32 *vb; |
584 | 584 | ||
585 | vb = r600_nomm_get_vb_ptr(dev); | ||
586 | |||
585 | if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { | 587 | if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { |
586 | max_bytes = 8192; | 588 | max_bytes = 8192; |
587 | 589 | ||
@@ -617,8 +619,8 @@ r600_blit_copy(struct drm_device *dev, | |||
617 | if (!dev_priv->blit_vb) | 619 | if (!dev_priv->blit_vb) |
618 | return; | 620 | return; |
619 | set_shaders(dev); | 621 | set_shaders(dev); |
622 | vb = r600_nomm_get_vb_ptr(dev); | ||
620 | } | 623 | } |
621 | vb = r600_nomm_get_vb_ptr(dev); | ||
622 | 624 | ||
623 | vb[0] = i2f(dst_x); | 625 | vb[0] = i2f(dst_x); |
624 | vb[1] = 0; | 626 | vb[1] = 0; |
@@ -706,8 +708,8 @@ r600_blit_copy(struct drm_device *dev, | |||
706 | return; | 708 | return; |
707 | 709 | ||
708 | set_shaders(dev); | 710 | set_shaders(dev); |
711 | vb = r600_nomm_get_vb_ptr(dev); | ||
709 | } | 712 | } |
710 | vb = r600_nomm_get_vb_ptr(dev); | ||
711 | 713 | ||
712 | vb[0] = i2f(dst_x / 4); | 714 | vb[0] = i2f(dst_x / 4); |
713 | vb[1] = 0; | 715 | vb[1] = 0; |
@@ -772,6 +774,7 @@ r600_blit_swap(struct drm_device *dev, | |||
772 | { | 774 | { |
773 | drm_radeon_private_t *dev_priv = dev->dev_private; | 775 | drm_radeon_private_t *dev_priv = dev->dev_private; |
774 | int cb_format, tex_format; | 776 | int cb_format, tex_format; |
777 | int sx2, sy2, dx2, dy2; | ||
775 | u64 vb_addr; | 778 | u64 vb_addr; |
776 | u32 *vb; | 779 | u32 *vb; |
777 | 780 | ||
@@ -786,16 +789,10 @@ r600_blit_swap(struct drm_device *dev, | |||
786 | } | 789 | } |
787 | vb = r600_nomm_get_vb_ptr(dev); | 790 | vb = r600_nomm_get_vb_ptr(dev); |
788 | 791 | ||
789 | if (cpp == 4) { | 792 | sx2 = sx + w; |
790 | cb_format = COLOR_8_8_8_8; | 793 | sy2 = sy + h; |
791 | tex_format = FMT_8_8_8_8; | 794 | dx2 = dx + w; |
792 | } else if (cpp == 2) { | 795 | dy2 = dy + h; |
793 | cb_format = COLOR_5_6_5; | ||
794 | tex_format = FMT_5_6_5; | ||
795 | } else { | ||
796 | cb_format = COLOR_8; | ||
797 | tex_format = FMT_8; | ||
798 | } | ||
799 | 796 | ||
800 | vb[0] = i2f(dx); | 797 | vb[0] = i2f(dx); |
801 | vb[1] = i2f(dy); | 798 | vb[1] = i2f(dy); |
@@ -803,31 +800,46 @@ r600_blit_swap(struct drm_device *dev, | |||
803 | vb[3] = i2f(sy); | 800 | vb[3] = i2f(sy); |
804 | 801 | ||
805 | vb[4] = i2f(dx); | 802 | vb[4] = i2f(dx); |
806 | vb[5] = i2f(dy + h); | 803 | vb[5] = i2f(dy2); |
807 | vb[6] = i2f(sx); | 804 | vb[6] = i2f(sx); |
808 | vb[7] = i2f(sy + h); | 805 | vb[7] = i2f(sy2); |
806 | |||
807 | vb[8] = i2f(dx2); | ||
808 | vb[9] = i2f(dy2); | ||
809 | vb[10] = i2f(sx2); | ||
810 | vb[11] = i2f(sy2); | ||
809 | 811 | ||
810 | vb[8] = i2f(dx + w); | 812 | switch(cpp) { |
811 | vb[9] = i2f(dy + h); | 813 | case 4: |
812 | vb[10] = i2f(sx + w); | 814 | cb_format = COLOR_8_8_8_8; |
813 | vb[11] = i2f(sy + h); | 815 | tex_format = FMT_8_8_8_8; |
816 | break; | ||
817 | case 2: | ||
818 | cb_format = COLOR_5_6_5; | ||
819 | tex_format = FMT_5_6_5; | ||
820 | break; | ||
821 | default: | ||
822 | cb_format = COLOR_8; | ||
823 | tex_format = FMT_8; | ||
824 | break; | ||
825 | } | ||
814 | 826 | ||
815 | /* src */ | 827 | /* src */ |
816 | set_tex_resource(dev_priv, tex_format, | 828 | set_tex_resource(dev_priv, tex_format, |
817 | src_pitch / cpp, | 829 | src_pitch / cpp, |
818 | sy + h, src_pitch / cpp, | 830 | sy2, src_pitch / cpp, |
819 | src_gpu_addr); | 831 | src_gpu_addr); |
820 | 832 | ||
821 | cp_set_surface_sync(dev_priv, | 833 | cp_set_surface_sync(dev_priv, |
822 | R600_TC_ACTION_ENA, (src_pitch * (sy + h)), src_gpu_addr); | 834 | R600_TC_ACTION_ENA, src_pitch * sy2, src_gpu_addr); |
823 | 835 | ||
824 | /* dst */ | 836 | /* dst */ |
825 | set_render_target(dev_priv, cb_format, | 837 | set_render_target(dev_priv, cb_format, |
826 | dst_pitch / cpp, dy + h, | 838 | dst_pitch / cpp, dy2, |
827 | dst_gpu_addr); | 839 | dst_gpu_addr); |
828 | 840 | ||
829 | /* scissors */ | 841 | /* scissors */ |
830 | set_scissors(dev_priv, dx, dy, dx + w, dy + h); | 842 | set_scissors(dev_priv, dx, dy, dx2, dy2); |
831 | 843 | ||
832 | /* Vertex buffer setup */ | 844 | /* Vertex buffer setup */ |
833 | vb_addr = dev_priv->gart_buffers_offset + | 845 | vb_addr = dev_priv->gart_buffers_offset + |
@@ -840,7 +852,7 @@ r600_blit_swap(struct drm_device *dev, | |||
840 | 852 | ||
841 | cp_set_surface_sync(dev_priv, | 853 | cp_set_surface_sync(dev_priv, |
842 | R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, | 854 | R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, |
843 | dst_pitch * (dy + h), dst_gpu_addr); | 855 | dst_pitch * dy2, dst_gpu_addr); |
844 | 856 | ||
845 | dev_priv->blit_vb->used += 12 * 4; | 857 | dev_priv->blit_vb->used += 12 * 4; |
846 | } | 858 | } |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 93108bb31d1d..9aecafb51b66 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -368,7 +368,7 @@ set_default_state(struct radeon_device *rdev) | |||
368 | if ((rdev->family == CHIP_RV610) || | 368 | if ((rdev->family == CHIP_RV610) || |
369 | (rdev->family == CHIP_RV620) || | 369 | (rdev->family == CHIP_RV620) || |
370 | (rdev->family == CHIP_RS780) || | 370 | (rdev->family == CHIP_RS780) || |
371 | (rdev->family == CHIP_RS780) || | 371 | (rdev->family == CHIP_RS880) || |
372 | (rdev->family == CHIP_RV710)) | 372 | (rdev->family == CHIP_RV710)) |
373 | sq_config = 0; | 373 | sq_config = 0; |
374 | else | 374 | else |
@@ -473,9 +473,8 @@ int r600_blit_init(struct radeon_device *rdev) | |||
473 | obj_size += r6xx_ps_size * 4; | 473 | obj_size += r6xx_ps_size * 4; |
474 | obj_size = ALIGN(obj_size, 256); | 474 | obj_size = ALIGN(obj_size, 256); |
475 | 475 | ||
476 | r = radeon_object_create(rdev, NULL, obj_size, | 476 | r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM, |
477 | true, RADEON_GEM_DOMAIN_VRAM, | 477 | &rdev->r600_blit.shader_obj); |
478 | false, &rdev->r600_blit.shader_obj); | ||
479 | if (r) { | 478 | if (r) { |
480 | DRM_ERROR("r600 failed to allocate shader\n"); | 479 | DRM_ERROR("r600 failed to allocate shader\n"); |
481 | return r; | 480 | return r; |
@@ -485,12 +484,14 @@ int r600_blit_init(struct radeon_device *rdev) | |||
485 | obj_size, | 484 | obj_size, |
486 | rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset); | 485 | rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset); |
487 | 486 | ||
488 | r = radeon_object_kmap(rdev->r600_blit.shader_obj, &ptr); | 487 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); |
488 | if (unlikely(r != 0)) | ||
489 | return r; | ||
490 | r = radeon_bo_kmap(rdev->r600_blit.shader_obj, &ptr); | ||
489 | if (r) { | 491 | if (r) { |
490 | DRM_ERROR("failed to map blit object %d\n", r); | 492 | DRM_ERROR("failed to map blit object %d\n", r); |
491 | return r; | 493 | return r; |
492 | } | 494 | } |
493 | |||
494 | if (rdev->family >= CHIP_RV770) | 495 | if (rdev->family >= CHIP_RV770) |
495 | memcpy_toio(ptr + rdev->r600_blit.state_offset, | 496 | memcpy_toio(ptr + rdev->r600_blit.state_offset, |
496 | r7xx_default_state, rdev->r600_blit.state_len * 4); | 497 | r7xx_default_state, rdev->r600_blit.state_len * 4); |
@@ -500,19 +501,26 @@ int r600_blit_init(struct radeon_device *rdev) | |||
500 | if (num_packet2s) | 501 | if (num_packet2s) |
501 | memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), | 502 | memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), |
502 | packet2s, num_packet2s * 4); | 503 | packet2s, num_packet2s * 4); |
503 | |||
504 | |||
505 | memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4); | 504 | memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4); |
506 | memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4); | 505 | memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4); |
507 | 506 | radeon_bo_kunmap(rdev->r600_blit.shader_obj); | |
508 | radeon_object_kunmap(rdev->r600_blit.shader_obj); | 507 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); |
509 | return 0; | 508 | return 0; |
510 | } | 509 | } |
511 | 510 | ||
512 | void r600_blit_fini(struct radeon_device *rdev) | 511 | void r600_blit_fini(struct radeon_device *rdev) |
513 | { | 512 | { |
514 | radeon_object_unpin(rdev->r600_blit.shader_obj); | 513 | int r; |
515 | radeon_object_unref(&rdev->r600_blit.shader_obj); | 514 | |
515 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
516 | if (unlikely(r != 0)) { | ||
517 | dev_err(rdev->dev, "(%d) can't finish r600 blit\n", r); | ||
518 | goto out_unref; | ||
519 | } | ||
520 | radeon_bo_unpin(rdev->r600_blit.shader_obj); | ||
521 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
522 | out_unref: | ||
523 | radeon_bo_unref(&rdev->r600_blit.shader_obj); | ||
516 | } | 524 | } |
517 | 525 | ||
518 | int r600_vb_ib_get(struct radeon_device *rdev) | 526 | int r600_vb_ib_get(struct radeon_device *rdev) |
@@ -569,9 +577,9 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) | |||
569 | ring_size = num_loops * dwords_per_loop; | 577 | ring_size = num_loops * dwords_per_loop; |
570 | /* set default + shaders */ | 578 | /* set default + shaders */ |
571 | ring_size += 40; /* shaders + def state */ | 579 | ring_size += 40; /* shaders + def state */ |
572 | ring_size += 3; /* fence emit for VB IB */ | 580 | ring_size += 5; /* fence emit for VB IB */ |
573 | ring_size += 5; /* done copy */ | 581 | ring_size += 5; /* done copy */ |
574 | ring_size += 3; /* fence emit for done copy */ | 582 | ring_size += 5; /* fence emit for done copy */ |
575 | r = radeon_ring_lock(rdev, ring_size); | 583 | r = radeon_ring_lock(rdev, ring_size); |
576 | WARN_ON(r); | 584 | WARN_ON(r); |
577 | 585 | ||
@@ -610,6 +618,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
610 | 618 | ||
611 | DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr, | 619 | DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr, |
612 | size_bytes, rdev->r600_blit.vb_used); | 620 | size_bytes, rdev->r600_blit.vb_used); |
621 | vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); | ||
613 | if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { | 622 | if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { |
614 | max_bytes = 8192; | 623 | max_bytes = 8192; |
615 | 624 | ||
@@ -652,7 +661,6 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
652 | vb = r600_nomm_get_vb_ptr(dev); | 661 | vb = r600_nomm_get_vb_ptr(dev); |
653 | #endif | 662 | #endif |
654 | } | 663 | } |
655 | vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); | ||
656 | 664 | ||
657 | vb[0] = i2f(dst_x); | 665 | vb[0] = i2f(dst_x); |
658 | vb[1] = 0; | 666 | vb[1] = 0; |
@@ -747,7 +755,6 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
747 | vb = r600_nomm_get_vb_ptr(dev); | 755 | vb = r600_nomm_get_vb_ptr(dev); |
748 | } | 756 | } |
749 | #endif | 757 | #endif |
750 | vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); | ||
751 | 758 | ||
752 | vb[0] = i2f(dst_x / 4); | 759 | vb[0] = i2f(dst_x / 4); |
753 | vb[1] = 0; | 760 | vb[1] = 0; |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 17e42195c632..0d820764f340 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -466,6 +466,23 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
466 | for (i = 0; i < pkt->count; i++) { | 466 | for (i = 0; i < pkt->count; i++) { |
467 | reg = start_reg + (4 * i); | 467 | reg = start_reg + (4 * i); |
468 | switch (reg) { | 468 | switch (reg) { |
469 | case SQ_ESGS_RING_BASE: | ||
470 | case SQ_GSVS_RING_BASE: | ||
471 | case SQ_ESTMP_RING_BASE: | ||
472 | case SQ_GSTMP_RING_BASE: | ||
473 | case SQ_VSTMP_RING_BASE: | ||
474 | case SQ_PSTMP_RING_BASE: | ||
475 | case SQ_FBUF_RING_BASE: | ||
476 | case SQ_REDUC_RING_BASE: | ||
477 | case SX_MEMORY_EXPORT_BASE: | ||
478 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
479 | if (r) { | ||
480 | DRM_ERROR("bad SET_CONFIG_REG " | ||
481 | "0x%04X\n", reg); | ||
482 | return -EINVAL; | ||
483 | } | ||
484 | ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
485 | break; | ||
469 | case CP_COHER_BASE: | 486 | case CP_COHER_BASE: |
470 | /* use PACKET3_SURFACE_SYNC */ | 487 | /* use PACKET3_SURFACE_SYNC */ |
471 | return -EINVAL; | 488 | return -EINVAL; |
@@ -487,6 +504,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
487 | reg = start_reg + (4 * i); | 504 | reg = start_reg + (4 * i); |
488 | switch (reg) { | 505 | switch (reg) { |
489 | case DB_DEPTH_BASE: | 506 | case DB_DEPTH_BASE: |
507 | case DB_HTILE_DATA_BASE: | ||
490 | case CB_COLOR0_BASE: | 508 | case CB_COLOR0_BASE: |
491 | case CB_COLOR1_BASE: | 509 | case CB_COLOR1_BASE: |
492 | case CB_COLOR2_BASE: | 510 | case CB_COLOR2_BASE: |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 9b64d47f1f82..05894edadab4 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -119,6 +119,7 @@ | |||
119 | #define DB_DEBUG 0x9830 | 119 | #define DB_DEBUG 0x9830 |
120 | #define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) | 120 | #define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) |
121 | #define DB_DEPTH_BASE 0x2800C | 121 | #define DB_DEPTH_BASE 0x2800C |
122 | #define DB_HTILE_DATA_BASE 0x28014 | ||
122 | #define DB_WATERMARKS 0x9838 | 123 | #define DB_WATERMARKS 0x9838 |
123 | #define DEPTH_FREE(x) ((x) << 0) | 124 | #define DEPTH_FREE(x) ((x) << 0) |
124 | #define DEPTH_FLUSH(x) ((x) << 5) | 125 | #define DEPTH_FLUSH(x) ((x) << 5) |
@@ -171,6 +172,14 @@ | |||
171 | #define SQ_STACK_RESOURCE_MGMT_2 0x8c14 | 172 | #define SQ_STACK_RESOURCE_MGMT_2 0x8c14 |
172 | # define NUM_GS_STACK_ENTRIES(x) ((x) << 0) | 173 | # define NUM_GS_STACK_ENTRIES(x) ((x) << 0) |
173 | # define NUM_ES_STACK_ENTRIES(x) ((x) << 16) | 174 | # define NUM_ES_STACK_ENTRIES(x) ((x) << 16) |
175 | #define SQ_ESGS_RING_BASE 0x8c40 | ||
176 | #define SQ_GSVS_RING_BASE 0x8c48 | ||
177 | #define SQ_ESTMP_RING_BASE 0x8c50 | ||
178 | #define SQ_GSTMP_RING_BASE 0x8c58 | ||
179 | #define SQ_VSTMP_RING_BASE 0x8c60 | ||
180 | #define SQ_PSTMP_RING_BASE 0x8c68 | ||
181 | #define SQ_FBUF_RING_BASE 0x8c70 | ||
182 | #define SQ_REDUC_RING_BASE 0x8c78 | ||
174 | 183 | ||
175 | #define GRBM_CNTL 0x8000 | 184 | #define GRBM_CNTL 0x8000 |
176 | # define GRBM_READ_TIMEOUT(x) ((x) << 0) | 185 | # define GRBM_READ_TIMEOUT(x) ((x) << 0) |
@@ -271,6 +280,10 @@ | |||
271 | #define PCIE_PORT_INDEX 0x0038 | 280 | #define PCIE_PORT_INDEX 0x0038 |
272 | #define PCIE_PORT_DATA 0x003C | 281 | #define PCIE_PORT_DATA 0x003C |
273 | 282 | ||
283 | #define CHMAP 0x2004 | ||
284 | #define NOOFCHAN_SHIFT 12 | ||
285 | #define NOOFCHAN_MASK 0x00003000 | ||
286 | |||
274 | #define RAMCFG 0x2408 | 287 | #define RAMCFG 0x2408 |
275 | #define NOOFBANK_SHIFT 0 | 288 | #define NOOFBANK_SHIFT 0 |
276 | #define NOOFBANK_MASK 0x00000001 | 289 | #define NOOFBANK_MASK 0x00000001 |
@@ -352,6 +365,7 @@ | |||
352 | 365 | ||
353 | 366 | ||
354 | #define SX_MISC 0x28350 | 367 | #define SX_MISC 0x28350 |
368 | #define SX_MEMORY_EXPORT_BASE 0x9010 | ||
355 | #define SX_DEBUG_1 0x9054 | 369 | #define SX_DEBUG_1 0x9054 |
356 | #define SMX_EVENT_RELEASE (1 << 0) | 370 | #define SMX_EVENT_RELEASE (1 << 0) |
357 | #define ENABLE_NEW_SMX_ADDRESS (1 << 16) | 371 | #define ENABLE_NEW_SMX_ADDRESS (1 << 16) |
@@ -442,7 +456,215 @@ | |||
442 | #define WAIT_2D_IDLECLEAN_bit (1 << 16) | 456 | #define WAIT_2D_IDLECLEAN_bit (1 << 16) |
443 | #define WAIT_3D_IDLECLEAN_bit (1 << 17) | 457 | #define WAIT_3D_IDLECLEAN_bit (1 << 17) |
444 | 458 | ||
445 | 459 | #define IH_RB_CNTL 0x3e00 | |
460 | # define IH_RB_ENABLE (1 << 0) | ||
461 | # define IH_IB_SIZE(x) ((x) << 1) /* log2 */ | ||
462 | # define IH_RB_FULL_DRAIN_ENABLE (1 << 6) | ||
463 | # define IH_WPTR_WRITEBACK_ENABLE (1 << 8) | ||
464 | # define IH_WPTR_WRITEBACK_TIMER(x) ((x) << 9) /* log2 */ | ||
465 | # define IH_WPTR_OVERFLOW_ENABLE (1 << 16) | ||
466 | # define IH_WPTR_OVERFLOW_CLEAR (1 << 31) | ||
467 | #define IH_RB_BASE 0x3e04 | ||
468 | #define IH_RB_RPTR 0x3e08 | ||
469 | #define IH_RB_WPTR 0x3e0c | ||
470 | # define RB_OVERFLOW (1 << 0) | ||
471 | # define WPTR_OFFSET_MASK 0x3fffc | ||
472 | #define IH_RB_WPTR_ADDR_HI 0x3e10 | ||
473 | #define IH_RB_WPTR_ADDR_LO 0x3e14 | ||
474 | #define IH_CNTL 0x3e18 | ||
475 | # define ENABLE_INTR (1 << 0) | ||
476 | # define IH_MC_SWAP(x) ((x) << 2) | ||
477 | # define IH_MC_SWAP_NONE 0 | ||
478 | # define IH_MC_SWAP_16BIT 1 | ||
479 | # define IH_MC_SWAP_32BIT 2 | ||
480 | # define IH_MC_SWAP_64BIT 3 | ||
481 | # define RPTR_REARM (1 << 4) | ||
482 | # define MC_WRREQ_CREDIT(x) ((x) << 15) | ||
483 | # define MC_WR_CLEAN_CNT(x) ((x) << 20) | ||
484 | |||
485 | #define RLC_CNTL 0x3f00 | ||
486 | # define RLC_ENABLE (1 << 0) | ||
487 | #define RLC_HB_BASE 0x3f10 | ||
488 | #define RLC_HB_CNTL 0x3f0c | ||
489 | #define RLC_HB_RPTR 0x3f20 | ||
490 | #define RLC_HB_WPTR 0x3f1c | ||
491 | #define RLC_HB_WPTR_LSB_ADDR 0x3f14 | ||
492 | #define RLC_HB_WPTR_MSB_ADDR 0x3f18 | ||
493 | #define RLC_MC_CNTL 0x3f44 | ||
494 | #define RLC_UCODE_CNTL 0x3f48 | ||
495 | #define RLC_UCODE_ADDR 0x3f2c | ||
496 | #define RLC_UCODE_DATA 0x3f30 | ||
497 | |||
498 | #define SRBM_SOFT_RESET 0xe60 | ||
499 | # define SOFT_RESET_RLC (1 << 13) | ||
500 | |||
501 | #define CP_INT_CNTL 0xc124 | ||
502 | # define CNTX_BUSY_INT_ENABLE (1 << 19) | ||
503 | # define CNTX_EMPTY_INT_ENABLE (1 << 20) | ||
504 | # define SCRATCH_INT_ENABLE (1 << 25) | ||
505 | # define TIME_STAMP_INT_ENABLE (1 << 26) | ||
506 | # define IB2_INT_ENABLE (1 << 29) | ||
507 | # define IB1_INT_ENABLE (1 << 30) | ||
508 | # define RB_INT_ENABLE (1 << 31) | ||
509 | #define CP_INT_STATUS 0xc128 | ||
510 | # define SCRATCH_INT_STAT (1 << 25) | ||
511 | # define TIME_STAMP_INT_STAT (1 << 26) | ||
512 | # define IB2_INT_STAT (1 << 29) | ||
513 | # define IB1_INT_STAT (1 << 30) | ||
514 | # define RB_INT_STAT (1 << 31) | ||
515 | |||
516 | #define GRBM_INT_CNTL 0x8060 | ||
517 | # define RDERR_INT_ENABLE (1 << 0) | ||
518 | # define WAIT_COUNT_TIMEOUT_INT_ENABLE (1 << 1) | ||
519 | # define GUI_IDLE_INT_ENABLE (1 << 19) | ||
520 | |||
521 | #define INTERRUPT_CNTL 0x5468 | ||
522 | # define IH_DUMMY_RD_OVERRIDE (1 << 0) | ||
523 | # define IH_DUMMY_RD_EN (1 << 1) | ||
524 | # define IH_REQ_NONSNOOP_EN (1 << 3) | ||
525 | # define GEN_IH_INT_EN (1 << 8) | ||
526 | #define INTERRUPT_CNTL2 0x546c | ||
527 | |||
528 | #define D1MODE_VBLANK_STATUS 0x6534 | ||
529 | #define D2MODE_VBLANK_STATUS 0x6d34 | ||
530 | # define DxMODE_VBLANK_OCCURRED (1 << 0) | ||
531 | # define DxMODE_VBLANK_ACK (1 << 4) | ||
532 | # define DxMODE_VBLANK_STAT (1 << 12) | ||
533 | # define DxMODE_VBLANK_INTERRUPT (1 << 16) | ||
534 | # define DxMODE_VBLANK_INTERRUPT_TYPE (1 << 17) | ||
535 | #define D1MODE_VLINE_STATUS 0x653c | ||
536 | #define D2MODE_VLINE_STATUS 0x6d3c | ||
537 | # define DxMODE_VLINE_OCCURRED (1 << 0) | ||
538 | # define DxMODE_VLINE_ACK (1 << 4) | ||
539 | # define DxMODE_VLINE_STAT (1 << 12) | ||
540 | # define DxMODE_VLINE_INTERRUPT (1 << 16) | ||
541 | # define DxMODE_VLINE_INTERRUPT_TYPE (1 << 17) | ||
542 | #define DxMODE_INT_MASK 0x6540 | ||
543 | # define D1MODE_VBLANK_INT_MASK (1 << 0) | ||
544 | # define D1MODE_VLINE_INT_MASK (1 << 4) | ||
545 | # define D2MODE_VBLANK_INT_MASK (1 << 8) | ||
546 | # define D2MODE_VLINE_INT_MASK (1 << 12) | ||
547 | #define DCE3_DISP_INTERRUPT_STATUS 0x7ddc | ||
548 | # define DC_HPD1_INTERRUPT (1 << 18) | ||
549 | # define DC_HPD2_INTERRUPT (1 << 19) | ||
550 | #define DISP_INTERRUPT_STATUS 0x7edc | ||
551 | # define LB_D1_VLINE_INTERRUPT (1 << 2) | ||
552 | # define LB_D2_VLINE_INTERRUPT (1 << 3) | ||
553 | # define LB_D1_VBLANK_INTERRUPT (1 << 4) | ||
554 | # define LB_D2_VBLANK_INTERRUPT (1 << 5) | ||
555 | # define DACA_AUTODETECT_INTERRUPT (1 << 16) | ||
556 | # define DACB_AUTODETECT_INTERRUPT (1 << 17) | ||
557 | # define DC_HOT_PLUG_DETECT1_INTERRUPT (1 << 18) | ||
558 | # define DC_HOT_PLUG_DETECT2_INTERRUPT (1 << 19) | ||
559 | # define DC_I2C_SW_DONE_INTERRUPT (1 << 20) | ||
560 | # define DC_I2C_HW_DONE_INTERRUPT (1 << 21) | ||
561 | #define DISP_INTERRUPT_STATUS_CONTINUE 0x7ee8 | ||
562 | #define DCE3_DISP_INTERRUPT_STATUS_CONTINUE 0x7de8 | ||
563 | # define DC_HPD4_INTERRUPT (1 << 14) | ||
564 | # define DC_HPD4_RX_INTERRUPT (1 << 15) | ||
565 | # define DC_HPD3_INTERRUPT (1 << 28) | ||
566 | # define DC_HPD1_RX_INTERRUPT (1 << 29) | ||
567 | # define DC_HPD2_RX_INTERRUPT (1 << 30) | ||
568 | #define DCE3_DISP_INTERRUPT_STATUS_CONTINUE2 0x7dec | ||
569 | # define DC_HPD3_RX_INTERRUPT (1 << 0) | ||
570 | # define DIGA_DP_VID_STREAM_DISABLE_INTERRUPT (1 << 1) | ||
571 | # define DIGA_DP_STEER_FIFO_OVERFLOW_INTERRUPT (1 << 2) | ||
572 | # define DIGB_DP_VID_STREAM_DISABLE_INTERRUPT (1 << 3) | ||
573 | # define DIGB_DP_STEER_FIFO_OVERFLOW_INTERRUPT (1 << 4) | ||
574 | # define AUX1_SW_DONE_INTERRUPT (1 << 5) | ||
575 | # define AUX1_LS_DONE_INTERRUPT (1 << 6) | ||
576 | # define AUX2_SW_DONE_INTERRUPT (1 << 7) | ||
577 | # define AUX2_LS_DONE_INTERRUPT (1 << 8) | ||
578 | # define AUX3_SW_DONE_INTERRUPT (1 << 9) | ||
579 | # define AUX3_LS_DONE_INTERRUPT (1 << 10) | ||
580 | # define AUX4_SW_DONE_INTERRUPT (1 << 11) | ||
581 | # define AUX4_LS_DONE_INTERRUPT (1 << 12) | ||
582 | # define DIGA_DP_FAST_TRAINING_COMPLETE_INTERRUPT (1 << 13) | ||
583 | # define DIGB_DP_FAST_TRAINING_COMPLETE_INTERRUPT (1 << 14) | ||
584 | /* DCE 3.2 */ | ||
585 | # define AUX5_SW_DONE_INTERRUPT (1 << 15) | ||
586 | # define AUX5_LS_DONE_INTERRUPT (1 << 16) | ||
587 | # define AUX6_SW_DONE_INTERRUPT (1 << 17) | ||
588 | # define AUX6_LS_DONE_INTERRUPT (1 << 18) | ||
589 | # define DC_HPD5_INTERRUPT (1 << 19) | ||
590 | # define DC_HPD5_RX_INTERRUPT (1 << 20) | ||
591 | # define DC_HPD6_INTERRUPT (1 << 21) | ||
592 | # define DC_HPD6_RX_INTERRUPT (1 << 22) | ||
593 | |||
594 | #define DACA_AUTO_DETECT_CONTROL 0x7828 | ||
595 | #define DACB_AUTO_DETECT_CONTROL 0x7a28 | ||
596 | #define DCE3_DACA_AUTO_DETECT_CONTROL 0x7028 | ||
597 | #define DCE3_DACB_AUTO_DETECT_CONTROL 0x7128 | ||
598 | # define DACx_AUTODETECT_MODE(x) ((x) << 0) | ||
599 | # define DACx_AUTODETECT_MODE_NONE 0 | ||
600 | # define DACx_AUTODETECT_MODE_CONNECT 1 | ||
601 | # define DACx_AUTODETECT_MODE_DISCONNECT 2 | ||
602 | # define DACx_AUTODETECT_FRAME_TIME_COUNTER(x) ((x) << 8) | ||
603 | /* bit 18 = R/C, 17 = G/Y, 16 = B/Comp */ | ||
604 | # define DACx_AUTODETECT_CHECK_MASK(x) ((x) << 16) | ||
605 | |||
606 | #define DCE3_DACA_AUTODETECT_INT_CONTROL 0x7038 | ||
607 | #define DCE3_DACB_AUTODETECT_INT_CONTROL 0x7138 | ||
608 | #define DACA_AUTODETECT_INT_CONTROL 0x7838 | ||
609 | #define DACB_AUTODETECT_INT_CONTROL 0x7a38 | ||
610 | # define DACx_AUTODETECT_ACK (1 << 0) | ||
611 | # define DACx_AUTODETECT_INT_ENABLE (1 << 16) | ||
612 | |||
613 | #define DC_HOT_PLUG_DETECT1_CONTROL 0x7d00 | ||
614 | #define DC_HOT_PLUG_DETECT2_CONTROL 0x7d10 | ||
615 | #define DC_HOT_PLUG_DETECT3_CONTROL 0x7d24 | ||
616 | # define DC_HOT_PLUG_DETECTx_EN (1 << 0) | ||
617 | |||
618 | #define DC_HOT_PLUG_DETECT1_INT_STATUS 0x7d04 | ||
619 | #define DC_HOT_PLUG_DETECT2_INT_STATUS 0x7d14 | ||
620 | #define DC_HOT_PLUG_DETECT3_INT_STATUS 0x7d28 | ||
621 | # define DC_HOT_PLUG_DETECTx_INT_STATUS (1 << 0) | ||
622 | # define DC_HOT_PLUG_DETECTx_SENSE (1 << 1) | ||
623 | |||
624 | /* DCE 3.0 */ | ||
625 | #define DC_HPD1_INT_STATUS 0x7d00 | ||
626 | #define DC_HPD2_INT_STATUS 0x7d0c | ||
627 | #define DC_HPD3_INT_STATUS 0x7d18 | ||
628 | #define DC_HPD4_INT_STATUS 0x7d24 | ||
629 | /* DCE 3.2 */ | ||
630 | #define DC_HPD5_INT_STATUS 0x7dc0 | ||
631 | #define DC_HPD6_INT_STATUS 0x7df4 | ||
632 | # define DC_HPDx_INT_STATUS (1 << 0) | ||
633 | # define DC_HPDx_SENSE (1 << 1) | ||
634 | # define DC_HPDx_RX_INT_STATUS (1 << 8) | ||
635 | |||
636 | #define DC_HOT_PLUG_DETECT1_INT_CONTROL 0x7d08 | ||
637 | #define DC_HOT_PLUG_DETECT2_INT_CONTROL 0x7d18 | ||
638 | #define DC_HOT_PLUG_DETECT3_INT_CONTROL 0x7d2c | ||
639 | # define DC_HOT_PLUG_DETECTx_INT_ACK (1 << 0) | ||
640 | # define DC_HOT_PLUG_DETECTx_INT_POLARITY (1 << 8) | ||
641 | # define DC_HOT_PLUG_DETECTx_INT_EN (1 << 16) | ||
642 | /* DCE 3.0 */ | ||
643 | #define DC_HPD1_INT_CONTROL 0x7d04 | ||
644 | #define DC_HPD2_INT_CONTROL 0x7d10 | ||
645 | #define DC_HPD3_INT_CONTROL 0x7d1c | ||
646 | #define DC_HPD4_INT_CONTROL 0x7d28 | ||
647 | /* DCE 3.2 */ | ||
648 | #define DC_HPD5_INT_CONTROL 0x7dc4 | ||
649 | #define DC_HPD6_INT_CONTROL 0x7df8 | ||
650 | # define DC_HPDx_INT_ACK (1 << 0) | ||
651 | # define DC_HPDx_INT_POLARITY (1 << 8) | ||
652 | # define DC_HPDx_INT_EN (1 << 16) | ||
653 | # define DC_HPDx_RX_INT_ACK (1 << 20) | ||
654 | # define DC_HPDx_RX_INT_EN (1 << 24) | ||
655 | |||
656 | /* DCE 3.0 */ | ||
657 | #define DC_HPD1_CONTROL 0x7d08 | ||
658 | #define DC_HPD2_CONTROL 0x7d14 | ||
659 | #define DC_HPD3_CONTROL 0x7d20 | ||
660 | #define DC_HPD4_CONTROL 0x7d2c | ||
661 | /* DCE 3.2 */ | ||
662 | #define DC_HPD5_CONTROL 0x7dc8 | ||
663 | #define DC_HPD6_CONTROL 0x7dfc | ||
664 | # define DC_HPDx_CONNECTION_TIMER(x) ((x) << 0) | ||
665 | # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) | ||
666 | /* DCE 3.2 */ | ||
667 | # define DC_HPDx_EN (1 << 28) | ||
446 | 668 | ||
447 | /* | 669 | /* |
448 | * PM4 | 670 | * PM4 |
@@ -486,7 +708,6 @@ | |||
486 | #define PACKET3_WAIT_REG_MEM 0x3C | 708 | #define PACKET3_WAIT_REG_MEM 0x3C |
487 | #define PACKET3_MEM_WRITE 0x3D | 709 | #define PACKET3_MEM_WRITE 0x3D |
488 | #define PACKET3_INDIRECT_BUFFER 0x32 | 710 | #define PACKET3_INDIRECT_BUFFER 0x32 |
489 | #define PACKET3_CP_INTERRUPT 0x40 | ||
490 | #define PACKET3_SURFACE_SYNC 0x43 | 711 | #define PACKET3_SURFACE_SYNC 0x43 |
491 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) | 712 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) |
492 | # define PACKET3_TC_ACTION_ENA (1 << 23) | 713 | # define PACKET3_TC_ACTION_ENA (1 << 23) |
@@ -660,4 +881,5 @@ | |||
660 | #define S_000E60_SOFT_RESET_TSC(x) (((x) & 1) << 16) | 881 | #define S_000E60_SOFT_RESET_TSC(x) (((x) & 1) << 16) |
661 | #define S_000E60_SOFT_RESET_VMC(x) (((x) & 1) << 17) | 882 | #define S_000E60_SOFT_RESET_VMC(x) (((x) & 1) << 17) |
662 | 883 | ||
884 | #define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 | ||
663 | #endif | 885 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5ab35b81c86b..c938bb54123c 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -28,8 +28,6 @@ | |||
28 | #ifndef __RADEON_H__ | 28 | #ifndef __RADEON_H__ |
29 | #define __RADEON_H__ | 29 | #define __RADEON_H__ |
30 | 30 | ||
31 | #include "radeon_object.h" | ||
32 | |||
33 | /* TODO: Here are things that needs to be done : | 31 | /* TODO: Here are things that needs to be done : |
34 | * - surface allocator & initializer : (bit like scratch reg) should | 32 | * - surface allocator & initializer : (bit like scratch reg) should |
35 | * initialize HDP_ stuff on RS600, R600, R700 hw, well anythings | 33 | * initialize HDP_ stuff on RS600, R600, R700 hw, well anythings |
@@ -67,6 +65,11 @@ | |||
67 | #include <linux/list.h> | 65 | #include <linux/list.h> |
68 | #include <linux/kref.h> | 66 | #include <linux/kref.h> |
69 | 67 | ||
68 | #include <ttm/ttm_bo_api.h> | ||
69 | #include <ttm/ttm_bo_driver.h> | ||
70 | #include <ttm/ttm_placement.h> | ||
71 | #include <ttm/ttm_module.h> | ||
72 | |||
70 | #include "radeon_family.h" | 73 | #include "radeon_family.h" |
71 | #include "radeon_mode.h" | 74 | #include "radeon_mode.h" |
72 | #include "radeon_reg.h" | 75 | #include "radeon_reg.h" |
@@ -85,6 +88,7 @@ extern int radeon_benchmarking; | |||
85 | extern int radeon_testing; | 88 | extern int radeon_testing; |
86 | extern int radeon_connector_table; | 89 | extern int radeon_connector_table; |
87 | extern int radeon_tv; | 90 | extern int radeon_tv; |
91 | extern int radeon_new_pll; | ||
88 | 92 | ||
89 | /* | 93 | /* |
90 | * Copy from radeon_drv.h so we don't have to include both and have conflicting | 94 | * Copy from radeon_drv.h so we don't have to include both and have conflicting |
@@ -139,6 +143,10 @@ struct radeon_clock { | |||
139 | uint32_t default_sclk; | 143 | uint32_t default_sclk; |
140 | }; | 144 | }; |
141 | 145 | ||
146 | /* | ||
147 | * Power management | ||
148 | */ | ||
149 | int radeon_pm_init(struct radeon_device *rdev); | ||
142 | 150 | ||
143 | /* | 151 | /* |
144 | * Fences. | 152 | * Fences. |
@@ -182,76 +190,62 @@ void radeon_fence_unref(struct radeon_fence **fence); | |||
182 | * Tiling registers | 190 | * Tiling registers |
183 | */ | 191 | */ |
184 | struct radeon_surface_reg { | 192 | struct radeon_surface_reg { |
185 | struct radeon_object *robj; | 193 | struct radeon_bo *bo; |
186 | }; | 194 | }; |
187 | 195 | ||
188 | #define RADEON_GEM_MAX_SURFACES 8 | 196 | #define RADEON_GEM_MAX_SURFACES 8 |
189 | 197 | ||
190 | /* | 198 | /* |
191 | * Radeon buffer. | 199 | * TTM. |
192 | */ | 200 | */ |
193 | struct radeon_object; | 201 | struct radeon_mman { |
202 | struct ttm_bo_global_ref bo_global_ref; | ||
203 | struct ttm_global_reference mem_global_ref; | ||
204 | bool mem_global_referenced; | ||
205 | struct ttm_bo_device bdev; | ||
206 | }; | ||
194 | 207 | ||
195 | struct radeon_object_list { | 208 | struct radeon_bo { |
209 | /* Protected by gem.mutex */ | ||
210 | struct list_head list; | ||
211 | /* Protected by tbo.reserved */ | ||
212 | u32 placements[3]; | ||
213 | struct ttm_placement placement; | ||
214 | struct ttm_buffer_object tbo; | ||
215 | struct ttm_bo_kmap_obj kmap; | ||
216 | unsigned pin_count; | ||
217 | void *kptr; | ||
218 | u32 tiling_flags; | ||
219 | u32 pitch; | ||
220 | int surface_reg; | ||
221 | /* Constant after initialization */ | ||
222 | struct radeon_device *rdev; | ||
223 | struct drm_gem_object *gobj; | ||
224 | }; | ||
225 | |||
226 | struct radeon_bo_list { | ||
196 | struct list_head list; | 227 | struct list_head list; |
197 | struct radeon_object *robj; | 228 | struct radeon_bo *bo; |
198 | uint64_t gpu_offset; | 229 | uint64_t gpu_offset; |
199 | unsigned rdomain; | 230 | unsigned rdomain; |
200 | unsigned wdomain; | 231 | unsigned wdomain; |
201 | uint32_t tiling_flags; | 232 | u32 tiling_flags; |
202 | }; | 233 | }; |
203 | 234 | ||
204 | int radeon_object_init(struct radeon_device *rdev); | ||
205 | void radeon_object_fini(struct radeon_device *rdev); | ||
206 | int radeon_object_create(struct radeon_device *rdev, | ||
207 | struct drm_gem_object *gobj, | ||
208 | unsigned long size, | ||
209 | bool kernel, | ||
210 | uint32_t domain, | ||
211 | bool interruptible, | ||
212 | struct radeon_object **robj_ptr); | ||
213 | int radeon_object_kmap(struct radeon_object *robj, void **ptr); | ||
214 | void radeon_object_kunmap(struct radeon_object *robj); | ||
215 | void radeon_object_unref(struct radeon_object **robj); | ||
216 | int radeon_object_pin(struct radeon_object *robj, uint32_t domain, | ||
217 | uint64_t *gpu_addr); | ||
218 | void radeon_object_unpin(struct radeon_object *robj); | ||
219 | int radeon_object_wait(struct radeon_object *robj); | ||
220 | int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement); | ||
221 | int radeon_object_evict_vram(struct radeon_device *rdev); | ||
222 | int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset); | ||
223 | void radeon_object_force_delete(struct radeon_device *rdev); | ||
224 | void radeon_object_list_add_object(struct radeon_object_list *lobj, | ||
225 | struct list_head *head); | ||
226 | int radeon_object_list_validate(struct list_head *head, void *fence); | ||
227 | void radeon_object_list_unvalidate(struct list_head *head); | ||
228 | void radeon_object_list_clean(struct list_head *head); | ||
229 | int radeon_object_fbdev_mmap(struct radeon_object *robj, | ||
230 | struct vm_area_struct *vma); | ||
231 | unsigned long radeon_object_size(struct radeon_object *robj); | ||
232 | void radeon_object_clear_surface_reg(struct radeon_object *robj); | ||
233 | int radeon_object_check_tiling(struct radeon_object *robj, bool has_moved, | ||
234 | bool force_drop); | ||
235 | void radeon_object_set_tiling_flags(struct radeon_object *robj, | ||
236 | uint32_t tiling_flags, uint32_t pitch); | ||
237 | void radeon_object_get_tiling_flags(struct radeon_object *robj, uint32_t *tiling_flags, uint32_t *pitch); | ||
238 | void radeon_bo_move_notify(struct ttm_buffer_object *bo, | ||
239 | struct ttm_mem_reg *mem); | ||
240 | void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); | ||
241 | /* | 235 | /* |
242 | * GEM objects. | 236 | * GEM objects. |
243 | */ | 237 | */ |
244 | struct radeon_gem { | 238 | struct radeon_gem { |
239 | struct mutex mutex; | ||
245 | struct list_head objects; | 240 | struct list_head objects; |
246 | }; | 241 | }; |
247 | 242 | ||
248 | int radeon_gem_init(struct radeon_device *rdev); | 243 | int radeon_gem_init(struct radeon_device *rdev); |
249 | void radeon_gem_fini(struct radeon_device *rdev); | 244 | void radeon_gem_fini(struct radeon_device *rdev); |
250 | int radeon_gem_object_create(struct radeon_device *rdev, int size, | 245 | int radeon_gem_object_create(struct radeon_device *rdev, int size, |
251 | int alignment, int initial_domain, | 246 | int alignment, int initial_domain, |
252 | bool discardable, bool kernel, | 247 | bool discardable, bool kernel, |
253 | bool interruptible, | 248 | struct drm_gem_object **obj); |
254 | struct drm_gem_object **obj); | ||
255 | int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain, | 249 | int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain, |
256 | uint64_t *gpu_addr); | 250 | uint64_t *gpu_addr); |
257 | void radeon_gem_object_unpin(struct drm_gem_object *obj); | 251 | void radeon_gem_object_unpin(struct drm_gem_object *obj); |
@@ -267,7 +261,7 @@ struct radeon_gart_table_ram { | |||
267 | }; | 261 | }; |
268 | 262 | ||
269 | struct radeon_gart_table_vram { | 263 | struct radeon_gart_table_vram { |
270 | struct radeon_object *robj; | 264 | struct radeon_bo *robj; |
271 | volatile uint32_t *ptr; | 265 | volatile uint32_t *ptr; |
272 | }; | 266 | }; |
273 | 267 | ||
@@ -276,6 +270,8 @@ union radeon_gart_table { | |||
276 | struct radeon_gart_table_vram vram; | 270 | struct radeon_gart_table_vram vram; |
277 | }; | 271 | }; |
278 | 272 | ||
273 | #define RADEON_GPU_PAGE_SIZE 4096 | ||
274 | |||
279 | struct radeon_gart { | 275 | struct radeon_gart { |
280 | dma_addr_t table_addr; | 276 | dma_addr_t table_addr; |
281 | unsigned num_gpu_pages; | 277 | unsigned num_gpu_pages; |
@@ -346,11 +342,16 @@ struct radeon_irq { | |||
346 | bool sw_int; | 342 | bool sw_int; |
347 | /* FIXME: use a define max crtc rather than hardcode it */ | 343 | /* FIXME: use a define max crtc rather than hardcode it */ |
348 | bool crtc_vblank_int[2]; | 344 | bool crtc_vblank_int[2]; |
345 | /* FIXME: use defines for max hpd/dacs */ | ||
346 | bool hpd[6]; | ||
347 | spinlock_t sw_lock; | ||
348 | int sw_refcount; | ||
349 | }; | 349 | }; |
350 | 350 | ||
351 | int radeon_irq_kms_init(struct radeon_device *rdev); | 351 | int radeon_irq_kms_init(struct radeon_device *rdev); |
352 | void radeon_irq_kms_fini(struct radeon_device *rdev); | 352 | void radeon_irq_kms_fini(struct radeon_device *rdev); |
353 | 353 | void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev); | |
354 | void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev); | ||
354 | 355 | ||
355 | /* | 356 | /* |
356 | * CP & ring. | 357 | * CP & ring. |
@@ -370,7 +371,7 @@ struct radeon_ib { | |||
370 | */ | 371 | */ |
371 | struct radeon_ib_pool { | 372 | struct radeon_ib_pool { |
372 | struct mutex mutex; | 373 | struct mutex mutex; |
373 | struct radeon_object *robj; | 374 | struct radeon_bo *robj; |
374 | struct list_head scheduled_ibs; | 375 | struct list_head scheduled_ibs; |
375 | struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; | 376 | struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; |
376 | bool ready; | 377 | bool ready; |
@@ -378,7 +379,7 @@ struct radeon_ib_pool { | |||
378 | }; | 379 | }; |
379 | 380 | ||
380 | struct radeon_cp { | 381 | struct radeon_cp { |
381 | struct radeon_object *ring_obj; | 382 | struct radeon_bo *ring_obj; |
382 | volatile uint32_t *ring; | 383 | volatile uint32_t *ring; |
383 | unsigned rptr; | 384 | unsigned rptr; |
384 | unsigned wptr; | 385 | unsigned wptr; |
@@ -393,8 +394,25 @@ struct radeon_cp { | |||
393 | bool ready; | 394 | bool ready; |
394 | }; | 395 | }; |
395 | 396 | ||
397 | /* | ||
398 | * R6xx+ IH ring | ||
399 | */ | ||
400 | struct r600_ih { | ||
401 | struct radeon_bo *ring_obj; | ||
402 | volatile uint32_t *ring; | ||
403 | unsigned rptr; | ||
404 | unsigned wptr; | ||
405 | unsigned wptr_old; | ||
406 | unsigned ring_size; | ||
407 | uint64_t gpu_addr; | ||
408 | uint32_t align_mask; | ||
409 | uint32_t ptr_mask; | ||
410 | spinlock_t lock; | ||
411 | bool enabled; | ||
412 | }; | ||
413 | |||
396 | struct r600_blit { | 414 | struct r600_blit { |
397 | struct radeon_object *shader_obj; | 415 | struct radeon_bo *shader_obj; |
398 | u64 shader_gpu_addr; | 416 | u64 shader_gpu_addr; |
399 | u32 vs_offset, ps_offset; | 417 | u32 vs_offset, ps_offset; |
400 | u32 state_offset; | 418 | u32 state_offset; |
@@ -424,8 +442,8 @@ void radeon_ring_fini(struct radeon_device *rdev); | |||
424 | */ | 442 | */ |
425 | struct radeon_cs_reloc { | 443 | struct radeon_cs_reloc { |
426 | struct drm_gem_object *gobj; | 444 | struct drm_gem_object *gobj; |
427 | struct radeon_object *robj; | 445 | struct radeon_bo *robj; |
428 | struct radeon_object_list lobj; | 446 | struct radeon_bo_list lobj; |
429 | uint32_t handle; | 447 | uint32_t handle; |
430 | uint32_t flags; | 448 | uint32_t flags; |
431 | }; | 449 | }; |
@@ -513,6 +531,7 @@ typedef int (*radeon_packet3_check_t)(struct radeon_cs_parser *p, | |||
513 | * AGP | 531 | * AGP |
514 | */ | 532 | */ |
515 | int radeon_agp_init(struct radeon_device *rdev); | 533 | int radeon_agp_init(struct radeon_device *rdev); |
534 | void radeon_agp_resume(struct radeon_device *rdev); | ||
516 | void radeon_agp_fini(struct radeon_device *rdev); | 535 | void radeon_agp_fini(struct radeon_device *rdev); |
517 | 536 | ||
518 | 537 | ||
@@ -520,7 +539,7 @@ void radeon_agp_fini(struct radeon_device *rdev); | |||
520 | * Writeback | 539 | * Writeback |
521 | */ | 540 | */ |
522 | struct radeon_wb { | 541 | struct radeon_wb { |
523 | struct radeon_object *wb_obj; | 542 | struct radeon_bo *wb_obj; |
524 | volatile uint32_t *wb; | 543 | volatile uint32_t *wb; |
525 | uint64_t gpu_addr; | 544 | uint64_t gpu_addr; |
526 | }; | 545 | }; |
@@ -621,7 +640,9 @@ struct radeon_asic { | |||
621 | uint64_t dst_offset, | 640 | uint64_t dst_offset, |
622 | unsigned num_pages, | 641 | unsigned num_pages, |
623 | struct radeon_fence *fence); | 642 | struct radeon_fence *fence); |
643 | uint32_t (*get_engine_clock)(struct radeon_device *rdev); | ||
624 | void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock); | 644 | void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock); |
645 | uint32_t (*get_memory_clock)(struct radeon_device *rdev); | ||
625 | void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock); | 646 | void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock); |
626 | void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes); | 647 | void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes); |
627 | void (*set_clock_gating)(struct radeon_device *rdev, int enable); | 648 | void (*set_clock_gating)(struct radeon_device *rdev, int enable); |
@@ -630,6 +651,11 @@ struct radeon_asic { | |||
630 | uint32_t offset, uint32_t obj_size); | 651 | uint32_t offset, uint32_t obj_size); |
631 | int (*clear_surface_reg)(struct radeon_device *rdev, int reg); | 652 | int (*clear_surface_reg)(struct radeon_device *rdev, int reg); |
632 | void (*bandwidth_update)(struct radeon_device *rdev); | 653 | void (*bandwidth_update)(struct radeon_device *rdev); |
654 | void (*hdp_flush)(struct radeon_device *rdev); | ||
655 | void (*hpd_init)(struct radeon_device *rdev); | ||
656 | void (*hpd_fini)(struct radeon_device *rdev); | ||
657 | bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
658 | void (*hpd_set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
633 | }; | 659 | }; |
634 | 660 | ||
635 | /* | 661 | /* |
@@ -742,9 +768,9 @@ struct radeon_device { | |||
742 | uint8_t *bios; | 768 | uint8_t *bios; |
743 | bool is_atom_bios; | 769 | bool is_atom_bios; |
744 | uint16_t bios_header_start; | 770 | uint16_t bios_header_start; |
745 | struct radeon_object *stollen_vga_memory; | 771 | struct radeon_bo *stollen_vga_memory; |
746 | struct fb_info *fbdev_info; | 772 | struct fb_info *fbdev_info; |
747 | struct radeon_object *fbdev_robj; | 773 | struct radeon_bo *fbdev_rbo; |
748 | struct radeon_framebuffer *fbdev_rfb; | 774 | struct radeon_framebuffer *fbdev_rfb; |
749 | /* Register mmio */ | 775 | /* Register mmio */ |
750 | resource_size_t rmmio_base; | 776 | resource_size_t rmmio_base; |
@@ -782,7 +808,12 @@ struct radeon_device { | |||
782 | struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES]; | 808 | struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES]; |
783 | const struct firmware *me_fw; /* all family ME firmware */ | 809 | const struct firmware *me_fw; /* all family ME firmware */ |
784 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ | 810 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ |
811 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ | ||
785 | struct r600_blit r600_blit; | 812 | struct r600_blit r600_blit; |
813 | int msi_enabled; /* msi enabled */ | ||
814 | struct r600_ih ih; /* r6/700 interrupt ring */ | ||
815 | struct workqueue_struct *wq; | ||
816 | struct work_struct hotplug_work; | ||
786 | }; | 817 | }; |
787 | 818 | ||
788 | int radeon_device_init(struct radeon_device *rdev, | 819 | int radeon_device_init(struct radeon_device *rdev, |
@@ -819,6 +850,10 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32 | |||
819 | } | 850 | } |
820 | } | 851 | } |
821 | 852 | ||
853 | /* | ||
854 | * Cast helper | ||
855 | */ | ||
856 | #define to_radeon_fence(p) ((struct radeon_fence *)(p)) | ||
822 | 857 | ||
823 | /* | 858 | /* |
824 | * Registers read & write functions. | 859 | * Registers read & write functions. |
@@ -952,19 +987,27 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
952 | #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f)) | 987 | #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f)) |
953 | #define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f)) | 988 | #define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f)) |
954 | #define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy((rdev), (s), (d), (np), (f)) | 989 | #define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy((rdev), (s), (d), (np), (f)) |
990 | #define radeon_get_engine_clock(rdev) (rdev)->asic->get_engine_clock((rdev)) | ||
955 | #define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e)) | 991 | #define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e)) |
956 | #define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e)) | 992 | #define radeon_get_memory_clock(rdev) (rdev)->asic->get_memory_clock((rdev)) |
993 | #define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_memory_clock((rdev), (e)) | ||
957 | #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l)) | 994 | #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l)) |
958 | #define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e)) | 995 | #define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e)) |
959 | #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s))) | 996 | #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s))) |
960 | #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r))) | 997 | #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r))) |
961 | #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev)) | 998 | #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev)) |
999 | #define radeon_hdp_flush(rdev) (rdev)->asic->hdp_flush((rdev)) | ||
1000 | #define radeon_hpd_init(rdev) (rdev)->asic->hpd_init((rdev)) | ||
1001 | #define radeon_hpd_fini(rdev) (rdev)->asic->hpd_fini((rdev)) | ||
1002 | #define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd)) | ||
1003 | #define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd)) | ||
962 | 1004 | ||
963 | /* Common functions */ | 1005 | /* Common functions */ |
964 | extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); | 1006 | extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); |
965 | extern int radeon_modeset_init(struct radeon_device *rdev); | 1007 | extern int radeon_modeset_init(struct radeon_device *rdev); |
966 | extern void radeon_modeset_fini(struct radeon_device *rdev); | 1008 | extern void radeon_modeset_fini(struct radeon_device *rdev); |
967 | extern bool radeon_card_posted(struct radeon_device *rdev); | 1009 | extern bool radeon_card_posted(struct radeon_device *rdev); |
1010 | extern bool radeon_boot_test_post_card(struct radeon_device *rdev); | ||
968 | extern int radeon_clocks_init(struct radeon_device *rdev); | 1011 | extern int radeon_clocks_init(struct radeon_device *rdev); |
969 | extern void radeon_clocks_fini(struct radeon_device *rdev); | 1012 | extern void radeon_clocks_fini(struct radeon_device *rdev); |
970 | extern void radeon_scratch_init(struct radeon_device *rdev); | 1013 | extern void radeon_scratch_init(struct radeon_device *rdev); |
@@ -972,6 +1015,7 @@ extern void radeon_surface_init(struct radeon_device *rdev); | |||
972 | extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); | 1015 | extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); |
973 | extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); | 1016 | extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); |
974 | extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); | 1017 | extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); |
1018 | extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain); | ||
975 | 1019 | ||
976 | /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ | 1020 | /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ |
977 | struct r100_mc_save { | 1021 | struct r100_mc_save { |
@@ -1009,7 +1053,7 @@ extern int r100_cp_reset(struct radeon_device *rdev); | |||
1009 | extern void r100_vga_render_disable(struct radeon_device *rdev); | 1053 | extern void r100_vga_render_disable(struct radeon_device *rdev); |
1010 | extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, | 1054 | extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, |
1011 | struct radeon_cs_packet *pkt, | 1055 | struct radeon_cs_packet *pkt, |
1012 | struct radeon_object *robj); | 1056 | struct radeon_bo *robj); |
1013 | extern int r100_cs_parse_packet0(struct radeon_cs_parser *p, | 1057 | extern int r100_cs_parse_packet0(struct radeon_cs_parser *p, |
1014 | struct radeon_cs_packet *pkt, | 1058 | struct radeon_cs_packet *pkt, |
1015 | const unsigned *auth, unsigned n, | 1059 | const unsigned *auth, unsigned n, |
@@ -1017,6 +1061,8 @@ extern int r100_cs_parse_packet0(struct radeon_cs_parser *p, | |||
1017 | extern int r100_cs_packet_parse(struct radeon_cs_parser *p, | 1061 | extern int r100_cs_packet_parse(struct radeon_cs_parser *p, |
1018 | struct radeon_cs_packet *pkt, | 1062 | struct radeon_cs_packet *pkt, |
1019 | unsigned idx); | 1063 | unsigned idx); |
1064 | extern void r100_enable_bm(struct radeon_device *rdev); | ||
1065 | extern void r100_set_common_regs(struct radeon_device *rdev); | ||
1020 | 1066 | ||
1021 | /* rv200,rv250,rv280 */ | 1067 | /* rv200,rv250,rv280 */ |
1022 | extern void r200_set_safe_registers(struct radeon_device *rdev); | 1068 | extern void r200_set_safe_registers(struct radeon_device *rdev); |
@@ -1092,7 +1138,14 @@ extern void r600_wb_disable(struct radeon_device *rdev); | |||
1092 | extern void r600_scratch_init(struct radeon_device *rdev); | 1138 | extern void r600_scratch_init(struct radeon_device *rdev); |
1093 | extern int r600_blit_init(struct radeon_device *rdev); | 1139 | extern int r600_blit_init(struct radeon_device *rdev); |
1094 | extern void r600_blit_fini(struct radeon_device *rdev); | 1140 | extern void r600_blit_fini(struct radeon_device *rdev); |
1095 | extern int r600_cp_init_microcode(struct radeon_device *rdev); | 1141 | extern int r600_init_microcode(struct radeon_device *rdev); |
1096 | extern int r600_gpu_reset(struct radeon_device *rdev); | 1142 | extern int r600_gpu_reset(struct radeon_device *rdev); |
1143 | /* r600 irq */ | ||
1144 | extern int r600_irq_init(struct radeon_device *rdev); | ||
1145 | extern void r600_irq_fini(struct radeon_device *rdev); | ||
1146 | extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size); | ||
1147 | extern int r600_irq_set(struct radeon_device *rdev); | ||
1148 | |||
1149 | #include "radeon_object.h" | ||
1097 | 1150 | ||
1098 | #endif | 1151 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index 23ea9955ac59..54bf49a6d676 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
@@ -237,6 +237,18 @@ int radeon_agp_init(struct radeon_device *rdev) | |||
237 | #endif | 237 | #endif |
238 | } | 238 | } |
239 | 239 | ||
240 | void radeon_agp_resume(struct radeon_device *rdev) | ||
241 | { | ||
242 | #if __OS_HAS_AGP | ||
243 | int r; | ||
244 | if (rdev->flags & RADEON_IS_AGP) { | ||
245 | r = radeon_agp_init(rdev); | ||
246 | if (r) | ||
247 | dev_warn(rdev->dev, "radeon AGP reinit failed\n"); | ||
248 | } | ||
249 | #endif | ||
250 | } | ||
251 | |||
240 | void radeon_agp_fini(struct radeon_device *rdev) | 252 | void radeon_agp_fini(struct radeon_device *rdev) |
241 | { | 253 | { |
242 | #if __OS_HAS_AGP | 254 | #if __OS_HAS_AGP |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index c3532c7a6f3f..636116bedcb4 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -31,10 +31,13 @@ | |||
31 | /* | 31 | /* |
32 | * common functions | 32 | * common functions |
33 | */ | 33 | */ |
34 | uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev); | ||
34 | void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); | 35 | void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); |
35 | void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); | 36 | void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); |
36 | 37 | ||
38 | uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev); | ||
37 | void radeon_atom_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); | 39 | void radeon_atom_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); |
40 | uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev); | ||
38 | void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock); | 41 | void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock); |
39 | void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); | 42 | void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); |
40 | 43 | ||
@@ -73,6 +76,12 @@ int r100_clear_surface_reg(struct radeon_device *rdev, int reg); | |||
73 | void r100_bandwidth_update(struct radeon_device *rdev); | 76 | void r100_bandwidth_update(struct radeon_device *rdev); |
74 | void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | 77 | void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); |
75 | int r100_ring_test(struct radeon_device *rdev); | 78 | int r100_ring_test(struct radeon_device *rdev); |
79 | void r100_hdp_flush(struct radeon_device *rdev); | ||
80 | void r100_hpd_init(struct radeon_device *rdev); | ||
81 | void r100_hpd_fini(struct radeon_device *rdev); | ||
82 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
83 | void r100_hpd_set_polarity(struct radeon_device *rdev, | ||
84 | enum radeon_hpd_id hpd); | ||
76 | 85 | ||
77 | static struct radeon_asic r100_asic = { | 86 | static struct radeon_asic r100_asic = { |
78 | .init = &r100_init, | 87 | .init = &r100_init, |
@@ -95,13 +104,20 @@ static struct radeon_asic r100_asic = { | |||
95 | .copy_blit = &r100_copy_blit, | 104 | .copy_blit = &r100_copy_blit, |
96 | .copy_dma = NULL, | 105 | .copy_dma = NULL, |
97 | .copy = &r100_copy_blit, | 106 | .copy = &r100_copy_blit, |
107 | .get_engine_clock = &radeon_legacy_get_engine_clock, | ||
98 | .set_engine_clock = &radeon_legacy_set_engine_clock, | 108 | .set_engine_clock = &radeon_legacy_set_engine_clock, |
109 | .get_memory_clock = NULL, | ||
99 | .set_memory_clock = NULL, | 110 | .set_memory_clock = NULL, |
100 | .set_pcie_lanes = NULL, | 111 | .set_pcie_lanes = NULL, |
101 | .set_clock_gating = &radeon_legacy_set_clock_gating, | 112 | .set_clock_gating = &radeon_legacy_set_clock_gating, |
102 | .set_surface_reg = r100_set_surface_reg, | 113 | .set_surface_reg = r100_set_surface_reg, |
103 | .clear_surface_reg = r100_clear_surface_reg, | 114 | .clear_surface_reg = r100_clear_surface_reg, |
104 | .bandwidth_update = &r100_bandwidth_update, | 115 | .bandwidth_update = &r100_bandwidth_update, |
116 | .hdp_flush = &r100_hdp_flush, | ||
117 | .hpd_init = &r100_hpd_init, | ||
118 | .hpd_fini = &r100_hpd_fini, | ||
119 | .hpd_sense = &r100_hpd_sense, | ||
120 | .hpd_set_polarity = &r100_hpd_set_polarity, | ||
105 | }; | 121 | }; |
106 | 122 | ||
107 | 123 | ||
@@ -148,13 +164,20 @@ static struct radeon_asic r300_asic = { | |||
148 | .copy_blit = &r100_copy_blit, | 164 | .copy_blit = &r100_copy_blit, |
149 | .copy_dma = &r300_copy_dma, | 165 | .copy_dma = &r300_copy_dma, |
150 | .copy = &r100_copy_blit, | 166 | .copy = &r100_copy_blit, |
167 | .get_engine_clock = &radeon_legacy_get_engine_clock, | ||
151 | .set_engine_clock = &radeon_legacy_set_engine_clock, | 168 | .set_engine_clock = &radeon_legacy_set_engine_clock, |
169 | .get_memory_clock = NULL, | ||
152 | .set_memory_clock = NULL, | 170 | .set_memory_clock = NULL, |
153 | .set_pcie_lanes = &rv370_set_pcie_lanes, | 171 | .set_pcie_lanes = &rv370_set_pcie_lanes, |
154 | .set_clock_gating = &radeon_legacy_set_clock_gating, | 172 | .set_clock_gating = &radeon_legacy_set_clock_gating, |
155 | .set_surface_reg = r100_set_surface_reg, | 173 | .set_surface_reg = r100_set_surface_reg, |
156 | .clear_surface_reg = r100_clear_surface_reg, | 174 | .clear_surface_reg = r100_clear_surface_reg, |
157 | .bandwidth_update = &r100_bandwidth_update, | 175 | .bandwidth_update = &r100_bandwidth_update, |
176 | .hdp_flush = &r100_hdp_flush, | ||
177 | .hpd_init = &r100_hpd_init, | ||
178 | .hpd_fini = &r100_hpd_fini, | ||
179 | .hpd_sense = &r100_hpd_sense, | ||
180 | .hpd_set_polarity = &r100_hpd_set_polarity, | ||
158 | }; | 181 | }; |
159 | 182 | ||
160 | /* | 183 | /* |
@@ -185,13 +208,20 @@ static struct radeon_asic r420_asic = { | |||
185 | .copy_blit = &r100_copy_blit, | 208 | .copy_blit = &r100_copy_blit, |
186 | .copy_dma = &r300_copy_dma, | 209 | .copy_dma = &r300_copy_dma, |
187 | .copy = &r100_copy_blit, | 210 | .copy = &r100_copy_blit, |
211 | .get_engine_clock = &radeon_atom_get_engine_clock, | ||
188 | .set_engine_clock = &radeon_atom_set_engine_clock, | 212 | .set_engine_clock = &radeon_atom_set_engine_clock, |
213 | .get_memory_clock = &radeon_atom_get_memory_clock, | ||
189 | .set_memory_clock = &radeon_atom_set_memory_clock, | 214 | .set_memory_clock = &radeon_atom_set_memory_clock, |
190 | .set_pcie_lanes = &rv370_set_pcie_lanes, | 215 | .set_pcie_lanes = &rv370_set_pcie_lanes, |
191 | .set_clock_gating = &radeon_atom_set_clock_gating, | 216 | .set_clock_gating = &radeon_atom_set_clock_gating, |
192 | .set_surface_reg = r100_set_surface_reg, | 217 | .set_surface_reg = r100_set_surface_reg, |
193 | .clear_surface_reg = r100_clear_surface_reg, | 218 | .clear_surface_reg = r100_clear_surface_reg, |
194 | .bandwidth_update = &r100_bandwidth_update, | 219 | .bandwidth_update = &r100_bandwidth_update, |
220 | .hdp_flush = &r100_hdp_flush, | ||
221 | .hpd_init = &r100_hpd_init, | ||
222 | .hpd_fini = &r100_hpd_fini, | ||
223 | .hpd_sense = &r100_hpd_sense, | ||
224 | .hpd_set_polarity = &r100_hpd_set_polarity, | ||
195 | }; | 225 | }; |
196 | 226 | ||
197 | 227 | ||
@@ -227,13 +257,20 @@ static struct radeon_asic rs400_asic = { | |||
227 | .copy_blit = &r100_copy_blit, | 257 | .copy_blit = &r100_copy_blit, |
228 | .copy_dma = &r300_copy_dma, | 258 | .copy_dma = &r300_copy_dma, |
229 | .copy = &r100_copy_blit, | 259 | .copy = &r100_copy_blit, |
260 | .get_engine_clock = &radeon_legacy_get_engine_clock, | ||
230 | .set_engine_clock = &radeon_legacy_set_engine_clock, | 261 | .set_engine_clock = &radeon_legacy_set_engine_clock, |
262 | .get_memory_clock = NULL, | ||
231 | .set_memory_clock = NULL, | 263 | .set_memory_clock = NULL, |
232 | .set_pcie_lanes = NULL, | 264 | .set_pcie_lanes = NULL, |
233 | .set_clock_gating = &radeon_legacy_set_clock_gating, | 265 | .set_clock_gating = &radeon_legacy_set_clock_gating, |
234 | .set_surface_reg = r100_set_surface_reg, | 266 | .set_surface_reg = r100_set_surface_reg, |
235 | .clear_surface_reg = r100_clear_surface_reg, | 267 | .clear_surface_reg = r100_clear_surface_reg, |
236 | .bandwidth_update = &r100_bandwidth_update, | 268 | .bandwidth_update = &r100_bandwidth_update, |
269 | .hdp_flush = &r100_hdp_flush, | ||
270 | .hpd_init = &r100_hpd_init, | ||
271 | .hpd_fini = &r100_hpd_fini, | ||
272 | .hpd_sense = &r100_hpd_sense, | ||
273 | .hpd_set_polarity = &r100_hpd_set_polarity, | ||
237 | }; | 274 | }; |
238 | 275 | ||
239 | 276 | ||
@@ -252,6 +289,12 @@ int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); | |||
252 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 289 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
253 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 290 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
254 | void rs600_bandwidth_update(struct radeon_device *rdev); | 291 | void rs600_bandwidth_update(struct radeon_device *rdev); |
292 | void rs600_hpd_init(struct radeon_device *rdev); | ||
293 | void rs600_hpd_fini(struct radeon_device *rdev); | ||
294 | bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
295 | void rs600_hpd_set_polarity(struct radeon_device *rdev, | ||
296 | enum radeon_hpd_id hpd); | ||
297 | |||
255 | static struct radeon_asic rs600_asic = { | 298 | static struct radeon_asic rs600_asic = { |
256 | .init = &rs600_init, | 299 | .init = &rs600_init, |
257 | .fini = &rs600_fini, | 300 | .fini = &rs600_fini, |
@@ -273,11 +316,18 @@ static struct radeon_asic rs600_asic = { | |||
273 | .copy_blit = &r100_copy_blit, | 316 | .copy_blit = &r100_copy_blit, |
274 | .copy_dma = &r300_copy_dma, | 317 | .copy_dma = &r300_copy_dma, |
275 | .copy = &r100_copy_blit, | 318 | .copy = &r100_copy_blit, |
319 | .get_engine_clock = &radeon_atom_get_engine_clock, | ||
276 | .set_engine_clock = &radeon_atom_set_engine_clock, | 320 | .set_engine_clock = &radeon_atom_set_engine_clock, |
321 | .get_memory_clock = &radeon_atom_get_memory_clock, | ||
277 | .set_memory_clock = &radeon_atom_set_memory_clock, | 322 | .set_memory_clock = &radeon_atom_set_memory_clock, |
278 | .set_pcie_lanes = NULL, | 323 | .set_pcie_lanes = NULL, |
279 | .set_clock_gating = &radeon_atom_set_clock_gating, | 324 | .set_clock_gating = &radeon_atom_set_clock_gating, |
280 | .bandwidth_update = &rs600_bandwidth_update, | 325 | .bandwidth_update = &rs600_bandwidth_update, |
326 | .hdp_flush = &r100_hdp_flush, | ||
327 | .hpd_init = &rs600_hpd_init, | ||
328 | .hpd_fini = &rs600_hpd_fini, | ||
329 | .hpd_sense = &rs600_hpd_sense, | ||
330 | .hpd_set_polarity = &rs600_hpd_set_polarity, | ||
281 | }; | 331 | }; |
282 | 332 | ||
283 | 333 | ||
@@ -312,13 +362,20 @@ static struct radeon_asic rs690_asic = { | |||
312 | .copy_blit = &r100_copy_blit, | 362 | .copy_blit = &r100_copy_blit, |
313 | .copy_dma = &r300_copy_dma, | 363 | .copy_dma = &r300_copy_dma, |
314 | .copy = &r300_copy_dma, | 364 | .copy = &r300_copy_dma, |
365 | .get_engine_clock = &radeon_atom_get_engine_clock, | ||
315 | .set_engine_clock = &radeon_atom_set_engine_clock, | 366 | .set_engine_clock = &radeon_atom_set_engine_clock, |
367 | .get_memory_clock = &radeon_atom_get_memory_clock, | ||
316 | .set_memory_clock = &radeon_atom_set_memory_clock, | 368 | .set_memory_clock = &radeon_atom_set_memory_clock, |
317 | .set_pcie_lanes = NULL, | 369 | .set_pcie_lanes = NULL, |
318 | .set_clock_gating = &radeon_atom_set_clock_gating, | 370 | .set_clock_gating = &radeon_atom_set_clock_gating, |
319 | .set_surface_reg = r100_set_surface_reg, | 371 | .set_surface_reg = r100_set_surface_reg, |
320 | .clear_surface_reg = r100_clear_surface_reg, | 372 | .clear_surface_reg = r100_clear_surface_reg, |
321 | .bandwidth_update = &rs690_bandwidth_update, | 373 | .bandwidth_update = &rs690_bandwidth_update, |
374 | .hdp_flush = &r100_hdp_flush, | ||
375 | .hpd_init = &rs600_hpd_init, | ||
376 | .hpd_fini = &rs600_hpd_fini, | ||
377 | .hpd_sense = &rs600_hpd_sense, | ||
378 | .hpd_set_polarity = &rs600_hpd_set_polarity, | ||
322 | }; | 379 | }; |
323 | 380 | ||
324 | 381 | ||
@@ -357,13 +414,20 @@ static struct radeon_asic rv515_asic = { | |||
357 | .copy_blit = &r100_copy_blit, | 414 | .copy_blit = &r100_copy_blit, |
358 | .copy_dma = &r300_copy_dma, | 415 | .copy_dma = &r300_copy_dma, |
359 | .copy = &r100_copy_blit, | 416 | .copy = &r100_copy_blit, |
417 | .get_engine_clock = &radeon_atom_get_engine_clock, | ||
360 | .set_engine_clock = &radeon_atom_set_engine_clock, | 418 | .set_engine_clock = &radeon_atom_set_engine_clock, |
419 | .get_memory_clock = &radeon_atom_get_memory_clock, | ||
361 | .set_memory_clock = &radeon_atom_set_memory_clock, | 420 | .set_memory_clock = &radeon_atom_set_memory_clock, |
362 | .set_pcie_lanes = &rv370_set_pcie_lanes, | 421 | .set_pcie_lanes = &rv370_set_pcie_lanes, |
363 | .set_clock_gating = &radeon_atom_set_clock_gating, | 422 | .set_clock_gating = &radeon_atom_set_clock_gating, |
364 | .set_surface_reg = r100_set_surface_reg, | 423 | .set_surface_reg = r100_set_surface_reg, |
365 | .clear_surface_reg = r100_clear_surface_reg, | 424 | .clear_surface_reg = r100_clear_surface_reg, |
366 | .bandwidth_update = &rv515_bandwidth_update, | 425 | .bandwidth_update = &rv515_bandwidth_update, |
426 | .hdp_flush = &r100_hdp_flush, | ||
427 | .hpd_init = &rs600_hpd_init, | ||
428 | .hpd_fini = &rs600_hpd_fini, | ||
429 | .hpd_sense = &rs600_hpd_sense, | ||
430 | .hpd_set_polarity = &rs600_hpd_set_polarity, | ||
367 | }; | 431 | }; |
368 | 432 | ||
369 | 433 | ||
@@ -393,13 +457,20 @@ static struct radeon_asic r520_asic = { | |||
393 | .copy_blit = &r100_copy_blit, | 457 | .copy_blit = &r100_copy_blit, |
394 | .copy_dma = &r300_copy_dma, | 458 | .copy_dma = &r300_copy_dma, |
395 | .copy = &r100_copy_blit, | 459 | .copy = &r100_copy_blit, |
460 | .get_engine_clock = &radeon_atom_get_engine_clock, | ||
396 | .set_engine_clock = &radeon_atom_set_engine_clock, | 461 | .set_engine_clock = &radeon_atom_set_engine_clock, |
462 | .get_memory_clock = &radeon_atom_get_memory_clock, | ||
397 | .set_memory_clock = &radeon_atom_set_memory_clock, | 463 | .set_memory_clock = &radeon_atom_set_memory_clock, |
398 | .set_pcie_lanes = &rv370_set_pcie_lanes, | 464 | .set_pcie_lanes = &rv370_set_pcie_lanes, |
399 | .set_clock_gating = &radeon_atom_set_clock_gating, | 465 | .set_clock_gating = &radeon_atom_set_clock_gating, |
400 | .set_surface_reg = r100_set_surface_reg, | 466 | .set_surface_reg = r100_set_surface_reg, |
401 | .clear_surface_reg = r100_clear_surface_reg, | 467 | .clear_surface_reg = r100_clear_surface_reg, |
402 | .bandwidth_update = &rv515_bandwidth_update, | 468 | .bandwidth_update = &rv515_bandwidth_update, |
469 | .hdp_flush = &r100_hdp_flush, | ||
470 | .hpd_init = &rs600_hpd_init, | ||
471 | .hpd_fini = &rs600_hpd_fini, | ||
472 | .hpd_sense = &rs600_hpd_sense, | ||
473 | .hpd_set_polarity = &rs600_hpd_set_polarity, | ||
403 | }; | 474 | }; |
404 | 475 | ||
405 | /* | 476 | /* |
@@ -436,6 +507,12 @@ int r600_ring_test(struct radeon_device *rdev); | |||
436 | int r600_copy_blit(struct radeon_device *rdev, | 507 | int r600_copy_blit(struct radeon_device *rdev, |
437 | uint64_t src_offset, uint64_t dst_offset, | 508 | uint64_t src_offset, uint64_t dst_offset, |
438 | unsigned num_pages, struct radeon_fence *fence); | 509 | unsigned num_pages, struct radeon_fence *fence); |
510 | void r600_hdp_flush(struct radeon_device *rdev); | ||
511 | void r600_hpd_init(struct radeon_device *rdev); | ||
512 | void r600_hpd_fini(struct radeon_device *rdev); | ||
513 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
514 | void r600_hpd_set_polarity(struct radeon_device *rdev, | ||
515 | enum radeon_hpd_id hpd); | ||
439 | 516 | ||
440 | static struct radeon_asic r600_asic = { | 517 | static struct radeon_asic r600_asic = { |
441 | .init = &r600_init, | 518 | .init = &r600_init, |
@@ -451,18 +528,26 @@ static struct radeon_asic r600_asic = { | |||
451 | .ring_ib_execute = &r600_ring_ib_execute, | 528 | .ring_ib_execute = &r600_ring_ib_execute, |
452 | .irq_set = &r600_irq_set, | 529 | .irq_set = &r600_irq_set, |
453 | .irq_process = &r600_irq_process, | 530 | .irq_process = &r600_irq_process, |
531 | .get_vblank_counter = &rs600_get_vblank_counter, | ||
454 | .fence_ring_emit = &r600_fence_ring_emit, | 532 | .fence_ring_emit = &r600_fence_ring_emit, |
455 | .cs_parse = &r600_cs_parse, | 533 | .cs_parse = &r600_cs_parse, |
456 | .copy_blit = &r600_copy_blit, | 534 | .copy_blit = &r600_copy_blit, |
457 | .copy_dma = &r600_copy_blit, | 535 | .copy_dma = &r600_copy_blit, |
458 | .copy = &r600_copy_blit, | 536 | .copy = &r600_copy_blit, |
537 | .get_engine_clock = &radeon_atom_get_engine_clock, | ||
459 | .set_engine_clock = &radeon_atom_set_engine_clock, | 538 | .set_engine_clock = &radeon_atom_set_engine_clock, |
539 | .get_memory_clock = &radeon_atom_get_memory_clock, | ||
460 | .set_memory_clock = &radeon_atom_set_memory_clock, | 540 | .set_memory_clock = &radeon_atom_set_memory_clock, |
461 | .set_pcie_lanes = NULL, | 541 | .set_pcie_lanes = NULL, |
462 | .set_clock_gating = &radeon_atom_set_clock_gating, | 542 | .set_clock_gating = &radeon_atom_set_clock_gating, |
463 | .set_surface_reg = r600_set_surface_reg, | 543 | .set_surface_reg = r600_set_surface_reg, |
464 | .clear_surface_reg = r600_clear_surface_reg, | 544 | .clear_surface_reg = r600_clear_surface_reg, |
465 | .bandwidth_update = &rv515_bandwidth_update, | 545 | .bandwidth_update = &rv515_bandwidth_update, |
546 | .hdp_flush = &r600_hdp_flush, | ||
547 | .hpd_init = &r600_hpd_init, | ||
548 | .hpd_fini = &r600_hpd_fini, | ||
549 | .hpd_sense = &r600_hpd_sense, | ||
550 | .hpd_set_polarity = &r600_hpd_set_polarity, | ||
466 | }; | 551 | }; |
467 | 552 | ||
468 | /* | 553 | /* |
@@ -488,18 +573,26 @@ static struct radeon_asic rv770_asic = { | |||
488 | .ring_ib_execute = &r600_ring_ib_execute, | 573 | .ring_ib_execute = &r600_ring_ib_execute, |
489 | .irq_set = &r600_irq_set, | 574 | .irq_set = &r600_irq_set, |
490 | .irq_process = &r600_irq_process, | 575 | .irq_process = &r600_irq_process, |
576 | .get_vblank_counter = &rs600_get_vblank_counter, | ||
491 | .fence_ring_emit = &r600_fence_ring_emit, | 577 | .fence_ring_emit = &r600_fence_ring_emit, |
492 | .cs_parse = &r600_cs_parse, | 578 | .cs_parse = &r600_cs_parse, |
493 | .copy_blit = &r600_copy_blit, | 579 | .copy_blit = &r600_copy_blit, |
494 | .copy_dma = &r600_copy_blit, | 580 | .copy_dma = &r600_copy_blit, |
495 | .copy = &r600_copy_blit, | 581 | .copy = &r600_copy_blit, |
582 | .get_engine_clock = &radeon_atom_get_engine_clock, | ||
496 | .set_engine_clock = &radeon_atom_set_engine_clock, | 583 | .set_engine_clock = &radeon_atom_set_engine_clock, |
584 | .get_memory_clock = &radeon_atom_get_memory_clock, | ||
497 | .set_memory_clock = &radeon_atom_set_memory_clock, | 585 | .set_memory_clock = &radeon_atom_set_memory_clock, |
498 | .set_pcie_lanes = NULL, | 586 | .set_pcie_lanes = NULL, |
499 | .set_clock_gating = &radeon_atom_set_clock_gating, | 587 | .set_clock_gating = &radeon_atom_set_clock_gating, |
500 | .set_surface_reg = r600_set_surface_reg, | 588 | .set_surface_reg = r600_set_surface_reg, |
501 | .clear_surface_reg = r600_clear_surface_reg, | 589 | .clear_surface_reg = r600_clear_surface_reg, |
502 | .bandwidth_update = &rv515_bandwidth_update, | 590 | .bandwidth_update = &rv515_bandwidth_update, |
591 | .hdp_flush = &r600_hdp_flush, | ||
592 | .hpd_init = &r600_hpd_init, | ||
593 | .hpd_fini = &r600_hpd_fini, | ||
594 | .hpd_sense = &r600_hpd_sense, | ||
595 | .hpd_set_polarity = &r600_hpd_set_polarity, | ||
503 | }; | 596 | }; |
504 | 597 | ||
505 | #endif | 598 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 5b6c08cee40e..12a0c760e7ff 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -46,7 +46,9 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
46 | uint32_t supported_device, | 46 | uint32_t supported_device, |
47 | int connector_type, | 47 | int connector_type, |
48 | struct radeon_i2c_bus_rec *i2c_bus, | 48 | struct radeon_i2c_bus_rec *i2c_bus, |
49 | bool linkb, uint32_t igp_lane_info); | 49 | bool linkb, uint32_t igp_lane_info, |
50 | uint16_t connector_object_id, | ||
51 | struct radeon_hpd *hpd); | ||
50 | 52 | ||
51 | /* from radeon_legacy_encoder.c */ | 53 | /* from radeon_legacy_encoder.c */ |
52 | extern void | 54 | extern void |
@@ -59,16 +61,16 @@ union atom_supported_devices { | |||
59 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; | 61 | struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; |
60 | }; | 62 | }; |
61 | 63 | ||
62 | static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device | 64 | static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, |
63 | *dev, uint8_t id) | 65 | uint8_t id) |
64 | { | 66 | { |
65 | struct radeon_device *rdev = dev->dev_private; | ||
66 | struct atom_context *ctx = rdev->mode_info.atom_context; | 67 | struct atom_context *ctx = rdev->mode_info.atom_context; |
67 | ATOM_GPIO_I2C_ASSIGMENT gpio; | 68 | ATOM_GPIO_I2C_ASSIGMENT *gpio; |
68 | struct radeon_i2c_bus_rec i2c; | 69 | struct radeon_i2c_bus_rec i2c; |
69 | int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); | 70 | int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); |
70 | struct _ATOM_GPIO_I2C_INFO *i2c_info; | 71 | struct _ATOM_GPIO_I2C_INFO *i2c_info; |
71 | uint16_t data_offset; | 72 | uint16_t data_offset; |
73 | int i; | ||
72 | 74 | ||
73 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); | 75 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); |
74 | i2c.valid = false; | 76 | i2c.valid = false; |
@@ -77,34 +79,121 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device | |||
77 | 79 | ||
78 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); | 80 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); |
79 | 81 | ||
80 | gpio = i2c_info->asGPIO_Info[id]; | 82 | |
81 | 83 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | |
82 | i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4; | 84 | gpio = &i2c_info->asGPIO_Info[i]; |
83 | i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4; | 85 | |
84 | i2c.put_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4; | 86 | if (gpio->sucI2cId.ucAccess == id) { |
85 | i2c.put_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4; | 87 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; |
86 | i2c.get_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4; | 88 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
87 | i2c.get_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4; | 89 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; |
88 | i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4; | 90 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; |
89 | i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4; | 91 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; |
90 | i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift); | 92 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; |
91 | i2c.mask_data_mask = (1 << gpio.ucDataMaskShift); | 93 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; |
92 | i2c.put_clk_mask = (1 << gpio.ucClkEnShift); | 94 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; |
93 | i2c.put_data_mask = (1 << gpio.ucDataEnShift); | 95 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); |
94 | i2c.get_clk_mask = (1 << gpio.ucClkY_Shift); | 96 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); |
95 | i2c.get_data_mask = (1 << gpio.ucDataY_Shift); | 97 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); |
96 | i2c.a_clk_mask = (1 << gpio.ucClkA_Shift); | 98 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); |
97 | i2c.a_data_mask = (1 << gpio.ucDataA_Shift); | 99 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); |
98 | i2c.valid = true; | 100 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); |
101 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); | ||
102 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); | ||
103 | |||
104 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | ||
105 | i2c.hw_capable = true; | ||
106 | else | ||
107 | i2c.hw_capable = false; | ||
108 | |||
109 | if (gpio->sucI2cId.ucAccess == 0xa0) | ||
110 | i2c.mm_i2c = true; | ||
111 | else | ||
112 | i2c.mm_i2c = false; | ||
113 | |||
114 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | ||
115 | |||
116 | i2c.valid = true; | ||
117 | } | ||
118 | } | ||
99 | 119 | ||
100 | return i2c; | 120 | return i2c; |
101 | } | 121 | } |
102 | 122 | ||
123 | static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev, | ||
124 | u8 id) | ||
125 | { | ||
126 | struct atom_context *ctx = rdev->mode_info.atom_context; | ||
127 | struct radeon_gpio_rec gpio; | ||
128 | int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT); | ||
129 | struct _ATOM_GPIO_PIN_LUT *gpio_info; | ||
130 | ATOM_GPIO_PIN_ASSIGNMENT *pin; | ||
131 | u16 data_offset, size; | ||
132 | int i, num_indices; | ||
133 | |||
134 | memset(&gpio, 0, sizeof(struct radeon_gpio_rec)); | ||
135 | gpio.valid = false; | ||
136 | |||
137 | atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset); | ||
138 | |||
139 | gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset); | ||
140 | |||
141 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT); | ||
142 | |||
143 | for (i = 0; i < num_indices; i++) { | ||
144 | pin = &gpio_info->asGPIO_Pin[i]; | ||
145 | if (id == pin->ucGPIO_ID) { | ||
146 | gpio.id = pin->ucGPIO_ID; | ||
147 | gpio.reg = pin->usGpioPin_AIndex * 4; | ||
148 | gpio.mask = (1 << pin->ucGpioPinBitShift); | ||
149 | gpio.valid = true; | ||
150 | break; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | return gpio; | ||
155 | } | ||
156 | |||
157 | static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev, | ||
158 | struct radeon_gpio_rec *gpio) | ||
159 | { | ||
160 | struct radeon_hpd hpd; | ||
161 | hpd.gpio = *gpio; | ||
162 | if (gpio->reg == AVIVO_DC_GPIO_HPD_A) { | ||
163 | switch(gpio->mask) { | ||
164 | case (1 << 0): | ||
165 | hpd.hpd = RADEON_HPD_1; | ||
166 | break; | ||
167 | case (1 << 8): | ||
168 | hpd.hpd = RADEON_HPD_2; | ||
169 | break; | ||
170 | case (1 << 16): | ||
171 | hpd.hpd = RADEON_HPD_3; | ||
172 | break; | ||
173 | case (1 << 24): | ||
174 | hpd.hpd = RADEON_HPD_4; | ||
175 | break; | ||
176 | case (1 << 26): | ||
177 | hpd.hpd = RADEON_HPD_5; | ||
178 | break; | ||
179 | case (1 << 28): | ||
180 | hpd.hpd = RADEON_HPD_6; | ||
181 | break; | ||
182 | default: | ||
183 | hpd.hpd = RADEON_HPD_NONE; | ||
184 | break; | ||
185 | } | ||
186 | } else | ||
187 | hpd.hpd = RADEON_HPD_NONE; | ||
188 | return hpd; | ||
189 | } | ||
190 | |||
103 | static bool radeon_atom_apply_quirks(struct drm_device *dev, | 191 | static bool radeon_atom_apply_quirks(struct drm_device *dev, |
104 | uint32_t supported_device, | 192 | uint32_t supported_device, |
105 | int *connector_type, | 193 | int *connector_type, |
106 | struct radeon_i2c_bus_rec *i2c_bus, | 194 | struct radeon_i2c_bus_rec *i2c_bus, |
107 | uint16_t *line_mux) | 195 | uint16_t *line_mux, |
196 | struct radeon_hpd *hpd) | ||
108 | { | 197 | { |
109 | 198 | ||
110 | /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ | 199 | /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ |
@@ -134,6 +223,23 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
134 | } | 223 | } |
135 | } | 224 | } |
136 | 225 | ||
226 | /* HIS X1300 is DVI+VGA, not DVI+DVI */ | ||
227 | if ((dev->pdev->device == 0x7146) && | ||
228 | (dev->pdev->subsystem_vendor == 0x17af) && | ||
229 | (dev->pdev->subsystem_device == 0x2058)) { | ||
230 | if (supported_device == ATOM_DEVICE_DFP1_SUPPORT) | ||
231 | return false; | ||
232 | } | ||
233 | |||
234 | /* Gigabyte X1300 is DVI+VGA, not DVI+DVI */ | ||
235 | if ((dev->pdev->device == 0x7142) && | ||
236 | (dev->pdev->subsystem_vendor == 0x1458) && | ||
237 | (dev->pdev->subsystem_device == 0x2134)) { | ||
238 | if (supported_device == ATOM_DEVICE_DFP1_SUPPORT) | ||
239 | return false; | ||
240 | } | ||
241 | |||
242 | |||
137 | /* Funky macbooks */ | 243 | /* Funky macbooks */ |
138 | if ((dev->pdev->device == 0x71C5) && | 244 | if ((dev->pdev->device == 0x71C5) && |
139 | (dev->pdev->subsystem_vendor == 0x106b) && | 245 | (dev->pdev->subsystem_vendor == 0x106b) && |
@@ -171,6 +277,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
171 | } | 277 | } |
172 | } | 278 | } |
173 | 279 | ||
280 | /* Acer laptop reports DVI-D as DVI-I */ | ||
281 | if ((dev->pdev->device == 0x95c4) && | ||
282 | (dev->pdev->subsystem_vendor == 0x1025) && | ||
283 | (dev->pdev->subsystem_device == 0x013c)) { | ||
284 | if ((*connector_type == DRM_MODE_CONNECTOR_DVII) && | ||
285 | (supported_device == ATOM_DEVICE_DFP1_SUPPORT)) | ||
286 | *connector_type = DRM_MODE_CONNECTOR_DVID; | ||
287 | } | ||
288 | |||
174 | return true; | 289 | return true; |
175 | } | 290 | } |
176 | 291 | ||
@@ -193,6 +308,23 @@ const int supported_devices_connector_convert[] = { | |||
193 | DRM_MODE_CONNECTOR_DisplayPort | 308 | DRM_MODE_CONNECTOR_DisplayPort |
194 | }; | 309 | }; |
195 | 310 | ||
311 | const uint16_t supported_devices_connector_object_id_convert[] = { | ||
312 | CONNECTOR_OBJECT_ID_NONE, | ||
313 | CONNECTOR_OBJECT_ID_VGA, | ||
314 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, /* not all boards support DL */ | ||
315 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D, /* not all boards support DL */ | ||
316 | CONNECTOR_OBJECT_ID_VGA, /* technically DVI-A */ | ||
317 | CONNECTOR_OBJECT_ID_COMPOSITE, | ||
318 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
319 | CONNECTOR_OBJECT_ID_LVDS, | ||
320 | CONNECTOR_OBJECT_ID_9PIN_DIN, | ||
321 | CONNECTOR_OBJECT_ID_9PIN_DIN, | ||
322 | CONNECTOR_OBJECT_ID_DISPLAYPORT, | ||
323 | CONNECTOR_OBJECT_ID_HDMI_TYPE_A, | ||
324 | CONNECTOR_OBJECT_ID_HDMI_TYPE_B, | ||
325 | CONNECTOR_OBJECT_ID_SVIDEO | ||
326 | }; | ||
327 | |||
196 | const int object_connector_convert[] = { | 328 | const int object_connector_convert[] = { |
197 | DRM_MODE_CONNECTOR_Unknown, | 329 | DRM_MODE_CONNECTOR_Unknown, |
198 | DRM_MODE_CONNECTOR_DVII, | 330 | DRM_MODE_CONNECTOR_DVII, |
@@ -222,16 +354,18 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
222 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 354 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
223 | struct atom_context *ctx = mode_info->atom_context; | 355 | struct atom_context *ctx = mode_info->atom_context; |
224 | int index = GetIndexIntoMasterTable(DATA, Object_Header); | 356 | int index = GetIndexIntoMasterTable(DATA, Object_Header); |
225 | uint16_t size, data_offset; | 357 | u16 size, data_offset; |
226 | uint8_t frev, crev, line_mux = 0; | 358 | u8 frev, crev; |
227 | ATOM_CONNECTOR_OBJECT_TABLE *con_obj; | 359 | ATOM_CONNECTOR_OBJECT_TABLE *con_obj; |
228 | ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; | 360 | ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; |
229 | ATOM_OBJECT_HEADER *obj_header; | 361 | ATOM_OBJECT_HEADER *obj_header; |
230 | int i, j, path_size, device_support; | 362 | int i, j, path_size, device_support; |
231 | int connector_type; | 363 | int connector_type; |
232 | uint16_t igp_lane_info, conn_id; | 364 | u16 igp_lane_info, conn_id, connector_object_id; |
233 | bool linkb; | 365 | bool linkb; |
234 | struct radeon_i2c_bus_rec ddc_bus; | 366 | struct radeon_i2c_bus_rec ddc_bus; |
367 | struct radeon_gpio_rec gpio; | ||
368 | struct radeon_hpd hpd; | ||
235 | 369 | ||
236 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | 370 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); |
237 | 371 | ||
@@ -258,7 +392,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
258 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; | 392 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; |
259 | path_size += le16_to_cpu(path->usSize); | 393 | path_size += le16_to_cpu(path->usSize); |
260 | linkb = false; | 394 | linkb = false; |
261 | |||
262 | if (device_support & le16_to_cpu(path->usDeviceTag)) { | 395 | if (device_support & le16_to_cpu(path->usDeviceTag)) { |
263 | uint8_t con_obj_id, con_obj_num, con_obj_type; | 396 | uint8_t con_obj_id, con_obj_num, con_obj_type; |
264 | 397 | ||
@@ -277,7 +410,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
277 | ATOM_DEVICE_CV_SUPPORT) | 410 | ATOM_DEVICE_CV_SUPPORT) |
278 | continue; | 411 | continue; |
279 | 412 | ||
280 | if ((rdev->family == CHIP_RS780) && | 413 | /* IGP chips */ |
414 | if ((rdev->flags & RADEON_IS_IGP) && | ||
281 | (con_obj_id == | 415 | (con_obj_id == |
282 | CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) { | 416 | CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) { |
283 | uint16_t igp_offset = 0; | 417 | uint16_t igp_offset = 0; |
@@ -311,6 +445,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
311 | connector_type = | 445 | connector_type = |
312 | object_connector_convert | 446 | object_connector_convert |
313 | [ct]; | 447 | [ct]; |
448 | connector_object_id = ct; | ||
314 | igp_lane_info = | 449 | igp_lane_info = |
315 | slot_config & 0xffff; | 450 | slot_config & 0xffff; |
316 | } else | 451 | } else |
@@ -321,6 +456,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
321 | igp_lane_info = 0; | 456 | igp_lane_info = 0; |
322 | connector_type = | 457 | connector_type = |
323 | object_connector_convert[con_obj_id]; | 458 | object_connector_convert[con_obj_id]; |
459 | connector_object_id = con_obj_id; | ||
324 | } | 460 | } |
325 | 461 | ||
326 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) | 462 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
@@ -356,10 +492,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
356 | } | 492 | } |
357 | } | 493 | } |
358 | 494 | ||
359 | /* look up gpio for ddc */ | 495 | /* look up gpio for ddc, hpd */ |
360 | if ((le16_to_cpu(path->usDeviceTag) & | 496 | if ((le16_to_cpu(path->usDeviceTag) & |
361 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | 497 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) { |
362 | == 0) { | ||
363 | for (j = 0; j < con_obj->ucNumberOfObjects; j++) { | 498 | for (j = 0; j < con_obj->ucNumberOfObjects; j++) { |
364 | if (le16_to_cpu(path->usConnObjectId) == | 499 | if (le16_to_cpu(path->usConnObjectId) == |
365 | le16_to_cpu(con_obj->asObjects[j]. | 500 | le16_to_cpu(con_obj->asObjects[j]. |
@@ -373,21 +508,34 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
373 | asObjects[j]. | 508 | asObjects[j]. |
374 | usRecordOffset)); | 509 | usRecordOffset)); |
375 | ATOM_I2C_RECORD *i2c_record; | 510 | ATOM_I2C_RECORD *i2c_record; |
511 | ATOM_HPD_INT_RECORD *hpd_record; | ||
512 | ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; | ||
513 | hpd.hpd = RADEON_HPD_NONE; | ||
376 | 514 | ||
377 | while (record->ucRecordType > 0 | 515 | while (record->ucRecordType > 0 |
378 | && record-> | 516 | && record-> |
379 | ucRecordType <= | 517 | ucRecordType <= |
380 | ATOM_MAX_OBJECT_RECORD_NUMBER) { | 518 | ATOM_MAX_OBJECT_RECORD_NUMBER) { |
381 | switch (record-> | 519 | switch (record->ucRecordType) { |
382 | ucRecordType) { | ||
383 | case ATOM_I2C_RECORD_TYPE: | 520 | case ATOM_I2C_RECORD_TYPE: |
384 | i2c_record = | 521 | i2c_record = |
385 | (ATOM_I2C_RECORD | 522 | (ATOM_I2C_RECORD *) |
386 | *) record; | 523 | record; |
387 | line_mux = | 524 | i2c_config = |
388 | i2c_record-> | 525 | (ATOM_I2C_ID_CONFIG_ACCESS *) |
389 | sucI2cId. | 526 | &i2c_record->sucI2cId; |
390 | bfI2C_LineMux; | 527 | ddc_bus = radeon_lookup_i2c_gpio(rdev, |
528 | i2c_config-> | ||
529 | ucAccess); | ||
530 | break; | ||
531 | case ATOM_HPD_INT_RECORD_TYPE: | ||
532 | hpd_record = | ||
533 | (ATOM_HPD_INT_RECORD *) | ||
534 | record; | ||
535 | gpio = radeon_lookup_gpio(rdev, | ||
536 | hpd_record->ucHPDIntGPIOID); | ||
537 | hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio); | ||
538 | hpd.plugged_state = hpd_record->ucPlugged_PinState; | ||
391 | break; | 539 | break; |
392 | } | 540 | } |
393 | record = | 541 | record = |
@@ -400,24 +548,16 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
400 | break; | 548 | break; |
401 | } | 549 | } |
402 | } | 550 | } |
403 | } else | 551 | } else { |
404 | line_mux = 0; | 552 | hpd.hpd = RADEON_HPD_NONE; |
405 | |||
406 | if ((le16_to_cpu(path->usDeviceTag) == | ||
407 | ATOM_DEVICE_TV1_SUPPORT) | ||
408 | || (le16_to_cpu(path->usDeviceTag) == | ||
409 | ATOM_DEVICE_TV2_SUPPORT) | ||
410 | || (le16_to_cpu(path->usDeviceTag) == | ||
411 | ATOM_DEVICE_CV_SUPPORT)) | ||
412 | ddc_bus.valid = false; | 553 | ddc_bus.valid = false; |
413 | else | 554 | } |
414 | ddc_bus = radeon_lookup_gpio(dev, line_mux); | ||
415 | 555 | ||
416 | conn_id = le16_to_cpu(path->usConnObjectId); | 556 | conn_id = le16_to_cpu(path->usConnObjectId); |
417 | 557 | ||
418 | if (!radeon_atom_apply_quirks | 558 | if (!radeon_atom_apply_quirks |
419 | (dev, le16_to_cpu(path->usDeviceTag), &connector_type, | 559 | (dev, le16_to_cpu(path->usDeviceTag), &connector_type, |
420 | &ddc_bus, &conn_id)) | 560 | &ddc_bus, &conn_id, &hpd)) |
421 | continue; | 561 | continue; |
422 | 562 | ||
423 | radeon_add_atom_connector(dev, | 563 | radeon_add_atom_connector(dev, |
@@ -425,7 +565,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
425 | le16_to_cpu(path-> | 565 | le16_to_cpu(path-> |
426 | usDeviceTag), | 566 | usDeviceTag), |
427 | connector_type, &ddc_bus, | 567 | connector_type, &ddc_bus, |
428 | linkb, igp_lane_info); | 568 | linkb, igp_lane_info, |
569 | connector_object_id, | ||
570 | &hpd); | ||
429 | 571 | ||
430 | } | 572 | } |
431 | } | 573 | } |
@@ -435,12 +577,52 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
435 | return true; | 577 | return true; |
436 | } | 578 | } |
437 | 579 | ||
580 | static uint16_t atombios_get_connector_object_id(struct drm_device *dev, | ||
581 | int connector_type, | ||
582 | uint16_t devices) | ||
583 | { | ||
584 | struct radeon_device *rdev = dev->dev_private; | ||
585 | |||
586 | if (rdev->flags & RADEON_IS_IGP) { | ||
587 | return supported_devices_connector_object_id_convert | ||
588 | [connector_type]; | ||
589 | } else if (((connector_type == DRM_MODE_CONNECTOR_DVII) || | ||
590 | (connector_type == DRM_MODE_CONNECTOR_DVID)) && | ||
591 | (devices & ATOM_DEVICE_DFP2_SUPPORT)) { | ||
592 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
593 | struct atom_context *ctx = mode_info->atom_context; | ||
594 | int index = GetIndexIntoMasterTable(DATA, XTMDS_Info); | ||
595 | uint16_t size, data_offset; | ||
596 | uint8_t frev, crev; | ||
597 | ATOM_XTMDS_INFO *xtmds; | ||
598 | |||
599 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | ||
600 | xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset); | ||
601 | |||
602 | if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) { | ||
603 | if (connector_type == DRM_MODE_CONNECTOR_DVII) | ||
604 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; | ||
605 | else | ||
606 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; | ||
607 | } else { | ||
608 | if (connector_type == DRM_MODE_CONNECTOR_DVII) | ||
609 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; | ||
610 | else | ||
611 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; | ||
612 | } | ||
613 | } else { | ||
614 | return supported_devices_connector_object_id_convert | ||
615 | [connector_type]; | ||
616 | } | ||
617 | } | ||
618 | |||
438 | struct bios_connector { | 619 | struct bios_connector { |
439 | bool valid; | 620 | bool valid; |
440 | uint16_t line_mux; | 621 | uint16_t line_mux; |
441 | uint16_t devices; | 622 | uint16_t devices; |
442 | int connector_type; | 623 | int connector_type; |
443 | struct radeon_i2c_bus_rec ddc_bus; | 624 | struct radeon_i2c_bus_rec ddc_bus; |
625 | struct radeon_hpd hpd; | ||
444 | }; | 626 | }; |
445 | 627 | ||
446 | bool radeon_get_atom_connector_info_from_supported_devices_table(struct | 628 | bool radeon_get_atom_connector_info_from_supported_devices_table(struct |
@@ -456,7 +638,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
456 | uint16_t device_support; | 638 | uint16_t device_support; |
457 | uint8_t dac; | 639 | uint8_t dac; |
458 | union atom_supported_devices *supported_devices; | 640 | union atom_supported_devices *supported_devices; |
459 | int i, j; | 641 | int i, j, max_device; |
460 | struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; | 642 | struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; |
461 | 643 | ||
462 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | 644 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); |
@@ -466,7 +648,12 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
466 | 648 | ||
467 | device_support = le16_to_cpu(supported_devices->info.usDeviceSupport); | 649 | device_support = le16_to_cpu(supported_devices->info.usDeviceSupport); |
468 | 650 | ||
469 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 651 | if (frev > 1) |
652 | max_device = ATOM_MAX_SUPPORTED_DEVICE; | ||
653 | else | ||
654 | max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO; | ||
655 | |||
656 | for (i = 0; i < max_device; i++) { | ||
470 | ATOM_CONNECTOR_INFO_I2C ci = | 657 | ATOM_CONNECTOR_INFO_I2C ci = |
471 | supported_devices->info.asConnInfo[i]; | 658 | supported_devices->info.asConnInfo[i]; |
472 | 659 | ||
@@ -492,22 +679,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
492 | 679 | ||
493 | dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC; | 680 | dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC; |
494 | 681 | ||
495 | if ((rdev->family == CHIP_RS690) || | 682 | bios_connectors[i].line_mux = |
496 | (rdev->family == CHIP_RS740)) { | 683 | ci.sucI2cId.ucAccess; |
497 | if ((i == ATOM_DEVICE_DFP2_INDEX) | ||
498 | && (ci.sucI2cId.sbfAccess.bfI2C_LineMux == 2)) | ||
499 | bios_connectors[i].line_mux = | ||
500 | ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1; | ||
501 | else if ((i == ATOM_DEVICE_DFP3_INDEX) | ||
502 | && (ci.sucI2cId.sbfAccess.bfI2C_LineMux == 1)) | ||
503 | bios_connectors[i].line_mux = | ||
504 | ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1; | ||
505 | else | ||
506 | bios_connectors[i].line_mux = | ||
507 | ci.sucI2cId.sbfAccess.bfI2C_LineMux; | ||
508 | } else | ||
509 | bios_connectors[i].line_mux = | ||
510 | ci.sucI2cId.sbfAccess.bfI2C_LineMux; | ||
511 | 684 | ||
512 | /* give tv unique connector ids */ | 685 | /* give tv unique connector ids */ |
513 | if (i == ATOM_DEVICE_TV1_INDEX) { | 686 | if (i == ATOM_DEVICE_TV1_INDEX) { |
@@ -521,8 +694,30 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
521 | bios_connectors[i].line_mux = 52; | 694 | bios_connectors[i].line_mux = 52; |
522 | } else | 695 | } else |
523 | bios_connectors[i].ddc_bus = | 696 | bios_connectors[i].ddc_bus = |
524 | radeon_lookup_gpio(dev, | 697 | radeon_lookup_i2c_gpio(rdev, |
525 | bios_connectors[i].line_mux); | 698 | bios_connectors[i].line_mux); |
699 | |||
700 | if ((crev > 1) && (frev > 1)) { | ||
701 | u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap; | ||
702 | switch (isb) { | ||
703 | case 0x4: | ||
704 | bios_connectors[i].hpd.hpd = RADEON_HPD_1; | ||
705 | break; | ||
706 | case 0xa: | ||
707 | bios_connectors[i].hpd.hpd = RADEON_HPD_2; | ||
708 | break; | ||
709 | default: | ||
710 | bios_connectors[i].hpd.hpd = RADEON_HPD_NONE; | ||
711 | break; | ||
712 | } | ||
713 | } else { | ||
714 | if (i == ATOM_DEVICE_DFP1_INDEX) | ||
715 | bios_connectors[i].hpd.hpd = RADEON_HPD_1; | ||
716 | else if (i == ATOM_DEVICE_DFP2_INDEX) | ||
717 | bios_connectors[i].hpd.hpd = RADEON_HPD_2; | ||
718 | else | ||
719 | bios_connectors[i].hpd.hpd = RADEON_HPD_NONE; | ||
720 | } | ||
526 | 721 | ||
527 | /* Always set the connector type to VGA for CRT1/CRT2. if they are | 722 | /* Always set the connector type to VGA for CRT1/CRT2. if they are |
528 | * shared with a DVI port, we'll pick up the DVI connector when we | 723 | * shared with a DVI port, we'll pick up the DVI connector when we |
@@ -534,7 +729,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
534 | 729 | ||
535 | if (!radeon_atom_apply_quirks | 730 | if (!radeon_atom_apply_quirks |
536 | (dev, (1 << i), &bios_connectors[i].connector_type, | 731 | (dev, (1 << i), &bios_connectors[i].connector_type, |
537 | &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux)) | 732 | &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux, |
733 | &bios_connectors[i].hpd)) | ||
538 | continue; | 734 | continue; |
539 | 735 | ||
540 | bios_connectors[i].valid = true; | 736 | bios_connectors[i].valid = true; |
@@ -556,9 +752,9 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
556 | } | 752 | } |
557 | 753 | ||
558 | /* combine shared connectors */ | 754 | /* combine shared connectors */ |
559 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 755 | for (i = 0; i < max_device; i++) { |
560 | if (bios_connectors[i].valid) { | 756 | if (bios_connectors[i].valid) { |
561 | for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) { | 757 | for (j = 0; j < max_device; j++) { |
562 | if (bios_connectors[j].valid && (i != j)) { | 758 | if (bios_connectors[j].valid && (i != j)) { |
563 | if (bios_connectors[i].line_mux == | 759 | if (bios_connectors[i].line_mux == |
564 | bios_connectors[j].line_mux) { | 760 | bios_connectors[j].line_mux) { |
@@ -582,6 +778,10 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
582 | bios_connectors[i]. | 778 | bios_connectors[i]. |
583 | connector_type = | 779 | connector_type = |
584 | DRM_MODE_CONNECTOR_DVII; | 780 | DRM_MODE_CONNECTOR_DVII; |
781 | if (bios_connectors[j].devices & | ||
782 | (ATOM_DEVICE_DFP_SUPPORT)) | ||
783 | bios_connectors[i].hpd = | ||
784 | bios_connectors[j].hpd; | ||
585 | bios_connectors[j]. | 785 | bios_connectors[j]. |
586 | valid = false; | 786 | valid = false; |
587 | } | 787 | } |
@@ -592,15 +792,22 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
592 | } | 792 | } |
593 | 793 | ||
594 | /* add the connectors */ | 794 | /* add the connectors */ |
595 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 795 | for (i = 0; i < max_device; i++) { |
596 | if (bios_connectors[i].valid) | 796 | if (bios_connectors[i].valid) { |
797 | uint16_t connector_object_id = | ||
798 | atombios_get_connector_object_id(dev, | ||
799 | bios_connectors[i].connector_type, | ||
800 | bios_connectors[i].devices); | ||
597 | radeon_add_atom_connector(dev, | 801 | radeon_add_atom_connector(dev, |
598 | bios_connectors[i].line_mux, | 802 | bios_connectors[i].line_mux, |
599 | bios_connectors[i].devices, | 803 | bios_connectors[i].devices, |
600 | bios_connectors[i]. | 804 | bios_connectors[i]. |
601 | connector_type, | 805 | connector_type, |
602 | &bios_connectors[i].ddc_bus, | 806 | &bios_connectors[i].ddc_bus, |
603 | false, 0); | 807 | false, 0, |
808 | connector_object_id, | ||
809 | &bios_connectors[i].hpd); | ||
810 | } | ||
604 | } | 811 | } |
605 | 812 | ||
606 | radeon_link_encoder_connector(dev); | 813 | radeon_link_encoder_connector(dev); |
@@ -641,8 +848,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
641 | le16_to_cpu(firmware_info->info.usReferenceClock); | 848 | le16_to_cpu(firmware_info->info.usReferenceClock); |
642 | p1pll->reference_div = 0; | 849 | p1pll->reference_div = 0; |
643 | 850 | ||
644 | p1pll->pll_out_min = | 851 | if (crev < 2) |
645 | le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output); | 852 | p1pll->pll_out_min = |
853 | le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output); | ||
854 | else | ||
855 | p1pll->pll_out_min = | ||
856 | le32_to_cpu(firmware_info->info_12.ulMinPixelClockPLL_Output); | ||
646 | p1pll->pll_out_max = | 857 | p1pll->pll_out_max = |
647 | le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); | 858 | le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); |
648 | 859 | ||
@@ -651,6 +862,17 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
651 | p1pll->pll_out_min = 64800; | 862 | p1pll->pll_out_min = 64800; |
652 | else | 863 | else |
653 | p1pll->pll_out_min = 20000; | 864 | p1pll->pll_out_min = 20000; |
865 | } else if (p1pll->pll_out_min > 64800) { | ||
866 | /* Limiting the pll output range is a good thing generally as | ||
867 | * it limits the number of possible pll combinations for a given | ||
868 | * frequency presumably to the ones that work best on each card. | ||
869 | * However, certain duallink DVI monitors seem to like | ||
870 | * pll combinations that would be limited by this at least on | ||
871 | * pre-DCE 3.0 r6xx hardware. This might need to be adjusted per | ||
872 | * family. | ||
873 | */ | ||
874 | if (!radeon_new_pll) | ||
875 | p1pll->pll_out_min = 64800; | ||
654 | } | 876 | } |
655 | 877 | ||
656 | p1pll->pll_in_min = | 878 | p1pll->pll_in_min = |
@@ -767,6 +989,52 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, | |||
767 | return false; | 989 | return false; |
768 | } | 990 | } |
769 | 991 | ||
992 | static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct | ||
993 | radeon_encoder | ||
994 | *encoder, | ||
995 | int id) | ||
996 | { | ||
997 | struct drm_device *dev = encoder->base.dev; | ||
998 | struct radeon_device *rdev = dev->dev_private; | ||
999 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
1000 | int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info); | ||
1001 | uint16_t data_offset; | ||
1002 | struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info; | ||
1003 | uint8_t frev, crev; | ||
1004 | struct radeon_atom_ss *ss = NULL; | ||
1005 | int i; | ||
1006 | |||
1007 | if (id > ATOM_MAX_SS_ENTRY) | ||
1008 | return NULL; | ||
1009 | |||
1010 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, | ||
1011 | &crev, &data_offset); | ||
1012 | |||
1013 | ss_info = | ||
1014 | (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset); | ||
1015 | |||
1016 | if (ss_info) { | ||
1017 | ss = | ||
1018 | kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL); | ||
1019 | |||
1020 | if (!ss) | ||
1021 | return NULL; | ||
1022 | |||
1023 | for (i = 0; i < ATOM_MAX_SS_ENTRY; i++) { | ||
1024 | if (ss_info->asSS_Info[i].ucSS_Id == id) { | ||
1025 | ss->percentage = | ||
1026 | le16_to_cpu(ss_info->asSS_Info[i].usSpreadSpectrumPercentage); | ||
1027 | ss->type = ss_info->asSS_Info[i].ucSpreadSpectrumType; | ||
1028 | ss->step = ss_info->asSS_Info[i].ucSS_Step; | ||
1029 | ss->delay = ss_info->asSS_Info[i].ucSS_Delay; | ||
1030 | ss->range = ss_info->asSS_Info[i].ucSS_Range; | ||
1031 | ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div; | ||
1032 | } | ||
1033 | } | ||
1034 | } | ||
1035 | return ss; | ||
1036 | } | ||
1037 | |||
770 | union lvds_info { | 1038 | union lvds_info { |
771 | struct _ATOM_LVDS_INFO info; | 1039 | struct _ATOM_LVDS_INFO info; |
772 | struct _ATOM_LVDS_INFO_V12 info_12; | 1040 | struct _ATOM_LVDS_INFO_V12 info_12; |
@@ -780,7 +1048,7 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
780 | struct radeon_device *rdev = dev->dev_private; | 1048 | struct radeon_device *rdev = dev->dev_private; |
781 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 1049 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
782 | int index = GetIndexIntoMasterTable(DATA, LVDS_Info); | 1050 | int index = GetIndexIntoMasterTable(DATA, LVDS_Info); |
783 | uint16_t data_offset; | 1051 | uint16_t data_offset, misc; |
784 | union lvds_info *lvds_info; | 1052 | union lvds_info *lvds_info; |
785 | uint8_t frev, crev; | 1053 | uint8_t frev, crev; |
786 | struct radeon_encoder_atom_dig *lvds = NULL; | 1054 | struct radeon_encoder_atom_dig *lvds = NULL; |
@@ -798,28 +1066,45 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
798 | if (!lvds) | 1066 | if (!lvds) |
799 | return NULL; | 1067 | return NULL; |
800 | 1068 | ||
801 | lvds->native_mode.dotclock = | 1069 | lvds->native_mode.clock = |
802 | le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10; | 1070 | le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10; |
803 | lvds->native_mode.panel_xres = | 1071 | lvds->native_mode.hdisplay = |
804 | le16_to_cpu(lvds_info->info.sLCDTiming.usHActive); | 1072 | le16_to_cpu(lvds_info->info.sLCDTiming.usHActive); |
805 | lvds->native_mode.panel_yres = | 1073 | lvds->native_mode.vdisplay = |
806 | le16_to_cpu(lvds_info->info.sLCDTiming.usVActive); | 1074 | le16_to_cpu(lvds_info->info.sLCDTiming.usVActive); |
807 | lvds->native_mode.hblank = | 1075 | lvds->native_mode.htotal = lvds->native_mode.hdisplay + |
808 | le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time); | 1076 | le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time); |
809 | lvds->native_mode.hoverplus = | 1077 | lvds->native_mode.hsync_start = lvds->native_mode.hdisplay + |
810 | le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset); | 1078 | le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset); |
811 | lvds->native_mode.hsync_width = | 1079 | lvds->native_mode.hsync_end = lvds->native_mode.hsync_start + |
812 | le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth); | 1080 | le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth); |
813 | lvds->native_mode.vblank = | 1081 | lvds->native_mode.vtotal = lvds->native_mode.vdisplay + |
814 | le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time); | 1082 | le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time); |
815 | lvds->native_mode.voverplus = | 1083 | lvds->native_mode.vsync_start = lvds->native_mode.vdisplay + |
816 | le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset); | 1084 | le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); |
817 | lvds->native_mode.vsync_width = | 1085 | lvds->native_mode.vsync_end = lvds->native_mode.vsync_start + |
818 | le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); | 1086 | le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); |
819 | lvds->panel_pwr_delay = | 1087 | lvds->panel_pwr_delay = |
820 | le16_to_cpu(lvds_info->info.usOffDelayInMs); | 1088 | le16_to_cpu(lvds_info->info.usOffDelayInMs); |
821 | lvds->lvds_misc = lvds_info->info.ucLVDS_Misc; | 1089 | lvds->lvds_misc = lvds_info->info.ucLVDS_Misc; |
822 | 1090 | ||
1091 | misc = le16_to_cpu(lvds_info->info.sLCDTiming.susModeMiscInfo.usAccess); | ||
1092 | if (misc & ATOM_VSYNC_POLARITY) | ||
1093 | lvds->native_mode.flags |= DRM_MODE_FLAG_NVSYNC; | ||
1094 | if (misc & ATOM_HSYNC_POLARITY) | ||
1095 | lvds->native_mode.flags |= DRM_MODE_FLAG_NHSYNC; | ||
1096 | if (misc & ATOM_COMPOSITESYNC) | ||
1097 | lvds->native_mode.flags |= DRM_MODE_FLAG_CSYNC; | ||
1098 | if (misc & ATOM_INTERLACE) | ||
1099 | lvds->native_mode.flags |= DRM_MODE_FLAG_INTERLACE; | ||
1100 | if (misc & ATOM_DOUBLE_CLOCK_MODE) | ||
1101 | lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN; | ||
1102 | |||
1103 | /* set crtc values */ | ||
1104 | drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); | ||
1105 | |||
1106 | lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id); | ||
1107 | |||
823 | encoder->native_mode = lvds->native_mode; | 1108 | encoder->native_mode = lvds->native_mode; |
824 | } | 1109 | } |
825 | return lvds; | 1110 | return lvds; |
@@ -857,8 +1142,7 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder) | |||
857 | } | 1142 | } |
858 | 1143 | ||
859 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | 1144 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, |
860 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, | 1145 | struct drm_display_mode *mode) |
861 | int32_t *pixel_clock) | ||
862 | { | 1146 | { |
863 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 1147 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
864 | ATOM_ANALOG_TV_INFO *tv_info; | 1148 | ATOM_ANALOG_TV_INFO *tv_info; |
@@ -866,7 +1150,7 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
866 | ATOM_DTD_FORMAT *dtd_timings; | 1150 | ATOM_DTD_FORMAT *dtd_timings; |
867 | int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); | 1151 | int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); |
868 | u8 frev, crev; | 1152 | u8 frev, crev; |
869 | uint16_t data_offset; | 1153 | u16 data_offset, misc; |
870 | 1154 | ||
871 | atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); | 1155 | atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); |
872 | 1156 | ||
@@ -876,28 +1160,37 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
876 | if (index > MAX_SUPPORTED_TV_TIMING) | 1160 | if (index > MAX_SUPPORTED_TV_TIMING) |
877 | return false; | 1161 | return false; |
878 | 1162 | ||
879 | crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); | 1163 | mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); |
880 | crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); | 1164 | mode->crtc_hdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); |
881 | crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); | 1165 | mode->crtc_hsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); |
882 | crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); | 1166 | mode->crtc_hsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart) + |
883 | 1167 | le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); | |
884 | crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); | 1168 | |
885 | crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); | 1169 | mode->crtc_vtotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); |
886 | crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); | 1170 | mode->crtc_vdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); |
887 | crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); | 1171 | mode->crtc_vsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); |
888 | 1172 | mode->crtc_vsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart) + | |
889 | crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo; | 1173 | le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); |
890 | 1174 | ||
891 | crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight); | 1175 | mode->flags = 0; |
892 | crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft); | 1176 | misc = le16_to_cpu(tv_info->aModeTimings[index].susModeMiscInfo.usAccess); |
893 | crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom); | 1177 | if (misc & ATOM_VSYNC_POLARITY) |
894 | crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop); | 1178 | mode->flags |= DRM_MODE_FLAG_NVSYNC; |
895 | *pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; | 1179 | if (misc & ATOM_HSYNC_POLARITY) |
1180 | mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
1181 | if (misc & ATOM_COMPOSITESYNC) | ||
1182 | mode->flags |= DRM_MODE_FLAG_CSYNC; | ||
1183 | if (misc & ATOM_INTERLACE) | ||
1184 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | ||
1185 | if (misc & ATOM_DOUBLE_CLOCK_MODE) | ||
1186 | mode->flags |= DRM_MODE_FLAG_DBLSCAN; | ||
1187 | |||
1188 | mode->clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; | ||
896 | 1189 | ||
897 | if (index == 1) { | 1190 | if (index == 1) { |
898 | /* PAL timings appear to have wrong values for totals */ | 1191 | /* PAL timings appear to have wrong values for totals */ |
899 | crtc_timing->usH_Total -= 1; | 1192 | mode->crtc_htotal -= 1; |
900 | crtc_timing->usV_Total -= 1; | 1193 | mode->crtc_vtotal -= 1; |
901 | } | 1194 | } |
902 | break; | 1195 | break; |
903 | case 2: | 1196 | case 2: |
@@ -906,17 +1199,36 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
906 | return false; | 1199 | return false; |
907 | 1200 | ||
908 | dtd_timings = &tv_info_v1_2->aModeTimings[index]; | 1201 | dtd_timings = &tv_info_v1_2->aModeTimings[index]; |
909 | crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time); | 1202 | mode->crtc_htotal = le16_to_cpu(dtd_timings->usHActive) + |
910 | crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive); | 1203 | le16_to_cpu(dtd_timings->usHBlanking_Time); |
911 | crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset); | 1204 | mode->crtc_hdisplay = le16_to_cpu(dtd_timings->usHActive); |
912 | crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth); | 1205 | mode->crtc_hsync_start = le16_to_cpu(dtd_timings->usHActive) + |
913 | crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time); | 1206 | le16_to_cpu(dtd_timings->usHSyncOffset); |
914 | crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive); | 1207 | mode->crtc_hsync_end = mode->crtc_hsync_start + |
915 | crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset); | 1208 | le16_to_cpu(dtd_timings->usHSyncWidth); |
916 | crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth); | 1209 | |
917 | 1210 | mode->crtc_vtotal = le16_to_cpu(dtd_timings->usVActive) + | |
918 | crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); | 1211 | le16_to_cpu(dtd_timings->usVBlanking_Time); |
919 | *pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10; | 1212 | mode->crtc_vdisplay = le16_to_cpu(dtd_timings->usVActive); |
1213 | mode->crtc_vsync_start = le16_to_cpu(dtd_timings->usVActive) + | ||
1214 | le16_to_cpu(dtd_timings->usVSyncOffset); | ||
1215 | mode->crtc_vsync_end = mode->crtc_vsync_start + | ||
1216 | le16_to_cpu(dtd_timings->usVSyncWidth); | ||
1217 | |||
1218 | mode->flags = 0; | ||
1219 | misc = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); | ||
1220 | if (misc & ATOM_VSYNC_POLARITY) | ||
1221 | mode->flags |= DRM_MODE_FLAG_NVSYNC; | ||
1222 | if (misc & ATOM_HSYNC_POLARITY) | ||
1223 | mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
1224 | if (misc & ATOM_COMPOSITESYNC) | ||
1225 | mode->flags |= DRM_MODE_FLAG_CSYNC; | ||
1226 | if (misc & ATOM_INTERLACE) | ||
1227 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | ||
1228 | if (misc & ATOM_DOUBLE_CLOCK_MODE) | ||
1229 | mode->flags |= DRM_MODE_FLAG_DBLSCAN; | ||
1230 | |||
1231 | mode->clock = le16_to_cpu(dtd_timings->usPixClk) * 10; | ||
920 | break; | 1232 | break; |
921 | } | 1233 | } |
922 | return true; | 1234 | return true; |
@@ -981,6 +1293,24 @@ void radeon_atom_static_pwrmgt_setup(struct radeon_device *rdev, int enable) | |||
981 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 1293 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
982 | } | 1294 | } |
983 | 1295 | ||
1296 | uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev) | ||
1297 | { | ||
1298 | GET_ENGINE_CLOCK_PS_ALLOCATION args; | ||
1299 | int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock); | ||
1300 | |||
1301 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1302 | return args.ulReturnEngineClock; | ||
1303 | } | ||
1304 | |||
1305 | uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev) | ||
1306 | { | ||
1307 | GET_MEMORY_CLOCK_PS_ALLOCATION args; | ||
1308 | int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock); | ||
1309 | |||
1310 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
1311 | return args.ulReturnMemoryClock; | ||
1312 | } | ||
1313 | |||
984 | void radeon_atom_set_engine_clock(struct radeon_device *rdev, | 1314 | void radeon_atom_set_engine_clock(struct radeon_device *rdev, |
985 | uint32_t eng_clock) | 1315 | uint32_t eng_clock) |
986 | { | 1316 | { |
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 2e938f7496fb..4ddfd4b5bc51 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c | |||
@@ -29,8 +29,8 @@ | |||
29 | void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, | 29 | void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, |
30 | unsigned sdomain, unsigned ddomain) | 30 | unsigned sdomain, unsigned ddomain) |
31 | { | 31 | { |
32 | struct radeon_object *dobj = NULL; | 32 | struct radeon_bo *dobj = NULL; |
33 | struct radeon_object *sobj = NULL; | 33 | struct radeon_bo *sobj = NULL; |
34 | struct radeon_fence *fence = NULL; | 34 | struct radeon_fence *fence = NULL; |
35 | uint64_t saddr, daddr; | 35 | uint64_t saddr, daddr; |
36 | unsigned long start_jiffies; | 36 | unsigned long start_jiffies; |
@@ -41,19 +41,27 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, | |||
41 | 41 | ||
42 | size = bsize; | 42 | size = bsize; |
43 | n = 1024; | 43 | n = 1024; |
44 | r = radeon_object_create(rdev, NULL, size, true, sdomain, false, &sobj); | 44 | r = radeon_bo_create(rdev, NULL, size, true, sdomain, &sobj); |
45 | if (r) { | 45 | if (r) { |
46 | goto out_cleanup; | 46 | goto out_cleanup; |
47 | } | 47 | } |
48 | r = radeon_object_pin(sobj, sdomain, &saddr); | 48 | r = radeon_bo_reserve(sobj, false); |
49 | if (unlikely(r != 0)) | ||
50 | goto out_cleanup; | ||
51 | r = radeon_bo_pin(sobj, sdomain, &saddr); | ||
52 | radeon_bo_unreserve(sobj); | ||
49 | if (r) { | 53 | if (r) { |
50 | goto out_cleanup; | 54 | goto out_cleanup; |
51 | } | 55 | } |
52 | r = radeon_object_create(rdev, NULL, size, true, ddomain, false, &dobj); | 56 | r = radeon_bo_create(rdev, NULL, size, true, ddomain, &dobj); |
53 | if (r) { | 57 | if (r) { |
54 | goto out_cleanup; | 58 | goto out_cleanup; |
55 | } | 59 | } |
56 | r = radeon_object_pin(dobj, ddomain, &daddr); | 60 | r = radeon_bo_reserve(dobj, false); |
61 | if (unlikely(r != 0)) | ||
62 | goto out_cleanup; | ||
63 | r = radeon_bo_pin(dobj, ddomain, &daddr); | ||
64 | radeon_bo_unreserve(dobj); | ||
57 | if (r) { | 65 | if (r) { |
58 | goto out_cleanup; | 66 | goto out_cleanup; |
59 | } | 67 | } |
@@ -63,7 +71,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, | |||
63 | if (r) { | 71 | if (r) { |
64 | goto out_cleanup; | 72 | goto out_cleanup; |
65 | } | 73 | } |
66 | r = radeon_copy_dma(rdev, saddr, daddr, size / 4096, fence); | 74 | r = radeon_copy_dma(rdev, saddr, daddr, size / RADEON_GPU_PAGE_SIZE, fence); |
67 | if (r) { | 75 | if (r) { |
68 | goto out_cleanup; | 76 | goto out_cleanup; |
69 | } | 77 | } |
@@ -88,7 +96,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, | |||
88 | if (r) { | 96 | if (r) { |
89 | goto out_cleanup; | 97 | goto out_cleanup; |
90 | } | 98 | } |
91 | r = radeon_copy_blit(rdev, saddr, daddr, size / 4096, fence); | 99 | r = radeon_copy_blit(rdev, saddr, daddr, size / RADEON_GPU_PAGE_SIZE, fence); |
92 | if (r) { | 100 | if (r) { |
93 | goto out_cleanup; | 101 | goto out_cleanup; |
94 | } | 102 | } |
@@ -109,12 +117,20 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, | |||
109 | } | 117 | } |
110 | out_cleanup: | 118 | out_cleanup: |
111 | if (sobj) { | 119 | if (sobj) { |
112 | radeon_object_unpin(sobj); | 120 | r = radeon_bo_reserve(sobj, false); |
113 | radeon_object_unref(&sobj); | 121 | if (likely(r == 0)) { |
122 | radeon_bo_unpin(sobj); | ||
123 | radeon_bo_unreserve(sobj); | ||
124 | } | ||
125 | radeon_bo_unref(&sobj); | ||
114 | } | 126 | } |
115 | if (dobj) { | 127 | if (dobj) { |
116 | radeon_object_unpin(dobj); | 128 | r = radeon_bo_reserve(dobj, false); |
117 | radeon_object_unref(&dobj); | 129 | if (likely(r == 0)) { |
130 | radeon_bo_unpin(dobj); | ||
131 | radeon_bo_unreserve(dobj); | ||
132 | } | ||
133 | radeon_bo_unref(&dobj); | ||
118 | } | 134 | } |
119 | if (fence) { | 135 | if (fence) { |
120 | radeon_fence_unref(&fence); | 136 | radeon_fence_unref(&fence); |
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 34a9b9119518..906921740c60 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
@@ -50,19 +50,16 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev) | |||
50 | vram_base = drm_get_resource_start(rdev->ddev, 0); | 50 | vram_base = drm_get_resource_start(rdev->ddev, 0); |
51 | bios = ioremap(vram_base, size); | 51 | bios = ioremap(vram_base, size); |
52 | if (!bios) { | 52 | if (!bios) { |
53 | DRM_ERROR("Unable to mmap vram\n"); | ||
54 | return false; | 53 | return false; |
55 | } | 54 | } |
56 | 55 | ||
57 | if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { | 56 | if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { |
58 | iounmap(bios); | 57 | iounmap(bios); |
59 | DRM_ERROR("bad rom signature\n"); | ||
60 | return false; | 58 | return false; |
61 | } | 59 | } |
62 | rdev->bios = kmalloc(size, GFP_KERNEL); | 60 | rdev->bios = kmalloc(size, GFP_KERNEL); |
63 | if (rdev->bios == NULL) { | 61 | if (rdev->bios == NULL) { |
64 | iounmap(bios); | 62 | iounmap(bios); |
65 | DRM_ERROR("kmalloc failed\n"); | ||
66 | return false; | 63 | return false; |
67 | } | 64 | } |
68 | memcpy(rdev->bios, bios, size); | 65 | memcpy(rdev->bios, bios, size); |
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index f5c32a766b10..b062109efbee 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include "atom.h" | 32 | #include "atom.h" |
33 | 33 | ||
34 | /* 10 khz */ | 34 | /* 10 khz */ |
35 | static uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) | 35 | uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) |
36 | { | 36 | { |
37 | struct radeon_pll *spll = &rdev->clock.spll; | 37 | struct radeon_pll *spll = &rdev->clock.spll; |
38 | uint32_t fb_div, ref_div, post_div, sclk; | 38 | uint32_t fb_div, ref_div, post_div, sclk; |
@@ -44,6 +44,10 @@ static uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) | |||
44 | 44 | ||
45 | ref_div = | 45 | ref_div = |
46 | RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; | 46 | RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; |
47 | |||
48 | if (ref_div == 0) | ||
49 | return 0; | ||
50 | |||
47 | sclk = fb_div / ref_div; | 51 | sclk = fb_div / ref_div; |
48 | 52 | ||
49 | post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK; | 53 | post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK; |
@@ -70,6 +74,10 @@ static uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) | |||
70 | 74 | ||
71 | ref_div = | 75 | ref_div = |
72 | RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; | 76 | RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; |
77 | |||
78 | if (ref_div == 0) | ||
79 | return 0; | ||
80 | |||
73 | mclk = fb_div / ref_div; | 81 | mclk = fb_div / ref_div; |
74 | 82 | ||
75 | post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7; | 83 | post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7; |
@@ -98,8 +106,19 @@ void radeon_get_clock_info(struct drm_device *dev) | |||
98 | ret = radeon_combios_get_clock_info(dev); | 106 | ret = radeon_combios_get_clock_info(dev); |
99 | 107 | ||
100 | if (ret) { | 108 | if (ret) { |
101 | if (p1pll->reference_div < 2) | 109 | if (p1pll->reference_div < 2) { |
102 | p1pll->reference_div = 12; | 110 | if (!ASIC_IS_AVIVO(rdev)) { |
111 | u32 tmp = RREG32_PLL(RADEON_PPLL_REF_DIV); | ||
112 | if (ASIC_IS_R300(rdev)) | ||
113 | p1pll->reference_div = | ||
114 | (tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT; | ||
115 | else | ||
116 | p1pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK; | ||
117 | if (p1pll->reference_div < 2) | ||
118 | p1pll->reference_div = 12; | ||
119 | } else | ||
120 | p1pll->reference_div = 12; | ||
121 | } | ||
103 | if (p2pll->reference_div < 2) | 122 | if (p2pll->reference_div < 2) |
104 | p2pll->reference_div = 12; | 123 | p2pll->reference_div = 12; |
105 | if (rdev->family < CHIP_RS600) { | 124 | if (rdev->family < CHIP_RS600) { |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 748265a105b3..c5021a3445de 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -49,7 +49,9 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
49 | uint32_t connector_id, | 49 | uint32_t connector_id, |
50 | uint32_t supported_device, | 50 | uint32_t supported_device, |
51 | int connector_type, | 51 | int connector_type, |
52 | struct radeon_i2c_bus_rec *i2c_bus); | 52 | struct radeon_i2c_bus_rec *i2c_bus, |
53 | uint16_t connector_object_id, | ||
54 | struct radeon_hpd *hpd); | ||
53 | 55 | ||
54 | /* from radeon_legacy_encoder.c */ | 56 | /* from radeon_legacy_encoder.c */ |
55 | extern void | 57 | extern void |
@@ -441,39 +443,71 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, | |||
441 | 443 | ||
442 | } | 444 | } |
443 | 445 | ||
444 | struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line) | 446 | static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev, |
447 | int ddc_line) | ||
445 | { | 448 | { |
446 | struct radeon_i2c_bus_rec i2c; | 449 | struct radeon_i2c_bus_rec i2c; |
447 | 450 | ||
448 | i2c.mask_clk_mask = RADEON_GPIO_EN_1; | 451 | if (ddc_line == RADEON_GPIOPAD_MASK) { |
449 | i2c.mask_data_mask = RADEON_GPIO_EN_0; | 452 | i2c.mask_clk_reg = RADEON_GPIOPAD_MASK; |
450 | i2c.a_clk_mask = RADEON_GPIO_A_1; | 453 | i2c.mask_data_reg = RADEON_GPIOPAD_MASK; |
451 | i2c.a_data_mask = RADEON_GPIO_A_0; | 454 | i2c.a_clk_reg = RADEON_GPIOPAD_A; |
452 | i2c.put_clk_mask = RADEON_GPIO_EN_1; | 455 | i2c.a_data_reg = RADEON_GPIOPAD_A; |
453 | i2c.put_data_mask = RADEON_GPIO_EN_0; | 456 | i2c.en_clk_reg = RADEON_GPIOPAD_EN; |
454 | i2c.get_clk_mask = RADEON_GPIO_Y_1; | 457 | i2c.en_data_reg = RADEON_GPIOPAD_EN; |
455 | i2c.get_data_mask = RADEON_GPIO_Y_0; | 458 | i2c.y_clk_reg = RADEON_GPIOPAD_Y; |
456 | if ((ddc_line == RADEON_LCD_GPIO_MASK) || | 459 | i2c.y_data_reg = RADEON_GPIOPAD_Y; |
457 | (ddc_line == RADEON_MDGPIO_EN_REG)) { | 460 | } else if (ddc_line == RADEON_MDGPIO_MASK) { |
458 | i2c.mask_clk_reg = ddc_line; | 461 | i2c.mask_clk_reg = RADEON_MDGPIO_MASK; |
459 | i2c.mask_data_reg = ddc_line; | 462 | i2c.mask_data_reg = RADEON_MDGPIO_MASK; |
460 | i2c.a_clk_reg = ddc_line; | 463 | i2c.a_clk_reg = RADEON_MDGPIO_A; |
461 | i2c.a_data_reg = ddc_line; | 464 | i2c.a_data_reg = RADEON_MDGPIO_A; |
462 | i2c.put_clk_reg = ddc_line; | 465 | i2c.en_clk_reg = RADEON_MDGPIO_EN; |
463 | i2c.put_data_reg = ddc_line; | 466 | i2c.en_data_reg = RADEON_MDGPIO_EN; |
464 | i2c.get_clk_reg = ddc_line + 4; | 467 | i2c.y_clk_reg = RADEON_MDGPIO_Y; |
465 | i2c.get_data_reg = ddc_line + 4; | 468 | i2c.y_data_reg = RADEON_MDGPIO_Y; |
466 | } else { | 469 | } else { |
470 | i2c.mask_clk_mask = RADEON_GPIO_EN_1; | ||
471 | i2c.mask_data_mask = RADEON_GPIO_EN_0; | ||
472 | i2c.a_clk_mask = RADEON_GPIO_A_1; | ||
473 | i2c.a_data_mask = RADEON_GPIO_A_0; | ||
474 | i2c.en_clk_mask = RADEON_GPIO_EN_1; | ||
475 | i2c.en_data_mask = RADEON_GPIO_EN_0; | ||
476 | i2c.y_clk_mask = RADEON_GPIO_Y_1; | ||
477 | i2c.y_data_mask = RADEON_GPIO_Y_0; | ||
478 | |||
467 | i2c.mask_clk_reg = ddc_line; | 479 | i2c.mask_clk_reg = ddc_line; |
468 | i2c.mask_data_reg = ddc_line; | 480 | i2c.mask_data_reg = ddc_line; |
469 | i2c.a_clk_reg = ddc_line; | 481 | i2c.a_clk_reg = ddc_line; |
470 | i2c.a_data_reg = ddc_line; | 482 | i2c.a_data_reg = ddc_line; |
471 | i2c.put_clk_reg = ddc_line; | 483 | i2c.en_clk_reg = ddc_line; |
472 | i2c.put_data_reg = ddc_line; | 484 | i2c.en_data_reg = ddc_line; |
473 | i2c.get_clk_reg = ddc_line; | 485 | i2c.y_clk_reg = ddc_line; |
474 | i2c.get_data_reg = ddc_line; | 486 | i2c.y_data_reg = ddc_line; |
475 | } | 487 | } |
476 | 488 | ||
489 | if (rdev->family < CHIP_R200) | ||
490 | i2c.hw_capable = false; | ||
491 | else { | ||
492 | switch (ddc_line) { | ||
493 | case RADEON_GPIO_VGA_DDC: | ||
494 | case RADEON_GPIO_DVI_DDC: | ||
495 | i2c.hw_capable = true; | ||
496 | break; | ||
497 | case RADEON_GPIO_MONID: | ||
498 | /* hw i2c on RADEON_GPIO_MONID doesn't seem to work | ||
499 | * reliably on some pre-r4xx hardware; not sure why. | ||
500 | */ | ||
501 | i2c.hw_capable = false; | ||
502 | break; | ||
503 | default: | ||
504 | i2c.hw_capable = false; | ||
505 | break; | ||
506 | } | ||
507 | } | ||
508 | i2c.mm_i2c = false; | ||
509 | i2c.i2c_id = 0; | ||
510 | |||
477 | if (ddc_line) | 511 | if (ddc_line) |
478 | i2c.valid = true; | 512 | i2c.valid = true; |
479 | else | 513 | else |
@@ -494,7 +528,7 @@ bool radeon_combios_get_clock_info(struct drm_device *dev) | |||
494 | uint16_t sclk, mclk; | 528 | uint16_t sclk, mclk; |
495 | 529 | ||
496 | if (rdev->bios == NULL) | 530 | if (rdev->bios == NULL) |
497 | return NULL; | 531 | return false; |
498 | 532 | ||
499 | pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE); | 533 | pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE); |
500 | if (pll_info) { | 534 | if (pll_info) { |
@@ -808,25 +842,25 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct | |||
808 | lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf; | 842 | lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf; |
809 | 843 | ||
810 | if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) | 844 | if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) |
811 | lvds->native_mode.panel_yres = | 845 | lvds->native_mode.vdisplay = |
812 | ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >> | 846 | ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >> |
813 | RADEON_VERT_PANEL_SHIFT) + 1; | 847 | RADEON_VERT_PANEL_SHIFT) + 1; |
814 | else | 848 | else |
815 | lvds->native_mode.panel_yres = | 849 | lvds->native_mode.vdisplay = |
816 | (RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1; | 850 | (RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1; |
817 | 851 | ||
818 | if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) | 852 | if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) |
819 | lvds->native_mode.panel_xres = | 853 | lvds->native_mode.hdisplay = |
820 | (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >> | 854 | (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >> |
821 | RADEON_HORZ_PANEL_SHIFT) + 1) * 8; | 855 | RADEON_HORZ_PANEL_SHIFT) + 1) * 8; |
822 | else | 856 | else |
823 | lvds->native_mode.panel_xres = | 857 | lvds->native_mode.hdisplay = |
824 | ((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8; | 858 | ((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8; |
825 | 859 | ||
826 | if ((lvds->native_mode.panel_xres < 640) || | 860 | if ((lvds->native_mode.hdisplay < 640) || |
827 | (lvds->native_mode.panel_yres < 480)) { | 861 | (lvds->native_mode.vdisplay < 480)) { |
828 | lvds->native_mode.panel_xres = 640; | 862 | lvds->native_mode.hdisplay = 640; |
829 | lvds->native_mode.panel_yres = 480; | 863 | lvds->native_mode.vdisplay = 480; |
830 | } | 864 | } |
831 | 865 | ||
832 | ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3; | 866 | ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3; |
@@ -846,8 +880,8 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct | |||
846 | lvds->panel_vcc_delay = 200; | 880 | lvds->panel_vcc_delay = 200; |
847 | 881 | ||
848 | DRM_INFO("Panel info derived from registers\n"); | 882 | DRM_INFO("Panel info derived from registers\n"); |
849 | DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres, | 883 | DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay, |
850 | lvds->native_mode.panel_yres); | 884 | lvds->native_mode.vdisplay); |
851 | 885 | ||
852 | return lvds; | 886 | return lvds; |
853 | } | 887 | } |
@@ -882,11 +916,11 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder | |||
882 | 916 | ||
883 | DRM_INFO("Panel ID String: %s\n", stmp); | 917 | DRM_INFO("Panel ID String: %s\n", stmp); |
884 | 918 | ||
885 | lvds->native_mode.panel_xres = RBIOS16(lcd_info + 0x19); | 919 | lvds->native_mode.hdisplay = RBIOS16(lcd_info + 0x19); |
886 | lvds->native_mode.panel_yres = RBIOS16(lcd_info + 0x1b); | 920 | lvds->native_mode.vdisplay = RBIOS16(lcd_info + 0x1b); |
887 | 921 | ||
888 | DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres, | 922 | DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay, |
889 | lvds->native_mode.panel_yres); | 923 | lvds->native_mode.vdisplay); |
890 | 924 | ||
891 | lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c); | 925 | lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c); |
892 | if (lvds->panel_vcc_delay > 2000 || lvds->panel_vcc_delay < 0) | 926 | if (lvds->panel_vcc_delay > 2000 || lvds->panel_vcc_delay < 0) |
@@ -944,27 +978,25 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder | |||
944 | if (tmp == 0) | 978 | if (tmp == 0) |
945 | break; | 979 | break; |
946 | 980 | ||
947 | if ((RBIOS16(tmp) == lvds->native_mode.panel_xres) && | 981 | if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) && |
948 | (RBIOS16(tmp + 2) == | 982 | (RBIOS16(tmp + 2) == |
949 | lvds->native_mode.panel_yres)) { | 983 | lvds->native_mode.vdisplay)) { |
950 | lvds->native_mode.hblank = | 984 | lvds->native_mode.htotal = RBIOS16(tmp + 17) * 8; |
951 | (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8; | 985 | lvds->native_mode.hsync_start = RBIOS16(tmp + 21) * 8; |
952 | lvds->native_mode.hoverplus = | 986 | lvds->native_mode.hsync_end = (RBIOS8(tmp + 23) + |
953 | (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - | 987 | RBIOS16(tmp + 21)) * 8; |
954 | 1) * 8; | 988 | |
955 | lvds->native_mode.hsync_width = | 989 | lvds->native_mode.vtotal = RBIOS16(tmp + 24); |
956 | RBIOS8(tmp + 23) * 8; | 990 | lvds->native_mode.vsync_start = RBIOS16(tmp + 28) & 0x7ff; |
957 | 991 | lvds->native_mode.vsync_end = | |
958 | lvds->native_mode.vblank = (RBIOS16(tmp + 24) - | 992 | ((RBIOS16(tmp + 28) & 0xf800) >> 11) + |
959 | RBIOS16(tmp + 26)); | 993 | (RBIOS16(tmp + 28) & 0x7ff); |
960 | lvds->native_mode.voverplus = | 994 | |
961 | ((RBIOS16(tmp + 28) & 0x7ff) - | 995 | lvds->native_mode.clock = RBIOS16(tmp + 9) * 10; |
962 | RBIOS16(tmp + 26)); | ||
963 | lvds->native_mode.vsync_width = | ||
964 | ((RBIOS16(tmp + 28) & 0xf800) >> 11); | ||
965 | lvds->native_mode.dotclock = | ||
966 | RBIOS16(tmp + 9) * 10; | ||
967 | lvds->native_mode.flags = 0; | 996 | lvds->native_mode.flags = 0; |
997 | /* set crtc values */ | ||
998 | drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); | ||
999 | |||
968 | } | 1000 | } |
969 | } | 1001 | } |
970 | } else { | 1002 | } else { |
@@ -994,8 +1026,8 @@ static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = { | |||
994 | {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R420 */ | 1026 | {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R420 */ |
995 | {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R423 */ | 1027 | {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R423 */ |
996 | {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RV410 */ | 1028 | {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RV410 */ |
997 | {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS400 */ | 1029 | { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS400 */ |
998 | {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS480 */ | 1030 | { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS480 */ |
999 | }; | 1031 | }; |
1000 | 1032 | ||
1001 | bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder, | 1033 | bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder, |
@@ -1029,7 +1061,6 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, | |||
1029 | tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); | 1061 | tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); |
1030 | 1062 | ||
1031 | if (tmds_info) { | 1063 | if (tmds_info) { |
1032 | |||
1033 | ver = RBIOS8(tmds_info); | 1064 | ver = RBIOS8(tmds_info); |
1034 | DRM_INFO("DFP table revision: %d\n", ver); | 1065 | DRM_INFO("DFP table revision: %d\n", ver); |
1035 | if (ver == 3) { | 1066 | if (ver == 3) { |
@@ -1064,51 +1095,139 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, | |||
1064 | tmds->tmds_pll[i].value); | 1095 | tmds->tmds_pll[i].value); |
1065 | } | 1096 | } |
1066 | } | 1097 | } |
1067 | } else | 1098 | } else { |
1068 | DRM_INFO("No TMDS info found in BIOS\n"); | 1099 | DRM_INFO("No TMDS info found in BIOS\n"); |
1100 | return false; | ||
1101 | } | ||
1069 | return true; | 1102 | return true; |
1070 | } | 1103 | } |
1071 | 1104 | ||
1072 | struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct radeon_encoder *encoder) | 1105 | bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder, |
1106 | struct radeon_encoder_ext_tmds *tmds) | ||
1073 | { | 1107 | { |
1074 | struct radeon_encoder_int_tmds *tmds = NULL; | 1108 | struct drm_device *dev = encoder->base.dev; |
1075 | bool ret; | 1109 | struct radeon_device *rdev = dev->dev_private; |
1076 | 1110 | struct radeon_i2c_bus_rec i2c_bus; | |
1077 | tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL); | ||
1078 | 1111 | ||
1079 | if (!tmds) | 1112 | /* default for macs */ |
1080 | return NULL; | 1113 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
1114 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | ||
1081 | 1115 | ||
1082 | ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds); | 1116 | /* XXX some macs have duallink chips */ |
1083 | if (ret == false) | 1117 | switch (rdev->mode_info.connector_table) { |
1084 | radeon_legacy_get_tmds_info_from_table(encoder, tmds); | 1118 | case CT_POWERBOOK_EXTERNAL: |
1119 | case CT_MINI_EXTERNAL: | ||
1120 | default: | ||
1121 | tmds->dvo_chip = DVO_SIL164; | ||
1122 | tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */ | ||
1123 | break; | ||
1124 | } | ||
1085 | 1125 | ||
1086 | return tmds; | 1126 | return true; |
1087 | } | 1127 | } |
1088 | 1128 | ||
1089 | void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder) | 1129 | bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder, |
1130 | struct radeon_encoder_ext_tmds *tmds) | ||
1090 | { | 1131 | { |
1091 | struct drm_device *dev = encoder->base.dev; | 1132 | struct drm_device *dev = encoder->base.dev; |
1092 | struct radeon_device *rdev = dev->dev_private; | 1133 | struct radeon_device *rdev = dev->dev_private; |
1093 | uint16_t ext_tmds_info; | 1134 | uint16_t offset; |
1094 | uint8_t ver; | 1135 | uint8_t ver, id, blocks, clk, data; |
1136 | int i; | ||
1137 | enum radeon_combios_ddc gpio; | ||
1138 | struct radeon_i2c_bus_rec i2c_bus; | ||
1095 | 1139 | ||
1096 | if (rdev->bios == NULL) | 1140 | if (rdev->bios == NULL) |
1097 | return; | 1141 | return false; |
1098 | 1142 | ||
1099 | ext_tmds_info = | 1143 | tmds->i2c_bus = NULL; |
1100 | combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); | 1144 | if (rdev->flags & RADEON_IS_IGP) { |
1101 | if (ext_tmds_info) { | 1145 | offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); |
1102 | ver = RBIOS8(ext_tmds_info); | 1146 | if (offset) { |
1103 | DRM_INFO("External TMDS Table revision: %d\n", ver); | 1147 | ver = RBIOS8(offset); |
1104 | // TODO | 1148 | DRM_INFO("GPIO Table revision: %d\n", ver); |
1149 | blocks = RBIOS8(offset + 2); | ||
1150 | for (i = 0; i < blocks; i++) { | ||
1151 | id = RBIOS8(offset + 3 + (i * 5) + 0); | ||
1152 | if (id == 136) { | ||
1153 | clk = RBIOS8(offset + 3 + (i * 5) + 3); | ||
1154 | data = RBIOS8(offset + 3 + (i * 5) + 4); | ||
1155 | i2c_bus.valid = true; | ||
1156 | i2c_bus.mask_clk_mask = (1 << clk); | ||
1157 | i2c_bus.mask_data_mask = (1 << data); | ||
1158 | i2c_bus.a_clk_mask = (1 << clk); | ||
1159 | i2c_bus.a_data_mask = (1 << data); | ||
1160 | i2c_bus.en_clk_mask = (1 << clk); | ||
1161 | i2c_bus.en_data_mask = (1 << data); | ||
1162 | i2c_bus.y_clk_mask = (1 << clk); | ||
1163 | i2c_bus.y_data_mask = (1 << data); | ||
1164 | i2c_bus.mask_clk_reg = RADEON_GPIOPAD_MASK; | ||
1165 | i2c_bus.mask_data_reg = RADEON_GPIOPAD_MASK; | ||
1166 | i2c_bus.a_clk_reg = RADEON_GPIOPAD_A; | ||
1167 | i2c_bus.a_data_reg = RADEON_GPIOPAD_A; | ||
1168 | i2c_bus.en_clk_reg = RADEON_GPIOPAD_EN; | ||
1169 | i2c_bus.en_data_reg = RADEON_GPIOPAD_EN; | ||
1170 | i2c_bus.y_clk_reg = RADEON_GPIOPAD_Y; | ||
1171 | i2c_bus.y_data_reg = RADEON_GPIOPAD_Y; | ||
1172 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | ||
1173 | tmds->dvo_chip = DVO_SIL164; | ||
1174 | tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */ | ||
1175 | break; | ||
1176 | } | ||
1177 | } | ||
1178 | } | ||
1179 | } else { | ||
1180 | offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); | ||
1181 | if (offset) { | ||
1182 | ver = RBIOS8(offset); | ||
1183 | DRM_INFO("External TMDS Table revision: %d\n", ver); | ||
1184 | tmds->slave_addr = RBIOS8(offset + 4 + 2); | ||
1185 | tmds->slave_addr >>= 1; /* 7 bit addressing */ | ||
1186 | gpio = RBIOS8(offset + 4 + 3); | ||
1187 | switch (gpio) { | ||
1188 | case DDC_MONID: | ||
1189 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); | ||
1190 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | ||
1191 | break; | ||
1192 | case DDC_DVI: | ||
1193 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); | ||
1194 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | ||
1195 | break; | ||
1196 | case DDC_VGA: | ||
1197 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); | ||
1198 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | ||
1199 | break; | ||
1200 | case DDC_CRT2: | ||
1201 | /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */ | ||
1202 | if (rdev->family >= CHIP_R300) | ||
1203 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); | ||
1204 | else | ||
1205 | i2c_bus = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); | ||
1206 | tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO"); | ||
1207 | break; | ||
1208 | case DDC_LCD: /* MM i2c */ | ||
1209 | DRM_ERROR("MM i2c requires hw i2c engine\n"); | ||
1210 | break; | ||
1211 | default: | ||
1212 | DRM_ERROR("Unsupported gpio %d\n", gpio); | ||
1213 | break; | ||
1214 | } | ||
1215 | } | ||
1216 | } | ||
1217 | |||
1218 | if (!tmds->i2c_bus) { | ||
1219 | DRM_INFO("No valid Ext TMDS info found in BIOS\n"); | ||
1220 | return false; | ||
1105 | } | 1221 | } |
1222 | |||
1223 | return true; | ||
1106 | } | 1224 | } |
1107 | 1225 | ||
1108 | bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | 1226 | bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) |
1109 | { | 1227 | { |
1110 | struct radeon_device *rdev = dev->dev_private; | 1228 | struct radeon_device *rdev = dev->dev_private; |
1111 | struct radeon_i2c_bus_rec ddc_i2c; | 1229 | struct radeon_i2c_bus_rec ddc_i2c; |
1230 | struct radeon_hpd hpd; | ||
1112 | 1231 | ||
1113 | rdev->mode_info.connector_table = radeon_connector_table; | 1232 | rdev->mode_info.connector_table = radeon_connector_table; |
1114 | if (rdev->mode_info.connector_table == CT_NONE) { | 1233 | if (rdev->mode_info.connector_table == CT_NONE) { |
@@ -1169,7 +1288,8 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1169 | /* these are the most common settings */ | 1288 | /* these are the most common settings */ |
1170 | if (rdev->flags & RADEON_SINGLE_CRTC) { | 1289 | if (rdev->flags & RADEON_SINGLE_CRTC) { |
1171 | /* VGA - primary dac */ | 1290 | /* VGA - primary dac */ |
1172 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1291 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1292 | hpd.hpd = RADEON_HPD_NONE; | ||
1173 | radeon_add_legacy_encoder(dev, | 1293 | radeon_add_legacy_encoder(dev, |
1174 | radeon_get_encoder_id(dev, | 1294 | radeon_get_encoder_id(dev, |
1175 | ATOM_DEVICE_CRT1_SUPPORT, | 1295 | ATOM_DEVICE_CRT1_SUPPORT, |
@@ -1178,10 +1298,13 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1178 | radeon_add_legacy_connector(dev, 0, | 1298 | radeon_add_legacy_connector(dev, 0, |
1179 | ATOM_DEVICE_CRT1_SUPPORT, | 1299 | ATOM_DEVICE_CRT1_SUPPORT, |
1180 | DRM_MODE_CONNECTOR_VGA, | 1300 | DRM_MODE_CONNECTOR_VGA, |
1181 | &ddc_i2c); | 1301 | &ddc_i2c, |
1302 | CONNECTOR_OBJECT_ID_VGA, | ||
1303 | &hpd); | ||
1182 | } else if (rdev->flags & RADEON_IS_MOBILITY) { | 1304 | } else if (rdev->flags & RADEON_IS_MOBILITY) { |
1183 | /* LVDS */ | 1305 | /* LVDS */ |
1184 | ddc_i2c = combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK); | 1306 | ddc_i2c = combios_setup_i2c_bus(rdev, 0); |
1307 | hpd.hpd = RADEON_HPD_NONE; | ||
1185 | radeon_add_legacy_encoder(dev, | 1308 | radeon_add_legacy_encoder(dev, |
1186 | radeon_get_encoder_id(dev, | 1309 | radeon_get_encoder_id(dev, |
1187 | ATOM_DEVICE_LCD1_SUPPORT, | 1310 | ATOM_DEVICE_LCD1_SUPPORT, |
@@ -1190,10 +1313,13 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1190 | radeon_add_legacy_connector(dev, 0, | 1313 | radeon_add_legacy_connector(dev, 0, |
1191 | ATOM_DEVICE_LCD1_SUPPORT, | 1314 | ATOM_DEVICE_LCD1_SUPPORT, |
1192 | DRM_MODE_CONNECTOR_LVDS, | 1315 | DRM_MODE_CONNECTOR_LVDS, |
1193 | &ddc_i2c); | 1316 | &ddc_i2c, |
1317 | CONNECTOR_OBJECT_ID_LVDS, | ||
1318 | &hpd); | ||
1194 | 1319 | ||
1195 | /* VGA - primary dac */ | 1320 | /* VGA - primary dac */ |
1196 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1321 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1322 | hpd.hpd = RADEON_HPD_NONE; | ||
1197 | radeon_add_legacy_encoder(dev, | 1323 | radeon_add_legacy_encoder(dev, |
1198 | radeon_get_encoder_id(dev, | 1324 | radeon_get_encoder_id(dev, |
1199 | ATOM_DEVICE_CRT1_SUPPORT, | 1325 | ATOM_DEVICE_CRT1_SUPPORT, |
@@ -1202,10 +1328,13 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1202 | radeon_add_legacy_connector(dev, 1, | 1328 | radeon_add_legacy_connector(dev, 1, |
1203 | ATOM_DEVICE_CRT1_SUPPORT, | 1329 | ATOM_DEVICE_CRT1_SUPPORT, |
1204 | DRM_MODE_CONNECTOR_VGA, | 1330 | DRM_MODE_CONNECTOR_VGA, |
1205 | &ddc_i2c); | 1331 | &ddc_i2c, |
1332 | CONNECTOR_OBJECT_ID_VGA, | ||
1333 | &hpd); | ||
1206 | } else { | 1334 | } else { |
1207 | /* DVI-I - tv dac, int tmds */ | 1335 | /* DVI-I - tv dac, int tmds */ |
1208 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1336 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1337 | hpd.hpd = RADEON_HPD_1; | ||
1209 | radeon_add_legacy_encoder(dev, | 1338 | radeon_add_legacy_encoder(dev, |
1210 | radeon_get_encoder_id(dev, | 1339 | radeon_get_encoder_id(dev, |
1211 | ATOM_DEVICE_DFP1_SUPPORT, | 1340 | ATOM_DEVICE_DFP1_SUPPORT, |
@@ -1220,10 +1349,13 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1220 | ATOM_DEVICE_DFP1_SUPPORT | | 1349 | ATOM_DEVICE_DFP1_SUPPORT | |
1221 | ATOM_DEVICE_CRT2_SUPPORT, | 1350 | ATOM_DEVICE_CRT2_SUPPORT, |
1222 | DRM_MODE_CONNECTOR_DVII, | 1351 | DRM_MODE_CONNECTOR_DVII, |
1223 | &ddc_i2c); | 1352 | &ddc_i2c, |
1353 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, | ||
1354 | &hpd); | ||
1224 | 1355 | ||
1225 | /* VGA - primary dac */ | 1356 | /* VGA - primary dac */ |
1226 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1357 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1358 | hpd.hpd = RADEON_HPD_NONE; | ||
1227 | radeon_add_legacy_encoder(dev, | 1359 | radeon_add_legacy_encoder(dev, |
1228 | radeon_get_encoder_id(dev, | 1360 | radeon_get_encoder_id(dev, |
1229 | ATOM_DEVICE_CRT1_SUPPORT, | 1361 | ATOM_DEVICE_CRT1_SUPPORT, |
@@ -1232,11 +1364,15 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1232 | radeon_add_legacy_connector(dev, 1, | 1364 | radeon_add_legacy_connector(dev, 1, |
1233 | ATOM_DEVICE_CRT1_SUPPORT, | 1365 | ATOM_DEVICE_CRT1_SUPPORT, |
1234 | DRM_MODE_CONNECTOR_VGA, | 1366 | DRM_MODE_CONNECTOR_VGA, |
1235 | &ddc_i2c); | 1367 | &ddc_i2c, |
1368 | CONNECTOR_OBJECT_ID_VGA, | ||
1369 | &hpd); | ||
1236 | } | 1370 | } |
1237 | 1371 | ||
1238 | if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) { | 1372 | if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) { |
1239 | /* TV - tv dac */ | 1373 | /* TV - tv dac */ |
1374 | ddc_i2c.valid = false; | ||
1375 | hpd.hpd = RADEON_HPD_NONE; | ||
1240 | radeon_add_legacy_encoder(dev, | 1376 | radeon_add_legacy_encoder(dev, |
1241 | radeon_get_encoder_id(dev, | 1377 | radeon_get_encoder_id(dev, |
1242 | ATOM_DEVICE_TV1_SUPPORT, | 1378 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1245,31 +1381,41 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1245 | radeon_add_legacy_connector(dev, 2, | 1381 | radeon_add_legacy_connector(dev, 2, |
1246 | ATOM_DEVICE_TV1_SUPPORT, | 1382 | ATOM_DEVICE_TV1_SUPPORT, |
1247 | DRM_MODE_CONNECTOR_SVIDEO, | 1383 | DRM_MODE_CONNECTOR_SVIDEO, |
1248 | &ddc_i2c); | 1384 | &ddc_i2c, |
1385 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
1386 | &hpd); | ||
1249 | } | 1387 | } |
1250 | break; | 1388 | break; |
1251 | case CT_IBOOK: | 1389 | case CT_IBOOK: |
1252 | DRM_INFO("Connector Table: %d (ibook)\n", | 1390 | DRM_INFO("Connector Table: %d (ibook)\n", |
1253 | rdev->mode_info.connector_table); | 1391 | rdev->mode_info.connector_table); |
1254 | /* LVDS */ | 1392 | /* LVDS */ |
1255 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1393 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1394 | hpd.hpd = RADEON_HPD_NONE; | ||
1256 | radeon_add_legacy_encoder(dev, | 1395 | radeon_add_legacy_encoder(dev, |
1257 | radeon_get_encoder_id(dev, | 1396 | radeon_get_encoder_id(dev, |
1258 | ATOM_DEVICE_LCD1_SUPPORT, | 1397 | ATOM_DEVICE_LCD1_SUPPORT, |
1259 | 0), | 1398 | 0), |
1260 | ATOM_DEVICE_LCD1_SUPPORT); | 1399 | ATOM_DEVICE_LCD1_SUPPORT); |
1261 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, | 1400 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
1262 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c); | 1401 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
1402 | CONNECTOR_OBJECT_ID_LVDS, | ||
1403 | &hpd); | ||
1263 | /* VGA - TV DAC */ | 1404 | /* VGA - TV DAC */ |
1264 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1405 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1406 | hpd.hpd = RADEON_HPD_NONE; | ||
1265 | radeon_add_legacy_encoder(dev, | 1407 | radeon_add_legacy_encoder(dev, |
1266 | radeon_get_encoder_id(dev, | 1408 | radeon_get_encoder_id(dev, |
1267 | ATOM_DEVICE_CRT2_SUPPORT, | 1409 | ATOM_DEVICE_CRT2_SUPPORT, |
1268 | 2), | 1410 | 2), |
1269 | ATOM_DEVICE_CRT2_SUPPORT); | 1411 | ATOM_DEVICE_CRT2_SUPPORT); |
1270 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, | 1412 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, |
1271 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c); | 1413 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
1414 | CONNECTOR_OBJECT_ID_VGA, | ||
1415 | &hpd); | ||
1272 | /* TV - TV DAC */ | 1416 | /* TV - TV DAC */ |
1417 | ddc_i2c.valid = false; | ||
1418 | hpd.hpd = RADEON_HPD_NONE; | ||
1273 | radeon_add_legacy_encoder(dev, | 1419 | radeon_add_legacy_encoder(dev, |
1274 | radeon_get_encoder_id(dev, | 1420 | radeon_get_encoder_id(dev, |
1275 | ATOM_DEVICE_TV1_SUPPORT, | 1421 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1277,22 +1423,28 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1277 | ATOM_DEVICE_TV1_SUPPORT); | 1423 | ATOM_DEVICE_TV1_SUPPORT); |
1278 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1424 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
1279 | DRM_MODE_CONNECTOR_SVIDEO, | 1425 | DRM_MODE_CONNECTOR_SVIDEO, |
1280 | &ddc_i2c); | 1426 | &ddc_i2c, |
1427 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
1428 | &hpd); | ||
1281 | break; | 1429 | break; |
1282 | case CT_POWERBOOK_EXTERNAL: | 1430 | case CT_POWERBOOK_EXTERNAL: |
1283 | DRM_INFO("Connector Table: %d (powerbook external tmds)\n", | 1431 | DRM_INFO("Connector Table: %d (powerbook external tmds)\n", |
1284 | rdev->mode_info.connector_table); | 1432 | rdev->mode_info.connector_table); |
1285 | /* LVDS */ | 1433 | /* LVDS */ |
1286 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1434 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1435 | hpd.hpd = RADEON_HPD_NONE; | ||
1287 | radeon_add_legacy_encoder(dev, | 1436 | radeon_add_legacy_encoder(dev, |
1288 | radeon_get_encoder_id(dev, | 1437 | radeon_get_encoder_id(dev, |
1289 | ATOM_DEVICE_LCD1_SUPPORT, | 1438 | ATOM_DEVICE_LCD1_SUPPORT, |
1290 | 0), | 1439 | 0), |
1291 | ATOM_DEVICE_LCD1_SUPPORT); | 1440 | ATOM_DEVICE_LCD1_SUPPORT); |
1292 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, | 1441 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
1293 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c); | 1442 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
1443 | CONNECTOR_OBJECT_ID_LVDS, | ||
1444 | &hpd); | ||
1294 | /* DVI-I - primary dac, ext tmds */ | 1445 | /* DVI-I - primary dac, ext tmds */ |
1295 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1446 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1447 | hpd.hpd = RADEON_HPD_2; /* ??? */ | ||
1296 | radeon_add_legacy_encoder(dev, | 1448 | radeon_add_legacy_encoder(dev, |
1297 | radeon_get_encoder_id(dev, | 1449 | radeon_get_encoder_id(dev, |
1298 | ATOM_DEVICE_DFP2_SUPPORT, | 1450 | ATOM_DEVICE_DFP2_SUPPORT, |
@@ -1303,11 +1455,16 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1303 | ATOM_DEVICE_CRT1_SUPPORT, | 1455 | ATOM_DEVICE_CRT1_SUPPORT, |
1304 | 1), | 1456 | 1), |
1305 | ATOM_DEVICE_CRT1_SUPPORT); | 1457 | ATOM_DEVICE_CRT1_SUPPORT); |
1458 | /* XXX some are SL */ | ||
1306 | radeon_add_legacy_connector(dev, 1, | 1459 | radeon_add_legacy_connector(dev, 1, |
1307 | ATOM_DEVICE_DFP2_SUPPORT | | 1460 | ATOM_DEVICE_DFP2_SUPPORT | |
1308 | ATOM_DEVICE_CRT1_SUPPORT, | 1461 | ATOM_DEVICE_CRT1_SUPPORT, |
1309 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c); | 1462 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
1463 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, | ||
1464 | &hpd); | ||
1310 | /* TV - TV DAC */ | 1465 | /* TV - TV DAC */ |
1466 | ddc_i2c.valid = false; | ||
1467 | hpd.hpd = RADEON_HPD_NONE; | ||
1311 | radeon_add_legacy_encoder(dev, | 1468 | radeon_add_legacy_encoder(dev, |
1312 | radeon_get_encoder_id(dev, | 1469 | radeon_get_encoder_id(dev, |
1313 | ATOM_DEVICE_TV1_SUPPORT, | 1470 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1315,22 +1472,28 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1315 | ATOM_DEVICE_TV1_SUPPORT); | 1472 | ATOM_DEVICE_TV1_SUPPORT); |
1316 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1473 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
1317 | DRM_MODE_CONNECTOR_SVIDEO, | 1474 | DRM_MODE_CONNECTOR_SVIDEO, |
1318 | &ddc_i2c); | 1475 | &ddc_i2c, |
1476 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
1477 | &hpd); | ||
1319 | break; | 1478 | break; |
1320 | case CT_POWERBOOK_INTERNAL: | 1479 | case CT_POWERBOOK_INTERNAL: |
1321 | DRM_INFO("Connector Table: %d (powerbook internal tmds)\n", | 1480 | DRM_INFO("Connector Table: %d (powerbook internal tmds)\n", |
1322 | rdev->mode_info.connector_table); | 1481 | rdev->mode_info.connector_table); |
1323 | /* LVDS */ | 1482 | /* LVDS */ |
1324 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1483 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1484 | hpd.hpd = RADEON_HPD_NONE; | ||
1325 | radeon_add_legacy_encoder(dev, | 1485 | radeon_add_legacy_encoder(dev, |
1326 | radeon_get_encoder_id(dev, | 1486 | radeon_get_encoder_id(dev, |
1327 | ATOM_DEVICE_LCD1_SUPPORT, | 1487 | ATOM_DEVICE_LCD1_SUPPORT, |
1328 | 0), | 1488 | 0), |
1329 | ATOM_DEVICE_LCD1_SUPPORT); | 1489 | ATOM_DEVICE_LCD1_SUPPORT); |
1330 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, | 1490 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
1331 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c); | 1491 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
1492 | CONNECTOR_OBJECT_ID_LVDS, | ||
1493 | &hpd); | ||
1332 | /* DVI-I - primary dac, int tmds */ | 1494 | /* DVI-I - primary dac, int tmds */ |
1333 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1495 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1496 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
1334 | radeon_add_legacy_encoder(dev, | 1497 | radeon_add_legacy_encoder(dev, |
1335 | radeon_get_encoder_id(dev, | 1498 | radeon_get_encoder_id(dev, |
1336 | ATOM_DEVICE_DFP1_SUPPORT, | 1499 | ATOM_DEVICE_DFP1_SUPPORT, |
@@ -1344,8 +1507,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1344 | radeon_add_legacy_connector(dev, 1, | 1507 | radeon_add_legacy_connector(dev, 1, |
1345 | ATOM_DEVICE_DFP1_SUPPORT | | 1508 | ATOM_DEVICE_DFP1_SUPPORT | |
1346 | ATOM_DEVICE_CRT1_SUPPORT, | 1509 | ATOM_DEVICE_CRT1_SUPPORT, |
1347 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c); | 1510 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
1511 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, | ||
1512 | &hpd); | ||
1348 | /* TV - TV DAC */ | 1513 | /* TV - TV DAC */ |
1514 | ddc_i2c.valid = false; | ||
1515 | hpd.hpd = RADEON_HPD_NONE; | ||
1349 | radeon_add_legacy_encoder(dev, | 1516 | radeon_add_legacy_encoder(dev, |
1350 | radeon_get_encoder_id(dev, | 1517 | radeon_get_encoder_id(dev, |
1351 | ATOM_DEVICE_TV1_SUPPORT, | 1518 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1353,30 +1520,40 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1353 | ATOM_DEVICE_TV1_SUPPORT); | 1520 | ATOM_DEVICE_TV1_SUPPORT); |
1354 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1521 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
1355 | DRM_MODE_CONNECTOR_SVIDEO, | 1522 | DRM_MODE_CONNECTOR_SVIDEO, |
1356 | &ddc_i2c); | 1523 | &ddc_i2c, |
1524 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
1525 | &hpd); | ||
1357 | break; | 1526 | break; |
1358 | case CT_POWERBOOK_VGA: | 1527 | case CT_POWERBOOK_VGA: |
1359 | DRM_INFO("Connector Table: %d (powerbook vga)\n", | 1528 | DRM_INFO("Connector Table: %d (powerbook vga)\n", |
1360 | rdev->mode_info.connector_table); | 1529 | rdev->mode_info.connector_table); |
1361 | /* LVDS */ | 1530 | /* LVDS */ |
1362 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1531 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1532 | hpd.hpd = RADEON_HPD_NONE; | ||
1363 | radeon_add_legacy_encoder(dev, | 1533 | radeon_add_legacy_encoder(dev, |
1364 | radeon_get_encoder_id(dev, | 1534 | radeon_get_encoder_id(dev, |
1365 | ATOM_DEVICE_LCD1_SUPPORT, | 1535 | ATOM_DEVICE_LCD1_SUPPORT, |
1366 | 0), | 1536 | 0), |
1367 | ATOM_DEVICE_LCD1_SUPPORT); | 1537 | ATOM_DEVICE_LCD1_SUPPORT); |
1368 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, | 1538 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
1369 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c); | 1539 | DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
1540 | CONNECTOR_OBJECT_ID_LVDS, | ||
1541 | &hpd); | ||
1370 | /* VGA - primary dac */ | 1542 | /* VGA - primary dac */ |
1371 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1543 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1544 | hpd.hpd = RADEON_HPD_NONE; | ||
1372 | radeon_add_legacy_encoder(dev, | 1545 | radeon_add_legacy_encoder(dev, |
1373 | radeon_get_encoder_id(dev, | 1546 | radeon_get_encoder_id(dev, |
1374 | ATOM_DEVICE_CRT1_SUPPORT, | 1547 | ATOM_DEVICE_CRT1_SUPPORT, |
1375 | 1), | 1548 | 1), |
1376 | ATOM_DEVICE_CRT1_SUPPORT); | 1549 | ATOM_DEVICE_CRT1_SUPPORT); |
1377 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, | 1550 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, |
1378 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c); | 1551 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
1552 | CONNECTOR_OBJECT_ID_VGA, | ||
1553 | &hpd); | ||
1379 | /* TV - TV DAC */ | 1554 | /* TV - TV DAC */ |
1555 | ddc_i2c.valid = false; | ||
1556 | hpd.hpd = RADEON_HPD_NONE; | ||
1380 | radeon_add_legacy_encoder(dev, | 1557 | radeon_add_legacy_encoder(dev, |
1381 | radeon_get_encoder_id(dev, | 1558 | radeon_get_encoder_id(dev, |
1382 | ATOM_DEVICE_TV1_SUPPORT, | 1559 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1384,13 +1561,16 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1384 | ATOM_DEVICE_TV1_SUPPORT); | 1561 | ATOM_DEVICE_TV1_SUPPORT); |
1385 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1562 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
1386 | DRM_MODE_CONNECTOR_SVIDEO, | 1563 | DRM_MODE_CONNECTOR_SVIDEO, |
1387 | &ddc_i2c); | 1564 | &ddc_i2c, |
1565 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
1566 | &hpd); | ||
1388 | break; | 1567 | break; |
1389 | case CT_MINI_EXTERNAL: | 1568 | case CT_MINI_EXTERNAL: |
1390 | DRM_INFO("Connector Table: %d (mini external tmds)\n", | 1569 | DRM_INFO("Connector Table: %d (mini external tmds)\n", |
1391 | rdev->mode_info.connector_table); | 1570 | rdev->mode_info.connector_table); |
1392 | /* DVI-I - tv dac, ext tmds */ | 1571 | /* DVI-I - tv dac, ext tmds */ |
1393 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1572 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
1573 | hpd.hpd = RADEON_HPD_2; /* ??? */ | ||
1394 | radeon_add_legacy_encoder(dev, | 1574 | radeon_add_legacy_encoder(dev, |
1395 | radeon_get_encoder_id(dev, | 1575 | radeon_get_encoder_id(dev, |
1396 | ATOM_DEVICE_DFP2_SUPPORT, | 1576 | ATOM_DEVICE_DFP2_SUPPORT, |
@@ -1401,11 +1581,16 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1401 | ATOM_DEVICE_CRT2_SUPPORT, | 1581 | ATOM_DEVICE_CRT2_SUPPORT, |
1402 | 2), | 1582 | 2), |
1403 | ATOM_DEVICE_CRT2_SUPPORT); | 1583 | ATOM_DEVICE_CRT2_SUPPORT); |
1584 | /* XXX are any DL? */ | ||
1404 | radeon_add_legacy_connector(dev, 0, | 1585 | radeon_add_legacy_connector(dev, 0, |
1405 | ATOM_DEVICE_DFP2_SUPPORT | | 1586 | ATOM_DEVICE_DFP2_SUPPORT | |
1406 | ATOM_DEVICE_CRT2_SUPPORT, | 1587 | ATOM_DEVICE_CRT2_SUPPORT, |
1407 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c); | 1588 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
1589 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, | ||
1590 | &hpd); | ||
1408 | /* TV - TV DAC */ | 1591 | /* TV - TV DAC */ |
1592 | ddc_i2c.valid = false; | ||
1593 | hpd.hpd = RADEON_HPD_NONE; | ||
1409 | radeon_add_legacy_encoder(dev, | 1594 | radeon_add_legacy_encoder(dev, |
1410 | radeon_get_encoder_id(dev, | 1595 | radeon_get_encoder_id(dev, |
1411 | ATOM_DEVICE_TV1_SUPPORT, | 1596 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1413,13 +1598,16 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1413 | ATOM_DEVICE_TV1_SUPPORT); | 1598 | ATOM_DEVICE_TV1_SUPPORT); |
1414 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, | 1599 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, |
1415 | DRM_MODE_CONNECTOR_SVIDEO, | 1600 | DRM_MODE_CONNECTOR_SVIDEO, |
1416 | &ddc_i2c); | 1601 | &ddc_i2c, |
1602 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
1603 | &hpd); | ||
1417 | break; | 1604 | break; |
1418 | case CT_MINI_INTERNAL: | 1605 | case CT_MINI_INTERNAL: |
1419 | DRM_INFO("Connector Table: %d (mini internal tmds)\n", | 1606 | DRM_INFO("Connector Table: %d (mini internal tmds)\n", |
1420 | rdev->mode_info.connector_table); | 1607 | rdev->mode_info.connector_table); |
1421 | /* DVI-I - tv dac, int tmds */ | 1608 | /* DVI-I - tv dac, int tmds */ |
1422 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1609 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
1610 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
1423 | radeon_add_legacy_encoder(dev, | 1611 | radeon_add_legacy_encoder(dev, |
1424 | radeon_get_encoder_id(dev, | 1612 | radeon_get_encoder_id(dev, |
1425 | ATOM_DEVICE_DFP1_SUPPORT, | 1613 | ATOM_DEVICE_DFP1_SUPPORT, |
@@ -1433,8 +1621,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1433 | radeon_add_legacy_connector(dev, 0, | 1621 | radeon_add_legacy_connector(dev, 0, |
1434 | ATOM_DEVICE_DFP1_SUPPORT | | 1622 | ATOM_DEVICE_DFP1_SUPPORT | |
1435 | ATOM_DEVICE_CRT2_SUPPORT, | 1623 | ATOM_DEVICE_CRT2_SUPPORT, |
1436 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c); | 1624 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
1625 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, | ||
1626 | &hpd); | ||
1437 | /* TV - TV DAC */ | 1627 | /* TV - TV DAC */ |
1628 | ddc_i2c.valid = false; | ||
1629 | hpd.hpd = RADEON_HPD_NONE; | ||
1438 | radeon_add_legacy_encoder(dev, | 1630 | radeon_add_legacy_encoder(dev, |
1439 | radeon_get_encoder_id(dev, | 1631 | radeon_get_encoder_id(dev, |
1440 | ATOM_DEVICE_TV1_SUPPORT, | 1632 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1442,30 +1634,40 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1442 | ATOM_DEVICE_TV1_SUPPORT); | 1634 | ATOM_DEVICE_TV1_SUPPORT); |
1443 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, | 1635 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, |
1444 | DRM_MODE_CONNECTOR_SVIDEO, | 1636 | DRM_MODE_CONNECTOR_SVIDEO, |
1445 | &ddc_i2c); | 1637 | &ddc_i2c, |
1638 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
1639 | &hpd); | ||
1446 | break; | 1640 | break; |
1447 | case CT_IMAC_G5_ISIGHT: | 1641 | case CT_IMAC_G5_ISIGHT: |
1448 | DRM_INFO("Connector Table: %d (imac g5 isight)\n", | 1642 | DRM_INFO("Connector Table: %d (imac g5 isight)\n", |
1449 | rdev->mode_info.connector_table); | 1643 | rdev->mode_info.connector_table); |
1450 | /* DVI-D - int tmds */ | 1644 | /* DVI-D - int tmds */ |
1451 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1645 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
1646 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
1452 | radeon_add_legacy_encoder(dev, | 1647 | radeon_add_legacy_encoder(dev, |
1453 | radeon_get_encoder_id(dev, | 1648 | radeon_get_encoder_id(dev, |
1454 | ATOM_DEVICE_DFP1_SUPPORT, | 1649 | ATOM_DEVICE_DFP1_SUPPORT, |
1455 | 0), | 1650 | 0), |
1456 | ATOM_DEVICE_DFP1_SUPPORT); | 1651 | ATOM_DEVICE_DFP1_SUPPORT); |
1457 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT, | 1652 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT, |
1458 | DRM_MODE_CONNECTOR_DVID, &ddc_i2c); | 1653 | DRM_MODE_CONNECTOR_DVID, &ddc_i2c, |
1654 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D, | ||
1655 | &hpd); | ||
1459 | /* VGA - tv dac */ | 1656 | /* VGA - tv dac */ |
1460 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1657 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1658 | hpd.hpd = RADEON_HPD_NONE; | ||
1461 | radeon_add_legacy_encoder(dev, | 1659 | radeon_add_legacy_encoder(dev, |
1462 | radeon_get_encoder_id(dev, | 1660 | radeon_get_encoder_id(dev, |
1463 | ATOM_DEVICE_CRT2_SUPPORT, | 1661 | ATOM_DEVICE_CRT2_SUPPORT, |
1464 | 2), | 1662 | 2), |
1465 | ATOM_DEVICE_CRT2_SUPPORT); | 1663 | ATOM_DEVICE_CRT2_SUPPORT); |
1466 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, | 1664 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, |
1467 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c); | 1665 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
1666 | CONNECTOR_OBJECT_ID_VGA, | ||
1667 | &hpd); | ||
1468 | /* TV - TV DAC */ | 1668 | /* TV - TV DAC */ |
1669 | ddc_i2c.valid = false; | ||
1670 | hpd.hpd = RADEON_HPD_NONE; | ||
1469 | radeon_add_legacy_encoder(dev, | 1671 | radeon_add_legacy_encoder(dev, |
1470 | radeon_get_encoder_id(dev, | 1672 | radeon_get_encoder_id(dev, |
1471 | ATOM_DEVICE_TV1_SUPPORT, | 1673 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1473,30 +1675,40 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1473 | ATOM_DEVICE_TV1_SUPPORT); | 1675 | ATOM_DEVICE_TV1_SUPPORT); |
1474 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1676 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
1475 | DRM_MODE_CONNECTOR_SVIDEO, | 1677 | DRM_MODE_CONNECTOR_SVIDEO, |
1476 | &ddc_i2c); | 1678 | &ddc_i2c, |
1679 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
1680 | &hpd); | ||
1477 | break; | 1681 | break; |
1478 | case CT_EMAC: | 1682 | case CT_EMAC: |
1479 | DRM_INFO("Connector Table: %d (emac)\n", | 1683 | DRM_INFO("Connector Table: %d (emac)\n", |
1480 | rdev->mode_info.connector_table); | 1684 | rdev->mode_info.connector_table); |
1481 | /* VGA - primary dac */ | 1685 | /* VGA - primary dac */ |
1482 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1686 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1687 | hpd.hpd = RADEON_HPD_NONE; | ||
1483 | radeon_add_legacy_encoder(dev, | 1688 | radeon_add_legacy_encoder(dev, |
1484 | radeon_get_encoder_id(dev, | 1689 | radeon_get_encoder_id(dev, |
1485 | ATOM_DEVICE_CRT1_SUPPORT, | 1690 | ATOM_DEVICE_CRT1_SUPPORT, |
1486 | 1), | 1691 | 1), |
1487 | ATOM_DEVICE_CRT1_SUPPORT); | 1692 | ATOM_DEVICE_CRT1_SUPPORT); |
1488 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, | 1693 | radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, |
1489 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c); | 1694 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
1695 | CONNECTOR_OBJECT_ID_VGA, | ||
1696 | &hpd); | ||
1490 | /* VGA - tv dac */ | 1697 | /* VGA - tv dac */ |
1491 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1698 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
1699 | hpd.hpd = RADEON_HPD_NONE; | ||
1492 | radeon_add_legacy_encoder(dev, | 1700 | radeon_add_legacy_encoder(dev, |
1493 | radeon_get_encoder_id(dev, | 1701 | radeon_get_encoder_id(dev, |
1494 | ATOM_DEVICE_CRT2_SUPPORT, | 1702 | ATOM_DEVICE_CRT2_SUPPORT, |
1495 | 2), | 1703 | 2), |
1496 | ATOM_DEVICE_CRT2_SUPPORT); | 1704 | ATOM_DEVICE_CRT2_SUPPORT); |
1497 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, | 1705 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, |
1498 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c); | 1706 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
1707 | CONNECTOR_OBJECT_ID_VGA, | ||
1708 | &hpd); | ||
1499 | /* TV - TV DAC */ | 1709 | /* TV - TV DAC */ |
1710 | ddc_i2c.valid = false; | ||
1711 | hpd.hpd = RADEON_HPD_NONE; | ||
1500 | radeon_add_legacy_encoder(dev, | 1712 | radeon_add_legacy_encoder(dev, |
1501 | radeon_get_encoder_id(dev, | 1713 | radeon_get_encoder_id(dev, |
1502 | ATOM_DEVICE_TV1_SUPPORT, | 1714 | ATOM_DEVICE_TV1_SUPPORT, |
@@ -1504,7 +1716,9 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1504 | ATOM_DEVICE_TV1_SUPPORT); | 1716 | ATOM_DEVICE_TV1_SUPPORT); |
1505 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | 1717 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
1506 | DRM_MODE_CONNECTOR_SVIDEO, | 1718 | DRM_MODE_CONNECTOR_SVIDEO, |
1507 | &ddc_i2c); | 1719 | &ddc_i2c, |
1720 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
1721 | &hpd); | ||
1508 | break; | 1722 | break; |
1509 | default: | 1723 | default: |
1510 | DRM_INFO("Connector table: %d (invalid)\n", | 1724 | DRM_INFO("Connector table: %d (invalid)\n", |
@@ -1521,7 +1735,8 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev, | |||
1521 | int bios_index, | 1735 | int bios_index, |
1522 | enum radeon_combios_connector | 1736 | enum radeon_combios_connector |
1523 | *legacy_connector, | 1737 | *legacy_connector, |
1524 | struct radeon_i2c_bus_rec *ddc_i2c) | 1738 | struct radeon_i2c_bus_rec *ddc_i2c, |
1739 | struct radeon_hpd *hpd) | ||
1525 | { | 1740 | { |
1526 | struct radeon_device *rdev = dev->dev_private; | 1741 | struct radeon_device *rdev = dev->dev_private; |
1527 | 1742 | ||
@@ -1529,29 +1744,26 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev, | |||
1529 | if ((rdev->family == CHIP_RS400 || | 1744 | if ((rdev->family == CHIP_RS400 || |
1530 | rdev->family == CHIP_RS480) && | 1745 | rdev->family == CHIP_RS480) && |
1531 | ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) | 1746 | ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) |
1532 | *ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1747 | *ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
1533 | else if ((rdev->family == CHIP_RS400 || | 1748 | else if ((rdev->family == CHIP_RS400 || |
1534 | rdev->family == CHIP_RS480) && | 1749 | rdev->family == CHIP_RS480) && |
1535 | ddc_i2c->mask_clk_reg == RADEON_GPIO_MONID) { | 1750 | ddc_i2c->mask_clk_reg == RADEON_GPIO_MONID) { |
1536 | ddc_i2c->valid = true; | 1751 | *ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIOPAD_MASK); |
1537 | ddc_i2c->mask_clk_mask = (0x20 << 8); | 1752 | ddc_i2c->mask_clk_mask = (0x20 << 8); |
1538 | ddc_i2c->mask_data_mask = 0x80; | 1753 | ddc_i2c->mask_data_mask = 0x80; |
1539 | ddc_i2c->a_clk_mask = (0x20 << 8); | 1754 | ddc_i2c->a_clk_mask = (0x20 << 8); |
1540 | ddc_i2c->a_data_mask = 0x80; | 1755 | ddc_i2c->a_data_mask = 0x80; |
1541 | ddc_i2c->put_clk_mask = (0x20 << 8); | 1756 | ddc_i2c->en_clk_mask = (0x20 << 8); |
1542 | ddc_i2c->put_data_mask = 0x80; | 1757 | ddc_i2c->en_data_mask = 0x80; |
1543 | ddc_i2c->get_clk_mask = (0x20 << 8); | 1758 | ddc_i2c->y_clk_mask = (0x20 << 8); |
1544 | ddc_i2c->get_data_mask = 0x80; | 1759 | ddc_i2c->y_data_mask = 0x80; |
1545 | ddc_i2c->mask_clk_reg = RADEON_GPIOPAD_MASK; | ||
1546 | ddc_i2c->mask_data_reg = RADEON_GPIOPAD_MASK; | ||
1547 | ddc_i2c->a_clk_reg = RADEON_GPIOPAD_A; | ||
1548 | ddc_i2c->a_data_reg = RADEON_GPIOPAD_A; | ||
1549 | ddc_i2c->put_clk_reg = RADEON_GPIOPAD_EN; | ||
1550 | ddc_i2c->put_data_reg = RADEON_GPIOPAD_EN; | ||
1551 | ddc_i2c->get_clk_reg = RADEON_LCD_GPIO_Y_REG; | ||
1552 | ddc_i2c->get_data_reg = RADEON_LCD_GPIO_Y_REG; | ||
1553 | } | 1760 | } |
1554 | 1761 | ||
1762 | /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */ | ||
1763 | if ((rdev->family >= CHIP_R300) && | ||
1764 | ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) | ||
1765 | *ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); | ||
1766 | |||
1555 | /* Certain IBM chipset RN50s have a BIOS reporting two VGAs, | 1767 | /* Certain IBM chipset RN50s have a BIOS reporting two VGAs, |
1556 | one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */ | 1768 | one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */ |
1557 | if (dev->pdev->device == 0x515e && | 1769 | if (dev->pdev->device == 0x515e && |
@@ -1581,15 +1793,74 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev, | |||
1581 | return true; | 1793 | return true; |
1582 | } | 1794 | } |
1583 | 1795 | ||
1796 | static bool radeon_apply_legacy_tv_quirks(struct drm_device *dev) | ||
1797 | { | ||
1798 | /* Acer 5102 has non-existent TV port */ | ||
1799 | if (dev->pdev->device == 0x5975 && | ||
1800 | dev->pdev->subsystem_vendor == 0x1025 && | ||
1801 | dev->pdev->subsystem_device == 0x009f) | ||
1802 | return false; | ||
1803 | |||
1804 | /* HP dc5750 has non-existent TV port */ | ||
1805 | if (dev->pdev->device == 0x5974 && | ||
1806 | dev->pdev->subsystem_vendor == 0x103c && | ||
1807 | dev->pdev->subsystem_device == 0x280a) | ||
1808 | return false; | ||
1809 | |||
1810 | /* MSI S270 has non-existent TV port */ | ||
1811 | if (dev->pdev->device == 0x5955 && | ||
1812 | dev->pdev->subsystem_vendor == 0x1462 && | ||
1813 | dev->pdev->subsystem_device == 0x0131) | ||
1814 | return false; | ||
1815 | |||
1816 | return true; | ||
1817 | } | ||
1818 | |||
1819 | static uint16_t combios_check_dl_dvi(struct drm_device *dev, int is_dvi_d) | ||
1820 | { | ||
1821 | struct radeon_device *rdev = dev->dev_private; | ||
1822 | uint32_t ext_tmds_info; | ||
1823 | |||
1824 | if (rdev->flags & RADEON_IS_IGP) { | ||
1825 | if (is_dvi_d) | ||
1826 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; | ||
1827 | else | ||
1828 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; | ||
1829 | } | ||
1830 | ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); | ||
1831 | if (ext_tmds_info) { | ||
1832 | uint8_t rev = RBIOS8(ext_tmds_info); | ||
1833 | uint8_t flags = RBIOS8(ext_tmds_info + 4 + 5); | ||
1834 | if (rev >= 3) { | ||
1835 | if (is_dvi_d) | ||
1836 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; | ||
1837 | else | ||
1838 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; | ||
1839 | } else { | ||
1840 | if (flags & 1) { | ||
1841 | if (is_dvi_d) | ||
1842 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; | ||
1843 | else | ||
1844 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; | ||
1845 | } | ||
1846 | } | ||
1847 | } | ||
1848 | if (is_dvi_d) | ||
1849 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; | ||
1850 | else | ||
1851 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; | ||
1852 | } | ||
1853 | |||
1584 | bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | 1854 | bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) |
1585 | { | 1855 | { |
1586 | struct radeon_device *rdev = dev->dev_private; | 1856 | struct radeon_device *rdev = dev->dev_private; |
1587 | uint32_t conn_info, entry, devices; | 1857 | uint32_t conn_info, entry, devices; |
1588 | uint16_t tmp; | 1858 | uint16_t tmp, connector_object_id; |
1589 | enum radeon_combios_ddc ddc_type; | 1859 | enum radeon_combios_ddc ddc_type; |
1590 | enum radeon_combios_connector connector; | 1860 | enum radeon_combios_connector connector; |
1591 | int i = 0; | 1861 | int i = 0; |
1592 | struct radeon_i2c_bus_rec ddc_i2c; | 1862 | struct radeon_i2c_bus_rec ddc_i2c; |
1863 | struct radeon_hpd hpd; | ||
1593 | 1864 | ||
1594 | if (rdev->bios == NULL) | 1865 | if (rdev->bios == NULL) |
1595 | return false; | 1866 | return false; |
@@ -1610,26 +1881,41 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1610 | switch (ddc_type) { | 1881 | switch (ddc_type) { |
1611 | case DDC_MONID: | 1882 | case DDC_MONID: |
1612 | ddc_i2c = | 1883 | ddc_i2c = |
1613 | combios_setup_i2c_bus(RADEON_GPIO_MONID); | 1884 | combios_setup_i2c_bus(rdev, RADEON_GPIO_MONID); |
1614 | break; | 1885 | break; |
1615 | case DDC_DVI: | 1886 | case DDC_DVI: |
1616 | ddc_i2c = | 1887 | ddc_i2c = |
1617 | combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 1888 | combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
1618 | break; | 1889 | break; |
1619 | case DDC_VGA: | 1890 | case DDC_VGA: |
1620 | ddc_i2c = | 1891 | ddc_i2c = |
1621 | combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | 1892 | combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); |
1622 | break; | 1893 | break; |
1623 | case DDC_CRT2: | 1894 | case DDC_CRT2: |
1624 | ddc_i2c = | 1895 | ddc_i2c = |
1625 | combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); | 1896 | combios_setup_i2c_bus(rdev, RADEON_GPIO_CRT2_DDC); |
1626 | break; | 1897 | break; |
1627 | default: | 1898 | default: |
1628 | break; | 1899 | break; |
1629 | } | 1900 | } |
1630 | 1901 | ||
1631 | radeon_apply_legacy_quirks(dev, i, &connector, | 1902 | switch (connector) { |
1632 | &ddc_i2c); | 1903 | case CONNECTOR_PROPRIETARY_LEGACY: |
1904 | case CONNECTOR_DVI_I_LEGACY: | ||
1905 | case CONNECTOR_DVI_D_LEGACY: | ||
1906 | if ((tmp >> 4) & 0x1) | ||
1907 | hpd.hpd = RADEON_HPD_2; | ||
1908 | else | ||
1909 | hpd.hpd = RADEON_HPD_1; | ||
1910 | break; | ||
1911 | default: | ||
1912 | hpd.hpd = RADEON_HPD_NONE; | ||
1913 | break; | ||
1914 | } | ||
1915 | |||
1916 | if (!radeon_apply_legacy_quirks(dev, i, &connector, | ||
1917 | &ddc_i2c, &hpd)) | ||
1918 | continue; | ||
1633 | 1919 | ||
1634 | switch (connector) { | 1920 | switch (connector) { |
1635 | case CONNECTOR_PROPRIETARY_LEGACY: | 1921 | case CONNECTOR_PROPRIETARY_LEGACY: |
@@ -1644,7 +1930,9 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1644 | radeon_add_legacy_connector(dev, i, devices, | 1930 | radeon_add_legacy_connector(dev, i, devices, |
1645 | legacy_connector_convert | 1931 | legacy_connector_convert |
1646 | [connector], | 1932 | [connector], |
1647 | &ddc_i2c); | 1933 | &ddc_i2c, |
1934 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D, | ||
1935 | &hpd); | ||
1648 | break; | 1936 | break; |
1649 | case CONNECTOR_CRT_LEGACY: | 1937 | case CONNECTOR_CRT_LEGACY: |
1650 | if (tmp & 0x1) { | 1938 | if (tmp & 0x1) { |
@@ -1669,7 +1957,9 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1669 | devices, | 1957 | devices, |
1670 | legacy_connector_convert | 1958 | legacy_connector_convert |
1671 | [connector], | 1959 | [connector], |
1672 | &ddc_i2c); | 1960 | &ddc_i2c, |
1961 | CONNECTOR_OBJECT_ID_VGA, | ||
1962 | &hpd); | ||
1673 | break; | 1963 | break; |
1674 | case CONNECTOR_DVI_I_LEGACY: | 1964 | case CONNECTOR_DVI_I_LEGACY: |
1675 | devices = 0; | 1965 | devices = 0; |
@@ -1698,6 +1988,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1698 | ATOM_DEVICE_DFP2_SUPPORT, | 1988 | ATOM_DEVICE_DFP2_SUPPORT, |
1699 | 0), | 1989 | 0), |
1700 | ATOM_DEVICE_DFP2_SUPPORT); | 1990 | ATOM_DEVICE_DFP2_SUPPORT); |
1991 | connector_object_id = combios_check_dl_dvi(dev, 0); | ||
1701 | } else { | 1992 | } else { |
1702 | devices |= ATOM_DEVICE_DFP1_SUPPORT; | 1993 | devices |= ATOM_DEVICE_DFP1_SUPPORT; |
1703 | radeon_add_legacy_encoder(dev, | 1994 | radeon_add_legacy_encoder(dev, |
@@ -1706,19 +1997,25 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1706 | ATOM_DEVICE_DFP1_SUPPORT, | 1997 | ATOM_DEVICE_DFP1_SUPPORT, |
1707 | 0), | 1998 | 0), |
1708 | ATOM_DEVICE_DFP1_SUPPORT); | 1999 | ATOM_DEVICE_DFP1_SUPPORT); |
2000 | connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; | ||
1709 | } | 2001 | } |
1710 | radeon_add_legacy_connector(dev, | 2002 | radeon_add_legacy_connector(dev, |
1711 | i, | 2003 | i, |
1712 | devices, | 2004 | devices, |
1713 | legacy_connector_convert | 2005 | legacy_connector_convert |
1714 | [connector], | 2006 | [connector], |
1715 | &ddc_i2c); | 2007 | &ddc_i2c, |
2008 | connector_object_id, | ||
2009 | &hpd); | ||
1716 | break; | 2010 | break; |
1717 | case CONNECTOR_DVI_D_LEGACY: | 2011 | case CONNECTOR_DVI_D_LEGACY: |
1718 | if ((tmp >> 4) & 0x1) | 2012 | if ((tmp >> 4) & 0x1) { |
1719 | devices = ATOM_DEVICE_DFP2_SUPPORT; | 2013 | devices = ATOM_DEVICE_DFP2_SUPPORT; |
1720 | else | 2014 | connector_object_id = combios_check_dl_dvi(dev, 1); |
2015 | } else { | ||
1721 | devices = ATOM_DEVICE_DFP1_SUPPORT; | 2016 | devices = ATOM_DEVICE_DFP1_SUPPORT; |
2017 | connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; | ||
2018 | } | ||
1722 | radeon_add_legacy_encoder(dev, | 2019 | radeon_add_legacy_encoder(dev, |
1723 | radeon_get_encoder_id | 2020 | radeon_get_encoder_id |
1724 | (dev, devices, 0), | 2021 | (dev, devices, 0), |
@@ -1726,7 +2023,9 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1726 | radeon_add_legacy_connector(dev, i, devices, | 2023 | radeon_add_legacy_connector(dev, i, devices, |
1727 | legacy_connector_convert | 2024 | legacy_connector_convert |
1728 | [connector], | 2025 | [connector], |
1729 | &ddc_i2c); | 2026 | &ddc_i2c, |
2027 | connector_object_id, | ||
2028 | &hpd); | ||
1730 | break; | 2029 | break; |
1731 | case CONNECTOR_CTV_LEGACY: | 2030 | case CONNECTOR_CTV_LEGACY: |
1732 | case CONNECTOR_STV_LEGACY: | 2031 | case CONNECTOR_STV_LEGACY: |
@@ -1740,7 +2039,9 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1740 | ATOM_DEVICE_TV1_SUPPORT, | 2039 | ATOM_DEVICE_TV1_SUPPORT, |
1741 | legacy_connector_convert | 2040 | legacy_connector_convert |
1742 | [connector], | 2041 | [connector], |
1743 | &ddc_i2c); | 2042 | &ddc_i2c, |
2043 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
2044 | &hpd); | ||
1744 | break; | 2045 | break; |
1745 | default: | 2046 | default: |
1746 | DRM_ERROR("Unknown connector type: %d\n", | 2047 | DRM_ERROR("Unknown connector type: %d\n", |
@@ -1766,16 +2067,39 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1766 | 0), | 2067 | 0), |
1767 | ATOM_DEVICE_DFP1_SUPPORT); | 2068 | ATOM_DEVICE_DFP1_SUPPORT); |
1768 | 2069 | ||
1769 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); | 2070 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_DVI_DDC); |
2071 | hpd.hpd = RADEON_HPD_NONE; | ||
1770 | radeon_add_legacy_connector(dev, | 2072 | radeon_add_legacy_connector(dev, |
1771 | 0, | 2073 | 0, |
1772 | ATOM_DEVICE_CRT1_SUPPORT | | 2074 | ATOM_DEVICE_CRT1_SUPPORT | |
1773 | ATOM_DEVICE_DFP1_SUPPORT, | 2075 | ATOM_DEVICE_DFP1_SUPPORT, |
1774 | DRM_MODE_CONNECTOR_DVII, | 2076 | DRM_MODE_CONNECTOR_DVII, |
1775 | &ddc_i2c); | 2077 | &ddc_i2c, |
2078 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, | ||
2079 | &hpd); | ||
1776 | } else { | 2080 | } else { |
1777 | DRM_DEBUG("No connector info found\n"); | 2081 | uint16_t crt_info = |
1778 | return false; | 2082 | combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); |
2083 | DRM_DEBUG("Found CRT table, assuming VGA connector\n"); | ||
2084 | if (crt_info) { | ||
2085 | radeon_add_legacy_encoder(dev, | ||
2086 | radeon_get_encoder_id(dev, | ||
2087 | ATOM_DEVICE_CRT1_SUPPORT, | ||
2088 | 1), | ||
2089 | ATOM_DEVICE_CRT1_SUPPORT); | ||
2090 | ddc_i2c = combios_setup_i2c_bus(rdev, RADEON_GPIO_VGA_DDC); | ||
2091 | hpd.hpd = RADEON_HPD_NONE; | ||
2092 | radeon_add_legacy_connector(dev, | ||
2093 | 0, | ||
2094 | ATOM_DEVICE_CRT1_SUPPORT, | ||
2095 | DRM_MODE_CONNECTOR_VGA, | ||
2096 | &ddc_i2c, | ||
2097 | CONNECTOR_OBJECT_ID_VGA, | ||
2098 | &hpd); | ||
2099 | } else { | ||
2100 | DRM_DEBUG("No connector info found\n"); | ||
2101 | return false; | ||
2102 | } | ||
1779 | } | 2103 | } |
1780 | } | 2104 | } |
1781 | 2105 | ||
@@ -1799,27 +2123,27 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1799 | case DDC_MONID: | 2123 | case DDC_MONID: |
1800 | ddc_i2c = | 2124 | ddc_i2c = |
1801 | combios_setup_i2c_bus | 2125 | combios_setup_i2c_bus |
1802 | (RADEON_GPIO_MONID); | 2126 | (rdev, RADEON_GPIO_MONID); |
1803 | break; | 2127 | break; |
1804 | case DDC_DVI: | 2128 | case DDC_DVI: |
1805 | ddc_i2c = | 2129 | ddc_i2c = |
1806 | combios_setup_i2c_bus | 2130 | combios_setup_i2c_bus |
1807 | (RADEON_GPIO_DVI_DDC); | 2131 | (rdev, RADEON_GPIO_DVI_DDC); |
1808 | break; | 2132 | break; |
1809 | case DDC_VGA: | 2133 | case DDC_VGA: |
1810 | ddc_i2c = | 2134 | ddc_i2c = |
1811 | combios_setup_i2c_bus | 2135 | combios_setup_i2c_bus |
1812 | (RADEON_GPIO_VGA_DDC); | 2136 | (rdev, RADEON_GPIO_VGA_DDC); |
1813 | break; | 2137 | break; |
1814 | case DDC_CRT2: | 2138 | case DDC_CRT2: |
1815 | ddc_i2c = | 2139 | ddc_i2c = |
1816 | combios_setup_i2c_bus | 2140 | combios_setup_i2c_bus |
1817 | (RADEON_GPIO_CRT2_DDC); | 2141 | (rdev, RADEON_GPIO_CRT2_DDC); |
1818 | break; | 2142 | break; |
1819 | case DDC_LCD: | 2143 | case DDC_LCD: |
1820 | ddc_i2c = | 2144 | ddc_i2c = |
1821 | combios_setup_i2c_bus | 2145 | combios_setup_i2c_bus |
1822 | (RADEON_LCD_GPIO_MASK); | 2146 | (rdev, RADEON_GPIOPAD_MASK); |
1823 | ddc_i2c.mask_clk_mask = | 2147 | ddc_i2c.mask_clk_mask = |
1824 | RBIOS32(lcd_ddc_info + 3); | 2148 | RBIOS32(lcd_ddc_info + 3); |
1825 | ddc_i2c.mask_data_mask = | 2149 | ddc_i2c.mask_data_mask = |
@@ -1828,19 +2152,19 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1828 | RBIOS32(lcd_ddc_info + 3); | 2152 | RBIOS32(lcd_ddc_info + 3); |
1829 | ddc_i2c.a_data_mask = | 2153 | ddc_i2c.a_data_mask = |
1830 | RBIOS32(lcd_ddc_info + 7); | 2154 | RBIOS32(lcd_ddc_info + 7); |
1831 | ddc_i2c.put_clk_mask = | 2155 | ddc_i2c.en_clk_mask = |
1832 | RBIOS32(lcd_ddc_info + 3); | 2156 | RBIOS32(lcd_ddc_info + 3); |
1833 | ddc_i2c.put_data_mask = | 2157 | ddc_i2c.en_data_mask = |
1834 | RBIOS32(lcd_ddc_info + 7); | 2158 | RBIOS32(lcd_ddc_info + 7); |
1835 | ddc_i2c.get_clk_mask = | 2159 | ddc_i2c.y_clk_mask = |
1836 | RBIOS32(lcd_ddc_info + 3); | 2160 | RBIOS32(lcd_ddc_info + 3); |
1837 | ddc_i2c.get_data_mask = | 2161 | ddc_i2c.y_data_mask = |
1838 | RBIOS32(lcd_ddc_info + 7); | 2162 | RBIOS32(lcd_ddc_info + 7); |
1839 | break; | 2163 | break; |
1840 | case DDC_GPIO: | 2164 | case DDC_GPIO: |
1841 | ddc_i2c = | 2165 | ddc_i2c = |
1842 | combios_setup_i2c_bus | 2166 | combios_setup_i2c_bus |
1843 | (RADEON_MDGPIO_EN_REG); | 2167 | (rdev, RADEON_MDGPIO_MASK); |
1844 | ddc_i2c.mask_clk_mask = | 2168 | ddc_i2c.mask_clk_mask = |
1845 | RBIOS32(lcd_ddc_info + 3); | 2169 | RBIOS32(lcd_ddc_info + 3); |
1846 | ddc_i2c.mask_data_mask = | 2170 | ddc_i2c.mask_data_mask = |
@@ -1849,13 +2173,13 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1849 | RBIOS32(lcd_ddc_info + 3); | 2173 | RBIOS32(lcd_ddc_info + 3); |
1850 | ddc_i2c.a_data_mask = | 2174 | ddc_i2c.a_data_mask = |
1851 | RBIOS32(lcd_ddc_info + 7); | 2175 | RBIOS32(lcd_ddc_info + 7); |
1852 | ddc_i2c.put_clk_mask = | 2176 | ddc_i2c.en_clk_mask = |
1853 | RBIOS32(lcd_ddc_info + 3); | 2177 | RBIOS32(lcd_ddc_info + 3); |
1854 | ddc_i2c.put_data_mask = | 2178 | ddc_i2c.en_data_mask = |
1855 | RBIOS32(lcd_ddc_info + 7); | 2179 | RBIOS32(lcd_ddc_info + 7); |
1856 | ddc_i2c.get_clk_mask = | 2180 | ddc_i2c.y_clk_mask = |
1857 | RBIOS32(lcd_ddc_info + 3); | 2181 | RBIOS32(lcd_ddc_info + 3); |
1858 | ddc_i2c.get_data_mask = | 2182 | ddc_i2c.y_data_mask = |
1859 | RBIOS32(lcd_ddc_info + 7); | 2183 | RBIOS32(lcd_ddc_info + 7); |
1860 | break; | 2184 | break; |
1861 | default: | 2185 | default: |
@@ -1866,11 +2190,14 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1866 | } else | 2190 | } else |
1867 | ddc_i2c.valid = false; | 2191 | ddc_i2c.valid = false; |
1868 | 2192 | ||
2193 | hpd.hpd = RADEON_HPD_NONE; | ||
1869 | radeon_add_legacy_connector(dev, | 2194 | radeon_add_legacy_connector(dev, |
1870 | 5, | 2195 | 5, |
1871 | ATOM_DEVICE_LCD1_SUPPORT, | 2196 | ATOM_DEVICE_LCD1_SUPPORT, |
1872 | DRM_MODE_CONNECTOR_LVDS, | 2197 | DRM_MODE_CONNECTOR_LVDS, |
1873 | &ddc_i2c); | 2198 | &ddc_i2c, |
2199 | CONNECTOR_OBJECT_ID_LVDS, | ||
2200 | &hpd); | ||
1874 | } | 2201 | } |
1875 | } | 2202 | } |
1876 | 2203 | ||
@@ -1880,16 +2207,21 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1880 | combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); | 2207 | combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); |
1881 | if (tv_info) { | 2208 | if (tv_info) { |
1882 | if (RBIOS8(tv_info + 6) == 'T') { | 2209 | if (RBIOS8(tv_info + 6) == 'T') { |
1883 | radeon_add_legacy_encoder(dev, | 2210 | if (radeon_apply_legacy_tv_quirks(dev)) { |
1884 | radeon_get_encoder_id | 2211 | hpd.hpd = RADEON_HPD_NONE; |
1885 | (dev, | 2212 | radeon_add_legacy_encoder(dev, |
1886 | ATOM_DEVICE_TV1_SUPPORT, | 2213 | radeon_get_encoder_id |
1887 | 2), | 2214 | (dev, |
1888 | ATOM_DEVICE_TV1_SUPPORT); | 2215 | ATOM_DEVICE_TV1_SUPPORT, |
1889 | radeon_add_legacy_connector(dev, 6, | 2216 | 2), |
1890 | ATOM_DEVICE_TV1_SUPPORT, | 2217 | ATOM_DEVICE_TV1_SUPPORT); |
1891 | DRM_MODE_CONNECTOR_SVIDEO, | 2218 | radeon_add_legacy_connector(dev, 6, |
1892 | &ddc_i2c); | 2219 | ATOM_DEVICE_TV1_SUPPORT, |
2220 | DRM_MODE_CONNECTOR_SVIDEO, | ||
2221 | &ddc_i2c, | ||
2222 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
2223 | &hpd); | ||
2224 | } | ||
1893 | } | 2225 | } |
1894 | } | 2226 | } |
1895 | } | 2227 | } |
@@ -1899,6 +2231,193 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1899 | return true; | 2231 | return true; |
1900 | } | 2232 | } |
1901 | 2233 | ||
2234 | void radeon_external_tmds_setup(struct drm_encoder *encoder) | ||
2235 | { | ||
2236 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
2237 | struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; | ||
2238 | |||
2239 | if (!tmds) | ||
2240 | return; | ||
2241 | |||
2242 | switch (tmds->dvo_chip) { | ||
2243 | case DVO_SIL164: | ||
2244 | /* sil 164 */ | ||
2245 | radeon_i2c_do_lock(tmds->i2c_bus, 1); | ||
2246 | radeon_i2c_sw_put_byte(tmds->i2c_bus, | ||
2247 | tmds->slave_addr, | ||
2248 | 0x08, 0x30); | ||
2249 | radeon_i2c_sw_put_byte(tmds->i2c_bus, | ||
2250 | tmds->slave_addr, | ||
2251 | 0x09, 0x00); | ||
2252 | radeon_i2c_sw_put_byte(tmds->i2c_bus, | ||
2253 | tmds->slave_addr, | ||
2254 | 0x0a, 0x90); | ||
2255 | radeon_i2c_sw_put_byte(tmds->i2c_bus, | ||
2256 | tmds->slave_addr, | ||
2257 | 0x0c, 0x89); | ||
2258 | radeon_i2c_sw_put_byte(tmds->i2c_bus, | ||
2259 | tmds->slave_addr, | ||
2260 | 0x08, 0x3b); | ||
2261 | radeon_i2c_do_lock(tmds->i2c_bus, 0); | ||
2262 | break; | ||
2263 | case DVO_SIL1178: | ||
2264 | /* sil 1178 - untested */ | ||
2265 | /* | ||
2266 | * 0x0f, 0x44 | ||
2267 | * 0x0f, 0x4c | ||
2268 | * 0x0e, 0x01 | ||
2269 | * 0x0a, 0x80 | ||
2270 | * 0x09, 0x30 | ||
2271 | * 0x0c, 0xc9 | ||
2272 | * 0x0d, 0x70 | ||
2273 | * 0x08, 0x32 | ||
2274 | * 0x08, 0x33 | ||
2275 | */ | ||
2276 | break; | ||
2277 | default: | ||
2278 | break; | ||
2279 | } | ||
2280 | |||
2281 | } | ||
2282 | |||
2283 | bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder) | ||
2284 | { | ||
2285 | struct drm_device *dev = encoder->dev; | ||
2286 | struct radeon_device *rdev = dev->dev_private; | ||
2287 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
2288 | uint16_t offset; | ||
2289 | uint8_t blocks, slave_addr, rev; | ||
2290 | uint32_t index, id; | ||
2291 | uint32_t reg, val, and_mask, or_mask; | ||
2292 | struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; | ||
2293 | |||
2294 | if (rdev->bios == NULL) | ||
2295 | return false; | ||
2296 | |||
2297 | if (!tmds) | ||
2298 | return false; | ||
2299 | |||
2300 | if (rdev->flags & RADEON_IS_IGP) { | ||
2301 | offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE); | ||
2302 | rev = RBIOS8(offset); | ||
2303 | if (offset) { | ||
2304 | rev = RBIOS8(offset); | ||
2305 | if (rev > 1) { | ||
2306 | blocks = RBIOS8(offset + 3); | ||
2307 | index = offset + 4; | ||
2308 | while (blocks > 0) { | ||
2309 | id = RBIOS16(index); | ||
2310 | index += 2; | ||
2311 | switch (id >> 13) { | ||
2312 | case 0: | ||
2313 | reg = (id & 0x1fff) * 4; | ||
2314 | val = RBIOS32(index); | ||
2315 | index += 4; | ||
2316 | WREG32(reg, val); | ||
2317 | break; | ||
2318 | case 2: | ||
2319 | reg = (id & 0x1fff) * 4; | ||
2320 | and_mask = RBIOS32(index); | ||
2321 | index += 4; | ||
2322 | or_mask = RBIOS32(index); | ||
2323 | index += 4; | ||
2324 | val = RREG32(reg); | ||
2325 | val = (val & and_mask) | or_mask; | ||
2326 | WREG32(reg, val); | ||
2327 | break; | ||
2328 | case 3: | ||
2329 | val = RBIOS16(index); | ||
2330 | index += 2; | ||
2331 | udelay(val); | ||
2332 | break; | ||
2333 | case 4: | ||
2334 | val = RBIOS16(index); | ||
2335 | index += 2; | ||
2336 | udelay(val * 1000); | ||
2337 | break; | ||
2338 | case 6: | ||
2339 | slave_addr = id & 0xff; | ||
2340 | slave_addr >>= 1; /* 7 bit addressing */ | ||
2341 | index++; | ||
2342 | reg = RBIOS8(index); | ||
2343 | index++; | ||
2344 | val = RBIOS8(index); | ||
2345 | index++; | ||
2346 | radeon_i2c_do_lock(tmds->i2c_bus, 1); | ||
2347 | radeon_i2c_sw_put_byte(tmds->i2c_bus, | ||
2348 | slave_addr, | ||
2349 | reg, val); | ||
2350 | radeon_i2c_do_lock(tmds->i2c_bus, 0); | ||
2351 | break; | ||
2352 | default: | ||
2353 | DRM_ERROR("Unknown id %d\n", id >> 13); | ||
2354 | break; | ||
2355 | } | ||
2356 | blocks--; | ||
2357 | } | ||
2358 | return true; | ||
2359 | } | ||
2360 | } | ||
2361 | } else { | ||
2362 | offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); | ||
2363 | if (offset) { | ||
2364 | index = offset + 10; | ||
2365 | id = RBIOS16(index); | ||
2366 | while (id != 0xffff) { | ||
2367 | index += 2; | ||
2368 | switch (id >> 13) { | ||
2369 | case 0: | ||
2370 | reg = (id & 0x1fff) * 4; | ||
2371 | val = RBIOS32(index); | ||
2372 | WREG32(reg, val); | ||
2373 | break; | ||
2374 | case 2: | ||
2375 | reg = (id & 0x1fff) * 4; | ||
2376 | and_mask = RBIOS32(index); | ||
2377 | index += 4; | ||
2378 | or_mask = RBIOS32(index); | ||
2379 | index += 4; | ||
2380 | val = RREG32(reg); | ||
2381 | val = (val & and_mask) | or_mask; | ||
2382 | WREG32(reg, val); | ||
2383 | break; | ||
2384 | case 4: | ||
2385 | val = RBIOS16(index); | ||
2386 | index += 2; | ||
2387 | udelay(val); | ||
2388 | break; | ||
2389 | case 5: | ||
2390 | reg = id & 0x1fff; | ||
2391 | and_mask = RBIOS32(index); | ||
2392 | index += 4; | ||
2393 | or_mask = RBIOS32(index); | ||
2394 | index += 4; | ||
2395 | val = RREG32_PLL(reg); | ||
2396 | val = (val & and_mask) | or_mask; | ||
2397 | WREG32_PLL(reg, val); | ||
2398 | break; | ||
2399 | case 6: | ||
2400 | reg = id & 0x1fff; | ||
2401 | val = RBIOS8(index); | ||
2402 | index += 1; | ||
2403 | radeon_i2c_do_lock(tmds->i2c_bus, 1); | ||
2404 | radeon_i2c_sw_put_byte(tmds->i2c_bus, | ||
2405 | tmds->slave_addr, | ||
2406 | reg, val); | ||
2407 | radeon_i2c_do_lock(tmds->i2c_bus, 0); | ||
2408 | break; | ||
2409 | default: | ||
2410 | DRM_ERROR("Unknown id %d\n", id >> 13); | ||
2411 | break; | ||
2412 | } | ||
2413 | id = RBIOS16(index); | ||
2414 | } | ||
2415 | return true; | ||
2416 | } | ||
2417 | } | ||
2418 | return false; | ||
2419 | } | ||
2420 | |||
1902 | static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset) | 2421 | static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset) |
1903 | { | 2422 | { |
1904 | struct radeon_device *rdev = dev->dev_private; | 2423 | struct radeon_device *rdev = dev->dev_private; |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index e376be47a4a0..5eece186e03c 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -40,6 +40,26 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
40 | struct drm_encoder *encoder, | 40 | struct drm_encoder *encoder, |
41 | bool connected); | 41 | bool connected); |
42 | 42 | ||
43 | void radeon_connector_hotplug(struct drm_connector *connector) | ||
44 | { | ||
45 | struct drm_device *dev = connector->dev; | ||
46 | struct radeon_device *rdev = dev->dev_private; | ||
47 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
48 | |||
49 | if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) | ||
50 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | ||
51 | |||
52 | if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { | ||
53 | if (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) { | ||
54 | if (radeon_dp_needs_link_train(radeon_connector)) { | ||
55 | if (connector->encoder) | ||
56 | dp_link_train(connector->encoder, connector); | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
61 | } | ||
62 | |||
43 | static void radeon_property_change_mode(struct drm_encoder *encoder) | 63 | static void radeon_property_change_mode(struct drm_encoder *encoder) |
44 | { | 64 | { |
45 | struct drm_crtc *crtc = encoder->crtc; | 65 | struct drm_crtc *crtc = encoder->crtc; |
@@ -178,25 +198,12 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode | |||
178 | struct drm_device *dev = encoder->dev; | 198 | struct drm_device *dev = encoder->dev; |
179 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 199 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
180 | struct drm_display_mode *mode = NULL; | 200 | struct drm_display_mode *mode = NULL; |
181 | struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; | 201 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
182 | |||
183 | if (native_mode->panel_xres != 0 && | ||
184 | native_mode->panel_yres != 0 && | ||
185 | native_mode->dotclock != 0) { | ||
186 | mode = drm_mode_create(dev); | ||
187 | |||
188 | mode->hdisplay = native_mode->panel_xres; | ||
189 | mode->vdisplay = native_mode->panel_yres; | ||
190 | |||
191 | mode->htotal = mode->hdisplay + native_mode->hblank; | ||
192 | mode->hsync_start = mode->hdisplay + native_mode->hoverplus; | ||
193 | mode->hsync_end = mode->hsync_start + native_mode->hsync_width; | ||
194 | mode->vtotal = mode->vdisplay + native_mode->vblank; | ||
195 | mode->vsync_start = mode->vdisplay + native_mode->voverplus; | ||
196 | mode->vsync_end = mode->vsync_start + native_mode->vsync_width; | ||
197 | mode->clock = native_mode->dotclock; | ||
198 | mode->flags = 0; | ||
199 | 202 | ||
203 | if (native_mode->hdisplay != 0 && | ||
204 | native_mode->vdisplay != 0 && | ||
205 | native_mode->clock != 0) { | ||
206 | mode = drm_mode_duplicate(dev, native_mode); | ||
200 | mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; | 207 | mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; |
201 | drm_mode_set_name(mode); | 208 | drm_mode_set_name(mode); |
202 | 209 | ||
@@ -210,7 +217,7 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn | |||
210 | struct drm_device *dev = encoder->dev; | 217 | struct drm_device *dev = encoder->dev; |
211 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 218 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
212 | struct drm_display_mode *mode = NULL; | 219 | struct drm_display_mode *mode = NULL; |
213 | struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; | 220 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
214 | int i; | 221 | int i; |
215 | struct mode_size { | 222 | struct mode_size { |
216 | int w; | 223 | int w; |
@@ -236,11 +243,16 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn | |||
236 | }; | 243 | }; |
237 | 244 | ||
238 | for (i = 0; i < 17; i++) { | 245 | for (i = 0; i < 17; i++) { |
246 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) { | ||
247 | if (common_modes[i].w > 1024 || | ||
248 | common_modes[i].h > 768) | ||
249 | continue; | ||
250 | } | ||
239 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 251 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
240 | if (common_modes[i].w > native_mode->panel_xres || | 252 | if (common_modes[i].w > native_mode->hdisplay || |
241 | common_modes[i].h > native_mode->panel_yres || | 253 | common_modes[i].h > native_mode->vdisplay || |
242 | (common_modes[i].w == native_mode->panel_xres && | 254 | (common_modes[i].w == native_mode->hdisplay && |
243 | common_modes[i].h == native_mode->panel_yres)) | 255 | common_modes[i].h == native_mode->vdisplay)) |
244 | continue; | 256 | continue; |
245 | } | 257 | } |
246 | if (common_modes[i].w < 320 || common_modes[i].h < 200) | 258 | if (common_modes[i].w < 320 || common_modes[i].h < 200) |
@@ -344,28 +356,23 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, | |||
344 | struct drm_connector *connector) | 356 | struct drm_connector *connector) |
345 | { | 357 | { |
346 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 358 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
347 | struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; | 359 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
348 | 360 | ||
349 | /* Try to get native mode details from EDID if necessary */ | 361 | /* Try to get native mode details from EDID if necessary */ |
350 | if (!native_mode->dotclock) { | 362 | if (!native_mode->clock) { |
351 | struct drm_display_mode *t, *mode; | 363 | struct drm_display_mode *t, *mode; |
352 | 364 | ||
353 | list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { | 365 | list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { |
354 | if (mode->hdisplay == native_mode->panel_xres && | 366 | if (mode->hdisplay == native_mode->hdisplay && |
355 | mode->vdisplay == native_mode->panel_yres) { | 367 | mode->vdisplay == native_mode->vdisplay) { |
356 | native_mode->hblank = mode->htotal - mode->hdisplay; | 368 | *native_mode = *mode; |
357 | native_mode->hoverplus = mode->hsync_start - mode->hdisplay; | 369 | drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V); |
358 | native_mode->hsync_width = mode->hsync_end - mode->hsync_start; | ||
359 | native_mode->vblank = mode->vtotal - mode->vdisplay; | ||
360 | native_mode->voverplus = mode->vsync_start - mode->vdisplay; | ||
361 | native_mode->vsync_width = mode->vsync_end - mode->vsync_start; | ||
362 | native_mode->dotclock = mode->clock; | ||
363 | DRM_INFO("Determined LVDS native mode details from EDID\n"); | 370 | DRM_INFO("Determined LVDS native mode details from EDID\n"); |
364 | break; | 371 | break; |
365 | } | 372 | } |
366 | } | 373 | } |
367 | } | 374 | } |
368 | if (!native_mode->dotclock) { | 375 | if (!native_mode->clock) { |
369 | DRM_INFO("No LVDS native mode details, disabling RMX\n"); | 376 | DRM_INFO("No LVDS native mode details, disabling RMX\n"); |
370 | radeon_encoder->rmx_type = RMX_OFF; | 377 | radeon_encoder->rmx_type = RMX_OFF; |
371 | } | 378 | } |
@@ -410,13 +417,64 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) | |||
410 | static int radeon_lvds_mode_valid(struct drm_connector *connector, | 417 | static int radeon_lvds_mode_valid(struct drm_connector *connector, |
411 | struct drm_display_mode *mode) | 418 | struct drm_display_mode *mode) |
412 | { | 419 | { |
420 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | ||
421 | |||
422 | if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) | ||
423 | return MODE_PANEL; | ||
424 | |||
425 | if (encoder) { | ||
426 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
427 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; | ||
428 | |||
429 | /* AVIVO hardware supports downscaling modes larger than the panel | ||
430 | * to the panel size, but I'm not sure this is desirable. | ||
431 | */ | ||
432 | if ((mode->hdisplay > native_mode->hdisplay) || | ||
433 | (mode->vdisplay > native_mode->vdisplay)) | ||
434 | return MODE_PANEL; | ||
435 | |||
436 | /* if scaling is disabled, block non-native modes */ | ||
437 | if (radeon_encoder->rmx_type == RMX_OFF) { | ||
438 | if ((mode->hdisplay != native_mode->hdisplay) || | ||
439 | (mode->vdisplay != native_mode->vdisplay)) | ||
440 | return MODE_PANEL; | ||
441 | } | ||
442 | } | ||
443 | |||
413 | return MODE_OK; | 444 | return MODE_OK; |
414 | } | 445 | } |
415 | 446 | ||
416 | static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) | 447 | static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) |
417 | { | 448 | { |
418 | enum drm_connector_status ret = connector_status_connected; | 449 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
450 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | ||
451 | enum drm_connector_status ret = connector_status_disconnected; | ||
452 | |||
453 | if (encoder) { | ||
454 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
455 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; | ||
456 | |||
457 | /* check if panel is valid */ | ||
458 | if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) | ||
459 | ret = connector_status_connected; | ||
460 | |||
461 | } | ||
462 | |||
463 | /* check for edid as well */ | ||
464 | if (radeon_connector->edid) | ||
465 | ret = connector_status_connected; | ||
466 | else { | ||
467 | if (radeon_connector->ddc_bus) { | ||
468 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); | ||
469 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, | ||
470 | &radeon_connector->ddc_bus->adapter); | ||
471 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | ||
472 | if (radeon_connector->edid) | ||
473 | ret = connector_status_connected; | ||
474 | } | ||
475 | } | ||
419 | /* check acpi lid status ??? */ | 476 | /* check acpi lid status ??? */ |
477 | |||
420 | radeon_connector_update_scratch_regs(connector, ret); | 478 | radeon_connector_update_scratch_regs(connector, ret); |
421 | return ret; | 479 | return ret; |
422 | } | 480 | } |
@@ -427,6 +485,8 @@ static void radeon_connector_destroy(struct drm_connector *connector) | |||
427 | 485 | ||
428 | if (radeon_connector->ddc_bus) | 486 | if (radeon_connector->ddc_bus) |
429 | radeon_i2c_destroy(radeon_connector->ddc_bus); | 487 | radeon_i2c_destroy(radeon_connector->ddc_bus); |
488 | if (radeon_connector->edid) | ||
489 | kfree(radeon_connector->edid); | ||
430 | kfree(radeon_connector->con_priv); | 490 | kfree(radeon_connector->con_priv); |
431 | drm_sysfs_connector_remove(connector); | 491 | drm_sysfs_connector_remove(connector); |
432 | drm_connector_cleanup(connector); | 492 | drm_connector_cleanup(connector); |
@@ -496,6 +556,8 @@ static int radeon_vga_get_modes(struct drm_connector *connector) | |||
496 | static int radeon_vga_mode_valid(struct drm_connector *connector, | 556 | static int radeon_vga_mode_valid(struct drm_connector *connector, |
497 | struct drm_display_mode *mode) | 557 | struct drm_display_mode *mode) |
498 | { | 558 | { |
559 | /* XXX check mode bandwidth */ | ||
560 | /* XXX verify against max DAC output frequency */ | ||
499 | return MODE_OK; | 561 | return MODE_OK; |
500 | } | 562 | } |
501 | 563 | ||
@@ -511,12 +573,36 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect | |||
511 | if (!encoder) | 573 | if (!encoder) |
512 | ret = connector_status_disconnected; | 574 | ret = connector_status_disconnected; |
513 | 575 | ||
514 | radeon_i2c_do_lock(radeon_connector, 1); | 576 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); |
515 | dret = radeon_ddc_probe(radeon_connector); | 577 | dret = radeon_ddc_probe(radeon_connector); |
516 | radeon_i2c_do_lock(radeon_connector, 0); | 578 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); |
517 | if (dret) | 579 | if (dret) { |
518 | ret = connector_status_connected; | 580 | if (radeon_connector->edid) { |
519 | else { | 581 | kfree(radeon_connector->edid); |
582 | radeon_connector->edid = NULL; | ||
583 | } | ||
584 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); | ||
585 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); | ||
586 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | ||
587 | |||
588 | if (!radeon_connector->edid) { | ||
589 | DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", | ||
590 | drm_get_connector_name(connector)); | ||
591 | ret = connector_status_connected; | ||
592 | } else { | ||
593 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | ||
594 | |||
595 | /* some oems have boards with separate digital and analog connectors | ||
596 | * with a shared ddc line (often vga + hdmi) | ||
597 | */ | ||
598 | if (radeon_connector->use_digital && radeon_connector->shared_ddc) { | ||
599 | kfree(radeon_connector->edid); | ||
600 | radeon_connector->edid = NULL; | ||
601 | ret = connector_status_disconnected; | ||
602 | } else | ||
603 | ret = connector_status_connected; | ||
604 | } | ||
605 | } else { | ||
520 | if (radeon_connector->dac_load_detect) { | 606 | if (radeon_connector->dac_load_detect) { |
521 | encoder_funcs = encoder->helper_private; | 607 | encoder_funcs = encoder->helper_private; |
522 | ret = encoder_funcs->detect(encoder, connector); | 608 | ret = encoder_funcs->detect(encoder, connector); |
@@ -570,6 +656,8 @@ static int radeon_tv_get_modes(struct drm_connector *connector) | |||
570 | static int radeon_tv_mode_valid(struct drm_connector *connector, | 656 | static int radeon_tv_mode_valid(struct drm_connector *connector, |
571 | struct drm_display_mode *mode) | 657 | struct drm_display_mode *mode) |
572 | { | 658 | { |
659 | if ((mode->hdisplay > 1024) || (mode->vdisplay > 768)) | ||
660 | return MODE_CLOCK_RANGE; | ||
573 | return MODE_OK; | 661 | return MODE_OK; |
574 | } | 662 | } |
575 | 663 | ||
@@ -640,24 +728,66 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect | |||
640 | enum drm_connector_status ret = connector_status_disconnected; | 728 | enum drm_connector_status ret = connector_status_disconnected; |
641 | bool dret; | 729 | bool dret; |
642 | 730 | ||
643 | radeon_i2c_do_lock(radeon_connector, 1); | 731 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); |
644 | dret = radeon_ddc_probe(radeon_connector); | 732 | dret = radeon_ddc_probe(radeon_connector); |
645 | radeon_i2c_do_lock(radeon_connector, 0); | 733 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); |
646 | if (dret) { | 734 | if (dret) { |
647 | radeon_i2c_do_lock(radeon_connector, 1); | 735 | if (radeon_connector->edid) { |
736 | kfree(radeon_connector->edid); | ||
737 | radeon_connector->edid = NULL; | ||
738 | } | ||
739 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); | ||
648 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); | 740 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
649 | radeon_i2c_do_lock(radeon_connector, 0); | 741 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); |
650 | 742 | ||
651 | if (!radeon_connector->edid) { | 743 | if (!radeon_connector->edid) { |
652 | DRM_ERROR("DDC responded but not EDID found for %s\n", | 744 | DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", |
653 | drm_get_connector_name(connector)); | 745 | drm_get_connector_name(connector)); |
654 | } else { | 746 | } else { |
655 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | 747 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
656 | 748 | ||
657 | /* if this isn't a digital monitor | 749 | /* some oems have boards with separate digital and analog connectors |
658 | then we need to make sure we don't have any | 750 | * with a shared ddc line (often vga + hdmi) |
659 | TV conflicts */ | 751 | */ |
660 | ret = connector_status_connected; | 752 | if ((!radeon_connector->use_digital) && radeon_connector->shared_ddc) { |
753 | kfree(radeon_connector->edid); | ||
754 | radeon_connector->edid = NULL; | ||
755 | ret = connector_status_disconnected; | ||
756 | } else | ||
757 | ret = connector_status_connected; | ||
758 | |||
759 | /* multiple connectors on the same encoder with the same ddc line | ||
760 | * This tends to be HDMI and DVI on the same encoder with the | ||
761 | * same ddc line. If the edid says HDMI, consider the HDMI port | ||
762 | * connected and the DVI port disconnected. If the edid doesn't | ||
763 | * say HDMI, vice versa. | ||
764 | */ | ||
765 | if (radeon_connector->shared_ddc && connector_status_connected) { | ||
766 | struct drm_device *dev = connector->dev; | ||
767 | struct drm_connector *list_connector; | ||
768 | struct radeon_connector *list_radeon_connector; | ||
769 | list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) { | ||
770 | if (connector == list_connector) | ||
771 | continue; | ||
772 | list_radeon_connector = to_radeon_connector(list_connector); | ||
773 | if (radeon_connector->devices == list_radeon_connector->devices) { | ||
774 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { | ||
775 | if (connector->connector_type == DRM_MODE_CONNECTOR_DVID) { | ||
776 | kfree(radeon_connector->edid); | ||
777 | radeon_connector->edid = NULL; | ||
778 | ret = connector_status_disconnected; | ||
779 | } | ||
780 | } else { | ||
781 | if ((connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) || | ||
782 | (connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) { | ||
783 | kfree(radeon_connector->edid); | ||
784 | radeon_connector->edid = NULL; | ||
785 | ret = connector_status_disconnected; | ||
786 | } | ||
787 | } | ||
788 | } | ||
789 | } | ||
790 | } | ||
661 | } | 791 | } |
662 | } | 792 | } |
663 | 793 | ||
@@ -753,9 +883,27 @@ static void radeon_dvi_force(struct drm_connector *connector) | |||
753 | radeon_connector->use_digital = true; | 883 | radeon_connector->use_digital = true; |
754 | } | 884 | } |
755 | 885 | ||
886 | static int radeon_dvi_mode_valid(struct drm_connector *connector, | ||
887 | struct drm_display_mode *mode) | ||
888 | { | ||
889 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
890 | |||
891 | /* XXX check mode bandwidth */ | ||
892 | |||
893 | if (radeon_connector->use_digital && (mode->clock > 165000)) { | ||
894 | if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || | ||
895 | (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || | ||
896 | (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) | ||
897 | return MODE_OK; | ||
898 | else | ||
899 | return MODE_CLOCK_HIGH; | ||
900 | } | ||
901 | return MODE_OK; | ||
902 | } | ||
903 | |||
756 | struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { | 904 | struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { |
757 | .get_modes = radeon_dvi_get_modes, | 905 | .get_modes = radeon_dvi_get_modes, |
758 | .mode_valid = radeon_vga_mode_valid, | 906 | .mode_valid = radeon_dvi_mode_valid, |
759 | .best_encoder = radeon_dvi_encoder, | 907 | .best_encoder = radeon_dvi_encoder, |
760 | }; | 908 | }; |
761 | 909 | ||
@@ -768,6 +916,91 @@ struct drm_connector_funcs radeon_dvi_connector_funcs = { | |||
768 | .force = radeon_dvi_force, | 916 | .force = radeon_dvi_force, |
769 | }; | 917 | }; |
770 | 918 | ||
919 | static void radeon_dp_connector_destroy(struct drm_connector *connector) | ||
920 | { | ||
921 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
922 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | ||
923 | |||
924 | if (radeon_connector->ddc_bus) | ||
925 | radeon_i2c_destroy(radeon_connector->ddc_bus); | ||
926 | if (radeon_connector->edid) | ||
927 | kfree(radeon_connector->edid); | ||
928 | if (radeon_dig_connector->dp_i2c_bus) | ||
929 | radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus); | ||
930 | kfree(radeon_connector->con_priv); | ||
931 | drm_sysfs_connector_remove(connector); | ||
932 | drm_connector_cleanup(connector); | ||
933 | kfree(connector); | ||
934 | } | ||
935 | |||
936 | static int radeon_dp_get_modes(struct drm_connector *connector) | ||
937 | { | ||
938 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
939 | int ret; | ||
940 | |||
941 | ret = radeon_ddc_get_modes(radeon_connector); | ||
942 | return ret; | ||
943 | } | ||
944 | |||
945 | static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector) | ||
946 | { | ||
947 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
948 | enum drm_connector_status ret = connector_status_disconnected; | ||
949 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | ||
950 | u8 sink_type; | ||
951 | |||
952 | if (radeon_connector->edid) { | ||
953 | kfree(radeon_connector->edid); | ||
954 | radeon_connector->edid = NULL; | ||
955 | } | ||
956 | |||
957 | sink_type = radeon_dp_getsinktype(radeon_connector); | ||
958 | if (sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { | ||
959 | if (radeon_dp_getdpcd(radeon_connector)) { | ||
960 | radeon_dig_connector->dp_sink_type = sink_type; | ||
961 | ret = connector_status_connected; | ||
962 | } | ||
963 | } else { | ||
964 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); | ||
965 | if (radeon_ddc_probe(radeon_connector)) { | ||
966 | radeon_dig_connector->dp_sink_type = sink_type; | ||
967 | ret = connector_status_connected; | ||
968 | } | ||
969 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | ||
970 | } | ||
971 | |||
972 | return ret; | ||
973 | } | ||
974 | |||
975 | static int radeon_dp_mode_valid(struct drm_connector *connector, | ||
976 | struct drm_display_mode *mode) | ||
977 | { | ||
978 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
979 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | ||
980 | |||
981 | /* XXX check mode bandwidth */ | ||
982 | |||
983 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) | ||
984 | return radeon_dp_mode_valid_helper(radeon_connector, mode); | ||
985 | else | ||
986 | return MODE_OK; | ||
987 | } | ||
988 | |||
989 | struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = { | ||
990 | .get_modes = radeon_dp_get_modes, | ||
991 | .mode_valid = radeon_dp_mode_valid, | ||
992 | .best_encoder = radeon_dvi_encoder, | ||
993 | }; | ||
994 | |||
995 | struct drm_connector_funcs radeon_dp_connector_funcs = { | ||
996 | .dpms = drm_helper_connector_dpms, | ||
997 | .detect = radeon_dp_detect, | ||
998 | .fill_modes = drm_helper_probe_single_connector_modes, | ||
999 | .set_property = radeon_connector_set_property, | ||
1000 | .destroy = radeon_dp_connector_destroy, | ||
1001 | .force = radeon_dvi_force, | ||
1002 | }; | ||
1003 | |||
771 | void | 1004 | void |
772 | radeon_add_atom_connector(struct drm_device *dev, | 1005 | radeon_add_atom_connector(struct drm_device *dev, |
773 | uint32_t connector_id, | 1006 | uint32_t connector_id, |
@@ -775,13 +1008,16 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
775 | int connector_type, | 1008 | int connector_type, |
776 | struct radeon_i2c_bus_rec *i2c_bus, | 1009 | struct radeon_i2c_bus_rec *i2c_bus, |
777 | bool linkb, | 1010 | bool linkb, |
778 | uint32_t igp_lane_info) | 1011 | uint32_t igp_lane_info, |
1012 | uint16_t connector_object_id, | ||
1013 | struct radeon_hpd *hpd) | ||
779 | { | 1014 | { |
780 | struct radeon_device *rdev = dev->dev_private; | 1015 | struct radeon_device *rdev = dev->dev_private; |
781 | struct drm_connector *connector; | 1016 | struct drm_connector *connector; |
782 | struct radeon_connector *radeon_connector; | 1017 | struct radeon_connector *radeon_connector; |
783 | struct radeon_connector_atom_dig *radeon_dig_connector; | 1018 | struct radeon_connector_atom_dig *radeon_dig_connector; |
784 | uint32_t subpixel_order = SubPixelNone; | 1019 | uint32_t subpixel_order = SubPixelNone; |
1020 | bool shared_ddc = false; | ||
785 | int ret; | 1021 | int ret; |
786 | 1022 | ||
787 | /* fixme - tv/cv/din */ | 1023 | /* fixme - tv/cv/din */ |
@@ -795,6 +1031,13 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
795 | radeon_connector->devices |= supported_device; | 1031 | radeon_connector->devices |= supported_device; |
796 | return; | 1032 | return; |
797 | } | 1033 | } |
1034 | if (radeon_connector->ddc_bus && i2c_bus->valid) { | ||
1035 | if (memcmp(&radeon_connector->ddc_bus->rec, i2c_bus, | ||
1036 | sizeof(struct radeon_i2c_bus_rec)) == 0) { | ||
1037 | radeon_connector->shared_ddc = true; | ||
1038 | shared_ddc = true; | ||
1039 | } | ||
1040 | } | ||
798 | } | 1041 | } |
799 | 1042 | ||
800 | radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); | 1043 | radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); |
@@ -805,6 +1048,9 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
805 | 1048 | ||
806 | radeon_connector->connector_id = connector_id; | 1049 | radeon_connector->connector_id = connector_id; |
807 | radeon_connector->devices = supported_device; | 1050 | radeon_connector->devices = supported_device; |
1051 | radeon_connector->shared_ddc = shared_ddc; | ||
1052 | radeon_connector->connector_object_id = connector_object_id; | ||
1053 | radeon_connector->hpd = *hpd; | ||
808 | switch (connector_type) { | 1054 | switch (connector_type) { |
809 | case DRM_MODE_CONNECTOR_VGA: | 1055 | case DRM_MODE_CONNECTOR_VGA: |
810 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 1056 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
@@ -857,10 +1103,12 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
857 | drm_connector_attach_property(&radeon_connector->base, | 1103 | drm_connector_attach_property(&radeon_connector->base, |
858 | rdev->mode_info.coherent_mode_property, | 1104 | rdev->mode_info.coherent_mode_property, |
859 | 1); | 1105 | 1); |
860 | radeon_connector->dac_load_detect = true; | 1106 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { |
861 | drm_connector_attach_property(&radeon_connector->base, | 1107 | radeon_connector->dac_load_detect = true; |
862 | rdev->mode_info.load_detect_property, | 1108 | drm_connector_attach_property(&radeon_connector->base, |
863 | 1); | 1109 | rdev->mode_info.load_detect_property, |
1110 | 1); | ||
1111 | } | ||
864 | break; | 1112 | break; |
865 | case DRM_MODE_CONNECTOR_HDMIA: | 1113 | case DRM_MODE_CONNECTOR_HDMIA: |
866 | case DRM_MODE_CONNECTOR_HDMIB: | 1114 | case DRM_MODE_CONNECTOR_HDMIB: |
@@ -891,16 +1139,23 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
891 | radeon_dig_connector->linkb = linkb; | 1139 | radeon_dig_connector->linkb = linkb; |
892 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1140 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
893 | radeon_connector->con_priv = radeon_dig_connector; | 1141 | radeon_connector->con_priv = radeon_dig_connector; |
894 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 1142 | drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); |
895 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); | 1143 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); |
896 | if (ret) | 1144 | if (ret) |
897 | goto failed; | 1145 | goto failed; |
898 | if (i2c_bus->valid) { | 1146 | if (i2c_bus->valid) { |
1147 | /* add DP i2c bus */ | ||
1148 | radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); | ||
1149 | if (!radeon_dig_connector->dp_i2c_bus) | ||
1150 | goto failed; | ||
899 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); | 1151 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); |
900 | if (!radeon_connector->ddc_bus) | 1152 | if (!radeon_connector->ddc_bus) |
901 | goto failed; | 1153 | goto failed; |
902 | } | 1154 | } |
903 | subpixel_order = SubPixelHorizontalRGB; | 1155 | subpixel_order = SubPixelHorizontalRGB; |
1156 | drm_connector_attach_property(&radeon_connector->base, | ||
1157 | rdev->mode_info.coherent_mode_property, | ||
1158 | 1); | ||
904 | break; | 1159 | break; |
905 | case DRM_MODE_CONNECTOR_SVIDEO: | 1160 | case DRM_MODE_CONNECTOR_SVIDEO: |
906 | case DRM_MODE_CONNECTOR_Composite: | 1161 | case DRM_MODE_CONNECTOR_Composite: |
@@ -914,6 +1169,9 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
914 | drm_connector_attach_property(&radeon_connector->base, | 1169 | drm_connector_attach_property(&radeon_connector->base, |
915 | rdev->mode_info.load_detect_property, | 1170 | rdev->mode_info.load_detect_property, |
916 | 1); | 1171 | 1); |
1172 | drm_connector_attach_property(&radeon_connector->base, | ||
1173 | rdev->mode_info.tv_std_property, | ||
1174 | 1); | ||
917 | } | 1175 | } |
918 | break; | 1176 | break; |
919 | case DRM_MODE_CONNECTOR_LVDS: | 1177 | case DRM_MODE_CONNECTOR_LVDS: |
@@ -932,7 +1190,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
932 | if (!radeon_connector->ddc_bus) | 1190 | if (!radeon_connector->ddc_bus) |
933 | goto failed; | 1191 | goto failed; |
934 | } | 1192 | } |
935 | drm_mode_create_scaling_mode_property(dev); | ||
936 | drm_connector_attach_property(&radeon_connector->base, | 1193 | drm_connector_attach_property(&radeon_connector->base, |
937 | dev->mode_config.scaling_mode_property, | 1194 | dev->mode_config.scaling_mode_property, |
938 | DRM_MODE_SCALE_FULLSCREEN); | 1195 | DRM_MODE_SCALE_FULLSCREEN); |
@@ -956,7 +1213,9 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
956 | uint32_t connector_id, | 1213 | uint32_t connector_id, |
957 | uint32_t supported_device, | 1214 | uint32_t supported_device, |
958 | int connector_type, | 1215 | int connector_type, |
959 | struct radeon_i2c_bus_rec *i2c_bus) | 1216 | struct radeon_i2c_bus_rec *i2c_bus, |
1217 | uint16_t connector_object_id, | ||
1218 | struct radeon_hpd *hpd) | ||
960 | { | 1219 | { |
961 | struct radeon_device *rdev = dev->dev_private; | 1220 | struct radeon_device *rdev = dev->dev_private; |
962 | struct drm_connector *connector; | 1221 | struct drm_connector *connector; |
@@ -985,6 +1244,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
985 | 1244 | ||
986 | radeon_connector->connector_id = connector_id; | 1245 | radeon_connector->connector_id = connector_id; |
987 | radeon_connector->devices = supported_device; | 1246 | radeon_connector->devices = supported_device; |
1247 | radeon_connector->connector_object_id = connector_object_id; | ||
1248 | radeon_connector->hpd = *hpd; | ||
988 | switch (connector_type) { | 1249 | switch (connector_type) { |
989 | case DRM_MODE_CONNECTOR_VGA: | 1250 | case DRM_MODE_CONNECTOR_VGA: |
990 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 1251 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
@@ -1042,9 +1303,19 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1042 | if (ret) | 1303 | if (ret) |
1043 | goto failed; | 1304 | goto failed; |
1044 | radeon_connector->dac_load_detect = true; | 1305 | radeon_connector->dac_load_detect = true; |
1306 | /* RS400,RC410,RS480 chipset seems to report a lot | ||
1307 | * of false positive on load detect, we haven't yet | ||
1308 | * found a way to make load detect reliable on those | ||
1309 | * chipset, thus just disable it for TV. | ||
1310 | */ | ||
1311 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) | ||
1312 | radeon_connector->dac_load_detect = false; | ||
1045 | drm_connector_attach_property(&radeon_connector->base, | 1313 | drm_connector_attach_property(&radeon_connector->base, |
1046 | rdev->mode_info.load_detect_property, | 1314 | rdev->mode_info.load_detect_property, |
1047 | 1); | 1315 | 1); |
1316 | drm_connector_attach_property(&radeon_connector->base, | ||
1317 | rdev->mode_info.tv_std_property, | ||
1318 | 1); | ||
1048 | } | 1319 | } |
1049 | break; | 1320 | break; |
1050 | case DRM_MODE_CONNECTOR_LVDS: | 1321 | case DRM_MODE_CONNECTOR_LVDS: |
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 4f7afc79dd82..0b2f9c2ad2c1 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -1941,8 +1941,8 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) | |||
1941 | for (t = 0; t < dev_priv->usec_timeout; t++) { | 1941 | for (t = 0; t < dev_priv->usec_timeout; t++) { |
1942 | u32 done_age = GET_SCRATCH(dev_priv, 1); | 1942 | u32 done_age = GET_SCRATCH(dev_priv, 1); |
1943 | DRM_DEBUG("done_age = %d\n", done_age); | 1943 | DRM_DEBUG("done_age = %d\n", done_age); |
1944 | for (i = start; i < dma->buf_count; i++) { | 1944 | for (i = 0; i < dma->buf_count; i++) { |
1945 | buf = dma->buflist[i]; | 1945 | buf = dma->buflist[start]; |
1946 | buf_priv = buf->dev_private; | 1946 | buf_priv = buf->dev_private; |
1947 | if (buf->file_priv == NULL || (buf->pending && | 1947 | if (buf->file_priv == NULL || (buf->pending && |
1948 | buf_priv->age <= | 1948 | buf_priv->age <= |
@@ -1951,7 +1951,8 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) | |||
1951 | buf->pending = 0; | 1951 | buf->pending = 0; |
1952 | return buf; | 1952 | return buf; |
1953 | } | 1953 | } |
1954 | start = 0; | 1954 | if (++start >= dma->buf_count) |
1955 | start = 0; | ||
1955 | } | 1956 | } |
1956 | 1957 | ||
1957 | if (t) { | 1958 | if (t) { |
@@ -1960,47 +1961,9 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) | |||
1960 | } | 1961 | } |
1961 | } | 1962 | } |
1962 | 1963 | ||
1963 | DRM_DEBUG("returning NULL!\n"); | ||
1964 | return NULL; | 1964 | return NULL; |
1965 | } | 1965 | } |
1966 | 1966 | ||
1967 | #if 0 | ||
1968 | struct drm_buf *radeon_freelist_get(struct drm_device * dev) | ||
1969 | { | ||
1970 | struct drm_device_dma *dma = dev->dma; | ||
1971 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
1972 | drm_radeon_buf_priv_t *buf_priv; | ||
1973 | struct drm_buf *buf; | ||
1974 | int i, t; | ||
1975 | int start; | ||
1976 | u32 done_age; | ||
1977 | |||
1978 | done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); | ||
1979 | if (++dev_priv->last_buf >= dma->buf_count) | ||
1980 | dev_priv->last_buf = 0; | ||
1981 | |||
1982 | start = dev_priv->last_buf; | ||
1983 | dev_priv->stats.freelist_loops++; | ||
1984 | |||
1985 | for (t = 0; t < 2; t++) { | ||
1986 | for (i = start; i < dma->buf_count; i++) { | ||
1987 | buf = dma->buflist[i]; | ||
1988 | buf_priv = buf->dev_private; | ||
1989 | if (buf->file_priv == 0 || (buf->pending && | ||
1990 | buf_priv->age <= | ||
1991 | done_age)) { | ||
1992 | dev_priv->stats.requested_bufs++; | ||
1993 | buf->pending = 0; | ||
1994 | return buf; | ||
1995 | } | ||
1996 | } | ||
1997 | start = 0; | ||
1998 | } | ||
1999 | |||
2000 | return NULL; | ||
2001 | } | ||
2002 | #endif | ||
2003 | |||
2004 | void radeon_freelist_reset(struct drm_device * dev) | 1967 | void radeon_freelist_reset(struct drm_device * dev) |
2005 | { | 1968 | { |
2006 | struct drm_device_dma *dma = dev->dma; | 1969 | struct drm_device_dma *dma = dev->dma; |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 5ab2cf96a264..65590a0f1d93 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -76,17 +76,17 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p) | |||
76 | } | 76 | } |
77 | p->relocs_ptr[i] = &p->relocs[i]; | 77 | p->relocs_ptr[i] = &p->relocs[i]; |
78 | p->relocs[i].robj = p->relocs[i].gobj->driver_private; | 78 | p->relocs[i].robj = p->relocs[i].gobj->driver_private; |
79 | p->relocs[i].lobj.robj = p->relocs[i].robj; | 79 | p->relocs[i].lobj.bo = p->relocs[i].robj; |
80 | p->relocs[i].lobj.rdomain = r->read_domains; | 80 | p->relocs[i].lobj.rdomain = r->read_domains; |
81 | p->relocs[i].lobj.wdomain = r->write_domain; | 81 | p->relocs[i].lobj.wdomain = r->write_domain; |
82 | p->relocs[i].handle = r->handle; | 82 | p->relocs[i].handle = r->handle; |
83 | p->relocs[i].flags = r->flags; | 83 | p->relocs[i].flags = r->flags; |
84 | INIT_LIST_HEAD(&p->relocs[i].lobj.list); | 84 | INIT_LIST_HEAD(&p->relocs[i].lobj.list); |
85 | radeon_object_list_add_object(&p->relocs[i].lobj, | 85 | radeon_bo_list_add_object(&p->relocs[i].lobj, |
86 | &p->validated); | 86 | &p->validated); |
87 | } | 87 | } |
88 | } | 88 | } |
89 | return radeon_object_list_validate(&p->validated, p->ib->fence); | 89 | return radeon_bo_list_validate(&p->validated, p->ib->fence); |
90 | } | 90 | } |
91 | 91 | ||
92 | int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | 92 | int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) |
@@ -190,9 +190,10 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
190 | unsigned i; | 190 | unsigned i; |
191 | 191 | ||
192 | if (error) { | 192 | if (error) { |
193 | radeon_object_list_unvalidate(&parser->validated); | 193 | radeon_bo_list_unvalidate(&parser->validated, |
194 | parser->ib->fence); | ||
194 | } else { | 195 | } else { |
195 | radeon_object_list_clean(&parser->validated); | 196 | radeon_bo_list_unreserve(&parser->validated); |
196 | } | 197 | } |
197 | for (i = 0; i < parser->nrelocs; i++) { | 198 | for (i = 0; i < parser->nrelocs; i++) { |
198 | if (parser->relocs[i].gobj) { | 199 | if (parser->relocs[i].gobj) { |
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index b13c79e38bc0..28772a37009c 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
@@ -109,9 +109,15 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, | |||
109 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 109 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
110 | struct radeon_device *rdev = crtc->dev->dev_private; | 110 | struct radeon_device *rdev = crtc->dev->dev_private; |
111 | 111 | ||
112 | if (ASIC_IS_AVIVO(rdev)) | 112 | if (ASIC_IS_AVIVO(rdev)) { |
113 | if (rdev->family >= CHIP_RV770) { | ||
114 | if (radeon_crtc->crtc_id) | ||
115 | WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, 0); | ||
116 | else | ||
117 | WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, 0); | ||
118 | } | ||
113 | WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr); | 119 | WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr); |
114 | else { | 120 | } else { |
115 | radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr; | 121 | radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr; |
116 | /* offset is from DISP(2)_BASE_ADDRESS */ | 122 | /* offset is from DISP(2)_BASE_ADDRESS */ |
117 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); | 123 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index df988142e6b0..02bcdb1240c0 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -44,10 +44,11 @@ void radeon_surface_init(struct radeon_device *rdev) | |||
44 | if (rdev->family < CHIP_R600) { | 44 | if (rdev->family < CHIP_R600) { |
45 | int i; | 45 | int i; |
46 | 46 | ||
47 | for (i = 0; i < 8; i++) { | 47 | for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) { |
48 | WREG32(RADEON_SURFACE0_INFO + | 48 | if (rdev->surface_regs[i].bo) |
49 | i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO), | 49 | radeon_bo_get_surface_reg(rdev->surface_regs[i].bo); |
50 | 0); | 50 | else |
51 | radeon_clear_surface_reg(rdev, i); | ||
51 | } | 52 | } |
52 | /* enable surfaces */ | 53 | /* enable surfaces */ |
53 | WREG32(RADEON_SURFACE_CNTL, 0); | 54 | WREG32(RADEON_SURFACE_CNTL, 0); |
@@ -208,6 +209,24 @@ bool radeon_card_posted(struct radeon_device *rdev) | |||
208 | 209 | ||
209 | } | 210 | } |
210 | 211 | ||
212 | bool radeon_boot_test_post_card(struct radeon_device *rdev) | ||
213 | { | ||
214 | if (radeon_card_posted(rdev)) | ||
215 | return true; | ||
216 | |||
217 | if (rdev->bios) { | ||
218 | DRM_INFO("GPU not posted. posting now...\n"); | ||
219 | if (rdev->is_atom_bios) | ||
220 | atom_asic_init(rdev->mode_info.atom_context); | ||
221 | else | ||
222 | radeon_combios_asic_init(rdev->ddev); | ||
223 | return true; | ||
224 | } else { | ||
225 | dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); | ||
226 | return false; | ||
227 | } | ||
228 | } | ||
229 | |||
211 | int radeon_dummy_page_init(struct radeon_device *rdev) | 230 | int radeon_dummy_page_init(struct radeon_device *rdev) |
212 | { | 231 | { |
213 | rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO); | 232 | rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO); |
@@ -444,27 +463,36 @@ static uint32_t cail_reg_read(struct card_info *info, uint32_t reg) | |||
444 | return r; | 463 | return r; |
445 | } | 464 | } |
446 | 465 | ||
447 | static struct card_info atom_card_info = { | ||
448 | .dev = NULL, | ||
449 | .reg_read = cail_reg_read, | ||
450 | .reg_write = cail_reg_write, | ||
451 | .mc_read = cail_mc_read, | ||
452 | .mc_write = cail_mc_write, | ||
453 | .pll_read = cail_pll_read, | ||
454 | .pll_write = cail_pll_write, | ||
455 | }; | ||
456 | |||
457 | int radeon_atombios_init(struct radeon_device *rdev) | 466 | int radeon_atombios_init(struct radeon_device *rdev) |
458 | { | 467 | { |
459 | atom_card_info.dev = rdev->ddev; | 468 | struct card_info *atom_card_info = |
460 | rdev->mode_info.atom_context = atom_parse(&atom_card_info, rdev->bios); | 469 | kzalloc(sizeof(struct card_info), GFP_KERNEL); |
470 | |||
471 | if (!atom_card_info) | ||
472 | return -ENOMEM; | ||
473 | |||
474 | rdev->mode_info.atom_card_info = atom_card_info; | ||
475 | atom_card_info->dev = rdev->ddev; | ||
476 | atom_card_info->reg_read = cail_reg_read; | ||
477 | atom_card_info->reg_write = cail_reg_write; | ||
478 | atom_card_info->mc_read = cail_mc_read; | ||
479 | atom_card_info->mc_write = cail_mc_write; | ||
480 | atom_card_info->pll_read = cail_pll_read; | ||
481 | atom_card_info->pll_write = cail_pll_write; | ||
482 | |||
483 | rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); | ||
461 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); | 484 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); |
485 | atom_allocate_fb_scratch(rdev->mode_info.atom_context); | ||
462 | return 0; | 486 | return 0; |
463 | } | 487 | } |
464 | 488 | ||
465 | void radeon_atombios_fini(struct radeon_device *rdev) | 489 | void radeon_atombios_fini(struct radeon_device *rdev) |
466 | { | 490 | { |
467 | kfree(rdev->mode_info.atom_context); | 491 | if (rdev->mode_info.atom_context) { |
492 | kfree(rdev->mode_info.atom_context->scratch); | ||
493 | kfree(rdev->mode_info.atom_context); | ||
494 | } | ||
495 | kfree(rdev->mode_info.atom_card_info); | ||
468 | } | 496 | } |
469 | 497 | ||
470 | int radeon_combios_init(struct radeon_device *rdev) | 498 | int radeon_combios_init(struct radeon_device *rdev) |
@@ -539,16 +567,24 @@ int radeon_device_init(struct radeon_device *rdev, | |||
539 | mutex_init(&rdev->cs_mutex); | 567 | mutex_init(&rdev->cs_mutex); |
540 | mutex_init(&rdev->ib_pool.mutex); | 568 | mutex_init(&rdev->ib_pool.mutex); |
541 | mutex_init(&rdev->cp.mutex); | 569 | mutex_init(&rdev->cp.mutex); |
570 | if (rdev->family >= CHIP_R600) | ||
571 | spin_lock_init(&rdev->ih.lock); | ||
572 | mutex_init(&rdev->gem.mutex); | ||
542 | rwlock_init(&rdev->fence_drv.lock); | 573 | rwlock_init(&rdev->fence_drv.lock); |
543 | INIT_LIST_HEAD(&rdev->gem.objects); | 574 | INIT_LIST_HEAD(&rdev->gem.objects); |
544 | 575 | ||
576 | /* setup workqueue */ | ||
577 | rdev->wq = create_workqueue("radeon"); | ||
578 | if (rdev->wq == NULL) | ||
579 | return -ENOMEM; | ||
580 | |||
545 | /* Set asic functions */ | 581 | /* Set asic functions */ |
546 | r = radeon_asic_init(rdev); | 582 | r = radeon_asic_init(rdev); |
547 | if (r) { | 583 | if (r) { |
548 | return r; | 584 | return r; |
549 | } | 585 | } |
550 | 586 | ||
551 | if (radeon_agpmode == -1) { | 587 | if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) { |
552 | radeon_agp_disable(rdev); | 588 | radeon_agp_disable(rdev); |
553 | } | 589 | } |
554 | 590 | ||
@@ -615,6 +651,7 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
615 | DRM_INFO("radeon: finishing device.\n"); | 651 | DRM_INFO("radeon: finishing device.\n"); |
616 | rdev->shutdown = true; | 652 | rdev->shutdown = true; |
617 | radeon_fini(rdev); | 653 | radeon_fini(rdev); |
654 | destroy_workqueue(rdev->wq); | ||
618 | vga_client_register(rdev->pdev, NULL, NULL, NULL); | 655 | vga_client_register(rdev->pdev, NULL, NULL, NULL); |
619 | iounmap(rdev->rmmio); | 656 | iounmap(rdev->rmmio); |
620 | rdev->rmmio = NULL; | 657 | rdev->rmmio = NULL; |
@@ -628,6 +665,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
628 | { | 665 | { |
629 | struct radeon_device *rdev = dev->dev_private; | 666 | struct radeon_device *rdev = dev->dev_private; |
630 | struct drm_crtc *crtc; | 667 | struct drm_crtc *crtc; |
668 | int r; | ||
631 | 669 | ||
632 | if (dev == NULL || rdev == NULL) { | 670 | if (dev == NULL || rdev == NULL) { |
633 | return -ENODEV; | 671 | return -ENODEV; |
@@ -638,26 +676,31 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
638 | /* unpin the front buffers */ | 676 | /* unpin the front buffers */ |
639 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 677 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
640 | struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); | 678 | struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); |
641 | struct radeon_object *robj; | 679 | struct radeon_bo *robj; |
642 | 680 | ||
643 | if (rfb == NULL || rfb->obj == NULL) { | 681 | if (rfb == NULL || rfb->obj == NULL) { |
644 | continue; | 682 | continue; |
645 | } | 683 | } |
646 | robj = rfb->obj->driver_private; | 684 | robj = rfb->obj->driver_private; |
647 | if (robj != rdev->fbdev_robj) { | 685 | if (robj != rdev->fbdev_rbo) { |
648 | radeon_object_unpin(robj); | 686 | r = radeon_bo_reserve(robj, false); |
687 | if (unlikely(r == 0)) { | ||
688 | radeon_bo_unpin(robj); | ||
689 | radeon_bo_unreserve(robj); | ||
690 | } | ||
649 | } | 691 | } |
650 | } | 692 | } |
651 | /* evict vram memory */ | 693 | /* evict vram memory */ |
652 | radeon_object_evict_vram(rdev); | 694 | radeon_bo_evict_vram(rdev); |
653 | /* wait for gpu to finish processing current batch */ | 695 | /* wait for gpu to finish processing current batch */ |
654 | radeon_fence_wait_last(rdev); | 696 | radeon_fence_wait_last(rdev); |
655 | 697 | ||
656 | radeon_save_bios_scratch_regs(rdev); | 698 | radeon_save_bios_scratch_regs(rdev); |
657 | 699 | ||
658 | radeon_suspend(rdev); | 700 | radeon_suspend(rdev); |
701 | radeon_hpd_fini(rdev); | ||
659 | /* evict remaining vram memory */ | 702 | /* evict remaining vram memory */ |
660 | radeon_object_evict_vram(rdev); | 703 | radeon_bo_evict_vram(rdev); |
661 | 704 | ||
662 | pci_save_state(dev->pdev); | 705 | pci_save_state(dev->pdev); |
663 | if (state.event == PM_EVENT_SUSPEND) { | 706 | if (state.event == PM_EVENT_SUSPEND) { |
@@ -683,11 +726,15 @@ int radeon_resume_kms(struct drm_device *dev) | |||
683 | return -1; | 726 | return -1; |
684 | } | 727 | } |
685 | pci_set_master(dev->pdev); | 728 | pci_set_master(dev->pdev); |
729 | /* resume AGP if in use */ | ||
730 | radeon_agp_resume(rdev); | ||
686 | radeon_resume(rdev); | 731 | radeon_resume(rdev); |
687 | radeon_restore_bios_scratch_regs(rdev); | 732 | radeon_restore_bios_scratch_regs(rdev); |
688 | fb_set_suspend(rdev->fbdev_info, 0); | 733 | fb_set_suspend(rdev->fbdev_info, 0); |
689 | release_console_sem(); | 734 | release_console_sem(); |
690 | 735 | ||
736 | /* reset hpd state */ | ||
737 | radeon_hpd_init(rdev); | ||
691 | /* blat the mode back in */ | 738 | /* blat the mode back in */ |
692 | drm_helper_resume_force_mode(dev); | 739 | drm_helper_resume_force_mode(dev); |
693 | return 0; | 740 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 3655d91993a6..a133b833e45d 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -137,9 +137,6 @@ static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, | |||
137 | if (size != 256) { | 137 | if (size != 256) { |
138 | return; | 138 | return; |
139 | } | 139 | } |
140 | if (crtc->fb == NULL) { | ||
141 | return; | ||
142 | } | ||
143 | 140 | ||
144 | /* userspace palettes are always correct as is */ | 141 | /* userspace palettes are always correct as is */ |
145 | for (i = 0; i < 256; i++) { | 142 | for (i = 0; i < 256; i++) { |
@@ -147,7 +144,6 @@ static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, | |||
147 | radeon_crtc->lut_g[i] = green[i] >> 6; | 144 | radeon_crtc->lut_g[i] = green[i] >> 6; |
148 | radeon_crtc->lut_b[i] = blue[i] >> 6; | 145 | radeon_crtc->lut_b[i] = blue[i] >> 6; |
149 | } | 146 | } |
150 | |||
151 | radeon_crtc_load_lut(crtc); | 147 | radeon_crtc_load_lut(crtc); |
152 | } | 148 | } |
153 | 149 | ||
@@ -254,6 +250,16 @@ static const char *connector_names[13] = { | |||
254 | "HDMI-B", | 250 | "HDMI-B", |
255 | }; | 251 | }; |
256 | 252 | ||
253 | static const char *hpd_names[7] = { | ||
254 | "NONE", | ||
255 | "HPD1", | ||
256 | "HPD2", | ||
257 | "HPD3", | ||
258 | "HPD4", | ||
259 | "HPD5", | ||
260 | "HPD6", | ||
261 | }; | ||
262 | |||
257 | static void radeon_print_display_setup(struct drm_device *dev) | 263 | static void radeon_print_display_setup(struct drm_device *dev) |
258 | { | 264 | { |
259 | struct drm_connector *connector; | 265 | struct drm_connector *connector; |
@@ -268,16 +274,18 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
268 | radeon_connector = to_radeon_connector(connector); | 274 | radeon_connector = to_radeon_connector(connector); |
269 | DRM_INFO("Connector %d:\n", i); | 275 | DRM_INFO("Connector %d:\n", i); |
270 | DRM_INFO(" %s\n", connector_names[connector->connector_type]); | 276 | DRM_INFO(" %s\n", connector_names[connector->connector_type]); |
277 | if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) | ||
278 | DRM_INFO(" %s\n", hpd_names[radeon_connector->hpd.hpd]); | ||
271 | if (radeon_connector->ddc_bus) | 279 | if (radeon_connector->ddc_bus) |
272 | DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", | 280 | DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
273 | radeon_connector->ddc_bus->rec.mask_clk_reg, | 281 | radeon_connector->ddc_bus->rec.mask_clk_reg, |
274 | radeon_connector->ddc_bus->rec.mask_data_reg, | 282 | radeon_connector->ddc_bus->rec.mask_data_reg, |
275 | radeon_connector->ddc_bus->rec.a_clk_reg, | 283 | radeon_connector->ddc_bus->rec.a_clk_reg, |
276 | radeon_connector->ddc_bus->rec.a_data_reg, | 284 | radeon_connector->ddc_bus->rec.a_data_reg, |
277 | radeon_connector->ddc_bus->rec.put_clk_reg, | 285 | radeon_connector->ddc_bus->rec.en_clk_reg, |
278 | radeon_connector->ddc_bus->rec.put_data_reg, | 286 | radeon_connector->ddc_bus->rec.en_data_reg, |
279 | radeon_connector->ddc_bus->rec.get_clk_reg, | 287 | radeon_connector->ddc_bus->rec.y_clk_reg, |
280 | radeon_connector->ddc_bus->rec.get_data_reg); | 288 | radeon_connector->ddc_bus->rec.y_data_reg); |
281 | DRM_INFO(" Encoders:\n"); | 289 | DRM_INFO(" Encoders:\n"); |
282 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 290 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
283 | radeon_encoder = to_radeon_encoder(encoder); | 291 | radeon_encoder = to_radeon_encoder(encoder); |
@@ -328,6 +336,7 @@ static bool radeon_setup_enc_conn(struct drm_device *dev) | |||
328 | ret = radeon_get_legacy_connector_info_from_table(dev); | 336 | ret = radeon_get_legacy_connector_info_from_table(dev); |
329 | } | 337 | } |
330 | if (ret) { | 338 | if (ret) { |
339 | radeon_setup_encoder_clones(dev); | ||
331 | radeon_print_display_setup(dev); | 340 | radeon_print_display_setup(dev); |
332 | list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) | 341 | list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) |
333 | radeon_ddc_dump(drm_connector); | 342 | radeon_ddc_dump(drm_connector); |
@@ -338,27 +347,24 @@ static bool radeon_setup_enc_conn(struct drm_device *dev) | |||
338 | 347 | ||
339 | int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | 348 | int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) |
340 | { | 349 | { |
341 | struct edid *edid; | ||
342 | int ret = 0; | 350 | int ret = 0; |
343 | 351 | ||
352 | if (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) { | ||
353 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; | ||
354 | if (dig->dp_i2c_bus) | ||
355 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter); | ||
356 | } | ||
344 | if (!radeon_connector->ddc_bus) | 357 | if (!radeon_connector->ddc_bus) |
345 | return -1; | 358 | return -1; |
346 | if (!radeon_connector->edid) { | 359 | if (!radeon_connector->edid) { |
347 | radeon_i2c_do_lock(radeon_connector, 1); | 360 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); |
348 | edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); | 361 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
349 | radeon_i2c_do_lock(radeon_connector, 0); | 362 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); |
350 | } else | 363 | } |
351 | edid = radeon_connector->edid; | ||
352 | 364 | ||
353 | if (edid) { | 365 | if (radeon_connector->edid) { |
354 | /* update digital bits here */ | 366 | drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid); |
355 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | 367 | ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid); |
356 | radeon_connector->use_digital = 1; | ||
357 | else | ||
358 | radeon_connector->use_digital = 0; | ||
359 | drm_mode_connector_update_edid_property(&radeon_connector->base, edid); | ||
360 | ret = drm_add_edid_modes(&radeon_connector->base, edid); | ||
361 | kfree(edid); | ||
362 | return ret; | 368 | return ret; |
363 | } | 369 | } |
364 | drm_mode_connector_update_edid_property(&radeon_connector->base, NULL); | 370 | drm_mode_connector_update_edid_property(&radeon_connector->base, NULL); |
@@ -373,9 +379,9 @@ static int radeon_ddc_dump(struct drm_connector *connector) | |||
373 | 379 | ||
374 | if (!radeon_connector->ddc_bus) | 380 | if (!radeon_connector->ddc_bus) |
375 | return -1; | 381 | return -1; |
376 | radeon_i2c_do_lock(radeon_connector, 1); | 382 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); |
377 | edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); | 383 | edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); |
378 | radeon_i2c_do_lock(radeon_connector, 0); | 384 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); |
379 | if (edid) { | 385 | if (edid) { |
380 | kfree(edid); | 386 | kfree(edid); |
381 | } | 387 | } |
@@ -554,6 +560,98 @@ void radeon_compute_pll(struct radeon_pll *pll, | |||
554 | *post_div_p = best_post_div; | 560 | *post_div_p = best_post_div; |
555 | } | 561 | } |
556 | 562 | ||
563 | void radeon_compute_pll_avivo(struct radeon_pll *pll, | ||
564 | uint64_t freq, | ||
565 | uint32_t *dot_clock_p, | ||
566 | uint32_t *fb_div_p, | ||
567 | uint32_t *frac_fb_div_p, | ||
568 | uint32_t *ref_div_p, | ||
569 | uint32_t *post_div_p, | ||
570 | int flags) | ||
571 | { | ||
572 | fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq; | ||
573 | fixed20_12 pll_out_max, pll_out_min; | ||
574 | fixed20_12 pll_in_max, pll_in_min; | ||
575 | fixed20_12 reference_freq; | ||
576 | fixed20_12 error, ffreq, a, b; | ||
577 | |||
578 | pll_out_max.full = rfixed_const(pll->pll_out_max); | ||
579 | pll_out_min.full = rfixed_const(pll->pll_out_min); | ||
580 | pll_in_max.full = rfixed_const(pll->pll_in_max); | ||
581 | pll_in_min.full = rfixed_const(pll->pll_in_min); | ||
582 | reference_freq.full = rfixed_const(pll->reference_freq); | ||
583 | do_div(freq, 10); | ||
584 | ffreq.full = rfixed_const(freq); | ||
585 | error.full = rfixed_const(100 * 100); | ||
586 | |||
587 | /* max p */ | ||
588 | p.full = rfixed_div(pll_out_max, ffreq); | ||
589 | p.full = rfixed_floor(p); | ||
590 | |||
591 | /* min m */ | ||
592 | m.full = rfixed_div(reference_freq, pll_in_max); | ||
593 | m.full = rfixed_ceil(m); | ||
594 | |||
595 | while (1) { | ||
596 | n.full = rfixed_div(ffreq, reference_freq); | ||
597 | n.full = rfixed_mul(n, m); | ||
598 | n.full = rfixed_mul(n, p); | ||
599 | |||
600 | f_vco.full = rfixed_div(n, m); | ||
601 | f_vco.full = rfixed_mul(f_vco, reference_freq); | ||
602 | |||
603 | f_pclk.full = rfixed_div(f_vco, p); | ||
604 | |||
605 | if (f_pclk.full > ffreq.full) | ||
606 | error.full = f_pclk.full - ffreq.full; | ||
607 | else | ||
608 | error.full = ffreq.full - f_pclk.full; | ||
609 | error.full = rfixed_div(error, f_pclk); | ||
610 | a.full = rfixed_const(100 * 100); | ||
611 | error.full = rfixed_mul(error, a); | ||
612 | |||
613 | a.full = rfixed_mul(m, p); | ||
614 | a.full = rfixed_div(n, a); | ||
615 | best_freq.full = rfixed_mul(reference_freq, a); | ||
616 | |||
617 | if (rfixed_trunc(error) < 25) | ||
618 | break; | ||
619 | |||
620 | a.full = rfixed_const(1); | ||
621 | m.full = m.full + a.full; | ||
622 | a.full = rfixed_div(reference_freq, m); | ||
623 | if (a.full >= pll_in_min.full) | ||
624 | continue; | ||
625 | |||
626 | m.full = rfixed_div(reference_freq, pll_in_max); | ||
627 | m.full = rfixed_ceil(m); | ||
628 | a.full= rfixed_const(1); | ||
629 | p.full = p.full - a.full; | ||
630 | a.full = rfixed_mul(p, ffreq); | ||
631 | if (a.full >= pll_out_min.full) | ||
632 | continue; | ||
633 | else { | ||
634 | DRM_ERROR("Unable to find pll dividers\n"); | ||
635 | break; | ||
636 | } | ||
637 | } | ||
638 | |||
639 | a.full = rfixed_const(10); | ||
640 | b.full = rfixed_mul(n, a); | ||
641 | |||
642 | frac_n.full = rfixed_floor(n); | ||
643 | frac_n.full = rfixed_mul(frac_n, a); | ||
644 | frac_n.full = b.full - frac_n.full; | ||
645 | |||
646 | *dot_clock_p = rfixed_trunc(best_freq); | ||
647 | *fb_div_p = rfixed_trunc(n); | ||
648 | *frac_fb_div_p = rfixed_trunc(frac_n); | ||
649 | *ref_div_p = rfixed_trunc(m); | ||
650 | *post_div_p = rfixed_trunc(p); | ||
651 | |||
652 | DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p); | ||
653 | } | ||
654 | |||
557 | static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) | 655 | static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) |
558 | { | 656 | { |
559 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); | 657 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); |
@@ -654,7 +752,7 @@ int radeon_modeset_create_props(struct radeon_device *rdev) | |||
654 | return -ENOMEM; | 752 | return -ENOMEM; |
655 | 753 | ||
656 | rdev->mode_info.coherent_mode_property->values[0] = 0; | 754 | rdev->mode_info.coherent_mode_property->values[0] = 0; |
657 | rdev->mode_info.coherent_mode_property->values[0] = 1; | 755 | rdev->mode_info.coherent_mode_property->values[1] = 1; |
658 | } | 756 | } |
659 | 757 | ||
660 | if (!ASIC_IS_AVIVO(rdev)) { | 758 | if (!ASIC_IS_AVIVO(rdev)) { |
@@ -678,7 +776,7 @@ int radeon_modeset_create_props(struct radeon_device *rdev) | |||
678 | if (!rdev->mode_info.load_detect_property) | 776 | if (!rdev->mode_info.load_detect_property) |
679 | return -ENOMEM; | 777 | return -ENOMEM; |
680 | rdev->mode_info.load_detect_property->values[0] = 0; | 778 | rdev->mode_info.load_detect_property->values[0] = 0; |
681 | rdev->mode_info.load_detect_property->values[0] = 1; | 779 | rdev->mode_info.load_detect_property->values[1] = 1; |
682 | 780 | ||
683 | drm_mode_create_scaling_mode_property(rdev->ddev); | 781 | drm_mode_create_scaling_mode_property(rdev->ddev); |
684 | 782 | ||
@@ -735,6 +833,8 @@ int radeon_modeset_init(struct radeon_device *rdev) | |||
735 | if (!ret) { | 833 | if (!ret) { |
736 | return ret; | 834 | return ret; |
737 | } | 835 | } |
836 | /* initialize hpd */ | ||
837 | radeon_hpd_init(rdev); | ||
738 | drm_helper_initial_config(rdev->ddev); | 838 | drm_helper_initial_config(rdev->ddev); |
739 | return 0; | 839 | return 0; |
740 | } | 840 | } |
@@ -742,6 +842,7 @@ int radeon_modeset_init(struct radeon_device *rdev) | |||
742 | void radeon_modeset_fini(struct radeon_device *rdev) | 842 | void radeon_modeset_fini(struct radeon_device *rdev) |
743 | { | 843 | { |
744 | if (rdev->mode_info.mode_config_initialized) { | 844 | if (rdev->mode_info.mode_config_initialized) { |
845 | radeon_hpd_fini(rdev); | ||
745 | drm_mode_config_cleanup(rdev->ddev); | 846 | drm_mode_config_cleanup(rdev->ddev); |
746 | rdev->mode_info.mode_config_initialized = false; | 847 | rdev->mode_info.mode_config_initialized = false; |
747 | } | 848 | } |
@@ -762,10 +863,18 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
762 | if (encoder->crtc != crtc) | 863 | if (encoder->crtc != crtc) |
763 | continue; | 864 | continue; |
764 | if (first) { | 865 | if (first) { |
765 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; | 866 | /* set scaling */ |
867 | if (radeon_encoder->rmx_type == RMX_OFF) | ||
868 | radeon_crtc->rmx_type = RMX_OFF; | ||
869 | else if (mode->hdisplay < radeon_encoder->native_mode.hdisplay || | ||
870 | mode->vdisplay < radeon_encoder->native_mode.vdisplay) | ||
871 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; | ||
872 | else | ||
873 | radeon_crtc->rmx_type = RMX_OFF; | ||
874 | /* copy native mode */ | ||
766 | memcpy(&radeon_crtc->native_mode, | 875 | memcpy(&radeon_crtc->native_mode, |
767 | &radeon_encoder->native_mode, | 876 | &radeon_encoder->native_mode, |
768 | sizeof(struct radeon_native_mode)); | 877 | sizeof(struct drm_display_mode)); |
769 | first = false; | 878 | first = false; |
770 | } else { | 879 | } else { |
771 | if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) { | 880 | if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) { |
@@ -783,10 +892,10 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
783 | if (radeon_crtc->rmx_type != RMX_OFF) { | 892 | if (radeon_crtc->rmx_type != RMX_OFF) { |
784 | fixed20_12 a, b; | 893 | fixed20_12 a, b; |
785 | a.full = rfixed_const(crtc->mode.vdisplay); | 894 | a.full = rfixed_const(crtc->mode.vdisplay); |
786 | b.full = rfixed_const(radeon_crtc->native_mode.panel_xres); | 895 | b.full = rfixed_const(radeon_crtc->native_mode.hdisplay); |
787 | radeon_crtc->vsc.full = rfixed_div(a, b); | 896 | radeon_crtc->vsc.full = rfixed_div(a, b); |
788 | a.full = rfixed_const(crtc->mode.hdisplay); | 897 | a.full = rfixed_const(crtc->mode.hdisplay); |
789 | b.full = rfixed_const(radeon_crtc->native_mode.panel_yres); | 898 | b.full = rfixed_const(radeon_crtc->native_mode.vdisplay); |
790 | radeon_crtc->hsc.full = rfixed_div(a, b); | 899 | radeon_crtc->hsc.full = rfixed_div(a, b); |
791 | } else { | 900 | } else { |
792 | radeon_crtc->vsc.full = rfixed_const(1); | 901 | radeon_crtc->vsc.full = rfixed_const(1); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 7f50fb864af8..c5c45e626d74 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -86,6 +86,7 @@ int radeon_benchmarking = 0; | |||
86 | int radeon_testing = 0; | 86 | int radeon_testing = 0; |
87 | int radeon_connector_table = 0; | 87 | int radeon_connector_table = 0; |
88 | int radeon_tv = 1; | 88 | int radeon_tv = 1; |
89 | int radeon_new_pll = 1; | ||
89 | 90 | ||
90 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); | 91 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); |
91 | module_param_named(no_wb, radeon_no_wb, int, 0444); | 92 | module_param_named(no_wb, radeon_no_wb, int, 0444); |
@@ -120,6 +121,9 @@ module_param_named(connector_table, radeon_connector_table, int, 0444); | |||
120 | MODULE_PARM_DESC(tv, "TV enable (0 = disable)"); | 121 | MODULE_PARM_DESC(tv, "TV enable (0 = disable)"); |
121 | module_param_named(tv, radeon_tv, int, 0444); | 122 | module_param_named(tv, radeon_tv, int, 0444); |
122 | 123 | ||
124 | MODULE_PARM_DESC(new_pll, "Select new PLL code for AVIVO chips"); | ||
125 | module_param_named(new_pll, radeon_new_pll, int, 0444); | ||
126 | |||
123 | static int radeon_suspend(struct drm_device *dev, pm_message_t state) | 127 | static int radeon_suspend(struct drm_device *dev, pm_message_t state) |
124 | { | 128 | { |
125 | drm_radeon_private_t *dev_priv = dev->dev_private; | 129 | drm_radeon_private_t *dev_priv = dev->dev_private; |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 350962e0f346..e13785282a82 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -1104,7 +1104,6 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); | |||
1104 | # define R600_IT_WAIT_REG_MEM 0x00003C00 | 1104 | # define R600_IT_WAIT_REG_MEM 0x00003C00 |
1105 | # define R600_IT_MEM_WRITE 0x00003D00 | 1105 | # define R600_IT_MEM_WRITE 0x00003D00 |
1106 | # define R600_IT_INDIRECT_BUFFER 0x00003200 | 1106 | # define R600_IT_INDIRECT_BUFFER 0x00003200 |
1107 | # define R600_IT_CP_INTERRUPT 0x00004000 | ||
1108 | # define R600_IT_SURFACE_SYNC 0x00004300 | 1107 | # define R600_IT_SURFACE_SYNC 0x00004300 |
1109 | # define R600_CB0_DEST_BASE_ENA (1 << 6) | 1108 | # define R600_CB0_DEST_BASE_ENA (1 << 6) |
1110 | # define R600_TC_ACTION_ENA (1 << 23) | 1109 | # define R600_TC_ACTION_ENA (1 << 23) |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index a65ab1a0dad2..b4f23ec93201 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -31,6 +31,55 @@ | |||
31 | 31 | ||
32 | extern int atom_debug; | 32 | extern int atom_debug; |
33 | 33 | ||
34 | /* evil but including atombios.h is much worse */ | ||
35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | ||
36 | struct drm_display_mode *mode); | ||
37 | |||
38 | static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) | ||
39 | { | ||
40 | struct drm_device *dev = encoder->dev; | ||
41 | struct radeon_device *rdev = dev->dev_private; | ||
42 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
43 | struct drm_encoder *clone_encoder; | ||
44 | uint32_t index_mask = 0; | ||
45 | int count; | ||
46 | |||
47 | /* DIG routing gets problematic */ | ||
48 | if (rdev->family >= CHIP_R600) | ||
49 | return index_mask; | ||
50 | /* LVDS/TV are too wacky */ | ||
51 | if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT) | ||
52 | return index_mask; | ||
53 | /* DVO requires 2x ppll clocks depending on tmds chip */ | ||
54 | if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) | ||
55 | return index_mask; | ||
56 | |||
57 | count = -1; | ||
58 | list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) { | ||
59 | struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder); | ||
60 | count++; | ||
61 | |||
62 | if (clone_encoder == encoder) | ||
63 | continue; | ||
64 | if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
65 | continue; | ||
66 | if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT) | ||
67 | continue; | ||
68 | else | ||
69 | index_mask |= (1 << count); | ||
70 | } | ||
71 | return index_mask; | ||
72 | } | ||
73 | |||
74 | void radeon_setup_encoder_clones(struct drm_device *dev) | ||
75 | { | ||
76 | struct drm_encoder *encoder; | ||
77 | |||
78 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
79 | encoder->possible_clones = radeon_encoder_clones(encoder); | ||
80 | } | ||
81 | } | ||
82 | |||
34 | uint32_t | 83 | uint32_t |
35 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) | 84 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) |
36 | { | 85 | { |
@@ -159,77 +208,54 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
159 | return NULL; | 208 | return NULL; |
160 | } | 209 | } |
161 | 210 | ||
162 | /* used for both atom and legacy */ | ||
163 | void radeon_rmx_mode_fixup(struct drm_encoder *encoder, | ||
164 | struct drm_display_mode *mode, | ||
165 | struct drm_display_mode *adjusted_mode) | ||
166 | { | ||
167 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
168 | struct drm_device *dev = encoder->dev; | ||
169 | struct radeon_device *rdev = dev->dev_private; | ||
170 | struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; | ||
171 | |||
172 | if (mode->hdisplay < native_mode->panel_xres || | ||
173 | mode->vdisplay < native_mode->panel_yres) { | ||
174 | if (ASIC_IS_AVIVO(rdev)) { | ||
175 | adjusted_mode->hdisplay = native_mode->panel_xres; | ||
176 | adjusted_mode->vdisplay = native_mode->panel_yres; | ||
177 | adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank; | ||
178 | adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus; | ||
179 | adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width; | ||
180 | adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank; | ||
181 | adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus; | ||
182 | adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width; | ||
183 | /* update crtc values */ | ||
184 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
185 | /* adjust crtc values */ | ||
186 | adjusted_mode->crtc_hdisplay = native_mode->panel_xres; | ||
187 | adjusted_mode->crtc_vdisplay = native_mode->panel_yres; | ||
188 | adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank; | ||
189 | adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus; | ||
190 | adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width; | ||
191 | adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank; | ||
192 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus; | ||
193 | adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width; | ||
194 | } else { | ||
195 | adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank; | ||
196 | adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus; | ||
197 | adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width; | ||
198 | adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank; | ||
199 | adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus; | ||
200 | adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width; | ||
201 | /* update crtc values */ | ||
202 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
203 | /* adjust crtc values */ | ||
204 | adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank; | ||
205 | adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus; | ||
206 | adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width; | ||
207 | adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank; | ||
208 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus; | ||
209 | adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width; | ||
210 | } | ||
211 | adjusted_mode->flags = native_mode->flags; | ||
212 | adjusted_mode->clock = native_mode->dotclock; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | |||
217 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | 211 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, |
218 | struct drm_display_mode *mode, | 212 | struct drm_display_mode *mode, |
219 | struct drm_display_mode *adjusted_mode) | 213 | struct drm_display_mode *adjusted_mode) |
220 | { | 214 | { |
221 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 215 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
216 | struct drm_device *dev = encoder->dev; | ||
217 | struct radeon_device *rdev = dev->dev_private; | ||
222 | 218 | ||
219 | /* set the active encoder to connector routing */ | ||
220 | radeon_encoder_set_active_device(encoder); | ||
223 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 221 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
224 | 222 | ||
225 | if (radeon_encoder->rmx_type != RMX_OFF) | ||
226 | radeon_rmx_mode_fixup(encoder, mode, adjusted_mode); | ||
227 | |||
228 | /* hw bug */ | 223 | /* hw bug */ |
229 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) | 224 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) |
230 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) | 225 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) |
231 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; | 226 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; |
232 | 227 | ||
228 | /* get the native mode for LVDS */ | ||
229 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
230 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; | ||
231 | int mode_id = adjusted_mode->base.id; | ||
232 | *adjusted_mode = *native_mode; | ||
233 | if (!ASIC_IS_AVIVO(rdev)) { | ||
234 | adjusted_mode->hdisplay = mode->hdisplay; | ||
235 | adjusted_mode->vdisplay = mode->vdisplay; | ||
236 | } | ||
237 | adjusted_mode->base.id = mode_id; | ||
238 | } | ||
239 | |||
240 | /* get the native mode for TV */ | ||
241 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { | ||
242 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; | ||
243 | if (tv_dac) { | ||
244 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
245 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
246 | tv_dac->tv_std == TV_STD_PAL_M) | ||
247 | radeon_atom_get_tv_timings(rdev, 0, adjusted_mode); | ||
248 | else | ||
249 | radeon_atom_get_tv_timings(rdev, 1, adjusted_mode); | ||
250 | } | ||
251 | } | ||
252 | |||
253 | if (ASIC_IS_DCE3(rdev) && | ||
254 | (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT))) { | ||
255 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
256 | radeon_dp_set_link_config(connector, mode); | ||
257 | } | ||
258 | |||
233 | return true; | 259 | return true; |
234 | } | 260 | } |
235 | 261 | ||
@@ -404,7 +430,7 @@ union lvds_encoder_control { | |||
404 | LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2; | 430 | LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2; |
405 | }; | 431 | }; |
406 | 432 | ||
407 | static void | 433 | void |
408 | atombios_digital_setup(struct drm_encoder *encoder, int action) | 434 | atombios_digital_setup(struct drm_encoder *encoder, int action) |
409 | { | 435 | { |
410 | struct drm_device *dev = encoder->dev; | 436 | struct drm_device *dev = encoder->dev; |
@@ -461,7 +487,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
461 | case 1: | 487 | case 1: |
462 | args.v1.ucMisc = 0; | 488 | args.v1.ucMisc = 0; |
463 | args.v1.ucAction = action; | 489 | args.v1.ucAction = action; |
464 | if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) | 490 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
465 | args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | 491 | args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; |
466 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 492 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
467 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 493 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
@@ -486,7 +512,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
486 | if (dig->coherent_mode) | 512 | if (dig->coherent_mode) |
487 | args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; | 513 | args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; |
488 | } | 514 | } |
489 | if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) | 515 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
490 | args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | 516 | args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; |
491 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 517 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
492 | args.v2.ucTruncate = 0; | 518 | args.v2.ucTruncate = 0; |
@@ -534,6 +560,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
534 | { | 560 | { |
535 | struct drm_connector *connector; | 561 | struct drm_connector *connector; |
536 | struct radeon_connector *radeon_connector; | 562 | struct radeon_connector *radeon_connector; |
563 | struct radeon_connector_atom_dig *radeon_dig_connector; | ||
537 | 564 | ||
538 | connector = radeon_get_connector_for_encoder(encoder); | 565 | connector = radeon_get_connector_for_encoder(encoder); |
539 | if (!connector) | 566 | if (!connector) |
@@ -544,7 +571,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
544 | switch (connector->connector_type) { | 571 | switch (connector->connector_type) { |
545 | case DRM_MODE_CONNECTOR_DVII: | 572 | case DRM_MODE_CONNECTOR_DVII: |
546 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | 573 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ |
547 | if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) | 574 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
548 | return ATOM_ENCODER_MODE_HDMI; | 575 | return ATOM_ENCODER_MODE_HDMI; |
549 | else if (radeon_connector->use_digital) | 576 | else if (radeon_connector->use_digital) |
550 | return ATOM_ENCODER_MODE_DVI; | 577 | return ATOM_ENCODER_MODE_DVI; |
@@ -554,7 +581,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
554 | case DRM_MODE_CONNECTOR_DVID: | 581 | case DRM_MODE_CONNECTOR_DVID: |
555 | case DRM_MODE_CONNECTOR_HDMIA: | 582 | case DRM_MODE_CONNECTOR_HDMIA: |
556 | default: | 583 | default: |
557 | if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) | 584 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
558 | return ATOM_ENCODER_MODE_HDMI; | 585 | return ATOM_ENCODER_MODE_HDMI; |
559 | else | 586 | else |
560 | return ATOM_ENCODER_MODE_DVI; | 587 | return ATOM_ENCODER_MODE_DVI; |
@@ -563,10 +590,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
563 | return ATOM_ENCODER_MODE_LVDS; | 590 | return ATOM_ENCODER_MODE_LVDS; |
564 | break; | 591 | break; |
565 | case DRM_MODE_CONNECTOR_DisplayPort: | 592 | case DRM_MODE_CONNECTOR_DisplayPort: |
566 | /*if (radeon_output->MonType == MT_DP) | 593 | radeon_dig_connector = radeon_connector->con_priv; |
567 | return ATOM_ENCODER_MODE_DP; | 594 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) |
568 | else*/ | 595 | return ATOM_ENCODER_MODE_DP; |
569 | if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) | 596 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
570 | return ATOM_ENCODER_MODE_HDMI; | 597 | return ATOM_ENCODER_MODE_HDMI; |
571 | else | 598 | else |
572 | return ATOM_ENCODER_MODE_DVI; | 599 | return ATOM_ENCODER_MODE_DVI; |
@@ -585,6 +612,30 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
585 | } | 612 | } |
586 | } | 613 | } |
587 | 614 | ||
615 | /* | ||
616 | * DIG Encoder/Transmitter Setup | ||
617 | * | ||
618 | * DCE 3.0/3.1 | ||
619 | * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA. | ||
620 | * Supports up to 3 digital outputs | ||
621 | * - 2 DIG encoder blocks. | ||
622 | * DIG1 can drive UNIPHY link A or link B | ||
623 | * DIG2 can drive UNIPHY link B or LVTMA | ||
624 | * | ||
625 | * DCE 3.2 | ||
626 | * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B). | ||
627 | * Supports up to 5 digital outputs | ||
628 | * - 2 DIG encoder blocks. | ||
629 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | ||
630 | * | ||
631 | * Routing | ||
632 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) | ||
633 | * Examples: | ||
634 | * crtc0 -> dig2 -> LVTMA links A+B -> TMDS/HDMI | ||
635 | * crtc1 -> dig1 -> UNIPHY0 link B -> DP | ||
636 | * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS | ||
637 | * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI | ||
638 | */ | ||
588 | static void | 639 | static void |
589 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | 640 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) |
590 | { | 641 | { |
@@ -626,10 +677,17 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
626 | } else { | 677 | } else { |
627 | switch (radeon_encoder->encoder_id) { | 678 | switch (radeon_encoder->encoder_id) { |
628 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 679 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
629 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | 680 | /* XXX doesn't really matter which dig encoder we pick as long as it's |
681 | * not already in use | ||
682 | */ | ||
683 | if (dig_connector->linkb) | ||
684 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | ||
685 | else | ||
686 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | ||
630 | num = 1; | 687 | num = 1; |
631 | break; | 688 | break; |
632 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 689 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
690 | /* Only dig2 encoder can drive LVTMA */ | ||
633 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | 691 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); |
634 | num = 2; | 692 | num = 2; |
635 | break; | 693 | break; |
@@ -664,18 +722,21 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
664 | } | 722 | } |
665 | } | 723 | } |
666 | 724 | ||
667 | if (radeon_encoder->pixel_clock > 165000) { | 725 | args.ucEncoderMode = atombios_get_encoder_mode(encoder); |
668 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B; | 726 | |
727 | if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | ||
728 | if (dig_connector->dp_clock == 270000) | ||
729 | args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
730 | args.ucLaneNum = dig_connector->dp_lane_count; | ||
731 | } else if (radeon_encoder->pixel_clock > 165000) | ||
669 | args.ucLaneNum = 8; | 732 | args.ucLaneNum = 8; |
670 | } else { | 733 | else |
671 | if (dig_connector->linkb) | ||
672 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
673 | else | ||
674 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
675 | args.ucLaneNum = 4; | 734 | args.ucLaneNum = 4; |
676 | } | ||
677 | 735 | ||
678 | args.ucEncoderMode = atombios_get_encoder_mode(encoder); | 736 | if (dig_connector->linkb) |
737 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
738 | else | ||
739 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
679 | 740 | ||
680 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 741 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
681 | 742 | ||
@@ -686,8 +747,8 @@ union dig_transmitter_control { | |||
686 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; | 747 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; |
687 | }; | 748 | }; |
688 | 749 | ||
689 | static void | 750 | void |
690 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | 751 | atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set) |
691 | { | 752 | { |
692 | struct drm_device *dev = encoder->dev; | 753 | struct drm_device *dev = encoder->dev; |
693 | struct radeon_device *rdev = dev->dev_private; | 754 | struct radeon_device *rdev = dev->dev_private; |
@@ -699,6 +760,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
699 | struct drm_connector *connector; | 760 | struct drm_connector *connector; |
700 | struct radeon_connector *radeon_connector; | 761 | struct radeon_connector *radeon_connector; |
701 | struct radeon_connector_atom_dig *dig_connector; | 762 | struct radeon_connector_atom_dig *dig_connector; |
763 | bool is_dp = false; | ||
702 | 764 | ||
703 | connector = radeon_get_connector_for_encoder(encoder); | 765 | connector = radeon_get_connector_for_encoder(encoder); |
704 | if (!connector) | 766 | if (!connector) |
@@ -716,6 +778,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
716 | 778 | ||
717 | dig_connector = radeon_connector->con_priv; | 779 | dig_connector = radeon_connector->con_priv; |
718 | 780 | ||
781 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) | ||
782 | is_dp = true; | ||
783 | |||
719 | memset(&args, 0, sizeof(args)); | 784 | memset(&args, 0, sizeof(args)); |
720 | 785 | ||
721 | if (ASIC_IS_DCE32(rdev)) | 786 | if (ASIC_IS_DCE32(rdev)) |
@@ -734,16 +799,25 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
734 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); | 799 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); |
735 | 800 | ||
736 | args.v1.ucAction = action; | 801 | args.v1.ucAction = action; |
737 | 802 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | |
803 | args.v1.usInitInfo = radeon_connector->connector_object_id; | ||
804 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | ||
805 | args.v1.asMode.ucLaneSel = lane_num; | ||
806 | args.v1.asMode.ucLaneSet = lane_set; | ||
807 | } else { | ||
808 | if (is_dp) | ||
809 | args.v1.usPixelClock = | ||
810 | cpu_to_le16(dig_connector->dp_clock / 10); | ||
811 | else if (radeon_encoder->pixel_clock > 165000) | ||
812 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | ||
813 | else | ||
814 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | ||
815 | } | ||
738 | if (ASIC_IS_DCE32(rdev)) { | 816 | if (ASIC_IS_DCE32(rdev)) { |
739 | if (radeon_encoder->pixel_clock > 165000) { | ||
740 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 2) / 100); | ||
741 | args.v2.acConfig.fDualLinkConnector = 1; | ||
742 | } else { | ||
743 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 4) / 100); | ||
744 | } | ||
745 | if (dig->dig_block) | 817 | if (dig->dig_block) |
746 | args.v2.acConfig.ucEncoderSel = 1; | 818 | args.v2.acConfig.ucEncoderSel = 1; |
819 | if (dig_connector->linkb) | ||
820 | args.v2.acConfig.ucLinkSel = 1; | ||
747 | 821 | ||
748 | switch (radeon_encoder->encoder_id) { | 822 | switch (radeon_encoder->encoder_id) { |
749 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 823 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
@@ -760,27 +834,31 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
760 | break; | 834 | break; |
761 | } | 835 | } |
762 | 836 | ||
763 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 837 | if (is_dp) |
838 | args.v2.acConfig.fCoherentMode = 1; | ||
839 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
764 | if (dig->coherent_mode) | 840 | if (dig->coherent_mode) |
765 | args.v2.acConfig.fCoherentMode = 1; | 841 | args.v2.acConfig.fCoherentMode = 1; |
766 | } | 842 | } |
767 | } else { | 843 | } else { |
768 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; | 844 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; |
769 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock) / 10); | ||
770 | 845 | ||
771 | switch (radeon_encoder->encoder_id) { | 846 | switch (radeon_encoder->encoder_id) { |
772 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 847 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
773 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | 848 | /* XXX doesn't really matter which dig encoder we pick as long as it's |
849 | * not already in use | ||
850 | */ | ||
851 | if (dig_connector->linkb) | ||
852 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | ||
853 | else | ||
854 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; | ||
774 | if (rdev->flags & RADEON_IS_IGP) { | 855 | if (rdev->flags & RADEON_IS_IGP) { |
775 | if (radeon_encoder->pixel_clock > 165000) { | 856 | if (radeon_encoder->pixel_clock > 165000) { |
776 | args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | | ||
777 | ATOM_TRANSMITTER_CONFIG_LINKA_B); | ||
778 | if (dig_connector->igp_lane_info & 0x3) | 857 | if (dig_connector->igp_lane_info & 0x3) |
779 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; | 858 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; |
780 | else if (dig_connector->igp_lane_info & 0xc) | 859 | else if (dig_connector->igp_lane_info & 0xc) |
781 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; | 860 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; |
782 | } else { | 861 | } else { |
783 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | ||
784 | if (dig_connector->igp_lane_info & 0x1) | 862 | if (dig_connector->igp_lane_info & 0x1) |
785 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | 863 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; |
786 | else if (dig_connector->igp_lane_info & 0x2) | 864 | else if (dig_connector->igp_lane_info & 0x2) |
@@ -790,35 +868,25 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action) | |||
790 | else if (dig_connector->igp_lane_info & 0x8) | 868 | else if (dig_connector->igp_lane_info & 0x8) |
791 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; | 869 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; |
792 | } | 870 | } |
793 | } else { | ||
794 | if (radeon_encoder->pixel_clock > 165000) | ||
795 | args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | | ||
796 | ATOM_TRANSMITTER_CONFIG_LINKA_B | | ||
797 | ATOM_TRANSMITTER_CONFIG_LANE_0_7); | ||
798 | else { | ||
799 | if (dig_connector->linkb) | ||
800 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
801 | else | ||
802 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
803 | } | ||
804 | } | 871 | } |
805 | break; | 872 | break; |
806 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 873 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
874 | /* Only dig2 encoder can drive LVTMA */ | ||
807 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; | 875 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; |
808 | if (radeon_encoder->pixel_clock > 165000) | ||
809 | args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | | ||
810 | ATOM_TRANSMITTER_CONFIG_LINKA_B | | ||
811 | ATOM_TRANSMITTER_CONFIG_LANE_0_7); | ||
812 | else { | ||
813 | if (dig_connector->linkb) | ||
814 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
815 | else | ||
816 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; | ||
817 | } | ||
818 | break; | 876 | break; |
819 | } | 877 | } |
820 | 878 | ||
821 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 879 | if (radeon_encoder->pixel_clock > 165000) |
880 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; | ||
881 | |||
882 | if (dig_connector->linkb) | ||
883 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; | ||
884 | else | ||
885 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | ||
886 | |||
887 | if (is_dp) | ||
888 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | ||
889 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
822 | if (dig->coherent_mode) | 890 | if (dig->coherent_mode) |
823 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | 891 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; |
824 | } | 892 | } |
@@ -874,16 +942,9 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
874 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; | 942 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; |
875 | int index = 0; | 943 | int index = 0; |
876 | bool is_dig = false; | 944 | bool is_dig = false; |
877 | int devices; | ||
878 | 945 | ||
879 | memset(&args, 0, sizeof(args)); | 946 | memset(&args, 0, sizeof(args)); |
880 | 947 | ||
881 | /* on DPMS off we have no idea if active device is meaningful */ | ||
882 | if (mode != DRM_MODE_DPMS_ON && !radeon_encoder->active_device) | ||
883 | devices = radeon_encoder->devices; | ||
884 | else | ||
885 | devices = radeon_encoder->active_device; | ||
886 | |||
887 | DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", | 948 | DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", |
888 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, | 949 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, |
889 | radeon_encoder->active_device); | 950 | radeon_encoder->active_device); |
@@ -914,18 +975,18 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
914 | break; | 975 | break; |
915 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | 976 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: |
916 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 977 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
917 | if (devices & (ATOM_DEVICE_TV_SUPPORT)) | 978 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
918 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | 979 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); |
919 | else if (devices & (ATOM_DEVICE_CV_SUPPORT)) | 980 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
920 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | 981 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); |
921 | else | 982 | else |
922 | index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); | 983 | index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); |
923 | break; | 984 | break; |
924 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | 985 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
925 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | 986 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
926 | if (devices & (ATOM_DEVICE_TV_SUPPORT)) | 987 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
927 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | 988 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); |
928 | else if (devices & (ATOM_DEVICE_CV_SUPPORT)) | 989 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
929 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | 990 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); |
930 | else | 991 | else |
931 | index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); | 992 | index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); |
@@ -935,12 +996,16 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
935 | if (is_dig) { | 996 | if (is_dig) { |
936 | switch (mode) { | 997 | switch (mode) { |
937 | case DRM_MODE_DPMS_ON: | 998 | case DRM_MODE_DPMS_ON: |
938 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE); | 999 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
1000 | { | ||
1001 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1002 | dp_link_train(encoder, connector); | ||
1003 | } | ||
939 | break; | 1004 | break; |
940 | case DRM_MODE_DPMS_STANDBY: | 1005 | case DRM_MODE_DPMS_STANDBY: |
941 | case DRM_MODE_DPMS_SUSPEND: | 1006 | case DRM_MODE_DPMS_SUSPEND: |
942 | case DRM_MODE_DPMS_OFF: | 1007 | case DRM_MODE_DPMS_OFF: |
943 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE); | 1008 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); |
944 | break; | 1009 | break; |
945 | } | 1010 | } |
946 | } else { | 1011 | } else { |
@@ -1042,13 +1107,33 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
1042 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | 1107 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; |
1043 | else | 1108 | else |
1044 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | 1109 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; |
1045 | } else | 1110 | } else { |
1046 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | 1111 | struct drm_connector *connector; |
1112 | struct radeon_connector *radeon_connector; | ||
1113 | struct radeon_connector_atom_dig *dig_connector; | ||
1114 | |||
1115 | connector = radeon_get_connector_for_encoder(encoder); | ||
1116 | if (!connector) | ||
1117 | return; | ||
1118 | radeon_connector = to_radeon_connector(connector); | ||
1119 | if (!radeon_connector->con_priv) | ||
1120 | return; | ||
1121 | dig_connector = radeon_connector->con_priv; | ||
1122 | |||
1123 | /* XXX doesn't really matter which dig encoder we pick as long as it's | ||
1124 | * not already in use | ||
1125 | */ | ||
1126 | if (dig_connector->linkb) | ||
1127 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
1128 | else | ||
1129 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | ||
1130 | } | ||
1047 | break; | 1131 | break; |
1048 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | 1132 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: |
1049 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; | 1133 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; |
1050 | break; | 1134 | break; |
1051 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1135 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1136 | /* Only dig2 encoder can drive LVTMA */ | ||
1052 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | 1137 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; |
1053 | break; | 1138 | break; |
1054 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 1139 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
@@ -1104,8 +1189,11 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder, | |||
1104 | } | 1189 | } |
1105 | 1190 | ||
1106 | /* set scaler clears this on some chips */ | 1191 | /* set scaler clears this on some chips */ |
1107 | if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) | 1192 | if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { |
1108 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN); | 1193 | if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) |
1194 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
1195 | AVIVO_D1MODE_INTERLEAVE_EN); | ||
1196 | } | ||
1109 | } | 1197 | } |
1110 | 1198 | ||
1111 | static void | 1199 | static void |
@@ -1118,11 +1206,14 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1118 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1206 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1119 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 1207 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
1120 | 1208 | ||
1121 | if (radeon_encoder->enc_priv) { | 1209 | if (radeon_encoder->active_device & |
1122 | struct radeon_encoder_atom_dig *dig; | 1210 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { |
1211 | if (radeon_encoder->enc_priv) { | ||
1212 | struct radeon_encoder_atom_dig *dig; | ||
1123 | 1213 | ||
1124 | dig = radeon_encoder->enc_priv; | 1214 | dig = radeon_encoder->enc_priv; |
1125 | dig->dig_block = radeon_crtc->crtc_id; | 1215 | dig->dig_block = radeon_crtc->crtc_id; |
1216 | } | ||
1126 | } | 1217 | } |
1127 | radeon_encoder->pixel_clock = adjusted_mode->clock; | 1218 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
1128 | 1219 | ||
@@ -1148,13 +1239,14 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1148 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1239 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1149 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1240 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1150 | /* disable the encoder and transmitter */ | 1241 | /* disable the encoder and transmitter */ |
1151 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE); | 1242 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1152 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); | 1243 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); |
1153 | 1244 | ||
1154 | /* setup and enable the encoder and transmitter */ | 1245 | /* setup and enable the encoder and transmitter */ |
1155 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); | 1246 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); |
1156 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP); | 1247 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); |
1157 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE); | 1248 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); |
1249 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1158 | break; | 1250 | break; |
1159 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 1251 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
1160 | atombios_ddia_setup(encoder, ATOM_ENABLE); | 1252 | atombios_ddia_setup(encoder, ATOM_ENABLE); |
@@ -1268,8 +1360,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
1268 | { | 1360 | { |
1269 | radeon_atom_output_lock(encoder, true); | 1361 | radeon_atom_output_lock(encoder, true); |
1270 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | 1362 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); |
1271 | |||
1272 | radeon_encoder_set_active_device(encoder); | ||
1273 | } | 1363 | } |
1274 | 1364 | ||
1275 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | 1365 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) |
@@ -1369,7 +1459,6 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1369 | encoder->possible_crtcs = 0x1; | 1459 | encoder->possible_crtcs = 0x1; |
1370 | else | 1460 | else |
1371 | encoder->possible_crtcs = 0x3; | 1461 | encoder->possible_crtcs = 0x3; |
1372 | encoder->possible_clones = 0; | ||
1373 | 1462 | ||
1374 | radeon_encoder->enc_priv = NULL; | 1463 | radeon_encoder->enc_priv = NULL; |
1375 | 1464 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index b38c4c8e2c61..3ba213d1b06c 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -59,7 +59,7 @@ static struct fb_ops radeonfb_ops = { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | /** | 61 | /** |
62 | * Curretly it is assumed that the old framebuffer is reused. | 62 | * Currently it is assumed that the old framebuffer is reused. |
63 | * | 63 | * |
64 | * LOCKING | 64 | * LOCKING |
65 | * caller should hold the mode config lock. | 65 | * caller should hold the mode config lock. |
@@ -140,7 +140,7 @@ int radeonfb_create(struct drm_device *dev, | |||
140 | struct radeon_framebuffer *rfb; | 140 | struct radeon_framebuffer *rfb; |
141 | struct drm_mode_fb_cmd mode_cmd; | 141 | struct drm_mode_fb_cmd mode_cmd; |
142 | struct drm_gem_object *gobj = NULL; | 142 | struct drm_gem_object *gobj = NULL; |
143 | struct radeon_object *robj = NULL; | 143 | struct radeon_bo *rbo = NULL; |
144 | struct device *device = &rdev->pdev->dev; | 144 | struct device *device = &rdev->pdev->dev; |
145 | int size, aligned_size, ret; | 145 | int size, aligned_size, ret; |
146 | u64 fb_gpuaddr; | 146 | u64 fb_gpuaddr; |
@@ -168,14 +168,14 @@ int radeonfb_create(struct drm_device *dev, | |||
168 | ret = radeon_gem_object_create(rdev, aligned_size, 0, | 168 | ret = radeon_gem_object_create(rdev, aligned_size, 0, |
169 | RADEON_GEM_DOMAIN_VRAM, | 169 | RADEON_GEM_DOMAIN_VRAM, |
170 | false, ttm_bo_type_kernel, | 170 | false, ttm_bo_type_kernel, |
171 | false, &gobj); | 171 | &gobj); |
172 | if (ret) { | 172 | if (ret) { |
173 | printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n", | 173 | printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n", |
174 | surface_width, surface_height); | 174 | surface_width, surface_height); |
175 | ret = -ENOMEM; | 175 | ret = -ENOMEM; |
176 | goto out; | 176 | goto out; |
177 | } | 177 | } |
178 | robj = gobj->driver_private; | 178 | rbo = gobj->driver_private; |
179 | 179 | ||
180 | if (fb_tiled) | 180 | if (fb_tiled) |
181 | tiling_flags = RADEON_TILING_MACRO; | 181 | tiling_flags = RADEON_TILING_MACRO; |
@@ -192,8 +192,13 @@ int radeonfb_create(struct drm_device *dev, | |||
192 | } | 192 | } |
193 | #endif | 193 | #endif |
194 | 194 | ||
195 | if (tiling_flags) | 195 | if (tiling_flags) { |
196 | radeon_object_set_tiling_flags(robj, tiling_flags | RADEON_TILING_SURFACE, mode_cmd.pitch); | 196 | ret = radeon_bo_set_tiling_flags(rbo, |
197 | tiling_flags | RADEON_TILING_SURFACE, | ||
198 | mode_cmd.pitch); | ||
199 | if (ret) | ||
200 | dev_err(rdev->dev, "FB failed to set tiling flags\n"); | ||
201 | } | ||
197 | mutex_lock(&rdev->ddev->struct_mutex); | 202 | mutex_lock(&rdev->ddev->struct_mutex); |
198 | fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj); | 203 | fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj); |
199 | if (fb == NULL) { | 204 | if (fb == NULL) { |
@@ -201,10 +206,19 @@ int radeonfb_create(struct drm_device *dev, | |||
201 | ret = -ENOMEM; | 206 | ret = -ENOMEM; |
202 | goto out_unref; | 207 | goto out_unref; |
203 | } | 208 | } |
204 | ret = radeon_object_pin(robj, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr); | 209 | ret = radeon_bo_reserve(rbo, false); |
210 | if (unlikely(ret != 0)) | ||
211 | goto out_unref; | ||
212 | ret = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr); | ||
213 | if (ret) { | ||
214 | radeon_bo_unreserve(rbo); | ||
215 | goto out_unref; | ||
216 | } | ||
217 | if (fb_tiled) | ||
218 | radeon_bo_check_tiling(rbo, 0, 0); | ||
219 | ret = radeon_bo_kmap(rbo, &fbptr); | ||
220 | radeon_bo_unreserve(rbo); | ||
205 | if (ret) { | 221 | if (ret) { |
206 | printk(KERN_ERR "failed to pin framebuffer\n"); | ||
207 | ret = -ENOMEM; | ||
208 | goto out_unref; | 222 | goto out_unref; |
209 | } | 223 | } |
210 | 224 | ||
@@ -213,7 +227,7 @@ int radeonfb_create(struct drm_device *dev, | |||
213 | *fb_p = fb; | 227 | *fb_p = fb; |
214 | rfb = to_radeon_framebuffer(fb); | 228 | rfb = to_radeon_framebuffer(fb); |
215 | rdev->fbdev_rfb = rfb; | 229 | rdev->fbdev_rfb = rfb; |
216 | rdev->fbdev_robj = robj; | 230 | rdev->fbdev_rbo = rbo; |
217 | 231 | ||
218 | info = framebuffer_alloc(sizeof(struct radeon_fb_device), device); | 232 | info = framebuffer_alloc(sizeof(struct radeon_fb_device), device); |
219 | if (info == NULL) { | 233 | if (info == NULL) { |
@@ -234,15 +248,7 @@ int radeonfb_create(struct drm_device *dev, | |||
234 | if (ret) | 248 | if (ret) |
235 | goto out_unref; | 249 | goto out_unref; |
236 | 250 | ||
237 | if (fb_tiled) | 251 | memset_io(fbptr, 0xff, aligned_size); |
238 | radeon_object_check_tiling(robj, 0, 0); | ||
239 | |||
240 | ret = radeon_object_kmap(robj, &fbptr); | ||
241 | if (ret) { | ||
242 | goto out_unref; | ||
243 | } | ||
244 | |||
245 | memset_io(fbptr, 0, aligned_size); | ||
246 | 252 | ||
247 | strcpy(info->fix.id, "radeondrmfb"); | 253 | strcpy(info->fix.id, "radeondrmfb"); |
248 | 254 | ||
@@ -288,8 +294,12 @@ int radeonfb_create(struct drm_device *dev, | |||
288 | return 0; | 294 | return 0; |
289 | 295 | ||
290 | out_unref: | 296 | out_unref: |
291 | if (robj) { | 297 | if (rbo) { |
292 | radeon_object_kunmap(robj); | 298 | ret = radeon_bo_reserve(rbo, false); |
299 | if (likely(ret == 0)) { | ||
300 | radeon_bo_kunmap(rbo); | ||
301 | radeon_bo_unreserve(rbo); | ||
302 | } | ||
293 | } | 303 | } |
294 | if (fb && ret) { | 304 | if (fb && ret) { |
295 | list_del(&fb->filp_head); | 305 | list_del(&fb->filp_head); |
@@ -321,14 +331,22 @@ int radeon_parse_options(char *options) | |||
321 | 331 | ||
322 | int radeonfb_probe(struct drm_device *dev) | 332 | int radeonfb_probe(struct drm_device *dev) |
323 | { | 333 | { |
324 | return drm_fb_helper_single_fb_probe(dev, 32, &radeonfb_create); | 334 | struct radeon_device *rdev = dev->dev_private; |
335 | int bpp_sel = 32; | ||
336 | |||
337 | /* select 8 bpp console on RN50 or 16MB cards */ | ||
338 | if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024)) | ||
339 | bpp_sel = 8; | ||
340 | |||
341 | return drm_fb_helper_single_fb_probe(dev, bpp_sel, &radeonfb_create); | ||
325 | } | 342 | } |
326 | 343 | ||
327 | int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) | 344 | int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) |
328 | { | 345 | { |
329 | struct fb_info *info; | 346 | struct fb_info *info; |
330 | struct radeon_framebuffer *rfb = to_radeon_framebuffer(fb); | 347 | struct radeon_framebuffer *rfb = to_radeon_framebuffer(fb); |
331 | struct radeon_object *robj; | 348 | struct radeon_bo *rbo; |
349 | int r; | ||
332 | 350 | ||
333 | if (!fb) { | 351 | if (!fb) { |
334 | return -EINVAL; | 352 | return -EINVAL; |
@@ -336,10 +354,14 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) | |||
336 | info = fb->fbdev; | 354 | info = fb->fbdev; |
337 | if (info) { | 355 | if (info) { |
338 | struct radeon_fb_device *rfbdev = info->par; | 356 | struct radeon_fb_device *rfbdev = info->par; |
339 | robj = rfb->obj->driver_private; | 357 | rbo = rfb->obj->driver_private; |
340 | unregister_framebuffer(info); | 358 | unregister_framebuffer(info); |
341 | radeon_object_kunmap(robj); | 359 | r = radeon_bo_reserve(rbo, false); |
342 | radeon_object_unpin(robj); | 360 | if (likely(r == 0)) { |
361 | radeon_bo_kunmap(rbo); | ||
362 | radeon_bo_unpin(rbo); | ||
363 | radeon_bo_unreserve(rbo); | ||
364 | } | ||
343 | drm_fb_helper_free(&rfbdev->helper); | 365 | drm_fb_helper_free(&rfbdev->helper); |
344 | framebuffer_release(info); | 366 | framebuffer_release(info); |
345 | } | 367 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 3beb26d74719..cb4cd97ae39f 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -168,37 +168,6 @@ bool radeon_fence_signaled(struct radeon_fence *fence) | |||
168 | return signaled; | 168 | return signaled; |
169 | } | 169 | } |
170 | 170 | ||
171 | int r600_fence_wait(struct radeon_fence *fence, bool intr, bool lazy) | ||
172 | { | ||
173 | struct radeon_device *rdev; | ||
174 | int ret = 0; | ||
175 | |||
176 | rdev = fence->rdev; | ||
177 | |||
178 | __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); | ||
179 | |||
180 | while (1) { | ||
181 | if (radeon_fence_signaled(fence)) | ||
182 | break; | ||
183 | |||
184 | if (time_after_eq(jiffies, fence->timeout)) { | ||
185 | ret = -EBUSY; | ||
186 | break; | ||
187 | } | ||
188 | |||
189 | if (lazy) | ||
190 | schedule_timeout(1); | ||
191 | |||
192 | if (intr && signal_pending(current)) { | ||
193 | ret = -ERESTARTSYS; | ||
194 | break; | ||
195 | } | ||
196 | } | ||
197 | __set_current_state(TASK_RUNNING); | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | |||
202 | int radeon_fence_wait(struct radeon_fence *fence, bool intr) | 171 | int radeon_fence_wait(struct radeon_fence *fence, bool intr) |
203 | { | 172 | { |
204 | struct radeon_device *rdev; | 173 | struct radeon_device *rdev; |
@@ -216,13 +185,6 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) | |||
216 | return 0; | 185 | return 0; |
217 | } | 186 | } |
218 | 187 | ||
219 | if (rdev->family >= CHIP_R600) { | ||
220 | r = r600_fence_wait(fence, intr, 0); | ||
221 | if (r == -ERESTARTSYS) | ||
222 | return -EBUSY; | ||
223 | return r; | ||
224 | } | ||
225 | |||
226 | retry: | 188 | retry: |
227 | cur_jiffies = jiffies; | 189 | cur_jiffies = jiffies; |
228 | timeout = HZ / 100; | 190 | timeout = HZ / 100; |
@@ -231,14 +193,17 @@ retry: | |||
231 | } | 193 | } |
232 | 194 | ||
233 | if (intr) { | 195 | if (intr) { |
196 | radeon_irq_kms_sw_irq_get(rdev); | ||
234 | r = wait_event_interruptible_timeout(rdev->fence_drv.queue, | 197 | r = wait_event_interruptible_timeout(rdev->fence_drv.queue, |
235 | radeon_fence_signaled(fence), timeout); | 198 | radeon_fence_signaled(fence), timeout); |
236 | if (unlikely(r == -ERESTARTSYS)) { | 199 | radeon_irq_kms_sw_irq_put(rdev); |
237 | return -EBUSY; | 200 | if (unlikely(r < 0)) |
238 | } | 201 | return r; |
239 | } else { | 202 | } else { |
203 | radeon_irq_kms_sw_irq_get(rdev); | ||
240 | r = wait_event_timeout(rdev->fence_drv.queue, | 204 | r = wait_event_timeout(rdev->fence_drv.queue, |
241 | radeon_fence_signaled(fence), timeout); | 205 | radeon_fence_signaled(fence), timeout); |
206 | radeon_irq_kms_sw_irq_put(rdev); | ||
242 | } | 207 | } |
243 | if (unlikely(!radeon_fence_signaled(fence))) { | 208 | if (unlikely(!radeon_fence_signaled(fence))) { |
244 | if (unlikely(r == 0)) { | 209 | if (unlikely(r == 0)) { |
diff --git a/drivers/gpu/drm/radeon/radeon_fixed.h b/drivers/gpu/drm/radeon/radeon_fixed.h index 90187d173847..3d4d84e078ac 100644 --- a/drivers/gpu/drm/radeon/radeon_fixed.h +++ b/drivers/gpu/drm/radeon/radeon_fixed.h | |||
@@ -38,6 +38,23 @@ typedef union rfixed { | |||
38 | #define fixed_init_half(A) { .full = rfixed_const_half((A)) } | 38 | #define fixed_init_half(A) { .full = rfixed_const_half((A)) } |
39 | #define rfixed_trunc(A) ((A).full >> 12) | 39 | #define rfixed_trunc(A) ((A).full >> 12) |
40 | 40 | ||
41 | static inline u32 rfixed_floor(fixed20_12 A) | ||
42 | { | ||
43 | u32 non_frac = rfixed_trunc(A); | ||
44 | |||
45 | return rfixed_const(non_frac); | ||
46 | } | ||
47 | |||
48 | static inline u32 rfixed_ceil(fixed20_12 A) | ||
49 | { | ||
50 | u32 non_frac = rfixed_trunc(A); | ||
51 | |||
52 | if (A.full > rfixed_const(non_frac)) | ||
53 | return rfixed_const(non_frac + 1); | ||
54 | else | ||
55 | return rfixed_const(non_frac); | ||
56 | } | ||
57 | |||
41 | static inline u32 rfixed_div(fixed20_12 A, fixed20_12 B) | 58 | static inline u32 rfixed_div(fixed20_12 A, fixed20_12 B) |
42 | { | 59 | { |
43 | u64 tmp = ((u64)A.full << 13); | 60 | u64 tmp = ((u64)A.full << 13); |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index a931af065dd4..e73d56e83fa6 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -78,11 +78,9 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev) | |||
78 | int r; | 78 | int r; |
79 | 79 | ||
80 | if (rdev->gart.table.vram.robj == NULL) { | 80 | if (rdev->gart.table.vram.robj == NULL) { |
81 | r = radeon_object_create(rdev, NULL, | 81 | r = radeon_bo_create(rdev, NULL, rdev->gart.table_size, |
82 | rdev->gart.table_size, | 82 | true, RADEON_GEM_DOMAIN_VRAM, |
83 | true, | 83 | &rdev->gart.table.vram.robj); |
84 | RADEON_GEM_DOMAIN_VRAM, | ||
85 | false, &rdev->gart.table.vram.robj); | ||
86 | if (r) { | 84 | if (r) { |
87 | return r; | 85 | return r; |
88 | } | 86 | } |
@@ -95,32 +93,38 @@ int radeon_gart_table_vram_pin(struct radeon_device *rdev) | |||
95 | uint64_t gpu_addr; | 93 | uint64_t gpu_addr; |
96 | int r; | 94 | int r; |
97 | 95 | ||
98 | r = radeon_object_pin(rdev->gart.table.vram.robj, | 96 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); |
99 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); | 97 | if (unlikely(r != 0)) |
100 | if (r) { | ||
101 | radeon_object_unref(&rdev->gart.table.vram.robj); | ||
102 | return r; | 98 | return r; |
103 | } | 99 | r = radeon_bo_pin(rdev->gart.table.vram.robj, |
104 | r = radeon_object_kmap(rdev->gart.table.vram.robj, | 100 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); |
105 | (void **)&rdev->gart.table.vram.ptr); | ||
106 | if (r) { | 101 | if (r) { |
107 | radeon_object_unpin(rdev->gart.table.vram.robj); | 102 | radeon_bo_unreserve(rdev->gart.table.vram.robj); |
108 | radeon_object_unref(&rdev->gart.table.vram.robj); | ||
109 | DRM_ERROR("radeon: failed to map gart vram table.\n"); | ||
110 | return r; | 103 | return r; |
111 | } | 104 | } |
105 | r = radeon_bo_kmap(rdev->gart.table.vram.robj, | ||
106 | (void **)&rdev->gart.table.vram.ptr); | ||
107 | if (r) | ||
108 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
109 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
112 | rdev->gart.table_addr = gpu_addr; | 110 | rdev->gart.table_addr = gpu_addr; |
113 | return 0; | 111 | return r; |
114 | } | 112 | } |
115 | 113 | ||
116 | void radeon_gart_table_vram_free(struct radeon_device *rdev) | 114 | void radeon_gart_table_vram_free(struct radeon_device *rdev) |
117 | { | 115 | { |
116 | int r; | ||
117 | |||
118 | if (rdev->gart.table.vram.robj == NULL) { | 118 | if (rdev->gart.table.vram.robj == NULL) { |
119 | return; | 119 | return; |
120 | } | 120 | } |
121 | radeon_object_kunmap(rdev->gart.table.vram.robj); | 121 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); |
122 | radeon_object_unpin(rdev->gart.table.vram.robj); | 122 | if (likely(r == 0)) { |
123 | radeon_object_unref(&rdev->gart.table.vram.robj); | 123 | radeon_bo_kunmap(rdev->gart.table.vram.robj); |
124 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
125 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
126 | } | ||
127 | radeon_bo_unref(&rdev->gart.table.vram.robj); | ||
124 | } | 128 | } |
125 | 129 | ||
126 | 130 | ||
@@ -140,15 +144,15 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
140 | WARN(1, "trying to unbind memory to unitialized GART !\n"); | 144 | WARN(1, "trying to unbind memory to unitialized GART !\n"); |
141 | return; | 145 | return; |
142 | } | 146 | } |
143 | t = offset / 4096; | 147 | t = offset / RADEON_GPU_PAGE_SIZE; |
144 | p = t / (PAGE_SIZE / 4096); | 148 | p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); |
145 | for (i = 0; i < pages; i++, p++) { | 149 | for (i = 0; i < pages; i++, p++) { |
146 | if (rdev->gart.pages[p]) { | 150 | if (rdev->gart.pages[p]) { |
147 | pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], | 151 | pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], |
148 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 152 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
149 | rdev->gart.pages[p] = NULL; | 153 | rdev->gart.pages[p] = NULL; |
150 | rdev->gart.pages_addr[p] = 0; | 154 | rdev->gart.pages_addr[p] = 0; |
151 | for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) { | 155 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
152 | radeon_gart_set_page(rdev, t, 0); | 156 | radeon_gart_set_page(rdev, t, 0); |
153 | } | 157 | } |
154 | } | 158 | } |
@@ -169,8 +173,8 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
169 | DRM_ERROR("trying to bind memory to unitialized GART !\n"); | 173 | DRM_ERROR("trying to bind memory to unitialized GART !\n"); |
170 | return -EINVAL; | 174 | return -EINVAL; |
171 | } | 175 | } |
172 | t = offset / 4096; | 176 | t = offset / RADEON_GPU_PAGE_SIZE; |
173 | p = t / (PAGE_SIZE / 4096); | 177 | p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); |
174 | 178 | ||
175 | for (i = 0; i < pages; i++, p++) { | 179 | for (i = 0; i < pages; i++, p++) { |
176 | /* we need to support large memory configurations */ | 180 | /* we need to support large memory configurations */ |
@@ -185,9 +189,9 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
185 | } | 189 | } |
186 | rdev->gart.pages[p] = pagelist[i]; | 190 | rdev->gart.pages[p] = pagelist[i]; |
187 | page_base = rdev->gart.pages_addr[p]; | 191 | page_base = rdev->gart.pages_addr[p]; |
188 | for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) { | 192 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
189 | radeon_gart_set_page(rdev, t, page_base); | 193 | radeon_gart_set_page(rdev, t, page_base); |
190 | page_base += 4096; | 194 | page_base += RADEON_GPU_PAGE_SIZE; |
191 | } | 195 | } |
192 | } | 196 | } |
193 | mb(); | 197 | mb(); |
@@ -200,14 +204,14 @@ int radeon_gart_init(struct radeon_device *rdev) | |||
200 | if (rdev->gart.pages) { | 204 | if (rdev->gart.pages) { |
201 | return 0; | 205 | return 0; |
202 | } | 206 | } |
203 | /* We need PAGE_SIZE >= 4096 */ | 207 | /* We need PAGE_SIZE >= RADEON_GPU_PAGE_SIZE */ |
204 | if (PAGE_SIZE < 4096) { | 208 | if (PAGE_SIZE < RADEON_GPU_PAGE_SIZE) { |
205 | DRM_ERROR("Page size is smaller than GPU page size!\n"); | 209 | DRM_ERROR("Page size is smaller than GPU page size!\n"); |
206 | return -EINVAL; | 210 | return -EINVAL; |
207 | } | 211 | } |
208 | /* Compute table size */ | 212 | /* Compute table size */ |
209 | rdev->gart.num_cpu_pages = rdev->mc.gtt_size / PAGE_SIZE; | 213 | rdev->gart.num_cpu_pages = rdev->mc.gtt_size / PAGE_SIZE; |
210 | rdev->gart.num_gpu_pages = rdev->mc.gtt_size / 4096; | 214 | rdev->gart.num_gpu_pages = rdev->mc.gtt_size / RADEON_GPU_PAGE_SIZE; |
211 | DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", | 215 | DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", |
212 | rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); | 216 | rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); |
213 | /* Allocate pages table */ | 217 | /* Allocate pages table */ |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index d880edf254db..2944486871b0 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -38,22 +38,21 @@ int radeon_gem_object_init(struct drm_gem_object *obj) | |||
38 | 38 | ||
39 | void radeon_gem_object_free(struct drm_gem_object *gobj) | 39 | void radeon_gem_object_free(struct drm_gem_object *gobj) |
40 | { | 40 | { |
41 | struct radeon_object *robj = gobj->driver_private; | 41 | struct radeon_bo *robj = gobj->driver_private; |
42 | 42 | ||
43 | gobj->driver_private = NULL; | 43 | gobj->driver_private = NULL; |
44 | if (robj) { | 44 | if (robj) { |
45 | radeon_object_unref(&robj); | 45 | radeon_bo_unref(&robj); |
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
49 | int radeon_gem_object_create(struct radeon_device *rdev, int size, | 49 | int radeon_gem_object_create(struct radeon_device *rdev, int size, |
50 | int alignment, int initial_domain, | 50 | int alignment, int initial_domain, |
51 | bool discardable, bool kernel, | 51 | bool discardable, bool kernel, |
52 | bool interruptible, | 52 | struct drm_gem_object **obj) |
53 | struct drm_gem_object **obj) | ||
54 | { | 53 | { |
55 | struct drm_gem_object *gobj; | 54 | struct drm_gem_object *gobj; |
56 | struct radeon_object *robj; | 55 | struct radeon_bo *robj; |
57 | int r; | 56 | int r; |
58 | 57 | ||
59 | *obj = NULL; | 58 | *obj = NULL; |
@@ -65,8 +64,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, | |||
65 | if (alignment < PAGE_SIZE) { | 64 | if (alignment < PAGE_SIZE) { |
66 | alignment = PAGE_SIZE; | 65 | alignment = PAGE_SIZE; |
67 | } | 66 | } |
68 | r = radeon_object_create(rdev, gobj, size, kernel, initial_domain, | 67 | r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj); |
69 | interruptible, &robj); | ||
70 | if (r) { | 68 | if (r) { |
71 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n", | 69 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n", |
72 | size, initial_domain, alignment); | 70 | size, initial_domain, alignment); |
@@ -83,33 +81,33 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, | |||
83 | int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain, | 81 | int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain, |
84 | uint64_t *gpu_addr) | 82 | uint64_t *gpu_addr) |
85 | { | 83 | { |
86 | struct radeon_object *robj = obj->driver_private; | 84 | struct radeon_bo *robj = obj->driver_private; |
87 | uint32_t flags; | 85 | int r; |
88 | 86 | ||
89 | switch (pin_domain) { | 87 | r = radeon_bo_reserve(robj, false); |
90 | case RADEON_GEM_DOMAIN_VRAM: | 88 | if (unlikely(r != 0)) |
91 | flags = TTM_PL_FLAG_VRAM; | 89 | return r; |
92 | break; | 90 | r = radeon_bo_pin(robj, pin_domain, gpu_addr); |
93 | case RADEON_GEM_DOMAIN_GTT: | 91 | radeon_bo_unreserve(robj); |
94 | flags = TTM_PL_FLAG_TT; | 92 | return r; |
95 | break; | ||
96 | default: | ||
97 | flags = TTM_PL_FLAG_SYSTEM; | ||
98 | break; | ||
99 | } | ||
100 | return radeon_object_pin(robj, flags, gpu_addr); | ||
101 | } | 93 | } |
102 | 94 | ||
103 | void radeon_gem_object_unpin(struct drm_gem_object *obj) | 95 | void radeon_gem_object_unpin(struct drm_gem_object *obj) |
104 | { | 96 | { |
105 | struct radeon_object *robj = obj->driver_private; | 97 | struct radeon_bo *robj = obj->driver_private; |
106 | radeon_object_unpin(robj); | 98 | int r; |
99 | |||
100 | r = radeon_bo_reserve(robj, false); | ||
101 | if (likely(r == 0)) { | ||
102 | radeon_bo_unpin(robj); | ||
103 | radeon_bo_unreserve(robj); | ||
104 | } | ||
107 | } | 105 | } |
108 | 106 | ||
109 | int radeon_gem_set_domain(struct drm_gem_object *gobj, | 107 | int radeon_gem_set_domain(struct drm_gem_object *gobj, |
110 | uint32_t rdomain, uint32_t wdomain) | 108 | uint32_t rdomain, uint32_t wdomain) |
111 | { | 109 | { |
112 | struct radeon_object *robj; | 110 | struct radeon_bo *robj; |
113 | uint32_t domain; | 111 | uint32_t domain; |
114 | int r; | 112 | int r; |
115 | 113 | ||
@@ -127,11 +125,12 @@ int radeon_gem_set_domain(struct drm_gem_object *gobj, | |||
127 | } | 125 | } |
128 | if (domain == RADEON_GEM_DOMAIN_CPU) { | 126 | if (domain == RADEON_GEM_DOMAIN_CPU) { |
129 | /* Asking for cpu access wait for object idle */ | 127 | /* Asking for cpu access wait for object idle */ |
130 | r = radeon_object_wait(robj); | 128 | r = radeon_bo_wait(robj, NULL, false); |
131 | if (r) { | 129 | if (r) { |
132 | printk(KERN_ERR "Failed to wait for object !\n"); | 130 | printk(KERN_ERR "Failed to wait for object !\n"); |
133 | return r; | 131 | return r; |
134 | } | 132 | } |
133 | radeon_hdp_flush(robj->rdev); | ||
135 | } | 134 | } |
136 | return 0; | 135 | return 0; |
137 | } | 136 | } |
@@ -144,7 +143,7 @@ int radeon_gem_init(struct radeon_device *rdev) | |||
144 | 143 | ||
145 | void radeon_gem_fini(struct radeon_device *rdev) | 144 | void radeon_gem_fini(struct radeon_device *rdev) |
146 | { | 145 | { |
147 | radeon_object_force_delete(rdev); | 146 | radeon_bo_force_delete(rdev); |
148 | } | 147 | } |
149 | 148 | ||
150 | 149 | ||
@@ -158,9 +157,13 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, | |||
158 | struct drm_radeon_gem_info *args = data; | 157 | struct drm_radeon_gem_info *args = data; |
159 | 158 | ||
160 | args->vram_size = rdev->mc.real_vram_size; | 159 | args->vram_size = rdev->mc.real_vram_size; |
161 | /* FIXME: report somethings that makes sense */ | 160 | args->vram_visible = rdev->mc.real_vram_size; |
162 | args->vram_visible = rdev->mc.real_vram_size - (4 * 1024 * 1024); | 161 | if (rdev->stollen_vga_memory) |
163 | args->gart_size = rdev->mc.gtt_size; | 162 | args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory); |
163 | if (rdev->fbdev_rbo) | ||
164 | args->vram_visible -= radeon_bo_size(rdev->fbdev_rbo); | ||
165 | args->gart_size = rdev->mc.gtt_size - rdev->cp.ring_size - 4096 - | ||
166 | RADEON_IB_POOL_SIZE*64*1024; | ||
164 | return 0; | 167 | return 0; |
165 | } | 168 | } |
166 | 169 | ||
@@ -192,8 +195,8 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, | |||
192 | /* create a gem object to contain this object in */ | 195 | /* create a gem object to contain this object in */ |
193 | args->size = roundup(args->size, PAGE_SIZE); | 196 | args->size = roundup(args->size, PAGE_SIZE); |
194 | r = radeon_gem_object_create(rdev, args->size, args->alignment, | 197 | r = radeon_gem_object_create(rdev, args->size, args->alignment, |
195 | args->initial_domain, false, | 198 | args->initial_domain, false, |
196 | false, true, &gobj); | 199 | false, &gobj); |
197 | if (r) { | 200 | if (r) { |
198 | return r; | 201 | return r; |
199 | } | 202 | } |
@@ -218,7 +221,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
218 | * just validate the BO into a certain domain */ | 221 | * just validate the BO into a certain domain */ |
219 | struct drm_radeon_gem_set_domain *args = data; | 222 | struct drm_radeon_gem_set_domain *args = data; |
220 | struct drm_gem_object *gobj; | 223 | struct drm_gem_object *gobj; |
221 | struct radeon_object *robj; | 224 | struct radeon_bo *robj; |
222 | int r; | 225 | int r; |
223 | 226 | ||
224 | /* for now if someone requests domain CPU - | 227 | /* for now if someone requests domain CPU - |
@@ -244,19 +247,18 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
244 | { | 247 | { |
245 | struct drm_radeon_gem_mmap *args = data; | 248 | struct drm_radeon_gem_mmap *args = data; |
246 | struct drm_gem_object *gobj; | 249 | struct drm_gem_object *gobj; |
247 | struct radeon_object *robj; | 250 | struct radeon_bo *robj; |
248 | int r; | ||
249 | 251 | ||
250 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 252 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
251 | if (gobj == NULL) { | 253 | if (gobj == NULL) { |
252 | return -EINVAL; | 254 | return -EINVAL; |
253 | } | 255 | } |
254 | robj = gobj->driver_private; | 256 | robj = gobj->driver_private; |
255 | r = radeon_object_mmap(robj, &args->addr_ptr); | 257 | args->addr_ptr = radeon_bo_mmap_offset(robj); |
256 | mutex_lock(&dev->struct_mutex); | 258 | mutex_lock(&dev->struct_mutex); |
257 | drm_gem_object_unreference(gobj); | 259 | drm_gem_object_unreference(gobj); |
258 | mutex_unlock(&dev->struct_mutex); | 260 | mutex_unlock(&dev->struct_mutex); |
259 | return r; | 261 | return 0; |
260 | } | 262 | } |
261 | 263 | ||
262 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | 264 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, |
@@ -264,16 +266,16 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
264 | { | 266 | { |
265 | struct drm_radeon_gem_busy *args = data; | 267 | struct drm_radeon_gem_busy *args = data; |
266 | struct drm_gem_object *gobj; | 268 | struct drm_gem_object *gobj; |
267 | struct radeon_object *robj; | 269 | struct radeon_bo *robj; |
268 | int r; | 270 | int r; |
269 | uint32_t cur_placement; | 271 | uint32_t cur_placement = 0; |
270 | 272 | ||
271 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 273 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
272 | if (gobj == NULL) { | 274 | if (gobj == NULL) { |
273 | return -EINVAL; | 275 | return -EINVAL; |
274 | } | 276 | } |
275 | robj = gobj->driver_private; | 277 | robj = gobj->driver_private; |
276 | r = radeon_object_busy_domain(robj, &cur_placement); | 278 | r = radeon_bo_wait(robj, &cur_placement, true); |
277 | switch (cur_placement) { | 279 | switch (cur_placement) { |
278 | case TTM_PL_VRAM: | 280 | case TTM_PL_VRAM: |
279 | args->domain = RADEON_GEM_DOMAIN_VRAM; | 281 | args->domain = RADEON_GEM_DOMAIN_VRAM; |
@@ -297,7 +299,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | |||
297 | { | 299 | { |
298 | struct drm_radeon_gem_wait_idle *args = data; | 300 | struct drm_radeon_gem_wait_idle *args = data; |
299 | struct drm_gem_object *gobj; | 301 | struct drm_gem_object *gobj; |
300 | struct radeon_object *robj; | 302 | struct radeon_bo *robj; |
301 | int r; | 303 | int r; |
302 | 304 | ||
303 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 305 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
@@ -305,10 +307,11 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | |||
305 | return -EINVAL; | 307 | return -EINVAL; |
306 | } | 308 | } |
307 | robj = gobj->driver_private; | 309 | robj = gobj->driver_private; |
308 | r = radeon_object_wait(robj); | 310 | r = radeon_bo_wait(robj, NULL, false); |
309 | mutex_lock(&dev->struct_mutex); | 311 | mutex_lock(&dev->struct_mutex); |
310 | drm_gem_object_unreference(gobj); | 312 | drm_gem_object_unreference(gobj); |
311 | mutex_unlock(&dev->struct_mutex); | 313 | mutex_unlock(&dev->struct_mutex); |
314 | radeon_hdp_flush(robj->rdev); | ||
312 | return r; | 315 | return r; |
313 | } | 316 | } |
314 | 317 | ||
@@ -317,7 +320,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
317 | { | 320 | { |
318 | struct drm_radeon_gem_set_tiling *args = data; | 321 | struct drm_radeon_gem_set_tiling *args = data; |
319 | struct drm_gem_object *gobj; | 322 | struct drm_gem_object *gobj; |
320 | struct radeon_object *robj; | 323 | struct radeon_bo *robj; |
321 | int r = 0; | 324 | int r = 0; |
322 | 325 | ||
323 | DRM_DEBUG("%d \n", args->handle); | 326 | DRM_DEBUG("%d \n", args->handle); |
@@ -325,7 +328,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
325 | if (gobj == NULL) | 328 | if (gobj == NULL) |
326 | return -EINVAL; | 329 | return -EINVAL; |
327 | robj = gobj->driver_private; | 330 | robj = gobj->driver_private; |
328 | radeon_object_set_tiling_flags(robj, args->tiling_flags, args->pitch); | 331 | r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch); |
329 | mutex_lock(&dev->struct_mutex); | 332 | mutex_lock(&dev->struct_mutex); |
330 | drm_gem_object_unreference(gobj); | 333 | drm_gem_object_unreference(gobj); |
331 | mutex_unlock(&dev->struct_mutex); | 334 | mutex_unlock(&dev->struct_mutex); |
@@ -337,16 +340,19 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, | |||
337 | { | 340 | { |
338 | struct drm_radeon_gem_get_tiling *args = data; | 341 | struct drm_radeon_gem_get_tiling *args = data; |
339 | struct drm_gem_object *gobj; | 342 | struct drm_gem_object *gobj; |
340 | struct radeon_object *robj; | 343 | struct radeon_bo *rbo; |
341 | int r = 0; | 344 | int r = 0; |
342 | 345 | ||
343 | DRM_DEBUG("\n"); | 346 | DRM_DEBUG("\n"); |
344 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 347 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
345 | if (gobj == NULL) | 348 | if (gobj == NULL) |
346 | return -EINVAL; | 349 | return -EINVAL; |
347 | robj = gobj->driver_private; | 350 | rbo = gobj->driver_private; |
348 | radeon_object_get_tiling_flags(robj, &args->tiling_flags, | 351 | r = radeon_bo_reserve(rbo, false); |
349 | &args->pitch); | 352 | if (unlikely(r != 0)) |
353 | return r; | ||
354 | radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch); | ||
355 | radeon_bo_unreserve(rbo); | ||
350 | mutex_lock(&dev->struct_mutex); | 356 | mutex_lock(&dev->struct_mutex); |
351 | drm_gem_object_unreference(gobj); | 357 | drm_gem_object_unreference(gobj); |
352 | mutex_unlock(&dev->struct_mutex); | 358 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index dd438d32e5c0..da3da1e89d00 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -59,35 +59,43 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) | |||
59 | } | 59 | } |
60 | 60 | ||
61 | 61 | ||
62 | void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state) | 62 | void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) |
63 | { | 63 | { |
64 | struct radeon_device *rdev = radeon_connector->base.dev->dev_private; | 64 | struct radeon_device *rdev = i2c->dev->dev_private; |
65 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | ||
65 | uint32_t temp; | 66 | uint32_t temp; |
66 | struct radeon_i2c_bus_rec *rec = &radeon_connector->ddc_bus->rec; | ||
67 | 67 | ||
68 | /* RV410 appears to have a bug where the hw i2c in reset | 68 | /* RV410 appears to have a bug where the hw i2c in reset |
69 | * holds the i2c port in a bad state - switch hw i2c away before | 69 | * holds the i2c port in a bad state - switch hw i2c away before |
70 | * doing DDC - do this for all r200s/r300s/r400s for safety sake | 70 | * doing DDC - do this for all r200s/r300s/r400s for safety sake |
71 | */ | 71 | */ |
72 | if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { | 72 | if (rec->hw_capable) { |
73 | if (rec->a_clk_reg == RADEON_GPIO_MONID) { | 73 | if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { |
74 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | | 74 | if (rec->a_clk_reg == RADEON_GPIO_MONID) { |
75 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); | 75 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | |
76 | } else { | 76 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); |
77 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | | 77 | } else { |
78 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); | 78 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | |
79 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); | ||
80 | } | ||
79 | } | 81 | } |
80 | } | 82 | } |
81 | if (lock_state) { | ||
82 | temp = RREG32(rec->a_clk_reg); | ||
83 | temp &= ~(rec->a_clk_mask); | ||
84 | WREG32(rec->a_clk_reg, temp); | ||
85 | |||
86 | temp = RREG32(rec->a_data_reg); | ||
87 | temp &= ~(rec->a_data_mask); | ||
88 | WREG32(rec->a_data_reg, temp); | ||
89 | } | ||
90 | 83 | ||
84 | /* clear the output pin values */ | ||
85 | temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; | ||
86 | WREG32(rec->a_clk_reg, temp); | ||
87 | |||
88 | temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask; | ||
89 | WREG32(rec->a_data_reg, temp); | ||
90 | |||
91 | /* set the pins to input */ | ||
92 | temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; | ||
93 | WREG32(rec->en_clk_reg, temp); | ||
94 | |||
95 | temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask; | ||
96 | WREG32(rec->en_data_reg, temp); | ||
97 | |||
98 | /* mask the gpio pins for software use */ | ||
91 | temp = RREG32(rec->mask_clk_reg); | 99 | temp = RREG32(rec->mask_clk_reg); |
92 | if (lock_state) | 100 | if (lock_state) |
93 | temp |= rec->mask_clk_mask; | 101 | temp |= rec->mask_clk_mask; |
@@ -112,8 +120,9 @@ static int get_clock(void *i2c_priv) | |||
112 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 120 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
113 | uint32_t val; | 121 | uint32_t val; |
114 | 122 | ||
115 | val = RREG32(rec->get_clk_reg); | 123 | /* read the value off the pin */ |
116 | val &= rec->get_clk_mask; | 124 | val = RREG32(rec->y_clk_reg); |
125 | val &= rec->y_clk_mask; | ||
117 | 126 | ||
118 | return (val != 0); | 127 | return (val != 0); |
119 | } | 128 | } |
@@ -126,8 +135,10 @@ static int get_data(void *i2c_priv) | |||
126 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 135 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
127 | uint32_t val; | 136 | uint32_t val; |
128 | 137 | ||
129 | val = RREG32(rec->get_data_reg); | 138 | /* read the value off the pin */ |
130 | val &= rec->get_data_mask; | 139 | val = RREG32(rec->y_data_reg); |
140 | val &= rec->y_data_mask; | ||
141 | |||
131 | return (val != 0); | 142 | return (val != 0); |
132 | } | 143 | } |
133 | 144 | ||
@@ -138,9 +149,10 @@ static void set_clock(void *i2c_priv, int clock) | |||
138 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 149 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
139 | uint32_t val; | 150 | uint32_t val; |
140 | 151 | ||
141 | val = RREG32(rec->put_clk_reg) & (uint32_t)~(rec->put_clk_mask); | 152 | /* set pin direction */ |
142 | val |= clock ? 0 : rec->put_clk_mask; | 153 | val = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; |
143 | WREG32(rec->put_clk_reg, val); | 154 | val |= clock ? 0 : rec->en_clk_mask; |
155 | WREG32(rec->en_clk_reg, val); | ||
144 | } | 156 | } |
145 | 157 | ||
146 | static void set_data(void *i2c_priv, int data) | 158 | static void set_data(void *i2c_priv, int data) |
@@ -150,14 +162,15 @@ static void set_data(void *i2c_priv, int data) | |||
150 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 162 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
151 | uint32_t val; | 163 | uint32_t val; |
152 | 164 | ||
153 | val = RREG32(rec->put_data_reg) & (uint32_t)~(rec->put_data_mask); | 165 | /* set pin direction */ |
154 | val |= data ? 0 : rec->put_data_mask; | 166 | val = RREG32(rec->en_data_reg) & ~rec->en_data_mask; |
155 | WREG32(rec->put_data_reg, val); | 167 | val |= data ? 0 : rec->en_data_mask; |
168 | WREG32(rec->en_data_reg, val); | ||
156 | } | 169 | } |
157 | 170 | ||
158 | struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | 171 | struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, |
159 | struct radeon_i2c_bus_rec *rec, | 172 | struct radeon_i2c_bus_rec *rec, |
160 | const char *name) | 173 | const char *name) |
161 | { | 174 | { |
162 | struct radeon_i2c_chan *i2c; | 175 | struct radeon_i2c_chan *i2c; |
163 | int ret; | 176 | int ret; |
@@ -167,20 +180,19 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
167 | return NULL; | 180 | return NULL; |
168 | 181 | ||
169 | i2c->adapter.owner = THIS_MODULE; | 182 | i2c->adapter.owner = THIS_MODULE; |
170 | i2c->adapter.algo_data = &i2c->algo; | ||
171 | i2c->dev = dev; | 183 | i2c->dev = dev; |
172 | i2c->algo.setsda = set_data; | 184 | i2c_set_adapdata(&i2c->adapter, i2c); |
173 | i2c->algo.setscl = set_clock; | 185 | i2c->adapter.algo_data = &i2c->algo.bit; |
174 | i2c->algo.getsda = get_data; | 186 | i2c->algo.bit.setsda = set_data; |
175 | i2c->algo.getscl = get_clock; | 187 | i2c->algo.bit.setscl = set_clock; |
176 | i2c->algo.udelay = 20; | 188 | i2c->algo.bit.getsda = get_data; |
189 | i2c->algo.bit.getscl = get_clock; | ||
190 | i2c->algo.bit.udelay = 20; | ||
177 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always | 191 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always |
178 | * make this, 2 jiffies is a lot more reliable */ | 192 | * make this, 2 jiffies is a lot more reliable */ |
179 | i2c->algo.timeout = 2; | 193 | i2c->algo.bit.timeout = 2; |
180 | i2c->algo.data = i2c; | 194 | i2c->algo.bit.data = i2c; |
181 | i2c->rec = *rec; | 195 | i2c->rec = *rec; |
182 | i2c_set_adapdata(&i2c->adapter, i2c); | ||
183 | |||
184 | ret = i2c_bit_add_bus(&i2c->adapter); | 196 | ret = i2c_bit_add_bus(&i2c->adapter); |
185 | if (ret) { | 197 | if (ret) { |
186 | DRM_INFO("Failed to register i2c %s\n", name); | 198 | DRM_INFO("Failed to register i2c %s\n", name); |
@@ -194,6 +206,38 @@ out_free: | |||
194 | 206 | ||
195 | } | 207 | } |
196 | 208 | ||
209 | struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, | ||
210 | struct radeon_i2c_bus_rec *rec, | ||
211 | const char *name) | ||
212 | { | ||
213 | struct radeon_i2c_chan *i2c; | ||
214 | int ret; | ||
215 | |||
216 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); | ||
217 | if (i2c == NULL) | ||
218 | return NULL; | ||
219 | |||
220 | i2c->rec = *rec; | ||
221 | i2c->adapter.owner = THIS_MODULE; | ||
222 | i2c->dev = dev; | ||
223 | i2c_set_adapdata(&i2c->adapter, i2c); | ||
224 | i2c->adapter.algo_data = &i2c->algo.dp; | ||
225 | i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch; | ||
226 | i2c->algo.dp.address = 0; | ||
227 | ret = i2c_dp_aux_add_bus(&i2c->adapter); | ||
228 | if (ret) { | ||
229 | DRM_INFO("Failed to register i2c %s\n", name); | ||
230 | goto out_free; | ||
231 | } | ||
232 | |||
233 | return i2c; | ||
234 | out_free: | ||
235 | kfree(i2c); | ||
236 | return NULL; | ||
237 | |||
238 | } | ||
239 | |||
240 | |||
197 | void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) | 241 | void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) |
198 | { | 242 | { |
199 | if (!i2c) | 243 | if (!i2c) |
@@ -207,3 +251,59 @@ struct drm_encoder *radeon_best_encoder(struct drm_connector *connector) | |||
207 | { | 251 | { |
208 | return NULL; | 252 | return NULL; |
209 | } | 253 | } |
254 | |||
255 | void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus, | ||
256 | u8 slave_addr, | ||
257 | u8 addr, | ||
258 | u8 *val) | ||
259 | { | ||
260 | u8 out_buf[2]; | ||
261 | u8 in_buf[2]; | ||
262 | struct i2c_msg msgs[] = { | ||
263 | { | ||
264 | .addr = slave_addr, | ||
265 | .flags = 0, | ||
266 | .len = 1, | ||
267 | .buf = out_buf, | ||
268 | }, | ||
269 | { | ||
270 | .addr = slave_addr, | ||
271 | .flags = I2C_M_RD, | ||
272 | .len = 1, | ||
273 | .buf = in_buf, | ||
274 | } | ||
275 | }; | ||
276 | |||
277 | out_buf[0] = addr; | ||
278 | out_buf[1] = 0; | ||
279 | |||
280 | if (i2c_transfer(&i2c_bus->adapter, msgs, 2) == 2) { | ||
281 | *val = in_buf[0]; | ||
282 | DRM_DEBUG("val = 0x%02x\n", *val); | ||
283 | } else { | ||
284 | DRM_ERROR("i2c 0x%02x 0x%02x read failed\n", | ||
285 | addr, *val); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c_bus, | ||
290 | u8 slave_addr, | ||
291 | u8 addr, | ||
292 | u8 val) | ||
293 | { | ||
294 | uint8_t out_buf[2]; | ||
295 | struct i2c_msg msg = { | ||
296 | .addr = slave_addr, | ||
297 | .flags = 0, | ||
298 | .len = 2, | ||
299 | .buf = out_buf, | ||
300 | }; | ||
301 | |||
302 | out_buf[0] = addr; | ||
303 | out_buf[1] = val; | ||
304 | |||
305 | if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1) | ||
306 | DRM_ERROR("i2c 0x%02x 0x%02x write failed\n", | ||
307 | addr, val); | ||
308 | } | ||
309 | |||
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 8e0a8759e428..9223296fe37b 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -39,11 +39,32 @@ irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) | |||
39 | return radeon_irq_process(rdev); | 39 | return radeon_irq_process(rdev); |
40 | } | 40 | } |
41 | 41 | ||
42 | /* | ||
43 | * Handle hotplug events outside the interrupt handler proper. | ||
44 | */ | ||
45 | static void radeon_hotplug_work_func(struct work_struct *work) | ||
46 | { | ||
47 | struct radeon_device *rdev = container_of(work, struct radeon_device, | ||
48 | hotplug_work); | ||
49 | struct drm_device *dev = rdev->ddev; | ||
50 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
51 | struct drm_connector *connector; | ||
52 | |||
53 | if (mode_config->num_connector) { | ||
54 | list_for_each_entry(connector, &mode_config->connector_list, head) | ||
55 | radeon_connector_hotplug(connector); | ||
56 | } | ||
57 | /* Just fire off a uevent and let userspace tell us what to do */ | ||
58 | drm_sysfs_hotplug_event(dev); | ||
59 | } | ||
60 | |||
42 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev) | 61 | void radeon_driver_irq_preinstall_kms(struct drm_device *dev) |
43 | { | 62 | { |
44 | struct radeon_device *rdev = dev->dev_private; | 63 | struct radeon_device *rdev = dev->dev_private; |
45 | unsigned i; | 64 | unsigned i; |
46 | 65 | ||
66 | INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); | ||
67 | |||
47 | /* Disable *all* interrupts */ | 68 | /* Disable *all* interrupts */ |
48 | rdev->irq.sw_int = false; | 69 | rdev->irq.sw_int = false; |
49 | for (i = 0; i < 2; i++) { | 70 | for (i = 0; i < 2; i++) { |
@@ -87,11 +108,26 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
87 | 108 | ||
88 | if (rdev->flags & RADEON_SINGLE_CRTC) | 109 | if (rdev->flags & RADEON_SINGLE_CRTC) |
89 | num_crtc = 1; | 110 | num_crtc = 1; |
90 | 111 | spin_lock_init(&rdev->irq.sw_lock); | |
91 | r = drm_vblank_init(rdev->ddev, num_crtc); | 112 | r = drm_vblank_init(rdev->ddev, num_crtc); |
92 | if (r) { | 113 | if (r) { |
93 | return r; | 114 | return r; |
94 | } | 115 | } |
116 | /* enable msi */ | ||
117 | rdev->msi_enabled = 0; | ||
118 | /* MSIs don't seem to work on my rs780; | ||
119 | * not sure about rs880 or other rs780s. | ||
120 | * Needs more investigation. | ||
121 | */ | ||
122 | if ((rdev->family >= CHIP_RV380) && | ||
123 | (rdev->family != CHIP_RS780) && | ||
124 | (rdev->family != CHIP_RS880)) { | ||
125 | int ret = pci_enable_msi(rdev->pdev); | ||
126 | if (!ret) { | ||
127 | rdev->msi_enabled = 1; | ||
128 | DRM_INFO("radeon: using MSI.\n"); | ||
129 | } | ||
130 | } | ||
95 | drm_irq_install(rdev->ddev); | 131 | drm_irq_install(rdev->ddev); |
96 | rdev->irq.installed = true; | 132 | rdev->irq.installed = true; |
97 | DRM_INFO("radeon: irq initialized.\n"); | 133 | DRM_INFO("radeon: irq initialized.\n"); |
@@ -103,5 +139,33 @@ void radeon_irq_kms_fini(struct radeon_device *rdev) | |||
103 | if (rdev->irq.installed) { | 139 | if (rdev->irq.installed) { |
104 | rdev->irq.installed = false; | 140 | rdev->irq.installed = false; |
105 | drm_irq_uninstall(rdev->ddev); | 141 | drm_irq_uninstall(rdev->ddev); |
142 | if (rdev->msi_enabled) | ||
143 | pci_disable_msi(rdev->pdev); | ||
106 | } | 144 | } |
107 | } | 145 | } |
146 | |||
147 | void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev) | ||
148 | { | ||
149 | unsigned long irqflags; | ||
150 | |||
151 | spin_lock_irqsave(&rdev->irq.sw_lock, irqflags); | ||
152 | if (rdev->ddev->irq_enabled && (++rdev->irq.sw_refcount == 1)) { | ||
153 | rdev->irq.sw_int = true; | ||
154 | radeon_irq_set(rdev); | ||
155 | } | ||
156 | spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); | ||
157 | } | ||
158 | |||
159 | void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev) | ||
160 | { | ||
161 | unsigned long irqflags; | ||
162 | |||
163 | spin_lock_irqsave(&rdev->irq.sw_lock, irqflags); | ||
164 | BUG_ON(rdev->ddev->irq_enabled && rdev->irq.sw_refcount <= 0); | ||
165 | if (rdev->ddev->irq_enabled && (--rdev->irq.sw_refcount == 0)) { | ||
166 | rdev->irq.sw_int = false; | ||
167 | radeon_irq_set(rdev); | ||
168 | } | ||
169 | spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); | ||
170 | } | ||
171 | |||
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index ba128621057a..f23b05606eb5 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -30,10 +30,19 @@ | |||
30 | #include "radeon.h" | 30 | #include "radeon.h" |
31 | #include "radeon_drm.h" | 31 | #include "radeon_drm.h" |
32 | 32 | ||
33 | int radeon_driver_unload_kms(struct drm_device *dev) | ||
34 | { | ||
35 | struct radeon_device *rdev = dev->dev_private; | ||
36 | |||
37 | if (rdev == NULL) | ||
38 | return 0; | ||
39 | radeon_modeset_fini(rdev); | ||
40 | radeon_device_fini(rdev); | ||
41 | kfree(rdev); | ||
42 | dev->dev_private = NULL; | ||
43 | return 0; | ||
44 | } | ||
33 | 45 | ||
34 | /* | ||
35 | * Driver load/unload | ||
36 | */ | ||
37 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | 46 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) |
38 | { | 47 | { |
39 | struct radeon_device *rdev; | 48 | struct radeon_device *rdev; |
@@ -62,31 +71,20 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
62 | */ | 71 | */ |
63 | r = radeon_device_init(rdev, dev, dev->pdev, flags); | 72 | r = radeon_device_init(rdev, dev, dev->pdev, flags); |
64 | if (r) { | 73 | if (r) { |
65 | DRM_ERROR("Fatal error while trying to initialize radeon.\n"); | 74 | dev_err(&dev->pdev->dev, "Fatal error during GPU init\n"); |
66 | return r; | 75 | goto out; |
67 | } | 76 | } |
68 | /* Again modeset_init should fail only on fatal error | 77 | /* Again modeset_init should fail only on fatal error |
69 | * otherwise it should provide enough functionalities | 78 | * otherwise it should provide enough functionalities |
70 | * for shadowfb to run | 79 | * for shadowfb to run |
71 | */ | 80 | */ |
72 | r = radeon_modeset_init(rdev); | 81 | r = radeon_modeset_init(rdev); |
73 | if (r) { | 82 | if (r) |
74 | return r; | 83 | dev_err(&dev->pdev->dev, "Fatal error during modeset init\n"); |
75 | } | 84 | out: |
76 | return 0; | 85 | if (r) |
77 | } | 86 | radeon_driver_unload_kms(dev); |
78 | 87 | return r; | |
79 | int radeon_driver_unload_kms(struct drm_device *dev) | ||
80 | { | ||
81 | struct radeon_device *rdev = dev->dev_private; | ||
82 | |||
83 | if (rdev == NULL) | ||
84 | return 0; | ||
85 | radeon_modeset_fini(rdev); | ||
86 | radeon_device_fini(rdev); | ||
87 | kfree(rdev); | ||
88 | dev->dev_private = NULL; | ||
89 | return 0; | ||
90 | } | 88 | } |
91 | 89 | ||
92 | 90 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 36410f85d705..b82ede98e152 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -30,6 +30,18 @@ | |||
30 | #include "radeon.h" | 30 | #include "radeon.h" |
31 | #include "atom.h" | 31 | #include "atom.h" |
32 | 32 | ||
33 | static void radeon_overscan_setup(struct drm_crtc *crtc, | ||
34 | struct drm_display_mode *mode) | ||
35 | { | ||
36 | struct drm_device *dev = crtc->dev; | ||
37 | struct radeon_device *rdev = dev->dev_private; | ||
38 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
39 | |||
40 | WREG32(RADEON_OVR_CLR + radeon_crtc->crtc_offset, 0); | ||
41 | WREG32(RADEON_OVR_WID_LEFT_RIGHT + radeon_crtc->crtc_offset, 0); | ||
42 | WREG32(RADEON_OVR_WID_TOP_BOTTOM + radeon_crtc->crtc_offset, 0); | ||
43 | } | ||
44 | |||
33 | static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | 45 | static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, |
34 | struct drm_display_mode *mode, | 46 | struct drm_display_mode *mode, |
35 | struct drm_display_mode *adjusted_mode) | 47 | struct drm_display_mode *adjusted_mode) |
@@ -48,7 +60,7 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | |||
48 | u32 fp_horz_stretch, fp_vert_stretch, fp_horz_vert_active; | 60 | u32 fp_horz_stretch, fp_vert_stretch, fp_horz_vert_active; |
49 | u32 fp_h_sync_strt_wid, fp_crtc_h_total_disp; | 61 | u32 fp_h_sync_strt_wid, fp_crtc_h_total_disp; |
50 | u32 fp_v_sync_strt_wid, fp_crtc_v_total_disp; | 62 | u32 fp_v_sync_strt_wid, fp_crtc_v_total_disp; |
51 | struct radeon_native_mode *native_mode = &radeon_crtc->native_mode; | 63 | struct drm_display_mode *native_mode = &radeon_crtc->native_mode; |
52 | 64 | ||
53 | fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH) & | 65 | fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH) & |
54 | (RADEON_VERT_STRETCH_RESERVED | | 66 | (RADEON_VERT_STRETCH_RESERVED | |
@@ -95,19 +107,19 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | |||
95 | 107 | ||
96 | fp_horz_vert_active = 0; | 108 | fp_horz_vert_active = 0; |
97 | 109 | ||
98 | if (native_mode->panel_xres == 0 || | 110 | if (native_mode->hdisplay == 0 || |
99 | native_mode->panel_yres == 0) { | 111 | native_mode->vdisplay == 0) { |
100 | hscale = false; | 112 | hscale = false; |
101 | vscale = false; | 113 | vscale = false; |
102 | } else { | 114 | } else { |
103 | if (xres > native_mode->panel_xres) | 115 | if (xres > native_mode->hdisplay) |
104 | xres = native_mode->panel_xres; | 116 | xres = native_mode->hdisplay; |
105 | if (yres > native_mode->panel_yres) | 117 | if (yres > native_mode->vdisplay) |
106 | yres = native_mode->panel_yres; | 118 | yres = native_mode->vdisplay; |
107 | 119 | ||
108 | if (xres == native_mode->panel_xres) | 120 | if (xres == native_mode->hdisplay) |
109 | hscale = false; | 121 | hscale = false; |
110 | if (yres == native_mode->panel_yres) | 122 | if (yres == native_mode->vdisplay) |
111 | vscale = false; | 123 | vscale = false; |
112 | } | 124 | } |
113 | 125 | ||
@@ -119,11 +131,11 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | |||
119 | else { | 131 | else { |
120 | inc = (fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0; | 132 | inc = (fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0; |
121 | scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX) | 133 | scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX) |
122 | / native_mode->panel_xres + 1; | 134 | / native_mode->hdisplay + 1; |
123 | fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) | | 135 | fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) | |
124 | RADEON_HORZ_STRETCH_BLEND | | 136 | RADEON_HORZ_STRETCH_BLEND | |
125 | RADEON_HORZ_STRETCH_ENABLE | | 137 | RADEON_HORZ_STRETCH_ENABLE | |
126 | ((native_mode->panel_xres/8-1) << 16)); | 138 | ((native_mode->hdisplay/8-1) << 16)); |
127 | } | 139 | } |
128 | 140 | ||
129 | if (!vscale) | 141 | if (!vscale) |
@@ -131,11 +143,11 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | |||
131 | else { | 143 | else { |
132 | inc = (fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0; | 144 | inc = (fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0; |
133 | scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX) | 145 | scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX) |
134 | / native_mode->panel_yres + 1; | 146 | / native_mode->vdisplay + 1; |
135 | fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) | | 147 | fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) | |
136 | RADEON_VERT_STRETCH_ENABLE | | 148 | RADEON_VERT_STRETCH_ENABLE | |
137 | RADEON_VERT_STRETCH_BLEND | | 149 | RADEON_VERT_STRETCH_BLEND | |
138 | ((native_mode->panel_yres-1) << 12)); | 150 | ((native_mode->vdisplay-1) << 12)); |
139 | } | 151 | } |
140 | break; | 152 | break; |
141 | case RMX_CENTER: | 153 | case RMX_CENTER: |
@@ -175,8 +187,8 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | |||
175 | ? RADEON_CRTC_V_SYNC_POL | 187 | ? RADEON_CRTC_V_SYNC_POL |
176 | : 0))); | 188 | : 0))); |
177 | 189 | ||
178 | fp_horz_vert_active = (((native_mode->panel_yres) & 0xfff) | | 190 | fp_horz_vert_active = (((native_mode->vdisplay) & 0xfff) | |
179 | (((native_mode->panel_xres / 8) & 0x1ff) << 16)); | 191 | (((native_mode->hdisplay / 8) & 0x1ff) << 16)); |
180 | break; | 192 | break; |
181 | case RMX_OFF: | 193 | case RMX_OFF: |
182 | default: | 194 | default: |
@@ -292,8 +304,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
292 | uint32_t mask; | 304 | uint32_t mask; |
293 | 305 | ||
294 | if (radeon_crtc->crtc_id) | 306 | if (radeon_crtc->crtc_id) |
295 | mask = (RADEON_CRTC2_EN | | 307 | mask = (RADEON_CRTC2_DISP_DIS | |
296 | RADEON_CRTC2_DISP_DIS | | ||
297 | RADEON_CRTC2_VSYNC_DIS | | 308 | RADEON_CRTC2_VSYNC_DIS | |
298 | RADEON_CRTC2_HSYNC_DIS | | 309 | RADEON_CRTC2_HSYNC_DIS | |
299 | RADEON_CRTC2_DISP_REQ_EN_B); | 310 | RADEON_CRTC2_DISP_REQ_EN_B); |
@@ -305,7 +316,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
305 | switch (mode) { | 316 | switch (mode) { |
306 | case DRM_MODE_DPMS_ON: | 317 | case DRM_MODE_DPMS_ON: |
307 | if (radeon_crtc->crtc_id) | 318 | if (radeon_crtc->crtc_id) |
308 | WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~mask); | 319 | WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask)); |
309 | else { | 320 | else { |
310 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | | 321 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | |
311 | RADEON_CRTC_DISP_REQ_EN_B)); | 322 | RADEON_CRTC_DISP_REQ_EN_B)); |
@@ -319,7 +330,7 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
319 | case DRM_MODE_DPMS_OFF: | 330 | case DRM_MODE_DPMS_OFF: |
320 | drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); | 331 | drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); |
321 | if (radeon_crtc->crtc_id) | 332 | if (radeon_crtc->crtc_id) |
322 | WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask); | 333 | WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask)); |
323 | else { | 334 | else { |
324 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | | 335 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | |
325 | RADEON_CRTC_DISP_REQ_EN_B)); | 336 | RADEON_CRTC_DISP_REQ_EN_B)); |
@@ -400,14 +411,21 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
400 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 411 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
401 | struct radeon_framebuffer *radeon_fb; | 412 | struct radeon_framebuffer *radeon_fb; |
402 | struct drm_gem_object *obj; | 413 | struct drm_gem_object *obj; |
414 | struct radeon_bo *rbo; | ||
403 | uint64_t base; | 415 | uint64_t base; |
404 | uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0; | 416 | uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0; |
405 | uint32_t crtc_pitch, pitch_pixels; | 417 | uint32_t crtc_pitch, pitch_pixels; |
406 | uint32_t tiling_flags; | 418 | uint32_t tiling_flags; |
407 | int format; | 419 | int format; |
408 | uint32_t gen_cntl_reg, gen_cntl_val; | 420 | uint32_t gen_cntl_reg, gen_cntl_val; |
421 | int r; | ||
409 | 422 | ||
410 | DRM_DEBUG("\n"); | 423 | DRM_DEBUG("\n"); |
424 | /* no fb bound */ | ||
425 | if (!crtc->fb) { | ||
426 | DRM_DEBUG("No FB bound\n"); | ||
427 | return 0; | ||
428 | } | ||
411 | 429 | ||
412 | radeon_fb = to_radeon_framebuffer(crtc->fb); | 430 | radeon_fb = to_radeon_framebuffer(crtc->fb); |
413 | 431 | ||
@@ -431,10 +449,22 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
431 | return false; | 449 | return false; |
432 | } | 450 | } |
433 | 451 | ||
452 | /* Pin framebuffer & get tilling informations */ | ||
434 | obj = radeon_fb->obj; | 453 | obj = radeon_fb->obj; |
435 | if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &base)) { | 454 | rbo = obj->driver_private; |
455 | r = radeon_bo_reserve(rbo, false); | ||
456 | if (unlikely(r != 0)) | ||
457 | return r; | ||
458 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &base); | ||
459 | if (unlikely(r != 0)) { | ||
460 | radeon_bo_unreserve(rbo); | ||
436 | return -EINVAL; | 461 | return -EINVAL; |
437 | } | 462 | } |
463 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); | ||
464 | radeon_bo_unreserve(rbo); | ||
465 | if (tiling_flags & RADEON_TILING_MICRO) | ||
466 | DRM_ERROR("trying to scanout microtiled buffer\n"); | ||
467 | |||
438 | /* if scanout was in GTT this really wouldn't work */ | 468 | /* if scanout was in GTT this really wouldn't work */ |
439 | /* crtc offset is from display base addr not FB location */ | 469 | /* crtc offset is from display base addr not FB location */ |
440 | radeon_crtc->legacy_display_base_addr = rdev->mc.vram_location; | 470 | radeon_crtc->legacy_display_base_addr = rdev->mc.vram_location; |
@@ -449,10 +479,6 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
449 | (crtc->fb->bits_per_pixel * 8)); | 479 | (crtc->fb->bits_per_pixel * 8)); |
450 | crtc_pitch |= crtc_pitch << 16; | 480 | crtc_pitch |= crtc_pitch << 16; |
451 | 481 | ||
452 | radeon_object_get_tiling_flags(obj->driver_private, | ||
453 | &tiling_flags, NULL); | ||
454 | if (tiling_flags & RADEON_TILING_MICRO) | ||
455 | DRM_ERROR("trying to scanout microtiled buffer\n"); | ||
456 | 482 | ||
457 | if (tiling_flags & RADEON_TILING_MACRO) { | 483 | if (tiling_flags & RADEON_TILING_MACRO) { |
458 | if (ASIC_IS_R300(rdev)) | 484 | if (ASIC_IS_R300(rdev)) |
@@ -530,8 +556,17 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
530 | 556 | ||
531 | if (old_fb && old_fb != crtc->fb) { | 557 | if (old_fb && old_fb != crtc->fb) { |
532 | radeon_fb = to_radeon_framebuffer(old_fb); | 558 | radeon_fb = to_radeon_framebuffer(old_fb); |
533 | radeon_gem_object_unpin(radeon_fb->obj); | 559 | rbo = radeon_fb->obj->driver_private; |
560 | r = radeon_bo_reserve(rbo, false); | ||
561 | if (unlikely(r != 0)) | ||
562 | return r; | ||
563 | radeon_bo_unpin(rbo); | ||
564 | radeon_bo_unreserve(rbo); | ||
534 | } | 565 | } |
566 | |||
567 | /* Bytes per pixel may have changed */ | ||
568 | radeon_bandwidth_update(rdev); | ||
569 | |||
535 | return 0; | 570 | return 0; |
536 | } | 571 | } |
537 | 572 | ||
@@ -638,12 +673,8 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod | |||
638 | uint32_t crtc2_gen_cntl; | 673 | uint32_t crtc2_gen_cntl; |
639 | uint32_t disp2_merge_cntl; | 674 | uint32_t disp2_merge_cntl; |
640 | 675 | ||
641 | /* check to see if TV DAC is enabled for another crtc and keep it enabled */ | 676 | /* if TV DAC is enabled for another crtc and keep it enabled */ |
642 | if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_CRT2_ON) | 677 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL) & 0x00718080; |
643 | crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON; | ||
644 | else | ||
645 | crtc2_gen_cntl = 0; | ||
646 | |||
647 | crtc2_gen_cntl |= ((format << 8) | 678 | crtc2_gen_cntl |= ((format << 8) |
648 | | RADEON_CRTC2_VSYNC_DIS | 679 | | RADEON_CRTC2_VSYNC_DIS |
649 | | RADEON_CRTC2_HSYNC_DIS | 680 | | RADEON_CRTC2_HSYNC_DIS |
@@ -664,12 +695,16 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod | |||
664 | 695 | ||
665 | WREG32(RADEON_DISP2_MERGE_CNTL, disp2_merge_cntl); | 696 | WREG32(RADEON_DISP2_MERGE_CNTL, disp2_merge_cntl); |
666 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | 697 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); |
698 | |||
699 | WREG32(RADEON_FP_H2_SYNC_STRT_WID, crtc_h_sync_strt_wid); | ||
700 | WREG32(RADEON_FP_V2_SYNC_STRT_WID, crtc_v_sync_strt_wid); | ||
667 | } else { | 701 | } else { |
668 | uint32_t crtc_gen_cntl; | 702 | uint32_t crtc_gen_cntl; |
669 | uint32_t crtc_ext_cntl; | 703 | uint32_t crtc_ext_cntl; |
670 | uint32_t disp_merge_cntl; | 704 | uint32_t disp_merge_cntl; |
671 | 705 | ||
672 | crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN | 706 | crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL) & 0x00718000; |
707 | crtc_gen_cntl |= (RADEON_CRTC_EXT_DISP_EN | ||
673 | | (format << 8) | 708 | | (format << 8) |
674 | | RADEON_CRTC_DISP_REQ_EN_B | 709 | | RADEON_CRTC_DISP_REQ_EN_B |
675 | | ((mode->flags & DRM_MODE_FLAG_DBLSCAN) | 710 | | ((mode->flags & DRM_MODE_FLAG_DBLSCAN) |
@@ -772,15 +807,17 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
772 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | 807 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
773 | pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; | 808 | pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; |
774 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { | 809 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { |
775 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 810 | if (!rdev->is_atom_bios) { |
776 | struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; | 811 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
777 | if (lvds) { | 812 | struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; |
778 | if (lvds->use_bios_dividers) { | 813 | if (lvds) { |
779 | pll_ref_div = lvds->panel_ref_divider; | 814 | if (lvds->use_bios_dividers) { |
780 | pll_fb_post_div = (lvds->panel_fb_divider | | 815 | pll_ref_div = lvds->panel_ref_divider; |
781 | (lvds->panel_post_divider << 16)); | 816 | pll_fb_post_div = (lvds->panel_fb_divider | |
782 | htotal_cntl = 0; | 817 | (lvds->panel_post_divider << 16)); |
783 | use_bios_divs = true; | 818 | htotal_cntl = 0; |
819 | use_bios_divs = true; | ||
820 | } | ||
784 | } | 821 | } |
785 | } | 822 | } |
786 | pll_flags |= RADEON_PLL_USE_REF_DIV; | 823 | pll_flags |= RADEON_PLL_USE_REF_DIV; |
@@ -1015,14 +1052,12 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, | |||
1015 | int x, int y, struct drm_framebuffer *old_fb) | 1052 | int x, int y, struct drm_framebuffer *old_fb) |
1016 | { | 1053 | { |
1017 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1054 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1018 | struct drm_device *dev = crtc->dev; | ||
1019 | struct radeon_device *rdev = dev->dev_private; | ||
1020 | 1055 | ||
1021 | /* TODO TV */ | 1056 | /* TODO TV */ |
1022 | radeon_crtc_set_base(crtc, x, y, old_fb); | 1057 | radeon_crtc_set_base(crtc, x, y, old_fb); |
1023 | radeon_set_crtc_timing(crtc, adjusted_mode); | 1058 | radeon_set_crtc_timing(crtc, adjusted_mode); |
1024 | radeon_set_pll(crtc, adjusted_mode); | 1059 | radeon_set_pll(crtc, adjusted_mode); |
1025 | radeon_bandwidth_update(rdev); | 1060 | radeon_overscan_setup(crtc, adjusted_mode); |
1026 | if (radeon_crtc->crtc_id == 0) { | 1061 | if (radeon_crtc->crtc_id == 0) { |
1027 | radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode); | 1062 | radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode); |
1028 | } else { | 1063 | } else { |
@@ -1038,12 +1073,29 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, | |||
1038 | 1073 | ||
1039 | static void radeon_crtc_prepare(struct drm_crtc *crtc) | 1074 | static void radeon_crtc_prepare(struct drm_crtc *crtc) |
1040 | { | 1075 | { |
1041 | radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 1076 | struct drm_device *dev = crtc->dev; |
1077 | struct drm_crtc *crtci; | ||
1078 | |||
1079 | /* | ||
1080 | * The hardware wedges sometimes if you reconfigure one CRTC | ||
1081 | * whilst another is running (see fdo bug #24611). | ||
1082 | */ | ||
1083 | list_for_each_entry(crtci, &dev->mode_config.crtc_list, head) | ||
1084 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_OFF); | ||
1042 | } | 1085 | } |
1043 | 1086 | ||
1044 | static void radeon_crtc_commit(struct drm_crtc *crtc) | 1087 | static void radeon_crtc_commit(struct drm_crtc *crtc) |
1045 | { | 1088 | { |
1046 | radeon_crtc_dpms(crtc, DRM_MODE_DPMS_ON); | 1089 | struct drm_device *dev = crtc->dev; |
1090 | struct drm_crtc *crtci; | ||
1091 | |||
1092 | /* | ||
1093 | * Reenable the CRTCs that should be running. | ||
1094 | */ | ||
1095 | list_for_each_entry(crtci, &dev->mode_config.crtc_list, head) { | ||
1096 | if (crtci->enabled) | ||
1097 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); | ||
1098 | } | ||
1047 | } | 1099 | } |
1048 | 1100 | ||
1049 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { | 1101 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 6ceb958fd194..df00515e81fa 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -107,8 +107,6 @@ static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder) | |||
107 | else | 107 | else |
108 | radeon_combios_output_lock(encoder, true); | 108 | radeon_combios_output_lock(encoder, true); |
109 | radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); | 109 | radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); |
110 | |||
111 | radeon_encoder_set_active_device(encoder); | ||
112 | } | 110 | } |
113 | 111 | ||
114 | static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) | 112 | static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) |
@@ -138,7 +136,14 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, | |||
138 | lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN; | 136 | lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN; |
139 | 137 | ||
140 | lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL); | 138 | lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL); |
141 | if ((!rdev->is_atom_bios)) { | 139 | if (rdev->is_atom_bios) { |
140 | /* LVDS_GEN_CNTL parameters are computed in LVDSEncoderControl | ||
141 | * need to call that on resume to set up the reg properly. | ||
142 | */ | ||
143 | radeon_encoder->pixel_clock = adjusted_mode->clock; | ||
144 | atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE); | ||
145 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); | ||
146 | } else { | ||
142 | struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; | 147 | struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; |
143 | if (lvds) { | 148 | if (lvds) { |
144 | DRM_DEBUG("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl); | 149 | DRM_DEBUG("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl); |
@@ -149,8 +154,7 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, | |||
149 | (lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT)); | 154 | (lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT)); |
150 | } else | 155 | } else |
151 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); | 156 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); |
152 | } else | 157 | } |
153 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); | ||
154 | lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; | 158 | lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; |
155 | lvds_gen_cntl &= ~(RADEON_LVDS_ON | | 159 | lvds_gen_cntl &= ~(RADEON_LVDS_ON | |
156 | RADEON_LVDS_BLON | | 160 | RADEON_LVDS_BLON | |
@@ -186,23 +190,32 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, | |||
186 | radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | 190 | radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); |
187 | } | 191 | } |
188 | 192 | ||
189 | static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder, | 193 | static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder, |
190 | struct drm_display_mode *mode, | 194 | struct drm_display_mode *mode, |
191 | struct drm_display_mode *adjusted_mode) | 195 | struct drm_display_mode *adjusted_mode) |
192 | { | 196 | { |
193 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 197 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
194 | 198 | ||
199 | /* set the active encoder to connector routing */ | ||
200 | radeon_encoder_set_active_device(encoder); | ||
195 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 201 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
196 | 202 | ||
197 | if (radeon_encoder->rmx_type != RMX_OFF) | 203 | /* get the native mode for LVDS */ |
198 | radeon_rmx_mode_fixup(encoder, mode, adjusted_mode); | 204 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { |
205 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; | ||
206 | int mode_id = adjusted_mode->base.id; | ||
207 | *adjusted_mode = *native_mode; | ||
208 | adjusted_mode->hdisplay = mode->hdisplay; | ||
209 | adjusted_mode->vdisplay = mode->vdisplay; | ||
210 | adjusted_mode->base.id = mode_id; | ||
211 | } | ||
199 | 212 | ||
200 | return true; | 213 | return true; |
201 | } | 214 | } |
202 | 215 | ||
203 | static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { | 216 | static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { |
204 | .dpms = radeon_legacy_lvds_dpms, | 217 | .dpms = radeon_legacy_lvds_dpms, |
205 | .mode_fixup = radeon_legacy_lvds_mode_fixup, | 218 | .mode_fixup = radeon_legacy_mode_fixup, |
206 | .prepare = radeon_legacy_lvds_prepare, | 219 | .prepare = radeon_legacy_lvds_prepare, |
207 | .mode_set = radeon_legacy_lvds_mode_set, | 220 | .mode_set = radeon_legacy_lvds_mode_set, |
208 | .commit = radeon_legacy_lvds_commit, | 221 | .commit = radeon_legacy_lvds_commit, |
@@ -214,16 +227,6 @@ static const struct drm_encoder_funcs radeon_legacy_lvds_enc_funcs = { | |||
214 | .destroy = radeon_enc_destroy, | 227 | .destroy = radeon_enc_destroy, |
215 | }; | 228 | }; |
216 | 229 | ||
217 | static bool radeon_legacy_primary_dac_mode_fixup(struct drm_encoder *encoder, | ||
218 | struct drm_display_mode *mode, | ||
219 | struct drm_display_mode *adjusted_mode) | ||
220 | { | ||
221 | |||
222 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
223 | |||
224 | return true; | ||
225 | } | ||
226 | |||
227 | static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode) | 230 | static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode) |
228 | { | 231 | { |
229 | struct drm_device *dev = encoder->dev; | 232 | struct drm_device *dev = encoder->dev; |
@@ -272,7 +275,6 @@ static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder) | |||
272 | else | 275 | else |
273 | radeon_combios_output_lock(encoder, true); | 276 | radeon_combios_output_lock(encoder, true); |
274 | radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); | 277 | radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); |
275 | radeon_encoder_set_active_device(encoder); | ||
276 | } | 278 | } |
277 | 279 | ||
278 | static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) | 280 | static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) |
@@ -410,7 +412,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc | |||
410 | 412 | ||
411 | static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = { | 413 | static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = { |
412 | .dpms = radeon_legacy_primary_dac_dpms, | 414 | .dpms = radeon_legacy_primary_dac_dpms, |
413 | .mode_fixup = radeon_legacy_primary_dac_mode_fixup, | 415 | .mode_fixup = radeon_legacy_mode_fixup, |
414 | .prepare = radeon_legacy_primary_dac_prepare, | 416 | .prepare = radeon_legacy_primary_dac_prepare, |
415 | .mode_set = radeon_legacy_primary_dac_mode_set, | 417 | .mode_set = radeon_legacy_primary_dac_mode_set, |
416 | .commit = radeon_legacy_primary_dac_commit, | 418 | .commit = radeon_legacy_primary_dac_commit, |
@@ -423,16 +425,6 @@ static const struct drm_encoder_funcs radeon_legacy_primary_dac_enc_funcs = { | |||
423 | .destroy = radeon_enc_destroy, | 425 | .destroy = radeon_enc_destroy, |
424 | }; | 426 | }; |
425 | 427 | ||
426 | static bool radeon_legacy_tmds_int_mode_fixup(struct drm_encoder *encoder, | ||
427 | struct drm_display_mode *mode, | ||
428 | struct drm_display_mode *adjusted_mode) | ||
429 | { | ||
430 | |||
431 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
432 | |||
433 | return true; | ||
434 | } | ||
435 | |||
436 | static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) | 428 | static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) |
437 | { | 429 | { |
438 | struct drm_device *dev = encoder->dev; | 430 | struct drm_device *dev = encoder->dev; |
@@ -468,7 +460,6 @@ static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder) | |||
468 | else | 460 | else |
469 | radeon_combios_output_lock(encoder, true); | 461 | radeon_combios_output_lock(encoder, true); |
470 | radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); | 462 | radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); |
471 | radeon_encoder_set_active_device(encoder); | ||
472 | } | 463 | } |
473 | 464 | ||
474 | static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) | 465 | static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) |
@@ -543,6 +534,14 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, | |||
543 | 534 | ||
544 | fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); | 535 | fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); |
545 | 536 | ||
537 | fp_gen_cntl &= ~(RADEON_FP_RMX_HVSYNC_CONTROL_EN | | ||
538 | RADEON_FP_DFP_SYNC_SEL | | ||
539 | RADEON_FP_CRT_SYNC_SEL | | ||
540 | RADEON_FP_CRTC_LOCK_8DOT | | ||
541 | RADEON_FP_USE_SHADOW_EN | | ||
542 | RADEON_FP_CRTC_USE_SHADOW_VEND | | ||
543 | RADEON_FP_CRT_SYNC_ALT); | ||
544 | |||
546 | if (1) /* FIXME rgbBits == 8 */ | 545 | if (1) /* FIXME rgbBits == 8 */ |
547 | fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */ | 546 | fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */ |
548 | else | 547 | else |
@@ -556,7 +555,7 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, | |||
556 | else | 555 | else |
557 | fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1; | 556 | fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1; |
558 | } else | 557 | } else |
559 | fp_gen_cntl |= RADEON_FP_SEL_CRTC1; | 558 | fp_gen_cntl &= ~RADEON_FP_SEL_CRTC2; |
560 | } else { | 559 | } else { |
561 | if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) { | 560 | if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) { |
562 | fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; | 561 | fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; |
@@ -577,7 +576,7 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, | |||
577 | 576 | ||
578 | static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = { | 577 | static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = { |
579 | .dpms = radeon_legacy_tmds_int_dpms, | 578 | .dpms = radeon_legacy_tmds_int_dpms, |
580 | .mode_fixup = radeon_legacy_tmds_int_mode_fixup, | 579 | .mode_fixup = radeon_legacy_mode_fixup, |
581 | .prepare = radeon_legacy_tmds_int_prepare, | 580 | .prepare = radeon_legacy_tmds_int_prepare, |
582 | .mode_set = radeon_legacy_tmds_int_mode_set, | 581 | .mode_set = radeon_legacy_tmds_int_mode_set, |
583 | .commit = radeon_legacy_tmds_int_commit, | 582 | .commit = radeon_legacy_tmds_int_commit, |
@@ -589,16 +588,6 @@ static const struct drm_encoder_funcs radeon_legacy_tmds_int_enc_funcs = { | |||
589 | .destroy = radeon_enc_destroy, | 588 | .destroy = radeon_enc_destroy, |
590 | }; | 589 | }; |
591 | 590 | ||
592 | static bool radeon_legacy_tmds_ext_mode_fixup(struct drm_encoder *encoder, | ||
593 | struct drm_display_mode *mode, | ||
594 | struct drm_display_mode *adjusted_mode) | ||
595 | { | ||
596 | |||
597 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
598 | |||
599 | return true; | ||
600 | } | ||
601 | |||
602 | static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) | 591 | static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) |
603 | { | 592 | { |
604 | struct drm_device *dev = encoder->dev; | 593 | struct drm_device *dev = encoder->dev; |
@@ -636,7 +625,6 @@ static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder) | |||
636 | else | 625 | else |
637 | radeon_combios_output_lock(encoder, true); | 626 | radeon_combios_output_lock(encoder, true); |
638 | radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); | 627 | radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); |
639 | radeon_encoder_set_active_device(encoder); | ||
640 | } | 628 | } |
641 | 629 | ||
642 | static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) | 630 | static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) |
@@ -690,6 +678,8 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, | |||
690 | /*if (mode->clock > 165000) | 678 | /*if (mode->clock > 165000) |
691 | fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/ | 679 | fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/ |
692 | } | 680 | } |
681 | if (!radeon_combios_external_tmds_setup(encoder)) | ||
682 | radeon_external_tmds_setup(encoder); | ||
693 | } | 683 | } |
694 | 684 | ||
695 | if (radeon_crtc->crtc_id == 0) { | 685 | if (radeon_crtc->crtc_id == 0) { |
@@ -717,9 +707,22 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, | |||
717 | radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | 707 | radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); |
718 | } | 708 | } |
719 | 709 | ||
710 | static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder) | ||
711 | { | ||
712 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
713 | struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; | ||
714 | if (tmds) { | ||
715 | if (tmds->i2c_bus) | ||
716 | radeon_i2c_destroy(tmds->i2c_bus); | ||
717 | } | ||
718 | kfree(radeon_encoder->enc_priv); | ||
719 | drm_encoder_cleanup(encoder); | ||
720 | kfree(radeon_encoder); | ||
721 | } | ||
722 | |||
720 | static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = { | 723 | static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = { |
721 | .dpms = radeon_legacy_tmds_ext_dpms, | 724 | .dpms = radeon_legacy_tmds_ext_dpms, |
722 | .mode_fixup = radeon_legacy_tmds_ext_mode_fixup, | 725 | .mode_fixup = radeon_legacy_mode_fixup, |
723 | .prepare = radeon_legacy_tmds_ext_prepare, | 726 | .prepare = radeon_legacy_tmds_ext_prepare, |
724 | .mode_set = radeon_legacy_tmds_ext_mode_set, | 727 | .mode_set = radeon_legacy_tmds_ext_mode_set, |
725 | .commit = radeon_legacy_tmds_ext_commit, | 728 | .commit = radeon_legacy_tmds_ext_commit, |
@@ -728,19 +731,9 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs | |||
728 | 731 | ||
729 | 732 | ||
730 | static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = { | 733 | static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = { |
731 | .destroy = radeon_enc_destroy, | 734 | .destroy = radeon_ext_tmds_enc_destroy, |
732 | }; | 735 | }; |
733 | 736 | ||
734 | static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder, | ||
735 | struct drm_display_mode *mode, | ||
736 | struct drm_display_mode *adjusted_mode) | ||
737 | { | ||
738 | |||
739 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
740 | |||
741 | return true; | ||
742 | } | ||
743 | |||
744 | static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) | 737 | static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) |
745 | { | 738 | { |
746 | struct drm_device *dev = encoder->dev; | 739 | struct drm_device *dev = encoder->dev; |
@@ -839,7 +832,6 @@ static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder) | |||
839 | else | 832 | else |
840 | radeon_combios_output_lock(encoder, true); | 833 | radeon_combios_output_lock(encoder, true); |
841 | radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); | 834 | radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); |
842 | radeon_encoder_set_active_device(encoder); | ||
843 | } | 835 | } |
844 | 836 | ||
845 | static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) | 837 | static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) |
@@ -1258,7 +1250,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
1258 | 1250 | ||
1259 | static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = { | 1251 | static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = { |
1260 | .dpms = radeon_legacy_tv_dac_dpms, | 1252 | .dpms = radeon_legacy_tv_dac_dpms, |
1261 | .mode_fixup = radeon_legacy_tv_dac_mode_fixup, | 1253 | .mode_fixup = radeon_legacy_mode_fixup, |
1262 | .prepare = radeon_legacy_tv_dac_prepare, | 1254 | .prepare = radeon_legacy_tv_dac_prepare, |
1263 | .mode_set = radeon_legacy_tv_dac_mode_set, | 1255 | .mode_set = radeon_legacy_tv_dac_mode_set, |
1264 | .commit = radeon_legacy_tv_dac_commit, | 1256 | .commit = radeon_legacy_tv_dac_commit, |
@@ -1295,6 +1287,29 @@ static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon | |||
1295 | return tmds; | 1287 | return tmds; |
1296 | } | 1288 | } |
1297 | 1289 | ||
1290 | static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct radeon_encoder *encoder) | ||
1291 | { | ||
1292 | struct drm_device *dev = encoder->base.dev; | ||
1293 | struct radeon_device *rdev = dev->dev_private; | ||
1294 | struct radeon_encoder_ext_tmds *tmds = NULL; | ||
1295 | bool ret; | ||
1296 | |||
1297 | if (rdev->is_atom_bios) | ||
1298 | return NULL; | ||
1299 | |||
1300 | tmds = kzalloc(sizeof(struct radeon_encoder_ext_tmds), GFP_KERNEL); | ||
1301 | |||
1302 | if (!tmds) | ||
1303 | return NULL; | ||
1304 | |||
1305 | ret = radeon_legacy_get_ext_tmds_info_from_combios(encoder, tmds); | ||
1306 | |||
1307 | if (ret == false) | ||
1308 | radeon_legacy_get_ext_tmds_info_from_table(encoder, tmds); | ||
1309 | |||
1310 | return tmds; | ||
1311 | } | ||
1312 | |||
1298 | void | 1313 | void |
1299 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) | 1314 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) |
1300 | { | 1315 | { |
@@ -1322,7 +1337,6 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t | |||
1322 | encoder->possible_crtcs = 0x1; | 1337 | encoder->possible_crtcs = 0x1; |
1323 | else | 1338 | else |
1324 | encoder->possible_crtcs = 0x3; | 1339 | encoder->possible_crtcs = 0x3; |
1325 | encoder->possible_clones = 0; | ||
1326 | 1340 | ||
1327 | radeon_encoder->enc_priv = NULL; | 1341 | radeon_encoder->enc_priv = NULL; |
1328 | 1342 | ||
@@ -1366,7 +1380,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t | |||
1366 | drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS); | 1380 | drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS); |
1367 | drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs); | 1381 | drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs); |
1368 | if (!rdev->is_atom_bios) | 1382 | if (!rdev->is_atom_bios) |
1369 | radeon_combios_get_ext_tmds_info(radeon_encoder); | 1383 | radeon_encoder->enc_priv = radeon_legacy_get_ext_tmds_info(radeon_encoder); |
1370 | break; | 1384 | break; |
1371 | } | 1385 | } |
1372 | } | 1386 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index e61226817ccf..44d4b652ea12 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <drm_crtc.h> | 33 | #include <drm_crtc.h> |
34 | #include <drm_mode.h> | 34 | #include <drm_mode.h> |
35 | #include <drm_edid.h> | 35 | #include <drm_edid.h> |
36 | #include <drm_dp_helper.h> | ||
36 | #include <linux/i2c.h> | 37 | #include <linux/i2c.h> |
37 | #include <linux/i2c-id.h> | 38 | #include <linux/i2c-id.h> |
38 | #include <linux/i2c-algo-bit.h> | 39 | #include <linux/i2c-algo-bit.h> |
@@ -89,24 +90,45 @@ enum radeon_tv_std { | |||
89 | TV_STD_PAL_CN, | 90 | TV_STD_PAL_CN, |
90 | }; | 91 | }; |
91 | 92 | ||
93 | /* radeon gpio-based i2c | ||
94 | * 1. "mask" reg and bits | ||
95 | * grabs the gpio pins for software use | ||
96 | * 0=not held 1=held | ||
97 | * 2. "a" reg and bits | ||
98 | * output pin value | ||
99 | * 0=low 1=high | ||
100 | * 3. "en" reg and bits | ||
101 | * sets the pin direction | ||
102 | * 0=input 1=output | ||
103 | * 4. "y" reg and bits | ||
104 | * input pin value | ||
105 | * 0=low 1=high | ||
106 | */ | ||
92 | struct radeon_i2c_bus_rec { | 107 | struct radeon_i2c_bus_rec { |
93 | bool valid; | 108 | bool valid; |
109 | /* id used by atom */ | ||
110 | uint8_t i2c_id; | ||
111 | /* can be used with hw i2c engine */ | ||
112 | bool hw_capable; | ||
113 | /* uses multi-media i2c engine */ | ||
114 | bool mm_i2c; | ||
115 | /* regs and bits */ | ||
94 | uint32_t mask_clk_reg; | 116 | uint32_t mask_clk_reg; |
95 | uint32_t mask_data_reg; | 117 | uint32_t mask_data_reg; |
96 | uint32_t a_clk_reg; | 118 | uint32_t a_clk_reg; |
97 | uint32_t a_data_reg; | 119 | uint32_t a_data_reg; |
98 | uint32_t put_clk_reg; | 120 | uint32_t en_clk_reg; |
99 | uint32_t put_data_reg; | 121 | uint32_t en_data_reg; |
100 | uint32_t get_clk_reg; | 122 | uint32_t y_clk_reg; |
101 | uint32_t get_data_reg; | 123 | uint32_t y_data_reg; |
102 | uint32_t mask_clk_mask; | 124 | uint32_t mask_clk_mask; |
103 | uint32_t mask_data_mask; | 125 | uint32_t mask_data_mask; |
104 | uint32_t put_clk_mask; | ||
105 | uint32_t put_data_mask; | ||
106 | uint32_t get_clk_mask; | ||
107 | uint32_t get_data_mask; | ||
108 | uint32_t a_clk_mask; | 126 | uint32_t a_clk_mask; |
109 | uint32_t a_data_mask; | 127 | uint32_t a_data_mask; |
128 | uint32_t en_clk_mask; | ||
129 | uint32_t en_data_mask; | ||
130 | uint32_t y_clk_mask; | ||
131 | uint32_t y_data_mask; | ||
110 | }; | 132 | }; |
111 | 133 | ||
112 | struct radeon_tmds_pll { | 134 | struct radeon_tmds_pll { |
@@ -150,9 +172,12 @@ struct radeon_pll { | |||
150 | }; | 172 | }; |
151 | 173 | ||
152 | struct radeon_i2c_chan { | 174 | struct radeon_i2c_chan { |
153 | struct drm_device *dev; | ||
154 | struct i2c_adapter adapter; | 175 | struct i2c_adapter adapter; |
155 | struct i2c_algo_bit_data algo; | 176 | struct drm_device *dev; |
177 | union { | ||
178 | struct i2c_algo_dp_aux_data dp; | ||
179 | struct i2c_algo_bit_data bit; | ||
180 | } algo; | ||
156 | struct radeon_i2c_bus_rec rec; | 181 | struct radeon_i2c_bus_rec rec; |
157 | }; | 182 | }; |
158 | 183 | ||
@@ -170,8 +195,14 @@ enum radeon_connector_table { | |||
170 | CT_EMAC, | 195 | CT_EMAC, |
171 | }; | 196 | }; |
172 | 197 | ||
198 | enum radeon_dvo_chip { | ||
199 | DVO_SIL164, | ||
200 | DVO_SIL1178, | ||
201 | }; | ||
202 | |||
173 | struct radeon_mode_info { | 203 | struct radeon_mode_info { |
174 | struct atom_context *atom_context; | 204 | struct atom_context *atom_context; |
205 | struct card_info *atom_card_info; | ||
175 | enum radeon_connector_table connector_table; | 206 | enum radeon_connector_table connector_table; |
176 | bool mode_config_initialized; | 207 | bool mode_config_initialized; |
177 | struct radeon_crtc *crtcs[2]; | 208 | struct radeon_crtc *crtcs[2]; |
@@ -186,17 +217,6 @@ struct radeon_mode_info { | |||
186 | 217 | ||
187 | }; | 218 | }; |
188 | 219 | ||
189 | struct radeon_native_mode { | ||
190 | /* preferred mode */ | ||
191 | uint32_t panel_xres, panel_yres; | ||
192 | uint32_t hoverplus, hsync_width; | ||
193 | uint32_t hblank; | ||
194 | uint32_t voverplus, vsync_width; | ||
195 | uint32_t vblank; | ||
196 | uint32_t dotclock; | ||
197 | uint32_t flags; | ||
198 | }; | ||
199 | |||
200 | #define MAX_H_CODE_TIMING_LEN 32 | 220 | #define MAX_H_CODE_TIMING_LEN 32 |
201 | #define MAX_V_CODE_TIMING_LEN 32 | 221 | #define MAX_V_CODE_TIMING_LEN 32 |
202 | 222 | ||
@@ -228,7 +248,7 @@ struct radeon_crtc { | |||
228 | enum radeon_rmx_type rmx_type; | 248 | enum radeon_rmx_type rmx_type; |
229 | fixed20_12 vsc; | 249 | fixed20_12 vsc; |
230 | fixed20_12 hsc; | 250 | fixed20_12 hsc; |
231 | struct radeon_native_mode native_mode; | 251 | struct drm_display_mode native_mode; |
232 | }; | 252 | }; |
233 | 253 | ||
234 | struct radeon_encoder_primary_dac { | 254 | struct radeon_encoder_primary_dac { |
@@ -248,7 +268,7 @@ struct radeon_encoder_lvds { | |||
248 | bool use_bios_dividers; | 268 | bool use_bios_dividers; |
249 | uint32_t lvds_gen_cntl; | 269 | uint32_t lvds_gen_cntl; |
250 | /* panel mode */ | 270 | /* panel mode */ |
251 | struct radeon_native_mode native_mode; | 271 | struct drm_display_mode native_mode; |
252 | }; | 272 | }; |
253 | 273 | ||
254 | struct radeon_encoder_tv_dac { | 274 | struct radeon_encoder_tv_dac { |
@@ -271,6 +291,23 @@ struct radeon_encoder_int_tmds { | |||
271 | struct radeon_tmds_pll tmds_pll[4]; | 291 | struct radeon_tmds_pll tmds_pll[4]; |
272 | }; | 292 | }; |
273 | 293 | ||
294 | struct radeon_encoder_ext_tmds { | ||
295 | /* tmds over dvo */ | ||
296 | struct radeon_i2c_chan *i2c_bus; | ||
297 | uint8_t slave_addr; | ||
298 | enum radeon_dvo_chip dvo_chip; | ||
299 | }; | ||
300 | |||
301 | /* spread spectrum */ | ||
302 | struct radeon_atom_ss { | ||
303 | uint16_t percentage; | ||
304 | uint8_t type; | ||
305 | uint8_t step; | ||
306 | uint8_t delay; | ||
307 | uint8_t range; | ||
308 | uint8_t refdiv; | ||
309 | }; | ||
310 | |||
274 | struct radeon_encoder_atom_dig { | 311 | struct radeon_encoder_atom_dig { |
275 | /* atom dig */ | 312 | /* atom dig */ |
276 | bool coherent_mode; | 313 | bool coherent_mode; |
@@ -278,8 +315,9 @@ struct radeon_encoder_atom_dig { | |||
278 | /* atom lvds */ | 315 | /* atom lvds */ |
279 | uint32_t lvds_misc; | 316 | uint32_t lvds_misc; |
280 | uint16_t panel_pwr_delay; | 317 | uint16_t panel_pwr_delay; |
318 | struct radeon_atom_ss *ss; | ||
281 | /* panel mode */ | 319 | /* panel mode */ |
282 | struct radeon_native_mode native_mode; | 320 | struct drm_display_mode native_mode; |
283 | }; | 321 | }; |
284 | 322 | ||
285 | struct radeon_encoder_atom_dac { | 323 | struct radeon_encoder_atom_dac { |
@@ -294,13 +332,42 @@ struct radeon_encoder { | |||
294 | uint32_t flags; | 332 | uint32_t flags; |
295 | uint32_t pixel_clock; | 333 | uint32_t pixel_clock; |
296 | enum radeon_rmx_type rmx_type; | 334 | enum radeon_rmx_type rmx_type; |
297 | struct radeon_native_mode native_mode; | 335 | struct drm_display_mode native_mode; |
298 | void *enc_priv; | 336 | void *enc_priv; |
299 | }; | 337 | }; |
300 | 338 | ||
301 | struct radeon_connector_atom_dig { | 339 | struct radeon_connector_atom_dig { |
302 | uint32_t igp_lane_info; | 340 | uint32_t igp_lane_info; |
303 | bool linkb; | 341 | bool linkb; |
342 | /* displayport */ | ||
343 | struct radeon_i2c_chan *dp_i2c_bus; | ||
344 | u8 dpcd[8]; | ||
345 | u8 dp_sink_type; | ||
346 | int dp_clock; | ||
347 | int dp_lane_count; | ||
348 | }; | ||
349 | |||
350 | struct radeon_gpio_rec { | ||
351 | bool valid; | ||
352 | u8 id; | ||
353 | u32 reg; | ||
354 | u32 mask; | ||
355 | }; | ||
356 | |||
357 | enum radeon_hpd_id { | ||
358 | RADEON_HPD_NONE = 0, | ||
359 | RADEON_HPD_1, | ||
360 | RADEON_HPD_2, | ||
361 | RADEON_HPD_3, | ||
362 | RADEON_HPD_4, | ||
363 | RADEON_HPD_5, | ||
364 | RADEON_HPD_6, | ||
365 | }; | ||
366 | |||
367 | struct radeon_hpd { | ||
368 | enum radeon_hpd_id hpd; | ||
369 | u8 plugged_state; | ||
370 | struct radeon_gpio_rec gpio; | ||
304 | }; | 371 | }; |
305 | 372 | ||
306 | struct radeon_connector { | 373 | struct radeon_connector { |
@@ -308,12 +375,16 @@ struct radeon_connector { | |||
308 | uint32_t connector_id; | 375 | uint32_t connector_id; |
309 | uint32_t devices; | 376 | uint32_t devices; |
310 | struct radeon_i2c_chan *ddc_bus; | 377 | struct radeon_i2c_chan *ddc_bus; |
378 | /* some systems have a an hdmi and vga port with a shared ddc line */ | ||
379 | bool shared_ddc; | ||
311 | bool use_digital; | 380 | bool use_digital; |
312 | /* we need to mind the EDID between detect | 381 | /* we need to mind the EDID between detect |
313 | and get modes due to analog/digital/tvencoder */ | 382 | and get modes due to analog/digital/tvencoder */ |
314 | struct edid *edid; | 383 | struct edid *edid; |
315 | void *con_priv; | 384 | void *con_priv; |
316 | bool dac_load_detect; | 385 | bool dac_load_detect; |
386 | uint16_t connector_object_id; | ||
387 | struct radeon_hpd hpd; | ||
317 | }; | 388 | }; |
318 | 389 | ||
319 | struct radeon_framebuffer { | 390 | struct radeon_framebuffer { |
@@ -321,10 +392,37 @@ struct radeon_framebuffer { | |||
321 | struct drm_gem_object *obj; | 392 | struct drm_gem_object *obj; |
322 | }; | 393 | }; |
323 | 394 | ||
395 | extern void radeon_connector_hotplug(struct drm_connector *connector); | ||
396 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); | ||
397 | extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, | ||
398 | struct drm_display_mode *mode); | ||
399 | extern void radeon_dp_set_link_config(struct drm_connector *connector, | ||
400 | struct drm_display_mode *mode); | ||
401 | extern void dp_link_train(struct drm_encoder *encoder, | ||
402 | struct drm_connector *connector); | ||
403 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); | ||
404 | extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); | ||
405 | extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, | ||
406 | int action, uint8_t lane_num, | ||
407 | uint8_t lane_set); | ||
408 | extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | ||
409 | uint8_t write_byte, uint8_t *read_byte); | ||
410 | |||
411 | extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, | ||
412 | struct radeon_i2c_bus_rec *rec, | ||
413 | const char *name); | ||
324 | extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | 414 | extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, |
325 | struct radeon_i2c_bus_rec *rec, | 415 | struct radeon_i2c_bus_rec *rec, |
326 | const char *name); | 416 | const char *name); |
327 | extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c); | 417 | extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c); |
418 | extern void radeon_i2c_sw_get_byte(struct radeon_i2c_chan *i2c_bus, | ||
419 | u8 slave_addr, | ||
420 | u8 addr, | ||
421 | u8 *val); | ||
422 | extern void radeon_i2c_sw_put_byte(struct radeon_i2c_chan *i2c, | ||
423 | u8 slave_addr, | ||
424 | u8 addr, | ||
425 | u8 val); | ||
328 | extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); | 426 | extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); |
329 | extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); | 427 | extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); |
330 | 428 | ||
@@ -339,12 +437,24 @@ extern void radeon_compute_pll(struct radeon_pll *pll, | |||
339 | uint32_t *post_div_p, | 437 | uint32_t *post_div_p, |
340 | int flags); | 438 | int flags); |
341 | 439 | ||
440 | extern void radeon_compute_pll_avivo(struct radeon_pll *pll, | ||
441 | uint64_t freq, | ||
442 | uint32_t *dot_clock_p, | ||
443 | uint32_t *fb_div_p, | ||
444 | uint32_t *frac_fb_div_p, | ||
445 | uint32_t *ref_div_p, | ||
446 | uint32_t *post_div_p, | ||
447 | int flags); | ||
448 | |||
449 | extern void radeon_setup_encoder_clones(struct drm_device *dev); | ||
450 | |||
342 | struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index); | 451 | struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index); |
343 | struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int with_tv); | 452 | struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int with_tv); |
344 | struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv); | 453 | struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv); |
345 | struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index); | 454 | struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index); |
346 | struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index); | 455 | struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index); |
347 | extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); | 456 | extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); |
457 | extern void atombios_digital_setup(struct drm_encoder *encoder, int action); | ||
348 | extern int atombios_get_encoder_mode(struct drm_encoder *encoder); | 458 | extern int atombios_get_encoder_mode(struct drm_encoder *encoder); |
349 | extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); | 459 | extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); |
350 | 460 | ||
@@ -374,12 +484,16 @@ extern bool radeon_atom_get_clock_info(struct drm_device *dev); | |||
374 | extern bool radeon_combios_get_clock_info(struct drm_device *dev); | 484 | extern bool radeon_combios_get_clock_info(struct drm_device *dev); |
375 | extern struct radeon_encoder_atom_dig * | 485 | extern struct radeon_encoder_atom_dig * |
376 | radeon_atombios_get_lvds_info(struct radeon_encoder *encoder); | 486 | radeon_atombios_get_lvds_info(struct radeon_encoder *encoder); |
377 | bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, | 487 | extern bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, |
378 | struct radeon_encoder_int_tmds *tmds); | 488 | struct radeon_encoder_int_tmds *tmds); |
379 | bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, | 489 | extern bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, |
380 | struct radeon_encoder_int_tmds *tmds); | 490 | struct radeon_encoder_int_tmds *tmds); |
381 | bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder, | 491 | extern bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder, |
382 | struct radeon_encoder_int_tmds *tmds); | 492 | struct radeon_encoder_int_tmds *tmds); |
493 | extern bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder, | ||
494 | struct radeon_encoder_ext_tmds *tmds); | ||
495 | extern bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder, | ||
496 | struct radeon_encoder_ext_tmds *tmds); | ||
383 | extern struct radeon_encoder_primary_dac * | 497 | extern struct radeon_encoder_primary_dac * |
384 | radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder); | 498 | radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder); |
385 | extern struct radeon_encoder_tv_dac * | 499 | extern struct radeon_encoder_tv_dac * |
@@ -391,6 +505,8 @@ extern struct radeon_encoder_tv_dac * | |||
391 | radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder); | 505 | radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder); |
392 | extern struct radeon_encoder_primary_dac * | 506 | extern struct radeon_encoder_primary_dac * |
393 | radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder); | 507 | radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder); |
508 | extern bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder); | ||
509 | extern void radeon_external_tmds_setup(struct drm_encoder *encoder); | ||
394 | extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock); | 510 | extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock); |
395 | extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev); | 511 | extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev); |
396 | extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock); | 512 | extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock); |
@@ -422,16 +538,13 @@ void radeon_atombios_init_crtc(struct drm_device *dev, | |||
422 | struct radeon_crtc *radeon_crtc); | 538 | struct radeon_crtc *radeon_crtc); |
423 | void radeon_legacy_init_crtc(struct drm_device *dev, | 539 | void radeon_legacy_init_crtc(struct drm_device *dev, |
424 | struct radeon_crtc *radeon_crtc); | 540 | struct radeon_crtc *radeon_crtc); |
425 | void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state); | 541 | extern void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state); |
426 | 542 | ||
427 | void radeon_get_clock_info(struct drm_device *dev); | 543 | void radeon_get_clock_info(struct drm_device *dev); |
428 | 544 | ||
429 | extern bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev); | 545 | extern bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev); |
430 | extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct drm_device *dev); | 546 | extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct drm_device *dev); |
431 | 547 | ||
432 | void radeon_rmx_mode_fixup(struct drm_encoder *encoder, | ||
433 | struct drm_display_mode *mode, | ||
434 | struct drm_display_mode *adjusted_mode); | ||
435 | void radeon_enc_destroy(struct drm_encoder *encoder); | 548 | void radeon_enc_destroy(struct drm_encoder *encoder); |
436 | void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); | 549 | void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); |
437 | void radeon_combios_asic_init(struct drm_device *dev); | 550 | void radeon_combios_asic_init(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1f056dadc5c2..544e18ffaf22 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -34,100 +34,53 @@ | |||
34 | #include "radeon_drm.h" | 34 | #include "radeon_drm.h" |
35 | #include "radeon.h" | 35 | #include "radeon.h" |
36 | 36 | ||
37 | struct radeon_object { | ||
38 | struct ttm_buffer_object tobj; | ||
39 | struct list_head list; | ||
40 | struct radeon_device *rdev; | ||
41 | struct drm_gem_object *gobj; | ||
42 | struct ttm_bo_kmap_obj kmap; | ||
43 | unsigned pin_count; | ||
44 | uint64_t gpu_addr; | ||
45 | void *kptr; | ||
46 | bool is_iomem; | ||
47 | uint32_t tiling_flags; | ||
48 | uint32_t pitch; | ||
49 | int surface_reg; | ||
50 | }; | ||
51 | 37 | ||
52 | int radeon_ttm_init(struct radeon_device *rdev); | 38 | int radeon_ttm_init(struct radeon_device *rdev); |
53 | void radeon_ttm_fini(struct radeon_device *rdev); | 39 | void radeon_ttm_fini(struct radeon_device *rdev); |
40 | static void radeon_bo_clear_surface_reg(struct radeon_bo *bo); | ||
54 | 41 | ||
55 | /* | 42 | /* |
56 | * To exclude mutual BO access we rely on bo_reserve exclusion, as all | 43 | * To exclude mutual BO access we rely on bo_reserve exclusion, as all |
57 | * function are calling it. | 44 | * function are calling it. |
58 | */ | 45 | */ |
59 | 46 | ||
60 | static int radeon_object_reserve(struct radeon_object *robj, bool interruptible) | 47 | static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo) |
61 | { | 48 | { |
62 | return ttm_bo_reserve(&robj->tobj, interruptible, false, false, 0); | 49 | struct radeon_bo *bo; |
63 | } | ||
64 | 50 | ||
65 | static void radeon_object_unreserve(struct radeon_object *robj) | 51 | bo = container_of(tbo, struct radeon_bo, tbo); |
66 | { | 52 | mutex_lock(&bo->rdev->gem.mutex); |
67 | ttm_bo_unreserve(&robj->tobj); | 53 | list_del_init(&bo->list); |
54 | mutex_unlock(&bo->rdev->gem.mutex); | ||
55 | radeon_bo_clear_surface_reg(bo); | ||
56 | kfree(bo); | ||
68 | } | 57 | } |
69 | 58 | ||
70 | static void radeon_ttm_object_object_destroy(struct ttm_buffer_object *tobj) | 59 | void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) |
71 | { | 60 | { |
72 | struct radeon_object *robj; | 61 | u32 c = 0; |
73 | 62 | ||
74 | robj = container_of(tobj, struct radeon_object, tobj); | 63 | rbo->placement.fpfn = 0; |
75 | list_del_init(&robj->list); | 64 | rbo->placement.lpfn = 0; |
76 | radeon_object_clear_surface_reg(robj); | 65 | rbo->placement.placement = rbo->placements; |
77 | kfree(robj); | 66 | rbo->placement.busy_placement = rbo->placements; |
67 | if (domain & RADEON_GEM_DOMAIN_VRAM) | ||
68 | rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | | ||
69 | TTM_PL_FLAG_VRAM; | ||
70 | if (domain & RADEON_GEM_DOMAIN_GTT) | ||
71 | rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; | ||
72 | if (domain & RADEON_GEM_DOMAIN_CPU) | ||
73 | rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; | ||
74 | rbo->placement.num_placement = c; | ||
75 | rbo->placement.num_busy_placement = c; | ||
78 | } | 76 | } |
79 | 77 | ||
80 | static inline void radeon_object_gpu_addr(struct radeon_object *robj) | 78 | int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, |
79 | unsigned long size, bool kernel, u32 domain, | ||
80 | struct radeon_bo **bo_ptr) | ||
81 | { | 81 | { |
82 | /* Default gpu address */ | 82 | struct radeon_bo *bo; |
83 | robj->gpu_addr = 0xFFFFFFFFFFFFFFFFULL; | ||
84 | if (robj->tobj.mem.mm_node == NULL) { | ||
85 | return; | ||
86 | } | ||
87 | robj->gpu_addr = ((u64)robj->tobj.mem.mm_node->start) << PAGE_SHIFT; | ||
88 | switch (robj->tobj.mem.mem_type) { | ||
89 | case TTM_PL_VRAM: | ||
90 | robj->gpu_addr += (u64)robj->rdev->mc.vram_location; | ||
91 | break; | ||
92 | case TTM_PL_TT: | ||
93 | robj->gpu_addr += (u64)robj->rdev->mc.gtt_location; | ||
94 | break; | ||
95 | default: | ||
96 | DRM_ERROR("Unknown placement %d\n", robj->tobj.mem.mem_type); | ||
97 | robj->gpu_addr = 0xFFFFFFFFFFFFFFFFULL; | ||
98 | return; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | static inline uint32_t radeon_object_flags_from_domain(uint32_t domain) | ||
103 | { | ||
104 | uint32_t flags = 0; | ||
105 | if (domain & RADEON_GEM_DOMAIN_VRAM) { | ||
106 | flags |= TTM_PL_FLAG_VRAM | TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED; | ||
107 | } | ||
108 | if (domain & RADEON_GEM_DOMAIN_GTT) { | ||
109 | flags |= TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; | ||
110 | } | ||
111 | if (domain & RADEON_GEM_DOMAIN_CPU) { | ||
112 | flags |= TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING; | ||
113 | } | ||
114 | if (!flags) { | ||
115 | flags |= TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING; | ||
116 | } | ||
117 | return flags; | ||
118 | } | ||
119 | |||
120 | int radeon_object_create(struct radeon_device *rdev, | ||
121 | struct drm_gem_object *gobj, | ||
122 | unsigned long size, | ||
123 | bool kernel, | ||
124 | uint32_t domain, | ||
125 | bool interruptible, | ||
126 | struct radeon_object **robj_ptr) | ||
127 | { | ||
128 | struct radeon_object *robj; | ||
129 | enum ttm_bo_type type; | 83 | enum ttm_bo_type type; |
130 | uint32_t flags; | ||
131 | int r; | 84 | int r; |
132 | 85 | ||
133 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { | 86 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { |
@@ -138,206 +91,125 @@ int radeon_object_create(struct radeon_device *rdev, | |||
138 | } else { | 91 | } else { |
139 | type = ttm_bo_type_device; | 92 | type = ttm_bo_type_device; |
140 | } | 93 | } |
141 | *robj_ptr = NULL; | 94 | *bo_ptr = NULL; |
142 | robj = kzalloc(sizeof(struct radeon_object), GFP_KERNEL); | 95 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); |
143 | if (robj == NULL) { | 96 | if (bo == NULL) |
144 | return -ENOMEM; | 97 | return -ENOMEM; |
145 | } | 98 | bo->rdev = rdev; |
146 | robj->rdev = rdev; | 99 | bo->gobj = gobj; |
147 | robj->gobj = gobj; | 100 | bo->surface_reg = -1; |
148 | robj->surface_reg = -1; | 101 | INIT_LIST_HEAD(&bo->list); |
149 | INIT_LIST_HEAD(&robj->list); | 102 | |
150 | 103 | radeon_ttm_placement_from_domain(bo, domain); | |
151 | flags = radeon_object_flags_from_domain(domain); | 104 | /* Kernel allocation are uninterruptible */ |
152 | r = ttm_buffer_object_init(&rdev->mman.bdev, &robj->tobj, size, type, flags, | 105 | r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, |
153 | 0, 0, false, NULL, size, | 106 | &bo->placement, 0, 0, !kernel, NULL, size, |
154 | &radeon_ttm_object_object_destroy); | 107 | &radeon_ttm_bo_destroy); |
155 | if (unlikely(r != 0)) { | 108 | if (unlikely(r != 0)) { |
156 | /* ttm call radeon_ttm_object_object_destroy if error happen */ | 109 | if (r != -ERESTARTSYS) |
157 | DRM_ERROR("Failed to allocate TTM object (%ld, 0x%08X, %u)\n", | 110 | dev_err(rdev->dev, |
158 | size, flags, 0); | 111 | "object_init failed for (%lu, 0x%08X)\n", |
112 | size, domain); | ||
159 | return r; | 113 | return r; |
160 | } | 114 | } |
161 | *robj_ptr = robj; | 115 | *bo_ptr = bo; |
162 | if (gobj) { | 116 | if (gobj) { |
163 | list_add_tail(&robj->list, &rdev->gem.objects); | 117 | mutex_lock(&bo->rdev->gem.mutex); |
118 | list_add_tail(&bo->list, &rdev->gem.objects); | ||
119 | mutex_unlock(&bo->rdev->gem.mutex); | ||
164 | } | 120 | } |
165 | return 0; | 121 | return 0; |
166 | } | 122 | } |
167 | 123 | ||
168 | int radeon_object_kmap(struct radeon_object *robj, void **ptr) | 124 | int radeon_bo_kmap(struct radeon_bo *bo, void **ptr) |
169 | { | 125 | { |
126 | bool is_iomem; | ||
170 | int r; | 127 | int r; |
171 | 128 | ||
172 | spin_lock(&robj->tobj.lock); | 129 | if (bo->kptr) { |
173 | if (robj->kptr) { | ||
174 | if (ptr) { | 130 | if (ptr) { |
175 | *ptr = robj->kptr; | 131 | *ptr = bo->kptr; |
176 | } | 132 | } |
177 | spin_unlock(&robj->tobj.lock); | ||
178 | return 0; | 133 | return 0; |
179 | } | 134 | } |
180 | spin_unlock(&robj->tobj.lock); | 135 | r = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap); |
181 | r = ttm_bo_kmap(&robj->tobj, 0, robj->tobj.num_pages, &robj->kmap); | ||
182 | if (r) { | 136 | if (r) { |
183 | return r; | 137 | return r; |
184 | } | 138 | } |
185 | spin_lock(&robj->tobj.lock); | 139 | bo->kptr = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); |
186 | robj->kptr = ttm_kmap_obj_virtual(&robj->kmap, &robj->is_iomem); | ||
187 | spin_unlock(&robj->tobj.lock); | ||
188 | if (ptr) { | 140 | if (ptr) { |
189 | *ptr = robj->kptr; | 141 | *ptr = bo->kptr; |
190 | } | 142 | } |
191 | radeon_object_check_tiling(robj, 0, 0); | 143 | radeon_bo_check_tiling(bo, 0, 0); |
192 | return 0; | 144 | return 0; |
193 | } | 145 | } |
194 | 146 | ||
195 | void radeon_object_kunmap(struct radeon_object *robj) | 147 | void radeon_bo_kunmap(struct radeon_bo *bo) |
196 | { | 148 | { |
197 | spin_lock(&robj->tobj.lock); | 149 | if (bo->kptr == NULL) |
198 | if (robj->kptr == NULL) { | ||
199 | spin_unlock(&robj->tobj.lock); | ||
200 | return; | 150 | return; |
201 | } | 151 | bo->kptr = NULL; |
202 | robj->kptr = NULL; | 152 | radeon_bo_check_tiling(bo, 0, 0); |
203 | spin_unlock(&robj->tobj.lock); | 153 | ttm_bo_kunmap(&bo->kmap); |
204 | radeon_object_check_tiling(robj, 0, 0); | ||
205 | ttm_bo_kunmap(&robj->kmap); | ||
206 | } | 154 | } |
207 | 155 | ||
208 | void radeon_object_unref(struct radeon_object **robj) | 156 | void radeon_bo_unref(struct radeon_bo **bo) |
209 | { | 157 | { |
210 | struct ttm_buffer_object *tobj; | 158 | struct ttm_buffer_object *tbo; |
211 | 159 | ||
212 | if ((*robj) == NULL) { | 160 | if ((*bo) == NULL) |
213 | return; | 161 | return; |
214 | } | 162 | tbo = &((*bo)->tbo); |
215 | tobj = &((*robj)->tobj); | 163 | ttm_bo_unref(&tbo); |
216 | ttm_bo_unref(&tobj); | 164 | if (tbo == NULL) |
217 | if (tobj == NULL) { | 165 | *bo = NULL; |
218 | *robj = NULL; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset) | ||
223 | { | ||
224 | *offset = robj->tobj.addr_space_offset; | ||
225 | return 0; | ||
226 | } | 166 | } |
227 | 167 | ||
228 | int radeon_object_pin(struct radeon_object *robj, uint32_t domain, | 168 | int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) |
229 | uint64_t *gpu_addr) | ||
230 | { | 169 | { |
231 | uint32_t flags; | 170 | int r, i; |
232 | uint32_t tmp; | ||
233 | int r; | ||
234 | 171 | ||
235 | flags = radeon_object_flags_from_domain(domain); | 172 | radeon_ttm_placement_from_domain(bo, domain); |
236 | spin_lock(&robj->tobj.lock); | 173 | if (bo->pin_count) { |
237 | if (robj->pin_count) { | 174 | bo->pin_count++; |
238 | robj->pin_count++; | 175 | if (gpu_addr) |
239 | if (gpu_addr != NULL) { | 176 | *gpu_addr = radeon_bo_gpu_offset(bo); |
240 | *gpu_addr = robj->gpu_addr; | ||
241 | } | ||
242 | spin_unlock(&robj->tobj.lock); | ||
243 | return 0; | 177 | return 0; |
244 | } | 178 | } |
245 | spin_unlock(&robj->tobj.lock); | 179 | radeon_ttm_placement_from_domain(bo, domain); |
246 | r = radeon_object_reserve(robj, false); | 180 | for (i = 0; i < bo->placement.num_placement; i++) |
247 | if (unlikely(r != 0)) { | 181 | bo->placements[i] |= TTM_PL_FLAG_NO_EVICT; |
248 | DRM_ERROR("radeon: failed to reserve object for pinning it.\n"); | 182 | r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); |
249 | return r; | 183 | if (likely(r == 0)) { |
250 | } | 184 | bo->pin_count = 1; |
251 | tmp = robj->tobj.mem.placement; | 185 | if (gpu_addr != NULL) |
252 | ttm_flag_masked(&tmp, flags, TTM_PL_MASK_MEM); | 186 | *gpu_addr = radeon_bo_gpu_offset(bo); |
253 | robj->tobj.proposed_placement = tmp | TTM_PL_FLAG_NO_EVICT | TTM_PL_MASK_CACHING; | 187 | } |
254 | r = ttm_buffer_object_validate(&robj->tobj, | 188 | if (unlikely(r != 0)) |
255 | robj->tobj.proposed_placement, | 189 | dev_err(bo->rdev->dev, "%p pin failed\n", bo); |
256 | false, false); | ||
257 | radeon_object_gpu_addr(robj); | ||
258 | if (gpu_addr != NULL) { | ||
259 | *gpu_addr = robj->gpu_addr; | ||
260 | } | ||
261 | robj->pin_count = 1; | ||
262 | if (unlikely(r != 0)) { | ||
263 | DRM_ERROR("radeon: failed to pin object.\n"); | ||
264 | } | ||
265 | radeon_object_unreserve(robj); | ||
266 | return r; | 190 | return r; |
267 | } | 191 | } |
268 | 192 | ||
269 | void radeon_object_unpin(struct radeon_object *robj) | 193 | int radeon_bo_unpin(struct radeon_bo *bo) |
270 | { | 194 | { |
271 | uint32_t flags; | 195 | int r, i; |
272 | int r; | ||
273 | 196 | ||
274 | spin_lock(&robj->tobj.lock); | 197 | if (!bo->pin_count) { |
275 | if (!robj->pin_count) { | 198 | dev_warn(bo->rdev->dev, "%p unpin not necessary\n", bo); |
276 | spin_unlock(&robj->tobj.lock); | 199 | return 0; |
277 | printk(KERN_WARNING "Unpin not necessary for %p !\n", robj); | ||
278 | return; | ||
279 | } | ||
280 | robj->pin_count--; | ||
281 | if (robj->pin_count) { | ||
282 | spin_unlock(&robj->tobj.lock); | ||
283 | return; | ||
284 | } | ||
285 | spin_unlock(&robj->tobj.lock); | ||
286 | r = radeon_object_reserve(robj, false); | ||
287 | if (unlikely(r != 0)) { | ||
288 | DRM_ERROR("radeon: failed to reserve object for unpinning it.\n"); | ||
289 | return; | ||
290 | } | ||
291 | flags = robj->tobj.mem.placement; | ||
292 | robj->tobj.proposed_placement = flags & ~TTM_PL_FLAG_NO_EVICT; | ||
293 | r = ttm_buffer_object_validate(&robj->tobj, | ||
294 | robj->tobj.proposed_placement, | ||
295 | false, false); | ||
296 | if (unlikely(r != 0)) { | ||
297 | DRM_ERROR("radeon: failed to unpin buffer.\n"); | ||
298 | } | ||
299 | radeon_object_unreserve(robj); | ||
300 | } | ||
301 | |||
302 | int radeon_object_wait(struct radeon_object *robj) | ||
303 | { | ||
304 | int r = 0; | ||
305 | |||
306 | /* FIXME: should use block reservation instead */ | ||
307 | r = radeon_object_reserve(robj, true); | ||
308 | if (unlikely(r != 0)) { | ||
309 | DRM_ERROR("radeon: failed to reserve object for waiting.\n"); | ||
310 | return r; | ||
311 | } | ||
312 | spin_lock(&robj->tobj.lock); | ||
313 | if (robj->tobj.sync_obj) { | ||
314 | r = ttm_bo_wait(&robj->tobj, true, true, false); | ||
315 | } | ||
316 | spin_unlock(&robj->tobj.lock); | ||
317 | radeon_object_unreserve(robj); | ||
318 | return r; | ||
319 | } | ||
320 | |||
321 | int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement) | ||
322 | { | ||
323 | int r = 0; | ||
324 | |||
325 | r = radeon_object_reserve(robj, true); | ||
326 | if (unlikely(r != 0)) { | ||
327 | DRM_ERROR("radeon: failed to reserve object for waiting.\n"); | ||
328 | return r; | ||
329 | } | ||
330 | spin_lock(&robj->tobj.lock); | ||
331 | *cur_placement = robj->tobj.mem.mem_type; | ||
332 | if (robj->tobj.sync_obj) { | ||
333 | r = ttm_bo_wait(&robj->tobj, true, true, true); | ||
334 | } | 200 | } |
335 | spin_unlock(&robj->tobj.lock); | 201 | bo->pin_count--; |
336 | radeon_object_unreserve(robj); | 202 | if (bo->pin_count) |
203 | return 0; | ||
204 | for (i = 0; i < bo->placement.num_placement; i++) | ||
205 | bo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT; | ||
206 | r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); | ||
207 | if (unlikely(r != 0)) | ||
208 | dev_err(bo->rdev->dev, "%p validate failed for unpin\n", bo); | ||
337 | return r; | 209 | return r; |
338 | } | 210 | } |
339 | 211 | ||
340 | int radeon_object_evict_vram(struct radeon_device *rdev) | 212 | int radeon_bo_evict_vram(struct radeon_device *rdev) |
341 | { | 213 | { |
342 | if (rdev->flags & RADEON_IS_IGP) { | 214 | if (rdev->flags & RADEON_IS_IGP) { |
343 | /* Useless to evict on IGP chips */ | 215 | /* Useless to evict on IGP chips */ |
@@ -346,30 +218,32 @@ int radeon_object_evict_vram(struct radeon_device *rdev) | |||
346 | return ttm_bo_evict_mm(&rdev->mman.bdev, TTM_PL_VRAM); | 218 | return ttm_bo_evict_mm(&rdev->mman.bdev, TTM_PL_VRAM); |
347 | } | 219 | } |
348 | 220 | ||
349 | void radeon_object_force_delete(struct radeon_device *rdev) | 221 | void radeon_bo_force_delete(struct radeon_device *rdev) |
350 | { | 222 | { |
351 | struct radeon_object *robj, *n; | 223 | struct radeon_bo *bo, *n; |
352 | struct drm_gem_object *gobj; | 224 | struct drm_gem_object *gobj; |
353 | 225 | ||
354 | if (list_empty(&rdev->gem.objects)) { | 226 | if (list_empty(&rdev->gem.objects)) { |
355 | return; | 227 | return; |
356 | } | 228 | } |
357 | DRM_ERROR("Userspace still has active objects !\n"); | 229 | dev_err(rdev->dev, "Userspace still has active objects !\n"); |
358 | list_for_each_entry_safe(robj, n, &rdev->gem.objects, list) { | 230 | list_for_each_entry_safe(bo, n, &rdev->gem.objects, list) { |
359 | mutex_lock(&rdev->ddev->struct_mutex); | 231 | mutex_lock(&rdev->ddev->struct_mutex); |
360 | gobj = robj->gobj; | 232 | gobj = bo->gobj; |
361 | DRM_ERROR("Force free for (%p,%p,%lu,%lu)\n", | 233 | dev_err(rdev->dev, "%p %p %lu %lu force free\n", |
362 | gobj, robj, (unsigned long)gobj->size, | 234 | gobj, bo, (unsigned long)gobj->size, |
363 | *((unsigned long *)&gobj->refcount)); | 235 | *((unsigned long *)&gobj->refcount)); |
364 | list_del_init(&robj->list); | 236 | mutex_lock(&bo->rdev->gem.mutex); |
365 | radeon_object_unref(&robj); | 237 | list_del_init(&bo->list); |
238 | mutex_unlock(&bo->rdev->gem.mutex); | ||
239 | radeon_bo_unref(&bo); | ||
366 | gobj->driver_private = NULL; | 240 | gobj->driver_private = NULL; |
367 | drm_gem_object_unreference(gobj); | 241 | drm_gem_object_unreference(gobj); |
368 | mutex_unlock(&rdev->ddev->struct_mutex); | 242 | mutex_unlock(&rdev->ddev->struct_mutex); |
369 | } | 243 | } |
370 | } | 244 | } |
371 | 245 | ||
372 | int radeon_object_init(struct radeon_device *rdev) | 246 | int radeon_bo_init(struct radeon_device *rdev) |
373 | { | 247 | { |
374 | /* Add an MTRR for the VRAM */ | 248 | /* Add an MTRR for the VRAM */ |
375 | rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size, | 249 | rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size, |
@@ -382,13 +256,13 @@ int radeon_object_init(struct radeon_device *rdev) | |||
382 | return radeon_ttm_init(rdev); | 256 | return radeon_ttm_init(rdev); |
383 | } | 257 | } |
384 | 258 | ||
385 | void radeon_object_fini(struct radeon_device *rdev) | 259 | void radeon_bo_fini(struct radeon_device *rdev) |
386 | { | 260 | { |
387 | radeon_ttm_fini(rdev); | 261 | radeon_ttm_fini(rdev); |
388 | } | 262 | } |
389 | 263 | ||
390 | void radeon_object_list_add_object(struct radeon_object_list *lobj, | 264 | void radeon_bo_list_add_object(struct radeon_bo_list *lobj, |
391 | struct list_head *head) | 265 | struct list_head *head) |
392 | { | 266 | { |
393 | if (lobj->wdomain) { | 267 | if (lobj->wdomain) { |
394 | list_add(&lobj->list, head); | 268 | list_add(&lobj->list, head); |
@@ -397,72 +271,62 @@ void radeon_object_list_add_object(struct radeon_object_list *lobj, | |||
397 | } | 271 | } |
398 | } | 272 | } |
399 | 273 | ||
400 | int radeon_object_list_reserve(struct list_head *head) | 274 | int radeon_bo_list_reserve(struct list_head *head) |
401 | { | 275 | { |
402 | struct radeon_object_list *lobj; | 276 | struct radeon_bo_list *lobj; |
403 | int r; | 277 | int r; |
404 | 278 | ||
405 | list_for_each_entry(lobj, head, list){ | 279 | list_for_each_entry(lobj, head, list){ |
406 | if (!lobj->robj->pin_count) { | 280 | r = radeon_bo_reserve(lobj->bo, false); |
407 | r = radeon_object_reserve(lobj->robj, true); | 281 | if (unlikely(r != 0)) |
408 | if (unlikely(r != 0)) { | 282 | return r; |
409 | DRM_ERROR("radeon: failed to reserve object.\n"); | ||
410 | return r; | ||
411 | } | ||
412 | } else { | ||
413 | } | ||
414 | } | 283 | } |
415 | return 0; | 284 | return 0; |
416 | } | 285 | } |
417 | 286 | ||
418 | void radeon_object_list_unreserve(struct list_head *head) | 287 | void radeon_bo_list_unreserve(struct list_head *head) |
419 | { | 288 | { |
420 | struct radeon_object_list *lobj; | 289 | struct radeon_bo_list *lobj; |
421 | 290 | ||
422 | list_for_each_entry(lobj, head, list) { | 291 | list_for_each_entry(lobj, head, list) { |
423 | if (!lobj->robj->pin_count) { | 292 | /* only unreserve object we successfully reserved */ |
424 | radeon_object_unreserve(lobj->robj); | 293 | if (radeon_bo_is_reserved(lobj->bo)) |
425 | } | 294 | radeon_bo_unreserve(lobj->bo); |
426 | } | 295 | } |
427 | } | 296 | } |
428 | 297 | ||
429 | int radeon_object_list_validate(struct list_head *head, void *fence) | 298 | int radeon_bo_list_validate(struct list_head *head, void *fence) |
430 | { | 299 | { |
431 | struct radeon_object_list *lobj; | 300 | struct radeon_bo_list *lobj; |
432 | struct radeon_object *robj; | 301 | struct radeon_bo *bo; |
433 | struct radeon_fence *old_fence = NULL; | 302 | struct radeon_fence *old_fence = NULL; |
434 | int r; | 303 | int r; |
435 | 304 | ||
436 | r = radeon_object_list_reserve(head); | 305 | r = radeon_bo_list_reserve(head); |
437 | if (unlikely(r != 0)) { | 306 | if (unlikely(r != 0)) { |
438 | radeon_object_list_unreserve(head); | ||
439 | return r; | 307 | return r; |
440 | } | 308 | } |
441 | list_for_each_entry(lobj, head, list) { | 309 | list_for_each_entry(lobj, head, list) { |
442 | robj = lobj->robj; | 310 | bo = lobj->bo; |
443 | if (!robj->pin_count) { | 311 | if (!bo->pin_count) { |
444 | if (lobj->wdomain) { | 312 | if (lobj->wdomain) { |
445 | robj->tobj.proposed_placement = | 313 | radeon_ttm_placement_from_domain(bo, |
446 | radeon_object_flags_from_domain(lobj->wdomain); | 314 | lobj->wdomain); |
447 | } else { | 315 | } else { |
448 | robj->tobj.proposed_placement = | 316 | radeon_ttm_placement_from_domain(bo, |
449 | radeon_object_flags_from_domain(lobj->rdomain); | 317 | lobj->rdomain); |
450 | } | 318 | } |
451 | r = ttm_buffer_object_validate(&robj->tobj, | 319 | r = ttm_bo_validate(&bo->tbo, &bo->placement, |
452 | robj->tobj.proposed_placement, | 320 | true, false); |
453 | true, false); | 321 | if (unlikely(r)) |
454 | if (unlikely(r)) { | ||
455 | DRM_ERROR("radeon: failed to validate.\n"); | ||
456 | return r; | 322 | return r; |
457 | } | ||
458 | radeon_object_gpu_addr(robj); | ||
459 | } | 323 | } |
460 | lobj->gpu_offset = robj->gpu_addr; | 324 | lobj->gpu_offset = radeon_bo_gpu_offset(bo); |
461 | lobj->tiling_flags = robj->tiling_flags; | 325 | lobj->tiling_flags = bo->tiling_flags; |
462 | if (fence) { | 326 | if (fence) { |
463 | old_fence = (struct radeon_fence *)robj->tobj.sync_obj; | 327 | old_fence = (struct radeon_fence *)bo->tbo.sync_obj; |
464 | robj->tobj.sync_obj = radeon_fence_ref(fence); | 328 | bo->tbo.sync_obj = radeon_fence_ref(fence); |
465 | robj->tobj.sync_obj_arg = NULL; | 329 | bo->tbo.sync_obj_arg = NULL; |
466 | } | 330 | } |
467 | if (old_fence) { | 331 | if (old_fence) { |
468 | radeon_fence_unref(&old_fence); | 332 | radeon_fence_unref(&old_fence); |
@@ -471,51 +335,44 @@ int radeon_object_list_validate(struct list_head *head, void *fence) | |||
471 | return 0; | 335 | return 0; |
472 | } | 336 | } |
473 | 337 | ||
474 | void radeon_object_list_unvalidate(struct list_head *head) | 338 | void radeon_bo_list_unvalidate(struct list_head *head, void *fence) |
475 | { | 339 | { |
476 | struct radeon_object_list *lobj; | 340 | struct radeon_bo_list *lobj; |
477 | struct radeon_fence *old_fence = NULL; | 341 | struct radeon_fence *old_fence; |
478 | 342 | ||
479 | list_for_each_entry(lobj, head, list) { | 343 | if (fence) |
480 | old_fence = (struct radeon_fence *)lobj->robj->tobj.sync_obj; | 344 | list_for_each_entry(lobj, head, list) { |
481 | lobj->robj->tobj.sync_obj = NULL; | 345 | old_fence = to_radeon_fence(lobj->bo->tbo.sync_obj); |
482 | if (old_fence) { | 346 | if (old_fence == fence) { |
483 | radeon_fence_unref(&old_fence); | 347 | lobj->bo->tbo.sync_obj = NULL; |
348 | radeon_fence_unref(&old_fence); | ||
349 | } | ||
484 | } | 350 | } |
485 | } | 351 | radeon_bo_list_unreserve(head); |
486 | radeon_object_list_unreserve(head); | ||
487 | } | ||
488 | |||
489 | void radeon_object_list_clean(struct list_head *head) | ||
490 | { | ||
491 | radeon_object_list_unreserve(head); | ||
492 | } | 352 | } |
493 | 353 | ||
494 | int radeon_object_fbdev_mmap(struct radeon_object *robj, | 354 | int radeon_bo_fbdev_mmap(struct radeon_bo *bo, |
495 | struct vm_area_struct *vma) | 355 | struct vm_area_struct *vma) |
496 | { | 356 | { |
497 | return ttm_fbdev_mmap(vma, &robj->tobj); | 357 | return ttm_fbdev_mmap(vma, &bo->tbo); |
498 | } | 358 | } |
499 | 359 | ||
500 | unsigned long radeon_object_size(struct radeon_object *robj) | 360 | int radeon_bo_get_surface_reg(struct radeon_bo *bo) |
501 | { | 361 | { |
502 | return robj->tobj.num_pages << PAGE_SHIFT; | 362 | struct radeon_device *rdev = bo->rdev; |
503 | } | ||
504 | |||
505 | int radeon_object_get_surface_reg(struct radeon_object *robj) | ||
506 | { | ||
507 | struct radeon_device *rdev = robj->rdev; | ||
508 | struct radeon_surface_reg *reg; | 363 | struct radeon_surface_reg *reg; |
509 | struct radeon_object *old_object; | 364 | struct radeon_bo *old_object; |
510 | int steal; | 365 | int steal; |
511 | int i; | 366 | int i; |
512 | 367 | ||
513 | if (!robj->tiling_flags) | 368 | BUG_ON(!atomic_read(&bo->tbo.reserved)); |
369 | |||
370 | if (!bo->tiling_flags) | ||
514 | return 0; | 371 | return 0; |
515 | 372 | ||
516 | if (robj->surface_reg >= 0) { | 373 | if (bo->surface_reg >= 0) { |
517 | reg = &rdev->surface_regs[robj->surface_reg]; | 374 | reg = &rdev->surface_regs[bo->surface_reg]; |
518 | i = robj->surface_reg; | 375 | i = bo->surface_reg; |
519 | goto out; | 376 | goto out; |
520 | } | 377 | } |
521 | 378 | ||
@@ -523,10 +380,10 @@ int radeon_object_get_surface_reg(struct radeon_object *robj) | |||
523 | for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) { | 380 | for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) { |
524 | 381 | ||
525 | reg = &rdev->surface_regs[i]; | 382 | reg = &rdev->surface_regs[i]; |
526 | if (!reg->robj) | 383 | if (!reg->bo) |
527 | break; | 384 | break; |
528 | 385 | ||
529 | old_object = reg->robj; | 386 | old_object = reg->bo; |
530 | if (old_object->pin_count == 0) | 387 | if (old_object->pin_count == 0) |
531 | steal = i; | 388 | steal = i; |
532 | } | 389 | } |
@@ -537,91 +394,101 @@ int radeon_object_get_surface_reg(struct radeon_object *robj) | |||
537 | return -ENOMEM; | 394 | return -ENOMEM; |
538 | /* find someone with a surface reg and nuke their BO */ | 395 | /* find someone with a surface reg and nuke their BO */ |
539 | reg = &rdev->surface_regs[steal]; | 396 | reg = &rdev->surface_regs[steal]; |
540 | old_object = reg->robj; | 397 | old_object = reg->bo; |
541 | /* blow away the mapping */ | 398 | /* blow away the mapping */ |
542 | DRM_DEBUG("stealing surface reg %d from %p\n", steal, old_object); | 399 | DRM_DEBUG("stealing surface reg %d from %p\n", steal, old_object); |
543 | ttm_bo_unmap_virtual(&old_object->tobj); | 400 | ttm_bo_unmap_virtual(&old_object->tbo); |
544 | old_object->surface_reg = -1; | 401 | old_object->surface_reg = -1; |
545 | i = steal; | 402 | i = steal; |
546 | } | 403 | } |
547 | 404 | ||
548 | robj->surface_reg = i; | 405 | bo->surface_reg = i; |
549 | reg->robj = robj; | 406 | reg->bo = bo; |
550 | 407 | ||
551 | out: | 408 | out: |
552 | radeon_set_surface_reg(rdev, i, robj->tiling_flags, robj->pitch, | 409 | radeon_set_surface_reg(rdev, i, bo->tiling_flags, bo->pitch, |
553 | robj->tobj.mem.mm_node->start << PAGE_SHIFT, | 410 | bo->tbo.mem.mm_node->start << PAGE_SHIFT, |
554 | robj->tobj.num_pages << PAGE_SHIFT); | 411 | bo->tbo.num_pages << PAGE_SHIFT); |
555 | return 0; | 412 | return 0; |
556 | } | 413 | } |
557 | 414 | ||
558 | void radeon_object_clear_surface_reg(struct radeon_object *robj) | 415 | static void radeon_bo_clear_surface_reg(struct radeon_bo *bo) |
559 | { | 416 | { |
560 | struct radeon_device *rdev = robj->rdev; | 417 | struct radeon_device *rdev = bo->rdev; |
561 | struct radeon_surface_reg *reg; | 418 | struct radeon_surface_reg *reg; |
562 | 419 | ||
563 | if (robj->surface_reg == -1) | 420 | if (bo->surface_reg == -1) |
564 | return; | 421 | return; |
565 | 422 | ||
566 | reg = &rdev->surface_regs[robj->surface_reg]; | 423 | reg = &rdev->surface_regs[bo->surface_reg]; |
567 | radeon_clear_surface_reg(rdev, robj->surface_reg); | 424 | radeon_clear_surface_reg(rdev, bo->surface_reg); |
568 | 425 | ||
569 | reg->robj = NULL; | 426 | reg->bo = NULL; |
570 | robj->surface_reg = -1; | 427 | bo->surface_reg = -1; |
571 | } | 428 | } |
572 | 429 | ||
573 | void radeon_object_set_tiling_flags(struct radeon_object *robj, | 430 | int radeon_bo_set_tiling_flags(struct radeon_bo *bo, |
574 | uint32_t tiling_flags, uint32_t pitch) | 431 | uint32_t tiling_flags, uint32_t pitch) |
575 | { | 432 | { |
576 | robj->tiling_flags = tiling_flags; | 433 | int r; |
577 | robj->pitch = pitch; | 434 | |
435 | r = radeon_bo_reserve(bo, false); | ||
436 | if (unlikely(r != 0)) | ||
437 | return r; | ||
438 | bo->tiling_flags = tiling_flags; | ||
439 | bo->pitch = pitch; | ||
440 | radeon_bo_unreserve(bo); | ||
441 | return 0; | ||
578 | } | 442 | } |
579 | 443 | ||
580 | void radeon_object_get_tiling_flags(struct radeon_object *robj, | 444 | void radeon_bo_get_tiling_flags(struct radeon_bo *bo, |
581 | uint32_t *tiling_flags, | 445 | uint32_t *tiling_flags, |
582 | uint32_t *pitch) | 446 | uint32_t *pitch) |
583 | { | 447 | { |
448 | BUG_ON(!atomic_read(&bo->tbo.reserved)); | ||
584 | if (tiling_flags) | 449 | if (tiling_flags) |
585 | *tiling_flags = robj->tiling_flags; | 450 | *tiling_flags = bo->tiling_flags; |
586 | if (pitch) | 451 | if (pitch) |
587 | *pitch = robj->pitch; | 452 | *pitch = bo->pitch; |
588 | } | 453 | } |
589 | 454 | ||
590 | int radeon_object_check_tiling(struct radeon_object *robj, bool has_moved, | 455 | int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved, |
591 | bool force_drop) | 456 | bool force_drop) |
592 | { | 457 | { |
593 | if (!(robj->tiling_flags & RADEON_TILING_SURFACE)) | 458 | BUG_ON(!atomic_read(&bo->tbo.reserved)); |
459 | |||
460 | if (!(bo->tiling_flags & RADEON_TILING_SURFACE)) | ||
594 | return 0; | 461 | return 0; |
595 | 462 | ||
596 | if (force_drop) { | 463 | if (force_drop) { |
597 | radeon_object_clear_surface_reg(robj); | 464 | radeon_bo_clear_surface_reg(bo); |
598 | return 0; | 465 | return 0; |
599 | } | 466 | } |
600 | 467 | ||
601 | if (robj->tobj.mem.mem_type != TTM_PL_VRAM) { | 468 | if (bo->tbo.mem.mem_type != TTM_PL_VRAM) { |
602 | if (!has_moved) | 469 | if (!has_moved) |
603 | return 0; | 470 | return 0; |
604 | 471 | ||
605 | if (robj->surface_reg >= 0) | 472 | if (bo->surface_reg >= 0) |
606 | radeon_object_clear_surface_reg(robj); | 473 | radeon_bo_clear_surface_reg(bo); |
607 | return 0; | 474 | return 0; |
608 | } | 475 | } |
609 | 476 | ||
610 | if ((robj->surface_reg >= 0) && !has_moved) | 477 | if ((bo->surface_reg >= 0) && !has_moved) |
611 | return 0; | 478 | return 0; |
612 | 479 | ||
613 | return radeon_object_get_surface_reg(robj); | 480 | return radeon_bo_get_surface_reg(bo); |
614 | } | 481 | } |
615 | 482 | ||
616 | void radeon_bo_move_notify(struct ttm_buffer_object *bo, | 483 | void radeon_bo_move_notify(struct ttm_buffer_object *bo, |
617 | struct ttm_mem_reg *mem) | 484 | struct ttm_mem_reg *mem) |
618 | { | 485 | { |
619 | struct radeon_object *robj = container_of(bo, struct radeon_object, tobj); | 486 | struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo); |
620 | radeon_object_check_tiling(robj, 0, 1); | 487 | radeon_bo_check_tiling(rbo, 0, 1); |
621 | } | 488 | } |
622 | 489 | ||
623 | void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) | 490 | void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) |
624 | { | 491 | { |
625 | struct radeon_object *robj = container_of(bo, struct radeon_object, tobj); | 492 | struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo); |
626 | radeon_object_check_tiling(robj, 0, 0); | 493 | radeon_bo_check_tiling(rbo, 0, 0); |
627 | } | 494 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 10e8af6bb456..f6b69c2c0d00 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h | |||
@@ -28,19 +28,152 @@ | |||
28 | #ifndef __RADEON_OBJECT_H__ | 28 | #ifndef __RADEON_OBJECT_H__ |
29 | #define __RADEON_OBJECT_H__ | 29 | #define __RADEON_OBJECT_H__ |
30 | 30 | ||
31 | #include <ttm/ttm_bo_api.h> | 31 | #include <drm/radeon_drm.h> |
32 | #include <ttm/ttm_bo_driver.h> | 32 | #include "radeon.h" |
33 | #include <ttm/ttm_placement.h> | ||
34 | #include <ttm/ttm_module.h> | ||
35 | 33 | ||
36 | /* | 34 | /** |
37 | * TTM. | 35 | * radeon_mem_type_to_domain - return domain corresponding to mem_type |
36 | * @mem_type: ttm memory type | ||
37 | * | ||
38 | * Returns corresponding domain of the ttm mem_type | ||
39 | */ | ||
40 | static inline unsigned radeon_mem_type_to_domain(u32 mem_type) | ||
41 | { | ||
42 | switch (mem_type) { | ||
43 | case TTM_PL_VRAM: | ||
44 | return RADEON_GEM_DOMAIN_VRAM; | ||
45 | case TTM_PL_TT: | ||
46 | return RADEON_GEM_DOMAIN_GTT; | ||
47 | case TTM_PL_SYSTEM: | ||
48 | return RADEON_GEM_DOMAIN_CPU; | ||
49 | default: | ||
50 | break; | ||
51 | } | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | /** | ||
56 | * radeon_bo_reserve - reserve bo | ||
57 | * @bo: bo structure | ||
58 | * @no_wait: don't sleep while trying to reserve (return -EBUSY) | ||
59 | * | ||
60 | * Returns: | ||
61 | * -EBUSY: buffer is busy and @no_wait is true | ||
62 | * -ERESTART: A wait for the buffer to become unreserved was interrupted by | ||
63 | * a signal. Release all buffer reservations and return to user-space. | ||
38 | */ | 64 | */ |
39 | struct radeon_mman { | 65 | static inline int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait) |
40 | struct ttm_bo_global_ref bo_global_ref; | 66 | { |
41 | struct ttm_global_reference mem_global_ref; | 67 | int r; |
42 | bool mem_global_referenced; | 68 | |
43 | struct ttm_bo_device bdev; | 69 | retry: |
44 | }; | 70 | r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); |
71 | if (unlikely(r != 0)) { | ||
72 | if (r == -ERESTART) | ||
73 | goto retry; | ||
74 | dev_err(bo->rdev->dev, "%p reserve failed\n", bo); | ||
75 | return r; | ||
76 | } | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static inline void radeon_bo_unreserve(struct radeon_bo *bo) | ||
81 | { | ||
82 | ttm_bo_unreserve(&bo->tbo); | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * radeon_bo_gpu_offset - return GPU offset of bo | ||
87 | * @bo: radeon object for which we query the offset | ||
88 | * | ||
89 | * Returns current GPU offset of the object. | ||
90 | * | ||
91 | * Note: object should either be pinned or reserved when calling this | ||
92 | * function, it might be usefull to add check for this for debugging. | ||
93 | */ | ||
94 | static inline u64 radeon_bo_gpu_offset(struct radeon_bo *bo) | ||
95 | { | ||
96 | return bo->tbo.offset; | ||
97 | } | ||
98 | |||
99 | static inline unsigned long radeon_bo_size(struct radeon_bo *bo) | ||
100 | { | ||
101 | return bo->tbo.num_pages << PAGE_SHIFT; | ||
102 | } | ||
103 | |||
104 | static inline bool radeon_bo_is_reserved(struct radeon_bo *bo) | ||
105 | { | ||
106 | return !!atomic_read(&bo->tbo.reserved); | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * radeon_bo_mmap_offset - return mmap offset of bo | ||
111 | * @bo: radeon object for which we query the offset | ||
112 | * | ||
113 | * Returns mmap offset of the object. | ||
114 | * | ||
115 | * Note: addr_space_offset is constant after ttm bo init thus isn't protected | ||
116 | * by any lock. | ||
117 | */ | ||
118 | static inline u64 radeon_bo_mmap_offset(struct radeon_bo *bo) | ||
119 | { | ||
120 | return bo->tbo.addr_space_offset; | ||
121 | } | ||
122 | |||
123 | static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, | ||
124 | bool no_wait) | ||
125 | { | ||
126 | int r; | ||
127 | |||
128 | retry: | ||
129 | r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); | ||
130 | if (unlikely(r != 0)) { | ||
131 | if (r == -ERESTART) | ||
132 | goto retry; | ||
133 | dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo); | ||
134 | return r; | ||
135 | } | ||
136 | spin_lock(&bo->tbo.lock); | ||
137 | if (mem_type) | ||
138 | *mem_type = bo->tbo.mem.mem_type; | ||
139 | if (bo->tbo.sync_obj) | ||
140 | r = ttm_bo_wait(&bo->tbo, true, true, no_wait); | ||
141 | spin_unlock(&bo->tbo.lock); | ||
142 | ttm_bo_unreserve(&bo->tbo); | ||
143 | if (unlikely(r == -ERESTART)) | ||
144 | goto retry; | ||
145 | return r; | ||
146 | } | ||
45 | 147 | ||
148 | extern int radeon_bo_create(struct radeon_device *rdev, | ||
149 | struct drm_gem_object *gobj, unsigned long size, | ||
150 | bool kernel, u32 domain, | ||
151 | struct radeon_bo **bo_ptr); | ||
152 | extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr); | ||
153 | extern void radeon_bo_kunmap(struct radeon_bo *bo); | ||
154 | extern void radeon_bo_unref(struct radeon_bo **bo); | ||
155 | extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr); | ||
156 | extern int radeon_bo_unpin(struct radeon_bo *bo); | ||
157 | extern int radeon_bo_evict_vram(struct radeon_device *rdev); | ||
158 | extern void radeon_bo_force_delete(struct radeon_device *rdev); | ||
159 | extern int radeon_bo_init(struct radeon_device *rdev); | ||
160 | extern void radeon_bo_fini(struct radeon_device *rdev); | ||
161 | extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj, | ||
162 | struct list_head *head); | ||
163 | extern int radeon_bo_list_reserve(struct list_head *head); | ||
164 | extern void radeon_bo_list_unreserve(struct list_head *head); | ||
165 | extern int radeon_bo_list_validate(struct list_head *head, void *fence); | ||
166 | extern void radeon_bo_list_unvalidate(struct list_head *head, void *fence); | ||
167 | extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, | ||
168 | struct vm_area_struct *vma); | ||
169 | extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, | ||
170 | u32 tiling_flags, u32 pitch); | ||
171 | extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo, | ||
172 | u32 *tiling_flags, u32 *pitch); | ||
173 | extern int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved, | ||
174 | bool force_drop); | ||
175 | extern void radeon_bo_move_notify(struct ttm_buffer_object *bo, | ||
176 | struct ttm_mem_reg *mem); | ||
177 | extern void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); | ||
178 | extern int radeon_bo_get_surface_reg(struct radeon_bo *bo); | ||
46 | #endif | 179 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c new file mode 100644 index 000000000000..34b08d307c81 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
3 | * copy of this software and associated documentation files (the "Software"), | ||
4 | * to deal in the Software without restriction, including without limitation | ||
5 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
6 | * and/or sell copies of the Software, and to permit persons to whom the | ||
7 | * Software is furnished to do so, subject to the following conditions: | ||
8 | * | ||
9 | * The above copyright notice and this permission notice shall be included in | ||
10 | * all copies or substantial portions of the Software. | ||
11 | * | ||
12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
13 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
15 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
16 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
18 | * OTHER DEALINGS IN THE SOFTWARE. | ||
19 | * | ||
20 | * Authors: Rafał Miłecki <zajec5@gmail.com> | ||
21 | */ | ||
22 | #include "drmP.h" | ||
23 | #include "radeon.h" | ||
24 | |||
25 | int radeon_debugfs_pm_init(struct radeon_device *rdev); | ||
26 | |||
27 | int radeon_pm_init(struct radeon_device *rdev) | ||
28 | { | ||
29 | if (radeon_debugfs_pm_init(rdev)) { | ||
30 | DRM_ERROR("Failed to register debugfs file for PM!\n"); | ||
31 | } | ||
32 | |||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * Debugfs info | ||
38 | */ | ||
39 | #if defined(CONFIG_DEBUG_FS) | ||
40 | |||
41 | static int radeon_debugfs_pm_info(struct seq_file *m, void *data) | ||
42 | { | ||
43 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
44 | struct drm_device *dev = node->minor->dev; | ||
45 | struct radeon_device *rdev = dev->dev_private; | ||
46 | |||
47 | seq_printf(m, "engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); | ||
48 | seq_printf(m, "memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); | ||
49 | |||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static struct drm_info_list radeon_pm_info_list[] = { | ||
54 | {"radeon_pm_info", radeon_debugfs_pm_info, 0, NULL}, | ||
55 | }; | ||
56 | #endif | ||
57 | |||
58 | int radeon_debugfs_pm_init(struct radeon_device *rdev) | ||
59 | { | ||
60 | #if defined(CONFIG_DEBUG_FS) | ||
61 | return radeon_debugfs_add_files(rdev, radeon_pm_info_list, ARRAY_SIZE(radeon_pm_info_list)); | ||
62 | #else | ||
63 | return 0; | ||
64 | #endif | ||
65 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index bfa1ab9c93e1..6d0a009dd4a1 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -290,6 +290,8 @@ | |||
290 | #define RADEON_BUS_CNTL 0x0030 | 290 | #define RADEON_BUS_CNTL 0x0030 |
291 | # define RADEON_BUS_MASTER_DIS (1 << 6) | 291 | # define RADEON_BUS_MASTER_DIS (1 << 6) |
292 | # define RADEON_BUS_BIOS_DIS_ROM (1 << 12) | 292 | # define RADEON_BUS_BIOS_DIS_ROM (1 << 12) |
293 | # define RS600_BUS_MASTER_DIS (1 << 14) | ||
294 | # define RS600_MSI_REARM (1 << 20) /* rs600/rs690/rs740 */ | ||
293 | # define RADEON_BUS_RD_DISCARD_EN (1 << 24) | 295 | # define RADEON_BUS_RD_DISCARD_EN (1 << 24) |
294 | # define RADEON_BUS_RD_ABORT_EN (1 << 25) | 296 | # define RADEON_BUS_RD_ABORT_EN (1 << 25) |
295 | # define RADEON_BUS_MSTR_DISCONNECT_EN (1 << 28) | 297 | # define RADEON_BUS_MSTR_DISCONNECT_EN (1 << 28) |
@@ -297,6 +299,9 @@ | |||
297 | # define RADEON_BUS_READ_BURST (1 << 30) | 299 | # define RADEON_BUS_READ_BURST (1 << 30) |
298 | #define RADEON_BUS_CNTL1 0x0034 | 300 | #define RADEON_BUS_CNTL1 0x0034 |
299 | # define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) | 301 | # define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) |
302 | /* rv370/rv380, rv410, r423/r430/r480, r5xx */ | ||
303 | #define RADEON_MSI_REARM_EN 0x0160 | ||
304 | # define RV370_MSI_REARM_EN (1 << 0) | ||
300 | 305 | ||
301 | /* #define RADEON_PCIE_INDEX 0x0030 */ | 306 | /* #define RADEON_PCIE_INDEX 0x0030 */ |
302 | /* #define RADEON_PCIE_DATA 0x0034 */ | 307 | /* #define RADEON_PCIE_DATA 0x0034 */ |
@@ -882,6 +887,7 @@ | |||
882 | # define RADEON_FP_PANEL_FORMAT (1 << 3) | 887 | # define RADEON_FP_PANEL_FORMAT (1 << 3) |
883 | # define RADEON_FP_EN_TMDS (1 << 7) | 888 | # define RADEON_FP_EN_TMDS (1 << 7) |
884 | # define RADEON_FP_DETECT_SENSE (1 << 8) | 889 | # define RADEON_FP_DETECT_SENSE (1 << 8) |
890 | # define RADEON_FP_DETECT_INT_POL (1 << 9) | ||
885 | # define R200_FP_SOURCE_SEL_MASK (3 << 10) | 891 | # define R200_FP_SOURCE_SEL_MASK (3 << 10) |
886 | # define R200_FP_SOURCE_SEL_CRTC1 (0 << 10) | 892 | # define R200_FP_SOURCE_SEL_CRTC1 (0 << 10) |
887 | # define R200_FP_SOURCE_SEL_CRTC2 (1 << 10) | 893 | # define R200_FP_SOURCE_SEL_CRTC2 (1 << 10) |
@@ -889,6 +895,7 @@ | |||
889 | # define R200_FP_SOURCE_SEL_TRANS (3 << 10) | 895 | # define R200_FP_SOURCE_SEL_TRANS (3 << 10) |
890 | # define RADEON_FP_SEL_CRTC1 (0 << 13) | 896 | # define RADEON_FP_SEL_CRTC1 (0 << 13) |
891 | # define RADEON_FP_SEL_CRTC2 (1 << 13) | 897 | # define RADEON_FP_SEL_CRTC2 (1 << 13) |
898 | # define R300_HPD_SEL(x) ((x) << 13) | ||
892 | # define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15) | 899 | # define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15) |
893 | # define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) | 900 | # define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) |
894 | # define RADEON_FP_CRTC_DONT_SHADOW_HEND (1 << 17) | 901 | # define RADEON_FP_CRTC_DONT_SHADOW_HEND (1 << 17) |
@@ -904,6 +911,7 @@ | |||
904 | # define RADEON_FP2_ON (1 << 2) | 911 | # define RADEON_FP2_ON (1 << 2) |
905 | # define RADEON_FP2_PANEL_FORMAT (1 << 3) | 912 | # define RADEON_FP2_PANEL_FORMAT (1 << 3) |
906 | # define RADEON_FP2_DETECT_SENSE (1 << 8) | 913 | # define RADEON_FP2_DETECT_SENSE (1 << 8) |
914 | # define RADEON_FP2_DETECT_INT_POL (1 << 9) | ||
907 | # define R200_FP2_SOURCE_SEL_MASK (3 << 10) | 915 | # define R200_FP2_SOURCE_SEL_MASK (3 << 10) |
908 | # define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10) | 916 | # define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10) |
909 | # define R200_FP2_SOURCE_SEL_CRTC2 (1 << 10) | 917 | # define R200_FP2_SOURCE_SEL_CRTC2 (1 << 10) |
@@ -983,14 +991,20 @@ | |||
983 | 991 | ||
984 | #define RADEON_GEN_INT_CNTL 0x0040 | 992 | #define RADEON_GEN_INT_CNTL 0x0040 |
985 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) | 993 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) |
994 | # define RADEON_FP_DETECT_MASK (1 << 4) | ||
986 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) | 995 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) |
996 | # define RADEON_FP2_DETECT_MASK (1 << 10) | ||
987 | # define RADEON_SW_INT_ENABLE (1 << 25) | 997 | # define RADEON_SW_INT_ENABLE (1 << 25) |
988 | #define RADEON_GEN_INT_STATUS 0x0044 | 998 | #define RADEON_GEN_INT_STATUS 0x0044 |
989 | # define AVIVO_DISPLAY_INT_STATUS (1 << 0) | 999 | # define AVIVO_DISPLAY_INT_STATUS (1 << 0) |
990 | # define RADEON_CRTC_VBLANK_STAT (1 << 0) | 1000 | # define RADEON_CRTC_VBLANK_STAT (1 << 0) |
991 | # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) | 1001 | # define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) |
1002 | # define RADEON_FP_DETECT_STAT (1 << 4) | ||
1003 | # define RADEON_FP_DETECT_STAT_ACK (1 << 4) | ||
992 | # define RADEON_CRTC2_VBLANK_STAT (1 << 9) | 1004 | # define RADEON_CRTC2_VBLANK_STAT (1 << 9) |
993 | # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) | 1005 | # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) |
1006 | # define RADEON_FP2_DETECT_STAT (1 << 10) | ||
1007 | # define RADEON_FP2_DETECT_STAT_ACK (1 << 10) | ||
994 | # define RADEON_SW_INT_FIRE (1 << 26) | 1008 | # define RADEON_SW_INT_FIRE (1 << 26) |
995 | # define RADEON_SW_INT_TEST (1 << 25) | 1009 | # define RADEON_SW_INT_TEST (1 << 25) |
996 | # define RADEON_SW_INT_TEST_ACK (1 << 25) | 1010 | # define RADEON_SW_INT_TEST_ACK (1 << 25) |
@@ -1046,20 +1060,25 @@ | |||
1046 | 1060 | ||
1047 | /* Multimedia I2C bus */ | 1061 | /* Multimedia I2C bus */ |
1048 | #define RADEON_I2C_CNTL_0 0x0090 | 1062 | #define RADEON_I2C_CNTL_0 0x0090 |
1049 | #define RADEON_I2C_DONE (1<<0) | 1063 | #define RADEON_I2C_DONE (1 << 0) |
1050 | #define RADEON_I2C_NACK (1<<1) | 1064 | #define RADEON_I2C_NACK (1 << 1) |
1051 | #define RADEON_I2C_HALT (1<<2) | 1065 | #define RADEON_I2C_HALT (1 << 2) |
1052 | #define RADEON_I2C_SOFT_RST (1<<5) | 1066 | #define RADEON_I2C_SOFT_RST (1 << 5) |
1053 | #define RADEON_I2C_DRIVE_EN (1<<6) | 1067 | #define RADEON_I2C_DRIVE_EN (1 << 6) |
1054 | #define RADEON_I2C_DRIVE_SEL (1<<7) | 1068 | #define RADEON_I2C_DRIVE_SEL (1 << 7) |
1055 | #define RADEON_I2C_START (1<<8) | 1069 | #define RADEON_I2C_START (1 << 8) |
1056 | #define RADEON_I2C_STOP (1<<9) | 1070 | #define RADEON_I2C_STOP (1 << 9) |
1057 | #define RADEON_I2C_RECEIVE (1<<10) | 1071 | #define RADEON_I2C_RECEIVE (1 << 10) |
1058 | #define RADEON_I2C_ABORT (1<<11) | 1072 | #define RADEON_I2C_ABORT (1 << 11) |
1059 | #define RADEON_I2C_GO (1<<12) | 1073 | #define RADEON_I2C_GO (1 << 12) |
1074 | #define RADEON_I2C_PRESCALE_SHIFT 16 | ||
1060 | #define RADEON_I2C_CNTL_1 0x0094 | 1075 | #define RADEON_I2C_CNTL_1 0x0094 |
1061 | #define RADEON_I2C_SEL (1<<16) | 1076 | #define RADEON_I2C_DATA_COUNT_SHIFT 0 |
1062 | #define RADEON_I2C_EN (1<<17) | 1077 | #define RADEON_I2C_ADDR_COUNT_SHIFT 4 |
1078 | #define RADEON_I2C_INTRA_BYTE_DELAY_SHIFT 8 | ||
1079 | #define RADEON_I2C_SEL (1 << 16) | ||
1080 | #define RADEON_I2C_EN (1 << 17) | ||
1081 | #define RADEON_I2C_TIME_LIMIT_SHIFT 24 | ||
1063 | #define RADEON_I2C_DATA 0x0098 | 1082 | #define RADEON_I2C_DATA 0x0098 |
1064 | 1083 | ||
1065 | #define RADEON_DVI_I2C_CNTL_0 0x02e0 | 1084 | #define RADEON_DVI_I2C_CNTL_0 0x02e0 |
@@ -1067,7 +1086,7 @@ | |||
1067 | # define R200_SEL_DDC1 0 /* 0x60 - VGA_DDC */ | 1086 | # define R200_SEL_DDC1 0 /* 0x60 - VGA_DDC */ |
1068 | # define R200_SEL_DDC2 1 /* 0x64 - DVI_DDC */ | 1087 | # define R200_SEL_DDC2 1 /* 0x64 - DVI_DDC */ |
1069 | # define R200_SEL_DDC3 2 /* 0x68 - MONID_DDC */ | 1088 | # define R200_SEL_DDC3 2 /* 0x68 - MONID_DDC */ |
1070 | #define RADEON_DVI_I2C_CNTL_1 0x02e4 /* ? */ | 1089 | #define RADEON_DVI_I2C_CNTL_1 0x02e4 |
1071 | #define RADEON_DVI_I2C_DATA 0x02e8 | 1090 | #define RADEON_DVI_I2C_DATA 0x02e8 |
1072 | 1091 | ||
1073 | #define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */ | 1092 | #define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */ |
@@ -1138,15 +1157,16 @@ | |||
1138 | # define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13) | 1157 | # define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13) |
1139 | # define RADEON_MC_MCLK_DYN_ENABLE (1 << 14) | 1158 | # define RADEON_MC_MCLK_DYN_ENABLE (1 << 14) |
1140 | # define RADEON_IO_MCLK_DYN_ENABLE (1 << 15) | 1159 | # define RADEON_IO_MCLK_DYN_ENABLE (1 << 15) |
1141 | #define RADEON_LCD_GPIO_MASK 0x01a0 | 1160 | |
1142 | #define RADEON_GPIOPAD_EN 0x01a0 | ||
1143 | #define RADEON_LCD_GPIO_Y_REG 0x01a4 | ||
1144 | #define RADEON_MDGPIO_A_REG 0x01ac | ||
1145 | #define RADEON_MDGPIO_EN_REG 0x01b0 | ||
1146 | #define RADEON_MDGPIO_MASK 0x0198 | ||
1147 | #define RADEON_GPIOPAD_MASK 0x0198 | 1161 | #define RADEON_GPIOPAD_MASK 0x0198 |
1148 | #define RADEON_GPIOPAD_A 0x019c | 1162 | #define RADEON_GPIOPAD_A 0x019c |
1149 | #define RADEON_MDGPIO_Y_REG 0x01b4 | 1163 | #define RADEON_GPIOPAD_EN 0x01a0 |
1164 | #define RADEON_GPIOPAD_Y 0x01a4 | ||
1165 | #define RADEON_MDGPIO_MASK 0x01a8 | ||
1166 | #define RADEON_MDGPIO_A 0x01ac | ||
1167 | #define RADEON_MDGPIO_EN 0x01b0 | ||
1168 | #define RADEON_MDGPIO_Y 0x01b4 | ||
1169 | |||
1150 | #define RADEON_MEM_ADDR_CONFIG 0x0148 | 1170 | #define RADEON_MEM_ADDR_CONFIG 0x0148 |
1151 | #define RADEON_MEM_BASE 0x0f10 /* PCI */ | 1171 | #define RADEON_MEM_BASE 0x0f10 /* PCI */ |
1152 | #define RADEON_MEM_CNTL 0x0140 | 1172 | #define RADEON_MEM_CNTL 0x0140 |
@@ -1355,6 +1375,9 @@ | |||
1355 | #define RADEON_OVR_CLR 0x0230 | 1375 | #define RADEON_OVR_CLR 0x0230 |
1356 | #define RADEON_OVR_WID_LEFT_RIGHT 0x0234 | 1376 | #define RADEON_OVR_WID_LEFT_RIGHT 0x0234 |
1357 | #define RADEON_OVR_WID_TOP_BOTTOM 0x0238 | 1377 | #define RADEON_OVR_WID_TOP_BOTTOM 0x0238 |
1378 | #define RADEON_OVR2_CLR 0x0330 | ||
1379 | #define RADEON_OVR2_WID_LEFT_RIGHT 0x0334 | ||
1380 | #define RADEON_OVR2_WID_TOP_BOTTOM 0x0338 | ||
1358 | 1381 | ||
1359 | /* first capture unit */ | 1382 | /* first capture unit */ |
1360 | 1383 | ||
@@ -3311,6 +3334,7 @@ | |||
3311 | #define RADEON_AIC_CNTL 0x01d0 | 3334 | #define RADEON_AIC_CNTL 0x01d0 |
3312 | # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) | 3335 | # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) |
3313 | # define RADEON_DIS_OUT_OF_PCI_GART_ACCESS (1 << 1) | 3336 | # define RADEON_DIS_OUT_OF_PCI_GART_ACCESS (1 << 1) |
3337 | # define RS400_MSI_REARM (1 << 3) /* rs400/rs480 */ | ||
3314 | #define RADEON_AIC_LO_ADDR 0x01dc | 3338 | #define RADEON_AIC_LO_ADDR 0x01dc |
3315 | #define RADEON_AIC_PT_BASE 0x01d8 | 3339 | #define RADEON_AIC_PT_BASE 0x01d8 |
3316 | #define RADEON_AIC_HI_ADDR 0x01e0 | 3340 | #define RADEON_AIC_HI_ADDR 0x01e0 |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 747b4bffb84b..4d12b2d17b4d 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -165,19 +165,24 @@ int radeon_ib_pool_init(struct radeon_device *rdev) | |||
165 | return 0; | 165 | return 0; |
166 | /* Allocate 1M object buffer */ | 166 | /* Allocate 1M object buffer */ |
167 | INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs); | 167 | INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs); |
168 | r = radeon_object_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, | 168 | r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, |
169 | true, RADEON_GEM_DOMAIN_GTT, | 169 | true, RADEON_GEM_DOMAIN_GTT, |
170 | false, &rdev->ib_pool.robj); | 170 | &rdev->ib_pool.robj); |
171 | if (r) { | 171 | if (r) { |
172 | DRM_ERROR("radeon: failed to ib pool (%d).\n", r); | 172 | DRM_ERROR("radeon: failed to ib pool (%d).\n", r); |
173 | return r; | 173 | return r; |
174 | } | 174 | } |
175 | r = radeon_object_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr); | 175 | r = radeon_bo_reserve(rdev->ib_pool.robj, false); |
176 | if (unlikely(r != 0)) | ||
177 | return r; | ||
178 | r = radeon_bo_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr); | ||
176 | if (r) { | 179 | if (r) { |
180 | radeon_bo_unreserve(rdev->ib_pool.robj); | ||
177 | DRM_ERROR("radeon: failed to pin ib pool (%d).\n", r); | 181 | DRM_ERROR("radeon: failed to pin ib pool (%d).\n", r); |
178 | return r; | 182 | return r; |
179 | } | 183 | } |
180 | r = radeon_object_kmap(rdev->ib_pool.robj, &ptr); | 184 | r = radeon_bo_kmap(rdev->ib_pool.robj, &ptr); |
185 | radeon_bo_unreserve(rdev->ib_pool.robj); | ||
181 | if (r) { | 186 | if (r) { |
182 | DRM_ERROR("radeon: failed to map ib poll (%d).\n", r); | 187 | DRM_ERROR("radeon: failed to map ib poll (%d).\n", r); |
183 | return r; | 188 | return r; |
@@ -203,14 +208,21 @@ int radeon_ib_pool_init(struct radeon_device *rdev) | |||
203 | 208 | ||
204 | void radeon_ib_pool_fini(struct radeon_device *rdev) | 209 | void radeon_ib_pool_fini(struct radeon_device *rdev) |
205 | { | 210 | { |
211 | int r; | ||
212 | |||
206 | if (!rdev->ib_pool.ready) { | 213 | if (!rdev->ib_pool.ready) { |
207 | return; | 214 | return; |
208 | } | 215 | } |
209 | mutex_lock(&rdev->ib_pool.mutex); | 216 | mutex_lock(&rdev->ib_pool.mutex); |
210 | bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); | 217 | bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); |
211 | if (rdev->ib_pool.robj) { | 218 | if (rdev->ib_pool.robj) { |
212 | radeon_object_kunmap(rdev->ib_pool.robj); | 219 | r = radeon_bo_reserve(rdev->ib_pool.robj, false); |
213 | radeon_object_unref(&rdev->ib_pool.robj); | 220 | if (likely(r == 0)) { |
221 | radeon_bo_kunmap(rdev->ib_pool.robj); | ||
222 | radeon_bo_unpin(rdev->ib_pool.robj); | ||
223 | radeon_bo_unreserve(rdev->ib_pool.robj); | ||
224 | } | ||
225 | radeon_bo_unref(&rdev->ib_pool.robj); | ||
214 | rdev->ib_pool.robj = NULL; | 226 | rdev->ib_pool.robj = NULL; |
215 | } | 227 | } |
216 | mutex_unlock(&rdev->ib_pool.mutex); | 228 | mutex_unlock(&rdev->ib_pool.mutex); |
@@ -288,29 +300,28 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) | |||
288 | rdev->cp.ring_size = ring_size; | 300 | rdev->cp.ring_size = ring_size; |
289 | /* Allocate ring buffer */ | 301 | /* Allocate ring buffer */ |
290 | if (rdev->cp.ring_obj == NULL) { | 302 | if (rdev->cp.ring_obj == NULL) { |
291 | r = radeon_object_create(rdev, NULL, rdev->cp.ring_size, | 303 | r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, true, |
292 | true, | 304 | RADEON_GEM_DOMAIN_GTT, |
293 | RADEON_GEM_DOMAIN_GTT, | 305 | &rdev->cp.ring_obj); |
294 | false, | ||
295 | &rdev->cp.ring_obj); | ||
296 | if (r) { | 306 | if (r) { |
297 | DRM_ERROR("radeon: failed to create ring buffer (%d).\n", r); | 307 | dev_err(rdev->dev, "(%d) ring create failed\n", r); |
298 | mutex_unlock(&rdev->cp.mutex); | ||
299 | return r; | 308 | return r; |
300 | } | 309 | } |
301 | r = radeon_object_pin(rdev->cp.ring_obj, | 310 | r = radeon_bo_reserve(rdev->cp.ring_obj, false); |
302 | RADEON_GEM_DOMAIN_GTT, | 311 | if (unlikely(r != 0)) |
303 | &rdev->cp.gpu_addr); | 312 | return r; |
313 | r = radeon_bo_pin(rdev->cp.ring_obj, RADEON_GEM_DOMAIN_GTT, | ||
314 | &rdev->cp.gpu_addr); | ||
304 | if (r) { | 315 | if (r) { |
305 | DRM_ERROR("radeon: failed to pin ring buffer (%d).\n", r); | 316 | radeon_bo_unreserve(rdev->cp.ring_obj); |
306 | mutex_unlock(&rdev->cp.mutex); | 317 | dev_err(rdev->dev, "(%d) ring pin failed\n", r); |
307 | return r; | 318 | return r; |
308 | } | 319 | } |
309 | r = radeon_object_kmap(rdev->cp.ring_obj, | 320 | r = radeon_bo_kmap(rdev->cp.ring_obj, |
310 | (void **)&rdev->cp.ring); | 321 | (void **)&rdev->cp.ring); |
322 | radeon_bo_unreserve(rdev->cp.ring_obj); | ||
311 | if (r) { | 323 | if (r) { |
312 | DRM_ERROR("radeon: failed to map ring buffer (%d).\n", r); | 324 | dev_err(rdev->dev, "(%d) ring map failed\n", r); |
313 | mutex_unlock(&rdev->cp.mutex); | ||
314 | return r; | 325 | return r; |
315 | } | 326 | } |
316 | } | 327 | } |
@@ -321,11 +332,17 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) | |||
321 | 332 | ||
322 | void radeon_ring_fini(struct radeon_device *rdev) | 333 | void radeon_ring_fini(struct radeon_device *rdev) |
323 | { | 334 | { |
335 | int r; | ||
336 | |||
324 | mutex_lock(&rdev->cp.mutex); | 337 | mutex_lock(&rdev->cp.mutex); |
325 | if (rdev->cp.ring_obj) { | 338 | if (rdev->cp.ring_obj) { |
326 | radeon_object_kunmap(rdev->cp.ring_obj); | 339 | r = radeon_bo_reserve(rdev->cp.ring_obj, false); |
327 | radeon_object_unpin(rdev->cp.ring_obj); | 340 | if (likely(r == 0)) { |
328 | radeon_object_unref(&rdev->cp.ring_obj); | 341 | radeon_bo_kunmap(rdev->cp.ring_obj); |
342 | radeon_bo_unpin(rdev->cp.ring_obj); | ||
343 | radeon_bo_unreserve(rdev->cp.ring_obj); | ||
344 | } | ||
345 | radeon_bo_unref(&rdev->cp.ring_obj); | ||
329 | rdev->cp.ring = NULL; | 346 | rdev->cp.ring = NULL; |
330 | rdev->cp.ring_obj = NULL; | 347 | rdev->cp.ring_obj = NULL; |
331 | } | 348 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 38537d971a3e..067167cb39ca 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -1950,7 +1950,7 @@ static void radeon_apply_surface_regs(int surf_index, | |||
1950 | * Note that refcount can be at most 2, since during a free refcount=3 | 1950 | * Note that refcount can be at most 2, since during a free refcount=3 |
1951 | * might mean we have to allocate a new surface which might not always | 1951 | * might mean we have to allocate a new surface which might not always |
1952 | * be available. | 1952 | * be available. |
1953 | * For example : we allocate three contigous surfaces ABC. If B is | 1953 | * For example : we allocate three contiguous surfaces ABC. If B is |
1954 | * freed, we suddenly need two surfaces to store A and C, which might | 1954 | * freed, we suddenly need two surfaces to store A and C, which might |
1955 | * not always be available. | 1955 | * not always be available. |
1956 | */ | 1956 | */ |
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 03c33cf4e14c..391c973ec4db 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c | |||
@@ -30,8 +30,8 @@ | |||
30 | /* Test BO GTT->VRAM and VRAM->GTT GPU copies across the whole GTT aperture */ | 30 | /* Test BO GTT->VRAM and VRAM->GTT GPU copies across the whole GTT aperture */ |
31 | void radeon_test_moves(struct radeon_device *rdev) | 31 | void radeon_test_moves(struct radeon_device *rdev) |
32 | { | 32 | { |
33 | struct radeon_object *vram_obj = NULL; | 33 | struct radeon_bo *vram_obj = NULL; |
34 | struct radeon_object **gtt_obj = NULL; | 34 | struct radeon_bo **gtt_obj = NULL; |
35 | struct radeon_fence *fence = NULL; | 35 | struct radeon_fence *fence = NULL; |
36 | uint64_t gtt_addr, vram_addr; | 36 | uint64_t gtt_addr, vram_addr; |
37 | unsigned i, n, size; | 37 | unsigned i, n, size; |
@@ -42,7 +42,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
42 | /* Number of tests = | 42 | /* Number of tests = |
43 | * (Total GTT - IB pool - writeback page - ring buffer) / test size | 43 | * (Total GTT - IB pool - writeback page - ring buffer) / test size |
44 | */ | 44 | */ |
45 | n = (rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - 4096 - | 45 | n = (rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE - |
46 | rdev->cp.ring_size) / size; | 46 | rdev->cp.ring_size) / size; |
47 | 47 | ||
48 | gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); | 48 | gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); |
@@ -52,38 +52,42 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
52 | goto out_cleanup; | 52 | goto out_cleanup; |
53 | } | 53 | } |
54 | 54 | ||
55 | r = radeon_object_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM, | 55 | r = radeon_bo_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM, |
56 | false, &vram_obj); | 56 | &vram_obj); |
57 | if (r) { | 57 | if (r) { |
58 | DRM_ERROR("Failed to create VRAM object\n"); | 58 | DRM_ERROR("Failed to create VRAM object\n"); |
59 | goto out_cleanup; | 59 | goto out_cleanup; |
60 | } | 60 | } |
61 | 61 | r = radeon_bo_reserve(vram_obj, false); | |
62 | r = radeon_object_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr); | 62 | if (unlikely(r != 0)) |
63 | goto out_cleanup; | ||
64 | r = radeon_bo_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr); | ||
63 | if (r) { | 65 | if (r) { |
64 | DRM_ERROR("Failed to pin VRAM object\n"); | 66 | DRM_ERROR("Failed to pin VRAM object\n"); |
65 | goto out_cleanup; | 67 | goto out_cleanup; |
66 | } | 68 | } |
67 | |||
68 | for (i = 0; i < n; i++) { | 69 | for (i = 0; i < n; i++) { |
69 | void *gtt_map, *vram_map; | 70 | void *gtt_map, *vram_map; |
70 | void **gtt_start, **gtt_end; | 71 | void **gtt_start, **gtt_end; |
71 | void **vram_start, **vram_end; | 72 | void **vram_start, **vram_end; |
72 | 73 | ||
73 | r = radeon_object_create(rdev, NULL, size, true, | 74 | r = radeon_bo_create(rdev, NULL, size, true, |
74 | RADEON_GEM_DOMAIN_GTT, false, gtt_obj + i); | 75 | RADEON_GEM_DOMAIN_GTT, gtt_obj + i); |
75 | if (r) { | 76 | if (r) { |
76 | DRM_ERROR("Failed to create GTT object %d\n", i); | 77 | DRM_ERROR("Failed to create GTT object %d\n", i); |
77 | goto out_cleanup; | 78 | goto out_cleanup; |
78 | } | 79 | } |
79 | 80 | ||
80 | r = radeon_object_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, >t_addr); | 81 | r = radeon_bo_reserve(gtt_obj[i], false); |
82 | if (unlikely(r != 0)) | ||
83 | goto out_cleanup; | ||
84 | r = radeon_bo_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, >t_addr); | ||
81 | if (r) { | 85 | if (r) { |
82 | DRM_ERROR("Failed to pin GTT object %d\n", i); | 86 | DRM_ERROR("Failed to pin GTT object %d\n", i); |
83 | goto out_cleanup; | 87 | goto out_cleanup; |
84 | } | 88 | } |
85 | 89 | ||
86 | r = radeon_object_kmap(gtt_obj[i], >t_map); | 90 | r = radeon_bo_kmap(gtt_obj[i], >t_map); |
87 | if (r) { | 91 | if (r) { |
88 | DRM_ERROR("Failed to map GTT object %d\n", i); | 92 | DRM_ERROR("Failed to map GTT object %d\n", i); |
89 | goto out_cleanup; | 93 | goto out_cleanup; |
@@ -94,7 +98,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
94 | gtt_start++) | 98 | gtt_start++) |
95 | *gtt_start = gtt_start; | 99 | *gtt_start = gtt_start; |
96 | 100 | ||
97 | radeon_object_kunmap(gtt_obj[i]); | 101 | radeon_bo_kunmap(gtt_obj[i]); |
98 | 102 | ||
99 | r = radeon_fence_create(rdev, &fence); | 103 | r = radeon_fence_create(rdev, &fence); |
100 | if (r) { | 104 | if (r) { |
@@ -102,7 +106,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
102 | goto out_cleanup; | 106 | goto out_cleanup; |
103 | } | 107 | } |
104 | 108 | ||
105 | r = radeon_copy(rdev, gtt_addr, vram_addr, size / 4096, fence); | 109 | r = radeon_copy(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, fence); |
106 | if (r) { | 110 | if (r) { |
107 | DRM_ERROR("Failed GTT->VRAM copy %d\n", i); | 111 | DRM_ERROR("Failed GTT->VRAM copy %d\n", i); |
108 | goto out_cleanup; | 112 | goto out_cleanup; |
@@ -116,7 +120,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
116 | 120 | ||
117 | radeon_fence_unref(&fence); | 121 | radeon_fence_unref(&fence); |
118 | 122 | ||
119 | r = radeon_object_kmap(vram_obj, &vram_map); | 123 | r = radeon_bo_kmap(vram_obj, &vram_map); |
120 | if (r) { | 124 | if (r) { |
121 | DRM_ERROR("Failed to map VRAM object after copy %d\n", i); | 125 | DRM_ERROR("Failed to map VRAM object after copy %d\n", i); |
122 | goto out_cleanup; | 126 | goto out_cleanup; |
@@ -131,13 +135,13 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
131 | "expected 0x%p (GTT map 0x%p-0x%p)\n", | 135 | "expected 0x%p (GTT map 0x%p-0x%p)\n", |
132 | i, *vram_start, gtt_start, gtt_map, | 136 | i, *vram_start, gtt_start, gtt_map, |
133 | gtt_end); | 137 | gtt_end); |
134 | radeon_object_kunmap(vram_obj); | 138 | radeon_bo_kunmap(vram_obj); |
135 | goto out_cleanup; | 139 | goto out_cleanup; |
136 | } | 140 | } |
137 | *vram_start = vram_start; | 141 | *vram_start = vram_start; |
138 | } | 142 | } |
139 | 143 | ||
140 | radeon_object_kunmap(vram_obj); | 144 | radeon_bo_kunmap(vram_obj); |
141 | 145 | ||
142 | r = radeon_fence_create(rdev, &fence); | 146 | r = radeon_fence_create(rdev, &fence); |
143 | if (r) { | 147 | if (r) { |
@@ -145,7 +149,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
145 | goto out_cleanup; | 149 | goto out_cleanup; |
146 | } | 150 | } |
147 | 151 | ||
148 | r = radeon_copy(rdev, vram_addr, gtt_addr, size / 4096, fence); | 152 | r = radeon_copy(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, fence); |
149 | if (r) { | 153 | if (r) { |
150 | DRM_ERROR("Failed VRAM->GTT copy %d\n", i); | 154 | DRM_ERROR("Failed VRAM->GTT copy %d\n", i); |
151 | goto out_cleanup; | 155 | goto out_cleanup; |
@@ -159,7 +163,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
159 | 163 | ||
160 | radeon_fence_unref(&fence); | 164 | radeon_fence_unref(&fence); |
161 | 165 | ||
162 | r = radeon_object_kmap(gtt_obj[i], >t_map); | 166 | r = radeon_bo_kmap(gtt_obj[i], >t_map); |
163 | if (r) { | 167 | if (r) { |
164 | DRM_ERROR("Failed to map GTT object after copy %d\n", i); | 168 | DRM_ERROR("Failed to map GTT object after copy %d\n", i); |
165 | goto out_cleanup; | 169 | goto out_cleanup; |
@@ -174,12 +178,12 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
174 | "expected 0x%p (VRAM map 0x%p-0x%p)\n", | 178 | "expected 0x%p (VRAM map 0x%p-0x%p)\n", |
175 | i, *gtt_start, vram_start, vram_map, | 179 | i, *gtt_start, vram_start, vram_map, |
176 | vram_end); | 180 | vram_end); |
177 | radeon_object_kunmap(gtt_obj[i]); | 181 | radeon_bo_kunmap(gtt_obj[i]); |
178 | goto out_cleanup; | 182 | goto out_cleanup; |
179 | } | 183 | } |
180 | } | 184 | } |
181 | 185 | ||
182 | radeon_object_kunmap(gtt_obj[i]); | 186 | radeon_bo_kunmap(gtt_obj[i]); |
183 | 187 | ||
184 | DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n", | 188 | DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n", |
185 | gtt_addr - rdev->mc.gtt_location); | 189 | gtt_addr - rdev->mc.gtt_location); |
@@ -187,14 +191,20 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
187 | 191 | ||
188 | out_cleanup: | 192 | out_cleanup: |
189 | if (vram_obj) { | 193 | if (vram_obj) { |
190 | radeon_object_unpin(vram_obj); | 194 | if (radeon_bo_is_reserved(vram_obj)) { |
191 | radeon_object_unref(&vram_obj); | 195 | radeon_bo_unpin(vram_obj); |
196 | radeon_bo_unreserve(vram_obj); | ||
197 | } | ||
198 | radeon_bo_unref(&vram_obj); | ||
192 | } | 199 | } |
193 | if (gtt_obj) { | 200 | if (gtt_obj) { |
194 | for (i = 0; i < n; i++) { | 201 | for (i = 0; i < n; i++) { |
195 | if (gtt_obj[i]) { | 202 | if (gtt_obj[i]) { |
196 | radeon_object_unpin(gtt_obj[i]); | 203 | if (radeon_bo_is_reserved(gtt_obj[i])) { |
197 | radeon_object_unref(>t_obj[i]); | 204 | radeon_bo_unpin(gtt_obj[i]); |
205 | radeon_bo_unreserve(gtt_obj[i]); | ||
206 | } | ||
207 | radeon_bo_unref(>t_obj[i]); | ||
198 | } | 208 | } |
199 | } | 209 | } |
200 | kfree(gtt_obj); | 210 | kfree(gtt_obj); |
@@ -206,4 +216,3 @@ out_cleanup: | |||
206 | printk(KERN_WARNING "Error while testing BO move.\n"); | 216 | printk(KERN_WARNING "Error while testing BO move.\n"); |
207 | } | 217 | } |
208 | } | 218 | } |
209 | |||
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 765bd184b6fc..5a19d529d1c0 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -150,7 +150,7 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
150 | man->default_caching = TTM_PL_FLAG_CACHED; | 150 | man->default_caching = TTM_PL_FLAG_CACHED; |
151 | break; | 151 | break; |
152 | case TTM_PL_TT: | 152 | case TTM_PL_TT: |
153 | man->gpu_offset = 0; | 153 | man->gpu_offset = rdev->mc.gtt_location; |
154 | man->available_caching = TTM_PL_MASK_CACHING; | 154 | man->available_caching = TTM_PL_MASK_CACHING; |
155 | man->default_caching = TTM_PL_FLAG_CACHED; | 155 | man->default_caching = TTM_PL_FLAG_CACHED; |
156 | man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA; | 156 | man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA; |
@@ -180,7 +180,7 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
180 | break; | 180 | break; |
181 | case TTM_PL_VRAM: | 181 | case TTM_PL_VRAM: |
182 | /* "On-card" video ram */ | 182 | /* "On-card" video ram */ |
183 | man->gpu_offset = 0; | 183 | man->gpu_offset = rdev->mc.vram_location; |
184 | man->flags = TTM_MEMTYPE_FLAG_FIXED | | 184 | man->flags = TTM_MEMTYPE_FLAG_FIXED | |
185 | TTM_MEMTYPE_FLAG_NEEDS_IOREMAP | | 185 | TTM_MEMTYPE_FLAG_NEEDS_IOREMAP | |
186 | TTM_MEMTYPE_FLAG_MAPPABLE; | 186 | TTM_MEMTYPE_FLAG_MAPPABLE; |
@@ -197,16 +197,19 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
200 | static uint32_t radeon_evict_flags(struct ttm_buffer_object *bo) | 200 | static void radeon_evict_flags(struct ttm_buffer_object *bo, |
201 | struct ttm_placement *placement) | ||
201 | { | 202 | { |
202 | uint32_t cur_placement = bo->mem.placement & ~TTM_PL_MASK_MEMTYPE; | 203 | struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo); |
203 | |||
204 | switch (bo->mem.mem_type) { | 204 | switch (bo->mem.mem_type) { |
205 | case TTM_PL_VRAM: | ||
206 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); | ||
207 | break; | ||
208 | case TTM_PL_TT: | ||
205 | default: | 209 | default: |
206 | return (cur_placement & ~TTM_PL_MASK_CACHING) | | 210 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); |
207 | TTM_PL_FLAG_SYSTEM | | ||
208 | TTM_PL_FLAG_CACHED; | ||
209 | } | 211 | } |
212 | *placement = rbo->placement; | ||
210 | } | 213 | } |
211 | 214 | ||
212 | static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp) | 215 | static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp) |
@@ -283,18 +286,31 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo, | |||
283 | struct radeon_device *rdev; | 286 | struct radeon_device *rdev; |
284 | struct ttm_mem_reg *old_mem = &bo->mem; | 287 | struct ttm_mem_reg *old_mem = &bo->mem; |
285 | struct ttm_mem_reg tmp_mem; | 288 | struct ttm_mem_reg tmp_mem; |
286 | uint32_t proposed_placement; | 289 | u32 placements; |
290 | struct ttm_placement placement; | ||
287 | int r; | 291 | int r; |
288 | 292 | ||
289 | rdev = radeon_get_rdev(bo->bdev); | 293 | rdev = radeon_get_rdev(bo->bdev); |
290 | tmp_mem = *new_mem; | 294 | tmp_mem = *new_mem; |
291 | tmp_mem.mm_node = NULL; | 295 | tmp_mem.mm_node = NULL; |
292 | proposed_placement = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; | 296 | placement.fpfn = 0; |
293 | r = ttm_bo_mem_space(bo, proposed_placement, &tmp_mem, | 297 | placement.lpfn = 0; |
298 | placement.num_placement = 1; | ||
299 | placement.placement = &placements; | ||
300 | placement.num_busy_placement = 1; | ||
301 | placement.busy_placement = &placements; | ||
302 | placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; | ||
303 | r = ttm_bo_mem_space(bo, &placement, &tmp_mem, | ||
294 | interruptible, no_wait); | 304 | interruptible, no_wait); |
295 | if (unlikely(r)) { | 305 | if (unlikely(r)) { |
296 | return r; | 306 | return r; |
297 | } | 307 | } |
308 | |||
309 | r = ttm_tt_set_placement_caching(bo->ttm, tmp_mem.placement); | ||
310 | if (unlikely(r)) { | ||
311 | goto out_cleanup; | ||
312 | } | ||
313 | |||
298 | r = ttm_tt_bind(bo->ttm, &tmp_mem); | 314 | r = ttm_tt_bind(bo->ttm, &tmp_mem); |
299 | if (unlikely(r)) { | 315 | if (unlikely(r)) { |
300 | goto out_cleanup; | 316 | goto out_cleanup; |
@@ -323,15 +339,21 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo, | |||
323 | struct radeon_device *rdev; | 339 | struct radeon_device *rdev; |
324 | struct ttm_mem_reg *old_mem = &bo->mem; | 340 | struct ttm_mem_reg *old_mem = &bo->mem; |
325 | struct ttm_mem_reg tmp_mem; | 341 | struct ttm_mem_reg tmp_mem; |
326 | uint32_t proposed_flags; | 342 | struct ttm_placement placement; |
343 | u32 placements; | ||
327 | int r; | 344 | int r; |
328 | 345 | ||
329 | rdev = radeon_get_rdev(bo->bdev); | 346 | rdev = radeon_get_rdev(bo->bdev); |
330 | tmp_mem = *new_mem; | 347 | tmp_mem = *new_mem; |
331 | tmp_mem.mm_node = NULL; | 348 | tmp_mem.mm_node = NULL; |
332 | proposed_flags = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; | 349 | placement.fpfn = 0; |
333 | r = ttm_bo_mem_space(bo, proposed_flags, &tmp_mem, | 350 | placement.lpfn = 0; |
334 | interruptible, no_wait); | 351 | placement.num_placement = 1; |
352 | placement.placement = &placements; | ||
353 | placement.num_busy_placement = 1; | ||
354 | placement.busy_placement = &placements; | ||
355 | placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; | ||
356 | r = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible, no_wait); | ||
335 | if (unlikely(r)) { | 357 | if (unlikely(r)) { |
336 | return r; | 358 | return r; |
337 | } | 359 | } |
@@ -372,7 +394,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, | |||
372 | new_mem->mem_type == TTM_PL_SYSTEM) || | 394 | new_mem->mem_type == TTM_PL_SYSTEM) || |
373 | (old_mem->mem_type == TTM_PL_SYSTEM && | 395 | (old_mem->mem_type == TTM_PL_SYSTEM && |
374 | new_mem->mem_type == TTM_PL_TT)) { | 396 | new_mem->mem_type == TTM_PL_TT)) { |
375 | /* bind is enought */ | 397 | /* bind is enough */ |
376 | radeon_move_null(bo, new_mem); | 398 | radeon_move_null(bo, new_mem); |
377 | return 0; | 399 | return 0; |
378 | } | 400 | } |
@@ -401,18 +423,6 @@ memcpy: | |||
401 | return r; | 423 | return r; |
402 | } | 424 | } |
403 | 425 | ||
404 | const uint32_t radeon_mem_prios[] = { | ||
405 | TTM_PL_VRAM, | ||
406 | TTM_PL_TT, | ||
407 | TTM_PL_SYSTEM, | ||
408 | }; | ||
409 | |||
410 | const uint32_t radeon_busy_prios[] = { | ||
411 | TTM_PL_TT, | ||
412 | TTM_PL_VRAM, | ||
413 | TTM_PL_SYSTEM, | ||
414 | }; | ||
415 | |||
416 | static int radeon_sync_obj_wait(void *sync_obj, void *sync_arg, | 426 | static int radeon_sync_obj_wait(void *sync_obj, void *sync_arg, |
417 | bool lazy, bool interruptible) | 427 | bool lazy, bool interruptible) |
418 | { | 428 | { |
@@ -440,10 +450,6 @@ static bool radeon_sync_obj_signaled(void *sync_obj, void *sync_arg) | |||
440 | } | 450 | } |
441 | 451 | ||
442 | static struct ttm_bo_driver radeon_bo_driver = { | 452 | static struct ttm_bo_driver radeon_bo_driver = { |
443 | .mem_type_prio = radeon_mem_prios, | ||
444 | .mem_busy_prio = radeon_busy_prios, | ||
445 | .num_mem_type_prio = ARRAY_SIZE(radeon_mem_prios), | ||
446 | .num_mem_busy_prio = ARRAY_SIZE(radeon_busy_prios), | ||
447 | .create_ttm_backend_entry = &radeon_create_ttm_backend_entry, | 453 | .create_ttm_backend_entry = &radeon_create_ttm_backend_entry, |
448 | .invalidate_caches = &radeon_invalidate_caches, | 454 | .invalidate_caches = &radeon_invalidate_caches, |
449 | .init_mem_type = &radeon_init_mem_type, | 455 | .init_mem_type = &radeon_init_mem_type, |
@@ -476,27 +482,31 @@ int radeon_ttm_init(struct radeon_device *rdev) | |||
476 | DRM_ERROR("failed initializing buffer object driver(%d).\n", r); | 482 | DRM_ERROR("failed initializing buffer object driver(%d).\n", r); |
477 | return r; | 483 | return r; |
478 | } | 484 | } |
479 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, 0, | 485 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, |
480 | ((rdev->mc.real_vram_size) >> PAGE_SHIFT)); | 486 | rdev->mc.real_vram_size >> PAGE_SHIFT); |
481 | if (r) { | 487 | if (r) { |
482 | DRM_ERROR("Failed initializing VRAM heap.\n"); | 488 | DRM_ERROR("Failed initializing VRAM heap.\n"); |
483 | return r; | 489 | return r; |
484 | } | 490 | } |
485 | r = radeon_object_create(rdev, NULL, 256 * 1024, true, | 491 | r = radeon_bo_create(rdev, NULL, 256 * 1024, true, |
486 | RADEON_GEM_DOMAIN_VRAM, false, | 492 | RADEON_GEM_DOMAIN_VRAM, |
487 | &rdev->stollen_vga_memory); | 493 | &rdev->stollen_vga_memory); |
488 | if (r) { | 494 | if (r) { |
489 | return r; | 495 | return r; |
490 | } | 496 | } |
491 | r = radeon_object_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL); | 497 | r = radeon_bo_reserve(rdev->stollen_vga_memory, false); |
498 | if (r) | ||
499 | return r; | ||
500 | r = radeon_bo_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL); | ||
501 | radeon_bo_unreserve(rdev->stollen_vga_memory); | ||
492 | if (r) { | 502 | if (r) { |
493 | radeon_object_unref(&rdev->stollen_vga_memory); | 503 | radeon_bo_unref(&rdev->stollen_vga_memory); |
494 | return r; | 504 | return r; |
495 | } | 505 | } |
496 | DRM_INFO("radeon: %uM of VRAM memory ready\n", | 506 | DRM_INFO("radeon: %uM of VRAM memory ready\n", |
497 | (unsigned)rdev->mc.real_vram_size / (1024 * 1024)); | 507 | (unsigned)rdev->mc.real_vram_size / (1024 * 1024)); |
498 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0, | 508 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, |
499 | ((rdev->mc.gtt_size) >> PAGE_SHIFT)); | 509 | rdev->mc.gtt_size >> PAGE_SHIFT); |
500 | if (r) { | 510 | if (r) { |
501 | DRM_ERROR("Failed initializing GTT heap.\n"); | 511 | DRM_ERROR("Failed initializing GTT heap.\n"); |
502 | return r; | 512 | return r; |
@@ -517,9 +527,15 @@ int radeon_ttm_init(struct radeon_device *rdev) | |||
517 | 527 | ||
518 | void radeon_ttm_fini(struct radeon_device *rdev) | 528 | void radeon_ttm_fini(struct radeon_device *rdev) |
519 | { | 529 | { |
530 | int r; | ||
531 | |||
520 | if (rdev->stollen_vga_memory) { | 532 | if (rdev->stollen_vga_memory) { |
521 | radeon_object_unpin(rdev->stollen_vga_memory); | 533 | r = radeon_bo_reserve(rdev->stollen_vga_memory, false); |
522 | radeon_object_unref(&rdev->stollen_vga_memory); | 534 | if (r == 0) { |
535 | radeon_bo_unpin(rdev->stollen_vga_memory); | ||
536 | radeon_bo_unreserve(rdev->stollen_vga_memory); | ||
537 | } | ||
538 | radeon_bo_unref(&rdev->stollen_vga_memory); | ||
523 | } | 539 | } |
524 | ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_VRAM); | 540 | ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_VRAM); |
525 | ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_TT); | 541 | ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_TT); |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index a769c296f6a6..c1fcdddb6be6 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -352,7 +352,7 @@ static int rs400_mc_init(struct radeon_device *rdev) | |||
352 | u32 tmp; | 352 | u32 tmp; |
353 | 353 | ||
354 | /* Setup GPU memory space */ | 354 | /* Setup GPU memory space */ |
355 | tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM)); | 355 | tmp = RREG32(R_00015C_NB_TOM); |
356 | rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16; | 356 | rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16; |
357 | rdev->mc.gtt_location = 0xFFFFFFFFUL; | 357 | rdev->mc.gtt_location = 0xFFFFFFFFUL; |
358 | r = radeon_mc_setup(rdev); | 358 | r = radeon_mc_setup(rdev); |
@@ -387,13 +387,13 @@ static int rs400_startup(struct radeon_device *rdev) | |||
387 | r300_clock_startup(rdev); | 387 | r300_clock_startup(rdev); |
388 | /* Initialize GPU configuration (# pipes, ...) */ | 388 | /* Initialize GPU configuration (# pipes, ...) */ |
389 | rs400_gpu_init(rdev); | 389 | rs400_gpu_init(rdev); |
390 | r100_enable_bm(rdev); | ||
390 | /* Initialize GART (initialize after TTM so we can allocate | 391 | /* Initialize GART (initialize after TTM so we can allocate |
391 | * memory through TTM but finalize after TTM) */ | 392 | * memory through TTM but finalize after TTM) */ |
392 | r = rs400_gart_enable(rdev); | 393 | r = rs400_gart_enable(rdev); |
393 | if (r) | 394 | if (r) |
394 | return r; | 395 | return r; |
395 | /* Enable IRQ */ | 396 | /* Enable IRQ */ |
396 | rdev->irq.sw_int = true; | ||
397 | r100_irq_set(rdev); | 397 | r100_irq_set(rdev); |
398 | /* 1M ring buffer */ | 398 | /* 1M ring buffer */ |
399 | r = r100_cp_init(rdev, 1024 * 1024); | 399 | r = r100_cp_init(rdev, 1024 * 1024); |
@@ -418,6 +418,8 @@ int rs400_resume(struct radeon_device *rdev) | |||
418 | rs400_gart_disable(rdev); | 418 | rs400_gart_disable(rdev); |
419 | /* Resume clock before doing reset */ | 419 | /* Resume clock before doing reset */ |
420 | r300_clock_startup(rdev); | 420 | r300_clock_startup(rdev); |
421 | /* setup MC before calling post tables */ | ||
422 | rs400_mc_program(rdev); | ||
421 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 423 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
422 | if (radeon_gpu_reset(rdev)) { | 424 | if (radeon_gpu_reset(rdev)) { |
423 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 425 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
@@ -428,6 +430,8 @@ int rs400_resume(struct radeon_device *rdev) | |||
428 | radeon_combios_asic_init(rdev->ddev); | 430 | radeon_combios_asic_init(rdev->ddev); |
429 | /* Resume clock after posting */ | 431 | /* Resume clock after posting */ |
430 | r300_clock_startup(rdev); | 432 | r300_clock_startup(rdev); |
433 | /* Initialize surface registers */ | ||
434 | radeon_surface_init(rdev); | ||
431 | return rs400_startup(rdev); | 435 | return rs400_startup(rdev); |
432 | } | 436 | } |
433 | 437 | ||
@@ -450,7 +454,7 @@ void rs400_fini(struct radeon_device *rdev) | |||
450 | rs400_gart_fini(rdev); | 454 | rs400_gart_fini(rdev); |
451 | radeon_irq_kms_fini(rdev); | 455 | radeon_irq_kms_fini(rdev); |
452 | radeon_fence_driver_fini(rdev); | 456 | radeon_fence_driver_fini(rdev); |
453 | radeon_object_fini(rdev); | 457 | radeon_bo_fini(rdev); |
454 | radeon_atombios_fini(rdev); | 458 | radeon_atombios_fini(rdev); |
455 | kfree(rdev->bios); | 459 | kfree(rdev->bios); |
456 | rdev->bios = NULL; | 460 | rdev->bios = NULL; |
@@ -488,10 +492,9 @@ int rs400_init(struct radeon_device *rdev) | |||
488 | RREG32(R_0007C0_CP_STAT)); | 492 | RREG32(R_0007C0_CP_STAT)); |
489 | } | 493 | } |
490 | /* check if cards are posted or not */ | 494 | /* check if cards are posted or not */ |
491 | if (!radeon_card_posted(rdev) && rdev->bios) { | 495 | if (radeon_boot_test_post_card(rdev) == false) |
492 | DRM_INFO("GPU not posted. posting now...\n"); | 496 | return -EINVAL; |
493 | radeon_combios_asic_init(rdev->ddev); | 497 | |
494 | } | ||
495 | /* Initialize clocks */ | 498 | /* Initialize clocks */ |
496 | radeon_get_clock_info(rdev->ddev); | 499 | radeon_get_clock_info(rdev->ddev); |
497 | /* Get vram informations */ | 500 | /* Get vram informations */ |
@@ -508,7 +511,7 @@ int rs400_init(struct radeon_device *rdev) | |||
508 | if (r) | 511 | if (r) |
509 | return r; | 512 | return r; |
510 | /* Memory manager */ | 513 | /* Memory manager */ |
511 | r = radeon_object_init(rdev); | 514 | r = radeon_bo_init(rdev); |
512 | if (r) | 515 | if (r) |
513 | return r; | 516 | return r; |
514 | r = rs400_gart_init(rdev); | 517 | r = rs400_gart_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 10dfa78762da..4f8ea4260572 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -45,6 +45,122 @@ | |||
45 | void rs600_gpu_init(struct radeon_device *rdev); | 45 | void rs600_gpu_init(struct radeon_device *rdev); |
46 | int rs600_mc_wait_for_idle(struct radeon_device *rdev); | 46 | int rs600_mc_wait_for_idle(struct radeon_device *rdev); |
47 | 47 | ||
48 | int rs600_mc_init(struct radeon_device *rdev) | ||
49 | { | ||
50 | /* read back the MC value from the hw */ | ||
51 | int r; | ||
52 | u32 tmp; | ||
53 | |||
54 | /* Setup GPU memory space */ | ||
55 | tmp = RREG32_MC(R_000004_MC_FB_LOCATION); | ||
56 | rdev->mc.vram_location = G_000004_MC_FB_START(tmp) << 16; | ||
57 | rdev->mc.gtt_location = 0xffffffffUL; | ||
58 | r = radeon_mc_setup(rdev); | ||
59 | if (r) | ||
60 | return r; | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | /* hpd for digital panel detect/disconnect */ | ||
65 | bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | ||
66 | { | ||
67 | u32 tmp; | ||
68 | bool connected = false; | ||
69 | |||
70 | switch (hpd) { | ||
71 | case RADEON_HPD_1: | ||
72 | tmp = RREG32(R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS); | ||
73 | if (G_007D04_DC_HOT_PLUG_DETECT1_SENSE(tmp)) | ||
74 | connected = true; | ||
75 | break; | ||
76 | case RADEON_HPD_2: | ||
77 | tmp = RREG32(R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS); | ||
78 | if (G_007D14_DC_HOT_PLUG_DETECT2_SENSE(tmp)) | ||
79 | connected = true; | ||
80 | break; | ||
81 | default: | ||
82 | break; | ||
83 | } | ||
84 | return connected; | ||
85 | } | ||
86 | |||
87 | void rs600_hpd_set_polarity(struct radeon_device *rdev, | ||
88 | enum radeon_hpd_id hpd) | ||
89 | { | ||
90 | u32 tmp; | ||
91 | bool connected = rs600_hpd_sense(rdev, hpd); | ||
92 | |||
93 | switch (hpd) { | ||
94 | case RADEON_HPD_1: | ||
95 | tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
96 | if (connected) | ||
97 | tmp &= ~S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1); | ||
98 | else | ||
99 | tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1); | ||
100 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
101 | break; | ||
102 | case RADEON_HPD_2: | ||
103 | tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
104 | if (connected) | ||
105 | tmp &= ~S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1); | ||
106 | else | ||
107 | tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1); | ||
108 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
109 | break; | ||
110 | default: | ||
111 | break; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | void rs600_hpd_init(struct radeon_device *rdev) | ||
116 | { | ||
117 | struct drm_device *dev = rdev->ddev; | ||
118 | struct drm_connector *connector; | ||
119 | |||
120 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
121 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
122 | switch (radeon_connector->hpd.hpd) { | ||
123 | case RADEON_HPD_1: | ||
124 | WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, | ||
125 | S_007D00_DC_HOT_PLUG_DETECT1_EN(1)); | ||
126 | rdev->irq.hpd[0] = true; | ||
127 | break; | ||
128 | case RADEON_HPD_2: | ||
129 | WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, | ||
130 | S_007D10_DC_HOT_PLUG_DETECT2_EN(1)); | ||
131 | rdev->irq.hpd[1] = true; | ||
132 | break; | ||
133 | default: | ||
134 | break; | ||
135 | } | ||
136 | } | ||
137 | rs600_irq_set(rdev); | ||
138 | } | ||
139 | |||
140 | void rs600_hpd_fini(struct radeon_device *rdev) | ||
141 | { | ||
142 | struct drm_device *dev = rdev->ddev; | ||
143 | struct drm_connector *connector; | ||
144 | |||
145 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
146 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
147 | switch (radeon_connector->hpd.hpd) { | ||
148 | case RADEON_HPD_1: | ||
149 | WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, | ||
150 | S_007D00_DC_HOT_PLUG_DETECT1_EN(0)); | ||
151 | rdev->irq.hpd[0] = false; | ||
152 | break; | ||
153 | case RADEON_HPD_2: | ||
154 | WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, | ||
155 | S_007D10_DC_HOT_PLUG_DETECT2_EN(0)); | ||
156 | rdev->irq.hpd[1] = false; | ||
157 | break; | ||
158 | default: | ||
159 | break; | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | |||
48 | /* | 164 | /* |
49 | * GART. | 165 | * GART. |
50 | */ | 166 | */ |
@@ -100,40 +216,40 @@ int rs600_gart_enable(struct radeon_device *rdev) | |||
100 | WREG32(R_00004C_BUS_CNTL, tmp); | 216 | WREG32(R_00004C_BUS_CNTL, tmp); |
101 | /* FIXME: setup default page */ | 217 | /* FIXME: setup default page */ |
102 | WREG32_MC(R_000100_MC_PT0_CNTL, | 218 | WREG32_MC(R_000100_MC_PT0_CNTL, |
103 | (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) | | 219 | (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) | |
104 | S_000100_EFFECTIVE_L2_QUEUE_SIZE(6))); | 220 | S_000100_EFFECTIVE_L2_QUEUE_SIZE(6))); |
221 | |||
105 | for (i = 0; i < 19; i++) { | 222 | for (i = 0; i < 19; i++) { |
106 | WREG32_MC(R_00016C_MC_PT0_CLIENT0_CNTL + i, | 223 | WREG32_MC(R_00016C_MC_PT0_CLIENT0_CNTL + i, |
107 | S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) | | 224 | S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) | |
108 | S_00016C_SYSTEM_ACCESS_MODE_MASK( | 225 | S_00016C_SYSTEM_ACCESS_MODE_MASK( |
109 | V_00016C_SYSTEM_ACCESS_MODE_IN_SYS) | | 226 | V_00016C_SYSTEM_ACCESS_MODE_NOT_IN_SYS) | |
110 | S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS( | 227 | S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS( |
111 | V_00016C_SYSTEM_APERTURE_UNMAPPED_DEFAULT_PAGE) | | 228 | V_00016C_SYSTEM_APERTURE_UNMAPPED_PASSTHROUGH) | |
112 | S_00016C_EFFECTIVE_L1_CACHE_SIZE(1) | | 229 | S_00016C_EFFECTIVE_L1_CACHE_SIZE(3) | |
113 | S_00016C_ENABLE_FRAGMENT_PROCESSING(1) | | 230 | S_00016C_ENABLE_FRAGMENT_PROCESSING(1) | |
114 | S_00016C_EFFECTIVE_L1_QUEUE_SIZE(1)); | 231 | S_00016C_EFFECTIVE_L1_QUEUE_SIZE(3)); |
115 | } | 232 | } |
116 | |||
117 | /* System context map to GART space */ | ||
118 | WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_start); | ||
119 | WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.gtt_end); | ||
120 | |||
121 | /* enable first context */ | 233 | /* enable first context */ |
122 | WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start); | ||
123 | WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end); | ||
124 | WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL, | 234 | WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL, |
125 | S_000102_ENABLE_PAGE_TABLE(1) | | 235 | S_000102_ENABLE_PAGE_TABLE(1) | |
126 | S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT)); | 236 | S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT)); |
237 | |||
127 | /* disable all other contexts */ | 238 | /* disable all other contexts */ |
128 | for (i = 1; i < 8; i++) { | 239 | for (i = 1; i < 8; i++) |
129 | WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL + i, 0); | 240 | WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL + i, 0); |
130 | } | ||
131 | 241 | ||
132 | /* setup the page table */ | 242 | /* setup the page table */ |
133 | WREG32_MC(R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, | 243 | WREG32_MC(R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, |
134 | rdev->gart.table_addr); | 244 | rdev->gart.table_addr); |
245 | WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start); | ||
246 | WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end); | ||
135 | WREG32_MC(R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); | 247 | WREG32_MC(R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); |
136 | 248 | ||
249 | /* System context maps to VRAM space */ | ||
250 | WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start); | ||
251 | WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end); | ||
252 | |||
137 | /* enable page tables */ | 253 | /* enable page tables */ |
138 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); | 254 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); |
139 | WREG32_MC(R_000100_MC_PT0_CNTL, (tmp | S_000100_ENABLE_PT(1))); | 255 | WREG32_MC(R_000100_MC_PT0_CNTL, (tmp | S_000100_ENABLE_PT(1))); |
@@ -146,15 +262,20 @@ int rs600_gart_enable(struct radeon_device *rdev) | |||
146 | 262 | ||
147 | void rs600_gart_disable(struct radeon_device *rdev) | 263 | void rs600_gart_disable(struct radeon_device *rdev) |
148 | { | 264 | { |
149 | uint32_t tmp; | 265 | u32 tmp; |
266 | int r; | ||
150 | 267 | ||
151 | /* FIXME: disable out of gart access */ | 268 | /* FIXME: disable out of gart access */ |
152 | WREG32_MC(R_000100_MC_PT0_CNTL, 0); | 269 | WREG32_MC(R_000100_MC_PT0_CNTL, 0); |
153 | tmp = RREG32_MC(R_000009_MC_CNTL1); | 270 | tmp = RREG32_MC(R_000009_MC_CNTL1); |
154 | WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES); | 271 | WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES); |
155 | if (rdev->gart.table.vram.robj) { | 272 | if (rdev->gart.table.vram.robj) { |
156 | radeon_object_kunmap(rdev->gart.table.vram.robj); | 273 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); |
157 | radeon_object_unpin(rdev->gart.table.vram.robj); | 274 | if (r == 0) { |
275 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
276 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
277 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
278 | } | ||
158 | } | 279 | } |
159 | } | 280 | } |
160 | 281 | ||
@@ -189,6 +310,10 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
189 | { | 310 | { |
190 | uint32_t tmp = 0; | 311 | uint32_t tmp = 0; |
191 | uint32_t mode_int = 0; | 312 | uint32_t mode_int = 0; |
313 | u32 hpd1 = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL) & | ||
314 | ~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); | ||
315 | u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & | ||
316 | ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | ||
192 | 317 | ||
193 | if (rdev->irq.sw_int) { | 318 | if (rdev->irq.sw_int) { |
194 | tmp |= S_000040_SW_INT_EN(1); | 319 | tmp |= S_000040_SW_INT_EN(1); |
@@ -199,8 +324,16 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
199 | if (rdev->irq.crtc_vblank_int[1]) { | 324 | if (rdev->irq.crtc_vblank_int[1]) { |
200 | mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); | 325 | mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); |
201 | } | 326 | } |
327 | if (rdev->irq.hpd[0]) { | ||
328 | hpd1 |= S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); | ||
329 | } | ||
330 | if (rdev->irq.hpd[1]) { | ||
331 | hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | ||
332 | } | ||
202 | WREG32(R_000040_GEN_INT_CNTL, tmp); | 333 | WREG32(R_000040_GEN_INT_CNTL, tmp); |
203 | WREG32(R_006540_DxMODE_INT_MASK, mode_int); | 334 | WREG32(R_006540_DxMODE_INT_MASK, mode_int); |
335 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); | ||
336 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); | ||
204 | return 0; | 337 | return 0; |
205 | } | 338 | } |
206 | 339 | ||
@@ -208,6 +341,7 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ | |||
208 | { | 341 | { |
209 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); | 342 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); |
210 | uint32_t irq_mask = ~C_000044_SW_INT; | 343 | uint32_t irq_mask = ~C_000044_SW_INT; |
344 | u32 tmp; | ||
211 | 345 | ||
212 | if (G_000044_DISPLAY_INT_STAT(irqs)) { | 346 | if (G_000044_DISPLAY_INT_STAT(irqs)) { |
213 | *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); | 347 | *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); |
@@ -219,6 +353,16 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ | |||
219 | WREG32(R_006D34_D2MODE_VBLANK_STATUS, | 353 | WREG32(R_006D34_D2MODE_VBLANK_STATUS, |
220 | S_006D34_D2MODE_VBLANK_ACK(1)); | 354 | S_006D34_D2MODE_VBLANK_ACK(1)); |
221 | } | 355 | } |
356 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(*r500_disp_int)) { | ||
357 | tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
358 | tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(1); | ||
359 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
360 | } | ||
361 | if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(*r500_disp_int)) { | ||
362 | tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
363 | tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(1); | ||
364 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
365 | } | ||
222 | } else { | 366 | } else { |
223 | *r500_disp_int = 0; | 367 | *r500_disp_int = 0; |
224 | } | 368 | } |
@@ -242,8 +386,9 @@ void rs600_irq_disable(struct radeon_device *rdev) | |||
242 | 386 | ||
243 | int rs600_irq_process(struct radeon_device *rdev) | 387 | int rs600_irq_process(struct radeon_device *rdev) |
244 | { | 388 | { |
245 | uint32_t status; | 389 | uint32_t status, msi_rearm; |
246 | uint32_t r500_disp_int; | 390 | uint32_t r500_disp_int; |
391 | bool queue_hotplug = false; | ||
247 | 392 | ||
248 | status = rs600_irq_ack(rdev, &r500_disp_int); | 393 | status = rs600_irq_ack(rdev, &r500_disp_int); |
249 | if (!status && !r500_disp_int) { | 394 | if (!status && !r500_disp_int) { |
@@ -258,8 +403,34 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
258 | drm_handle_vblank(rdev->ddev, 0); | 403 | drm_handle_vblank(rdev->ddev, 0); |
259 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) | 404 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) |
260 | drm_handle_vblank(rdev->ddev, 1); | 405 | drm_handle_vblank(rdev->ddev, 1); |
406 | if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) { | ||
407 | queue_hotplug = true; | ||
408 | DRM_DEBUG("HPD1\n"); | ||
409 | } | ||
410 | if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(r500_disp_int)) { | ||
411 | queue_hotplug = true; | ||
412 | DRM_DEBUG("HPD2\n"); | ||
413 | } | ||
261 | status = rs600_irq_ack(rdev, &r500_disp_int); | 414 | status = rs600_irq_ack(rdev, &r500_disp_int); |
262 | } | 415 | } |
416 | if (queue_hotplug) | ||
417 | queue_work(rdev->wq, &rdev->hotplug_work); | ||
418 | if (rdev->msi_enabled) { | ||
419 | switch (rdev->family) { | ||
420 | case CHIP_RS600: | ||
421 | case CHIP_RS690: | ||
422 | case CHIP_RS740: | ||
423 | msi_rearm = RREG32(RADEON_BUS_CNTL) & ~RS600_MSI_REARM; | ||
424 | WREG32(RADEON_BUS_CNTL, msi_rearm); | ||
425 | WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM); | ||
426 | break; | ||
427 | default: | ||
428 | msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; | ||
429 | WREG32(RADEON_MSI_REARM_EN, msi_rearm); | ||
430 | WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); | ||
431 | break; | ||
432 | } | ||
433 | } | ||
263 | return IRQ_HANDLED; | 434 | return IRQ_HANDLED; |
264 | } | 435 | } |
265 | 436 | ||
@@ -285,9 +456,7 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev) | |||
285 | 456 | ||
286 | void rs600_gpu_init(struct radeon_device *rdev) | 457 | void rs600_gpu_init(struct radeon_device *rdev) |
287 | { | 458 | { |
288 | /* FIXME: HDP same place on rs600 ? */ | ||
289 | r100_hdp_reset(rdev); | 459 | r100_hdp_reset(rdev); |
290 | /* FIXME: is this correct ? */ | ||
291 | r420_pipes_init(rdev); | 460 | r420_pipes_init(rdev); |
292 | /* Wait for mc idle */ | 461 | /* Wait for mc idle */ |
293 | if (rs600_mc_wait_for_idle(rdev)) | 462 | if (rs600_mc_wait_for_idle(rdev)) |
@@ -296,9 +465,20 @@ void rs600_gpu_init(struct radeon_device *rdev) | |||
296 | 465 | ||
297 | void rs600_vram_info(struct radeon_device *rdev) | 466 | void rs600_vram_info(struct radeon_device *rdev) |
298 | { | 467 | { |
299 | /* FIXME: to do or is these values sane ? */ | ||
300 | rdev->mc.vram_is_ddr = true; | 468 | rdev->mc.vram_is_ddr = true; |
301 | rdev->mc.vram_width = 128; | 469 | rdev->mc.vram_width = 128; |
470 | |||
471 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); | ||
472 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; | ||
473 | |||
474 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | ||
475 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | ||
476 | |||
477 | if (rdev->mc.mc_vram_size > rdev->mc.aper_size) | ||
478 | rdev->mc.mc_vram_size = rdev->mc.aper_size; | ||
479 | |||
480 | if (rdev->mc.real_vram_size > rdev->mc.aper_size) | ||
481 | rdev->mc.real_vram_size = rdev->mc.aper_size; | ||
302 | } | 482 | } |
303 | 483 | ||
304 | void rs600_bandwidth_update(struct radeon_device *rdev) | 484 | void rs600_bandwidth_update(struct radeon_device *rdev) |
@@ -372,7 +552,6 @@ static int rs600_startup(struct radeon_device *rdev) | |||
372 | if (r) | 552 | if (r) |
373 | return r; | 553 | return r; |
374 | /* Enable IRQ */ | 554 | /* Enable IRQ */ |
375 | rdev->irq.sw_int = true; | ||
376 | rs600_irq_set(rdev); | 555 | rs600_irq_set(rdev); |
377 | /* 1M ring buffer */ | 556 | /* 1M ring buffer */ |
378 | r = r100_cp_init(rdev, 1024 * 1024); | 557 | r = r100_cp_init(rdev, 1024 * 1024); |
@@ -407,6 +586,8 @@ int rs600_resume(struct radeon_device *rdev) | |||
407 | atom_asic_init(rdev->mode_info.atom_context); | 586 | atom_asic_init(rdev->mode_info.atom_context); |
408 | /* Resume clock after posting */ | 587 | /* Resume clock after posting */ |
409 | rv515_clock_startup(rdev); | 588 | rv515_clock_startup(rdev); |
589 | /* Initialize surface registers */ | ||
590 | radeon_surface_init(rdev); | ||
410 | return rs600_startup(rdev); | 591 | return rs600_startup(rdev); |
411 | } | 592 | } |
412 | 593 | ||
@@ -429,7 +610,7 @@ void rs600_fini(struct radeon_device *rdev) | |||
429 | rs600_gart_fini(rdev); | 610 | rs600_gart_fini(rdev); |
430 | radeon_irq_kms_fini(rdev); | 611 | radeon_irq_kms_fini(rdev); |
431 | radeon_fence_driver_fini(rdev); | 612 | radeon_fence_driver_fini(rdev); |
432 | radeon_object_fini(rdev); | 613 | radeon_bo_fini(rdev); |
433 | radeon_atombios_fini(rdev); | 614 | radeon_atombios_fini(rdev); |
434 | kfree(rdev->bios); | 615 | kfree(rdev->bios); |
435 | rdev->bios = NULL; | 616 | rdev->bios = NULL; |
@@ -466,16 +647,17 @@ int rs600_init(struct radeon_device *rdev) | |||
466 | RREG32(R_0007C0_CP_STAT)); | 647 | RREG32(R_0007C0_CP_STAT)); |
467 | } | 648 | } |
468 | /* check if cards are posted or not */ | 649 | /* check if cards are posted or not */ |
469 | if (!radeon_card_posted(rdev) && rdev->bios) { | 650 | if (radeon_boot_test_post_card(rdev) == false) |
470 | DRM_INFO("GPU not posted. posting now...\n"); | 651 | return -EINVAL; |
471 | atom_asic_init(rdev->mode_info.atom_context); | 652 | |
472 | } | ||
473 | /* Initialize clocks */ | 653 | /* Initialize clocks */ |
474 | radeon_get_clock_info(rdev->ddev); | 654 | radeon_get_clock_info(rdev->ddev); |
655 | /* Initialize power management */ | ||
656 | radeon_pm_init(rdev); | ||
475 | /* Get vram informations */ | 657 | /* Get vram informations */ |
476 | rs600_vram_info(rdev); | 658 | rs600_vram_info(rdev); |
477 | /* Initialize memory controller (also test AGP) */ | 659 | /* Initialize memory controller (also test AGP) */ |
478 | r = r420_mc_init(rdev); | 660 | r = rs600_mc_init(rdev); |
479 | if (r) | 661 | if (r) |
480 | return r; | 662 | return r; |
481 | rs600_debugfs(rdev); | 663 | rs600_debugfs(rdev); |
@@ -487,7 +669,7 @@ int rs600_init(struct radeon_device *rdev) | |||
487 | if (r) | 669 | if (r) |
488 | return r; | 670 | return r; |
489 | /* Memory manager */ | 671 | /* Memory manager */ |
490 | r = radeon_object_init(rdev); | 672 | r = radeon_bo_init(rdev); |
491 | if (r) | 673 | if (r) |
492 | return r; | 674 | return r; |
493 | r = rs600_gart_init(rdev); | 675 | r = rs600_gart_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/rs600d.h b/drivers/gpu/drm/radeon/rs600d.h index 81308924859a..c1c8f5885cbb 100644 --- a/drivers/gpu/drm/radeon/rs600d.h +++ b/drivers/gpu/drm/radeon/rs600d.h | |||
@@ -30,27 +30,12 @@ | |||
30 | 30 | ||
31 | /* Registers */ | 31 | /* Registers */ |
32 | #define R_000040_GEN_INT_CNTL 0x000040 | 32 | #define R_000040_GEN_INT_CNTL 0x000040 |
33 | #define S_000040_DISPLAY_INT_STATUS(x) (((x) & 0x1) << 0) | 33 | #define S_000040_SCRATCH_INT_MASK(x) (((x) & 0x1) << 18) |
34 | #define G_000040_DISPLAY_INT_STATUS(x) (((x) >> 0) & 0x1) | 34 | #define G_000040_SCRATCH_INT_MASK(x) (((x) >> 18) & 0x1) |
35 | #define C_000040_DISPLAY_INT_STATUS 0xFFFFFFFE | 35 | #define C_000040_SCRATCH_INT_MASK 0xFFFBFFFF |
36 | #define S_000040_DMA_VIPH0_INT_EN(x) (((x) & 0x1) << 12) | 36 | #define S_000040_GUI_IDLE_MASK(x) (((x) & 0x1) << 19) |
37 | #define G_000040_DMA_VIPH0_INT_EN(x) (((x) >> 12) & 0x1) | 37 | #define G_000040_GUI_IDLE_MASK(x) (((x) >> 19) & 0x1) |
38 | #define C_000040_DMA_VIPH0_INT_EN 0xFFFFEFFF | 38 | #define C_000040_GUI_IDLE_MASK 0xFFF7FFFF |
39 | #define S_000040_CRTC2_VSYNC(x) (((x) & 0x1) << 6) | ||
40 | #define G_000040_CRTC2_VSYNC(x) (((x) >> 6) & 0x1) | ||
41 | #define C_000040_CRTC2_VSYNC 0xFFFFFFBF | ||
42 | #define S_000040_SNAPSHOT2(x) (((x) & 0x1) << 7) | ||
43 | #define G_000040_SNAPSHOT2(x) (((x) >> 7) & 0x1) | ||
44 | #define C_000040_SNAPSHOT2 0xFFFFFF7F | ||
45 | #define S_000040_CRTC2_VBLANK(x) (((x) & 0x1) << 9) | ||
46 | #define G_000040_CRTC2_VBLANK(x) (((x) >> 9) & 0x1) | ||
47 | #define C_000040_CRTC2_VBLANK 0xFFFFFDFF | ||
48 | #define S_000040_FP2_DETECT(x) (((x) & 0x1) << 10) | ||
49 | #define G_000040_FP2_DETECT(x) (((x) >> 10) & 0x1) | ||
50 | #define C_000040_FP2_DETECT 0xFFFFFBFF | ||
51 | #define S_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) & 0x1) << 11) | ||
52 | #define G_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) >> 11) & 0x1) | ||
53 | #define C_000040_VSYNC_DIFF_OVER_LIMIT 0xFFFFF7FF | ||
54 | #define S_000040_DMA_VIPH1_INT_EN(x) (((x) & 0x1) << 13) | 39 | #define S_000040_DMA_VIPH1_INT_EN(x) (((x) & 0x1) << 13) |
55 | #define G_000040_DMA_VIPH1_INT_EN(x) (((x) >> 13) & 0x1) | 40 | #define G_000040_DMA_VIPH1_INT_EN(x) (((x) >> 13) & 0x1) |
56 | #define C_000040_DMA_VIPH1_INT_EN 0xFFFFDFFF | 41 | #define C_000040_DMA_VIPH1_INT_EN 0xFFFFDFFF |
@@ -370,7 +355,90 @@ | |||
370 | #define S_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) & 0x1) << 5) | 355 | #define S_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) & 0x1) << 5) |
371 | #define G_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) >> 5) & 0x1) | 356 | #define G_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) >> 5) & 0x1) |
372 | #define C_007EDC_LB_D2_VBLANK_INTERRUPT 0xFFFFFFDF | 357 | #define C_007EDC_LB_D2_VBLANK_INTERRUPT 0xFFFFFFDF |
373 | 358 | #define S_007EDC_DACA_AUTODETECT_INTERRUPT(x) (((x) & 0x1) << 16) | |
359 | #define G_007EDC_DACA_AUTODETECT_INTERRUPT(x) (((x) >> 16) & 0x1) | ||
360 | #define C_007EDC_DACA_AUTODETECT_INTERRUPT 0xFFFEFFFF | ||
361 | #define S_007EDC_DACB_AUTODETECT_INTERRUPT(x) (((x) & 0x1) << 17) | ||
362 | #define G_007EDC_DACB_AUTODETECT_INTERRUPT(x) (((x) >> 17) & 0x1) | ||
363 | #define C_007EDC_DACB_AUTODETECT_INTERRUPT 0xFFFDFFFF | ||
364 | #define S_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x) (((x) & 0x1) << 18) | ||
365 | #define G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x) (((x) >> 18) & 0x1) | ||
366 | #define C_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT 0xFFFBFFFF | ||
367 | #define S_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x) (((x) & 0x1) << 19) | ||
368 | #define G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x) (((x) >> 19) & 0x1) | ||
369 | #define C_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT 0xFFF7FFFF | ||
370 | #define R_007828_DACA_AUTODETECT_CONTROL 0x007828 | ||
371 | #define S_007828_DACA_AUTODETECT_MODE(x) (((x) & 0x3) << 0) | ||
372 | #define G_007828_DACA_AUTODETECT_MODE(x) (((x) >> 0) & 0x3) | ||
373 | #define C_007828_DACA_AUTODETECT_MODE 0xFFFFFFFC | ||
374 | #define S_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8) | ||
375 | #define G_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff) | ||
376 | #define C_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER 0xFFFF00FF | ||
377 | #define S_007828_DACA_AUTODETECT_CHECK_MASK(x) (((x) & 0x3) << 16) | ||
378 | #define G_007828_DACA_AUTODETECT_CHECK_MASK(x) (((x) >> 16) & 0x3) | ||
379 | #define C_007828_DACA_AUTODETECT_CHECK_MASK 0xFFFCFFFF | ||
380 | #define R_007838_DACA_AUTODETECT_INT_CONTROL 0x007838 | ||
381 | #define S_007838_DACA_AUTODETECT_ACK(x) (((x) & 0x1) << 0) | ||
382 | #define C_007838_DACA_DACA_AUTODETECT_ACK 0xFFFFFFFE | ||
383 | #define S_007838_DACA_AUTODETECT_INT_ENABLE(x) (((x) & 0x1) << 16) | ||
384 | #define G_007838_DACA_AUTODETECT_INT_ENABLE(x) (((x) >> 16) & 0x1) | ||
385 | #define C_007838_DACA_AUTODETECT_INT_ENABLE 0xFFFCFFFF | ||
386 | #define R_007A28_DACB_AUTODETECT_CONTROL 0x007A28 | ||
387 | #define S_007A28_DACB_AUTODETECT_MODE(x) (((x) & 0x3) << 0) | ||
388 | #define G_007A28_DACB_AUTODETECT_MODE(x) (((x) >> 0) & 0x3) | ||
389 | #define C_007A28_DACB_AUTODETECT_MODE 0xFFFFFFFC | ||
390 | #define S_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8) | ||
391 | #define G_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff) | ||
392 | #define C_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER 0xFFFF00FF | ||
393 | #define S_007A28_DACB_AUTODETECT_CHECK_MASK(x) (((x) & 0x3) << 16) | ||
394 | #define G_007A28_DACB_AUTODETECT_CHECK_MASK(x) (((x) >> 16) & 0x3) | ||
395 | #define C_007A28_DACB_AUTODETECT_CHECK_MASK 0xFFFCFFFF | ||
396 | #define R_007A38_DACB_AUTODETECT_INT_CONTROL 0x007A38 | ||
397 | #define S_007A38_DACB_AUTODETECT_ACK(x) (((x) & 0x1) << 0) | ||
398 | #define C_007A38_DACB_DACA_AUTODETECT_ACK 0xFFFFFFFE | ||
399 | #define S_007A38_DACB_AUTODETECT_INT_ENABLE(x) (((x) & 0x1) << 16) | ||
400 | #define G_007A38_DACB_AUTODETECT_INT_ENABLE(x) (((x) >> 16) & 0x1) | ||
401 | #define C_007A38_DACB_AUTODETECT_INT_ENABLE 0xFFFCFFFF | ||
402 | #define R_007D00_DC_HOT_PLUG_DETECT1_CONTROL 0x007D00 | ||
403 | #define S_007D00_DC_HOT_PLUG_DETECT1_EN(x) (((x) & 0x1) << 0) | ||
404 | #define G_007D00_DC_HOT_PLUG_DETECT1_EN(x) (((x) >> 0) & 0x1) | ||
405 | #define C_007D00_DC_HOT_PLUG_DETECT1_EN 0xFFFFFFFE | ||
406 | #define R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS 0x007D04 | ||
407 | #define S_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x) (((x) & 0x1) << 0) | ||
408 | #define G_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x) (((x) >> 0) & 0x1) | ||
409 | #define C_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS 0xFFFFFFFE | ||
410 | #define S_007D04_DC_HOT_PLUG_DETECT1_SENSE(x) (((x) & 0x1) << 1) | ||
411 | #define G_007D04_DC_HOT_PLUG_DETECT1_SENSE(x) (((x) >> 1) & 0x1) | ||
412 | #define C_007D04_DC_HOT_PLUG_DETECT1_SENSE 0xFFFFFFFD | ||
413 | #define R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL 0x007D08 | ||
414 | #define S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(x) (((x) & 0x1) << 0) | ||
415 | #define C_007D08_DC_HOT_PLUG_DETECT1_INT_ACK 0xFFFFFFFE | ||
416 | #define S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) & 0x1) << 8) | ||
417 | #define G_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) >> 8) & 0x1) | ||
418 | #define C_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY 0xFFFFFEFF | ||
419 | #define S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x) (((x) & 0x1) << 16) | ||
420 | #define G_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x) (((x) >> 16) & 0x1) | ||
421 | #define C_007D08_DC_HOT_PLUG_DETECT1_INT_EN 0xFFFEFFFF | ||
422 | #define R_007D10_DC_HOT_PLUG_DETECT2_CONTROL 0x007D10 | ||
423 | #define S_007D10_DC_HOT_PLUG_DETECT2_EN(x) (((x) & 0x1) << 0) | ||
424 | #define G_007D10_DC_HOT_PLUG_DETECT2_EN(x) (((x) >> 0) & 0x1) | ||
425 | #define C_007D10_DC_HOT_PLUG_DETECT2_EN 0xFFFFFFFE | ||
426 | #define R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS 0x007D14 | ||
427 | #define S_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x) (((x) & 0x1) << 0) | ||
428 | #define G_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x) (((x) >> 0) & 0x1) | ||
429 | #define C_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS 0xFFFFFFFE | ||
430 | #define S_007D14_DC_HOT_PLUG_DETECT2_SENSE(x) (((x) & 0x1) << 1) | ||
431 | #define G_007D14_DC_HOT_PLUG_DETECT2_SENSE(x) (((x) >> 1) & 0x1) | ||
432 | #define C_007D14_DC_HOT_PLUG_DETECT2_SENSE 0xFFFFFFFD | ||
433 | #define R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL 0x007D18 | ||
434 | #define S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(x) (((x) & 0x1) << 0) | ||
435 | #define C_007D18_DC_HOT_PLUG_DETECT2_INT_ACK 0xFFFFFFFE | ||
436 | #define S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) & 0x1) << 8) | ||
437 | #define G_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) >> 8) & 0x1) | ||
438 | #define C_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY 0xFFFFFEFF | ||
439 | #define S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) & 0x1) << 16) | ||
440 | #define G_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) >> 16) & 0x1) | ||
441 | #define C_007D18_DC_HOT_PLUG_DETECT2_INT_EN 0xFFFEFFFF | ||
374 | 442 | ||
375 | /* MC registers */ | 443 | /* MC registers */ |
376 | #define R_000000_MC_STATUS 0x000000 | 444 | #define R_000000_MC_STATUS 0x000000 |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 025e3225346c..1e22f52d6039 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -131,24 +131,25 @@ void rs690_pm_info(struct radeon_device *rdev) | |||
131 | 131 | ||
132 | void rs690_vram_info(struct radeon_device *rdev) | 132 | void rs690_vram_info(struct radeon_device *rdev) |
133 | { | 133 | { |
134 | uint32_t tmp; | ||
135 | fixed20_12 a; | 134 | fixed20_12 a; |
136 | 135 | ||
137 | rs400_gart_adjust_size(rdev); | 136 | rs400_gart_adjust_size(rdev); |
138 | /* DDR for all card after R300 & IGP */ | 137 | |
139 | rdev->mc.vram_is_ddr = true; | 138 | rdev->mc.vram_is_ddr = true; |
140 | /* FIXME: is this correct for RS690/RS740 ? */ | 139 | rdev->mc.vram_width = 128; |
141 | tmp = RREG32(RADEON_MEM_CNTL); | 140 | |
142 | if (tmp & R300_MEM_NUM_CHANNELS_MASK) { | ||
143 | rdev->mc.vram_width = 128; | ||
144 | } else { | ||
145 | rdev->mc.vram_width = 64; | ||
146 | } | ||
147 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); | 141 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); |
148 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; | 142 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; |
149 | 143 | ||
150 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 144 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); |
151 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 145 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); |
146 | |||
147 | if (rdev->mc.mc_vram_size > rdev->mc.aper_size) | ||
148 | rdev->mc.mc_vram_size = rdev->mc.aper_size; | ||
149 | |||
150 | if (rdev->mc.real_vram_size > rdev->mc.aper_size) | ||
151 | rdev->mc.real_vram_size = rdev->mc.aper_size; | ||
152 | |||
152 | rs690_pm_info(rdev); | 153 | rs690_pm_info(rdev); |
153 | /* FIXME: we should enforce default clock in case GPU is not in | 154 | /* FIXME: we should enforce default clock in case GPU is not in |
154 | * default setup | 155 | * default setup |
@@ -161,6 +162,21 @@ void rs690_vram_info(struct radeon_device *rdev) | |||
161 | rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a); | 162 | rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a); |
162 | } | 163 | } |
163 | 164 | ||
165 | static int rs690_mc_init(struct radeon_device *rdev) | ||
166 | { | ||
167 | int r; | ||
168 | u32 tmp; | ||
169 | |||
170 | /* Setup GPU memory space */ | ||
171 | tmp = RREG32_MC(R_000100_MCCFG_FB_LOCATION); | ||
172 | rdev->mc.vram_location = G_000100_MC_FB_START(tmp) << 16; | ||
173 | rdev->mc.gtt_location = 0xFFFFFFFFUL; | ||
174 | r = radeon_mc_setup(rdev); | ||
175 | if (r) | ||
176 | return r; | ||
177 | return 0; | ||
178 | } | ||
179 | |||
164 | void rs690_line_buffer_adjust(struct radeon_device *rdev, | 180 | void rs690_line_buffer_adjust(struct radeon_device *rdev, |
165 | struct drm_display_mode *mode1, | 181 | struct drm_display_mode *mode1, |
166 | struct drm_display_mode *mode2) | 182 | struct drm_display_mode *mode2) |
@@ -244,8 +260,9 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, | |||
244 | 260 | ||
245 | b.full = rfixed_const(mode->crtc_hdisplay); | 261 | b.full = rfixed_const(mode->crtc_hdisplay); |
246 | c.full = rfixed_const(256); | 262 | c.full = rfixed_const(256); |
247 | a.full = rfixed_mul(wm->num_line_pair, b); | 263 | a.full = rfixed_div(b, c); |
248 | request_fifo_depth.full = rfixed_div(a, c); | 264 | request_fifo_depth.full = rfixed_mul(a, wm->num_line_pair); |
265 | request_fifo_depth.full = rfixed_ceil(request_fifo_depth); | ||
249 | if (a.full < rfixed_const(4)) { | 266 | if (a.full < rfixed_const(4)) { |
250 | wm->lb_request_fifo_depth = 4; | 267 | wm->lb_request_fifo_depth = 4; |
251 | } else { | 268 | } else { |
@@ -374,6 +391,7 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, | |||
374 | a.full = rfixed_const(16); | 391 | a.full = rfixed_const(16); |
375 | wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay); | 392 | wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay); |
376 | wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a); | 393 | wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a); |
394 | wm->priority_mark_max.full = rfixed_ceil(wm->priority_mark_max); | ||
377 | 395 | ||
378 | /* Determine estimated width */ | 396 | /* Determine estimated width */ |
379 | estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; | 397 | estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; |
@@ -383,6 +401,7 @@ void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, | |||
383 | } else { | 401 | } else { |
384 | a.full = rfixed_const(16); | 402 | a.full = rfixed_const(16); |
385 | wm->priority_mark.full = rfixed_div(estimated_width, a); | 403 | wm->priority_mark.full = rfixed_div(estimated_width, a); |
404 | wm->priority_mark.full = rfixed_ceil(wm->priority_mark); | ||
386 | wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; | 405 | wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; |
387 | } | 406 | } |
388 | } | 407 | } |
@@ -605,7 +624,6 @@ static int rs690_startup(struct radeon_device *rdev) | |||
605 | if (r) | 624 | if (r) |
606 | return r; | 625 | return r; |
607 | /* Enable IRQ */ | 626 | /* Enable IRQ */ |
608 | rdev->irq.sw_int = true; | ||
609 | rs600_irq_set(rdev); | 627 | rs600_irq_set(rdev); |
610 | /* 1M ring buffer */ | 628 | /* 1M ring buffer */ |
611 | r = r100_cp_init(rdev, 1024 * 1024); | 629 | r = r100_cp_init(rdev, 1024 * 1024); |
@@ -640,6 +658,8 @@ int rs690_resume(struct radeon_device *rdev) | |||
640 | atom_asic_init(rdev->mode_info.atom_context); | 658 | atom_asic_init(rdev->mode_info.atom_context); |
641 | /* Resume clock after posting */ | 659 | /* Resume clock after posting */ |
642 | rv515_clock_startup(rdev); | 660 | rv515_clock_startup(rdev); |
661 | /* Initialize surface registers */ | ||
662 | radeon_surface_init(rdev); | ||
643 | return rs690_startup(rdev); | 663 | return rs690_startup(rdev); |
644 | } | 664 | } |
645 | 665 | ||
@@ -662,7 +682,7 @@ void rs690_fini(struct radeon_device *rdev) | |||
662 | rs400_gart_fini(rdev); | 682 | rs400_gart_fini(rdev); |
663 | radeon_irq_kms_fini(rdev); | 683 | radeon_irq_kms_fini(rdev); |
664 | radeon_fence_driver_fini(rdev); | 684 | radeon_fence_driver_fini(rdev); |
665 | radeon_object_fini(rdev); | 685 | radeon_bo_fini(rdev); |
666 | radeon_atombios_fini(rdev); | 686 | radeon_atombios_fini(rdev); |
667 | kfree(rdev->bios); | 687 | kfree(rdev->bios); |
668 | rdev->bios = NULL; | 688 | rdev->bios = NULL; |
@@ -700,16 +720,17 @@ int rs690_init(struct radeon_device *rdev) | |||
700 | RREG32(R_0007C0_CP_STAT)); | 720 | RREG32(R_0007C0_CP_STAT)); |
701 | } | 721 | } |
702 | /* check if cards are posted or not */ | 722 | /* check if cards are posted or not */ |
703 | if (!radeon_card_posted(rdev) && rdev->bios) { | 723 | if (radeon_boot_test_post_card(rdev) == false) |
704 | DRM_INFO("GPU not posted. posting now...\n"); | 724 | return -EINVAL; |
705 | atom_asic_init(rdev->mode_info.atom_context); | 725 | |
706 | } | ||
707 | /* Initialize clocks */ | 726 | /* Initialize clocks */ |
708 | radeon_get_clock_info(rdev->ddev); | 727 | radeon_get_clock_info(rdev->ddev); |
728 | /* Initialize power management */ | ||
729 | radeon_pm_init(rdev); | ||
709 | /* Get vram informations */ | 730 | /* Get vram informations */ |
710 | rs690_vram_info(rdev); | 731 | rs690_vram_info(rdev); |
711 | /* Initialize memory controller (also test AGP) */ | 732 | /* Initialize memory controller (also test AGP) */ |
712 | r = r420_mc_init(rdev); | 733 | r = rs690_mc_init(rdev); |
713 | if (r) | 734 | if (r) |
714 | return r; | 735 | return r; |
715 | rv515_debugfs(rdev); | 736 | rv515_debugfs(rdev); |
@@ -721,7 +742,7 @@ int rs690_init(struct radeon_device *rdev) | |||
721 | if (r) | 742 | if (r) |
722 | return r; | 743 | return r; |
723 | /* Memory manager */ | 744 | /* Memory manager */ |
724 | r = radeon_object_init(rdev); | 745 | r = radeon_bo_init(rdev); |
725 | if (r) | 746 | if (r) |
726 | return r; | 747 | return r; |
727 | r = rs400_gart_init(rdev); | 748 | r = rs400_gart_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 41a34c23e6d8..59632a506b46 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -380,7 +380,6 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
380 | save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); | 380 | save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); |
381 | 381 | ||
382 | /* Stop all video */ | 382 | /* Stop all video */ |
383 | WREG32(R_000330_D1VGA_CONTROL, 0); | ||
384 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 383 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
385 | WREG32(R_000300_VGA_RENDER_CONTROL, 0); | 384 | WREG32(R_000300_VGA_RENDER_CONTROL, 0); |
386 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | 385 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); |
@@ -389,6 +388,8 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
389 | WREG32(R_006880_D2CRTC_CONTROL, 0); | 388 | WREG32(R_006880_D2CRTC_CONTROL, 0); |
390 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | 389 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); |
391 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 390 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
391 | WREG32(R_000330_D1VGA_CONTROL, 0); | ||
392 | WREG32(R_000338_D2VGA_CONTROL, 0); | ||
392 | } | 393 | } |
393 | 394 | ||
394 | void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | 395 | void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) |
@@ -402,14 +403,14 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
402 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); | 403 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); |
403 | mdelay(1); | 404 | mdelay(1); |
404 | /* Restore video state */ | 405 | /* Restore video state */ |
406 | WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); | ||
407 | WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); | ||
405 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | 408 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); |
406 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); | 409 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); |
407 | WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); | 410 | WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); |
408 | WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); | 411 | WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); |
409 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | 412 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); |
410 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 413 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
411 | WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); | ||
412 | WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); | ||
413 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); | 414 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); |
414 | } | 415 | } |
415 | 416 | ||
@@ -477,7 +478,6 @@ static int rv515_startup(struct radeon_device *rdev) | |||
477 | return r; | 478 | return r; |
478 | } | 479 | } |
479 | /* Enable IRQ */ | 480 | /* Enable IRQ */ |
480 | rdev->irq.sw_int = true; | ||
481 | rs600_irq_set(rdev); | 481 | rs600_irq_set(rdev); |
482 | /* 1M ring buffer */ | 482 | /* 1M ring buffer */ |
483 | r = r100_cp_init(rdev, 1024 * 1024); | 483 | r = r100_cp_init(rdev, 1024 * 1024); |
@@ -513,6 +513,8 @@ int rv515_resume(struct radeon_device *rdev) | |||
513 | atom_asic_init(rdev->mode_info.atom_context); | 513 | atom_asic_init(rdev->mode_info.atom_context); |
514 | /* Resume clock after posting */ | 514 | /* Resume clock after posting */ |
515 | rv515_clock_startup(rdev); | 515 | rv515_clock_startup(rdev); |
516 | /* Initialize surface registers */ | ||
517 | radeon_surface_init(rdev); | ||
516 | return rv515_startup(rdev); | 518 | return rv515_startup(rdev); |
517 | } | 519 | } |
518 | 520 | ||
@@ -539,11 +541,11 @@ void rv515_fini(struct radeon_device *rdev) | |||
539 | r100_wb_fini(rdev); | 541 | r100_wb_fini(rdev); |
540 | r100_ib_fini(rdev); | 542 | r100_ib_fini(rdev); |
541 | radeon_gem_fini(rdev); | 543 | radeon_gem_fini(rdev); |
542 | rv370_pcie_gart_fini(rdev); | 544 | rv370_pcie_gart_fini(rdev); |
543 | radeon_agp_fini(rdev); | 545 | radeon_agp_fini(rdev); |
544 | radeon_irq_kms_fini(rdev); | 546 | radeon_irq_kms_fini(rdev); |
545 | radeon_fence_driver_fini(rdev); | 547 | radeon_fence_driver_fini(rdev); |
546 | radeon_object_fini(rdev); | 548 | radeon_bo_fini(rdev); |
547 | radeon_atombios_fini(rdev); | 549 | radeon_atombios_fini(rdev); |
548 | kfree(rdev->bios); | 550 | kfree(rdev->bios); |
549 | rdev->bios = NULL; | 551 | rdev->bios = NULL; |
@@ -579,12 +581,12 @@ int rv515_init(struct radeon_device *rdev) | |||
579 | RREG32(R_0007C0_CP_STAT)); | 581 | RREG32(R_0007C0_CP_STAT)); |
580 | } | 582 | } |
581 | /* check if cards are posted or not */ | 583 | /* check if cards are posted or not */ |
582 | if (!radeon_card_posted(rdev) && rdev->bios) { | 584 | if (radeon_boot_test_post_card(rdev) == false) |
583 | DRM_INFO("GPU not posted. posting now...\n"); | 585 | return -EINVAL; |
584 | atom_asic_init(rdev->mode_info.atom_context); | ||
585 | } | ||
586 | /* Initialize clocks */ | 586 | /* Initialize clocks */ |
587 | radeon_get_clock_info(rdev->ddev); | 587 | radeon_get_clock_info(rdev->ddev); |
588 | /* Initialize power management */ | ||
589 | radeon_pm_init(rdev); | ||
588 | /* Get vram informations */ | 590 | /* Get vram informations */ |
589 | rv515_vram_info(rdev); | 591 | rv515_vram_info(rdev); |
590 | /* Initialize memory controller (also test AGP) */ | 592 | /* Initialize memory controller (also test AGP) */ |
@@ -600,7 +602,7 @@ int rv515_init(struct radeon_device *rdev) | |||
600 | if (r) | 602 | if (r) |
601 | return r; | 603 | return r; |
602 | /* Memory manager */ | 604 | /* Memory manager */ |
603 | r = radeon_object_init(rdev); | 605 | r = radeon_bo_init(rdev); |
604 | if (r) | 606 | if (r) |
605 | return r; | 607 | return r; |
606 | r = rv370_pcie_gart_init(rdev); | 608 | r = rv370_pcie_gart_init(rdev); |
@@ -889,8 +891,9 @@ void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, | |||
889 | 891 | ||
890 | b.full = rfixed_const(mode->crtc_hdisplay); | 892 | b.full = rfixed_const(mode->crtc_hdisplay); |
891 | c.full = rfixed_const(256); | 893 | c.full = rfixed_const(256); |
892 | a.full = rfixed_mul(wm->num_line_pair, b); | 894 | a.full = rfixed_div(b, c); |
893 | request_fifo_depth.full = rfixed_div(a, c); | 895 | request_fifo_depth.full = rfixed_mul(a, wm->num_line_pair); |
896 | request_fifo_depth.full = rfixed_ceil(request_fifo_depth); | ||
894 | if (a.full < rfixed_const(4)) { | 897 | if (a.full < rfixed_const(4)) { |
895 | wm->lb_request_fifo_depth = 4; | 898 | wm->lb_request_fifo_depth = 4; |
896 | } else { | 899 | } else { |
@@ -992,15 +995,17 @@ void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, | |||
992 | a.full = rfixed_const(16); | 995 | a.full = rfixed_const(16); |
993 | wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay); | 996 | wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay); |
994 | wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a); | 997 | wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a); |
998 | wm->priority_mark_max.full = rfixed_ceil(wm->priority_mark_max); | ||
995 | 999 | ||
996 | /* Determine estimated width */ | 1000 | /* Determine estimated width */ |
997 | estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; | 1001 | estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; |
998 | estimated_width.full = rfixed_div(estimated_width, consumption_time); | 1002 | estimated_width.full = rfixed_div(estimated_width, consumption_time); |
999 | if (rfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { | 1003 | if (rfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { |
1000 | wm->priority_mark.full = rfixed_const(10); | 1004 | wm->priority_mark.full = wm->priority_mark_max.full; |
1001 | } else { | 1005 | } else { |
1002 | a.full = rfixed_const(16); | 1006 | a.full = rfixed_const(16); |
1003 | wm->priority_mark.full = rfixed_div(estimated_width, a); | 1007 | wm->priority_mark.full = rfixed_div(estimated_width, a); |
1008 | wm->priority_mark.full = rfixed_ceil(wm->priority_mark); | ||
1004 | wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; | 1009 | wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; |
1005 | } | 1010 | } |
1006 | } | 1011 | } |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 595ac638039d..fbb0357f1ec3 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -92,7 +92,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev) | |||
92 | void rv770_pcie_gart_disable(struct radeon_device *rdev) | 92 | void rv770_pcie_gart_disable(struct radeon_device *rdev) |
93 | { | 93 | { |
94 | u32 tmp; | 94 | u32 tmp; |
95 | int i; | 95 | int i, r; |
96 | 96 | ||
97 | /* Disable all tables */ | 97 | /* Disable all tables */ |
98 | for (i = 0; i < 7; i++) | 98 | for (i = 0; i < 7; i++) |
@@ -113,8 +113,12 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev) | |||
113 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | 113 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); |
114 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); | 114 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); |
115 | if (rdev->gart.table.vram.robj) { | 115 | if (rdev->gart.table.vram.robj) { |
116 | radeon_object_kunmap(rdev->gart.table.vram.robj); | 116 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); |
117 | radeon_object_unpin(rdev->gart.table.vram.robj); | 117 | if (likely(r == 0)) { |
118 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
119 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
120 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
121 | } | ||
118 | } | 122 | } |
119 | } | 123 | } |
120 | 124 | ||
@@ -529,11 +533,11 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
529 | if (rdev->family == CHIP_RV770) | 533 | if (rdev->family == CHIP_RV770) |
530 | gb_tiling_config |= BANK_TILING(1); | 534 | gb_tiling_config |= BANK_TILING(1); |
531 | else | 535 | else |
532 | gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_SHIFT) >> NOOFBANK_MASK); | 536 | gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); |
533 | 537 | ||
534 | gb_tiling_config |= GROUP_SIZE(0); | 538 | gb_tiling_config |= GROUP_SIZE(0); |
535 | 539 | ||
536 | if (((mc_arb_ramcfg & NOOFROWS_MASK) & NOOFROWS_SHIFT) > 3) { | 540 | if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) { |
537 | gb_tiling_config |= ROW_TILING(3); | 541 | gb_tiling_config |= ROW_TILING(3); |
538 | gb_tiling_config |= SAMPLE_SPLIT(3); | 542 | gb_tiling_config |= SAMPLE_SPLIT(3); |
539 | } else { | 543 | } else { |
@@ -579,14 +583,14 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
579 | 583 | ||
580 | /* set HW defaults for 3D engine */ | 584 | /* set HW defaults for 3D engine */ |
581 | WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | | 585 | WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | |
582 | ROQ_IB2_START(0x2b))); | 586 | ROQ_IB2_START(0x2b))); |
583 | 587 | ||
584 | WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30)); | 588 | WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30)); |
585 | 589 | ||
586 | WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | | 590 | WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | |
587 | SYNC_GRADIENT | | 591 | SYNC_GRADIENT | |
588 | SYNC_WALKER | | 592 | SYNC_WALKER | |
589 | SYNC_ALIGNER)); | 593 | SYNC_ALIGNER)); |
590 | 594 | ||
591 | sx_debug_1 = RREG32(SX_DEBUG_1); | 595 | sx_debug_1 = RREG32(SX_DEBUG_1); |
592 | sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; | 596 | sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; |
@@ -598,9 +602,9 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
598 | WREG32(SMX_DC_CTL0, smx_dc_ctl0); | 602 | WREG32(SMX_DC_CTL0, smx_dc_ctl0); |
599 | 603 | ||
600 | WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) | | 604 | WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) | |
601 | GS_FLUSH_CTL(4) | | 605 | GS_FLUSH_CTL(4) | |
602 | ACK_FLUSH_CTL(3) | | 606 | ACK_FLUSH_CTL(3) | |
603 | SYNC_FLUSH_CTL)); | 607 | SYNC_FLUSH_CTL)); |
604 | 608 | ||
605 | if (rdev->family == CHIP_RV770) | 609 | if (rdev->family == CHIP_RV770) |
606 | WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f)); | 610 | WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f)); |
@@ -611,12 +615,12 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
611 | } | 615 | } |
612 | 616 | ||
613 | WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) | | 617 | WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) | |
614 | POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) | | 618 | POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) | |
615 | SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1))); | 619 | SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1))); |
616 | 620 | ||
617 | WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) | | 621 | WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) | |
618 | SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) | | 622 | SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) | |
619 | SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize))); | 623 | SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize))); |
620 | 624 | ||
621 | WREG32(PA_SC_MULTI_CHIP_CNTL, 0); | 625 | WREG32(PA_SC_MULTI_CHIP_CNTL, 0); |
622 | 626 | ||
@@ -774,14 +778,36 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
774 | { | 778 | { |
775 | fixed20_12 a; | 779 | fixed20_12 a; |
776 | u32 tmp; | 780 | u32 tmp; |
781 | int chansize, numchan; | ||
777 | int r; | 782 | int r; |
778 | 783 | ||
779 | /* Get VRAM informations */ | 784 | /* Get VRAM informations */ |
780 | /* FIXME: Don't know how to determine vram width, need to check | ||
781 | * vram_width usage | ||
782 | */ | ||
783 | rdev->mc.vram_width = 128; | ||
784 | rdev->mc.vram_is_ddr = true; | 785 | rdev->mc.vram_is_ddr = true; |
786 | tmp = RREG32(MC_ARB_RAMCFG); | ||
787 | if (tmp & CHANSIZE_OVERRIDE) { | ||
788 | chansize = 16; | ||
789 | } else if (tmp & CHANSIZE_MASK) { | ||
790 | chansize = 64; | ||
791 | } else { | ||
792 | chansize = 32; | ||
793 | } | ||
794 | tmp = RREG32(MC_SHARED_CHMAP); | ||
795 | switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { | ||
796 | case 0: | ||
797 | default: | ||
798 | numchan = 1; | ||
799 | break; | ||
800 | case 1: | ||
801 | numchan = 2; | ||
802 | break; | ||
803 | case 2: | ||
804 | numchan = 4; | ||
805 | break; | ||
806 | case 3: | ||
807 | numchan = 8; | ||
808 | break; | ||
809 | } | ||
810 | rdev->mc.vram_width = numchan * chansize; | ||
785 | /* Could aper size report 0 ? */ | 811 | /* Could aper size report 0 ? */ |
786 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 812 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); |
787 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 813 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); |
@@ -807,11 +833,11 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
807 | * AGP so that GPU can catch out of VRAM/AGP access | 833 | * AGP so that GPU can catch out of VRAM/AGP access |
808 | */ | 834 | */ |
809 | if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { | 835 | if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { |
810 | /* Enought place before */ | 836 | /* Enough place before */ |
811 | rdev->mc.vram_location = rdev->mc.gtt_location - | 837 | rdev->mc.vram_location = rdev->mc.gtt_location - |
812 | rdev->mc.mc_vram_size; | 838 | rdev->mc.mc_vram_size; |
813 | } else if (tmp > rdev->mc.mc_vram_size) { | 839 | } else if (tmp > rdev->mc.mc_vram_size) { |
814 | /* Enought place after */ | 840 | /* Enough place after */ |
815 | rdev->mc.vram_location = rdev->mc.gtt_location + | 841 | rdev->mc.vram_location = rdev->mc.gtt_location + |
816 | rdev->mc.gtt_size; | 842 | rdev->mc.gtt_size; |
817 | } else { | 843 | } else { |
@@ -848,6 +874,14 @@ static int rv770_startup(struct radeon_device *rdev) | |||
848 | { | 874 | { |
849 | int r; | 875 | int r; |
850 | 876 | ||
877 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | ||
878 | r = r600_init_microcode(rdev); | ||
879 | if (r) { | ||
880 | DRM_ERROR("Failed to load firmware!\n"); | ||
881 | return r; | ||
882 | } | ||
883 | } | ||
884 | |||
851 | rv770_mc_program(rdev); | 885 | rv770_mc_program(rdev); |
852 | if (rdev->flags & RADEON_IS_AGP) { | 886 | if (rdev->flags & RADEON_IS_AGP) { |
853 | rv770_agp_enable(rdev); | 887 | rv770_agp_enable(rdev); |
@@ -858,13 +892,26 @@ static int rv770_startup(struct radeon_device *rdev) | |||
858 | } | 892 | } |
859 | rv770_gpu_init(rdev); | 893 | rv770_gpu_init(rdev); |
860 | 894 | ||
861 | r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | 895 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); |
862 | &rdev->r600_blit.shader_gpu_addr); | 896 | if (unlikely(r != 0)) |
897 | return r; | ||
898 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
899 | &rdev->r600_blit.shader_gpu_addr); | ||
900 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
863 | if (r) { | 901 | if (r) { |
864 | DRM_ERROR("failed to pin blit object %d\n", r); | 902 | DRM_ERROR("failed to pin blit object %d\n", r); |
865 | return r; | 903 | return r; |
866 | } | 904 | } |
867 | 905 | ||
906 | /* Enable IRQ */ | ||
907 | r = r600_irq_init(rdev); | ||
908 | if (r) { | ||
909 | DRM_ERROR("radeon: IH init failed (%d).\n", r); | ||
910 | radeon_irq_kms_fini(rdev); | ||
911 | return r; | ||
912 | } | ||
913 | r600_irq_set(rdev); | ||
914 | |||
868 | r = radeon_ring_init(rdev, rdev->cp.ring_size); | 915 | r = radeon_ring_init(rdev, rdev->cp.ring_size); |
869 | if (r) | 916 | if (r) |
870 | return r; | 917 | return r; |
@@ -912,13 +959,19 @@ int rv770_resume(struct radeon_device *rdev) | |||
912 | 959 | ||
913 | int rv770_suspend(struct radeon_device *rdev) | 960 | int rv770_suspend(struct radeon_device *rdev) |
914 | { | 961 | { |
962 | int r; | ||
963 | |||
915 | /* FIXME: we should wait for ring to be empty */ | 964 | /* FIXME: we should wait for ring to be empty */ |
916 | r700_cp_stop(rdev); | 965 | r700_cp_stop(rdev); |
917 | rdev->cp.ready = false; | 966 | rdev->cp.ready = false; |
918 | r600_wb_disable(rdev); | 967 | r600_wb_disable(rdev); |
919 | rv770_pcie_gart_disable(rdev); | 968 | rv770_pcie_gart_disable(rdev); |
920 | /* unpin shaders bo */ | 969 | /* unpin shaders bo */ |
921 | radeon_object_unpin(rdev->r600_blit.shader_obj); | 970 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); |
971 | if (likely(r == 0)) { | ||
972 | radeon_bo_unpin(rdev->r600_blit.shader_obj); | ||
973 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
974 | } | ||
922 | return 0; | 975 | return 0; |
923 | } | 976 | } |
924 | 977 | ||
@@ -953,7 +1006,11 @@ int rv770_init(struct radeon_device *rdev) | |||
953 | if (r) | 1006 | if (r) |
954 | return r; | 1007 | return r; |
955 | /* Post card if necessary */ | 1008 | /* Post card if necessary */ |
956 | if (!r600_card_posted(rdev) && rdev->bios) { | 1009 | if (!r600_card_posted(rdev)) { |
1010 | if (!rdev->bios) { | ||
1011 | dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); | ||
1012 | return -EINVAL; | ||
1013 | } | ||
957 | DRM_INFO("GPU not posted. posting now...\n"); | 1014 | DRM_INFO("GPU not posted. posting now...\n"); |
958 | atom_asic_init(rdev->mode_info.atom_context); | 1015 | atom_asic_init(rdev->mode_info.atom_context); |
959 | } | 1016 | } |
@@ -961,10 +1018,13 @@ int rv770_init(struct radeon_device *rdev) | |||
961 | r600_scratch_init(rdev); | 1018 | r600_scratch_init(rdev); |
962 | /* Initialize surface registers */ | 1019 | /* Initialize surface registers */ |
963 | radeon_surface_init(rdev); | 1020 | radeon_surface_init(rdev); |
1021 | /* Initialize clocks */ | ||
964 | radeon_get_clock_info(rdev->ddev); | 1022 | radeon_get_clock_info(rdev->ddev); |
965 | r = radeon_clocks_init(rdev); | 1023 | r = radeon_clocks_init(rdev); |
966 | if (r) | 1024 | if (r) |
967 | return r; | 1025 | return r; |
1026 | /* Initialize power management */ | ||
1027 | radeon_pm_init(rdev); | ||
968 | /* Fence driver */ | 1028 | /* Fence driver */ |
969 | r = radeon_fence_driver_init(rdev); | 1029 | r = radeon_fence_driver_init(rdev); |
970 | if (r) | 1030 | if (r) |
@@ -973,31 +1033,31 @@ int rv770_init(struct radeon_device *rdev) | |||
973 | if (r) | 1033 | if (r) |
974 | return r; | 1034 | return r; |
975 | /* Memory manager */ | 1035 | /* Memory manager */ |
976 | r = radeon_object_init(rdev); | 1036 | r = radeon_bo_init(rdev); |
1037 | if (r) | ||
1038 | return r; | ||
1039 | |||
1040 | r = radeon_irq_kms_init(rdev); | ||
977 | if (r) | 1041 | if (r) |
978 | return r; | 1042 | return r; |
1043 | |||
979 | rdev->cp.ring_obj = NULL; | 1044 | rdev->cp.ring_obj = NULL; |
980 | r600_ring_init(rdev, 1024 * 1024); | 1045 | r600_ring_init(rdev, 1024 * 1024); |
981 | 1046 | ||
982 | if (!rdev->me_fw || !rdev->pfp_fw) { | 1047 | rdev->ih.ring_obj = NULL; |
983 | r = r600_cp_init_microcode(rdev); | 1048 | r600_ih_ring_init(rdev, 64 * 1024); |
984 | if (r) { | ||
985 | DRM_ERROR("Failed to load firmware!\n"); | ||
986 | return r; | ||
987 | } | ||
988 | } | ||
989 | 1049 | ||
990 | r = r600_pcie_gart_init(rdev); | 1050 | r = r600_pcie_gart_init(rdev); |
991 | if (r) | 1051 | if (r) |
992 | return r; | 1052 | return r; |
993 | 1053 | ||
994 | rdev->accel_working = true; | ||
995 | r = r600_blit_init(rdev); | 1054 | r = r600_blit_init(rdev); |
996 | if (r) { | 1055 | if (r) { |
997 | DRM_ERROR("radeon: failled blitter (%d).\n", r); | 1056 | DRM_ERROR("radeon: failed blitter (%d).\n", r); |
998 | rdev->accel_working = false; | 1057 | return r; |
999 | } | 1058 | } |
1000 | 1059 | ||
1060 | rdev->accel_working = true; | ||
1001 | r = rv770_startup(rdev); | 1061 | r = rv770_startup(rdev); |
1002 | if (r) { | 1062 | if (r) { |
1003 | rv770_suspend(rdev); | 1063 | rv770_suspend(rdev); |
@@ -1009,12 +1069,12 @@ int rv770_init(struct radeon_device *rdev) | |||
1009 | if (rdev->accel_working) { | 1069 | if (rdev->accel_working) { |
1010 | r = radeon_ib_pool_init(rdev); | 1070 | r = radeon_ib_pool_init(rdev); |
1011 | if (r) { | 1071 | if (r) { |
1012 | DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); | 1072 | DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r); |
1013 | rdev->accel_working = false; | 1073 | rdev->accel_working = false; |
1014 | } | 1074 | } |
1015 | r = r600_ib_test(rdev); | 1075 | r = r600_ib_test(rdev); |
1016 | if (r) { | 1076 | if (r) { |
1017 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | 1077 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); |
1018 | rdev->accel_working = false; | 1078 | rdev->accel_working = false; |
1019 | } | 1079 | } |
1020 | } | 1080 | } |
@@ -1026,6 +1086,8 @@ void rv770_fini(struct radeon_device *rdev) | |||
1026 | rv770_suspend(rdev); | 1086 | rv770_suspend(rdev); |
1027 | 1087 | ||
1028 | r600_blit_fini(rdev); | 1088 | r600_blit_fini(rdev); |
1089 | r600_irq_fini(rdev); | ||
1090 | radeon_irq_kms_fini(rdev); | ||
1029 | radeon_ring_fini(rdev); | 1091 | radeon_ring_fini(rdev); |
1030 | r600_wb_fini(rdev); | 1092 | r600_wb_fini(rdev); |
1031 | rv770_pcie_gart_fini(rdev); | 1093 | rv770_pcie_gart_fini(rdev); |
@@ -1034,7 +1096,7 @@ void rv770_fini(struct radeon_device *rdev) | |||
1034 | radeon_clocks_fini(rdev); | 1096 | radeon_clocks_fini(rdev); |
1035 | if (rdev->flags & RADEON_IS_AGP) | 1097 | if (rdev->flags & RADEON_IS_AGP) |
1036 | radeon_agp_fini(rdev); | 1098 | radeon_agp_fini(rdev); |
1037 | radeon_object_fini(rdev); | 1099 | radeon_bo_fini(rdev); |
1038 | radeon_atombios_fini(rdev); | 1100 | radeon_atombios_fini(rdev); |
1039 | kfree(rdev->bios); | 1101 | kfree(rdev->bios); |
1040 | rdev->bios = NULL; | 1102 | rdev->bios = NULL; |
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 4b9c3d6396ff..a1367ab6f261 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h | |||
@@ -129,6 +129,10 @@ | |||
129 | #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 | 129 | #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 |
130 | #define HDP_TILING_CONFIG 0x2F3C | 130 | #define HDP_TILING_CONFIG 0x2F3C |
131 | 131 | ||
132 | #define MC_SHARED_CHMAP 0x2004 | ||
133 | #define NOOFCHAN_SHIFT 12 | ||
134 | #define NOOFCHAN_MASK 0x00003000 | ||
135 | |||
132 | #define MC_ARB_RAMCFG 0x2760 | 136 | #define MC_ARB_RAMCFG 0x2760 |
133 | #define NOOFBANK_SHIFT 0 | 137 | #define NOOFBANK_SHIFT 0 |
134 | #define NOOFBANK_MASK 0x00000003 | 138 | #define NOOFBANK_MASK 0x00000003 |
@@ -142,6 +146,7 @@ | |||
142 | #define CHANSIZE_MASK 0x00000100 | 146 | #define CHANSIZE_MASK 0x00000100 |
143 | #define BURSTLENGTH_SHIFT 9 | 147 | #define BURSTLENGTH_SHIFT 9 |
144 | #define BURSTLENGTH_MASK 0x00000200 | 148 | #define BURSTLENGTH_MASK 0x00000200 |
149 | #define CHANSIZE_OVERRIDE (1 << 11) | ||
145 | #define MC_VM_AGP_TOP 0x2028 | 150 | #define MC_VM_AGP_TOP 0x2028 |
146 | #define MC_VM_AGP_BOT 0x202C | 151 | #define MC_VM_AGP_BOT 0x202C |
147 | #define MC_VM_AGP_BASE 0x2030 | 152 | #define MC_VM_AGP_BASE 0x2030 |