+static u32 nb_clk_did(int node, u32 cpuRev,u8 procPkg) {
+ u8 link0isGen3 = 0;
+ u8 offset;
+ if (AMD_CpuFindCapability(node, 0, &offset)) {
+ link0isGen3 = (AMD_checkLinkType(node, 0, offset) & HTPHY_LINKTYPE_HT3 );
+ }
+ /* FIXME: NB_CLKDID should be 101b for AMD_DA_C2 in package
+ S1g3 in link Gen3 mode, but I don't know how to tell
+ package S1g3 from S1g4 */
+ if ((cpuRev & AMD_DA_C2) && (procPkg & AMD_PKGTYPE_S1gX)
+ && link0isGen3) {
+ return 5 ; /* divide clk by 128*/
+ } else {
+ return 4 ; /* divide clk by 16 */
+ }
+}
+
+
+static u32 power_up_down(int node, u8 procPkg) {
+ u32 dword=0;
+ /* from CPU rev guide #41322 rev 3.74 June 2010 Table 26 */
+ u8 singleLinkFlag = ((procPkg == AMD_PKGTYPE_AM3_2r2)
+ || (procPkg == AMD_PKGTYPE_S1gX)
+ || (procPkg == AMD_PKGTYPE_ASB2));
+
+ if (singleLinkFlag) {
+ /*
+ * PowerStepUp=01000b - 50nS
+ * PowerStepDown=01000b - 50ns
+ */
+ dword |= PW_STP_UP50 | PW_STP_DN50;
+ } else {
+ u32 dispRefModeEn = (pci_read_config32(NODE_PCI(node,0),0x68) >> 24) & 1;
+ u32 isocEn = 0;
+ int j;
+ for(j=0 ; (j<4) && (!isocEn) ; j++ ) {
+ u8 offset;
+ if (AMD_CpuFindCapability(node, j, &offset)) {
+ isocEn = (pci_read_config32(NODE_PCI(node,0),offset+4) >>12) & 1;
+ }
+ }
+
+ if (dispRefModeEn || isocEn) {
+ dword |= PW_STP_UP50 | PW_STP_DN50 ;
+ } else {
+ /* get number of cores for PowerStepUp & PowerStepDown in server
+ 1 core - 400nS - 0000b
+ 2 cores - 200nS - 0010b
+ 3 cores - 133nS -> 100nS - 0011b
+ 4 cores - 100nS - 0011b
+ */
+ switch (get_core_num_in_bsp(node)) {
+ case 0:
+ dword |= PW_STP_UP400 | PW_STP_DN400;
+ break;
+ case 1:
+ case 2:
+ dword |= PW_STP_UP200 | PW_STP_DN200;
+ break;
+ case 3:
+ dword |= PW_STP_UP100 | PW_STP_DN100;
+ break;
+ default:
+ dword |= PW_STP_UP100 | PW_STP_DN100;
+ break;
+ }
+ }
+ }
+ return dword;
+}
+
+static void config_clk_power_ctrl_reg0(int node, u32 cpuRev, u8 procPkg) {
+ device_t dev = NODE_PCI(node, 3);
+
+ /* Program fields in Clock Power/Control register0 (F3xD4) */
+
+ /* set F3xD4 Clock Power/Timing Control 0 Register
+ * NbClkDidApplyAll=1b
+ * NbClkDid=100b or 101b
+ * PowerStepUp= "platform dependent"
+ * PowerStepDown= "platform dependent"
+ * LinkPllLink=01b
+ * ClkRampHystCtl=HW default
+ * ClkRampHystSel=1111b
+ */
+ u32 dword= pci_read_config32(dev, 0xd4);
+ dword &= CPTC0_MASK;
+ dword |= NB_CLKDID_ALL | LNK_PLL_LOCK | CLK_RAMP_HYST_SEL_VAL;
+ dword |= (nb_clk_did(node,cpuRev,procPkg) << NB_CLKDID_SHIFT);
+
+ dword |= power_up_down(node, procPkg);
+
+ pci_write_config32(dev, 0xd4, dword);
+
+}
+
+static void config_power_ctrl_misc_reg(device_t dev,u32 cpuRev, u8 procPkg) {
+ /* check PVI/SVI */
+ u32 dword = pci_read_config32(dev, 0xA0);
+
+ /* BKDG r31116 2010-04-22 2.4.1.7 step b F3xA0[VSSlamVidMod] */
+ /* PllLockTime and PsiVidEn set in ruleset in defaults.h */
+ if (dword & PVI_MODE) { /* PVI */
+ /* set slamVidMode to 0 for PVI */
+ dword &= VID_SLAM_OFF ;
+ } else { /* SVI */
+ /* set slamVidMode to 1 for SVI */
+ dword |= VID_SLAM_ON;
+ }
+ /* set the rest of A0 since we're at it... */
+
+ if (cpuRev & (AMD_DA_Cx | AMD_RB_C3 )) {
+ dword |= NB_PSTATE_FORCE_ON;
+ } // else should we clear it ?
+
+
+ if ((procPkg == AMD_PKGTYPE_G34) || (procPkg == AMD_PKGTYPE_C32) ) {
+ dword |= BP_INS_TRI_EN_ON ;
+ }
+
+ /* TODO: look into C1E state and F3xA0[IdleExitEn]*/
+ #if CONFIG_SVI_HIGH_FREQ
+ if (cpuRev & AMD_FAM10_C3) {
+ dword |= SVI_HIGH_FREQ_ON;
+ }
+ #endif
+ pci_write_config32(dev, 0xA0, dword);
+}
+
+static void config_nb_syn_ptr_adj(device_t dev, u32 cpuRev) {
+ /* Note the following settings are additional from the ported
+ * function setFidVidRegs()
+ */
+ /* adjust FIFO between nb and core clocks to max allowed
+ values (min latency) */
+ u32 nbPstate = pci_read_config32(dev,0x1f0) & NB_PSTATE_MASK;
+ u8 nbSynPtrAdj;
+ if ((cpuRev & (AMD_DR_Bx|AMD_DA_Cx) )
+ || ( (cpuRev & AMD_RB_C3) && (nbPstate!=0))) {
+ nbSynPtrAdj = 5;
+ } else {
+ nbSynPtrAdj = 6;
+ }
+
+ u32 dword = pci_read_config32(dev, 0xDc);
+ dword &= ~ NB_SYN_PTR_ADJ_MASK;
+ dword |= nbSynPtrAdj << NB_SYN_PTR_ADJ_POS;
+ /* NbsynPtrAdj set to 5 or 6 per BKDG (needs reset) */
+ pci_write_config32(dev, 0xdc, dword);
+}
+
+static void config_acpi_pwr_state_ctrl_regs(device_t dev, u32 cpuRev, u8 procPkg) {
+ /* step 1, chapter 2.4.2.6 of AMD Fam 10 BKDG #31116 Rev 3.48 22.4.2010 */
+ u32 dword;
+ u32 c1= 1;
+ if (cpuRev & (AMD_DR_Bx)) {
+ // will coreboot ever enable cache scrubbing ?
+ // if it does, will it be enough to check the current state
+ // or should we configure for what we'll set up later ?
+ dword = pci_read_config32(dev, 0x58);
+ u32 scrubbingCache = dword &
+ ( (0x1F << 16) // DCacheScrub
+ | (0x1F << 8) ); // L2Scrub
+ if (scrubbingCache) {
+ c1 = 0x80;
+ } else {
+ c1 = 0xA0;
+ }
+ } else { // rev C or later
+ // same doubt as cache scrubbing: ok to check current state ?
+ dword = pci_read_config32(dev, 0xDC);
+ u32 cacheFlushOnHalt = dword & (7 << 16);
+ if (!cacheFlushOnHalt) {
+ c1 = 0x80;
+ }
+ }
+ dword = (c1 << 24) | (0xE641E6);
+ pci_write_config32(dev, 0x84, dword);
+
+
+ /* FIXME: BKDG Table 100 says if the link is at a Gen1
+frequency and the chipset does not support a 10us minimum LDTSTOP
+assertion time, then { If ASB2 && SVI then smaf001 = F6h else
+smaf001=87h. } else ... I hardly know what it means or how to check
+it from here, so I bluntly assume it is false and code here the else,
+which is easier */
+
+ u32 smaf001 = 0xE6;
+ if (cpuRev & AMD_DR_Bx ) {
+ smaf001 = 0xA6;
+ } else {
+ #if CONFIG_SVI_HIGH_FREQ
+ if (cpuRev & (AMD_RB_C3 | AMD_DA_C3)) {
+ smaf001 = 0xF6;
+ }
+ #endif
+ }
+ u32 fidvidChange = 0;
+ if (((cpuRev & AMD_DA_Cx) && (procPkg & AMD_PKGTYPE_S1gX))
+ || (cpuRev & AMD_RB_C3) ) {
+ fidvidChange=0x0B;
+ }
+ dword = (0xE6 << 24) | (fidvidChange << 16)
+ | (smaf001 << 8) | 0x81;
+ pci_write_config32(dev, 0x80, dword);
+}
+