static void program_read_timing(const int ch, const int lane, read_timing_t *const timing) { normalize_read_timing(timing); u32 reg = MCHBAR32(CxRDTy_MCHBAR(ch, lane)); reg &= ~(CxRDTy_T_MASK | CxRDTy_P_MASK); reg |= CxRDTy_T(timing->t) | CxRDTy_P(timing->p); MCHBAR32(CxRDTy_MCHBAR(ch, lane)) = reg; }
int fixup_i945_errata(void) { u32 reg32; /* Mobile Intel 945 Express only */ reg32 = MCHBAR32(FSBPMC3); reg32 &= ~((1 << 13) | (1 << 29)); MCHBAR32(FSBPMC3) = reg32; return 0; }
void init_iommu() { /* FIXME: proper test? */ int me_active = pci_read_config8(PCI_DEV(0, 3, 0), PCI_CLASS_REVISION) != 0xff; int stepping = pci_read_config8(PCI_DEV(0, 0, 0), PCI_CLASS_REVISION); MCHBAR32(0x28) = IOMMU_BASE1 | 1; /* HDA @ 0:1b.0 */ if (stepping != STEPPING_B2) { /* The official workaround is to run SMM every 64ms. The only winning move is not to play. */ MCHBAR32(0x18) = IOMMU_BASE2 | 1; /* IGD @ 0:2.0-1 */ } else { /* write-once, so lock it down */ MCHBAR32(0x18) = 0; /* disable IOMMU for IGD @ 0:2.0-1 */ } if (me_active) { MCHBAR32(0x10) = IOMMU_BASE3 | 1; /* ME @ 0:3.0-3 */ } MCHBAR32(0x20) = IOMMU_BASE4 | 1; /* all other DMA sources */ /* clear GTT */ u32 gtt = pci_read_config16(PCI_DEV(0, 0, 0), 0x52); if (gtt & 0x400) { /* VT mode */ device_t igd = PCI_DEV(0, 2, 0); /* setup somewhere */ u8 cmd = pci_read_config8(igd, PCI_COMMAND); cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; pci_write_config8(igd, PCI_COMMAND, cmd); void* bar = (void*)pci_read_config32(igd, PCI_BASE_ADDRESS_0); /* clear GTT, 2MB is enough (and should be safe) */ memset(bar, 0, 2<<20); /* and now disable again */ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); pci_write_config8(igd, PCI_COMMAND, cmd); pci_write_config32(igd, PCI_BASE_ADDRESS_0, 0); } if (stepping == STEPPING_B3) { MCHBAR8(0xffc) |= 1 << 4; device_t peg = PCI_DEV(0, 1, 0); /* FIXME: proper test? */ if (pci_read_config8(peg, PCI_CLASS_REVISION) != 0xff) { int val = pci_read_config32(peg, 0xfc) | (1 << 15); pci_write_config32(peg, 0xfc, val); } } /* final */ MCHBAR8(0x94) |= 1 << 3; }
static void haswell_setup_graphics(void) { #if 0 //<CHW+> u32 reg32; u16 reg16; u8 reg8; printk(BIOS_DEBUG, "Initializing Graphics...\n"); /* Setup IGD memory by setting GGC[7:3] = 1 for 32MB */ reg16 = pci_read_config16(PCI_DEV(0,0,0), GGC); reg16 &= ~0x00f8; reg16 |= 1 << 3; /* Program GTT memory by setting GGC[9:8] = 2MB */ reg16 &= ~0x0300; reg16 |= 2 << 8; /* Enable VGA decode */ reg16 &= ~0x0002; pci_write_config16(PCI_DEV(0,0,0), GGC, reg16); /* Enable 256MB aperture */ reg8 = pci_read_config8(PCI_DEV(0, 2, 0), MSAC); reg8 &= ~0x06; reg8 |= 0x02; pci_write_config8(PCI_DEV(0, 2, 0), MSAC, reg8); /* Erratum workarounds */ reg32 = MCHBAR32(0x5f00); reg32 |= (1 << 9)|(1 << 10); MCHBAR32(0x5f00) = reg32; /* Enable SA Clock Gating */ reg32 = MCHBAR32(0x5f00); MCHBAR32(0x5f00) = reg32 | 1; /* GPU RC6 workaround for sighting 366252 */ reg32 = MCHBAR32(0x5d14); reg32 |= (1 << 31); MCHBAR32(0x5d14) = reg32; /* VLW */ reg32 = MCHBAR32(0x6120); reg32 &= ~(1 << 0); MCHBAR32(0x6120) = reg32; reg32 = MCHBAR32(0x5418); reg32 |= (1 << 4) | (1 << 5); MCHBAR32(0x5418) = reg32; #endif //<CHW+> }
static void init_egress(void) { u32 reg32; /* VC0: TC0 only */ EPBAR8(0x14) = 1; EPBAR8(0x4) = 1; switch (MCHBAR32(0xc00) & 0x7) { case 0x0: /* FSB 1066 */ EPBAR32(0x2c) = 0x0001a6db; break; case 0x2: /* FSB 800 */ EPBAR32(0x2c) = 0x00014514; break; default: case 0x4: /* FSB 1333 */ EPBAR32(0x2c) = 0x00022861; break; } EPBAR32(0x28) = 0x0a0a0a0a; EPBAR8(0xc) = (EPBAR8(0xc) & ~0xe) | 2; EPBAR32(0x1c) = (EPBAR32(0x1c) & ~0x7f0000) | 0x0a0000; MCHBAR8(0x3c) = MCHBAR8(0x3c) | 0x7; /* VC1: ID1, TC7 */ reg32 = (EPBAR32(0x20) & ~(7 << 24)) | (1 << 24); reg32 = (reg32 & ~0xfe) | (1 << 7); EPBAR32(0x20) = reg32; /* Init VC1 port arbitration table */ EPBAR32(0x100) = 0x001000001; EPBAR32(0x104) = 0x000040000; EPBAR32(0x108) = 0x000001000; EPBAR32(0x10c) = 0x000000040; EPBAR32(0x110) = 0x001000001; EPBAR32(0x114) = 0x000040000; EPBAR32(0x118) = 0x000001000; EPBAR32(0x11c) = 0x000000040; /* Load table */ reg32 = EPBAR32(0x20) | (1 << 16); EPBAR32(0x20) = reg32; asm("nop"); EPBAR32(0x20) = reg32; /* Wait for table load */ while ((EPBAR8(0x26) & (1 << 0)) != 0); /* VC1: enable */ EPBAR32(0x20) |= 1 << 31; /* Wait for VC1 */ while ((EPBAR8(0x26) & (1 << 1)) != 0); printk(BIOS_DEBUG, "Done Egress Port\n"); }
static void read_training_per_lane(const int channel, const int lane, const address_bunch_t *const addresses) { read_timing_t lower, upper; MCHBAR32(CxRDTy_MCHBAR(channel, lane)) |= 3 << 25; /* Search lower bound. */ lower.t = 0; lower.p = 0; program_read_timing(channel, lane, &lower); /* Coarse search for good t. */ while (!read_training_test(channel, lane, addresses)) { ++lower.t; program_read_timing(channel, lane, &lower); } /* Step back, then fine search for good p. */ if (lower.t > 0) { --lower.t; program_read_timing(channel, lane, &lower); while (!read_training_test(channel, lane, addresses)) { ++lower.p; program_read_timing(channel, lane, &lower); } } /* Search upper bound. */ upper.t = lower.t + 1; upper.p = lower.p; program_read_timing(channel, lane, &upper); if (!read_training_test(channel, lane, addresses)) die("Read training failed: limits too narrow.\n"); /* Coarse search for bad t. */ do { ++upper.t; program_read_timing(channel, lane, &upper); } while (read_training_test(channel, lane, addresses)); /* Fine search for bad p. */ --upper.t; program_read_timing(channel, lane, &upper); while (read_training_test(channel, lane, addresses)) { ++upper.p; program_read_timing(channel, lane, &upper); } /* Calculate and program mean value. */ lower.p += lower.t << READ_TIMING_P_SHIFT; upper.p += upper.t << READ_TIMING_P_SHIFT; const int mean_p = (lower.p + upper.p) >> 1; /* lower becomes the mean value. */ lower.t = mean_p >> READ_TIMING_P_SHIFT; lower.p = mean_p & (READ_TIMING_P_BOUND - 1); program_read_timing(channel, lane, &lower); printk(BIOS_DEBUG, "Final timings for byte lane %d on channel %d: " "%d.%d\n", lane, channel, lower.t, lower.p); }
void intel_sandybridge_finalize_smm(void) { pcie_or_config16(PCI_DEV_SNB, 0x50, 1 << 0); /* GGC */ pcie_or_config32(PCI_DEV_SNB, 0x5c, 1 << 0); /* DPR */ pcie_or_config32(PCI_DEV_SNB, 0x78, 1 << 10); /* ME */ pcie_or_config32(PCI_DEV_SNB, 0x90, 1 << 0); /* REMAPBASE */ pcie_or_config32(PCI_DEV_SNB, 0x98, 1 << 0); /* REMAPLIMIT */ pcie_or_config32(PCI_DEV_SNB, 0xa0, 1 << 0); /* TOM */ pcie_or_config32(PCI_DEV_SNB, 0xa8, 1 << 0); /* TOUUD */ pcie_or_config32(PCI_DEV_SNB, 0xb0, 1 << 0); /* BDSM */ pcie_or_config32(PCI_DEV_SNB, 0xb4, 1 << 0); /* BGSM */ pcie_or_config32(PCI_DEV_SNB, 0xb8, 1 << 0); /* TSEGMB */ pcie_or_config32(PCI_DEV_SNB, 0xbc, 1 << 0); /* TOLUD */ MCHBAR32_OR(0x5500, 1 << 0); /* PAVP */ MCHBAR32_OR(0x5f00, 1 << 31); /* SA PM */ MCHBAR32_OR(0x6020, 1 << 0); /* UMA GFX */ MCHBAR32_OR(0x63fc, 1 << 0); /* VTDTRK */ MCHBAR32_OR(0x6800, 1 << 31); MCHBAR32_OR(0x7000, 1 << 31); MCHBAR32_OR(0x77fc, 1 << 0); /* Memory Controller Lockdown */ MCHBAR8(0x50fc) = 0x8f; /* Read+write the following */ MCHBAR32(0x6030) = MCHBAR32(0x6030); MCHBAR32(0x6034) = MCHBAR32(0x6034); MCHBAR32(0x6008) = MCHBAR32(0x6008); }
static void broadwell_finalize(void *unused) { printk(BIOS_DEBUG, "Finalizing chipset.\n"); reg_script_run_on_dev(SA_DEV_ROOT, system_agent_finalize_script); reg_script_run_on_dev(PCH_DEV_LPC, pch_finalize_script); /* Lock */ RCBA32_OR(0x3a6c, 0x00000001); /* Read+Write the following registers */ MCHBAR32(0x6030) = MCHBAR32(0x6030); MCHBAR32(0x6034) = MCHBAR32(0x6034); MCHBAR32(0x6008) = MCHBAR32(0x6008); RCBA32(0x21a4) = RCBA32(0x21a4); /* Re-init SPI after lockdown */ spi_init(); printk(BIOS_DEBUG, "Finalizing SMM.\n"); outb(APM_CNT_FINALIZE, APM_CNT); /* Indicate finalize step with post code */ post_code(POST_OS_BOOT); }
/* * Dump in the log memory controller configuration as read from the memory * controller registers. */ static void report_memory_config(void) { u32 addr_decoder_common, addr_decode_ch[2]; int i; addr_decoder_common = MCHBAR32(0x5000); addr_decode_ch[0] = MCHBAR32(0x5004); addr_decode_ch[1] = MCHBAR32(0x5008); printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n", (MCHBAR32(0x5e04) * 13333 * 2 + 50)/100); printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n", addr_decoder_common & 3, (addr_decoder_common >> 2) & 3, (addr_decoder_common >> 4) & 3); for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) { u32 ch_conf = addr_decode_ch[i]; printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n", i, ch_conf); printk(BIOS_DEBUG, " ECC %s\n", ecc_decoder[(ch_conf >> 24) & 3]); printk(BIOS_DEBUG, " enhanced interleave mode %s\n", ((ch_conf >> 22) & 1) ? "on" : "off"); printk(BIOS_DEBUG, " rank interleave %s\n", ((ch_conf >> 21) & 1) ? "on" : "off"); printk(BIOS_DEBUG, " DIMMA %d MB width %s %s rank%s\n", ((ch_conf >> 0) & 0xff) * 256, ((ch_conf >> 19) & 1) ? "x16" : "x8 or x32", ((ch_conf >> 17) & 1) ? "dual" : "single", ((ch_conf >> 16) & 1) ? "" : ", selected"); printk(BIOS_DEBUG, " DIMMB %d MB width %s %s rank%s\n", ((ch_conf >> 8) & 0xff) * 256, ((ch_conf >> 19) & 1) ? "x16" : "x8 or x32", ((ch_conf >> 18) & 1) ? "dual" : "single", ((ch_conf >> 16) & 1) ? ", selected" : ""); } }
/** * sample the strobes signal */ static u32 sample_strobes(int channel_offset, struct sys_info *sysinfo) { u32 reg32, addr; int i; MCHBAR32(C0DRC1 + channel_offset) |= (1 << 6); MCHBAR32(C0DRC1 + channel_offset) &= ~(1 << 6); addr = 0; if (channel_offset != 0) { /* must be dual channel */ if (sysinfo->interleaved == 1) { addr |= (1 << 6); } else { addr = ((u32)MCHBAR8(C0DRB3)) << 25; } } for (i = 0; i < 28; i++) { read32((void *)addr); read32((void *)(addr + 0x80)); } reg32 = MCHBAR32(RCVENMT); if (channel_offset == 0) { reg32 = reg32 << 2; } /** * [19] = 1: all bits are high * [18] = 1: all bits are low * [19:18] = 00: bits are mixed high, low */ return reg32; }
/* * Punit Initialization code. This all isn't documented, but * this is the recipe. */ static bool punit_init(void) { uint32_t reg; uint32_t data; struct stopwatch sw; /* Thermal throttle activation offset */ configure_thermal_target(); /* * Software Core Disable Mask (P_CR_CORE_DISABLE_MASK_0_0_0_MCHBAR). * Enable all cores here. */ MCHBAR32(CORE_DISABLE_MASK) = 0x0; /* P-Unit bring up */ reg = MCHBAR32(BIOS_RESET_CPL); if (reg == 0xffffffff) { /* P-unit not found */ printk(BIOS_DEBUG, "Punit MMIO not available\n"); return false; } /* Set Punit interrupt pin IPIN offset 3D */ pci_write_config8(SA_DEV_PUNIT, PCI_INTERRUPT_PIN, 0x2); /* Set PUINT IRQ to 24 and INTPIN LOCK */ MCHBAR32(PUNIT_THERMAL_DEVICE_IRQ) = PUINT_THERMAL_DEVICE_IRQ_VEC_NUMBER | PUINT_THERMAL_DEVICE_IRQ_LOCK; if (!CONFIG(SOC_INTEL_GLK)) { data = MCHBAR32(0x7818); data &= 0xFFFFE01F; data |= 0x20 | 0x200; MCHBAR32(0x7818) = data; } /* Stage0 BIOS Reset Complete (RST_CPL) */ enable_bios_reset_cpl(); /* * Poll for bit 8 to check if PCODE has completed its action * in reponse to BIOS Reset complete. * We wait here till 1 ms for the bit to get set. */ stopwatch_init_msecs_expire(&sw, 1); while (!(MCHBAR32(BIOS_RESET_CPL) & PCODE_INIT_DONE)) { if (stopwatch_expired(&sw)) { printk(BIOS_DEBUG, "PCODE Init Done Failure\n"); return false; } udelay(100); } return true; }
static void set_receive_enable(int channel_offset, u8 medium, u8 coarse) { u32 reg32; printk(BIOS_SPEW, " set_receive_enable() medium=0x%x, coarse=0x%x\n", medium, coarse); reg32 = MCHBAR32(C0DRT1 + channel_offset); reg32 &= 0xf0ffffff; reg32 |= ((u32)coarse & 0x0f) << 24; MCHBAR32(C0DRT1 + channel_offset) = reg32; /* This should never happen: */ if (coarse > 0x0f) printk(BIOS_DEBUG, "set_receive_enable: coarse overflow: 0x%02x.\n", coarse); /* medium control * * 00 - 1/4 clock * 01 - 1/2 clock * 10 - 3/4 clock * 11 - 1 clock */ reg32 = MCHBAR32(RCVENMT); if (!channel_offset) { /* Channel 0 */ reg32 &= ~(3 << 2); reg32 |= medium << 2; } else { /* Channel 1 */ reg32 &= ~(3 << 0); reg32 |= medium; } MCHBAR32(RCVENMT) = reg32; }
void mainboard_romstage_entry(unsigned long bist) { // ch0 ch1 const u8 spd_addrmap[4] = { 0x50, 0, 0x52, 0 }; u8 boot_path = 0; u8 s3_resume; timestamp_init(get_initial_timestamp()); timestamp_add_now(TS_START_ROMSTAGE); /* Set southbridge and Super I/O GPIOs. */ ich7_enable_lpc(); mb_lpc_setup(); console_init(); report_bist_failure(bist); enable_smbus(); x4x_early_init(); s3_resume = southbridge_detect_s3_resume(); if (s3_resume) boot_path = BOOT_PATH_RESUME; if (MCHBAR32(PMSTS_MCHBAR) & PMSTS_WARM_RESET) boot_path = BOOT_PATH_WARM_RESET; printk(BIOS_DEBUG, "Initializing memory\n"); timestamp_add_now(TS_BEFORE_INITRAM); sdram_initialize(boot_path, spd_addrmap); timestamp_add_now(TS_AFTER_INITRAM); quick_ram_check(); printk(BIOS_DEBUG, "Memory initialized\n"); x4x_late_init(s3_resume); printk(BIOS_DEBUG, "x4x late init complete\n"); }
void intel_nehalem_finalize_smm(void) { MCHBAR32_OR(0x5500, 1 << 0); /* PAVP */ MCHBAR32_OR(0x5f00, 1 << 31); /* SA PM */ MCHBAR32_OR(0x6020, 1 << 0); /* UMA GFX */ MCHBAR32_OR(0x63fc, 1 << 0); /* VTDTRK */ MCHBAR32_OR(0x6800, 1 << 31); MCHBAR32_OR(0x7000, 1 << 31); MCHBAR32_OR(0x77fc, 1 << 0); /* Memory Controller Lockdown */ MCHBAR8(0x50fc) = 0x8f; /* Read+write the following */ MCHBAR32(0x6030) = MCHBAR32(0x6030); MCHBAR32(0x6034) = MCHBAR32(0x6034); MCHBAR32(0x6008) = MCHBAR32(0x6008); }
void init_pm(const sysinfo_t *const sysinfo) { const stepping_t stepping = sysinfo->stepping; const fsb_clock_t fsb = sysinfo->selected_timings.fsb_clock; const mem_clock_t memclk = sysinfo->selected_timings.mem_clock; MCHBAR16(0xc14) = 0; MCHBAR16(0xc20) = 0; MCHBAR32(0xfc0) = 0x001f00fd; MCHBAR32(0xfc0) |= 3 << 25; MCHBAR32(0xfc0) |= 1 << 11; MCHBAR8(0xfb0) = 3; MCHBAR8(0xf10) |= 1 << 1; if (fsb == FSB_CLOCK_667MHz) { MCHBAR16(0xc3a) = 0xea6; MCHBAR8(0xc16) = (MCHBAR8(0xc16) & 0x80) | 0x0e; } else if (fsb == FSB_CLOCK_800MHz) { MCHBAR16(0xc3a) = 0x1194; MCHBAR8(0xc16) = (MCHBAR8(0xc16) & 0x80) | 0x10; } else if (fsb == FSB_CLOCK_1067MHz) { MCHBAR16(0xc3a) = 0x1777; MCHBAR8(0xc16) = (MCHBAR8(0xc16) & 0x80) | 0x15; } MCHBAR8(0xfb8) = 3; if (fsb == FSB_CLOCK_667MHz) MCHBAR16(0xc38) = 0x0ea6; else if (fsb == FSB_CLOCK_800MHz) MCHBAR16(0xc38) = 0x1194; else if (fsb == FSB_CLOCK_1067MHz) MCHBAR16(0xc38) = 0x1777; MCHBAR8(0xf10) |= 1 << 5; MCHBAR16(0xc16) |= 3 << 12; MCHBAR32(0xf60) = 0x01030419; if (fsb == FSB_CLOCK_667MHz) { MCHBAR32(0xf00) = 0x00000600; MCHBAR32(0xf04) = 0x00001d80; } else if (fsb == FSB_CLOCK_800MHz) { MCHBAR32(0xf00) = 0x00000700; MCHBAR32(0xf04) = 0x00002380; } else if (fsb == FSB_CLOCK_1067MHz) { MCHBAR32(0xf00) = 0x00000900; MCHBAR32(0xf04) = 0x00002e80; } MCHBAR16(0xf08) = 0x730f; if (fsb == FSB_CLOCK_667MHz) MCHBAR16(0xf0c) = 0x0b96; else if (fsb == FSB_CLOCK_800MHz) MCHBAR16(0xf0c) = 0x0c99; else if (fsb == FSB_CLOCK_1067MHz) MCHBAR16(0xf0c) = 0x10a4; MCHBAR32(0xf80) |= 1 << 31; MCHBAR32(0x40) = (MCHBAR32(0x40) & ~(0x3f << 24)) | (sysinfo->cores == 4) ? (1 << 24) : 0; MCHBAR32(0x40) &= ~(1 << 19); MCHBAR32(0x40) |= 1 << 13; MCHBAR32(0x40) |= 1 << 21; MCHBAR32(0x40) |= 1 << 9; if (stepping > STEPPING_B1) { if (fsb != FSB_CLOCK_1067MHz) { MCHBAR32(0x70) |= 1 << 30; } else { MCHBAR32(0x70) &= ~(1 << 30); } } if (stepping < STEPPING_B1) MCHBAR32(0x70) |= 1 << 29; else MCHBAR32(0x70) &= ~(1 << 29); if (stepping > STEPPING_B1) { MCHBAR32(0x70) |= 1 << 28; MCHBAR32(0x70) |= 1 << 25; } if (stepping > STEPPING_B0) { if (fsb != FSB_CLOCK_667MHz) MCHBAR32(0x70) = (MCHBAR32(0x70) & ~(3<<21)) | (1 << 21); else MCHBAR32(0x70) = (MCHBAR32(0x70) & ~(3<<21)); } if (stepping > STEPPING_B2) MCHBAR32(0x44) |= 1 << 30; MCHBAR32(0x44) |= 1 << 31; if (sysinfo->cores == 2) MCHBAR32(0x44) |= 1 << 26; MCHBAR32(0x44) |= 1 << 21; MCHBAR32(0x44) = (MCHBAR32(0x44) & ~(3 << 24)) | (2 << 24); MCHBAR32(0x44) |= 1 << 5; MCHBAR32(0x44) |= 1 << 4; MCHBAR32(0x90) = (MCHBAR32(0x90) & ~7) | 4; MCHBAR32(0x94) |= 1 << 29; MCHBAR32(0x94) |= 1 << 11; if (stepping < STEPPING_B0) MCHBAR32(0x94) = (MCHBAR32(0x94) & ~(3 << 19)) | (2 << 19); if (stepping > STEPPING_B2) MCHBAR32(0x94) |= 1 << 21; MCHBAR8(0xb00) &= ~1; MCHBAR8(0xb00) |= 1 << 7; if (fsb != FSB_CLOCK_1067MHz) MCHBAR8(0x75) |= 1 << 6; else MCHBAR8(0x75) &= 1 << 1; MCHBAR8(0x77) |= 3; if (stepping >= STEPPING_B1) MCHBAR8(0x77) |= 1 << 2; if (stepping > STEPPING_B2) MCHBAR8(0x77) |= 1 << 4; if (MCHBAR16(0x90) & 0x100) MCHBAR8(0x90) &= ~(7 << 4); if (stepping >= STEPPING_B0) MCHBAR8(0xd0) |= 1 << 1; MCHBAR8(0xbd8) |= 3 << 2; if (stepping >= STEPPING_B3) MCHBAR32(0x70) |= 1 << 0; MCHBAR32(0x70) |= 1 << 3; if (stepping >= STEPPING_B0) MCHBAR32(0x70) &= ~(1 << 16); else MCHBAR32(0x70) |= 1 << 16; if (stepping >= STEPPING_B3) MCHBAR8(0xc14) |= 1 << 1; if (stepping >= STEPPING_B1) MCHBAR16(0xffc) = (MCHBAR16(0xffc) & ~0x7ff) | 0x7c0; MCHBAR16(0x48) = (MCHBAR16(0x48) & ~(0xff << 2)) | (0xaa << 2); if (stepping == STEPPING_CONVERSION_A1) { MCHBAR16(0x40) |= 1 << 12; MCHBAR32(0x94) |= 3 << 22; } const int cpu_supports_super_lfm = rdmsr(0xee).lo & (1 << 27); if ((stepping >= STEPPING_B0) && cpu_supports_super_lfm) { MCHBAR16(CLKCFG_MCHBAR) &= ~(1 << 7); MCHBAR16(CLKCFG_MCHBAR) |= 1 << 14; } else { MCHBAR16(CLKCFG_MCHBAR) &= ~(1 << 14); MCHBAR16(CLKCFG_MCHBAR) |= 1 << 7; MCHBAR32(0x44) &= ~(1 << 31); /* Was set above. */ } if ((sysinfo->gfx_type != GMCH_PM45) && (sysinfo->gfx_type != GMCH_UNKNOWN)) init_freq_scaling(sysinfo->gfx_type, sysinfo->gs45_low_power_mode); /* This has to be the last write to CLKCFG. */ if ((fsb == FSB_CLOCK_1067MHz) && (memclk == MEM_CLOCK_667MT)) MCHBAR32(CLKCFG_MCHBAR) &= ~(1 << 17); }
static void post_system_agent_init(struct pei_data *pei_data) { /* If PCIe init is skipped, set the PEG clock gating */ if (!pei_data->pcie_init) MCHBAR32(0x7010) = MCHBAR32(0x7010) | 0x01; }
static void pineview_setup_bars(void) { u8 reg8; u16 reg16; u32 reg32; /* Setting up Southbridge. In the northbridge code. */ printk(BIOS_DEBUG, "Setting up static southbridge registers..."); pci_write_config32(LPC, RCBA, (uintptr_t)DEFAULT_RCBA | 1); pci_write_config32(LPC, PMBASE, DEFAULT_PMBASE | 1); pci_write_config8(LPC, 0x44 /* ACPI_CNTL */ , 0x80); /* Enable ACPI */ pci_write_config32(LPC, GPIOBASE, DEFAULT_GPIOBASE | 1); pci_write_config8(LPC, 0x4c /* GC */ , 0x10); /* Enable GPIOs */ pci_write_config32(LPC, 0x88, 0x007c0291); pci_write_config32(PCI_DEV(0, 0x1e, 0), 0x1b, 0x20); printk(BIOS_DEBUG, " done.\n"); printk(BIOS_DEBUG, "Disabling Watchdog reboot..."); RCBA32(GCS) = RCBA32(GCS) | (1 << 5); /* No reset */ outw((1 << 11), DEFAULT_PMBASE | 0x60 | 0x08); /* halt timer */ printk(BIOS_DEBUG, " done.\n"); /* Enable upper 128bytes of CMOS */ RCBA32(0x3400) = (1 << 2); printk(BIOS_DEBUG, "Setting up static northbridge registers..."); pci_write_config8(D0F0, 0x8, 0x69); /* Set up all hardcoded northbridge BARs */ pci_write_config32(D0F0, EPBAR, DEFAULT_EPBAR | 1); pci_write_config32(D0F0, MCHBAR, (uintptr_t)DEFAULT_MCHBAR | 1); pci_write_config32(D0F0, DMIBAR, (uintptr_t)DEFAULT_DMIBAR | 1); pci_write_config32(D0F0, PMIOBAR, (uintptr_t)0x400 | 1); reg32 = MCHBAR32(0x30); MCHBAR32(0x30) = 0x21800; DMIBAR32(0x2c) = 0x86000040; pci_write_config8(D0F0, DEVEN, 0x09); pci_write_config32(PCI_DEV(0, 0x1e, 0), 0x18, 0x00020200); pci_write_config32(PCI_DEV(0, 0x1e, 0), 0x18, 0x00000000); reg8 = pci_read_config8(D0F0, 0xe5); // 0x10 reg16 = pci_read_config16(PCI_DEV(0, 0x02, 0), 0x0); // 0x8086 reg16 = pci_read_config16(D0F0, GGC); pci_write_config16(D0F0, GGC, 0x130); reg16 = pci_read_config16(D0F0, GGC); pci_write_config16(D0F0, GGC, 0x130); MCHBAR8(0xb08) = 0x20; reg8 = pci_read_config8(D0F0, 0xe6); // 0x11 reg16 = MCHBAR16(0xc8c); MCHBAR16(0xc8c) = reg16 | 0x0200; reg8 = MCHBAR8(0xc8c); MCHBAR8(0xc8c) = reg8; MCHBAR8(0xc8c) = 0x12; pci_write_config8(PCI_DEV(0, 0x02, 0), 0x62, 0x02); pci_write_config16(PCI_DEV(0, 0x02, 0), 0xe8, 0x8000); MCHBAR32(0x3004) = 0x48000000; MCHBAR32(0x3008) = 0xfffffe00; MCHBAR32(0xb08) = 0x06028220; MCHBAR32(0xff4) = 0xc6db8b5f; MCHBAR16(0xff8) = 0x024f; // PLL Voltage controlled oscillator //MCHBAR8(0xc38) = 0x04; pci_write_config16(PCI_DEV(0, 0x02, 0), 0xcc, 0x014d); reg32 = MCHBAR32(0x40); MCHBAR32(0x40) = 0x0; reg32 = MCHBAR32(0x40); MCHBAR32(0x40) = 0x8; pci_write_config8(LPC, 0x8, 0x1d); pci_write_config8(LPC, 0x8, 0x0); RCBA32(0x3410) = 0x00020465; RCBA32(0x88) = 0x0011d000; RCBA32(0x1fc) = 0x60f; RCBA32(0x1f4) = 0x86000040; RCBA32(0x214) = 0x10030509; RCBA32(0x218) = 0x00020504; RCBA32(0x220) = 0xc5; RCBA32(0x3430) = 0x1; RCBA32(0x2027) = 0x38f6a70d; RCBA16(0x3e08) = 0x0080; RCBA16(0x3e48) = 0x0080; RCBA32(0x3e0e) = 0x00000080; RCBA32(0x3e4e) = 0x00000080; RCBA32(0x2034) = 0xb24577cc; RCBA32(0x1c) = 0x03128010; RCBA32(0x2010) = 0x400; RCBA32(0x3400) = 0x4; RCBA32(0x2080) = 0x18006007; RCBA32(0x20a0) = 0x18006007; RCBA32(0x20c0) = 0x18006007; RCBA32(0x20e0) = 0x18006007; pci_write_config32(PCI_DEV(0, 0x1d, 0), 0xca, 0x1); pci_write_config32(PCI_DEV(0, 0x1d, 1), 0xca, 0x1); pci_write_config32(PCI_DEV(0, 0x1d, 2), 0xca, 0x1); pci_write_config32(PCI_DEV(0, 0x1d, 3), 0xca, 0x1); RCBA32(0x3100) = 0x42210; RCBA32(0x3108) = 0x10004321; RCBA32(0x310c) = 0x00214321; RCBA32(0x3110) = 0x1; RCBA32(0x3140) = 0x01460132; RCBA32(0x3142) = 0x02370146; RCBA32(0x3144) = 0x32010237; RCBA32(0x3146) = 0x01463201; RCBA32(0x3148) = 0x146; /* Set C0000-FFFFF to access RAM on both reads and writes */ pci_write_config8(D0F0, PAM0, 0x30); pci_write_config8(D0F0, PAM1, 0x33); pci_write_config8(D0F0, PAM2, 0x33); pci_write_config8(D0F0, PAM3, 0x33); pci_write_config8(D0F0, PAM4, 0x33); pci_write_config8(D0F0, PAM5, 0x33); pci_write_config8(D0F0, PAM6, 0x33); pci_write_config32(D0F0, SKPAD, SKPAD_NORMAL_BOOT_MAGIC); printk(BIOS_DEBUG, " done.\n"); }
/** * Find PEI executable in coreboot filesystem and execute it. * * @param pei_data: configuration data for UEFI PEI reference code */ void sdram_initialize(struct pei_data *pei_data) { struct sys_info sysinfo; int (*entry) (struct pei_data *pei_data) __attribute__ ((regparm(1))); report_platform_info(); /* Wait for ME to be ready */ intel_early_me_init(); intel_early_me_uma_size(); printk(BIOS_DEBUG, "Starting UEFI PEI System Agent\n"); memset(&sysinfo, 0, sizeof(sysinfo)); sysinfo.boot_path = pei_data->boot_mode; /* * Do not pass MRC data in for recovery mode boot, * Always pass it in for S3 resume. */ if (!vboot_recovery_mode_enabled() || pei_data->boot_mode == 2) prepare_mrc_cache(pei_data); /* If MRC data is not found we cannot continue S3 resume. */ if (pei_data->boot_mode == 2 && !pei_data->mrc_input) { printk(BIOS_DEBUG, "Giving up in sdram_initialize: No MRC data\n"); outb(0x6, 0xcf9); halt(); } /* Pass console handler in pei_data */ pei_data->tx_byte = do_putchar; /* Locate and call UEFI System Agent binary. */ entry = cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL); if (entry) { int rv; rv = entry (pei_data); if (rv) { switch (rv) { case -1: printk(BIOS_ERR, "PEI version mismatch.\n"); break; case -2: printk(BIOS_ERR, "Invalid memory frequency.\n"); break; default: printk(BIOS_ERR, "MRC returned %x.\n", rv); } die("Nonzero MRC return value.\n"); } } else { die("UEFI PEI System Agent not found.\n"); } #if CONFIG_USBDEBUG_IN_ROMSTAGE /* mrc.bin reconfigures USB, so reinit it to have debug */ usbdebug_init(); #endif /* For reference print the System Agent version * after executing the UEFI PEI stage. */ u32 version = MCHBAR32(0x5034); printk(BIOS_DEBUG, "System Agent Version %d.%d.%d Build %d\n", version >> 24 , (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); /* Send ME init done for SandyBridge here. This is done * inside the SystemAgent binary on IvyBridge. */ if (BASE_REV_SNB == (pci_read_config16(PCI_CPU_DEVICE, PCI_DEVICE_ID) & BASE_REV_MASK)) intel_early_me_init_done(ME_INIT_STATUS_SUCCESS); else intel_early_me_status(); report_memory_config(); }
void gm45_early_reset(void/*const timings_t *const timings*/) { int ch, r; /* Reset DRAM power-up settings in CLKCFG (they are not affected by system reset but may disrupt raminit). */ MCHBAR32(CLKCFG_MCHBAR) = (MCHBAR32(CLKCFG_MCHBAR) & ~(3 << 21)) | (1 << 3); /*\ Next settings are the real purpose of this function: If these steps are not performed, reset results in power off. \*/ /* Initialize some DRAM settings to 1 populated rank of 128MB. */ FOR_EACH_CHANNEL(ch) { /* Configure DRAM control mode. */ MCHBAR32(CxDRC0_MCHBAR(ch)) = (MCHBAR32(CxDRC0_MCHBAR(ch)) & ~CxDRC0_RANKEN_MASK) | (ch ? 0 : CxDRC0_RANKEN(0)); MCHBAR32(CxDRC1_MCHBAR(ch)) = (MCHBAR32(CxDRC1_MCHBAR(ch)) | CxDRC1_NOTPOP_MASK) & ~(ch ? 0 : CxDRC1_NOTPOP(0)); MCHBAR32(CxDRC2_MCHBAR(ch)) = (MCHBAR32(CxDRC2_MCHBAR(ch)) | CxDRC2_NOTPOP_MASK) & ~(ch ? 0 : CxDRC2_NOTPOP(0)); /*if (timings && (timings->mem_clock == MEM_CLOCK_1067MT)) MCHBAR32(CxDRC2_MCHBAR(ch)) |= CxDRC2_CLK1067MT;*/ /* Program rank boundaries (CxDRBy). */ for (r = 0; r < RANKS_PER_CHANNEL; r += 2) MCHBAR32(CxDRBy_MCHBAR(ch, r)) = CxDRBy_BOUND_MB(r, 128) | CxDRBy_BOUND_MB(r+1, 128); } /* Set DCC mode to no operation and do magic 0xf0 thing. */ MCHBAR32(DCC_MCHBAR) = (MCHBAR32(DCC_MCHBAR) & ~DCC_CMD_MASK) | DCC_CMD_NOP; u8 reg8 = pci_read_config8(PCI_DEV(0, 0, 0), 0xf0); pci_write_config8(PCI_DEV(0, 0, 0), 0xf0, reg8 & ~(1 << 2)); reg8 = pci_read_config8(PCI_DEV(0, 0, 0), 0xf0); pci_write_config8(PCI_DEV(0, 0, 0), 0xf0, reg8 | (1 << 2)); /* Normally, we would set this after successful raminit. */ MCHBAR32(DCC_MCHBAR) |= (1 << 19); /* Perform system reset through CF9 interface. */ outb(0x02, 0xcf9); /* Set system reset bit. */ outb(0x06, 0xcf9); /* Set cpu reset bit, too. */ while (1) asm("hlt"); }
static void init_freq_scaling(const gmch_gfx_t sku, const int low_power_mode) { int i; MCHBAR32(0x11cc) = (MCHBAR32(0x11cc) & ~(0x1f)) | 0x17; switch (sku) { case GMCH_GM45: case GMCH_GE45: case GMCH_GS45: case GMCH_GM47: case GMCH_GM49: break; default: /* No more to be done for the others. */ return; } static const u32 voltage_mask = (0x1f << 24) | (0x1f << 16) | (0x1f << 8) | 0x1f; MCHBAR32(0x1120) = (MCHBAR32(0x1120) & ~voltage_mask) | 0x10111213; MCHBAR32(0x1124) = (MCHBAR32(0x1124) & ~voltage_mask) | 0x14151617; MCHBAR32(0x1128) = (MCHBAR32(0x1128) & ~voltage_mask) | 0x18191a1b; MCHBAR32(0x112c) = (MCHBAR32(0x112c) & ~voltage_mask) | 0x1c1d1e1f; MCHBAR32(0x1130) = (MCHBAR32(0x1130) & ~voltage_mask) | 0x00010203; MCHBAR32(0x1134) = (MCHBAR32(0x1134) & ~voltage_mask) | 0x04050607; MCHBAR32(0x1138) = (MCHBAR32(0x1138) & ~voltage_mask) | 0x08090a0b; MCHBAR32(0x113c) = (MCHBAR32(0x113c) & ~voltage_mask) | 0x0c0d0e0f; /* Program frequencies. */ static const u32 frequencies_from_sku_vco[][4][8] = { /* GM45/GE45/GS45_perf */ { /* VCO 2666 */ { 0xcd, 0xbc, 0x9b, 0x8a, 0x79, 0x78, 0x67, 0x56 }, /* VCO 3200 */ { 0xcd, 0xac, 0x9b, 0x8a, 0x89, 0x78, 0x67, 0x56 }, /* VCO 4000 */ { 0xac, 0x9b, 0x9a, 0x89, 0x89, 0x68, 0x56, 0x45 }, /* VCO 5333 */ { 0xab, 0x9a, 0x79, 0x68, 0x57, 0x56, 0x45, 0x34 }, }, /* GS45_low_power */ { /* VCO 2666 */ { 0xcd, 0x8a }, /* VCO 3200 */ { 0xcd, 0x89 }, /* VCO 4000 */ { 0xac, 0x89 }, /* VCO 5333 */ { 0xab, 0x68 }, }, /* GM47 */ { /* VCO 2666 */ { 0xcd, 0xcd, 0xbc, 0x9b, 0x79, 0x78, 0x67, 0x56 }, /* VCO 3200 */ { 0xde, 0xcd, 0xac, 0x9b, 0x89, 0x78, 0x67, 0x56 }, /* VCO 4000 */ { 0xcd, 0xac, 0x9b, 0x9a, 0x89, 0x68, 0x56, 0x45 }, /* VCO 5333 */ { 0xac, 0xab, 0x9a, 0x79, 0x68, 0x56, 0x45, 0x34 }, }, /* GM49 */ { /* VCO 2666 */ { }, /* VCO 3200 */ { 0xef, 0xde, 0xcd, 0xac, 0x89, 0x78, 0x67, 0x56 }, /* VCO 4000 */ { 0xef, 0xde, 0xac, 0x9b, 0x89, 0x68, 0x56, 0x45 }, /* VCO 5333 */ { 0xce, 0xbd, 0xab, 0x9a, 0x68, 0x57, 0x45, 0x34 }, }}; const int sku_index = sku_freq_index(sku, low_power_mode); const int vco_index = raminit_read_vco_index(); const int reg_limit = low_power_mode ? 1 : 4; if (sku == GMCH_GM49) MCHBAR8(0x1110+3) = 0x1b; else MCHBAR8(0x1110+3) = 0x17; MCHBAR8(0x1110+1) = 0x17; if (!low_power_mode) { MCHBAR8(0x1114+3) = 0x17; MCHBAR8(0x1114+1) = 0x17; MCHBAR8(0x1118+3) = 0x17; MCHBAR8(0x1118+1) = 0x17; MCHBAR8(0x111c+3) = 0x17; MCHBAR8(0x111c+1) = 0x17; } for (i = 0; i < reg_limit; ++i) { const int mchbar = 0x1110 + (i * 4); MCHBAR8(mchbar + 2) = frequencies_from_sku_vco [sku_index][vco_index][i * 2 + 0]; MCHBAR8(mchbar + 0) = frequencies_from_sku_vco [sku_index][vco_index][i * 2 + 1]; } if (low_power_mode) { MCHBAR16(0x1190) = (MCHBAR16(0x1190) & ~((7 << 8) | (7 << 4) | 7)) | (1 << 8) | (1 << 4) | 1; } else { MCHBAR16(0x1190) = (MCHBAR16(0x1190) & ~((7 << 8) | (7 << 4))) | 7; if (sku == GMCH_GS45) /* performance mode */ MCHBAR32(0x0ffc) &= ~(1 << 31); } MCHBAR16(0x0fc0) |= (1 << 11); MCHBAR16(0x11b8) = 0x333c; MCHBAR16(0x11c0 + 2) = 0x0303; MCHBAR32(0x11c4) = 0x0a030a03; MCHBAR16(0x1100) = (MCHBAR16(0x1100) & ~(0x1f << 8)) | (3 << 8); MCHBAR16(0x11b8 + 2) = 0x4000; }
static void gma_pm_init_pre_vbios(struct device *dev) { u32 reg32; printk(BIOS_DEBUG, "GT Power Management Init\n"); gtt_res = find_resource(dev, PCI_BASE_ADDRESS_0); if (!gtt_res || !gtt_res->base) return; if (bridge_silicon_revision() < IVB_STEP_C0) { /* 1: Enable force wake */ gtt_write(0xa18c, 0x00000001); gtt_poll(0x130090, (1 << 0), (1 << 0)); } else { gtt_write(0xa180, 1 << 5); gtt_write(0xa188, 0xffff0001); gtt_poll(0x130040, (1 << 0), (1 << 0)); } if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) { /* 1d: Set GTT+0x42004 [15:14]=11 (SnB C1+) */ reg32 = gtt_read(0x42004); reg32 |= (1 << 14) | (1 << 15); gtt_write(0x42004, reg32); } if (bridge_silicon_revision() >= IVB_STEP_A0) { /* Display Reset Acknowledge Settings */ reg32 = gtt_read(0x45010); reg32 |= (1 << 1) | (1 << 0); gtt_write(0x45010, reg32); } /* 2: Get GT SKU from GTT+0x911c[13] */ reg32 = gtt_read(0x911c); if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) { if (reg32 & (1 << 13)) { printk(BIOS_DEBUG, "SNB GT1 Power Meter Weights\n"); gtt_write_powermeter(snb_pm_gt1); } else { printk(BIOS_DEBUG, "SNB GT2 Power Meter Weights\n"); gtt_write_powermeter(snb_pm_gt2); } } else { u32 unit = MCHBAR32(0x5938) & 0xf; if (reg32 & (1 << 13)) { /* GT1 SKU */ printk(BIOS_DEBUG, "IVB GT1 Power Meter Weights\n"); gtt_write_powermeter(ivb_pm_gt1); } else { /* GT2 SKU */ u32 tdp = MCHBAR32(0x5930) & 0x7fff; tdp /= (1 << unit); if (tdp <= 17) { /* <=17W ULV */ printk(BIOS_DEBUG, "IVB GT2 17W " "Power Meter Weights\n"); gtt_write_powermeter(ivb_pm_gt2_17w); } else if ((tdp >= 25) && (tdp <= 35)) { /* 25W-35W */ printk(BIOS_DEBUG, "IVB GT2 25W-35W " "Power Meter Weights\n"); gtt_write_powermeter(ivb_pm_gt2_35w); } else { /* All others */ printk(BIOS_DEBUG, "IVB GT2 35W " "Power Meter Weights\n"); gtt_write_powermeter(ivb_pm_gt2_35w); } } } /* 3: Gear ratio map */ gtt_write(0xa004, 0x00000010); /* 4: GFXPAUSE */ gtt_write(0xa000, 0x00070020); /* 5: Dynamic EU trip control */ gtt_write(0xa080, 0x00000004); /* 6: ECO bits */ reg32 = gtt_read(0xa180); reg32 |= (1 << 26) | (1 << 31); /* (bit 20=1 for SNB step D1+ / IVB A0+) */ if (bridge_silicon_revision() >= SNB_STEP_D1) reg32 |= (1 << 20); gtt_write(0xa180, reg32); /* 6a: for SnB step D2+ only */ if (((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) && (bridge_silicon_revision() >= SNB_STEP_D2)) { reg32 = gtt_read(0x9400); reg32 |= (1 << 7); gtt_write(0x9400, reg32); reg32 = gtt_read(0x941c); reg32 &= 0xf; reg32 |= (1 << 1); gtt_write(0x941c, reg32); gtt_poll(0x941c, (1 << 1), (0 << 1)); } if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) { reg32 = gtt_read(0x907c); reg32 |= (1 << 16); gtt_write(0x907c, reg32); /* 6b: Clocking reset controls */ gtt_write(0x9424, 0x00000001); } else { /* 6b: Clocking reset controls */ gtt_write(0x9424, 0x00000000); } /* 7 */ if (gtt_poll(0x138124, (1 << 31), (0 << 31))) { gtt_write(0x138128, 0x00000029); /* Mailbox Data */ gtt_write(0x138124, 0x80000004); /* Mailbox Cmd for RC6 VID */ if (gtt_poll(0x138124, (1 << 31), (0 << 31))) gtt_write(0x138124, 0x8000000a); gtt_poll(0x138124, (1 << 31), (0 << 31)); } /* 8 */ gtt_write(0xa090, 0x00000000); /* RC Control */ gtt_write(0xa098, 0x03e80000); /* RC1e Wake Rate Limit */ gtt_write(0xa09c, 0x0028001e); /* RC6/6p Wake Rate Limit */ gtt_write(0xa0a0, 0x0000001e); /* RC6pp Wake Rate Limit */ gtt_write(0xa0a8, 0x0001e848); /* RC Evaluation Interval */ gtt_write(0xa0ac, 0x00000019); /* RC Idle Hysteresis */ /* 9 */ gtt_write(0x2054, 0x0000000a); /* Render Idle Max Count */ gtt_write(0x12054,0x0000000a); /* Video Idle Max Count */ gtt_write(0x22054,0x0000000a); /* Blitter Idle Max Count */ /* 10 */ gtt_write(0xa0b0, 0x00000000); /* Unblock Ack to Busy */ gtt_write(0xa0b4, 0x000003e8); /* RC1e Threshold */ gtt_write(0xa0b8, 0x0000c350); /* RC6 Threshold */ gtt_write(0xa0bc, 0x000186a0); /* RC6p Threshold */ gtt_write(0xa0c0, 0x0000fa00); /* RC6pp Threshold */ /* 11 */ gtt_write(0xa010, 0x000f4240); /* RP Down Timeout */ gtt_write(0xa014, 0x12060000); /* RP Interrupt Limits */ gtt_write(0xa02c, 0x00015f90); /* RP Up Threshold */ gtt_write(0xa030, 0x000186a0); /* RP Down Threshold */ gtt_write(0xa068, 0x000186a0); /* RP Up EI */ gtt_write(0xa06c, 0x000493e0); /* RP Down EI */ gtt_write(0xa070, 0x0000000a); /* RP Idle Hysteresis */ /* 11a: Enable Render Standby (RC6) */ if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) { /* * IvyBridge should also support DeepRenderStandby. * * Unfortunately it does not work reliably on all SKUs so * disable it here and it can be enabled by the kernel. */ gtt_write(0xa090, 0x88040000); /* HW RC Control */ } else { gtt_write(0xa090, 0x88040000); /* HW RC Control */ } /* 12: Normal Frequency Request */ /* RPNFREQ_VAL comes from MCHBAR 0x5998 23:16 */ /* only the lower 7 bits are used and shifted left by 25 */ reg32 = MCHBAR32(0x5998); reg32 >>= 16; reg32 &= 0x7f; reg32 <<= 25; gtt_write(0xa008, reg32); /* 13: RP Control */ gtt_write(0xa024, 0x00000592); /* 14: Enable PM Interrupts */ gtt_write(0x4402c, 0x03000076); /* Clear 0x6c024 [8:6] */ reg32 = gtt_read(0x6c024); reg32 &= ~0x000001c0; gtt_write(0x6c024, reg32); /* Initialize DP buffer translation with recommended defaults */ gtt_write(0xe4f00, 0x0100030c); gtt_write(0xe4f04, 0x00b8230c); gtt_write(0xe4f08, 0x06f8930c); gtt_write(0xe4f0c, 0x05f8e38e); gtt_write(0xe4f10, 0x00b8030c); gtt_write(0xe4f14, 0x0b78830c); gtt_write(0xe4f18, 0x09f8d3cf); gtt_write(0xe4f1c, 0x01e8030c); gtt_write(0xe4f20, 0x09f863cf); gtt_write(0xe4f24, 0x0ff803cf); }