diff options
-rw-r--r-- | drivers/gpu/drm/radeon/Makefile | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 370 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_dp.c | 62 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 794 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_reg.h | 176 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 50 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_clocks.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_combios.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_cursor.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 42 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 241 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_family.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_reg.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770d.h | 2 | ||||
-rw-r--r-- | include/drm/drm_pciids.h | 35 |
19 files changed, 1775 insertions, 121 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 1cc7b937b1ea..83c59079193b 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -54,7 +54,8 @@ radeon-y += radeon_device.o radeon_kms.o \ | |||
54 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ | 54 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ |
55 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ | 55 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ |
56 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ | 56 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ |
57 | r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o | 57 | r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ |
58 | evergreen.o | ||
58 | 59 | ||
59 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 60 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
60 | 61 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index bb45517719ae..7e7c0b32bb65 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -249,13 +249,17 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
249 | if (ASIC_IS_DCE3(rdev)) | 249 | if (ASIC_IS_DCE3(rdev)) |
250 | atombios_enable_crtc_memreq(crtc, 1); | 250 | atombios_enable_crtc_memreq(crtc, 1); |
251 | atombios_blank_crtc(crtc, 0); | 251 | atombios_blank_crtc(crtc, 0); |
252 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); | 252 | /* XXX re-enable when interrupt support is added */ |
253 | if (!ASIC_IS_DCE4(rdev)) | ||
254 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); | ||
253 | radeon_crtc_load_lut(crtc); | 255 | radeon_crtc_load_lut(crtc); |
254 | break; | 256 | break; |
255 | case DRM_MODE_DPMS_STANDBY: | 257 | case DRM_MODE_DPMS_STANDBY: |
256 | case DRM_MODE_DPMS_SUSPEND: | 258 | case DRM_MODE_DPMS_SUSPEND: |
257 | case DRM_MODE_DPMS_OFF: | 259 | case DRM_MODE_DPMS_OFF: |
258 | drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); | 260 | /* XXX re-enable when interrupt support is added */ |
261 | if (!ASIC_IS_DCE4(rdev)) | ||
262 | drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); | ||
259 | atombios_blank_crtc(crtc, 1); | 263 | atombios_blank_crtc(crtc, 1); |
260 | if (ASIC_IS_DCE3(rdev)) | 264 | if (ASIC_IS_DCE3(rdev)) |
261 | atombios_enable_crtc_memreq(crtc, 0); | 265 | atombios_enable_crtc_memreq(crtc, 0); |
@@ -367,6 +371,10 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable) | |||
367 | uint16_t percentage = 0; | 371 | uint16_t percentage = 0; |
368 | uint8_t type = 0, step = 0, delay = 0, range = 0; | 372 | uint8_t type = 0, step = 0, delay = 0, range = 0; |
369 | 373 | ||
374 | /* XXX add ss support for DCE4 */ | ||
375 | if (ASIC_IS_DCE4(rdev)) | ||
376 | return; | ||
377 | |||
370 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 378 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
371 | if (encoder->crtc == crtc) { | 379 | if (encoder->crtc == crtc) { |
372 | radeon_encoder = to_radeon_encoder(encoder); | 380 | radeon_encoder = to_radeon_encoder(encoder); |
@@ -411,6 +419,7 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable) | |||
411 | 419 | ||
412 | union adjust_pixel_clock { | 420 | union adjust_pixel_clock { |
413 | ADJUST_DISPLAY_PLL_PS_ALLOCATION v1; | 421 | ADJUST_DISPLAY_PLL_PS_ALLOCATION v1; |
422 | ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3; | ||
414 | }; | 423 | }; |
415 | 424 | ||
416 | static u32 atombios_adjust_pll(struct drm_crtc *crtc, | 425 | static u32 atombios_adjust_pll(struct drm_crtc *crtc, |
@@ -422,6 +431,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
422 | struct drm_encoder *encoder = NULL; | 431 | struct drm_encoder *encoder = NULL; |
423 | struct radeon_encoder *radeon_encoder = NULL; | 432 | struct radeon_encoder *radeon_encoder = NULL; |
424 | u32 adjusted_clock = mode->clock; | 433 | u32 adjusted_clock = mode->clock; |
434 | int encoder_mode = 0; | ||
425 | 435 | ||
426 | /* reset the pll flags */ | 436 | /* reset the pll flags */ |
427 | pll->flags = 0; | 437 | pll->flags = 0; |
@@ -459,6 +469,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
459 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 469 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
460 | if (encoder->crtc == crtc) { | 470 | if (encoder->crtc == crtc) { |
461 | radeon_encoder = to_radeon_encoder(encoder); | 471 | radeon_encoder = to_radeon_encoder(encoder); |
472 | encoder_mode = atombios_get_encoder_mode(encoder); | ||
462 | if (ASIC_IS_AVIVO(rdev)) { | 473 | if (ASIC_IS_AVIVO(rdev)) { |
463 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | 474 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ |
464 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | 475 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) |
@@ -484,14 +495,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
484 | */ | 495 | */ |
485 | if (ASIC_IS_DCE3(rdev)) { | 496 | if (ASIC_IS_DCE3(rdev)) { |
486 | union adjust_pixel_clock args; | 497 | union adjust_pixel_clock args; |
487 | struct radeon_encoder_atom_dig *dig; | ||
488 | u8 frev, crev; | 498 | u8 frev, crev; |
489 | int index; | 499 | int index; |
490 | 500 | ||
491 | if (!radeon_encoder->enc_priv) | ||
492 | return adjusted_clock; | ||
493 | dig = radeon_encoder->enc_priv; | ||
494 | |||
495 | index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); | 501 | index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); |
496 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, | 502 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, |
497 | &crev); | 503 | &crev); |
@@ -505,12 +511,51 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
505 | case 2: | 511 | case 2: |
506 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); | 512 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); |
507 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; | 513 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; |
508 | args.v1.ucEncodeMode = atombios_get_encoder_mode(encoder); | 514 | args.v1.ucEncodeMode = encoder_mode; |
509 | 515 | ||
510 | atom_execute_table(rdev->mode_info.atom_context, | 516 | atom_execute_table(rdev->mode_info.atom_context, |
511 | index, (uint32_t *)&args); | 517 | index, (uint32_t *)&args); |
512 | adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10; | 518 | adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10; |
513 | break; | 519 | break; |
520 | case 3: | ||
521 | args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10); | ||
522 | args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; | ||
523 | args.v3.sInput.ucEncodeMode = encoder_mode; | ||
524 | args.v3.sInput.ucDispPllConfig = 0; | ||
525 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
526 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
527 | |||
528 | if (encoder_mode == ATOM_ENCODER_MODE_DP) | ||
529 | args.v3.sInput.ucDispPllConfig |= | ||
530 | DISPPLL_CONFIG_COHERENT_MODE; | ||
531 | else { | ||
532 | if (dig->coherent_mode) | ||
533 | args.v3.sInput.ucDispPllConfig |= | ||
534 | DISPPLL_CONFIG_COHERENT_MODE; | ||
535 | if (mode->clock > 165000) | ||
536 | args.v3.sInput.ucDispPllConfig |= | ||
537 | DISPPLL_CONFIG_DUAL_LINK; | ||
538 | } | ||
539 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
540 | /* may want to enable SS on DP/eDP eventually */ | ||
541 | args.v3.sInput.ucDispPllConfig |= | ||
542 | DISPPLL_CONFIG_SS_ENABLE; | ||
543 | if (mode->clock > 165000) | ||
544 | args.v3.sInput.ucDispPllConfig |= | ||
545 | DISPPLL_CONFIG_DUAL_LINK; | ||
546 | } | ||
547 | atom_execute_table(rdev->mode_info.atom_context, | ||
548 | index, (uint32_t *)&args); | ||
549 | adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; | ||
550 | if (args.v3.sOutput.ucRefDiv) { | ||
551 | pll->flags |= RADEON_PLL_USE_REF_DIV; | ||
552 | pll->reference_div = args.v3.sOutput.ucRefDiv; | ||
553 | } | ||
554 | if (args.v3.sOutput.ucPostDiv) { | ||
555 | pll->flags |= RADEON_PLL_USE_POST_DIV; | ||
556 | pll->post_div = args.v3.sOutput.ucPostDiv; | ||
557 | } | ||
558 | break; | ||
514 | default: | 559 | default: |
515 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); | 560 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
516 | return adjusted_clock; | 561 | return adjusted_clock; |
@@ -529,9 +574,47 @@ union set_pixel_clock { | |||
529 | PIXEL_CLOCK_PARAMETERS v1; | 574 | PIXEL_CLOCK_PARAMETERS v1; |
530 | PIXEL_CLOCK_PARAMETERS_V2 v2; | 575 | PIXEL_CLOCK_PARAMETERS_V2 v2; |
531 | PIXEL_CLOCK_PARAMETERS_V3 v3; | 576 | PIXEL_CLOCK_PARAMETERS_V3 v3; |
577 | PIXEL_CLOCK_PARAMETERS_V5 v5; | ||
532 | }; | 578 | }; |
533 | 579 | ||
534 | void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | 580 | static void atombios_crtc_set_dcpll(struct drm_crtc *crtc) |
581 | { | ||
582 | struct drm_device *dev = crtc->dev; | ||
583 | struct radeon_device *rdev = dev->dev_private; | ||
584 | u8 frev, crev; | ||
585 | int index; | ||
586 | union set_pixel_clock args; | ||
587 | |||
588 | memset(&args, 0, sizeof(args)); | ||
589 | |||
590 | index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); | ||
591 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, | ||
592 | &crev); | ||
593 | |||
594 | switch (frev) { | ||
595 | case 1: | ||
596 | switch (crev) { | ||
597 | case 5: | ||
598 | /* if the default dcpll clock is specified, | ||
599 | * SetPixelClock provides the dividers | ||
600 | */ | ||
601 | args.v5.ucCRTC = ATOM_CRTC_INVALID; | ||
602 | args.v5.usPixelClock = rdev->clock.default_dispclk; | ||
603 | args.v5.ucPpll = ATOM_DCPLL; | ||
604 | break; | ||
605 | default: | ||
606 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); | ||
607 | return; | ||
608 | } | ||
609 | break; | ||
610 | default: | ||
611 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); | ||
612 | return; | ||
613 | } | ||
614 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
615 | } | ||
616 | |||
617 | static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | ||
535 | { | 618 | { |
536 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 619 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
537 | struct drm_device *dev = crtc->dev; | 620 | struct drm_device *dev = crtc->dev; |
@@ -545,12 +628,14 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
545 | u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; | 628 | u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; |
546 | struct radeon_pll *pll; | 629 | struct radeon_pll *pll; |
547 | u32 adjusted_clock; | 630 | u32 adjusted_clock; |
631 | int encoder_mode = 0; | ||
548 | 632 | ||
549 | memset(&args, 0, sizeof(args)); | 633 | memset(&args, 0, sizeof(args)); |
550 | 634 | ||
551 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 635 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
552 | if (encoder->crtc == crtc) { | 636 | if (encoder->crtc == crtc) { |
553 | radeon_encoder = to_radeon_encoder(encoder); | 637 | radeon_encoder = to_radeon_encoder(encoder); |
638 | encoder_mode = atombios_get_encoder_mode(encoder); | ||
554 | break; | 639 | break; |
555 | } | 640 | } |
556 | } | 641 | } |
@@ -558,10 +643,18 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
558 | if (!radeon_encoder) | 643 | if (!radeon_encoder) |
559 | return; | 644 | return; |
560 | 645 | ||
561 | if (radeon_crtc->crtc_id == 0) | 646 | switch (radeon_crtc->pll_id) { |
647 | case ATOM_PPLL1: | ||
562 | pll = &rdev->clock.p1pll; | 648 | pll = &rdev->clock.p1pll; |
563 | else | 649 | break; |
650 | case ATOM_PPLL2: | ||
564 | pll = &rdev->clock.p2pll; | 651 | pll = &rdev->clock.p2pll; |
652 | break; | ||
653 | case ATOM_DCPLL: | ||
654 | case ATOM_PPLL_INVALID: | ||
655 | pll = &rdev->clock.dcpll; | ||
656 | break; | ||
657 | } | ||
565 | 658 | ||
566 | /* adjust pixel clock as needed */ | 659 | /* adjust pixel clock as needed */ |
567 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll); | 660 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll); |
@@ -582,8 +675,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
582 | args.v1.usFbDiv = cpu_to_le16(fb_div); | 675 | args.v1.usFbDiv = cpu_to_le16(fb_div); |
583 | args.v1.ucFracFbDiv = frac_fb_div; | 676 | args.v1.ucFracFbDiv = frac_fb_div; |
584 | args.v1.ucPostDiv = post_div; | 677 | args.v1.ucPostDiv = post_div; |
585 | args.v1.ucPpll = | 678 | args.v1.ucPpll = radeon_crtc->pll_id; |
586 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; | ||
587 | args.v1.ucCRTC = radeon_crtc->crtc_id; | 679 | args.v1.ucCRTC = radeon_crtc->crtc_id; |
588 | args.v1.ucRefDivSrc = 1; | 680 | args.v1.ucRefDivSrc = 1; |
589 | break; | 681 | break; |
@@ -593,8 +685,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
593 | args.v2.usFbDiv = cpu_to_le16(fb_div); | 685 | args.v2.usFbDiv = cpu_to_le16(fb_div); |
594 | args.v2.ucFracFbDiv = frac_fb_div; | 686 | args.v2.ucFracFbDiv = frac_fb_div; |
595 | args.v2.ucPostDiv = post_div; | 687 | args.v2.ucPostDiv = post_div; |
596 | args.v2.ucPpll = | 688 | args.v2.ucPpll = radeon_crtc->pll_id; |
597 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; | ||
598 | args.v2.ucCRTC = radeon_crtc->crtc_id; | 689 | args.v2.ucCRTC = radeon_crtc->crtc_id; |
599 | args.v2.ucRefDivSrc = 1; | 690 | args.v2.ucRefDivSrc = 1; |
600 | break; | 691 | break; |
@@ -604,12 +695,22 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
604 | args.v3.usFbDiv = cpu_to_le16(fb_div); | 695 | args.v3.usFbDiv = cpu_to_le16(fb_div); |
605 | args.v3.ucFracFbDiv = frac_fb_div; | 696 | args.v3.ucFracFbDiv = frac_fb_div; |
606 | args.v3.ucPostDiv = post_div; | 697 | args.v3.ucPostDiv = post_div; |
607 | args.v3.ucPpll = | 698 | args.v3.ucPpll = radeon_crtc->pll_id; |
608 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; | 699 | args.v3.ucMiscInfo = (radeon_crtc->pll_id << 2); |
609 | args.v3.ucMiscInfo = (radeon_crtc->crtc_id << 2); | ||
610 | args.v3.ucTransmitterId = radeon_encoder->encoder_id; | 700 | args.v3.ucTransmitterId = radeon_encoder->encoder_id; |
611 | args.v3.ucEncoderMode = | 701 | args.v3.ucEncoderMode = encoder_mode; |
612 | atombios_get_encoder_mode(encoder); | 702 | break; |
703 | case 5: | ||
704 | args.v5.ucCRTC = radeon_crtc->crtc_id; | ||
705 | args.v5.usPixelClock = cpu_to_le16(mode->clock / 10); | ||
706 | args.v5.ucRefDiv = ref_div; | ||
707 | args.v5.usFbDiv = cpu_to_le16(fb_div); | ||
708 | args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); | ||
709 | args.v5.ucPostDiv = post_div; | ||
710 | args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */ | ||
711 | args.v5.ucTransmitterID = radeon_encoder->encoder_id; | ||
712 | args.v5.ucEncoderMode = encoder_mode; | ||
713 | args.v5.ucPpll = radeon_crtc->pll_id; | ||
613 | break; | 714 | break; |
614 | default: | 715 | default: |
615 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); | 716 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
@@ -624,6 +725,140 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
624 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 725 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
625 | } | 726 | } |
626 | 727 | ||
728 | static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | ||
729 | struct drm_framebuffer *old_fb) | ||
730 | { | ||
731 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
732 | struct drm_device *dev = crtc->dev; | ||
733 | struct radeon_device *rdev = dev->dev_private; | ||
734 | struct radeon_framebuffer *radeon_fb; | ||
735 | struct drm_gem_object *obj; | ||
736 | struct radeon_bo *rbo; | ||
737 | uint64_t fb_location; | ||
738 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; | ||
739 | int r; | ||
740 | |||
741 | /* no fb bound */ | ||
742 | if (!crtc->fb) { | ||
743 | DRM_DEBUG("No FB bound\n"); | ||
744 | return 0; | ||
745 | } | ||
746 | |||
747 | radeon_fb = to_radeon_framebuffer(crtc->fb); | ||
748 | |||
749 | /* Pin framebuffer & get tilling informations */ | ||
750 | obj = radeon_fb->obj; | ||
751 | rbo = obj->driver_private; | ||
752 | r = radeon_bo_reserve(rbo, false); | ||
753 | if (unlikely(r != 0)) | ||
754 | return r; | ||
755 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); | ||
756 | if (unlikely(r != 0)) { | ||
757 | radeon_bo_unreserve(rbo); | ||
758 | return -EINVAL; | ||
759 | } | ||
760 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); | ||
761 | radeon_bo_unreserve(rbo); | ||
762 | |||
763 | switch (crtc->fb->bits_per_pixel) { | ||
764 | case 8: | ||
765 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) | | ||
766 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED)); | ||
767 | break; | ||
768 | case 15: | ||
769 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | | ||
770 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555)); | ||
771 | break; | ||
772 | case 16: | ||
773 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | | ||
774 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565)); | ||
775 | break; | ||
776 | case 24: | ||
777 | case 32: | ||
778 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) | | ||
779 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888)); | ||
780 | break; | ||
781 | default: | ||
782 | DRM_ERROR("Unsupported screen depth %d\n", | ||
783 | crtc->fb->bits_per_pixel); | ||
784 | return -EINVAL; | ||
785 | } | ||
786 | |||
787 | switch (radeon_crtc->crtc_id) { | ||
788 | case 0: | ||
789 | WREG32(AVIVO_D1VGA_CONTROL, 0); | ||
790 | break; | ||
791 | case 1: | ||
792 | WREG32(AVIVO_D2VGA_CONTROL, 0); | ||
793 | break; | ||
794 | case 2: | ||
795 | WREG32(EVERGREEN_D3VGA_CONTROL, 0); | ||
796 | break; | ||
797 | case 3: | ||
798 | WREG32(EVERGREEN_D4VGA_CONTROL, 0); | ||
799 | break; | ||
800 | case 4: | ||
801 | WREG32(EVERGREEN_D5VGA_CONTROL, 0); | ||
802 | break; | ||
803 | case 5: | ||
804 | WREG32(EVERGREEN_D6VGA_CONTROL, 0); | ||
805 | break; | ||
806 | default: | ||
807 | break; | ||
808 | } | ||
809 | |||
810 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, | ||
811 | upper_32_bits(fb_location)); | ||
812 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, | ||
813 | upper_32_bits(fb_location)); | ||
814 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
815 | (u32)fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK); | ||
816 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
817 | (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK); | ||
818 | WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); | ||
819 | |||
820 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); | ||
821 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); | ||
822 | WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); | ||
823 | WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0); | ||
824 | WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width); | ||
825 | WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height); | ||
826 | |||
827 | fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8); | ||
828 | WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); | ||
829 | WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); | ||
830 | |||
831 | WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, | ||
832 | crtc->mode.vdisplay); | ||
833 | x &= ~3; | ||
834 | y &= ~1; | ||
835 | WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, | ||
836 | (x << 16) | y); | ||
837 | WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, | ||
838 | (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); | ||
839 | |||
840 | if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) | ||
841 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
842 | EVERGREEN_INTERLEAVE_EN); | ||
843 | else | ||
844 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | ||
845 | |||
846 | if (old_fb && old_fb != crtc->fb) { | ||
847 | radeon_fb = to_radeon_framebuffer(old_fb); | ||
848 | rbo = radeon_fb->obj->driver_private; | ||
849 | r = radeon_bo_reserve(rbo, false); | ||
850 | if (unlikely(r != 0)) | ||
851 | return r; | ||
852 | radeon_bo_unpin(rbo); | ||
853 | radeon_bo_unreserve(rbo); | ||
854 | } | ||
855 | |||
856 | /* Bytes per pixel may have changed */ | ||
857 | radeon_bandwidth_update(rdev); | ||
858 | |||
859 | return 0; | ||
860 | } | ||
861 | |||
627 | static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 862 | static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
628 | struct drm_framebuffer *old_fb) | 863 | struct drm_framebuffer *old_fb) |
629 | { | 864 | { |
@@ -761,7 +996,9 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
761 | struct drm_device *dev = crtc->dev; | 996 | struct drm_device *dev = crtc->dev; |
762 | struct radeon_device *rdev = dev->dev_private; | 997 | struct radeon_device *rdev = dev->dev_private; |
763 | 998 | ||
764 | if (ASIC_IS_AVIVO(rdev)) | 999 | if (ASIC_IS_DCE4(rdev)) |
1000 | return evergreen_crtc_set_base(crtc, x, y, old_fb); | ||
1001 | else if (ASIC_IS_AVIVO(rdev)) | ||
765 | return avivo_crtc_set_base(crtc, x, y, old_fb); | 1002 | return avivo_crtc_set_base(crtc, x, y, old_fb); |
766 | else | 1003 | else |
767 | return radeon_crtc_set_base(crtc, x, y, old_fb); | 1004 | return radeon_crtc_set_base(crtc, x, y, old_fb); |
@@ -791,6 +1028,46 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc) | |||
791 | } | 1028 | } |
792 | } | 1029 | } |
793 | 1030 | ||
1031 | static int radeon_atom_pick_pll(struct drm_crtc *crtc) | ||
1032 | { | ||
1033 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1034 | struct drm_device *dev = crtc->dev; | ||
1035 | struct radeon_device *rdev = dev->dev_private; | ||
1036 | struct drm_encoder *test_encoder; | ||
1037 | struct drm_crtc *test_crtc; | ||
1038 | uint32_t pll_in_use = 0; | ||
1039 | |||
1040 | if (ASIC_IS_DCE4(rdev)) { | ||
1041 | /* if crtc is driving DP and we have an ext clock, use that */ | ||
1042 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | ||
1043 | if (test_encoder->crtc && (test_encoder->crtc == crtc)) { | ||
1044 | if (atombios_get_encoder_mode(test_encoder) == ATOM_ENCODER_MODE_DP) { | ||
1045 | if (rdev->clock.dp_extclk) | ||
1046 | return ATOM_PPLL_INVALID; | ||
1047 | } | ||
1048 | } | ||
1049 | } | ||
1050 | |||
1051 | /* otherwise, pick one of the plls */ | ||
1052 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { | ||
1053 | struct radeon_crtc *radeon_test_crtc; | ||
1054 | |||
1055 | if (crtc == test_crtc) | ||
1056 | continue; | ||
1057 | |||
1058 | radeon_test_crtc = to_radeon_crtc(test_crtc); | ||
1059 | if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) && | ||
1060 | (radeon_test_crtc->pll_id <= ATOM_PPLL2)) | ||
1061 | pll_in_use |= (1 << radeon_test_crtc->pll_id); | ||
1062 | } | ||
1063 | if (!(pll_in_use & 1)) | ||
1064 | return ATOM_PPLL1; | ||
1065 | return ATOM_PPLL2; | ||
1066 | } else | ||
1067 | return radeon_crtc->crtc_id; | ||
1068 | |||
1069 | } | ||
1070 | |||
794 | int atombios_crtc_mode_set(struct drm_crtc *crtc, | 1071 | int atombios_crtc_mode_set(struct drm_crtc *crtc, |
795 | struct drm_display_mode *mode, | 1072 | struct drm_display_mode *mode, |
796 | struct drm_display_mode *adjusted_mode, | 1073 | struct drm_display_mode *adjusted_mode, |
@@ -802,19 +1079,27 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
802 | 1079 | ||
803 | /* TODO color tiling */ | 1080 | /* TODO color tiling */ |
804 | 1081 | ||
1082 | /* pick pll */ | ||
1083 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); | ||
1084 | |||
805 | atombios_set_ss(crtc, 0); | 1085 | atombios_set_ss(crtc, 0); |
1086 | /* always set DCPLL */ | ||
1087 | if (ASIC_IS_DCE4(rdev)) | ||
1088 | atombios_crtc_set_dcpll(crtc); | ||
806 | atombios_crtc_set_pll(crtc, adjusted_mode); | 1089 | atombios_crtc_set_pll(crtc, adjusted_mode); |
807 | atombios_set_ss(crtc, 1); | 1090 | atombios_set_ss(crtc, 1); |
808 | atombios_crtc_set_timing(crtc, adjusted_mode); | ||
809 | 1091 | ||
810 | if (ASIC_IS_AVIVO(rdev)) | 1092 | if (ASIC_IS_DCE4(rdev)) |
811 | atombios_crtc_set_base(crtc, x, y, old_fb); | 1093 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
1094 | else if (ASIC_IS_AVIVO(rdev)) | ||
1095 | atombios_crtc_set_timing(crtc, adjusted_mode); | ||
812 | else { | 1096 | else { |
1097 | atombios_crtc_set_timing(crtc, adjusted_mode); | ||
813 | if (radeon_crtc->crtc_id == 0) | 1098 | if (radeon_crtc->crtc_id == 0) |
814 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | 1099 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
815 | atombios_crtc_set_base(crtc, x, y, old_fb); | ||
816 | radeon_legacy_atom_fixup(crtc); | 1100 | radeon_legacy_atom_fixup(crtc); |
817 | } | 1101 | } |
1102 | atombios_crtc_set_base(crtc, x, y, old_fb); | ||
818 | atombios_overscan_setup(crtc, mode, adjusted_mode); | 1103 | atombios_overscan_setup(crtc, mode, adjusted_mode); |
819 | atombios_scaler_setup(crtc); | 1104 | atombios_scaler_setup(crtc); |
820 | return 0; | 1105 | return 0; |
@@ -854,8 +1139,37 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = { | |||
854 | void radeon_atombios_init_crtc(struct drm_device *dev, | 1139 | void radeon_atombios_init_crtc(struct drm_device *dev, |
855 | struct radeon_crtc *radeon_crtc) | 1140 | struct radeon_crtc *radeon_crtc) |
856 | { | 1141 | { |
857 | if (radeon_crtc->crtc_id == 1) | 1142 | struct radeon_device *rdev = dev->dev_private; |
858 | radeon_crtc->crtc_offset = | 1143 | |
859 | AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL; | 1144 | if (ASIC_IS_DCE4(rdev)) { |
1145 | switch (radeon_crtc->crtc_id) { | ||
1146 | case 0: | ||
1147 | default: | ||
1148 | radeon_crtc->crtc_id = EVERGREEN_CRTC0_REGISTER_OFFSET; | ||
1149 | break; | ||
1150 | case 1: | ||
1151 | radeon_crtc->crtc_id = EVERGREEN_CRTC1_REGISTER_OFFSET; | ||
1152 | break; | ||
1153 | case 2: | ||
1154 | radeon_crtc->crtc_id = EVERGREEN_CRTC2_REGISTER_OFFSET; | ||
1155 | break; | ||
1156 | case 3: | ||
1157 | radeon_crtc->crtc_id = EVERGREEN_CRTC3_REGISTER_OFFSET; | ||
1158 | break; | ||
1159 | case 4: | ||
1160 | radeon_crtc->crtc_id = EVERGREEN_CRTC4_REGISTER_OFFSET; | ||
1161 | break; | ||
1162 | case 5: | ||
1163 | radeon_crtc->crtc_id = EVERGREEN_CRTC5_REGISTER_OFFSET; | ||
1164 | break; | ||
1165 | } | ||
1166 | } else { | ||
1167 | if (radeon_crtc->crtc_id == 1) | ||
1168 | radeon_crtc->crtc_offset = | ||
1169 | AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL; | ||
1170 | else | ||
1171 | radeon_crtc->crtc_offset = 0; | ||
1172 | } | ||
1173 | radeon_crtc->pll_id = -1; | ||
860 | drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); | 1174 | drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); |
861 | } | 1175 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 71060114d5de..0b6f2cef1c52 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -321,6 +321,10 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], | |||
321 | train_set[lane] = v | p; | 321 | train_set[lane] = v | p; |
322 | } | 322 | } |
323 | 323 | ||
324 | union aux_channel_transaction { | ||
325 | PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1; | ||
326 | PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2; | ||
327 | }; | ||
324 | 328 | ||
325 | /* radeon aux chan functions */ | 329 | /* radeon aux chan functions */ |
326 | bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, | 330 | bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, |
@@ -329,7 +333,7 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, | |||
329 | { | 333 | { |
330 | struct drm_device *dev = chan->dev; | 334 | struct drm_device *dev = chan->dev; |
331 | struct radeon_device *rdev = dev->dev_private; | 335 | struct radeon_device *rdev = dev->dev_private; |
332 | PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args; | 336 | union aux_channel_transaction args; |
333 | int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); | 337 | int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); |
334 | unsigned char *base; | 338 | unsigned char *base; |
335 | 339 | ||
@@ -339,29 +343,31 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, | |||
339 | 343 | ||
340 | memcpy(base, req_bytes, num_bytes); | 344 | memcpy(base, req_bytes, num_bytes); |
341 | 345 | ||
342 | args.lpAuxRequest = 0; | 346 | args.v1.lpAuxRequest = 0; |
343 | args.lpDataOut = 16; | 347 | args.v1.lpDataOut = 16; |
344 | args.ucDataOutLen = 0; | 348 | args.v1.ucDataOutLen = 0; |
345 | args.ucChannelID = chan->rec.i2c_id; | 349 | args.v1.ucChannelID = chan->rec.i2c_id; |
346 | args.ucDelay = delay / 10; | 350 | args.v1.ucDelay = delay / 10; |
351 | if (ASIC_IS_DCE4(rdev)) | ||
352 | args.v2.ucHPD_ID = chan->rec.hpd_id; | ||
347 | 353 | ||
348 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 354 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
349 | 355 | ||
350 | if (args.ucReplyStatus) { | 356 | if (args.v1.ucReplyStatus) { |
351 | DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n", | 357 | 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], | 358 | req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], |
353 | chan->rec.i2c_id, args.ucReplyStatus); | 359 | chan->rec.i2c_id, args.v1.ucReplyStatus); |
354 | return false; | 360 | return false; |
355 | } | 361 | } |
356 | 362 | ||
357 | if (args.ucDataOutLen && read_byte && read_buf_len) { | 363 | if (args.v1.ucDataOutLen && read_byte && read_buf_len) { |
358 | if (read_buf_len < args.ucDataOutLen) { | 364 | if (read_buf_len < args.v1.ucDataOutLen) { |
359 | DRM_ERROR("Buffer to small for return answer %d %d\n", | 365 | DRM_ERROR("Buffer to small for return answer %d %d\n", |
360 | read_buf_len, args.ucDataOutLen); | 366 | read_buf_len, args.v1.ucDataOutLen); |
361 | return false; | 367 | return false; |
362 | } | 368 | } |
363 | { | 369 | { |
364 | int len = min(read_buf_len, args.ucDataOutLen); | 370 | int len = min(read_buf_len, args.v1.ucDataOutLen); |
365 | memcpy(read_byte, base + 16, len); | 371 | memcpy(read_byte, base + 16, len); |
366 | } | 372 | } |
367 | } | 373 | } |
@@ -622,12 +628,19 @@ void dp_link_train(struct drm_encoder *encoder, | |||
622 | dp_set_link_bw_lanes(radeon_connector, link_configuration); | 628 | dp_set_link_bw_lanes(radeon_connector, link_configuration); |
623 | /* disable downspread on the sink */ | 629 | /* disable downspread on the sink */ |
624 | dp_set_downspread(radeon_connector, 0); | 630 | dp_set_downspread(radeon_connector, 0); |
625 | /* start training on the source */ | 631 | if (ASIC_IS_DCE4(rdev)) { |
626 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START, | 632 | /* start training on the source */ |
627 | dig_connector->dp_clock, enc_id, 0); | 633 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START); |
628 | /* set training pattern 1 on the source */ | 634 | /* set training pattern 1 on the source */ |
629 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, | 635 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1); |
630 | dig_connector->dp_clock, enc_id, 0); | 636 | } else { |
637 | /* start training on the source */ | ||
638 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START, | ||
639 | dig_connector->dp_clock, enc_id, 0); | ||
640 | /* set training pattern 1 on the source */ | ||
641 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, | ||
642 | dig_connector->dp_clock, enc_id, 0); | ||
643 | } | ||
631 | 644 | ||
632 | /* set initial vs/emph */ | 645 | /* set initial vs/emph */ |
633 | memset(train_set, 0, 4); | 646 | memset(train_set, 0, 4); |
@@ -687,8 +700,11 @@ void dp_link_train(struct drm_encoder *encoder, | |||
687 | /* set training pattern 2 on the sink */ | 700 | /* set training pattern 2 on the sink */ |
688 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2); | 701 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2); |
689 | /* set training pattern 2 on the source */ | 702 | /* set training pattern 2 on the source */ |
690 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, | 703 | if (ASIC_IS_DCE4(rdev)) |
691 | dig_connector->dp_clock, enc_id, 1); | 704 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2); |
705 | else | ||
706 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, | ||
707 | dig_connector->dp_clock, enc_id, 1); | ||
692 | 708 | ||
693 | /* channel equalization loop */ | 709 | /* channel equalization loop */ |
694 | tries = 0; | 710 | tries = 0; |
@@ -725,7 +741,11 @@ void dp_link_train(struct drm_encoder *encoder, | |||
725 | >> DP_TRAIN_PRE_EMPHASIS_SHIFT); | 741 | >> DP_TRAIN_PRE_EMPHASIS_SHIFT); |
726 | 742 | ||
727 | /* disable the training pattern on the sink */ | 743 | /* disable the training pattern on the sink */ |
728 | dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE); | 744 | if (ASIC_IS_DCE4(rdev)) |
745 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE); | ||
746 | else | ||
747 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, | ||
748 | dig_connector->dp_clock, enc_id, 0); | ||
729 | 749 | ||
730 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, | 750 | radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, |
731 | dig_connector->dp_clock, enc_id, 0); | 751 | dig_connector->dp_clock, enc_id, 0); |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c new file mode 100644 index 000000000000..c2f9752e4ee0 --- /dev/null +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -0,0 +1,794 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Alex Deucher | ||
23 | */ | ||
24 | #include <linux/firmware.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include "drmP.h" | ||
27 | #include "radeon.h" | ||
28 | #include "radeon_drm.h" | ||
29 | #include "rv770d.h" | ||
30 | #include "atom.h" | ||
31 | #include "avivod.h" | ||
32 | #include "evergreen_reg.h" | ||
33 | |||
34 | static void evergreen_gpu_init(struct radeon_device *rdev); | ||
35 | void evergreen_fini(struct radeon_device *rdev); | ||
36 | |||
37 | bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | ||
38 | { | ||
39 | bool connected = false; | ||
40 | /* XXX */ | ||
41 | return connected; | ||
42 | } | ||
43 | |||
44 | void evergreen_hpd_set_polarity(struct radeon_device *rdev, | ||
45 | enum radeon_hpd_id hpd) | ||
46 | { | ||
47 | /* XXX */ | ||
48 | } | ||
49 | |||
50 | void evergreen_hpd_init(struct radeon_device *rdev) | ||
51 | { | ||
52 | /* XXX */ | ||
53 | } | ||
54 | |||
55 | |||
56 | void evergreen_bandwidth_update(struct radeon_device *rdev) | ||
57 | { | ||
58 | /* XXX */ | ||
59 | } | ||
60 | |||
61 | void evergreen_hpd_fini(struct radeon_device *rdev) | ||
62 | { | ||
63 | /* XXX */ | ||
64 | } | ||
65 | |||
66 | static int evergreen_mc_wait_for_idle(struct radeon_device *rdev) | ||
67 | { | ||
68 | unsigned i; | ||
69 | u32 tmp; | ||
70 | |||
71 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
72 | /* read MC_STATUS */ | ||
73 | tmp = RREG32(SRBM_STATUS) & 0x1F00; | ||
74 | if (!tmp) | ||
75 | return 0; | ||
76 | udelay(1); | ||
77 | } | ||
78 | return -1; | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * GART | ||
83 | */ | ||
84 | int evergreen_pcie_gart_enable(struct radeon_device *rdev) | ||
85 | { | ||
86 | u32 tmp; | ||
87 | int r, i; | ||
88 | |||
89 | if (rdev->gart.table.vram.robj == NULL) { | ||
90 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | ||
91 | return -EINVAL; | ||
92 | } | ||
93 | r = radeon_gart_table_vram_pin(rdev); | ||
94 | if (r) | ||
95 | return r; | ||
96 | /* Setup L2 cache */ | ||
97 | WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | | ||
98 | ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | | ||
99 | EFFECTIVE_L2_QUEUE_SIZE(7)); | ||
100 | WREG32(VM_L2_CNTL2, 0); | ||
101 | WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); | ||
102 | /* Setup TLB control */ | ||
103 | tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | | ||
104 | SYSTEM_ACCESS_MODE_NOT_IN_SYS | | ||
105 | SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | | ||
106 | EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); | ||
107 | WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | ||
108 | WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | ||
109 | WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | ||
110 | WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); | ||
111 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); | ||
112 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | ||
113 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); | ||
114 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); | ||
115 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); | ||
116 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); | ||
117 | WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | | ||
118 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); | ||
119 | WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, | ||
120 | (u32)(rdev->dummy_page.addr >> 12)); | ||
121 | for (i = 1; i < 7; i++) | ||
122 | WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); | ||
123 | |||
124 | r600_pcie_gart_tlb_flush(rdev); | ||
125 | rdev->gart.ready = true; | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | void evergreen_pcie_gart_disable(struct radeon_device *rdev) | ||
130 | { | ||
131 | u32 tmp; | ||
132 | int i, r; | ||
133 | |||
134 | /* Disable all tables */ | ||
135 | for (i = 0; i < 7; i++) | ||
136 | WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); | ||
137 | |||
138 | /* Setup L2 cache */ | ||
139 | WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING | | ||
140 | EFFECTIVE_L2_QUEUE_SIZE(7)); | ||
141 | WREG32(VM_L2_CNTL2, 0); | ||
142 | WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); | ||
143 | /* Setup TLB control */ | ||
144 | tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); | ||
145 | WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | ||
146 | WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | ||
147 | WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | ||
148 | WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); | ||
149 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); | ||
150 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | ||
151 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); | ||
152 | if (rdev->gart.table.vram.robj) { | ||
153 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | ||
154 | if (likely(r == 0)) { | ||
155 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
156 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
157 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
158 | } | ||
159 | } | ||
160 | } | ||
161 | |||
162 | void evergreen_pcie_gart_fini(struct radeon_device *rdev) | ||
163 | { | ||
164 | evergreen_pcie_gart_disable(rdev); | ||
165 | radeon_gart_table_vram_free(rdev); | ||
166 | radeon_gart_fini(rdev); | ||
167 | } | ||
168 | |||
169 | |||
170 | void evergreen_agp_enable(struct radeon_device *rdev) | ||
171 | { | ||
172 | u32 tmp; | ||
173 | int i; | ||
174 | |||
175 | /* Setup L2 cache */ | ||
176 | WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | | ||
177 | ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | | ||
178 | EFFECTIVE_L2_QUEUE_SIZE(7)); | ||
179 | WREG32(VM_L2_CNTL2, 0); | ||
180 | WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); | ||
181 | /* Setup TLB control */ | ||
182 | tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | | ||
183 | SYSTEM_ACCESS_MODE_NOT_IN_SYS | | ||
184 | SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | | ||
185 | EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); | ||
186 | WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | ||
187 | WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | ||
188 | WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | ||
189 | WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); | ||
190 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); | ||
191 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | ||
192 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); | ||
193 | for (i = 0; i < 7; i++) | ||
194 | WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); | ||
195 | } | ||
196 | |||
197 | static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) | ||
198 | { | ||
199 | save->vga_control[0] = RREG32(D1VGA_CONTROL); | ||
200 | save->vga_control[1] = RREG32(D2VGA_CONTROL); | ||
201 | save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); | ||
202 | save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); | ||
203 | save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); | ||
204 | save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); | ||
205 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); | ||
206 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); | ||
207 | save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); | ||
208 | save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); | ||
209 | save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
210 | save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
211 | save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
212 | save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
213 | |||
214 | /* Stop all video */ | ||
215 | WREG32(VGA_RENDER_CONTROL, 0); | ||
216 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | ||
217 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | ||
218 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | ||
219 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | ||
220 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | ||
221 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | ||
222 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | ||
223 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | ||
224 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | ||
225 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | ||
226 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
227 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
228 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | ||
229 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | ||
230 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | ||
231 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | ||
232 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
233 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
234 | |||
235 | WREG32(D1VGA_CONTROL, 0); | ||
236 | WREG32(D2VGA_CONTROL, 0); | ||
237 | WREG32(EVERGREEN_D3VGA_CONTROL, 0); | ||
238 | WREG32(EVERGREEN_D4VGA_CONTROL, 0); | ||
239 | WREG32(EVERGREEN_D5VGA_CONTROL, 0); | ||
240 | WREG32(EVERGREEN_D6VGA_CONTROL, 0); | ||
241 | } | ||
242 | |||
243 | static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) | ||
244 | { | ||
245 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, | ||
246 | upper_32_bits(rdev->mc.vram_start)); | ||
247 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, | ||
248 | upper_32_bits(rdev->mc.vram_start)); | ||
249 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET, | ||
250 | (u32)rdev->mc.vram_start); | ||
251 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET, | ||
252 | (u32)rdev->mc.vram_start); | ||
253 | |||
254 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
255 | upper_32_bits(rdev->mc.vram_start)); | ||
256 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
257 | upper_32_bits(rdev->mc.vram_start)); | ||
258 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
259 | (u32)rdev->mc.vram_start); | ||
260 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
261 | (u32)rdev->mc.vram_start); | ||
262 | |||
263 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
264 | upper_32_bits(rdev->mc.vram_start)); | ||
265 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
266 | upper_32_bits(rdev->mc.vram_start)); | ||
267 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
268 | (u32)rdev->mc.vram_start); | ||
269 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
270 | (u32)rdev->mc.vram_start); | ||
271 | |||
272 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
273 | upper_32_bits(rdev->mc.vram_start)); | ||
274 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
275 | upper_32_bits(rdev->mc.vram_start)); | ||
276 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
277 | (u32)rdev->mc.vram_start); | ||
278 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
279 | (u32)rdev->mc.vram_start); | ||
280 | |||
281 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
282 | upper_32_bits(rdev->mc.vram_start)); | ||
283 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
284 | upper_32_bits(rdev->mc.vram_start)); | ||
285 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
286 | (u32)rdev->mc.vram_start); | ||
287 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
288 | (u32)rdev->mc.vram_start); | ||
289 | |||
290 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, | ||
291 | upper_32_bits(rdev->mc.vram_start)); | ||
292 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, | ||
293 | upper_32_bits(rdev->mc.vram_start)); | ||
294 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, | ||
295 | (u32)rdev->mc.vram_start); | ||
296 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, | ||
297 | (u32)rdev->mc.vram_start); | ||
298 | |||
299 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); | ||
300 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); | ||
301 | /* Unlock host access */ | ||
302 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); | ||
303 | mdelay(1); | ||
304 | /* Restore video state */ | ||
305 | WREG32(D1VGA_CONTROL, save->vga_control[0]); | ||
306 | WREG32(D2VGA_CONTROL, save->vga_control[1]); | ||
307 | WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); | ||
308 | WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); | ||
309 | WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); | ||
310 | WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); | ||
311 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | ||
312 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | ||
313 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | ||
314 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | ||
315 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | ||
316 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | ||
317 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); | ||
318 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); | ||
319 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); | ||
320 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); | ||
321 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); | ||
322 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); | ||
323 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | ||
324 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | ||
325 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | ||
326 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | ||
327 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
328 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
329 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); | ||
330 | } | ||
331 | |||
332 | static void evergreen_mc_program(struct radeon_device *rdev) | ||
333 | { | ||
334 | struct evergreen_mc_save save; | ||
335 | u32 tmp; | ||
336 | int i, j; | ||
337 | |||
338 | /* Initialize HDP */ | ||
339 | for (i = 0, j = 0; i < 32; i++, j += 0x18) { | ||
340 | WREG32((0x2c14 + j), 0x00000000); | ||
341 | WREG32((0x2c18 + j), 0x00000000); | ||
342 | WREG32((0x2c1c + j), 0x00000000); | ||
343 | WREG32((0x2c20 + j), 0x00000000); | ||
344 | WREG32((0x2c24 + j), 0x00000000); | ||
345 | } | ||
346 | WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); | ||
347 | |||
348 | evergreen_mc_stop(rdev, &save); | ||
349 | if (evergreen_mc_wait_for_idle(rdev)) { | ||
350 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
351 | } | ||
352 | /* Lockout access through VGA aperture*/ | ||
353 | WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); | ||
354 | /* Update configuration */ | ||
355 | if (rdev->flags & RADEON_IS_AGP) { | ||
356 | if (rdev->mc.vram_start < rdev->mc.gtt_start) { | ||
357 | /* VRAM before AGP */ | ||
358 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, | ||
359 | rdev->mc.vram_start >> 12); | ||
360 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, | ||
361 | rdev->mc.gtt_end >> 12); | ||
362 | } else { | ||
363 | /* VRAM after AGP */ | ||
364 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, | ||
365 | rdev->mc.gtt_start >> 12); | ||
366 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, | ||
367 | rdev->mc.vram_end >> 12); | ||
368 | } | ||
369 | } else { | ||
370 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, | ||
371 | rdev->mc.vram_start >> 12); | ||
372 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, | ||
373 | rdev->mc.vram_end >> 12); | ||
374 | } | ||
375 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | ||
376 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; | ||
377 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); | ||
378 | WREG32(MC_VM_FB_LOCATION, tmp); | ||
379 | WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); | ||
380 | WREG32(HDP_NONSURFACE_INFO, (2 << 7)); | ||
381 | WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF); | ||
382 | if (rdev->flags & RADEON_IS_AGP) { | ||
383 | WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16); | ||
384 | WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); | ||
385 | WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); | ||
386 | } else { | ||
387 | WREG32(MC_VM_AGP_BASE, 0); | ||
388 | WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); | ||
389 | WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); | ||
390 | } | ||
391 | if (evergreen_mc_wait_for_idle(rdev)) { | ||
392 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
393 | } | ||
394 | evergreen_mc_resume(rdev, &save); | ||
395 | /* we need to own VRAM, so turn off the VGA renderer here | ||
396 | * to stop it overwriting our objects */ | ||
397 | rv515_vga_render_disable(rdev); | ||
398 | } | ||
399 | |||
400 | #if 0 | ||
401 | /* | ||
402 | * CP. | ||
403 | */ | ||
404 | static void evergreen_cp_stop(struct radeon_device *rdev) | ||
405 | { | ||
406 | /* XXX */ | ||
407 | } | ||
408 | |||
409 | |||
410 | static int evergreen_cp_load_microcode(struct radeon_device *rdev) | ||
411 | { | ||
412 | /* XXX */ | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | |||
418 | /* | ||
419 | * Core functions | ||
420 | */ | ||
421 | static u32 evergreen_get_tile_pipe_to_backend_map(u32 num_tile_pipes, | ||
422 | u32 num_backends, | ||
423 | u32 backend_disable_mask) | ||
424 | { | ||
425 | u32 backend_map = 0; | ||
426 | |||
427 | return backend_map; | ||
428 | } | ||
429 | #endif | ||
430 | |||
431 | static void evergreen_gpu_init(struct radeon_device *rdev) | ||
432 | { | ||
433 | /* XXX */ | ||
434 | } | ||
435 | |||
436 | int evergreen_mc_init(struct radeon_device *rdev) | ||
437 | { | ||
438 | fixed20_12 a; | ||
439 | u32 tmp; | ||
440 | int chansize, numchan; | ||
441 | int r; | ||
442 | |||
443 | /* Get VRAM informations */ | ||
444 | rdev->mc.vram_is_ddr = true; | ||
445 | tmp = RREG32(MC_ARB_RAMCFG); | ||
446 | if (tmp & CHANSIZE_OVERRIDE) { | ||
447 | chansize = 16; | ||
448 | } else if (tmp & CHANSIZE_MASK) { | ||
449 | chansize = 64; | ||
450 | } else { | ||
451 | chansize = 32; | ||
452 | } | ||
453 | tmp = RREG32(MC_SHARED_CHMAP); | ||
454 | switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { | ||
455 | case 0: | ||
456 | default: | ||
457 | numchan = 1; | ||
458 | break; | ||
459 | case 1: | ||
460 | numchan = 2; | ||
461 | break; | ||
462 | case 2: | ||
463 | numchan = 4; | ||
464 | break; | ||
465 | case 3: | ||
466 | numchan = 8; | ||
467 | break; | ||
468 | } | ||
469 | rdev->mc.vram_width = numchan * chansize; | ||
470 | /* Could aper size report 0 ? */ | ||
471 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | ||
472 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | ||
473 | /* Setup GPU memory space */ | ||
474 | /* size in MB on evergreen */ | ||
475 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | ||
476 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | ||
477 | |||
478 | if (rdev->mc.mc_vram_size > rdev->mc.aper_size) | ||
479 | rdev->mc.mc_vram_size = rdev->mc.aper_size; | ||
480 | |||
481 | if (rdev->mc.real_vram_size > rdev->mc.aper_size) | ||
482 | rdev->mc.real_vram_size = rdev->mc.aper_size; | ||
483 | |||
484 | if (rdev->flags & RADEON_IS_AGP) { | ||
485 | r = radeon_agp_init(rdev); | ||
486 | if (r) | ||
487 | return r; | ||
488 | /* gtt_size is setup by radeon_agp_init */ | ||
489 | rdev->mc.gtt_location = rdev->mc.agp_base; | ||
490 | tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size; | ||
491 | /* Try to put vram before or after AGP because we | ||
492 | * we want SYSTEM_APERTURE to cover both VRAM and | ||
493 | * AGP so that GPU can catch out of VRAM/AGP access | ||
494 | */ | ||
495 | if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { | ||
496 | /* Enought place before */ | ||
497 | rdev->mc.vram_location = rdev->mc.gtt_location - | ||
498 | rdev->mc.mc_vram_size; | ||
499 | } else if (tmp > rdev->mc.mc_vram_size) { | ||
500 | /* Enought place after */ | ||
501 | rdev->mc.vram_location = rdev->mc.gtt_location + | ||
502 | rdev->mc.gtt_size; | ||
503 | } else { | ||
504 | /* Try to setup VRAM then AGP might not | ||
505 | * not work on some card | ||
506 | */ | ||
507 | rdev->mc.vram_location = 0x00000000UL; | ||
508 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
509 | } | ||
510 | } else { | ||
511 | rdev->mc.vram_location = 0x00000000UL; | ||
512 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
513 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
514 | } | ||
515 | rdev->mc.vram_start = rdev->mc.vram_location; | ||
516 | rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; | ||
517 | rdev->mc.gtt_start = rdev->mc.gtt_location; | ||
518 | rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; | ||
519 | /* FIXME: we should enforce default clock in case GPU is not in | ||
520 | * default setup | ||
521 | */ | ||
522 | a.full = rfixed_const(100); | ||
523 | rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); | ||
524 | rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); | ||
525 | return 0; | ||
526 | } | ||
527 | int evergreen_gpu_reset(struct radeon_device *rdev) | ||
528 | { | ||
529 | /* FIXME: implement for evergreen */ | ||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | static int evergreen_startup(struct radeon_device *rdev) | ||
534 | { | ||
535 | #if 0 | ||
536 | int r; | ||
537 | |||
538 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | ||
539 | r = r600_init_microcode(rdev); | ||
540 | if (r) { | ||
541 | DRM_ERROR("Failed to load firmware!\n"); | ||
542 | return r; | ||
543 | } | ||
544 | } | ||
545 | #endif | ||
546 | evergreen_mc_program(rdev); | ||
547 | #if 0 | ||
548 | if (rdev->flags & RADEON_IS_AGP) { | ||
549 | evergreem_agp_enable(rdev); | ||
550 | } else { | ||
551 | r = evergreen_pcie_gart_enable(rdev); | ||
552 | if (r) | ||
553 | return r; | ||
554 | } | ||
555 | #endif | ||
556 | evergreen_gpu_init(rdev); | ||
557 | #if 0 | ||
558 | if (!rdev->r600_blit.shader_obj) { | ||
559 | r = r600_blit_init(rdev); | ||
560 | if (r) { | ||
561 | DRM_ERROR("radeon: failed blitter (%d).\n", r); | ||
562 | return r; | ||
563 | } | ||
564 | } | ||
565 | |||
566 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
567 | if (unlikely(r != 0)) | ||
568 | return r; | ||
569 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
570 | &rdev->r600_blit.shader_gpu_addr); | ||
571 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
572 | if (r) { | ||
573 | DRM_ERROR("failed to pin blit object %d\n", r); | ||
574 | return r; | ||
575 | } | ||
576 | |||
577 | /* Enable IRQ */ | ||
578 | r = r600_irq_init(rdev); | ||
579 | if (r) { | ||
580 | DRM_ERROR("radeon: IH init failed (%d).\n", r); | ||
581 | radeon_irq_kms_fini(rdev); | ||
582 | return r; | ||
583 | } | ||
584 | r600_irq_set(rdev); | ||
585 | |||
586 | r = radeon_ring_init(rdev, rdev->cp.ring_size); | ||
587 | if (r) | ||
588 | return r; | ||
589 | r = evergreen_cp_load_microcode(rdev); | ||
590 | if (r) | ||
591 | return r; | ||
592 | r = r600_cp_resume(rdev); | ||
593 | if (r) | ||
594 | return r; | ||
595 | /* write back buffer are not vital so don't worry about failure */ | ||
596 | r600_wb_enable(rdev); | ||
597 | #endif | ||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | int evergreen_resume(struct radeon_device *rdev) | ||
602 | { | ||
603 | int r; | ||
604 | |||
605 | /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, | ||
606 | * posting will perform necessary task to bring back GPU into good | ||
607 | * shape. | ||
608 | */ | ||
609 | /* post card */ | ||
610 | atom_asic_init(rdev->mode_info.atom_context); | ||
611 | /* Initialize clocks */ | ||
612 | r = radeon_clocks_init(rdev); | ||
613 | if (r) { | ||
614 | return r; | ||
615 | } | ||
616 | |||
617 | r = evergreen_startup(rdev); | ||
618 | if (r) { | ||
619 | DRM_ERROR("r600 startup failed on resume\n"); | ||
620 | return r; | ||
621 | } | ||
622 | #if 0 | ||
623 | r = r600_ib_test(rdev); | ||
624 | if (r) { | ||
625 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | ||
626 | return r; | ||
627 | } | ||
628 | #endif | ||
629 | return r; | ||
630 | |||
631 | } | ||
632 | |||
633 | int evergreen_suspend(struct radeon_device *rdev) | ||
634 | { | ||
635 | #if 0 | ||
636 | int r; | ||
637 | |||
638 | /* FIXME: we should wait for ring to be empty */ | ||
639 | r700_cp_stop(rdev); | ||
640 | rdev->cp.ready = false; | ||
641 | r600_wb_disable(rdev); | ||
642 | evergreen_pcie_gart_disable(rdev); | ||
643 | /* unpin shaders bo */ | ||
644 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
645 | if (likely(r == 0)) { | ||
646 | radeon_bo_unpin(rdev->r600_blit.shader_obj); | ||
647 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
648 | } | ||
649 | #endif | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | static bool evergreen_card_posted(struct radeon_device *rdev) | ||
654 | { | ||
655 | u32 reg; | ||
656 | |||
657 | /* first check CRTCs */ | ||
658 | reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | | ||
659 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | | ||
660 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | | ||
661 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | | ||
662 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | | ||
663 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
664 | if (reg & EVERGREEN_CRTC_MASTER_EN) | ||
665 | return true; | ||
666 | |||
667 | /* then check MEM_SIZE, in case the crtcs are off */ | ||
668 | if (RREG32(CONFIG_MEMSIZE)) | ||
669 | return true; | ||
670 | |||
671 | return false; | ||
672 | } | ||
673 | |||
674 | /* Plan is to move initialization in that function and use | ||
675 | * helper function so that radeon_device_init pretty much | ||
676 | * do nothing more than calling asic specific function. This | ||
677 | * should also allow to remove a bunch of callback function | ||
678 | * like vram_info. | ||
679 | */ | ||
680 | int evergreen_init(struct radeon_device *rdev) | ||
681 | { | ||
682 | int r; | ||
683 | |||
684 | r = radeon_dummy_page_init(rdev); | ||
685 | if (r) | ||
686 | return r; | ||
687 | /* This don't do much */ | ||
688 | r = radeon_gem_init(rdev); | ||
689 | if (r) | ||
690 | return r; | ||
691 | /* Read BIOS */ | ||
692 | if (!radeon_get_bios(rdev)) { | ||
693 | if (ASIC_IS_AVIVO(rdev)) | ||
694 | return -EINVAL; | ||
695 | } | ||
696 | /* Must be an ATOMBIOS */ | ||
697 | if (!rdev->is_atom_bios) { | ||
698 | dev_err(rdev->dev, "Expecting atombios for R600 GPU\n"); | ||
699 | return -EINVAL; | ||
700 | } | ||
701 | r = radeon_atombios_init(rdev); | ||
702 | if (r) | ||
703 | return r; | ||
704 | /* Post card if necessary */ | ||
705 | if (!evergreen_card_posted(rdev)) { | ||
706 | if (!rdev->bios) { | ||
707 | dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); | ||
708 | return -EINVAL; | ||
709 | } | ||
710 | DRM_INFO("GPU not posted. posting now...\n"); | ||
711 | atom_asic_init(rdev->mode_info.atom_context); | ||
712 | } | ||
713 | /* Initialize scratch registers */ | ||
714 | r600_scratch_init(rdev); | ||
715 | /* Initialize surface registers */ | ||
716 | radeon_surface_init(rdev); | ||
717 | /* Initialize clocks */ | ||
718 | radeon_get_clock_info(rdev->ddev); | ||
719 | r = radeon_clocks_init(rdev); | ||
720 | if (r) | ||
721 | return r; | ||
722 | /* Initialize power management */ | ||
723 | radeon_pm_init(rdev); | ||
724 | /* Fence driver */ | ||
725 | r = radeon_fence_driver_init(rdev); | ||
726 | if (r) | ||
727 | return r; | ||
728 | r = evergreen_mc_init(rdev); | ||
729 | if (r) | ||
730 | return r; | ||
731 | /* Memory manager */ | ||
732 | r = radeon_bo_init(rdev); | ||
733 | if (r) | ||
734 | return r; | ||
735 | #if 0 | ||
736 | r = radeon_irq_kms_init(rdev); | ||
737 | if (r) | ||
738 | return r; | ||
739 | |||
740 | rdev->cp.ring_obj = NULL; | ||
741 | r600_ring_init(rdev, 1024 * 1024); | ||
742 | |||
743 | rdev->ih.ring_obj = NULL; | ||
744 | r600_ih_ring_init(rdev, 64 * 1024); | ||
745 | |||
746 | r = r600_pcie_gart_init(rdev); | ||
747 | if (r) | ||
748 | return r; | ||
749 | #endif | ||
750 | rdev->accel_working = false; | ||
751 | r = evergreen_startup(rdev); | ||
752 | if (r) { | ||
753 | evergreen_suspend(rdev); | ||
754 | /*r600_wb_fini(rdev);*/ | ||
755 | /*radeon_ring_fini(rdev);*/ | ||
756 | /*evergreen_pcie_gart_fini(rdev);*/ | ||
757 | rdev->accel_working = false; | ||
758 | } | ||
759 | if (rdev->accel_working) { | ||
760 | r = radeon_ib_pool_init(rdev); | ||
761 | if (r) { | ||
762 | DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r); | ||
763 | rdev->accel_working = false; | ||
764 | } | ||
765 | r = r600_ib_test(rdev); | ||
766 | if (r) { | ||
767 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); | ||
768 | rdev->accel_working = false; | ||
769 | } | ||
770 | } | ||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | void evergreen_fini(struct radeon_device *rdev) | ||
775 | { | ||
776 | evergreen_suspend(rdev); | ||
777 | #if 0 | ||
778 | r600_blit_fini(rdev); | ||
779 | r600_irq_fini(rdev); | ||
780 | radeon_irq_kms_fini(rdev); | ||
781 | radeon_ring_fini(rdev); | ||
782 | r600_wb_fini(rdev); | ||
783 | evergreen_pcie_gart_fini(rdev); | ||
784 | #endif | ||
785 | radeon_gem_fini(rdev); | ||
786 | radeon_fence_driver_fini(rdev); | ||
787 | radeon_clocks_fini(rdev); | ||
788 | radeon_agp_fini(rdev); | ||
789 | radeon_bo_fini(rdev); | ||
790 | radeon_atombios_fini(rdev); | ||
791 | kfree(rdev->bios); | ||
792 | rdev->bios = NULL; | ||
793 | radeon_dummy_page_fini(rdev); | ||
794 | } | ||
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h new file mode 100644 index 000000000000..f7c7c9643433 --- /dev/null +++ b/drivers/gpu/drm/radeon/evergreen_reg.h | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Alex Deucher | ||
23 | */ | ||
24 | #ifndef __EVERGREEN_REG_H__ | ||
25 | #define __EVERGREEN_REG_H__ | ||
26 | |||
27 | /* evergreen */ | ||
28 | #define EVERGREEN_VGA_MEMORY_BASE_ADDRESS 0x310 | ||
29 | #define EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH 0x324 | ||
30 | #define EVERGREEN_D3VGA_CONTROL 0x3e0 | ||
31 | #define EVERGREEN_D4VGA_CONTROL 0x3e4 | ||
32 | #define EVERGREEN_D5VGA_CONTROL 0x3e8 | ||
33 | #define EVERGREEN_D6VGA_CONTROL 0x3ec | ||
34 | |||
35 | #define EVERGREEN_P1PLL_SS_CNTL 0x414 | ||
36 | #define EVERGREEN_P2PLL_SS_CNTL 0x454 | ||
37 | # define EVERGREEN_PxPLL_SS_EN (1 << 12) | ||
38 | /* GRPH blocks at 0x6800, 0x7400, 0x10000, 0x10c00, 0x11800, 0x12400 */ | ||
39 | #define EVERGREEN_GRPH_ENABLE 0x6800 | ||
40 | #define EVERGREEN_GRPH_CONTROL 0x6804 | ||
41 | # define EVERGREEN_GRPH_DEPTH(x) (((x) & 0x3) << 0) | ||
42 | # define EVERGREEN_GRPH_DEPTH_8BPP 0 | ||
43 | # define EVERGREEN_GRPH_DEPTH_16BPP 1 | ||
44 | # define EVERGREEN_GRPH_DEPTH_32BPP 2 | ||
45 | # define EVERGREEN_GRPH_FORMAT(x) (((x) & 0x7) << 8) | ||
46 | /* 8 BPP */ | ||
47 | # define EVERGREEN_GRPH_FORMAT_INDEXED 0 | ||
48 | /* 16 BPP */ | ||
49 | # define EVERGREEN_GRPH_FORMAT_ARGB1555 0 | ||
50 | # define EVERGREEN_GRPH_FORMAT_ARGB565 1 | ||
51 | # define EVERGREEN_GRPH_FORMAT_ARGB4444 2 | ||
52 | # define EVERGREEN_GRPH_FORMAT_AI88 3 | ||
53 | # define EVERGREEN_GRPH_FORMAT_MONO16 4 | ||
54 | # define EVERGREEN_GRPH_FORMAT_BGRA5551 5 | ||
55 | /* 32 BPP */ | ||
56 | # define EVERGREEN_GRPH_FORMAT_ARGB8888 0 | ||
57 | # define EVERGREEN_GRPH_FORMAT_ARGB2101010 1 | ||
58 | # define EVERGREEN_GRPH_FORMAT_32BPP_DIG 2 | ||
59 | # define EVERGREEN_GRPH_FORMAT_8B_ARGB2101010 3 | ||
60 | # define EVERGREEN_GRPH_FORMAT_BGRA1010102 4 | ||
61 | # define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102 5 | ||
62 | # define EVERGREEN_GRPH_FORMAT_RGB111110 6 | ||
63 | # define EVERGREEN_GRPH_FORMAT_BGR101111 7 | ||
64 | #define EVERGREEN_GRPH_SWAP_CONTROL 0x680c | ||
65 | # define EVERGREEN_GRPH_ENDIAN_SWAP(x) (((x) & 0x3) << 0) | ||
66 | # define EVERGREEN_GRPH_ENDIAN_NONE 0 | ||
67 | # define EVERGREEN_GRPH_ENDIAN_8IN16 1 | ||
68 | # define EVERGREEN_GRPH_ENDIAN_8IN32 2 | ||
69 | # define EVERGREEN_GRPH_ENDIAN_8IN64 3 | ||
70 | # define EVERGREEN_GRPH_RED_CROSSBAR(x) (((x) & 0x3) << 4) | ||
71 | # define EVERGREEN_GRPH_RED_SEL_R 0 | ||
72 | # define EVERGREEN_GRPH_RED_SEL_G 1 | ||
73 | # define EVERGREEN_GRPH_RED_SEL_B 2 | ||
74 | # define EVERGREEN_GRPH_RED_SEL_A 3 | ||
75 | # define EVERGREEN_GRPH_GREEN_CROSSBAR(x) (((x) & 0x3) << 6) | ||
76 | # define EVERGREEN_GRPH_GREEN_SEL_G 0 | ||
77 | # define EVERGREEN_GRPH_GREEN_SEL_B 1 | ||
78 | # define EVERGREEN_GRPH_GREEN_SEL_A 2 | ||
79 | # define EVERGREEN_GRPH_GREEN_SEL_R 3 | ||
80 | # define EVERGREEN_GRPH_BLUE_CROSSBAR(x) (((x) & 0x3) << 8) | ||
81 | # define EVERGREEN_GRPH_BLUE_SEL_B 0 | ||
82 | # define EVERGREEN_GRPH_BLUE_SEL_A 1 | ||
83 | # define EVERGREEN_GRPH_BLUE_SEL_R 2 | ||
84 | # define EVERGREEN_GRPH_BLUE_SEL_G 3 | ||
85 | # define EVERGREEN_GRPH_ALPHA_CROSSBAR(x) (((x) & 0x3) << 10) | ||
86 | # define EVERGREEN_GRPH_ALPHA_SEL_A 0 | ||
87 | # define EVERGREEN_GRPH_ALPHA_SEL_R 1 | ||
88 | # define EVERGREEN_GRPH_ALPHA_SEL_G 2 | ||
89 | # define EVERGREEN_GRPH_ALPHA_SEL_B 3 | ||
90 | #define EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS 0x6810 | ||
91 | #define EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS 0x6814 | ||
92 | # define EVERGREEN_GRPH_DFQ_ENABLE (1 << 0) | ||
93 | # define EVERGREEN_GRPH_SURFACE_ADDRESS_MASK 0xffffff00 | ||
94 | #define EVERGREEN_GRPH_PITCH 0x6818 | ||
95 | #define EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x681c | ||
96 | #define EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x6820 | ||
97 | #define EVERGREEN_GRPH_SURFACE_OFFSET_X 0x6824 | ||
98 | #define EVERGREEN_GRPH_SURFACE_OFFSET_Y 0x6828 | ||
99 | #define EVERGREEN_GRPH_X_START 0x682c | ||
100 | #define EVERGREEN_GRPH_Y_START 0x6830 | ||
101 | #define EVERGREEN_GRPH_X_END 0x6834 | ||
102 | #define EVERGREEN_GRPH_Y_END 0x6838 | ||
103 | |||
104 | /* CUR blocks at 0x6998, 0x7598, 0x10198, 0x10d98, 0x11998, 0x12598 */ | ||
105 | #define EVERGREEN_CUR_CONTROL 0x6998 | ||
106 | # define EVERGREEN_CURSOR_EN (1 << 0) | ||
107 | # define EVERGREEN_CURSOR_MODE(x) (((x) & 0x3) << 8) | ||
108 | # define EVERGREEN_CURSOR_MONO 0 | ||
109 | # define EVERGREEN_CURSOR_24_1 1 | ||
110 | # define EVERGREEN_CURSOR_24_8_PRE_MULT 2 | ||
111 | # define EVERGREEN_CURSOR_24_8_UNPRE_MULT 3 | ||
112 | # define EVERGREEN_CURSOR_2X_MAGNIFY (1 << 16) | ||
113 | # define EVERGREEN_CURSOR_FORCE_MC_ON (1 << 20) | ||
114 | # define EVERGREEN_CURSOR_URGENT_CONTROL(x) (((x) & 0x7) << 24) | ||
115 | # define EVERGREEN_CURSOR_URGENT_ALWAYS 0 | ||
116 | # define EVERGREEN_CURSOR_URGENT_1_8 1 | ||
117 | # define EVERGREEN_CURSOR_URGENT_1_4 2 | ||
118 | # define EVERGREEN_CURSOR_URGENT_3_8 3 | ||
119 | # define EVERGREEN_CURSOR_URGENT_1_2 4 | ||
120 | #define EVERGREEN_CUR_SURFACE_ADDRESS 0x699c | ||
121 | # define EVERGREEN_CUR_SURFACE_ADDRESS_MASK 0xfffff000 | ||
122 | #define EVERGREEN_CUR_SIZE 0x69a0 | ||
123 | #define EVERGREEN_CUR_SURFACE_ADDRESS_HIGH 0x69a4 | ||
124 | #define EVERGREEN_CUR_POSITION 0x69a8 | ||
125 | #define EVERGREEN_CUR_HOT_SPOT 0x69ac | ||
126 | #define EVERGREEN_CUR_COLOR1 0x69b0 | ||
127 | #define EVERGREEN_CUR_COLOR2 0x69b4 | ||
128 | #define EVERGREEN_CUR_UPDATE 0x69b8 | ||
129 | # define EVERGREEN_CURSOR_UPDATE_PENDING (1 << 0) | ||
130 | # define EVERGREEN_CURSOR_UPDATE_TAKEN (1 << 1) | ||
131 | # define EVERGREEN_CURSOR_UPDATE_LOCK (1 << 16) | ||
132 | # define EVERGREEN_CURSOR_DISABLE_MULTIPLE_UPDATE (1 << 24) | ||
133 | |||
134 | /* LUT blocks at 0x69e0, 0x75e0, 0x101e0, 0x10de0, 0x119e0, 0x125e0 */ | ||
135 | #define EVERGREEN_DC_LUT_RW_MODE 0x69e0 | ||
136 | #define EVERGREEN_DC_LUT_RW_INDEX 0x69e4 | ||
137 | #define EVERGREEN_DC_LUT_SEQ_COLOR 0x69e8 | ||
138 | #define EVERGREEN_DC_LUT_PWL_DATA 0x69ec | ||
139 | #define EVERGREEN_DC_LUT_30_COLOR 0x69f0 | ||
140 | #define EVERGREEN_DC_LUT_VGA_ACCESS_ENABLE 0x69f4 | ||
141 | #define EVERGREEN_DC_LUT_WRITE_EN_MASK 0x69f8 | ||
142 | #define EVERGREEN_DC_LUT_AUTOFILL 0x69fc | ||
143 | #define EVERGREEN_DC_LUT_CONTROL 0x6a00 | ||
144 | #define EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE 0x6a04 | ||
145 | #define EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN 0x6a08 | ||
146 | #define EVERGREEN_DC_LUT_BLACK_OFFSET_RED 0x6a0c | ||
147 | #define EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE 0x6a10 | ||
148 | #define EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN 0x6a14 | ||
149 | #define EVERGREEN_DC_LUT_WHITE_OFFSET_RED 0x6a18 | ||
150 | |||
151 | #define EVERGREEN_DATA_FORMAT 0x6b00 | ||
152 | # define EVERGREEN_INTERLEAVE_EN (1 << 0) | ||
153 | #define EVERGREEN_DESKTOP_HEIGHT 0x6b04 | ||
154 | |||
155 | #define EVERGREEN_VIEWPORT_START 0x6d70 | ||
156 | #define EVERGREEN_VIEWPORT_SIZE 0x6d74 | ||
157 | |||
158 | /* display controller offsets used for crtc/cur/lut/grph/viewport/etc. */ | ||
159 | #define EVERGREEN_CRTC0_REGISTER_OFFSET (0x6df0 - 0x6df0) | ||
160 | #define EVERGREEN_CRTC1_REGISTER_OFFSET (0x79f0 - 0x6df0) | ||
161 | #define EVERGREEN_CRTC2_REGISTER_OFFSET (0x105f0 - 0x6df0) | ||
162 | #define EVERGREEN_CRTC3_REGISTER_OFFSET (0x111f0 - 0x6df0) | ||
163 | #define EVERGREEN_CRTC4_REGISTER_OFFSET (0x11df0 - 0x6df0) | ||
164 | #define EVERGREEN_CRTC5_REGISTER_OFFSET (0x129f0 - 0x6df0) | ||
165 | |||
166 | /* CRTC blocks at 0x6df0, 0x79f0, 0x105f0, 0x111f0, 0x11df0, 0x129f0 */ | ||
167 | #define EVERGREEN_CRTC_CONTROL 0x6e70 | ||
168 | # define EVERGREEN_CRTC_MASTER_EN (1 << 0) | ||
169 | #define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 | ||
170 | |||
171 | #define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0 | ||
172 | #define EVERGREEN_DC_GPIO_HPD_A 0x64b4 | ||
173 | #define EVERGREEN_DC_GPIO_HPD_EN 0x64b8 | ||
174 | #define EVERGREEN_DC_GPIO_HPD_Y 0x64bc | ||
175 | |||
176 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b519d7db2dcb..a7a96a240844 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -138,11 +138,14 @@ void radeon_dummy_page_fini(struct radeon_device *rdev); | |||
138 | struct radeon_clock { | 138 | struct radeon_clock { |
139 | struct radeon_pll p1pll; | 139 | struct radeon_pll p1pll; |
140 | struct radeon_pll p2pll; | 140 | struct radeon_pll p2pll; |
141 | struct radeon_pll dcpll; | ||
141 | struct radeon_pll spll; | 142 | struct radeon_pll spll; |
142 | struct radeon_pll mpll; | 143 | struct radeon_pll mpll; |
143 | /* 10 Khz units */ | 144 | /* 10 Khz units */ |
144 | uint32_t default_mclk; | 145 | uint32_t default_mclk; |
145 | uint32_t default_sclk; | 146 | uint32_t default_sclk; |
147 | uint32_t default_dispclk; | ||
148 | uint32_t dp_extclk; | ||
146 | }; | 149 | }; |
147 | 150 | ||
148 | /* | 151 | /* |
@@ -1062,7 +1065,7 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); | |||
1062 | #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600)) | 1065 | #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600)) |
1063 | #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620)) | 1066 | #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620)) |
1064 | #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730)) | 1067 | #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730)) |
1065 | 1068 | #define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR)) | |
1066 | 1069 | ||
1067 | /* | 1070 | /* |
1068 | * BIOS helpers. | 1071 | * BIOS helpers. |
@@ -1296,6 +1299,14 @@ extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, | |||
1296 | uint8_t status_bits, | 1299 | uint8_t status_bits, |
1297 | uint8_t category_code); | 1300 | uint8_t category_code); |
1298 | 1301 | ||
1302 | /* evergreen */ | ||
1303 | struct evergreen_mc_save { | ||
1304 | u32 vga_control[6]; | ||
1305 | u32 vga_render_control; | ||
1306 | u32 vga_hdp_control; | ||
1307 | u32 crtc_control[6]; | ||
1308 | }; | ||
1309 | |||
1299 | #include "radeon_object.h" | 1310 | #include "radeon_object.h" |
1300 | 1311 | ||
1301 | #endif | 1312 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 3f3c7a2169f1..4b0cb67a379a 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -606,4 +606,54 @@ static struct radeon_asic rv770_asic = { | |||
606 | .ioctl_wait_idle = r600_ioctl_wait_idle, | 606 | .ioctl_wait_idle = r600_ioctl_wait_idle, |
607 | }; | 607 | }; |
608 | 608 | ||
609 | /* | ||
610 | * evergreen | ||
611 | */ | ||
612 | int evergreen_init(struct radeon_device *rdev); | ||
613 | void evergreen_fini(struct radeon_device *rdev); | ||
614 | int evergreen_suspend(struct radeon_device *rdev); | ||
615 | int evergreen_resume(struct radeon_device *rdev); | ||
616 | int evergreen_gpu_reset(struct radeon_device *rdev); | ||
617 | void evergreen_bandwidth_update(struct radeon_device *rdev); | ||
618 | void evergreen_hpd_init(struct radeon_device *rdev); | ||
619 | void evergreen_hpd_fini(struct radeon_device *rdev); | ||
620 | bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | ||
621 | void evergreen_hpd_set_polarity(struct radeon_device *rdev, | ||
622 | enum radeon_hpd_id hpd); | ||
623 | |||
624 | static struct radeon_asic evergreen_asic = { | ||
625 | .init = &evergreen_init, | ||
626 | .fini = &evergreen_fini, | ||
627 | .suspend = &evergreen_suspend, | ||
628 | .resume = &evergreen_resume, | ||
629 | .cp_commit = NULL, | ||
630 | .gpu_reset = &evergreen_gpu_reset, | ||
631 | .vga_set_state = &r600_vga_set_state, | ||
632 | .gart_tlb_flush = &r600_pcie_gart_tlb_flush, | ||
633 | .gart_set_page = &rs600_gart_set_page, | ||
634 | .ring_test = NULL, | ||
635 | .ring_ib_execute = NULL, | ||
636 | .irq_set = NULL, | ||
637 | .irq_process = NULL, | ||
638 | .get_vblank_counter = NULL, | ||
639 | .fence_ring_emit = NULL, | ||
640 | .cs_parse = NULL, | ||
641 | .copy_blit = NULL, | ||
642 | .copy_dma = NULL, | ||
643 | .copy = NULL, | ||
644 | .get_engine_clock = &radeon_atom_get_engine_clock, | ||
645 | .set_engine_clock = &radeon_atom_set_engine_clock, | ||
646 | .get_memory_clock = &radeon_atom_get_memory_clock, | ||
647 | .set_memory_clock = &radeon_atom_set_memory_clock, | ||
648 | .set_pcie_lanes = NULL, | ||
649 | .set_clock_gating = NULL, | ||
650 | .set_surface_reg = r600_set_surface_reg, | ||
651 | .clear_surface_reg = r600_clear_surface_reg, | ||
652 | .bandwidth_update = &evergreen_bandwidth_update, | ||
653 | .hpd_init = &evergreen_hpd_init, | ||
654 | .hpd_fini = &evergreen_hpd_fini, | ||
655 | .hpd_sense = &evergreen_hpd_sense, | ||
656 | .hpd_set_polarity = &evergreen_hpd_set_polarity, | ||
657 | }; | ||
658 | |||
609 | #endif | 659 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index c3198453528f..4f7dbce9883a 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -159,8 +159,15 @@ static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device | |||
159 | struct radeon_gpio_rec *gpio) | 159 | struct radeon_gpio_rec *gpio) |
160 | { | 160 | { |
161 | struct radeon_hpd hpd; | 161 | struct radeon_hpd hpd; |
162 | u32 reg; | ||
163 | |||
164 | if (ASIC_IS_DCE4(rdev)) | ||
165 | reg = EVERGREEN_DC_GPIO_HPD_A; | ||
166 | else | ||
167 | reg = AVIVO_DC_GPIO_HPD_A; | ||
168 | |||
162 | hpd.gpio = *gpio; | 169 | hpd.gpio = *gpio; |
163 | if (gpio->reg == AVIVO_DC_GPIO_HPD_A) { | 170 | if (gpio->reg == reg) { |
164 | switch(gpio->mask) { | 171 | switch(gpio->mask) { |
165 | case (1 << 0): | 172 | case (1 << 0): |
166 | hpd.hpd = RADEON_HPD_1; | 173 | hpd.hpd = RADEON_HPD_1; |
@@ -556,6 +563,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
556 | ddc_bus.valid = false; | 563 | ddc_bus.valid = false; |
557 | } | 564 | } |
558 | 565 | ||
566 | /* needed for aux chan transactions */ | ||
567 | ddc_bus.hpd_id = hpd.hpd ? (hpd.hpd - 1) : 0; | ||
568 | |||
559 | conn_id = le16_to_cpu(path->usConnObjectId); | 569 | conn_id = le16_to_cpu(path->usConnObjectId); |
560 | 570 | ||
561 | if (!radeon_atom_apply_quirks | 571 | if (!radeon_atom_apply_quirks |
@@ -820,6 +830,7 @@ union firmware_info { | |||
820 | ATOM_FIRMWARE_INFO_V1_2 info_12; | 830 | ATOM_FIRMWARE_INFO_V1_2 info_12; |
821 | ATOM_FIRMWARE_INFO_V1_3 info_13; | 831 | ATOM_FIRMWARE_INFO_V1_3 info_13; |
822 | ATOM_FIRMWARE_INFO_V1_4 info_14; | 832 | ATOM_FIRMWARE_INFO_V1_4 info_14; |
833 | ATOM_FIRMWARE_INFO_V2_1 info_21; | ||
823 | }; | 834 | }; |
824 | 835 | ||
825 | bool radeon_atom_get_clock_info(struct drm_device *dev) | 836 | bool radeon_atom_get_clock_info(struct drm_device *dev) |
@@ -831,6 +842,7 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
831 | uint8_t frev, crev; | 842 | uint8_t frev, crev; |
832 | struct radeon_pll *p1pll = &rdev->clock.p1pll; | 843 | struct radeon_pll *p1pll = &rdev->clock.p1pll; |
833 | struct radeon_pll *p2pll = &rdev->clock.p2pll; | 844 | struct radeon_pll *p2pll = &rdev->clock.p2pll; |
845 | struct radeon_pll *dcpll = &rdev->clock.dcpll; | ||
834 | struct radeon_pll *spll = &rdev->clock.spll; | 846 | struct radeon_pll *spll = &rdev->clock.spll; |
835 | struct radeon_pll *mpll = &rdev->clock.mpll; | 847 | struct radeon_pll *mpll = &rdev->clock.mpll; |
836 | uint16_t data_offset; | 848 | uint16_t data_offset; |
@@ -933,8 +945,19 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
933 | rdev->clock.default_mclk = | 945 | rdev->clock.default_mclk = |
934 | le32_to_cpu(firmware_info->info.ulDefaultMemoryClock); | 946 | le32_to_cpu(firmware_info->info.ulDefaultMemoryClock); |
935 | 947 | ||
948 | if (ASIC_IS_DCE4(rdev)) { | ||
949 | rdev->clock.default_dispclk = | ||
950 | le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq); | ||
951 | if (rdev->clock.default_dispclk == 0) | ||
952 | rdev->clock.default_dispclk = 60000; /* 600 Mhz */ | ||
953 | rdev->clock.dp_extclk = | ||
954 | le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq); | ||
955 | } | ||
956 | *dcpll = *p1pll; | ||
957 | |||
936 | return true; | 958 | return true; |
937 | } | 959 | } |
960 | |||
938 | return false; | 961 | return false; |
939 | } | 962 | } |
940 | 963 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index 3ec94a0d3109..f64936cc4dd9 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
@@ -96,6 +96,7 @@ void radeon_get_clock_info(struct drm_device *dev) | |||
96 | struct radeon_device *rdev = dev->dev_private; | 96 | struct radeon_device *rdev = dev->dev_private; |
97 | struct radeon_pll *p1pll = &rdev->clock.p1pll; | 97 | struct radeon_pll *p1pll = &rdev->clock.p1pll; |
98 | struct radeon_pll *p2pll = &rdev->clock.p2pll; | 98 | struct radeon_pll *p2pll = &rdev->clock.p2pll; |
99 | struct radeon_pll *dcpll = &rdev->clock.dcpll; | ||
99 | struct radeon_pll *spll = &rdev->clock.spll; | 100 | struct radeon_pll *spll = &rdev->clock.spll; |
100 | struct radeon_pll *mpll = &rdev->clock.mpll; | 101 | struct radeon_pll *mpll = &rdev->clock.mpll; |
101 | int ret; | 102 | int ret; |
@@ -204,6 +205,17 @@ void radeon_get_clock_info(struct drm_device *dev) | |||
204 | p2pll->max_frac_feedback_div = 0; | 205 | p2pll->max_frac_feedback_div = 0; |
205 | } | 206 | } |
206 | 207 | ||
208 | /* dcpll is DCE4 only */ | ||
209 | dcpll->min_post_div = 2; | ||
210 | dcpll->max_post_div = 0x7f; | ||
211 | dcpll->min_frac_feedback_div = 0; | ||
212 | dcpll->max_frac_feedback_div = 9; | ||
213 | dcpll->min_ref_div = 2; | ||
214 | dcpll->max_ref_div = 0x3ff; | ||
215 | dcpll->min_feedback_div = 4; | ||
216 | dcpll->max_feedback_div = 0xfff; | ||
217 | dcpll->best_vco = 0; | ||
218 | |||
207 | p1pll->min_ref_div = 2; | 219 | p1pll->min_ref_div = 2; |
208 | p1pll->max_ref_div = 0x3ff; | 220 | p1pll->max_ref_div = 0x3ff; |
209 | p1pll->min_feedback_div = 4; | 221 | p1pll->min_feedback_div = 4; |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index a4d40de50434..26fb42450cb2 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -600,6 +600,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde | |||
600 | } | 600 | } |
601 | i2c.mm_i2c = false; | 601 | i2c.mm_i2c = false; |
602 | i2c.i2c_id = 0; | 602 | i2c.i2c_id = 0; |
603 | i2c.hpd_id = 0; | ||
603 | 604 | ||
604 | if (ddc_line) | 605 | if (ddc_line) |
605 | i2c.valid = true; | 606 | i2c.valid = true; |
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 28772a37009c..9514f3275357 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
@@ -36,7 +36,14 @@ static void radeon_lock_cursor(struct drm_crtc *crtc, bool lock) | |||
36 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 36 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
37 | uint32_t cur_lock; | 37 | uint32_t cur_lock; |
38 | 38 | ||
39 | if (ASIC_IS_AVIVO(rdev)) { | 39 | if (ASIC_IS_DCE4(rdev)) { |
40 | cur_lock = RREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset); | ||
41 | if (lock) | ||
42 | cur_lock |= EVERGREEN_CURSOR_UPDATE_LOCK; | ||
43 | else | ||
44 | cur_lock &= ~EVERGREEN_CURSOR_UPDATE_LOCK; | ||
45 | WREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock); | ||
46 | } else if (ASIC_IS_AVIVO(rdev)) { | ||
40 | cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset); | 47 | cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset); |
41 | if (lock) | 48 | if (lock) |
42 | cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK; | 49 | cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK; |
@@ -58,7 +65,10 @@ static void radeon_hide_cursor(struct drm_crtc *crtc) | |||
58 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 65 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
59 | struct radeon_device *rdev = crtc->dev->dev_private; | 66 | struct radeon_device *rdev = crtc->dev->dev_private; |
60 | 67 | ||
61 | if (ASIC_IS_AVIVO(rdev)) { | 68 | if (ASIC_IS_DCE4(rdev)) { |
69 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); | ||
70 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); | ||
71 | } else if (ASIC_IS_AVIVO(rdev)) { | ||
62 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); | 72 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
63 | WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); | 73 | WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); |
64 | } else { | 74 | } else { |
@@ -81,10 +91,14 @@ static void radeon_show_cursor(struct drm_crtc *crtc) | |||
81 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 91 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
82 | struct radeon_device *rdev = crtc->dev->dev_private; | 92 | struct radeon_device *rdev = crtc->dev->dev_private; |
83 | 93 | ||
84 | if (ASIC_IS_AVIVO(rdev)) { | 94 | if (ASIC_IS_DCE4(rdev)) { |
95 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); | ||
96 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | | ||
97 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); | ||
98 | } else if (ASIC_IS_AVIVO(rdev)) { | ||
85 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); | 99 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
86 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | | 100 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | |
87 | (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); | 101 | (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); |
88 | } else { | 102 | } else { |
89 | switch (radeon_crtc->crtc_id) { | 103 | switch (radeon_crtc->crtc_id) { |
90 | case 0: | 104 | case 0: |
@@ -109,7 +123,10 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, | |||
109 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 123 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
110 | struct radeon_device *rdev = crtc->dev->dev_private; | 124 | struct radeon_device *rdev = crtc->dev->dev_private; |
111 | 125 | ||
112 | if (ASIC_IS_AVIVO(rdev)) { | 126 | if (ASIC_IS_DCE4(rdev)) { |
127 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, 0); | ||
128 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr); | ||
129 | } else if (ASIC_IS_AVIVO(rdev)) { | ||
113 | if (rdev->family >= CHIP_RV770) { | 130 | if (rdev->family >= CHIP_RV770) { |
114 | if (radeon_crtc->crtc_id) | 131 | if (radeon_crtc->crtc_id) |
115 | WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, 0); | 132 | WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, 0); |
@@ -201,7 +218,15 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, | |||
201 | yorigin = CURSOR_HEIGHT - 1; | 218 | yorigin = CURSOR_HEIGHT - 1; |
202 | 219 | ||
203 | radeon_lock_cursor(crtc, true); | 220 | radeon_lock_cursor(crtc, true); |
204 | if (ASIC_IS_AVIVO(rdev)) { | 221 | if (ASIC_IS_DCE4(rdev)) { |
222 | /* XXX: check if evergreen has the same issues as avivo chips */ | ||
223 | WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, | ||
224 | ((xorigin ? 0 : x) << 16) | | ||
225 | (yorigin ? 0 : y)); | ||
226 | WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); | ||
227 | WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset, | ||
228 | ((radeon_crtc->cursor_width - 1) << 16) | (radeon_crtc->cursor_height - 1)); | ||
229 | } else if (ASIC_IS_AVIVO(rdev)) { | ||
205 | int w = radeon_crtc->cursor_width; | 230 | int w = radeon_crtc->cursor_width; |
206 | int i = 0; | 231 | int i = 0; |
207 | struct drm_crtc *crtc_p; | 232 | struct drm_crtc *crtc_p; |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index c90f8d370266..c224c1d944ef 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -182,7 +182,16 @@ bool radeon_card_posted(struct radeon_device *rdev) | |||
182 | uint32_t reg; | 182 | uint32_t reg; |
183 | 183 | ||
184 | /* first check CRTCs */ | 184 | /* first check CRTCs */ |
185 | if (ASIC_IS_AVIVO(rdev)) { | 185 | if (ASIC_IS_DCE4(rdev)) { |
186 | reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | | ||
187 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | | ||
188 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | | ||
189 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | | ||
190 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | | ||
191 | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
192 | if (reg & EVERGREEN_CRTC_MASTER_EN) | ||
193 | return true; | ||
194 | } else if (ASIC_IS_AVIVO(rdev)) { | ||
186 | reg = RREG32(AVIVO_D1CRTC_CONTROL) | | 195 | reg = RREG32(AVIVO_D1CRTC_CONTROL) | |
187 | RREG32(AVIVO_D2CRTC_CONTROL); | 196 | RREG32(AVIVO_D2CRTC_CONTROL); |
188 | if (reg & AVIVO_CRTC_EN) { | 197 | if (reg & AVIVO_CRTC_EN) { |
@@ -310,7 +319,7 @@ void radeon_register_accessor_init(struct radeon_device *rdev) | |||
310 | rdev->mc_rreg = &rs600_mc_rreg; | 319 | rdev->mc_rreg = &rs600_mc_rreg; |
311 | rdev->mc_wreg = &rs600_mc_wreg; | 320 | rdev->mc_wreg = &rs600_mc_wreg; |
312 | } | 321 | } |
313 | if (rdev->family >= CHIP_R600) { | 322 | if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) { |
314 | rdev->pciep_rreg = &r600_pciep_rreg; | 323 | rdev->pciep_rreg = &r600_pciep_rreg; |
315 | rdev->pciep_wreg = &r600_pciep_wreg; | 324 | rdev->pciep_wreg = &r600_pciep_wreg; |
316 | } | 325 | } |
@@ -387,6 +396,13 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
387 | case CHIP_RV740: | 396 | case CHIP_RV740: |
388 | rdev->asic = &rv770_asic; | 397 | rdev->asic = &rv770_asic; |
389 | break; | 398 | break; |
399 | case CHIP_CEDAR: | ||
400 | case CHIP_REDWOOD: | ||
401 | case CHIP_JUNIPER: | ||
402 | case CHIP_CYPRESS: | ||
403 | case CHIP_HEMLOCK: | ||
404 | rdev->asic = &evergreen_asic; | ||
405 | break; | ||
390 | default: | 406 | default: |
391 | /* FIXME: not supported yet */ | 407 | /* FIXME: not supported yet */ |
392 | return -EINVAL; | 408 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index a41ed40c13fb..257827806aee 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -68,6 +68,36 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc) | |||
68 | WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id); | 68 | WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id); |
69 | } | 69 | } |
70 | 70 | ||
71 | static void evergreen_crtc_load_lut(struct drm_crtc *crtc) | ||
72 | { | ||
73 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
74 | struct drm_device *dev = crtc->dev; | ||
75 | struct radeon_device *rdev = dev->dev_private; | ||
76 | int i; | ||
77 | |||
78 | DRM_DEBUG("%d\n", radeon_crtc->crtc_id); | ||
79 | WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0); | ||
80 | |||
81 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); | ||
82 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0); | ||
83 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0); | ||
84 | |||
85 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff); | ||
86 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff); | ||
87 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); | ||
88 | |||
89 | WREG32(EVERGREEN_DC_LUT_RW_MODE, radeon_crtc->crtc_id); | ||
90 | WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK, 0x00000007); | ||
91 | |||
92 | WREG32(EVERGREEN_DC_LUT_RW_INDEX, 0); | ||
93 | for (i = 0; i < 256; i++) { | ||
94 | WREG32(EVERGREEN_DC_LUT_30_COLOR, | ||
95 | (radeon_crtc->lut_r[i] << 20) | | ||
96 | (radeon_crtc->lut_g[i] << 10) | | ||
97 | (radeon_crtc->lut_b[i] << 0)); | ||
98 | } | ||
99 | } | ||
100 | |||
71 | static void legacy_crtc_load_lut(struct drm_crtc *crtc) | 101 | static void legacy_crtc_load_lut(struct drm_crtc *crtc) |
72 | { | 102 | { |
73 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 103 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
@@ -100,7 +130,9 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc) | |||
100 | if (!crtc->enabled) | 130 | if (!crtc->enabled) |
101 | return; | 131 | return; |
102 | 132 | ||
103 | if (ASIC_IS_AVIVO(rdev)) | 133 | if (ASIC_IS_DCE4(rdev)) |
134 | evergreen_crtc_load_lut(crtc); | ||
135 | else if (ASIC_IS_AVIVO(rdev)) | ||
104 | avivo_crtc_load_lut(crtc); | 136 | avivo_crtc_load_lut(crtc); |
105 | else | 137 | else |
106 | legacy_crtc_load_lut(crtc); | 138 | legacy_crtc_load_lut(crtc); |
@@ -862,8 +894,12 @@ int radeon_modeset_init(struct radeon_device *rdev) | |||
862 | 894 | ||
863 | if (rdev->flags & RADEON_SINGLE_CRTC) | 895 | if (rdev->flags & RADEON_SINGLE_CRTC) |
864 | rdev->num_crtc = 1; | 896 | rdev->num_crtc = 1; |
865 | else | 897 | else { |
866 | rdev->num_crtc = 2; | 898 | if (ASIC_IS_DCE4(rdev)) |
899 | rdev->num_crtc = 6; | ||
900 | else | ||
901 | rdev->num_crtc = 2; | ||
902 | } | ||
867 | 903 | ||
868 | /* allocate crtcs */ | 904 | /* allocate crtcs */ |
869 | for (i = 0; i < rdev->num_crtc; i++) { | 905 | for (i = 0; i < rdev->num_crtc; i++) { |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index f7d6078876c5..bc926ea0a530 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -53,7 +53,7 @@ static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) | |||
53 | /* DVO requires 2x ppll clocks depending on tmds chip */ | 53 | /* DVO requires 2x ppll clocks depending on tmds chip */ |
54 | if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) | 54 | if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) |
55 | return index_mask; | 55 | return index_mask; |
56 | 56 | ||
57 | count = -1; | 57 | count = -1; |
58 | list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) { | 58 | list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) { |
59 | struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder); | 59 | struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder); |
@@ -671,6 +671,18 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
671 | * - 2 DIG encoder blocks. | 671 | * - 2 DIG encoder blocks. |
672 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | 672 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B |
673 | * | 673 | * |
674 | * DCE 4.0 | ||
675 | * - 3 DIG transmitter blocks UNPHY0/1/2 (links A and B). | ||
676 | * Supports up to 6 digital outputs | ||
677 | * - 6 DIG encoder blocks. | ||
678 | * - DIG to PHY mapping is hardcoded | ||
679 | * DIG1 drives UNIPHY0 link A, A+B | ||
680 | * DIG2 drives UNIPHY0 link B | ||
681 | * DIG3 drives UNIPHY1 link A, A+B | ||
682 | * DIG4 drives UNIPHY1 link B | ||
683 | * DIG5 drives UNIPHY2 link A, A+B | ||
684 | * DIG6 drives UNIPHY2 link B | ||
685 | * | ||
674 | * Routing | 686 | * Routing |
675 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) | 687 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) |
676 | * Examples: | 688 | * Examples: |
@@ -679,7 +691,14 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
679 | * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS | 691 | * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS |
680 | * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI | 692 | * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI |
681 | */ | 693 | */ |
682 | static void | 694 | |
695 | union dig_encoder_control { | ||
696 | DIG_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
697 | DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; | ||
698 | DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; | ||
699 | }; | ||
700 | |||
701 | void | ||
683 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | 702 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) |
684 | { | 703 | { |
685 | struct drm_device *dev = encoder->dev; | 704 | struct drm_device *dev = encoder->dev; |
@@ -688,7 +707,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
688 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 707 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
689 | struct radeon_connector_atom_dig *dig_connector = | 708 | struct radeon_connector_atom_dig *dig_connector = |
690 | radeon_get_atom_connector_priv_from_encoder(encoder); | 709 | radeon_get_atom_connector_priv_from_encoder(encoder); |
691 | DIG_ENCODER_CONTROL_PS_ALLOCATION args; | 710 | union dig_encoder_control args; |
692 | int index = 0, num = 0; | 711 | int index = 0, num = 0; |
693 | uint8_t frev, crev; | 712 | uint8_t frev, crev; |
694 | 713 | ||
@@ -697,56 +716,53 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
697 | 716 | ||
698 | memset(&args, 0, sizeof(args)); | 717 | memset(&args, 0, sizeof(args)); |
699 | 718 | ||
700 | if (dig->dig_encoder) | 719 | if (ASIC_IS_DCE4(rdev)) |
701 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | 720 | index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl); |
702 | else | 721 | else { |
703 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | 722 | if (dig->dig_encoder) |
723 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | ||
724 | else | ||
725 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | ||
726 | } | ||
704 | num = dig->dig_encoder + 1; | 727 | num = dig->dig_encoder + 1; |
705 | 728 | ||
706 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); | 729 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); |
707 | 730 | ||
708 | args.ucAction = action; | 731 | args.v1.ucAction = action; |
709 | args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 732 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
733 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
710 | 734 | ||
711 | if (ASIC_IS_DCE32(rdev)) { | 735 | if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { |
736 | if (dig_connector->dp_clock == 270000) | ||
737 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
738 | args.v1.ucLaneNum = dig_connector->dp_lane_count; | ||
739 | } else if (radeon_encoder->pixel_clock > 165000) | ||
740 | args.v1.ucLaneNum = 8; | ||
741 | else | ||
742 | args.v1.ucLaneNum = 4; | ||
743 | |||
744 | if (ASIC_IS_DCE4(rdev)) { | ||
745 | args.v3.acConfig.ucDigSel = dig->dig_encoder; | ||
746 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
747 | } else { | ||
712 | switch (radeon_encoder->encoder_id) { | 748 | switch (radeon_encoder->encoder_id) { |
713 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 749 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
714 | args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; | 750 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; |
715 | break; | 751 | break; |
716 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 752 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
717 | args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; | 753 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
754 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; | ||
718 | break; | 755 | break; |
719 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 756 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
720 | args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; | 757 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; |
721 | break; | ||
722 | } | ||
723 | } else { | ||
724 | switch (radeon_encoder->encoder_id) { | ||
725 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
726 | args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1; | ||
727 | break; | ||
728 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
729 | args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2; | ||
730 | break; | 758 | break; |
731 | } | 759 | } |
760 | if (dig_connector->linkb) | ||
761 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
762 | else | ||
763 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
732 | } | 764 | } |
733 | 765 | ||
734 | args.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
735 | |||
736 | if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | ||
737 | if (dig_connector->dp_clock == 270000) | ||
738 | args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
739 | args.ucLaneNum = dig_connector->dp_lane_count; | ||
740 | } else if (radeon_encoder->pixel_clock > 165000) | ||
741 | args.ucLaneNum = 8; | ||
742 | else | ||
743 | args.ucLaneNum = 4; | ||
744 | |||
745 | if (dig_connector->linkb) | ||
746 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
747 | else | ||
748 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
749 | |||
750 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 766 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
751 | 767 | ||
752 | } | 768 | } |
@@ -754,6 +770,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
754 | union dig_transmitter_control { | 770 | union dig_transmitter_control { |
755 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; | 771 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; |
756 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; | 772 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; |
773 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; | ||
757 | }; | 774 | }; |
758 | 775 | ||
759 | void | 776 | void |
@@ -771,6 +788,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
771 | int index = 0, num = 0; | 788 | int index = 0, num = 0; |
772 | uint8_t frev, crev; | 789 | uint8_t frev, crev; |
773 | bool is_dp = false; | 790 | bool is_dp = false; |
791 | int pll_id = 0; | ||
774 | 792 | ||
775 | if (!dig || !dig_connector) | 793 | if (!dig || !dig_connector) |
776 | return; | 794 | return; |
@@ -783,7 +801,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
783 | 801 | ||
784 | memset(&args, 0, sizeof(args)); | 802 | memset(&args, 0, sizeof(args)); |
785 | 803 | ||
786 | if (ASIC_IS_DCE32(rdev)) | 804 | if (ASIC_IS_DCE32(rdev) || ASIC_IS_DCE4(rdev)) |
787 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | 805 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); |
788 | else { | 806 | else { |
789 | switch (radeon_encoder->encoder_id) { | 807 | switch (radeon_encoder->encoder_id) { |
@@ -813,7 +831,54 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
813 | else | 831 | else |
814 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 832 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
815 | } | 833 | } |
816 | if (ASIC_IS_DCE32(rdev)) { | 834 | if (ASIC_IS_DCE4(rdev)) { |
835 | if (is_dp) | ||
836 | args.v3.ucLaneNum = dig_connector->dp_lane_count; | ||
837 | else if (radeon_encoder->pixel_clock > 165000) | ||
838 | args.v3.ucLaneNum = 8; | ||
839 | else | ||
840 | args.v3.ucLaneNum = 4; | ||
841 | |||
842 | if (dig_connector->linkb) { | ||
843 | args.v3.acConfig.ucLinkSel = 1; | ||
844 | args.v3.acConfig.ucEncoderSel = 1; | ||
845 | } | ||
846 | |||
847 | /* Select the PLL for the PHY | ||
848 | * DP PHY should be clocked from external src if there is | ||
849 | * one. | ||
850 | */ | ||
851 | if (encoder->crtc) { | ||
852 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
853 | pll_id = radeon_crtc->pll_id; | ||
854 | } | ||
855 | if (is_dp && rdev->clock.dp_extclk) | ||
856 | args.v3.acConfig.ucRefClkSource = 2; /* external src */ | ||
857 | else | ||
858 | args.v3.acConfig.ucRefClkSource = pll_id; | ||
859 | |||
860 | switch (radeon_encoder->encoder_id) { | ||
861 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
862 | args.v3.acConfig.ucTransmitterSel = 0; | ||
863 | num = 0; | ||
864 | break; | ||
865 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
866 | args.v3.acConfig.ucTransmitterSel = 1; | ||
867 | num = 1; | ||
868 | break; | ||
869 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
870 | args.v3.acConfig.ucTransmitterSel = 2; | ||
871 | num = 2; | ||
872 | break; | ||
873 | } | ||
874 | |||
875 | if (is_dp) | ||
876 | args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */ | ||
877 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
878 | if (dig->coherent_mode) | ||
879 | args.v3.acConfig.fCoherentMode = 1; | ||
880 | } | ||
881 | } else if (ASIC_IS_DCE32(rdev)) { | ||
817 | if (dig->dig_encoder == 1) | 882 | if (dig->dig_encoder == 1) |
818 | args.v2.acConfig.ucEncoderSel = 1; | 883 | args.v2.acConfig.ucEncoderSel = 1; |
819 | if (dig_connector->linkb) | 884 | if (dig_connector->linkb) |
@@ -841,7 +906,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
841 | args.v2.acConfig.fCoherentMode = 1; | 906 | args.v2.acConfig.fCoherentMode = 1; |
842 | } | 907 | } |
843 | } else { | 908 | } else { |
844 | |||
845 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; | 909 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; |
846 | 910 | ||
847 | if (dig->dig_encoder) | 911 | if (dig->dig_encoder) |
@@ -1102,10 +1166,26 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
1102 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1166 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1103 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1167 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1104 | dig = radeon_encoder->enc_priv; | 1168 | dig = radeon_encoder->enc_priv; |
1105 | if (dig->dig_encoder) | 1169 | switch (dig->dig_encoder) { |
1106 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | 1170 | case 0: |
1107 | else | ||
1108 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | 1171 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; |
1172 | break; | ||
1173 | case 1: | ||
1174 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
1175 | break; | ||
1176 | case 2: | ||
1177 | args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID; | ||
1178 | break; | ||
1179 | case 3: | ||
1180 | args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID; | ||
1181 | break; | ||
1182 | case 4: | ||
1183 | args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID; | ||
1184 | break; | ||
1185 | case 5: | ||
1186 | args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID; | ||
1187 | break; | ||
1188 | } | ||
1109 | break; | 1189 | break; |
1110 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | 1190 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: |
1111 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; | 1191 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; |
@@ -1162,6 +1242,7 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder, | |||
1162 | } | 1242 | } |
1163 | 1243 | ||
1164 | /* set scaler clears this on some chips */ | 1244 | /* set scaler clears this on some chips */ |
1245 | /* XXX check DCE4 */ | ||
1165 | if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { | 1246 | if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { |
1166 | if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) | 1247 | if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) |
1167 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, | 1248 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, |
@@ -1178,6 +1259,33 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
1178 | struct drm_encoder *test_encoder; | 1259 | struct drm_encoder *test_encoder; |
1179 | struct radeon_encoder_atom_dig *dig; | 1260 | struct radeon_encoder_atom_dig *dig; |
1180 | uint32_t dig_enc_in_use = 0; | 1261 | uint32_t dig_enc_in_use = 0; |
1262 | |||
1263 | if (ASIC_IS_DCE4(rdev)) { | ||
1264 | struct radeon_connector_atom_dig *dig_connector = | ||
1265 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
1266 | |||
1267 | switch (radeon_encoder->encoder_id) { | ||
1268 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1269 | if (dig_connector->linkb) | ||
1270 | return 1; | ||
1271 | else | ||
1272 | return 0; | ||
1273 | break; | ||
1274 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1275 | if (dig_connector->linkb) | ||
1276 | return 3; | ||
1277 | else | ||
1278 | return 2; | ||
1279 | break; | ||
1280 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1281 | if (dig_connector->linkb) | ||
1282 | return 5; | ||
1283 | else | ||
1284 | return 4; | ||
1285 | break; | ||
1286 | } | ||
1287 | } | ||
1288 | |||
1181 | /* on DCE32 and encoder can driver any block so just crtc id */ | 1289 | /* on DCE32 and encoder can driver any block so just crtc id */ |
1182 | if (ASIC_IS_DCE32(rdev)) { | 1290 | if (ASIC_IS_DCE32(rdev)) { |
1183 | return radeon_crtc->crtc_id; | 1291 | return radeon_crtc->crtc_id; |
@@ -1249,15 +1357,26 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1249 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1357 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
1250 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1358 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1251 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1359 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1252 | /* disable the encoder and transmitter */ | 1360 | if (ASIC_IS_DCE4(rdev)) { |
1253 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 1361 | /* disable the transmitter */ |
1254 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); | 1362 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1255 | 1363 | /* setup and enable the encoder */ | |
1256 | /* setup and enable the encoder and transmitter */ | 1364 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP); |
1257 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); | 1365 | |
1258 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); | 1366 | /* init and enable the transmitter */ |
1259 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | 1367 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); |
1260 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1368 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
1369 | } else { | ||
1370 | /* disable the encoder and transmitter */ | ||
1371 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1372 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); | ||
1373 | |||
1374 | /* setup and enable the encoder and transmitter */ | ||
1375 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); | ||
1376 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); | ||
1377 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
1378 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1379 | } | ||
1261 | break; | 1380 | break; |
1262 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 1381 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
1263 | atombios_ddia_setup(encoder, ATOM_ENABLE); | 1382 | atombios_ddia_setup(encoder, ATOM_ENABLE); |
@@ -1277,7 +1396,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1277 | } | 1396 | } |
1278 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | 1397 | atombios_apply_encoder_quirks(encoder, adjusted_mode); |
1279 | 1398 | ||
1280 | r600_hdmi_setmode(encoder, adjusted_mode); | 1399 | /* XXX */ |
1400 | if (!ASIC_IS_DCE4(rdev)) | ||
1401 | r600_hdmi_setmode(encoder, adjusted_mode); | ||
1281 | } | 1402 | } |
1282 | 1403 | ||
1283 | static bool | 1404 | static bool |
@@ -1475,10 +1596,18 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1475 | return; | 1596 | return; |
1476 | 1597 | ||
1477 | encoder = &radeon_encoder->base; | 1598 | encoder = &radeon_encoder->base; |
1478 | if (rdev->flags & RADEON_SINGLE_CRTC) | 1599 | switch (rdev->num_crtc) { |
1600 | case 1: | ||
1479 | encoder->possible_crtcs = 0x1; | 1601 | encoder->possible_crtcs = 0x1; |
1480 | else | 1602 | break; |
1603 | case 2: | ||
1604 | default: | ||
1481 | encoder->possible_crtcs = 0x3; | 1605 | encoder->possible_crtcs = 0x3; |
1606 | break; | ||
1607 | case 6: | ||
1608 | encoder->possible_crtcs = 0x3f; | ||
1609 | break; | ||
1610 | } | ||
1482 | 1611 | ||
1483 | radeon_encoder->enc_priv = NULL; | 1612 | radeon_encoder->enc_priv = NULL; |
1484 | 1613 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h index 797972e344a6..93c7d5d41914 100644 --- a/drivers/gpu/drm/radeon/radeon_family.h +++ b/drivers/gpu/drm/radeon/radeon_family.h | |||
@@ -75,6 +75,11 @@ enum radeon_family { | |||
75 | CHIP_RV730, | 75 | CHIP_RV730, |
76 | CHIP_RV710, | 76 | CHIP_RV710, |
77 | CHIP_RV740, | 77 | CHIP_RV740, |
78 | CHIP_CEDAR, | ||
79 | CHIP_REDWOOD, | ||
80 | CHIP_JUNIPER, | ||
81 | CHIP_CYPRESS, | ||
82 | CHIP_HEMLOCK, | ||
78 | CHIP_LAST, | 83 | CHIP_LAST, |
79 | }; | 84 | }; |
80 | 85 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index d1e859d1dbf9..8912f2e8e640 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -83,6 +83,8 @@ struct radeon_i2c_bus_rec { | |||
83 | bool valid; | 83 | bool valid; |
84 | /* id used by atom */ | 84 | /* id used by atom */ |
85 | uint8_t i2c_id; | 85 | uint8_t i2c_id; |
86 | /* id used by atom */ | ||
87 | uint8_t hpd_id; | ||
86 | /* can be used with hw i2c engine */ | 88 | /* can be used with hw i2c engine */ |
87 | bool hw_capable; | 89 | bool hw_capable; |
88 | /* uses multi-media i2c engine */ | 90 | /* uses multi-media i2c engine */ |
@@ -207,7 +209,7 @@ struct radeon_mode_info { | |||
207 | struct card_info *atom_card_info; | 209 | struct card_info *atom_card_info; |
208 | enum radeon_connector_table connector_table; | 210 | enum radeon_connector_table connector_table; |
209 | bool mode_config_initialized; | 211 | bool mode_config_initialized; |
210 | struct radeon_crtc *crtcs[2]; | 212 | struct radeon_crtc *crtcs[6]; |
211 | /* DVI-I properties */ | 213 | /* DVI-I properties */ |
212 | struct drm_property *coherent_mode_property; | 214 | struct drm_property *coherent_mode_property; |
213 | /* DAC enable load detect */ | 215 | /* DAC enable load detect */ |
@@ -252,6 +254,7 @@ struct radeon_crtc { | |||
252 | fixed20_12 vsc; | 254 | fixed20_12 vsc; |
253 | fixed20_12 hsc; | 255 | fixed20_12 hsc; |
254 | struct drm_display_mode native_mode; | 256 | struct drm_display_mode native_mode; |
257 | int pll_id; | ||
255 | }; | 258 | }; |
256 | 259 | ||
257 | struct radeon_encoder_primary_dac { | 260 | struct radeon_encoder_primary_dac { |
@@ -414,6 +417,7 @@ extern void dp_link_train(struct drm_encoder *encoder, | |||
414 | struct drm_connector *connector); | 417 | struct drm_connector *connector); |
415 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); | 418 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); |
416 | extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); | 419 | extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); |
420 | extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action); | ||
417 | extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, | 421 | extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, |
418 | int action, uint8_t lane_num, | 422 | int action, uint8_t lane_num, |
419 | uint8_t lane_set); | 423 | uint8_t lane_set); |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index b4a06676fff6..5c0dc082d330 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -54,7 +54,7 @@ | |||
54 | #include "r300_reg.h" | 54 | #include "r300_reg.h" |
55 | #include "r500_reg.h" | 55 | #include "r500_reg.h" |
56 | #include "r600_reg.h" | 56 | #include "r600_reg.h" |
57 | 57 | #include "evergreen_reg.h" | |
58 | 58 | ||
59 | #define RADEON_MC_AGP_LOCATION 0x014c | 59 | #define RADEON_MC_AGP_LOCATION 0x014c |
60 | #define RADEON_MC_AGP_START_MASK 0x0000FFFF | 60 | #define RADEON_MC_AGP_START_MASK 0x0000FFFF |
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index a1367ab6f261..9506f8cb99e0 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h | |||
@@ -343,4 +343,6 @@ | |||
343 | 343 | ||
344 | #define WAIT_UNTIL 0x8040 | 344 | #define WAIT_UNTIL 0x8040 |
345 | 345 | ||
346 | #define SRBM_STATUS 0x0E50 | ||
347 | |||
346 | #endif | 348 | #endif |
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index e6f3b120f51a..403490c7b647 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h | |||
@@ -141,6 +141,41 @@ | |||
141 | {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ | 141 | {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ |
142 | {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ | 142 | {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ |
143 | {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ | 143 | {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ |
144 | {0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
145 | {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ | ||
146 | {0x1002, 0x6889, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ | ||
147 | {0x1002, 0x688A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ | ||
148 | {0x1002, 0x6898, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ | ||
149 | {0x1002, 0x6899, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ | ||
150 | {0x1002, 0x689c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HEMLOCK|RADEON_NEW_MEMMAP}, \ | ||
151 | {0x1002, 0x689d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HEMLOCK|RADEON_NEW_MEMMAP}, \ | ||
152 | {0x1002, 0x689e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ | ||
153 | {0x1002, 0x68a0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
154 | {0x1002, 0x68a1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
155 | {0x1002, 0x68a8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ | ||
156 | {0x1002, 0x68a9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ | ||
157 | {0x1002, 0x68b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
158 | {0x1002, 0x68b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ | ||
159 | {0x1002, 0x68b9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ | ||
160 | {0x1002, 0x68be, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ | ||
161 | {0x1002, 0x68c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
162 | {0x1002, 0x68c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
163 | {0x1002, 0x68c8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ | ||
164 | {0x1002, 0x68c9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ | ||
165 | {0x1002, 0x68d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ | ||
166 | {0x1002, 0x68d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ | ||
167 | {0x1002, 0x68da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ | ||
168 | {0x1002, 0x68de, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ | ||
169 | {0x1002, 0x68e0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
170 | {0x1002, 0x68e1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
171 | {0x1002, 0x68e4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
172 | {0x1002, 0x68e5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
173 | {0x1002, 0x68e8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ | ||
174 | {0x1002, 0x68e9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ | ||
175 | {0x1002, 0x68f1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ | ||
176 | {0x1002, 0x68f8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ | ||
177 | {0x1002, 0x68f9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ | ||
178 | {0x1002, 0x68fe, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ | ||
144 | {0x1002, 0x7100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ | 179 | {0x1002, 0x7100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ |
145 | {0x1002, 0x7101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 180 | {0x1002, 0x7101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
146 | {0x1002, 0x7102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 181 | {0x1002, 0x7102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |