libreboot

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 60453ff2cbd1befe24959fba1d24f734406444e3
parent 51f5487e7d2c8809bdc7690fe26948064257b34d
Author: Francis Rowe <info@gluglug.org.uk>
Date:   Fri,  6 Nov 2015 07:45:49 +0000

Update coreboot to new version (use latest stable kgpe-d16 tree)

Diffstat:
resources/libreboot/patch/kgpe-d16/0001-drivers-i2c-w83795-Add-full-support-for-fan-control-.patch | 710-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0002-southbridge-amd-sb700-Allow-use-of-auxiliary-SMBUS-c.patch | 142+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
resources/libreboot/patch/kgpe-d16/0003-drivers-i2c-w83795-Add-full-support-for-core-functio.patch | 725+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0003-drivers-i2c-w83795-Add-option-to-use-auxiliary-SMBUS.patch | 62--------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0004-drivers-aspeed-Add-native-text-mode-VGA-support-for-.patch | 3675-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0004-drivers-i2c-w83795-Add-option-to-use-auxiliary-SMBUS.patch | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0005-mainboard-Update-mainboards-using-the-w83795-sensor-.patch | 323+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0005-southbridge-amd-sb700-Fix-boot-hang-on-ASUS-KGPE-D16.patch | 642-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0006-drivers-aspeed-Add-native-text-mode-VGA-support-for-.patch | 3675+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0006-southbridge-amd-sr5650-Fix-boot-failure-on-ASUS-KGPE.patch | 621-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0007-cpu-amd-Add-initial-support-for-AMD-Socket-G34-proce.patch | 832-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0007-southbridge-amd-sb700-Fix-boot-hang-on-ASUS-KGPE-D16.patch | 619+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0008-northbridge-amd-amdmct-Fix-broken-AMD-K10-DDR3-memor.patch | 3463-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0008-southbridge-amd-sr5650-Fix-boot-failure-on-ASUS-KGPE.patch | 621+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0009-cpu-amd-Add-initial-support-for-AMD-Socket-G34-proce.patch | 832+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0009-northbridge-amd-amdmct-mct_ddr3-Fix-curly-brace-styl.patch | 95-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0010-northbridge-amd-amdfam10-Limit-maximum-RAM-clock-to-.patch | 121-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0010-northbridge-amd-amdmct-Fix-broken-AMD-K10-DDR3-memor.patch | 3454+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0011-northbridge-amd-amdfam10-Fix-typo-in-comment.patch | 27---------------------------
resources/libreboot/patch/kgpe-d16/0011-northbridge-amd-amdmct-mct_ddr3-Fix-curly-brace-styl.patch | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0012-device-hypertransport-Add-additional-debug-output.patch | 35-----------------------------------
resources/libreboot/patch/kgpe-d16/0012-northbridge-amd-amdfam10-Limit-maximum-RAM-clock-to-.patch | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0013-device-hypertransport-Add-additional-debug-output.patch | 35+++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0013-mainboard-asus-kgpe-d16-Add-initial-support-for-the-.patch | 3221-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0014-mainboard-asus-kgpe-d16-Add-initial-support-for-the-.patch | 3222+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0014-mainboard-asus-kgpe-d16-Add-nvram-option-to-enable-d.patch | 72------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0015-cpu-amd-model_10xxx-Clean-up-debugging-statements.patch | 116-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0015-mainboard-asus-kgpe-d16-Add-nvram-option-to-enable-d.patch | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0016-cpu-amd-model_10xxx-Clean-up-debugging-statements.patch | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0016-southbridge-amd-sb700-Add-Suspend-to-RAM-S3-support.patch | 367-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0017-southbridge-amd-sb700-Add-Suspend-to-RAM-S3-support.patch | 367+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0017-superio-nuvoton-nct5572d-Enable-power-state-after-po.patch | 82-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0018-northbridge-amd-amdfam10-Add-Suspend-to-RAM-S3-Flash.patch | 135-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0018-superio-nuvoton-nct5572d-Enable-power-state-after-po.patch | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0019-mainboard-asrock-e350m1-Update-CMOS-layout-to-match-.patch | 38++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0019-northbridge-amd-amdmct-mct_ddr3-Add-initial-Suspend-.patch | 1007-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0020-cpu-amd-car-Add-initial-Suspend-to-RAM-S3-support.patch | 56--------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0020-northbridge-amd-amdfam10-Add-Suspend-to-RAM-S3-Flash.patch | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0021-mainboard-asus-kgpe-d16-Add-initial-Suspend-to-RAM-S.patch | 832-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0021-northbridge-amd-amdmct-mct_ddr3-Add-initial-Suspend-.patch | 1017+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0022-cpu-amd-car-Add-initial-Suspend-to-RAM-S3-support.patch | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0022-include-smbios-Update-SMBIOS-memory-structures-to-ve.patch | 33---------------------------------
resources/libreboot/patch/kgpe-d16/0023-mainboard-asus-kgpe-d16-Add-initial-Suspend-to-RAM-S.patch | 832+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0023-northbridge-amd-amdfam10-Set-DIMM-voltage-based-on-S.patch | 198-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0024-include-smbios-Update-SMBIOS-memory-structures-to-ve.patch | 33+++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0024-mainboard-asus-kgpe-d16-Set-DDR3-memory-voltage-base.patch | 166-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0025-northbridge-amd-amdfam10-Set-DIMM-voltage-based-on-S.patch | 198+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0025-src-console-Add-x86-romstage-spinlock-option.patch | 100-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0026-mainboard-asus-kgpe-d16-Set-DDR3-memory-voltage-base.patch | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0026-northbridge-amd-amdmct-mct_ddr3-Fix-S3-suspend-overr.patch | 51---------------------------------------------------
resources/libreboot/patch/kgpe-d16/0027-northbridge-amd-amdmct-mct_ddr3-Fix-failing-S3-resum.patch | 53-----------------------------------------------------
resources/libreboot/patch/kgpe-d16/0027-src-console-Add-x86-romstage-spinlock-option-and-pri.patch | 193+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0028-northbridge-amd-amdmct-mct_ddr3-Fix-S3-suspend-overr.patch | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0028-src-console-Add-x86-printk-spinlock-support.patch | 149-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0029-lib-stack-Add-stack-overrun-detection.patch | 8++++----
resources/libreboot/patch/kgpe-d16/0030-cpu-x86-lapic-Add-stack-overrun-detection.patch | 8++++----
resources/libreboot/patch/kgpe-d16/0031-southbridge-amd-sr5650-Add-AMD-Family-15h-CPU-suppor.patch | 8++++----
resources/libreboot/patch/kgpe-d16/0032-cpu-amd-Move-model_10xxx-to-family_10h-family_15h.patch | 24+++++++++++-------------
resources/libreboot/patch/kgpe-d16/0033-cpu-amd-Add-initial-AMD-Family-15h-support.patch | 16206-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0033-cpu-amd-family_10h-family_15h-Use-correct-label-for-.patch | 28++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0034-cpu-amd-Add-initial-AMD-Family-15h-support.patch | 16249+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0034-mainboard-asus-kgpe-d16-Add-initial-Family-15h-CPU-s.patch | 565-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0035-cpu-amd-family_10h-family_15h-Add-Family-15h-microco.patch | 28----------------------------
resources/libreboot/patch/kgpe-d16/0035-mainboard-asus-kgpe-d16-Add-initial-Family-15h-CPU-s.patch | 556+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0036-amdmct-mct_ddr3-Disable-Fam10h-specific-MTRR-setup-o.patch | 38--------------------------------------
resources/libreboot/patch/kgpe-d16/0036-cpu-amd-family_10h-family_15h-Add-Family-15h-microco.patch | 28++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0037-amdmct-mct_ddr3-Disable-Fam10h-specific-MTRR-setup-o.patch | 38++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0037-cpu-amd-car-Add-romstage-BSP-stack-overrun-detection.patch | 58----------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0038-cpu-amd-car-Add-romstage-BSP-stack-overrun-detection.patch | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0038-cpu-amd-car-Increase-Family-10h-CAR-size-limit-to-12.patch | 31-------------------------------
resources/libreboot/patch/kgpe-d16/0039-cpu-amd-car-Increase-Family-10h-CAR-size-limit-to-12.patch | 31+++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0039-cpu-amd-car-Move-AP-stacks-below-the-BSP-stack-to-fr.patch | 33---------------------------------
resources/libreboot/patch/kgpe-d16/0040-cpu-amd-car-Move-AP-stacks-below-the-BSP-stack-to-fr.patch | 33+++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0040-northbridge-amd-amdmct-Read-SPD-data-into-cache-to-d.patch | 461-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0041-cpu-amd-car-Initialize-entire-CAR-space-instead-of-o.patch | 34----------------------------------
resources/libreboot/patch/kgpe-d16/0041-northbridge-amd-amdmct-Read-SPD-data-into-cache-to-d.patch | 461+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0042-amd-amdmct-mct_ddr3-Improve-SPD-DIMM-detect-reliabil.patch | 49-------------------------------------------------
resources/libreboot/patch/kgpe-d16/0042-cpu-amd-car-Initialize-entire-CAR-space-instead-of-o.patch | 34++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0043-amd-amdmct-mct_ddr3-Improve-SPD-DIMM-detect-reliabil.patch | 49+++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0043-amd-amdmct-mct_ddr3-Use-training-values-from-previou.patch | 781-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0044-amd-amdmct-mct_ddr3-Use-training-values-from-previou.patch | 781+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0044-northbridge-amd-amdfam10-Enable-CC6-DRAM-save-area-s.patch | 261-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0045-mainboard-asus-kgpe-d16-Enable-CC6.patch | 70----------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0045-northbridge-amd-amdfam10-Enable-CC6-DRAM-save-area-s.patch | 261+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0046-cpu-amd-Add-CC6-support.patch | 1307-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0046-mainboard-asus-kgpe-d16-Enable-CC6.patch | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0047-cpu-amd-Add-CC6-support.patch | 1318+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0047-northbridge-amd-amdmct-Skip-DCT-config-write-to-Flas.patch | 103-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0048-northbridge-amd-amdmct-Skip-DCT-config-write-to-Flas.patch | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0048-southbridge-amd-sb700-Add-AHCI-support.patch | 656-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0049-mainboard-asus-kgpe-d16-Properly-initialize-SB700-SA.patch | 49-------------------------------------------------
resources/libreboot/patch/kgpe-d16/0049-southbridge-amd-sb700-Add-AHCI-support.patch | 656+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0050-mainboard-asus-kgpe-d16-Properly-initialize-SB700-SA.patch | 49+++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0050-southbridge-amd-sb700-Disable-broken-SATA-MSI-functi.patch | 41-----------------------------------------
resources/libreboot/patch/kgpe-d16/0051-southbridge-amd-sb700-Disable-broken-SATA-MSI-functi.patch | 41+++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0051-southbridge-amd-sb700-Indicate-iSATA-eSATA-port-type.patch | 93-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0052-northbridge-amd-amdfam10-Add-ability-to-set-maximum-.patch | 84-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0052-southbridge-amd-sb700-Indicate-iSATA-eSATA-port-type.patch | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0053-northbridge-amd-amdfam10-Add-ability-to-set-maximum-.patch | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0053-northbridge-amd-amdmct-Verify-MCT-NVRAM-options-befo.patch | 149-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0054-northbridge-amd-amdmct-Verify-MCT-NVRAM-options-befo.patch | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0054-src-northbridge-amd-amdmct-Add-option-to-override-ba.patch | 104-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0055-mainboard-asus-kgpe-d16-Add-missing-IRQ-routing-for-.patch | 209-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0055-src-northbridge-amd-amdmct-Add-option-to-override-ba.patch | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0056-mainboard-asus-kgpe-d16-Add-missing-IRQ-routing-for-.patch | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0056-northbridge-amd-amdmct-Fix-hang-on-boot-due-to-inval.patch | 37-------------------------------------
resources/libreboot/patch/kgpe-d16/0057-northbridge-amd-amdmct-Fix-hang-on-boot-due-to-inval.patch | 37+++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0057-southbridge-amd-sr5650-Fix-GPP3a-link-training-in-hi.patch | 85-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0058-southbridge-amd-sr5650-Add-optional-delay-after-link.patch | 71-----------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0058-southbridge-amd-sr5650-Fix-GPP3a-link-training-in-hi.patch | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0059-mainboard-asus-kgpe-d16-Properly-configure-SR5690-so.patch | 32--------------------------------
resources/libreboot/patch/kgpe-d16/0059-southbridge-amd-sr5650-Add-optional-delay-after-link.patch | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0060-mainboard-asus-kgpe-d16-Properly-configure-SR5690-so.patch | 32++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0060-southbridge-amd-sb700-Add-option-to-disable-SATA-ALP.patch | 86-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0061-mainboard-asus-kgpe-d16-Set-SP5100-subtype.patch | 26--------------------------
resources/libreboot/patch/kgpe-d16/0061-southbridge-amd-sb700-Add-option-to-disable-SATA-ALP.patch | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0062-mainboard-asus-kgpe-d16-Set-SP5100-subtype.patch | 26++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0062-northbridge-amd-amdmct-Fix-crash-on-startup-due-to-N.patch | 33---------------------------------
resources/libreboot/patch/kgpe-d16/0063-northbridge-amd-amdmct-Clear-memory-before-enabling-.patch | 185-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0063-northbridge-amd-amdmct-Fix-crash-on-startup-due-to-N.patch | 33+++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0064-northbridge-amd-amdmct-Clear-memory-before-enabling-.patch | 185+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0064-southbridge-amd-sb700-Do-drive-detection-even-in-AHC.patch | 142-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0065-southbridge-amd-sb700-Do-drive-detection-even-in-AHC.patch | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0065-src-southbridge-amd-sb700-Reset-SATA-controller-in-A.patch | 96-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0066-southbridge-amd-sb700-Recover-if-AHCI-disk-detection.patch | 163-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0066-src-southbridge-amd-sb700-Reset-SATA-controller-in-A.patch | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0067-southbridge-amd-sb700-Fix-SATA-port-4-5-drive-detect.patch | 97-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0067-southbridge-amd-sb700-Recover-if-AHCI-disk-detection.patch | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0068-southbridge-amd-sb700-Fix-SATA-port-4-5-drive-detect.patch | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0068-southbridge-amd-sb700-Fix-random-persistent-SATA-AHC.patch | 165-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0069-northbridge-amd-amdmct-mct_ddr3-Fix-lockups-and-wast.patch | 407-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0069-southbridge-amd-sb700-Fix-random-persistent-SATA-AHC.patch | 165+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0070-cpu-amd-Fix-AMD-Family-15h-ECC-initialization-reliab.patch | 474-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0070-northbridge-amd-amdmct-mct_ddr3-Fix-lockups-and-wast.patch | 409+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0071-cpu-amd-Fix-AMD-Family-15h-ECC-initialization-reliab.patch | 474+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0071-northbridge-amd-amdfam10-Properly-indicate-node-and-.patch | 120-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0072-amd-amdmct-mct_ddr3-Add-Family-15h-RDIMM-timing-and-.patch | 508-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0072-northbridge-amd-amdfam10-Properly-indicate-node-and-.patch | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0073-amd-amdmct-mct_ddr3-Add-Family-15h-RDIMM-timing-and-.patch | 508+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0073-northbridge-amd-amdmct-mct_ddr3-Attempt-to-recover-f.patch | 256-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0074-northbridge-amd-amdmct-mct_ddr3-Attempt-to-recover-f.patch | 256+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0074-northbridge-amd-amdmct-mct_ddr3-Work-around-strange-.patch | 42------------------------------------------
resources/libreboot/patch/kgpe-d16/0075-northbridge-amd-amdmct-mct_ddr3-Add-additional-debug.patch | 120-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0075-northbridge-amd-amdmct-mct_ddr3-Work-around-strange-.patch | 42++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0076-northbridge-amd-amdmct-mct_ddr3-Add-additional-debug.patch | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0076-northbridge-amd-amdmct-mct_ddr3-Fix-null-pointer-acc.patch | 240-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0077-northbridge-amd-amdmct-mct_ddr3-Add-missing-Family-1.patch | 268-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0077-northbridge-amd-amdmct-mct_ddr3-Fix-null-pointer-acc.patch | 240+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0078-northbridge-amd-amdmct-mct_ddr3-Add-missing-Family-1.patch | 268+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0078-northbridge-amd-amdmct-mct_ddr3-Set-SkewMemClk-when-.patch | 114-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0079-northbridge-amd-amdmct-mct_ddr3-Properly-indicate-cl.patch | 58----------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0079-northbridge-amd-amdmct-mct_ddr3-Set-SkewMemClk-when-.patch | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0080-northbridge-amd-amdmct-mct_ddr3-Fix-Family-10h-boot-.patch | 100-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0080-northbridge-amd-amdmct-mct_ddr3-Properly-indicate-cl.patch | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0081-northbridge-amd-amdmct-mct_ddr3-Fix-Family-10h-boot-.patch | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0081-src-southbridge-amd-sr5650-Always-configure-lane-dir.patch | 51---------------------------------------------------
resources/libreboot/patch/kgpe-d16/0082-cpu-amd-family_10h-family_15h-Fix-BSP-stack-corrupti.patch | 28----------------------------
resources/libreboot/patch/kgpe-d16/0082-src-southbridge-amd-sr5650-Always-configure-lane-dir.patch | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0083-cpu-amd-family_10h-family_15h-Fix-BSP-stack-corrupti.patch | 40++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0083-northbridge-amd-amdmct-mct_ddr3-Fix-RDIMM-errors-due.patch | 330-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0084-amd-amdmct-mct_ddr3-Partially-fix-up-registered-DIMM.patch | 960-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0084-northbridge-amd-amdmct-mct_ddr3-Fix-RDIMM-errors-due.patch | 304+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0085-amd-amdmct-mct_ddr3-Partially-fix-up-registered-DIMM.patch | 960+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0085-northbridge-amd-amdmct-Fix-Family-15h-detection.patch | 49-------------------------------------------------
resources/libreboot/patch/kgpe-d16/0086-northbridge-amd-amdmct-Fix-Family-15h-detection.patch | 49+++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0086-northbridge-amd-amdmct-mct_ddr3-Add-registered-and-x.patch | 1887-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0087-cpu-amd-family_10h-family_15h-Fix-Family-15h-multipl.patch | 1931-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0087-northbridge-amd-amdmct-Reduce-maximum-number-of-DDR3.patch | 41+++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0088-northbridge-amd-amdfam10-Add-probe-filter-support.patch | 214-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0088-northbridge-amd-amdmct-mct_ddr3-Add-registered-and-x.patch | 1887+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0089-cpu-amd-family_10h-family_15h-Bring-initial-HT-regis.patch | 248-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0089-cpu-amd-family_10h-family_15h-Fix-Family-15h-multipl.patch | 1244+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0090-northbridge-amd-amdfam10-Add-probe-filter-support.patch | 282+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0090-northbridge-amd-amdmct-mct_ddr3-Move-K10D-configurat.patch | 338-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0091-cpu-amd-family_10h-family_15h-Bring-initial-HT-regis.patch | 248+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0091-mainboard-asus-kgpe-d16-Fix-I-O-link-detection.patch | 28----------------------------
resources/libreboot/patch/kgpe-d16/0092-cpu-amd-family_10h-family_15h-Set-northbridge-thrott.patch | 139-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0092-northbridge-amd-amdmct-mct_ddr3-Move-K10D-configurat.patch | 336+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0093-cpu-amd-family_10h-family_15h-Fix-incorrect-revision.patch | 64----------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0093-mainboard-asus-kgpe-d16-Fix-I-O-link-detection.patch | 28++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0094-cpu-amd-family_10h-family_15h-Set-northbridge-thrott.patch | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0094-northbridge-amd-amdht-Add-support-for-HT3-2.8GHz-and.patch | 561-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0095-amd-family_10h-family_15h-Fix-poor-performance-on-Fa.patch | 124-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0095-cpu-amd-family_10h-family_15h-Fix-incorrect-revision.patch | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0096-amd-amdmct-mct_ddr3-Fix-poor-performance-on-Family-1.patch | 1089-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0096-northbridge-amd-amdht-Add-support-for-HT3-2.8GHz-and.patch | 532+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0097-amd-family_10h-family_15h-Fix-poor-performance-on-Fa.patch | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0097-northbridge-amd-amdht-Fix-poor-performance-on-Family.patch | 30------------------------------
resources/libreboot/patch/kgpe-d16/0098-amd-amdmct-mct_ddr3-Fix-poor-performance-on-Family-1.patch | 1089+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0098-northbridge-amd-amdfam10-Fix-poor-performance-on-Fam.patch | 72------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0099-cpu-amd-family_10h-family_15h-Configure-NB-register-.patch | 34----------------------------------
resources/libreboot/patch/kgpe-d16/0099-northbridge-amd-amdht-Fix-poor-performance-on-Family.patch | 30++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0100-cpu-amd-family_10h-family_15h-Set-up-link-XCS-token-.patch | 344-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0100-northbridge-amd-amdfam10-Fix-poor-performance-on-Fam.patch | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0101-cpu-amd-family_10h-family_15h-Configure-NB-register-.patch | 34++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0101-northbridge-amd-amdmct-mct_ddr3-Force-retraining-on-.patch | 36------------------------------------
resources/libreboot/patch/kgpe-d16/0102-cpu-amd-family_10h-family_15h-Set-up-link-XCS-token-.patch | 344+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0102-northbridge-amd-amdfam10-Fix-invalid-NUMA-table.patch | 28----------------------------
resources/libreboot/patch/kgpe-d16/0103-northbridge-amd-amdfam10-Add-Family-15h-cache-partit.patch | 123-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0103-northbridge-amd-amdmct-mct_ddr3-Force-retraining-on-.patch | 36++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0104-amd-amdmct-mct_ddr3-Set-prefetch-double-stride-to-im.patch | 27---------------------------
resources/libreboot/patch/kgpe-d16/0104-northbridge-amd-amdfam10-Fix-invalid-NUMA-table.patch | 28++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0105-cpu-amd-family_10h-family_15h-Set-up-Family-15h-Link.patch | 192-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0105-northbridge-amd-amdfam10-Add-Family-15h-cache-partit.patch | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0106-amd-amdmct-mct_ddr3-Set-prefetch-double-stride-to-im.patch | 27+++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0106-cpu-amd-family_10h-family_15h-Set-up-cache-controls-.patch | 43-------------------------------------------
resources/libreboot/patch/kgpe-d16/0107-cpu-amd-family_10h-family_15h-Set-up-Family-15h-Link.patch | 192+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0107-cpu-amd-family_10h-family_15h-Set-up-SRI-to-XCS-Toke.patch | 66------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0108-amd-amdfam10-Control-Family-15h-cache-partitioning-a.patch | 177-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0108-cpu-amd-family_10h-family_15h-Set-up-cache-controls-.patch | 43+++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0109-cpu-amd-family_10h-family_15h-Set-up-SRI-to-XCS-Toke.patch | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0109-northbridge-amd-amdht-Add-isochronous-setup-support-.patch | 272-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0110-amd-amdfam10-Control-Family-15h-cache-partitioning-a.patch | 190+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0110-arch-x86-acpi-Add-IVRS-table-generation-routines.patch | 121-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0111-northbridge-amd-amdht-Add-isochronous-setup-support-.patch | 279+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0111-southbridge-amd-sr5650-Add-IOMMU-support.patch | 711-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0112-arch-x86-acpi-Add-IVRS-table-generation-routines.patch | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0112-southbridge-amd-sr5650-Hide-clock-configuration-devi.patch | 57---------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0113-northbridge-amd-amdfam10-Rename-mislabeled-iommu-nvr.patch | 55-------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0113-southbridge-amd-sr5650-Add-IOMMU-support.patch | 804+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0114-northbridge-amd-amdfam10-Fix-gart-setup-not-working-.patch | 96-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0114-southbridge-amd-sr5650-Hide-clock-configuration-devi.patch | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0115-mainboard-asus-kgpe-d16-Add-several-nvram-configurat.patch | 129-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0115-northbridge-amd-amdfam10-Rename-mislabeled-iommu-nvr.patch | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0116-northbridge-amd-amdfam10-Fix-gart-setup-not-working-.patch | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0116-southbridge-amd-sr5650-Use-correct-PCI-configuration.patch | 30------------------------------
resources/libreboot/patch/kgpe-d16/0117-mainboard-asus-kgpe-d16-Add-several-nvram-configurat.patch | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0117-southbridge-amd-sr5650-Add-MCFG-ACPI-table-support.patch | 119-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0118-southbridge-amd-sb700-Fix-mismatched-FADT-entries.patch | 36------------------------------------
resources/libreboot/patch/kgpe-d16/0118-southbridge-amd-sr5650-Use-correct-PCI-configuration.patch | 30++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0119-southbridge-amd-sb700-Fix-drifting-system-clock.patch | 47-----------------------------------------------
resources/libreboot/patch/kgpe-d16/0119-southbridge-amd-sr5650-Add-MCFG-ACPI-table-support.patch | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0120-northbridge-amd-amdmct-mct_ddr3-Add-cc6-setup-inform.patch | 58----------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0120-southbridge-amd-sb700-Fix-mismatched-FADT-entries.patch | 36++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0121-northbridge-amd-amdfam10-Work-around-sporadic-lockup.patch | 40----------------------------------------
resources/libreboot/patch/kgpe-d16/0121-southbridge-amd-sb700-Fix-drifting-system-clock.patch | 47+++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0122-northbridge-amd-amdmct-mct_ddr3-Add-cc6-setup-inform.patch | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0122-northbridge-amd-amdmct-mct_ddr3-Ensure-channel-clock.patch | 115-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0123-northbridge-amd-amdfam10-Work-around-sporadic-lockup.patch | 40++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0123-northbridge-amd-amdmct-mct_ddr3-Add-DDR3-termination.patch | 36------------------------------------
resources/libreboot/patch/kgpe-d16/0124-northbridge-amd-amdmct-mct_ddr3-Ensure-channel-clock.patch | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0124-northbridge-amd-amdmct-mct_ddr3-Fix-a-minor-RDIMM-CS.patch | 37-------------------------------------
resources/libreboot/patch/kgpe-d16/0125-northbridge-amd-amdmct-mct_ddr3-Add-DDR3-termination.patch | 36++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0125-northbridge-amd-amdmct-mct_ddr3-Fix-odd-rank-data-co.patch | 65-----------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0126-northbridge-amd-amdmct-mct_ddr3-Fix-a-minor-RDIMM-CS.patch | 37+++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0126-northbridge-amd-amdmct-mct_ddr3-Use-antiphase-to-bet.patch | 157-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0127-northbridge-amd-amdmct-mct_ddr3-Fix-broken-support-f.patch | 602-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0127-northbridge-amd-amdmct-mct_ddr3-Fix-odd-rank-data-co.patch | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0128-drivers-pc80-Add-optional-spinlock-for-nvram-CBFS-ac.patch | 175-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0128-northbridge-amd-amdmct-mct_ddr3-Use-antiphase-to-bet.patch | 157+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0129-mainboard-asus-kgpe-d16-Enable-CBFS-spinlocks.patch | 68--------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0129-northbridge-amd-amdmct-mct_ddr3-Fix-broken-support-f.patch | 602+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0130-cpu-amd-microcode-Introduce-CBFS-access-spinlock-to-.patch | 155-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0130-drivers-pc80-Add-optional-spinlock-for-nvram-CBFS-ac.patch | 175+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0131-mainboard-asus-kgpe-d16-Enable-CBFS-spinlocks.patch | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0131-mainboard-asus-kgpe-d16-Limit-HT-speed-to-2.6GHz.patch | 41-----------------------------------------
resources/libreboot/patch/kgpe-d16/0132-cpu-amd-family_10h-family_15h-Apply-missing-Family-1.patch | 70----------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0132-cpu-amd-microcode-Introduce-CBFS-access-spinlock-to-.patch | 155+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0133-mainboard-asus-kgpe-d16-Limit-HT-speed-to-2.6GHz.patch | 41+++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0133-northbridge-amd-amdmct-mct_ddr3-Use-StopOnError-to-d.patch | 231-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0134-cpu-amd-family_10h-family_15h-Apply-missing-Family-1.patch | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0134-mainboard-asus-kgpe-d16-Enable-GART-by-default.patch | 27---------------------------
resources/libreboot/patch/kgpe-d16/0135-northbridge-amd-amdfam10-Fix-incorrect-channel-buffe.patch | 42------------------------------------------
resources/libreboot/patch/kgpe-d16/0135-northbridge-amd-amdmct-mct_ddr3-Use-StopOnError-to-d.patch | 231+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0136-cpu-amd-family_10h-family_15h-Force-iolink-detect-to.patch | 37-------------------------------------
resources/libreboot/patch/kgpe-d16/0136-mainboard-asus-kgpe-d16-Enable-GART-by-default.patch | 27+++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0137-northbridge-amd-amdfam10-Fix-incorrect-channel-buffe.patch | 42++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0137-northbridge-amd-amdht-Fix-XCS-buffer-count-setup-on-.patch | 144-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0138-cpu-amd-family_10h-family_15h-Fix-link-type-detectio.patch | 158-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0138-cpu-amd-family_10h-family_15h-Force-iolink-detect-to.patch | 37+++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0139-cpu-amd-family_10h-family_15h-Enable-DFE-on-Family-1.patch | 32--------------------------------
resources/libreboot/patch/kgpe-d16/0139-northbridge-amd-amdht-Fix-XCS-buffer-count-setup-on-.patch | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0140-cpu-amd-family_10h-family_15h-Fix-link-type-detectio.patch | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0141-cpu-amd-family_10h-family_15h-Enable-DFE-on-Family-1.patch | 32++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0142-cpu-amd-family_10h-family_15h-Fix-build-when-microco.patch | 28++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0143-device-smbus-Avoid-infinite-loop-if-i2c-device-has-w.patch | 39+++++++++++++++++++++++++++++++++++++++
resources/scripts/helpers/download/coreboot | 2+-
resources/utilities/coreboot-libre/nonblobs | 7+++++++
278 files changed, 55312 insertions(+), 55515 deletions(-)

diff --git a/resources/libreboot/patch/kgpe-d16/0001-drivers-i2c-w83795-Add-full-support-for-fan-control-.patch b/resources/libreboot/patch/kgpe-d16/0001-drivers-i2c-w83795-Add-full-support-for-fan-control-.patch @@ -1,710 +0,0 @@ -From f7b8be27ea159845a982c310799a5896865016cd Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <tpearson@raptorengineeringinc.com> -Date: Sat, 5 Sep 2015 17:53:20 -0500 -Subject: [PATCH 001/139] drivers/i2c/w83795: Add full support for fan control, - fan monitoring, and voltage monitoring - -Change-Id: I3e246af0e398d65ee43ea708060885c67fd7d202 -Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> ---- - src/drivers/i2c/w83795/chip.h | 142 +++++++++++++++++ - src/drivers/i2c/w83795/w83795.c | 334 ++++++++++++++++++++++++++-------------- - src/drivers/i2c/w83795/w83795.h | 52 +++++-- - 3 files changed, 399 insertions(+), 129 deletions(-) - create mode 100644 src/drivers/i2c/w83795/chip.h - -diff --git a/src/drivers/i2c/w83795/chip.h b/src/drivers/i2c/w83795/chip.h -new file mode 100644 -index 0000000..effe119 ---- /dev/null -+++ b/src/drivers/i2c/w83795/chip.h -@@ -0,0 +1,142 @@ -+/* -+ * This file is part of the coreboot project. -+ * -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc. -+ */ -+ -+struct drivers_i2c_w83795_config { -+ uint8_t fanin_ctl1; -+ uint8_t fanin_ctl2; -+ -+ uint8_t temp_ctl1; -+ uint8_t temp_ctl2; -+ uint8_t temp_dtse; -+ -+ uint8_t volt_ctl1; -+ uint8_t volt_ctl2; -+ -+ uint8_t temp1_fan_select; -+ uint8_t temp2_fan_select; -+ uint8_t temp3_fan_select; -+ uint8_t temp4_fan_select; -+ uint8_t temp5_fan_select; -+ uint8_t temp6_fan_select; -+ -+ uint8_t temp1_source_select; -+ uint8_t temp2_source_select; -+ uint8_t temp3_source_select; -+ uint8_t temp4_source_select; -+ uint8_t temp5_source_select; -+ uint8_t temp6_source_select; -+ -+ uint32_t vcore1_high_limit_mv; /* mV */ -+ uint32_t vcore1_low_limit_mv; /* mV */ -+ uint32_t vcore2_high_limit_mv; /* mV */ -+ uint32_t vcore2_low_limit_mv; /* mV */ -+ uint32_t vtt_high_limit_mv; /* mV */ -+ uint32_t vtt_low_limit_mv; /* mV */ -+ uint32_t vsen3_high_limit_mv; /* mV */ -+ uint32_t vsen3_low_limit_mv; /* mV */ -+ uint32_t vsen4_high_limit_mv; /* mV */ -+ uint32_t vsen4_low_limit_mv; /* mV */ -+ uint32_t vsen5_high_limit_mv; /* mV */ -+ uint32_t vsen5_low_limit_mv; /* mV */ -+ uint32_t vsen6_high_limit_mv; /* mV */ -+ uint32_t vsen6_low_limit_mv; /* mV */ -+ uint32_t vsen7_high_limit_mv; /* mV */ -+ uint32_t vsen7_low_limit_mv; /* mV */ -+ uint32_t vsen8_high_limit_mv; /* mV */ -+ uint32_t vsen8_low_limit_mv; /* mV */ -+ uint32_t vsen9_high_limit_mv; /* mV */ -+ uint32_t vsen9_low_limit_mv; /* mV */ -+ uint32_t vsen10_high_limit_mv; /* mV */ -+ uint32_t vsen10_low_limit_mv; /* mV */ -+ uint32_t vsen11_high_limit_mv; /* mV */ -+ uint32_t vsen11_low_limit_mv; /* mV */ -+ uint32_t vsen12_high_limit_mv; /* mV */ -+ uint32_t vsen12_low_limit_mv; /* mV */ -+ uint32_t vsen13_high_limit_mv; /* mV */ -+ uint32_t vsen13_low_limit_mv; /* mV */ -+ uint32_t vdd_high_limit_mv; /* mV */ -+ uint32_t vdd_low_limit_mv; /* mV */ -+ uint32_t vsb_high_limit_mv; /* mV */ -+ uint32_t vsb_low_limit_mv; /* mV */ -+ uint32_t vbat_high_limit_mv; /* mV */ -+ uint32_t vbat_low_limit_mv; /* mV */ -+ -+ int8_t tr1_critical_temperature; /* °C */ -+ int8_t tr1_critical_hysteresis; /* °C */ -+ int8_t tr1_warning_temperature; /* °C */ -+ int8_t tr1_warning_hysteresis; /* °C */ -+ int8_t tr2_critical_temperature; /* °C */ -+ int8_t tr2_critical_hysteresis; /* °C */ -+ int8_t tr2_warning_temperature; /* °C */ -+ int8_t tr2_warning_hysteresis; /* °C */ -+ int8_t tr3_critical_temperature; /* °C */ -+ int8_t tr3_critical_hysteresis; /* °C */ -+ int8_t tr3_warning_temperature; /* °C */ -+ int8_t tr3_warning_hysteresis; /* °C */ -+ int8_t tr4_critical_temperature; /* °C */ -+ int8_t tr4_critical_hysteresis; /* °C */ -+ int8_t tr4_warning_temperature; /* °C */ -+ int8_t tr4_warning_hysteresis; /* °C */ -+ int8_t tr5_critical_temperature; /* °C */ -+ int8_t tr5_critical_hysteresis; /* °C */ -+ int8_t tr5_warning_temperature; /* °C */ -+ int8_t tr5_warning_hysteresis; /* °C */ -+ int8_t tr6_critical_temperature; /* °C */ -+ int8_t tr6_critical_hysteresis; /* °C */ -+ int8_t tr6_warning_temperature; /* °C */ -+ int8_t tr6_warning_hysteresis; /* °C */ -+ int8_t dts_critical_temperature; /* °C */ -+ int8_t dts_critical_hysteresis; /* °C */ -+ int8_t dts_warning_temperature; /* °C */ -+ int8_t dts_warning_hysteresis; /* °C */ -+ -+ int8_t temp1_critical_temperature; /* °C */ -+ int8_t temp2_critical_temperature; /* °C */ -+ int8_t temp3_critical_temperature; /* °C */ -+ int8_t temp4_critical_temperature; /* °C */ -+ int8_t temp5_critical_temperature; /* °C */ -+ int8_t temp6_critical_temperature; /* °C */ -+ -+ int8_t temp1_target_temperature; /* °C */ -+ int8_t temp2_target_temperature; /* °C */ -+ int8_t temp3_target_temperature; /* °C */ -+ int8_t temp4_target_temperature; /* °C */ -+ int8_t temp5_target_temperature; /* °C */ -+ int8_t temp6_target_temperature; /* °C */ -+ -+ uint8_t fan1_nonstop; /* % of full speed (0-100) */ -+ uint8_t fan2_nonstop; /* % of full speed (0-100) */ -+ uint8_t fan3_nonstop; /* % of full speed (0-100) */ -+ uint8_t fan4_nonstop; /* % of full speed (0-100) */ -+ uint8_t fan5_nonstop; /* % of full speed (0-100) */ -+ uint8_t fan6_nonstop; /* % of full speed (0-100) */ -+ uint8_t fan7_nonstop; /* % of full speed (0-100) */ -+ uint8_t fan8_nonstop; /* % of full speed (0-100) */ -+ -+ uint8_t default_speed; /* % of full speed (0-100) */ -+ -+ uint8_t fan1_duty; /* % of full speed (0-100) */ -+ uint8_t fan2_duty; /* % of full speed (0-100) */ -+ uint8_t fan3_duty; /* % of full speed (0-100) */ -+ uint8_t fan4_duty; /* % of full speed (0-100) */ -+ uint8_t fan5_duty; /* % of full speed (0-100) */ -+ uint8_t fan6_duty; /* % of full speed (0-100) */ -+ uint8_t fan7_duty; /* % of full speed (0-100) */ -+ uint8_t fan8_duty; /* % of full speed (0-100) */ -+}; -diff --git a/src/drivers/i2c/w83795/w83795.c b/src/drivers/i2c/w83795/w83795.c -index 2bbe0be..cf0cf2f 100644 ---- a/src/drivers/i2c/w83795/w83795.c -+++ b/src/drivers/i2c/w83795/w83795.c -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -21,106 +22,68 @@ - #include <arch/cpu.h> - #include <console/console.h> - #include <device/device.h> --#include "southbridge/amd/cimx/sb700/smbus.h" /*SMBUS_IO_BASE*/ - #include "w83795.h" -+#include <device/smbus.h> -+#include "chip.h" - --static int w83795_set_bank(u8 bank) -+static int w83795_set_bank(struct device *dev, uint8_t bank) - { -- return do_smbus_write_byte(SMBUS_IO_BASE, W83795_DEV, W83795_REG_BANKSEL, bank); -+ return smbus_write_byte(dev, W83795_REG_BANKSEL, bank); - } - --static u8 w83795_read(u16 reg) -+static uint8_t w83795_read(struct device *dev, uint16_t reg) - { - int ret; - -- ret = w83795_set_bank(reg >> 8); -+ ret = w83795_set_bank(dev, reg >> 8); - if (ret < 0) { -- printk(BIOS_DEBUG, "read faild to set bank %x\n", reg >> 8); -+ printk(BIOS_DEBUG, "read failed to set bank %x\n", reg >> 8); - return -1; - } - -- ret = do_smbus_read_byte(SMBUS_IO_BASE, W83795_DEV, reg & 0xff); -+ ret = smbus_read_byte(dev, reg & 0xff); - return ret; - } - --static u8 w83795_write(u16 reg, u8 value) -+static uint8_t w83795_write(struct device *dev, uint16_t reg, uint8_t value) - { - int err; - -- err = w83795_set_bank(reg >> 8); -+ err = w83795_set_bank(dev, reg >> 8); - if (err < 0) { -- printk(BIOS_DEBUG, "write faild to set bank %x\n", reg >> 8); -+ printk(BIOS_DEBUG, "write failed to set bank %x\n", reg >> 8); - return -1; - } - -- err = do_smbus_write_byte(SMBUS_IO_BASE, W83795_DEV, reg & 0xff, value); -+ err = smbus_write_byte(dev, reg & 0xff, value); - return err; - } - - /* -- * Enable Digital Temperature Sensor -+ * Configure Digital Temperature Sensor - */ --static void w83795_dts_enable(u8 dts_src) -+static void w83795_dts_configure(struct device *dev, uint8_t dts_src) - { - u8 val; - - /* DIS */ -- val = w83795_read(W83795_REG_DTSC); -+ val = w83795_read(dev, W83795_REG_DTSC); - val |= (dts_src & 0x01); -- w83795_write(W83795_REG_DTSC, val); -- -- /* DTSE */ -- val = w83795_read(W83795_REG_DTSE); -- val |= 0xFF; -- w83795_write(W83795_REG_DTSE, val); -- -- /* store bank3 regs first before enable DTS */ -- -- /* -- * TD/TR1-4 thermal diode by default -- * 0x00 Disable -- * 0x01 thermistors on motherboard -- * 0x10 different mode voltage -- * 0x11 CPU internal thermal diode output -- * -- * TR5-6 thermistors by default TRn -- */ -- val = 0x55; /* thermal diode */ -- w83795_write(W83795_REG_TEMP_CTRL2, val); -- -- /* Enable Digital Temperature Sensor */ -- val = w83795_read(W83795_REG_TEMP_CTRL1); -- val |= W83795_REG_TEMP_CTRL1_EN_DTS; /* EN_DTS */ -- w83795_write(W83795_REG_TEMP_CTRL1, val); -+ w83795_write(dev, W83795_REG_DTSC, val); - } - --static void w83795_set_tfmr(w83795_fan_mode_t mode) --{ -- u8 val; -- u8 i; -- -- if ((mode == SMART_FAN_MODE) || (mode == THERMAL_CRUISE_MODE)) { -- val = 0xFF; -- } else { -- val = 0x00; -- } -- -- for (i = 0; i < 6; i++) -- w83795_write(W83795_REG_TFMR(i), val); --} -- --static u32 w83795_set_fan_mode(w83795_fan_mode_t mode) -+static u32 w83795_set_fan_mode(struct device *dev, w83795_fan_mode_t mode) - { - if (mode == SPEED_CRUISE_MODE) { -- w83795_write(W83795_REG_FCMS1, 0xFF); -+ w83795_write(dev, W83795_REG_FCMS1, 0xFF); - printk(BIOS_INFO, "W83795G/ADG work in Speed Cruise Mode\n"); - } else { -- w83795_write(W83795_REG_FCMS1, 0x00); -+ w83795_write(dev, W83795_REG_FCMS1, 0x00); - if (mode == THERMAL_CRUISE_MODE) { -- w83795_write(W83795_REG_FCMS2, 0x00); -+ w83795_write(dev, W83795_REG_FCMS2, 0x00); - printk(BIOS_INFO, "W83795G/ADG work in Thermal Cruise Mode\n"); - } else if (mode == SMART_FAN_MODE) { -- w83795_write(W83795_REG_FCMS2, 0x3F); -+ w83795_write(dev, W83795_REG_FCMS2, 0x3F); - printk(BIOS_INFO, "W83795G/ADG work in Smart Fan Mode\n"); - } else { - printk(BIOS_INFO, "W83795G/ADG work in Manual Mode\n"); -@@ -131,40 +94,12 @@ static u32 w83795_set_fan_mode(w83795_fan_mode_t mode) - return 0; - } - --static void w83795_set_tss(void) --{ -- u8 val; -- -- val = 0x00; -- w83795_write(W83795_REG_TSS(0), val); /* Temp1, 2 */ -- w83795_write(W83795_REG_TSS(1), val); /* Temp3, 4 */ -- w83795_write(W83795_REG_TSS(2), val); /* Temp5, 6 */ --} -- --static void w83795_set_fan(w83795_fan_mode_t mode) -+static void w83795_set_fan(struct device *dev, w83795_fan_mode_t mode) - { -- u8 i; -- -- /* select temperature sensor (TSS)*/ -- w83795_set_tss(); -- -- /* select Temperature to Fan mapping Relationships (TFMR)*/ -- w83795_set_tfmr(mode); -- - /* set fan output controlled mode (FCMS)*/ -- w83795_set_fan_mode(mode); -+ w83795_set_fan_mode(dev, mode); - -- /* Set Critical Temperature to Full Speed all fan (CTFS) */ -- for (i = 0; i < 6; i++) { -- w83795_write(W83795_REG_CTFS(i), 0x50); /* default 80 celsius degree */ -- } -- -- if (mode == THERMAL_CRUISE_MODE) { -- /* Set Target Temperature of Temperature Inputs (TTTI) */ -- for (i = 0; i < 6; i++) { -- w83795_write(W83795_REG_TTTI(i), 0x28); /* default 40 celsius degree */ -- } -- } else if (mode == SMART_FAN_MODE) { -+ if (mode == SMART_FAN_MODE) { - /* Set the Relative Register-at SMART FAN IV Control Mode Table */ - //SFIV TODO - } -@@ -173,16 +108,44 @@ static void w83795_set_fan(w83795_fan_mode_t mode) - //TODO - } - --static void w83795_init(w83795_fan_mode_t mode, u8 dts_src) -+static uint8_t fan_pct_to_cfg_val(uint8_t percent) - { -- u8 i; -- u8 val; -+ uint16_t cfg = (((unsigned int)percent * 10000) / 3922); -+ if (cfg > 0xff) -+ cfg = 0xff; -+ return cfg; -+} -+ -+static uint8_t millivolts_to_limit_value_type1(int millivolts) -+{ -+ /* Datasheet v1.41 page 44 (VSEN1 - VSEN13, VTT) */ -+ return ((millivolts / 2) >> 2); -+} - -- if (do_smbus_read_byte(SMBUS_IO_BASE, W83795_DEV, 0x00) < 0) { -+static uint8_t millivolts_to_limit_value_type2(int millivolts) -+{ -+ /* Datasheet v1.41 page 44 (3VSB, 3VDD, VBAT) */ -+ return ((millivolts / 6) >> 2); -+} -+ -+static uint16_t millivolts_to_limit_value_type3(int millivolts) -+{ -+ /* Datasheet v1.41 page 44 (VDSEN14 - VDSEN17) */ -+ return (millivolts / 2); -+} -+ -+static void w83795_init(struct device *dev, w83795_fan_mode_t mode, u8 dts_src) -+{ -+ struct drivers_i2c_w83795_config *config = dev->chip_info; -+ uint8_t i; -+ uint8_t val; -+ uint16_t limit_value; -+ -+ if (smbus_read_byte(dev, 0x00) < 0) { - printk(BIOS_ERR, "W83795G/ADG Nuvoton H/W Monitor not found\n"); - return; - } -- val = w83795_read(W83795_REG_CONFIG); -+ val = w83795_read(dev, W83795_REG_CONFIG); - if ((val & W83795_REG_CONFIG_CONFIG48) == 0) - printk(BIOS_INFO, "Found 64 pin W83795G Nuvoton H/W Monitor\n"); - else if ((val & W83795_REG_CONFIG_CONFIG48) == 1) -@@ -190,35 +153,178 @@ static void w83795_init(w83795_fan_mode_t mode, u8 dts_src) - - /* Reset */ - val |= W83795_REG_CONFIG_INIT; -- w83795_write(W83795_REG_CONFIG, val); -+ w83795_write(dev, W83795_REG_CONFIG, val); -+ -+ /* Fan monitor settings */ -+ w83795_write(dev, W83795_REG_FANIN_CTRL1, config->fanin_ctl1); -+ w83795_write(dev, W83795_REG_FANIN_CTRL2, config->fanin_ctl2); -+ -+ /* Temperature thresholds */ -+ w83795_write(dev, W83795_REG_TEMP_CRIT(0), config->tr1_critical_temperature); -+ w83795_write(dev, W83795_REG_TEMP_CRIT_HYSTER(0), config->tr1_critical_hysteresis); -+ w83795_write(dev, W83795_REG_TEMP_WARN(0), config->tr1_warning_temperature); -+ w83795_write(dev, W83795_REG_TEMP_WARN_HYSTER(0), config->tr1_warning_hysteresis); -+ w83795_write(dev, W83795_REG_TEMP_CRIT(1), config->tr2_critical_temperature); -+ w83795_write(dev, W83795_REG_TEMP_CRIT_HYSTER(1), config->tr2_critical_hysteresis); -+ w83795_write(dev, W83795_REG_TEMP_WARN(1), config->tr2_warning_temperature); -+ w83795_write(dev, W83795_REG_TEMP_WARN_HYSTER(1), config->tr2_warning_hysteresis); -+ w83795_write(dev, W83795_REG_TEMP_CRIT(2), config->tr3_critical_temperature); -+ w83795_write(dev, W83795_REG_TEMP_CRIT_HYSTER(2), config->tr3_critical_hysteresis); -+ w83795_write(dev, W83795_REG_TEMP_WARN(2), config->tr3_warning_temperature); -+ w83795_write(dev, W83795_REG_TEMP_WARN_HYSTER(2), config->tr3_warning_hysteresis); -+ w83795_write(dev, W83795_REG_TEMP_CRIT(3), config->tr4_critical_temperature); -+ w83795_write(dev, W83795_REG_TEMP_CRIT_HYSTER(3), config->tr4_critical_hysteresis); -+ w83795_write(dev, W83795_REG_TEMP_WARN(3), config->tr4_warning_temperature); -+ w83795_write(dev, W83795_REG_TEMP_WARN_HYSTER(3), config->tr4_warning_hysteresis); -+ w83795_write(dev, W83795_REG_TEMP_CRIT(4), config->tr5_critical_temperature); -+ w83795_write(dev, W83795_REG_TEMP_CRIT_HYSTER(4), config->tr5_critical_hysteresis); -+ w83795_write(dev, W83795_REG_TEMP_WARN(4), config->tr5_warning_temperature); -+ w83795_write(dev, W83795_REG_TEMP_WARN_HYSTER(4), config->tr5_warning_hysteresis); -+ w83795_write(dev, W83795_REG_TEMP_CRIT(5), config->tr6_critical_temperature); -+ w83795_write(dev, W83795_REG_TEMP_CRIT_HYSTER(5), config->tr6_critical_hysteresis); -+ w83795_write(dev, W83795_REG_TEMP_WARN(5), config->tr6_warning_temperature); -+ w83795_write(dev, W83795_REG_TEMP_WARN_HYSTER(5), config->tr6_warning_hysteresis); -+ -+ /* DTS enable */ -+ w83795_write(dev, W83795_REG_DTSE, config->temp_dtse); -+ -+ /* DTS temperature thresholds */ -+ w83795_write(dev, W83795_REG_DTS_CRIT, config->dts_critical_temperature); -+ w83795_write(dev, W83795_REG_DTS_CRIT_HYSTER, config->dts_critical_hysteresis); -+ w83795_write(dev, W83795_REG_DTS_WARN, config->dts_warning_temperature); -+ w83795_write(dev, W83795_REG_DTS_WARN_HYSTER, config->dts_warning_hysteresis); -+ -+ /* Configure DTS registers in bank3 before enabling DTS */ -+ w83795_dts_configure(dev, dts_src); -+ -+ /* Temperature monitor settings */ -+ w83795_write(dev, W83795_REG_TEMP_CTRL1, config->temp_ctl1); -+ w83795_write(dev, W83795_REG_TEMP_CTRL2, config->temp_ctl2); -+ -+ /* Temperature to fan mappings */ -+ w83795_write(dev, W83795_REG_TFMR(0), config->temp1_fan_select); -+ w83795_write(dev, W83795_REG_TFMR(1), config->temp2_fan_select); -+ w83795_write(dev, W83795_REG_TFMR(2), config->temp3_fan_select); -+ w83795_write(dev, W83795_REG_TFMR(3), config->temp4_fan_select); -+ w83795_write(dev, W83795_REG_TFMR(4), config->temp5_fan_select); -+ w83795_write(dev, W83795_REG_TFMR(5), config->temp6_fan_select); -+ -+ /* Temperature data source to temperature mappings */ -+ w83795_write(dev, W83795_REG_T12TSS, ((config->temp2_source_select & 0xff) << 8) | (config->temp1_source_select & 0xff)); -+ w83795_write(dev, W83795_REG_T34TSS, ((config->temp4_source_select & 0xff) << 8) | (config->temp3_source_select & 0xff)); -+ w83795_write(dev, W83795_REG_T56TSS, ((config->temp6_source_select & 0xff) << 8) | (config->temp5_source_select & 0xff)); - -- /* Fan monitoring setting */ -- val = 0xFF; /* FAN1-FAN8 */ -- w83795_write(W83795_REG_FANIN_CTRL1, val); -- val = 0x3F; /* FAN9-FAN14 */ -- w83795_write(W83795_REG_FANIN_CTRL2, val); -- -- /* enable monitoring operations */ -- val = w83795_read(W83795_REG_CONFIG); -- val |= W83795_REG_CONFIG_START; -- w83795_write(W83795_REG_CONFIG, val); -- -- w83795_dts_enable(dts_src); -- w83795_set_fan(mode); -+ /* Set Critical Temperature to Full Speed all fan (CTFS) */ -+ w83795_write(dev, W83795_REG_CTFS(0), config->temp1_critical_temperature); -+ w83795_write(dev, W83795_REG_CTFS(1), config->temp2_critical_temperature); -+ w83795_write(dev, W83795_REG_CTFS(2), config->temp3_critical_temperature); -+ w83795_write(dev, W83795_REG_CTFS(3), config->temp4_critical_temperature); -+ w83795_write(dev, W83795_REG_CTFS(4), config->temp5_critical_temperature); -+ w83795_write(dev, W83795_REG_CTFS(5), config->temp6_critical_temperature); -+ -+ /* Set fan control target temperatures */ -+ w83795_write(dev, W83795_REG_TTTI(0), config->temp1_target_temperature); -+ w83795_write(dev, W83795_REG_TTTI(1), config->temp2_target_temperature); -+ w83795_write(dev, W83795_REG_TTTI(2), config->temp3_target_temperature); -+ w83795_write(dev, W83795_REG_TTTI(3), config->temp4_target_temperature); -+ w83795_write(dev, W83795_REG_TTTI(4), config->temp5_target_temperature); -+ w83795_write(dev, W83795_REG_TTTI(5), config->temp6_target_temperature); -+ -+ /* Set fan stall prevention parameters */ -+ w83795_write(dev, W83795_REG_FAN_NONSTOP(0), config->fan1_nonstop); -+ w83795_write(dev, W83795_REG_FAN_NONSTOP(1), config->fan2_nonstop); -+ w83795_write(dev, W83795_REG_FAN_NONSTOP(2), config->fan3_nonstop); -+ w83795_write(dev, W83795_REG_FAN_NONSTOP(3), config->fan4_nonstop); -+ w83795_write(dev, W83795_REG_FAN_NONSTOP(4), config->fan5_nonstop); -+ w83795_write(dev, W83795_REG_FAN_NONSTOP(5), config->fan6_nonstop); -+ w83795_write(dev, W83795_REG_FAN_NONSTOP(6), config->fan7_nonstop); -+ w83795_write(dev, W83795_REG_FAN_NONSTOP(7), config->fan8_nonstop); -+ -+ /* Set fan default speed */ -+ w83795_write(dev, W83795_REG_DFSP, fan_pct_to_cfg_val(config->default_speed)); -+ -+ /* Set initial fan speeds */ -+ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(0), fan_pct_to_cfg_val(config->fan1_duty)); -+ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(1), fan_pct_to_cfg_val(config->fan2_duty)); -+ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(2), fan_pct_to_cfg_val(config->fan3_duty)); -+ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(3), fan_pct_to_cfg_val(config->fan4_duty)); -+ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(4), fan_pct_to_cfg_val(config->fan5_duty)); -+ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(5), fan_pct_to_cfg_val(config->fan6_duty)); -+ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(6), fan_pct_to_cfg_val(config->fan7_duty)); -+ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(7), fan_pct_to_cfg_val(config->fan8_duty)); -+ -+ /* Voltage monitor settings */ -+ w83795_write(dev, W83795_REG_VOLT_CTRL1, config->volt_ctl1); -+ w83795_write(dev, W83795_REG_VOLT_CTRL2, config->volt_ctl2); -+ -+ /* Voltage high/low limits */ -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(0), millivolts_to_limit_value_type1(config->vcore1_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(0), millivolts_to_limit_value_type1(config->vcore1_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(1), millivolts_to_limit_value_type1(config->vcore2_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(1), millivolts_to_limit_value_type1(config->vcore2_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(2), millivolts_to_limit_value_type1(config->vsen3_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(2), millivolts_to_limit_value_type1(config->vsen3_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(3), millivolts_to_limit_value_type1(config->vsen4_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(3), millivolts_to_limit_value_type1(config->vsen4_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(4), millivolts_to_limit_value_type1(config->vsen5_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(4), millivolts_to_limit_value_type1(config->vsen5_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(5), millivolts_to_limit_value_type1(config->vsen6_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(5), millivolts_to_limit_value_type1(config->vsen6_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(6), millivolts_to_limit_value_type1(config->vsen7_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(6), millivolts_to_limit_value_type1(config->vsen7_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(7), millivolts_to_limit_value_type1(config->vsen8_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(7), millivolts_to_limit_value_type1(config->vsen8_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(8), millivolts_to_limit_value_type1(config->vsen9_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(8), millivolts_to_limit_value_type1(config->vsen9_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(9), millivolts_to_limit_value_type1(config->vsen10_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(9), millivolts_to_limit_value_type1(config->vsen10_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(10), millivolts_to_limit_value_type1(config->vsen11_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(10), millivolts_to_limit_value_type1(config->vsen11_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(11), millivolts_to_limit_value_type1(config->vtt_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(11), millivolts_to_limit_value_type1(config->vtt_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(12), millivolts_to_limit_value_type2(config->vdd_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(12), millivolts_to_limit_value_type2(config->vdd_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(13), millivolts_to_limit_value_type2(config->vsb_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(13), millivolts_to_limit_value_type2(config->vsb_low_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(14), millivolts_to_limit_value_type2(config->vbat_high_limit_mv)); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(14), millivolts_to_limit_value_type2(config->vbat_low_limit_mv)); -+ -+ /* VSEN12 limits */ -+ limit_value = millivolts_to_limit_value_type3(config->vsen12_high_limit_mv); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH_2_M(4), limit_value >> 2); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH_2_L(4), limit_value & 0x3); -+ limit_value = millivolts_to_limit_value_type3(config->vsen12_low_limit_mv); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW_2_M(4), limit_value >> 2); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW_2_L(4), limit_value & 0x3); -+ -+ /* VSEN13 limits */ -+ limit_value = millivolts_to_limit_value_type3(config->vsen13_high_limit_mv); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH_2_M(5), limit_value >> 2); -+ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH_2_L(5), limit_value & 0x3); -+ limit_value = millivolts_to_limit_value_type3(config->vsen13_low_limit_mv); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW_2_M(5), limit_value >> 2); -+ w83795_write(dev, W83795_REG_VOLT_LIM_LOW_2_L(5), limit_value & 0x3); -+ -+ w83795_set_fan(dev, mode); - - printk(BIOS_INFO, "Fan CTFS(celsius) TTTI(celsius)\n"); - for (i = 0; i < 6; i++) { -- val = w83795_read(W83795_REG_CTFS(i)); -+ val = w83795_read(dev, W83795_REG_CTFS(i)); - printk(BIOS_INFO, " %x %d", i, val); -- val = w83795_read(W83795_REG_TTTI(i)); -+ val = w83795_read(dev, W83795_REG_TTTI(i)); - printk(BIOS_INFO, " %d\n", val); - } - - /* Temperature ReadOut */ - for (i = 0; i < 9; i++) { -- val = w83795_read(W83795_REG_DTS(i)); -+ val = w83795_read(dev, W83795_REG_DTS(i)); - printk(BIOS_DEBUG, "DTS%x ReadOut=%x\n", i, val); - } -+ -+ /* start monitoring operation */ -+ val = w83795_read(dev, W83795_REG_CONFIG); -+ val |= W83795_REG_CONFIG_START; -+ w83795_write(dev, W83795_REG_CONFIG, val); - } - - static void w83795_hwm_init(struct device *dev) -@@ -232,9 +338,9 @@ static void w83795_hwm_init(struct device *dev) - die("CPU: missing cpu device structure"); - - if (cpu->vendor == X86_VENDOR_AMD) -- w83795_init(THERMAL_CRUISE_MODE, DTS_SRC_AMD_SBTSI); -+ w83795_init(dev, THERMAL_CRUISE_MODE, DTS_SRC_AMD_SBTSI); - else if (cpu->vendor == X86_VENDOR_INTEL) -- w83795_init(THERMAL_CRUISE_MODE, DTS_SRC_INTEL_PECI); -+ w83795_init(dev, THERMAL_CRUISE_MODE, DTS_SRC_INTEL_PECI); - else - printk(BIOS_ERR, "Neither AMD nor INTEL CPU detected\n"); - } -diff --git a/src/drivers/i2c/w83795/w83795.h b/src/drivers/i2c/w83795/w83795.h -index cac4d5f..0727dc5 100644 ---- a/src/drivers/i2c/w83795/w83795.h -+++ b/src/drivers/i2c/w83795/w83795.h -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -20,8 +21,6 @@ - #ifndef _W83795_H_ - #define _W83795_H_ - --#define W83795_DEV 0x2F /* Host I2c Addr (strap to addr1 addr0 1 1, 0x5E) */ -- - #define W83795_REG_I2C_ADDR 0xFC - #define W83795_REG_BANKSEL 0x00 - #define W83795_REG_CONFIG 0x01 -@@ -29,6 +28,8 @@ - #define W83795_REG_CONFIG_CONFIG48 0x04 - #define W83795_REG_CONFIG_INIT 0x80 - -+#define W83795_REG_VOLT_CTRL1 0x02 -+#define W83795_REG_VOLT_CTRL2 0x03 - #define W83795_REG_TEMP_CTRL1 0x04 /* Temperature Monitoring Control Register */ - #define W83795_REG_TEMP_CTRL2 0x05 /* Temperature Monitoring Control Register */ - #define W83795_REG_FANIN_CTRL1 0x06 -@@ -37,37 +38,58 @@ - #define DTS_SRC_INTEL_PECI (0 << 0) - #define DTS_SRC_AMD_SBTSI (1 << 0) - --#define W83795_REG_TSS(n) (0x209 + (n)) /* Temperature Source Selection Register */ - #define W83795_REG_TTTI(n) (0x260 + (n)) /* Target temperature W83795G/ADG will try to tune the fan output to keep */ - #define W83795_REG_CTFS(n) (0x268 + (n)) /* Critical Temperature to Full Speed all fan */ --#define W83795_REG_HT(n) (0x270 + (n)) /* Hysteresis of Temperature */ - #define W83795_REG_DTSC 0x301 /* Digital Temperature Sensor Configuration */ - - #define W83795_REG_DTSE 0x302 /* Digital Temperature Sensor Enable */ - #define W83795_REG_DTS(n) (0x26 + (n)) - #define W83795_REG_VRLSB 0x3C - --#define W83795_TEMP_REG_TR1 0x21 --#define W83795_TEMP_REG_TR2 0x22 --#define W83795_TEMP_REG_TR3 0x23 --#define W83795_TEMP_REG_TR4 0x24 --#define W83795_TEMP_REG_TR5 0x1F --#define W83795_TEMP_REG_TR6 0x20 -+#define W83795_REG_TEMP_TR1 0x21 -+#define W83795_REG_TEMP_TR2 0x22 -+#define W83795_REG_TEMP_TR3 0x23 -+#define W83795_REG_TEMP_TR4 0x24 -+#define W83795_REG_TEMP_TR5 0x1F -+#define W83795_REG_TEMP_TR6 0x20 -+ -+#define W83795_REG_VOLT_LIM_HIGH(n) (0x70 + (n * 2)) /* Voltage high limit (0 == VSEN1) */ -+#define W83795_REG_VOLT_LIM_LOW(n) (0x71 + (n * 2)) /* Voltage low limit (0 == VSEN1) */ -+#define W83795_REG_VOLT_LIM_HIGH_2_M(n) (0x96 + (n * 4)) /* Voltage high limit MSB (0 == VDSEN14) */ -+#define W83795_REG_VOLT_LIM_LOW_2_M(n) (0x97 + (n * 4)) /* Voltage low limit MSB (0 == VDSEN14) */ -+#define W83795_REG_VOLT_LIM_HIGH_2_L(n) (0x98 + (n * 4)) /* Voltage high limit LSB (0 == VDSEN14) */ -+#define W83795_REG_VOLT_LIM_LOW_2_L(n) (0x99 + (n * 4)) /* Voltage low limit LSB (0 == VDSEN14) */ -+ -+#define W83795_REG_TEMP_CRIT(n) (0x96 + (n * 4)) /* Temperature critical limit */ -+#define W83795_REG_TEMP_CRIT_HYSTER(n) (0x97 + (n * 4)) /* Temperature critical limit hysteresis */ -+#define W83795_REG_TEMP_WARN(n) (0x98 + (n * 4)) /* Temperature warning limit */ -+#define W83795_REG_TEMP_WARN_HYSTER(n) (0x99 + (n * 4)) /* Temperature warning limit hysteresis */ -+ -+#define W83795_REG_DTS_CRIT 0xB2 /* Temperature critical limit */ -+#define W83795_REG_DTS_CRIT_HYSTER 0xB3 /* Temperature critical limit hysteresis */ -+#define W83795_REG_DTS_WARN 0xB4 /* Temperature warning limit */ -+#define W83795_REG_DTS_WARN_HYSTER 0xB5 /* Temperature warning limit hysteresis */ - - #define W83795_REG_FCMS1 0x201 - #define W83795_REG_FCMS2 0x208 --#define W83795_REG_TFMR(n) (0x202 + (n)) /*temperature to fam mappig*/ -+#define W83795_REG_TFMR(n) (0x202 + (n)) /* Temperature to fan mapping */ -+#define W83795_REG_T12TSS 0x209 /* Temperature Source Selection Register 1 */ -+#define W83795_REG_T34TSS 0x20A /* Temperature Source Selection Register 2 */ -+#define W83795_REG_T56TSS 0x20B /* Temperature Source Selection Register 3 */ -+#define W83795_REG_FAN_MANUAL_SPEED(n) (0x210 + n) - #define W83795_REG_DFSP 0x20C - -+#define W83795_REG_FAN_NONSTOP(n) (0x228 + (n)) /* Fan Nonstop Value */ -+ - #define W83795_REG_FTSH(n) (0x240 + (n) * 2) - #define W83795_REG_FTSL(n) (0x241 + (n) * 2) - #define W83795_REG_TFTS 0x250 - - typedef enum w83795_fan_mode { -- SPEED_CRUISE_MODE, ///< Fan Speed Cruise mode keeps the fan speed in a specified range -- THERMAL_CRUISE_MODE, ///< Thermal Cruise mode is an algorithm to control the fan speed to keep the temperature source around the TTTI -- SMART_FAN_MODE, ///< Smart Fan mode offers 6 slopes to control the fan speed -- MANUAL_MODE, ///< control manually -+ SPEED_CRUISE_MODE = 0, ///< Fan Speed Cruise mode keeps the fan speed in a specified range -+ THERMAL_CRUISE_MODE = 1, ///< Thermal Cruise mode is an algorithm to control the fan speed to keep the temperature source around the TTTI -+ SMART_FAN_MODE = 2, ///< Smart Fan mode offers 6 slopes to control the fan speed -+ MANUAL_MODE = 3, ///< control manually - } w83795_fan_mode_t; - - #endif --- -1.9.1 - diff --git a/resources/libreboot/patch/kgpe-d16/0002-southbridge-amd-sb700-Allow-use-of-auxiliary-SMBUS-c.patch b/resources/libreboot/patch/kgpe-d16/0002-southbridge-amd-sb700-Allow-use-of-auxiliary-SMBUS-c.patch @@ -1,28 +1,29 @@ -From 6ae8695f880a4a15672eda801226b4b1c83aa1a8 Mon Sep 17 00:00:00 2001 +From c3691fe7c155d63baedbb1836e6ccf9c1fcb5846 Mon Sep 17 00:00:00 2001 From: Timothy Pearson <tpearson@raptorengineeringinc.com> Date: Sat, 17 Oct 2015 04:36:47 -0500 -Subject: [PATCH 002/139] southbridge/amd/sb700: Allow use of auxiliary SMBUS +Subject: [PATCH 002/143] southbridge/amd/sb700: Allow use of auxiliary SMBUS controller Change-Id: I29ece10eeefc2c75a3829c169f1e1aede7194ec2 Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> --- - src/device/Kconfig | 4 ++++ - src/include/device/smbus.h | 5 +++++ - src/southbridge/amd/sb700/Kconfig | 1 + - src/southbridge/amd/sb700/sm.c | 36 +++++++++++++++++++++++++++++++----- - src/southbridge/amd/sb700/smbus.c | 15 +++++++++++++++ - 5 files changed, 56 insertions(+), 5 deletions(-) + src/device/Kconfig | 4 ++++ + src/include/device/smbus.h | 5 ++++ + src/southbridge/amd/sb700/Kconfig | 1 + + src/southbridge/amd/sb700/sm.c | 47 ++++++++++++++++++++++++++++++------- + src/southbridge/amd/sb700/smbus.c | 15 ++++++++++++ + src/southbridge/amd/sb700/smbus.h | 5 ++-- + 6 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/device/Kconfig b/src/device/Kconfig -index 613461b..3dd2b61 100644 +index 613461b..bcf7dad 100644 --- a/src/device/Kconfig +++ b/src/device/Kconfig @@ -192,6 +192,10 @@ config MULTIPLE_VGA_ADAPTERS bool default n -+config SMBUS_HAS_AUX ++config SMBUS_HAS_AUX_CHANNELS + bool + default n + @@ -30,129 +31,133 @@ index 613461b..3dd2b61 100644 bool default n diff --git a/src/include/device/smbus.h b/src/include/device/smbus.h -index 073d7e2..53e90fb 100644 +index 073d7e2..a838f55 100644 --- a/src/include/device/smbus.h +++ b/src/include/device/smbus.h @@ -47,4 +47,9 @@ int smbus_process_call(device_t dev, u8 cmd, u16 data); int smbus_block_read(device_t dev, u8 cmd, u8 bytes, u8 *buffer); int smbus_block_write(device_t dev, u8 cmd, u8 bytes, const u8 *buffer); -+#if IS_ENABLED(CONFIG_SMBUS_HAS_AUX) -+void smbus_switch_to_aux(uint8_t enable_aux); -+uint8_t smbus_switched_to_aux(void); ++#if IS_ENABLED(CONFIG_SMBUS_HAS_AUX_CHANNELS) ++void smbus_switch_to_aux_channel(uint8_t aux_channel_number); ++uint8_t smbus_current_aux_channel(void); +#endif + #endif /* DEVICE_SMBUS_H */ diff --git a/src/southbridge/amd/sb700/Kconfig b/src/southbridge/amd/sb700/Kconfig -index 42ca2bb..a5dfe07 100644 +index 42ca2bb..0761934 100644 --- a/src/southbridge/amd/sb700/Kconfig +++ b/src/southbridge/amd/sb700/Kconfig @@ -27,6 +27,7 @@ config SOUTHBRIDGE_SPECIFIC_OPTIONS # dummy select IOAPIC select HAVE_USBDEBUG_OPTIONS select HAVE_HARD_RESET -+ select SMBUS_HAS_AUX ++ select SMBUS_HAS_AUX_CHANNELS # Set for southbridge SP5100 which also uses SB700 driver config SOUTHBRIDGE_AMD_SUBTYPE_SP5100 diff --git a/src/southbridge/amd/sb700/sm.c b/src/southbridge/amd/sb700/sm.c -index f544c88..c216e1f 100644 +index f544c88..598ebec 100644 --- a/src/southbridge/amd/sb700/sm.c +++ b/src/southbridge/amd/sb700/sm.c -@@ -40,6 +40,8 @@ +@@ -40,6 +40,11 @@ #define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON #endif ++#define PRIMARY_SMBUS_RESOURCE_NUMBER 0x90 ++#define AUXILIARY_SMBUS_RESOURCE_NUMBER 0x58 ++ +uint8_t smbus_use_aux = 0; + /* * SB700 enables all USB controllers by default in SMBUS Control. * SB700 enables SATA by default in SMBUS Control. -@@ -312,7 +314,10 @@ static int lsmbus_recv_byte(device_t dev) +@@ -312,7 +317,10 @@ static int lsmbus_recv_byte(device_t dev) device = dev->path.i2c.device; pbus = get_pbus_smbus(dev); - res = find_resource(pbus->dev, 0x90); + if (!smbus_use_aux) -+ res = find_resource(pbus->dev, 0x90); ++ res = find_resource(pbus->dev, PRIMARY_SMBUS_RESOURCE_NUMBER); + else -+ res = find_resource(pbus->dev, 0x58); ++ res = find_resource(pbus->dev, AUXILIARY_SMBUS_RESOURCE_NUMBER); return do_smbus_recv_byte(res->base, device); } -@@ -326,7 +331,10 @@ static int lsmbus_send_byte(device_t dev, u8 val) +@@ -326,7 +334,10 @@ static int lsmbus_send_byte(device_t dev, u8 val) device = dev->path.i2c.device; pbus = get_pbus_smbus(dev); - res = find_resource(pbus->dev, 0x90); + if (!smbus_use_aux) -+ res = find_resource(pbus->dev, 0x90); ++ res = find_resource(pbus->dev, PRIMARY_SMBUS_RESOURCE_NUMBER); + else -+ res = find_resource(pbus->dev, 0x58); ++ res = find_resource(pbus->dev, AUXILIARY_SMBUS_RESOURCE_NUMBER); return do_smbus_send_byte(res->base, device, val); } -@@ -340,7 +348,10 @@ static int lsmbus_read_byte(device_t dev, u8 address) +@@ -340,7 +351,10 @@ static int lsmbus_read_byte(device_t dev, u8 address) device = dev->path.i2c.device; pbus = get_pbus_smbus(dev); - res = find_resource(pbus->dev, 0x90); + if (!smbus_use_aux) -+ res = find_resource(pbus->dev, 0x90); ++ res = find_resource(pbus->dev, PRIMARY_SMBUS_RESOURCE_NUMBER); + else -+ res = find_resource(pbus->dev, 0x58); ++ res = find_resource(pbus->dev, AUXILIARY_SMBUS_RESOURCE_NUMBER); return do_smbus_read_byte(res->base, device, address); } -@@ -354,7 +365,10 @@ static int lsmbus_write_byte(device_t dev, u8 address, u8 val) +@@ -354,7 +368,10 @@ static int lsmbus_write_byte(device_t dev, u8 address, u8 val) device = dev->path.i2c.device; pbus = get_pbus_smbus(dev); - res = find_resource(pbus->dev, 0x90); + if (!smbus_use_aux) -+ res = find_resource(pbus->dev, 0x90); ++ res = find_resource(pbus->dev, PRIMARY_SMBUS_RESOURCE_NUMBER); + else -+ res = find_resource(pbus->dev, 0x58); ++ res = find_resource(pbus->dev, AUXILIARY_SMBUS_RESOURCE_NUMBER); return do_smbus_write_byte(res->base, device, address, val); } -@@ -393,7 +407,7 @@ static void sb700_sm_read_resources(device_t dev) +@@ -393,9 +410,18 @@ static void sb700_sm_read_resources(device_t dev) /* dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; */ - /* smbus */ +- res = new_resource(dev, 0x90); +- res->base = 0xB00; + /* primary smbus */ - res = new_resource(dev, 0x90); - res->base = 0xB00; - res->size = 0x10; -@@ -402,6 +416,15 @@ static void sb700_sm_read_resources(device_t dev) - res->gran = 8; - res->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_RESERVE | IORESOURCE_ASSIGNED; - -+ /* auxiliary smbus */ -+ res = new_resource(dev, 0x58); -+ res->base = 0xB20; ++ res = new_resource(dev, PRIMARY_SMBUS_RESOURCE_NUMBER); ++ res->base = SMBUS_IO_BASE; + res->size = 0x10; + res->limit = 0xFFFFUL; /* res->base + res->size -1; */ + res->align = 8; + res->gran = 8; + res->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_RESERVE | IORESOURCE_ASSIGNED; + - compact_resources(dev); - } - -@@ -441,6 +464,9 @@ static void sb700_sm_set_resources(struct device *dev) - - res = find_resource(dev, 0x90); - pci_write_config32(dev, 0x90, res->base | 1); ++ /* auxiliary smbus */ ++ res = new_resource(dev, AUXILIARY_SMBUS_RESOURCE_NUMBER); ++ res->base = SMBUS_AUX_IO_BASE; + res->size = 0x10; + res->limit = 0xFFFFUL; /* res->base + res->size -1; */ + res->align = 8; +@@ -439,8 +465,11 @@ static void sb700_sm_set_resources(struct device *dev) + pci_write_config8(dev, 0x65, byte); + /* TODO: End of test hpet */ + +- res = find_resource(dev, 0x90); +- pci_write_config32(dev, 0x90, res->base | 1); ++ res = find_resource(dev, PRIMARY_SMBUS_RESOURCE_NUMBER); ++ pci_write_config32(dev, PRIMARY_SMBUS_RESOURCE_NUMBER, res->base | 1); + -+ res = find_resource(dev, 0x58); -+ pci_write_config32(dev, 0x58, res->base | 1); ++ res = find_resource(dev, AUXILIARY_SMBUS_RESOURCE_NUMBER); ++ pci_write_config32(dev, AUXILIARY_SMBUS_RESOURCE_NUMBER, res->base | 1); } static struct pci_operations lops_pci = { diff --git a/src/southbridge/amd/sb700/smbus.c b/src/southbridge/amd/sb700/smbus.c -index 94f5e24..a89e830 100644 +index 94f5e24..e1cfe6b 100644 --- a/src/southbridge/amd/sb700/smbus.c +++ b/src/southbridge/amd/sb700/smbus.c @@ -22,6 +22,11 @@ @@ -161,8 +166,8 @@ index 94f5e24..a89e830 100644 +extern uint8_t smbus_use_aux; + -+void smbus_switch_to_aux(uint8_t enable_aux); -+uint8_t smbus_switched_to_aux(void); ++void smbus_switch_to_aux_channel(uint8_t aux_channel_number); ++uint8_t smbus_current_aux_channel(void); + void alink_ab_indx(u32 reg_space, u32 reg_addr, u32 mask, u32 val) { @@ -171,17 +176,40 @@ index 94f5e24..a89e830 100644 return 0; } -+void smbus_switch_to_aux(uint8_t enable_aux) ++void smbus_switch_to_aux_channel(uint8_t aux_channel_number) +{ -+ smbus_use_aux = enable_aux; ++ smbus_use_aux = (aux_channel_number != 0); +} + -+uint8_t smbus_switched_to_aux(void) ++uint8_t smbus_current_aux_channel(void) +{ + return smbus_use_aux; +} + #endif +diff --git a/src/southbridge/amd/sb700/smbus.h b/src/southbridge/amd/sb700/smbus.h +index d223fe7..34b4098 100644 +--- a/src/southbridge/amd/sb700/smbus.h ++++ b/src/southbridge/amd/sb700/smbus.h +@@ -2,6 +2,7 @@ + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Advanced Micro Devices, Inc. ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -24,8 +25,8 @@ + #include "stddef.h" + #include <arch/io.h> + +-#define SMBUS_IO_BASE 0x6000 /* Is it a temporary SMBus I/O base address? */ +- /*SIZE 0x40 */ ++#define SMBUS_IO_BASE 0xb00 ++#define SMBUS_AUX_IO_BASE 0xb20 + + #define SMBHSTSTAT 0x0 + #define SMBSLVSTAT 0x1 -- -1.9.1 +1.7.9.5 diff --git a/resources/libreboot/patch/kgpe-d16/0003-drivers-i2c-w83795-Add-full-support-for-core-functio.patch b/resources/libreboot/patch/kgpe-d16/0003-drivers-i2c-w83795-Add-full-support-for-core-functio.patch @@ -0,0 +1,725 @@ +From 72d183bad6db0f2f91b991710d1c0a8113a071f3 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Sat, 5 Sep 2015 17:53:20 -0500 +Subject: [PATCH 003/143] drivers/i2c/w83795: Add full support for core + functions + +Add full support for fan control, fan monitoring, and voltage +monitoring. Fan speeds and functions are configurable via +each mainboard's devicetree.cb file. + +NOTE: This patch effectively rewrites large portions of +the original driver. You may need to re-verify correct +operation on your hardware if you were using the old +driver code. + +Change-Id: I3e246af0e398d65ee43ea708060885c67fd7d202 +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/drivers/i2c/w83795/chip.h | 142 ++++++++++++++++ + src/drivers/i2c/w83795/w83795.c | 339 ++++++++++++++++++++++++++------------- + src/drivers/i2c/w83795/w83795.h | 52 ++++-- + 3 files changed, 405 insertions(+), 128 deletions(-) + create mode 100644 src/drivers/i2c/w83795/chip.h + +diff --git a/src/drivers/i2c/w83795/chip.h b/src/drivers/i2c/w83795/chip.h +new file mode 100644 +index 0000000..c8a42ea +--- /dev/null ++++ b/src/drivers/i2c/w83795/chip.h +@@ -0,0 +1,142 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2015 Raptor Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc. ++ */ ++ ++struct drivers_i2c_w83795_config { ++ uint8_t fanin_ctl1; ++ uint8_t fanin_ctl2; ++ ++ uint8_t temp_ctl1; ++ uint8_t temp_ctl2; ++ uint8_t temp_dtse; ++ ++ uint8_t volt_ctl1; ++ uint8_t volt_ctl2; ++ ++ uint8_t temp1_fan_select; ++ uint8_t temp2_fan_select; ++ uint8_t temp3_fan_select; ++ uint8_t temp4_fan_select; ++ uint8_t temp5_fan_select; ++ uint8_t temp6_fan_select; ++ ++ uint8_t temp1_source_select; ++ uint8_t temp2_source_select; ++ uint8_t temp3_source_select; ++ uint8_t temp4_source_select; ++ uint8_t temp5_source_select; ++ uint8_t temp6_source_select; ++ ++ uint32_t vcore1_high_limit_mv; /* mV */ ++ uint32_t vcore1_low_limit_mv; /* mV */ ++ uint32_t vcore2_high_limit_mv; /* mV */ ++ uint32_t vcore2_low_limit_mv; /* mV */ ++ uint32_t vtt_high_limit_mv; /* mV */ ++ uint32_t vtt_low_limit_mv; /* mV */ ++ uint32_t vsen3_high_limit_mv; /* mV */ ++ uint32_t vsen3_low_limit_mv; /* mV */ ++ uint32_t vsen4_high_limit_mv; /* mV */ ++ uint32_t vsen4_low_limit_mv; /* mV */ ++ uint32_t vsen5_high_limit_mv; /* mV */ ++ uint32_t vsen5_low_limit_mv; /* mV */ ++ uint32_t vsen6_high_limit_mv; /* mV */ ++ uint32_t vsen6_low_limit_mv; /* mV */ ++ uint32_t vsen7_high_limit_mv; /* mV */ ++ uint32_t vsen7_low_limit_mv; /* mV */ ++ uint32_t vsen8_high_limit_mv; /* mV */ ++ uint32_t vsen8_low_limit_mv; /* mV */ ++ uint32_t vsen9_high_limit_mv; /* mV */ ++ uint32_t vsen9_low_limit_mv; /* mV */ ++ uint32_t vsen10_high_limit_mv; /* mV */ ++ uint32_t vsen10_low_limit_mv; /* mV */ ++ uint32_t vsen11_high_limit_mv; /* mV */ ++ uint32_t vsen11_low_limit_mv; /* mV */ ++ uint32_t vsen12_high_limit_mv; /* mV */ ++ uint32_t vsen12_low_limit_mv; /* mV */ ++ uint32_t vsen13_high_limit_mv; /* mV */ ++ uint32_t vsen13_low_limit_mv; /* mV */ ++ uint32_t vdd_high_limit_mv; /* mV */ ++ uint32_t vdd_low_limit_mv; /* mV */ ++ uint32_t vsb_high_limit_mv; /* mV */ ++ uint32_t vsb_low_limit_mv; /* mV */ ++ uint32_t vbat_high_limit_mv; /* mV */ ++ uint32_t vbat_low_limit_mv; /* mV */ ++ ++ int8_t tr1_critical_temperature; /* °C */ ++ int8_t tr1_critical_hysteresis; /* °C */ ++ int8_t tr1_warning_temperature; /* °C */ ++ int8_t tr1_warning_hysteresis; /* °C */ ++ int8_t tr2_critical_temperature; /* °C */ ++ int8_t tr2_critical_hysteresis; /* °C */ ++ int8_t tr2_warning_temperature; /* °C */ ++ int8_t tr2_warning_hysteresis; /* °C */ ++ int8_t tr3_critical_temperature; /* °C */ ++ int8_t tr3_critical_hysteresis; /* °C */ ++ int8_t tr3_warning_temperature; /* °C */ ++ int8_t tr3_warning_hysteresis; /* °C */ ++ int8_t tr4_critical_temperature; /* °C */ ++ int8_t tr4_critical_hysteresis; /* °C */ ++ int8_t tr4_warning_temperature; /* °C */ ++ int8_t tr4_warning_hysteresis; /* °C */ ++ int8_t tr5_critical_temperature; /* °C */ ++ int8_t tr5_critical_hysteresis; /* °C */ ++ int8_t tr5_warning_temperature; /* °C */ ++ int8_t tr5_warning_hysteresis; /* °C */ ++ int8_t tr6_critical_temperature; /* °C */ ++ int8_t tr6_critical_hysteresis; /* °C */ ++ int8_t tr6_warning_temperature; /* °C */ ++ int8_t tr6_warning_hysteresis; /* °C */ ++ int8_t dts_critical_temperature; /* °C */ ++ int8_t dts_critical_hysteresis; /* °C */ ++ int8_t dts_warning_temperature; /* °C */ ++ int8_t dts_warning_hysteresis; /* °C */ ++ ++ int8_t temp1_critical_temperature; /* °C */ ++ int8_t temp2_critical_temperature; /* °C */ ++ int8_t temp3_critical_temperature; /* °C */ ++ int8_t temp4_critical_temperature; /* °C */ ++ int8_t temp5_critical_temperature; /* °C */ ++ int8_t temp6_critical_temperature; /* °C */ ++ ++ int8_t temp1_target_temperature; /* °C */ ++ int8_t temp2_target_temperature; /* °C */ ++ int8_t temp3_target_temperature; /* °C */ ++ int8_t temp4_target_temperature; /* °C */ ++ int8_t temp5_target_temperature; /* °C */ ++ int8_t temp6_target_temperature; /* °C */ ++ ++ uint8_t fan1_nonstop; /* % of full speed (0-100) */ ++ uint8_t fan2_nonstop; /* % of full speed (0-100) */ ++ uint8_t fan3_nonstop; /* % of full speed (0-100) */ ++ uint8_t fan4_nonstop; /* % of full speed (0-100) */ ++ uint8_t fan5_nonstop; /* % of full speed (0-100) */ ++ uint8_t fan6_nonstop; /* % of full speed (0-100) */ ++ uint8_t fan7_nonstop; /* % of full speed (0-100) */ ++ uint8_t fan8_nonstop; /* % of full speed (0-100) */ ++ ++ uint8_t default_speed; /* % of full speed (0-100) */ ++ ++ uint8_t fan1_duty; /* % of full speed (0-100) */ ++ uint8_t fan2_duty; /* % of full speed (0-100) */ ++ uint8_t fan3_duty; /* % of full speed (0-100) */ ++ uint8_t fan4_duty; /* % of full speed (0-100) */ ++ uint8_t fan5_duty; /* % of full speed (0-100) */ ++ uint8_t fan6_duty; /* % of full speed (0-100) */ ++ uint8_t fan7_duty; /* % of full speed (0-100) */ ++ uint8_t fan8_duty; /* % of full speed (0-100) */ ++}; +diff --git a/src/drivers/i2c/w83795/w83795.c b/src/drivers/i2c/w83795/w83795.c +index 2bbe0be..0af272f 100644 +--- a/src/drivers/i2c/w83795/w83795.c ++++ b/src/drivers/i2c/w83795/w83795.c +@@ -2,6 +2,7 @@ + * This file is part of the coreboot project. + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. ++ * Copyright (C) 2015 Raptor Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -21,106 +22,68 @@ + #include <arch/cpu.h> + #include <console/console.h> + #include <device/device.h> +-#include "southbridge/amd/cimx/sb700/smbus.h" /*SMBUS_IO_BASE*/ + #include "w83795.h" ++#include <device/smbus.h> ++#include "chip.h" + +-static int w83795_set_bank(u8 bank) ++static int w83795_set_bank(struct device *dev, uint8_t bank) + { +- return do_smbus_write_byte(SMBUS_IO_BASE, W83795_DEV, W83795_REG_BANKSEL, bank); ++ return smbus_write_byte(dev, W83795_REG_BANKSEL, bank); + } + +-static u8 w83795_read(u16 reg) ++static uint8_t w83795_read(struct device *dev, uint16_t reg) + { + int ret; + +- ret = w83795_set_bank(reg >> 8); ++ ret = w83795_set_bank(dev, reg >> 8); + if (ret < 0) { +- printk(BIOS_DEBUG, "read faild to set bank %x\n", reg >> 8); ++ printk(BIOS_DEBUG, "read failed to set bank %x\n", reg >> 8); + return -1; + } + +- ret = do_smbus_read_byte(SMBUS_IO_BASE, W83795_DEV, reg & 0xff); ++ ret = smbus_read_byte(dev, reg & 0xff); + return ret; + } + +-static u8 w83795_write(u16 reg, u8 value) ++static uint8_t w83795_write(struct device *dev, uint16_t reg, uint8_t value) + { + int err; + +- err = w83795_set_bank(reg >> 8); ++ err = w83795_set_bank(dev, reg >> 8); + if (err < 0) { +- printk(BIOS_DEBUG, "write faild to set bank %x\n", reg >> 8); ++ printk(BIOS_DEBUG, "write failed to set bank %x\n", reg >> 8); + return -1; + } + +- err = do_smbus_write_byte(SMBUS_IO_BASE, W83795_DEV, reg & 0xff, value); ++ err = smbus_write_byte(dev, reg & 0xff, value); + return err; + } + + /* +- * Enable Digital Temperature Sensor ++ * Configure Digital Temperature Sensor + */ +-static void w83795_dts_enable(u8 dts_src) ++static void w83795_dts_configure(struct device *dev, uint8_t dts_src) + { + u8 val; + + /* DIS */ +- val = w83795_read(W83795_REG_DTSC); ++ val = w83795_read(dev, W83795_REG_DTSC); + val |= (dts_src & 0x01); +- w83795_write(W83795_REG_DTSC, val); +- +- /* DTSE */ +- val = w83795_read(W83795_REG_DTSE); +- val |= 0xFF; +- w83795_write(W83795_REG_DTSE, val); +- +- /* store bank3 regs first before enable DTS */ +- +- /* +- * TD/TR1-4 thermal diode by default +- * 0x00 Disable +- * 0x01 thermistors on motherboard +- * 0x10 different mode voltage +- * 0x11 CPU internal thermal diode output +- * +- * TR5-6 thermistors by default TRn +- */ +- val = 0x55; /* thermal diode */ +- w83795_write(W83795_REG_TEMP_CTRL2, val); +- +- /* Enable Digital Temperature Sensor */ +- val = w83795_read(W83795_REG_TEMP_CTRL1); +- val |= W83795_REG_TEMP_CTRL1_EN_DTS; /* EN_DTS */ +- w83795_write(W83795_REG_TEMP_CTRL1, val); ++ w83795_write(dev, W83795_REG_DTSC, val); + } + +-static void w83795_set_tfmr(w83795_fan_mode_t mode) +-{ +- u8 val; +- u8 i; +- +- if ((mode == SMART_FAN_MODE) || (mode == THERMAL_CRUISE_MODE)) { +- val = 0xFF; +- } else { +- val = 0x00; +- } +- +- for (i = 0; i < 6; i++) +- w83795_write(W83795_REG_TFMR(i), val); +-} +- +-static u32 w83795_set_fan_mode(w83795_fan_mode_t mode) ++static u32 w83795_set_fan_mode(struct device *dev, w83795_fan_mode_t mode) + { + if (mode == SPEED_CRUISE_MODE) { +- w83795_write(W83795_REG_FCMS1, 0xFF); ++ w83795_write(dev, W83795_REG_FCMS1, 0xFF); + printk(BIOS_INFO, "W83795G/ADG work in Speed Cruise Mode\n"); + } else { +- w83795_write(W83795_REG_FCMS1, 0x00); ++ w83795_write(dev, W83795_REG_FCMS1, 0x00); + if (mode == THERMAL_CRUISE_MODE) { +- w83795_write(W83795_REG_FCMS2, 0x00); ++ w83795_write(dev, W83795_REG_FCMS2, 0x00); + printk(BIOS_INFO, "W83795G/ADG work in Thermal Cruise Mode\n"); + } else if (mode == SMART_FAN_MODE) { +- w83795_write(W83795_REG_FCMS2, 0x3F); ++ w83795_write(dev, W83795_REG_FCMS2, 0x3F); + printk(BIOS_INFO, "W83795G/ADG work in Smart Fan Mode\n"); + } else { + printk(BIOS_INFO, "W83795G/ADG work in Manual Mode\n"); +@@ -131,40 +94,12 @@ static u32 w83795_set_fan_mode(w83795_fan_mode_t mode) + return 0; + } + +-static void w83795_set_tss(void) ++static void w83795_set_fan(struct device *dev, w83795_fan_mode_t mode) + { +- u8 val; +- +- val = 0x00; +- w83795_write(W83795_REG_TSS(0), val); /* Temp1, 2 */ +- w83795_write(W83795_REG_TSS(1), val); /* Temp3, 4 */ +- w83795_write(W83795_REG_TSS(2), val); /* Temp5, 6 */ +-} +- +-static void w83795_set_fan(w83795_fan_mode_t mode) +-{ +- u8 i; +- +- /* select temperature sensor (TSS)*/ +- w83795_set_tss(); +- +- /* select Temperature to Fan mapping Relationships (TFMR)*/ +- w83795_set_tfmr(mode); +- + /* set fan output controlled mode (FCMS)*/ +- w83795_set_fan_mode(mode); ++ w83795_set_fan_mode(dev, mode); + +- /* Set Critical Temperature to Full Speed all fan (CTFS) */ +- for (i = 0; i < 6; i++) { +- w83795_write(W83795_REG_CTFS(i), 0x50); /* default 80 celsius degree */ +- } +- +- if (mode == THERMAL_CRUISE_MODE) { +- /* Set Target Temperature of Temperature Inputs (TTTI) */ +- for (i = 0; i < 6; i++) { +- w83795_write(W83795_REG_TTTI(i), 0x28); /* default 40 celsius degree */ +- } +- } else if (mode == SMART_FAN_MODE) { ++ if (mode == SMART_FAN_MODE) { + /* Set the Relative Register-at SMART FAN IV Control Mode Table */ + //SFIV TODO + } +@@ -173,16 +108,44 @@ static void w83795_set_fan(w83795_fan_mode_t mode) + //TODO + } + +-static void w83795_init(w83795_fan_mode_t mode, u8 dts_src) ++static uint8_t fan_pct_to_cfg_val(uint8_t percent) + { +- u8 i; +- u8 val; ++ uint16_t cfg = (((unsigned int)percent * 10000) / 3922); ++ if (cfg > 0xff) ++ cfg = 0xff; ++ return cfg; ++} ++ ++static uint8_t millivolts_to_limit_value_type1(int millivolts) ++{ ++ /* Datasheet v1.41 page 44 (VSEN1 - VSEN13, VTT) */ ++ return ((millivolts / 2) >> 2); ++} ++ ++static uint8_t millivolts_to_limit_value_type2(int millivolts) ++{ ++ /* Datasheet v1.41 page 44 (3VSB, 3VDD, VBAT) */ ++ return ((millivolts / 6) >> 2); ++} ++ ++static uint16_t millivolts_to_limit_value_type3(int millivolts) ++{ ++ /* Datasheet v1.41 page 44 (VDSEN14 - VDSEN17) */ ++ return (millivolts / 2); ++} ++ ++static void w83795_init(struct device *dev, w83795_fan_mode_t mode, u8 dts_src) ++{ ++ struct drivers_i2c_w83795_config *config = dev->chip_info; ++ uint8_t i; ++ uint8_t val; ++ uint16_t limit_value; + +- if (do_smbus_read_byte(SMBUS_IO_BASE, W83795_DEV, 0x00) < 0) { ++ if (smbus_read_byte(dev, 0x00) < 0) { + printk(BIOS_ERR, "W83795G/ADG Nuvoton H/W Monitor not found\n"); + return; + } +- val = w83795_read(W83795_REG_CONFIG); ++ val = w83795_read(dev, W83795_REG_CONFIG); + if ((val & W83795_REG_CONFIG_CONFIG48) == 0) + printk(BIOS_INFO, "Found 64 pin W83795G Nuvoton H/W Monitor\n"); + else if ((val & W83795_REG_CONFIG_CONFIG48) == 1) +@@ -190,35 +153,185 @@ static void w83795_init(w83795_fan_mode_t mode, u8 dts_src) + + /* Reset */ + val |= W83795_REG_CONFIG_INIT; +- w83795_write(W83795_REG_CONFIG, val); +- +- /* Fan monitoring setting */ +- val = 0xFF; /* FAN1-FAN8 */ +- w83795_write(W83795_REG_FANIN_CTRL1, val); +- val = 0x3F; /* FAN9-FAN14 */ +- w83795_write(W83795_REG_FANIN_CTRL2, val); ++ w83795_write(dev, W83795_REG_CONFIG, val); ++ ++ /* Fan monitor settings */ ++ w83795_write(dev, W83795_REG_FANIN_CTRL1, config->fanin_ctl1); ++ w83795_write(dev, W83795_REG_FANIN_CTRL2, config->fanin_ctl2); ++ ++ /* Temperature thresholds */ ++ w83795_write(dev, W83795_REG_TEMP_CRIT(0), config->tr1_critical_temperature); ++ w83795_write(dev, W83795_REG_TEMP_CRIT_HYSTER(0), config->tr1_critical_hysteresis); ++ w83795_write(dev, W83795_REG_TEMP_WARN(0), config->tr1_warning_temperature); ++ w83795_write(dev, W83795_REG_TEMP_WARN_HYSTER(0), config->tr1_warning_hysteresis); ++ w83795_write(dev, W83795_REG_TEMP_CRIT(1), config->tr2_critical_temperature); ++ w83795_write(dev, W83795_REG_TEMP_CRIT_HYSTER(1), config->tr2_critical_hysteresis); ++ w83795_write(dev, W83795_REG_TEMP_WARN(1), config->tr2_warning_temperature); ++ w83795_write(dev, W83795_REG_TEMP_WARN_HYSTER(1), config->tr2_warning_hysteresis); ++ w83795_write(dev, W83795_REG_TEMP_CRIT(2), config->tr3_critical_temperature); ++ w83795_write(dev, W83795_REG_TEMP_CRIT_HYSTER(2), config->tr3_critical_hysteresis); ++ w83795_write(dev, W83795_REG_TEMP_WARN(2), config->tr3_warning_temperature); ++ w83795_write(dev, W83795_REG_TEMP_WARN_HYSTER(2), config->tr3_warning_hysteresis); ++ w83795_write(dev, W83795_REG_TEMP_CRIT(3), config->tr4_critical_temperature); ++ w83795_write(dev, W83795_REG_TEMP_CRIT_HYSTER(3), config->tr4_critical_hysteresis); ++ w83795_write(dev, W83795_REG_TEMP_WARN(3), config->tr4_warning_temperature); ++ w83795_write(dev, W83795_REG_TEMP_WARN_HYSTER(3), config->tr4_warning_hysteresis); ++ w83795_write(dev, W83795_REG_TEMP_CRIT(4), config->tr5_critical_temperature); ++ w83795_write(dev, W83795_REG_TEMP_CRIT_HYSTER(4), config->tr5_critical_hysteresis); ++ w83795_write(dev, W83795_REG_TEMP_WARN(4), config->tr5_warning_temperature); ++ w83795_write(dev, W83795_REG_TEMP_WARN_HYSTER(4), config->tr5_warning_hysteresis); ++ w83795_write(dev, W83795_REG_TEMP_CRIT(5), config->tr6_critical_temperature); ++ w83795_write(dev, W83795_REG_TEMP_CRIT_HYSTER(5), config->tr6_critical_hysteresis); ++ w83795_write(dev, W83795_REG_TEMP_WARN(5), config->tr6_warning_temperature); ++ w83795_write(dev, W83795_REG_TEMP_WARN_HYSTER(5), config->tr6_warning_hysteresis); ++ ++ /* DTS enable */ ++ w83795_write(dev, W83795_REG_DTSE, config->temp_dtse); ++ ++ /* DTS temperature thresholds */ ++ w83795_write(dev, W83795_REG_DTS_CRIT, config->dts_critical_temperature); ++ w83795_write(dev, W83795_REG_DTS_CRIT_HYSTER, config->dts_critical_hysteresis); ++ w83795_write(dev, W83795_REG_DTS_WARN, config->dts_warning_temperature); ++ w83795_write(dev, W83795_REG_DTS_WARN_HYSTER, config->dts_warning_hysteresis); ++ ++ /* Configure DTS registers in bank3 before enabling DTS */ ++ w83795_dts_configure(dev, dts_src); ++ ++ /* Temperature monitor settings */ ++ w83795_write(dev, W83795_REG_TEMP_CTRL1, config->temp_ctl1); ++ w83795_write(dev, W83795_REG_TEMP_CTRL2, config->temp_ctl2); ++ ++ /* Temperature to fan mappings */ ++ w83795_write(dev, W83795_REG_TFMR(0), config->temp1_fan_select); ++ w83795_write(dev, W83795_REG_TFMR(1), config->temp2_fan_select); ++ w83795_write(dev, W83795_REG_TFMR(2), config->temp3_fan_select); ++ w83795_write(dev, W83795_REG_TFMR(3), config->temp4_fan_select); ++ w83795_write(dev, W83795_REG_TFMR(4), config->temp5_fan_select); ++ w83795_write(dev, W83795_REG_TFMR(5), config->temp6_fan_select); ++ ++ /* Temperature data source to temperature mappings */ ++ w83795_write(dev, W83795_REG_T12TSS, ((config->temp2_source_select & 0xff) << 8) | (config->temp1_source_select & 0xff)); ++ w83795_write(dev, W83795_REG_T34TSS, ((config->temp4_source_select & 0xff) << 8) | (config->temp3_source_select & 0xff)); ++ w83795_write(dev, W83795_REG_T56TSS, ((config->temp6_source_select & 0xff) << 8) | (config->temp5_source_select & 0xff)); ++ ++ /* Set critical temperatures ++ * If any sensor exceeds the associated critical temperature, ++ * all fans will be forced to full speed. ++ */ ++ w83795_write(dev, W83795_REG_CTFS(0), config->temp1_critical_temperature); ++ w83795_write(dev, W83795_REG_CTFS(1), config->temp2_critical_temperature); ++ w83795_write(dev, W83795_REG_CTFS(2), config->temp3_critical_temperature); ++ w83795_write(dev, W83795_REG_CTFS(3), config->temp4_critical_temperature); ++ w83795_write(dev, W83795_REG_CTFS(4), config->temp5_critical_temperature); ++ w83795_write(dev, W83795_REG_CTFS(5), config->temp6_critical_temperature); ++ ++ /* Set fan control target temperatures */ ++ w83795_write(dev, W83795_REG_TTTI(0), config->temp1_target_temperature); ++ w83795_write(dev, W83795_REG_TTTI(1), config->temp2_target_temperature); ++ w83795_write(dev, W83795_REG_TTTI(2), config->temp3_target_temperature); ++ w83795_write(dev, W83795_REG_TTTI(3), config->temp4_target_temperature); ++ w83795_write(dev, W83795_REG_TTTI(4), config->temp5_target_temperature); ++ w83795_write(dev, W83795_REG_TTTI(5), config->temp6_target_temperature); ++ ++ /* Set fan stall prevention parameters */ ++ w83795_write(dev, W83795_REG_FAN_NONSTOP(0), config->fan1_nonstop); ++ w83795_write(dev, W83795_REG_FAN_NONSTOP(1), config->fan2_nonstop); ++ w83795_write(dev, W83795_REG_FAN_NONSTOP(2), config->fan3_nonstop); ++ w83795_write(dev, W83795_REG_FAN_NONSTOP(3), config->fan4_nonstop); ++ w83795_write(dev, W83795_REG_FAN_NONSTOP(4), config->fan5_nonstop); ++ w83795_write(dev, W83795_REG_FAN_NONSTOP(5), config->fan6_nonstop); ++ w83795_write(dev, W83795_REG_FAN_NONSTOP(6), config->fan7_nonstop); ++ w83795_write(dev, W83795_REG_FAN_NONSTOP(7), config->fan8_nonstop); ++ ++ /* Set fan default speed */ ++ w83795_write(dev, W83795_REG_DFSP, fan_pct_to_cfg_val(config->default_speed)); ++ ++ /* Set initial fan speeds */ ++ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(0), fan_pct_to_cfg_val(config->fan1_duty)); ++ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(1), fan_pct_to_cfg_val(config->fan2_duty)); ++ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(2), fan_pct_to_cfg_val(config->fan3_duty)); ++ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(3), fan_pct_to_cfg_val(config->fan4_duty)); ++ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(4), fan_pct_to_cfg_val(config->fan5_duty)); ++ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(5), fan_pct_to_cfg_val(config->fan6_duty)); ++ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(6), fan_pct_to_cfg_val(config->fan7_duty)); ++ w83795_write(dev, W83795_REG_FAN_MANUAL_SPEED(7), fan_pct_to_cfg_val(config->fan8_duty)); ++ ++ /* Voltage monitor settings */ ++ w83795_write(dev, W83795_REG_VOLT_CTRL1, config->volt_ctl1); ++ w83795_write(dev, W83795_REG_VOLT_CTRL2, config->volt_ctl2); ++ ++ /* Voltage high/low limits */ ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(0), millivolts_to_limit_value_type1(config->vcore1_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(0), millivolts_to_limit_value_type1(config->vcore1_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(1), millivolts_to_limit_value_type1(config->vcore2_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(1), millivolts_to_limit_value_type1(config->vcore2_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(2), millivolts_to_limit_value_type1(config->vsen3_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(2), millivolts_to_limit_value_type1(config->vsen3_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(3), millivolts_to_limit_value_type1(config->vsen4_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(3), millivolts_to_limit_value_type1(config->vsen4_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(4), millivolts_to_limit_value_type1(config->vsen5_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(4), millivolts_to_limit_value_type1(config->vsen5_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(5), millivolts_to_limit_value_type1(config->vsen6_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(5), millivolts_to_limit_value_type1(config->vsen6_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(6), millivolts_to_limit_value_type1(config->vsen7_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(6), millivolts_to_limit_value_type1(config->vsen7_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(7), millivolts_to_limit_value_type1(config->vsen8_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(7), millivolts_to_limit_value_type1(config->vsen8_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(8), millivolts_to_limit_value_type1(config->vsen9_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(8), millivolts_to_limit_value_type1(config->vsen9_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(9), millivolts_to_limit_value_type1(config->vsen10_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(9), millivolts_to_limit_value_type1(config->vsen10_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(10), millivolts_to_limit_value_type1(config->vsen11_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(10), millivolts_to_limit_value_type1(config->vsen11_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(11), millivolts_to_limit_value_type1(config->vtt_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(11), millivolts_to_limit_value_type1(config->vtt_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(12), millivolts_to_limit_value_type2(config->vdd_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(12), millivolts_to_limit_value_type2(config->vdd_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(13), millivolts_to_limit_value_type2(config->vsb_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(13), millivolts_to_limit_value_type2(config->vsb_low_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH(14), millivolts_to_limit_value_type2(config->vbat_high_limit_mv)); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW(14), millivolts_to_limit_value_type2(config->vbat_low_limit_mv)); ++ ++ /* VSEN12 limits */ ++ if (config->temp_ctl1 & 0x2) { ++ limit_value = millivolts_to_limit_value_type3(config->vsen12_high_limit_mv); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH_2_M(4), limit_value >> 2); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH_2_L(4), limit_value & 0x3); ++ limit_value = millivolts_to_limit_value_type3(config->vsen12_low_limit_mv); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW_2_M(4), limit_value >> 2); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW_2_L(4), limit_value & 0x3); ++ } + +- /* enable monitoring operations */ +- val = w83795_read(W83795_REG_CONFIG); +- val |= W83795_REG_CONFIG_START; +- w83795_write(W83795_REG_CONFIG, val); ++ /* VSEN13 limits */ ++ if (config->temp_ctl1 & 0x8) { ++ limit_value = millivolts_to_limit_value_type3(config->vsen13_high_limit_mv); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH_2_M(5), limit_value >> 2); ++ w83795_write(dev, W83795_REG_VOLT_LIM_HIGH_2_L(5), limit_value & 0x3); ++ limit_value = millivolts_to_limit_value_type3(config->vsen13_low_limit_mv); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW_2_M(5), limit_value >> 2); ++ w83795_write(dev, W83795_REG_VOLT_LIM_LOW_2_L(5), limit_value & 0x3); ++ } + +- w83795_dts_enable(dts_src); +- w83795_set_fan(mode); ++ w83795_set_fan(dev, mode); + + printk(BIOS_INFO, "Fan CTFS(celsius) TTTI(celsius)\n"); + for (i = 0; i < 6; i++) { +- val = w83795_read(W83795_REG_CTFS(i)); ++ val = w83795_read(dev, W83795_REG_CTFS(i)); + printk(BIOS_INFO, " %x %d", i, val); +- val = w83795_read(W83795_REG_TTTI(i)); ++ val = w83795_read(dev, W83795_REG_TTTI(i)); + printk(BIOS_INFO, " %d\n", val); + } + + /* Temperature ReadOut */ + for (i = 0; i < 9; i++) { +- val = w83795_read(W83795_REG_DTS(i)); ++ val = w83795_read(dev, W83795_REG_DTS(i)); + printk(BIOS_DEBUG, "DTS%x ReadOut=%x\n", i, val); + } ++ ++ /* start monitoring operation */ ++ val = w83795_read(dev, W83795_REG_CONFIG); ++ val |= W83795_REG_CONFIG_START; ++ w83795_write(dev, W83795_REG_CONFIG, val); + } + + static void w83795_hwm_init(struct device *dev) +@@ -232,9 +345,9 @@ static void w83795_hwm_init(struct device *dev) + die("CPU: missing cpu device structure"); + + if (cpu->vendor == X86_VENDOR_AMD) +- w83795_init(THERMAL_CRUISE_MODE, DTS_SRC_AMD_SBTSI); ++ w83795_init(dev, THERMAL_CRUISE_MODE, DTS_SRC_AMD_SBTSI); + else if (cpu->vendor == X86_VENDOR_INTEL) +- w83795_init(THERMAL_CRUISE_MODE, DTS_SRC_INTEL_PECI); ++ w83795_init(dev, THERMAL_CRUISE_MODE, DTS_SRC_INTEL_PECI); + else + printk(BIOS_ERR, "Neither AMD nor INTEL CPU detected\n"); + } +diff --git a/src/drivers/i2c/w83795/w83795.h b/src/drivers/i2c/w83795/w83795.h +index cac4d5f..ef603f5 100644 +--- a/src/drivers/i2c/w83795/w83795.h ++++ b/src/drivers/i2c/w83795/w83795.h +@@ -2,6 +2,7 @@ + * This file is part of the coreboot project. + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. ++ * Copyright (C) 2015 Raptor Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -20,8 +21,6 @@ + #ifndef _W83795_H_ + #define _W83795_H_ + +-#define W83795_DEV 0x2F /* Host I2c Addr (strap to addr1 addr0 1 1, 0x5E) */ +- + #define W83795_REG_I2C_ADDR 0xFC + #define W83795_REG_BANKSEL 0x00 + #define W83795_REG_CONFIG 0x01 +@@ -29,6 +28,8 @@ + #define W83795_REG_CONFIG_CONFIG48 0x04 + #define W83795_REG_CONFIG_INIT 0x80 + ++#define W83795_REG_VOLT_CTRL1 0x02 ++#define W83795_REG_VOLT_CTRL2 0x03 + #define W83795_REG_TEMP_CTRL1 0x04 /* Temperature Monitoring Control Register */ + #define W83795_REG_TEMP_CTRL2 0x05 /* Temperature Monitoring Control Register */ + #define W83795_REG_FANIN_CTRL1 0x06 +@@ -37,37 +38,58 @@ + #define DTS_SRC_INTEL_PECI (0 << 0) + #define DTS_SRC_AMD_SBTSI (1 << 0) + +-#define W83795_REG_TSS(n) (0x209 + (n)) /* Temperature Source Selection Register */ + #define W83795_REG_TTTI(n) (0x260 + (n)) /* Target temperature W83795G/ADG will try to tune the fan output to keep */ + #define W83795_REG_CTFS(n) (0x268 + (n)) /* Critical Temperature to Full Speed all fan */ +-#define W83795_REG_HT(n) (0x270 + (n)) /* Hysteresis of Temperature */ + #define W83795_REG_DTSC 0x301 /* Digital Temperature Sensor Configuration */ + + #define W83795_REG_DTSE 0x302 /* Digital Temperature Sensor Enable */ + #define W83795_REG_DTS(n) (0x26 + (n)) + #define W83795_REG_VRLSB 0x3C + +-#define W83795_TEMP_REG_TR1 0x21 +-#define W83795_TEMP_REG_TR2 0x22 +-#define W83795_TEMP_REG_TR3 0x23 +-#define W83795_TEMP_REG_TR4 0x24 +-#define W83795_TEMP_REG_TR5 0x1F +-#define W83795_TEMP_REG_TR6 0x20 ++#define W83795_REG_TEMP_TR1 0x21 ++#define W83795_REG_TEMP_TR2 0x22 ++#define W83795_REG_TEMP_TR3 0x23 ++#define W83795_REG_TEMP_TR4 0x24 ++#define W83795_REG_TEMP_TR5 0x1F ++#define W83795_REG_TEMP_TR6 0x20 ++ ++#define W83795_REG_VOLT_LIM_HIGH(n) (0x70 + (n * 2)) /* Voltage high limit (0 == VSEN1) */ ++#define W83795_REG_VOLT_LIM_LOW(n) (0x71 + (n * 2)) /* Voltage low limit (0 == VSEN1) */ ++#define W83795_REG_VOLT_LIM_HIGH_2_M(n) (0x96 + (n * 4)) /* Voltage high limit MSB (0 == VDSEN14) */ ++#define W83795_REG_VOLT_LIM_LOW_2_M(n) (0x97 + (n * 4)) /* Voltage low limit MSB (0 == VDSEN14) */ ++#define W83795_REG_VOLT_LIM_HIGH_2_L(n) (0x98 + (n * 4)) /* Voltage high limit LSB (0 == VDSEN14) */ ++#define W83795_REG_VOLT_LIM_LOW_2_L(n) (0x99 + (n * 4)) /* Voltage low limit LSB (0 == VDSEN14) */ ++ ++#define W83795_REG_TEMP_CRIT(n) (0x96 + (n * 4)) /* Temperature critical limit */ ++#define W83795_REG_TEMP_CRIT_HYSTER(n) (0x97 + (n * 4)) /* Temperature critical limit hysteresis */ ++#define W83795_REG_TEMP_WARN(n) (0x98 + (n * 4)) /* Temperature warning limit */ ++#define W83795_REG_TEMP_WARN_HYSTER(n) (0x99 + (n * 4)) /* Temperature warning limit hysteresis */ ++ ++#define W83795_REG_DTS_CRIT 0xB2 /* Temperature critical limit */ ++#define W83795_REG_DTS_CRIT_HYSTER 0xB3 /* Temperature critical limit hysteresis */ ++#define W83795_REG_DTS_WARN 0xB4 /* Temperature warning limit */ ++#define W83795_REG_DTS_WARN_HYSTER 0xB5 /* Temperature warning limit hysteresis */ + + #define W83795_REG_FCMS1 0x201 + #define W83795_REG_FCMS2 0x208 +-#define W83795_REG_TFMR(n) (0x202 + (n)) /*temperature to fam mappig*/ ++#define W83795_REG_TFMR(n) (0x202 + (n)) /* Temperature to fan mapping */ ++#define W83795_REG_T12TSS 0x209 /* Temperature Source Selection Register 1 */ ++#define W83795_REG_T34TSS 0x20A /* Temperature Source Selection Register 2 */ ++#define W83795_REG_T56TSS 0x20B /* Temperature Source Selection Register 3 */ ++#define W83795_REG_FAN_MANUAL_SPEED(n) (0x210 + n) + #define W83795_REG_DFSP 0x20C + ++#define W83795_REG_FAN_NONSTOP(n) (0x228 + (n)) /* Fan Nonstop Value */ ++ + #define W83795_REG_FTSH(n) (0x240 + (n) * 2) + #define W83795_REG_FTSL(n) (0x241 + (n) * 2) + #define W83795_REG_TFTS 0x250 + + typedef enum w83795_fan_mode { +- SPEED_CRUISE_MODE, ///< Fan Speed Cruise mode keeps the fan speed in a specified range +- THERMAL_CRUISE_MODE, ///< Thermal Cruise mode is an algorithm to control the fan speed to keep the temperature source around the TTTI +- SMART_FAN_MODE, ///< Smart Fan mode offers 6 slopes to control the fan speed +- MANUAL_MODE, ///< control manually ++ SPEED_CRUISE_MODE = 0, ///< Fan Speed Cruise mode keeps the fan speed in a specified range ++ THERMAL_CRUISE_MODE = 1, ///< Thermal Cruise mode is an algorithm to control the fan speed to keep the temperature source around the TTTI ++ SMART_FAN_MODE = 2, ///< Smart Fan mode offers 6 slopes to control the fan speed ++ MANUAL_MODE = 3, ///< control manually + } w83795_fan_mode_t; + + #endif +-- +1.7.9.5 + diff --git a/resources/libreboot/patch/kgpe-d16/0003-drivers-i2c-w83795-Add-option-to-use-auxiliary-SMBUS.patch b/resources/libreboot/patch/kgpe-d16/0003-drivers-i2c-w83795-Add-option-to-use-auxiliary-SMBUS.patch @@ -1,62 +0,0 @@ -From 3e2be2d88101331eedb59c1459630b553c7cb660 Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <tpearson@raptorengineeringinc.com> -Date: Sat, 17 Oct 2015 04:37:10 -0500 -Subject: [PATCH 003/139] drivers/i2c/w83795: Add option to use auxiliary SMBUS - controller - -Change-Id: I5a9b5eba992853b84b0cb6c3a1764edf42ac49b2 -Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> ---- - src/drivers/i2c/w83795/chip.h | 4 ++++ - src/drivers/i2c/w83795/w83795.c | 14 ++++++++++++++ - 2 files changed, 18 insertions(+) - -diff --git a/src/drivers/i2c/w83795/chip.h b/src/drivers/i2c/w83795/chip.h -index effe119..413ea87 100644 ---- a/src/drivers/i2c/w83795/chip.h -+++ b/src/drivers/i2c/w83795/chip.h -@@ -139,4 +139,8 @@ struct drivers_i2c_w83795_config { - uint8_t fan6_duty; /* % of full speed (0-100) */ - uint8_t fan7_duty; /* % of full speed (0-100) */ - uint8_t fan8_duty; /* % of full speed (0-100) */ -+ -+ uint8_t smbus_aux; /* 0 == device located on first SMBUS, -+ * 1 == device located on auxiliary SMBUS -+ */ - }; -diff --git a/src/drivers/i2c/w83795/w83795.c b/src/drivers/i2c/w83795/w83795.c -index cf0cf2f..453e0af 100644 ---- a/src/drivers/i2c/w83795/w83795.c -+++ b/src/drivers/i2c/w83795/w83795.c -@@ -141,7 +141,16 @@ static void w83795_init(struct device *dev, w83795_fan_mode_t mode, u8 dts_src) - uint8_t val; - uint16_t limit_value; - -+#if IS_ENABLED(CONFIG_SMBUS_HAS_AUX) -+ uint8_t smbus_aux_prev = smbus_switched_to_aux(); -+ smbus_switch_to_aux(config->smbus_aux); -+#endif -+ - if (smbus_read_byte(dev, 0x00) < 0) { -+#if IS_ENABLED(CONFIG_SMBUS_HAS_AUX) -+ /* Restore SMBUS channel setting */ -+ smbus_switch_to_aux(smbus_aux_prev); -+#endif - printk(BIOS_ERR, "W83795G/ADG Nuvoton H/W Monitor not found\n"); - return; - } -@@ -325,6 +334,11 @@ static void w83795_init(struct device *dev, w83795_fan_mode_t mode, u8 dts_src) - val = w83795_read(dev, W83795_REG_CONFIG); - val |= W83795_REG_CONFIG_START; - w83795_write(dev, W83795_REG_CONFIG, val); -+ -+#if IS_ENABLED(CONFIG_SMBUS_HAS_AUX) -+ /* Restore SMBUS channel setting */ -+ smbus_switch_to_aux(smbus_aux_prev); -+#endif - } - - static void w83795_hwm_init(struct device *dev) --- -1.9.1 - diff --git a/resources/libreboot/patch/kgpe-d16/0004-drivers-aspeed-Add-native-text-mode-VGA-support-for-.patch b/resources/libreboot/patch/kgpe-d16/0004-drivers-aspeed-Add-native-text-mode-VGA-support-for-.patch @@ -1,3675 +0,0 @@ -From 7075bbddd264958b80ea4831b602b6fbfaf60b0d Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <tpearson@raptorengineeringinc.com> -Date: Sat, 5 Sep 2015 17:38:09 -0500 -Subject: [PATCH 004/139] drivers/aspeed: Add native text mode VGA support for - the AST2050 - -Change-Id: I37763a59d2546cd0c0e57b31fdb7aa77c2c50bee -Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> ---- - src/drivers/aspeed/Kconfig | 2 + - src/drivers/aspeed/Makefile.inc | 1 + - src/drivers/aspeed/ast2050/Kconfig | 14 + - src/drivers/aspeed/ast2050/Makefile.inc | 1 + - src/drivers/aspeed/ast2050/ast2050.c | 83 ++ - src/drivers/aspeed/common/Kconfig | 10 + - src/drivers/aspeed/common/Makefile.inc | 1 + - src/drivers/aspeed/common/aspeed_coreboot.h | 210 ++++ - src/drivers/aspeed/common/ast_dp501.c | 443 +++++++ - src/drivers/aspeed/common/ast_dram_tables.h | 165 +++ - src/drivers/aspeed/common/ast_drv.h | 223 ++++ - src/drivers/aspeed/common/ast_main.c | 393 +++++++ - src/drivers/aspeed/common/ast_post.c | 1679 +++++++++++++++++++++++++++ - src/drivers/aspeed/common/ast_tables.h | 305 +++++ - src/include/device/pci_ids.h | 3 + - 15 files changed, 3533 insertions(+) - create mode 100644 src/drivers/aspeed/Kconfig - create mode 100644 src/drivers/aspeed/Makefile.inc - create mode 100644 src/drivers/aspeed/ast2050/Kconfig - create mode 100644 src/drivers/aspeed/ast2050/Makefile.inc - create mode 100644 src/drivers/aspeed/ast2050/ast2050.c - create mode 100644 src/drivers/aspeed/common/Kconfig - create mode 100644 src/drivers/aspeed/common/Makefile.inc - create mode 100644 src/drivers/aspeed/common/aspeed_coreboot.h - create mode 100644 src/drivers/aspeed/common/ast_dp501.c - create mode 100644 src/drivers/aspeed/common/ast_dram_tables.h - create mode 100644 src/drivers/aspeed/common/ast_drv.h - create mode 100644 src/drivers/aspeed/common/ast_main.c - create mode 100644 src/drivers/aspeed/common/ast_post.c - create mode 100644 src/drivers/aspeed/common/ast_tables.h - -diff --git a/src/drivers/aspeed/Kconfig b/src/drivers/aspeed/Kconfig -new file mode 100644 -index 0000000..27469b5 ---- /dev/null -+++ b/src/drivers/aspeed/Kconfig -@@ -0,0 +1,2 @@ -+source src/drivers/aspeed/common/Kconfig -+source src/drivers/aspeed/ast2050/Kconfig -\ No newline at end of file -diff --git a/src/drivers/aspeed/Makefile.inc b/src/drivers/aspeed/Makefile.inc -new file mode 100644 -index 0000000..955a213 ---- /dev/null -+++ b/src/drivers/aspeed/Makefile.inc -@@ -0,0 +1 @@ -+subdirs-y += common ast2050 -\ No newline at end of file -diff --git a/src/drivers/aspeed/ast2050/Kconfig b/src/drivers/aspeed/ast2050/Kconfig -new file mode 100644 -index 0000000..f110d58 ---- /dev/null -+++ b/src/drivers/aspeed/ast2050/Kconfig -@@ -0,0 +1,14 @@ -+config DRIVERS_ASPEED_AST2050 -+ bool -+ -+if DRIVERS_ASPEED_AST2050 -+ -+config DEVICE_SPECIFIC_OPTIONS # dummy -+ def_bool y -+ select DRIVERS_ASPEED_AST_COMMON -+ -+config NATIVE_VGA_INIT_USE_EDID -+ bool -+ default n -+ -+endif # DRIVERS_ASPEED_AST2050 -diff --git a/src/drivers/aspeed/ast2050/Makefile.inc b/src/drivers/aspeed/ast2050/Makefile.inc -new file mode 100644 -index 0000000..3ba9dde ---- /dev/null -+++ b/src/drivers/aspeed/ast2050/Makefile.inc -@@ -0,0 +1 @@ -+ramstage-$(CONFIG_DRIVERS_ASPEED_AST2050) += ast2050.c -\ No newline at end of file -diff --git a/src/drivers/aspeed/ast2050/ast2050.c b/src/drivers/aspeed/ast2050/ast2050.c -new file mode 100644 -index 0000000..809e9de ---- /dev/null -+++ b/src/drivers/aspeed/ast2050/ast2050.c -@@ -0,0 +1,83 @@ -+/* -+ * This file is part of the coreboot project. -+ * -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+#include <delay.h> -+#include <stdlib.h> -+#include <string.h> -+#include <arch/io.h> -+#include <edid.h> -+ -+#include <console/console.h> -+#include <device/device.h> -+#include <device/pci.h> -+#include <device/pci_ids.h> -+#include <device/pci_ops.h> -+ -+#include <pc80/vga.h> -+ -+#include "../common/aspeed_coreboot.h" -+#include "../common/ast_drv.h" -+ -+static void aspeed_ast2050_set_resources(device_t dev) -+{ -+ /* Reserve VGA regions */ -+ mmio_resource(dev, 3, 0xa0000 >> 10, 0x1ffff >> 10); -+ -+ /* Run standard resource set routine */ -+ pci_dev_set_resources(dev); -+} -+ -+static void aspeed_ast2050_init(struct device *dev) -+{ -+ u8 ret; -+ struct drm_device drm_dev; -+ -+ drm_dev.pdev = dev; -+ -+ printk(BIOS_INFO, "ASpeed AST2050: initializing video device\n"); -+ ret = ast_driver_load(&drm_dev, 0); -+ -+ /* Unlock extended configuration registers */ -+ outb(0x80, 0x3d4); outb(0xa8, 0x3d5); -+ -+ /* Set CRT Request Threshold */ -+ outb(0xa6, 0x3d4); outb(0x2f, 0x3d5); -+ outb(0xa7, 0x3d4); outb(0x3f, 0x3d5); -+ -+ /* Initialize standard VGA text mode */ -+ vga_io_init(); -+ vga_textmode_init(); -+ printk(BIOS_INFO, "ASpeed VGA text mode initialized\n"); -+ -+ /* if we don't have console, at least print something... */ -+ vga_line_write(0, "ASpeed VGA text mode initialized"); -+} -+ -+static struct device_operations aspeed_ast2050_ops = { -+ .read_resources = pci_dev_read_resources, -+ .set_resources = aspeed_ast2050_set_resources, -+ .enable_resources = pci_dev_enable_resources, -+ .init = aspeed_ast2050_init, -+ .scan_bus = 0, -+}; -+ -+static const struct pci_driver aspeed_ast2050_driver __pci_driver = { -+ .ops = &aspeed_ast2050_ops, -+ .vendor = PCI_VENDOR_ID_ASPEED, -+ .device = PCI_DEVICE_ID_ASPEED_AST2050_VGA, -+}; -diff --git a/src/drivers/aspeed/common/Kconfig b/src/drivers/aspeed/common/Kconfig -new file mode 100644 -index 0000000..0f7056b ---- /dev/null -+++ b/src/drivers/aspeed/common/Kconfig -@@ -0,0 +1,10 @@ -+config DRIVERS_ASPEED_AST_COMMON -+ bool -+ -+if !MAINBOARD_DO_NATIVE_VGA_INIT -+ -+config DEVICE_SPECIFIC_OPTIONS # dummy -+ def_bool y -+ select VGA -+ -+endif # MAINBOARD_DO_NATIVE_VGA_INIT -diff --git a/src/drivers/aspeed/common/Makefile.inc b/src/drivers/aspeed/common/Makefile.inc -new file mode 100644 -index 0000000..75f8b48 ---- /dev/null -+++ b/src/drivers/aspeed/common/Makefile.inc -@@ -0,0 +1 @@ -+ramstage-$(CONFIG_DRIVERS_ASPEED_AST_COMMON) += ast_dp501.c ast_main.c ast_post.c -diff --git a/src/drivers/aspeed/common/aspeed_coreboot.h b/src/drivers/aspeed/common/aspeed_coreboot.h -new file mode 100644 -index 0000000..237c23f ---- /dev/null -+++ b/src/drivers/aspeed/common/aspeed_coreboot.h -@@ -0,0 +1,210 @@ -+/* -+ * This file is part of the coreboot project. -+ * -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef _ASPEED_COREBOOT_ -+#define _ASPEED_COREBOOT_ -+ -+#include <delay.h> -+#include <stdlib.h> -+#include <stdint.h> -+#include <string.h> -+#include <arch/io.h> -+ -+#include <console/console.h> -+#include <device/device.h> -+#include <device/pci.h> -+#include <device/pci_ids.h> -+#include <device/pci_ops.h> -+ -+/* coreboot <--> kernel code interface */ -+#define __iomem -+typedef u64 phys_addr_t; -+#define pci_dev device -+ -+#define SZ_16M 0x01000000 -+ -+#define min_t(type, x, y) ({ \ -+ type __min1 = (x); \ -+ type __min2 = (y); \ -+ __min1 < __min2 ? __min1 : __min2; }) -+ -+#define dev_info(dev, format, arg...) printk(BIOS_INFO, "ASpeed VGA: " format, ##arg) -+#define dev_dbg(dev, format, arg...) printk(BIOS_DEBUG, "ASpeed VGA: " format, ##arg) -+#define dev_err(dev, format, arg...) printk(BIOS_ERR, "ASpeed VGA: " format, ##arg) -+ -+#define pr_info(format, arg...) printk(BIOS_INFO, "ASpeed VGA: " format, ##arg) -+#define pr_debug(format, arg...) printk(BIOS_INFO, "ASpeed VGA: " format, ##arg) -+#define pr_err(format, arg...) printk(BIOS_ERR, "ASpeed VGA: " format, ##arg) -+ -+#define DRM_INFO pr_info -+ -+#define GFP_KERNEL 0 -+#define GFP_ATOMIC 1 -+#define kfree(address) free(address) -+ -+#define EIO 5 -+#define ENOMEM 12 -+ -+struct firmware { -+ size_t size; -+ const u8 *data; -+ struct page **pages; -+ -+ /* firmware loader private fields */ -+ void *priv; -+}; -+ -+struct drm_device { -+ struct pci_dev *pdev; -+ void *dev_private; -+}; -+ -+static inline void *kzalloc(size_t size, int flags) { -+ void* ptr = malloc(size); -+ memset(ptr, 0, size); -+ return ptr; -+} -+ -+static inline void writel(u32 val, volatile void *addr) { -+ *(u32*)addr = val; -+} -+ -+static inline u32 readl(const volatile void *addr) { -+ return *(u32*)addr; -+} -+ -+static inline void writew(u16 val, volatile void *addr) { -+ *(u16*)addr = val; -+} -+ -+static inline u16 readw(const volatile void *addr) { -+ return *(u16*)addr; -+} -+ -+static inline void writeb(u8 val, volatile void *addr) { -+ *(u8*)addr = val; -+} -+ -+static inline u8 readb(const volatile void *addr) { -+ return *(u8*)addr; -+} -+ -+static inline int pci_read_config_dword(struct pci_dev *dev, int where, -+ u32 *val) -+{ -+ *val = pci_read_config32(dev, where); -+ return 0; -+} -+ -+static inline int pci_write_config_dword(struct pci_dev *dev, int where, -+ u32 val) -+{ -+ pci_write_config32(dev, where, val); -+ return 0; -+} -+ -+static inline int pci_read_config_byte(struct pci_dev *dev, int where, -+ u8 *val) -+{ -+ *val = pci_read_config8(dev, where); -+ return 0; -+} -+ -+static inline struct resource* resource_at_bar(struct pci_dev *dev, u8 bar) { -+ struct resource *res = dev->resource_list; -+ int i; -+ for (i = 0; i < bar; i++) { -+ res = res->next; -+ if (res == NULL) -+ return NULL; -+ } -+ -+ return res; -+} -+ -+static inline resource_t pci_resource_len(struct pci_dev *dev, u8 bar) { -+ struct resource *res = resource_at_bar(dev, bar); -+ if (res) -+ return res->size; -+ else -+ return 0; -+} -+ -+static inline resource_t pci_resource_start(struct pci_dev *dev, u8 bar) { -+ struct resource *res = resource_at_bar(dev, bar); -+ if (res) -+ return res->base; -+ else -+ return 0; -+} -+ -+static inline unsigned int ioread32(void __iomem *p) { -+ return readl(p); -+} -+ -+static inline void iowrite32(u32 val, void __iomem *p) { -+ writel(val, p); -+} -+ -+static inline unsigned int ioread16(void __iomem *p) { -+ return readw(p); -+} -+ -+static inline void iowrite16(u16 val, void __iomem *p) { -+ writew(val, p); -+} -+ -+static inline unsigned int ioread8(void __iomem *p) { -+ return readb(p); -+} -+ -+static inline void iowrite8(u8 val, void __iomem *p) { -+ writeb(val, p); -+} -+ -+static inline unsigned int ioread_cbio32(void __iomem *p) { -+ return inl((uint16_t)((intptr_t)p)); -+} -+ -+static inline void iowrite_cbio32(u32 val, void __iomem *p) { -+ outl(val, (uint16_t)((intptr_t)p)); -+} -+ -+static inline unsigned int ioread_cbio16(void __iomem *p) { -+ return inw((uint16_t)((intptr_t)p)); -+} -+ -+static inline void iowrite_cbio16(u16 val, void __iomem *p) { -+ outw(val, (uint16_t)((intptr_t)p)); -+} -+ -+static inline unsigned int ioread_cbio8(void __iomem *p) { -+ return inb((uint16_t)((intptr_t)p)); -+} -+ -+static inline void iowrite_cbio8(u8 val, void __iomem *p) { -+ outb(val, (uint16_t)((intptr_t)p)); -+} -+ -+static inline void msleep(unsigned int msecs) { -+ udelay(msecs * 1000); -+} -+ -+#endif -\ No newline at end of file -diff --git a/src/drivers/aspeed/common/ast_dp501.c b/src/drivers/aspeed/common/ast_dp501.c -new file mode 100644 -index 0000000..5be8ec3 ---- /dev/null -+++ b/src/drivers/aspeed/common/ast_dp501.c -@@ -0,0 +1,443 @@ -+/* -+ * This file is part of the coreboot project. -+ * -+ * File taken from the Linux ast driver (v3.18.5) -+ * Coreboot-specific includes added at top and/or contents modified -+ * as needed to function within the coreboot environment. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc. -+ */ -+ -+#include "ast_drv.h" -+ -+static void send_ack(struct ast_private *ast) -+{ -+ u8 sendack; -+ sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff); -+ sendack |= 0x80; -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack); -+} -+ -+static void send_nack(struct ast_private *ast) -+{ -+ u8 sendack; -+ sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff); -+ sendack &= ~0x80; -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack); -+} -+ -+static bool wait_ack(struct ast_private *ast) -+{ -+ u8 waitack; -+ u32 retry = 0; -+ do { -+ waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); -+ waitack &= 0x80; -+ udelay(100); -+ } while ((!waitack) && (retry++ < 1000)); -+ -+ if (retry < 1000) -+ return true; -+ else -+ return false; -+} -+ -+static bool wait_nack(struct ast_private *ast) -+{ -+ u8 waitack; -+ u32 retry = 0; -+ do { -+ waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); -+ waitack &= 0x80; -+ udelay(100); -+ } while ((waitack) && (retry++ < 1000)); -+ -+ if (retry < 1000) -+ return true; -+ else -+ return false; -+} -+ -+static void set_cmd_trigger(struct ast_private *ast) -+{ -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x40); -+} -+ -+static void clear_cmd_trigger(struct ast_private *ast) -+{ -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x00); -+} -+ -+#if 0 -+static bool wait_fw_ready(struct ast_private *ast) -+{ -+ u8 waitready; -+ u32 retry = 0; -+ do { -+ waitready = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); -+ waitready &= 0x40; -+ udelay(100); -+ } while ((!waitready) && (retry++ < 1000)); -+ -+ if (retry < 1000) -+ return true; -+ else -+ return false; -+} -+#endif -+ -+static bool ast_write_cmd(struct drm_device *dev, u8 data) -+{ -+ struct ast_private *ast = dev->dev_private; -+ int retry = 0; -+ if (wait_nack(ast)) { -+ send_nack(ast); -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data); -+ send_ack(ast); -+ set_cmd_trigger(ast); -+ do { -+ if (wait_ack(ast)) { -+ clear_cmd_trigger(ast); -+ send_nack(ast); -+ return true; -+ } -+ } while (retry++ < 100); -+ } -+ clear_cmd_trigger(ast); -+ send_nack(ast); -+ return false; -+} -+ -+static bool ast_write_data(struct drm_device *dev, u8 data) -+{ -+ struct ast_private *ast = dev->dev_private; -+ -+ if (wait_nack(ast)) { -+ send_nack(ast); -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data); -+ send_ack(ast); -+ if (wait_ack(ast)) { -+ send_nack(ast); -+ return true; -+ } -+ } -+ send_nack(ast); -+ return false; -+} -+ -+#if 0 -+static bool ast_read_data(struct drm_device *dev, u8 *data) -+{ -+ struct ast_private *ast = dev->dev_private; -+ u8 tmp; -+ -+ *data = 0; -+ -+ if (wait_ack(ast) == false) -+ return false; -+ tmp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd3, 0xff); -+ *data = tmp; -+ if (wait_nack(ast) == false) { -+ send_nack(ast); -+ return false; -+ } -+ send_nack(ast); -+ return true; -+} -+ -+static void clear_cmd(struct ast_private *ast) -+{ -+ send_nack(ast); -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, 0x00); -+} -+#endif -+ -+void ast_set_dp501_video_output(struct drm_device *dev, u8 mode) -+{ -+ ast_write_cmd(dev, 0x40); -+ ast_write_data(dev, mode); -+ -+ msleep(10); -+} -+ -+static u32 get_fw_base(struct ast_private *ast) -+{ -+ return ast_mindwm(ast, 0x1e6e2104) & 0x7fffffff; -+} -+ -+bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size) -+{ -+ struct ast_private *ast = dev->dev_private; -+ u32 i, data; -+ u32 boot_address; -+ -+ data = ast_mindwm(ast, 0x1e6e2100) & 0x01; -+ if (data) { -+ boot_address = get_fw_base(ast); -+ for (i = 0; i < size; i += 4) -+ *(u32 *)(addr + i) = ast_mindwm(ast, boot_address + i); -+ return true; -+ } -+ return false; -+} -+ -+bool ast_launch_m68k(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ u32 i, data, len = 0; -+ u32 boot_address; -+ u8 *fw_addr = NULL; -+ u8 jreg; -+ -+ data = ast_mindwm(ast, 0x1e6e2100) & 0x01; -+ if (!data) { -+ -+ if (ast->dp501_fw_addr) { -+ fw_addr = ast->dp501_fw_addr; -+ len = 32*1024; -+ } else if (ast->dp501_fw) { -+ fw_addr = (u8 *)ast->dp501_fw->data; -+ len = ast->dp501_fw->size; -+ } -+ /* Get BootAddress */ -+ ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8); -+ data = ast_mindwm(ast, 0x1e6e0004); -+ switch (data & 0x03) { -+ case 0: -+ boot_address = 0x44000000; -+ break; -+ default: -+ case 1: -+ boot_address = 0x48000000; -+ break; -+ case 2: -+ boot_address = 0x50000000; -+ break; -+ case 3: -+ boot_address = 0x60000000; -+ break; -+ } -+ boot_address -= 0x200000; /* -2MB */ -+ -+ /* copy image to buffer */ -+ for (i = 0; i < len; i += 4) { -+ data = *(u32 *)(fw_addr + i); -+ ast_moutdwm(ast, boot_address + i, data); -+ } -+ -+ /* Init SCU */ -+ ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8); -+ -+ /* Launch FW */ -+ ast_moutdwm(ast, 0x1e6e2104, 0x80000000 + boot_address); -+ ast_moutdwm(ast, 0x1e6e2100, 1); -+ -+ /* Update Scratch */ -+ data = ast_mindwm(ast, 0x1e6e2040) & 0xfffff1ff; /* D[11:9] = 100b: UEFI handling */ -+ data |= 0x800; -+ ast_moutdwm(ast, 0x1e6e2040, data); -+ -+ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */ -+ jreg |= 0x02; -+ ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x99, jreg); -+ } -+ return true; -+} -+ -+u8 ast_get_dp501_max_clk(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ u32 boot_address, offset, data; -+ u8 linkcap[4], linkrate, linklanes, maxclk = 0xff; -+ -+ boot_address = get_fw_base(ast); -+ -+ /* validate FW version */ -+ offset = 0xf000; -+ data = ast_mindwm(ast, boot_address + offset); -+ if ((data & 0xf0) != 0x10) /* version: 1x */ -+ return maxclk; -+ -+ /* Read Link Capability */ -+ offset = 0xf014; -+ data = ast_mindwm(ast, boot_address + offset); -+ linkcap[0] = (data & 0xff000000) >> 24; -+ linkcap[1] = (data & 0x00ff0000) >> 16; -+ linkcap[2] = (data & 0x0000ff00) >> 8; -+ linkcap[3] = (data & 0x000000ff); -+ if (linkcap[2] == 0) { -+ linkrate = linkcap[0]; -+ linklanes = linkcap[1]; -+ data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes); -+ if (data > 0xff) -+ data = 0xff; -+ maxclk = (u8)data; -+ } -+ return maxclk; -+} -+ -+bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata) -+{ -+ struct ast_private *ast = dev->dev_private; -+ u32 i, boot_address, offset, data; -+ -+ boot_address = get_fw_base(ast); -+ -+ /* validate FW version */ -+ offset = 0xf000; -+ data = ast_mindwm(ast, boot_address + offset); -+ if ((data & 0xf0) != 0x10) -+ return false; -+ -+ /* validate PnP Monitor */ -+ offset = 0xf010; -+ data = ast_mindwm(ast, boot_address + offset); -+ if (!(data & 0x01)) -+ return false; -+ -+ /* Read EDID */ -+ offset = 0xf020; -+ for (i = 0; i < 128; i += 4) { -+ data = ast_mindwm(ast, boot_address + offset + i); -+ *(u32 *)(ediddata + i) = data; -+ } -+ -+ return true; -+} -+ -+static bool ast_init_dvo(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ u8 jreg; -+ u32 data; -+ ast_write32(ast, 0xf004, 0x1e6e0000); -+ ast_write32(ast, 0xf000, 0x1); -+ ast_write32(ast, 0x12000, 0x1688a8a8); -+ -+ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); -+ if (!(jreg & 0x80)) { -+ /* Init SCU DVO Settings */ -+ data = ast_read32(ast, 0x12008); -+ /* delay phase */ -+ data &= 0xfffff8ff; -+ data |= 0x00000500; -+ ast_write32(ast, 0x12008, data); -+ -+ if (ast->chip == AST2300) { -+ data = ast_read32(ast, 0x12084); -+ /* multi-pins for DVO single-edge */ -+ data |= 0xfffe0000; -+ ast_write32(ast, 0x12084, data); -+ -+ data = ast_read32(ast, 0x12088); -+ /* multi-pins for DVO single-edge */ -+ data |= 0x000fffff; -+ ast_write32(ast, 0x12088, data); -+ -+ data = ast_read32(ast, 0x12090); -+ /* multi-pins for DVO single-edge */ -+ data &= 0xffffffcf; -+ data |= 0x00000020; -+ ast_write32(ast, 0x12090, data); -+ } else { /* AST2400 */ -+ data = ast_read32(ast, 0x12088); -+ /* multi-pins for DVO single-edge */ -+ data |= 0x30000000; -+ ast_write32(ast, 0x12088, data); -+ -+ data = ast_read32(ast, 0x1208c); -+ /* multi-pins for DVO single-edge */ -+ data |= 0x000000cf; -+ ast_write32(ast, 0x1208c, data); -+ -+ data = ast_read32(ast, 0x120a4); -+ /* multi-pins for DVO single-edge */ -+ data |= 0xffff0000; -+ ast_write32(ast, 0x120a4, data); -+ -+ data = ast_read32(ast, 0x120a8); -+ /* multi-pins for DVO single-edge */ -+ data |= 0x0000000f; -+ ast_write32(ast, 0x120a8, data); -+ -+ data = ast_read32(ast, 0x12094); -+ /* multi-pins for DVO single-edge */ -+ data |= 0x00000002; -+ ast_write32(ast, 0x12094, data); -+ } -+ } -+ -+ /* Force to DVO */ -+ data = ast_read32(ast, 0x1202c); -+ data &= 0xfffbffff; -+ ast_write32(ast, 0x1202c, data); -+ -+ /* Init VGA DVO Settings */ -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); -+ return true; -+} -+ -+ -+static void ast_init_analog(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ u32 data; -+ -+ /* -+ * Set DAC source to VGA mode in SCU2C via the P2A -+ * bridge. First configure the P2U to target the SCU -+ * in case it isn't at this stage. -+ */ -+ ast_write32(ast, 0xf004, 0x1e6e0000); -+ ast_write32(ast, 0xf000, 0x1); -+ -+ /* Then unlock the SCU with the magic password */ -+ ast_write32(ast, 0x12000, 0x1688a8a8); -+ ast_write32(ast, 0x12000, 0x1688a8a8); -+ ast_write32(ast, 0x12000, 0x1688a8a8); -+ -+ /* Finally, clear bits [17:16] of SCU2c */ -+ data = ast_read32(ast, 0x1202c); -+ data &= 0xfffcffff; -+ ast_write32(ast, 0, data); -+ -+ /* Disable DVO */ -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x00); -+} -+ -+void ast_init_3rdtx(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ u8 jreg; -+ -+ if (ast->chip == AST2300 || ast->chip == AST2400) { -+ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); -+ switch (jreg & 0x0e) { -+ case 0x04: -+ ast_init_dvo(dev); -+ break; -+ case 0x08: -+ ast_launch_m68k(dev); -+ break; -+ case 0x0c: -+ ast_init_dvo(dev); -+ break; -+ default: -+ if (ast->tx_chip_type == AST_TX_SIL164) -+ ast_init_dvo(dev); -+ else -+ ast_init_analog(dev); -+ } -+ } -+} -diff --git a/src/drivers/aspeed/common/ast_dram_tables.h b/src/drivers/aspeed/common/ast_dram_tables.h -new file mode 100644 -index 0000000..4884cba ---- /dev/null -+++ b/src/drivers/aspeed/common/ast_dram_tables.h -@@ -0,0 +1,165 @@ -+/* -+ * This file is part of the coreboot project. -+ * -+ * File taken from the Linux ast driver (v3.18.5) -+ * Coreboot-specific includes added at top and/or contents modified -+ * as needed to function within the coreboot environment. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc. -+ */ -+ -+#ifndef AST_DRAM_TABLES_H -+#define AST_DRAM_TABLES_H -+ -+/* DRAM timing tables */ -+struct ast_dramstruct { -+ u16 index; -+ u32 data; -+}; -+ -+static const struct ast_dramstruct ast2000_dram_table_data[] = { -+ { 0x0108, 0x00000000 }, -+ { 0x0120, 0x00004a21 }, -+ { 0xFF00, 0x00000043 }, -+ { 0x0000, 0xFFFFFFFF }, -+ { 0x0004, 0x00000089 }, -+ { 0x0008, 0x22331353 }, -+ { 0x000C, 0x0d07000b }, -+ { 0x0010, 0x11113333 }, -+ { 0x0020, 0x00110350 }, -+ { 0x0028, 0x1e0828f0 }, -+ { 0x0024, 0x00000001 }, -+ { 0x001C, 0x00000000 }, -+ { 0x0014, 0x00000003 }, -+ { 0xFF00, 0x00000043 }, -+ { 0x0018, 0x00000131 }, -+ { 0x0014, 0x00000001 }, -+ { 0xFF00, 0x00000043 }, -+ { 0x0018, 0x00000031 }, -+ { 0x0014, 0x00000001 }, -+ { 0xFF00, 0x00000043 }, -+ { 0x0028, 0x1e0828f1 }, -+ { 0x0024, 0x00000003 }, -+ { 0x002C, 0x1f0f28fb }, -+ { 0x0030, 0xFFFFFE01 }, -+ { 0xFFFF, 0xFFFFFFFF } -+}; -+ -+static const struct ast_dramstruct ast1100_dram_table_data[] = { -+ { 0x2000, 0x1688a8a8 }, -+ { 0x2020, 0x000041f0 }, -+ { 0xFF00, 0x00000043 }, -+ { 0x0000, 0xfc600309 }, -+ { 0x006C, 0x00909090 }, -+ { 0x0064, 0x00050000 }, -+ { 0x0004, 0x00000585 }, -+ { 0x0008, 0x0011030f }, -+ { 0x0010, 0x22201724 }, -+ { 0x0018, 0x1e29011a }, -+ { 0x0020, 0x00c82222 }, -+ { 0x0014, 0x01001523 }, -+ { 0x001C, 0x1024010d }, -+ { 0x0024, 0x00cb2522 }, -+ { 0x0038, 0xffffff82 }, -+ { 0x003C, 0x00000000 }, -+ { 0x0040, 0x00000000 }, -+ { 0x0044, 0x00000000 }, -+ { 0x0048, 0x00000000 }, -+ { 0x004C, 0x00000000 }, -+ { 0x0050, 0x00000000 }, -+ { 0x0054, 0x00000000 }, -+ { 0x0058, 0x00000000 }, -+ { 0x005C, 0x00000000 }, -+ { 0x0060, 0x032aa02a }, -+ { 0x0064, 0x002d3000 }, -+ { 0x0068, 0x00000000 }, -+ { 0x0070, 0x00000000 }, -+ { 0x0074, 0x00000000 }, -+ { 0x0078, 0x00000000 }, -+ { 0x007C, 0x00000000 }, -+ { 0x0034, 0x00000001 }, -+ { 0xFF00, 0x00000043 }, -+ { 0x002C, 0x00000732 }, -+ { 0x0030, 0x00000040 }, -+ { 0x0028, 0x00000005 }, -+ { 0x0028, 0x00000007 }, -+ { 0x0028, 0x00000003 }, -+ { 0x0028, 0x00000001 }, -+ { 0x000C, 0x00005a08 }, -+ { 0x002C, 0x00000632 }, -+ { 0x0028, 0x00000001 }, -+ { 0x0030, 0x000003c0 }, -+ { 0x0028, 0x00000003 }, -+ { 0x0030, 0x00000040 }, -+ { 0x0028, 0x00000003 }, -+ { 0x000C, 0x00005a21 }, -+ { 0x0034, 0x00007c03 }, -+ { 0x0120, 0x00004c41 }, -+ { 0xffff, 0xffffffff }, -+}; -+ -+static const struct ast_dramstruct ast2100_dram_table_data[] = { -+ { 0x2000, 0x1688a8a8 }, -+ { 0x2020, 0x00004120 }, -+ { 0xFF00, 0x00000043 }, -+ { 0x0000, 0xfc600309 }, -+ { 0x006C, 0x00909090 }, -+ { 0x0064, 0x00070000 }, -+ { 0x0004, 0x00000489 }, -+ { 0x0008, 0x0011030f }, -+ { 0x0010, 0x32302926 }, -+ { 0x0018, 0x274c0122 }, -+ { 0x0020, 0x00ce2222 }, -+ { 0x0014, 0x01001523 }, -+ { 0x001C, 0x1024010d }, -+ { 0x0024, 0x00cb2522 }, -+ { 0x0038, 0xffffff82 }, -+ { 0x003C, 0x00000000 }, -+ { 0x0040, 0x00000000 }, -+ { 0x0044, 0x00000000 }, -+ { 0x0048, 0x00000000 }, -+ { 0x004C, 0x00000000 }, -+ { 0x0050, 0x00000000 }, -+ { 0x0054, 0x00000000 }, -+ { 0x0058, 0x00000000 }, -+ { 0x005C, 0x00000000 }, -+ { 0x0060, 0x0f2aa02a }, -+ { 0x0064, 0x003f3005 }, -+ { 0x0068, 0x02020202 }, -+ { 0x0070, 0x00000000 }, -+ { 0x0074, 0x00000000 }, -+ { 0x0078, 0x00000000 }, -+ { 0x007C, 0x00000000 }, -+ { 0x0034, 0x00000001 }, -+ { 0xFF00, 0x00000043 }, -+ { 0x002C, 0x00000942 }, -+ { 0x0030, 0x00000040 }, -+ { 0x0028, 0x00000005 }, -+ { 0x0028, 0x00000007 }, -+ { 0x0028, 0x00000003 }, -+ { 0x0028, 0x00000001 }, -+ { 0x000C, 0x00005a08 }, -+ { 0x002C, 0x00000842 }, -+ { 0x0028, 0x00000001 }, -+ { 0x0030, 0x000003c0 }, -+ { 0x0028, 0x00000003 }, -+ { 0x0030, 0x00000040 }, -+ { 0x0028, 0x00000003 }, -+ { 0x000C, 0x00005a21 }, -+ { 0x0034, 0x00007c03 }, -+ { 0x0120, 0x00005061 }, -+ { 0xffff, 0xffffffff }, -+}; -+ -+#endif -diff --git a/src/drivers/aspeed/common/ast_drv.h b/src/drivers/aspeed/common/ast_drv.h -new file mode 100644 -index 0000000..53640f1 ---- /dev/null -+++ b/src/drivers/aspeed/common/ast_drv.h -@@ -0,0 +1,223 @@ -+/* -+ * Copyright 2012 Red Hat Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sub license, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, -+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -+ * USE OR OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * The above copyright notice and this permission notice (including the -+ * next paragraph) shall be included in all copies or substantial portions -+ * of the Software. -+ * -+ */ -+/* -+ * Authors: Dave Airlie <airlied@redhat.com> -+ */ -+#ifndef __AST_DRV_H__ -+#define __AST_DRV_H__ -+ -+#include "aspeed_coreboot.h" -+ -+#define PCI_CHIP_AST2000 0x2000 -+#define PCI_CHIP_AST2100 0x2010 -+#define PCI_CHIP_AST1180 0x1180 -+ -+ -+enum ast_chip { -+ AST2000, -+ AST2100, -+ AST1100, -+ AST2200, -+ AST2150, -+ AST2300, -+ AST2400, -+ AST1180, -+}; -+ -+enum ast_tx_chip { -+ AST_TX_NONE, -+ AST_TX_SIL164, -+ AST_TX_ITE66121, -+ AST_TX_DP501, -+}; -+ -+#define AST_DRAM_512Mx16 0 -+#define AST_DRAM_1Gx16 1 -+#define AST_DRAM_512Mx32 2 -+#define AST_DRAM_1Gx32 3 -+#define AST_DRAM_2Gx16 6 -+#define AST_DRAM_4Gx16 7 -+ -+struct ast_fbdev; -+ -+struct ast_private { -+ struct drm_device *dev; -+ -+ void __iomem *regs; -+ void __iomem *ioregs; -+ bool io_space_uses_mmap; -+ -+ enum ast_chip chip; -+ bool vga2_clone; -+ uint32_t dram_bus_width; -+ uint32_t dram_type; -+ uint32_t mclk; -+ uint32_t vram_size; -+ -+ struct ast_fbdev *fbdev; -+ -+ int fb_mtrr; -+ -+ struct drm_gem_object *cursor_cache; -+ uint64_t cursor_cache_gpu_addr; -+ -+ int next_cursor; -+ bool support_wide_screen; -+ -+ enum ast_tx_chip tx_chip_type; -+ u8 dp501_maxclk; -+ u8 *dp501_fw_addr; -+ const struct firmware *dp501_fw; /* dp501 fw */ -+}; -+ -+int ast_driver_load(struct drm_device *dev, unsigned long flags); -+int ast_driver_unload(struct drm_device *dev); -+ -+#define AST_IO_AR_PORT_WRITE (0x40) -+#define AST_IO_MISC_PORT_WRITE (0x42) -+#define AST_IO_VGA_ENABLE_PORT (0x43) -+#define AST_IO_SEQ_PORT (0x44) -+#define AST_IO_DAC_INDEX_READ (0x47) -+#define AST_IO_DAC_INDEX_WRITE (0x48) -+#define AST_IO_DAC_DATA (0x49) -+#define AST_IO_GR_PORT (0x4E) -+#define AST_IO_CRTC_PORT (0x54) -+#define AST_IO_INPUT_STATUS1_READ (0x5A) -+#define AST_IO_MISC_PORT_READ (0x4C) -+ -+#define AST_IO_MM_OFFSET (0x380) -+ -+#define __ast_read(x) \ -+static inline u##x ast_read##x(struct ast_private *ast, u32 reg) { \ -+u##x val = 0;\ -+val = ioread##x(ast->regs + reg); \ -+return val;\ -+} -+ -+__ast_read(8); -+__ast_read(16); -+__ast_read(32) -+ -+#define __ast_io_read(x) \ -+static inline u##x ast_io_read##x(struct ast_private *ast, u32 reg) { \ -+u##x val = 0;\ -+if (ast->io_space_uses_mmap) \ -+val = ioread##x(ast->regs + reg); \ -+else \ -+val = ioread_cbio##x(ast->ioregs + reg); \ -+return val;\ -+} -+ -+__ast_io_read(8); -+__ast_io_read(16); -+__ast_io_read(32); -+ -+#define __ast_write(x) \ -+static inline void ast_write##x(struct ast_private *ast, u32 reg, u##x val) {\ -+ iowrite##x(val, ast->regs + reg);\ -+ } -+ -+__ast_write(8); -+__ast_write(16); -+__ast_write(32); -+ -+#define __ast_io_write(x) \ -+static inline void ast_io_write##x(struct ast_private *ast, u32 reg, u##x val) {\ -+ if (ast->io_space_uses_mmap) \ -+ iowrite##x(val, ast->regs + reg);\ -+ else \ -+ iowrite_cbio##x(val, ast->ioregs + reg);\ -+ } -+ -+__ast_io_write(8); -+__ast_io_write(16); -+#undef __ast_io_write -+ -+static inline void ast_set_index_reg(struct ast_private *ast, -+ uint32_t base, uint8_t index, -+ uint8_t val) -+{ -+ ast_io_write16(ast, base, ((u16)val << 8) | index); -+} -+ -+void ast_set_index_reg_mask(struct ast_private *ast, -+ uint32_t base, uint8_t index, -+ uint8_t mask, uint8_t val); -+uint8_t ast_get_index_reg(struct ast_private *ast, -+ uint32_t base, uint8_t index); -+uint8_t ast_get_index_reg_mask(struct ast_private *ast, -+ uint32_t base, uint8_t index, uint8_t mask); -+ -+static inline void ast_open_key(struct ast_private *ast) -+{ -+ ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x80, 0xA8); -+} -+ -+#define AST_VIDMEM_SIZE_8M 0x00800000 -+#define AST_VIDMEM_SIZE_16M 0x01000000 -+#define AST_VIDMEM_SIZE_32M 0x02000000 -+#define AST_VIDMEM_SIZE_64M 0x04000000 -+#define AST_VIDMEM_SIZE_128M 0x08000000 -+ -+#define AST_VIDMEM_DEFAULT_SIZE AST_VIDMEM_SIZE_8M -+ -+#define AST_MAX_HWC_WIDTH 64 -+#define AST_MAX_HWC_HEIGHT 64 -+ -+#define AST_HWC_SIZE (AST_MAX_HWC_WIDTH*AST_MAX_HWC_HEIGHT*2) -+#define AST_HWC_SIGNATURE_SIZE 32 -+ -+#define AST_DEFAULT_HWC_NUM 2 -+/* define for signature structure */ -+#define AST_HWC_SIGNATURE_CHECKSUM 0x00 -+#define AST_HWC_SIGNATURE_SizeX 0x04 -+#define AST_HWC_SIGNATURE_SizeY 0x08 -+#define AST_HWC_SIGNATURE_X 0x0C -+#define AST_HWC_SIGNATURE_Y 0x10 -+#define AST_HWC_SIGNATURE_HOTSPOTX 0x14 -+#define AST_HWC_SIGNATURE_HOTSPOTY 0x18 -+ -+#define AST_MM_ALIGN_SHIFT 4 -+#define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1) -+ -+#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) -+ -+/* ast post */ -+void ast_enable_vga(struct drm_device *dev); -+void ast_enable_mmio(struct drm_device *dev); -+bool ast_is_vga_enabled(struct drm_device *dev); -+void ast_post_gpu(struct drm_device *dev); -+u32 ast_mindwm(struct ast_private *ast, u32 r); -+void ast_moutdwm(struct ast_private *ast, u32 r, u32 v); -+/* ast dp501 */ -+int ast_load_dp501_microcode(struct drm_device *dev); -+void ast_set_dp501_video_output(struct drm_device *dev, u8 mode); -+bool ast_launch_m68k(struct drm_device *dev); -+bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size); -+bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata); -+u8 ast_get_dp501_max_clk(struct drm_device *dev); -+void ast_init_3rdtx(struct drm_device *dev); -+#endif -diff --git a/src/drivers/aspeed/common/ast_main.c b/src/drivers/aspeed/common/ast_main.c -new file mode 100644 -index 0000000..2939442 ---- /dev/null -+++ b/src/drivers/aspeed/common/ast_main.c -@@ -0,0 +1,393 @@ -+/* -+ * Copyright 2012 Red Hat Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sub license, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, -+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -+ * USE OR OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * The above copyright notice and this permission notice (including the -+ * next paragraph) shall be included in all copies or substantial portions -+ * of the Software. -+ * -+ */ -+/* -+ * Authors: Dave Airlie <airlied@redhat.com> -+ */ -+#include "ast_drv.h" -+ -+#include "ast_dram_tables.h" -+ -+void ast_set_index_reg_mask(struct ast_private *ast, -+ uint32_t base, uint8_t index, -+ uint8_t mask, uint8_t val) -+{ -+ u8 tmp; -+ ast_io_write8(ast, base, index); -+ tmp = (ast_io_read8(ast, base + 1) & mask) | val; -+ ast_set_index_reg(ast, base, index, tmp); -+} -+ -+uint8_t ast_get_index_reg(struct ast_private *ast, -+ uint32_t base, uint8_t index) -+{ -+ uint8_t ret; -+ ast_io_write8(ast, base, index); -+ ret = ast_io_read8(ast, base + 1); -+ return ret; -+} -+ -+uint8_t ast_get_index_reg_mask(struct ast_private *ast, -+ uint32_t base, uint8_t index, uint8_t mask) -+{ -+ uint8_t ret; -+ ast_io_write8(ast, base, index); -+ ret = ast_io_read8(ast, base + 1) & mask; -+ return ret; -+} -+ -+ -+static int ast_detect_chip(struct drm_device *dev, bool *need_post) -+{ -+ struct ast_private *ast = dev->dev_private; -+ uint32_t data, jreg; -+ ast_open_key(ast); -+ -+ if (dev->pdev->device == PCI_CHIP_AST1180) { -+ ast->chip = AST1100; -+ DRM_INFO("AST 1180 detected\n"); -+ } else { -+ pci_read_config_dword(ast->dev->pdev, 0x08, &data); -+ uint8_t revision = data & 0xff; -+ -+ if (revision >= 0x30) { -+ ast->chip = AST2400; -+ DRM_INFO("AST 2400 detected\n"); -+ } else if (revision >= 0x20) { -+ ast->chip = AST2300; -+ DRM_INFO("AST 2300 detected\n"); -+ } else if (revision >= 0x10) { -+ ast_write32(ast, 0xf004, 0x1e6e0000); -+ ast_write32(ast, 0xf000, 0x1); -+ -+ data = ast_read32(ast, 0x1207c); -+ switch (data & 0x0300) { -+ case 0x0200: -+ ast->chip = AST1100; -+ DRM_INFO("AST 1100 detected\n"); -+ break; -+ case 0x0100: -+ ast->chip = AST2200; -+ DRM_INFO("AST 2200 detected\n"); -+ break; -+ case 0x0000: -+ ast->chip = AST2150; -+ DRM_INFO("AST 2150 detected\n"); -+ break; -+ default: -+ ast->chip = AST2100; -+ DRM_INFO("AST 2100 detected\n"); -+ break; -+ } -+ ast->vga2_clone = false; -+ } else { -+ ast->chip = AST2000; -+ DRM_INFO("AST 2000 detected\n"); -+ } -+ } -+ -+ /* -+ * If VGA isn't enabled, we need to enable now or subsequent -+ * access to the scratch registers will fail. We also inform -+ * our caller that it needs to POST the chip -+ * (Assumption: VGA not enabled -> need to POST) -+ */ -+ if (!ast_is_vga_enabled(dev)) { -+ ast_enable_vga(dev); -+ ast_enable_mmio(dev); -+ DRM_INFO("VGA not enabled on entry, requesting chip POST\n"); -+ *need_post = true; -+ } else -+ *need_post = false; -+ -+ /* Check if we support wide screen */ -+ switch (ast->chip) { -+ case AST1180: -+ ast->support_wide_screen = true; -+ break; -+ case AST2000: -+ ast->support_wide_screen = false; -+ break; -+ default: -+ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); -+ if (!(jreg & 0x80)) -+ ast->support_wide_screen = true; -+ else if (jreg & 0x01) -+ ast->support_wide_screen = true; -+ else { -+ ast->support_wide_screen = false; -+ /* Read SCU7c (silicon revision register) */ -+ ast_write32(ast, 0xf004, 0x1e6e0000); -+ ast_write32(ast, 0xf000, 0x1); -+ data = ast_read32(ast, 0x1207c); -+ data &= 0x300; -+ if (ast->chip == AST2300 && data == 0x0) /* ast1300 */ -+ ast->support_wide_screen = true; -+ if (ast->chip == AST2400 && data == 0x100) /* ast1400 */ -+ ast->support_wide_screen = true; -+ } -+ break; -+ } -+ -+ /* Check 3rd Tx option (digital output afaik) */ -+ ast->tx_chip_type = AST_TX_NONE; -+ -+ /* -+ * VGACRA3 Enhanced Color Mode Register, check if DVO is already -+ * enabled, in that case, assume we have a SIL164 TMDS transmitter -+ * -+ * Don't make that assumption if we the chip wasn't enabled and -+ * is at power-on reset, otherwise we'll incorrectly "detect" a -+ * SIL164 when there is none. -+ */ -+ if (!*need_post) { -+ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff); -+ if (jreg & 0x80) -+ ast->tx_chip_type = AST_TX_SIL164; -+ } -+ -+ if ((ast->chip == AST2300) || (ast->chip == AST2400)) { -+ /* -+ * On AST2300 and 2400, look the configuration set by the SoC in -+ * the SOC scratch register #1 bits 11:8 (interestingly marked -+ * as "reserved" in the spec) -+ */ -+ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); -+ switch (jreg) { -+ case 0x04: -+ ast->tx_chip_type = AST_TX_SIL164; -+ break; -+ case 0x08: -+ ast->dp501_fw_addr = kzalloc(32*1024, GFP_KERNEL); -+ if (ast->dp501_fw_addr) { -+ /* backup firmware */ -+ if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) { -+ kfree(ast->dp501_fw_addr); -+ ast->dp501_fw_addr = NULL; -+ } -+ } -+ /* fallthrough */ -+ case 0x0c: -+ ast->tx_chip_type = AST_TX_DP501; -+ } -+ } -+ -+ /* Print stuff for diagnostic purposes */ -+ switch(ast->tx_chip_type) { -+ case AST_TX_SIL164: -+ DRM_INFO("Using Sil164 TMDS transmitter\n"); -+ break; -+ case AST_TX_DP501: -+ DRM_INFO("Using DP501 DisplayPort transmitter\n"); -+ break; -+ default: -+ DRM_INFO("Analog VGA only\n"); -+ } -+ return 0; -+} -+ -+static int ast_get_dram_info(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ uint8_t i; -+ uint32_t data, data2; -+ uint32_t denum, num, div, ref_pll; -+ -+ ast_write32(ast, 0xf004, 0x1e6e0000); -+ ast_write32(ast, 0xf000, 0x1); -+ -+ -+ ast_write32(ast, 0x10000, 0xfc600309); -+ -+ /* Wait up to 2.5 seconds for device initialization / register unlock */ -+ for (i = 0; i < 250; i++) { -+ if (ast_read32(ast, 0x10000) == 0x01) -+ break; -+ mdelay(10); -+ } -+ if (ast_read32(ast, 0x10000) != 0x01) -+ dev_err(dev->pdev, "Unable to unlock SDRAM control registers\n"); -+ -+ data = ast_read32(ast, 0x10004); -+ -+ if (data & 0x400) -+ ast->dram_bus_width = 16; -+ else -+ ast->dram_bus_width = 32; -+ -+ if (ast->chip == AST2300 || ast->chip == AST2400) { -+ switch (data & 0x03) { -+ case 0: -+ ast->dram_type = AST_DRAM_512Mx16; -+ break; -+ default: -+ case 1: -+ ast->dram_type = AST_DRAM_1Gx16; -+ break; -+ case 2: -+ ast->dram_type = AST_DRAM_2Gx16; -+ break; -+ case 3: -+ ast->dram_type = AST_DRAM_4Gx16; -+ break; -+ } -+ } else { -+ switch (data & 0x0c) { -+ case 0: -+ case 4: -+ ast->dram_type = AST_DRAM_512Mx16; -+ break; -+ case 8: -+ if (data & 0x40) -+ ast->dram_type = AST_DRAM_1Gx16; -+ else -+ ast->dram_type = AST_DRAM_512Mx32; -+ break; -+ case 0xc: -+ ast->dram_type = AST_DRAM_1Gx32; -+ break; -+ } -+ } -+ -+ data = ast_read32(ast, 0x10120); -+ data2 = ast_read32(ast, 0x10170); -+ if (data2 & 0x2000) -+ ref_pll = 14318; -+ else -+ ref_pll = 12000; -+ -+ denum = data & 0x1f; -+ num = (data & 0x3fe0) >> 5; -+ data = (data & 0xc000) >> 14; -+ switch (data) { -+ case 3: -+ div = 0x4; -+ break; -+ case 2: -+ case 1: -+ div = 0x2; -+ break; -+ default: -+ div = 0x1; -+ break; -+ } -+ ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000); -+ return 0; -+} -+ -+static u32 ast_get_vram_info(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ u8 jreg; -+ u32 vram_size; -+ ast_open_key(ast); -+ -+ vram_size = AST_VIDMEM_DEFAULT_SIZE; -+ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff); -+ switch (jreg & 3) { -+ case 0: vram_size = AST_VIDMEM_SIZE_8M; break; -+ case 1: vram_size = AST_VIDMEM_SIZE_16M; break; -+ case 2: vram_size = AST_VIDMEM_SIZE_32M; break; -+ case 3: vram_size = AST_VIDMEM_SIZE_64M; break; -+ } -+ -+ return vram_size; -+} -+ -+int ast_driver_load(struct drm_device *dev, unsigned long flags) -+{ -+ struct ast_private *ast; -+ bool need_post; -+ int ret = 0; -+ struct resource *res; -+ -+ ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL); -+ if (!ast) -+ return -ENOMEM; -+ -+ dev->dev_private = ast; -+ ast->dev = dev; -+ -+ /* PCI BAR 1 */ -+ res = find_resource(dev->pdev, 0x14); -+ if (!res) { -+ dev_err(dev->pdev, "BAR1 resource not found.\n"); -+ ret = -EIO; -+ goto out_free; -+ } -+ ast->regs = res2mmio(res, 0, 0); -+ if (!ast->regs) { -+ ret = -EIO; -+ goto out_free; -+ } -+ -+ /* PCI BAR 2 */ -+ ast->io_space_uses_mmap = false; -+ res = find_resource(dev->pdev, 0x18); -+ if (!res) { -+ dev_err(dev->pdev, "BAR2 resource not found.\n"); -+ ret = -EIO; -+ goto out_free; -+ } -+ -+ /* -+ * If we don't have IO space at all, use MMIO now and -+ * assume the chip has MMIO enabled by default (rev 0x20 -+ * and higher). -+ */ -+ if (!(res->flags & IORESOURCE_IO)) { -+ DRM_INFO("platform has no IO space, trying MMIO\n"); -+ ast->ioregs = ast->regs + AST_IO_MM_OFFSET; -+ ast->io_space_uses_mmap = true; -+ } -+ -+ /* "map" IO regs if the above hasn't done so already */ -+ if (!ast->ioregs) { -+ ast->ioregs = res2mmio(res, 0, 0); -+ if (!ast->ioregs) { -+ ret = -EIO; -+ goto out_free; -+ } -+ /* Adjust the I/O space location to match expectations (the code expects offset 0x0 to be I/O location 0x380) */ -+ ast->ioregs = (void *)AST_IO_MM_OFFSET; -+ } -+ -+ ast_detect_chip(dev, &need_post); -+ -+ if (ast->chip != AST1180) { -+ ast_get_dram_info(dev); -+ ast->vram_size = ast_get_vram_info(dev); -+ DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size); -+ } -+ -+ if (need_post) -+ ast_post_gpu(dev); -+ -+ return 0; -+out_free: -+ kfree(ast); -+ dev->dev_private = NULL; -+ return ret; -+} -diff --git a/src/drivers/aspeed/common/ast_post.c b/src/drivers/aspeed/common/ast_post.c -new file mode 100644 -index 0000000..7d31845 ---- /dev/null -+++ b/src/drivers/aspeed/common/ast_post.c -@@ -0,0 +1,1679 @@ -+/* -+ * Copyright 2012 Red Hat Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sub license, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, -+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -+ * USE OR OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * The above copyright notice and this permission notice (including the -+ * next paragraph) shall be included in all copies or substantial portions -+ * of the Software. -+ * -+ */ -+/* -+ * Authors: Dave Airlie <airlied@redhat.com> -+ */ -+ -+#include "ast_drv.h" -+ -+#include "ast_dram_tables.h" -+ -+static void ast_init_dram_2300(struct drm_device *dev); -+ -+void ast_enable_vga(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ -+ ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01); -+ ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, 0x01); -+} -+ -+void ast_enable_mmio(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x04); -+} -+ -+ -+bool ast_is_vga_enabled(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ u8 ch; -+ -+ if (ast->chip == AST1180) { -+ /* TODO 1180 */ -+ } else { -+ ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT); -+ if (ch) { -+ ast_open_key(ast); -+ ch = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff); -+ return ch & 0x04; -+ } -+ } -+ return 0; -+} -+ -+static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff }; -+static const u8 extreginfo_ast2300a0[] = { 0x0f, 0x04, 0x1c, 0xff }; -+static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff }; -+ -+static void -+ast_set_def_ext_reg(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ u8 i, index, reg; -+ uint32_t data; -+ const u8 *ext_reg_info; -+ -+ pci_read_config_dword(ast->dev->pdev, 0x08, &data); -+ uint8_t revision = data & 0xff; -+ -+ /* reset scratch */ -+ for (i = 0x81; i <= 0x8f; i++) -+ ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00); -+ -+ if (ast->chip == AST2300 || ast->chip == AST2400) { -+ if (revision >= 0x20) -+ ext_reg_info = extreginfo_ast2300; -+ else -+ ext_reg_info = extreginfo_ast2300a0; -+ } else -+ ext_reg_info = extreginfo; -+ -+ index = 0xa0; -+ while (*ext_reg_info != 0xff) { -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, index, 0x00, *ext_reg_info); -+ index++; -+ ext_reg_info++; -+ } -+ -+ /* disable standard IO/MEM decode if secondary */ -+ /* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */ -+ -+ /* Set Ext. Default */ -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x8c, 0x00, 0x01); -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x00, 0x00); -+ -+ /* Enable RAMDAC for A1 */ -+ reg = 0x04; -+ if (ast->chip == AST2300 || ast->chip == AST2400) -+ reg |= 0x20; -+ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg); -+} -+ -+u32 ast_mindwm(struct ast_private *ast, u32 r) -+{ -+ uint32_t data; -+ -+ ast_write32(ast, 0xf004, r & 0xffff0000); -+ ast_write32(ast, 0xf000, 0x1); -+ -+ do { -+ data = ast_read32(ast, 0xf004) & 0xffff0000; -+ } while (data != (r & 0xffff0000)); -+ return ast_read32(ast, 0x10000 + (r & 0x0000ffff)); -+} -+ -+void ast_moutdwm(struct ast_private *ast, u32 r, u32 v) -+{ -+ uint32_t data; -+ ast_write32(ast, 0xf004, r & 0xffff0000); -+ ast_write32(ast, 0xf000, 0x1); -+ do { -+ data = ast_read32(ast, 0xf004) & 0xffff0000; -+ } while (data != (r & 0xffff0000)); -+ ast_write32(ast, 0x10000 + (r & 0x0000ffff), v); -+} -+ -+/* -+ * AST2100/2150 DLL CBR Setting -+ */ -+#define CBR_SIZE_AST2150 ((16 << 10) - 1) -+#define CBR_PASSNUM_AST2150 5 -+#define CBR_THRESHOLD_AST2150 10 -+#define CBR_THRESHOLD2_AST2150 10 -+#define TIMEOUT_AST2150 5000000 -+ -+#define CBR_PATNUM_AST2150 8 -+ -+static const u32 pattern_AST2150[14] = { -+ 0xFF00FF00, -+ 0xCC33CC33, -+ 0xAA55AA55, -+ 0xFFFE0001, -+ 0x683501FE, -+ 0x0F1929B0, -+ 0x2D0B4346, -+ 0x60767F02, -+ 0x6FBE36A6, -+ 0x3A253035, -+ 0x3019686D, -+ 0x41C6167E, -+ 0x620152BF, -+ 0x20F050E0 -+}; -+ -+static u32 mmctestburst2_ast2150(struct ast_private *ast, u32 datagen) -+{ -+ u32 data, timeout; -+ -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000001 | (datagen << 3)); -+ timeout = 0; -+ do { -+ data = ast_mindwm(ast, 0x1e6e0070) & 0x40; -+ if (++timeout > TIMEOUT_AST2150) { -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ return 0xffffffff; -+ } -+ } while (!data); -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000003 | (datagen << 3)); -+ timeout = 0; -+ do { -+ data = ast_mindwm(ast, 0x1e6e0070) & 0x40; -+ if (++timeout > TIMEOUT_AST2150) { -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ return 0xffffffff; -+ } -+ } while (!data); -+ data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7; -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ return data; -+} -+ -+#if 0 /* unused in DDX driver - here for completeness */ -+static u32 mmctestsingle2_ast2150(struct ast_private *ast, u32 datagen) -+{ -+ u32 data, timeout; -+ -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3)); -+ timeout = 0; -+ do { -+ data = ast_mindwm(ast, 0x1e6e0070) & 0x40; -+ if (++timeout > TIMEOUT_AST2150) { -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ return 0xffffffff; -+ } -+ } while (!data); -+ data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7; -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ return data; -+} -+#endif -+ -+static int cbrtest_ast2150(struct ast_private *ast) -+{ -+ int i; -+ -+ for (i = 0; i < 8; i++) -+ if (mmctestburst2_ast2150(ast, i)) -+ return 0; -+ return 1; -+} -+ -+static int cbrscan_ast2150(struct ast_private *ast, int busw) -+{ -+ u32 patcnt, loop; -+ -+ for (patcnt = 0; patcnt < CBR_PATNUM_AST2150; patcnt++) { -+ ast_moutdwm(ast, 0x1e6e007c, pattern_AST2150[patcnt]); -+ for (loop = 0; loop < CBR_PASSNUM_AST2150; loop++) { -+ if (cbrtest_ast2150(ast)) -+ break; -+ } -+ if (loop == CBR_PASSNUM_AST2150) -+ return 0; -+ } -+ return 1; -+} -+ -+ -+static void cbrdlli_ast2150(struct ast_private *ast, int busw) -+{ -+ u32 dll_min[4], dll_max[4], dlli, data, passcnt; -+ -+cbr_start: -+ dll_min[0] = dll_min[1] = dll_min[2] = dll_min[3] = 0xff; -+ dll_max[0] = dll_max[1] = dll_max[2] = dll_max[3] = 0x0; -+ passcnt = 0; -+ -+ for (dlli = 0; dlli < 100; dlli++) { -+ ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24)); -+ data = cbrscan_ast2150(ast, busw); -+ if (data != 0) { -+ if (data & 0x1) { -+ if (dll_min[0] > dlli) -+ dll_min[0] = dlli; -+ if (dll_max[0] < dlli) -+ dll_max[0] = dlli; -+ } -+ passcnt++; -+ } else if (passcnt >= CBR_THRESHOLD_AST2150) -+ goto cbr_start; -+ } -+ if (dll_max[0] == 0 || (dll_max[0]-dll_min[0]) < CBR_THRESHOLD_AST2150) -+ goto cbr_start; -+ -+ dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4); -+ ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24)); -+} -+ -+ -+ -+static void ast_init_dram_reg(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ u8 j; -+ u32 data, temp, i; -+ const struct ast_dramstruct *dram_reg_info; -+ -+ j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); -+ -+ if ((j & 0x80) == 0) { /* VGA only */ -+ if (ast->chip == AST2000) { -+ dram_reg_info = ast2000_dram_table_data; -+ ast_write32(ast, 0xf004, 0x1e6e0000); -+ ast_write32(ast, 0xf000, 0x1); -+ ast_write32(ast, 0x10100, 0xa8); -+ -+ do { -+ ; -+ } while (ast_read32(ast, 0x10100) != 0xa8); -+ } else {/* AST2100/1100 */ -+ if (ast->chip == AST2100 || ast->chip == 2200) -+ dram_reg_info = ast2100_dram_table_data; -+ else -+ dram_reg_info = ast1100_dram_table_data; -+ -+ ast_write32(ast, 0xf004, 0x1e6e0000); -+ ast_write32(ast, 0xf000, 0x1); -+ ast_write32(ast, 0x12000, 0x1688A8A8); -+ -+ /* Wait up to 2.5 seconds for device initialization / register unlock */ -+ for (i = 0; i < 250; i++) { -+ if (ast_read32(ast, 0x12000) == 0x01) -+ break; -+ mdelay(10); -+ } -+ if (ast_read32(ast, 0x12000) != 0x01) -+ dev_err(dev->pdev, "Unable to unlock SCU registers\n"); -+ -+ ast_write32(ast, 0x10000, 0xfc600309); -+ -+ /* Wait up to 2.5 seconds for device initialization / register unlock */ -+ for (i = 0; i < 250; i++) { -+ if (ast_read32(ast, 0x10000) == 0x01) -+ break; -+ mdelay(10); -+ } -+ if (ast_read32(ast, 0x10000) != 0x01) -+ dev_err(dev->pdev, "Unable to unlock SDRAM control registers\n"); -+ } -+ -+ while (dram_reg_info->index != 0xffff) { -+ if (dram_reg_info->index == 0xff00) {/* delay fn */ -+ for (i = 0; i < 15; i++) -+ udelay(dram_reg_info->data); -+ } else if (dram_reg_info->index == 0x4 && ast->chip != AST2000) { -+ data = dram_reg_info->data; -+ if (ast->dram_type == AST_DRAM_1Gx16) -+ data = 0x00000d89; -+ else if (ast->dram_type == AST_DRAM_1Gx32) -+ data = 0x00000c8d; -+ -+ temp = ast_read32(ast, 0x12070); -+ temp &= 0xc; -+ temp <<= 2; -+ ast_write32(ast, 0x10000 + dram_reg_info->index, data | temp); -+ } else -+ ast_write32(ast, 0x10000 + dram_reg_info->index, dram_reg_info->data); -+ dram_reg_info++; -+ } -+ -+ /* AST 2100/2150 DRAM calibration */ -+ data = ast_read32(ast, 0x10120); -+ if (data == 0x5061) { /* 266Mhz */ -+ data = ast_read32(ast, 0x10004); -+ if (data & 0x40) -+ cbrdlli_ast2150(ast, 16); /* 16 bits */ -+ else -+ cbrdlli_ast2150(ast, 32); /* 32 bits */ -+ } -+ -+ switch (ast->chip) { -+ case AST2000: -+ temp = ast_read32(ast, 0x10140); -+ ast_write32(ast, 0x10140, temp | 0x40); -+ break; -+ case AST1100: -+ case AST2100: -+ case AST2200: -+ case AST2150: -+ temp = ast_read32(ast, 0x1200c); -+ ast_write32(ast, 0x1200c, temp & 0xfffffffd); -+ temp = ast_read32(ast, 0x12040); -+ ast_write32(ast, 0x12040, temp | 0x40); -+ break; -+ default: -+ break; -+ } -+ } -+ -+ /* wait ready */ -+ /* Wait up to 2.5 seconds for device to become ready */ -+ for (i = 0; i < 250; i++) { -+ j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); -+ mdelay(10); -+ if ((j & 0x40) != 0) -+ break; -+ } -+ if ((j & 0x40) == 0) -+ dev_err(dev->pdev, "Timeout while waiting for device to signal ready\n"); -+} -+ -+void ast_post_gpu(struct drm_device *dev) -+{ -+ u32 reg; -+ struct ast_private *ast = dev->dev_private; -+ -+ pci_read_config_dword(ast->dev->pdev, 0x04, &reg); -+ reg |= 0x3; -+ pci_write_config_dword(ast->dev->pdev, 0x04, reg); -+ -+ ast_enable_vga(dev); -+ ast_enable_mmio(dev); -+ ast_open_key(ast); -+ ast_set_def_ext_reg(dev); -+ -+ if (ast->chip == AST2300 || ast->chip == AST2400) -+ ast_init_dram_2300(dev); -+ else -+ ast_init_dram_reg(dev); -+ -+ ast_init_3rdtx(dev); -+} -+ -+/* AST 2300 DRAM settings */ -+#define AST_DDR3 0 -+#define AST_DDR2 1 -+ -+struct ast2300_dram_param { -+ u32 dram_type; -+ u32 dram_chipid; -+ u32 dram_freq; -+ u32 vram_size; -+ u32 odt; -+ u32 wodt; -+ u32 rodt; -+ u32 dram_config; -+ u32 reg_PERIOD; -+ u32 reg_MADJ; -+ u32 reg_SADJ; -+ u32 reg_MRS; -+ u32 reg_EMRS; -+ u32 reg_AC1; -+ u32 reg_AC2; -+ u32 reg_DQSIC; -+ u32 reg_DRV; -+ u32 reg_IOZ; -+ u32 reg_DQIDLY; -+ u32 reg_FREQ; -+ u32 madj_max; -+ u32 dll2_finetune_step; -+}; -+ -+/* -+ * DQSI DLL CBR Setting -+ */ -+#define CBR_SIZE0 ((1 << 10) - 1) -+#define CBR_SIZE1 ((4 << 10) - 1) -+#define CBR_SIZE2 ((64 << 10) - 1) -+#define CBR_PASSNUM 5 -+#define CBR_PASSNUM2 5 -+#define CBR_THRESHOLD 10 -+#define CBR_THRESHOLD2 10 -+#define TIMEOUT 5000000 -+#define CBR_PATNUM 8 -+ -+static const u32 pattern[8] = { -+ 0xFF00FF00, -+ 0xCC33CC33, -+ 0xAA55AA55, -+ 0x88778877, -+ 0x92CC4D6E, -+ 0x543D3CDE, -+ 0xF1E843C7, -+ 0x7C61D253 -+}; -+ -+static int mmc_test_burst(struct ast_private *ast, u32 datagen) -+{ -+ u32 data, timeout; -+ -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ ast_moutdwm(ast, 0x1e6e0070, 0x000000c1 | (datagen << 3)); -+ timeout = 0; -+ do { -+ data = ast_mindwm(ast, 0x1e6e0070) & 0x3000; -+ if (data & 0x2000) { -+ return 0; -+ } -+ if (++timeout > TIMEOUT) { -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ return 0; -+ } -+ } while (!data); -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ return 1; -+} -+ -+static int mmc_test_burst2(struct ast_private *ast, u32 datagen) -+{ -+ u32 data, timeout; -+ -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000041 | (datagen << 3)); -+ timeout = 0; -+ do { -+ data = ast_mindwm(ast, 0x1e6e0070) & 0x1000; -+ if (++timeout > TIMEOUT) { -+ ast_moutdwm(ast, 0x1e6e0070, 0x0); -+ return -1; -+ } -+ } while (!data); -+ data = ast_mindwm(ast, 0x1e6e0078); -+ data = (data | (data >> 16)) & 0xffff; -+ ast_moutdwm(ast, 0x1e6e0070, 0x0); -+ return data; -+} -+ -+static int mmc_test_single(struct ast_private *ast, u32 datagen) -+{ -+ u32 data, timeout; -+ -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ ast_moutdwm(ast, 0x1e6e0070, 0x000000c5 | (datagen << 3)); -+ timeout = 0; -+ do { -+ data = ast_mindwm(ast, 0x1e6e0070) & 0x3000; -+ if (data & 0x2000) -+ return 0; -+ if (++timeout > TIMEOUT) { -+ ast_moutdwm(ast, 0x1e6e0070, 0x0); -+ return 0; -+ } -+ } while (!data); -+ ast_moutdwm(ast, 0x1e6e0070, 0x0); -+ return 1; -+} -+ -+static int mmc_test_single2(struct ast_private *ast, u32 datagen) -+{ -+ u32 data, timeout; -+ -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); -+ ast_moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3)); -+ timeout = 0; -+ do { -+ data = ast_mindwm(ast, 0x1e6e0070) & 0x1000; -+ if (++timeout > TIMEOUT) { -+ ast_moutdwm(ast, 0x1e6e0070, 0x0); -+ return -1; -+ } -+ } while (!data); -+ data = ast_mindwm(ast, 0x1e6e0078); -+ data = (data | (data >> 16)) & 0xffff; -+ ast_moutdwm(ast, 0x1e6e0070, 0x0); -+ return data; -+} -+ -+static int cbr_test(struct ast_private *ast) -+{ -+ u32 data; -+ int i; -+ data = mmc_test_single2(ast, 0); -+ if ((data & 0xff) && (data & 0xff00)) -+ return 0; -+ for (i = 0; i < 8; i++) { -+ data = mmc_test_burst2(ast, i); -+ if ((data & 0xff) && (data & 0xff00)) -+ return 0; -+ } -+ if (!data) -+ return 3; -+ else if (data & 0xff) -+ return 2; -+ return 1; -+} -+ -+static int cbr_scan(struct ast_private *ast) -+{ -+ u32 data, data2, patcnt, loop; -+ -+ data2 = 3; -+ for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) { -+ ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]); -+ for (loop = 0; loop < CBR_PASSNUM2; loop++) { -+ if ((data = cbr_test(ast)) != 0) { -+ data2 &= data; -+ if (!data2) -+ return 0; -+ break; -+ } -+ } -+ if (loop == CBR_PASSNUM2) -+ return 0; -+ } -+ return data2; -+} -+ -+static u32 cbr_test2(struct ast_private *ast) -+{ -+ u32 data; -+ -+ data = mmc_test_burst2(ast, 0); -+ if (data == 0xffff) -+ return 0; -+ data |= mmc_test_single2(ast, 0); -+ if (data == 0xffff) -+ return 0; -+ -+ return ~data & 0xffff; -+} -+ -+static u32 cbr_scan2(struct ast_private *ast) -+{ -+ u32 data, data2, patcnt, loop; -+ -+ data2 = 0xffff; -+ for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) { -+ ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]); -+ for (loop = 0; loop < CBR_PASSNUM2; loop++) { -+ if ((data = cbr_test2(ast)) != 0) { -+ data2 &= data; -+ if (!data2) -+ return 0; -+ break; -+ } -+ } -+ if (loop == CBR_PASSNUM2) -+ return 0; -+ } -+ return data2; -+} -+ -+static u32 cbr_test3(struct ast_private *ast) -+{ -+ if (!mmc_test_burst(ast, 0)) -+ return 0; -+ if (!mmc_test_single(ast, 0)) -+ return 0; -+ return 1; -+} -+ -+static u32 cbr_scan3(struct ast_private *ast) -+{ -+ u32 patcnt, loop; -+ -+ for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) { -+ ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]); -+ for (loop = 0; loop < 2; loop++) { -+ if (cbr_test3(ast)) -+ break; -+ } -+ if (loop == 2) -+ return 0; -+ } -+ return 1; -+} -+ -+static bool finetuneDQI_L(struct ast_private *ast, struct ast2300_dram_param *param) -+{ -+ u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0; -+ bool status = false; -+FINETUNE_START: -+ for (cnt = 0; cnt < 16; cnt++) { -+ dllmin[cnt] = 0xff; -+ dllmax[cnt] = 0x0; -+ } -+ passcnt = 0; -+ for (dlli = 0; dlli < 76; dlli++) { -+ ast_moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24)); -+ ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE1); -+ data = cbr_scan2(ast); -+ if (data != 0) { -+ mask = 0x00010001; -+ for (cnt = 0; cnt < 16; cnt++) { -+ if (data & mask) { -+ if (dllmin[cnt] > dlli) { -+ dllmin[cnt] = dlli; -+ } -+ if (dllmax[cnt] < dlli) { -+ dllmax[cnt] = dlli; -+ } -+ } -+ mask <<= 1; -+ } -+ passcnt++; -+ } else if (passcnt >= CBR_THRESHOLD2) { -+ break; -+ } -+ } -+ gold_sadj[0] = 0x0; -+ passcnt = 0; -+ for (cnt = 0; cnt < 16; cnt++) { -+ if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) { -+ gold_sadj[0] += dllmin[cnt]; -+ passcnt++; -+ } -+ } -+ if (retry++ > 10) -+ goto FINETUNE_DONE; -+ if (passcnt != 16) { -+ goto FINETUNE_START; -+ } -+ status = true; -+FINETUNE_DONE: -+ gold_sadj[0] = gold_sadj[0] >> 4; -+ gold_sadj[1] = gold_sadj[0]; -+ -+ data = 0; -+ for (cnt = 0; cnt < 8; cnt++) { -+ data >>= 3; -+ if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) { -+ dlli = dllmin[cnt]; -+ if (gold_sadj[0] >= dlli) { -+ dlli = ((gold_sadj[0] - dlli) * 19) >> 5; -+ if (dlli > 3) { -+ dlli = 3; -+ } -+ } else { -+ dlli = ((dlli - gold_sadj[0]) * 19) >> 5; -+ if (dlli > 4) { -+ dlli = 4; -+ } -+ dlli = (8 - dlli) & 0x7; -+ } -+ data |= dlli << 21; -+ } -+ } -+ ast_moutdwm(ast, 0x1E6E0080, data); -+ -+ data = 0; -+ for (cnt = 8; cnt < 16; cnt++) { -+ data >>= 3; -+ if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) { -+ dlli = dllmin[cnt]; -+ if (gold_sadj[1] >= dlli) { -+ dlli = ((gold_sadj[1] - dlli) * 19) >> 5; -+ if (dlli > 3) { -+ dlli = 3; -+ } else { -+ dlli = (dlli - 1) & 0x7; -+ } -+ } else { -+ dlli = ((dlli - gold_sadj[1]) * 19) >> 5; -+ dlli += 1; -+ if (dlli > 4) { -+ dlli = 4; -+ } -+ dlli = (8 - dlli) & 0x7; -+ } -+ data |= dlli << 21; -+ } -+ } -+ ast_moutdwm(ast, 0x1E6E0084, data); -+ return status; -+} /* finetuneDQI_L */ -+ -+static void finetuneDQSI(struct ast_private *ast) -+{ -+ u32 dlli, dqsip, dqidly; -+ u32 reg_mcr18, reg_mcr0c, passcnt[2], diff; -+ u32 g_dqidly, g_dqsip, g_margin, g_side; -+ u16 pass[32][2][2]; -+ char tag[2][76]; -+ -+ /* Disable DQI CBR */ -+ reg_mcr0c = ast_mindwm(ast, 0x1E6E000C); -+ reg_mcr18 = ast_mindwm(ast, 0x1E6E0018); -+ reg_mcr18 &= 0x0000ffff; -+ ast_moutdwm(ast, 0x1E6E0018, reg_mcr18); -+ -+ for (dlli = 0; dlli < 76; dlli++) { -+ tag[0][dlli] = 0x0; -+ tag[1][dlli] = 0x0; -+ } -+ for (dqidly = 0; dqidly < 32; dqidly++) { -+ pass[dqidly][0][0] = 0xff; -+ pass[dqidly][0][1] = 0x0; -+ pass[dqidly][1][0] = 0xff; -+ pass[dqidly][1][1] = 0x0; -+ } -+ for (dqidly = 0; dqidly < 32; dqidly++) { -+ passcnt[0] = passcnt[1] = 0; -+ for (dqsip = 0; dqsip < 2; dqsip++) { -+ ast_moutdwm(ast, 0x1E6E000C, 0); -+ ast_moutdwm(ast, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23)); -+ ast_moutdwm(ast, 0x1E6E000C, reg_mcr0c); -+ for (dlli = 0; dlli < 76; dlli++) { -+ ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24)); -+ ast_moutdwm(ast, 0x1E6E0070, 0); -+ ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE0); -+ if (cbr_scan3(ast)) { -+ if (dlli == 0) -+ break; -+ passcnt[dqsip]++; -+ tag[dqsip][dlli] = 'P'; -+ if (dlli < pass[dqidly][dqsip][0]) -+ pass[dqidly][dqsip][0] = (u16) dlli; -+ if (dlli > pass[dqidly][dqsip][1]) -+ pass[dqidly][dqsip][1] = (u16) dlli; -+ } else if (passcnt[dqsip] >= 5) -+ break; -+ else { -+ pass[dqidly][dqsip][0] = 0xff; -+ pass[dqidly][dqsip][1] = 0x0; -+ } -+ } -+ } -+ if (passcnt[0] == 0 && passcnt[1] == 0) -+ dqidly++; -+ } -+ /* Search margin */ -+ g_dqidly = g_dqsip = g_margin = g_side = 0; -+ -+ for (dqidly = 0; dqidly < 32; dqidly++) { -+ for (dqsip = 0; dqsip < 2; dqsip++) { -+ if (pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1]) -+ continue; -+ diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0]; -+ if ((diff+2) < g_margin) -+ continue; -+ passcnt[0] = passcnt[1] = 0; -+ for (dlli = pass[dqidly][dqsip][0]; dlli > 0 && tag[dqsip][dlli] != 0; dlli--, passcnt[0]++); -+ for (dlli = pass[dqidly][dqsip][1]; dlli < 76 && tag[dqsip][dlli] != 0; dlli++, passcnt[1]++); -+ if (passcnt[0] > passcnt[1]) -+ passcnt[0] = passcnt[1]; -+ passcnt[1] = 0; -+ if (passcnt[0] > g_side) -+ passcnt[1] = passcnt[0] - g_side; -+ if (diff > (g_margin+1) && (passcnt[1] > 0 || passcnt[0] > 8)) { -+ g_margin = diff; -+ g_dqidly = dqidly; -+ g_dqsip = dqsip; -+ g_side = passcnt[0]; -+ } else if (passcnt[1] > 1 && g_side < 8) { -+ if (diff > g_margin) -+ g_margin = diff; -+ g_dqidly = dqidly; -+ g_dqsip = dqsip; -+ g_side = passcnt[0]; -+ } -+ } -+ } -+ reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23); -+ ast_moutdwm(ast, 0x1E6E0018, reg_mcr18); -+ -+} -+static bool cbr_dll2(struct ast_private *ast, struct ast2300_dram_param *param) -+{ -+ u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0; -+ bool status = false; -+ -+ finetuneDQSI(ast); -+ if (finetuneDQI_L(ast, param) == false) -+ return status; -+ -+CBR_START2: -+ dllmin[0] = dllmin[1] = 0xff; -+ dllmax[0] = dllmax[1] = 0x0; -+ passcnt = 0; -+ for (dlli = 0; dlli < 76; dlli++) { -+ ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24)); -+ ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE2); -+ data = cbr_scan(ast); -+ if (data != 0) { -+ if (data & 0x1) { -+ if (dllmin[0] > dlli) { -+ dllmin[0] = dlli; -+ } -+ if (dllmax[0] < dlli) { -+ dllmax[0] = dlli; -+ } -+ } -+ if (data & 0x2) { -+ if (dllmin[1] > dlli) { -+ dllmin[1] = dlli; -+ } -+ if (dllmax[1] < dlli) { -+ dllmax[1] = dlli; -+ } -+ } -+ passcnt++; -+ } else if (passcnt >= CBR_THRESHOLD) { -+ break; -+ } -+ } -+ if (retry++ > 10) -+ goto CBR_DONE2; -+ if (dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD) { -+ goto CBR_START2; -+ } -+ if (dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD) { -+ goto CBR_START2; -+ } -+ status = true; -+CBR_DONE2: -+ dlli = (dllmin[1] + dllmax[1]) >> 1; -+ dlli <<= 8; -+ dlli += (dllmin[0] + dllmax[0]) >> 1; -+ ast_moutdwm(ast, 0x1E6E0068, ast_mindwm(ast, 0x1E720058) | (dlli << 16)); -+ return status; -+} /* CBRDLL2 */ -+ -+static void get_ddr3_info(struct ast_private *ast, struct ast2300_dram_param *param) -+{ -+ u32 trap, trap_AC2, trap_MRS; -+ -+ ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8); -+ -+ /* Ger trap info */ -+ trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3; -+ trap_AC2 = 0x00020000 + (trap << 16); -+ trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19); -+ trap_MRS = 0x00000010 + (trap << 4); -+ trap_MRS |= ((trap & 0x2) << 18); -+ -+ param->reg_MADJ = 0x00034C4C; -+ param->reg_SADJ = 0x00001800; -+ param->reg_DRV = 0x000000F0; -+ param->reg_PERIOD = param->dram_freq; -+ param->rodt = 0; -+ -+ switch (param->dram_freq) { -+ case 336: -+ ast_moutdwm(ast, 0x1E6E2020, 0x0190); -+ param->wodt = 0; -+ param->reg_AC1 = 0x22202725; -+ param->reg_AC2 = 0xAA007613 | trap_AC2; -+ param->reg_DQSIC = 0x000000BA; -+ param->reg_MRS = 0x04001400 | trap_MRS; -+ param->reg_EMRS = 0x00000000; -+ param->reg_IOZ = 0x00000023; -+ param->reg_DQIDLY = 0x00000074; -+ param->reg_FREQ = 0x00004DC0; -+ param->madj_max = 96; -+ param->dll2_finetune_step = 3; -+ switch (param->dram_chipid) { -+ default: -+ case AST_DRAM_512Mx16: -+ case AST_DRAM_1Gx16: -+ param->reg_AC2 = 0xAA007613 | trap_AC2; -+ break; -+ case AST_DRAM_2Gx16: -+ param->reg_AC2 = 0xAA00761C | trap_AC2; -+ break; -+ case AST_DRAM_4Gx16: -+ param->reg_AC2 = 0xAA007636 | trap_AC2; -+ break; -+ } -+ break; -+ default: -+ case 396: -+ ast_moutdwm(ast, 0x1E6E2020, 0x03F1); -+ param->wodt = 1; -+ param->reg_AC1 = 0x33302825; -+ param->reg_AC2 = 0xCC009617 | trap_AC2; -+ param->reg_DQSIC = 0x000000E2; -+ param->reg_MRS = 0x04001600 | trap_MRS; -+ param->reg_EMRS = 0x00000000; -+ param->reg_IOZ = 0x00000034; -+ param->reg_DRV = 0x000000FA; -+ param->reg_DQIDLY = 0x00000089; -+ param->reg_FREQ = 0x00005040; -+ param->madj_max = 96; -+ param->dll2_finetune_step = 4; -+ -+ switch (param->dram_chipid) { -+ default: -+ case AST_DRAM_512Mx16: -+ case AST_DRAM_1Gx16: -+ param->reg_AC2 = 0xCC009617 | trap_AC2; -+ break; -+ case AST_DRAM_2Gx16: -+ param->reg_AC2 = 0xCC009622 | trap_AC2; -+ break; -+ case AST_DRAM_4Gx16: -+ param->reg_AC2 = 0xCC00963F | trap_AC2; -+ break; -+ } -+ break; -+ -+ case 408: -+ ast_moutdwm(ast, 0x1E6E2020, 0x01F0); -+ param->wodt = 1; -+ param->reg_AC1 = 0x33302825; -+ param->reg_AC2 = 0xCC009617 | trap_AC2; -+ param->reg_DQSIC = 0x000000E2; -+ param->reg_MRS = 0x04001600 | trap_MRS; -+ param->reg_EMRS = 0x00000000; -+ param->reg_IOZ = 0x00000023; -+ param->reg_DRV = 0x000000FA; -+ param->reg_DQIDLY = 0x00000089; -+ param->reg_FREQ = 0x000050C0; -+ param->madj_max = 96; -+ param->dll2_finetune_step = 4; -+ -+ switch (param->dram_chipid) { -+ default: -+ case AST_DRAM_512Mx16: -+ case AST_DRAM_1Gx16: -+ param->reg_AC2 = 0xCC009617 | trap_AC2; -+ break; -+ case AST_DRAM_2Gx16: -+ param->reg_AC2 = 0xCC009622 | trap_AC2; -+ break; -+ case AST_DRAM_4Gx16: -+ param->reg_AC2 = 0xCC00963F | trap_AC2; -+ break; -+ } -+ -+ break; -+ case 456: -+ ast_moutdwm(ast, 0x1E6E2020, 0x0230); -+ param->wodt = 0; -+ param->reg_AC1 = 0x33302926; -+ param->reg_AC2 = 0xCD44961A; -+ param->reg_DQSIC = 0x000000FC; -+ param->reg_MRS = 0x00081830; -+ param->reg_EMRS = 0x00000000; -+ param->reg_IOZ = 0x00000045; -+ param->reg_DQIDLY = 0x00000097; -+ param->reg_FREQ = 0x000052C0; -+ param->madj_max = 88; -+ param->dll2_finetune_step = 4; -+ break; -+ case 504: -+ ast_moutdwm(ast, 0x1E6E2020, 0x0270); -+ param->wodt = 1; -+ param->reg_AC1 = 0x33302926; -+ param->reg_AC2 = 0xDE44A61D; -+ param->reg_DQSIC = 0x00000117; -+ param->reg_MRS = 0x00081A30; -+ param->reg_EMRS = 0x00000000; -+ param->reg_IOZ = 0x070000BB; -+ param->reg_DQIDLY = 0x000000A0; -+ param->reg_FREQ = 0x000054C0; -+ param->madj_max = 79; -+ param->dll2_finetune_step = 4; -+ break; -+ case 528: -+ ast_moutdwm(ast, 0x1E6E2020, 0x0290); -+ param->wodt = 1; -+ param->rodt = 1; -+ param->reg_AC1 = 0x33302926; -+ param->reg_AC2 = 0xEF44B61E; -+ param->reg_DQSIC = 0x00000125; -+ param->reg_MRS = 0x00081A30; -+ param->reg_EMRS = 0x00000040; -+ param->reg_DRV = 0x000000F5; -+ param->reg_IOZ = 0x00000023; -+ param->reg_DQIDLY = 0x00000088; -+ param->reg_FREQ = 0x000055C0; -+ param->madj_max = 76; -+ param->dll2_finetune_step = 3; -+ break; -+ case 576: -+ ast_moutdwm(ast, 0x1E6E2020, 0x0140); -+ param->reg_MADJ = 0x00136868; -+ param->reg_SADJ = 0x00004534; -+ param->wodt = 1; -+ param->rodt = 1; -+ param->reg_AC1 = 0x33302A37; -+ param->reg_AC2 = 0xEF56B61E; -+ param->reg_DQSIC = 0x0000013F; -+ param->reg_MRS = 0x00101A50; -+ param->reg_EMRS = 0x00000040; -+ param->reg_DRV = 0x000000FA; -+ param->reg_IOZ = 0x00000023; -+ param->reg_DQIDLY = 0x00000078; -+ param->reg_FREQ = 0x000057C0; -+ param->madj_max = 136; -+ param->dll2_finetune_step = 3; -+ break; -+ case 600: -+ ast_moutdwm(ast, 0x1E6E2020, 0x02E1); -+ param->reg_MADJ = 0x00136868; -+ param->reg_SADJ = 0x00004534; -+ param->wodt = 1; -+ param->rodt = 1; -+ param->reg_AC1 = 0x32302A37; -+ param->reg_AC2 = 0xDF56B61F; -+ param->reg_DQSIC = 0x0000014D; -+ param->reg_MRS = 0x00101A50; -+ param->reg_EMRS = 0x00000004; -+ param->reg_DRV = 0x000000F5; -+ param->reg_IOZ = 0x00000023; -+ param->reg_DQIDLY = 0x00000078; -+ param->reg_FREQ = 0x000058C0; -+ param->madj_max = 132; -+ param->dll2_finetune_step = 3; -+ break; -+ case 624: -+ ast_moutdwm(ast, 0x1E6E2020, 0x0160); -+ param->reg_MADJ = 0x00136868; -+ param->reg_SADJ = 0x00004534; -+ param->wodt = 1; -+ param->rodt = 1; -+ param->reg_AC1 = 0x32302A37; -+ param->reg_AC2 = 0xEF56B621; -+ param->reg_DQSIC = 0x0000015A; -+ param->reg_MRS = 0x02101A50; -+ param->reg_EMRS = 0x00000004; -+ param->reg_DRV = 0x000000F5; -+ param->reg_IOZ = 0x00000034; -+ param->reg_DQIDLY = 0x00000078; -+ param->reg_FREQ = 0x000059C0; -+ param->madj_max = 128; -+ param->dll2_finetune_step = 3; -+ break; -+ } /* switch freq */ -+ -+ switch (param->dram_chipid) { -+ case AST_DRAM_512Mx16: -+ param->dram_config = 0x130; -+ break; -+ default: -+ case AST_DRAM_1Gx16: -+ param->dram_config = 0x131; -+ break; -+ case AST_DRAM_2Gx16: -+ param->dram_config = 0x132; -+ break; -+ case AST_DRAM_4Gx16: -+ param->dram_config = 0x133; -+ break; -+ } /* switch size */ -+ -+ switch (param->vram_size) { -+ default: -+ case AST_VIDMEM_SIZE_8M: -+ param->dram_config |= 0x00; -+ break; -+ case AST_VIDMEM_SIZE_16M: -+ param->dram_config |= 0x04; -+ break; -+ case AST_VIDMEM_SIZE_32M: -+ param->dram_config |= 0x08; -+ break; -+ case AST_VIDMEM_SIZE_64M: -+ param->dram_config |= 0x0c; -+ break; -+ } -+ -+} -+ -+static void ddr3_init(struct ast_private *ast, struct ast2300_dram_param *param) -+{ -+ u32 data, data2, retry = 0; -+ -+ddr3_init_start: -+ ast_moutdwm(ast, 0x1E6E0000, 0xFC600309); -+ ast_moutdwm(ast, 0x1E6E0018, 0x00000100); -+ ast_moutdwm(ast, 0x1E6E0024, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0034, 0x00000000); -+ udelay(10); -+ ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ); -+ ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ); -+ udelay(10); -+ ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000); -+ udelay(10); -+ -+ ast_moutdwm(ast, 0x1E6E0004, param->dram_config); -+ ast_moutdwm(ast, 0x1E6E0008, 0x90040f); -+ ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1); -+ ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2); -+ ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC); -+ ast_moutdwm(ast, 0x1E6E0080, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0084, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY); -+ ast_moutdwm(ast, 0x1E6E0018, 0x4000A170); -+ ast_moutdwm(ast, 0x1E6E0018, 0x00002370); -+ ast_moutdwm(ast, 0x1E6E0038, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0040, 0xFF444444); -+ ast_moutdwm(ast, 0x1E6E0044, 0x22222222); -+ ast_moutdwm(ast, 0x1E6E0048, 0x22222222); -+ ast_moutdwm(ast, 0x1E6E004C, 0x00000002); -+ ast_moutdwm(ast, 0x1E6E0050, 0x80000000); -+ ast_moutdwm(ast, 0x1E6E0050, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0054, 0); -+ ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV); -+ ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ); -+ ast_moutdwm(ast, 0x1E6E0070, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0074, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0078, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E007C, 0x00000000); -+ /* Wait MCLK2X lock to MCLK */ -+ do { -+ data = ast_mindwm(ast, 0x1E6E001C); -+ } while (!(data & 0x08000000)); -+ data = ast_mindwm(ast, 0x1E6E001C); -+ data = (data >> 8) & 0xff; -+ while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) { -+ data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4; -+ if ((data2 & 0xff) > param->madj_max) { -+ break; -+ } -+ ast_moutdwm(ast, 0x1E6E0064, data2); -+ if (data2 & 0x00100000) { -+ data2 = ((data2 & 0xff) >> 3) + 3; -+ } else { -+ data2 = ((data2 & 0xff) >> 2) + 5; -+ } -+ data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff; -+ data2 += data & 0xff; -+ data = data | (data2 << 8); -+ ast_moutdwm(ast, 0x1E6E0068, data); -+ udelay(10); -+ ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000); -+ udelay(10); -+ data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff; -+ ast_moutdwm(ast, 0x1E6E0018, data); -+ data = data | 0x200; -+ ast_moutdwm(ast, 0x1E6E0018, data); -+ do { -+ data = ast_mindwm(ast, 0x1E6E001C); -+ } while (!(data & 0x08000000)); -+ -+ data = ast_mindwm(ast, 0x1E6E001C); -+ data = (data >> 8) & 0xff; -+ } -+ ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0068) & 0xffff); -+ data = ast_mindwm(ast, 0x1E6E0018) | 0xC00; -+ ast_moutdwm(ast, 0x1E6E0018, data); -+ -+ ast_moutdwm(ast, 0x1E6E0034, 0x00000001); -+ ast_moutdwm(ast, 0x1E6E000C, 0x00000040); -+ udelay(50); -+ /* Mode Register Setting */ -+ ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100); -+ ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS); -+ ast_moutdwm(ast, 0x1E6E0028, 0x00000005); -+ ast_moutdwm(ast, 0x1E6E0028, 0x00000007); -+ ast_moutdwm(ast, 0x1E6E0028, 0x00000003); -+ ast_moutdwm(ast, 0x1E6E0028, 0x00000001); -+ ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS); -+ ast_moutdwm(ast, 0x1E6E000C, 0x00005C08); -+ ast_moutdwm(ast, 0x1E6E0028, 0x00000001); -+ -+ ast_moutdwm(ast, 0x1E6E000C, 0x00005C01); -+ data = 0; -+ if (param->wodt) { -+ data = 0x300; -+ } -+ if (param->rodt) { -+ data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3); -+ } -+ ast_moutdwm(ast, 0x1E6E0034, data | 0x3); -+ -+ /* Calibrate the DQSI delay */ -+ if ((cbr_dll2(ast, param) == false) && (retry++ < 10)) -+ goto ddr3_init_start; -+ -+ ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ); -+ /* ECC Memory Initialization */ -+#ifdef ECC -+ ast_moutdwm(ast, 0x1E6E007C, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0070, 0x221); -+ do { -+ data = ast_mindwm(ast, 0x1E6E0070); -+ } while (!(data & 0x00001000)); -+ ast_moutdwm(ast, 0x1E6E0070, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0050, 0x80000000); -+ ast_moutdwm(ast, 0x1E6E0050, 0x00000000); -+#endif -+ -+ -+} -+ -+static void get_ddr2_info(struct ast_private *ast, struct ast2300_dram_param *param) -+{ -+ u32 trap, trap_AC2, trap_MRS; -+ -+ ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8); -+ -+ /* Ger trap info */ -+ trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3; -+ trap_AC2 = (trap << 20) | (trap << 16); -+ trap_AC2 += 0x00110000; -+ trap_MRS = 0x00000040 | (trap << 4); -+ -+ -+ param->reg_MADJ = 0x00034C4C; -+ param->reg_SADJ = 0x00001800; -+ param->reg_DRV = 0x000000F0; -+ param->reg_PERIOD = param->dram_freq; -+ param->rodt = 0; -+ -+ switch (param->dram_freq) { -+ case 264: -+ ast_moutdwm(ast, 0x1E6E2020, 0x0130); -+ param->wodt = 0; -+ param->reg_AC1 = 0x11101513; -+ param->reg_AC2 = 0x78117011; -+ param->reg_DQSIC = 0x00000092; -+ param->reg_MRS = 0x00000842; -+ param->reg_EMRS = 0x00000000; -+ param->reg_DRV = 0x000000F0; -+ param->reg_IOZ = 0x00000034; -+ param->reg_DQIDLY = 0x0000005A; -+ param->reg_FREQ = 0x00004AC0; -+ param->madj_max = 138; -+ param->dll2_finetune_step = 3; -+ break; -+ case 336: -+ ast_moutdwm(ast, 0x1E6E2020, 0x0190); -+ param->wodt = 1; -+ param->reg_AC1 = 0x22202613; -+ param->reg_AC2 = 0xAA009016 | trap_AC2; -+ param->reg_DQSIC = 0x000000BA; -+ param->reg_MRS = 0x00000A02 | trap_MRS; -+ param->reg_EMRS = 0x00000040; -+ param->reg_DRV = 0x000000FA; -+ param->reg_IOZ = 0x00000034; -+ param->reg_DQIDLY = 0x00000074; -+ param->reg_FREQ = 0x00004DC0; -+ param->madj_max = 96; -+ param->dll2_finetune_step = 3; -+ switch (param->dram_chipid) { -+ default: -+ case AST_DRAM_512Mx16: -+ param->reg_AC2 = 0xAA009012 | trap_AC2; -+ break; -+ case AST_DRAM_1Gx16: -+ param->reg_AC2 = 0xAA009016 | trap_AC2; -+ break; -+ case AST_DRAM_2Gx16: -+ param->reg_AC2 = 0xAA009023 | trap_AC2; -+ break; -+ case AST_DRAM_4Gx16: -+ param->reg_AC2 = 0xAA00903B | trap_AC2; -+ break; -+ } -+ break; -+ default: -+ case 396: -+ ast_moutdwm(ast, 0x1E6E2020, 0x03F1); -+ param->wodt = 1; -+ param->rodt = 0; -+ param->reg_AC1 = 0x33302714; -+ param->reg_AC2 = 0xCC00B01B | trap_AC2; -+ param->reg_DQSIC = 0x000000E2; -+ param->reg_MRS = 0x00000C02 | trap_MRS; -+ param->reg_EMRS = 0x00000040; -+ param->reg_DRV = 0x000000FA; -+ param->reg_IOZ = 0x00000034; -+ param->reg_DQIDLY = 0x00000089; -+ param->reg_FREQ = 0x00005040; -+ param->madj_max = 96; -+ param->dll2_finetune_step = 4; -+ -+ switch (param->dram_chipid) { -+ case AST_DRAM_512Mx16: -+ param->reg_AC2 = 0xCC00B016 | trap_AC2; -+ break; -+ default: -+ case AST_DRAM_1Gx16: -+ param->reg_AC2 = 0xCC00B01B | trap_AC2; -+ break; -+ case AST_DRAM_2Gx16: -+ param->reg_AC2 = 0xCC00B02B | trap_AC2; -+ break; -+ case AST_DRAM_4Gx16: -+ param->reg_AC2 = 0xCC00B03F | trap_AC2; -+ break; -+ } -+ -+ break; -+ -+ case 408: -+ ast_moutdwm(ast, 0x1E6E2020, 0x01F0); -+ param->wodt = 1; -+ param->rodt = 0; -+ param->reg_AC1 = 0x33302714; -+ param->reg_AC2 = 0xCC00B01B | trap_AC2; -+ param->reg_DQSIC = 0x000000E2; -+ param->reg_MRS = 0x00000C02 | trap_MRS; -+ param->reg_EMRS = 0x00000040; -+ param->reg_DRV = 0x000000FA; -+ param->reg_IOZ = 0x00000034; -+ param->reg_DQIDLY = 0x00000089; -+ param->reg_FREQ = 0x000050C0; -+ param->madj_max = 96; -+ param->dll2_finetune_step = 4; -+ -+ switch (param->dram_chipid) { -+ case AST_DRAM_512Mx16: -+ param->reg_AC2 = 0xCC00B016 | trap_AC2; -+ break; -+ default: -+ case AST_DRAM_1Gx16: -+ param->reg_AC2 = 0xCC00B01B | trap_AC2; -+ break; -+ case AST_DRAM_2Gx16: -+ param->reg_AC2 = 0xCC00B02B | trap_AC2; -+ break; -+ case AST_DRAM_4Gx16: -+ param->reg_AC2 = 0xCC00B03F | trap_AC2; -+ break; -+ } -+ -+ break; -+ case 456: -+ ast_moutdwm(ast, 0x1E6E2020, 0x0230); -+ param->wodt = 0; -+ param->reg_AC1 = 0x33302815; -+ param->reg_AC2 = 0xCD44B01E; -+ param->reg_DQSIC = 0x000000FC; -+ param->reg_MRS = 0x00000E72; -+ param->reg_EMRS = 0x00000000; -+ param->reg_DRV = 0x00000000; -+ param->reg_IOZ = 0x00000034; -+ param->reg_DQIDLY = 0x00000097; -+ param->reg_FREQ = 0x000052C0; -+ param->madj_max = 88; -+ param->dll2_finetune_step = 3; -+ break; -+ case 504: -+ ast_moutdwm(ast, 0x1E6E2020, 0x0261); -+ param->wodt = 1; -+ param->rodt = 1; -+ param->reg_AC1 = 0x33302815; -+ param->reg_AC2 = 0xDE44C022; -+ param->reg_DQSIC = 0x00000117; -+ param->reg_MRS = 0x00000E72; -+ param->reg_EMRS = 0x00000040; -+ param->reg_DRV = 0x0000000A; -+ param->reg_IOZ = 0x00000045; -+ param->reg_DQIDLY = 0x000000A0; -+ param->reg_FREQ = 0x000054C0; -+ param->madj_max = 79; -+ param->dll2_finetune_step = 3; -+ break; -+ case 528: -+ ast_moutdwm(ast, 0x1E6E2020, 0x0120); -+ param->wodt = 1; -+ param->rodt = 1; -+ param->reg_AC1 = 0x33302815; -+ param->reg_AC2 = 0xEF44D024; -+ param->reg_DQSIC = 0x00000125; -+ param->reg_MRS = 0x00000E72; -+ param->reg_EMRS = 0x00000004; -+ param->reg_DRV = 0x000000F9; -+ param->reg_IOZ = 0x00000045; -+ param->reg_DQIDLY = 0x000000A7; -+ param->reg_FREQ = 0x000055C0; -+ param->madj_max = 76; -+ param->dll2_finetune_step = 3; -+ break; -+ case 552: -+ ast_moutdwm(ast, 0x1E6E2020, 0x02A1); -+ param->wodt = 1; -+ param->rodt = 1; -+ param->reg_AC1 = 0x43402915; -+ param->reg_AC2 = 0xFF44E025; -+ param->reg_DQSIC = 0x00000132; -+ param->reg_MRS = 0x00000E72; -+ param->reg_EMRS = 0x00000040; -+ param->reg_DRV = 0x0000000A; -+ param->reg_IOZ = 0x00000045; -+ param->reg_DQIDLY = 0x000000AD; -+ param->reg_FREQ = 0x000056C0; -+ param->madj_max = 76; -+ param->dll2_finetune_step = 3; -+ break; -+ case 576: -+ ast_moutdwm(ast, 0x1E6E2020, 0x0140); -+ param->wodt = 1; -+ param->rodt = 1; -+ param->reg_AC1 = 0x43402915; -+ param->reg_AC2 = 0xFF44E027; -+ param->reg_DQSIC = 0x0000013F; -+ param->reg_MRS = 0x00000E72; -+ param->reg_EMRS = 0x00000004; -+ param->reg_DRV = 0x000000F5; -+ param->reg_IOZ = 0x00000045; -+ param->reg_DQIDLY = 0x000000B3; -+ param->reg_FREQ = 0x000057C0; -+ param->madj_max = 76; -+ param->dll2_finetune_step = 3; -+ break; -+ } -+ -+ switch (param->dram_chipid) { -+ case AST_DRAM_512Mx16: -+ param->dram_config = 0x100; -+ break; -+ default: -+ case AST_DRAM_1Gx16: -+ param->dram_config = 0x121; -+ break; -+ case AST_DRAM_2Gx16: -+ param->dram_config = 0x122; -+ break; -+ case AST_DRAM_4Gx16: -+ param->dram_config = 0x123; -+ break; -+ } /* switch size */ -+ -+ switch (param->vram_size) { -+ default: -+ case AST_VIDMEM_SIZE_8M: -+ param->dram_config |= 0x00; -+ break; -+ case AST_VIDMEM_SIZE_16M: -+ param->dram_config |= 0x04; -+ break; -+ case AST_VIDMEM_SIZE_32M: -+ param->dram_config |= 0x08; -+ break; -+ case AST_VIDMEM_SIZE_64M: -+ param->dram_config |= 0x0c; -+ break; -+ } -+} -+ -+static void ddr2_init(struct ast_private *ast, struct ast2300_dram_param *param) -+{ -+ u32 data, data2, retry = 0; -+ -+ddr2_init_start: -+ ast_moutdwm(ast, 0x1E6E0000, 0xFC600309); -+ ast_moutdwm(ast, 0x1E6E0018, 0x00000100); -+ ast_moutdwm(ast, 0x1E6E0024, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ); -+ ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ); -+ udelay(10); -+ ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000); -+ udelay(10); -+ -+ ast_moutdwm(ast, 0x1E6E0004, param->dram_config); -+ ast_moutdwm(ast, 0x1E6E0008, 0x90040f); -+ ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1); -+ ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2); -+ ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC); -+ ast_moutdwm(ast, 0x1E6E0080, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0084, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY); -+ ast_moutdwm(ast, 0x1E6E0018, 0x4000A130); -+ ast_moutdwm(ast, 0x1E6E0018, 0x00002330); -+ ast_moutdwm(ast, 0x1E6E0038, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0040, 0xFF808000); -+ ast_moutdwm(ast, 0x1E6E0044, 0x88848466); -+ ast_moutdwm(ast, 0x1E6E0048, 0x44440008); -+ ast_moutdwm(ast, 0x1E6E004C, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0050, 0x80000000); -+ ast_moutdwm(ast, 0x1E6E0050, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0054, 0); -+ ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV); -+ ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ); -+ ast_moutdwm(ast, 0x1E6E0070, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0074, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0078, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E007C, 0x00000000); -+ -+ /* Wait MCLK2X lock to MCLK */ -+ do { -+ data = ast_mindwm(ast, 0x1E6E001C); -+ } while (!(data & 0x08000000)); -+ data = ast_mindwm(ast, 0x1E6E001C); -+ data = (data >> 8) & 0xff; -+ while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) { -+ data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4; -+ if ((data2 & 0xff) > param->madj_max) { -+ break; -+ } -+ ast_moutdwm(ast, 0x1E6E0064, data2); -+ if (data2 & 0x00100000) { -+ data2 = ((data2 & 0xff) >> 3) + 3; -+ } else { -+ data2 = ((data2 & 0xff) >> 2) + 5; -+ } -+ data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff; -+ data2 += data & 0xff; -+ data = data | (data2 << 8); -+ ast_moutdwm(ast, 0x1E6E0068, data); -+ udelay(10); -+ ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000); -+ udelay(10); -+ data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff; -+ ast_moutdwm(ast, 0x1E6E0018, data); -+ data = data | 0x200; -+ ast_moutdwm(ast, 0x1E6E0018, data); -+ do { -+ data = ast_mindwm(ast, 0x1E6E001C); -+ } while (!(data & 0x08000000)); -+ -+ data = ast_mindwm(ast, 0x1E6E001C); -+ data = (data >> 8) & 0xff; -+ } -+ ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0008) & 0xffff); -+ data = ast_mindwm(ast, 0x1E6E0018) | 0xC00; -+ ast_moutdwm(ast, 0x1E6E0018, data); -+ -+ ast_moutdwm(ast, 0x1E6E0034, 0x00000001); -+ ast_moutdwm(ast, 0x1E6E000C, 0x00000000); -+ udelay(50); -+ /* Mode Register Setting */ -+ ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100); -+ ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS); -+ ast_moutdwm(ast, 0x1E6E0028, 0x00000005); -+ ast_moutdwm(ast, 0x1E6E0028, 0x00000007); -+ ast_moutdwm(ast, 0x1E6E0028, 0x00000003); -+ ast_moutdwm(ast, 0x1E6E0028, 0x00000001); -+ -+ ast_moutdwm(ast, 0x1E6E000C, 0x00005C08); -+ ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS); -+ ast_moutdwm(ast, 0x1E6E0028, 0x00000001); -+ ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380); -+ ast_moutdwm(ast, 0x1E6E0028, 0x00000003); -+ ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS); -+ ast_moutdwm(ast, 0x1E6E0028, 0x00000003); -+ -+ ast_moutdwm(ast, 0x1E6E000C, 0x7FFF5C01); -+ data = 0; -+ if (param->wodt) { -+ data = 0x500; -+ } -+ if (param->rodt) { -+ data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3); -+ } -+ ast_moutdwm(ast, 0x1E6E0034, data | 0x3); -+ ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ); -+ -+ /* Calibrate the DQSI delay */ -+ if ((cbr_dll2(ast, param) == false) && (retry++ < 10)) -+ goto ddr2_init_start; -+ -+ /* ECC Memory Initialization */ -+#ifdef ECC -+ ast_moutdwm(ast, 0x1E6E007C, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0070, 0x221); -+ do { -+ data = ast_mindwm(ast, 0x1E6E0070); -+ } while (!(data & 0x00001000)); -+ ast_moutdwm(ast, 0x1E6E0070, 0x00000000); -+ ast_moutdwm(ast, 0x1E6E0050, 0x80000000); -+ ast_moutdwm(ast, 0x1E6E0050, 0x00000000); -+#endif -+ -+} -+ -+static void ast_init_dram_2300(struct drm_device *dev) -+{ -+ struct ast_private *ast = dev->dev_private; -+ struct ast2300_dram_param param; -+ u32 temp; -+ u8 reg; -+ -+ reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); -+ if ((reg & 0x80) == 0) {/* vga only */ -+ ast_write32(ast, 0xf004, 0x1e6e0000); -+ ast_write32(ast, 0xf000, 0x1); -+ ast_write32(ast, 0x12000, 0x1688a8a8); -+ do { -+ ; -+ } while (ast_read32(ast, 0x12000) != 0x1); -+ -+ ast_write32(ast, 0x10000, 0xfc600309); -+ do { -+ ; -+ } while (ast_read32(ast, 0x10000) != 0x1); -+ -+ /* Slow down CPU/AHB CLK in VGA only mode */ -+ temp = ast_read32(ast, 0x12008); -+ temp |= 0x73; -+ ast_write32(ast, 0x12008, temp); -+ -+ param.dram_type = AST_DDR3; -+ if (temp & 0x01000000) -+ param.dram_type = AST_DDR2; -+ param.dram_chipid = ast->dram_type; -+ param.dram_freq = ast->mclk; -+ param.vram_size = ast->vram_size; -+ -+ if (param.dram_type == AST_DDR3) { -+ get_ddr3_info(ast, &param); -+ ddr3_init(ast, &param); -+ } else { -+ get_ddr2_info(ast, &param); -+ ddr2_init(ast, &param); -+ } -+ -+ temp = ast_mindwm(ast, 0x1e6e2040); -+ ast_moutdwm(ast, 0x1e6e2040, temp | 0x40); -+ } -+ -+ /* wait ready */ -+ do { -+ reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); -+ } while ((reg & 0x40) == 0); -+} -+ -diff --git a/src/drivers/aspeed/common/ast_tables.h b/src/drivers/aspeed/common/ast_tables.h -new file mode 100644 -index 0000000..3608d5a ---- /dev/null -+++ b/src/drivers/aspeed/common/ast_tables.h -@@ -0,0 +1,305 @@ -+/* -+ * Copyright (c) 2005 ASPEED Technology Inc. -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and its -+ * documentation for any purpose is hereby granted without fee, provided that -+ * the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation, and that the name of the authors not be used in -+ * advertising or publicity pertaining to distribution of the software without -+ * specific, written prior permission. The authors makes no representations -+ * about the suitability of this software for any purpose. It is provided -+ * "as is" without express or implied warranty. -+ * -+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR -+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -+ * PERFORMANCE OF THIS SOFTWARE. -+ */ -+/* Ported from xf86-video-ast driver */ -+ -+#ifndef AST_TABLES_H -+#define AST_TABLES_H -+ -+/* Std. Table Index Definition */ -+#define TextModeIndex 0 -+#define EGAModeIndex 1 -+#define VGAModeIndex 2 -+#define HiCModeIndex 3 -+#define TrueCModeIndex 4 -+ -+#define Charx8Dot 0x00000001 -+#define HalfDCLK 0x00000002 -+#define DoubleScanMode 0x00000004 -+#define LineCompareOff 0x00000008 -+#define HBorder 0x00000020 -+#define VBorder 0x00000010 -+#define WideScreenMode 0x00000100 -+#define NewModeInfo 0x00000200 -+#define NHSync 0x00000400 -+#define PHSync 0x00000800 -+#define NVSync 0x00001000 -+#define PVSync 0x00002000 -+#define SyncPP (PVSync | PHSync) -+#define SyncPN (PVSync | NHSync) -+#define SyncNP (NVSync | PHSync) -+#define SyncNN (NVSync | NHSync) -+ -+/* DCLK Index */ -+#define VCLK25_175 0x00 -+#define VCLK28_322 0x01 -+#define VCLK31_5 0x02 -+#define VCLK36 0x03 -+#define VCLK40 0x04 -+#define VCLK49_5 0x05 -+#define VCLK50 0x06 -+#define VCLK56_25 0x07 -+#define VCLK65 0x08 -+#define VCLK75 0x09 -+#define VCLK78_75 0x0A -+#define VCLK94_5 0x0B -+#define VCLK108 0x0C -+#define VCLK135 0x0D -+#define VCLK157_5 0x0E -+#define VCLK162 0x0F -+/* #define VCLK193_25 0x10 */ -+#define VCLK154 0x10 -+#define VCLK83_5 0x11 -+#define VCLK106_5 0x12 -+#define VCLK146_25 0x13 -+#define VCLK148_5 0x14 -+#define VCLK71 0x15 -+#define VCLK88_75 0x16 -+#define VCLK119 0x17 -+#define VCLK85_5 0x18 -+#define VCLK97_75 0x19 -+#define VCLK118_25 0x1A -+ -+static struct ast_vbios_dclk_info dclk_table[] = { -+ {0x2C, 0xE7, 0x03}, /* 00: VCLK25_175 */ -+ {0x95, 0x62, 0x03}, /* 01: VCLK28_322 */ -+ {0x67, 0x63, 0x01}, /* 02: VCLK31_5 */ -+ {0x76, 0x63, 0x01}, /* 03: VCLK36 */ -+ {0xEE, 0x67, 0x01}, /* 04: VCLK40 */ -+ {0x82, 0x62, 0x01}, /* 05: VCLK49_5 */ -+ {0xC6, 0x64, 0x01}, /* 06: VCLK50 */ -+ {0x94, 0x62, 0x01}, /* 07: VCLK56_25 */ -+ {0x80, 0x64, 0x00}, /* 08: VCLK65 */ -+ {0x7B, 0x63, 0x00}, /* 09: VCLK75 */ -+ {0x67, 0x62, 0x00}, /* 0A: VCLK78_75 */ -+ {0x7C, 0x62, 0x00}, /* 0B: VCLK94_5 */ -+ {0x8E, 0x62, 0x00}, /* 0C: VCLK108 */ -+ {0x85, 0x24, 0x00}, /* 0D: VCLK135 */ -+ {0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */ -+ {0x6A, 0x22, 0x00}, /* 0F: VCLK162 */ -+ {0x4d, 0x4c, 0x80}, /* 10: VCLK154 */ -+ {0xa7, 0x78, 0x80}, /* 11: VCLK83.5 */ -+ {0x28, 0x49, 0x80}, /* 12: VCLK106.5 */ -+ {0x37, 0x49, 0x80}, /* 13: VCLK146.25 */ -+ {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */ -+ {0x47, 0x6c, 0x80}, /* 15: VCLK71 */ -+ {0x25, 0x65, 0x80}, /* 16: VCLK88.75 */ -+ {0x77, 0x58, 0x80}, /* 17: VCLK119 */ -+ {0x32, 0x67, 0x80}, /* 18: VCLK85_5 */ -+ {0x6a, 0x6d, 0x80}, /* 19: VCLK97_75 */ -+ {0x3b, 0x2c, 0x81}, /* 1A: VCLK118_25 */ -+}; -+ -+static struct ast_vbios_stdtable vbios_stdtable[] = { -+ /* MD_2_3_400 */ -+ { -+ 0x67, -+ {0x00,0x03,0x00,0x02}, -+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, -+ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, -+ 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, -+ 0xff}, -+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, -+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, -+ 0x0c,0x00,0x0f,0x08}, -+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, -+ 0xff} -+ }, -+ /* Mode12/ExtEGATable */ -+ { -+ 0xe3, -+ {0x01,0x0f,0x00,0x06}, -+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, -+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3, -+ 0xff}, -+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, -+ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, -+ 0x01,0x00,0x0f,0x00}, -+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, -+ 0xff} -+ }, -+ /* ExtVGATable */ -+ { -+ 0x2f, -+ {0x01,0x0f,0x00,0x0e}, -+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, -+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, -+ 0xff}, -+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, -+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, -+ 0x01,0x00,0x00,0x00}, -+ {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, -+ 0xff} -+ }, -+ /* ExtHiCTable */ -+ { -+ 0x2f, -+ {0x01,0x0f,0x00,0x0e}, -+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, -+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, -+ 0xff}, -+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, -+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, -+ 0x01,0x00,0x00,0x00}, -+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, -+ 0xff} -+ }, -+ /* ExtTrueCTable */ -+ { -+ 0x2f, -+ {0x01,0x0f,0x00,0x0e}, -+ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, -+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, -+ 0xff}, -+ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, -+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, -+ 0x01,0x00,0x00,0x00}, -+ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, -+ 0xff} -+ }, -+}; -+ -+static struct ast_vbios_enhtable res_640x480[] = { -+ { 800, 640, 8, 96, 525, 480, 2, 2, VCLK25_175, /* 60Hz */ -+ (SyncNN | HBorder | VBorder | Charx8Dot), 60, 1, 0x2E }, -+ { 832, 640, 16, 40, 520, 480, 1, 3, VCLK31_5, /* 72Hz */ -+ (SyncNN | HBorder | VBorder | Charx8Dot), 72, 2, 0x2E }, -+ { 840, 640, 16, 64, 500, 480, 1, 3, VCLK31_5, /* 75Hz */ -+ (SyncNN | Charx8Dot) , 75, 3, 0x2E }, -+ { 832, 640, 56, 56, 509, 480, 1, 3, VCLK36, /* 85Hz */ -+ (SyncNN | Charx8Dot) , 85, 4, 0x2E }, -+ { 832, 640, 56, 56, 509, 480, 1, 3, VCLK36, /* end */ -+ (SyncNN | Charx8Dot) , 0xFF, 4, 0x2E }, -+}; -+ -+static struct ast_vbios_enhtable res_800x600[] = { -+ {1024, 800, 24, 72, 625, 600, 1, 2, VCLK36, /* 56Hz */ -+ (SyncPP | Charx8Dot), 56, 1, 0x30 }, -+ {1056, 800, 40, 128, 628, 600, 1, 4, VCLK40, /* 60Hz */ -+ (SyncPP | Charx8Dot), 60, 2, 0x30 }, -+ {1040, 800, 56, 120, 666, 600, 37, 6, VCLK50, /* 72Hz */ -+ (SyncPP | Charx8Dot), 72, 3, 0x30 }, -+ {1056, 800, 16, 80, 625, 600, 1, 3, VCLK49_5, /* 75Hz */ -+ (SyncPP | Charx8Dot), 75, 4, 0x30 }, -+ {1048, 800, 32, 64, 631, 600, 1, 3, VCLK56_25, /* 85Hz */ -+ (SyncPP | Charx8Dot), 84, 5, 0x30 }, -+ {1048, 800, 32, 64, 631, 600, 1, 3, VCLK56_25, /* end */ -+ (SyncPP | Charx8Dot), 0xFF, 5, 0x30 }, -+}; -+ -+ -+static struct ast_vbios_enhtable res_1024x768[] = { -+ {1344, 1024, 24, 136, 806, 768, 3, 6, VCLK65, /* 60Hz */ -+ (SyncNN | Charx8Dot), 60, 1, 0x31 }, -+ {1328, 1024, 24, 136, 806, 768, 3, 6, VCLK75, /* 70Hz */ -+ (SyncNN | Charx8Dot), 70, 2, 0x31 }, -+ {1312, 1024, 16, 96, 800, 768, 1, 3, VCLK78_75, /* 75Hz */ -+ (SyncPP | Charx8Dot), 75, 3, 0x31 }, -+ {1376, 1024, 48, 96, 808, 768, 1, 3, VCLK94_5, /* 85Hz */ -+ (SyncPP | Charx8Dot), 84, 4, 0x31 }, -+ {1376, 1024, 48, 96, 808, 768, 1, 3, VCLK94_5, /* end */ -+ (SyncPP | Charx8Dot), 0xFF, 4, 0x31 }, -+}; -+ -+static struct ast_vbios_enhtable res_1280x1024[] = { -+ {1688, 1280, 48, 112, 1066, 1024, 1, 3, VCLK108, /* 60Hz */ -+ (SyncPP | Charx8Dot), 60, 1, 0x32 }, -+ {1688, 1280, 16, 144, 1066, 1024, 1, 3, VCLK135, /* 75Hz */ -+ (SyncPP | Charx8Dot), 75, 2, 0x32 }, -+ {1728, 1280, 64, 160, 1072, 1024, 1, 3, VCLK157_5, /* 85Hz */ -+ (SyncPP | Charx8Dot), 85, 3, 0x32 }, -+ {1728, 1280, 64, 160, 1072, 1024, 1, 3, VCLK157_5, /* end */ -+ (SyncPP | Charx8Dot), 0xFF, 3, 0x32 }, -+}; -+ -+static struct ast_vbios_enhtable res_1600x1200[] = { -+ {2160, 1600, 64, 192, 1250, 1200, 1, 3, VCLK162, /* 60Hz */ -+ (SyncPP | Charx8Dot), 60, 1, 0x33 }, -+ {2160, 1600, 64, 192, 1250, 1200, 1, 3, VCLK162, /* end */ -+ (SyncPP | Charx8Dot), 0xFF, 1, 0x33 }, -+}; -+ -+/* 16:9 */ -+static struct ast_vbios_enhtable res_1360x768[] = { -+ {1792, 1360, 64,112, 795, 768, 3, 6, VCLK85_5, /* 60Hz */ -+ (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x39 }, -+ {1792, 1360, 64,112, 795, 768, 3, 6, VCLK85_5, /* end */ -+ (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x39 }, -+}; -+ -+static struct ast_vbios_enhtable res_1600x900[] = { -+ {1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75, /* 60Hz CVT RB */ -+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x3A }, -+ {2112, 1600, 88,168, 934, 900, 3, 5, VCLK118_25, /* 60Hz CVT */ -+ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x3A }, -+ {2112, 1600, 88,168, 934, 900, 3, 5, VCLK118_25, /* 60Hz CVT */ -+ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 2, 0x3A }, -+}; -+ -+static struct ast_vbios_enhtable res_1920x1080[] = { -+ {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ -+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x38 }, -+ {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ -+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x38 }, -+}; -+ -+ -+/* 16:10 */ -+static struct ast_vbios_enhtable res_1280x800[] = { -+ {1440, 1280, 48, 32, 823, 800, 3, 6, VCLK71, /* 60Hz RB */ -+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x35 }, -+ {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */ -+ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x35 }, -+ {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */ -+ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 2, 0x35 }, -+ -+}; -+ -+static struct ast_vbios_enhtable res_1440x900[] = { -+ {1600, 1440, 48, 32, 926, 900, 3, 6, VCLK88_75, /* 60Hz RB */ -+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x36 }, -+ {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */ -+ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x36 }, -+ {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */ -+ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 2, 0x36 }, -+}; -+ -+static struct ast_vbios_enhtable res_1680x1050[] = { -+ {1840, 1680, 48, 32, 1080, 1050, 3, 6, VCLK119, /* 60Hz RB */ -+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x37 }, -+ {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */ -+ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x37 }, -+ {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */ -+ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 2, 0x37 }, -+}; -+ -+static struct ast_vbios_enhtable res_1920x1200[] = { -+ {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz RB*/ -+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x34 }, -+ {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz RB */ -+ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x34 }, -+}; -+ -+#endif -diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h -index dcb8a42..fcaf4aa 100644 ---- a/src/include/device/pci_ids.h -+++ b/src/include/device/pci_ids.h -@@ -1991,6 +1991,9 @@ - #define PCI_DEVICE_ID_XGI_20 0x0020 - #define PCI_DEVICE_ID_XGI_40 0x0040 - -+#define PCI_VENDOR_ID_ASPEED 0x1a03 -+#define PCI_DEVICE_ID_ASPEED_AST2050_VGA 0x2000 -+ - #define PCI_VENDOR_ID_SYMPHONY 0x1c1c - #define PCI_DEVICE_ID_SYMPHONY_101 0x0001 - --- -1.9.1 - diff --git a/resources/libreboot/patch/kgpe-d16/0004-drivers-i2c-w83795-Add-option-to-use-auxiliary-SMBUS.patch b/resources/libreboot/patch/kgpe-d16/0004-drivers-i2c-w83795-Add-option-to-use-auxiliary-SMBUS.patch @@ -0,0 +1,68 @@ +From 8996dda2293b74ec84251cc2eefb7722acd6bd6b Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Sat, 17 Oct 2015 04:37:10 -0500 +Subject: [PATCH 004/143] drivers/i2c/w83795: Add option to use auxiliary + SMBUS controller + +Change-Id: I5a9b5eba992853b84b0cb6c3a1764edf42ac49b2 +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/drivers/i2c/w83795/chip.h | 7 +++++++ + src/drivers/i2c/w83795/w83795.c | 17 +++++++++++++++++ + 2 files changed, 24 insertions(+) + +diff --git a/src/drivers/i2c/w83795/chip.h b/src/drivers/i2c/w83795/chip.h +index c8a42ea..9a3f847 100644 +--- a/src/drivers/i2c/w83795/chip.h ++++ b/src/drivers/i2c/w83795/chip.h +@@ -139,4 +139,11 @@ struct drivers_i2c_w83795_config { + uint8_t fan6_duty; /* % of full speed (0-100) */ + uint8_t fan7_duty; /* % of full speed (0-100) */ + uint8_t fan8_duty; /* % of full speed (0-100) */ ++ ++ uint8_t smbus_aux; /* 0 == device located on primary SMBUS, ++ * 1 == device located on first auxiliary ++ * SMBUS channel, ++ * <n> == device located on <n> auxiliary ++ * SMBUS channel ++ */ + }; +diff --git a/src/drivers/i2c/w83795/w83795.c b/src/drivers/i2c/w83795/w83795.c +index 0af272f..0f82e1c 100644 +--- a/src/drivers/i2c/w83795/w83795.c ++++ b/src/drivers/i2c/w83795/w83795.c +@@ -141,7 +141,18 @@ static void w83795_init(struct device *dev, w83795_fan_mode_t mode, u8 dts_src) + uint8_t val; + uint16_t limit_value; + ++#if IS_ENABLED(CONFIG_SMBUS_HAS_AUX_CHANNELS) ++ uint8_t smbus_aux_channel_prev = smbus_current_aux_channel(); ++ smbus_switch_to_aux_channel(config->smbus_aux); ++ printk(BIOS_DEBUG, "Set SMBUS controller to channel %d\n", config->smbus_aux); ++#endif ++ + if (smbus_read_byte(dev, 0x00) < 0) { ++#if IS_ENABLED(CONFIG_SMBUS_HAS_AUX_CHANNELS) ++ /* Restore SMBUS channel setting */ ++ smbus_switch_to_aux_channel(smbus_aux_channel_prev); ++ printk(BIOS_DEBUG, "Set SMBUS controller to channel %d\n", smbus_aux_channel_prev); ++#endif + printk(BIOS_ERR, "W83795G/ADG Nuvoton H/W Monitor not found\n"); + return; + } +@@ -332,6 +343,12 @@ static void w83795_init(struct device *dev, w83795_fan_mode_t mode, u8 dts_src) + val = w83795_read(dev, W83795_REG_CONFIG); + val |= W83795_REG_CONFIG_START; + w83795_write(dev, W83795_REG_CONFIG, val); ++ ++#if IS_ENABLED(CONFIG_SMBUS_HAS_AUX_CHANNELS) ++ /* Restore SMBUS channel setting */ ++ smbus_switch_to_aux_channel(smbus_aux_channel_prev); ++ printk(BIOS_DEBUG, "Set SMBUS controller to channel %d\n", smbus_aux_channel_prev); ++#endif + } + + static void w83795_hwm_init(struct device *dev) +-- +1.7.9.5 + diff --git a/resources/libreboot/patch/kgpe-d16/0005-mainboard-Update-mainboards-using-the-w83795-sensor-.patch b/resources/libreboot/patch/kgpe-d16/0005-mainboard-Update-mainboards-using-the-w83795-sensor-.patch @@ -0,0 +1,323 @@ +From 2b9d5ca0b29cbe6e1600879b5cc731c2c4cb106d Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Thu, 22 Oct 2015 02:53:39 -0500 +Subject: [PATCH 005/143] mainboard: Update mainboards using the w83795 sensor + device + +Update mainboards using the w83795 sensor device with sane default +values. Note that in some cases the defaults may vary from the +defaults provided by the old driver, for example the default fan +speeds and control modes have changed as I do not have any information +on the correct sensor to fan mappings for these boards. + +Change-Id: Id2ad6222d7a0f29483b022fa097d7d098c6b4122 +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/supermicro/h8qgi/devicetree.cb | 89 ++++++++++++++++++++++++++ + src/mainboard/supermicro/h8scm/devicetree.cb | 89 ++++++++++++++++++++++++++ + src/mainboard/tyan/s8226/devicetree.cb | 89 ++++++++++++++++++++++++++ + 3 files changed, 267 insertions(+) + +diff --git a/src/mainboard/supermicro/h8qgi/devicetree.cb b/src/mainboard/supermicro/h8qgi/devicetree.cb +index 59740c9..6c3ee90 100644 +--- a/src/mainboard/supermicro/h8qgi/devicetree.cb ++++ b/src/mainboard/supermicro/h8qgi/devicetree.cb +@@ -107,6 +107,95 @@ chip northbridge/amd/agesa/family15/root_complex + end + end #superio/winbond/w83627dhg + chip drivers/i2c/w83795 ++ register "fanin_ctl1" = "0xff" # Enable monitoring of FANIN1 - FANIN8 ++ register "fanin_ctl2" = "0x00" # Connect FANIN11 - FANIN14 to alternate functions ++ register "temp_ctl1" = "0x2a" # Enable monitoring of DTS, VSEN12, and VSEN13 ++ register "temp_ctl2" = "0x01" # Enable monitoring of TD1/TR1 ++ register "temp_dtse" = "0x03" # Enable DTS1 and DTS2 ++ register "volt_ctl1" = "0xff" # Enable monitoring of VSEN1 - VSEN8 ++ register "volt_ctl2" = "0xf7" # Enable monitoring of VSEN9 - VSEN11, 3VDD, 3VSB, and VBAT ++ register "temp1_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp1) ++ register "temp2_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp2) ++ register "temp3_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp3) ++ register "temp4_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp4) ++ register "temp5_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp5) ++ register "temp6_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp6) ++ register "temp1_source_select" = "0x00" # Use TD1/TR1 as data source for Temp1 ++ register "temp2_source_select" = "0x00" # Use TD2/TR2 as data source for Temp2 ++ register "temp3_source_select" = "0x00" # Use TD3/TR3 as data source for Temp3 ++ register "temp4_source_select" = "0x00" # Use TD4/TR4 as data source for Temp4 ++ register "temp5_source_select" = "0x00" # Use TR5 as data source for Temp5 ++ register "temp6_source_select" = "0x00" # Use TR6 as data source for Temp6 ++ register "tr1_critical_temperature" = "85" # Set TD1/TR1 critical temperature to 85°C ++ register "tr1_critical_hysteresis" = "80" # Set TD1/TR1 critical hysteresis temperature to 80°C ++ register "tr1_warning_temperature" = "70" # Set TD1/TR1 warning temperature to 70°C ++ register "tr1_warning_hysteresis" = "65" # Set TD1/TR1 warning hysteresis temperature to 65°C ++ register "dts_critical_temperature" = "85" # Set DTS (CPU) critical temperature to 85°C ++ register "dts_critical_hysteresis" = "80" # Set DTS (CPU) critical hysteresis temperature to 80°C ++ register "dts_warning_temperature" = "70" # Set DTS (CPU) warning temperature to 70°C ++ register "dts_warning_hysteresis" = "65" # Set DTS (CPU) warning hysteresis temperature to 65°C ++ register "temp1_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp2_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp3_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp4_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp5_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp6_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp1_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp2_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp3_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp4_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp5_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp6_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "fan1_nonstop" = "7" # Set Fan 1 minimum speed ++ register "fan2_nonstop" = "7" # Set Fan 2 minimum speed ++ register "fan3_nonstop" = "7" # Set Fan 3 minimum speed ++ register "fan4_nonstop" = "7" # Set Fan 4 minimum speed ++ register "fan5_nonstop" = "7" # Set Fan 5 minimum speed ++ register "fan6_nonstop" = "7" # Set Fan 6 minimum speed ++ register "fan7_nonstop" = "7" # Set Fan 7 minimum speed ++ register "fan8_nonstop" = "7" # Set Fan 8 minimum speed ++ register "default_speed" = "100" # All fans to full speed on power up ++ register "fan1_duty" = "100" # Fan 1 to full speed ++ register "fan2_duty" = "100" # Fan 2 to full speed ++ register "fan3_duty" = "100" # Fan 3 to full speed ++ register "fan4_duty" = "100" # Fan 4 to full speed ++ register "fan5_duty" = "100" # Fan 5 to full speed ++ register "fan6_duty" = "100" # Fan 6 to full speed ++ register "fan7_duty" = "100" # Fan 7 to full speed ++ register "fan8_duty" = "100" # Fan 8 to full speed ++ register "vcore1_high_limit_mv" = "1500" # VCORE1 (Node 0) high limit to 1.5V ++ register "vcore1_low_limit_mv" = "900" # VCORE1 (Node 0) low limit to 0.9V ++ register "vcore2_high_limit_mv" = "1500" # VCORE2 (Node 1) high limit to 1.5V ++ register "vcore2_low_limit_mv" = "900" # VCORE2 (Node 1) low limit to 0.9V ++ register "vsen3_high_limit_mv" = "1600" # VSEN1 (Node 0 RAM voltage) high limit to 1.6V ++ register "vsen3_low_limit_mv" = "1100" # VSEN1 (Node 0 RAM voltage) low limit to 1.1V ++ register "vsen4_high_limit_mv" = "1600" # VSEN2 (Node 1 RAM voltage) high limit to 1.6V ++ register "vsen4_low_limit_mv" = "1100" # VSEN2 (Node 1 RAM voltage) low limit to 1.1V ++ register "vsen5_high_limit_mv" = "1250" # VSEN5 (Node 0 HT link voltage) high limit to 1.25V ++ register "vsen5_low_limit_mv" = "1150" # VSEN5 (Node 0 HT link voltage) low limit to 1.15V ++ register "vsen6_high_limit_mv" = "1250" # VSEN6 (Node 1 HT link voltage) high limit to 1.25V ++ register "vsen6_low_limit_mv" = "1150" # VSEN6 (Node 1 HT link voltage) low limit to 1.15V ++ register "vsen7_high_limit_mv" = "1150" # VSEN7 (Northbridge core voltage) high limit to 1.15V ++ register "vsen7_low_limit_mv" = "1050" # VSEN7 (Northbridge core voltage) low limit to 1.05V ++ register "vsen8_high_limit_mv" = "1900" # VSEN8 (+1.8V) high limit to 1.9V ++ register "vsen8_low_limit_mv" = "1700" # VSEN8 (+1.8V) low limit to 1.7V ++ register "vsen9_high_limit_mv" = "1250" # VSEN9 (+1.2V) high limit to 1.25V ++ register "vsen9_low_limit_mv" = "1150" # VSEN9 (+1.2V) low limit to 1.15V ++ register "vsen10_high_limit_mv" = "1150" # VSEN10 (+1.1V) high limit to 1.15V ++ register "vsen10_low_limit_mv" = "1050" # VSEN10 (+1.1V) low limit to 1.05V ++ register "vsen11_high_limit_mv" = "1625" # VSEN11 (5VSB, scaling factor ~3.2) high limit to 5.2V ++ register "vsen11_low_limit_mv" = "1500" # VSEN11 (5VSB, scaling factor ~3.2) low limit to 4.8V ++ register "vsen12_high_limit_mv" = "1083" # VSEN12 (+12V, scaling factor ~12) high limit to 13V ++ register "vsen12_low_limit_mv" = "917" # VSEN12 (+12V, scaling factor ~12) low limit to 11V ++ register "vsen13_high_limit_mv" = "1625" # VSEN13 (+5V, scaling factor ~3.2) high limit to 5.2V ++ register "vsen13_low_limit_mv" = "1500" # VSEN13 (+5V, scaling factor ~3.2) low limit to 4.8V ++ register "vdd_high_limit_mv" = "3500" # 3VDD high limit to 3.5V ++ register "vdd_low_limit_mv" = "3100" # 3VDD low limit to 3.1V ++ register "vsb_high_limit_mv" = "3500" # 3VSB high limit to 3.5V ++ register "vsb_low_limit_mv" = "3100" # 3VSB low limit to 3.1V ++ register "vbat_high_limit_mv" = "3500" # VBAT (+3V) high limit to 3.5V ++ register "vbat_low_limit_mv" = "2500" # VBAT (+3V) low limit to 2.5V ++ register "smbus_aux" = "0" # Device located on primary SMBUS + device pnp 5e on #hwm + end + end #drivers/i2c/w83795 +diff --git a/src/mainboard/supermicro/h8scm/devicetree.cb b/src/mainboard/supermicro/h8scm/devicetree.cb +index b8fb823..a280e62 100644 +--- a/src/mainboard/supermicro/h8scm/devicetree.cb ++++ b/src/mainboard/supermicro/h8scm/devicetree.cb +@@ -106,6 +106,95 @@ chip northbridge/amd/agesa/family15/root_complex + end + end #superio/winbond/w83627dhg + chip drivers/i2c/w83795 ++ register "fanin_ctl1" = "0xff" # Enable monitoring of FANIN1 - FANIN8 ++ register "fanin_ctl2" = "0x00" # Connect FANIN11 - FANIN14 to alternate functions ++ register "temp_ctl1" = "0x2a" # Enable monitoring of DTS, VSEN12, and VSEN13 ++ register "temp_ctl2" = "0x01" # Enable monitoring of TD1/TR1 ++ register "temp_dtse" = "0x03" # Enable DTS1 and DTS2 ++ register "volt_ctl1" = "0xff" # Enable monitoring of VSEN1 - VSEN8 ++ register "volt_ctl2" = "0xf7" # Enable monitoring of VSEN9 - VSEN11, 3VDD, 3VSB, and VBAT ++ register "temp1_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp1) ++ register "temp2_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp2) ++ register "temp3_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp3) ++ register "temp4_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp4) ++ register "temp5_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp5) ++ register "temp6_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp6) ++ register "temp1_source_select" = "0x00" # Use TD1/TR1 as data source for Temp1 ++ register "temp2_source_select" = "0x00" # Use TD2/TR2 as data source for Temp2 ++ register "temp3_source_select" = "0x00" # Use TD3/TR3 as data source for Temp3 ++ register "temp4_source_select" = "0x00" # Use TD4/TR4 as data source for Temp4 ++ register "temp5_source_select" = "0x00" # Use TR5 as data source for Temp5 ++ register "temp6_source_select" = "0x00" # Use TR6 as data source for Temp6 ++ register "tr1_critical_temperature" = "85" # Set TD1/TR1 critical temperature to 85°C ++ register "tr1_critical_hysteresis" = "80" # Set TD1/TR1 critical hysteresis temperature to 80°C ++ register "tr1_warning_temperature" = "70" # Set TD1/TR1 warning temperature to 70°C ++ register "tr1_warning_hysteresis" = "65" # Set TD1/TR1 warning hysteresis temperature to 65°C ++ register "dts_critical_temperature" = "85" # Set DTS (CPU) critical temperature to 85°C ++ register "dts_critical_hysteresis" = "80" # Set DTS (CPU) critical hysteresis temperature to 80°C ++ register "dts_warning_temperature" = "70" # Set DTS (CPU) warning temperature to 70°C ++ register "dts_warning_hysteresis" = "65" # Set DTS (CPU) warning hysteresis temperature to 65°C ++ register "temp1_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp2_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp3_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp4_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp5_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp6_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp1_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp2_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp3_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp4_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp5_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp6_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "fan1_nonstop" = "7" # Set Fan 1 minimum speed ++ register "fan2_nonstop" = "7" # Set Fan 2 minimum speed ++ register "fan3_nonstop" = "7" # Set Fan 3 minimum speed ++ register "fan4_nonstop" = "7" # Set Fan 4 minimum speed ++ register "fan5_nonstop" = "7" # Set Fan 5 minimum speed ++ register "fan6_nonstop" = "7" # Set Fan 6 minimum speed ++ register "fan7_nonstop" = "7" # Set Fan 7 minimum speed ++ register "fan8_nonstop" = "7" # Set Fan 8 minimum speed ++ register "default_speed" = "100" # All fans to full speed on power up ++ register "fan1_duty" = "100" # Fan 1 to full speed ++ register "fan2_duty" = "100" # Fan 2 to full speed ++ register "fan3_duty" = "100" # Fan 3 to full speed ++ register "fan4_duty" = "100" # Fan 4 to full speed ++ register "fan5_duty" = "100" # Fan 5 to full speed ++ register "fan6_duty" = "100" # Fan 6 to full speed ++ register "fan7_duty" = "100" # Fan 7 to full speed ++ register "fan8_duty" = "100" # Fan 8 to full speed ++ register "vcore1_high_limit_mv" = "1500" # VCORE1 (Node 0) high limit to 1.5V ++ register "vcore1_low_limit_mv" = "900" # VCORE1 (Node 0) low limit to 0.9V ++ register "vcore2_high_limit_mv" = "1500" # VCORE2 (Node 1) high limit to 1.5V ++ register "vcore2_low_limit_mv" = "900" # VCORE2 (Node 1) low limit to 0.9V ++ register "vsen3_high_limit_mv" = "1600" # VSEN1 (Node 0 RAM voltage) high limit to 1.6V ++ register "vsen3_low_limit_mv" = "1100" # VSEN1 (Node 0 RAM voltage) low limit to 1.1V ++ register "vsen4_high_limit_mv" = "1600" # VSEN2 (Node 1 RAM voltage) high limit to 1.6V ++ register "vsen4_low_limit_mv" = "1100" # VSEN2 (Node 1 RAM voltage) low limit to 1.1V ++ register "vsen5_high_limit_mv" = "1250" # VSEN5 (Node 0 HT link voltage) high limit to 1.25V ++ register "vsen5_low_limit_mv" = "1150" # VSEN5 (Node 0 HT link voltage) low limit to 1.15V ++ register "vsen6_high_limit_mv" = "1250" # VSEN6 (Node 1 HT link voltage) high limit to 1.25V ++ register "vsen6_low_limit_mv" = "1150" # VSEN6 (Node 1 HT link voltage) low limit to 1.15V ++ register "vsen7_high_limit_mv" = "1150" # VSEN7 (Northbridge core voltage) high limit to 1.15V ++ register "vsen7_low_limit_mv" = "1050" # VSEN7 (Northbridge core voltage) low limit to 1.05V ++ register "vsen8_high_limit_mv" = "1900" # VSEN8 (+1.8V) high limit to 1.9V ++ register "vsen8_low_limit_mv" = "1700" # VSEN8 (+1.8V) low limit to 1.7V ++ register "vsen9_high_limit_mv" = "1250" # VSEN9 (+1.2V) high limit to 1.25V ++ register "vsen9_low_limit_mv" = "1150" # VSEN9 (+1.2V) low limit to 1.15V ++ register "vsen10_high_limit_mv" = "1150" # VSEN10 (+1.1V) high limit to 1.15V ++ register "vsen10_low_limit_mv" = "1050" # VSEN10 (+1.1V) low limit to 1.05V ++ register "vsen11_high_limit_mv" = "1625" # VSEN11 (5VSB, scaling factor ~3.2) high limit to 5.2V ++ register "vsen11_low_limit_mv" = "1500" # VSEN11 (5VSB, scaling factor ~3.2) low limit to 4.8V ++ register "vsen12_high_limit_mv" = "1083" # VSEN12 (+12V, scaling factor ~12) high limit to 13V ++ register "vsen12_low_limit_mv" = "917" # VSEN12 (+12V, scaling factor ~12) low limit to 11V ++ register "vsen13_high_limit_mv" = "1625" # VSEN13 (+5V, scaling factor ~3.2) high limit to 5.2V ++ register "vsen13_low_limit_mv" = "1500" # VSEN13 (+5V, scaling factor ~3.2) low limit to 4.8V ++ register "vdd_high_limit_mv" = "3500" # 3VDD high limit to 3.5V ++ register "vdd_low_limit_mv" = "3100" # 3VDD low limit to 3.1V ++ register "vsb_high_limit_mv" = "3500" # 3VSB high limit to 3.5V ++ register "vsb_low_limit_mv" = "3100" # 3VSB low limit to 3.1V ++ register "vbat_high_limit_mv" = "3500" # VBAT (+3V) high limit to 3.5V ++ register "vbat_low_limit_mv" = "2500" # VBAT (+3V) low limit to 2.5V ++ register "smbus_aux" = "0" # Device located on primary SMBUS + device pnp 5e on #hwm + end + end #drivers/i2c/w83795 +diff --git a/src/mainboard/tyan/s8226/devicetree.cb b/src/mainboard/tyan/s8226/devicetree.cb +index 64701a5..9f5e584 100644 +--- a/src/mainboard/tyan/s8226/devicetree.cb ++++ b/src/mainboard/tyan/s8226/devicetree.cb +@@ -106,6 +106,95 @@ chip northbridge/amd/agesa/family15/root_complex + end + end #superio/winbond/w83627dhg + chip drivers/i2c/w83795 ++ register "fanin_ctl1" = "0xff" # Enable monitoring of FANIN1 - FANIN8 ++ register "fanin_ctl2" = "0x00" # Connect FANIN11 - FANIN14 to alternate functions ++ register "temp_ctl1" = "0x2a" # Enable monitoring of DTS, VSEN12, and VSEN13 ++ register "temp_ctl2" = "0x01" # Enable monitoring of TD1/TR1 ++ register "temp_dtse" = "0x03" # Enable DTS1 and DTS2 ++ register "volt_ctl1" = "0xff" # Enable monitoring of VSEN1 - VSEN8 ++ register "volt_ctl2" = "0xf7" # Enable monitoring of VSEN9 - VSEN11, 3VDD, 3VSB, and VBAT ++ register "temp1_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp1) ++ register "temp2_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp2) ++ register "temp3_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp3) ++ register "temp4_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp4) ++ register "temp5_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp5) ++ register "temp6_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp6) ++ register "temp1_source_select" = "0x00" # Use TD1/TR1 as data source for Temp1 ++ register "temp2_source_select" = "0x00" # Use TD2/TR2 as data source for Temp2 ++ register "temp3_source_select" = "0x00" # Use TD3/TR3 as data source for Temp3 ++ register "temp4_source_select" = "0x00" # Use TD4/TR4 as data source for Temp4 ++ register "temp5_source_select" = "0x00" # Use TR5 as data source for Temp5 ++ register "temp6_source_select" = "0x00" # Use TR6 as data source for Temp6 ++ register "tr1_critical_temperature" = "85" # Set TD1/TR1 critical temperature to 85°C ++ register "tr1_critical_hysteresis" = "80" # Set TD1/TR1 critical hysteresis temperature to 80°C ++ register "tr1_warning_temperature" = "70" # Set TD1/TR1 warning temperature to 70°C ++ register "tr1_warning_hysteresis" = "65" # Set TD1/TR1 warning hysteresis temperature to 65°C ++ register "dts_critical_temperature" = "85" # Set DTS (CPU) critical temperature to 85°C ++ register "dts_critical_hysteresis" = "80" # Set DTS (CPU) critical hysteresis temperature to 80°C ++ register "dts_warning_temperature" = "70" # Set DTS (CPU) warning temperature to 70°C ++ register "dts_warning_hysteresis" = "65" # Set DTS (CPU) warning hysteresis temperature to 65°C ++ register "temp1_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp2_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp3_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp4_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp5_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp6_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp1_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp2_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp3_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp4_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp5_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp6_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "fan1_nonstop" = "7" # Set Fan 1 minimum speed ++ register "fan2_nonstop" = "7" # Set Fan 2 minimum speed ++ register "fan3_nonstop" = "7" # Set Fan 3 minimum speed ++ register "fan4_nonstop" = "7" # Set Fan 4 minimum speed ++ register "fan5_nonstop" = "7" # Set Fan 5 minimum speed ++ register "fan6_nonstop" = "7" # Set Fan 6 minimum speed ++ register "fan7_nonstop" = "7" # Set Fan 7 minimum speed ++ register "fan8_nonstop" = "7" # Set Fan 8 minimum speed ++ register "default_speed" = "100" # All fans to full speed on power up ++ register "fan1_duty" = "100" # Fan 1 to full speed ++ register "fan2_duty" = "100" # Fan 2 to full speed ++ register "fan3_duty" = "100" # Fan 3 to full speed ++ register "fan4_duty" = "100" # Fan 4 to full speed ++ register "fan5_duty" = "100" # Fan 5 to full speed ++ register "fan6_duty" = "100" # Fan 6 to full speed ++ register "fan7_duty" = "100" # Fan 7 to full speed ++ register "fan8_duty" = "100" # Fan 8 to full speed ++ register "vcore1_high_limit_mv" = "1500" # VCORE1 (Node 0) high limit to 1.5V ++ register "vcore1_low_limit_mv" = "900" # VCORE1 (Node 0) low limit to 0.9V ++ register "vcore2_high_limit_mv" = "1500" # VCORE2 (Node 1) high limit to 1.5V ++ register "vcore2_low_limit_mv" = "900" # VCORE2 (Node 1) low limit to 0.9V ++ register "vsen3_high_limit_mv" = "1600" # VSEN1 (Node 0 RAM voltage) high limit to 1.6V ++ register "vsen3_low_limit_mv" = "1100" # VSEN1 (Node 0 RAM voltage) low limit to 1.1V ++ register "vsen4_high_limit_mv" = "1600" # VSEN2 (Node 1 RAM voltage) high limit to 1.6V ++ register "vsen4_low_limit_mv" = "1100" # VSEN2 (Node 1 RAM voltage) low limit to 1.1V ++ register "vsen5_high_limit_mv" = "1250" # VSEN5 (Node 0 HT link voltage) high limit to 1.25V ++ register "vsen5_low_limit_mv" = "1150" # VSEN5 (Node 0 HT link voltage) low limit to 1.15V ++ register "vsen6_high_limit_mv" = "1250" # VSEN6 (Node 1 HT link voltage) high limit to 1.25V ++ register "vsen6_low_limit_mv" = "1150" # VSEN6 (Node 1 HT link voltage) low limit to 1.15V ++ register "vsen7_high_limit_mv" = "1150" # VSEN7 (Northbridge core voltage) high limit to 1.15V ++ register "vsen7_low_limit_mv" = "1050" # VSEN7 (Northbridge core voltage) low limit to 1.05V ++ register "vsen8_high_limit_mv" = "1900" # VSEN8 (+1.8V) high limit to 1.9V ++ register "vsen8_low_limit_mv" = "1700" # VSEN8 (+1.8V) low limit to 1.7V ++ register "vsen9_high_limit_mv" = "1250" # VSEN9 (+1.2V) high limit to 1.25V ++ register "vsen9_low_limit_mv" = "1150" # VSEN9 (+1.2V) low limit to 1.15V ++ register "vsen10_high_limit_mv" = "1150" # VSEN10 (+1.1V) high limit to 1.15V ++ register "vsen10_low_limit_mv" = "1050" # VSEN10 (+1.1V) low limit to 1.05V ++ register "vsen11_high_limit_mv" = "1625" # VSEN11 (5VSB, scaling factor ~3.2) high limit to 5.2V ++ register "vsen11_low_limit_mv" = "1500" # VSEN11 (5VSB, scaling factor ~3.2) low limit to 4.8V ++ register "vsen12_high_limit_mv" = "1083" # VSEN12 (+12V, scaling factor ~12) high limit to 13V ++ register "vsen12_low_limit_mv" = "917" # VSEN12 (+12V, scaling factor ~12) low limit to 11V ++ register "vsen13_high_limit_mv" = "1625" # VSEN13 (+5V, scaling factor ~3.2) high limit to 5.2V ++ register "vsen13_low_limit_mv" = "1500" # VSEN13 (+5V, scaling factor ~3.2) low limit to 4.8V ++ register "vdd_high_limit_mv" = "3500" # 3VDD high limit to 3.5V ++ register "vdd_low_limit_mv" = "3100" # 3VDD low limit to 3.1V ++ register "vsb_high_limit_mv" = "3500" # 3VSB high limit to 3.5V ++ register "vsb_low_limit_mv" = "3100" # 3VSB low limit to 3.1V ++ register "vbat_high_limit_mv" = "3500" # VBAT (+3V) high limit to 3.5V ++ register "vbat_low_limit_mv" = "2500" # VBAT (+3V) low limit to 2.5V ++ register "smbus_aux" = "0" # Device located on primary SMBUS + device pnp 5e on #hwm + end + end #drivers/i2c/w83795 +-- +1.7.9.5 + diff --git a/resources/libreboot/patch/kgpe-d16/0005-southbridge-amd-sb700-Fix-boot-hang-on-ASUS-KGPE-D16.patch b/resources/libreboot/patch/kgpe-d16/0005-southbridge-amd-sb700-Fix-boot-hang-on-ASUS-KGPE-D16.patch @@ -1,642 +0,0 @@ -From e897086a84f3b7c1af321e2a8a303cc49367b390 Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <tpearson@raptorengineeringinc.com> -Date: Sat, 5 Sep 2015 17:46:15 -0500 -Subject: [PATCH 005/139] southbridge/amd/sb700: Fix boot hang on ASUS KGPE-D16 - -Change-Id: I1d7d6715663a13ab94fd6d71808e35f0f7384d00 -Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> ---- - src/southbridge/amd/sb700/Kconfig | 4 + - src/southbridge/amd/sb700/acpi/ide.asl | 234 ++++++++++++++++++++++++++++++++ - src/southbridge/amd/sb700/acpi/sata.asl | 133 ++++++++++++++++++ - src/southbridge/amd/sb700/bootblock.c | 46 ++++++- - src/southbridge/amd/sb700/early_setup.c | 18 +++ - src/southbridge/amd/sb700/lpc.c | 3 + - src/southbridge/amd/sb700/sm.c | 21 +-- - src/southbridge/amd/sb700/smbus.h | 5 +- - 8 files changed, 447 insertions(+), 17 deletions(-) - create mode 100644 src/southbridge/amd/sb700/acpi/ide.asl - create mode 100644 src/southbridge/amd/sb700/acpi/sata.asl - -diff --git a/src/southbridge/amd/sb700/Kconfig b/src/southbridge/amd/sb700/Kconfig -index a5dfe07..f56f84a 100644 ---- a/src/southbridge/amd/sb700/Kconfig -+++ b/src/southbridge/amd/sb700/Kconfig -@@ -42,6 +42,10 @@ config SOUTHBRIDGE_AMD_SB700_SKIP_ISA_DMA_INIT - bool - default n - -+config SOUTHBRIDGE_AMD_SB700_DISABLE_ISA_DMA -+ bool -+ default n -+ - config EHCI_BAR - hex - default 0xfef00000 -diff --git a/src/southbridge/amd/sb700/acpi/ide.asl b/src/southbridge/amd/sb700/acpi/ide.asl -new file mode 100644 -index 0000000..9b5e3ea ---- /dev/null -+++ b/src/southbridge/amd/sb700/acpi/ide.asl -@@ -0,0 +1,234 @@ -+/* -+ * This file is part of the coreboot project. -+ * -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering -+ * Copyright (C) 2010 Advanced Micro Devices, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/* Some timing tables */ -+Name(UDTT, Package(){ /* Udma timing table */ -+ 120, 90, 60, 45, 30, 20, 15, 0 /* UDMA modes 0 -> 6 */ -+}) -+ -+Name(MDTT, Package(){ /* MWDma timing table */ -+ 480, 150, 120, 0 /* Legacy DMA modes 0 -> 2 */ -+}) -+ -+Name(POTT, Package(){ /* Pio timing table */ -+ 600, 390, 270, 180, 120, 0 /* PIO modes 0 -> 4 */ -+}) -+ -+/* Some timing register value tables */ -+Name(MDRT, Package(){ /* MWDma timing register table */ -+ 0x77, 0x21, 0x20, 0xFF /* Legacy DMA modes 0 -> 2 */ -+}) -+ -+Name(PORT, Package(){ -+ 0x99, 0x47, 0x34, 0x22, 0x20, 0x99 /* PIO modes 0 -> 4 */ -+}) -+ -+OperationRegion(ICRG, PCI_Config, 0x40, 0x20) /* ide control registers */ -+ Field(ICRG, AnyAcc, NoLock, Preserve) -+{ -+ PPTS, 8, /* Primary PIO Slave Timing */ -+ PPTM, 8, /* Primary PIO Master Timing */ -+ OFFSET(0x04), PMTS, 8, /* Primary MWDMA Slave Timing */ -+ PMTM, 8, /* Primary MWDMA Master Timing */ -+ OFFSET(0x08), PPCR, 8, /* Primary PIO Control */ -+ OFFSET(0x0A), PPMM, 4, /* Primary PIO master Mode */ -+ PPSM, 4, /* Primary PIO slave Mode */ -+ OFFSET(0x14), PDCR, 2, /* Primary UDMA Control */ -+ OFFSET(0x16), PDMM, 4, /* Primary UltraDMA Mode */ -+ PDSM, 4, /* Primary UltraDMA Mode */ -+} -+ -+Method(GTTM, 1) /* get total time*/ -+{ -+ Store(And(Arg0, 0x0F), Local0) /* Recovery Width */ -+ Increment(Local0) -+ Store(ShiftRight(Arg0, 4), Local1) /* Command Width */ -+ Increment(Local1) -+ Return(Multiply(30, Add(Local0, Local1))) -+} -+ -+Device(PRID) -+{ -+ Name (_ADR, Zero) -+ Method(_GTM, 0, Serialized) -+ { -+ NAME(OTBF, Buffer(20) { /* out buffer */ -+ 0xFF, 0xFF, 0xFF, 0xFF, -+ 0xFF, 0xFF, 0xFF, 0xFF, -+ 0xFF, 0xFF, 0xFF, 0xFF, -+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 -+ }) -+ -+ CreateDwordField(OTBF, 0, PSD0) /* PIO spd0 */ -+ CreateDwordField(OTBF, 4, DSD0) /* DMA spd0 */ -+ CreateDwordField(OTBF, 8, PSD1) /* PIO spd1 */ -+ CreateDwordField(OTBF, 12, DSD1) /* DMA spd1 */ -+ CreateDwordField(OTBF, 16, BFFG) /* buffer flags */ -+ -+ /* Just return if the channel is disabled */ -+ If(And(PPCR, 0x01)) { /* primary PIO control */ -+ Return(OTBF) -+ } -+ -+ /* Always tell them independent timing available and IOChannelReady used on both drives */ -+ Or(BFFG, 0x1A, BFFG) -+ -+ Store(GTTM(PPTM), PSD0) /* save total time of primary PIO master timming to PIO spd0 */ -+ Store(GTTM(PPTS), PSD1) /* save total time of primary PIO slave Timing to PIO spd1 */ -+ -+ If(And(PDCR, 0x01)) { /* It's under UDMA mode */ -+ Or(BFFG, 0x01, BFFG) -+ Store(DerefOf(Index(UDTT, PDMM)), DSD0) -+ } -+ Else { -+ Store(GTTM(PMTM), DSD0) /* Primary MWDMA Master Timing, DmaSpd0 */ -+ } -+ -+ If(And(PDCR, 0x02)) { /* It's under UDMA mode */ -+ Or(BFFG, 0x04, BFFG) -+ Store(DerefOf(Index(UDTT, PDSM)), DSD1) -+ } -+ Else { -+ Store(GTTM(PMTS), DSD1) /* Primary MWDMA Slave Timing, DmaSpd0 */ -+ } -+ -+ Return(OTBF) /* out buffer */ -+ } /* End Method(_GTM) */ -+ -+ Method(_STM, 3, Serialized) -+ { -+ NAME(INBF, Buffer(20) { /* in buffer */ -+ 0xFF, 0xFF, 0xFF, 0xFF, -+ 0xFF, 0xFF, 0xFF, 0xFF, -+ 0xFF, 0xFF, 0xFF, 0xFF, -+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 -+ }) -+ -+ CreateDwordField(INBF, 0, PSD0) /* PIO spd0 */ -+ CreateDwordField(INBF, 4, DSD0) /* PIO spd0 */ -+ CreateDwordField(INBF, 8, PSD1) /* PIO spd1 */ -+ CreateDwordField(INBF, 12, DSD1) /* DMA spd1 */ -+ CreateDwordField(INBF, 16, BFFG) /*buffer flag */ -+ -+ Store(Match(POTT, MLE, PSD0, MTR, 0, 0), Local0) -+ Divide(Local0, 5, PPMM,) /* Primary PIO master Mode */ -+ Store(Match(POTT, MLE, PSD1, MTR, 0, 0), Local1) -+ Divide(Local1, 5, PPSM,) /* Primary PIO slave Mode */ -+ -+ Store(DerefOf(Index(PORT, Local0)), PPTM) /* Primary PIO Master Timing */ -+ Store(DerefOf(Index(PORT, Local1)), PPTS) /* Primary PIO Slave Timing */ -+ -+ If(And(BFFG, 0x01)) { /* Drive 0 is under UDMA mode */ -+ Store(Match(UDTT, MLE, DSD0, MTR, 0, 0), Local0) -+ Divide(Local0, 7, PDMM,) -+ Or(PDCR, 0x01, PDCR) -+ } -+ Else { -+ If(LNotEqual(DSD0, 0xFFFFFFFF)) { -+ Store(Match(MDTT, MLE, DSD0, MTR, 0, 0), Local0) -+ Store(DerefOf(Index(MDRT, Local0)), PMTM) -+ } -+ } -+ -+ If(And(BFFG, 0x04)) { /* Drive 1 is under UDMA mode */ -+ Store(Match(UDTT, MLE, DSD1, MTR, 0, 0), Local0) -+ Divide(Local0, 7, PDSM,) -+ Or(PDCR, 0x02, PDCR) -+ } -+ Else { -+ If(LNotEqual(DSD1, 0xFFFFFFFF)) { -+ Store(Match(MDTT, MLE, DSD1, MTR, 0, 0), Local0) -+ Store(DerefOf(Index(MDRT, Local0)), PMTS) -+ } -+ } -+ /* Return(INBF) */ -+ } /*End Method(_STM) */ -+ Device(MST) -+ { -+ Name(_ADR, 0) -+ Method(_GTF, 0, Serialized) { -+ Name(CMBF, Buffer(21) { -+ 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, -+ 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5 -+ }) -+ CreateByteField(CMBF, 1, POMD) -+ CreateByteField(CMBF, 8, DMMD) -+ CreateByteField(CMBF, 5, CMDA) -+ CreateByteField(CMBF, 12, CMDB) -+ CreateByteField(CMBF, 19, CMDC) -+ -+ Store(0xA0, CMDA) -+ Store(0xA0, CMDB) -+ Store(0xA0, CMDC) -+ -+ Or(PPMM, 0x08, POMD) -+ -+ If(And(PDCR, 0x01)) { -+ Or(PDMM, 0x40, DMMD) -+ } -+ Else { -+ Store(Match -+ (MDTT, MLE, GTTM(PMTM), -+ MTR, 0, 0), Local0) -+ If(LLess(Local0, 3)) { -+ Or(0x20, Local0, DMMD) -+ } -+ } -+ Return(CMBF) -+ } -+ } /* End Device(MST) */ -+ -+ Device(SLAV) -+ { -+ Name(_ADR, 1) -+ Method(_GTF, 0, Serialized) { -+ Name(CMBF, Buffer(21) { -+ 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, -+ 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5 -+ }) -+ CreateByteField(CMBF, 1, POMD) -+ CreateByteField(CMBF, 8, DMMD) -+ CreateByteField(CMBF, 5, CMDA) -+ CreateByteField(CMBF, 12, CMDB) -+ CreateByteField(CMBF, 19, CMDC) -+ -+ Store(0xB0, CMDA) -+ Store(0xB0, CMDB) -+ Store(0xB0, CMDC) -+ -+ Or(PPSM, 0x08, POMD) -+ -+ If(And(PDCR, 0x02)) { -+ Or(PDSM, 0x40, DMMD) -+ } -+ Else { -+ Store(Match -+ (MDTT, MLE, GTTM(PMTS), -+ MTR, 0, 0), Local0) -+ If(LLess(Local0, 3)) { -+ Or(0x20, Local0, DMMD) -+ } -+ } -+ Return(CMBF) -+ } -+ } /* End Device(SLAV) */ -+} -diff --git a/src/southbridge/amd/sb700/acpi/sata.asl b/src/southbridge/amd/sb700/acpi/sata.asl -new file mode 100644 -index 0000000..46a82b7 ---- /dev/null -+++ b/src/southbridge/amd/sb700/acpi/sata.asl -@@ -0,0 +1,133 @@ -+/* -+ * This file is part of the coreboot project. -+ * -+ * Copyright (C) 2010 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+Name(STTM, Buffer(20) { -+ 0x78, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, -+ 0x78, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, -+ 0x1f, 0x00, 0x00, 0x00 -+}) -+ -+/* Start by clearing the PhyRdyChg bits */ -+Method(_INI) { -+ \_GPE._L1F() -+} -+ -+Device(PMRY) -+{ -+ Name(_ADR, 0) -+ Method(_GTM, 0x0, NotSerialized) { -+ Return(STTM) -+ } -+ Method(_STM, 0x3, NotSerialized) {} -+ -+ Device(PMST) { -+ Name(_ADR, 0) -+ Method(_STA,0) { -+ if (LGreater(P0IS,0)) { -+ return (0x0F) /* sata is visible */ -+ } else { -+ return (0x00) /* sata is missing */ -+ } -+ } -+ }/* end of PMST */ -+ -+ Device(PSLA) -+ { -+ Name(_ADR, 1) -+ Method(_STA,0) { -+ if (LGreater(P1IS,0)) { -+ return (0x0F) /* sata is visible */ -+ } else { -+ return (0x00) /* sata is missing */ -+ } -+ } -+ } /* end of PSLA */ -+} /* end of PMRY */ -+ -+ -+Device(SEDY) -+{ -+ Name(_ADR, 1) /* IDE Scondary Channel */ -+ Method(_GTM, 0x0, NotSerialized) { -+ Return(STTM) -+ } -+ Method(_STM, 0x3, NotSerialized) {} -+ -+ Device(SMST) -+ { -+ Name(_ADR, 0) -+ Method(_STA,0) { -+ if (LGreater(P2IS,0)) { -+ return (0x0F) /* sata is visible */ -+ } else { -+ return (0x00) /* sata is missing */ -+ } -+ } -+ } /* end of SMST */ -+ -+ Device(SSLA) -+ { -+ Name(_ADR, 1) -+ Method(_STA,0) { -+ if (LGreater(P3IS,0)) { -+ return (0x0F) /* sata is visible */ -+ } else { -+ return (0x00) /* sata is missing */ -+ } -+ } -+ } /* end of SSLA */ -+} /* end of SEDY */ -+ -+/* SATA Hot Plug Support */ -+Scope(\_GPE) { -+ Method(_L1F,0x0,NotSerialized) { -+ if (\_SB.P0PR) { -+ if (LGreater(\_SB.P0IS,0)) { -+ sleep(32) -+ } -+ Notify(\_SB.PCI0.SAT0.PMRY.PMST, 0x01) /* NOTIFY_DEVICE_CHECK */ -+ store(one, \_SB.P0PR) -+ } -+ -+ if (\_SB.P1PR) { -+ if (LGreater(\_SB.P1IS,0)) { -+ sleep(32) -+ } -+ Notify(\_SB.PCI0.SAT0.PMRY.PSLA, 0x01) /* NOTIFY_DEVICE_CHECK */ -+ store(one, \_SB.P1PR) -+ } -+ -+ if (\_SB.P2PR) { -+ if (LGreater(\_SB.P2IS,0)) { -+ sleep(32) -+ } -+ Notify(\_SB.PCI0.SAT0.SEDY.SMST, 0x01) /* NOTIFY_DEVICE_CHECK */ -+ store(one, \_SB.P2PR) -+ } -+ -+ if (\_SB.P3PR) { -+ if (LGreater(\_SB.P3IS,0)) { -+ sleep(32) -+ } -+ Notify(\_SB.PCI0.SAT0.SEDY.SSLA, 0x01) /* NOTIFY_DEVICE_CHECK */ -+ store(one, \_SB.P3PR) -+ } -+ } -+} -diff --git a/src/southbridge/amd/sb700/bootblock.c b/src/southbridge/amd/sb700/bootblock.c -index 67e6434..8f722a8 100644 ---- a/src/southbridge/amd/sb700/bootblock.c -+++ b/src/southbridge/amd/sb700/bootblock.c -@@ -1,6 +1,7 @@ - /* - * This file is part of the coreboot project. - * -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * Copyright (C) 2010 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify -@@ -35,10 +36,17 @@ - static void sb700_enable_rom(void) - { - u8 reg8; -+ u32 dword; - pci_devfn_t dev; - - dev = PCI_DEV(0, 0x14, 3); - -+ /* The LPC settings below work for SPI flash as well; -+ * the hardware does not distinguish between LPC and SPI flash ROM -+ * aside from offering additional side-channel access to SPI flash -+ * via a separate register-based interface. -+ */ -+ - /* Decode variable LPC ROM address ranges 1 and 2. */ - reg8 = pci_io_read_config8(dev, 0x48); - reg8 |= (1 << 3) | (1 << 4); -@@ -52,15 +60,41 @@ static void sb700_enable_rom(void) - - /* LPC ROM address range 2: */ - /* -- * Enable LPC ROM range start at: -- * 0xfff8(0000): 512KB -- * 0xfff0(0000): 1MB -- * 0xffe0(0000): 2MB -- * 0xffc0(0000): 4MB -- */ -+ * Enable LPC ROM range start at: -+ * 0xfff8(0000): 512KB -+ * 0xfff0(0000): 1MB -+ * 0xffe0(0000): 2MB -+ * 0xffc0(0000): 4MB -+ * 0xff80(0000): 8MB -+ */ - pci_io_write_config16(dev, 0x6c, 0x10000 - (CONFIG_COREBOOT_ROMSIZE_KB >> 6)); - /* Enable LPC ROM range end at 0xffff(ffff). */ - pci_io_write_config16(dev, 0x6e, 0xffff); -+ -+ /* SB700 LPC Bridge 0x48h. -+ * Turn on all LPC IO Port decode enables -+ */ -+ dword = pci_io_read_config32(dev, 0x44); -+ dword = 0xffffffff; -+ pci_io_write_config32(dev, 0x44, dword); -+ -+ /* SB700 LPC Bridge 0x48h. -+ * BIT0: Port Enable for SuperIO 0x2E-0x2F -+ * BIT1: Port Enable for SuperIO 0x4E-0x4F -+ * BIT4: Port Enable for LPC ROM Address Arrage2 (0x68-0x6C) -+ * BIT6: Port Enable for RTC IO 0x70-0x73 -+ * BIT21: Port Enable for Port 0x80 -+ */ -+ reg8 = pci_io_read_config8(dev, 0x48); -+ reg8 |= (1<<0) | (1<<1) | (1<<4) | (1<<6); -+ pci_io_write_config8(dev, 0x48, reg8); -+ -+ /* SB700 LPC Bridge 0x4ah. -+ * BIT4: Port Enable for Port 0x80 -+ */ -+ reg8 = pci_io_read_config8(dev, 0x4a); -+ reg8 |= (1<<4); -+ pci_io_write_config8(dev, 0x4a, reg8); - } - - static void bootblock_southbridge_init(void) -diff --git a/src/southbridge/amd/sb700/early_setup.c b/src/southbridge/amd/sb700/early_setup.c -index d25599e..de3fa97 100644 ---- a/src/southbridge/amd/sb700/early_setup.c -+++ b/src/southbridge/amd/sb700/early_setup.c -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -395,6 +396,15 @@ static void sb700_devices_por_init(void) - byte |= (1 << 0); - pci_write_config8(dev, 0xd2, byte); - -+ /* set auxiliary smbus iobase and enable controller */ -+ pci_write_config32(dev, 0x58, SMBUS_AUX_IO_BASE | 1); -+ -+ if (inw(SMBUS_IO_BASE) == 0xFF) -+ printk(BIOS_INFO, "sb700_devices_por_init(): Primary SMBUS controller I/O not found\n"); -+ -+ if (inw(SMBUS_AUX_IO_BASE) == 0xFF) -+ printk(BIOS_INFO, "sb700_devices_por_init(): Secondary SMBUS controller I/O not found\n"); -+ - /* KB2RstEnable */ - pci_write_config8(dev, 0x40, 0x44); - -@@ -439,6 +449,14 @@ static void sb700_devices_por_init(void) - /*pci_write_config8(dev, 0x79, 0x4F); */ - pci_write_config8(dev, 0x78, 0xFF); - -+ if (IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_SB700_DISABLE_ISA_DMA)) { -+ printk(BIOS_DEBUG, "sb700_devices_por_init(): Disabling ISA DMA support\n"); -+ /* Disable LPC ISA DMA Capability */ -+ byte = pci_read_config8(dev, 0x78); -+ byte &= ~(1 << 0); -+ pci_write_config8(dev, 0x78, byte); -+ } -+ - /* Set smbus iospace enable, I don't know why write 0x04 into reg5 that is reserved */ - pci_write_config16(dev, 0x4, 0x0407); - -diff --git a/src/southbridge/amd/sb700/lpc.c b/src/southbridge/amd/sb700/lpc.c -index a39ec18..0cc1e8b 100644 ---- a/src/southbridge/amd/sb700/lpc.c -+++ b/src/southbridge/amd/sb700/lpc.c -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -45,6 +46,8 @@ static void lpc_init(device_t dev) - u32 dword; - device_t sm_dev; - -+ printk(BIOS_SPEW, "%s\n", __func__); -+ - /* Enable the LPC Controller */ - sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); - dword = pci_read_config32(sm_dev, 0x64); -diff --git a/src/southbridge/amd/sb700/sm.c b/src/southbridge/amd/sb700/sm.c -index c216e1f..a4b78d0 100644 ---- a/src/southbridge/amd/sb700/sm.c -+++ b/src/southbridge/amd/sb700/sm.c -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -59,11 +60,8 @@ static void sm_init(device_t dev) - printk(BIOS_INFO, "sm_init().\n"); - - rev = get_sb700_revision(dev); -- ioapic_base = (void *)(pci_read_config32(dev, 0x74) & (0xffffffe0)); /* some like mem resource, but does not have enable bit */ -- /* Don't rename APIC ID */ -- /* TODO: We should call setup_ioapic() here. But kernel hangs if cpu is K8. -- * We need to check out why and change back. */ -- clear_ioapic(ioapic_base); -+ ioapic_base = (void *)(pci_read_config32(dev, 0x74) & (0xffffffe0)); /* some like mem resource, but does not have enable bit */ -+ setup_ioapic(ioapic_base, 0); /* Don't rename IOAPIC ID. */ - - /* 2.10 Interrupt Routing/Filtering */ - dword = pci_read_config8(dev, 0x62); -@@ -129,9 +127,10 @@ static void sm_init(device_t dev) - get_option(&on, "power_on_after_fail"); - byte = pm_ioread(0x74); - byte &= ~0x03; -- if (on) { -- byte |= 2; -- } -+ if (on == 1) -+ byte |= 0x1; /* Force power on */ -+ else if (on == 2) -+ byte |= 0x2; /* Use last power state */ - byte |= 1 << 2; - pm_iowrite(0x74, byte); - printk(BIOS_INFO, "set power %s after power fail\n", on ? "on" : "off"); -@@ -295,6 +294,10 @@ static void sm_init(device_t dev) - byte &= ~(1 << 1); - pm_iowrite(0x59, byte); - -+ /* Enable SCI as irq9. */ -+ outb(0x4, 0xC00); -+ outb(0x9, 0xC01); -+ - printk(BIOS_INFO, "sm_init() end\n"); - - /* Enable NbSb virtual channel */ -@@ -385,7 +388,7 @@ static void sb700_sm_read_resources(device_t dev) - struct resource *res; - - /* Get the normal pci resources of this device */ -- /* pci_dev_read_resources(dev); */ -+ pci_dev_read_resources(dev); - - /* apic */ - res = new_resource(dev, 0x74); -diff --git a/src/southbridge/amd/sb700/smbus.h b/src/southbridge/amd/sb700/smbus.h -index d223fe7..34b4098 100644 ---- a/src/southbridge/amd/sb700/smbus.h -+++ b/src/southbridge/amd/sb700/smbus.h -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -24,8 +25,8 @@ - #include "stddef.h" - #include <arch/io.h> - --#define SMBUS_IO_BASE 0x6000 /* Is it a temporary SMBus I/O base address? */ -- /*SIZE 0x40 */ -+#define SMBUS_IO_BASE 0xb00 -+#define SMBUS_AUX_IO_BASE 0xb20 - - #define SMBHSTSTAT 0x0 - #define SMBSLVSTAT 0x1 --- -1.9.1 - diff --git a/resources/libreboot/patch/kgpe-d16/0006-drivers-aspeed-Add-native-text-mode-VGA-support-for-.patch b/resources/libreboot/patch/kgpe-d16/0006-drivers-aspeed-Add-native-text-mode-VGA-support-for-.patch @@ -0,0 +1,3675 @@ +From 913f5fe9e0107c27e0029fe76f62b37f88ccb221 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Sat, 5 Sep 2015 17:38:09 -0500 +Subject: [PATCH 006/143] drivers/aspeed: Add native text mode VGA support for + the AST2050 + +Change-Id: I37763a59d2546cd0c0e57b31fdb7aa77c2c50bee +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/drivers/aspeed/Kconfig | 2 + + src/drivers/aspeed/Makefile.inc | 1 + + src/drivers/aspeed/ast2050/Kconfig | 14 + + src/drivers/aspeed/ast2050/Makefile.inc | 1 + + src/drivers/aspeed/ast2050/ast2050.c | 83 ++ + src/drivers/aspeed/common/Kconfig | 10 + + src/drivers/aspeed/common/Makefile.inc | 1 + + src/drivers/aspeed/common/aspeed_coreboot.h | 210 ++++ + src/drivers/aspeed/common/ast_dp501.c | 443 +++++++ + src/drivers/aspeed/common/ast_dram_tables.h | 165 +++ + src/drivers/aspeed/common/ast_drv.h | 223 ++++ + src/drivers/aspeed/common/ast_main.c | 393 +++++++ + src/drivers/aspeed/common/ast_post.c | 1679 +++++++++++++++++++++++++++ + src/drivers/aspeed/common/ast_tables.h | 305 +++++ + src/include/device/pci_ids.h | 3 + + 15 files changed, 3533 insertions(+) + create mode 100644 src/drivers/aspeed/Kconfig + create mode 100644 src/drivers/aspeed/Makefile.inc + create mode 100644 src/drivers/aspeed/ast2050/Kconfig + create mode 100644 src/drivers/aspeed/ast2050/Makefile.inc + create mode 100644 src/drivers/aspeed/ast2050/ast2050.c + create mode 100644 src/drivers/aspeed/common/Kconfig + create mode 100644 src/drivers/aspeed/common/Makefile.inc + create mode 100644 src/drivers/aspeed/common/aspeed_coreboot.h + create mode 100644 src/drivers/aspeed/common/ast_dp501.c + create mode 100644 src/drivers/aspeed/common/ast_dram_tables.h + create mode 100644 src/drivers/aspeed/common/ast_drv.h + create mode 100644 src/drivers/aspeed/common/ast_main.c + create mode 100644 src/drivers/aspeed/common/ast_post.c + create mode 100644 src/drivers/aspeed/common/ast_tables.h + +diff --git a/src/drivers/aspeed/Kconfig b/src/drivers/aspeed/Kconfig +new file mode 100644 +index 0000000..27469b5 +--- /dev/null ++++ b/src/drivers/aspeed/Kconfig +@@ -0,0 +1,2 @@ ++source src/drivers/aspeed/common/Kconfig ++source src/drivers/aspeed/ast2050/Kconfig +\ No newline at end of file +diff --git a/src/drivers/aspeed/Makefile.inc b/src/drivers/aspeed/Makefile.inc +new file mode 100644 +index 0000000..955a213 +--- /dev/null ++++ b/src/drivers/aspeed/Makefile.inc +@@ -0,0 +1 @@ ++subdirs-y += common ast2050 +\ No newline at end of file +diff --git a/src/drivers/aspeed/ast2050/Kconfig b/src/drivers/aspeed/ast2050/Kconfig +new file mode 100644 +index 0000000..f110d58 +--- /dev/null ++++ b/src/drivers/aspeed/ast2050/Kconfig +@@ -0,0 +1,14 @@ ++config DRIVERS_ASPEED_AST2050 ++ bool ++ ++if DRIVERS_ASPEED_AST2050 ++ ++config DEVICE_SPECIFIC_OPTIONS # dummy ++ def_bool y ++ select DRIVERS_ASPEED_AST_COMMON ++ ++config NATIVE_VGA_INIT_USE_EDID ++ bool ++ default n ++ ++endif # DRIVERS_ASPEED_AST2050 +diff --git a/src/drivers/aspeed/ast2050/Makefile.inc b/src/drivers/aspeed/ast2050/Makefile.inc +new file mode 100644 +index 0000000..3ba9dde +--- /dev/null ++++ b/src/drivers/aspeed/ast2050/Makefile.inc +@@ -0,0 +1 @@ ++ramstage-$(CONFIG_DRIVERS_ASPEED_AST2050) += ast2050.c +\ No newline at end of file +diff --git a/src/drivers/aspeed/ast2050/ast2050.c b/src/drivers/aspeed/ast2050/ast2050.c +new file mode 100644 +index 0000000..809e9de +--- /dev/null ++++ b/src/drivers/aspeed/ast2050/ast2050.c +@@ -0,0 +1,83 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++#include <delay.h> ++#include <stdlib.h> ++#include <string.h> ++#include <arch/io.h> ++#include <edid.h> ++ ++#include <console/console.h> ++#include <device/device.h> ++#include <device/pci.h> ++#include <device/pci_ids.h> ++#include <device/pci_ops.h> ++ ++#include <pc80/vga.h> ++ ++#include "../common/aspeed_coreboot.h" ++#include "../common/ast_drv.h" ++ ++static void aspeed_ast2050_set_resources(device_t dev) ++{ ++ /* Reserve VGA regions */ ++ mmio_resource(dev, 3, 0xa0000 >> 10, 0x1ffff >> 10); ++ ++ /* Run standard resource set routine */ ++ pci_dev_set_resources(dev); ++} ++ ++static void aspeed_ast2050_init(struct device *dev) ++{ ++ u8 ret; ++ struct drm_device drm_dev; ++ ++ drm_dev.pdev = dev; ++ ++ printk(BIOS_INFO, "ASpeed AST2050: initializing video device\n"); ++ ret = ast_driver_load(&drm_dev, 0); ++ ++ /* Unlock extended configuration registers */ ++ outb(0x80, 0x3d4); outb(0xa8, 0x3d5); ++ ++ /* Set CRT Request Threshold */ ++ outb(0xa6, 0x3d4); outb(0x2f, 0x3d5); ++ outb(0xa7, 0x3d4); outb(0x3f, 0x3d5); ++ ++ /* Initialize standard VGA text mode */ ++ vga_io_init(); ++ vga_textmode_init(); ++ printk(BIOS_INFO, "ASpeed VGA text mode initialized\n"); ++ ++ /* if we don't have console, at least print something... */ ++ vga_line_write(0, "ASpeed VGA text mode initialized"); ++} ++ ++static struct device_operations aspeed_ast2050_ops = { ++ .read_resources = pci_dev_read_resources, ++ .set_resources = aspeed_ast2050_set_resources, ++ .enable_resources = pci_dev_enable_resources, ++ .init = aspeed_ast2050_init, ++ .scan_bus = 0, ++}; ++ ++static const struct pci_driver aspeed_ast2050_driver __pci_driver = { ++ .ops = &aspeed_ast2050_ops, ++ .vendor = PCI_VENDOR_ID_ASPEED, ++ .device = PCI_DEVICE_ID_ASPEED_AST2050_VGA, ++}; +diff --git a/src/drivers/aspeed/common/Kconfig b/src/drivers/aspeed/common/Kconfig +new file mode 100644 +index 0000000..0f7056b +--- /dev/null ++++ b/src/drivers/aspeed/common/Kconfig +@@ -0,0 +1,10 @@ ++config DRIVERS_ASPEED_AST_COMMON ++ bool ++ ++if !MAINBOARD_DO_NATIVE_VGA_INIT ++ ++config DEVICE_SPECIFIC_OPTIONS # dummy ++ def_bool y ++ select VGA ++ ++endif # MAINBOARD_DO_NATIVE_VGA_INIT +diff --git a/src/drivers/aspeed/common/Makefile.inc b/src/drivers/aspeed/common/Makefile.inc +new file mode 100644 +index 0000000..75f8b48 +--- /dev/null ++++ b/src/drivers/aspeed/common/Makefile.inc +@@ -0,0 +1 @@ ++ramstage-$(CONFIG_DRIVERS_ASPEED_AST_COMMON) += ast_dp501.c ast_main.c ast_post.c +diff --git a/src/drivers/aspeed/common/aspeed_coreboot.h b/src/drivers/aspeed/common/aspeed_coreboot.h +new file mode 100644 +index 0000000..237c23f +--- /dev/null ++++ b/src/drivers/aspeed/common/aspeed_coreboot.h +@@ -0,0 +1,210 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef _ASPEED_COREBOOT_ ++#define _ASPEED_COREBOOT_ ++ ++#include <delay.h> ++#include <stdlib.h> ++#include <stdint.h> ++#include <string.h> ++#include <arch/io.h> ++ ++#include <console/console.h> ++#include <device/device.h> ++#include <device/pci.h> ++#include <device/pci_ids.h> ++#include <device/pci_ops.h> ++ ++/* coreboot <--> kernel code interface */ ++#define __iomem ++typedef u64 phys_addr_t; ++#define pci_dev device ++ ++#define SZ_16M 0x01000000 ++ ++#define min_t(type, x, y) ({ \ ++ type __min1 = (x); \ ++ type __min2 = (y); \ ++ __min1 < __min2 ? __min1 : __min2; }) ++ ++#define dev_info(dev, format, arg...) printk(BIOS_INFO, "ASpeed VGA: " format, ##arg) ++#define dev_dbg(dev, format, arg...) printk(BIOS_DEBUG, "ASpeed VGA: " format, ##arg) ++#define dev_err(dev, format, arg...) printk(BIOS_ERR, "ASpeed VGA: " format, ##arg) ++ ++#define pr_info(format, arg...) printk(BIOS_INFO, "ASpeed VGA: " format, ##arg) ++#define pr_debug(format, arg...) printk(BIOS_INFO, "ASpeed VGA: " format, ##arg) ++#define pr_err(format, arg...) printk(BIOS_ERR, "ASpeed VGA: " format, ##arg) ++ ++#define DRM_INFO pr_info ++ ++#define GFP_KERNEL 0 ++#define GFP_ATOMIC 1 ++#define kfree(address) free(address) ++ ++#define EIO 5 ++#define ENOMEM 12 ++ ++struct firmware { ++ size_t size; ++ const u8 *data; ++ struct page **pages; ++ ++ /* firmware loader private fields */ ++ void *priv; ++}; ++ ++struct drm_device { ++ struct pci_dev *pdev; ++ void *dev_private; ++}; ++ ++static inline void *kzalloc(size_t size, int flags) { ++ void* ptr = malloc(size); ++ memset(ptr, 0, size); ++ return ptr; ++} ++ ++static inline void writel(u32 val, volatile void *addr) { ++ *(u32*)addr = val; ++} ++ ++static inline u32 readl(const volatile void *addr) { ++ return *(u32*)addr; ++} ++ ++static inline void writew(u16 val, volatile void *addr) { ++ *(u16*)addr = val; ++} ++ ++static inline u16 readw(const volatile void *addr) { ++ return *(u16*)addr; ++} ++ ++static inline void writeb(u8 val, volatile void *addr) { ++ *(u8*)addr = val; ++} ++ ++static inline u8 readb(const volatile void *addr) { ++ return *(u8*)addr; ++} ++ ++static inline int pci_read_config_dword(struct pci_dev *dev, int where, ++ u32 *val) ++{ ++ *val = pci_read_config32(dev, where); ++ return 0; ++} ++ ++static inline int pci_write_config_dword(struct pci_dev *dev, int where, ++ u32 val) ++{ ++ pci_write_config32(dev, where, val); ++ return 0; ++} ++ ++static inline int pci_read_config_byte(struct pci_dev *dev, int where, ++ u8 *val) ++{ ++ *val = pci_read_config8(dev, where); ++ return 0; ++} ++ ++static inline struct resource* resource_at_bar(struct pci_dev *dev, u8 bar) { ++ struct resource *res = dev->resource_list; ++ int i; ++ for (i = 0; i < bar; i++) { ++ res = res->next; ++ if (res == NULL) ++ return NULL; ++ } ++ ++ return res; ++} ++ ++static inline resource_t pci_resource_len(struct pci_dev *dev, u8 bar) { ++ struct resource *res = resource_at_bar(dev, bar); ++ if (res) ++ return res->size; ++ else ++ return 0; ++} ++ ++static inline resource_t pci_resource_start(struct pci_dev *dev, u8 bar) { ++ struct resource *res = resource_at_bar(dev, bar); ++ if (res) ++ return res->base; ++ else ++ return 0; ++} ++ ++static inline unsigned int ioread32(void __iomem *p) { ++ return readl(p); ++} ++ ++static inline void iowrite32(u32 val, void __iomem *p) { ++ writel(val, p); ++} ++ ++static inline unsigned int ioread16(void __iomem *p) { ++ return readw(p); ++} ++ ++static inline void iowrite16(u16 val, void __iomem *p) { ++ writew(val, p); ++} ++ ++static inline unsigned int ioread8(void __iomem *p) { ++ return readb(p); ++} ++ ++static inline void iowrite8(u8 val, void __iomem *p) { ++ writeb(val, p); ++} ++ ++static inline unsigned int ioread_cbio32(void __iomem *p) { ++ return inl((uint16_t)((intptr_t)p)); ++} ++ ++static inline void iowrite_cbio32(u32 val, void __iomem *p) { ++ outl(val, (uint16_t)((intptr_t)p)); ++} ++ ++static inline unsigned int ioread_cbio16(void __iomem *p) { ++ return inw((uint16_t)((intptr_t)p)); ++} ++ ++static inline void iowrite_cbio16(u16 val, void __iomem *p) { ++ outw(val, (uint16_t)((intptr_t)p)); ++} ++ ++static inline unsigned int ioread_cbio8(void __iomem *p) { ++ return inb((uint16_t)((intptr_t)p)); ++} ++ ++static inline void iowrite_cbio8(u8 val, void __iomem *p) { ++ outb(val, (uint16_t)((intptr_t)p)); ++} ++ ++static inline void msleep(unsigned int msecs) { ++ udelay(msecs * 1000); ++} ++ ++#endif +\ No newline at end of file +diff --git a/src/drivers/aspeed/common/ast_dp501.c b/src/drivers/aspeed/common/ast_dp501.c +new file mode 100644 +index 0000000..5be8ec3 +--- /dev/null ++++ b/src/drivers/aspeed/common/ast_dp501.c +@@ -0,0 +1,443 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * File taken from the Linux ast driver (v3.18.5) ++ * Coreboot-specific includes added at top and/or contents modified ++ * as needed to function within the coreboot environment. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc. ++ */ ++ ++#include "ast_drv.h" ++ ++static void send_ack(struct ast_private *ast) ++{ ++ u8 sendack; ++ sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff); ++ sendack |= 0x80; ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack); ++} ++ ++static void send_nack(struct ast_private *ast) ++{ ++ u8 sendack; ++ sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff); ++ sendack &= ~0x80; ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack); ++} ++ ++static bool wait_ack(struct ast_private *ast) ++{ ++ u8 waitack; ++ u32 retry = 0; ++ do { ++ waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); ++ waitack &= 0x80; ++ udelay(100); ++ } while ((!waitack) && (retry++ < 1000)); ++ ++ if (retry < 1000) ++ return true; ++ else ++ return false; ++} ++ ++static bool wait_nack(struct ast_private *ast) ++{ ++ u8 waitack; ++ u32 retry = 0; ++ do { ++ waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); ++ waitack &= 0x80; ++ udelay(100); ++ } while ((waitack) && (retry++ < 1000)); ++ ++ if (retry < 1000) ++ return true; ++ else ++ return false; ++} ++ ++static void set_cmd_trigger(struct ast_private *ast) ++{ ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x40); ++} ++ ++static void clear_cmd_trigger(struct ast_private *ast) ++{ ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x00); ++} ++ ++#if 0 ++static bool wait_fw_ready(struct ast_private *ast) ++{ ++ u8 waitready; ++ u32 retry = 0; ++ do { ++ waitready = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); ++ waitready &= 0x40; ++ udelay(100); ++ } while ((!waitready) && (retry++ < 1000)); ++ ++ if (retry < 1000) ++ return true; ++ else ++ return false; ++} ++#endif ++ ++static bool ast_write_cmd(struct drm_device *dev, u8 data) ++{ ++ struct ast_private *ast = dev->dev_private; ++ int retry = 0; ++ if (wait_nack(ast)) { ++ send_nack(ast); ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data); ++ send_ack(ast); ++ set_cmd_trigger(ast); ++ do { ++ if (wait_ack(ast)) { ++ clear_cmd_trigger(ast); ++ send_nack(ast); ++ return true; ++ } ++ } while (retry++ < 100); ++ } ++ clear_cmd_trigger(ast); ++ send_nack(ast); ++ return false; ++} ++ ++static bool ast_write_data(struct drm_device *dev, u8 data) ++{ ++ struct ast_private *ast = dev->dev_private; ++ ++ if (wait_nack(ast)) { ++ send_nack(ast); ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data); ++ send_ack(ast); ++ if (wait_ack(ast)) { ++ send_nack(ast); ++ return true; ++ } ++ } ++ send_nack(ast); ++ return false; ++} ++ ++#if 0 ++static bool ast_read_data(struct drm_device *dev, u8 *data) ++{ ++ struct ast_private *ast = dev->dev_private; ++ u8 tmp; ++ ++ *data = 0; ++ ++ if (wait_ack(ast) == false) ++ return false; ++ tmp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd3, 0xff); ++ *data = tmp; ++ if (wait_nack(ast) == false) { ++ send_nack(ast); ++ return false; ++ } ++ send_nack(ast); ++ return true; ++} ++ ++static void clear_cmd(struct ast_private *ast) ++{ ++ send_nack(ast); ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, 0x00); ++} ++#endif ++ ++void ast_set_dp501_video_output(struct drm_device *dev, u8 mode) ++{ ++ ast_write_cmd(dev, 0x40); ++ ast_write_data(dev, mode); ++ ++ msleep(10); ++} ++ ++static u32 get_fw_base(struct ast_private *ast) ++{ ++ return ast_mindwm(ast, 0x1e6e2104) & 0x7fffffff; ++} ++ ++bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size) ++{ ++ struct ast_private *ast = dev->dev_private; ++ u32 i, data; ++ u32 boot_address; ++ ++ data = ast_mindwm(ast, 0x1e6e2100) & 0x01; ++ if (data) { ++ boot_address = get_fw_base(ast); ++ for (i = 0; i < size; i += 4) ++ *(u32 *)(addr + i) = ast_mindwm(ast, boot_address + i); ++ return true; ++ } ++ return false; ++} ++ ++bool ast_launch_m68k(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ u32 i, data, len = 0; ++ u32 boot_address; ++ u8 *fw_addr = NULL; ++ u8 jreg; ++ ++ data = ast_mindwm(ast, 0x1e6e2100) & 0x01; ++ if (!data) { ++ ++ if (ast->dp501_fw_addr) { ++ fw_addr = ast->dp501_fw_addr; ++ len = 32*1024; ++ } else if (ast->dp501_fw) { ++ fw_addr = (u8 *)ast->dp501_fw->data; ++ len = ast->dp501_fw->size; ++ } ++ /* Get BootAddress */ ++ ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8); ++ data = ast_mindwm(ast, 0x1e6e0004); ++ switch (data & 0x03) { ++ case 0: ++ boot_address = 0x44000000; ++ break; ++ default: ++ case 1: ++ boot_address = 0x48000000; ++ break; ++ case 2: ++ boot_address = 0x50000000; ++ break; ++ case 3: ++ boot_address = 0x60000000; ++ break; ++ } ++ boot_address -= 0x200000; /* -2MB */ ++ ++ /* copy image to buffer */ ++ for (i = 0; i < len; i += 4) { ++ data = *(u32 *)(fw_addr + i); ++ ast_moutdwm(ast, boot_address + i, data); ++ } ++ ++ /* Init SCU */ ++ ast_moutdwm(ast, 0x1e6e2000, 0x1688a8a8); ++ ++ /* Launch FW */ ++ ast_moutdwm(ast, 0x1e6e2104, 0x80000000 + boot_address); ++ ast_moutdwm(ast, 0x1e6e2100, 1); ++ ++ /* Update Scratch */ ++ data = ast_mindwm(ast, 0x1e6e2040) & 0xfffff1ff; /* D[11:9] = 100b: UEFI handling */ ++ data |= 0x800; ++ ast_moutdwm(ast, 0x1e6e2040, data); ++ ++ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */ ++ jreg |= 0x02; ++ ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x99, jreg); ++ } ++ return true; ++} ++ ++u8 ast_get_dp501_max_clk(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ u32 boot_address, offset, data; ++ u8 linkcap[4], linkrate, linklanes, maxclk = 0xff; ++ ++ boot_address = get_fw_base(ast); ++ ++ /* validate FW version */ ++ offset = 0xf000; ++ data = ast_mindwm(ast, boot_address + offset); ++ if ((data & 0xf0) != 0x10) /* version: 1x */ ++ return maxclk; ++ ++ /* Read Link Capability */ ++ offset = 0xf014; ++ data = ast_mindwm(ast, boot_address + offset); ++ linkcap[0] = (data & 0xff000000) >> 24; ++ linkcap[1] = (data & 0x00ff0000) >> 16; ++ linkcap[2] = (data & 0x0000ff00) >> 8; ++ linkcap[3] = (data & 0x000000ff); ++ if (linkcap[2] == 0) { ++ linkrate = linkcap[0]; ++ linklanes = linkcap[1]; ++ data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes); ++ if (data > 0xff) ++ data = 0xff; ++ maxclk = (u8)data; ++ } ++ return maxclk; ++} ++ ++bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata) ++{ ++ struct ast_private *ast = dev->dev_private; ++ u32 i, boot_address, offset, data; ++ ++ boot_address = get_fw_base(ast); ++ ++ /* validate FW version */ ++ offset = 0xf000; ++ data = ast_mindwm(ast, boot_address + offset); ++ if ((data & 0xf0) != 0x10) ++ return false; ++ ++ /* validate PnP Monitor */ ++ offset = 0xf010; ++ data = ast_mindwm(ast, boot_address + offset); ++ if (!(data & 0x01)) ++ return false; ++ ++ /* Read EDID */ ++ offset = 0xf020; ++ for (i = 0; i < 128; i += 4) { ++ data = ast_mindwm(ast, boot_address + offset + i); ++ *(u32 *)(ediddata + i) = data; ++ } ++ ++ return true; ++} ++ ++static bool ast_init_dvo(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ u8 jreg; ++ u32 data; ++ ast_write32(ast, 0xf004, 0x1e6e0000); ++ ast_write32(ast, 0xf000, 0x1); ++ ast_write32(ast, 0x12000, 0x1688a8a8); ++ ++ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); ++ if (!(jreg & 0x80)) { ++ /* Init SCU DVO Settings */ ++ data = ast_read32(ast, 0x12008); ++ /* delay phase */ ++ data &= 0xfffff8ff; ++ data |= 0x00000500; ++ ast_write32(ast, 0x12008, data); ++ ++ if (ast->chip == AST2300) { ++ data = ast_read32(ast, 0x12084); ++ /* multi-pins for DVO single-edge */ ++ data |= 0xfffe0000; ++ ast_write32(ast, 0x12084, data); ++ ++ data = ast_read32(ast, 0x12088); ++ /* multi-pins for DVO single-edge */ ++ data |= 0x000fffff; ++ ast_write32(ast, 0x12088, data); ++ ++ data = ast_read32(ast, 0x12090); ++ /* multi-pins for DVO single-edge */ ++ data &= 0xffffffcf; ++ data |= 0x00000020; ++ ast_write32(ast, 0x12090, data); ++ } else { /* AST2400 */ ++ data = ast_read32(ast, 0x12088); ++ /* multi-pins for DVO single-edge */ ++ data |= 0x30000000; ++ ast_write32(ast, 0x12088, data); ++ ++ data = ast_read32(ast, 0x1208c); ++ /* multi-pins for DVO single-edge */ ++ data |= 0x000000cf; ++ ast_write32(ast, 0x1208c, data); ++ ++ data = ast_read32(ast, 0x120a4); ++ /* multi-pins for DVO single-edge */ ++ data |= 0xffff0000; ++ ast_write32(ast, 0x120a4, data); ++ ++ data = ast_read32(ast, 0x120a8); ++ /* multi-pins for DVO single-edge */ ++ data |= 0x0000000f; ++ ast_write32(ast, 0x120a8, data); ++ ++ data = ast_read32(ast, 0x12094); ++ /* multi-pins for DVO single-edge */ ++ data |= 0x00000002; ++ ast_write32(ast, 0x12094, data); ++ } ++ } ++ ++ /* Force to DVO */ ++ data = ast_read32(ast, 0x1202c); ++ data &= 0xfffbffff; ++ ast_write32(ast, 0x1202c, data); ++ ++ /* Init VGA DVO Settings */ ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); ++ return true; ++} ++ ++ ++static void ast_init_analog(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ u32 data; ++ ++ /* ++ * Set DAC source to VGA mode in SCU2C via the P2A ++ * bridge. First configure the P2U to target the SCU ++ * in case it isn't at this stage. ++ */ ++ ast_write32(ast, 0xf004, 0x1e6e0000); ++ ast_write32(ast, 0xf000, 0x1); ++ ++ /* Then unlock the SCU with the magic password */ ++ ast_write32(ast, 0x12000, 0x1688a8a8); ++ ast_write32(ast, 0x12000, 0x1688a8a8); ++ ast_write32(ast, 0x12000, 0x1688a8a8); ++ ++ /* Finally, clear bits [17:16] of SCU2c */ ++ data = ast_read32(ast, 0x1202c); ++ data &= 0xfffcffff; ++ ast_write32(ast, 0, data); ++ ++ /* Disable DVO */ ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x00); ++} ++ ++void ast_init_3rdtx(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ u8 jreg; ++ ++ if (ast->chip == AST2300 || ast->chip == AST2400) { ++ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); ++ switch (jreg & 0x0e) { ++ case 0x04: ++ ast_init_dvo(dev); ++ break; ++ case 0x08: ++ ast_launch_m68k(dev); ++ break; ++ case 0x0c: ++ ast_init_dvo(dev); ++ break; ++ default: ++ if (ast->tx_chip_type == AST_TX_SIL164) ++ ast_init_dvo(dev); ++ else ++ ast_init_analog(dev); ++ } ++ } ++} +diff --git a/src/drivers/aspeed/common/ast_dram_tables.h b/src/drivers/aspeed/common/ast_dram_tables.h +new file mode 100644 +index 0000000..4884cba +--- /dev/null ++++ b/src/drivers/aspeed/common/ast_dram_tables.h +@@ -0,0 +1,165 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * File taken from the Linux ast driver (v3.18.5) ++ * Coreboot-specific includes added at top and/or contents modified ++ * as needed to function within the coreboot environment. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc. ++ */ ++ ++#ifndef AST_DRAM_TABLES_H ++#define AST_DRAM_TABLES_H ++ ++/* DRAM timing tables */ ++struct ast_dramstruct { ++ u16 index; ++ u32 data; ++}; ++ ++static const struct ast_dramstruct ast2000_dram_table_data[] = { ++ { 0x0108, 0x00000000 }, ++ { 0x0120, 0x00004a21 }, ++ { 0xFF00, 0x00000043 }, ++ { 0x0000, 0xFFFFFFFF }, ++ { 0x0004, 0x00000089 }, ++ { 0x0008, 0x22331353 }, ++ { 0x000C, 0x0d07000b }, ++ { 0x0010, 0x11113333 }, ++ { 0x0020, 0x00110350 }, ++ { 0x0028, 0x1e0828f0 }, ++ { 0x0024, 0x00000001 }, ++ { 0x001C, 0x00000000 }, ++ { 0x0014, 0x00000003 }, ++ { 0xFF00, 0x00000043 }, ++ { 0x0018, 0x00000131 }, ++ { 0x0014, 0x00000001 }, ++ { 0xFF00, 0x00000043 }, ++ { 0x0018, 0x00000031 }, ++ { 0x0014, 0x00000001 }, ++ { 0xFF00, 0x00000043 }, ++ { 0x0028, 0x1e0828f1 }, ++ { 0x0024, 0x00000003 }, ++ { 0x002C, 0x1f0f28fb }, ++ { 0x0030, 0xFFFFFE01 }, ++ { 0xFFFF, 0xFFFFFFFF } ++}; ++ ++static const struct ast_dramstruct ast1100_dram_table_data[] = { ++ { 0x2000, 0x1688a8a8 }, ++ { 0x2020, 0x000041f0 }, ++ { 0xFF00, 0x00000043 }, ++ { 0x0000, 0xfc600309 }, ++ { 0x006C, 0x00909090 }, ++ { 0x0064, 0x00050000 }, ++ { 0x0004, 0x00000585 }, ++ { 0x0008, 0x0011030f }, ++ { 0x0010, 0x22201724 }, ++ { 0x0018, 0x1e29011a }, ++ { 0x0020, 0x00c82222 }, ++ { 0x0014, 0x01001523 }, ++ { 0x001C, 0x1024010d }, ++ { 0x0024, 0x00cb2522 }, ++ { 0x0038, 0xffffff82 }, ++ { 0x003C, 0x00000000 }, ++ { 0x0040, 0x00000000 }, ++ { 0x0044, 0x00000000 }, ++ { 0x0048, 0x00000000 }, ++ { 0x004C, 0x00000000 }, ++ { 0x0050, 0x00000000 }, ++ { 0x0054, 0x00000000 }, ++ { 0x0058, 0x00000000 }, ++ { 0x005C, 0x00000000 }, ++ { 0x0060, 0x032aa02a }, ++ { 0x0064, 0x002d3000 }, ++ { 0x0068, 0x00000000 }, ++ { 0x0070, 0x00000000 }, ++ { 0x0074, 0x00000000 }, ++ { 0x0078, 0x00000000 }, ++ { 0x007C, 0x00000000 }, ++ { 0x0034, 0x00000001 }, ++ { 0xFF00, 0x00000043 }, ++ { 0x002C, 0x00000732 }, ++ { 0x0030, 0x00000040 }, ++ { 0x0028, 0x00000005 }, ++ { 0x0028, 0x00000007 }, ++ { 0x0028, 0x00000003 }, ++ { 0x0028, 0x00000001 }, ++ { 0x000C, 0x00005a08 }, ++ { 0x002C, 0x00000632 }, ++ { 0x0028, 0x00000001 }, ++ { 0x0030, 0x000003c0 }, ++ { 0x0028, 0x00000003 }, ++ { 0x0030, 0x00000040 }, ++ { 0x0028, 0x00000003 }, ++ { 0x000C, 0x00005a21 }, ++ { 0x0034, 0x00007c03 }, ++ { 0x0120, 0x00004c41 }, ++ { 0xffff, 0xffffffff }, ++}; ++ ++static const struct ast_dramstruct ast2100_dram_table_data[] = { ++ { 0x2000, 0x1688a8a8 }, ++ { 0x2020, 0x00004120 }, ++ { 0xFF00, 0x00000043 }, ++ { 0x0000, 0xfc600309 }, ++ { 0x006C, 0x00909090 }, ++ { 0x0064, 0x00070000 }, ++ { 0x0004, 0x00000489 }, ++ { 0x0008, 0x0011030f }, ++ { 0x0010, 0x32302926 }, ++ { 0x0018, 0x274c0122 }, ++ { 0x0020, 0x00ce2222 }, ++ { 0x0014, 0x01001523 }, ++ { 0x001C, 0x1024010d }, ++ { 0x0024, 0x00cb2522 }, ++ { 0x0038, 0xffffff82 }, ++ { 0x003C, 0x00000000 }, ++ { 0x0040, 0x00000000 }, ++ { 0x0044, 0x00000000 }, ++ { 0x0048, 0x00000000 }, ++ { 0x004C, 0x00000000 }, ++ { 0x0050, 0x00000000 }, ++ { 0x0054, 0x00000000 }, ++ { 0x0058, 0x00000000 }, ++ { 0x005C, 0x00000000 }, ++ { 0x0060, 0x0f2aa02a }, ++ { 0x0064, 0x003f3005 }, ++ { 0x0068, 0x02020202 }, ++ { 0x0070, 0x00000000 }, ++ { 0x0074, 0x00000000 }, ++ { 0x0078, 0x00000000 }, ++ { 0x007C, 0x00000000 }, ++ { 0x0034, 0x00000001 }, ++ { 0xFF00, 0x00000043 }, ++ { 0x002C, 0x00000942 }, ++ { 0x0030, 0x00000040 }, ++ { 0x0028, 0x00000005 }, ++ { 0x0028, 0x00000007 }, ++ { 0x0028, 0x00000003 }, ++ { 0x0028, 0x00000001 }, ++ { 0x000C, 0x00005a08 }, ++ { 0x002C, 0x00000842 }, ++ { 0x0028, 0x00000001 }, ++ { 0x0030, 0x000003c0 }, ++ { 0x0028, 0x00000003 }, ++ { 0x0030, 0x00000040 }, ++ { 0x0028, 0x00000003 }, ++ { 0x000C, 0x00005a21 }, ++ { 0x0034, 0x00007c03 }, ++ { 0x0120, 0x00005061 }, ++ { 0xffff, 0xffffffff }, ++}; ++ ++#endif +diff --git a/src/drivers/aspeed/common/ast_drv.h b/src/drivers/aspeed/common/ast_drv.h +new file mode 100644 +index 0000000..53640f1 +--- /dev/null ++++ b/src/drivers/aspeed/common/ast_drv.h +@@ -0,0 +1,223 @@ ++/* ++ * Copyright 2012 Red Hat Inc. ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ */ ++/* ++ * Authors: Dave Airlie <airlied@redhat.com> ++ */ ++#ifndef __AST_DRV_H__ ++#define __AST_DRV_H__ ++ ++#include "aspeed_coreboot.h" ++ ++#define PCI_CHIP_AST2000 0x2000 ++#define PCI_CHIP_AST2100 0x2010 ++#define PCI_CHIP_AST1180 0x1180 ++ ++ ++enum ast_chip { ++ AST2000, ++ AST2100, ++ AST1100, ++ AST2200, ++ AST2150, ++ AST2300, ++ AST2400, ++ AST1180, ++}; ++ ++enum ast_tx_chip { ++ AST_TX_NONE, ++ AST_TX_SIL164, ++ AST_TX_ITE66121, ++ AST_TX_DP501, ++}; ++ ++#define AST_DRAM_512Mx16 0 ++#define AST_DRAM_1Gx16 1 ++#define AST_DRAM_512Mx32 2 ++#define AST_DRAM_1Gx32 3 ++#define AST_DRAM_2Gx16 6 ++#define AST_DRAM_4Gx16 7 ++ ++struct ast_fbdev; ++ ++struct ast_private { ++ struct drm_device *dev; ++ ++ void __iomem *regs; ++ void __iomem *ioregs; ++ bool io_space_uses_mmap; ++ ++ enum ast_chip chip; ++ bool vga2_clone; ++ uint32_t dram_bus_width; ++ uint32_t dram_type; ++ uint32_t mclk; ++ uint32_t vram_size; ++ ++ struct ast_fbdev *fbdev; ++ ++ int fb_mtrr; ++ ++ struct drm_gem_object *cursor_cache; ++ uint64_t cursor_cache_gpu_addr; ++ ++ int next_cursor; ++ bool support_wide_screen; ++ ++ enum ast_tx_chip tx_chip_type; ++ u8 dp501_maxclk; ++ u8 *dp501_fw_addr; ++ const struct firmware *dp501_fw; /* dp501 fw */ ++}; ++ ++int ast_driver_load(struct drm_device *dev, unsigned long flags); ++int ast_driver_unload(struct drm_device *dev); ++ ++#define AST_IO_AR_PORT_WRITE (0x40) ++#define AST_IO_MISC_PORT_WRITE (0x42) ++#define AST_IO_VGA_ENABLE_PORT (0x43) ++#define AST_IO_SEQ_PORT (0x44) ++#define AST_IO_DAC_INDEX_READ (0x47) ++#define AST_IO_DAC_INDEX_WRITE (0x48) ++#define AST_IO_DAC_DATA (0x49) ++#define AST_IO_GR_PORT (0x4E) ++#define AST_IO_CRTC_PORT (0x54) ++#define AST_IO_INPUT_STATUS1_READ (0x5A) ++#define AST_IO_MISC_PORT_READ (0x4C) ++ ++#define AST_IO_MM_OFFSET (0x380) ++ ++#define __ast_read(x) \ ++static inline u##x ast_read##x(struct ast_private *ast, u32 reg) { \ ++u##x val = 0;\ ++val = ioread##x(ast->regs + reg); \ ++return val;\ ++} ++ ++__ast_read(8); ++__ast_read(16); ++__ast_read(32) ++ ++#define __ast_io_read(x) \ ++static inline u##x ast_io_read##x(struct ast_private *ast, u32 reg) { \ ++u##x val = 0;\ ++if (ast->io_space_uses_mmap) \ ++val = ioread##x(ast->regs + reg); \ ++else \ ++val = ioread_cbio##x(ast->ioregs + reg); \ ++return val;\ ++} ++ ++__ast_io_read(8); ++__ast_io_read(16); ++__ast_io_read(32); ++ ++#define __ast_write(x) \ ++static inline void ast_write##x(struct ast_private *ast, u32 reg, u##x val) {\ ++ iowrite##x(val, ast->regs + reg);\ ++ } ++ ++__ast_write(8); ++__ast_write(16); ++__ast_write(32); ++ ++#define __ast_io_write(x) \ ++static inline void ast_io_write##x(struct ast_private *ast, u32 reg, u##x val) {\ ++ if (ast->io_space_uses_mmap) \ ++ iowrite##x(val, ast->regs + reg);\ ++ else \ ++ iowrite_cbio##x(val, ast->ioregs + reg);\ ++ } ++ ++__ast_io_write(8); ++__ast_io_write(16); ++#undef __ast_io_write ++ ++static inline void ast_set_index_reg(struct ast_private *ast, ++ uint32_t base, uint8_t index, ++ uint8_t val) ++{ ++ ast_io_write16(ast, base, ((u16)val << 8) | index); ++} ++ ++void ast_set_index_reg_mask(struct ast_private *ast, ++ uint32_t base, uint8_t index, ++ uint8_t mask, uint8_t val); ++uint8_t ast_get_index_reg(struct ast_private *ast, ++ uint32_t base, uint8_t index); ++uint8_t ast_get_index_reg_mask(struct ast_private *ast, ++ uint32_t base, uint8_t index, uint8_t mask); ++ ++static inline void ast_open_key(struct ast_private *ast) ++{ ++ ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x80, 0xA8); ++} ++ ++#define AST_VIDMEM_SIZE_8M 0x00800000 ++#define AST_VIDMEM_SIZE_16M 0x01000000 ++#define AST_VIDMEM_SIZE_32M 0x02000000 ++#define AST_VIDMEM_SIZE_64M 0x04000000 ++#define AST_VIDMEM_SIZE_128M 0x08000000 ++ ++#define AST_VIDMEM_DEFAULT_SIZE AST_VIDMEM_SIZE_8M ++ ++#define AST_MAX_HWC_WIDTH 64 ++#define AST_MAX_HWC_HEIGHT 64 ++ ++#define AST_HWC_SIZE (AST_MAX_HWC_WIDTH*AST_MAX_HWC_HEIGHT*2) ++#define AST_HWC_SIGNATURE_SIZE 32 ++ ++#define AST_DEFAULT_HWC_NUM 2 ++/* define for signature structure */ ++#define AST_HWC_SIGNATURE_CHECKSUM 0x00 ++#define AST_HWC_SIGNATURE_SizeX 0x04 ++#define AST_HWC_SIGNATURE_SizeY 0x08 ++#define AST_HWC_SIGNATURE_X 0x0C ++#define AST_HWC_SIGNATURE_Y 0x10 ++#define AST_HWC_SIGNATURE_HOTSPOTX 0x14 ++#define AST_HWC_SIGNATURE_HOTSPOTY 0x18 ++ ++#define AST_MM_ALIGN_SHIFT 4 ++#define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1) ++ ++#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) ++ ++/* ast post */ ++void ast_enable_vga(struct drm_device *dev); ++void ast_enable_mmio(struct drm_device *dev); ++bool ast_is_vga_enabled(struct drm_device *dev); ++void ast_post_gpu(struct drm_device *dev); ++u32 ast_mindwm(struct ast_private *ast, u32 r); ++void ast_moutdwm(struct ast_private *ast, u32 r, u32 v); ++/* ast dp501 */ ++int ast_load_dp501_microcode(struct drm_device *dev); ++void ast_set_dp501_video_output(struct drm_device *dev, u8 mode); ++bool ast_launch_m68k(struct drm_device *dev); ++bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size); ++bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata); ++u8 ast_get_dp501_max_clk(struct drm_device *dev); ++void ast_init_3rdtx(struct drm_device *dev); ++#endif +diff --git a/src/drivers/aspeed/common/ast_main.c b/src/drivers/aspeed/common/ast_main.c +new file mode 100644 +index 0000000..2939442 +--- /dev/null ++++ b/src/drivers/aspeed/common/ast_main.c +@@ -0,0 +1,393 @@ ++/* ++ * Copyright 2012 Red Hat Inc. ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ */ ++/* ++ * Authors: Dave Airlie <airlied@redhat.com> ++ */ ++#include "ast_drv.h" ++ ++#include "ast_dram_tables.h" ++ ++void ast_set_index_reg_mask(struct ast_private *ast, ++ uint32_t base, uint8_t index, ++ uint8_t mask, uint8_t val) ++{ ++ u8 tmp; ++ ast_io_write8(ast, base, index); ++ tmp = (ast_io_read8(ast, base + 1) & mask) | val; ++ ast_set_index_reg(ast, base, index, tmp); ++} ++ ++uint8_t ast_get_index_reg(struct ast_private *ast, ++ uint32_t base, uint8_t index) ++{ ++ uint8_t ret; ++ ast_io_write8(ast, base, index); ++ ret = ast_io_read8(ast, base + 1); ++ return ret; ++} ++ ++uint8_t ast_get_index_reg_mask(struct ast_private *ast, ++ uint32_t base, uint8_t index, uint8_t mask) ++{ ++ uint8_t ret; ++ ast_io_write8(ast, base, index); ++ ret = ast_io_read8(ast, base + 1) & mask; ++ return ret; ++} ++ ++ ++static int ast_detect_chip(struct drm_device *dev, bool *need_post) ++{ ++ struct ast_private *ast = dev->dev_private; ++ uint32_t data, jreg; ++ ast_open_key(ast); ++ ++ if (dev->pdev->device == PCI_CHIP_AST1180) { ++ ast->chip = AST1100; ++ DRM_INFO("AST 1180 detected\n"); ++ } else { ++ pci_read_config_dword(ast->dev->pdev, 0x08, &data); ++ uint8_t revision = data & 0xff; ++ ++ if (revision >= 0x30) { ++ ast->chip = AST2400; ++ DRM_INFO("AST 2400 detected\n"); ++ } else if (revision >= 0x20) { ++ ast->chip = AST2300; ++ DRM_INFO("AST 2300 detected\n"); ++ } else if (revision >= 0x10) { ++ ast_write32(ast, 0xf004, 0x1e6e0000); ++ ast_write32(ast, 0xf000, 0x1); ++ ++ data = ast_read32(ast, 0x1207c); ++ switch (data & 0x0300) { ++ case 0x0200: ++ ast->chip = AST1100; ++ DRM_INFO("AST 1100 detected\n"); ++ break; ++ case 0x0100: ++ ast->chip = AST2200; ++ DRM_INFO("AST 2200 detected\n"); ++ break; ++ case 0x0000: ++ ast->chip = AST2150; ++ DRM_INFO("AST 2150 detected\n"); ++ break; ++ default: ++ ast->chip = AST2100; ++ DRM_INFO("AST 2100 detected\n"); ++ break; ++ } ++ ast->vga2_clone = false; ++ } else { ++ ast->chip = AST2000; ++ DRM_INFO("AST 2000 detected\n"); ++ } ++ } ++ ++ /* ++ * If VGA isn't enabled, we need to enable now or subsequent ++ * access to the scratch registers will fail. We also inform ++ * our caller that it needs to POST the chip ++ * (Assumption: VGA not enabled -> need to POST) ++ */ ++ if (!ast_is_vga_enabled(dev)) { ++ ast_enable_vga(dev); ++ ast_enable_mmio(dev); ++ DRM_INFO("VGA not enabled on entry, requesting chip POST\n"); ++ *need_post = true; ++ } else ++ *need_post = false; ++ ++ /* Check if we support wide screen */ ++ switch (ast->chip) { ++ case AST1180: ++ ast->support_wide_screen = true; ++ break; ++ case AST2000: ++ ast->support_wide_screen = false; ++ break; ++ default: ++ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); ++ if (!(jreg & 0x80)) ++ ast->support_wide_screen = true; ++ else if (jreg & 0x01) ++ ast->support_wide_screen = true; ++ else { ++ ast->support_wide_screen = false; ++ /* Read SCU7c (silicon revision register) */ ++ ast_write32(ast, 0xf004, 0x1e6e0000); ++ ast_write32(ast, 0xf000, 0x1); ++ data = ast_read32(ast, 0x1207c); ++ data &= 0x300; ++ if (ast->chip == AST2300 && data == 0x0) /* ast1300 */ ++ ast->support_wide_screen = true; ++ if (ast->chip == AST2400 && data == 0x100) /* ast1400 */ ++ ast->support_wide_screen = true; ++ } ++ break; ++ } ++ ++ /* Check 3rd Tx option (digital output afaik) */ ++ ast->tx_chip_type = AST_TX_NONE; ++ ++ /* ++ * VGACRA3 Enhanced Color Mode Register, check if DVO is already ++ * enabled, in that case, assume we have a SIL164 TMDS transmitter ++ * ++ * Don't make that assumption if we the chip wasn't enabled and ++ * is at power-on reset, otherwise we'll incorrectly "detect" a ++ * SIL164 when there is none. ++ */ ++ if (!*need_post) { ++ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff); ++ if (jreg & 0x80) ++ ast->tx_chip_type = AST_TX_SIL164; ++ } ++ ++ if ((ast->chip == AST2300) || (ast->chip == AST2400)) { ++ /* ++ * On AST2300 and 2400, look the configuration set by the SoC in ++ * the SOC scratch register #1 bits 11:8 (interestingly marked ++ * as "reserved" in the spec) ++ */ ++ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); ++ switch (jreg) { ++ case 0x04: ++ ast->tx_chip_type = AST_TX_SIL164; ++ break; ++ case 0x08: ++ ast->dp501_fw_addr = kzalloc(32*1024, GFP_KERNEL); ++ if (ast->dp501_fw_addr) { ++ /* backup firmware */ ++ if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) { ++ kfree(ast->dp501_fw_addr); ++ ast->dp501_fw_addr = NULL; ++ } ++ } ++ /* fallthrough */ ++ case 0x0c: ++ ast->tx_chip_type = AST_TX_DP501; ++ } ++ } ++ ++ /* Print stuff for diagnostic purposes */ ++ switch(ast->tx_chip_type) { ++ case AST_TX_SIL164: ++ DRM_INFO("Using Sil164 TMDS transmitter\n"); ++ break; ++ case AST_TX_DP501: ++ DRM_INFO("Using DP501 DisplayPort transmitter\n"); ++ break; ++ default: ++ DRM_INFO("Analog VGA only\n"); ++ } ++ return 0; ++} ++ ++static int ast_get_dram_info(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ uint8_t i; ++ uint32_t data, data2; ++ uint32_t denum, num, div, ref_pll; ++ ++ ast_write32(ast, 0xf004, 0x1e6e0000); ++ ast_write32(ast, 0xf000, 0x1); ++ ++ ++ ast_write32(ast, 0x10000, 0xfc600309); ++ ++ /* Wait up to 2.5 seconds for device initialization / register unlock */ ++ for (i = 0; i < 250; i++) { ++ if (ast_read32(ast, 0x10000) == 0x01) ++ break; ++ mdelay(10); ++ } ++ if (ast_read32(ast, 0x10000) != 0x01) ++ dev_err(dev->pdev, "Unable to unlock SDRAM control registers\n"); ++ ++ data = ast_read32(ast, 0x10004); ++ ++ if (data & 0x400) ++ ast->dram_bus_width = 16; ++ else ++ ast->dram_bus_width = 32; ++ ++ if (ast->chip == AST2300 || ast->chip == AST2400) { ++ switch (data & 0x03) { ++ case 0: ++ ast->dram_type = AST_DRAM_512Mx16; ++ break; ++ default: ++ case 1: ++ ast->dram_type = AST_DRAM_1Gx16; ++ break; ++ case 2: ++ ast->dram_type = AST_DRAM_2Gx16; ++ break; ++ case 3: ++ ast->dram_type = AST_DRAM_4Gx16; ++ break; ++ } ++ } else { ++ switch (data & 0x0c) { ++ case 0: ++ case 4: ++ ast->dram_type = AST_DRAM_512Mx16; ++ break; ++ case 8: ++ if (data & 0x40) ++ ast->dram_type = AST_DRAM_1Gx16; ++ else ++ ast->dram_type = AST_DRAM_512Mx32; ++ break; ++ case 0xc: ++ ast->dram_type = AST_DRAM_1Gx32; ++ break; ++ } ++ } ++ ++ data = ast_read32(ast, 0x10120); ++ data2 = ast_read32(ast, 0x10170); ++ if (data2 & 0x2000) ++ ref_pll = 14318; ++ else ++ ref_pll = 12000; ++ ++ denum = data & 0x1f; ++ num = (data & 0x3fe0) >> 5; ++ data = (data & 0xc000) >> 14; ++ switch (data) { ++ case 3: ++ div = 0x4; ++ break; ++ case 2: ++ case 1: ++ div = 0x2; ++ break; ++ default: ++ div = 0x1; ++ break; ++ } ++ ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000); ++ return 0; ++} ++ ++static u32 ast_get_vram_info(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ u8 jreg; ++ u32 vram_size; ++ ast_open_key(ast); ++ ++ vram_size = AST_VIDMEM_DEFAULT_SIZE; ++ jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff); ++ switch (jreg & 3) { ++ case 0: vram_size = AST_VIDMEM_SIZE_8M; break; ++ case 1: vram_size = AST_VIDMEM_SIZE_16M; break; ++ case 2: vram_size = AST_VIDMEM_SIZE_32M; break; ++ case 3: vram_size = AST_VIDMEM_SIZE_64M; break; ++ } ++ ++ return vram_size; ++} ++ ++int ast_driver_load(struct drm_device *dev, unsigned long flags) ++{ ++ struct ast_private *ast; ++ bool need_post; ++ int ret = 0; ++ struct resource *res; ++ ++ ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL); ++ if (!ast) ++ return -ENOMEM; ++ ++ dev->dev_private = ast; ++ ast->dev = dev; ++ ++ /* PCI BAR 1 */ ++ res = find_resource(dev->pdev, 0x14); ++ if (!res) { ++ dev_err(dev->pdev, "BAR1 resource not found.\n"); ++ ret = -EIO; ++ goto out_free; ++ } ++ ast->regs = res2mmio(res, 0, 0); ++ if (!ast->regs) { ++ ret = -EIO; ++ goto out_free; ++ } ++ ++ /* PCI BAR 2 */ ++ ast->io_space_uses_mmap = false; ++ res = find_resource(dev->pdev, 0x18); ++ if (!res) { ++ dev_err(dev->pdev, "BAR2 resource not found.\n"); ++ ret = -EIO; ++ goto out_free; ++ } ++ ++ /* ++ * If we don't have IO space at all, use MMIO now and ++ * assume the chip has MMIO enabled by default (rev 0x20 ++ * and higher). ++ */ ++ if (!(res->flags & IORESOURCE_IO)) { ++ DRM_INFO("platform has no IO space, trying MMIO\n"); ++ ast->ioregs = ast->regs + AST_IO_MM_OFFSET; ++ ast->io_space_uses_mmap = true; ++ } ++ ++ /* "map" IO regs if the above hasn't done so already */ ++ if (!ast->ioregs) { ++ ast->ioregs = res2mmio(res, 0, 0); ++ if (!ast->ioregs) { ++ ret = -EIO; ++ goto out_free; ++ } ++ /* Adjust the I/O space location to match expectations (the code expects offset 0x0 to be I/O location 0x380) */ ++ ast->ioregs = (void *)AST_IO_MM_OFFSET; ++ } ++ ++ ast_detect_chip(dev, &need_post); ++ ++ if (ast->chip != AST1180) { ++ ast_get_dram_info(dev); ++ ast->vram_size = ast_get_vram_info(dev); ++ DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size); ++ } ++ ++ if (need_post) ++ ast_post_gpu(dev); ++ ++ return 0; ++out_free: ++ kfree(ast); ++ dev->dev_private = NULL; ++ return ret; ++} +diff --git a/src/drivers/aspeed/common/ast_post.c b/src/drivers/aspeed/common/ast_post.c +new file mode 100644 +index 0000000..7d31845 +--- /dev/null ++++ b/src/drivers/aspeed/common/ast_post.c +@@ -0,0 +1,1679 @@ ++/* ++ * Copyright 2012 Red Hat Inc. ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ */ ++/* ++ * Authors: Dave Airlie <airlied@redhat.com> ++ */ ++ ++#include "ast_drv.h" ++ ++#include "ast_dram_tables.h" ++ ++static void ast_init_dram_2300(struct drm_device *dev); ++ ++void ast_enable_vga(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ ++ ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01); ++ ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, 0x01); ++} ++ ++void ast_enable_mmio(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x04); ++} ++ ++ ++bool ast_is_vga_enabled(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ u8 ch; ++ ++ if (ast->chip == AST1180) { ++ /* TODO 1180 */ ++ } else { ++ ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT); ++ if (ch) { ++ ast_open_key(ast); ++ ch = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff); ++ return ch & 0x04; ++ } ++ } ++ return 0; ++} ++ ++static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff }; ++static const u8 extreginfo_ast2300a0[] = { 0x0f, 0x04, 0x1c, 0xff }; ++static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff }; ++ ++static void ++ast_set_def_ext_reg(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ u8 i, index, reg; ++ uint32_t data; ++ const u8 *ext_reg_info; ++ ++ pci_read_config_dword(ast->dev->pdev, 0x08, &data); ++ uint8_t revision = data & 0xff; ++ ++ /* reset scratch */ ++ for (i = 0x81; i <= 0x8f; i++) ++ ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00); ++ ++ if (ast->chip == AST2300 || ast->chip == AST2400) { ++ if (revision >= 0x20) ++ ext_reg_info = extreginfo_ast2300; ++ else ++ ext_reg_info = extreginfo_ast2300a0; ++ } else ++ ext_reg_info = extreginfo; ++ ++ index = 0xa0; ++ while (*ext_reg_info != 0xff) { ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, index, 0x00, *ext_reg_info); ++ index++; ++ ext_reg_info++; ++ } ++ ++ /* disable standard IO/MEM decode if secondary */ ++ /* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */ ++ ++ /* Set Ext. Default */ ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x8c, 0x00, 0x01); ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x00, 0x00); ++ ++ /* Enable RAMDAC for A1 */ ++ reg = 0x04; ++ if (ast->chip == AST2300 || ast->chip == AST2400) ++ reg |= 0x20; ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg); ++} ++ ++u32 ast_mindwm(struct ast_private *ast, u32 r) ++{ ++ uint32_t data; ++ ++ ast_write32(ast, 0xf004, r & 0xffff0000); ++ ast_write32(ast, 0xf000, 0x1); ++ ++ do { ++ data = ast_read32(ast, 0xf004) & 0xffff0000; ++ } while (data != (r & 0xffff0000)); ++ return ast_read32(ast, 0x10000 + (r & 0x0000ffff)); ++} ++ ++void ast_moutdwm(struct ast_private *ast, u32 r, u32 v) ++{ ++ uint32_t data; ++ ast_write32(ast, 0xf004, r & 0xffff0000); ++ ast_write32(ast, 0xf000, 0x1); ++ do { ++ data = ast_read32(ast, 0xf004) & 0xffff0000; ++ } while (data != (r & 0xffff0000)); ++ ast_write32(ast, 0x10000 + (r & 0x0000ffff), v); ++} ++ ++/* ++ * AST2100/2150 DLL CBR Setting ++ */ ++#define CBR_SIZE_AST2150 ((16 << 10) - 1) ++#define CBR_PASSNUM_AST2150 5 ++#define CBR_THRESHOLD_AST2150 10 ++#define CBR_THRESHOLD2_AST2150 10 ++#define TIMEOUT_AST2150 5000000 ++ ++#define CBR_PATNUM_AST2150 8 ++ ++static const u32 pattern_AST2150[14] = { ++ 0xFF00FF00, ++ 0xCC33CC33, ++ 0xAA55AA55, ++ 0xFFFE0001, ++ 0x683501FE, ++ 0x0F1929B0, ++ 0x2D0B4346, ++ 0x60767F02, ++ 0x6FBE36A6, ++ 0x3A253035, ++ 0x3019686D, ++ 0x41C6167E, ++ 0x620152BF, ++ 0x20F050E0 ++}; ++ ++static u32 mmctestburst2_ast2150(struct ast_private *ast, u32 datagen) ++{ ++ u32 data, timeout; ++ ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000001 | (datagen << 3)); ++ timeout = 0; ++ do { ++ data = ast_mindwm(ast, 0x1e6e0070) & 0x40; ++ if (++timeout > TIMEOUT_AST2150) { ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ return 0xffffffff; ++ } ++ } while (!data); ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000003 | (datagen << 3)); ++ timeout = 0; ++ do { ++ data = ast_mindwm(ast, 0x1e6e0070) & 0x40; ++ if (++timeout > TIMEOUT_AST2150) { ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ return 0xffffffff; ++ } ++ } while (!data); ++ data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7; ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ return data; ++} ++ ++#if 0 /* unused in DDX driver - here for completeness */ ++static u32 mmctestsingle2_ast2150(struct ast_private *ast, u32 datagen) ++{ ++ u32 data, timeout; ++ ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3)); ++ timeout = 0; ++ do { ++ data = ast_mindwm(ast, 0x1e6e0070) & 0x40; ++ if (++timeout > TIMEOUT_AST2150) { ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ return 0xffffffff; ++ } ++ } while (!data); ++ data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7; ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ return data; ++} ++#endif ++ ++static int cbrtest_ast2150(struct ast_private *ast) ++{ ++ int i; ++ ++ for (i = 0; i < 8; i++) ++ if (mmctestburst2_ast2150(ast, i)) ++ return 0; ++ return 1; ++} ++ ++static int cbrscan_ast2150(struct ast_private *ast, int busw) ++{ ++ u32 patcnt, loop; ++ ++ for (patcnt = 0; patcnt < CBR_PATNUM_AST2150; patcnt++) { ++ ast_moutdwm(ast, 0x1e6e007c, pattern_AST2150[patcnt]); ++ for (loop = 0; loop < CBR_PASSNUM_AST2150; loop++) { ++ if (cbrtest_ast2150(ast)) ++ break; ++ } ++ if (loop == CBR_PASSNUM_AST2150) ++ return 0; ++ } ++ return 1; ++} ++ ++ ++static void cbrdlli_ast2150(struct ast_private *ast, int busw) ++{ ++ u32 dll_min[4], dll_max[4], dlli, data, passcnt; ++ ++cbr_start: ++ dll_min[0] = dll_min[1] = dll_min[2] = dll_min[3] = 0xff; ++ dll_max[0] = dll_max[1] = dll_max[2] = dll_max[3] = 0x0; ++ passcnt = 0; ++ ++ for (dlli = 0; dlli < 100; dlli++) { ++ ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24)); ++ data = cbrscan_ast2150(ast, busw); ++ if (data != 0) { ++ if (data & 0x1) { ++ if (dll_min[0] > dlli) ++ dll_min[0] = dlli; ++ if (dll_max[0] < dlli) ++ dll_max[0] = dlli; ++ } ++ passcnt++; ++ } else if (passcnt >= CBR_THRESHOLD_AST2150) ++ goto cbr_start; ++ } ++ if (dll_max[0] == 0 || (dll_max[0]-dll_min[0]) < CBR_THRESHOLD_AST2150) ++ goto cbr_start; ++ ++ dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4); ++ ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24)); ++} ++ ++ ++ ++static void ast_init_dram_reg(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ u8 j; ++ u32 data, temp, i; ++ const struct ast_dramstruct *dram_reg_info; ++ ++ j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); ++ ++ if ((j & 0x80) == 0) { /* VGA only */ ++ if (ast->chip == AST2000) { ++ dram_reg_info = ast2000_dram_table_data; ++ ast_write32(ast, 0xf004, 0x1e6e0000); ++ ast_write32(ast, 0xf000, 0x1); ++ ast_write32(ast, 0x10100, 0xa8); ++ ++ do { ++ ; ++ } while (ast_read32(ast, 0x10100) != 0xa8); ++ } else {/* AST2100/1100 */ ++ if (ast->chip == AST2100 || ast->chip == 2200) ++ dram_reg_info = ast2100_dram_table_data; ++ else ++ dram_reg_info = ast1100_dram_table_data; ++ ++ ast_write32(ast, 0xf004, 0x1e6e0000); ++ ast_write32(ast, 0xf000, 0x1); ++ ast_write32(ast, 0x12000, 0x1688A8A8); ++ ++ /* Wait up to 2.5 seconds for device initialization / register unlock */ ++ for (i = 0; i < 250; i++) { ++ if (ast_read32(ast, 0x12000) == 0x01) ++ break; ++ mdelay(10); ++ } ++ if (ast_read32(ast, 0x12000) != 0x01) ++ dev_err(dev->pdev, "Unable to unlock SCU registers\n"); ++ ++ ast_write32(ast, 0x10000, 0xfc600309); ++ ++ /* Wait up to 2.5 seconds for device initialization / register unlock */ ++ for (i = 0; i < 250; i++) { ++ if (ast_read32(ast, 0x10000) == 0x01) ++ break; ++ mdelay(10); ++ } ++ if (ast_read32(ast, 0x10000) != 0x01) ++ dev_err(dev->pdev, "Unable to unlock SDRAM control registers\n"); ++ } ++ ++ while (dram_reg_info->index != 0xffff) { ++ if (dram_reg_info->index == 0xff00) {/* delay fn */ ++ for (i = 0; i < 15; i++) ++ udelay(dram_reg_info->data); ++ } else if (dram_reg_info->index == 0x4 && ast->chip != AST2000) { ++ data = dram_reg_info->data; ++ if (ast->dram_type == AST_DRAM_1Gx16) ++ data = 0x00000d89; ++ else if (ast->dram_type == AST_DRAM_1Gx32) ++ data = 0x00000c8d; ++ ++ temp = ast_read32(ast, 0x12070); ++ temp &= 0xc; ++ temp <<= 2; ++ ast_write32(ast, 0x10000 + dram_reg_info->index, data | temp); ++ } else ++ ast_write32(ast, 0x10000 + dram_reg_info->index, dram_reg_info->data); ++ dram_reg_info++; ++ } ++ ++ /* AST 2100/2150 DRAM calibration */ ++ data = ast_read32(ast, 0x10120); ++ if (data == 0x5061) { /* 266Mhz */ ++ data = ast_read32(ast, 0x10004); ++ if (data & 0x40) ++ cbrdlli_ast2150(ast, 16); /* 16 bits */ ++ else ++ cbrdlli_ast2150(ast, 32); /* 32 bits */ ++ } ++ ++ switch (ast->chip) { ++ case AST2000: ++ temp = ast_read32(ast, 0x10140); ++ ast_write32(ast, 0x10140, temp | 0x40); ++ break; ++ case AST1100: ++ case AST2100: ++ case AST2200: ++ case AST2150: ++ temp = ast_read32(ast, 0x1200c); ++ ast_write32(ast, 0x1200c, temp & 0xfffffffd); ++ temp = ast_read32(ast, 0x12040); ++ ast_write32(ast, 0x12040, temp | 0x40); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ /* wait ready */ ++ /* Wait up to 2.5 seconds for device to become ready */ ++ for (i = 0; i < 250; i++) { ++ j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); ++ mdelay(10); ++ if ((j & 0x40) != 0) ++ break; ++ } ++ if ((j & 0x40) == 0) ++ dev_err(dev->pdev, "Timeout while waiting for device to signal ready\n"); ++} ++ ++void ast_post_gpu(struct drm_device *dev) ++{ ++ u32 reg; ++ struct ast_private *ast = dev->dev_private; ++ ++ pci_read_config_dword(ast->dev->pdev, 0x04, &reg); ++ reg |= 0x3; ++ pci_write_config_dword(ast->dev->pdev, 0x04, reg); ++ ++ ast_enable_vga(dev); ++ ast_enable_mmio(dev); ++ ast_open_key(ast); ++ ast_set_def_ext_reg(dev); ++ ++ if (ast->chip == AST2300 || ast->chip == AST2400) ++ ast_init_dram_2300(dev); ++ else ++ ast_init_dram_reg(dev); ++ ++ ast_init_3rdtx(dev); ++} ++ ++/* AST 2300 DRAM settings */ ++#define AST_DDR3 0 ++#define AST_DDR2 1 ++ ++struct ast2300_dram_param { ++ u32 dram_type; ++ u32 dram_chipid; ++ u32 dram_freq; ++ u32 vram_size; ++ u32 odt; ++ u32 wodt; ++ u32 rodt; ++ u32 dram_config; ++ u32 reg_PERIOD; ++ u32 reg_MADJ; ++ u32 reg_SADJ; ++ u32 reg_MRS; ++ u32 reg_EMRS; ++ u32 reg_AC1; ++ u32 reg_AC2; ++ u32 reg_DQSIC; ++ u32 reg_DRV; ++ u32 reg_IOZ; ++ u32 reg_DQIDLY; ++ u32 reg_FREQ; ++ u32 madj_max; ++ u32 dll2_finetune_step; ++}; ++ ++/* ++ * DQSI DLL CBR Setting ++ */ ++#define CBR_SIZE0 ((1 << 10) - 1) ++#define CBR_SIZE1 ((4 << 10) - 1) ++#define CBR_SIZE2 ((64 << 10) - 1) ++#define CBR_PASSNUM 5 ++#define CBR_PASSNUM2 5 ++#define CBR_THRESHOLD 10 ++#define CBR_THRESHOLD2 10 ++#define TIMEOUT 5000000 ++#define CBR_PATNUM 8 ++ ++static const u32 pattern[8] = { ++ 0xFF00FF00, ++ 0xCC33CC33, ++ 0xAA55AA55, ++ 0x88778877, ++ 0x92CC4D6E, ++ 0x543D3CDE, ++ 0xF1E843C7, ++ 0x7C61D253 ++}; ++ ++static int mmc_test_burst(struct ast_private *ast, u32 datagen) ++{ ++ u32 data, timeout; ++ ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ ast_moutdwm(ast, 0x1e6e0070, 0x000000c1 | (datagen << 3)); ++ timeout = 0; ++ do { ++ data = ast_mindwm(ast, 0x1e6e0070) & 0x3000; ++ if (data & 0x2000) { ++ return 0; ++ } ++ if (++timeout > TIMEOUT) { ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ return 0; ++ } ++ } while (!data); ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ return 1; ++} ++ ++static int mmc_test_burst2(struct ast_private *ast, u32 datagen) ++{ ++ u32 data, timeout; ++ ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000041 | (datagen << 3)); ++ timeout = 0; ++ do { ++ data = ast_mindwm(ast, 0x1e6e0070) & 0x1000; ++ if (++timeout > TIMEOUT) { ++ ast_moutdwm(ast, 0x1e6e0070, 0x0); ++ return -1; ++ } ++ } while (!data); ++ data = ast_mindwm(ast, 0x1e6e0078); ++ data = (data | (data >> 16)) & 0xffff; ++ ast_moutdwm(ast, 0x1e6e0070, 0x0); ++ return data; ++} ++ ++static int mmc_test_single(struct ast_private *ast, u32 datagen) ++{ ++ u32 data, timeout; ++ ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ ast_moutdwm(ast, 0x1e6e0070, 0x000000c5 | (datagen << 3)); ++ timeout = 0; ++ do { ++ data = ast_mindwm(ast, 0x1e6e0070) & 0x3000; ++ if (data & 0x2000) ++ return 0; ++ if (++timeout > TIMEOUT) { ++ ast_moutdwm(ast, 0x1e6e0070, 0x0); ++ return 0; ++ } ++ } while (!data); ++ ast_moutdwm(ast, 0x1e6e0070, 0x0); ++ return 1; ++} ++ ++static int mmc_test_single2(struct ast_private *ast, u32 datagen) ++{ ++ u32 data, timeout; ++ ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000000); ++ ast_moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3)); ++ timeout = 0; ++ do { ++ data = ast_mindwm(ast, 0x1e6e0070) & 0x1000; ++ if (++timeout > TIMEOUT) { ++ ast_moutdwm(ast, 0x1e6e0070, 0x0); ++ return -1; ++ } ++ } while (!data); ++ data = ast_mindwm(ast, 0x1e6e0078); ++ data = (data | (data >> 16)) & 0xffff; ++ ast_moutdwm(ast, 0x1e6e0070, 0x0); ++ return data; ++} ++ ++static int cbr_test(struct ast_private *ast) ++{ ++ u32 data; ++ int i; ++ data = mmc_test_single2(ast, 0); ++ if ((data & 0xff) && (data & 0xff00)) ++ return 0; ++ for (i = 0; i < 8; i++) { ++ data = mmc_test_burst2(ast, i); ++ if ((data & 0xff) && (data & 0xff00)) ++ return 0; ++ } ++ if (!data) ++ return 3; ++ else if (data & 0xff) ++ return 2; ++ return 1; ++} ++ ++static int cbr_scan(struct ast_private *ast) ++{ ++ u32 data, data2, patcnt, loop; ++ ++ data2 = 3; ++ for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) { ++ ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]); ++ for (loop = 0; loop < CBR_PASSNUM2; loop++) { ++ if ((data = cbr_test(ast)) != 0) { ++ data2 &= data; ++ if (!data2) ++ return 0; ++ break; ++ } ++ } ++ if (loop == CBR_PASSNUM2) ++ return 0; ++ } ++ return data2; ++} ++ ++static u32 cbr_test2(struct ast_private *ast) ++{ ++ u32 data; ++ ++ data = mmc_test_burst2(ast, 0); ++ if (data == 0xffff) ++ return 0; ++ data |= mmc_test_single2(ast, 0); ++ if (data == 0xffff) ++ return 0; ++ ++ return ~data & 0xffff; ++} ++ ++static u32 cbr_scan2(struct ast_private *ast) ++{ ++ u32 data, data2, patcnt, loop; ++ ++ data2 = 0xffff; ++ for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) { ++ ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]); ++ for (loop = 0; loop < CBR_PASSNUM2; loop++) { ++ if ((data = cbr_test2(ast)) != 0) { ++ data2 &= data; ++ if (!data2) ++ return 0; ++ break; ++ } ++ } ++ if (loop == CBR_PASSNUM2) ++ return 0; ++ } ++ return data2; ++} ++ ++static u32 cbr_test3(struct ast_private *ast) ++{ ++ if (!mmc_test_burst(ast, 0)) ++ return 0; ++ if (!mmc_test_single(ast, 0)) ++ return 0; ++ return 1; ++} ++ ++static u32 cbr_scan3(struct ast_private *ast) ++{ ++ u32 patcnt, loop; ++ ++ for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) { ++ ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]); ++ for (loop = 0; loop < 2; loop++) { ++ if (cbr_test3(ast)) ++ break; ++ } ++ if (loop == 2) ++ return 0; ++ } ++ return 1; ++} ++ ++static bool finetuneDQI_L(struct ast_private *ast, struct ast2300_dram_param *param) ++{ ++ u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0; ++ bool status = false; ++FINETUNE_START: ++ for (cnt = 0; cnt < 16; cnt++) { ++ dllmin[cnt] = 0xff; ++ dllmax[cnt] = 0x0; ++ } ++ passcnt = 0; ++ for (dlli = 0; dlli < 76; dlli++) { ++ ast_moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24)); ++ ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE1); ++ data = cbr_scan2(ast); ++ if (data != 0) { ++ mask = 0x00010001; ++ for (cnt = 0; cnt < 16; cnt++) { ++ if (data & mask) { ++ if (dllmin[cnt] > dlli) { ++ dllmin[cnt] = dlli; ++ } ++ if (dllmax[cnt] < dlli) { ++ dllmax[cnt] = dlli; ++ } ++ } ++ mask <<= 1; ++ } ++ passcnt++; ++ } else if (passcnt >= CBR_THRESHOLD2) { ++ break; ++ } ++ } ++ gold_sadj[0] = 0x0; ++ passcnt = 0; ++ for (cnt = 0; cnt < 16; cnt++) { ++ if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) { ++ gold_sadj[0] += dllmin[cnt]; ++ passcnt++; ++ } ++ } ++ if (retry++ > 10) ++ goto FINETUNE_DONE; ++ if (passcnt != 16) { ++ goto FINETUNE_START; ++ } ++ status = true; ++FINETUNE_DONE: ++ gold_sadj[0] = gold_sadj[0] >> 4; ++ gold_sadj[1] = gold_sadj[0]; ++ ++ data = 0; ++ for (cnt = 0; cnt < 8; cnt++) { ++ data >>= 3; ++ if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) { ++ dlli = dllmin[cnt]; ++ if (gold_sadj[0] >= dlli) { ++ dlli = ((gold_sadj[0] - dlli) * 19) >> 5; ++ if (dlli > 3) { ++ dlli = 3; ++ } ++ } else { ++ dlli = ((dlli - gold_sadj[0]) * 19) >> 5; ++ if (dlli > 4) { ++ dlli = 4; ++ } ++ dlli = (8 - dlli) & 0x7; ++ } ++ data |= dlli << 21; ++ } ++ } ++ ast_moutdwm(ast, 0x1E6E0080, data); ++ ++ data = 0; ++ for (cnt = 8; cnt < 16; cnt++) { ++ data >>= 3; ++ if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) { ++ dlli = dllmin[cnt]; ++ if (gold_sadj[1] >= dlli) { ++ dlli = ((gold_sadj[1] - dlli) * 19) >> 5; ++ if (dlli > 3) { ++ dlli = 3; ++ } else { ++ dlli = (dlli - 1) & 0x7; ++ } ++ } else { ++ dlli = ((dlli - gold_sadj[1]) * 19) >> 5; ++ dlli += 1; ++ if (dlli > 4) { ++ dlli = 4; ++ } ++ dlli = (8 - dlli) & 0x7; ++ } ++ data |= dlli << 21; ++ } ++ } ++ ast_moutdwm(ast, 0x1E6E0084, data); ++ return status; ++} /* finetuneDQI_L */ ++ ++static void finetuneDQSI(struct ast_private *ast) ++{ ++ u32 dlli, dqsip, dqidly; ++ u32 reg_mcr18, reg_mcr0c, passcnt[2], diff; ++ u32 g_dqidly, g_dqsip, g_margin, g_side; ++ u16 pass[32][2][2]; ++ char tag[2][76]; ++ ++ /* Disable DQI CBR */ ++ reg_mcr0c = ast_mindwm(ast, 0x1E6E000C); ++ reg_mcr18 = ast_mindwm(ast, 0x1E6E0018); ++ reg_mcr18 &= 0x0000ffff; ++ ast_moutdwm(ast, 0x1E6E0018, reg_mcr18); ++ ++ for (dlli = 0; dlli < 76; dlli++) { ++ tag[0][dlli] = 0x0; ++ tag[1][dlli] = 0x0; ++ } ++ for (dqidly = 0; dqidly < 32; dqidly++) { ++ pass[dqidly][0][0] = 0xff; ++ pass[dqidly][0][1] = 0x0; ++ pass[dqidly][1][0] = 0xff; ++ pass[dqidly][1][1] = 0x0; ++ } ++ for (dqidly = 0; dqidly < 32; dqidly++) { ++ passcnt[0] = passcnt[1] = 0; ++ for (dqsip = 0; dqsip < 2; dqsip++) { ++ ast_moutdwm(ast, 0x1E6E000C, 0); ++ ast_moutdwm(ast, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23)); ++ ast_moutdwm(ast, 0x1E6E000C, reg_mcr0c); ++ for (dlli = 0; dlli < 76; dlli++) { ++ ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24)); ++ ast_moutdwm(ast, 0x1E6E0070, 0); ++ ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE0); ++ if (cbr_scan3(ast)) { ++ if (dlli == 0) ++ break; ++ passcnt[dqsip]++; ++ tag[dqsip][dlli] = 'P'; ++ if (dlli < pass[dqidly][dqsip][0]) ++ pass[dqidly][dqsip][0] = (u16) dlli; ++ if (dlli > pass[dqidly][dqsip][1]) ++ pass[dqidly][dqsip][1] = (u16) dlli; ++ } else if (passcnt[dqsip] >= 5) ++ break; ++ else { ++ pass[dqidly][dqsip][0] = 0xff; ++ pass[dqidly][dqsip][1] = 0x0; ++ } ++ } ++ } ++ if (passcnt[0] == 0 && passcnt[1] == 0) ++ dqidly++; ++ } ++ /* Search margin */ ++ g_dqidly = g_dqsip = g_margin = g_side = 0; ++ ++ for (dqidly = 0; dqidly < 32; dqidly++) { ++ for (dqsip = 0; dqsip < 2; dqsip++) { ++ if (pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1]) ++ continue; ++ diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0]; ++ if ((diff+2) < g_margin) ++ continue; ++ passcnt[0] = passcnt[1] = 0; ++ for (dlli = pass[dqidly][dqsip][0]; dlli > 0 && tag[dqsip][dlli] != 0; dlli--, passcnt[0]++); ++ for (dlli = pass[dqidly][dqsip][1]; dlli < 76 && tag[dqsip][dlli] != 0; dlli++, passcnt[1]++); ++ if (passcnt[0] > passcnt[1]) ++ passcnt[0] = passcnt[1]; ++ passcnt[1] = 0; ++ if (passcnt[0] > g_side) ++ passcnt[1] = passcnt[0] - g_side; ++ if (diff > (g_margin+1) && (passcnt[1] > 0 || passcnt[0] > 8)) { ++ g_margin = diff; ++ g_dqidly = dqidly; ++ g_dqsip = dqsip; ++ g_side = passcnt[0]; ++ } else if (passcnt[1] > 1 && g_side < 8) { ++ if (diff > g_margin) ++ g_margin = diff; ++ g_dqidly = dqidly; ++ g_dqsip = dqsip; ++ g_side = passcnt[0]; ++ } ++ } ++ } ++ reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23); ++ ast_moutdwm(ast, 0x1E6E0018, reg_mcr18); ++ ++} ++static bool cbr_dll2(struct ast_private *ast, struct ast2300_dram_param *param) ++{ ++ u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0; ++ bool status = false; ++ ++ finetuneDQSI(ast); ++ if (finetuneDQI_L(ast, param) == false) ++ return status; ++ ++CBR_START2: ++ dllmin[0] = dllmin[1] = 0xff; ++ dllmax[0] = dllmax[1] = 0x0; ++ passcnt = 0; ++ for (dlli = 0; dlli < 76; dlli++) { ++ ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24)); ++ ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE2); ++ data = cbr_scan(ast); ++ if (data != 0) { ++ if (data & 0x1) { ++ if (dllmin[0] > dlli) { ++ dllmin[0] = dlli; ++ } ++ if (dllmax[0] < dlli) { ++ dllmax[0] = dlli; ++ } ++ } ++ if (data & 0x2) { ++ if (dllmin[1] > dlli) { ++ dllmin[1] = dlli; ++ } ++ if (dllmax[1] < dlli) { ++ dllmax[1] = dlli; ++ } ++ } ++ passcnt++; ++ } else if (passcnt >= CBR_THRESHOLD) { ++ break; ++ } ++ } ++ if (retry++ > 10) ++ goto CBR_DONE2; ++ if (dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD) { ++ goto CBR_START2; ++ } ++ if (dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD) { ++ goto CBR_START2; ++ } ++ status = true; ++CBR_DONE2: ++ dlli = (dllmin[1] + dllmax[1]) >> 1; ++ dlli <<= 8; ++ dlli += (dllmin[0] + dllmax[0]) >> 1; ++ ast_moutdwm(ast, 0x1E6E0068, ast_mindwm(ast, 0x1E720058) | (dlli << 16)); ++ return status; ++} /* CBRDLL2 */ ++ ++static void get_ddr3_info(struct ast_private *ast, struct ast2300_dram_param *param) ++{ ++ u32 trap, trap_AC2, trap_MRS; ++ ++ ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8); ++ ++ /* Ger trap info */ ++ trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3; ++ trap_AC2 = 0x00020000 + (trap << 16); ++ trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19); ++ trap_MRS = 0x00000010 + (trap << 4); ++ trap_MRS |= ((trap & 0x2) << 18); ++ ++ param->reg_MADJ = 0x00034C4C; ++ param->reg_SADJ = 0x00001800; ++ param->reg_DRV = 0x000000F0; ++ param->reg_PERIOD = param->dram_freq; ++ param->rodt = 0; ++ ++ switch (param->dram_freq) { ++ case 336: ++ ast_moutdwm(ast, 0x1E6E2020, 0x0190); ++ param->wodt = 0; ++ param->reg_AC1 = 0x22202725; ++ param->reg_AC2 = 0xAA007613 | trap_AC2; ++ param->reg_DQSIC = 0x000000BA; ++ param->reg_MRS = 0x04001400 | trap_MRS; ++ param->reg_EMRS = 0x00000000; ++ param->reg_IOZ = 0x00000023; ++ param->reg_DQIDLY = 0x00000074; ++ param->reg_FREQ = 0x00004DC0; ++ param->madj_max = 96; ++ param->dll2_finetune_step = 3; ++ switch (param->dram_chipid) { ++ default: ++ case AST_DRAM_512Mx16: ++ case AST_DRAM_1Gx16: ++ param->reg_AC2 = 0xAA007613 | trap_AC2; ++ break; ++ case AST_DRAM_2Gx16: ++ param->reg_AC2 = 0xAA00761C | trap_AC2; ++ break; ++ case AST_DRAM_4Gx16: ++ param->reg_AC2 = 0xAA007636 | trap_AC2; ++ break; ++ } ++ break; ++ default: ++ case 396: ++ ast_moutdwm(ast, 0x1E6E2020, 0x03F1); ++ param->wodt = 1; ++ param->reg_AC1 = 0x33302825; ++ param->reg_AC2 = 0xCC009617 | trap_AC2; ++ param->reg_DQSIC = 0x000000E2; ++ param->reg_MRS = 0x04001600 | trap_MRS; ++ param->reg_EMRS = 0x00000000; ++ param->reg_IOZ = 0x00000034; ++ param->reg_DRV = 0x000000FA; ++ param->reg_DQIDLY = 0x00000089; ++ param->reg_FREQ = 0x00005040; ++ param->madj_max = 96; ++ param->dll2_finetune_step = 4; ++ ++ switch (param->dram_chipid) { ++ default: ++ case AST_DRAM_512Mx16: ++ case AST_DRAM_1Gx16: ++ param->reg_AC2 = 0xCC009617 | trap_AC2; ++ break; ++ case AST_DRAM_2Gx16: ++ param->reg_AC2 = 0xCC009622 | trap_AC2; ++ break; ++ case AST_DRAM_4Gx16: ++ param->reg_AC2 = 0xCC00963F | trap_AC2; ++ break; ++ } ++ break; ++ ++ case 408: ++ ast_moutdwm(ast, 0x1E6E2020, 0x01F0); ++ param->wodt = 1; ++ param->reg_AC1 = 0x33302825; ++ param->reg_AC2 = 0xCC009617 | trap_AC2; ++ param->reg_DQSIC = 0x000000E2; ++ param->reg_MRS = 0x04001600 | trap_MRS; ++ param->reg_EMRS = 0x00000000; ++ param->reg_IOZ = 0x00000023; ++ param->reg_DRV = 0x000000FA; ++ param->reg_DQIDLY = 0x00000089; ++ param->reg_FREQ = 0x000050C0; ++ param->madj_max = 96; ++ param->dll2_finetune_step = 4; ++ ++ switch (param->dram_chipid) { ++ default: ++ case AST_DRAM_512Mx16: ++ case AST_DRAM_1Gx16: ++ param->reg_AC2 = 0xCC009617 | trap_AC2; ++ break; ++ case AST_DRAM_2Gx16: ++ param->reg_AC2 = 0xCC009622 | trap_AC2; ++ break; ++ case AST_DRAM_4Gx16: ++ param->reg_AC2 = 0xCC00963F | trap_AC2; ++ break; ++ } ++ ++ break; ++ case 456: ++ ast_moutdwm(ast, 0x1E6E2020, 0x0230); ++ param->wodt = 0; ++ param->reg_AC1 = 0x33302926; ++ param->reg_AC2 = 0xCD44961A; ++ param->reg_DQSIC = 0x000000FC; ++ param->reg_MRS = 0x00081830; ++ param->reg_EMRS = 0x00000000; ++ param->reg_IOZ = 0x00000045; ++ param->reg_DQIDLY = 0x00000097; ++ param->reg_FREQ = 0x000052C0; ++ param->madj_max = 88; ++ param->dll2_finetune_step = 4; ++ break; ++ case 504: ++ ast_moutdwm(ast, 0x1E6E2020, 0x0270); ++ param->wodt = 1; ++ param->reg_AC1 = 0x33302926; ++ param->reg_AC2 = 0xDE44A61D; ++ param->reg_DQSIC = 0x00000117; ++ param->reg_MRS = 0x00081A30; ++ param->reg_EMRS = 0x00000000; ++ param->reg_IOZ = 0x070000BB; ++ param->reg_DQIDLY = 0x000000A0; ++ param->reg_FREQ = 0x000054C0; ++ param->madj_max = 79; ++ param->dll2_finetune_step = 4; ++ break; ++ case 528: ++ ast_moutdwm(ast, 0x1E6E2020, 0x0290); ++ param->wodt = 1; ++ param->rodt = 1; ++ param->reg_AC1 = 0x33302926; ++ param->reg_AC2 = 0xEF44B61E; ++ param->reg_DQSIC = 0x00000125; ++ param->reg_MRS = 0x00081A30; ++ param->reg_EMRS = 0x00000040; ++ param->reg_DRV = 0x000000F5; ++ param->reg_IOZ = 0x00000023; ++ param->reg_DQIDLY = 0x00000088; ++ param->reg_FREQ = 0x000055C0; ++ param->madj_max = 76; ++ param->dll2_finetune_step = 3; ++ break; ++ case 576: ++ ast_moutdwm(ast, 0x1E6E2020, 0x0140); ++ param->reg_MADJ = 0x00136868; ++ param->reg_SADJ = 0x00004534; ++ param->wodt = 1; ++ param->rodt = 1; ++ param->reg_AC1 = 0x33302A37; ++ param->reg_AC2 = 0xEF56B61E; ++ param->reg_DQSIC = 0x0000013F; ++ param->reg_MRS = 0x00101A50; ++ param->reg_EMRS = 0x00000040; ++ param->reg_DRV = 0x000000FA; ++ param->reg_IOZ = 0x00000023; ++ param->reg_DQIDLY = 0x00000078; ++ param->reg_FREQ = 0x000057C0; ++ param->madj_max = 136; ++ param->dll2_finetune_step = 3; ++ break; ++ case 600: ++ ast_moutdwm(ast, 0x1E6E2020, 0x02E1); ++ param->reg_MADJ = 0x00136868; ++ param->reg_SADJ = 0x00004534; ++ param->wodt = 1; ++ param->rodt = 1; ++ param->reg_AC1 = 0x32302A37; ++ param->reg_AC2 = 0xDF56B61F; ++ param->reg_DQSIC = 0x0000014D; ++ param->reg_MRS = 0x00101A50; ++ param->reg_EMRS = 0x00000004; ++ param->reg_DRV = 0x000000F5; ++ param->reg_IOZ = 0x00000023; ++ param->reg_DQIDLY = 0x00000078; ++ param->reg_FREQ = 0x000058C0; ++ param->madj_max = 132; ++ param->dll2_finetune_step = 3; ++ break; ++ case 624: ++ ast_moutdwm(ast, 0x1E6E2020, 0x0160); ++ param->reg_MADJ = 0x00136868; ++ param->reg_SADJ = 0x00004534; ++ param->wodt = 1; ++ param->rodt = 1; ++ param->reg_AC1 = 0x32302A37; ++ param->reg_AC2 = 0xEF56B621; ++ param->reg_DQSIC = 0x0000015A; ++ param->reg_MRS = 0x02101A50; ++ param->reg_EMRS = 0x00000004; ++ param->reg_DRV = 0x000000F5; ++ param->reg_IOZ = 0x00000034; ++ param->reg_DQIDLY = 0x00000078; ++ param->reg_FREQ = 0x000059C0; ++ param->madj_max = 128; ++ param->dll2_finetune_step = 3; ++ break; ++ } /* switch freq */ ++ ++ switch (param->dram_chipid) { ++ case AST_DRAM_512Mx16: ++ param->dram_config = 0x130; ++ break; ++ default: ++ case AST_DRAM_1Gx16: ++ param->dram_config = 0x131; ++ break; ++ case AST_DRAM_2Gx16: ++ param->dram_config = 0x132; ++ break; ++ case AST_DRAM_4Gx16: ++ param->dram_config = 0x133; ++ break; ++ } /* switch size */ ++ ++ switch (param->vram_size) { ++ default: ++ case AST_VIDMEM_SIZE_8M: ++ param->dram_config |= 0x00; ++ break; ++ case AST_VIDMEM_SIZE_16M: ++ param->dram_config |= 0x04; ++ break; ++ case AST_VIDMEM_SIZE_32M: ++ param->dram_config |= 0x08; ++ break; ++ case AST_VIDMEM_SIZE_64M: ++ param->dram_config |= 0x0c; ++ break; ++ } ++ ++} ++ ++static void ddr3_init(struct ast_private *ast, struct ast2300_dram_param *param) ++{ ++ u32 data, data2, retry = 0; ++ ++ddr3_init_start: ++ ast_moutdwm(ast, 0x1E6E0000, 0xFC600309); ++ ast_moutdwm(ast, 0x1E6E0018, 0x00000100); ++ ast_moutdwm(ast, 0x1E6E0024, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0034, 0x00000000); ++ udelay(10); ++ ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ); ++ ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ); ++ udelay(10); ++ ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000); ++ udelay(10); ++ ++ ast_moutdwm(ast, 0x1E6E0004, param->dram_config); ++ ast_moutdwm(ast, 0x1E6E0008, 0x90040f); ++ ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1); ++ ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2); ++ ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC); ++ ast_moutdwm(ast, 0x1E6E0080, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0084, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY); ++ ast_moutdwm(ast, 0x1E6E0018, 0x4000A170); ++ ast_moutdwm(ast, 0x1E6E0018, 0x00002370); ++ ast_moutdwm(ast, 0x1E6E0038, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0040, 0xFF444444); ++ ast_moutdwm(ast, 0x1E6E0044, 0x22222222); ++ ast_moutdwm(ast, 0x1E6E0048, 0x22222222); ++ ast_moutdwm(ast, 0x1E6E004C, 0x00000002); ++ ast_moutdwm(ast, 0x1E6E0050, 0x80000000); ++ ast_moutdwm(ast, 0x1E6E0050, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0054, 0); ++ ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV); ++ ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ); ++ ast_moutdwm(ast, 0x1E6E0070, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0074, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0078, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E007C, 0x00000000); ++ /* Wait MCLK2X lock to MCLK */ ++ do { ++ data = ast_mindwm(ast, 0x1E6E001C); ++ } while (!(data & 0x08000000)); ++ data = ast_mindwm(ast, 0x1E6E001C); ++ data = (data >> 8) & 0xff; ++ while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) { ++ data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4; ++ if ((data2 & 0xff) > param->madj_max) { ++ break; ++ } ++ ast_moutdwm(ast, 0x1E6E0064, data2); ++ if (data2 & 0x00100000) { ++ data2 = ((data2 & 0xff) >> 3) + 3; ++ } else { ++ data2 = ((data2 & 0xff) >> 2) + 5; ++ } ++ data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff; ++ data2 += data & 0xff; ++ data = data | (data2 << 8); ++ ast_moutdwm(ast, 0x1E6E0068, data); ++ udelay(10); ++ ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000); ++ udelay(10); ++ data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff; ++ ast_moutdwm(ast, 0x1E6E0018, data); ++ data = data | 0x200; ++ ast_moutdwm(ast, 0x1E6E0018, data); ++ do { ++ data = ast_mindwm(ast, 0x1E6E001C); ++ } while (!(data & 0x08000000)); ++ ++ data = ast_mindwm(ast, 0x1E6E001C); ++ data = (data >> 8) & 0xff; ++ } ++ ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0068) & 0xffff); ++ data = ast_mindwm(ast, 0x1E6E0018) | 0xC00; ++ ast_moutdwm(ast, 0x1E6E0018, data); ++ ++ ast_moutdwm(ast, 0x1E6E0034, 0x00000001); ++ ast_moutdwm(ast, 0x1E6E000C, 0x00000040); ++ udelay(50); ++ /* Mode Register Setting */ ++ ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100); ++ ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS); ++ ast_moutdwm(ast, 0x1E6E0028, 0x00000005); ++ ast_moutdwm(ast, 0x1E6E0028, 0x00000007); ++ ast_moutdwm(ast, 0x1E6E0028, 0x00000003); ++ ast_moutdwm(ast, 0x1E6E0028, 0x00000001); ++ ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS); ++ ast_moutdwm(ast, 0x1E6E000C, 0x00005C08); ++ ast_moutdwm(ast, 0x1E6E0028, 0x00000001); ++ ++ ast_moutdwm(ast, 0x1E6E000C, 0x00005C01); ++ data = 0; ++ if (param->wodt) { ++ data = 0x300; ++ } ++ if (param->rodt) { ++ data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3); ++ } ++ ast_moutdwm(ast, 0x1E6E0034, data | 0x3); ++ ++ /* Calibrate the DQSI delay */ ++ if ((cbr_dll2(ast, param) == false) && (retry++ < 10)) ++ goto ddr3_init_start; ++ ++ ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ); ++ /* ECC Memory Initialization */ ++#ifdef ECC ++ ast_moutdwm(ast, 0x1E6E007C, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0070, 0x221); ++ do { ++ data = ast_mindwm(ast, 0x1E6E0070); ++ } while (!(data & 0x00001000)); ++ ast_moutdwm(ast, 0x1E6E0070, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0050, 0x80000000); ++ ast_moutdwm(ast, 0x1E6E0050, 0x00000000); ++#endif ++ ++ ++} ++ ++static void get_ddr2_info(struct ast_private *ast, struct ast2300_dram_param *param) ++{ ++ u32 trap, trap_AC2, trap_MRS; ++ ++ ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8); ++ ++ /* Ger trap info */ ++ trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3; ++ trap_AC2 = (trap << 20) | (trap << 16); ++ trap_AC2 += 0x00110000; ++ trap_MRS = 0x00000040 | (trap << 4); ++ ++ ++ param->reg_MADJ = 0x00034C4C; ++ param->reg_SADJ = 0x00001800; ++ param->reg_DRV = 0x000000F0; ++ param->reg_PERIOD = param->dram_freq; ++ param->rodt = 0; ++ ++ switch (param->dram_freq) { ++ case 264: ++ ast_moutdwm(ast, 0x1E6E2020, 0x0130); ++ param->wodt = 0; ++ param->reg_AC1 = 0x11101513; ++ param->reg_AC2 = 0x78117011; ++ param->reg_DQSIC = 0x00000092; ++ param->reg_MRS = 0x00000842; ++ param->reg_EMRS = 0x00000000; ++ param->reg_DRV = 0x000000F0; ++ param->reg_IOZ = 0x00000034; ++ param->reg_DQIDLY = 0x0000005A; ++ param->reg_FREQ = 0x00004AC0; ++ param->madj_max = 138; ++ param->dll2_finetune_step = 3; ++ break; ++ case 336: ++ ast_moutdwm(ast, 0x1E6E2020, 0x0190); ++ param->wodt = 1; ++ param->reg_AC1 = 0x22202613; ++ param->reg_AC2 = 0xAA009016 | trap_AC2; ++ param->reg_DQSIC = 0x000000BA; ++ param->reg_MRS = 0x00000A02 | trap_MRS; ++ param->reg_EMRS = 0x00000040; ++ param->reg_DRV = 0x000000FA; ++ param->reg_IOZ = 0x00000034; ++ param->reg_DQIDLY = 0x00000074; ++ param->reg_FREQ = 0x00004DC0; ++ param->madj_max = 96; ++ param->dll2_finetune_step = 3; ++ switch (param->dram_chipid) { ++ default: ++ case AST_DRAM_512Mx16: ++ param->reg_AC2 = 0xAA009012 | trap_AC2; ++ break; ++ case AST_DRAM_1Gx16: ++ param->reg_AC2 = 0xAA009016 | trap_AC2; ++ break; ++ case AST_DRAM_2Gx16: ++ param->reg_AC2 = 0xAA009023 | trap_AC2; ++ break; ++ case AST_DRAM_4Gx16: ++ param->reg_AC2 = 0xAA00903B | trap_AC2; ++ break; ++ } ++ break; ++ default: ++ case 396: ++ ast_moutdwm(ast, 0x1E6E2020, 0x03F1); ++ param->wodt = 1; ++ param->rodt = 0; ++ param->reg_AC1 = 0x33302714; ++ param->reg_AC2 = 0xCC00B01B | trap_AC2; ++ param->reg_DQSIC = 0x000000E2; ++ param->reg_MRS = 0x00000C02 | trap_MRS; ++ param->reg_EMRS = 0x00000040; ++ param->reg_DRV = 0x000000FA; ++ param->reg_IOZ = 0x00000034; ++ param->reg_DQIDLY = 0x00000089; ++ param->reg_FREQ = 0x00005040; ++ param->madj_max = 96; ++ param->dll2_finetune_step = 4; ++ ++ switch (param->dram_chipid) { ++ case AST_DRAM_512Mx16: ++ param->reg_AC2 = 0xCC00B016 | trap_AC2; ++ break; ++ default: ++ case AST_DRAM_1Gx16: ++ param->reg_AC2 = 0xCC00B01B | trap_AC2; ++ break; ++ case AST_DRAM_2Gx16: ++ param->reg_AC2 = 0xCC00B02B | trap_AC2; ++ break; ++ case AST_DRAM_4Gx16: ++ param->reg_AC2 = 0xCC00B03F | trap_AC2; ++ break; ++ } ++ ++ break; ++ ++ case 408: ++ ast_moutdwm(ast, 0x1E6E2020, 0x01F0); ++ param->wodt = 1; ++ param->rodt = 0; ++ param->reg_AC1 = 0x33302714; ++ param->reg_AC2 = 0xCC00B01B | trap_AC2; ++ param->reg_DQSIC = 0x000000E2; ++ param->reg_MRS = 0x00000C02 | trap_MRS; ++ param->reg_EMRS = 0x00000040; ++ param->reg_DRV = 0x000000FA; ++ param->reg_IOZ = 0x00000034; ++ param->reg_DQIDLY = 0x00000089; ++ param->reg_FREQ = 0x000050C0; ++ param->madj_max = 96; ++ param->dll2_finetune_step = 4; ++ ++ switch (param->dram_chipid) { ++ case AST_DRAM_512Mx16: ++ param->reg_AC2 = 0xCC00B016 | trap_AC2; ++ break; ++ default: ++ case AST_DRAM_1Gx16: ++ param->reg_AC2 = 0xCC00B01B | trap_AC2; ++ break; ++ case AST_DRAM_2Gx16: ++ param->reg_AC2 = 0xCC00B02B | trap_AC2; ++ break; ++ case AST_DRAM_4Gx16: ++ param->reg_AC2 = 0xCC00B03F | trap_AC2; ++ break; ++ } ++ ++ break; ++ case 456: ++ ast_moutdwm(ast, 0x1E6E2020, 0x0230); ++ param->wodt = 0; ++ param->reg_AC1 = 0x33302815; ++ param->reg_AC2 = 0xCD44B01E; ++ param->reg_DQSIC = 0x000000FC; ++ param->reg_MRS = 0x00000E72; ++ param->reg_EMRS = 0x00000000; ++ param->reg_DRV = 0x00000000; ++ param->reg_IOZ = 0x00000034; ++ param->reg_DQIDLY = 0x00000097; ++ param->reg_FREQ = 0x000052C0; ++ param->madj_max = 88; ++ param->dll2_finetune_step = 3; ++ break; ++ case 504: ++ ast_moutdwm(ast, 0x1E6E2020, 0x0261); ++ param->wodt = 1; ++ param->rodt = 1; ++ param->reg_AC1 = 0x33302815; ++ param->reg_AC2 = 0xDE44C022; ++ param->reg_DQSIC = 0x00000117; ++ param->reg_MRS = 0x00000E72; ++ param->reg_EMRS = 0x00000040; ++ param->reg_DRV = 0x0000000A; ++ param->reg_IOZ = 0x00000045; ++ param->reg_DQIDLY = 0x000000A0; ++ param->reg_FREQ = 0x000054C0; ++ param->madj_max = 79; ++ param->dll2_finetune_step = 3; ++ break; ++ case 528: ++ ast_moutdwm(ast, 0x1E6E2020, 0x0120); ++ param->wodt = 1; ++ param->rodt = 1; ++ param->reg_AC1 = 0x33302815; ++ param->reg_AC2 = 0xEF44D024; ++ param->reg_DQSIC = 0x00000125; ++ param->reg_MRS = 0x00000E72; ++ param->reg_EMRS = 0x00000004; ++ param->reg_DRV = 0x000000F9; ++ param->reg_IOZ = 0x00000045; ++ param->reg_DQIDLY = 0x000000A7; ++ param->reg_FREQ = 0x000055C0; ++ param->madj_max = 76; ++ param->dll2_finetune_step = 3; ++ break; ++ case 552: ++ ast_moutdwm(ast, 0x1E6E2020, 0x02A1); ++ param->wodt = 1; ++ param->rodt = 1; ++ param->reg_AC1 = 0x43402915; ++ param->reg_AC2 = 0xFF44E025; ++ param->reg_DQSIC = 0x00000132; ++ param->reg_MRS = 0x00000E72; ++ param->reg_EMRS = 0x00000040; ++ param->reg_DRV = 0x0000000A; ++ param->reg_IOZ = 0x00000045; ++ param->reg_DQIDLY = 0x000000AD; ++ param->reg_FREQ = 0x000056C0; ++ param->madj_max = 76; ++ param->dll2_finetune_step = 3; ++ break; ++ case 576: ++ ast_moutdwm(ast, 0x1E6E2020, 0x0140); ++ param->wodt = 1; ++ param->rodt = 1; ++ param->reg_AC1 = 0x43402915; ++ param->reg_AC2 = 0xFF44E027; ++ param->reg_DQSIC = 0x0000013F; ++ param->reg_MRS = 0x00000E72; ++ param->reg_EMRS = 0x00000004; ++ param->reg_DRV = 0x000000F5; ++ param->reg_IOZ = 0x00000045; ++ param->reg_DQIDLY = 0x000000B3; ++ param->reg_FREQ = 0x000057C0; ++ param->madj_max = 76; ++ param->dll2_finetune_step = 3; ++ break; ++ } ++ ++ switch (param->dram_chipid) { ++ case AST_DRAM_512Mx16: ++ param->dram_config = 0x100; ++ break; ++ default: ++ case AST_DRAM_1Gx16: ++ param->dram_config = 0x121; ++ break; ++ case AST_DRAM_2Gx16: ++ param->dram_config = 0x122; ++ break; ++ case AST_DRAM_4Gx16: ++ param->dram_config = 0x123; ++ break; ++ } /* switch size */ ++ ++ switch (param->vram_size) { ++ default: ++ case AST_VIDMEM_SIZE_8M: ++ param->dram_config |= 0x00; ++ break; ++ case AST_VIDMEM_SIZE_16M: ++ param->dram_config |= 0x04; ++ break; ++ case AST_VIDMEM_SIZE_32M: ++ param->dram_config |= 0x08; ++ break; ++ case AST_VIDMEM_SIZE_64M: ++ param->dram_config |= 0x0c; ++ break; ++ } ++} ++ ++static void ddr2_init(struct ast_private *ast, struct ast2300_dram_param *param) ++{ ++ u32 data, data2, retry = 0; ++ ++ddr2_init_start: ++ ast_moutdwm(ast, 0x1E6E0000, 0xFC600309); ++ ast_moutdwm(ast, 0x1E6E0018, 0x00000100); ++ ast_moutdwm(ast, 0x1E6E0024, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ); ++ ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ); ++ udelay(10); ++ ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000); ++ udelay(10); ++ ++ ast_moutdwm(ast, 0x1E6E0004, param->dram_config); ++ ast_moutdwm(ast, 0x1E6E0008, 0x90040f); ++ ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1); ++ ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2); ++ ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC); ++ ast_moutdwm(ast, 0x1E6E0080, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0084, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY); ++ ast_moutdwm(ast, 0x1E6E0018, 0x4000A130); ++ ast_moutdwm(ast, 0x1E6E0018, 0x00002330); ++ ast_moutdwm(ast, 0x1E6E0038, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0040, 0xFF808000); ++ ast_moutdwm(ast, 0x1E6E0044, 0x88848466); ++ ast_moutdwm(ast, 0x1E6E0048, 0x44440008); ++ ast_moutdwm(ast, 0x1E6E004C, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0050, 0x80000000); ++ ast_moutdwm(ast, 0x1E6E0050, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0054, 0); ++ ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV); ++ ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ); ++ ast_moutdwm(ast, 0x1E6E0070, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0074, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0078, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E007C, 0x00000000); ++ ++ /* Wait MCLK2X lock to MCLK */ ++ do { ++ data = ast_mindwm(ast, 0x1E6E001C); ++ } while (!(data & 0x08000000)); ++ data = ast_mindwm(ast, 0x1E6E001C); ++ data = (data >> 8) & 0xff; ++ while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) { ++ data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4; ++ if ((data2 & 0xff) > param->madj_max) { ++ break; ++ } ++ ast_moutdwm(ast, 0x1E6E0064, data2); ++ if (data2 & 0x00100000) { ++ data2 = ((data2 & 0xff) >> 3) + 3; ++ } else { ++ data2 = ((data2 & 0xff) >> 2) + 5; ++ } ++ data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff; ++ data2 += data & 0xff; ++ data = data | (data2 << 8); ++ ast_moutdwm(ast, 0x1E6E0068, data); ++ udelay(10); ++ ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000); ++ udelay(10); ++ data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff; ++ ast_moutdwm(ast, 0x1E6E0018, data); ++ data = data | 0x200; ++ ast_moutdwm(ast, 0x1E6E0018, data); ++ do { ++ data = ast_mindwm(ast, 0x1E6E001C); ++ } while (!(data & 0x08000000)); ++ ++ data = ast_mindwm(ast, 0x1E6E001C); ++ data = (data >> 8) & 0xff; ++ } ++ ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0008) & 0xffff); ++ data = ast_mindwm(ast, 0x1E6E0018) | 0xC00; ++ ast_moutdwm(ast, 0x1E6E0018, data); ++ ++ ast_moutdwm(ast, 0x1E6E0034, 0x00000001); ++ ast_moutdwm(ast, 0x1E6E000C, 0x00000000); ++ udelay(50); ++ /* Mode Register Setting */ ++ ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100); ++ ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS); ++ ast_moutdwm(ast, 0x1E6E0028, 0x00000005); ++ ast_moutdwm(ast, 0x1E6E0028, 0x00000007); ++ ast_moutdwm(ast, 0x1E6E0028, 0x00000003); ++ ast_moutdwm(ast, 0x1E6E0028, 0x00000001); ++ ++ ast_moutdwm(ast, 0x1E6E000C, 0x00005C08); ++ ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS); ++ ast_moutdwm(ast, 0x1E6E0028, 0x00000001); ++ ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380); ++ ast_moutdwm(ast, 0x1E6E0028, 0x00000003); ++ ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS); ++ ast_moutdwm(ast, 0x1E6E0028, 0x00000003); ++ ++ ast_moutdwm(ast, 0x1E6E000C, 0x7FFF5C01); ++ data = 0; ++ if (param->wodt) { ++ data = 0x500; ++ } ++ if (param->rodt) { ++ data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3); ++ } ++ ast_moutdwm(ast, 0x1E6E0034, data | 0x3); ++ ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ); ++ ++ /* Calibrate the DQSI delay */ ++ if ((cbr_dll2(ast, param) == false) && (retry++ < 10)) ++ goto ddr2_init_start; ++ ++ /* ECC Memory Initialization */ ++#ifdef ECC ++ ast_moutdwm(ast, 0x1E6E007C, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0070, 0x221); ++ do { ++ data = ast_mindwm(ast, 0x1E6E0070); ++ } while (!(data & 0x00001000)); ++ ast_moutdwm(ast, 0x1E6E0070, 0x00000000); ++ ast_moutdwm(ast, 0x1E6E0050, 0x80000000); ++ ast_moutdwm(ast, 0x1E6E0050, 0x00000000); ++#endif ++ ++} ++ ++static void ast_init_dram_2300(struct drm_device *dev) ++{ ++ struct ast_private *ast = dev->dev_private; ++ struct ast2300_dram_param param; ++ u32 temp; ++ u8 reg; ++ ++ reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); ++ if ((reg & 0x80) == 0) {/* vga only */ ++ ast_write32(ast, 0xf004, 0x1e6e0000); ++ ast_write32(ast, 0xf000, 0x1); ++ ast_write32(ast, 0x12000, 0x1688a8a8); ++ do { ++ ; ++ } while (ast_read32(ast, 0x12000) != 0x1); ++ ++ ast_write32(ast, 0x10000, 0xfc600309); ++ do { ++ ; ++ } while (ast_read32(ast, 0x10000) != 0x1); ++ ++ /* Slow down CPU/AHB CLK in VGA only mode */ ++ temp = ast_read32(ast, 0x12008); ++ temp |= 0x73; ++ ast_write32(ast, 0x12008, temp); ++ ++ param.dram_type = AST_DDR3; ++ if (temp & 0x01000000) ++ param.dram_type = AST_DDR2; ++ param.dram_chipid = ast->dram_type; ++ param.dram_freq = ast->mclk; ++ param.vram_size = ast->vram_size; ++ ++ if (param.dram_type == AST_DDR3) { ++ get_ddr3_info(ast, &param); ++ ddr3_init(ast, &param); ++ } else { ++ get_ddr2_info(ast, &param); ++ ddr2_init(ast, &param); ++ } ++ ++ temp = ast_mindwm(ast, 0x1e6e2040); ++ ast_moutdwm(ast, 0x1e6e2040, temp | 0x40); ++ } ++ ++ /* wait ready */ ++ do { ++ reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); ++ } while ((reg & 0x40) == 0); ++} ++ +diff --git a/src/drivers/aspeed/common/ast_tables.h b/src/drivers/aspeed/common/ast_tables.h +new file mode 100644 +index 0000000..3608d5a +--- /dev/null ++++ b/src/drivers/aspeed/common/ast_tables.h +@@ -0,0 +1,305 @@ ++/* ++ * Copyright (c) 2005 ASPEED Technology Inc. ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and its ++ * documentation for any purpose is hereby granted without fee, provided that ++ * the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of the authors not be used in ++ * advertising or publicity pertaining to distribution of the software without ++ * specific, written prior permission. The authors makes no representations ++ * about the suitability of this software for any purpose. It is provided ++ * "as is" without express or implied warranty. ++ * ++ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO ++ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR ++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, ++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER ++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++/* Ported from xf86-video-ast driver */ ++ ++#ifndef AST_TABLES_H ++#define AST_TABLES_H ++ ++/* Std. Table Index Definition */ ++#define TextModeIndex 0 ++#define EGAModeIndex 1 ++#define VGAModeIndex 2 ++#define HiCModeIndex 3 ++#define TrueCModeIndex 4 ++ ++#define Charx8Dot 0x00000001 ++#define HalfDCLK 0x00000002 ++#define DoubleScanMode 0x00000004 ++#define LineCompareOff 0x00000008 ++#define HBorder 0x00000020 ++#define VBorder 0x00000010 ++#define WideScreenMode 0x00000100 ++#define NewModeInfo 0x00000200 ++#define NHSync 0x00000400 ++#define PHSync 0x00000800 ++#define NVSync 0x00001000 ++#define PVSync 0x00002000 ++#define SyncPP (PVSync | PHSync) ++#define SyncPN (PVSync | NHSync) ++#define SyncNP (NVSync | PHSync) ++#define SyncNN (NVSync | NHSync) ++ ++/* DCLK Index */ ++#define VCLK25_175 0x00 ++#define VCLK28_322 0x01 ++#define VCLK31_5 0x02 ++#define VCLK36 0x03 ++#define VCLK40 0x04 ++#define VCLK49_5 0x05 ++#define VCLK50 0x06 ++#define VCLK56_25 0x07 ++#define VCLK65 0x08 ++#define VCLK75 0x09 ++#define VCLK78_75 0x0A ++#define VCLK94_5 0x0B ++#define VCLK108 0x0C ++#define VCLK135 0x0D ++#define VCLK157_5 0x0E ++#define VCLK162 0x0F ++/* #define VCLK193_25 0x10 */ ++#define VCLK154 0x10 ++#define VCLK83_5 0x11 ++#define VCLK106_5 0x12 ++#define VCLK146_25 0x13 ++#define VCLK148_5 0x14 ++#define VCLK71 0x15 ++#define VCLK88_75 0x16 ++#define VCLK119 0x17 ++#define VCLK85_5 0x18 ++#define VCLK97_75 0x19 ++#define VCLK118_25 0x1A ++ ++static struct ast_vbios_dclk_info dclk_table[] = { ++ {0x2C, 0xE7, 0x03}, /* 00: VCLK25_175 */ ++ {0x95, 0x62, 0x03}, /* 01: VCLK28_322 */ ++ {0x67, 0x63, 0x01}, /* 02: VCLK31_5 */ ++ {0x76, 0x63, 0x01}, /* 03: VCLK36 */ ++ {0xEE, 0x67, 0x01}, /* 04: VCLK40 */ ++ {0x82, 0x62, 0x01}, /* 05: VCLK49_5 */ ++ {0xC6, 0x64, 0x01}, /* 06: VCLK50 */ ++ {0x94, 0x62, 0x01}, /* 07: VCLK56_25 */ ++ {0x80, 0x64, 0x00}, /* 08: VCLK65 */ ++ {0x7B, 0x63, 0x00}, /* 09: VCLK75 */ ++ {0x67, 0x62, 0x00}, /* 0A: VCLK78_75 */ ++ {0x7C, 0x62, 0x00}, /* 0B: VCLK94_5 */ ++ {0x8E, 0x62, 0x00}, /* 0C: VCLK108 */ ++ {0x85, 0x24, 0x00}, /* 0D: VCLK135 */ ++ {0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */ ++ {0x6A, 0x22, 0x00}, /* 0F: VCLK162 */ ++ {0x4d, 0x4c, 0x80}, /* 10: VCLK154 */ ++ {0xa7, 0x78, 0x80}, /* 11: VCLK83.5 */ ++ {0x28, 0x49, 0x80}, /* 12: VCLK106.5 */ ++ {0x37, 0x49, 0x80}, /* 13: VCLK146.25 */ ++ {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */ ++ {0x47, 0x6c, 0x80}, /* 15: VCLK71 */ ++ {0x25, 0x65, 0x80}, /* 16: VCLK88.75 */ ++ {0x77, 0x58, 0x80}, /* 17: VCLK119 */ ++ {0x32, 0x67, 0x80}, /* 18: VCLK85_5 */ ++ {0x6a, 0x6d, 0x80}, /* 19: VCLK97_75 */ ++ {0x3b, 0x2c, 0x81}, /* 1A: VCLK118_25 */ ++}; ++ ++static struct ast_vbios_stdtable vbios_stdtable[] = { ++ /* MD_2_3_400 */ ++ { ++ 0x67, ++ {0x00,0x03,0x00,0x02}, ++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, ++ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, ++ 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, ++ 0xff}, ++ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, ++ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, ++ 0x0c,0x00,0x0f,0x08}, ++ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, ++ 0xff} ++ }, ++ /* Mode12/ExtEGATable */ ++ { ++ 0xe3, ++ {0x01,0x0f,0x00,0x06}, ++ {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, ++ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3, ++ 0xff}, ++ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, ++ 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, ++ 0x01,0x00,0x0f,0x00}, ++ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, ++ 0xff} ++ }, ++ /* ExtVGATable */ ++ { ++ 0x2f, ++ {0x01,0x0f,0x00,0x0e}, ++ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, ++ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, ++ 0xff}, ++ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, ++ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, ++ 0x01,0x00,0x00,0x00}, ++ {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, ++ 0xff} ++ }, ++ /* ExtHiCTable */ ++ { ++ 0x2f, ++ {0x01,0x0f,0x00,0x0e}, ++ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, ++ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, ++ 0xff}, ++ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, ++ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, ++ 0x01,0x00,0x00,0x00}, ++ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, ++ 0xff} ++ }, ++ /* ExtTrueCTable */ ++ { ++ 0x2f, ++ {0x01,0x0f,0x00,0x0e}, ++ {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, ++ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, ++ 0xff}, ++ {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, ++ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, ++ 0x01,0x00,0x00,0x00}, ++ {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f, ++ 0xff} ++ }, ++}; ++ ++static struct ast_vbios_enhtable res_640x480[] = { ++ { 800, 640, 8, 96, 525, 480, 2, 2, VCLK25_175, /* 60Hz */ ++ (SyncNN | HBorder | VBorder | Charx8Dot), 60, 1, 0x2E }, ++ { 832, 640, 16, 40, 520, 480, 1, 3, VCLK31_5, /* 72Hz */ ++ (SyncNN | HBorder | VBorder | Charx8Dot), 72, 2, 0x2E }, ++ { 840, 640, 16, 64, 500, 480, 1, 3, VCLK31_5, /* 75Hz */ ++ (SyncNN | Charx8Dot) , 75, 3, 0x2E }, ++ { 832, 640, 56, 56, 509, 480, 1, 3, VCLK36, /* 85Hz */ ++ (SyncNN | Charx8Dot) , 85, 4, 0x2E }, ++ { 832, 640, 56, 56, 509, 480, 1, 3, VCLK36, /* end */ ++ (SyncNN | Charx8Dot) , 0xFF, 4, 0x2E }, ++}; ++ ++static struct ast_vbios_enhtable res_800x600[] = { ++ {1024, 800, 24, 72, 625, 600, 1, 2, VCLK36, /* 56Hz */ ++ (SyncPP | Charx8Dot), 56, 1, 0x30 }, ++ {1056, 800, 40, 128, 628, 600, 1, 4, VCLK40, /* 60Hz */ ++ (SyncPP | Charx8Dot), 60, 2, 0x30 }, ++ {1040, 800, 56, 120, 666, 600, 37, 6, VCLK50, /* 72Hz */ ++ (SyncPP | Charx8Dot), 72, 3, 0x30 }, ++ {1056, 800, 16, 80, 625, 600, 1, 3, VCLK49_5, /* 75Hz */ ++ (SyncPP | Charx8Dot), 75, 4, 0x30 }, ++ {1048, 800, 32, 64, 631, 600, 1, 3, VCLK56_25, /* 85Hz */ ++ (SyncPP | Charx8Dot), 84, 5, 0x30 }, ++ {1048, 800, 32, 64, 631, 600, 1, 3, VCLK56_25, /* end */ ++ (SyncPP | Charx8Dot), 0xFF, 5, 0x30 }, ++}; ++ ++ ++static struct ast_vbios_enhtable res_1024x768[] = { ++ {1344, 1024, 24, 136, 806, 768, 3, 6, VCLK65, /* 60Hz */ ++ (SyncNN | Charx8Dot), 60, 1, 0x31 }, ++ {1328, 1024, 24, 136, 806, 768, 3, 6, VCLK75, /* 70Hz */ ++ (SyncNN | Charx8Dot), 70, 2, 0x31 }, ++ {1312, 1024, 16, 96, 800, 768, 1, 3, VCLK78_75, /* 75Hz */ ++ (SyncPP | Charx8Dot), 75, 3, 0x31 }, ++ {1376, 1024, 48, 96, 808, 768, 1, 3, VCLK94_5, /* 85Hz */ ++ (SyncPP | Charx8Dot), 84, 4, 0x31 }, ++ {1376, 1024, 48, 96, 808, 768, 1, 3, VCLK94_5, /* end */ ++ (SyncPP | Charx8Dot), 0xFF, 4, 0x31 }, ++}; ++ ++static struct ast_vbios_enhtable res_1280x1024[] = { ++ {1688, 1280, 48, 112, 1066, 1024, 1, 3, VCLK108, /* 60Hz */ ++ (SyncPP | Charx8Dot), 60, 1, 0x32 }, ++ {1688, 1280, 16, 144, 1066, 1024, 1, 3, VCLK135, /* 75Hz */ ++ (SyncPP | Charx8Dot), 75, 2, 0x32 }, ++ {1728, 1280, 64, 160, 1072, 1024, 1, 3, VCLK157_5, /* 85Hz */ ++ (SyncPP | Charx8Dot), 85, 3, 0x32 }, ++ {1728, 1280, 64, 160, 1072, 1024, 1, 3, VCLK157_5, /* end */ ++ (SyncPP | Charx8Dot), 0xFF, 3, 0x32 }, ++}; ++ ++static struct ast_vbios_enhtable res_1600x1200[] = { ++ {2160, 1600, 64, 192, 1250, 1200, 1, 3, VCLK162, /* 60Hz */ ++ (SyncPP | Charx8Dot), 60, 1, 0x33 }, ++ {2160, 1600, 64, 192, 1250, 1200, 1, 3, VCLK162, /* end */ ++ (SyncPP | Charx8Dot), 0xFF, 1, 0x33 }, ++}; ++ ++/* 16:9 */ ++static struct ast_vbios_enhtable res_1360x768[] = { ++ {1792, 1360, 64,112, 795, 768, 3, 6, VCLK85_5, /* 60Hz */ ++ (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x39 }, ++ {1792, 1360, 64,112, 795, 768, 3, 6, VCLK85_5, /* end */ ++ (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x39 }, ++}; ++ ++static struct ast_vbios_enhtable res_1600x900[] = { ++ {1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75, /* 60Hz CVT RB */ ++ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x3A }, ++ {2112, 1600, 88,168, 934, 900, 3, 5, VCLK118_25, /* 60Hz CVT */ ++ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x3A }, ++ {2112, 1600, 88,168, 934, 900, 3, 5, VCLK118_25, /* 60Hz CVT */ ++ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 2, 0x3A }, ++}; ++ ++static struct ast_vbios_enhtable res_1920x1080[] = { ++ {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ ++ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x38 }, ++ {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ ++ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x38 }, ++}; ++ ++ ++/* 16:10 */ ++static struct ast_vbios_enhtable res_1280x800[] = { ++ {1440, 1280, 48, 32, 823, 800, 3, 6, VCLK71, /* 60Hz RB */ ++ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x35 }, ++ {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */ ++ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x35 }, ++ {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */ ++ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 2, 0x35 }, ++ ++}; ++ ++static struct ast_vbios_enhtable res_1440x900[] = { ++ {1600, 1440, 48, 32, 926, 900, 3, 6, VCLK88_75, /* 60Hz RB */ ++ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x36 }, ++ {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */ ++ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x36 }, ++ {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */ ++ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 2, 0x36 }, ++}; ++ ++static struct ast_vbios_enhtable res_1680x1050[] = { ++ {1840, 1680, 48, 32, 1080, 1050, 3, 6, VCLK119, /* 60Hz RB */ ++ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x37 }, ++ {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */ ++ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 2, 0x37 }, ++ {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */ ++ (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 2, 0x37 }, ++}; ++ ++static struct ast_vbios_enhtable res_1920x1200[] = { ++ {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz RB*/ ++ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 1, 0x34 }, ++ {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz RB */ ++ (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 0xFF, 1, 0x34 }, ++}; ++ ++#endif +diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h +index dcb8a42..fcaf4aa 100644 +--- a/src/include/device/pci_ids.h ++++ b/src/include/device/pci_ids.h +@@ -1991,6 +1991,9 @@ + #define PCI_DEVICE_ID_XGI_20 0x0020 + #define PCI_DEVICE_ID_XGI_40 0x0040 + ++#define PCI_VENDOR_ID_ASPEED 0x1a03 ++#define PCI_DEVICE_ID_ASPEED_AST2050_VGA 0x2000 ++ + #define PCI_VENDOR_ID_SYMPHONY 0x1c1c + #define PCI_DEVICE_ID_SYMPHONY_101 0x0001 + +-- +1.7.9.5 + diff --git a/resources/libreboot/patch/kgpe-d16/0006-southbridge-amd-sr5650-Fix-boot-failure-on-ASUS-KGPE.patch b/resources/libreboot/patch/kgpe-d16/0006-southbridge-amd-sr5650-Fix-boot-failure-on-ASUS-KGPE.patch @@ -1,621 +0,0 @@ -From 03ff36542c8f8260b2ff7db5f41a16e9299a1bd0 Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <tpearson@raptorengineeringinc.com> -Date: Sat, 5 Sep 2015 17:46:38 -0500 -Subject: [PATCH 006/139] southbridge/amd/sr5650: Fix boot failure on ASUS - KGPE-D16 - -Change-Id: Ia13ba58118a826e830a4dc6e2378b76110fcabad -Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> ---- - src/southbridge/amd/sr5650/acpi/sr5650.asl | 388 +++++++++++++++++++++++++++++ - src/southbridge/amd/sr5650/early_setup.c | 7 +- - src/southbridge/amd/sr5650/ht.c | 3 +- - src/southbridge/amd/sr5650/pcie.c | 37 ++- - src/southbridge/amd/sr5650/sr5650.c | 51 ++-- - 5 files changed, 456 insertions(+), 30 deletions(-) - create mode 100644 src/southbridge/amd/sr5650/acpi/sr5650.asl - -diff --git a/src/southbridge/amd/sr5650/acpi/sr5650.asl b/src/southbridge/amd/sr5650/acpi/sr5650.asl -new file mode 100644 -index 0000000..a6ab114 ---- /dev/null -+++ b/src/southbridge/amd/sr5650/acpi/sr5650.asl -@@ -0,0 +1,388 @@ -+/* -+ * This file is part of the coreboot project. -+ * -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering -+ * Copyright (C) 2009 Advanced Micro Devices, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+Scope(\) { -+ Name(PCBA, 0xE0000000) /* Base address of PCIe config space */ -+ Name(HPBA, 0xFED00000) /* Base address of HPET table */ -+ -+ /* PIC IRQ mapping registers, C00h-C01h */ -+ OperationRegion(PRQM, SystemIO, 0x00000C00, 0x00000002) -+ Field(PRQM, ByteAcc, NoLock, Preserve) { -+ PRQI, 0x00000008, -+ PRQD, 0x00000008, /* Offset: 1h */ -+ } -+ IndexField(PRQI, PRQD, ByteAcc, NoLock, Preserve) { -+ PINA, 0x00000008, /* Index 0 */ -+ PINB, 0x00000008, /* Index 1 */ -+ PINC, 0x00000008, /* Index 2 */ -+ PIND, 0x00000008, /* Index 3 */ -+ AINT, 0x00000008, /* Index 4 */ -+ SINT, 0x00000008, /* Index 5 */ -+ , 0x00000008, /* Index 6 */ -+ AAUD, 0x00000008, /* Index 7 */ -+ AMOD, 0x00000008, /* Index 8 */ -+ PINE, 0x00000008, /* Index 9 */ -+ PINF, 0x00000008, /* Index A */ -+ PING, 0x00000008, /* Index B */ -+ PINH, 0x00000008, /* Index C */ -+ } -+ -+ /* PCI Error control register */ -+ OperationRegion(PERC, SystemIO, 0x00000C14, 0x00000001) -+ Field(PERC, ByteAcc, NoLock, Preserve) { -+ SENS, 0x00000001, -+ PENS, 0x00000001, -+ SENE, 0x00000001, -+ PENE, 0x00000001, -+ } -+ -+ Scope(\_SB) { -+ /* PCIe Configuration Space for 16 busses */ -+ OperationRegion(PCFG, SystemMemory, PCBA, 0x01000000) /* Each bus consumes 1MB */ -+ Field(PCFG, ByteAcc, NoLock, Preserve) { -+ /* Byte offsets are computed using the following technique: -+ * ((bus number + 1) * ((device number * 8) * 4096)) + register offset -+ * The 8 comes from 8 functions per device, and 4096 bytes per function config space -+ */ -+ Offset(0x00088024), /* Byte offset to SATA register 24h - Bus 0, Device 17, Function 0 */ -+ STB5, 32, -+ Offset(0x00098042), /* Byte offset to OHCI0 register 42h - Bus 0, Device 19, Function 0 */ -+ PT0D, 1, -+ PT1D, 1, -+ PT2D, 1, -+ PT3D, 1, -+ PT4D, 1, -+ PT5D, 1, -+ PT6D, 1, -+ PT7D, 1, -+ PT8D, 1, -+ PT9D, 1, -+ Offset(0x000A0004), /* Byte offset to SMBUS register 4h - Bus 0, Device 20, Function 0 */ -+ SBIE, 1, -+ SBME, 1, -+ Offset(0x000A0008), /* Byte offset to SMBUS register 8h - Bus 0, Device 20, Function 0 */ -+ SBRI, 8, -+ Offset(0x000A0014), /* Byte offset to SMBUS register 14h - Bus 0, Device 20, Function 0 */ -+ SBB1, 32, -+ Offset(0x000A0078), /* Byte offset to SMBUS register 78h - Bus 0, Device 20, Function 0 */ -+ ,14, -+ P92E, 1, /* Port92 decode enable */ -+ } -+ -+ OperationRegion(SB5, SystemMemory, STB5, 0x1000) -+ Field(SB5, AnyAcc, NoLock, Preserve){ -+ /* Port 0 */ -+ Offset(0x120), /* Port 0 Task file status */ -+ P0ER, 1, -+ , 2, -+ P0DQ, 1, -+ , 3, -+ P0BY, 1, -+ Offset(0x128), /* Port 0 Serial ATA status */ -+ P0DD, 4, -+ , 4, -+ P0IS, 4, -+ Offset(0x12C), /* Port 0 Serial ATA control */ -+ P0DI, 4, -+ Offset(0x130), /* Port 0 Serial ATA error */ -+ , 16, -+ P0PR, 1, -+ -+ /* Port 1 */ -+ offset(0x1A0), /* Port 1 Task file status */ -+ P1ER, 1, -+ , 2, -+ P1DQ, 1, -+ , 3, -+ P1BY, 1, -+ Offset(0x1A8), /* Port 1 Serial ATA status */ -+ P1DD, 4, -+ , 4, -+ P1IS, 4, -+ Offset(0x1AC), /* Port 1 Serial ATA control */ -+ P1DI, 4, -+ Offset(0x1B0), /* Port 1 Serial ATA error */ -+ , 16, -+ P1PR, 1, -+ -+ /* Port 2 */ -+ Offset(0x220), /* Port 2 Task file status */ -+ P2ER, 1, -+ , 2, -+ P2DQ, 1, -+ , 3, -+ P2BY, 1, -+ Offset(0x228), /* Port 2 Serial ATA status */ -+ P2DD, 4, -+ , 4, -+ P2IS, 4, -+ Offset(0x22C), /* Port 2 Serial ATA control */ -+ P2DI, 4, -+ Offset(0x230), /* Port 2 Serial ATA error */ -+ , 16, -+ P2PR, 1, -+ -+ /* Port 3 */ -+ Offset(0x2A0), /* Port 3 Task file status */ -+ P3ER, 1, -+ , 2, -+ P3DQ, 1, -+ , 3, -+ P3BY, 1, -+ Offset(0x2A8), /* Port 3 Serial ATA status */ -+ P3DD, 4, -+ , 4, -+ P3IS, 4, -+ Offset(0x2AC), /* Port 3 Serial ATA control */ -+ P3DI, 4, -+ Offset(0x2B0), /* Port 3 Serial ATA error */ -+ , 16, -+ P3PR, 1, -+ } -+ -+ Method(CIRQ, 0x00, NotSerialized){ -+ Store(0, PINA) -+ Store(0, PINB) -+ Store(0, PINC) -+ Store(0, PIND) -+ Store(0, PINE) -+ Store(0, PINF) -+ Store(0, PING) -+ Store(0, PINH) -+ } -+ -+ /* set "A", 8259 interrupts */ -+ Name (PRSA, ResourceTemplate () { -+ IRQ(Level, ActiveLow, Exclusive) {4, 7, 10, 11, 12, 14, 15} -+ }) -+ -+ Method (CRSA, 1, Serialized) { -+ Name (LRTL, ResourceTemplate() { -+ IRQ(Level, ActiveLow, Shared) {15} -+ }) -+ CreateWordField(LRTL, 1, LIRQ) -+ ShiftLeft(1, Arg0, LIRQ) -+ Return (LRTL) -+ } -+ -+ Method (SRSA, 1, Serialized) { -+ CreateWordField(Arg0, 1, LIRQ) -+ FindSetRightBit(LIRQ, Local0) -+ if (Local0) { -+ Decrement(Local0) -+ } -+ Return (Local0) -+ } -+ -+ Device(LNKA) { -+ Name(_HID, EISAID("PNP0C0F")) -+ Name(_UID, 1) -+ Method(_STA, 0) { -+ if (PINA) { -+ Return(0x0B) /* LNKA is invisible */ -+ } else { -+ Return(0x09) /* LNKA is disabled */ -+ } -+ } -+ Method(_DIS, 0) { -+ Store(0, PINA) -+ } -+ Method(_PRS, 0) { -+ Return (PRSA) -+ } -+ Method (_CRS, 0, Serialized) { -+ Return (CRSA(PINA)) -+ } -+ Method (_SRS, 1, Serialized) { -+ Store (SRSA(Arg0), PINA) -+ } -+ } -+ -+ Device(LNKB) { -+ Name(_HID, EISAID("PNP0C0F")) -+ Name(_UID, 2) -+ Method(_STA, 0) { -+ if (PINB) { -+ Return(0x0B) /* LNKB is invisible */ -+ } else { -+ Return(0x09) /* LNKB is disabled */ -+ } -+ } -+ Method(_DIS, 0) { -+ Store(0, PINB) -+ } -+ Method(_PRS, 0) { -+ Return (PRSA) -+ } -+ Method (_CRS, 0, Serialized) { -+ Return (CRSA(PINB)) -+ } -+ Method (_SRS, 1, Serialized) { -+ Store (SRSA(Arg0), PINB) -+ } -+ } -+ -+ Device(LNKC) { -+ Name(_HID, EISAID("PNP0C0F")) -+ Name(_UID, 3) -+ Method(_STA, 0) { -+ if (PINC) { -+ Return(0x0B) /* LNKC is invisible */ -+ } else { -+ Return(0x09) /* LNKC is disabled */ -+ } -+ } -+ Method(_DIS, 0) { -+ Store(0, PINC) -+ } -+ Method(_PRS, 0) { -+ Return (PRSA) -+ } -+ Method (_CRS, 0, Serialized) { -+ Return (CRSA(PINC)) -+ } -+ Method (_SRS, 1, Serialized) { -+ Store (SRSA(Arg0), PINC) -+ } -+ } -+ -+ Device(LNKD) { -+ Name(_HID, EISAID("PNP0C0F")) -+ Name(_UID, 4) -+ Method(_STA, 0) { -+ if (PIND) { -+ Return(0x0B) /* LNKD is invisible */ -+ } else { -+ Return(0x09) /* LNKD is disabled */ -+ } -+ } -+ Method(_DIS, 0) { -+ Store(0, PIND) -+ } -+ Method(_PRS, 0) { -+ Return (PRSA) -+ } -+ Method (_CRS, 0, Serialized) { -+ Return (CRSA(PIND)) -+ } -+ Method (_SRS, 1, Serialized) { -+ Store (SRSA(Arg0), PIND) -+ } -+ } -+ -+ Device(LNKE) { -+ Name(_HID, EISAID("PNP0C0F")) -+ Name(_UID, 5) -+ Method(_STA, 0) { -+ if (PINE) { -+ Return(0x0B) /* LNKE is invisible */ -+ } else { -+ Return(0x09) /* LNKE is disabled */ -+ } -+ } -+ Method(_DIS, 0) { -+ Store(0, PINE) -+ } -+ Method(_PRS, 0) { -+ Return (PRSA) -+ } -+ Method (_CRS, 0, Serialized) { -+ Return (CRSA(PINE)) -+ } -+ Method (_SRS, 1, Serialized) { -+ Store (SRSA(Arg0), PINE) -+ } -+ } -+ -+ Device(LNKF) { -+ Name(_HID, EISAID("PNP0C0F")) -+ Name(_UID, 6) -+ Method(_STA, 0) { -+ if (PINF) { -+ Return(0x0B) /* LNKF is invisible */ -+ } else { -+ Return(0x09) /* LNKF is disabled */ -+ } -+ } -+ Method(_DIS, 0) { -+ Store(0, PINF) -+ } -+ Method(_PRS, 0) { -+ Return (PRSA) -+ } -+ Method (_CRS, 0, Serialized) { -+ Return (CRSA(PINF)) -+ } -+ Method (_SRS, 1, Serialized) { -+ Store (SRSA(Arg0), PINF) -+ } -+ } -+ -+ Device(LNKG) { -+ Name(_HID, EISAID("PNP0C0F")) -+ Name(_UID, 7) -+ Method(_STA, 0) { -+ if (PING) { -+ Return(0x0B) /* LNKG is invisible */ -+ } else { -+ Return(0x09) /* LNKG is disabled */ -+ } -+ } -+ Method(_DIS, 0) { -+ Store(0, PING) -+ } -+ Method(_PRS, 0) { -+ Return (PRSA) -+ } -+ Method (_CRS, 0, Serialized) { -+ Return (CRSA(PING)) -+ } -+ Method (_SRS, 1, Serialized) { -+ Store (SRSA(Arg0), PING) -+ } -+ } -+ -+ Device(LNKH) { -+ Name(_HID, EISAID("PNP0C0F")) -+ Name(_UID, 8) -+ Method(_STA, 0) { -+ if (PINH) { -+ Return(0x0B) /* LNKH is invisible */ -+ } else { -+ Return(0x09) /* LNKH is disabled */ -+ } -+ } -+ Method(_DIS, 0) { -+ Store(0, PINH) -+ } -+ Method(_PRS, 0) { -+ Return (PRSA) -+ } -+ Method (_CRS, 0, Serialized) { -+ Return (CRSA(PINH)) -+ } -+ Method (_SRS, 1, Serialized) { -+ Store (SRSA(Arg0), PINH) -+ } -+ } -+ -+ } /* End Scope(_SB) */ -+ -+} /* End Scope(/) */ -diff --git a/src/southbridge/amd/sr5650/early_setup.c b/src/southbridge/amd/sr5650/early_setup.c -index ec555f8..664f60a 100644 ---- a/src/southbridge/amd/sr5650/early_setup.c -+++ b/src/southbridge/amd/sr5650/early_setup.c -@@ -3,6 +3,7 @@ - * - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * Copyright (C) 2010 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -504,7 +505,8 @@ void sr5650_early_setup(void) - /*ATINB_PrepareInit */ - get_cpu_rev(); - -- switch (get_nb_rev(nb_dev)) { /* PCIEMiscInit */ -+ uint8_t revno = get_nb_rev(nb_dev); -+ switch (revno) { /* PCIEMiscInit */ - case REV_SR5650_A11: - printk(BIOS_INFO, "NB Revision is A11.\n"); - break; -@@ -514,6 +516,9 @@ void sr5650_early_setup(void) - case REV_SR5650_A21: - printk(BIOS_INFO, "NB Revision is A21.\n"); - break; -+ default: -+ printk(BIOS_INFO, "NB Revision is %02x (Unrecognized).\n", revno); -+ break; - } - - fam10_optimization(); -diff --git a/src/southbridge/amd/sr5650/ht.c b/src/southbridge/amd/sr5650/ht.c -index c497107..02f4f7f 100644 ---- a/src/southbridge/amd/sr5650/ht.c -+++ b/src/southbridge/amd/sr5650/ht.c -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -55,7 +56,7 @@ static const apic_device_info default_apic_device_info_t [] = { - [13] = {4, ABCD, 30} /* Dev13 Grp4 [Int - 16..19] */ - }; - --/* Their name are quite regular. So I undefine them. */ -+/* These define names are common, so undefine them to avoid potential issues in other code */ - #undef ABCD - #undef BCDA - #undef CDAB -diff --git a/src/southbridge/amd/sr5650/pcie.c b/src/southbridge/amd/sr5650/pcie.c -index 3720a61..d306b5a 100644 ---- a/src/southbridge/amd/sr5650/pcie.c -+++ b/src/southbridge/amd/sr5650/pcie.c -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -61,8 +62,10 @@ static void ValidatePortEn(device_t nb_dev) - *****************************************************************/ - static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port) - { -+ printk(BIOS_DEBUG, "PciePowerOffGppPorts() port %d\n", port); - u32 reg; - u16 state_save; -+ uint8_t i; - struct southbridge_amd_sr5650_config *cfg = - (struct southbridge_amd_sr5650_config *)nb_dev->chip_info; - u16 state = cfg->port_enable; -@@ -72,6 +75,28 @@ static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port) - state = ~state; - state &= (1 << 4) + (1 << 5) + (1 << 6) + (1 << 7); - state_save = state << 17; -+ /* Disable ports any that failed training */ -+ for (i = 9; i <= 13; i++) { -+ if (!(AtiPcieCfg.PortDetect & 1 << i)) { -+ if ((port >= 9) && (port <= 13)) { -+ state |= (1 << (port + 7)); -+ } -+ if (port == 9) -+ state_save |= 1 << 25; -+ if (port == 10) -+ state_save |= 1 << 26; -+ if (port == 11) -+ state_save |= 1 << 6; -+ if (port == 12) -+ state_save |= 1 << 7; -+ -+ if (port == 13) { -+ reg = nbmisc_read_index(nb_dev, 0x2a); -+ reg |= 1 << 4; -+ nbmisc_write_index(nb_dev, 0x2a, reg); -+ } -+ } -+ } - state &= !(AtiPcieCfg.PortHp); - reg = nbmisc_read_index(nb_dev, 0x0c); - reg |= state; -@@ -483,6 +508,8 @@ static void EnableLclkGating(device_t dev) - *****************************************/ - void sr5650_gpp_sb_init(device_t nb_dev, device_t dev, u32 port) - { -+ uint8_t training_ok = 1; -+ - u32 gpp_sb_sel = 0; - struct southbridge_amd_sr5650_config *cfg = - (struct southbridge_amd_sr5650_config *)nb_dev->chip_info; -@@ -701,6 +728,12 @@ void sr5650_gpp_sb_init(device_t nb_dev, device_t dev, u32 port) - printk(BIOS_DEBUG, "PcieTrainPort port=0x%x result=%d\n", port, res); - if (res) { - AtiPcieCfg.PortDetect |= 1 << port; -+ } else { -+ /* If the training failed the disable the bridge to prevent subsequent -+ * lockup on bridge configuration register read during the PCI bus scan -+ */ -+ training_ok = 0; -+ dev->enabled = 0; - } - } - } -@@ -747,8 +780,8 @@ void sr5650_gpp_sb_init(device_t nb_dev, device_t dev, u32 port) - * wait dev 0x6B bit3 clear - */ - -- if (port == 8){ -- PciePowerOffGppPorts(nb_dev, dev, port); /* , This should be run for all ports that are not hotplug and don't detect devices */ -+ if ((port == 8) || (!training_ok)) { -+ PciePowerOffGppPorts(nb_dev, dev, port); /* This is run for all ports that are not hotplug and don't detect devices */ - } - } - -diff --git a/src/southbridge/amd/sr5650/sr5650.c b/src/southbridge/amd/sr5650/sr5650.c -index 441be66..75383de 100644 ---- a/src/southbridge/amd/sr5650/sr5650.c -+++ b/src/southbridge/amd/sr5650/sr5650.c -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -95,32 +96,30 @@ void nbpcie_ind_write_index(device_t nb_dev, u32 index, u32 data) - void ProgK8TempMmioBase(u8 in_out, u32 pcie_base_add, u32 mmio_base_add) - { - /* K8 Function1 is address map */ -- device_t k8_f1; -- device_t np = dev_find_slot(0, PCI_DEVFN(0x19, 1)); -- u16 node; -- -- for (node = 0; node < CONFIG_MAX_PHYSICAL_CPUS; node++) { -- k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18 + node, 1)); -- if (!k8_f1) { -- break; -- } -- -- if (in_out) { -- /* Fill MMIO limit/base pair. */ -- pci_write_config32(k8_f1, 0xbc, -- (((pcie_base_add + 0x10000000 - -- 1) >> 8) & 0xffffff00) | 0x8 | (np ? 2 << 4 : 0 << 4)); -- pci_write_config32(k8_f1, 0xb8, (pcie_base_add >> 8) | 0x3); -- pci_write_config32(k8_f1, 0xb4, -- ((mmio_base_add + 0x10000000 - -- 1) >> 8) | (np ? 2 << 4 : 0 << 4)); -- pci_write_config32(k8_f1, 0xb0, (mmio_base_add >> 8) | 0x3); -- } else { -- pci_write_config32(k8_f1, 0xb8, 0); -- pci_write_config32(k8_f1, 0xbc, 0); -- pci_write_config32(k8_f1, 0xb0, 0); -- pci_write_config32(k8_f1, 0xb4, 0); -- } -+ device_t k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1)); -+ device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0)); -+ -+ if (in_out) { -+ u32 dword, sblk; -+ -+ /* Get SBLink value (HyperTransport I/O Hub Link ID). */ -+ dword = pci_read_config32(k8_f0, 0x64); -+ sblk = (dword >> 8) & 0x3; -+ -+ /* Fill MMIO limit/base pair. */ -+ pci_write_config32(k8_f1, 0xbc, -+ (((pcie_base_add + 0x10000000 - -+ 1) >> 8) & 0xffffff00) | 0x80 | (sblk << 4)); -+ pci_write_config32(k8_f1, 0xb8, (pcie_base_add >> 8) | 0x3); -+ pci_write_config32(k8_f1, 0xb4, -+ (((mmio_base_add + 0x10000000 - -+ 1) >> 8) & 0xffffff00) | (sblk << 4)); -+ pci_write_config32(k8_f1, 0xb0, (mmio_base_add >> 8) | 0x3); -+ } else { -+ pci_write_config32(k8_f1, 0xb8, 0); -+ pci_write_config32(k8_f1, 0xbc, 0); -+ pci_write_config32(k8_f1, 0xb0, 0); -+ pci_write_config32(k8_f1, 0xb4, 0); - } - } - --- -1.9.1 - diff --git a/resources/libreboot/patch/kgpe-d16/0007-cpu-amd-Add-initial-support-for-AMD-Socket-G34-proce.patch b/resources/libreboot/patch/kgpe-d16/0007-cpu-amd-Add-initial-support-for-AMD-Socket-G34-proce.patch @@ -1,832 +0,0 @@ -From 1c4603c0b0003dc41519ed8e03782ff6e1f9222f Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <tpearson@raptorengineeringinc.com> -Date: Sat, 5 Sep 2015 17:50:29 -0500 -Subject: [PATCH 007/139] cpu/amd: Add initial support for AMD Socket G34 - processors - -Change-Id: Iccd034f32c26513edd52ca3a11a30f61c362682d -Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> ---- - src/cpu/amd/Kconfig | 1 + - src/cpu/amd/Makefile.inc | 1 + - src/cpu/amd/car/post_cache_as_ram.c | 19 ++++- - src/cpu/amd/model_10xxx/init_cpus.c | 34 ++++++++- - src/cpu/amd/model_10xxx/model_10xxx_init.c | 2 + - src/cpu/amd/model_10xxx/processor_name.c | 23 +++++++ - src/cpu/amd/model_10xxx/ram_calc.c | 2 + - src/cpu/amd/quadcore/quadcore_id.c | 77 ++++++++++++++++----- - src/cpu/amd/socket_G34/Kconfig | 29 ++++++++ - src/cpu/amd/socket_G34/Makefile.inc | 14 ++++ - src/cpu/amd/socket_G34/socket_G34.c | 25 +++++++ - src/northbridge/amd/amdfam10/northbridge.c | 102 ++++++++++++++++++++++----- - src/northbridge/amd/amdht/ht_wrapper.c | 107 ++++++++++++++++++++++++++++- - src/northbridge/amd/amdht/ht_wrapper.h | 25 +++++++ - 14 files changed, 417 insertions(+), 44 deletions(-) - create mode 100644 src/cpu/amd/socket_G34/Kconfig - create mode 100644 src/cpu/amd/socket_G34/Makefile.inc - create mode 100644 src/cpu/amd/socket_G34/socket_G34.c - create mode 100644 src/northbridge/amd/amdht/ht_wrapper.h - -diff --git a/src/cpu/amd/Kconfig b/src/cpu/amd/Kconfig -index 8286b2a..3a02043 100644 ---- a/src/cpu/amd/Kconfig -+++ b/src/cpu/amd/Kconfig -@@ -5,6 +5,7 @@ source src/cpu/amd/socket_AM2/Kconfig - source src/cpu/amd/socket_AM2r2/Kconfig - source src/cpu/amd/socket_AM3/Kconfig - source src/cpu/amd/socket_C32/Kconfig -+source src/cpu/amd/socket_G34/Kconfig - source src/cpu/amd/socket_ASB2/Kconfig - source src/cpu/amd/socket_F/Kconfig - source src/cpu/amd/socket_F_1207/Kconfig -diff --git a/src/cpu/amd/Makefile.inc b/src/cpu/amd/Makefile.inc -index a73e25f..e532aba 100644 ---- a/src/cpu/amd/Makefile.inc -+++ b/src/cpu/amd/Makefile.inc -@@ -8,6 +8,7 @@ subdirs-$(CONFIG_CPU_AMD_SOCKET_AM2R2) += socket_AM2r2 - subdirs-$(CONFIG_CPU_AMD_SOCKET_AM3) += socket_AM3 - subdirs-$(CONFIG_CPU_AMD_SOCKET_ASB2) += socket_ASB2 - subdirs-$(CONFIG_CPU_AMD_SOCKET_C32_NON_AGESA) += socket_C32 -+subdirs-$(CONFIG_CPU_AMD_SOCKET_G34_NON_AGESA) += socket_G34 - subdirs-$(CONFIG_CPU_AMD_GEODE_GX2) += geode_gx2 - subdirs-$(CONFIG_CPU_AMD_GEODE_LX) += geode_lx - subdirs-$(CONFIG_CPU_AMD_SOCKET_S1G1) += socket_S1G1 -diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c -index 96df3e7..230d1aa 100644 ---- a/src/cpu/amd/car/post_cache_as_ram.c -+++ b/src/cpu/amd/car/post_cache_as_ram.c -@@ -1,4 +1,5 @@ --/* 2005.6 by yhlu -+/* Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering -+ * 2005.6 by yhlu - * 2006.3 yhlu add copy data from CAR to ram - */ - #include <string.h> -@@ -46,6 +47,15 @@ static void memset_(void *d, int val, size_t len) - memset(d, val, len); - } - -+static int memcmp_(void *d, const void *s, size_t len) -+{ -+#if PRINTK_IN_CAR -+ printk(BIOS_SPEW, " Compare [%08x-%08x] with [%08x - %08x] ... ", -+ (u32) s, (u32) (s + len - 1), (u32) d, (u32) (d + len - 1)); -+#endif -+ return memcmp(d, s, len); -+} -+ - static void prepare_romstage_ramstack(void *resume_backup_memory) - { - size_t backup_top = backup_size(); -@@ -110,6 +120,12 @@ void post_cache_as_ram(void) - memcpy_(migrated_car, &_car_data_start[0], car_size); - print_car_debug("Done\n"); - -+ print_car_debug("Verifying data integrity in RAM... "); -+ if (memcmp_(migrated_car, &_car_data_start[0], car_size) == 0) -+ print_car_debug("Done\n"); -+ else -+ print_car_debug("FAILED\n"); -+ - /* New stack grows right below migrated_car. */ - print_car_debug("Switching to use RAM as stack... "); - cache_as_ram_switch_stack(migrated_car); -@@ -128,6 +144,7 @@ void cache_as_ram_new_stack (void) - disable_cache_as_ram_bsp(); - - disable_cache(); -+ /* Enable cached access to RAM in the range 1M to CONFIG_RAMTOP */ - set_var_mtrr(0, 0x00000000, CONFIG_RAMTOP, MTRR_TYPE_WRBACK); - enable_cache(); - -diff --git a/src/cpu/amd/model_10xxx/init_cpus.c b/src/cpu/amd/model_10xxx/init_cpus.c -index 4c72848..8de6d25 100644 ---- a/src/cpu/amd/model_10xxx/init_cpus.c -+++ b/src/cpu/amd/model_10xxx/init_cpus.c -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -67,6 +68,9 @@ static void for_each_ap(u32 bsp_apicid, u32 core_range, process_ap_t process_ap, - u32 nb_cfg_54; - int i, j; - u32 ApicIdCoreIdSize; -+ uint8_t rev_gte_d = 0; -+ uint8_t dual_node = 0; -+ uint32_t f3xe8; - - /* get_nodes define in ht_wrapper.c */ - nodes = get_nodes(); -@@ -81,6 +85,16 @@ static void for_each_ap(u32 bsp_apicid, u32 core_range, process_ap_t process_ap, - /* Assume that all node are same stepping, otherwise we can use use - nb_cfg_54 from bsp for all nodes */ - nb_cfg_54 = read_nb_cfg_54(); -+ f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8); -+ -+ if (cpuid_eax(0x80000001) >= 0x8) -+ /* Revision D or later */ -+ rev_gte_d = 1; -+ -+ if (rev_gte_d) -+ /* Check for dual node capability */ -+ if (f3xe8 & 0x20000000) -+ dual_node = 1; - - ApicIdCoreIdSize = (cpuid_ecx(0x80000008) >> 12 & 0xf); - if (ApicIdCoreIdSize) { -@@ -91,6 +105,8 @@ static void for_each_ap(u32 bsp_apicid, u32 core_range, process_ap_t process_ap, - - for (i = 0; i < nodes; i++) { - cores_found = get_core_num_in_bsp(i); -+ if (siblings > cores_found) -+ siblings = cores_found; - - u32 jstart, jend; - -@@ -107,9 +123,21 @@ static void for_each_ap(u32 bsp_apicid, u32 core_range, process_ap_t process_ap, - } - - for (j = jstart; j <= jend; j++) { -- ap_apicid = -- i * (nb_cfg_54 ? (siblings + 1) : 1) + -- j * (nb_cfg_54 ? 1 : 64); -+ if (dual_node) { -+ ap_apicid = 0; -+ if (nb_cfg_54) { -+ ap_apicid |= ((i >> 1) & 0x3) << 4; /* Node ID */ -+ ap_apicid |= ((i & 0x1) * (siblings + 1)) + j; /* Core ID */ -+ } else { -+ ap_apicid |= i & 0x3; /* Node ID */ -+ ap_apicid |= (((i & 0x1) * (siblings + 1)) + j) << 4; /* Core ID */ -+ } -+ } else { -+ ap_apicid = -+ i * (nb_cfg_54 ? (siblings + 1) : 1) + -+ j * (nb_cfg_54 ? 1 : 64); -+ } -+ - - #if CONFIG_ENABLE_APIC_EXT_ID && (CONFIG_APIC_ID_OFFSET > 0) - #if !CONFIG_LIFT_BSP_APIC_ID -diff --git a/src/cpu/amd/model_10xxx/model_10xxx_init.c b/src/cpu/amd/model_10xxx/model_10xxx_init.c -index 590b89d..b942c1a 100644 ---- a/src/cpu/amd/model_10xxx/model_10xxx_init.c -+++ b/src/cpu/amd/model_10xxx/model_10xxx_init.c -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -153,6 +154,7 @@ static struct cpu_device_id cpu_table[] = { - { X86_VENDOR_AMD, 0x100F63 }, /* DA-C3 */ - { X86_VENDOR_AMD, 0x100F80 }, /* HY-D0 */ - { X86_VENDOR_AMD, 0x100F81 }, /* HY-D1 */ -+ { X86_VENDOR_AMD, 0x100F91 }, /* HY-D1 */ - { X86_VENDOR_AMD, 0x100FA0 }, /* PH-E0 */ - { 0, 0 }, - }; -diff --git a/src/cpu/amd/model_10xxx/processor_name.c b/src/cpu/amd/model_10xxx/processor_name.c -index a25e3a9..12c45c9 100644 ---- a/src/cpu/amd/model_10xxx/processor_name.c -+++ b/src/cpu/amd/model_10xxx/processor_name.c -@@ -157,6 +157,24 @@ static const struct str_s String2_socket_AM2[] = { - {0, 0, 0, NULL} - }; - -+static const struct str_s String1_socket_G34[] = { -+ {0x00, 0x07, 0x00, "AMD Opteron(tm) Processor 61"}, -+ {0x00, 0x0B, 0x00, "AMD Opteron(tm) Processor 61"}, -+ {0x01, 0x07, 0x01, "Embedded AMD Opteron(tm) Processor "}, -+ {0, 0, 0, NULL} -+}; -+ -+static const struct str_s String2_socket_G34[] = { -+ {0x00, 0x07, 0x00, " HE"}, -+ {0x00, 0x07, 0x01, " SE"}, -+ {0x00, 0x0B, 0x00, " HE"}, -+ {0x00, 0x0B, 0x01, " SE"}, -+ {0x00, 0x0B, 0x0F, ""}, -+ {0x01, 0x07, 0x01, " QS"}, -+ {0x01, 0x07, 0x02, " KS"}, -+ {0, 0, 0, NULL} -+}; -+ - static const struct str_s String1_socket_C32[] = { - {0x00, 0x03, 0x00, "AMD Opteron(tm) Processor 41"}, - {0x00, 0x05, 0x00, "AMD Opteron(tm) Processor 41"}, -@@ -240,6 +258,11 @@ int init_processor_name(void) - str = String1_socket_AM2; - str2 = String2_socket_AM2; - break; -+ case 3: /* G34 */ -+ str = String1_socket_G34; -+ str2 = String2_socket_G34; -+ str2_checkNC = 0; -+ break; - case 5: /* C32 */ - str = String1_socket_C32; - str2 = String2_socket_C32; -diff --git a/src/cpu/amd/model_10xxx/ram_calc.c b/src/cpu/amd/model_10xxx/ram_calc.c -index c8637c9..46ccdbd 100644 ---- a/src/cpu/amd/model_10xxx/ram_calc.c -+++ b/src/cpu/amd/model_10xxx/ram_calc.c -@@ -26,6 +26,7 @@ - - #include "ram_calc.h" - -+#if !IS_ENABLED(CONFIG_LATE_CBMEM_INIT) - uint64_t get_uma_memory_size(uint64_t topmem) - { - uint64_t uma_size = 0; -@@ -50,3 +51,4 @@ void *cbmem_top(void) - - return (void *) topmem - get_uma_memory_size(topmem); - } -+#endif -diff --git a/src/cpu/amd/quadcore/quadcore_id.c b/src/cpu/amd/quadcore/quadcore_id.c -index cf45196..c5921de 100644 ---- a/src/cpu/amd/quadcore/quadcore_id.c -+++ b/src/cpu/amd/quadcore/quadcore_id.c -@@ -1,6 +1,7 @@ - /* - * This file is part of the coreboot project. - * -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify -@@ -37,33 +38,71 @@ u32 get_initial_apicid(void) - return ((cpuid_ebx(1) >> 24) & 0xff); - } - --//called by amd_siblings too --#define CORE_ID_BIT 2 --#define NODE_ID_BIT 6 -+/* Called by amd_siblings (ramstage) as well */ - struct node_core_id get_node_core_id(u32 nb_cfg_54) - { - struct node_core_id id; -- u32 core_id_bits; -+ uint8_t apicid; -+ uint8_t rev_gte_d = 0; -+ uint8_t dual_node = 0; -+ uint32_t f3xe8; - -- u32 ApicIdCoreIdSize = (cpuid_ecx(0x80000008)>>12 & 0xf); -- if(ApicIdCoreIdSize) { -- core_id_bits = ApicIdCoreIdSize; -- } else { -- core_id_bits = CORE_ID_BIT; //quad core -- } -+#ifdef __PRE_RAM__ -+ f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8); -+#else -+ f3xe8 = pci_read_config32(get_node_pci(0, 3), 0xe8); -+#endif -+ -+ if (cpuid_eax(0x80000001) >= 0x8) -+ /* Revision D or later */ -+ rev_gte_d = 1; - -- // get the apicid via cpuid(1) ebx[31:24] -+ if (rev_gte_d) -+ /* Check for dual node capability */ -+ if (f3xe8 & 0x20000000) -+ dual_node = 1; -+ -+ /* Get the apicid via cpuid(1) ebx[31:24] -+ * The apicid format varies based on processor revision -+ */ -+ apicid = (cpuid_ebx(1) >> 24) & 0xff; - if( nb_cfg_54) { -- // when NB_CFG[54] is set, nodeid = ebx[31:26], coreid = ebx[25:24] -- id.coreid = (cpuid_ebx(1) >> 24) & 0xff; -- id.nodeid = (id.coreid>>core_id_bits); -- id.coreid &= ((1<<core_id_bits)-1); -+ if (rev_gte_d && dual_node) { -+ id.coreid = apicid & 0xf; -+ id.nodeid = (apicid & 0x30) >> 4; -+ } else if (rev_gte_d && !dual_node) { -+ id.coreid = apicid & 0x7; -+ id.nodeid = (apicid & 0x38) >> 3; -+ } else { -+ id.coreid = apicid & 0x3; -+ id.nodeid = (apicid & 0x1c) >> 2; -+ } - } else { -- // when NB_CFG[54] is clear, nodeid = ebx[29:24], coreid = ebx[31:30] -- id.nodeid = (cpuid_ebx(1) >> 24) & 0xff; -- id.coreid = (id.nodeid>>NODE_ID_BIT); -- id.nodeid &= ((1<<NODE_ID_BIT)-1); -+ if (rev_gte_d && dual_node) { -+ id.coreid = (apicid & 0xf0) >> 4; -+ id.nodeid = apicid & 0x3; -+ } else if (rev_gte_d && !dual_node) { -+ id.coreid = (apicid & 0xe0) >> 5; -+ id.nodeid = apicid & 0x7; -+ } else { -+ id.coreid = (apicid & 0x60) >> 5; -+ id.nodeid = apicid & 0x7; -+ } - } -+ -+ if (rev_gte_d && dual_node) { -+ /* Coreboot expects each separate processor die to be on a different nodeid. -+ * Since the code above returns nodeid 0 even on internal node 1 some fixup is needed... -+ */ -+ uint8_t core_count = (((f3xe8 & 0x00008000) >> 13) | ((f3xe8 & 0x00003000) >> 12)) + 1; -+ -+ id.nodeid = id.nodeid * 2; -+ if (id.coreid >= core_count) { -+ id.nodeid += 1; -+ id.coreid = id.coreid - core_count; -+ } -+ } -+ - return id; - } - -diff --git a/src/cpu/amd/socket_G34/Kconfig b/src/cpu/amd/socket_G34/Kconfig -new file mode 100644 -index 0000000..abc9726 ---- /dev/null -+++ b/src/cpu/amd/socket_G34/Kconfig -@@ -0,0 +1,29 @@ -+config CPU_AMD_SOCKET_G34_NON_AGESA -+ bool -+ select CPU_AMD_MODEL_10XXX -+ select PCI_IO_CFG_EXT -+ select X86_AMD_FIXED_MTRRS -+ -+if CPU_AMD_SOCKET_G34_NON_AGESA -+ -+config CPU_SOCKET_TYPE -+ hex -+ default 0x15 -+ -+config EXT_RT_TBL_SUPPORT -+ bool -+ default n -+ -+config CBB -+ hex -+ default 0x0 -+ -+config CDB -+ hex -+ default 0x18 -+ -+config XIP_ROM_SIZE -+ hex -+ default 0x80000 -+ -+endif -diff --git a/src/cpu/amd/socket_G34/Makefile.inc b/src/cpu/amd/socket_G34/Makefile.inc -new file mode 100644 -index 0000000..a8e1333 ---- /dev/null -+++ b/src/cpu/amd/socket_G34/Makefile.inc -@@ -0,0 +1,14 @@ -+ramstage-y += socket_G34.c -+subdirs-y += ../model_10xxx -+subdirs-y += ../quadcore -+subdirs-y += ../mtrr -+subdirs-y += ../microcode -+subdirs-y += ../../x86/tsc -+subdirs-y += ../../x86/lapic -+subdirs-y += ../../x86/cache -+subdirs-y += ../../x86/pae -+subdirs-y += ../../x86/mtrr -+subdirs-y += ../../x86/smm -+subdirs-y += ../smm -+ -+cpu_incs-y += $(src)/cpu/amd/car/cache_as_ram.inc -diff --git a/src/cpu/amd/socket_G34/socket_G34.c b/src/cpu/amd/socket_G34/socket_G34.c -new file mode 100644 -index 0000000..90f7b8c ---- /dev/null -+++ b/src/cpu/amd/socket_G34/socket_G34.c -@@ -0,0 +1,25 @@ -+/* -+ * This file is part of the coreboot project. -+ * -+ * Copyright (C) 2010 Advanced Micro Devices, Inc. -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include <device/device.h> -+ -+struct chip_operations cpu_amd_socket_G34_ops = { -+ CHIP_NAME("socket G34") -+}; -diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c -index 6d91cbd..74cecc8 100644 ---- a/src/northbridge/amd/amdfam10/northbridge.c -+++ b/src/northbridge/amd/amdfam10/northbridge.c -@@ -187,6 +187,43 @@ static void ht_route_link(struct bus *link, scan_state mode) - } - } - -+static void amd_g34_fixup(struct bus *link, device_t dev) -+{ -+ uint32_t nodeid = amdfam10_nodeid(dev); -+ uint8_t rev_gte_d = 0; -+ uint8_t dual_node = 0; -+ uint32_t f3xe8; -+ -+ if (cpuid_eax(0x80000001) >= 0x8) -+ /* Revision D or later */ -+ rev_gte_d = 1; -+ -+ if (rev_gte_d) { -+ f3xe8 = pci_read_config32(get_node_pci(0, 3), 0xe8); -+ -+ /* Check for dual node capability */ -+ if (f3xe8 & 0x20000000) -+ dual_node = 1; -+ -+ if (dual_node) { -+ /* Each G34 processor contains a defective HT link. -+ * See the BKDG Rev 3.62 section 2.7.1.5 for details. -+ */ -+ f3xe8 = pci_read_config32(get_node_pci(nodeid, 3), 0xe8); -+ uint8_t internal_node_number = ((f3xe8 & 0xc0000000) >> 30); -+ if (internal_node_number == 0) { -+ /* Node 0 */ -+ if (link->link_num == 6) /* Link 2 Sublink 1 */ -+ printk(BIOS_DEBUG, "amdfam10_scan_chain(): node %d (internal node ID %d): skipping defective HT link\n", nodeid, internal_node_number); -+ } else { -+ /* Node 1 */ -+ if (link->link_num == 5) /* Link 1 Sublink 1 */ -+ printk(BIOS_DEBUG, "amdfam10_scan_chain(): node %d (internal node ID %d): skipping defective HT link\n", nodeid, internal_node_number); -+ } -+ } -+ } -+} -+ - static void amdfam10_scan_chain(struct bus *link) - { - unsigned int next_unitid; -@@ -277,8 +314,11 @@ static void amdfam10_scan_chains(device_t dev) - trim_ht_chain(dev); - - for (link = dev->link_list; link; link = link->next) { -- if (link->ht_link_up) -+ if (link->ht_link_up) { -+ if (IS_ENABLED(CONFIG_CPU_AMD_MODEL_10XXX)) -+ amd_g34_fixup(link, dev); - amdfam10_scan_chain(link); -+ } - } - } - -@@ -323,8 +363,7 @@ static struct resource *amdfam10_find_iopair(device_t dev, unsigned nodeid, unsi - if (result == 1) { - /* I have been allocated this one */ - break; -- } -- else if (result > 1) { -+ } else if (result > 1) { - /* I have a free register pair */ - free_reg = reg; - } -@@ -357,8 +396,7 @@ static struct resource *amdfam10_find_mempair(device_t dev, u32 nodeid, u32 link - if (result == 1) { - /* I have been allocated this one */ - break; -- } -- else if (result > 1) { -+ } else if (result > 1) { - /* I have a free register pair */ - free_reg = reg; - } -@@ -473,8 +511,7 @@ static void amdfam10_set_resource(device_t dev, struct resource *resource, - - set_io_addr_reg(dev, nodeid, link_num, reg, rbase>>8, rend>>8); - store_conf_io_addr(nodeid, link_num, reg, (resource->index >> 24), rbase>>8, rend>>8); -- } -- else if (resource->flags & IORESOURCE_MEM) { -+ } else if (resource->flags & IORESOURCE_MEM) { - set_mmio_addr_reg(nodeid, link_num, reg, (resource->index >>24), rbase>>8, rend>>8, sysconf.nodes) ;// [39:8] - store_conf_mmio_addr(nodeid, link_num, reg, (resource->index >>24), rbase>>8, rend>>8); - } -@@ -799,8 +836,7 @@ static void amdfam10_domain_set_resources(device_t dev) - } - if ((basek + sizek) <= 4*1024*1024) { - sizek = 0; -- } -- else { -+ } else { - basek = 4*1024*1024; - sizek -= (4*1024*1024 - mmio_basek); - } -@@ -977,8 +1013,7 @@ static int amdfam10_get_smbios_data17(int* count, int handle, int parent_handle, - if (dimm_size_bytes > 0x800000000) { - t->size = 0x7FFF; - t->extended_size = dimm_size_bytes; -- } -- else { -+ } else { - t->size = dimm_size_bytes / (1024*1024); - t->size &= (~0x8000); /* size specified in megabytes */ - } -@@ -1005,8 +1040,7 @@ static int amdfam10_get_smbios_data17(int* count, int handle, int parent_handle, - t->part_number = smbios_add_string(t->eos, mem_info->dct_stat[node].DimmPartNumber[slot]); - if (mem_info->dct_stat[node].DimmSerialNumber[slot] == 0) { - t->serial_number = smbios_add_string(t->eos, "None"); -- } -- else { -+ } else { - snprintf(string_buffer, sizeof (string_buffer), "%08X", mem_info->dct_stat[node].DimmSerialNumber[slot]); - t->serial_number = smbios_add_string(t->eos, string_buffer); - } -@@ -1108,8 +1142,7 @@ static void add_more_links(device_t dev, unsigned total_links) - memset(link, 0, links*sizeof(*link)); - last->next = link; - } -- } -- else { -+ } else { - link = malloc(total_links*sizeof(*link)); - memset(link, 0, total_links*sizeof(*link)); - dev->link_list = link; -@@ -1244,6 +1277,10 @@ static void cpu_bus_scan(device_t dev) - unsigned busn, devn; - struct bus *pbus; - -+ uint8_t rev_gte_d = 0; -+ uint8_t dual_node = 0; -+ uint32_t f3xe8; -+ - busn = CONFIG_CBB; - devn = CONFIG_CDB+i; - pbus = dev_mc->bus; -@@ -1268,6 +1305,7 @@ static void cpu_bus_scan(device_t dev) - } - } - -+ - /* Ok, We need to set the links for that device. - * otherwise the device under it will not be scanned - */ -@@ -1279,6 +1317,17 @@ static void cpu_bus_scan(device_t dev) - if (cdb_dev) - add_more_links(cdb_dev, 4); - -+ f3xe8 = pci_read_config32(get_node_pci(0, 3), 0xe8); -+ -+ if (cpuid_eax(0x80000001) >= 0x8) -+ /* Revision D or later */ -+ rev_gte_d = 1; -+ -+ if (rev_gte_d) -+ /* Check for dual node capability */ -+ if (f3xe8 & 0x20000000) -+ dual_node = 1; -+ - cores_found = 0; // one core - cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 3)); - int enable_node = cdb_dev && cdb_dev->enabled; -@@ -1290,6 +1339,9 @@ static void cpu_bus_scan(device_t dev) - printk(BIOS_DEBUG, " %s siblings=%d\n", dev_path(cdb_dev), cores_found); - } - -+ if (siblings > cores_found) -+ siblings = cores_found; -+ - u32 jj; - if(disable_siblings) { - jj = 0; -@@ -1299,7 +1351,20 @@ static void cpu_bus_scan(device_t dev) - } - - for (j = 0; j <=jj; j++ ) { -- u32 apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:64); // ? -+ u32 apic_id; -+ -+ if (dual_node) { -+ apic_id = 0; -+ if (nb_cfg_54) { -+ apic_id |= ((i >> 1) & 0x3) << 4; /* Node ID */ -+ apic_id |= ((i & 0x1) * (siblings + 1)) + j; /* Core ID */ -+ } else { -+ apic_id |= i & 0x3; /* Node ID */ -+ apic_id |= (((i & 0x1) * (siblings + 1)) + j) << 4; /* Core ID */ -+ } -+ } else { -+ apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:64); // ? -+ } - - #if CONFIG_ENABLE_APIC_EXT_ID && (CONFIG_APIC_ID_OFFSET>0) - if(sysconf.enabled_apic_ext_id) { -@@ -1311,7 +1376,7 @@ static void cpu_bus_scan(device_t dev) - device_t cpu = add_cpu_device(cpu_bus, apic_id, enable_node); - if (cpu) - amd_cpu_topology(cpu, i, j); -- } //j -+ } - } - } - -@@ -1356,8 +1421,7 @@ static void root_complex_enable_dev(struct device *dev) - /* Set the operations if it is a special bus type */ - if (dev->path.type == DEVICE_PATH_DOMAIN) { - dev->ops = &pci_domain_ops; -- } -- else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) { -+ } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) { - dev->ops = &cpu_bus_ops; - } - } -diff --git a/src/northbridge/amd/amdht/ht_wrapper.c b/src/northbridge/amd/amdht/ht_wrapper.c -index 36fe60b..389b1b1 100644 ---- a/src/northbridge/amd/amdht/ht_wrapper.c -+++ b/src/northbridge/amd/amdht/ht_wrapper.c -@@ -22,6 +22,8 @@ - #include <console/console.h> - #include <northbridge/amd/amdfam10/amdfam10.h> - -+#include "ht_wrapper.h" -+ - /*---------------------------------------------------------------------------- - * TYPEDEFS, DEFINITIONS AND MACROS - * -@@ -113,6 +115,20 @@ void getAmdTopolist(u8 ***p) - *p = (u8 **)amd_topo_list; - } - -+/** -+ * BOOL AMD_CB_IgnoreLink(u8 Node, u8 Link) -+ * Description: -+ * This routine is used to ignore connected yet faulty HT links, -+ * such as those present in a G34 processor package. -+ * -+ * Parameters: -+ * @param[in] node = The node on which this chain is located -+ * @param[in] link = The link on the host for this chain -+ */ -+static BOOL AMD_CB_IgnoreLink (u8 node, u8 link) -+{ -+ return 0; -+} - - /** - * void amd_ht_init(struct sys_info *sysinfo) -@@ -128,7 +144,7 @@ static void amd_ht_init(struct sys_info *sysinfo) - 0, // u8 AutoBusStart; - 32, // u8 AutoBusMax; - 6, // u8 AutoBusIncrement; -- NULL, // BOOL (*AMD_CB_IgnoreLink)(); -+ AMD_CB_IgnoreLink, // BOOL (*AMD_CB_IgnoreLink)(); - NULL, // BOOL (*AMD_CB_OverrideBusNumbers)(); - AMD_CB_ManualBUIDSwapList, // BOOL (*AMD_CB_ManualBUIDSwapList)(); - NULL, // void (*AMD_CB_DeviceCapOverride)(); -@@ -146,6 +162,93 @@ static void amd_ht_init(struct sys_info *sysinfo) - printk(BIOS_DEBUG, "Enter amd_ht_init()\n"); - amdHtInitialize(&ht_wrapper); - printk(BIOS_DEBUG, "Exit amd_ht_init()\n"); -+} - -- -+/** -+ * void amd_ht_fixup(struct sys_info *sysinfo) -+ * -+ * AMD HT fixup -+ * -+ */ -+void amd_ht_fixup(struct sys_info *sysinfo) { -+ printk(BIOS_DEBUG, "amd_ht_fixup()\n"); -+ if (IS_ENABLED(CONFIG_CPU_AMD_MODEL_10XXX)) { -+ uint8_t rev_gte_d = 0; -+ uint8_t dual_node = 0; -+ uint32_t f3xe8; -+ uint32_t family; -+ uint32_t model; -+ -+ family = model = cpuid_eax(0x80000001); -+ model = ((model & 0xf0000) >> 16) | ((model & 0xf0) >> 4); -+ -+ if (model >= 0x8) -+ /* Revision D or later */ -+ rev_gte_d = 1; -+ -+ if (rev_gte_d) { -+ f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8); -+ -+ /* Check for dual node capability */ -+ if (f3xe8 & 0x20000000) -+ dual_node = 1; -+ -+ if (dual_node) { -+ /* Each G34 processor contains a defective HT link. -+ * See the BKDG Rev 3.62 section 2.7.1.5 for details. -+ */ -+ uint8_t node; -+ uint8_t node_count = get_nodes(); -+ uint32_t dword; -+ for (node = 0; node < node_count; node++) { -+ f3xe8 = pci_read_config32(NODE_PCI(node, 3), 0xe8); -+ uint8_t internal_node_number = ((f3xe8 & 0xc0000000) >> 30); -+ printk(BIOS_DEBUG, "amd_ht_fixup(): node %d (internal node ID %d): disabling defective HT link\n", node, internal_node_number); -+ if (internal_node_number == 0) { -+ uint8_t package_link_3_connected = pci_read_config32(NODE_PCI(node, 0), 0xd8) & 0x1; -+ if (package_link_3_connected) { -+ /* Set WidthIn and WidthOut to 0 */ -+ dword = pci_read_config32(NODE_PCI(node, 0), 0xc4); -+ dword &= ~0x77000000; -+ pci_write_config32(NODE_PCI(node, 0), 0xc4, dword); -+ /* Set Ganged to 1 */ -+ dword = pci_read_config32(NODE_PCI(node, 0), 0x178); -+ dword |= 0x00000001; -+ pci_write_config32(NODE_PCI(node, 0), 0x178, dword); -+ } else { -+ /* Set ConnDly to 1 */ -+ dword = pci_read_config32(NODE_PCI(node, 0), 0x16c); -+ dword |= 0x00000100; -+ pci_write_config32(NODE_PCI(node, 0), 0x16c, dword); -+ /* Set TransOff and EndOfChain to 1 */ -+ dword = pci_read_config32(NOD