libreboot

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

commit 0622df6194dbb1b2120743c0fd1cc5e72c380128
parent 5999dba5f71f1c05040a551d2420ab8c7f3a9da4
Author: Francis Rowe <info@gluglug.org.uk>
Date:   Mon, 19 Oct 2015 00:12:53 +0100

KGPE-D16: update patch set (also update coreboot and vboot)

Also contains other fixes from coreboot, like:
* 551cff0 Derive lvds_dual_channel from EDID timings.
^ makes single/dual channel LVDS selection on GM45 automatic
* 26fc544 lenovo/t60: Enable native intel gfx init.
^ was being maintained in libreboot, now upstreamed so not needed

Framebuffer mode was disabled for the KGPE-D16, because only
text-mode works at the moment.

Diffstat:
resources/libreboot/config/depthcharge/veyron_speedy/config | 1+
resources/libreboot/config/grub/kfsn4-dre/config | 3+++
resources/libreboot/config/grub/kfsn4-dre_2mb/config | 3+++
resources/libreboot/config/grub/kgpe-d16/config | 13++++++++-----
resources/libreboot/config/grub/macbook21/config | 2++
resources/libreboot/config/grub/qemu_i440fx_piix4/config | 1+
resources/libreboot/config/grub/qemu_q35_ich9/config | 1+
resources/libreboot/config/grub/r400_4mb/config | 1+
resources/libreboot/config/grub/r400_8mb/config | 1+
resources/libreboot/config/grub/t400_4mb/config | 1+
resources/libreboot/config/grub/t400_8mb/config | 1+
resources/libreboot/config/grub/t500_4mb/config | 1+
resources/libreboot/config/grub/t500_8mb/config | 1+
resources/libreboot/config/grub/t60/config | 1+
resources/libreboot/config/grub/x200_4mb/config | 1+
resources/libreboot/config/grub/x200_8mb/config | 1+
resources/libreboot/config/grub/x60/config | 1+
resources/libreboot/patch/0001-southbridge-intel-common-spi-Add-Flash-lockdown-opti.patch | 83-------------------------------------------------------------------------------
resources/libreboot/patch/0002-mainboard-lenovo-t400-Add-initial-hybrid-graphics-su.patch | 232-------------------------------------------------------------------------------
resources/libreboot/patch/0003-NOTFORMERGE-lenovo-t400-hard-code-enable-integrated-.patch | 36------------------------------------
resources/libreboot/patch/0004-lenovo-x60-use-correct-BLC_PWM_CTL-value.patch | 31-------------------------------
resources/libreboot/patch/0005-lenovo-t60-Enable-native-intel-gfx-init.patch | 49-------------------------------------------------
resources/libreboot/patch/0006-lenovo-t60-Enable-VESA-framebuffer-mode-native-graph.patch | 31-------------------------------
resources/libreboot/patch/0007-lenovo-t60-Enable-brightness-controls-native-graphic.patch | 37-------------------------------------
resources/libreboot/patch/0008-NOTFORMERGE-ec-lenovo-h8-wlan-trackpoint-touchpad-bl.patch | 88-------------------------------------------------------------------------------
resources/libreboot/patch/0009-northbridge-gm45-raminit.c-enable-GS45-high-performa.patch | 48------------------------------------------------
resources/libreboot/patch/0010-gm45-fix-uneven-backlight-native-gfx-init.patch | 42------------------------------------------
resources/libreboot/patch/0011-lenovo-r400-Add-clone-of-Lenovo-T400.patch | 86-------------------------------------------------------------------------------
resources/libreboot/patch/0012-lenovo-t500-Add-clone-of-Lenovo-T400.patch | 67-------------------------------------------------------------------
resources/libreboot/patch/0013-ec-lenovo-h8-re-factor-handling-of-power_management_.patch | 53-----------------------------------------------------
resources/libreboot/patch/kgpe-d16/0001-drivers-i2c-w83795-Add-full-support-for-fan-control-.patch | 710+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0001-util-cbmem-Fix-failure-with-certain-cbmem-base-align.patch | 205-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0002-cpu-amd-microcode-Update-microcode-parser-to-handle-.patch | 41-----------------------------------------
resources/libreboot/patch/kgpe-d16/0002-southbridge-amd-sb700-Allow-use-of-auxiliary-SMBUS-c.patch | 187+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0003-arch-x86-boot-smbios-Add-SPD-IDs-for-Kingston-and-Co.patch | 36------------------------------------
resources/libreboot/patch/kgpe-d16/0003-drivers-i2c-w83795-Add-option-to-use-auxiliary-SMBUS.patch | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0004-arch-x86-smbios-Add-Crucial-DIMM-manufacturer-ID.patch | 27---------------------------
resources/libreboot/patch/kgpe-d16/0004-drivers-aspeed-Add-native-text-mode-VGA-support-for-.patch | 3675+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0005-southbridge-amd-sb700-Fix-boot-hang-on-ASUS-KGPE-D16.patch | 642+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0005-southbridge-amd-sr5650-Remove-unnecessary-register-c.patch | 33---------------------------------
resources/libreboot/patch/kgpe-d16/0006-drivers-i2c-w83795-Add-full-support-for-fan-control-.patch | 661-------------------------------------------------------------------------------
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-drivers-aspeed-Add-native-text-mode-VGA-support-for-.patch | 3673-------------------------------------------------------------------------------
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-sb700-Fix-boot-hang-on-ASUS-KGPE-D16.patch | 641-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0009-northbridge-amd-amdmct-mct_ddr3-Fix-curly-brace-styl.patch | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0009-southbridge-amd-sr5650-Fix-boot-failure-on-ASUS-KGPE.patch | 619-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0010-cpu-amd-Add-initial-support-for-AMD-Socket-G34-proce.patch | 788-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0010-northbridge-amd-amdfam10-Limit-maximum-RAM-clock-to-.patch | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0011-northbridge-amd-amdfam10-Fix-typo-in-comment.patch | 27+++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0011-northbridge-amd-amdmct-Fix-broken-AMD-K10-DDR3-memor.patch | 3451-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0012-device-hypertransport-Add-additional-debug-output.patch | 35+++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0012-northbridge-amd-amdmct-mct_ddr3-Fix-curly-brace-styl.patch | 93-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0013-mainboard-asus-kgpe-d16-Add-initial-support-for-the-.patch | 3221+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0013-northbridge-amd-amdfam10-Limit-maximum-RAM-clock-to-.patch | 120-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0014-mainboard-asus-kgpe-d16-Add-nvram-option-to-enable-d.patch | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0014-northbridge-amd-amdfam10-Fix-typo-in-comment.patch | 33---------------------------------
resources/libreboot/patch/kgpe-d16/0015-cpu-amd-model_10xxx-Clean-up-debugging-statements.patch | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0015-device-hypertransport-Add-additional-debug-output.patch | 33---------------------------------
resources/libreboot/patch/kgpe-d16/0016-mainboard-asus-kgpe-d16-Add-initial-support-for-the-.patch | 3218-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0016-southbridge-amd-sb700-Add-Suspend-to-RAM-S3-support.patch | 367+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0017-mainboard-asus-kgpe-d16-Add-nvram-option-to-enable-d.patch | 70----------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0017-superio-nuvoton-nct5572d-Enable-power-state-after-po.patch | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0018-cpu-amd-model_10xxx-Clean-up-debugging-statements.patch | 114-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0018-northbridge-amd-amdfam10-Add-Suspend-to-RAM-S3-Flash.patch | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0019-northbridge-amd-amdmct-mct_ddr3-Add-initial-Suspend-.patch | 1007+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0019-southbridge-amd-sb700-Add-Suspend-to-RAM-S3-support.patch | 365-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0020-cpu-amd-car-Add-initial-Suspend-to-RAM-S3-support.patch | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0020-superio-nuvoton-nct5572d-Enable-power-state-after-po.patch | 80-------------------------------------------------------------------------------
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-amdfam10-Add-Suspend-to-RAM-S3-Flash.patch | 156-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0022-include-smbios-Update-SMBIOS-memory-structures-to-ve.patch | 33+++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0022-northbridge-amd-amdmct-mct_ddr3-Add-initial-Suspend-.patch | 986-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0023-cpu-amd-car-Add-initial-Suspend-to-RAM-S3-support.patch | 54------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0023-northbridge-amd-amdfam10-Set-DIMM-voltage-based-on-S.patch | 198+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0024-mainboard-asus-kgpe-d16-Add-initial-Suspend-to-RAM-S.patch | 830-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0024-mainboard-asus-kgpe-d16-Set-DDR3-memory-voltage-base.patch | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0025-include-smbios-Update-SMBIOS-memory-structures-to-ve.patch | 31-------------------------------
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 | 151------------------------------------------------------------------------------
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-amdfam10-Set-DIMM-voltage-based-on-S.patch | 176-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0027-northbridge-amd-amdmct-mct_ddr3-Fix-failing-S3-resum.patch | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0028-src-console-Add-x86-printk-spinlock-support.patch | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0028-src-console-Add-x86-romstage-spinlock-option.patch | 98-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0029-lib-stack-Add-stack-overrun-detection.patch | 38++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0029-northbridge-amd-amdmct-mct_ddr3-Fix-S3-suspend-overr.patch | 49-------------------------------------------------
resources/libreboot/patch/kgpe-d16/0030-cpu-x86-lapic-Add-stack-overrun-detection.patch | 34++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0030-northbridge-amd-amdmct-mct_ddr3-Fix-failing-S3-resum.patch | 46----------------------------------------------
resources/libreboot/patch/kgpe-d16/0031-northbridge-amd-amdmct-Fix-S3-suspend-resume-with-la.patch | 78------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0031-southbridge-amd-sr5650-Add-AMD-Family-15h-CPU-suppor.patch | 28++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0032-cpu-amd-Move-model_10xxx-to-family_10h-family_15h.patch | 7898+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0032-src-console-Add-x86-printk-spinlock-support.patch | 126-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0033-cpu-amd-Add-initial-AMD-Family-15h-support.patch | 16206+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0033-lib-stack-Add-stack-overrun-detection.patch | 36------------------------------------
resources/libreboot/patch/kgpe-d16/0034-cpu-x86-lapic-Add-stack-overrun-detection.patch | 32--------------------------------
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-southbridge-amd-sr5650-Add-AMD-Family-15h-CPU-suppor.patch | 26--------------------------
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-Add-initial-AMD-Family-15h-support.patch | 15930-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0037-cpu-amd-car-Add-romstage-BSP-stack-overrun-detection.patch | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0037-mainboard-asus-kgpe-d16-Add-initial-Family-15h-CPU-s.patch | 563-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0038-amdmct-mct_ddr3-Disable-Fam10h-specific-MTRR-setup-o.patch | 36------------------------------------
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-Add-romstage-BSP-stack-overrun-detection.patch | 57---------------------------------------------------------
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-Increase-Family-10h-CAR-size-limit-to-12.patch | 28----------------------------
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-cpu-amd-car-Move-AP-stacks-below-the-BSP-stack-to-fr.patch | 30------------------------------
resources/libreboot/patch/kgpe-d16/0042-amd-amdmct-mct_ddr3-Improve-SPD-DIMM-detect-reliabil.patch | 49+++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0042-northbridge-amd-amdmct-Read-SPD-data-into-cache-to-d.patch | 459-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0043-amd-amdmct-mct_ddr3-Use-training-values-from-previou.patch | 781+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0043-cpu-amd-car-Initialize-entire-CAR-space-instead-of-o.patch | 32--------------------------------
resources/libreboot/patch/kgpe-d16/0044-amd-amdmct-mct_ddr3-Improve-SPD-DIMM-detect-reliabil.patch | 47-----------------------------------------------
resources/libreboot/patch/kgpe-d16/0044-northbridge-amd-amdfam10-Enable-CC6-DRAM-save-area-s.patch | 261+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0045-amd-amdmct-mct_ddr3-Use-training-values-from-previou.patch | 769-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0045-mainboard-asus-kgpe-d16-Enable-CC6.patch | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0046-cpu-amd-Add-CC6-support.patch | 1307+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0046-northbridge-amd-amdfam10-Enable-CC6-DRAM-save-area-s.patch | 259-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0047-mainboard-asus-kgpe-d16-Enable-CC6.patch | 68--------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0047-northbridge-amd-amdmct-Skip-DCT-config-write-to-Flas.patch | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0048-cpu-amd-Add-CC6-support.patch | 1302-------------------------------------------------------------------------------
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-northbridge-amd-amdmct-Skip-DCT-config-write-to-Flas.patch | 101-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0050-southbridge-amd-sb700-Add-AHCI-support.patch | 658-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0050-southbridge-amd-sb700-Disable-broken-SATA-MSI-functi.patch | 41+++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0051-mainboard-asus-kgpe-d16-Properly-initialize-SB700-SA.patch | 47-----------------------------------------------
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-Disable-broken-SATA-MSI-functi.patch | 39---------------------------------------
resources/libreboot/patch/kgpe-d16/0053-northbridge-amd-amdmct-Verify-MCT-NVRAM-options-befo.patch | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0053-southbridge-amd-sb700-Indicate-iSATA-eSATA-port-type.patch | 92-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0054-northbridge-amd-amdfam10-Add-ability-to-set-maximum-.patch | 90-------------------------------------------------------------------------------
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-northbridge-amd-amdmct-Verify-MCT-NVRAM-options-befo.patch | 143-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0056-northbridge-amd-amdmct-Fix-hang-on-boot-due-to-inval.patch | 37+++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0056-src-northbridge-amd-amdmct-Add-option-to-override-ba.patch | 106-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0057-mainboard-asus-kgpe-d16-Add-missing-IRQ-routing-for-.patch | 207-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0057-southbridge-amd-sr5650-Fix-GPP3a-link-training-in-hi.patch | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0058-northbridge-amd-amdmct-Fix-hang-on-boot-due-to-inval.patch | 35-----------------------------------
resources/libreboot/patch/kgpe-d16/0058-southbridge-amd-sr5650-Add-optional-delay-after-link.patch | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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-Fix-GPP3a-link-training-in-hi.patch | 83-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0060-southbridge-amd-sb700-Add-option-to-disable-SATA-ALP.patch | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0060-southbridge-amd-sr5650-Add-optional-delay-after-link.patch | 68--------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0061-mainboard-asus-kgpe-d16-Properly-configure-SR5690-so.patch | 30------------------------------
resources/libreboot/patch/kgpe-d16/0061-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/0062-southbridge-amd-sb700-Add-option-to-disable-SATA-ALP.patch | 84-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0063-mainboard-asus-kgpe-d16-Set-SP5100-subtype.patch | 24------------------------
resources/libreboot/patch/kgpe-d16/0063-northbridge-amd-amdmct-Clear-memory-before-enabling-.patch | 185+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0064-northbridge-amd-amdmct-Fix-crash-on-startup-due-to-N.patch | 31-------------------------------
resources/libreboot/patch/kgpe-d16/0064-southbridge-amd-sb700-Do-drive-detection-even-in-AHC.patch | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0065-northbridge-amd-amdmct-Clear-memory-before-enabling-.patch | 183-------------------------------------------------------------------------------
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-Do-drive-detection-even-in-AHC.patch | 140-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0066-southbridge-amd-sb700-Recover-if-AHCI-disk-detection.patch | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0067-southbridge-amd-sb700-Fix-SATA-port-4-5-drive-detect.patch | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0067-src-southbridge-amd-sb700-Reset-SATA-controller-in-A.patch | 93-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0068-southbridge-amd-sb700-Fix-random-persistent-SATA-AHC.patch | 165+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0068-southbridge-amd-sb700-Recover-if-AHCI-disk-detection.patch | 161-------------------------------------------------------------------------------
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-SATA-port-4-5-drive-detect.patch | 95-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0070-cpu-amd-Fix-AMD-Family-15h-ECC-initialization-reliab.patch | 474+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0070-southbridge-amd-sb700-Fix-random-persistent-SATA-AHC.patch | 163-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0071-northbridge-amd-amdfam10-Properly-indicate-node-and-.patch | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0071-northbridge-amd-amdmct-mct_ddr3-Fix-lockups-and-wast.patch | 423-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0072-amd-amdmct-mct_ddr3-Add-Family-15h-RDIMM-timing-and-.patch | 508+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0072-cpu-amd-Fix-AMD-Family-15h-ECC-initialization-reliab.patch | 479-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0073-northbridge-amd-amdfam10-Properly-indicate-node-and-.patch | 75---------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0073-northbridge-amd-amdmct-mct_ddr3-Attempt-to-recover-f.patch | 256+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0074-amd-amdmct-mct_ddr3-Add-Family-15h-RDIMM-timing-and-.patch | 513-------------------------------------------------------------------------------
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-Attempt-to-recover-f.patch | 254-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0076-northbridge-amd-amdmct-mct_ddr3-Fix-null-pointer-acc.patch | 240+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0076-northbridge-amd-amdmct-mct_ddr3-Work-around-strange-.patch | 40----------------------------------------
resources/libreboot/patch/kgpe-d16/0077-northbridge-amd-amdmct-mct_ddr3-Add-additional-debug.patch | 118-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0077-northbridge-amd-amdmct-mct_ddr3-Add-missing-Family-1.patch | 268+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0078-northbridge-amd-amdmct-mct_ddr3-Fix-null-pointer-acc.patch | 238-------------------------------------------------------------------------------
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-Add-missing-Family-1.patch | 266-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0079-northbridge-amd-amdmct-mct_ddr3-Properly-indicate-cl.patch | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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-Set-SkewMemClk-when-.patch | 112-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0081-northbridge-amd-amdmct-mct_ddr3-Properly-indicate-cl.patch | 56--------------------------------------------------------
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-northbridge-amd-amdmct-mct_ddr3-Fix-Family-10h-boot-.patch | 98-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0083-northbridge-amd-amdmct-mct_ddr3-Fix-RDIMM-errors-due.patch | 330+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0083-src-southbridge-amd-sr5650-Always-configure-lane-dir.patch | 48------------------------------------------------
resources/libreboot/patch/kgpe-d16/0084-amd-amdmct-mct_ddr3-Partially-fix-up-registered-DIMM.patch | 960+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0084-cpu-amd-model_10xxx-Fix-BSP-stack-corruption-on-32-c.patch | 26--------------------------
resources/libreboot/patch/kgpe-d16/0085-northbridge-amd-amdmct-Fix-Family-15h-detection.patch | 49+++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0085-northbridge-amd-amdmct-mct_ddr3-Fix-RDIMM-errors-due.patch | 411-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0086-amd-amdmct-mct_ddr3-Partially-fix-up-registered-DIMM.patch | 957-------------------------------------------------------------------------------
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-Fix-Family-15h-detection.patch | 47-----------------------------------------------
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 | 1893-------------------------------------------------------------------------------
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-model_10xxx-Fix-Family-15h-multiple-package-.patch | 948-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0090-northbridge-amd-amdfam10-Add-probe-filter-support.patch | 212-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0090-northbridge-amd-amdmct-mct_ddr3-Move-K10D-configurat.patch | 338+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0091-cpu-amd-model_10xxx-Bring-initial-HT-register-config.patch | 246-------------------------------------------------------------------------------
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 | 334-------------------------------------------------------------------------------
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 | 26--------------------------
resources/libreboot/patch/kgpe-d16/0094-cpu-amd-model_10xxx-Set-northbridge-throttle-values.patch | 136-------------------------------------------------------------------------------
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-model_10xxx-Fix-incorrect-revision-detection.patch | 62--------------------------------------------------------------
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 | 559-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0097-amd-model_10xxx-Fix-poor-performance-on-Family-15h-C.patch | 122-------------------------------------------------------------------------------
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 | 1087-------------------------------------------------------------------------------
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 | 28----------------------------
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 | 70----------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0101-cpu-amd-model_10xxx-Configure-NB-register-2.patch | 31-------------------------------
resources/libreboot/patch/kgpe-d16/0101-northbridge-amd-amdmct-mct_ddr3-Force-retraining-on-.patch | 36++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0102-cpu-amd-model_10xxx-Set-up-link-XCS-token-counts-on-.patch | 342-------------------------------------------------------------------------------
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 | 34----------------------------------
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 | 26--------------------------
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 | 121-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0106-amd-amdmct-mct_ddr3-Set-prefetch-double-stride-to-im.patch | 25-------------------------
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-SRI-to-XCS-Toke.patch | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0107-cpu-amd-model_10xxx-Set-up-Family-15h-Link-Base-Chan.patch | 190-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0108-amd-amdfam10-Control-Family-15h-cache-partitioning-a.patch | 177+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/kgpe-d16/0108-cpu-amd-model_10xxx-Set-up-cache-controls-on-Family-.patch | 41-----------------------------------------
resources/libreboot/patch/kgpe-d16/0109-cpu-amd-model_10xxx-Set-up-SRI-to-XCS-Token-Count-re.patch | 64----------------------------------------------------------------
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 | 175-------------------------------------------------------------------------------
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 | 270-------------------------------------------------------------------------------
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 | 119-------------------------------------------------------------------------------
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 | 709-------------------------------------------------------------------------------
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 | 55-------------------------------------------------------
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 | 53-----------------------------------------------------
resources/libreboot/patch/kgpe-d16/0116-northbridge-amd-amdfam10-Fix-gart-setup-not-working-.patch | 94-------------------------------------------------------------------------------
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 | 127-------------------------------------------------------------------------------
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 | 28----------------------------
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 | 83-------------------------------------------------------------------------------
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 | 34----------------------------------
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 | 45---------------------------------------------
resources/libreboot/patch/kgpe-d16/0122-northbridge-amd-amdmct-mct_ddr3-Add-cc6-setup-inform.patch | 56--------------------------------------------------------
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 | 38--------------------------------------
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 | 113-------------------------------------------------------------------------------
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 | 34----------------------------------
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 | 35-----------------------------------
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 | 63---------------------------------------------------------------
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 | 156-------------------------------------------------------------------------------
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 | 172-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0131-mainboard-asus-kgpe-d16-Enable-CBFS-spinlocks.patch | 66------------------------------------------------------------------
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 | 151------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0133-mainboard-asus-kgpe-d16-Limit-HT-speed-to-2.6GHz.patch | 38--------------------------------------
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-model_10xxx-Apply-missing-Family-15h-errata-.patch | 68--------------------------------------------------------------------
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 | 229-------------------------------------------------------------------------------
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 | 25-------------------------
resources/libreboot/patch/kgpe-d16/0137-northbridge-amd-amdfam10-Fix-incorrect-channel-buffe.patch | 40----------------------------------------
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-model_10xxx-Force-iolink-detect-to-either-1-.patch | 35-----------------------------------
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 | 142-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0140-cpu-amd-model_10xxx-Fix-link-type-detection-and-XCS-.patch | 156-------------------------------------------------------------------------------
resources/libreboot/patch/kgpe-d16/0141-cpu-amd-model_10xxx-Enable-DFE-on-Family-15h-HT3-lin.patch | 44--------------------------------------------
resources/libreboot/patch/misc/0001-mainboard-lenovo-t400-Add-initial-hybrid-graphics-su.patch | 232+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/misc/0002-NOTFORMERGE-lenovo-t400-hard-code-enable-integrated-.patch | 36++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/misc/0003-lenovo-x60-use-correct-BLC_PWM_CTL-value.patch | 31+++++++++++++++++++++++++++++++
resources/libreboot/patch/misc/0004-lenovo-t60-Enable-brightness-controls-native-graphic.patch | 36++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/misc/0005-NOTFORMERGE-ec-lenovo-h8-wlan-trackpoint-touchpad-bl.patch | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/misc/0006-northbridge-gm45-raminit.c-enable-GS45-high-performa.patch | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/misc/0007-lenovo-r400-Add-clone-of-Lenovo-T400.patch | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/misc/0008-lenovo-t500-Add-clone-of-Lenovo-T400.patch | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/misc/0009-chromeos-Allow-disabling-vboot-firmware-verification.patch | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
resources/libreboot/patch/tmpfix/0001-NOTFORMERGE-don-t-add-CPU-microcode-on-fam10h-to-fam.patch | 41+++++++++++++++++++++++++++++++++++++++++
resources/scripts/helpers/build/roms/withgrub_helper | 7+++++++
resources/scripts/helpers/download/coreboot | 95+++++++++++++++++++------------------------------------------------------------
resources/utilities/coreboot-libre/nonblobs | 8+++++---
323 files changed, 64418 insertions(+), 55205 deletions(-)

