aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/intel/x4x/x4x.h
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2015-08-19 15:16:59 +1000
committerMartin Roth <martinroth@google.com>2015-12-29 18:03:33 +0100
commit43a1f780ff6809f758092136b0b38c6917c27340 (patch)
treeebb641caf31e477a61addedc46678ba6be4b4889 /src/northbridge/intel/x4x/x4x.h
parente7a336ac29b1ef5aaa1b0aa4926ed75829b491b1 (diff)
northbridge/intel/x4x: Intel 4-series northbridge support
Boots to console on Gigabyte GA-G41M-ES2L Ram initialization *not* included in this patch VGA native init works on analog connector Change-Id: I5262f73fd03d5e5c12e9f11d027bdfbbf0ddde82 Signed-off-by: Damien Zammit <damien@zamaudio.com> Reviewed-on: https://review.coreboot.org/11305 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Diffstat (limited to 'src/northbridge/intel/x4x/x4x.h')
-rw-r--r--src/northbridge/intel/x4x/x4x.h320
1 files changed, 320 insertions, 0 deletions
diff --git a/src/northbridge/intel/x4x/x4x.h b/src/northbridge/intel/x4x/x4x.h
new file mode 100644
index 0000000000..89ca9313b9
--- /dev/null
+++ b/src/northbridge/intel/x4x/x4x.h
@@ -0,0 +1,320 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2008 coresystems GmbH
+ * 2012 secunet Security Networks AG
+ * Copyright (C) 2015 Damien Zammit <damien@zamaudio.com>
+ *
+ * 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.
+ */
+
+#ifndef __NORTHBRIDGE_INTEL_X4X_H__
+#define __NORTHBRIDGE_INTEL_X4X_H__
+
+#include <northbridge/intel/x4x/iomap.h>
+#include <southbridge/intel/i82801gx/i82801gx.h>
+
+/*
+ * D0:F0
+ */
+#define D0F0_EPBAR_LO 0x40
+#define D0F0_EPBAR_HI 0x44
+#define D0F0_MCHBAR_LO 0x48
+#define D0F0_MCHBAR_HI 0x4c
+#define D0F0_GGC 0x52
+#define D0F0_DEVEN 0x54
+#define D0F0_PCIEXBAR_LO 0x60
+#define D0F0_PCIEXBAR_HI 0x64
+#define D0F0_DMIBAR_LO 0x68
+#define D0F0_DMIBAR_HI 0x6c
+#define D0F0_PMBASE 0x78
+#define D0F0_PAM(x) (0x90+(x)) /* 0-6*/
+#define D0F0_REMAPBASE 0x98
+#define D0F0_REMAPLIMIT 0x9a
+#define D0F0_SMRAM 0x9d
+#define D0F0_ESMRAMC 0x9e
+#define D0F0_TOM 0xa0
+#define D0F0_TOUUD 0xa2
+#define D0F0_TOLUD 0xb0
+#define D0F0_GBSM 0xa4
+#define D0F0_BGSM 0xa8
+#define D0F0_TSEG 0xac
+#define D0F0_SKPD 0xdc /* Scratchpad Data */
+#define D0F0_CAPID0 0xe0
+
+/*
+ * D1:F0 PEG
+ */
+#define PEG_CAP 0xa2
+#define SLOTCAP 0xb4
+#define PEGLC 0xec
+#define D1F0_VCCAP 0x104
+#define D1F0_VC0RCTL 0x114
+
+/*
+ * Graphics frequencies
+ */
+#define GCFGC_PCIDEV PCI_DEV(0, 2, 0)
+#define GCFGC_OFFSET 0xf0
+#define GCFGC_CR_SHIFT 0
+#define GCFGC_CR_MASK (0xf << GCFGC_CR_SHIFT)
+#define GCFGC_CS_SHIFT 8
+#define GCFGC_CS_MASK (0xf << GCFGC_CS_SHIFT)
+#define GCFGC_CD_SHIFT 12
+#define GCFGC_CD_MASK (0x1 << GCFGC_CD_SHIFT)
+#define GCFGC_UPDATE_SHIFT 5
+#define GCFGC_UPDATE (0x1 << GCFGC_UPDATE_SHIFT)
+
+/*
+ * MCHBAR
+ */
+
+#define MCHBAR8(x) *((volatile u8 *)(DEFAULT_MCHBAR + x))
+#define MCHBAR16(x) *((volatile u16 *)(DEFAULT_MCHBAR + x))
+#define MCHBAR32(x) *((volatile u32 *)(DEFAULT_MCHBAR + x))
+
+#define PMSTS_MCHBAR 0x0f14 /* Self refresh channel status */
+#define PMSTS_WARM_RESET (1 << 1)
+#define PMSTS_BOTH_SELFREFRESH (1 << 0)
+
+#define CLKCFG_MCHBAR 0x0c00
+#define CLKCFG_FSBCLK_SHIFT 0
+#define CLKCFG_FSBCLK_MASK (7 << CLKCFG_FSBCLK_SHIFT)
+#define CLKCFG_MEMCLK_SHIFT 4
+#define CLKCFG_MEMCLK_MASK (7 << CLKCFG_MEMCLK_SHIFT)
+#define CLKCFG_UPDATE (1 << 12)
+
+#define SSKPD_MCHBAR 0x0c1c
+#define SSKPD_CLK_SHIFT 0
+#define SSKPD_CLK_MASK (7 << SSKPD_CLK_SHIFT)
+
+/*
+ * DMIBAR
+ */
+
+#define DMIBAR8(x) *((volatile u8 *)(DEFAULT_DMIBAR + x))
+#define DMIBAR16(x) *((volatile u16 *)(DEFAULT_DMIBAR + x))
+#define DMIBAR32(x) *((volatile u32 *)(DEFAULT_DMIBAR + x))
+
+#define DMIVC0RCTL 0x14
+#define DMIVC1RCTL 0x20
+#define DMIVC1RSTS 0x26
+#define DMIESD 0x44
+#define DMILE1D 0x50
+#define DMILE1A 0x58
+#define DMILE2D 0x60
+#define DMILE2A 0x68
+
+/*
+ * EPBAR
+ */
+
+#define EPBAR8(x) *((volatile u8 *)(DEFAULT_EPBAR + x))
+#define EPBAR16(x) *((volatile u16 *)(DEFAULT_EPBAR + x))
+#define EPBAR32(x) *((volatile u32 *)(DEFAULT_EPBAR + x))
+
+#define EPESD 0x44
+#define EPLE1D 0x50
+#define EPLE1A 0x58
+#define EPLE2D 0x60
+
+#define NOP_CMD 0x2
+#define PRECHARGE_CMD 0x4
+#define MRS_CMD 0x6
+#define EMRS_CMD 0x8
+#define EMRS1_CMD (EMRS_CMD | 0x10)
+#define EMRS2_CMD (EMRS_CMD | 0x20)
+#define EMRS3_CMD (EMRS_CMD | 0x30)
+#define ZQCAL_CMD 0xa
+#define CBR_CMD 0xc
+#define NORMALOP_CMD 0xe
+
+#define TOTAL_CHANNELS 2
+#define TOTAL_DIMMS 4
+
+#define DIMM_IS_POPULATED(dimms, idx) (dimms[idx].card_type != 0)
+#define IF_DIMM_POPULATED(dimms, idx) if (dimms[idx].card_type != 0)
+#define ONLY_DIMMA_IS_POPULATED(dimms, ch) ( \
+ (DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2) && \
+ !DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3)))
+#define ONLY_DIMMB_IS_POPULATED(dimms, ch) ( \
+ (DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3) && \
+ !DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2)))
+#define BOTH_DIMMS_ARE_POPULATED(dimms, ch) ( \
+ (DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2) && \
+ (DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3))))
+#define FOR_EACH_DIMM(idx) \
+ for (idx = 0; idx < TOTAL_DIMMS; ++idx)
+#define FOR_EACH_POPULATED_DIMM(dimms, idx) \
+ FOR_EACH_DIMM(idx) IF_DIMM_POPULATED(dimms, idx)
+#define CHANNEL_IS_POPULATED(dimms, idx) ((dimms[idx<<1].card_type != 0) || (dimms[(idx<<1) + 1].card_type != 0))
+#define CHANNEL_IS_CARDF(dimms, idx) ((dimms[idx<<1].card_type == 0xf) || (dimms[(idx<<1) + 1].card_type == 0xf))
+#define IF_CHANNEL_POPULATED(dimms, idx) if ((dimms[idx<<1].card_type != 0) || (dimms[(idx<<1) + 1].card_type != 0))
+#define FOR_EACH_CHANNEL(idx) \
+ for (idx = 0; idx < TOTAL_CHANNELS; ++idx)
+#define FOR_EACH_POPULATED_CHANNEL(dimms, idx) \
+ FOR_EACH_CHANNEL(idx) IF_CHANNEL_POPULATED(dimms, idx)
+
+#define RANKS_PER_CHANNEL 4
+#define RANK_IS_POPULATED(dimms, ch, r) \
+ ((dimms[ch<<1].card_type && ((r) < dimms[ch<<1].ranks)) || \
+ (dimms[(ch<<1) + 1].card_type && ((r) >= 2) && ((r) < (dimms[(ch<<1) + 1].ranks + 2))))
+#define IF_RANK_POPULATED(dimms, ch, r) \
+ if ((dimms[ch<<1].card_type && ((r) < dimms[ch<<1].ranks)) || \
+ (dimms[(ch<<1) + 1].card_type && ((r) >= 2) && ((r) < (dimms[(ch<<1) + 1].ranks + 2))))
+#define FOR_EACH_RANK_IN_CHANNEL(r) \
+ for (r = 0; r < RANKS_PER_CHANNEL; ++r)
+#define FOR_EACH_POPULATED_RANK_IN_CHANNEL(dimms, ch, r) \
+ FOR_EACH_RANK_IN_CHANNEL(r) IF_RANK_POPULATED(dimms, ch, r)
+#define FOR_EACH_RANK(ch, r) \
+ FOR_EACH_CHANNEL(ch) FOR_EACH_RANK_IN_CHANNEL(r)
+#define FOR_EACH_POPULATED_RANK(dimms, ch, r) \
+ FOR_EACH_RANK(ch, r) IF_RANK_POPULATED(dimms, ch, r)
+
+#define DDR3_MAX_CAS 18
+
+enum fsb_clock {
+ FSB_CLOCK_800MHz = 0,
+ FSB_CLOCK_1066MHz = 1,
+ FSB_CLOCK_1333MHz = 2,
+};
+
+enum mem_clock {
+ MEM_CLOCK_400MHz = 0,
+ MEM_CLOCK_533MHz = 1,
+ MEM_CLOCK_667MHz = 2,
+ MEM_CLOCK_800MHz = 3,
+ MEM_CLOCK_1066MHz = 4,
+ MEM_CLOCK_1333MHz = 5,
+};
+
+enum ddr {
+ DDR2 = 2,
+ DDR3 = 3,
+};
+
+enum ddrxspd {
+ DDR2SPD = 0x8,
+ DDR3SPD = 0xb,
+};
+
+enum chip_width { /* as in DDR3 spd */
+ CHIP_WIDTH_x4 = 0,
+ CHIP_WIDTH_x8 = 1,
+ CHIP_WIDTH_x16 = 2,
+ CHIP_WIDTH_x32 = 3,
+};
+
+enum chip_cap { /* as in DDR3 spd */
+ CHIP_CAP_256M = 0,
+ CHIP_CAP_512M = 1,
+ CHIP_CAP_1G = 2,
+ CHIP_CAP_2G = 3,
+ CHIP_CAP_4G = 4,
+ CHIP_CAP_8G = 5,
+ CHIP_CAP_16G = 6,
+};
+
+struct timings {
+ unsigned int CAS;
+ enum fsb_clock fsb_clk;
+ enum mem_clock mem_clk;
+ unsigned int tRAS;
+ unsigned int tRP;
+ unsigned int tRCD;
+ unsigned int tWR;
+ unsigned int tRFC;
+ unsigned int tWTR;
+ unsigned int tRRD;
+ unsigned int tRTP;
+};
+
+struct dimminfo {
+ unsigned int card_type; /* 0x0: unpopulated,
+ 0xa - 0xf: raw card type A - F */
+ enum chip_width width;
+ enum chip_cap chip_capacity;
+ unsigned int page_size; /* of whole DIMM in Bytes (4096 or 8192) */
+ unsigned int sides;
+ unsigned int banks;
+ unsigned int ranks;
+ unsigned int rows;
+ unsigned int cols;
+ unsigned int cas_latencies;
+ unsigned int tAAmin;
+ unsigned int tCKmin;
+ unsigned int tWR;
+ unsigned int tRP;
+ unsigned int tRCD;
+ unsigned int tRAS;
+ unsigned int rank_capacity_mb; /* per rank in Mega Bytes */
+ u8 spd_data[256];
+};
+
+/* The setup is up to two DIMMs per channel */
+struct sysinfo {
+ int txt_enabled;
+ int cores;
+ int boot_path;
+ int max_ddr2_mhz;
+ int max_ddr3_mt;
+ enum fsb_clock max_fsb;
+ int max_fsb_mhz;
+ int max_render_mhz;
+ int enable_igd;
+ int enable_peg;
+ u16 ggc;
+
+ int dimm_config[2];
+ int dimms_per_ch;
+ int spd_type;
+ int channel_capacity[2];
+ struct timings selected_timings;
+ struct dimminfo dimms[4];
+ u8 spd_map[4];
+};
+
+enum ddr2_signals {
+ CLKSET0 = 0,
+ CTRL0,
+ CLKSET1,
+ CMD,
+ CTRL1,
+ CTRL2,
+ CTRL3,
+ DQS1,
+ DQS2,
+ DQS3,
+ DQS4,
+ DQS5,
+ DQS6,
+ DQS7,
+ DQS8,
+ DQ1,
+ DQ2,
+ DQ3,
+ DQ4,
+ DQ5,
+ DQ6,
+ DQ7,
+ DQ8
+};
+
+void x4x_early_init(void);
+u32 decode_igd_memory_size(u32 gms);
+u32 decode_igd_gtt_size(u32 gsm);
+u8 decode_pciebar(u32 *const base, u32 *const len);
+void sdram_initialize(int boot_path, const u8 *spd_map);
+void raminit_ddr2(struct sysinfo *);
+
+struct acpi_rsdp;
+unsigned long northbridge_write_acpi_tables(device_t device, unsigned long start, struct acpi_rsdp *rsdp);
+
+#endif /* __NORTHBRIDGE_INTEL_X4X_H__ */