diff --git a/resources/libreboot/config/depthcharge/veyron_speedy/config b/resources/libreboot/config/depthcharge/veyron_speedy/config @@ -356,6 +356,7 @@ CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT=y CONFIG_NATIVE_VGA_INIT_USE_EDID=y # CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set # CONFIG_PCI is not set # CONFIG_PXE_ROM is not set diff --git a/resources/libreboot/config/grub/kfsn4-dre/config b/resources/libreboot/config/grub/kfsn4-dre/config @@ -263,6 +263,7 @@ CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y # CONFIG_CPU_MICROCODE_CBFS_GENERATE is not set # CONFIG_CPU_MICROCODE_CBFS_EXTERNAL is not set CONFIG_CPU_MICROCODE_CBFS_NONE=y +CONFIG_CPU_MICROCODE_MULTIPLE_FILES=y # # Northbridge @@ -276,6 +277,7 @@ CONFIG_NORTHBRIDGE_AMD_AMDFAM10=y CONFIG_DIMM_DDR2=y # CONFIG_DIMM_DDR3 is not set CONFIG_DIMM_REGISTERED=y +# CONFIG_DIMM_VOLTAGE_SET_SUPPORT is not set # CONFIG_SVI_HIGH_FREQ is not set # @@ -384,6 +386,7 @@ CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT=y diff --git a/resources/libreboot/config/grub/kfsn4-dre_2mb/config b/resources/libreboot/config/grub/kfsn4-dre_2mb/config @@ -263,6 +263,7 @@ CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y # CONFIG_CPU_MICROCODE_CBFS_GENERATE is not set # CONFIG_CPU_MICROCODE_CBFS_EXTERNAL is not set CONFIG_CPU_MICROCODE_CBFS_NONE=y +CONFIG_CPU_MICROCODE_MULTIPLE_FILES=y # # Northbridge @@ -276,6 +277,7 @@ CONFIG_NORTHBRIDGE_AMD_AMDFAM10=y CONFIG_DIMM_DDR2=y # CONFIG_DIMM_DDR3 is not set CONFIG_DIMM_REGISTERED=y +# CONFIG_DIMM_VOLTAGE_SET_SUPPORT is not set # CONFIG_SVI_HIGH_FREQ is not set # @@ -384,6 +386,7 @@ CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT=y diff --git a/resources/libreboot/config/grub/kgpe-d16/config b/resources/libreboot/config/grub/kgpe-d16/config @@ -162,7 +162,7 @@ CONFIG_RAMTOP=0x400000 CONFIG_USBDEBUG_HCD_INDEX=0 CONFIG_BOOT_MEDIA_SPI_BUS=0 CONFIG_TTYS0_LCS=3 -CONFIG_CBFS_SIZE=0x800000 +CONFIG_CBFS_SIZE=0x200000 CONFIG_CACHE_ROM_SIZE_OVERRIDE=0 CONFIG_POST_DEVICE=y CONFIG_CPU_ADDR_BITS=48 @@ -176,13 +176,13 @@ CONFIG_BOARD_ROMSIZE_KB_2048=y # CONFIG_COREBOOT_ROMSIZE_KB_256 is not set # CONFIG_COREBOOT_ROMSIZE_KB_512 is not set # CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_2048 is not set +CONFIG_COREBOOT_ROMSIZE_KB_2048=y # CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set -CONFIG_COREBOOT_ROMSIZE_KB_8192=y +# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set # CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set # CONFIG_COREBOOT_ROMSIZE_KB_16384 is not set -CONFIG_COREBOOT_ROMSIZE_KB=8192 -CONFIG_ROM_SIZE=0x800000 +CONFIG_COREBOOT_ROMSIZE_KB=2048 +CONFIG_ROM_SIZE=0x200000 # CONFIG_SYSTEM_TYPE_LAPTOP is not set # @@ -262,6 +262,7 @@ CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y # CONFIG_CPU_MICROCODE_CBFS_GENERATE is not set # CONFIG_CPU_MICROCODE_CBFS_EXTERNAL is not set CONFIG_CPU_MICROCODE_CBFS_NONE=y +CONFIG_CPU_MICROCODE_MULTIPLE_FILES=y # # Northbridge @@ -275,6 +276,7 @@ CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY=y # CONFIG_DIMM_DDR2 is not set CONFIG_DIMM_DDR3=y CONFIG_DIMM_REGISTERED=y +CONFIG_DIMM_VOLTAGE_SET_SUPPORT=y # CONFIG_SVI_HIGH_FREQ is not set # @@ -385,6 +387,7 @@ CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_VGA_ROM_RUN is not set # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +CONFIG_SMBUS_HAS_AUX=y # CONFIG_SPD_CACHE is not set CONFIG_PCI=y CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT=y diff --git a/resources/libreboot/config/grub/macbook21/config b/resources/libreboot/config/grub/macbook21/config @@ -120,6 +120,7 @@ CONFIG_DCACHE_RAM_BASE=0xffdf8000 CONFIG_DCACHE_RAM_SIZE=0x8000 # CONFIG_BOARD_APPLE_MACBOOK11 is not set CONFIG_BOARD_APPLE_MACBOOK21=y +# CONFIG_BOARD_APPLE_MACBOOKAIR4_2 is not set CONFIG_MMCONF_BASE_ADDRESS=0xf0000000 CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="Apple Inc." CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT=y @@ -323,6 +324,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/config/grub/qemu_i440fx_piix4/config b/resources/libreboot/config/grub/qemu_i440fx_piix4/config @@ -303,6 +303,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/config/grub/qemu_q35_ich9/config b/resources/libreboot/config/grub/qemu_q35_ich9/config @@ -305,6 +305,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/config/grub/r400_4mb/config b/resources/libreboot/config/grub/r400_4mb/config @@ -326,6 +326,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/config/grub/r400_8mb/config b/resources/libreboot/config/grub/r400_8mb/config @@ -326,6 +326,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/config/grub/t400_4mb/config b/resources/libreboot/config/grub/t400_4mb/config @@ -326,6 +326,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/config/grub/t400_8mb/config b/resources/libreboot/config/grub/t400_8mb/config @@ -326,6 +326,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/config/grub/t500_4mb/config b/resources/libreboot/config/grub/t500_4mb/config @@ -326,6 +326,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/config/grub/t500_8mb/config b/resources/libreboot/config/grub/t500_8mb/config @@ -326,6 +326,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/config/grub/t60/config b/resources/libreboot/config/grub/t60/config @@ -339,6 +339,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/config/grub/x200_4mb/config b/resources/libreboot/config/grub/x200_4mb/config @@ -323,6 +323,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/config/grub/x200_8mb/config b/resources/libreboot/config/grub/x200_8mb/config @@ -323,6 +323,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/config/grub/x60/config b/resources/libreboot/config/grub/x60/config @@ -340,6 +340,7 @@ CONFIG_NATIVE_VGA_INIT_USE_EDID=y CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y # CONFIG_ON_DEVICE_ROM_RUN is not set # CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX is not set # CONFIG_SPD_CACHE is not set CONFIG_PCI=y # CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set diff --git a/resources/libreboot/patch/0001-southbridge-intel-common-spi-Add-Flash-lockdown-opti.patch b/resources/libreboot/patch/0001-southbridge-intel-common-spi-Add-Flash-lockdown-opti.patch @@ -1,83 +0,0 @@ -From 60b17a1eee72342ff226761caea2501960d44a30 Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <tpearson@raptorengineeringinc.com> -Date: Tue, 7 Apr 2015 13:45:06 -0500 -Subject: [PATCH 01/13] southbridge/intel/common/spi: Add Flash lockdown option - -Under certain circumstances it is desirable to prevent -software from altering the contents of the Flash device. - -This Expert-mode option allows the hardware write protect -to be set on bootup. - -Change-Id: I92d3c60a69f1688579d954d0476e30a6892cf4d5 -Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> ---- - src/southbridge/intel/common/Kconfig | 9 +++++++++ - src/southbridge/intel/common/spi.c | 20 ++++++++++++++------ - 2 files changed, 23 insertions(+), 6 deletions(-) - -diff --git a/src/southbridge/intel/common/Kconfig b/src/southbridge/intel/common/Kconfig -index 949310b..52ada30 100644 ---- a/src/southbridge/intel/common/Kconfig -+++ b/src/southbridge/intel/common/Kconfig -@@ -1,2 +1,11 @@ - config SOUTHBRIDGE_INTEL_COMMON - def_bool n -+ -+config LOCK_DOWN_BIOS -+ bool "Lock down the Flash" -+ default n -+ depends on EXPERT -+ help -+ Lock down the Flash chip to prevent further modification by software. -+ WARNING: Altering the contents of the Flash chip further WILL require -+ a hardware programmer AND physical access to the Flash device! -\ No newline at end of file -diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c -index 1d3ebf6..04f05ed 100644 ---- a/src/southbridge/intel/common/spi.c -+++ b/src/southbridge/intel/common/spi.c -@@ -2,6 +2,7 @@ - * Copyright (c) 2011 The Chromium OS Authors. - * Copyright (C) 2009, 2010 Carl-Daniel Hailfinger - * Copyright (C) 2011 Stefan Tauner -+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * See file CREDITS for list of people who contributed to this - * project. -@@ -353,11 +354,19 @@ void spi_init(void) - - ich_set_bbar(0); - -- /* Disable the BIOS write protect so write commands are allowed. */ -- pci_read_config_byte(dev, 0xdc, &bios_cntl); -- /* Deassert SMM BIOS Write Protect Disable. */ -- bios_cntl &= ~(1 << 5); -- pci_write_config_byte(dev, 0xdc, bios_cntl | 0x1); -+ if (IS_ENABLED(CONFIG_LOCK_DOWN_BIOS)) { -+ /* Engage lockdown */ -+ hsfs = readw_(&ich9_spi->hsfs); -+ hsfs = hsfs | HSFS_FLOCKDN; -+ writew_(hsfs, &ich9_spi->hsfs); -+ } -+ else { -+ /* Disable the BIOS write protect so write commands are allowed. */ -+ pci_read_config_byte(dev, 0xdc, &bios_cntl); -+ /* Deassert SMM BIOS Write Protect Disable. */ -+ bios_cntl &= ~(1 << 5); -+ pci_write_config_byte(dev, 0xdc, bios_cntl | 0x1); -+ } - } - #ifndef __SMM__ - static void spi_init_cb(void *unused) -@@ -927,7 +936,6 @@ static int ich_hwseq_write(struct spi_flash *flash, - return 0; - } - -- - static struct spi_flash *spi_flash_hwseq(struct spi_slave *spi) - { - struct spi_flash *flash = NULL; --- -1.9.1 - diff --git a/resources/libreboot/patch/0002-mainboard-lenovo-t400-Add-initial-hybrid-graphics-su.patch b/resources/libreboot/patch/0002-mainboard-lenovo-t400-Add-initial-hybrid-graphics-su.patch @@ -1,232 +0,0 @@ -From 26cfb399e15e9e2afa311bcd7774926a07c545c1 Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <tpearson@raptorengineeringinc.com> -Date: Sun, 5 Apr 2015 18:10:09 -0500 -Subject: [PATCH 02/13] mainboard/lenovo/t400: Add initial hybrid graphics - support - -TEST: Booted T400 with Intel/ATI hybrid graphics in integrated -mode with native Intel graphics init and verified integrated -panel framebuffer functionality in SeaBIOS and Linux. - -Change-Id: I37e72c5dad0d7ab3915cc3d439ae9a4a9b3787e3 -Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> ---- - src/mainboard/lenovo/t400/cmos.default | 1 + - src/mainboard/lenovo/t400/cmos.layout | 8 +- - src/mainboard/lenovo/t400/romstage.c | 143 +++++++++++++++++++++++++++++++++ - 3 files changed, 151 insertions(+), 1 deletion(-) - -diff --git a/src/mainboard/lenovo/t400/cmos.default b/src/mainboard/lenovo/t400/cmos.default -index 67b8920..06eec57 100644 ---- a/src/mainboard/lenovo/t400/cmos.default -+++ b/src/mainboard/lenovo/t400/cmos.default -@@ -14,3 +14,4 @@ sticky_fn=Disable - power_management_beeps=Enable - low_battery_beep=Enable - sata_mode=AHCI -+hybrid_graphics_mode=Integrated Only -\ No newline at end of file -diff --git a/src/mainboard/lenovo/t400/cmos.layout b/src/mainboard/lenovo/t400/cmos.layout -index 2dc91bf..44f5d04 100644 ---- a/src/mainboard/lenovo/t400/cmos.layout -+++ b/src/mainboard/lenovo/t400/cmos.layout -@@ -85,7 +85,10 @@ entries - # coreboot config options: northbridge - 941 3 e 11 gfx_uma_size - --#944 2 r 0 unused -+# coreboot config options: graphics -+944 2 e 12 hybrid_graphics_mode -+ -+#946 2 r 0 unused - - # coreboot config options: check sums - 984 16 h 0 check_sum -@@ -137,6 +140,9 @@ enumerations - 11 3 128M - 11 5 96M - 11 6 160M -+12 0 Integrated Only -+12 1 Discrete Only -+12 2 Switchable - - # ----------------------------------------------------------------- - checksums -diff --git a/src/mainboard/lenovo/t400/romstage.c b/src/mainboard/lenovo/t400/romstage.c -index a739d18..c62df60 100644 ---- a/src/mainboard/lenovo/t400/romstage.c -+++ b/src/mainboard/lenovo/t400/romstage.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) 2012 secunet Security Networks AG - * - * This program is free software; you can redistribute it and/or -@@ -37,6 +38,118 @@ - #define LPC_DEV PCI_DEV(0, 0x1f, 0) - #define MCH_DEV PCI_DEV(0, 0, 0) - -+#define HYBRID_GRAPHICS_INTEGRATED_ONLY 0 -+#define HYBRID_GRAPHICS_DISCRETE_ONLY 1 -+#define HYBRID_GRAPHICS_SWITCHABLE 2 -+ -+#define HYBRID_GRAPHICS_GP_LVL_BITS 0x004a0000 -+#define HYBRID_GRAPHICS_GP_LVL2_BITS 0x00020000 -+ -+#define HYBRID_GRAPHICS_DETECT_GP_BITS 0x00000010 -+ -+#define HYBRID_GRAPHICS_INT_CLAIM_VGA 0x2 -+#define HYBRID_GRAPHICS_SEC_VGA_EN 0x2 -+ -+static void hybrid_graphics_configure_switchable_graphics(bool enable) -+{ -+ uint32_t tmp; -+ -+ if (enable) { -+ /* Disable integrated graphics legacy VGA cycles */ -+ tmp = pci_read_config16(MCH_DEV, D0F0_GGC); -+ pci_write_config16(MCH_DEV, D0F0_GGC, tmp | HYBRID_GRAPHICS_INT_CLAIM_VGA); -+ -+ /* Enable secondary VGA controller */ -+ tmp = pci_read_config16(MCH_DEV, D0F0_DEVEN); -+ pci_write_config16(MCH_DEV, D0F0_DEVEN, tmp | HYBRID_GRAPHICS_SEC_VGA_EN); -+ } -+ else { -+ /* Enable integrated graphics legacy VGA cycles */ -+ tmp = pci_read_config16(MCH_DEV, D0F0_GGC); -+ pci_write_config16(MCH_DEV, D0F0_GGC, tmp & ~HYBRID_GRAPHICS_INT_CLAIM_VGA); -+ -+ /* Disable secondary VGA controller */ -+ tmp = pci_read_config16(MCH_DEV, D0F0_DEVEN); -+ pci_write_config16(MCH_DEV, D0F0_DEVEN, tmp & ~HYBRID_GRAPHICS_SEC_VGA_EN); -+ } -+} -+ -+static void hybrid_graphics_set_up_gpio(void) -+{ -+ uint32_t tmp; -+ -+ /* Enable hybrid graphics GPIO lines */ -+ tmp = inl(DEFAULT_GPIOBASE + GP_IO_USE_SEL); -+ tmp = tmp | HYBRID_GRAPHICS_GP_LVL_BITS; -+ outl(tmp, DEFAULT_GPIOBASE + GP_IO_USE_SEL); -+ -+ tmp = inl(DEFAULT_GPIOBASE + GP_IO_USE_SEL2); -+ tmp = tmp | HYBRID_GRAPHICS_GP_LVL2_BITS; -+ outl(tmp, DEFAULT_GPIOBASE + GP_IO_USE_SEL2); -+ -+ /* Set hybrid graphics control GPIO lines to output */ -+ tmp = inl(DEFAULT_GPIOBASE + GP_IO_SEL); -+ tmp = tmp & ~HYBRID_GRAPHICS_GP_LVL_BITS; -+ outl(tmp, DEFAULT_GPIOBASE + GP_IO_SEL); -+ -+ tmp = inl(DEFAULT_GPIOBASE + GP_IO_SEL2); -+ tmp = tmp & ~HYBRID_GRAPHICS_GP_LVL2_BITS; -+ outl(tmp, DEFAULT_GPIOBASE + GP_IO_SEL2); -+ -+ /* Set hybrid graphics detect GPIO lines to input */ -+ tmp = inl(DEFAULT_GPIOBASE + GP_IO_SEL); -+ tmp = tmp | HYBRID_GRAPHICS_DETECT_GP_BITS; -+ outl(tmp, DEFAULT_GPIOBASE + GP_IO_SEL); -+} -+ -+static bool hybrid_graphics_installed(void) -+{ -+ if (inl(DEFAULT_GPIOBASE + GP_LVL) & HYBRID_GRAPHICS_DETECT_GP_BITS) -+ return false; -+ else -+ return true; -+} -+ -+static void hybrid_graphics_switch_to_integrated_graphics(void) -+{ -+ uint32_t tmp; -+ -+ /* Disable switchable graphics */ -+ hybrid_graphics_configure_switchable_graphics(false); -+ -+ /* Configure muxes */ -+ tmp = inl(DEFAULT_GPIOBASE + GP_LVL); -+ tmp = tmp & ~HYBRID_GRAPHICS_GP_LVL_BITS; -+ outl(tmp, DEFAULT_GPIOBASE + GP_LVL); -+ -+ tmp = inl(DEFAULT_GPIOBASE + GP_LVL2); -+ tmp = tmp & ~HYBRID_GRAPHICS_GP_LVL2_BITS; -+ outl(tmp, DEFAULT_GPIOBASE + GP_LVL2); -+} -+ -+static void hybrid_graphics_switch_to_discrete_graphics(void) -+{ -+ uint32_t tmp; -+ -+ /* Disable switchable graphics */ -+ hybrid_graphics_configure_switchable_graphics(false); -+ -+ /* Configure muxes */ -+ tmp = inl(DEFAULT_GPIOBASE + GP_LVL); -+ tmp = tmp | HYBRID_GRAPHICS_GP_LVL_BITS; -+ outl(tmp, DEFAULT_GPIOBASE + GP_LVL); -+ -+ tmp = inl(DEFAULT_GPIOBASE + GP_LVL2); -+ tmp = tmp | HYBRID_GRAPHICS_GP_LVL2_BITS; -+ outl(tmp, DEFAULT_GPIOBASE + GP_LVL2); -+} -+ -+static void hybrid_graphics_switch_to_dual_graphics(void) -+{ -+ /* Enable switchable graphics */ -+ hybrid_graphics_configure_switchable_graphics(true); -+} -+ - static void default_southbridge_gpio_setup(void) - { - outl(0x197e23fe, DEFAULT_GPIOBASE + GP_IO_USE_SEL); -@@ -98,6 +211,31 @@ void main(unsigned long bist) - - default_southbridge_gpio_setup(); - -+ uint8_t hybrid_graphics_mode = HYBRID_GRAPHICS_INTEGRATED_ONLY; -+ get_option(&hybrid_graphics_mode, "hybrid_graphics_mode"); -+ -+ /* Set up hybrid graphics */ -+ hybrid_graphics_set_up_gpio(); -+ if (hybrid_graphics_installed()) { -+ /* Select appropriate hybrid graphics device */ -+ printk(BIOS_DEBUG, "Hybrid graphics available, setting mode %d\n", hybrid_graphics_mode); -+ if (hybrid_graphics_mode == HYBRID_GRAPHICS_INTEGRATED_ONLY) -+ hybrid_graphics_switch_to_integrated_graphics(); -+ else if (hybrid_graphics_mode == HYBRID_GRAPHICS_DISCRETE_ONLY) -+ hybrid_graphics_switch_to_discrete_graphics(); -+ else if (hybrid_graphics_mode == HYBRID_GRAPHICS_SWITCHABLE) -+ hybrid_graphics_switch_to_integrated_graphics(); -+ /* Switchable graphics are fully enabled after raminit */ -+ /* FIXME -+ * Enabling switchable graphics prevents bootup! -+ * Debug and fix appropriately... -+ */ -+ } -+ else { -+ printk(BIOS_DEBUG, "Hybrid graphics not installed\n"); -+ hybrid_graphics_switch_to_integrated_graphics(); -+ } -+ - /* ASPM related setting, set early by original BIOS. */ - DMIBAR16(0x204) &= ~(3 << 10); - -@@ -177,6 +315,11 @@ void main(unsigned long bist) - outl(inl(DEFAULT_GPIOBASE + 0x38) & ~0x400, DEFAULT_GPIOBASE + 0x38); - - cbmem_initted = !cbmem_recovery(s3resume); -+ -+ if (hybrid_graphics_installed()) -+ if (hybrid_graphics_mode == HYBRID_GRAPHICS_SWITCHABLE) -+ hybrid_graphics_switch_to_dual_graphics(); -+ - #if CONFIG_HAVE_ACPI_RESUME - /* If there is no high memory area, we didn't boot before, so - * this is not a resume. In that case we just create the cbmem toc. --- -1.9.1 - diff --git a/resources/libreboot/patch/0003-NOTFORMERGE-lenovo-t400-hard-code-enable-integrated-.patch b/resources/libreboot/patch/0003-NOTFORMERGE-lenovo-t400-hard-code-enable-integrated-.patch @@ -1,36 +0,0 @@ -From dad7e30fcaf87af2d51232896b2cabc59bba4a88 Mon Sep 17 00:00:00 2001 -From: Francis Rowe <info@gluglug.org.uk> -Date: Mon, 15 Jun 2015 03:44:15 +0100 -Subject: [PATCH 03/13] NOTFORMERGE: lenovo/t400: hard-code enable - integrated-only video - -Written with libreboot in mind. Libreboot uses native graphics -initialization only, so we want to ensure that these systems -only use the integrated (Intel) GPU for which native init exists. - -Native graphics initialization does not yet exist for the ATI GPUs -on these laptops... - -Change-Id: I2c056a8fb498972f87c4ec1122b239fdc9a4c666 -Signed-off-by: Francis Rowe <info@gluglug.org.uk> ---- - src/mainboard/lenovo/t400/romstage.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/mainboard/lenovo/t400/romstage.c b/src/mainboard/lenovo/t400/romstage.c -index c62df60..daf6fa8 100644 ---- a/src/mainboard/lenovo/t400/romstage.c -+++ b/src/mainboard/lenovo/t400/romstage.c -@@ -212,7 +212,8 @@ void main(unsigned long bist) - default_southbridge_gpio_setup(); - - uint8_t hybrid_graphics_mode = HYBRID_GRAPHICS_INTEGRATED_ONLY; -- get_option(&hybrid_graphics_mode, "hybrid_graphics_mode"); -+ /* Not for merge! Hard-code enable integrated-only by commenting this line: */ -+ /* get_option(&hybrid_graphics_mode, "hybrid_graphics_mode"); */ - - /* Set up hybrid graphics */ - hybrid_graphics_set_up_gpio(); --- -1.9.1 - diff --git a/resources/libreboot/patch/0004-lenovo-x60-use-correct-BLC_PWM_CTL-value.patch b/resources/libreboot/patch/0004-lenovo-x60-use-correct-BLC_PWM_CTL-value.patch @@ -1,31 +0,0 @@ -From c18e0e855487069dd2c836d9a48b1e63fb7d47d3 Mon Sep 17 00:00:00 2001 -From: Francis Rowe <info@gluglug.org.uk> -Date: Mon, 22 Jun 2015 17:37:06 +0100 -Subject: [PATCH 04/13] lenovo/x60: use correct BLC_PWM_CTL value - -Bit 16 in BLC_PWM_CTL enables brightness controls, but the -current value is generic. Use the proper value, obtained -by reading BLC_PWM_CTL while running the VBIOS. - -Change-Id: Ib273359e1c285b405a9bb26fc217c2f7e255b99f -Signed-off-by: Francis Rowe <info@gluglug.org.uk> ---- - src/mainboard/lenovo/x60/devicetree.cb | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/mainboard/lenovo/x60/devicetree.cb b/src/mainboard/lenovo/x60/devicetree.cb -index b20dde5..9c3c524 100644 ---- a/src/mainboard/lenovo/x60/devicetree.cb -+++ b/src/mainboard/lenovo/x60/devicetree.cb -@@ -27,7 +27,7 @@ chip northbridge/intel/i945 - register "gpu_hotplug" = "0x00000220" - register "gpu_lvds_use_spread_spectrum_clock" = "1" - register "gpu_lvds_is_dual_channel" = "0" -- register "gpu_backlight" = "0x1290128" -+ register "gpu_backlight" = "0x879F879E" - - device cpu_cluster 0 on - chip cpu/intel/socket_mFCPGA478 --- -1.9.1 - diff --git a/resources/libreboot/patch/0005-lenovo-t60-Enable-native-intel-gfx-init.patch b/resources/libreboot/patch/0005-lenovo-t60-Enable-native-intel-gfx-init.patch @@ -1,49 +0,0 @@ -From 4c337212bd77ab456f018d05b69bd8d0ef5d7761 Mon Sep 17 00:00:00 2001 -From: Vladimir Serbinenko <phcoder@gmail.com> -Date: Tue, 4 Mar 2014 18:08:26 +0100 -Subject: [PATCH 05/13] lenovo/t60: Enable native intel gfx init. - -Tested on T60 with intel graphics. - -Change-Id: Id74d0a1315749052e7313135242e6b64862aa5e1 -Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com> ---- - src/mainboard/lenovo/t60/Kconfig | 3 +++ - src/mainboard/lenovo/t60/devicetree.cb | 5 +++++ - 2 files changed, 8 insertions(+) - -diff --git a/src/mainboard/lenovo/t60/Kconfig b/src/mainboard/lenovo/t60/Kconfig -index 0cf19a1..2254185 100644 ---- a/src/mainboard/lenovo/t60/Kconfig -+++ b/src/mainboard/lenovo/t60/Kconfig -@@ -20,8 +20,11 @@ config BOARD_SPECIFIC_OPTIONS # dummy - select CHANNEL_XOR_RANDOMIZATION - select HAVE_ACPI_TABLES - select HAVE_ACPI_RESUME -+ select MAINBOARD_HAS_NATIVE_VGA_INIT - select H8_DOCK_EARLY_INIT - select HAVE_CMOS_DEFAULT -+ select INTEL_EDID -+ - config MAINBOARD_DIR - string - default lenovo/t60 -diff --git a/src/mainboard/lenovo/t60/devicetree.cb b/src/mainboard/lenovo/t60/devicetree.cb -index 719fa9a..fdced26 100644 ---- a/src/mainboard/lenovo/t60/devicetree.cb -+++ b/src/mainboard/lenovo/t60/devicetree.cb -@@ -24,6 +24,11 @@ chip northbridge/intel/i945 - register "gfx.ndid" = "3" - register "gfx.did" = "{ 0x80000100, 0x80000240, 0x80000410, 0x80000410, 0x00000005 }" - -+ register "gpu_hotplug" = "0x00000220" -+ register "gpu_lvds_use_spread_spectrum_clock" = "1" -+ register "gpu_lvds_is_dual_channel" = "1" -+ register "gpu_backlight" = "0x1280128" -+ - device cpu_cluster 0 on - chip cpu/intel/socket_mFCPGA478 - device lapic 0 on end --- -1.9.1 - diff --git a/resources/libreboot/patch/0006-lenovo-t60-Enable-VESA-framebuffer-mode-native-graph.patch b/resources/libreboot/patch/0006-lenovo-t60-Enable-VESA-framebuffer-mode-native-graph.patch @@ -1,31 +0,0 @@ -From 1623f381e7c5b8329d035d666d5498a75e81d635 Mon Sep 17 00:00:00 2001 -From: Francis Rowe <info@gluglug.org.uk> -Date: Mon, 15 Jun 2015 19:56:29 +0100 -Subject: [PATCH 06/13] lenovo/t60: Enable VESA framebuffer mode (native - graphics) - -At present, no option exists for "Keep VESA framebuffer", which -means that text-mode will be used. Add the appropriate Kconfig -option. - -Change-Id: Ie8c91fc04c8d6a8ff41977be0b730e86e34546af -Signed-off-by: Francis Rowe <info@gluglug.org.uk> ---- - src/mainboard/lenovo/t60/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/mainboard/lenovo/t60/Kconfig b/src/mainboard/lenovo/t60/Kconfig -index 2254185..52eeda3 100644 ---- a/src/mainboard/lenovo/t60/Kconfig -+++ b/src/mainboard/lenovo/t60/Kconfig -@@ -21,6 +21,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy - select HAVE_ACPI_TABLES - select HAVE_ACPI_RESUME - select MAINBOARD_HAS_NATIVE_VGA_INIT -+ select MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG - select H8_DOCK_EARLY_INIT - select HAVE_CMOS_DEFAULT - select INTEL_EDID --- -1.9.1 - diff --git a/resources/libreboot/patch/0007-lenovo-t60-Enable-brightness-controls-native-graphic.patch b/resources/libreboot/patch/0007-lenovo-t60-Enable-brightness-controls-native-graphic.patch @@ -1,37 +0,0 @@ -From 172b2fad7663f3c52cd8830cf064234b0ae53575 Mon Sep 17 00:00:00 2001 -From: Francis Rowe <info@gluglug.org.uk> -Date: Mon, 15 Jun 2015 19:59:46 +0100 -Subject: [PATCH 07/13] lenovo/t60: Enable brightness controls (native - graphics) - -This makes the Fn Home/End keys work for controlling the -brightness of the display. Value obtained by reading -BLC_PWM_CTL when running the VBIOS (option ROM). - -On i945 legacy brightness control is enabled by a single -bit in BLC_PWM_CTL. It's bit 16 or bit 0 (the other one -reverses polarity). Set the bit to enable brightness -controls. - -Change-Id: I22e261f2ce28ec81cd208a73e6311ec67146eb72 -Signed-off-by: Francis Rowe <info@gluglug.org.uk> ---- - src/mainboard/lenovo/t60/devicetree.cb | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/mainboard/lenovo/t60/devicetree.cb b/src/mainboard/lenovo/t60/devicetree.cb -index fdced26..5f90a73 100644 ---- a/src/mainboard/lenovo/t60/devicetree.cb -+++ b/src/mainboard/lenovo/t60/devicetree.cb -@@ -27,7 +27,7 @@ chip northbridge/intel/i945 - register "gpu_hotplug" = "0x00000220" - register "gpu_lvds_use_spread_spectrum_clock" = "1" - register "gpu_lvds_is_dual_channel" = "1" -- register "gpu_backlight" = "0x1280128" -+ register "gpu_backlight" = "0x58BF58BE" - - device cpu_cluster 0 on - chip cpu/intel/socket_mFCPGA478 --- -1.9.1 - diff --git a/resources/libreboot/patch/0008-NOTFORMERGE-ec-lenovo-h8-wlan-trackpoint-touchpad-bl.patch b/resources/libreboot/patch/0008-NOTFORMERGE-ec-lenovo-h8-wlan-trackpoint-touchpad-bl.patch @@ -1,88 +0,0 @@ -From 49c5977adafea4b0953e1fc7e9e830353273b76e Mon Sep 17 00:00:00 2001 -From: Francis Rowe <info@gluglug.org.uk> -Date: Mon, 13 Oct 2014 00:14:53 +0100 -Subject: [PATCH 08/13] NOTFORMERGE: ec/lenovo/h8: - wlan/trackpoint/touchpad/bluetooth/wwan - -Permanently enable them. - -Change-Id: Ic76ab9ab9c865f30312378e18af58bece6c3260a -Signed-off-by: Francis Rowe <info@gluglug.org.uk> ---- - src/ec/lenovo/h8/h8.c | 21 +++++++++++---------- - src/ec/lenovo/pmh7/pmh7.c | 11 ++++------- - 2 files changed, 15 insertions(+), 17 deletions(-) - -diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c -index 2cafc88..a6cb6b6 100644 ---- a/src/ec/lenovo/h8/h8.c -+++ b/src/ec/lenovo/h8/h8.c -@@ -255,9 +255,11 @@ static void h8_enable(struct device *dev) - - ec_write(H8_FAN_CONTROL, H8_FAN_CONTROL_AUTO); - -- if (get_option(&val, "wlan") != CB_SUCCESS) -- val = 1; -- h8_wlan_enable(val); -+ // Permanently enable wifi -+ // Intel wifi could be a security risk because it uses firmware. Wlan chip has DMA -+ // and could leak data over a side-channel. Using another manufacturer is recommended. -+ // see http://libreboot.org/docs/index.html#recommended_wifi -+ h8_wlan_enable(1); - - h8_trackpoint_enable(1); - h8_usb_power_enable(1); -@@ -265,14 +267,13 @@ static void h8_enable(struct device *dev) - if (get_option(&val, "volume") == CB_SUCCESS) - ec_write(H8_VOLUME_CONTROL, val); - -- if (get_option(&val, "bluetooth") != CB_SUCCESS) -- val = 1; -- h8_bluetooth_enable(val); -- -- if (get_option(&val, "wwan") != CB_SUCCESS) -- val = 1; -+ // Permanently enable bluetooth. -+ // NOTE: bluetooth is a potential security risk. Physical removal of the bluetooth module is recommended. -+ h8_bluetooth_enable(1); - -- h8_wwan_enable(val); -+ // Permanently enable wwan. -+ // NOTE: wwan is a security risk (remove access plus DMA). Physical removal of both the wwan and sim card is recommended. -+ h8_wwan_enable(1); - - if (conf->has_uwb) { - if (get_option(&val, "uwb") != CB_SUCCESS) -diff --git a/src/ec/lenovo/pmh7/pmh7.c b/src/ec/lenovo/pmh7/pmh7.c -index cc6e891..38aef16 100644 ---- a/src/ec/lenovo/pmh7/pmh7.c -+++ b/src/ec/lenovo/pmh7/pmh7.c -@@ -106,7 +106,6 @@ static void enable_dev(struct device *dev) - { - struct ec_lenovo_pmh7_config *conf = dev->chip_info; - struct resource *resource; -- u8 val; - - resource = new_resource(dev, EC_LENOVO_PMH7_INDEX); - resource->flags = IORESOURCE_IO | IORESOURCE_FIXED; -@@ -118,13 +117,11 @@ static void enable_dev(struct device *dev) - pmh7_backlight_enable(conf->backlight_enable); - pmh7_dock_event_enable(conf->dock_event_enable); - -- if (get_option(&val, "touchpad") != CB_SUCCESS) -- val = 1; -- pmh7_touchpad_enable(val); -+ // Permanently enable touchpad -+ pmh7_touchpad_enable(1); - -- if (get_option(&val, "trackpoint") != CB_SUCCESS) -- val = 1; -- pmh7_trackpoint_enable(val); -+ // Permanently enable trackpoint -+ pmh7_trackpoint_enable(1); - } - - struct chip_operations ec_lenovo_pmh7_ops = { --- -1.9.1 - diff --git a/resources/libreboot/patch/0009-northbridge-gm45-raminit.c-enable-GS45-high-performa.patch b/resources/libreboot/patch/0009-northbridge-gm45-raminit.c-enable-GS45-high-performa.patch @@ -1,48 +0,0 @@ -From a59b0e652911627cb00b748bb71f07ce0fa90534 Mon Sep 17 00:00:00 2001 -From: Steve Shenton <sgsit@libreboot.org> -Date: Fri, 12 Dec 2014 12:42:01 +0000 -Subject: [PATCH] northbridge/gm45/raminit.c: enable GS45 high-performance mode - -The datasheets for GS45 describe a high- and low-performance mode -for different CPUs. Coreboot currently disables GS45 altogether, -but forcing coreboot to treat high-performance GS45 as GM45 makes -the X200S and X200 Tablet boot if it has the right CPU type. - -Hardcode-enable GS45 high-performance mode in coreboot, passing it -off as GM45. This is known to work with all CPUs except the SU -(low performance) models. - -Change-Id: I57032bb6e1ebdaf4e2aa09548e73d253afb9b078 -Signed-off-by: Steve Shenton <sgsit@libreboot.org> -Signed-off-by: Francis Rowe <info@gluglug.org.uk> ---- - src/northbridge/intel/gm45/raminit.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/northbridge/intel/gm45/raminit.c b/src/northbridge/intel/gm45/raminit.c -index 9c4fecd..9f5aa06 100644 ---- a/src/northbridge/intel/gm45/raminit.c -+++ b/src/northbridge/intel/gm45/raminit.c -@@ -108,8 +108,8 @@ void get_gmch_info(sysinfo_t *sysinfo) - printk(BIOS_SPEW, "GMCH: GS40\n"); - break; - case GMCH_GS45: -- printk(BIOS_SPEW, "GMCH: GS45, using low power mode by default\n"); -- sysinfo->gs45_low_power_mode = 1; -+ printk(BIOS_SPEW, "GMCH: GS45, using high performance mode by default\n"); -+ sysinfo->gs45_low_power_mode = 0; - break; - case GMCH_PM45: - printk(BIOS_SPEW, "GMCH: PM45\n"); -@@ -1692,7 +1692,7 @@ void raminit(sysinfo_t *const sysinfo, const int s3resume) - { - const dimminfo_t *const dimms = sysinfo->dimms; - const timings_t *const timings = &sysinfo->selected_timings; -- const int sff = sysinfo->gfx_type == GMCH_GS45; -+ const int sff = (sysinfo->gfx_type == GMCH_GS45) && (sysinfo->gs45_low_power_mode == 1); - - int ch; - u8 reg8; --- -1.9.1 - diff --git a/resources/libreboot/patch/0010-gm45-fix-uneven-backlight-native-gfx-init.patch b/resources/libreboot/patch/0010-gm45-fix-uneven-backlight-native-gfx-init.patch @@ -1,42 +0,0 @@ -From bea0f09575914be6f2d35dbc53220bce6ac03aac Mon Sep 17 00:00:00 2001 -From: Francis Rowe <info@gluglug.org.uk> -Date: Mon, 29 Dec 2014 21:02:48 +0000 -Subject: [PATCH 10/13] gm45: fix uneven backlight (native gfx init) - -When setting brightness levels low, backlight becomes uneven. -This patch fixes that. - -Tested on X200. - -Change-Id: Ie71bf696ba4431ab25076f92dd5fdc9fdc167b09 -Signed-off-by: Francis Rowe <info@gluglug.org.uk> ---- - src/northbridge/intel/gm45/acpi/igd.asl | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/northbridge/intel/gm45/acpi/igd.asl b/src/northbridge/intel/gm45/acpi/igd.asl -index 696cc2b..39fefb2 100644 ---- a/src/northbridge/intel/gm45/acpi/igd.asl -+++ b/src/northbridge/intel/gm45/acpi/igd.asl -@@ -62,15 +62,15 @@ Device (GFX0) - - Method (XBCM, 1, NotSerialized) - { -- Store (ShiftLeft (Arg0, 4), BCLV) -+ Store (ShiftLeft (Arg0, 8), BCLV) - Store (0x80000000, CR1) -- Store (0x0610, BCLM) -+ Store (ShiftLeft (0x61, 8), BCLM) - } - - Method (XBQC, 0, NotSerialized) - { - Store (BCLV, Local0) -- ShiftRight (Local0, 4, Local0) -+ ShiftRight (Local0, 8, Local0) - Return (Local0) - } - #include <drivers/intel/gma/igd.asl> --- -1.9.1 - diff --git a/resources/libreboot/patch/0011-lenovo-r400-Add-clone-of-Lenovo-T400.patch b/resources/libreboot/patch/0011-lenovo-r400-Add-clone-of-Lenovo-T400.patch @@ -1,86 +0,0 @@ -From 93c1510605981a38c6d616a9c77a7675d7c66b59 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Micha=C5=82=20Mas=C5=82owski?= <mtjm@mtjm.eu> -Date: Tue, 3 Feb 2015 23:26:05 +0100 -Subject: [PATCH 11/13] lenovo/r400: Add clone of Lenovo T400 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The existing code for the Lenovo T400 works without changes on the -Lenovo R400. Same HDA verbs are provided by Lenovo BIOS on both -laptops. - -Change-Id: I1dadddd7250ab80a4c40c2435865d72e3e5d99c9 -Signed-off-by: Michał Masłowski <mtjm@mtjm.eu> -Signed-off-by: Francis Rowe <info@gluglug.org.uk> ---- - src/mainboard/lenovo/r400/Kconfig | 7 +++++++ - src/mainboard/lenovo/r400/Kconfig.name | 2 ++ - src/mainboard/lenovo/r400/board_info.txt | 6 ++++++ - src/mainboard/lenovo/t400/Kconfig | 6 +++++- - 4 files changed, 20 insertions(+), 1 deletion(-) - create mode 100644 src/mainboard/lenovo/r400/Kconfig - create mode 100644 src/mainboard/lenovo/r400/Kconfig.name - create mode 100644 src/mainboard/lenovo/r400/board_info.txt - -diff --git a/src/mainboard/lenovo/r400/Kconfig b/src/mainboard/lenovo/r400/Kconfig -new file mode 100644 -index 0000000..0966bf1 ---- /dev/null -+++ b/src/mainboard/lenovo/r400/Kconfig -@@ -0,0 +1,7 @@ -+if BOARD_LENOVO_R400 -+ -+config MAINBOARD_PART_NUMBER -+ string -+ default "ThinkPad R400" -+ -+endif -diff --git a/src/mainboard/lenovo/r400/Kconfig.name b/src/mainboard/lenovo/r400/Kconfig.name -new file mode 100644 -index 0000000..15a99b1 ---- /dev/null -+++ b/src/mainboard/lenovo/r400/Kconfig.name -@@ -0,0 +1,2 @@ -+config BOARD_LENOVO_R400 -+ bool "ThinkPad R400" -diff --git a/src/mainboard/lenovo/r400/board_info.txt b/src/mainboard/lenovo/r400/board_info.txt -new file mode 100644 -index 0000000..007ec6c ---- /dev/null -+++ b/src/mainboard/lenovo/r400/board_info.txt -@@ -0,0 +1,6 @@ -+Category: laptop -+ROM package: SOIC-16 or SOIC-8 -+ROM protocol: SPI -+ROM socketed: n -+Flashrom support: n -+Clone of: lenovo/t400 -diff --git a/src/mainboard/lenovo/t400/Kconfig b/src/mainboard/lenovo/t400/Kconfig -index e410f20..467cd63 100644 ---- a/src/mainboard/lenovo/t400/Kconfig -+++ b/src/mainboard/lenovo/t400/Kconfig -@@ -1,4 +1,4 @@ --if BOARD_LENOVO_T400 -+if BOARD_LENOVO_T400 || BOARD_LENOVO_R400 - - config BOARD_SPECIFIC_OPTIONS # dummy - def_bool y -@@ -27,10 +27,14 @@ config MAINBOARD_DIR - string - default lenovo/t400 - -+if BOARD_LENOVO_T400 -+ - config MAINBOARD_PART_NUMBER - string - default "ThinkPad T400" - -+endif -+ - config MMCONF_BASE_ADDRESS - hex - default 0xf0000000 --- -1.9.1 - diff --git a/resources/libreboot/patch/0012-lenovo-t500-Add-clone-of-Lenovo-T400.patch b/resources/libreboot/patch/0012-lenovo-t500-Add-clone-of-Lenovo-T400.patch @@ -1,67 +0,0 @@ -From 330670470afd0b12fd58f8cf734cb3c85c3a20f5 Mon Sep 17 00:00:00 2001 -From: Francis Rowe <info@gluglug.org.uk> -Date: Sun, 14 Jun 2015 15:40:00 +0100 -Subject: [PATCH 12/13] lenovo/t500: Add clone of Lenovo T400 - -The existing code for the Lenovo T400 works without changes on the -Lenovo T500. Same HDA verbs are provided by Lenovo BIOS on both -laptops. - -Change-Id: I300408a8a0ed00476aee6061925befc2822fb505 -Signed-off-by: Francis Rowe <info@gluglug.org.uk> ---- - src/mainboard/lenovo/t400/Kconfig | 2 +- - src/mainboard/lenovo/t500/Kconfig | 7 +++++++ - src/mainboard/lenovo/t500/Kconfig.name | 2 ++ - src/mainboard/lenovo/t500/board_info.txt | 6 ++++++ - 4 files changed, 16 insertions(+), 1 deletion(-) - create mode 100644 src/mainboard/lenovo/t500/Kconfig - create mode 100644 src/mainboard/lenovo/t500/Kconfig.name - create mode 100644 src/mainboard/lenovo/t500/board_info.txt - -diff --git a/src/mainboard/lenovo/t400/Kconfig b/src/mainboard/lenovo/t400/Kconfig -index 467cd63..0eac311 100644 ---- a/src/mainboard/lenovo/t400/Kconfig -+++ b/src/mainboard/lenovo/t400/Kconfig -@@ -1,4 +1,4 @@ --if BOARD_LENOVO_T400 || BOARD_LENOVO_R400 -+if BOARD_LENOVO_T400 || BOARD_LENOVO_T500 || BOARD_LENOVO_R400 - - config BOARD_SPECIFIC_OPTIONS # dummy - def_bool y -diff --git a/src/mainboard/lenovo/t500/Kconfig b/src/mainboard/lenovo/t500/Kconfig -new file mode 100644 -index 0000000..e1e8420 ---- /dev/null -+++ b/src/mainboard/lenovo/t500/Kconfig -@@ -0,0 +1,7 @@ -+if BOARD_LENOVO_T500 -+ -+config MAINBOARD_PART_NUMBER -+ string -+ default "ThinkPad T500" -+ -+endif -diff --git a/src/mainboard/lenovo/t500/Kconfig.name b/src/mainboard/lenovo/t500/Kconfig.name -new file mode 100644 -index 0000000..89c6087 ---- /dev/null -+++ b/src/mainboard/lenovo/t500/Kconfig.name -@@ -0,0 +1,2 @@ -+config BOARD_LENOVO_T500 -+ bool "ThinkPad T500" -diff --git a/src/mainboard/lenovo/t500/board_info.txt b/src/mainboard/lenovo/t500/board_info.txt -new file mode 100644 -index 0000000..007ec6c ---- /dev/null -+++ b/src/mainboard/lenovo/t500/board_info.txt -@@ -0,0 +1,6 @@ -+Category: laptop -+ROM package: SOIC-16 or SOIC-8 -+ROM protocol: SPI -+ROM socketed: n -+Flashrom support: n -+Clone of: lenovo/t400 --- -1.9.1 - diff --git a/resources/libreboot/patch/0013-ec-lenovo-h8-re-factor-handling-of-power_management_.patch b/resources/libreboot/patch/0013-ec-lenovo-h8-re-factor-handling-of-power_management_.patch @@ -1,53 +0,0 @@ -From fc3e9f93b5b08abe1a684550d2ddda998657882b Mon Sep 17 00:00:00 2001 -From: Francis Rowe <info@gluglug.org.uk> -Date: Fri, 12 Jun 2015 23:10:52 +0100 -Subject: [PATCH 13/13] ec/lenovo/h8: re-factor handling of - power_management_beeps - -The current code duplicates the same check unnecessarily, -and has no handling of when the option power_management_beeps -is not set. - -Change-Id: I189c5ce382e1a270d24b9b6e897358268b9a141d -Signed-off-by: Francis Rowe <info@gluglug.org.uk> ---- - src/ec/lenovo/h8/h8.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c -index a6cb6b6..6493ec2 100644 ---- a/src/ec/lenovo/h8/h8.c -+++ b/src/ec/lenovo/h8/h8.c -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright (C) 2011 Sven Schnelle <svens@stackframe.org> -+ * Copyright (C) 2015 Francis Rowe <info@gluglug.org.uk> - * - * 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 -@@ -212,14 +213,14 @@ static void h8_enable(struct device *dev) - beepmask0 = conf->beepmask0; - beepmask1 = conf->beepmask1; - -- if (conf->has_power_management_beeps -- && get_option(&val, "power_management_beeps") == CB_SUCCESS -- && val == 0) { -- beepmask0 = 0x00; -- beepmask1 = 0x00; -- } -- - if (conf->has_power_management_beeps) { -+ if (get_option(&val, "power_management_beeps") != CB_SUCCESS) -+ val = 1; -+ if (!val) { -+ beepmask0 = 0x00; -+ beepmask1 = 0x00; -+ } -+ - if (get_option(&val, "low_battery_beep") != CB_SUCCESS) - val = 1; - if (val) --- -1.9.1 - 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 @@ -0,0 +1,710 @@ +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/0001-util-cbmem-Fix-failure-with-certain-cbmem-base-align.patch b/resources/libreboot/patch/kgpe-d16/0001-util-cbmem-Fix-failure-with-certain-cbmem-base-align.patch @@ -1,205 +0,0 @@ -From 4e0a69562a189e9abe06979a993f50e3f0b2069b Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <kb9vqf@pearsoncomputing.net> -Date: Sat, 5 Sep 2015 18:07:17 -0500 -Subject: [PATCH 001/146] util/cbmem: Fix failure with certain cbmem base - alignments - ---- - util/cbmem/cbmem.c | 61 ++++++++++++++++++++++++++++++++-------------------- - 1 file changed, 38 insertions(+), 23 deletions(-) - -diff --git a/util/cbmem/cbmem.c b/util/cbmem/cbmem.c -index 74cb52d..69ffbaf 100644 ---- a/util/cbmem/cbmem.c -+++ b/util/cbmem/cbmem.c -@@ -2,6 +2,7 @@ - * This file is part of the coreboot project. - * - * Copyright 2012 Google 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 -@@ -103,8 +104,7 @@ static void unmap_memory(void) - if (size_to_mib(mapped_size) == 0) { - debug("Unmapping %zuMB of virtual memory at %p.\n", - size_to_mib(mapped_size), mapped_virtual); -- } -- else { -+ } else { - debug("Unmapping %zuMB of virtual memory at %p.\n", - size_to_mib(mapped_size), mapped_virtual); - } -@@ -113,7 +113,7 @@ static void unmap_memory(void) - mapped_size = 0; - } - --static void *map_memory_size(u64 physical, size_t size) -+static void *map_memory_size(u64 physical, size_t size, uint8_t abort_on_failure) - { - void *v; - off_t p; -@@ -131,8 +131,7 @@ static void *map_memory_size(u64 physical, size_t size) - if (size_to_mib(size) == 0) { - debug("Mapping %zuB of physical memory at 0x%jx (requested 0x%jx).\n", - size, (intmax_t)p, (intmax_t)physical); -- } -- else { -+ } else { - debug("Mapping %zuMB of physical memory at 0x%jx (requested 0x%jx).\n", - size_to_mib(size), (intmax_t)p, (intmax_t)physical); - } -@@ -153,9 +152,13 @@ static void *map_memory_size(u64 physical, size_t size) - } - - if (v == MAP_FAILED) { -- fprintf(stderr, "Failed to mmap /dev/mem: %s\n", -- strerror(errno)); -- exit(1); -+ if (abort_on_failure) { -+ fprintf(stderr, "Failed to mmap /dev/mem: %s\n", -+ strerror(errno)); -+ exit(1); -+ } else { -+ return 0; -+ } - } - - /* Remember what we actually mapped ... */ -@@ -173,7 +176,7 @@ static void *map_memory_size(u64 physical, size_t size) - - static void *map_memory(u64 physical) - { -- return map_memory_size(physical, MAP_BYTES); -+ return map_memory_size(physical, MAP_BYTES, 1); - } - - /* -@@ -210,14 +213,16 @@ static struct lb_cbmem_ref parse_cbmem_ref(struct lb_cbmem_ref *cbmem_ref) - return ret; - } - --static int parse_cbtable(u64 address, size_t table_size) -+static int parse_cbtable(u64 address, size_t table_size, uint8_t abort_on_failure) - { -- int i, found = 0; -+ int i, found, ret = 0; - void *buf; - - debug("Looking for coreboot table at %" PRIx64 " %zd bytes.\n", - address, table_size); -- buf = map_memory_size(address, table_size); -+ buf = map_memory_size(address, table_size, abort_on_failure); -+ if (!buf) -+ return -2; - - /* look at every 16 bytes within 4K of the base */ - -@@ -283,7 +288,17 @@ static int parse_cbtable(u64 address, size_t table_size) - *(struct lb_forward *) lbr_p; - debug(" Found forwarding entry.\n"); - unmap_memory(); -- return parse_cbtable(lbf_p.forward, table_size); -+ ret = parse_cbtable(lbf_p.forward, table_size, 0); -+ if (ret == -2) { -+ /* try again with a smaller memory mapping request */ -+ ret = parse_cbtable(lbf_p.forward, table_size / 2, 1); -+ if (ret == -2) -+ exit(1); -+ else -+ return ret; -+ } else { -+ return ret; -+ } - } - default: - break; -@@ -544,7 +559,7 @@ static void dump_timestamps(int mach_readable) - } - - size = sizeof(*tst_p); -- tst_p = map_memory_size((unsigned long)timestamps.cbmem_addr, size); -+ tst_p = map_memory_size((unsigned long)timestamps.cbmem_addr, size, 1); - - timestamp_set_tick_freq(tst_p->tick_freq_mhz); - -@@ -553,7 +568,7 @@ static void dump_timestamps(int mach_readable) - size += tst_p->num_entries * sizeof(tst_p->entries[0]); - - unmap_memory(); -- tst_p = map_memory_size((unsigned long)timestamps.cbmem_addr, size); -+ tst_p = map_memory_size((unsigned long)timestamps.cbmem_addr, size, 1); - - /* Report the base time within the table. */ - prev_stamp = 0; -@@ -604,7 +619,7 @@ static void dump_console(void) - } - - console_p = map_memory_size((unsigned long)console.cbmem_addr, -- 2 * sizeof(uint32_t)); -+ 2 * sizeof(uint32_t), 1); - /* The in-memory format of the console area is: - * u32 size - * u32 cursor -@@ -626,7 +641,7 @@ static void dump_console(void) - } - - console_p = map_memory_size((unsigned long)console.cbmem_addr, -- size + sizeof(size) + sizeof(cursor)); -+ size + sizeof(size) + sizeof(cursor), 1); - memcpy(console_c, console_p + 8, size); - console_c[size] = 0; - console_c[cursor] = 0; -@@ -647,7 +662,7 @@ static void hexdump(unsigned long memory, int length) - uint8_t *m; - int all_zero = 0; - -- m = map_memory_size((intptr_t)memory, length); -+ m = map_memory_size((intptr_t)memory, length, 1); - - if (length > MAP_BYTES) { - printf("Truncating hex dump from %d to %d bytes\n\n", -@@ -803,7 +818,7 @@ static void dump_cbmem_toc(void) - - start = unpack_lb64(cbmem.start); - -- cbmem_area = map_memory_size(start, unpack_lb64(cbmem.size)); -+ cbmem_area = map_memory_size(start, unpack_lb64(cbmem.size), 1); - entries = (struct cbmem_entry *)cbmem_area; - - if (entries[0].magic == CBMEM_MAGIC) { -@@ -814,12 +829,12 @@ static void dump_cbmem_toc(void) - rootptr -= sizeof(struct cbmem_root_pointer); - unmap_memory(); - struct cbmem_root_pointer *r = -- map_memory_size(rootptr, sizeof(*r)); -+ map_memory_size(rootptr, sizeof(*r), 1); - if (r->magic == CBMEM_POINTER_MAGIC) { - struct cbmem_root *root; - uint64_t rootaddr = rootptr + r->root_offset; - unmap_memory(); -- root = map_memory_size(rootaddr, ROOT_MIN_SIZE); -+ root = map_memory_size(rootaddr, ROOT_MIN_SIZE, 1); - dump_dynamic_cbmem_toc(root); - } else - fprintf(stderr, "No valid coreboot CBMEM root pointer found.\n"); -@@ -1205,14 +1220,14 @@ int main(int argc, char** argv) - dtbuffer++; - } - -- parse_cbtable(baseaddr, cb_table_size); -+ parse_cbtable(baseaddr, cb_table_size, 1); - #else - int j; - static const int possible_base_addresses[] = { 0, 0xf0000 }; - - /* Find and parse coreboot table */ - for (j = 0; j < ARRAY_SIZE(possible_base_addresses); j++) { -- if (parse_cbtable(possible_base_addresses[j], MAP_BYTES)) -+ if (parse_cbtable(possible_base_addresses[j], MAP_BYTES, 1)) - break; - } - #endif --- -1.7.9.5 - diff --git a/resources/libreboot/patch/kgpe-d16/0002-cpu-amd-microcode-Update-microcode-parser-to-handle-.patch b/resources/libreboot/patch/kgpe-d16/0002-cpu-amd-microcode-Update-microcode-parser-to-handle-.patch @@ -1,41 +0,0 @@ -From f65e4abec63a8ec3bfb5a784cecb7405c463c038 Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <kb9vqf@pearsoncomputing.net> -Date: Tue, 11 Aug 2015 19:14:34 -0500 -Subject: [PATCH 002/146] cpu/amd/microcode: Update microcode parser to handle - expanded blob files - ---- - src/cpu/amd/microcode/microcode.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/cpu/amd/microcode/microcode.c b/src/cpu/amd/microcode/microcode.c -index 45e4bf0..ce5b08f 100644 ---- a/src/cpu/amd/microcode/microcode.c -+++ b/src/cpu/amd/microcode/microcode.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 -@@ -83,13 +84,13 @@ static void amd_update_microcode(const void *ucode, size_t ucode_len, - const uint8_t *c = ucode; - const uint8_t *ucode_end = (uint8_t*)ucode + ucode_len; - -- while (c <= (ucode_end - 2048)) { -+ while (c <= (ucode_end - 4096)) { - m = (struct microcode *)c; - if (m->processor_rev_id == equivalent_processor_rev_id) { - apply_microcode_patch(m); - break; - } -- c += 2048; -+ c += 4096; - } - } - --- -1.7.9.5 - 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 @@ -0,0 +1,187 @@ +From 6ae8695f880a4a15672eda801226b4b1c83aa1a8 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 + 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(-) + +diff --git a/src/device/Kconfig b/src/device/Kconfig +index 613461b..3dd2b61 100644 +--- a/src/device/Kconfig ++++ b/src/device/Kconfig +@@ -192,6 +192,10 @@ config MULTIPLE_VGA_ADAPTERS + bool + default n + ++config SMBUS_HAS_AUX ++ bool ++ default n ++ + config SPD_CACHE + bool + default n +diff --git a/src/include/device/smbus.h b/src/include/device/smbus.h +index 073d7e2..53e90fb 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); ++#endif ++ + #endif /* DEVICE_SMBUS_H */ +diff --git a/src/southbridge/amd/sb700/Kconfig b/src/southbridge/amd/sb700/Kconfig +index 42ca2bb..a5dfe07 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 + + # 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 +--- a/src/southbridge/amd/sb700/sm.c ++++ b/src/southbridge/amd/sb700/sm.c +@@ -40,6 +40,8 @@ + #define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON + #endif + ++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) + 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); ++ else ++ res = find_resource(pbus->dev, 0x58); + + return do_smbus_recv_byte(res->base, device); + } +@@ -326,7 +331,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); ++ else ++ res = find_resource(pbus->dev, 0x58); + + return do_smbus_send_byte(res->base, device, val); + } +@@ -340,7 +348,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); ++ else ++ res = find_resource(pbus->dev, 0x58); + + 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) + 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); ++ else ++ res = find_resource(pbus->dev, 0x58); + + return do_smbus_write_byte(res->base, device, address, val); + } +@@ -393,7 +407,7 @@ static void sb700_sm_read_resources(device_t dev) + + /* dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; */ + +- /* smbus */ ++ /* 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->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); ++ ++ res = find_resource(dev, 0x58); ++ pci_write_config32(dev, 0x58, 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 +--- a/src/southbridge/amd/sb700/smbus.c ++++ b/src/southbridge/amd/sb700/smbus.c +@@ -22,6 +22,11 @@ + + #include "smbus.h" + ++extern uint8_t smbus_use_aux; ++ ++void smbus_switch_to_aux(uint8_t enable_aux); ++uint8_t smbus_switched_to_aux(void); ++ + void alink_ab_indx(u32 reg_space, u32 reg_addr, u32 mask, u32 val) + { + u32 tmp; +@@ -216,4 +221,14 @@ int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val) + return 0; + } + ++void smbus_switch_to_aux(uint8_t enable_aux) ++{ ++ smbus_use_aux = enable_aux; ++} ++ ++uint8_t smbus_switched_to_aux(void) ++{ ++ return smbus_use_aux; ++} ++ + #endif +-- +1.9.1 + diff --git a/resources/libreboot/patch/kgpe-d16/0003-arch-x86-boot-smbios-Add-SPD-IDs-for-Kingston-and-Co.patch b/resources/libreboot/patch/kgpe-d16/0003-arch-x86-boot-smbios-Add-SPD-IDs-for-Kingston-and-Co.patch @@ -1,36 +0,0 @@ -From f612a5cc0afba6e1af60652283dd47f3f34dcca7 Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <kb9vqf@pearsoncomputing.net> -Date: Thu, 25 Jun 2015 18:37:58 -0500 -Subject: [PATCH 003/146] arch/x86/boot/smbios: Add SPD IDs for Kingston and - Corsair - ---- - src/arch/x86/smbios.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c -index a1f05da..74288f9 100644 ---- a/src/arch/x86/smbios.c -+++ b/src/arch/x86/smbios.c -@@ -124,10 +124,18 @@ static int smbios_processor_name(char *start) - void smbios_fill_dimm_manufacturer_from_id(uint16_t mod_id, struct smbios_type17 *t) - { - switch (mod_id) { -+ case 0x9801: -+ t->manufacturer = smbios_add_string(t->eos, -+ "Kingston"); -+ break; - case 0x987f: - t->manufacturer = smbios_add_string(t->eos, - "Hynix"); - break; -+ case 0x9e02: -+ t->manufacturer = smbios_add_string(t->eos, -+ "Corsair"); -+ break; - case 0xad80: - t->manufacturer = smbios_add_string(t->eos, - "Hynix/Hyundai"); --- -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 @@ -0,0 +1,62 @@ +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-arch-x86-smbios-Add-Crucial-DIMM-manufacturer-ID.patch b/resources/libreboot/patch/kgpe-d16/0004-arch-x86-smbios-Add-Crucial-DIMM-manufacturer-ID.patch @@ -1,27 +0,0 @@ -From 4daf71b080abe86e2fe61af3adbc57a710b7ea02 Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <kb9vqf@pearsoncomputing.net> -Date: Tue, 28 Jul 2015 09:22:59 -0500 -Subject: [PATCH 004/146] arch/x86/smbios: Add Crucial DIMM manufacturer ID - ---- - src/arch/x86/smbios.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c -index 74288f9..6d645a3 100644 ---- a/src/arch/x86/smbios.c -+++ b/src/arch/x86/smbios.c -@@ -124,6 +124,10 @@ static int smbios_processor_name(char *start) - void smbios_fill_dimm_manufacturer_from_id(uint16_t mod_id, struct smbios_type17 *t) - { - switch (mod_id) { -+ case 0x2c80: -+ t->manufacturer = smbios_add_string(t->eos, -+ "Crucial"); -+ break; - case 0x9801: - t->manufacturer = smbios_add_string(t->eos, - "Kingston"); --- -1.7.9.5 - 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 @@ -0,0 +1,3675 @@ +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/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 @@ -0,0 +1,642 @@ +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/0005-southbridge-amd-sr5650-Remove-unnecessary-register-c.patch b/resources/libreboot/patch/kgpe-d16/0005-southbridge-amd-sr5650-Remove-unnecessary-register-c.patch @@ -1,33 +0,0 @@ -From 0d0290e3866dd24c77de9114937b692bba0e9db9 Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <kb9vqf@pearsoncomputing.net> -Date: Sun, 2 Aug 2015 21:29:20 -0500 -Subject: [PATCH 005/146] southbridge/amd/sr5650: Remove unnecessary register - configuration - ---- - src/southbridge/amd/sr5650/early_setup.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/southbridge/amd/sr5650/early_setup.c b/src/southbridge/amd/sr5650/early_setup.c -index d91f3bd..ec555f8 100644 ---- a/src/southbridge/amd/sr5650/early_setup.c -+++ b/src/southbridge/amd/sr5650/early_setup.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 -@@ -437,7 +438,6 @@ static void sr5650_por_htiu_index_init(device_t nb_dev) - set_htiu_enable_bits(nb_dev, 0x1D, 0x1<<2, 0x1<<2); - set_htiu_enable_bits(nb_dev, 0x1D, 0x1<<4, 0x1<<4); - -- set_nbcfg_enable_bits(cpu_f0, 0x68, 3 << 21, 0 << 21); - axindxc_reg(0x10, 1 << 9, 1 << 9); - set_pcie_enable_bits(nb_dev, 0x10 | 5 << 16, 1 << 9, 1 << 9); - set_htiu_enable_bits(nb_dev, 0x06, 0x1<<26, 0x1<<26); --- -1.7.9.5 - diff --git a/resources/libreboot/patch/kgpe-d16/0006-drivers-i2c-w83795-Add-full-support-for-fan-control-.patch b/resources/libreboot/patch/kgpe-d16/0006-drivers-i2c-w83795-Add-full-support-for-fan-control-.patch @@ -1,661 +0,0 @@ -From 12a58e8598d572ee4997f0a6670796b5e82d318b Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <kb9vqf@pearsoncomputing.net> -Date: Sat, 5 Sep 2015 17:53:20 -0500 -Subject: [PATCH 006/146] drivers/i2c/w83795: Add full support for fan - control, fan monitoring, and voltage monitoring - ---- - src/drivers/i2c/w83795/chip.h | 146 +++++++++++++++++++ - src/drivers/i2c/w83795/w83795.c | 301 +++++++++++++++++++++++++++------------ - src/drivers/i2c/w83795/w83795.h | 50 +++++-- - 3 files changed, 392 insertions(+), 105 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..413ea87 ---- /dev/null -+++ b/src/drivers/i2c/w83795/chip.h -@@ -0,0 +1,146 @@ -+/* -+ * 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) */ -+ -+ 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 2bbe0be..0e40710 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,12 +22,19 @@ - #include <arch/cpu.h> - #include <console/console.h> - #include <device/device.h> --#include "southbridge/amd/cimx/sb700/smbus.h" /*SMBUS_IO_BASE*/ -+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_SB700) -+# include "southbridge/amd/sb700/smbus.h" /*SMBUS_IO_BASE*/ -+#else -+# include "southbridge/amd/cimx/sb700/smbus.h" /*SMBUS_IO_BASE*/ -+#endif - #include "w83795.h" -+#include "chip.h" -+ -+static uint32_t smbus_io_base; - - static int w83795_set_bank(u8 bank) - { -- return do_smbus_write_byte(SMBUS_IO_BASE, W83795_DEV, W83795_REG_BANKSEL, bank); -+ return do_smbus_write_byte(smbus_io_base, W83795_DEV, W83795_REG_BANKSEL, bank); - } - - static u8 w83795_read(u16 reg) -@@ -35,11 +43,11 @@ static u8 w83795_read(u16 reg) - - ret = w83795_set_bank(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 = do_smbus_read_byte(smbus_io_base, W83795_DEV, reg & 0xff); - return ret; - } - -@@ -49,18 +57,18 @@ static u8 w83795_write(u16 reg, u8 value) - - err = w83795_set_bank(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 = do_smbus_write_byte(smbus_io_base, W83795_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(u8 dts_src) - { - u8 val; - -@@ -68,45 +76,6 @@ static void w83795_dts_enable(u8 dts_src) - val = w83795_read(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); --} -- --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) -@@ -131,40 +100,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) - { -- 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); - -- /* 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,12 +114,45 @@ 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 (config->smbus_aux) -+ smbus_io_base = SMBUS_AUX_IO_BASE; -+ else -+ smbus_io_base = SMBUS_IO_BASE; - -- if (do_smbus_read_byte(SMBUS_IO_BASE, W83795_DEV, 0x00) < 0) { -+ if (do_smbus_read_byte(smbus_io_base, W83795_DEV, 0x00) < 0) { - printk(BIOS_ERR, "W83795G/ADG Nuvoton H/W Monitor not found\n"); - return; - } -@@ -192,18 +166,156 @@ static void w83795_init(w83795_fan_mode_t mode, u8 dts_src) - 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); -+ /* Fan monitor settings */ -+ w83795_write(W83795_REG_FANIN_CTRL1, config->fanin_ctl1); -+ w83795_write(W83795_REG_FANIN_CTRL2, config->fanin_ctl2); -+ -+ /* Temperature thresholds */ -+ w83795_write(W83795_REG_TEMP_CRIT(0), config->tr1_critical_temperature); -+ w83795_write(W83795_REG_TEMP_CRIT_HYSTER(0), config->tr1_critical_hysteresis); -+ w83795_write(W83795_REG_TEMP_WARN(0), config->tr1_warning_temperature); -+ w83795_write(W83795_REG_TEMP_WARN_HYSTER(0), config->tr1_warning_hysteresis); -+ w83795_write(W83795_REG_TEMP_CRIT(1), config->tr2_critical_temperature); -+ w83795_write(W83795_REG_TEMP_CRIT_HYSTER(1), config->tr2_critical_hysteresis); -+ w83795_write(W83795_REG_TEMP_WARN(1), config->tr2_warning_temperature); -+ w83795_write(W83795_REG_TEMP_WARN_HYSTER(1), config->tr2_warning_hysteresis); -+ w83795_write(W83795_REG_TEMP_CRIT(2), config->tr3_critical_temperature); -+ w83795_write(W83795_REG_TEMP_CRIT_HYSTER(2), config->tr3_critical_hysteresis); -+ w83795_write(W83795_REG_TEMP_WARN(2), config->tr3_warning_temperature); -+ w83795_write(W83795_REG_TEMP_WARN_HYSTER(2), config->tr3_warning_hysteresis); -+ w83795_write(W83795_REG_TEMP_CRIT(3), config->tr4_critical_temperature); -+ w83795_write(W83795_REG_TEMP_CRIT_HYSTER(3), config->tr4_critical_hysteresis); -+ w83795_write(W83795_REG_TEMP_WARN(3), config->tr4_warning_temperature); -+ w83795_write(W83795_REG_TEMP_WARN_HYSTER(3), config->tr4_warning_hysteresis); -+ w83795_write(W83795_REG_TEMP_CRIT(4), config->tr5_critical_temperature); -+ w83795_write(W83795_REG_TEMP_CRIT_HYSTER(4), config->tr5_critical_hysteresis); -+ w83795_write(W83795_REG_TEMP_WARN(4), config->tr5_warning_temperature); -+ w83795_write(W83795_REG_TEMP_WARN_HYSTER(4), config->tr5_warning_hysteresis); -+ w83795_write(W83795_REG_TEMP_CRIT(5), config->tr6_critical_temperature); -+ w83795_write(W83795_REG_TEMP_CRIT_HYSTER(5), config->tr6_critical_hysteresis); -+ w83795_write(W83795_REG_TEMP_WARN(5), config->tr6_warning_temperature); -+ w83795_write(W83795_REG_TEMP_WARN_HYSTER(5), config->tr6_warning_hysteresis); -+ -+ /* DTS enable */ -+ w83795_write(W83795_REG_DTSE, config->temp_dtse); -+ -+ /* DTS temperature thresholds */ -+ w83795_write(W83795_REG_DTS_CRIT, config->dts_critical_temperature); -+ w83795_write(W83795_REG_DTS_CRIT_HYSTER, config->dts_critical_hysteresis); -+ w83795_write(W83795_REG_DTS_WARN, config->dts_warning_temperature); -+ w83795_write(W83795_REG_DTS_WARN_HYSTER, config->dts_warning_hysteresis); -+ -+ /* Configure DTS registers in bank3 before enabling DTS */ -+ w83795_dts_configure(dts_src); -+ -+ /* Temperature monitor settings */ -+ w83795_write(W83795_REG_TEMP_CTRL1, config->temp_ctl1); -+ w83795_write(W83795_REG_TEMP_CTRL2, config->temp_ctl2); -+ -+ /* Temperature to fan mappings */ -+ w83795_write(W83795_REG_TFMR(0), config->temp1_fan_select); -+ w83795_write(W83795_REG_TFMR(1), config->temp2_fan_select); -+ w83795_write(W83795_REG_TFMR(2), config->temp3_fan_select); -+ w83795_write(W83795_REG_TFMR(3), config->temp4_fan_select); -+ w83795_write(W83795_REG_TFMR(4), config->temp5_fan_select); -+ w83795_write(W83795_REG_TFMR(5), config->temp6_fan_select); -+ -+ /* Temperature data source to temperature mappings */ -+ w83795_write(W83795_REG_T12TSS, ((config->temp2_source_select & 0xff) << 8) | (config->temp1_source_select & 0xff)); -+ w83795_write(W83795_REG_T34TSS, ((config->temp4_source_select & 0xff) << 8) | (config->temp3_source_select & 0xff)); -+ w83795_write(W83795_REG_T56TSS, ((config->temp6_source_select & 0xff) << 8) | (config->temp5_source_select & 0xff)); - -- /* enable monitoring operations */ -- val = w83795_read(W83795_REG_CONFIG); -- val |= W83795_REG_CONFIG_START; -- w83795_write(W83795_REG_CONFIG, val); -+ /* Set Critical Temperature to Full Speed all fan (CTFS) */ -+ w83795_write(W83795_REG_CTFS(0), config->temp1_critical_temperature); -+ w83795_write(W83795_REG_CTFS(1), config->temp2_critical_temperature); -+ w83795_write(W83795_REG_CTFS(2), config->temp3_critical_temperature); -+ w83795_write(W83795_REG_CTFS(3), config->temp4_critical_temperature); -+ w83795_write(W83795_REG_CTFS(4), config->temp5_critical_temperature); -+ w83795_write(W83795_REG_CTFS(5), config->temp6_critical_temperature); -+ -+ /* Set fan control target temperatures */ -+ w83795_write(W83795_REG_TTTI(0), config->temp1_target_temperature); -+ w83795_write(W83795_REG_TTTI(1), config->temp2_target_temperature); -+ w83795_write(W83795_REG_TTTI(2), config->temp3_target_temperature); -+ w83795_write(W83795_REG_TTTI(3), config->temp4_target_temperature); -+ w83795_write(W83795_REG_TTTI(4), config->temp5_target_temperature); -+ w83795_write(W83795_REG_TTTI(5), config->temp6_target_temperature); -+ -+ /* Set fan stall prevention parameters */ -+ w83795_write(W83795_REG_FAN_NONSTOP(0), config->fan1_nonstop); -+ w83795_write(W83795_REG_FAN_NONSTOP(1), config->fan2_nonstop); -+ w83795_write(W83795_REG_FAN_NONSTOP(2), config->fan3_nonstop); -+ w83795_write(W83795_REG_FAN_NONSTOP(3), config->fan4_nonstop); -+ w83795_write(W83795_REG_FAN_NONSTOP(4), config->fan5_nonstop); -+ w83795_write(W83795_REG_FAN_NONSTOP(5), config->fan6_nonstop); -+ w83795_write(W83795_REG_FAN_NONSTOP(6), config->fan7_nonstop); -+ w83795_write(W83795_REG_FAN_NONSTOP(7), config->fan8_nonstop); -+ -+ /* Set fan default speed */ -+ w83795_write(W83795_REG_DFSP, fan_pct_to_cfg_val(config->default_speed)); -+ -+ /* Set initial fan speeds */ -+ w83795_write(W83795_REG_FAN_MANUAL_SPEED(0), fan_pct_to_cfg_val(config->fan1_duty)); -+ w83795_write(W83795_REG_FAN_MANUAL_SPEED(1), fan_pct_to_cfg_val(config->fan2_duty)); -+ w83795_write(W83795_REG_FAN_MANUAL_SPEED(2), fan_pct_to_cfg_val(config->fan3_duty)); -+ w83795_write(W83795_REG_FAN_MANUAL_SPEED(3), fan_pct_to_cfg_val(config->fan4_duty)); -+ w83795_write(W83795_REG_FAN_MANUAL_SPEED(4), fan_pct_to_cfg_val(config->fan5_duty)); -+ w83795_write(W83795_REG_FAN_MANUAL_SPEED(5), fan_pct_to_cfg_val(config->fan6_duty)); -+ w83795_write(W83795_REG_FAN_MANUAL_SPEED(6), fan_pct_to_cfg_val(config->fan7_duty)); -+ w83795_write(W83795_REG_FAN_MANUAL_SPEED(7), fan_pct_to_cfg_val(config->fan8_duty)); -+ -+ /* Voltage monitor settings */ -+ w83795_write(W83795_REG_VOLT_CTRL1, config->volt_ctl1); -+ w83795_write(W83795_REG_VOLT_CTRL2, config->volt_ctl2); -+ -+ /* Voltage high/low limits */ -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(0), millivolts_to_limit_value_type1(config->vcore1_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(0), millivolts_to_limit_value_type1(config->vcore1_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(1), millivolts_to_limit_value_type1(config->vcore2_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(1), millivolts_to_limit_value_type1(config->vcore2_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(2), millivolts_to_limit_value_type1(config->vsen3_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(2), millivolts_to_limit_value_type1(config->vsen3_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(3), millivolts_to_limit_value_type1(config->vsen4_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(3), millivolts_to_limit_value_type1(config->vsen4_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(4), millivolts_to_limit_value_type1(config->vsen5_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(4), millivolts_to_limit_value_type1(config->vsen5_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(5), millivolts_to_limit_value_type1(config->vsen6_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(5), millivolts_to_limit_value_type1(config->vsen6_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(6), millivolts_to_limit_value_type1(config->vsen7_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(6), millivolts_to_limit_value_type1(config->vsen7_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(7), millivolts_to_limit_value_type1(config->vsen8_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(7), millivolts_to_limit_value_type1(config->vsen8_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(8), millivolts_to_limit_value_type1(config->vsen9_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(8), millivolts_to_limit_value_type1(config->vsen9_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(9), millivolts_to_limit_value_type1(config->vsen10_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(9), millivolts_to_limit_value_type1(config->vsen10_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(10), millivolts_to_limit_value_type1(config->vsen11_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(10), millivolts_to_limit_value_type1(config->vsen11_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(11), millivolts_to_limit_value_type1(config->vtt_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(11), millivolts_to_limit_value_type1(config->vtt_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(12), millivolts_to_limit_value_type2(config->vdd_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(12), millivolts_to_limit_value_type2(config->vdd_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(13), millivolts_to_limit_value_type2(config->vsb_high_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_LOW(13), millivolts_to_limit_value_type2(config->vsb_low_limit_mv)); -+ w83795_write(W83795_REG_VOLT_LIM_HIGH(14), millivolts_to_limit_value_type2(config->vbat_high_limit_mv)); -+ w83795_write(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(W83795_REG_VOLT_LIM_HIGH_2_M(4), limit_value >> 2); -+ w83795_write(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(W83795_REG_VOLT_LIM_LOW_2_M(4), limit_value >> 2); -+ w83795_write(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(W83795_REG_VOLT_LIM_HIGH_2_M(5), limit_value >> 2); -+ w83795_write(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(W83795_REG_VOLT_LIM_LOW_2_M(5), limit_value >> 2); -+ w83795_write(W83795_REG_VOLT_LIM_LOW_2_L(5), limit_value & 0x3); - -- w83795_dts_enable(dts_src); - w83795_set_fan(mode); - - printk(BIOS_INFO, "Fan CTFS(celsius) TTTI(celsius)\n"); -@@ -219,6 +331,11 @@ static void w83795_init(w83795_fan_mode_t mode, u8 dts_src) - val = w83795_read(W83795_REG_DTS(i)); - printk(BIOS_DEBUG, "DTS%x ReadOut=%x\n", i, val); - } -+ -+ /* start monitoring operation */ -+ val = w83795_read(W83795_REG_CONFIG); -+ val |= W83795_REG_CONFIG_START; -+ w83795_write(W83795_REG_CONFIG, val); - } - - static void w83795_hwm_init(struct device *dev) -@@ -232,9 +349,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..59fa273 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 -@@ -29,6 +30,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 +40,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/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 @@ -0,0 +1,621 @@ +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 @@ -0,0 +1,832 @@ +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(NODE_PCI(node, 4), 0xc4); ++ dword |= 0x000000c0; ++ pci_write_config32(NODE_PCI(node, 4), 0xc4, dword); ++ } ++ } else if (internal_node_number == 1) { ++ uint8_t package_link_3_connected = pci_read_config32(NODE_PCI(node, 0), 0xb8) & 0x1; ++ if (package_link_3_connected) { ++ /* Set WidthIn and WidthOut to 0 */ ++ dword = pci_read_config32(NODE_PCI(node, 0), 0xa4); ++ dword &= ~0x77000000; ++ pci_write_config32(NODE_PCI(node, 0), 0xa4, dword); ++ /* Set Ganged to 1 */ ++ dword = pci_read_config32(NODE_PCI(node, 0), 0x174); ++ dword |= 0x00000001; ++ pci_write_config32(NODE_PCI(node, 0), 0x174, 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(NODE_PCI(node, 4), 0xa4); ++ dword |= 0x000000c0; ++ pci_write_config32(NODE_PCI(node, 4), 0xa4, dword); ++ } ++ } ++ } ++ } ++ } ++ } + } +diff --git a/src/northbridge/amd/amdht/ht_wrapper.h b/src/northbridge/amd/amdht/ht_wrapper.h +new file mode 100644 +index 0000000..3e9d957 +--- /dev/null ++++ b/src/northbridge/amd/amdht/ht_wrapper.h +@@ -0,0 +1,25 @@ ++/* ++ * 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. ++ */ ++ ++#ifndef AMD_HT_WRAPPER_H ++#define AMD_HT_WRAPPER_H ++ ++void amd_ht_fixup(struct sys_info *sysinfo); ++ ++#endif +-- +1.9.1 + diff --git a/resources/libreboot/patch/kgpe-d16/0007-drivers-aspeed-Add-native-text-mode-VGA-support-for-.patch b/resources/libreboot/patch/kgpe-d16/0007-drivers-aspeed-Add-native-text-mode-VGA-support-for-.patch @@ -1,3673 +0,0 @@ -From 27f2cdc381f7bac82f868acef86bcc95467fe24c Mon Sep 17 00:00:00 2001 -From: Timothy Pearson <kb9vqf@pearsoncomputing.net> -Date: Sat, 5 Sep 2015 17:38:09 -0500 -Subject: [PATCH 007/146] drivers/aspeed: Add native text mode VGA support for - the AST2050 - ---- - 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..cc090bb ---- /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]; -+ } -+ } -+ }