Skip to contentSkip to conversation

x86: Add additional system setup for ivybridge

PATCH Superseded Simon Glass 3 participants 54 messages Nov 12, 2014 – Nov 14, 2014

Subsystems (5)
x86 Kbuild PCI Library code +1 more subsystems

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

cover x86: Add additional system setup for ivybridge

This series adds full support for the LPC (Low Pin Count) bridge, the PCH (Platform Controller Hub), PCI devices like USB and SATA and more CPU init support (turbo mode, etc.)

With this series, chromebook_link can use SATA and USB at the command line.

Simon Glass (33):
Add build date values to Makefile
Align embedded device tree correctly
Add ALIGN_DOWN() to find next smallest alignment
pci: Update pci_ids.h to include some missing IDs
x86: Remove board_early_init_r()
x86: Panic if there is not relocation data
x86: Ensure that all relocation data is included in the image
WIP: x86: Drop u-boot.srec from the Makefile
x86: Factor out common values in the link script
rtc: mc146818: Set up RTC at start of day
x86: Add ioapic.h header
x86: pci: Add handlers before and after a PCI hose scan
x86: config: Enable plug-and-play for link PCI
pci: Add functions to read and write a BAR address
x86: ivybridge: Add support for BD82x6x PCH
x86: Add basic i8259 implementation
x86: Add ISA DMA implementation
x86: Add a simple header file for ACPI
x86: ivybridge: Add PCH init
x86: ivybridge: Add additional LPC init
x86: dts: Move PCI peripherals into a pci node
x86: dts: Add LPC settings for link
x86: ivybridge: Add SATA init
x86: dts: Add SATA settings for link
x86: ivybridge: Set up EHCI USB
x86: config: Enable USB on link
x86: ivybridge: Set up XHCI USB
x86: Add Intel speedstep and turbo mode code
x86: Add LAPIC setup code
x86: Add init for model 206AX CPU
x86: Drop some msr functions that we don't support
x86: ivybridge: Add northbridge init functions
x86: config: Enable SPI for chromebook_link

 Makefile                                          |  12 +-
 arch/x86/cpu/Makefile                             |   2 +
 arch/x86/cpu/config.mk                            |   5 +-
 arch/x86/cpu/coreboot/coreboot.c                  |  11 -
 arch/x86/cpu/ivybridge/Makefile                   |   7 +
 arch/x86/cpu/ivybridge/bd82x6x.c                  | 135 ++++++
 arch/x86/cpu/ivybridge/lpc.c                      | 529 +++++++++++++++++++++-
 arch/x86/cpu/ivybridge/model_206ax.c              | 514 +++++++++++++++++++++
 arch/x86/cpu/ivybridge/northbridge.c              | 188 ++++++++
 arch/x86/cpu/ivybridge/pch.c                      | 123 +++++
 arch/x86/cpu/ivybridge/pci.c                      |  40 ++
 arch/x86/cpu/ivybridge/sata.c                     | 243 ++++++++++
 arch/x86/cpu/ivybridge/usb_ehci.c                 |  29 ++
 arch/x86/cpu/ivybridge/usb_xhci.c                 |  32 ++
 arch/x86/cpu/lapic.c                              |  68 +++
 arch/x86/cpu/pci.c                                |  14 +-
 arch/x86/cpu/turbo.c                              |  98 ++++
 arch/x86/cpu/u-boot.lds                           |  17 +-
 arch/x86/dts/link.dts                             |  41 +-
 arch/x86/include/asm/acpi.h                       |  24 +
 arch/x86/include/asm/arch-ivybridge/bd82x6x.h     |  21 +
 arch/x86/include/asm/arch-ivybridge/model_206ax.h |   4 +
 arch/x86/include/asm/arch-ivybridge/pch.h         | 120 +++++
 arch/x86/include/asm/arch-ivybridge/sandybridge.h |  13 +-
 arch/x86/include/asm/i8259.h                      |   3 +
 arch/x86/include/asm/ioapic.h                     |  38 ++
 arch/x86/include/asm/isa_dma.h                    |  14 +
 arch/x86/include/asm/lapic.h                      | 123 +++++
 arch/x86/include/asm/msr-index.h                  |   2 +
 arch/x86/include/asm/msr.h                        |  11 -
 arch/x86/include/asm/pci.h                        |   3 +
 arch/x86/include/asm/post.h                       |   1 +
 arch/x86/include/asm/speedstep.h                  |  89 ++++
 arch/x86/include/asm/turbo.h                      |  31 ++
 arch/x86/lib/Makefile                             |   2 +
 arch/x86/lib/i8259.c                              | 134 ++++++
 arch/x86/lib/isa_dma.c                            |  56 +++
 arch/x86/lib/relocate.c                           |   3 +
 board/google/chromebook_link/link.c               |   5 -
 common/board_r.c                                  |   3 -
 doc/device-tree-bindings/ata/intel-sata.txt       |  26 ++
 doc/device-tree-bindings/misc/intel-lpc.txt       |  47 +-
 drivers/pci/pci.c                                 |  24 +-
 drivers/rtc/mc146818.c                            |  49 +-
 include/common.h                                  |  15 +
 include/configs/chromebook_link.h                 |  11 +-
 include/fdtdec.h                                  |   2 +
 include/pci.h                                     |  23 +
 include/pci_ids.h                                 | 187 +++++++-
 include/rtc.h                                     |   7 +
 lib/fdtdec.c                                      |   2 +
 scripts/Makefile.lib                              |   2 +
 52 files changed, 3125 insertions(+), 78 deletions(-)
 create mode 100644 arch/x86/cpu/ivybridge/bd82x6x.c
 create mode 100644 arch/x86/cpu/ivybridge/model_206ax.c
 create mode 100644 arch/x86/cpu/ivybridge/northbridge.c
 create mode 100644 arch/x86/cpu/ivybridge/pch.c
 create mode 100644 arch/x86/cpu/ivybridge/sata.c
 create mode 100644 arch/x86/cpu/ivybridge/usb_ehci.c
 create mode 100644 arch/x86/cpu/ivybridge/usb_xhci.c
 create mode 100644 arch/x86/cpu/lapic.c
 create mode 100644 arch/x86/cpu/turbo.c
 create mode 100644 arch/x86/include/asm/acpi.h
 create mode 100644 arch/x86/include/asm/arch-ivybridge/bd82x6x.h
 create mode 100644 arch/x86/include/asm/ioapic.h
 create mode 100644 arch/x86/include/asm/isa_dma.h
 create mode 100644 arch/x86/include/asm/speedstep.h
 create mode 100644 arch/x86/include/asm/turbo.h
 create mode 100644 arch/x86/lib/i8259.c
 create mode 100644 arch/x86/lib/isa_dma.c
 create mode 100644 doc/device-tree-bindings/ata/intel-sata.txt
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#1 lore raw

PATCH 1/33 Add build date values to Makefile

At present there is a string for the build date and time. In the case of an Real Time Clock which needs to be reset, it is useful to reset it to the build date, since it can't be earlier than that.

---

 Makefile | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
Makefile +6 -1
index 8e94948..fb72c29 100644
@@ -1146,7 +1146,12 @@ endef
 
 define filechk_timestamp.h
 	(LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"'; \
-	LC_ALL=C date +'#define U_BOOT_TIME "%T"')
+	LC_ALL=C date +'#define U_BOOT_TIME "%T"'; \
+	LC_ALL=C date +'#define U_BOOT_DAY %-d'; \
+	LC_ALL=C date +'#define U_BOOT_MONTH %-m'; \
+	LC_ALL=C date +'#define U_BOOT_YEAR %Y'; \
+	LC_ALL=C date +'#define U_BOOT_WEEKDAY %u'; \
+	)
 endef
 
 $(version_h): include/config/uboot.release FORCE
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#2 lore raw

PATCH 1/33 Add build date values to Makefile

Dear Simon,

Quoted 3 lines · In message <[email protected]> you wrote:

At present there is a string for the build date and time. In the case of an Real Time Clock which needs to be reset, it is useful to reset it to the build date, since it can't be earlier than that.

I can't see the fundamental difference between two wrong dates? The build time of U-Boot is as wrong as any other time.

Best regards,

Wolfgang Denk

Signature · 6 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
1st Old Man:  Gee, its windy today.
2nd Old Man:  No it's not... it's Thursday.
3rd Old Man:  Yeh, me too.  Let's go for a beer.
#3 lore raw

PATCH 1/33 Add build date values to Makefile

Hi Wolfgang,

Quoted 9 lines · Wolfgang Denk

Dear Simon,

Quoted 3 lines · In message <[email protected]> you wrote:

At present there is a string for the build date and time. In the case of an Real Time Clock which needs to be reset, it is useful to reset it to the build date, since it can't be earlier than that.

I can't see the fundamental difference between two wrong dates? The build time of U-Boot is as wrong as any other time.

Well if you buy a product (car, TV, microwave, phone) it tends to use a recent date when erased, rather than 1970. No fundamental difference, but closer to reality.

Regards,
Simon

#4 lore raw

PATCH 2/33 Align embedded device tree correctly

In reply to Simon Glass

Device trees must be aligned to a 4-byte boundary. This was dropped in the Kbuild conversion. Bring it back, and use 16-byte alignment for good measure.

---

 scripts/Makefile.lib | 2 ++
 1 file changed, 2 insertions(+)
scripts/Makefile.lib +2 -0
index 072abaa..e8c0467 100644
@@ -251,11 +251,13 @@ quiet_cmd_dt_S_dtb= DTB     $@
 cmd_dt_S_dtb=						\
 (							\
 	echo '.section .dtb.init.rodata,"a"';		\
+	echo '.balign 16';				\
 	echo '.global __dtb_$(*F)_begin';		\
 	echo '__dtb_$(*F)_begin:';			\
 	echo '.incbin "$<" ';				\
 	echo '__dtb_$(*F)_end:';			\
 	echo '.global __dtb_$(*F)_end';			\
+	echo '.balign 16';				\
 ) > $@
 
 $(obj)/%.dtb.S: $(obj)/%.dtb
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#5 lore raw

PATCH 3/33 Add ALIGN_DOWN() to find next smallest alignment

In reply to Simon Glass

We have an ALIGN() macro - add a comment as to what this does. Also add a new ALIGN_DOWN() macro, which aligns a value to the next smallest multiple.

---

 include/common.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
include/common.h +15 -0
index ecf7fca..28fba79 100644
@@ -970,9 +970,24 @@ static inline phys_addr_t map_to_sysmem(const void *ptr)
 }							\
 )
 
+/**
+ * ALIGN() - return an aligned value not less than the given value
+ *
+ * @x:	Value to align
+ * @a:	Alignment to use, e.g. 4 to align to multiples of 4
+ */
 #define ALIGN(x,a)		__ALIGN_MASK((x),(typeof(x))(a)-1)
+
 #define __ALIGN_MASK(x,mask)	(((x)+(mask))&~(mask))
 
+/**
+ * ALIGN_DOWN() - return an aligned value not greater than the given value
+ *
+ * @x:	Value to align
+ * @a:	Alignment to use, e.g. 4 to align to multiples of 4
+ */
+#define ALIGN_DOWN(x, a)	((x) & ~((typeof(x))(a) - 1UL))
+
 /*
  * ARCH_DMA_MINALIGN is defined in asm/cache.h for each architecture.  It
  * is used to align DMA buffers.
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#6 lore raw

PATCH 4/33 pci: Update pci_ids.h to include some missing IDs

In reply to Simon Glass

This was taken from Linux 3.18 with some additional IDs from Chrome OS Coreboot commit 688ef385.

---

 include/pci_ids.h | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 181 insertions(+), 6 deletions(-)
include/pci_ids.h +181 -6
index f84c13a..ee98bee 100644
@@ -526,7 +526,19 @@
 #define PCI_DEVICE_ID_AMD_11H_NB_DRAM	0x1302
 #define PCI_DEVICE_ID_AMD_11H_NB_MISC	0x1303
 #define PCI_DEVICE_ID_AMD_11H_NB_LINK	0x1304
-#define PCI_DEVICE_ID_AMD_15H_NB_MISC	0x1603
+#define PCI_DEVICE_ID_AMD_15H_M10H_F3	0x1403
+#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F3 0x141d
+#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F4 0x141e
+#define PCI_DEVICE_ID_AMD_15H_NB_F0	0x1600
+#define PCI_DEVICE_ID_AMD_15H_NB_F1	0x1601
+#define PCI_DEVICE_ID_AMD_15H_NB_F2	0x1602
+#define PCI_DEVICE_ID_AMD_15H_NB_F3	0x1603
+#define PCI_DEVICE_ID_AMD_15H_NB_F4	0x1604
+#define PCI_DEVICE_ID_AMD_15H_NB_F5	0x1605
+#define PCI_DEVICE_ID_AMD_16H_NB_F3	0x1533
+#define PCI_DEVICE_ID_AMD_16H_NB_F4	0x1534
+#define PCI_DEVICE_ID_AMD_16H_M30H_NB_F3 0x1583
+#define PCI_DEVICE_ID_AMD_16H_M30H_NB_F4 0x1584
 #define PCI_DEVICE_ID_AMD_CNB17H_F3	0x1703
 #define PCI_DEVICE_ID_AMD_LANCE		0x2000
 #define PCI_DEVICE_ID_AMD_LANCE_HOME	0x2001
@@ -569,8 +581,9 @@
 #define PCI_DEVICE_ID_AMD_CS5536_IDE    0x209A
 #define PCI_DEVICE_ID_AMD_LX_VIDEO  0x2081
 #define PCI_DEVICE_ID_AMD_LX_AES    0x2082
-#define PCI_DEVICE_ID_AMD_HUDSON2_IDE		0x780c
 #define PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE	0x7800
+#define PCI_DEVICE_ID_AMD_HUDSON2_SMBUS		0x780b
+#define PCI_DEVICE_ID_AMD_HUDSON2_IDE		0x780c
 
 #define PCI_VENDOR_ID_TRIDENT		0x1023
 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX	0x2000
@@ -616,6 +629,8 @@
 #define PCI_DEVICE_ID_MATROX_G550	0x2527
 #define PCI_DEVICE_ID_MATROX_VIA	0x4536
 
+#define PCI_VENDOR_ID_MOBILITY_ELECTRONICS	0x14f2
+
 #define PCI_VENDOR_ID_CT		0x102c
 #define PCI_DEVICE_ID_CT_69000		0x00c0
 #define PCI_DEVICE_ID_CT_65545		0x00d8
@@ -724,6 +739,7 @@
 #define PCI_DEVICE_ID_SI_7018		0x7018
 
 #define PCI_VENDOR_ID_HP		0x103c
+#define PCI_VENDOR_ID_HP_3PAR		0x1590
 #define PCI_DEVICE_ID_HP_VISUALIZE_EG	0x1005
 #define PCI_DEVICE_ID_HP_VISUALIZE_FX6	0x1006
 #define PCI_DEVICE_ID_HP_VISUALIZE_FX4	0x1008
@@ -755,6 +771,8 @@
 #define PCI_DEVICE_ID_HP_CISSD		0x3238
 #define PCI_DEVICE_ID_HP_CISSE		0x323a
 #define PCI_DEVICE_ID_HP_CISSF		0x323b
+#define PCI_DEVICE_ID_HP_CISSH		0x323c
+#define PCI_DEVICE_ID_HP_CISSI		0x3239
 #define PCI_DEVICE_ID_HP_ZX2_IOC	0x4031
 
 #define PCI_VENDOR_ID_PCTECH		0x1042
@@ -779,6 +797,29 @@
 #define PCI_DEVICE_ID_ELSA_QS3000	0x3000
 
 #define PCI_VENDOR_ID_STMICRO		0x104A
+#define PCI_DEVICE_ID_STMICRO_USB_HOST	0xCC00
+#define PCI_DEVICE_ID_STMICRO_USB_OHCI	0xCC01
+#define PCI_DEVICE_ID_STMICRO_USB_OTG	0xCC02
+#define PCI_DEVICE_ID_STMICRO_UART_HWFC 0xCC03
+#define PCI_DEVICE_ID_STMICRO_UART_NO_HWFC	0xCC04
+#define PCI_DEVICE_ID_STMICRO_SOC_DMA	0xCC05
+#define PCI_DEVICE_ID_STMICRO_SATA	0xCC06
+#define PCI_DEVICE_ID_STMICRO_I2C	0xCC07
+#define PCI_DEVICE_ID_STMICRO_SPI_HS	0xCC08
+#define PCI_DEVICE_ID_STMICRO_MAC	0xCC09
+#define PCI_DEVICE_ID_STMICRO_SDIO_EMMC 0xCC0A
+#define PCI_DEVICE_ID_STMICRO_SDIO	0xCC0B
+#define PCI_DEVICE_ID_STMICRO_GPIO	0xCC0C
+#define PCI_DEVICE_ID_STMICRO_VIP	0xCC0D
+#define PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_DMA	0xCC0E
+#define PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_SRCS 0xCC0F
+#define PCI_DEVICE_ID_STMICRO_AUDIO_ROUTER_MSPS 0xCC10
+#define PCI_DEVICE_ID_STMICRO_CAN	0xCC11
+#define PCI_DEVICE_ID_STMICRO_MLB	0xCC12
+#define PCI_DEVICE_ID_STMICRO_DBP	0xCC13
+#define PCI_DEVICE_ID_STMICRO_SATA_PHY	0xCC14
+#define PCI_DEVICE_ID_STMICRO_ESRAM	0xCC15
+#define PCI_DEVICE_ID_STMICRO_VIC	0xCC16
 
 #define PCI_VENDOR_ID_BUSLOGIC		      0x104B
 #define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
@@ -1294,6 +1335,8 @@
 #define PCI_VENDOR_ID_TUNDRA		0x10e3
 #define PCI_DEVICE_ID_TUNDRA_CA91C042	0x0000
 
+#define PCI_VENDOR_ID_AMCC		0x10e8
+
 #define PCI_VENDOR_ID_INTERG		0x10ea
 #define PCI_DEVICE_ID_INTERG_1682	0x1682
 #define PCI_DEVICE_ID_INTERG_2000	0x2000
@@ -1322,6 +1365,7 @@
 #define PCI_SUBDEVICE_ID_CREATIVE_SB08801	0x0041
 #define PCI_SUBDEVICE_ID_CREATIVE_SB08802	0x0042
 #define PCI_SUBDEVICE_ID_CREATIVE_SB08803	0x0043
+#define PCI_SUBDEVICE_ID_CREATIVE_SB1270	0x0062
 #define PCI_SUBDEVICE_ID_CREATIVE_HENDRIX	0x6000
 
 #define PCI_VENDOR_ID_ECTIVA		0x1102 /* duplicate: CREATIVE */
@@ -1411,6 +1455,7 @@
 #define PCI_DEVICE_ID_VIA_CX700_IDE	0x0581
 #define PCI_DEVICE_ID_VIA_VX800		0x8353
 #define PCI_DEVICE_ID_VIA_VX855		0x8409
+#define PCI_DEVICE_ID_VIA_VX900		0x8410
 #define PCI_DEVICE_ID_VIA_8371_1	0x8391
 #define PCI_DEVICE_ID_VIA_82C598_1	0x8598
 #define PCI_DEVICE_ID_VIA_838X_1	0xB188
@@ -1551,6 +1596,8 @@
 #define PCI_DEVICE_ID_RICOH_RL5C476	0x0476
 #define PCI_DEVICE_ID_RICOH_RL5C478	0x0478
 #define PCI_DEVICE_ID_RICOH_R5C822	0x0822
+#define PCI_DEVICE_ID_RICOH_R5CE822	0xe822
+#define PCI_DEVICE_ID_RICOH_R5CE823	0xe823
 #define PCI_DEVICE_ID_RICOH_R5C832	0x0832
 #define PCI_DEVICE_ID_RICOH_R5C843	0x0843
 
@@ -1586,6 +1633,7 @@
 #define PCI_SUBDEVICE_ID_KEYSPAN_SX2	0x5334
 
 #define PCI_VENDOR_ID_MARVELL		0x11ab
+#define PCI_VENDOR_ID_MARVELL_EXT	0x1b4b
 #define PCI_DEVICE_ID_MARVELL_GT64111	0x4146
 #define PCI_DEVICE_ID_MARVELL_GT64260	0x6430
 #define PCI_DEVICE_ID_MARVELL_MV64360	0x6460
@@ -1798,6 +1846,8 @@
 #define PCI_VENDOR_ID_ESDGMBH		0x12fe
 #define PCI_DEVICE_ID_ESDGMBH_CPCIASIO4 0x0111
 
+#define PCI_VENDOR_ID_CB		0x1307	/* Measurement Computing */
+
 #define PCI_VENDOR_ID_SIIG		0x131f
 #define PCI_SUBVENDOR_ID_SIIG		0x131f
 #define PCI_DEVICE_ID_SIIG_1S_10x_550	0x1000
@@ -1860,8 +1910,23 @@
 #define PCI_VENDOR_ID_QUATECH		0x135C
 #define PCI_DEVICE_ID_QUATECH_QSC100	0x0010
 #define PCI_DEVICE_ID_QUATECH_DSC100	0x0020
+#define PCI_DEVICE_ID_QUATECH_DSC200	0x0030
+#define PCI_DEVICE_ID_QUATECH_QSC200	0x0040
 #define PCI_DEVICE_ID_QUATECH_ESC100D	0x0050
 #define PCI_DEVICE_ID_QUATECH_ESC100M	0x0060
+#define PCI_DEVICE_ID_QUATECH_QSCP100	0x0120
+#define PCI_DEVICE_ID_QUATECH_DSCP100	0x0130
+#define PCI_DEVICE_ID_QUATECH_QSCP200	0x0140
+#define PCI_DEVICE_ID_QUATECH_DSCP200	0x0150
+#define PCI_DEVICE_ID_QUATECH_QSCLP100	0x0170
+#define PCI_DEVICE_ID_QUATECH_DSCLP100	0x0180
+#define PCI_DEVICE_ID_QUATECH_DSC100E	0x0181
+#define PCI_DEVICE_ID_QUATECH_SSCLP100	0x0190
+#define PCI_DEVICE_ID_QUATECH_QSCLP200	0x01A0
+#define PCI_DEVICE_ID_QUATECH_DSCLP200	0x01B0
+#define PCI_DEVICE_ID_QUATECH_DSC200E	0x01B1
+#define PCI_DEVICE_ID_QUATECH_SSCLP200	0x01C0
+#define PCI_DEVICE_ID_QUATECH_ESCLP100	0x01E0
 #define PCI_DEVICE_ID_QUATECH_SPPXP_100 0x0278
 
 #define PCI_VENDOR_ID_SEALEVEL		0x135e
@@ -1978,6 +2043,9 @@
 #define PCI_DEVICE_ID_EXAR_XR17C152	0x0152
 #define PCI_DEVICE_ID_EXAR_XR17C154	0x0154
 #define PCI_DEVICE_ID_EXAR_XR17C158	0x0158
+#define PCI_DEVICE_ID_EXAR_XR17V352	0x0352
+#define PCI_DEVICE_ID_EXAR_XR17V354	0x0354
+#define PCI_DEVICE_ID_EXAR_XR17V358	0x0358
 
 #define PCI_VENDOR_ID_MICROGATE		0x13c0
 #define PCI_DEVICE_ID_MICROGATE_USC	0x0010
@@ -2002,6 +2070,10 @@
 #define PCI_DEVICE_ID_CMEDIA_CM8738	0x0111
 #define PCI_DEVICE_ID_CMEDIA_CM8738B	0x0112
 
+#define PCI_VENDOR_ID_ADVANTECH		0x13fe
+
+#define PCI_VENDOR_ID_MEILHAUS		0x1402
+
 #define PCI_VENDOR_ID_LAVA		0x1407
 #define PCI_DEVICE_ID_LAVA_DSERIAL	0x0100 /* 2x 16550 */
 #define PCI_DEVICE_ID_LAVA_QUATRO_A	0x0101 /* 2x 16550, half of 4 port */
@@ -2047,6 +2119,8 @@
 
 #define PCI_VENDOR_ID_CHELSIO		0x1425
 
+#define PCI_VENDOR_ID_ADLINK		0x144a
+
 #define PCI_VENDOR_ID_SAMSUNG		0x144d
 
 #define PCI_VENDOR_ID_GIGABYTE		0x1458
@@ -2080,6 +2154,8 @@
 #define PCI_DEVICE_ID_AFAVLAB_P030	0x2182
 #define PCI_SUBDEVICE_ID_AFAVLAB_P061		0x2150
 
+#define PCI_VENDOR_ID_AMPLICON		0x14dc
+
 #define PCI_VENDOR_ID_BCM_GVC          0x14a4
 #define PCI_VENDOR_ID_BROADCOM		0x14e4
 #define PCI_DEVICE_ID_TIGON3_5752	0x1600
@@ -2100,19 +2176,25 @@
 #define PCI_DEVICE_ID_NX2_57711E	0x1650
 #define PCI_DEVICE_ID_TIGON3_5705	0x1653
 #define PCI_DEVICE_ID_TIGON3_5705_2	0x1654
+#define PCI_DEVICE_ID_TIGON3_5719	0x1657
 #define PCI_DEVICE_ID_TIGON3_5721	0x1659
 #define PCI_DEVICE_ID_TIGON3_5722	0x165a
 #define PCI_DEVICE_ID_TIGON3_5723	0x165b
 #define PCI_DEVICE_ID_TIGON3_5705M	0x165d
 #define PCI_DEVICE_ID_TIGON3_5705M_2	0x165e
+#define PCI_DEVICE_ID_NX2_57712		0x1662
+#define PCI_DEVICE_ID_NX2_57712E	0x1663
+#define PCI_DEVICE_ID_NX2_57712_MF	0x1663
 #define PCI_DEVICE_ID_TIGON3_5714	0x1668
 #define PCI_DEVICE_ID_TIGON3_5714S	0x1669
 #define PCI_DEVICE_ID_TIGON3_5780	0x166a
 #define PCI_DEVICE_ID_TIGON3_5780S	0x166b
 #define PCI_DEVICE_ID_TIGON3_5705F	0x166e
+#define PCI_DEVICE_ID_NX2_57712_VF	0x166f
 #define PCI_DEVICE_ID_TIGON3_5754M	0x1672
 #define PCI_DEVICE_ID_TIGON3_5755M	0x1673
 #define PCI_DEVICE_ID_TIGON3_5756	0x1674
+#define PCI_DEVICE_ID_TIGON3_5750	0x1676
 #define PCI_DEVICE_ID_TIGON3_5751	0x1677
 #define PCI_DEVICE_ID_TIGON3_5715	0x1678
 #define PCI_DEVICE_ID_TIGON3_5715S	0x1679
@@ -2124,6 +2206,9 @@
 #define PCI_DEVICE_ID_TIGON3_5761E	0x1680
 #define PCI_DEVICE_ID_TIGON3_5761	0x1681
 #define PCI_DEVICE_ID_TIGON3_5764	0x1684
+#define PCI_DEVICE_ID_NX2_57800		0x168a
+#define PCI_DEVICE_ID_NX2_57840		0x168d
+#define PCI_DEVICE_ID_NX2_57810		0x168e
 #define PCI_DEVICE_ID_TIGON3_5787M	0x1693
 #define PCI_DEVICE_ID_TIGON3_5782	0x1696
 #define PCI_DEVICE_ID_TIGON3_5784	0x1698
@@ -2131,11 +2216,19 @@
 #define PCI_DEVICE_ID_TIGON3_5787	0x169b
 #define PCI_DEVICE_ID_TIGON3_5788	0x169c
 #define PCI_DEVICE_ID_TIGON3_5789	0x169d
+#define PCI_DEVICE_ID_NX2_57840_4_10	0x16a1
+#define PCI_DEVICE_ID_NX2_57840_2_20	0x16a2
+#define PCI_DEVICE_ID_NX2_57840_MF	0x16a4
+#define PCI_DEVICE_ID_NX2_57800_MF	0x16a5
 #define PCI_DEVICE_ID_TIGON3_5702X	0x16a6
 #define PCI_DEVICE_ID_TIGON3_5703X	0x16a7
 #define PCI_DEVICE_ID_TIGON3_5704S	0x16a8
+#define PCI_DEVICE_ID_NX2_57800_VF	0x16a9
 #define PCI_DEVICE_ID_NX2_5706S		0x16aa
 #define PCI_DEVICE_ID_NX2_5708S		0x16ac
+#define PCI_DEVICE_ID_NX2_57840_VF	0x16ad
+#define PCI_DEVICE_ID_NX2_57810_MF	0x16ae
+#define PCI_DEVICE_ID_NX2_57810_VF	0x16af
 #define PCI_DEVICE_ID_TIGON3_5702A3	0x16c6
 #define PCI_DEVICE_ID_TIGON3_5703A3	0x16c7
 #define PCI_DEVICE_ID_TIGON3_5781	0x16dd
@@ -2307,6 +2400,8 @@
 
 #define PCI_VENDOR_ID_TOPSPIN		0x1867
 
+#define PCI_VENDOR_ID_COMMTECH		0x18f7
+
 #define PCI_VENDOR_ID_SILAN		0x1904
 
 #define PCI_VENDOR_ID_RENESAS		0x1912
@@ -2316,6 +2411,11 @@
 #define PCI_DEVICE_ID_RENESAS_SH7785	0x0007
 #define PCI_DEVICE_ID_RENESAS_SH7786	0x0010
 
+#define PCI_VENDOR_ID_SOLARFLARE	0x1924
+#define PCI_DEVICE_ID_SOLARFLARE_SFC4000A_0	0x0703
+#define PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1	0x6703
+#define PCI_DEVICE_ID_SOLARFLARE_SFC4000B	0x0710
+
 #define PCI_VENDOR_ID_TDI               0x192E
 #define PCI_DEVICE_ID_TDI_EHCI          0x0101
 
@@ -2414,6 +2514,11 @@
 
 #define PCI_VENDOR_ID_AZWAVE		0x1a3b
 
+#define PCI_VENDOR_ID_ASMEDIA		0x1b21
+
+#define PCI_VENDOR_ID_CIRCUITCO		0x1cc8
+#define PCI_SUBSYSTEM_ID_CIRCUITCO_MINNOWBOARD	0x0001
+
 #define PCI_VENDOR_ID_TEKRAM		0x1de1
 #define PCI_DEVICE_ID_TEKRAM_DC290	0xdc29
 
@@ -2463,6 +2568,9 @@
 
 #define PCI_VENDOR_ID_INTEL		0x8086
 #define PCI_DEVICE_ID_INTEL_EESSC	0x0008
+#define PCI_DEVICE_ID_INTEL_SNB_IMC	0x0100
+#define PCI_DEVICE_ID_INTEL_IVB_IMC	0x0154
+#define PCI_DEVICE_ID_INTEL_HSW_IMC	0x0c00
 #define PCI_DEVICE_ID_INTEL_PXHD_0	0x0320
 #define PCI_DEVICE_ID_INTEL_PXHD_1	0x0321
 #define PCI_DEVICE_ID_INTEL_PXH_0	0x0329
@@ -2485,6 +2593,7 @@
 #define PCI_DEVICE_ID_INTEL_MRST_SD2	0x084F
 #define PCI_DEVICE_ID_INTEL_I960	0x0960
 #define PCI_DEVICE_ID_INTEL_I960RM	0x0962
+#define PCI_DEVICE_ID_INTEL_CENTERTON_ILB	0x0c60
 #define PCI_DEVICE_ID_INTEL_82541ER	0x1078
 #define PCI_DEVICE_ID_INTEL_82541GI_LF	0x107c
 #define PCI_DEVICE_ID_INTEL_82542	0x1000
@@ -2564,13 +2673,50 @@
 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_HDA	0x1c20
 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS	0x1c22
 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN	0x1c41
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_Z68		0x1c44
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_P67		0x1c46
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_UM67	0x1c47
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_HM65	0x1c49
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_H67		0x1c4a
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_HM67	0x1c4b
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_Q65		0x1c4c
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_QS67	0x1c4d
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_Q67		0x1c4e
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_QM67	0x1c4f
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_B65		0x1c50
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_C202	0x1c52
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_C204	0x1c54
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_C206	0x1c56
+#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_H61		0x1c5c
 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX	0x1c5f
-#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE	0x1e03
-#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_HDA	0x1e20
-#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e41
-#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f
 #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS	0x1d22
 #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC	0x1d40
+#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0	0x1d40
+#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1	0x1d41
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE	0x1e03
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_HDA	0x1e20
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI	0x1e31
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN	0x1e41
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_B75	0x1e49
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_C216	0x1e53
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_H77	0x1e4A
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_HM70	0x1e5e
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_HM75	0x1e5d
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_HM76	0x1e59
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_HM77	0x1e57
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MBL_SAMPLE 0x1e42
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_NM70	0x1e5f
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_Q75	0x1e48
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_Q77	0x1e47
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_QM77	0x1e55
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_QS77	0x1e56
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_SFF_SAMPLE 0x1e43
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_UM77	0x1e58
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_Z75	0x1e46
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_Z77	0x1e44
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX	0x1e5f
+#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN	0x2310
+#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX	0x231f
 #define PCI_DEVICE_ID_INTEL_82801AA_0	0x2410
 #define PCI_DEVICE_ID_INTEL_82801AA_1	0x2411
 #define PCI_DEVICE_ID_INTEL_82801AA_3	0x2413
@@ -2783,8 +2929,30 @@
 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MIN	0x3b00
 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MAX	0x3b1f
 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS	0x3b30
+#define PCI_DEVICE_ID_INTEL_IOAT_SNB0	0x3c20
+#define PCI_DEVICE_ID_INTEL_IOAT_SNB1	0x3c21
+#define PCI_DEVICE_ID_INTEL_IOAT_SNB2	0x3c22
+#define PCI_DEVICE_ID_INTEL_IOAT_SNB3	0x3c23
+#define PCI_DEVICE_ID_INTEL_IOAT_SNB4	0x3c24
+#define PCI_DEVICE_ID_INTEL_IOAT_SNB5	0x3c25
+#define PCI_DEVICE_ID_INTEL_IOAT_SNB6	0x3c26
+#define PCI_DEVICE_ID_INTEL_IOAT_SNB7	0x3c27
+#define PCI_DEVICE_ID_INTEL_IOAT_SNB8	0x3c2e
+#define PCI_DEVICE_ID_INTEL_IOAT_SNB9	0x3c2f
+#define PCI_DEVICE_ID_INTEL_UNC_HA	0x3c46
+#define PCI_DEVICE_ID_INTEL_UNC_IMC0	0x3cb0
+#define PCI_DEVICE_ID_INTEL_UNC_IMC1	0x3cb1
+#define PCI_DEVICE_ID_INTEL_UNC_IMC2	0x3cb4
+#define PCI_DEVICE_ID_INTEL_UNC_IMC3	0x3cb5
+#define PCI_DEVICE_ID_INTEL_UNC_QPI0	0x3c41
+#define PCI_DEVICE_ID_INTEL_UNC_QPI1	0x3c42
+#define PCI_DEVICE_ID_INTEL_UNC_R2PCIE	0x3c43
+#define PCI_DEVICE_ID_INTEL_UNC_R3QPI0	0x3c44
+#define PCI_DEVICE_ID_INTEL_UNC_R3QPI1	0x3c45
+#define PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX	0x3ce0
 #define PCI_DEVICE_ID_INTEL_IOAT_SNB	0x402f
 #define PCI_DEVICE_ID_INTEL_5100_16	0x65f0
+#define PCI_DEVICE_ID_INTEL_5100_19	0x65f3
 #define PCI_DEVICE_ID_INTEL_5100_21	0x65f5
 #define PCI_DEVICE_ID_INTEL_5100_22	0x65f6
 #define PCI_DEVICE_ID_INTEL_5400_ERR	0x4030
@@ -2823,6 +2991,7 @@
 #define PCI_DEVICE_ID_INTEL_82372FB_1	0x7601
 #define PCI_DEVICE_ID_INTEL_SCH_LPC	0x8119
 #define PCI_DEVICE_ID_INTEL_SCH_IDE	0x811a
+#define PCI_DEVICE_ID_INTEL_ITC_LPC	0x8186
 #define PCI_DEVICE_ID_INTEL_82454GX	0x84c4
 #define PCI_DEVICE_ID_INTEL_82450GX	0x84c5
 #define PCI_DEVICE_ID_INTEL_82451NX	0x84ca
@@ -2905,7 +3074,11 @@
 #define PCI_DEVICE_ID_NETMOS_9845	0x9845
 #define PCI_DEVICE_ID_NETMOS_9855	0x9855
 #define PCI_DEVICE_ID_NETMOS_9865	0x9865
+#define PCI_DEVICE_ID_NETMOS_9900	0x9900
 #define PCI_DEVICE_ID_NETMOS_9901	0x9901
+#define PCI_DEVICE_ID_NETMOS_9904	0x9904
+#define PCI_DEVICE_ID_NETMOS_9912	0x9912
+#define PCI_DEVICE_ID_NETMOS_9922	0x9922
 
 #define PCI_VENDOR_ID_3COM_2		0xa727
 
@@ -2927,3 +3100,5 @@
 
 #define PCI_VENDOR_ID_XEN		0x5853
 #define PCI_DEVICE_ID_XEN_PLATFORM	0x0001
+
+#define PCI_VENDOR_ID_OCZ		0x1b85
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#7 lore raw

PATCH 5/33 x86: Remove board_early_init_r()

In reply to Simon Glass

This function is not needed. Remove it to improve the generic init sequence slightly.

---

 arch/x86/cpu/coreboot/coreboot.c    | 11 -----------
 board/google/chromebook_link/link.c |  5 -----
 common/board_r.c                    |  3 ---
 include/configs/chromebook_link.h   |  1 -
 4 files changed, 20 deletions(-)
arch/x86/cpu/coreboot/coreboot.c +0 -11
index d8ce768..e995e7f 100644
@@ -39,17 +39,6 @@ int board_early_init_f(void)
 	return 0;
 }
 
-int board_early_init_r(void)
-{
-	/* CPU Speed to 100MHz */
-	gd->cpu_clk = 100000000;
-
-	/* Crystal is 33.000MHz */
-	gd->bus_clk = 33000000;
-
-	return 0;
-}
-
 int last_stage_init(void)
 {
 	if (gd->flags & GD_FLG_COLD_BOOT)
board/google/chromebook_link/link.c +0 -5
index 88cee05..0a1ae61 100644
@@ -12,11 +12,6 @@ int arch_early_init_r(void)
 	return 0;
 }
 
-int board_early_init_r(void)
-{
-	return 0;
-}
-
 static const struct pch_gpio_set1 pch_gpio_set1_mode = {
 	.gpio0 = GPIO_MODE_GPIO,  /* NMI_DBG# */
 	.gpio3 = GPIO_MODE_GPIO,  /* ALS_INT# */
common/board_r.c +0 -3
index 7c33900..8625a90 100644
@@ -837,9 +837,6 @@ init_fnc_t init_sequence_r[] = {
 #ifdef CONFIG_CMD_KGDB
 	initr_kgdb,
 #endif
-#ifdef CONFIG_X86
-	board_early_init_r,
-#endif
 	interrupt_init,
 #if defined(CONFIG_ARM) || defined(CONFIG_x86)
 	initr_enable_interrupts,
include/configs/chromebook_link.h +0 -1
index 8caeca6..cd4a8a0 100644
@@ -21,7 +21,6 @@
 #define CONFIG_DCACHE_RAM_MRC_VAR_SIZE		0x4000
 #define CONFIG_SYS_X86_START16			0xfffff800
 #define CONFIG_BOARD_EARLY_INIT_F
-#define CONFIG_BOARD_EARLY_INIT_R
 #define CONFIG_DISPLAY_CPUINFO
 
 #define CONFIG_X86_RESET_VECTOR
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#8 lore raw

PATCH 5/33 x86: Remove board_early_init_r()

Quoted 69 lines · Simon Glass

This function is not needed. Remove it to improve the generic init sequence slightly.

---

 arch/x86/cpu/coreboot/coreboot.c    | 11 -----------
 board/google/chromebook_link/link.c |  5 -----
 common/board_r.c                    |  3 ---
 include/configs/chromebook_link.h   |  1 -
 4 files changed, 20 deletions(-)
arch/x86/cpu/coreboot/coreboot.c +0 -11
index d8ce768..e995e7f 100644
@@ -39,17 +39,6 @@ int board_early_init_f(void)
        return 0;
 }
 
-int board_early_init_r(void)
-{
-       /* CPU Speed to 100MHz */
-       gd->cpu_clk = 100000000;
-
-       /* Crystal is 33.000MHz */
-       gd->bus_clk = 33000000;
-
-       return 0;
-}
-
 int last_stage_init(void)
 {
        if (gd->flags & GD_FLG_COLD_BOOT)
board/google/chromebook_link/link.c +0 -5
index 88cee05..0a1ae61 100644
@@ -12,11 +12,6 @@ int arch_early_init_r(void)
        return 0;
 }
 
-int board_early_init_r(void)
-{
-       return 0;
-}
-
 static const struct pch_gpio_set1 pch_gpio_set1_mode = {
        .gpio0 = GPIO_MODE_GPIO,  /* NMI_DBG# */
        .gpio3 = GPIO_MODE_GPIO,  /* ALS_INT# */
common/board_r.c +0 -3
index 7c33900..8625a90 100644
@@ -837,9 +837,6 @@ init_fnc_t init_sequence_r[] = {
 #ifdef CONFIG_CMD_KGDB
        initr_kgdb,
 #endif
-#ifdef CONFIG_X86
-       board_early_init_r,
-#endif
        interrupt_init,
 #if defined(CONFIG_ARM) || defined(CONFIG_x86)
        initr_enable_interrupts,
include/configs/chromebook_link.h +0 -0
index 8caeca6..cd4a8a0 100644

include/configs/chromebook_link.h

Quoted 8 lines
include/configs/chromebook_link.h +0 -2
@@ -21,7 +21,6 @@
 #define CONFIG_DCACHE_RAM_MRC_VAR_SIZE         0x4000
 #define CONFIG_SYS_X86_START16                 0xfffff800
 #define CONFIG_BOARD_EARLY_INIT_F
-#define CONFIG_BOARD_EARLY_INIT_R
 #define CONFIG_DISPLAY_CPUINFO
 
 #define CONFIG_X86_RESET_VECTOR
--
#9 lore raw

PATCH 6/33 x86: Panic if there is not relocation data

In reply to Simon Glass

This normally indicates a problem which will prevent relocation from functioning, resulting in a hang. Panic in this case to make it easier to debug.

---

 arch/x86/lib/relocate.c | 3 +++
 1 file changed, 3 insertions(+)
arch/x86/lib/relocate.c +3 -0
index faca38f..b33586b 100644
@@ -76,6 +76,9 @@ int do_elf_reloc_fixups(void)
 	/* The size of the region of u-boot that runs out of RAM. */
 	uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start;
 
+	if (re_src == re_end)
+		panic("No relocation data");
+
 	do {
 		/* Get the location from the relocation entry */
 		offset_ptr_rom = (Elf32_Addr *)re_src->r_offset;
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#10 lore raw

PATCH 6/33 x86: Panic if there is not relocation data

Quoted 15 lines · Simon Glass

This normally indicates a problem which will prevent relocation from functioning, resulting in a hang. Panic in this case to make it easier to debug.

---

 arch/x86/lib/relocate.c | 3 +++
 1 file changed, 3 insertions(+)
arch/x86/lib/relocate.c +0 -0
index faca38f..b33586b 100644

arch/x86/lib/relocate.c int do_elf_reloc_fixups(void)

Quoted 10 lines
arch/x86/lib/relocate.c +3 -1
@@ -76,6 +76,9 @@ int do_elf_reloc_fixups(void)
        /* The size of the region of u-boot that runs out of RAM. */
        uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start;
 
+       if (re_src == re_end)
+               panic("No relocation data");
+
        do {
                /* Get the location from the relocation entry */
                offset_ptr_rom = (Elf32_Addr *)re_src->r_offset;
--
#11 lore raw

PATCH 7/33 x86: Ensure that all relocation data is included in the image

In reply to Simon Glass

Some toolchains put the relocation data into separate sections. Adjust the linker script to catch this case. Without relocation data, U-Boot will not boot.

---

 arch/x86/cpu/u-boot.lds | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/cpu/u-boot.lds +3 -1
index f48bff5..95ab7dd 100644
@@ -44,7 +44,9 @@ SECTIONS
 
 	. = ALIGN(4);
 	__rel_dyn_start = .;
-	.rel.dyn : { *(.rel.dyn) }
+	.rel.dyn : {
+		*(.rel.*)
+	}
 	__rel_dyn_end = .;
 	. = ALIGN(4);
 	_end = .;
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#12 lore raw

PATCH 7/33 x86: Ensure that all relocation data is included in the image

Quoted 15 lines · Simon Glass

Some toolchains put the relocation data into separate sections. Adjust the linker script to catch this case. Without relocation data, U-Boot will not boot.

---

 arch/x86/cpu/u-boot.lds | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/cpu/u-boot.lds +0 -0
index f48bff5..95ab7dd 100644

arch/x86/cpu/u-boot.lds SECTIONS · line 48

Quoted 6 lines
arch/x86/cpu/u-boot.lds +2 -1
@@ -44,7 +44,9 @@ SECTIONS
 
        . = ALIGN(4);
        __rel_dyn_start = .;
-       .rel.dyn : { *(.rel.dyn) }
+       .rel.dyn : {
+               *(.rel.*)

Should it be more generic to use *(.rel*) here?

arch/x86/cpu/u-boot.lds SECTIONS

Quoted 5 lines
arch/x86/cpu/u-boot.lds +1 -1
+       }
        __rel_dyn_end = .;
        . = ALIGN(4);
        _end = .;
--

Regards,
Bin

#13 lore raw

PATCH 7/33 x86: Ensure that all relocation data is included in the image

Hi Bin,

Quoted 17 lines · Bin Meng
Quoted 16 lines · Simon Glass

Some toolchains put the relocation data into separate sections. Adjust the linker script to catch this case. Without relocation data, U-Boot will not boot.

---

 arch/x86/cpu/u-boot.lds | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/cpu/u-boot.lds +0 -0
index f48bff5..95ab7dd 100644
@@ -44,7 +44,9 @@ SECTIONS
 
Quoted 7 lines

arch/x86/cpu/u-boot.lds SECTIONS · line 48

Quoted 5 lines
arch/x86/cpu/u-boot.lds +2 -1
        . = ALIGN(4);
        __rel_dyn_start = .;
-       .rel.dyn : { *(.rel.dyn) }
+       .rel.dyn : {
+               *(.rel.*)

Should it be more generic to use *(.rel*) here?

I suspect that would be safe, but why?

Quoted 6 lines

arch/x86/cpu/u-boot.lds SECTIONS

Quoted 6 lines
arch/x86/cpu/u-boot.lds +1 -1
+       }
        __rel_dyn_end = .;
        . = ALIGN(4);
        _end = .;
--

Regards,
Simon

#14 lore raw

PATCH 7/33 x86: Ensure that all relocation data is included in the image

Hi Simon,

Quoted 28 lines · Simon Glass

Hi Bin,

Quoted 17 lines · Bin Meng
Quoted 16 lines · Simon Glass

Some toolchains put the relocation data into separate sections. Adjust the linker script to catch this case. Without relocation data, U-Boot will not boot.

---

 arch/x86/cpu/u-boot.lds | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/cpu/u-boot.lds +0 -0
index f48bff5..95ab7dd 100644
@@ -44,7 +44,9 @@ SECTIONS
 
Quoted 7 lines

arch/x86/cpu/u-boot.lds SECTIONS · line 48

Quoted 5 lines
arch/x86/cpu/u-boot.lds +2 -1
        . = ALIGN(4);
        __rel_dyn_start = .;
-       .rel.dyn : { *(.rel.dyn) }
+       .rel.dyn : {
+               *(.rel.*)

Should it be more generic to use *(.rel*) here?

Quoted 1 line

I suspect that would be safe, but why?

Just in case some weird toolchain omit the "." afer "rel". Which toolchain are you using now that exposes such behavior?

Quoted 9 lines
Quoted 6 lines

arch/x86/cpu/u-boot.lds SECTIONS

Quoted 6 lines
arch/x86/cpu/u-boot.lds +1 -1
+       }
        __rel_dyn_end = .;
        . = ALIGN(4);
        _end = .;
--

Regards,
Simon

Regards,
Bin

#15 lore raw

PATCH 8/33 WIP: x86: Drop u-boot.srec from the Makefile

In reply to Simon Glass

This is not needed on x86 and creates a 4GB file due to the addressing used on x86.

This needs to be investigated.

---

 Makefile | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
Makefile +4 -1
index fb72c29..c54a2f1 100644
@@ -722,7 +722,10 @@ DO_STATIC_RELA =
 endif
 
 # Always append ALL so that arch config.mk's can add custom ones
-ALL-y += u-boot.srec u-boot.bin System.map binary_size_check
+ALL-y += u-boot.bin System.map binary_size_check
+ifeq ($(CONFIG_X86),)
+ALL-y += u-boot.srec
+endif
 
 ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin
 ifeq ($(CONFIG_SPL_FSL_PBL),y)
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#16 lore raw

PATCH 8/33 WIP: x86: Drop u-boot.srec from the Makefile

Hi Simon,

Quoted 5 lines · Simon Glass

This is not needed on x86 and creates a 4GB file due to the addressing used on x86.

This needs to be investigated.

This is due to your patch "[09/33] x86: Factor out common values in the link script" (see http://patchwork.ozlabs.org/patch/409725/) that changes the AT value of .start16/.resetvec to the real mode address instead of 0xffff_xxxx which will cause a 4GB file creation by objcopy.

Quoted 13 lines

---

 Makefile | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
Makefile +0 -0
index fb72c29..c54a2f1 100644
@@ -722,7 +722,10 @@ DO_STATIC_RELA =
 endif
 

Makefile DO_STATIC_RELA =

Quoted 10 lines
Makefile +4 -2
 # Always append ALL so that arch config.mk's can add custom ones
-ALL-y += u-boot.srec u-boot.bin System.map binary_size_check
+ALL-y += u-boot.bin System.map binary_size_check
+ifeq ($(CONFIG_X86),)
+ALL-y += u-boot.srec
+endif
 
 ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin
 ifeq ($(CONFIG_SPL_FSL_PBL),y)
--

Regards,
Bin

#17 lore raw

PATCH 9/33 x86: Factor out common values in the link script

In reply to Simon Glass

Define the reset base in config.mk so that it does not need to be calculated twice in the link script. Also tidy up the START_16 and RESET_VEC_LOC values to fit with this new approach.

---

 arch/x86/cpu/config.mk  |  5 +++--
 arch/x86/cpu/u-boot.lds | 13 +++++++++----
 2 files changed, 12 insertions(+), 6 deletions(-)
arch/x86/cpu/config.mk +3 -2
index f7b01d3..84aeaf3 100644
@@ -12,5 +12,6 @@ PLATFORM_CPPFLAGS += -D__I386__ -Werror
 # DO NOT MODIFY THE FOLLOWING UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!
 LDPPFLAGS += -DRESET_SEG_START=0xffff0000
 LDPPFLAGS += -DRESET_SEG_SIZE=0x10000
-LDPPFLAGS += -DRESET_VEC_LOC=0xfff0
-LDPPFLAGS += -DSTART_16=0xf800
+LDPPFLAGS += -DRESET_VEC_LOC=0xfffffff0
+LDPPFLAGS += -DSTART_16=$(CONFIG_SYS_X86_START16)
+LDPPFLAGS += -DRESET_BASE="CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE)"
arch/x86/cpu/u-boot.lds +9 -4
index 95ab7dd..2a23e18 100644
@@ -71,10 +71,15 @@ SECTIONS
 	 * The following expressions place the 16-bit Real-Mode code and
 	 * Reset Vector at the end of the Flash ROM
 	 */
-	. = START_16;
-	.start16 : AT (CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE + START_16)) { KEEP(*(.start16)); }
+	. = START_16 - RESET_SEG_START;
+	.start16 : AT (START_16 - RESET_SEG_START) {
+		KEEP(*(.start16));
+	}
 
-	. = RESET_VEC_LOC;
-	.resetvec : AT (CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE + RESET_VEC_LOC)) { KEEP(*(.resetvec)); }
+	. = RESET_VEC_LOC - RESET_SEG_START;
+	.resetvec : AT (RESET_VEC_LOC - RESET_SEG_START) {
+		KEEP(*(.resetvec));
+	}
 #endif
+
 }
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#18 lore raw

PATCH 9/33 x86: Factor out common values in the link script

Hi Simon,

Quoted 29 lines · Simon Glass

Define the reset base in config.mk so that it does not need to be calculated twice in the link script. Also tidy up the START_16 and RESET_VEC_LOC values to fit with this new approach.

---

 arch/x86/cpu/config.mk  |  5 +++--
 arch/x86/cpu/u-boot.lds | 13 +++++++++----
 2 files changed, 12 insertions(+), 6 deletions(-)
arch/x86/cpu/config.mk +3 -2
index f7b01d3..84aeaf3 100644
@@ -12,5 +12,6 @@ PLATFORM_CPPFLAGS += -D__I386__ -Werror
 # DO NOT MODIFY THE FOLLOWING UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!
 LDPPFLAGS += -DRESET_SEG_START=0xffff0000
 LDPPFLAGS += -DRESET_SEG_SIZE=0x10000
-LDPPFLAGS += -DRESET_VEC_LOC=0xfff0
-LDPPFLAGS += -DSTART_16=0xf800
+LDPPFLAGS += -DRESET_VEC_LOC=0xfffffff0
+LDPPFLAGS += -DSTART_16=$(CONFIG_SYS_X86_START16)
+LDPPFLAGS += -DRESET_BASE="CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE)"
arch/x86/cpu/u-boot.lds +0 -0
index 95ab7dd..2a23e18 100644

arch/x86/cpu/u-boot.lds SECTIONS · line 77

Quoted 9 lines
arch/x86/cpu/u-boot.lds +4 -2
@@ -71,10 +71,15 @@ SECTIONS
         * The following expressions place the 16-bit Real-Mode code and
         * Reset Vector at the end of the Flash ROM
         */
-       . = START_16;
-       .start16 : AT (CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE + START_16)) { KEEP(*(.start16)); }
+       . = START_16 - RESET_SEG_START;
+       .start16 : AT (START_16 - RESET_SEG_START) {
+               KEEP(*(.start16));
+       }

What's the reason of changing AT of .start16 section?

arch/x86/cpu/u-boot.lds SECTIONS · line 82

Quoted 6 lines
arch/x86/cpu/u-boot.lds +4 -2
-       . = RESET_VEC_LOC;
-       .resetvec : AT (CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE + RESET_VEC_LOC)) { KEEP(*(.resetvec)); }
+       . = RESET_VEC_LOC - RESET_SEG_START;
+       .resetvec : AT (RESET_VEC_LOC - RESET_SEG_START) {
+               KEEP(*(.resetvec));
+       }

Ditto.

arch/x86/cpu/u-boot.lds SECTIONS

Quoted 4 lines
arch/x86/cpu/u-boot.lds +1 -1
 #endif
+
 }
--

Regards,
Bin

#19 lore raw

PATCH 10/33 rtc: mc146818: Set up RTC at start of day

In reply to Simon Glass

If the RTC needs to be cleared, write the U-Boot build date to it. In any case make sure the settings are correct.

---

 drivers/rtc/mc146818.c | 49 +++++++++++++++++++++++++++++++++++++++++++++----
 include/rtc.h          |  7 +++++++
 2 files changed, 52 insertions(+), 4 deletions(-)
drivers/rtc/mc146818.c +45 -4
index f7cf106..7528044 100644
@@ -14,6 +14,7 @@
 #include <common.h>
 #include <command.h>
 #include <rtc.h>
+#include <version.h>
 
 #if defined(__I386__) || defined(CONFIG_MALTA)
 #include <asm/io.h>
@@ -42,6 +43,12 @@ static void  rtc_write (uchar reg, uchar val);
 #define RTC_CONFIG_C		0x0C
 #define RTC_CONFIG_D		0x0D
 
+#define RTC_CONFIG_A_REF_CLCK_32KHZ	(1 << 5)
+#define RTC_CONFIG_A_RATE_1024HZ	6
+
+#define RTC_CONFIG_B_24H		(1 << 1)
+
+#define RTC_CONFIG_D_VALID_RAM_AND_TIME	0x80
 
 /* ------------------------------------------------------------------------- */
 
@@ -128,25 +135,59 @@ void rtc_reset (void)
  */
 static uchar rtc_read (uchar reg)
 {
-	return(in8(CONFIG_SYS_RTC_REG_BASE_ADDR+reg));
+	return in8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg);
 }
 
 static void rtc_write (uchar reg, uchar val)
 {
-	out8(CONFIG_SYS_RTC_REG_BASE_ADDR+reg, val);
+	out8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg, val);
 }
 #else
 static uchar rtc_read (uchar reg)
 {
 	out8(RTC_PORT_MC146818,reg);
-	return(in8(RTC_PORT_MC146818+1));
+	return in8(RTC_PORT_MC146818 + 1);
 }
 
 static void rtc_write (uchar reg, uchar val)
 {
 	out8(RTC_PORT_MC146818,reg);
-	out8(RTC_PORT_MC146818+1,val);
+	out8(RTC_PORT_MC146818+1, val);
 }
 #endif
 
+void rtc_init(bool invalid)
+{
+	debug("RTC Init\n");
+
+#define CLEAR_CMOS 0
+#else
+#define CLEAR_CMOS 1
 #endif
+
+	if (invalid) {
+#if CLEAR_CMOS
+		int i;
+
+		rtc_write(0x01, 0);
+		rtc_write(0x03, 0);
+		rtc_write(0x05, 0);
+		for (i = 10; i < 128; i++)
+			rtc_write(i, 0);
+#endif
+		printf("RTC:%s%s\n",
+		       invalid ? " Clear requested" : "",
+		       CLEAR_CMOS ? " zeroing cmos" : "");
+	}
+
+	/* Setup the real time clock */
+	rtc_write(RTC_CONFIG_B, RTC_CONFIG_B_24H);
+	/* Setup the frequency it operates@*/
+	rtc_write(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ |
+		  RTC_CONFIG_A_RATE_1024HZ);
+	/* Ensure all reserved bits are 0 in register D */
+	rtc_write(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME);
+
+	/* Clear any pending interrupts */
+	rtc_read(RTC_CONFIG_C);
+}
include/rtc.h +7 -0
index c034966..8be06bb 100644
@@ -50,4 +50,11 @@ void to_tm (int, struct rtc_time *);
 unsigned long mktime (unsigned int, unsigned int, unsigned int,
 		      unsigned int, unsigned int, unsigned int);
 
+/**
+ * rtc_init() - Set up the real time clock ready for use
+ *
+ * @rtc_failed:	true if time was lost (e.g. flat battery), else false
+ */
+void rtc_init(bool rtc_failed);
+
 #endif	/* _RTC_H_ */
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#20 lore raw

PATCH 10/33 rtc: mc146818: Set up RTC at start of day

Hi Simon,

Quoted 62 lines · Simon Glass

If the RTC needs to be cleared, write the U-Boot build date to it. In any case make sure the settings are correct.

---

 drivers/rtc/mc146818.c | 49 +++++++++++++++++++++++++++++++++++++++++++++----
 include/rtc.h          |  7 +++++++
 2 files changed, 52 insertions(+), 4 deletions(-)
drivers/rtc/mc146818.c +11 -4
index f7cf106..7528044 100644
@@ -14,6 +14,7 @@
 #include <common.h>
 #include <command.h>
 #include <rtc.h>
+#include <version.h>
 
 #if defined(__I386__) || defined(CONFIG_MALTA)
 #include <asm/io.h>
@@ -42,6 +43,12 @@ static void  rtc_write (uchar reg, uchar val);
 #define RTC_CONFIG_C           0x0C
 #define RTC_CONFIG_D           0x0D
 
+#define RTC_CONFIG_A_REF_CLCK_32KHZ    (1 << 5)
+#define RTC_CONFIG_A_RATE_1024HZ       6
+
+#define RTC_CONFIG_B_24H               (1 << 1)
+
+#define RTC_CONFIG_D_VALID_RAM_AND_TIME        0x80
 
 /* ------------------------------------------------------------------------- */
 
@@ -128,25 +135,59 @@ void rtc_reset (void)
  */
 static uchar rtc_read (uchar reg)
 {
-       return(in8(CONFIG_SYS_RTC_REG_BASE_ADDR+reg));
+       return in8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg);
 }
 
 static void rtc_write (uchar reg, uchar val)
 {
-       out8(CONFIG_SYS_RTC_REG_BASE_ADDR+reg, val);
+       out8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg, val);
 }
 #else
 static uchar rtc_read (uchar reg)
 {
        out8(RTC_PORT_MC146818,reg);
-       return(in8(RTC_PORT_MC146818+1));
+       return in8(RTC_PORT_MC146818 + 1);
 }
 
 static void rtc_write (uchar reg, uchar val)
 {
        out8(RTC_PORT_MC146818,reg);
-       out8(RTC_PORT_MC146818+1,val);
+       out8(RTC_PORT_MC146818+1, val);
 }

drivers/rtc/mc146818.c void rtc_reset (void) · line 166

Quoted 10 lines
drivers/rtc/mc146818.c +7 -0
 #endif
 
+void rtc_init(bool invalid)
+{
+       debug("RTC Init\n");
+
+#define CLEAR_CMOS 0
+#else
+#define CLEAR_CMOS 1
 #endif

It would be better if we change this #if #else like below which should help better understanding.

#if defined(CONFIG_CMD_DATE)
#define CLEAR_CMOS 0
#else
#define CLEAR_CMOS 1
#endif

And put the above logic to the head of this file, or maybe include/rtc.h if we want to make it generic for other RTC drivers as well.

drivers/rtc/mc146818.c void rtc_reset (void) · line 174

Quoted 8 lines
drivers/rtc/mc146818.c +8 -0
+
+       if (invalid) {
+#if CLEAR_CMOS
+               int i;
+
+               rtc_write(0x01, 0);
+               rtc_write(0x03, 0);
+               rtc_write(0x05, 0);

Please replace these 01/03/05 with macros.

Quoted 26 lines
drivers/rtc/mc146818.c +19 -0
+               for (i = 10; i < 128; i++)
+                       rtc_write(i, 0);
+#endif
+               printf("RTC:%s%s\n",
+                      invalid ? " Clear requested" : "",
+                      CLEAR_CMOS ? " zeroing cmos" : "");
+       }
+
+       /* Setup the real time clock */
+       rtc_write(RTC_CONFIG_B, RTC_CONFIG_B_24H);
+       /* Setup the frequency it operates at */
+       rtc_write(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ |
+                 RTC_CONFIG_A_RATE_1024HZ);
+       /* Ensure all reserved bits are 0 in register D */
+       rtc_write(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME);
+
+       /* Clear any pending interrupts */
+       rtc_read(RTC_CONFIG_C);
+}
include/rtc.h +0 -0
index c034966..8be06bb 100644
@@ -50,4 +50,11 @@ void to_tm (int, struct rtc_time *);
 unsigned long mktime (unsigned int, unsigned int, unsigned int,
                      unsigned int, unsigned int, unsigned int);

include/rtc.h void to_tm (int, struct rtc_time *);

Quoted 10 lines
include/rtc.h +7 -1
 
+/**
+ * rtc_init() - Set up the real time clock ready for use
+ *
+ * @rtc_failed:        true if time was lost (e.g. flat battery), else false
+ */
+void rtc_init(bool rtc_failed);
+
 #endif /* _RTC_H_ */
--

This adds an API in the generic RTC driver header, however there are some RTC drivers which already have the API but without any parameters.

arch/mips/include/asm/jz4740.h:1147:extern void rtc_init(void); board/cogent/mb.c:268: rtc_init (); drivers/rtc/bfin_rtc.c:30:static void rtc_init(void) drivers/rtc/pl031.c:42:void rtc_init(void) drivers/rtc/ds1302.c:192:rtc_init(void)

Do you plan to update other RTC drivers as well? Or if we want to keep this x86 specific, maybe a CONFIG_X86 is needed?

Regards,
Bin

#21 lore raw

PATCH 10/33 rtc: mc146818: Set up RTC at start of day

In reply to Simon Glass

Dear Simon,

Quoted 2 lines · In message <[email protected]> you wrote:

If the RTC needs to be cleared, write the U-Boot build date to it. In any case make sure the settings are correct.

Is this really a good idea? Why writing the build date? It is as wrong as any other arbitrarily chose point of time, and when each device comes up with a different (incorrect) time this could be pretty much confusing.

If you need a sane time for initialization, would it not make more sense to chose a fixed date? If you don't want to use the epoch (say, to avoid y2038 issues), you could use 2010-01-01 00:00 or similar instead.

If I see the clock comes up at such a date I will notice that this is an uninitialized time. It it comes up with something as "Tue, 11 Nov 2014 17:17:58" I will assume this is a real time, and wonder what's gone wrong that i's in the past.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Anything that is worth doing at all is worth doing well.
                                       -- Philip Earl of Chesterfield
#22 lore raw

PATCH 10/33 rtc: mc146818: Set up RTC at start of day

Hi Wolfgang,

Quoted 16 lines · Wolfgang Denk

Dear Simon,

Quoted 2 lines · In message <[email protected]> you wrote:

If the RTC needs to be cleared, write the U-Boot build date to it. In any case make sure the settings are correct.

Is this really a good idea? Why writing the build date? It is as wrong as any other arbitrarily chose point of time, and when each device comes up with a different (incorrect) time this could be pretty much confusing.

If you need a sane time for initialization, would it not make more sense to chose a fixed date? If you don't want to use the epoch (say, to avoid y2038 issues), you could use 2010-01-01 00:00 or similar instead.

Quoted 4 lines

If I see the clock comes up at such a date I will notice that this is an uninitialized time. It it comes up with something as "Tue, 11 Nov 2014 17:17:58" I will assume this is a real time, and wonder what's gone wrong that i's in the past.

OK I think going with a 2010 date makes more sense, so I'll drop the build date patch.

Regards,
Simon

#23 lore raw

PATCH 11/33 x86: Add ioapic.h header

In reply to Simon Glass

Add definitions for the I/O Advanced Peripheral Interrupt Controller.

---

 arch/x86/include/asm/ioapic.h | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 arch/x86/include/asm/ioapic.h
arch/x86/include/asm/ioapic.h new file +38 -0
new file mode 100644
index 0000000..699160f
@@ -0,0 +1,38 @@
+/*
+ * From coreboot file of the same name
+ *
+ * Copyright (C) 2010 coresystems GmbH
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef __ASM_IOAPIC_H
+#define __ASM_IOAPIC_H
+
+#define IO_APIC_ADDR		0xfec00000
+#define IO_APIC_INDEX		IO_APIC_ADDR
+#define IO_APIC_DATA		(IO_APIC_ADDR + 0x10)
+#define IO_APIC_INTERRUPTS	24
+
+#define ALL		(0xff << 24)
+#define NONE		0
+#define DISABLED	(1 << 16)
+#define ENABLED		(0 << 16)
+#define TRIGGER_EDGE	(0 << 15)
+#define TRIGGER_LEVEL	(1 << 15)
+#define POLARITY_HIGH	(0 << 13)
+#define POLARITY_LOW	(1 << 13)
+#define PHYSICAL_DEST	(0 << 11)
+#define LOGICAL_DEST	(1 << 11)
+#define ExtINT		(7 << 8)
+#define NMI		(4 << 8)
+#define SMI		(2 << 8)
+#define INT		(1 << 8)
+
+u32 io_apic_read(u32 ioapic_base, u32 reg);
+void io_apic_write(u32 ioapic_base, u32 reg, u32 value);
+void set_ioapic_id(u32 ioapic_base, u8 ioapic_id);
+void setup_ioapic(u32 ioapic_base, u8 ioapic_id);
+void clear_ioapic(u32 ioapic_base);
+
+#endif
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#24 lore raw

PATCH 12/33 x86: pci: Add handlers before and after a PCI hose scan

In reply to Simon Glass

Some boards will want to do some setup before and after a PCI hose is scanned.

---

 arch/x86/cpu/pci.c         | 14 +++++++++++++-
 arch/x86/include/asm/pci.h |  3 +++
 2 files changed, 16 insertions(+), 1 deletion(-)
arch/x86/cpu/pci.c +13 -1
index 36057c6..43a4cb9 100644
@@ -32,6 +32,16 @@ int pci_early_init_hose(struct pci_controller **hosep)
 	return 0;
 }
 
+__weak int board_pci_pre_scan(struct pci_controller *hose)
+{
+	return 0;
+}
+
+__weak int board_pci_post_scan(struct pci_controller *hose)
+{
+	return 0;
+}
+
 void pci_init_board(void)
 {
 	struct pci_controller *hose = &x86_hose;
@@ -42,7 +52,9 @@ void pci_init_board(void)
 	board_pci_setup_hose(hose);
 	pci_register_hose(hose);
 
-	pci_hose_scan(hose);
+	board_pci_pre_scan(hose);
+	hose->last_busno = pci_hose_scan(hose);
+	board_pci_post_scan(hose);
 }
 
 static struct pci_controller *get_hose(void)
arch/x86/include/asm/pci.h +3 -0
index 98817aa..ac1a808 100644
@@ -34,6 +34,9 @@ void board_pci_setup_hose(struct pci_controller *hose);
  */
 int pci_early_init_hose(struct pci_controller **hosep);
 
+int board_pci_pre_scan(struct pci_controller *hose);
+int board_pci_post_scan(struct pci_controller *hose);
+
 /*
  * Simple PCI access routines - these work from either the early PCI hose
  * or the 'real' one, created after U-Boot has memory available
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#25 lore raw

PATCH 12/33 x86: pci: Add handlers before and after a PCI hose scan

Quoted 47 lines · Simon Glass

Some boards will want to do some setup before and after a PCI hose is scanned.

---

 arch/x86/cpu/pci.c         | 14 +++++++++++++-
 arch/x86/include/asm/pci.h |  3 +++
 2 files changed, 16 insertions(+), 1 deletion(-)
arch/x86/cpu/pci.c +13 -1
index 36057c6..43a4cb9 100644
@@ -32,6 +32,16 @@ int pci_early_init_hose(struct pci_controller **hosep)
        return 0;
 }
 
+__weak int board_pci_pre_scan(struct pci_controller *hose)
+{
+       return 0;
+}
+
+__weak int board_pci_post_scan(struct pci_controller *hose)
+{
+       return 0;
+}
+
 void pci_init_board(void)
 {
        struct pci_controller *hose = &x86_hose;
@@ -42,7 +52,9 @@ void pci_init_board(void)
        board_pci_setup_hose(hose);
        pci_register_hose(hose);
 
-       pci_hose_scan(hose);
+       board_pci_pre_scan(hose);
+       hose->last_busno = pci_hose_scan(hose);
+       board_pci_post_scan(hose);
 }
 
 static struct pci_controller *get_hose(void)
arch/x86/include/asm/pci.h +0 -0
index 98817aa..ac1a808 100644

arch/x86/include/asm/pci.h void board_pci_setup_hose(struct pci_controller *hose);

Quoted 10 lines
arch/x86/include/asm/pci.h +3 -1
@@ -34,6 +34,9 @@ void board_pci_setup_hose(struct pci_controller *hose);
  */
 int pci_early_init_hose(struct pci_controller **hosep);
 
+int board_pci_pre_scan(struct pci_controller *hose);
+int board_pci_post_scan(struct pci_controller *hose);
+
 /*
  * Simple PCI access routines - these work from either the early PCI hose
  * or the 'real' one, created after U-Boot has memory available
--
#26 lore raw

PATCH 13/33 x86: config: Enable plug-and-play for link PCI

In reply to Simon Glass

Enable this option so that we can configure the available PCI devices. Also make sure that PCI is available early after relocation as we use it for several other subsystems.

---

 include/configs/chromebook_link.h | 3 +++
 1 file changed, 3 insertions(+)
include/configs/chromebook_link.h +3 -0
index cd4a8a0..055b3ac 100644
@@ -66,6 +66,9 @@
 #define CONFIG_PCI_IO_PHYS	CONFIG_PCI_IO_BUS
 #define CONFIG_PCI_IO_SIZE	0xefff
 
+#define CONFIG_SYS_EARLY_PCI_INIT
+#define CONFIG_PCI_PNP
+
 #define CONFIG_STD_DEVICES_SETTINGS     "stdin=usbkbd,vga,serial\0" \
 					"stdout=vga,serial\0" \
 					"stderr=vga,serial\0"
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#27 lore raw

PATCH 14/33 pci: Add functions to read and write a BAR address

In reply to Simon Glass

Some PCI functions cannot be auto-configured. Add a function to set up a fixed BAR which can be used in these situations. Also add a function to read the current address of a BAR.

---

 drivers/pci/pci.c | 24 +++++++++++++++++++++---
 include/pci.h     | 23 +++++++++++++++++++++++
 2 files changed, 44 insertions(+), 3 deletions(-)
drivers/pci/pci.c +21 -3
index 60c333e..e879d1e 100644
@@ -363,9 +363,27 @@ phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
 	return phys_addr;
 }
 
-/*
- *
- */
+void pci_config_fixed(struct pci_controller *hose, pci_dev_t dev, int barnum,
+		      u32 addr)
+{
+	int bar;
+
+	bar = PCI_BASE_ADDRESS_0 + barnum * 4;
+	pci_hose_write_config_dword(hose, dev, bar, addr);
+}
+
+u32 pci_read_bar(struct pci_controller *hose, pci_dev_t dev, int barnum)
+{
+	u32 addr;
+	int bar;
+
+	bar = PCI_BASE_ADDRESS_0 + barnum * 4;
+	pci_hose_read_config_dword(hose, dev, bar, &addr);
+	if (addr & PCI_BASE_ADDRESS_SPACE_IO)
+		return addr & PCI_BASE_ADDRESS_IO_MASK;
+	else
+		return addr & PCI_BASE_ADDRESS_MEM_MASK;
+}
 
 int pci_hose_config_device(struct pci_controller *hose,
 			   pci_dev_t dev,
include/pci.h +23 -0
index 2ff7365..05c67bc 100644
@@ -677,5 +677,28 @@ extern void pci_mpc824x_init (struct pci_controller *hose);
 extern void pci_mpc85xx_init (struct pci_controller *hose);
 #endif
 
+/**
+ * pci_config_fixed() - Write the address of a BAR including control bits
+ *
+ * This writes a raw address (with control bits) to a bar
+ *
+ * @hose:	PCI hose to use
+ * @dev:	PCI device to update
+ * @barnum:	BAR number (0-5)
+ * @addr:	BAR address with controll bits
+ */
+void pci_config_fixed(struct pci_controller *hose, pci_dev_t dev, int barnum,
+		      u32 addr);
+
+/**
+ * pci_read_bar() - read the address of a bar
+ *
+ * @hose:	PCI hose to use
+ * @dev:	PCI device to inspect
+ * @barnum:	BAR number (0-5)
+ * @return address of the bar, masking out any control bits
+ * */
+u32 pci_read_bar(struct pci_controller *hose, pci_dev_t dev, int barnum);
+
 #endif /* __ASSEMBLY__ */
 #endif /* _PCI_H */
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#28 lore raw

PATCH 14/33 pci: Add functions to read and write a BAR address

Hi Simon,

Quoted 21 lines · Simon Glass

Some PCI functions cannot be auto-configured. Add a function to set up a fixed BAR which can be used in these situations. Also add a function to read the current address of a BAR.

---

 drivers/pci/pci.c | 24 +++++++++++++++++++++---
 include/pci.h     | 23 +++++++++++++++++++++++
 2 files changed, 44 insertions(+), 3 deletions(-)
drivers/pci/pci.c +0 -2
index 60c333e..e879d1e 100644
@@ -363,9 +363,27 @@ phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
        return phys_addr;
 }
 
-/*
- *

drivers/pci/pci.c phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose, · line 374

Quoted 10 lines
drivers/pci/pci.c +9 -1
- */
+void pci_config_fixed(struct pci_controller *hose, pci_dev_t dev, int barnum,
+                     u32 addr)
+{
+       int bar;
+
+       bar = PCI_BASE_ADDRESS_0 + barnum * 4;
+       pci_hose_write_config_dword(hose, dev, bar, addr);
+}
+

Maybe better renane it to pci_write_bar() to match the pci_read_bar() below? And considering it only covers the 32-bit bar, maybe pci_write_bar32() is even better.

drivers/pci/pci.c phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose, · line 387

Quoted 13 lines
drivers/pci/pci.c +12 -0
+u32 pci_read_bar(struct pci_controller *hose, pci_dev_t dev, int barnum)
+{
+       u32 addr;
+       int bar;
+
+       bar = PCI_BASE_ADDRESS_0 + barnum * 4;
+       pci_hose_read_config_dword(hose, dev, bar, &addr);
+       if (addr & PCI_BASE_ADDRESS_SPACE_IO)
+               return addr & PCI_BASE_ADDRESS_IO_MASK;
+       else
+               return addr & PCI_BASE_ADDRESS_MEM_MASK;
+}
 

pci_read_bar32()?

Quoted 26 lines
drivers/pci/pci.c +0 -0
 int pci_hose_config_device(struct pci_controller *hose,
                           pci_dev_t dev,
include/pci.h +16 -0
index 2ff7365..05c67bc 100644
@@ -677,5 +677,28 @@ extern void pci_mpc824x_init (struct pci_controller *hose);
 extern void pci_mpc85xx_init (struct pci_controller *hose);
 #endif
 
+/**
+ * pci_config_fixed() - Write the address of a BAR including control bits
+ *
+ * This writes a raw address (with control bits) to a bar
+ *
+ * @hose:      PCI hose to use
+ * @dev:       PCI device to update
+ * @barnum:    BAR number (0-5)
+ * @addr:      BAR address with controll bits
+ */
+void pci_config_fixed(struct pci_controller *hose, pci_dev_t dev, int barnum,
+                     u32 addr);
+
+/**
+ * pci_read_bar() - read the address of a bar
+ *

include/pci.h extern void pci_mpc824x_init (struct pci_controller *hose);

Quoted 10 lines
include/pci.h +7 -1
+ * @hose:      PCI hose to use
+ * @dev:       PCI device to inspect
+ * @barnum:    BAR number (0-5)
+ * @return address of the bar, masking out any control bits
+ * */
+u32 pci_read_bar(struct pci_controller *hose, pci_dev_t dev, int barnum);
+
 #endif /* __ASSEMBLY__ */
 #endif /* _PCI_H */
--

Regards,
Bin

#29 lore raw

PATCH 15/33 x86: ivybridge: Add support for BD82x6x PCH

In reply to Simon Glass

Add basic setup for the PCH.

---

 arch/x86/cpu/ivybridge/Makefile               |  1 +
 arch/x86/cpu/ivybridge/bd82x6x.c              | 99 +++++++++++++++++++++++++++
 arch/x86/cpu/ivybridge/pci.c                  | 40 +++++++++++
 arch/x86/include/asm/arch-ivybridge/bd82x6x.h | 14 ++++
 arch/x86/include/asm/arch-ivybridge/pch.h     | 13 ++++
 5 files changed, 167 insertions(+)
 create mode 100644 arch/x86/cpu/ivybridge/bd82x6x.c
 create mode 100644 arch/x86/include/asm/arch-ivybridge/bd82x6x.h
arch/x86/cpu/ivybridge/Makefile +1 -0
index 721b37e..b37fb8f 100644
@@ -4,6 +4,7 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+obj-y += bd82x6x.o
 obj-y += car.o
 obj-y += cpu.o
 obj-y += early_init.o
arch/x86/cpu/ivybridge/bd82x6x.c new file +99 -0

99 lines not on this page · raw message

arch/x86/cpu/ivybridge/pci.c +40 -0
index 8469797..596d48e 100644
@@ -12,6 +12,8 @@
 #include <common.h>
 #include <pci.h>
 #include <asm/pci.h>
+#include <asm/arch/bd82x6x.h>
+#include <asm/arch/pch.h>
 
 static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev,
 			      struct pci_config_table *table)
@@ -61,3 +63,41 @@ void board_pci_setup_hose(struct pci_controller *hose)
 
 	pci_setup_type1(hose);
 }
+
+int board_pci_pre_scan(struct pci_controller *hose)
+{
+	pci_dev_t dev;
+	u16 reg16;
+
+	bd82x6x_init();
+
+	reg16 = 0xff;
+	dev = PCH_DEV;
+	reg16 = pci_read_config16(dev, PCI_COMMAND);
+	reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	pci_write_config16(dev, PCI_COMMAND, reg16);
+
+	/*
+	* Clear non-reserved bits in status register.
+	*/
+	pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+	pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+	pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+	pci_config_fixed(hose, dev, 0, 0xf0000000);
+
+	return 0;
+}
+
+int board_pci_post_scan(struct pci_controller *hose)
+{
+	int ret;
+
+	ret = bd82x6x_init_pci_devices();
+	if (ret) {
+		printf("bd82x6x_init_pci_devices() failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
arch/x86/include/asm/arch-ivybridge/bd82x6x.h new file +14 -0
new file mode 100644
index 0000000..e02520c
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_BD82X6X_H
+#define _ASM_ARCH_BD82X6X_H
+
+void bd82x6x_pci_init(pci_dev_t dev);
+int bd82x6x_init_pci_devices(void);
+int bd82x6x_init(void);
+
+#endif
arch/x86/include/asm/arch-ivybridge/pch.h +13 -0
index c6efdb8..aa626ad 100644
@@ -19,6 +19,16 @@
 
 #define SMBUS_IO_BASE		0x0400
 
+/* PCI Configuration Space (D30:F0): PCI2PCI */
+#define PSTS	0x06
+#define SMLT	0x1b
+#define SECSTS	0x1e
+#define INTR	0x3c
+#define BCTRL	0x3e
+#define   SBR	(1 << 6)
+#define   SEE	(1 << 1)
+#define   PERE	(1 << 0)
+
 #define PCH_EHCI1_DEV		PCI_BDF(0, 0x1d, 0)
 #define PCH_EHCI2_DEV		PCI_BDF(0, 0x1a, 0)
 #define PCH_XHCI_DEV		PCI_BDF(0, 0x14, 0)
@@ -343,6 +353,9 @@
 #define   DMISCI_STS	(1 << 9)
 #define TCO2_STS	0x66
 
+int lpc_init(struct pci_controller *hose, pci_dev_t dev);
+void lpc_enable(pci_dev_t dev);
+
 /**
  * lpc_early_init() - set up LPC serial ports and other early things
  *
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#30 lore raw

PATCH 16/33 x86: Add basic i8259 implementation

In reply to Simon Glass

The i8259 is a basic interrupt controller from the 1970s which is still present in modern Intel hardware. Add some code to set it up.

---

 arch/x86/include/asm/i8259.h |   3 +
 arch/x86/lib/Makefile        |   1 +
 arch/x86/lib/i8259.c         | 134 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 138 insertions(+)
 create mode 100644 arch/x86/lib/i8259.c
arch/x86/include/asm/i8259.h +3 -0
index 73113f9..bac073d 100644
@@ -69,4 +69,7 @@
 #define	ICW4_AEOI	0x02	/* Automatic EOI Mode */
 #define ICW4_PM		0x01	/* Microprocessor Mode */
 
+void i8259_setup(void);
+void i8259_configure_irq_trigger(int int_num, bool is_level_triggered);
+
 #endif
arch/x86/lib/Makefile +1 -0
index d0c7f30..2d75f9f 100644
@@ -8,6 +8,7 @@
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
 obj-y	+= cmd_boot.o
 obj-y	+= gcc.o
+obj-y += i8259.o
 obj-y	+= init_helpers.o
 obj-y	+= interrupts.o
 obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
arch/x86/lib/i8259.c new file +134 -0

134 lines not on this page · raw message

Signature · 1 line
2.1.0.rc2.206.gedb03e5
#31 lore raw

PATCH 16/33 x86: Add basic i8259 implementation

Hi Simon,

Quoted 167 lines · Simon Glass

The i8259 is a basic interrupt controller from the 1970s which is still present in modern Intel hardware. Add some code to set it up.

---

 arch/x86/include/asm/i8259.h |   3 +
 arch/x86/lib/Makefile        |   1 +
 arch/x86/lib/i8259.c         | 134 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 138 insertions(+)
 create mode 100644 arch/x86/lib/i8259.c
arch/x86/include/asm/i8259.h +3 -0
index 73113f9..bac073d 100644
@@ -69,4 +69,7 @@
 #define        ICW4_AEOI       0x02    /* Automatic EOI Mode */
 #define ICW4_PM                0x01    /* Microprocessor Mode */
 
+void i8259_setup(void);
+void i8259_configure_irq_trigger(int int_num, bool is_level_triggered);
+
 #endif
arch/x86/lib/Makefile +1 -0
index d0c7f30..2d75f9f 100644
@@ -8,6 +8,7 @@
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
 obj-y  += cmd_boot.o
 obj-y  += gcc.o
+obj-y += i8259.o
 obj-y  += init_helpers.o
 obj-y  += interrupts.o
 obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
arch/x86/lib/i8259.c new file +125 -0
new file mode 100644
index 0000000..442d904
@@ -0,0 +1,134 @@
+/*
+ * From Coreboot file of the same name
+ *
+ * Copyright (C) 2009 coresystems GmbH
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/i8259.h>
+
+#define MASTER_PIC_ICW1                0x20
+#define SLAVE_PIC_ICW1         0xa0
+#define   ICW_SELECT           (1 << 4)
+#define   OCW_SELECT           (0 << 4)
+#define   ADI                  (1 << 2)
+#define   SNGL                 (1 << 1)
+#define   IC4                  (1 << 0)
+
+#define MASTER_PIC_ICW2                0x21
+#define SLAVE_PIC_ICW2         0xa1
+#define   INT_VECTOR_MASTER    0x20
+#define   IRQ0                 0x00
+#define   IRQ1                 0x01
+#define   INT_VECTOR_SLAVE     0x28
+#define   IRQ8                 0x00
+#define   IRQ9                 0x01
+
+#define MASTER_PIC_ICW3                0x21
+#define   CASCADED_PIC         (1 << 2)
+
+#define MASTER_PIC_ICW4                0x21
+#define SLAVE_PIC_ICW4         0xa1
+#define   MICROPROCESSOR_MODE  (1 << 0)
+
+#define SLAVE_PIC_ICW3         0xa1
+#define    SLAVE_ID            0x02
+
+#define MASTER_PIC_OCW1                0x21
+#define SLAVE_PIC_OCW1         0xa1
+#define    IRQ2                        (1 << 2)
+#define    ALL_IRQS            0xff
+
+#define ELCR1                  0x4d0
+#define ELCR2                  0x4d1
+
+void i8259_setup(void)
+{
+       /* A write to ICW1 starts the Interrupt Controller Initialization
+        * Sequence. This implicitly causes the following to happen:
+        *   - Interrupt Mask register is cleared
+        *   - Priority 7 is assigned to IRQ7 input
+        *   - Slave mode address is set to 7
+        *   - Special mask mode is cleared
+        *
+        * We send the initialization sequence to both the master and
+        * slave i8259 controller.
+        */
+       outb(ICW_SELECT|IC4, MASTER_PIC_ICW1);
+       outb(ICW_SELECT|IC4, SLAVE_PIC_ICW1);
+
+       /* Now the interrupt controller expects us to write to ICW2. */
+       outb(INT_VECTOR_MASTER | IRQ0, MASTER_PIC_ICW2);
+       outb(INT_VECTOR_SLAVE  | IRQ8, SLAVE_PIC_ICW2);
+
+       /* Now the interrupt controller expects us to write to ICW3.
+        *
+        * The normal scenario is to set up cascading on IRQ2 on the master
+        * i8259 and assign the slave ID 2 to the slave i8259.
+        */
+       outb(CASCADED_PIC, MASTER_PIC_ICW3);
+       outb(SLAVE_ID, SLAVE_PIC_ICW3);
+
+       /* Now the interrupt controller expects us to write to ICW4.
+        *
+        * We switch both i8259 to microprocessor mode because they're
+        * operating as part of an x86 architecture based chipset
+        */
+       outb(MICROPROCESSOR_MODE, MASTER_PIC_ICW2);
+       outb(MICROPROCESSOR_MODE, SLAVE_PIC_ICW2);
+
+       /* Now clear the interrupts through OCW1.
+        * First we mask off all interrupts on the slave interrupt controller
+        * then we mask off all interrupts but interrupt 2 on the master
+        * controller. This way the cascading stays alife.
+        */
+       outb(ALL_IRQS, SLAVE_PIC_OCW1);
+       outb(ALL_IRQS & ~IRQ2, MASTER_PIC_OCW1);
+       debug("i8259 inited\n");
+}
+
+/**
+ * i8259_configure_irq_trigger() - Configure IRQ triggering
+ *
+ * Switch the given interrupt to be level / edge triggered
+ *
+ * @param int_num legacy interrupt number (3-7, 9-15)
+ * @param is_level_triggered true for level triggered interrupt, false for
+ *     edge triggered interrupt
+ */
+void i8259_configure_irq_trigger(int int_num, bool is_level_triggered)
+{
+       u16 int_bits = inb(ELCR1) | (((u16)inb(ELCR2)) << 8);
+
+       debug("%s: current interrupts are 0x%x\n", __func__, int_bits);
+       if (is_level_triggered)
+               int_bits |= (1 << int_num);
+       else
+               int_bits &= ~(1 << int_num);
+
+       /* Write new values */
+       debug("%s: try to set interrupts 0x%x\n", __func__, int_bits);
+       outb((u8)(int_bits & 0xff), ELCR1);
+       outb((u8)(int_bits >> 8), ELCR2);
+
+#ifdef PARANOID_IRQ_TRIGGERS
+       /*
+        * Try reading back the new values. This seems like an error but is
+        * not
+        */
+       if (inb(ELCR1) != (int_bits & 0xff)) {
+               printf("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
+                      __func__, (int_bits & 0xff), inb(ELCR1));
+       }

arch/x86/lib/i8259.c

Quoted 10 lines
arch/x86/lib/i8259.c new file +9 -1
+
+       if (inb(ELCR2) != (int_bits >> 8)) {
+               printf("%s: higher order bits are wrong: want 0x%x, got 0x%x\n",
+                      __func__, (int_bits>>8), inb(ELCR2));
+       }
+#endif
+}
+
+
--

Can you make the changes to the existing arch/x86/lib/pcat_interrupts.c which is also the i8259 pic driver initialization?

Regards,
Bin

#32 lore raw

PATCH 17/33 x86: Add ISA DMA implementation

In reply to Simon Glass

Add simple init for the ISA DMA settings.

---

 arch/x86/include/asm/isa_dma.h | 14 +++++++++++
 arch/x86/lib/Makefile          |  1 +
 arch/x86/lib/isa_dma.c         | 56 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)
 create mode 100644 arch/x86/include/asm/isa_dma.h
 create mode 100644 arch/x86/lib/isa_dma.c
arch/x86/include/asm/isa_dma.h new file +14 -0
new file mode 100644
index 0000000..69c6a84
@@ -0,0 +1,14 @@
+/*
+ * From Coreboot
+ * Copyright (C) 2014 Google, Inc
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef __ASM_ISA_DMA_H
+#define _ASM_ISA_DMA_H
+
+void isa_dma_init(void);
+
+#endif
arch/x86/lib/Makefile +1 -0
index 2d75f9f..622ef08 100644
@@ -11,6 +11,7 @@ obj-y	+= gcc.o
 obj-y += i8259.o
 obj-y	+= init_helpers.o
 obj-y	+= interrupts.o
+obj-y += isa_dma.o
 obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
 obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o
 obj-$(CONFIG_PCI) += pci_type1.o
arch/x86/lib/isa_dma.c new file +56 -0

56 lines not on this page · raw message

Signature · 1 line
2.1.0.rc2.206.gedb03e5
#33 lore raw

PATCH 17/33 x86: Add ISA DMA implementation

Hi Simon,

Quoted 97 lines · Simon Glass

Add simple init for the ISA DMA settings.

---

 arch/x86/include/asm/isa_dma.h | 14 +++++++++++
 arch/x86/lib/Makefile          |  1 +
 arch/x86/lib/isa_dma.c         | 56 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)
 create mode 100644 arch/x86/include/asm/isa_dma.h
 create mode 100644 arch/x86/lib/isa_dma.c
arch/x86/include/asm/isa_dma.h new file +14 -0
new file mode 100644
index 0000000..69c6a84
@@ -0,0 +1,14 @@
+/*
+ * From Coreboot
+ * Copyright (C) 2014 Google, Inc
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#ifndef __ASM_ISA_DMA_H
+#define _ASM_ISA_DMA_H
+
+void isa_dma_init(void);
+
+#endif
arch/x86/lib/Makefile +1 -0
index 2d75f9f..622ef08 100644
@@ -11,6 +11,7 @@ obj-y += gcc.o
 obj-y += i8259.o
 obj-y  += init_helpers.o
 obj-y  += interrupts.o
+obj-y += isa_dma.o
 obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
 obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o
 obj-$(CONFIG_PCI) += pci_type1.o
arch/x86/lib/isa_dma.c new file +47 -0
new file mode 100644
index 0000000..36d6ee5
@@ -0,0 +1,56 @@
+/*
+ * From Coreboot
+ * Copyright (C) 2014 Google, Inc
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/isa_dma.h>
+
+/* DMA controller registers */
+#define DMA1_CMD_REG           0x08    /* command register (w) */
+#define DMA1_STAT_REG          0x08    /* status register (r) */
+#define DMA1_REQ_REG            0x09    /* request register (w) */
+#define DMA1_MASK_REG          0x0A    /* single-channel mask (w) */
+#define DMA1_MODE_REG          0x0B    /* mode register (w) */
+#define DMA1_CLEAR_FF_REG      0x0C    /* clear pointer flip-flop (w) */
+#define DMA1_TEMP_REG           0x0D    /* Temporary Register (r) */
+#define DMA1_RESET_REG         0x0D    /* Master Clear (w) */
+#define DMA1_CLR_MASK_REG       0x0E    /* Clear Mask */
+#define DMA1_MASK_ALL_REG       0x0F    /* all-channels mask (w) */
+
+#define DMA2_CMD_REG           0xD0    /* command register (w) */
+#define DMA2_STAT_REG          0xD0    /* status register (r) */
+#define DMA2_REQ_REG            0xD2    /* request register (w) */
+#define DMA2_MASK_REG          0xD4    /* single-channel mask (w) */
+#define DMA2_MODE_REG          0xD6    /* mode register (w) */
+#define DMA2_CLEAR_FF_REG      0xD8    /* clear pointer flip-flop (w) */
+#define DMA2_TEMP_REG           0xDA    /* Temporary Register (r) */
+#define DMA2_RESET_REG         0xDA    /* Master Clear (w) */
+#define DMA2_CLR_MASK_REG       0xDC    /* Clear Mask */
+#define DMA2_MASK_ALL_REG       0xDE    /* all-channels mask (w) */
+
+/* I/O to memory, no autoinit, increment, single mode */
+#define DMA_MODE_READ  0x44
+/* memory to I/O, no autoinit, increment, single mode */
+#define DMA_MODE_WRITE 0x48
+#define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
+
+#define DMA_AUTOINIT   0x10
+
+void isa_dma_init(void)
+{
+       /*
+        * slave at 0x00 - 0x0f

arch/x86/lib/isa_dma.c

Quoted 10 lines
arch/x86/lib/isa_dma.c new file +9 -1
+        * master at 0xc0 - 0xdf
+        * 0x80 - 0x8f DMA page registers
+        * DMA: 0x00, 0x02, 0x4, 0x06 base address for DMA channel
+        */
+       outb(0, DMA1_RESET_REG);
+       outb(0, DMA2_RESET_REG);
+       outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
+       outb(0, DMA2_MASK_REG);
+}
--

Why is this whole patch needed? Is there any U-Boot driver that depends on this driver to initialize the DMA to work correctly? If not, I'd suggest we drop this patch.

Regards,
Bin

#34 lore raw

PATCH 18/33 x86: Add a simple header file for ACPI

In reply to Simon Glass

We don't use many features yet, so this only has a few declarations. It will be expanded as needed.

---

 arch/x86/include/asm/acpi.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 arch/x86/include/asm/acpi.h
arch/x86/include/asm/acpi.h new file +24 -0
new file mode 100644
index 0000000..4872b92
@@ -0,0 +1,24 @@
+/*
+ * From coreboot
+ *
+ * Copyright (C) 2004 SUSE LINUX AG
+ * Copyright (C) 2004 Nick Barker
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * (Written by Stefan Reinauer <[email protected]>)
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef __ASM_ACPI_H
+#define __ASM_ACPI_H
+
+#define RSDP_SIG		"RSD PTR "  /* RSDT pointer signature */
+#define ACPI_TABLE_CREATOR	"U-BootAC"  /* Must be exactly 8 bytes long! */
+#define OEM_ID			"U-Boot"    /* Must be exactly 6 bytes long! */
+#define ASLC			"U-Bo"      /* Must be exactly 4 bytes long! */
+
+/* 0 = S0, 1 = S1 ...*/
+int acpi_get_slp_type(void);
+void apci_set_slp_type(int type);
+
+#endif
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#35 lore raw

PATCH 19/33 x86: ivybridge: Add PCH init

In reply to Simon Glass

Add required init for the Intel Platform Controller Hub in ivybridge.

---

 arch/x86/cpu/ivybridge/Makefile           |   1 +
 arch/x86/cpu/ivybridge/pch.c              | 123 ++++++++++++++++++++++++++++++
 arch/x86/include/asm/arch-ivybridge/pch.h |  49 ++++++++++++
 3 files changed, 173 insertions(+)
 create mode 100644 arch/x86/cpu/ivybridge/pch.c
arch/x86/cpu/ivybridge/Makefile +1 -0
index b37fb8f..479e446 100644
@@ -12,6 +12,7 @@ obj-y += early_me.o
 obj-y += lpc.o
 obj-y += me_status.o
 obj-y += microcode_intel.o
+obj-y += pch.o
 obj-y += pci.o
 obj-y += report_platform.o
 obj-y += sdram.o
arch/x86/cpu/ivybridge/pch.c new file +123 -0

123 lines not on this page · raw message

arch/x86/include/asm/arch-ivybridge/pch.h +49 -0

66 lines not on this page · raw message

Signature · 1 line
2.1.0.rc2.206.gedb03e5
#36 lore raw

PATCH 20/33 x86: ivybridge: Add additional LPC init

In reply to Simon Glass

Set up all the remaining pieces of the LPC (low-pin-count) peripheral in PCH (Peripheral Controller Hub).

---

 arch/x86/cpu/ivybridge/bd82x6x.c            |   6 +
 arch/x86/cpu/ivybridge/lpc.c                | 529 +++++++++++++++++++++++++++-
 doc/device-tree-bindings/misc/intel-lpc.txt |  47 ++-
 3 files changed, 578 insertions(+), 4 deletions(-)
arch/x86/cpu/ivybridge/bd82x6x.c +6 -0
index fab7c53..be4db74 100644
@@ -88,6 +88,12 @@ void bd82x6x_pci_bus_enable_resources(pci_dev_t dev)
 
 int bd82x6x_init_pci_devices(void)
 {
+	struct pci_controller *hose;
+
+	hose = pci_bus_to_hose(0);
+	lpc_enable(PCH_LPC_DEV);
+	lpc_init(hose, PCH_LPC_DEV);
+
 	return 0;
 }
 
arch/x86/cpu/ivybridge/lpc.c +528 -1

548 lines not on this page · raw message

doc/device-tree-bindings/misc/intel-lpc.txt +44 -3

59 lines not on this page · raw message

Signature · 1 line
2.1.0.rc2.206.gedb03e5
#37 lore raw

PATCH 21/33 x86: dts: Move PCI peripherals into a pci node

In reply to Simon Glass

These peripherals should not be at the top level, since they exist inside the PCI bus. We don't have a full device tree node for pci yet, but we should at least put it at the right level.

---

 arch/x86/dts/link.dts | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)
arch/x86/dts/link.dts +15 -13
index 9329916..4520db5 100644
@@ -163,21 +163,23 @@
 		};
 	};
 
-	lpc {
-		compatible = "intel,lpc";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		gen-dec = <0x800 0xfc 0x900 0xfc>;
-		cros-ec at 200 {
-			compatible = "google,cros-ec";
-			reg = <0x204 1 0x200 1 0x880 0x80>;
-
-			/* This describes the flash memory within the EC */
+	pci {
+		lpc {
+			compatible = "intel,lpc";
 			#address-cells = <1>;
 			#size-cells = <1>;
-			flash at 8000000 {
-				reg = <0x08000000 0x20000>;
-				erase-value = <0xff>;
+			gen-dec = <0x800 0xfc 0x900 0xfc>;
+			cros-ec at 200 {
+				compatible = "google,cros-ec";
+				reg = <0x204 1 0x200 1 0x880 0x80>;
+
+				/* Describes the flash memory within the EC */
+				#address-cells = <1>;
+				#size-cells = <1>;
+				flash at 8000000 {
+					reg = <0x08000000 0x20000>;
+					erase-value = <0xff>;
+				};
 			};
 		};
 	};
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#38 lore raw

PATCH 22/33 x86: dts: Add LPC settings for link

In reply to Simon Glass

Add some settings required to set up the LPC correctly.

---

 arch/x86/dts/link.dts | 8 ++++++++
 1 file changed, 8 insertions(+)
arch/x86/dts/link.dts +8 -0
index 4520db5..28cef07 100644
@@ -169,6 +169,14 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 			gen-dec = <0x800 0xfc 0x900 0xfc>;
+			intel,gen-dec = <0x800 0xfc 0x900 0xfc>;
+			intel,pirq-routing = <0x8b 0x8a 0x8b 0x8b
+						0x80 0x80 0x80 0x80>;
+			intel,gpi-routing = <0 0 0 0 0 0 0 2
+						1 0 0 0 0 0 0 0>;
+			/* Enable EC SMI source */
+			intel,alt-gp-smi-enable = <0x0100>;
+
 			cros-ec at 200 {
 				compatible = "google,cros-ec";
 				reg = <0x204 1 0x200 1 0x880 0x80>;
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#39 lore raw

PATCH 23/33 x86: ivybridge: Add SATA init

In reply to Simon Glass

Add code to set up the SATA interfaces on boot.

---

 arch/x86/cpu/ivybridge/Makefile               |   1 +
 arch/x86/cpu/ivybridge/bd82x6x.c              |  20 +++
 arch/x86/cpu/ivybridge/sata.c                 | 243 ++++++++++++++++++++++++++
 arch/x86/include/asm/arch-ivybridge/bd82x6x.h |   2 +
 arch/x86/include/asm/arch-ivybridge/pch.h     |  58 ++++++
 doc/device-tree-bindings/ata/intel-sata.txt   |  26 +++
 include/fdtdec.h                              |   1 +
 lib/fdtdec.c                                  |   1 +
 8 files changed, 352 insertions(+)
 create mode 100644 arch/x86/cpu/ivybridge/sata.c
 create mode 100644 doc/device-tree-bindings/ata/intel-sata.txt
arch/x86/cpu/ivybridge/Makefile +1 -0
index 479e446..c6342cd 100644
@@ -15,4 +15,5 @@ obj-y += microcode_intel.o
 obj-y += pch.o
 obj-y += pci.o
 obj-y += report_platform.o
+obj-y += sata.o
 obj-y += sdram.o
arch/x86/cpu/ivybridge/bd82x6x.c +20 -0
index be4db74..b54f5c7 100644
@@ -88,18 +88,38 @@ void bd82x6x_pci_bus_enable_resources(pci_dev_t dev)
 
 int bd82x6x_init_pci_devices(void)
 {
+	const void *blob = gd->fdt_blob;
 	struct pci_controller *hose;
+	int sata_node;
 
 	hose = pci_bus_to_hose(0);
 	lpc_enable(PCH_LPC_DEV);
 	lpc_init(hose, PCH_LPC_DEV);
+	sata_node = fdtdec_next_compatible(blob, 0,
+					   COMPAT_INTEL_PANTHERPOINT_AHCI);
+	if (sata_node < 0) {
+		debug("%s: Cannot find SATA node\n", __func__);
+		return -EINVAL;
+	}
+	bd82x6x_sata_init(PCH_SATA_DEV, blob, sata_node);
 
 	return 0;
 }
 
 int bd82x6x_init(void)
 {
+	const void *blob = gd->fdt_blob;
+	int sata_node;
+
+	sata_node = fdtdec_next_compatible(blob, 0,
+					   COMPAT_INTEL_PANTHERPOINT_AHCI);
+	if (sata_node < 0) {
+		debug("%s: Cannot find SATA node\n", __func__);
+		return -EINVAL;
+	}
+
 	bd82x6x_pci_init(PCH_DEV);
+	bd82x6x_sata_enable(PCH_SATA_DEV, blob, sata_node);
 
 	return 0;
 }
arch/x86/cpu/ivybridge/sata.c new file +243 -0

243 lines not on this page · raw message

arch/x86/include/asm/arch-ivybridge/bd82x6x.h +2 -0
index e02520c..644755f 100644
@@ -7,6 +7,8 @@
 #ifndef _ASM_ARCH_BD82X6X_H
 #define _ASM_ARCH_BD82X6X_H
 
+void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node);
+void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node);
 void bd82x6x_pci_init(pci_dev_t dev);
 int bd82x6x_init_pci_devices(void);
 int bd82x6x_init(void);
arch/x86/include/asm/arch-ivybridge/pch.h +58 -0

64 lines not on this page · raw message

doc/device-tree-bindings/ata/intel-sata.txt new file +26 -0
new file mode 100644
index 0000000..5e4da83
@@ -0,0 +1,26 @@
+Intel Pantherpoint SATA Device Binding
+======================================
+
+The device tree node which describes the operation of the Intel Pantherpoint
+SATA device is as follows:
+
+Required properties :
+- compatible = "intel,pantherpoint-ahci"
+- intel,sata-mode : string, one of:
+     "ahci" : Use AHCI mode (default)
+     "combined" : Use combined IDE + legacy mode
+     "plain-ide" : Use plain IDE mode
+- intel,sata-port-map : Which SATA ports are enabled, bit 0=enable first port,
+    bit 1=enable second port, etc.
+- intel,sata-port0-gen3-tx : Value for the IOBP_SP0G3IR register
+- intel,sata-port1-gen3-tx : Value for the IOBP_SP1G3IR register
+
+Example
+-------
+
+sata {
+	compatible = "intel,pantherpoint-ahci";
+	intel,sata-mode = "ahci";
+	intel,sata-port-map = <1>;
+	intel,sata-port0-gen3-tx = <0x00880a7f>;
+};
include/fdtdec.h +1 -0
index abfd678..0a0afce 100644
@@ -120,6 +120,7 @@ enum fdt_compat_id {
 	COMPAT_INTEL_LPC,		/* Intel Low Pin Count I/F */
 	COMPAT_INTEL_MICROCODE,		/* Intel microcode update */
 	COMPAT_MEMORY_SPD,		/* Memory SPD information */
+	COMPAT_INTEL_PANTHERPOINT_AHCI,	/* Intel Pantherpoint AHCI */
 
 	COMPAT_COUNT,
 };
lib/fdtdec.c +1 -0
index aafc4f9..8865a26 100644
@@ -75,6 +75,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(COMPAT_INTEL_LPC, "intel,lpc"),
 	COMPAT(INTEL_MICROCODE, "intel,microcode"),
 	COMPAT(MEMORY_SPD, "memory-spd"),
+	COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#40 lore raw

PATCH 23/33 x86: ivybridge: Add SATA init

Hi Simon,

Quoted 289 lines · Simon Glass

Add code to set up the SATA interfaces on boot.

---

 arch/x86/cpu/ivybridge/Makefile               |   1 +
 arch/x86/cpu/ivybridge/bd82x6x.c              |  20 +++
 arch/x86/cpu/ivybridge/sata.c                 | 243 ++++++++++++++++++++++++++
 arch/x86/include/asm/arch-ivybridge/bd82x6x.h |   2 +
 arch/x86/include/asm/arch-ivybridge/pch.h     |  58 ++++++
 doc/device-tree-bindings/ata/intel-sata.txt   |  26 +++
 include/fdtdec.h                              |   1 +
 lib/fdtdec.c                                  |   1 +
 8 files changed, 352 insertions(+)
 create mode 100644 arch/x86/cpu/ivybridge/sata.c
 create mode 100644 doc/device-tree-bindings/ata/intel-sata.txt
arch/x86/cpu/ivybridge/Makefile +1 -0
index 479e446..c6342cd 100644
@@ -15,4 +15,5 @@ obj-y += microcode_intel.o
 obj-y += pch.o
 obj-y += pci.o
 obj-y += report_platform.o
+obj-y += sata.o
 obj-y += sdram.o
arch/x86/cpu/ivybridge/bd82x6x.c +20 -0
index be4db74..b54f5c7 100644
@@ -88,18 +88,38 @@ void bd82x6x_pci_bus_enable_resources(pci_dev_t dev)
 
 int bd82x6x_init_pci_devices(void)
 {
+       const void *blob = gd->fdt_blob;
        struct pci_controller *hose;
+       int sata_node;
 
        hose = pci_bus_to_hose(0);
        lpc_enable(PCH_LPC_DEV);
        lpc_init(hose, PCH_LPC_DEV);
+       sata_node = fdtdec_next_compatible(blob, 0,
+                                          COMPAT_INTEL_PANTHERPOINT_AHCI);
+       if (sata_node < 0) {
+               debug("%s: Cannot find SATA node\n", __func__);
+               return -EINVAL;
+       }
+       bd82x6x_sata_init(PCH_SATA_DEV, blob, sata_node);
 
        return 0;
 }
 
 int bd82x6x_init(void)
 {
+       const void *blob = gd->fdt_blob;
+       int sata_node;
+
+       sata_node = fdtdec_next_compatible(blob, 0,
+                                          COMPAT_INTEL_PANTHERPOINT_AHCI);
+       if (sata_node < 0) {
+               debug("%s: Cannot find SATA node\n", __func__);
+               return -EINVAL;
+       }
+
        bd82x6x_pci_init(PCH_DEV);
+       bd82x6x_sata_enable(PCH_SATA_DEV, blob, sata_node);
 
        return 0;
 }
arch/x86/cpu/ivybridge/sata.c new file +213 -0
new file mode 100644
index 0000000..134afb9
@@ -0,0 +1,243 @@
+/*
+ * From Coreboot
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/arch/pch.h>
+#include <asm/arch/bd82x6x.h>
+
+static inline u32 sir_read(pci_dev_t dev, int idx)
+{
+       pci_write_config32(dev, SATA_SIRI, idx);
+       return pci_read_config32(dev, SATA_SIRD);
+}
+
+static inline void sir_write(pci_dev_t dev, int idx, u32 value)
+{
+       pci_write_config32(dev, SATA_SIRI, idx);
+       pci_write_config32(dev, SATA_SIRD, value);
+}
+
+void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
+{
+       unsigned int port_map, speed_support, port_tx;
+       const char *mode;
+       u32 reg32;
+       u16 reg16;
+
+       debug("SATA: Initializing...\n");
+
+       /* SATA configuration */
+       port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
+       speed_support = fdtdec_get_int(blob, node,
+                                      "sata_interface_speed_support", 0);
+
+       /* Enable BARs */
+       pci_write_config16(dev, PCI_COMMAND, 0x0007);
+
+       mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
+       if (!mode || !strcmp(mode, "ahci")) {
+               u32 abar;
+
+               debug("SATA: Controller in AHCI mode\n");
+
+               /* Set Interrupt Line, Interrupt Pin is set by D31IP.PIP */
+               pci_write_config8(dev, INTR_LN, 0x0a);
+
+               /* Set timings */
+               pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+                               IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+                               IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+               pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+                               IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
+
+               /* Sync DMA */
+               pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
+               pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
+
+               /* Set IDE I/O Configuration */
+               reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 |
+                               PCB0;
+               pci_write_config32(dev, IDE_CONFIG, reg32);
+
+               /* for AHCI, Port Enable is managed in memory-mapped space */
+               reg16 = pci_read_config16(dev, 0x92);
+               reg16 &= ~0x3f; /* 6 ports SKU + ORM */
+               reg16 |= 0x8000 | port_map;
+               pci_write_config16(dev, 0x92, reg16);
+
+               /* SATA Initialization register */
+               pci_write_config32(dev, 0x94,
+                                  ((port_map ^ 0x3f) << 24) | 0x183);
+
+               /* Initialize AHCI memory-mapped space */
+               abar = pci_read_config32(dev, PCI_BASE_ADDRESS_5) & ~1;
+               debug("ABAR: %08X\n", abar);
+               /* CAP (HBA Capabilities) : enable power management */
+               reg32 = readl(abar + 0x00);
+               reg32 |= 0x0c006000;  /* set PSC+SSC+SALP+SSS */
+               reg32 &= ~0x00020060; /* clear SXS+EMS+PMS */
+               /* Set ISS, if available */
+               if (speed_support) {
+                       reg32 &= ~0x00f00000;
+                       reg32 |= (speed_support & 0x03) << 20;
+               }
+               writel(reg32, abar + 0x00);
+               /* PI (Ports implemented) */
+               writel(port_map, abar + 0x0c);
+               (void) readl(abar + 0x0c); /* Read back 1 */
+               (void) readl(abar + 0x0c); /* Read back 2 */
+               /* CAP2 (HBA Capabilities Extended)*/
+               reg32 = readl(abar + 0x24);
+               reg32 &= ~0x00000002;
+               writel(reg32, abar + 0x24);
+               /* VSP (Vendor Specific Register */
+               reg32 = readl(abar + 0xa0);
+               reg32 &= ~0x00000005;
+               writel(reg32, abar + 0xa0);
+       } else if (!strcmp(mode, "combined")) {
+               debug("SATA: Controller in combined mode\n");
+
+               /* No AHCI: clear AHCI base */
+               pci_write_config32(dev, 0x24, 0x00000000);
+               /* And without AHCI BAR no memory decoding */
+               reg16 = pci_read_config16(dev, PCI_COMMAND);
+               reg16 &= ~PCI_COMMAND_MEMORY;
+               pci_write_config16(dev, PCI_COMMAND, reg16);
+
+               pci_write_config8(dev, 0x09, 0x80);
+
+               /* Set timings */
+               pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+                               IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
+               pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+                               IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+                               IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+
+               /* Sync DMA */
+               pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
+               pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
+
+               /* Set IDE I/O Configuration */
+               reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 |
+                               PCB0;
+               pci_write_config32(dev, IDE_CONFIG, reg32);
+
+               /* Port enable */
+               reg16 = pci_read_config16(dev, 0x92);
+               reg16 &= ~0x3f;
+               reg16 |= port_map;
+               pci_write_config16(dev, 0x92, reg16);
+
+               /* SATA Initialization register */
+               pci_write_config32(dev, 0x94,
+                                  ((port_map ^ 0x3f) << 24) | 0x183);
+       } else {
+               debug("SATA: Controller in plain-ide mode\n");
+
+               /* No AHCI: clear AHCI base */
+               pci_write_config32(dev, 0x24, 0x00000000);
+
+               /* And without AHCI BAR no memory decoding */
+               reg16 = pci_read_config16(dev, PCI_COMMAND);
+               reg16 &= ~PCI_COMMAND_MEMORY;
+               pci_write_config16(dev, PCI_COMMAND, reg16);
+
+               /*
+                * Native mode capable on both primary and secondary (0xa)
+                * OR'ed with enabled (0x50) = 0xf
+                */
+               pci_write_config8(dev, 0x09, 0x8f);
+
+               /* Set Interrupt Line */
+               /* Interrupt Pin is set by D31IP.PIP */
+               pci_write_config8(dev, INTR_LN, 0xff);
+
+               /* Set timings */
+               pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+                               IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+                               IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+               pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+                               IDE_SITRE | IDE_ISP_3_CLOCKS |
+                               IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
+
+               /* Sync DMA */
+               pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
+               pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
+
+               /* Set IDE I/O Configuration */
+               reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 |
+                               PCB0;
+               pci_write_config32(dev, IDE_CONFIG, reg32);
+
+               /* Port enable */
+               reg16 = pci_read_config16(dev, 0x92);
+               reg16 &= ~0x3f;
+               reg16 |= port_map;
+               pci_write_config16(dev, 0x92, reg16);
+
+               /* SATA Initialization register */
+               pci_write_config32(dev, 0x94,
+                                  ((port_map ^ 0x3f) << 24) | 0x183);
+       }
+
+       /* Set Gen3 Transmitter settings if needed */
+       port_tx = fdtdec_get_int(blob, node, "intel,sata-port0-gen3-tx", 0);
+       if (port_tx)
+               pch_iobp_update(SATA_IOBP_SP0G3IR, 0, port_tx);
+
+       port_tx = fdtdec_get_int(blob, node, "intel,sata-port1-gen3-tx", 0);
+       if (port_tx)
+               pch_iobp_update(SATA_IOBP_SP1G3IR, 0, port_tx);
+
+       /* Additional Programming Requirements */
+       sir_write(dev, 0x04, 0x00001600);
+       sir_write(dev, 0x28, 0xa0000033);
+       reg32 = sir_read(dev, 0x54);
+       reg32 &= 0xff000000;
+       reg32 |= 0x5555aa;
+       sir_write(dev, 0x54, reg32);
+       sir_write(dev, 0x64, 0xcccc8484);
+       reg32 = sir_read(dev, 0x68);
+       reg32 &= 0xffff0000;
+       reg32 |= 0xcccc;
+       sir_write(dev, 0x68, reg32);
+       reg32 = sir_read(dev, 0x78);
+       reg32 &= 0x0000ffff;
+       reg32 |= 0x88880000;

arch/x86/cpu/ivybridge/sata.c line 223

Quoted 10 lines
arch/x86/cpu/ivybridge/sata.c new file +10 -0
+       sir_write(dev, 0x78, reg32);
+       sir_write(dev, 0x84, 0x001c7000);
+       sir_write(dev, 0x88, 0x88338822);
+       sir_write(dev, 0xa0, 0x001c7000);
+       sir_write(dev, 0xc4, 0x0c0c0c0c);
+       sir_write(dev, 0xc8, 0x0c0c0c0c);
+       sir_write(dev, 0xd4, 0x10000000);
+
+       pch_iobp_update(0xea004001, 0x3fffffff, 0xc0000000);
+       pch_iobp_update(0xea00408a, 0xfffffcff, 0x00000100);

There are many magic numbers here.

Quoted 139 lines
arch/x86/cpu/ivybridge/sata.c new file +20 -0
+}
+
+void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node)
+{
+       unsigned port_map;
+       const char *mode;
+       u16 map = 0;
+
+       /*
+        * Set SATA controller mode early so the resource allocator can
+        * properly assign IO/Memory resources for the controller.
+        */
+       mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
+       if (mode && !strcmp(mode, "ahci"))
+               map = 0x0060;
+       port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
+
+       map |= (port_map ^ 0x3f) << 8;
+       pci_write_config16(dev, 0x90, map);
+}
arch/x86/include/asm/arch-ivybridge/bd82x6x.h +2 -0
index e02520c..644755f 100644
@@ -7,6 +7,8 @@
 #ifndef _ASM_ARCH_BD82X6X_H
 #define _ASM_ARCH_BD82X6X_H
 
+void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node);
+void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node);
 void bd82x6x_pci_init(pci_dev_t dev);
 int bd82x6x_init_pci_devices(void);
 int bd82x6x_init(void);
arch/x86/include/asm/arch-ivybridge/pch.h +58 -0
index b3ec7c5..21df083 100644
@@ -122,6 +122,64 @@ void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue);
 #define LPC_GEN4_DEC           0x90 /* LPC IF Generic Decode Range 4 */
 #define LPC_GENX_DEC(x)                (0x84 + 4 * (x))
 
+/* PCI Configuration Space (D31:F1): IDE */
+#define PCH_IDE_DEV            PCI_BDF(0, 0x1f, 1)
+#define PCH_SATA_DEV           PCI_BDF(0, 0x1f, 2)
+#define PCH_SATA2_DEV          PCI_BDF(0, 0x1f, 5)
+
+#define INTR_LN                        0x3c
+#define IDE_TIM_PRI            0x40    /* IDE timings, primary */
+#define   IDE_DECODE_ENABLE    (1 << 15)
+#define   IDE_SITRE            (1 << 14)
+#define   IDE_ISP_5_CLOCKS     (0 << 12)
+#define   IDE_ISP_4_CLOCKS     (1 << 12)
+#define   IDE_ISP_3_CLOCKS     (2 << 12)
+#define   IDE_RCT_4_CLOCKS     (0 <<  8)
+#define   IDE_RCT_3_CLOCKS     (1 <<  8)
+#define   IDE_RCT_2_CLOCKS     (2 <<  8)
+#define   IDE_RCT_1_CLOCKS     (3 <<  8)
+#define   IDE_DTE1             (1 <<  7)
+#define   IDE_PPE1             (1 <<  6)
+#define   IDE_IE1              (1 <<  5)
+#define   IDE_TIME1            (1 <<  4)
+#define   IDE_DTE0             (1 <<  3)
+#define   IDE_PPE0             (1 <<  2)
+#define   IDE_IE0              (1 <<  1)
+#define   IDE_TIME0            (1 <<  0)
+#define IDE_TIM_SEC            0x42    /* IDE timings, secondary */
+
+#define IDE_SDMA_CNT           0x48    /* Synchronous DMA control */
+#define   IDE_SSDE1            (1 <<  3)
+#define   IDE_SSDE0            (1 <<  2)
+#define   IDE_PSDE1            (1 <<  1)
+#define   IDE_PSDE0            (1 <<  0)
+
+#define IDE_SDMA_TIM           0x4a
+
+#define IDE_CONFIG             0x54    /* IDE I/O Configuration Register */
+#define   SIG_MODE_SEC_NORMAL  (0 << 18)
+#define   SIG_MODE_SEC_TRISTATE        (1 << 18)
+#define   SIG_MODE_SEC_DRIVELOW        (2 << 18)
+#define   SIG_MODE_PRI_NORMAL  (0 << 16)
+#define   SIG_MODE_PRI_TRISTATE        (1 << 16)
+#define   SIG_MODE_PRI_DRIVELOW        (2 << 16)
+#define   FAST_SCB1            (1 << 15)
+#define   FAST_SCB0            (1 << 14)
+#define   FAST_PCB1            (1 << 13)
+#define   FAST_PCB0            (1 << 12)
+#define   SCB1                 (1 <<  3)
+#define   SCB0                 (1 <<  2)
+#define   PCB1                 (1 <<  1)
+#define   PCB0                 (1 <<  0)
+
+#define SATA_SIRI              0xa0 /* SATA Indexed Register Index */
+#define SATA_SIRD              0xa4 /* SATA Indexed Register Data */
+#define SATA_SP                        0xd0 /* Scratchpad */
+
+/* SATA IOBP Registers */
+#define SATA_IOBP_SP0G3IR      0xea000151
+#define SATA_IOBP_SP1G3IR      0xea000051
+
 /* PCI Configuration Space (D31:F3): SMBus */
 #define PCH_SMBUS_DEV          PCI_BDF(0, 0x1f, 3)
 #define SMB_BASE               0x20
doc/device-tree-bindings/ata/intel-sata.txt new file +26 -0
new file mode 100644
index 0000000..5e4da83
@@ -0,0 +1,26 @@
+Intel Pantherpoint SATA Device Binding
+======================================
+
+The device tree node which describes the operation of the Intel Pantherpoint
+SATA device is as follows:
+
+Required properties :
+- compatible = "intel,pantherpoint-ahci"
+- intel,sata-mode : string, one of:
+     "ahci" : Use AHCI mode (default)
+     "combined" : Use combined IDE + legacy mode
+     "plain-ide" : Use plain IDE mode
+- intel,sata-port-map : Which SATA ports are enabled, bit 0=enable first port,
+    bit 1=enable second port, etc.
+- intel,sata-port0-gen3-tx : Value for the IOBP_SP0G3IR register
+- intel,sata-port1-gen3-tx : Value for the IOBP_SP1G3IR register
+
+Example
+-------
+
+sata {
+       compatible = "intel,pantherpoint-ahci";
+       intel,sata-mode = "ahci";
+       intel,sata-port-map = <1>;
+       intel,sata-port0-gen3-tx = <0x00880a7f>;
+};
include/fdtdec.h +0 -0
index abfd678..0a0afce 100644

include/fdtdec.h enum fdt_compat_id { · line 123

Quoted 4 lines
include/fdtdec.h +1 -0
@@ -120,6 +120,7 @@ enum fdt_compat_id {
        COMPAT_INTEL_LPC,               /* Intel Low Pin Count I/F */
        COMPAT_INTEL_MICROCODE,         /* Intel microcode update */
        COMPAT_MEMORY_SPD,              /* Memory SPD information */
+       COMPAT_INTEL_PANTHERPOINT_AHCI, /* Intel Pantherpoint AHCI */

I have not started to look into the new driver model and the of_control device tree stuff. One questoin that comes just off the top of my head is that: why should we add the PCI device into the device tree? The device tree spec is designed to describe the devices which cannot be probed by some mechanism. For devices under such buses like PCI/USB, we can easily identify the device via vendor id and device id, thus there is no need to describe them in the device tree. I keep seeing we update the fdt_compat_id which is a central database, but eventually someday when all U-Boot drivers are converted to driver model, it will become a huge list and unmaintainable.

Quoted 8 lines
include/fdtdec.h +0 -0
        COMPAT_COUNT,
 };
lib/fdtdec.c +0 -0
index aafc4f9..8865a26 100644

lib/fdtdec.c static const char * const compat_names[COMPAT_COUNT] = {

Quoted 8 lines
lib/fdtdec.c +1 -1
@@ -75,6 +75,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(COMPAT_INTEL_LPC, "intel,lpc"),
        COMPAT(INTEL_MICROCODE, "intel,microcode"),
        COMPAT(MEMORY_SPD, "memory-spd"),
+       COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
--

Regards,
Bin

#41 lore raw

PATCH 23/33 x86: ivybridge: Add SATA init

Hi Bin,

Quoted 451 lines · Bin Meng

Hi Simon,

Quoted 289 lines · Simon Glass

Add code to set up the SATA interfaces on boot.

---

 arch/x86/cpu/ivybridge/Makefile               |   1 +
 arch/x86/cpu/ivybridge/bd82x6x.c              |  20 +++
 arch/x86/cpu/ivybridge/sata.c                 | 243 ++++++++++++++++++++++++++
 arch/x86/include/asm/arch-ivybridge/bd82x6x.h |   2 +
 arch/x86/include/asm/arch-ivybridge/pch.h     |  58 ++++++
 doc/device-tree-bindings/ata/intel-sata.txt   |  26 +++
 include/fdtdec.h                              |   1 +
 lib/fdtdec.c                                  |   1 +
 8 files changed, 352 insertions(+)
 create mode 100644 arch/x86/cpu/ivybridge/sata.c
 create mode 100644 doc/device-tree-bindings/ata/intel-sata.txt
arch/x86/cpu/ivybridge/Makefile +1 -0
index 479e446..c6342cd 100644
@@ -15,4 +15,5 @@ obj-y += microcode_intel.o
 obj-y += pch.o
 obj-y += pci.o
 obj-y += report_platform.o
+obj-y += sata.o
 obj-y += sdram.o
arch/x86/cpu/ivybridge/bd82x6x.c +20 -0
index be4db74..b54f5c7 100644
@@ -88,18 +88,38 @@ void bd82x6x_pci_bus_enable_resources(pci_dev_t dev)
 
 int bd82x6x_init_pci_devices(void)
 {
+       const void *blob = gd->fdt_blob;
        struct pci_controller *hose;
+       int sata_node;
 
        hose = pci_bus_to_hose(0);
        lpc_enable(PCH_LPC_DEV);
        lpc_init(hose, PCH_LPC_DEV);
+       sata_node = fdtdec_next_compatible(blob, 0,
+                                          COMPAT_INTEL_PANTHERPOINT_AHCI);
+       if (sata_node < 0) {
+               debug("%s: Cannot find SATA node\n", __func__);
+               return -EINVAL;
+       }
+       bd82x6x_sata_init(PCH_SATA_DEV, blob, sata_node);
 
        return 0;
 }
 
 int bd82x6x_init(void)
 {
+       const void *blob = gd->fdt_blob;
+       int sata_node;
+
+       sata_node = fdtdec_next_compatible(blob, 0,
+                                          COMPAT_INTEL_PANTHERPOINT_AHCI);
+       if (sata_node < 0) {
+               debug("%s: Cannot find SATA node\n", __func__);
+               return -EINVAL;
+       }
+
        bd82x6x_pci_init(PCH_DEV);
+       bd82x6x_sata_enable(PCH_SATA_DEV, blob, sata_node);
 
        return 0;
 }
arch/x86/cpu/ivybridge/sata.c new file +213 -0
new file mode 100644
index 0000000..134afb9
@@ -0,0 +1,243 @@
+/*
+ * From Coreboot
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/arch/pch.h>
+#include <asm/arch/bd82x6x.h>
+
+static inline u32 sir_read(pci_dev_t dev, int idx)
+{
+       pci_write_config32(dev, SATA_SIRI, idx);
+       return pci_read_config32(dev, SATA_SIRD);
+}
+
+static inline void sir_write(pci_dev_t dev, int idx, u32 value)
+{
+       pci_write_config32(dev, SATA_SIRI, idx);
+       pci_write_config32(dev, SATA_SIRD, value);
+}
+
+void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
+{
+       unsigned int port_map, speed_support, port_tx;
+       const char *mode;
+       u32 reg32;
+       u16 reg16;
+
+       debug("SATA: Initializing...\n");
+
+       /* SATA configuration */
+       port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
+       speed_support = fdtdec_get_int(blob, node,
+                                      "sata_interface_speed_support", 0);
+
+       /* Enable BARs */
+       pci_write_config16(dev, PCI_COMMAND, 0x0007);
+
+       mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
+       if (!mode || !strcmp(mode, "ahci")) {
+               u32 abar;
+
+               debug("SATA: Controller in AHCI mode\n");
+
+               /* Set Interrupt Line, Interrupt Pin is set by D31IP.PIP */
+               pci_write_config8(dev, INTR_LN, 0x0a);
+
+               /* Set timings */
+               pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+                               IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+                               IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+               pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+                               IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
+
+               /* Sync DMA */
+               pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
+               pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
+
+               /* Set IDE I/O Configuration */
+               reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 |
+                               PCB0;
+               pci_write_config32(dev, IDE_CONFIG, reg32);
+
+               /* for AHCI, Port Enable is managed in memory-mapped space */
+               reg16 = pci_read_config16(dev, 0x92);
+               reg16 &= ~0x3f; /* 6 ports SKU + ORM */
+               reg16 |= 0x8000 | port_map;
+               pci_write_config16(dev, 0x92, reg16);
+
+               /* SATA Initialization register */
+               pci_write_config32(dev, 0x94,
+                                  ((port_map ^ 0x3f) << 24) | 0x183);
+
+               /* Initialize AHCI memory-mapped space */
+               abar = pci_read_config32(dev, PCI_BASE_ADDRESS_5) & ~1;
+               debug("ABAR: %08X\n", abar);
+               /* CAP (HBA Capabilities) : enable power management */
+               reg32 = readl(abar + 0x00);
+               reg32 |= 0x0c006000;  /* set PSC+SSC+SALP+SSS */
+               reg32 &= ~0x00020060; /* clear SXS+EMS+PMS */
+               /* Set ISS, if available */
+               if (speed_support) {
+                       reg32 &= ~0x00f00000;
+                       reg32 |= (speed_support & 0x03) << 20;
+               }
+               writel(reg32, abar + 0x00);
+               /* PI (Ports implemented) */
+               writel(port_map, abar + 0x0c);
+               (void) readl(abar + 0x0c); /* Read back 1 */
+               (void) readl(abar + 0x0c); /* Read back 2 */
+               /* CAP2 (HBA Capabilities Extended)*/
+               reg32 = readl(abar + 0x24);
+               reg32 &= ~0x00000002;
+               writel(reg32, abar + 0x24);
+               /* VSP (Vendor Specific Register */
+               reg32 = readl(abar + 0xa0);
+               reg32 &= ~0x00000005;
+               writel(reg32, abar + 0xa0);
+       } else if (!strcmp(mode, "combined")) {
+               debug("SATA: Controller in combined mode\n");
+
+               /* No AHCI: clear AHCI base */
+               pci_write_config32(dev, 0x24, 0x00000000);
+               /* And without AHCI BAR no memory decoding */
+               reg16 = pci_read_config16(dev, PCI_COMMAND);
+               reg16 &= ~PCI_COMMAND_MEMORY;
+               pci_write_config16(dev, PCI_COMMAND, reg16);
+
+               pci_write_config8(dev, 0x09, 0x80);
+
+               /* Set timings */
+               pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+                               IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
+               pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+                               IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+                               IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+
+               /* Sync DMA */
+               pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
+               pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
+
+               /* Set IDE I/O Configuration */
+               reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 |
+                               PCB0;
+               pci_write_config32(dev, IDE_CONFIG, reg32);
+
+               /* Port enable */
+               reg16 = pci_read_config16(dev, 0x92);
+               reg16 &= ~0x3f;
+               reg16 |= port_map;
+               pci_write_config16(dev, 0x92, reg16);
+
+               /* SATA Initialization register */
+               pci_write_config32(dev, 0x94,
+                                  ((port_map ^ 0x3f) << 24) | 0x183);
+       } else {
+               debug("SATA: Controller in plain-ide mode\n");
+
+               /* No AHCI: clear AHCI base */
+               pci_write_config32(dev, 0x24, 0x00000000);
+
+               /* And without AHCI BAR no memory decoding */
+               reg16 = pci_read_config16(dev, PCI_COMMAND);
+               reg16 &= ~PCI_COMMAND_MEMORY;
+               pci_write_config16(dev, PCI_COMMAND, reg16);
+
+               /*
+                * Native mode capable on both primary and secondary (0xa)
+                * OR'ed with enabled (0x50) = 0xf
+                */
+               pci_write_config8(dev, 0x09, 0x8f);
+
+               /* Set Interrupt Line */
+               /* Interrupt Pin is set by D31IP.PIP */
+               pci_write_config8(dev, INTR_LN, 0xff);
+
+               /* Set timings */
+               pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+                               IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+                               IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+               pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+                               IDE_SITRE | IDE_ISP_3_CLOCKS |
+                               IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
+
+               /* Sync DMA */
+               pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
+               pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
+
+               /* Set IDE I/O Configuration */
+               reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 |
+                               PCB0;
+               pci_write_config32(dev, IDE_CONFIG, reg32);
+
+               /* Port enable */
+               reg16 = pci_read_config16(dev, 0x92);
+               reg16 &= ~0x3f;
+               reg16 |= port_map;
+               pci_write_config16(dev, 0x92, reg16);
+
+               /* SATA Initialization register */
+               pci_write_config32(dev, 0x94,
+                                  ((port_map ^ 0x3f) << 24) | 0x183);
+       }
+
+       /* Set Gen3 Transmitter settings if needed */
+       port_tx = fdtdec_get_int(blob, node, "intel,sata-port0-gen3-tx", 0);
+       if (port_tx)
+               pch_iobp_update(SATA_IOBP_SP0G3IR, 0, port_tx);
+
+       port_tx = fdtdec_get_int(blob, node, "intel,sata-port1-gen3-tx", 0);
+       if (port_tx)
+               pch_iobp_update(SATA_IOBP_SP1G3IR, 0, port_tx);
+
+       /* Additional Programming Requirements */
+       sir_write(dev, 0x04, 0x00001600);
+       sir_write(dev, 0x28, 0xa0000033);
+       reg32 = sir_read(dev, 0x54);
+       reg32 &= 0xff000000;
+       reg32 |= 0x5555aa;
+       sir_write(dev, 0x54, reg32);
+       sir_write(dev, 0x64, 0xcccc8484);
+       reg32 = sir_read(dev, 0x68);
+       reg32 &= 0xffff0000;
+       reg32 |= 0xcccc;
+       sir_write(dev, 0x68, reg32);
+       reg32 = sir_read(dev, 0x78);
+       reg32 &= 0x0000ffff;
+       reg32 |= 0x88880000;

arch/x86/cpu/ivybridge/sata.c line 223

Quoted 10 lines
arch/x86/cpu/ivybridge/sata.c new file +10 -0
+       sir_write(dev, 0x78, reg32);
+       sir_write(dev, 0x84, 0x001c7000);
+       sir_write(dev, 0x88, 0x88338822);
+       sir_write(dev, 0xa0, 0x001c7000);
+       sir_write(dev, 0xc4, 0x0c0c0c0c);
+       sir_write(dev, 0xc8, 0x0c0c0c0c);
+       sir_write(dev, 0xd4, 0x10000000);
+
+       pch_iobp_update(0xea004001, 0x3fffffff, 0xc0000000);
+       pch_iobp_update(0xea00408a, 0xfffffcff, 0x00000100);

There are many magic numbers here.

Quoted 139 lines
arch/x86/cpu/ivybridge/sata.c new file +20 -0
+}
+
+void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node)
+{
+       unsigned port_map;
+       const char *mode;
+       u16 map = 0;
+
+       /*
+        * Set SATA controller mode early so the resource allocator can
+        * properly assign IO/Memory resources for the controller.
+        */
+       mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
+       if (mode && !strcmp(mode, "ahci"))
+               map = 0x0060;
+       port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
+
+       map |= (port_map ^ 0x3f) << 8;
+       pci_write_config16(dev, 0x90, map);
+}
arch/x86/include/asm/arch-ivybridge/bd82x6x.h +2 -0
index e02520c..644755f 100644
@@ -7,6 +7,8 @@
 #ifndef _ASM_ARCH_BD82X6X_H
 #define _ASM_ARCH_BD82X6X_H
 
+void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node);
+void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node);
 void bd82x6x_pci_init(pci_dev_t dev);
 int bd82x6x_init_pci_devices(void);
 int bd82x6x_init(void);
arch/x86/include/asm/arch-ivybridge/pch.h +58 -0
index b3ec7c5..21df083 100644
@@ -122,6 +122,64 @@ void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue);
 #define LPC_GEN4_DEC           0x90 /* LPC IF Generic Decode Range 4 */
 #define LPC_GENX_DEC(x)                (0x84 + 4 * (x))
 
+/* PCI Configuration Space (D31:F1): IDE */
+#define PCH_IDE_DEV            PCI_BDF(0, 0x1f, 1)
+#define PCH_SATA_DEV           PCI_BDF(0, 0x1f, 2)
+#define PCH_SATA2_DEV          PCI_BDF(0, 0x1f, 5)
+
+#define INTR_LN                        0x3c
+#define IDE_TIM_PRI            0x40    /* IDE timings, primary */
+#define   IDE_DECODE_ENABLE    (1 << 15)
+#define   IDE_SITRE            (1 << 14)
+#define   IDE_ISP_5_CLOCKS     (0 << 12)
+#define   IDE_ISP_4_CLOCKS     (1 << 12)
+#define   IDE_ISP_3_CLOCKS     (2 << 12)
+#define   IDE_RCT_4_CLOCKS     (0 <<  8)
+#define   IDE_RCT_3_CLOCKS     (1 <<  8)
+#define   IDE_RCT_2_CLOCKS     (2 <<  8)
+#define   IDE_RCT_1_CLOCKS     (3 <<  8)
+#define   IDE_DTE1             (1 <<  7)
+#define   IDE_PPE1             (1 <<  6)
+#define   IDE_IE1              (1 <<  5)
+#define   IDE_TIME1            (1 <<  4)
+#define   IDE_DTE0             (1 <<  3)
+#define   IDE_PPE0             (1 <<  2)
+#define   IDE_IE0              (1 <<  1)
+#define   IDE_TIME0            (1 <<  0)
+#define IDE_TIM_SEC            0x42    /* IDE timings, secondary */
+
+#define IDE_SDMA_CNT           0x48    /* Synchronous DMA control */
+#define   IDE_SSDE1            (1 <<  3)
+#define   IDE_SSDE0            (1 <<  2)
+#define   IDE_PSDE1            (1 <<  1)
+#define   IDE_PSDE0            (1 <<  0)
+
+#define IDE_SDMA_TIM           0x4a
+
+#define IDE_CONFIG             0x54    /* IDE I/O Configuration Register */
+#define   SIG_MODE_SEC_NORMAL  (0 << 18)
+#define   SIG_MODE_SEC_TRISTATE        (1 << 18)
+#define   SIG_MODE_SEC_DRIVELOW        (2 << 18)
+#define   SIG_MODE_PRI_NORMAL  (0 << 16)
+#define   SIG_MODE_PRI_TRISTATE        (1 << 16)
+#define   SIG_MODE_PRI_DRIVELOW        (2 << 16)
+#define   FAST_SCB1            (1 << 15)
+#define   FAST_SCB0            (1 << 14)
+#define   FAST_PCB1            (1 << 13)
+#define   FAST_PCB0            (1 << 12)
+#define   SCB1                 (1 <<  3)
+#define   SCB0                 (1 <<  2)
+#define   PCB1                 (1 <<  1)
+#define   PCB0                 (1 <<  0)
+
+#define SATA_SIRI              0xa0 /* SATA Indexed Register Index */
+#define SATA_SIRD              0xa4 /* SATA Indexed Register Data */
+#define SATA_SP                        0xd0 /* Scratchpad */
+
+/* SATA IOBP Registers */
+#define SATA_IOBP_SP0G3IR      0xea000151
+#define SATA_IOBP_SP1G3IR      0xea000051
+
 /* PCI Configuration Space (D31:F3): SMBus */
 #define PCH_SMBUS_DEV          PCI_BDF(0, 0x1f, 3)
 #define SMB_BASE               0x20
doc/device-tree-bindings/ata/intel-sata.txt new file +26 -0
new file mode 100644
index 0000000..5e4da83
@@ -0,0 +1,26 @@
+Intel Pantherpoint SATA Device Binding
+======================================
+
+The device tree node which describes the operation of the Intel Pantherpoint
+SATA device is as follows:
+
+Required properties :
+- compatible = "intel,pantherpoint-ahci"
+- intel,sata-mode : string, one of:
+     "ahci" : Use AHCI mode (default)
+     "combined" : Use combined IDE + legacy mode
+     "plain-ide" : Use plain IDE mode
+- intel,sata-port-map : Which SATA ports are enabled, bit 0=enable first port,
+    bit 1=enable second port, etc.
+- intel,sata-port0-gen3-tx : Value for the IOBP_SP0G3IR register
+- intel,sata-port1-gen3-tx : Value for the IOBP_SP1G3IR register
+
+Example
+-------
+
+sata {
+       compatible = "intel,pantherpoint-ahci";
+       intel,sata-mode = "ahci";
+       intel,sata-port-map = <1>;
+       intel,sata-port0-gen3-tx = <0x00880a7f>;
+};
include/fdtdec.h +0 -0
index abfd678..0a0afce 100644

include/fdtdec.h enum fdt_compat_id { · line 123

Quoted 4 lines
include/fdtdec.h +1 -0
@@ -120,6 +120,7 @@ enum fdt_compat_id {
        COMPAT_INTEL_LPC,               /* Intel Low Pin Count I/F */
        COMPAT_INTEL_MICROCODE,         /* Intel microcode update */
        COMPAT_MEMORY_SPD,              /* Memory SPD information */
+       COMPAT_INTEL_PANTHERPOINT_AHCI, /* Intel Pantherpoint AHCI */

I have not started to look into the new driver model and the of_control device tree stuff. One questoin that comes just off the top

Quoted 8 lines

of my head is that: why should we add the PCI device into the device tree? The device tree spec is designed to describe the devices which cannot be probed by some mechanism. For devices under such buses like PCI/USB, we can easily identify the device via vendor id and device id, thus there is no need to describe them in the device tree. I keep seeing we update the fdt_compat_id which is a central database, but eventually someday when all U-Boot drivers are converted to driver model, it will become a huge list and unmaintainable.

We want to indicate which devices should be enabled and which should not be. Also we want to provide parameters to say how a particular device should be set up. In the case of SATA, we need to know if it should be SATA or legacy ATA, for example. If you look at the chromebook_link.dts file you will see quite a few settings.

The fdt_compat_id will go away as things are converted to driver model. It was a stop-gap so that we didn't forget all the places that need to be changed.

I have formed the view that we need to convert PCI to driver model before long, but it is of course much easier to come up with a suitable uclass when you have a body of code to convert. I think the x86 ivybridge port will provide a reasonable base for that.

Regards,
Simon

#42 lore raw

PATCH 23/33 x86: ivybridge: Add SATA init

In reply to Bin Meng

Hi Bin,

Quoted 296 lines · Bin Meng

Hi Simon,

Quoted 293 lines · Simon Glass

Add code to set up the SATA interfaces on boot.

---

 arch/x86/cpu/ivybridge/Makefile               |   1 +
 arch/x86/cpu/ivybridge/bd82x6x.c              |  20 +++
 arch/x86/cpu/ivybridge/sata.c                 | 243 ++++++++++++++++++++++++++
 arch/x86/include/asm/arch-ivybridge/bd82x6x.h |   2 +
 arch/x86/include/asm/arch-ivybridge/pch.h     |  58 ++++++
 doc/device-tree-bindings/ata/intel-sata.txt   |  26 +++
 include/fdtdec.h                              |   1 +
 lib/fdtdec.c                                  |   1 +
 8 files changed, 352 insertions(+)
 create mode 100644 arch/x86/cpu/ivybridge/sata.c
 create mode 100644 doc/device-tree-bindings/ata/intel-sata.txt
arch/x86/cpu/ivybridge/Makefile +1 -0
index 479e446..c6342cd 100644
@@ -15,4 +15,5 @@ obj-y += microcode_intel.o
 obj-y += pch.o
 obj-y += pci.o
 obj-y += report_platform.o
+obj-y += sata.o
 obj-y += sdram.o
arch/x86/cpu/ivybridge/bd82x6x.c +20 -0
index be4db74..b54f5c7 100644
@@ -88,18 +88,38 @@ void bd82x6x_pci_bus_enable_resources(pci_dev_t dev)
 
 int bd82x6x_init_pci_devices(void)
 {
+       const void *blob = gd->fdt_blob;
        struct pci_controller *hose;
+       int sata_node;
 
        hose = pci_bus_to_hose(0);
        lpc_enable(PCH_LPC_DEV);
        lpc_init(hose, PCH_LPC_DEV);
+       sata_node = fdtdec_next_compatible(blob, 0,
+                                          COMPAT_INTEL_PANTHERPOINT_AHCI);
+       if (sata_node < 0) {
+               debug("%s: Cannot find SATA node\n", __func__);
+               return -EINVAL;
+       }
+       bd82x6x_sata_init(PCH_SATA_DEV, blob, sata_node);
 
        return 0;
 }
 
 int bd82x6x_init(void)
 {
+       const void *blob = gd->fdt_blob;
+       int sata_node;
+
+       sata_node = fdtdec_next_compatible(blob, 0,
+                                          COMPAT_INTEL_PANTHERPOINT_AHCI);
+       if (sata_node < 0) {
+               debug("%s: Cannot find SATA node\n", __func__);
+               return -EINVAL;
+       }
+
        bd82x6x_pci_init(PCH_DEV);
+       bd82x6x_sata_enable(PCH_SATA_DEV, blob, sata_node);
 
        return 0;
 }
arch/x86/cpu/ivybridge/sata.c new file +217 -0
new file mode 100644
index 0000000..134afb9
@@ -0,0 +1,243 @@
+/*
+ * From Coreboot
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/arch/pch.h>
+#include <asm/arch/bd82x6x.h>
+
+static inline u32 sir_read(pci_dev_t dev, int idx)
+{
+       pci_write_config32(dev, SATA_SIRI, idx);
+       return pci_read_config32(dev, SATA_SIRD);
+}
+
+static inline void sir_write(pci_dev_t dev, int idx, u32 value)
+{
+       pci_write_config32(dev, SATA_SIRI, idx);
+       pci_write_config32(dev, SATA_SIRD, value);
+}
+
+void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
+{
+       unsigned int port_map, speed_support, port_tx;
+       const char *mode;
+       u32 reg32;
+       u16 reg16;
+
+       debug("SATA: Initializing...\n");
+
+       /* SATA configuration */
+       port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
+       speed_support = fdtdec_get_int(blob, node,
+                                      "sata_interface_speed_support", 0);
+
+       /* Enable BARs */
+       pci_write_config16(dev, PCI_COMMAND, 0x0007);
+
+       mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
+       if (!mode || !strcmp(mode, "ahci")) {
+               u32 abar;
+
+               debug("SATA: Controller in AHCI mode\n");
+
+               /* Set Interrupt Line, Interrupt Pin is set by D31IP.PIP */
+               pci_write_config8(dev, INTR_LN, 0x0a);
+
+               /* Set timings */
+               pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+                               IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+                               IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+               pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+                               IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
+
+               /* Sync DMA */
+               pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
+               pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
+
+               /* Set IDE I/O Configuration */
+               reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 |
+                               PCB0;
+               pci_write_config32(dev, IDE_CONFIG, reg32);
+
+               /* for AHCI, Port Enable is managed in memory-mapped space */
+               reg16 = pci_read_config16(dev, 0x92);
+               reg16 &= ~0x3f; /* 6 ports SKU + ORM */
+               reg16 |= 0x8000 | port_map;
+               pci_write_config16(dev, 0x92, reg16);
+
+               /* SATA Initialization register */
+               pci_write_config32(dev, 0x94,
+                                  ((port_map ^ 0x3f) << 24) | 0x183);
+
+               /* Initialize AHCI memory-mapped space */
+               abar = pci_read_config32(dev, PCI_BASE_ADDRESS_5) & ~1;
+               debug("ABAR: %08X\n", abar);
+               /* CAP (HBA Capabilities) : enable power management */
+               reg32 = readl(abar + 0x00);
+               reg32 |= 0x0c006000;  /* set PSC+SSC+SALP+SSS */
+               reg32 &= ~0x00020060; /* clear SXS+EMS+PMS */
+               /* Set ISS, if available */
+               if (speed_support) {
+                       reg32 &= ~0x00f00000;
+                       reg32 |= (speed_support & 0x03) << 20;
+               }
+               writel(reg32, abar + 0x00);
+               /* PI (Ports implemented) */
+               writel(port_map, abar + 0x0c);
+               (void) readl(abar + 0x0c); /* Read back 1 */
+               (void) readl(abar + 0x0c); /* Read back 2 */
+               /* CAP2 (HBA Capabilities Extended)*/
+               reg32 = readl(abar + 0x24);
+               reg32 &= ~0x00000002;
+               writel(reg32, abar + 0x24);
+               /* VSP (Vendor Specific Register */
+               reg32 = readl(abar + 0xa0);
+               reg32 &= ~0x00000005;
+               writel(reg32, abar + 0xa0);
+       } else if (!strcmp(mode, "combined")) {
+               debug("SATA: Controller in combined mode\n");
+
+               /* No AHCI: clear AHCI base */
+               pci_write_config32(dev, 0x24, 0x00000000);
+               /* And without AHCI BAR no memory decoding */
+               reg16 = pci_read_config16(dev, PCI_COMMAND);
+               reg16 &= ~PCI_COMMAND_MEMORY;
+               pci_write_config16(dev, PCI_COMMAND, reg16);
+
+               pci_write_config8(dev, 0x09, 0x80);
+
+               /* Set timings */
+               pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+                               IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
+               pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+                               IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+                               IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+
+               /* Sync DMA */
+               pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
+               pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
+
+               /* Set IDE I/O Configuration */
+               reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 |
+                               PCB0;
+               pci_write_config32(dev, IDE_CONFIG, reg32);
+
+               /* Port enable */
+               reg16 = pci_read_config16(dev, 0x92);
+               reg16 &= ~0x3f;
+               reg16 |= port_map;
+               pci_write_config16(dev, 0x92, reg16);
+
+               /* SATA Initialization register */
+               pci_write_config32(dev, 0x94,
+                                  ((port_map ^ 0x3f) << 24) | 0x183);
+       } else {
+               debug("SATA: Controller in plain-ide mode\n");
+
+               /* No AHCI: clear AHCI base */
+               pci_write_config32(dev, 0x24, 0x00000000);
+
+               /* And without AHCI BAR no memory decoding */
+               reg16 = pci_read_config16(dev, PCI_COMMAND);
+               reg16 &= ~PCI_COMMAND_MEMORY;
+               pci_write_config16(dev, PCI_COMMAND, reg16);
+
+               /*
+                * Native mode capable on both primary and secondary (0xa)
+                * OR'ed with enabled (0x50) = 0xf
+                */
+               pci_write_config8(dev, 0x09, 0x8f);
+
+               /* Set Interrupt Line */
+               /* Interrupt Pin is set by D31IP.PIP */
+               pci_write_config8(dev, INTR_LN, 0xff);
+
+               /* Set timings */
+               pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+                               IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+                               IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+               pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+                               IDE_SITRE | IDE_ISP_3_CLOCKS |
+                               IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
+
+               /* Sync DMA */
+               pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
+               pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
+
+               /* Set IDE I/O Configuration */
+               reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 |
+                               PCB0;
+               pci_write_config32(dev, IDE_CONFIG, reg32);
+
+               /* Port enable */
+               reg16 = pci_read_config16(dev, 0x92);
+               reg16 &= ~0x3f;
+               reg16 |= port_map;
+               pci_write_config16(dev, 0x92, reg16);
+
+               /* SATA Initialization register */
+               pci_write_config32(dev, 0x94,
+                                  ((port_map ^ 0x3f) << 24) | 0x183);
+       }
+
+       /* Set Gen3 Transmitter settings if needed */
+       port_tx = fdtdec_get_int(blob, node, "intel,sata-port0-gen3-tx", 0);
+       if (port_tx)
+               pch_iobp_update(SATA_IOBP_SP0G3IR, 0, port_tx);
+
+       port_tx = fdtdec_get_int(blob, node, "intel,sata-port1-gen3-tx", 0);
+       if (port_tx)
+               pch_iobp_update(SATA_IOBP_SP1G3IR, 0, port_tx);
+
+       /* Additional Programming Requirements */
+       sir_write(dev, 0x04, 0x00001600);
+       sir_write(dev, 0x28, 0xa0000033);
+       reg32 = sir_read(dev, 0x54);
+       reg32 &= 0xff000000;
+       reg32 |= 0x5555aa;
+       sir_write(dev, 0x54, reg32);
+       sir_write(dev, 0x64, 0xcccc8484);
+       reg32 = sir_read(dev, 0x68);
+       reg32 &= 0xffff0000;
+       reg32 |= 0xcccc;
+       sir_write(dev, 0x68, reg32);
+       reg32 = sir_read(dev, 0x78);
+       reg32 &= 0x0000ffff;
+       reg32 |= 0x88880000;
+       sir_write(dev, 0x78, reg32);
+       sir_write(dev, 0x84, 0x001c7000);
+       sir_write(dev, 0x88, 0x88338822);
+       sir_write(dev, 0xa0, 0x001c7000);
Quoted 8 lines

arch/x86/cpu/ivybridge/sata.c line 223

Quoted 6 lines
arch/x86/cpu/ivybridge/sata.c new file +6 -0
+       sir_write(dev, 0xc4, 0x0c0c0c0c);
+       sir_write(dev, 0xc8, 0x0c0c0c0c);
+       sir_write(dev, 0xd4, 0x10000000);
+
+       pch_iobp_update(0xea004001, 0x3fffffff, 0xc0000000);
+       pch_iobp_update(0xea00408a, 0xfffffcff, 0x00000100);

There are many magic numbers here.

Yes there are. I might be able to figure out what these are and name them at some point.

Regards,
Simon

#43 lore raw

PATCH 24/33 x86: dts: Add SATA settings for link

In reply to Simon Glass

Add the requires settings to enable SATA on link.

---

 arch/x86/dts/link.dts             | 7 +++++++
 include/configs/chromebook_link.h | 1 -
 2 files changed, 7 insertions(+), 1 deletion(-)
arch/x86/dts/link.dts +7 -0
index 28cef07..d3c94e0 100644
@@ -164,6 +164,13 @@
 	};
 
 	pci {
+		sata {
+			compatible = "intel,pantherpoint-ahci";
+			intel,sata-mode = "ahci";
+			intel,sata-port-map = <1>;
+			intel,sata-port0-gen3-tx = <0x00880a7f>;
+		};
+
 		lpc {
 			compatible = "intel,lpc";
 			#address-cells = <1>;
include/configs/chromebook_link.h +0 -1
index 055b3ac..e9efd7c 100644
@@ -52,7 +52,6 @@
 #undef CONFIG_CMD_SF
 #undef CONFIG_USB_EHCI
 #undef CONFIG_CMD_USB
-#undef CONFIG_CMD_SCSI
 
 #define CONFIG_PCI_MEM_BUS	0xe0000000
 #define CONFIG_PCI_MEM_PHYS	CONFIG_PCI_MEM_BUS
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#44 lore raw

PATCH 25/33 x86: ivybridge: Set up EHCI USB

In reply to Simon Glass

Add init for EHCI so that USB can be used.

---

 arch/x86/cpu/ivybridge/Makefile               |  1 +
 arch/x86/cpu/ivybridge/bd82x6x.c              |  2 ++
 arch/x86/cpu/ivybridge/usb_ehci.c             | 29 +++++++++++++++++++++++++++
 arch/x86/include/asm/arch-ivybridge/bd82x6x.h |  1 +
 4 files changed, 33 insertions(+)
 create mode 100644 arch/x86/cpu/ivybridge/usb_ehci.c
arch/x86/cpu/ivybridge/Makefile +1 -0
index c6342cd..4a00757 100644
@@ -17,3 +17,4 @@ obj-y += pci.o
 obj-y += report_platform.o
 obj-y += sata.o
 obj-y += sdram.o
+obj-y += usb_ehci.o
arch/x86/cpu/ivybridge/bd82x6x.c +2 -0
index b54f5c7..1fcbc28 100644
@@ -102,6 +102,8 @@ int bd82x6x_init_pci_devices(void)
 		return -EINVAL;
 	}
 	bd82x6x_sata_init(PCH_SATA_DEV, blob, sata_node);
+	bd82x6x_usb_ehci_init(PCH_EHCI1_DEV);
+	bd82x6x_usb_ehci_init(PCH_EHCI2_DEV);
 
 	return 0;
 }
arch/x86/cpu/ivybridge/usb_ehci.c new file +29 -0
new file mode 100644
index 0000000..291c971
@@ -0,0 +1,29 @@
+/*
+ * From Coreboot
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/arch/pch.h>
+
+void bd82x6x_usb_ehci_init(pci_dev_t dev)
+{
+	u32 reg32;
+
+	/* Disable Wake on Disconnect in RMH */
+	reg32 = readl(RCB_REG(0x35b0));
+	reg32 |= 0x22;
+	writel(reg32, RCB_REG(0x35b0));
+
+	debug("EHCI: Setting up controller.. ");
+	reg32 = pci_read_config32(dev, PCI_COMMAND);
+	reg32 |= PCI_COMMAND_MASTER;
+	/* reg32 |= PCI_COMMAND_SERR; */
+	pci_write_config32(dev, PCI_COMMAND, reg32);
+
+	debug("done.\n");
+}
arch/x86/include/asm/arch-ivybridge/bd82x6x.h +1 -0
index 644755f..2e6a079 100644
@@ -10,6 +10,7 @@
 void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node);
 void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node);
 void bd82x6x_pci_init(pci_dev_t dev);
+void bd82x6x_usb_ehci_init(pci_dev_t dev);
 int bd82x6x_init_pci_devices(void);
 int bd82x6x_init(void);
 
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#45 lore raw

PATCH 26/33 x86: config: Enable USB on link

In reply to Simon Glass

Enable USB support on link - there are two EHCI ports available.

---

 include/configs/chromebook_link.h | 2 --
 1 file changed, 2 deletions(-)
include/configs/chromebook_link.h +0 -2
index e9efd7c..86429cf 100644
@@ -50,8 +50,6 @@
 #undef CONFIG_SPI
 #undef CONFIG_CMD_SPI
 #undef CONFIG_CMD_SF
-#undef CONFIG_USB_EHCI
-#undef CONFIG_CMD_USB
 
 #define CONFIG_PCI_MEM_BUS	0xe0000000
 #define CONFIG_PCI_MEM_PHYS	CONFIG_PCI_MEM_BUS
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#46 lore raw

PATCH 27/33 x86: ivybridge: Set up XHCI USB

In reply to Simon Glass

Add init for XHCI so that high-speed USB can be used.

---

 arch/x86/cpu/ivybridge/Makefile               |  1 +
 arch/x86/cpu/ivybridge/usb_xhci.c             | 32 +++++++++++++++++++++++++++
 arch/x86/include/asm/arch-ivybridge/bd82x6x.h |  1 +
 3 files changed, 34 insertions(+)
 create mode 100644 arch/x86/cpu/ivybridge/usb_xhci.c
arch/x86/cpu/ivybridge/Makefile +1 -0
index 4a00757..aedc395 100644
@@ -18,3 +18,4 @@ obj-y += report_platform.o
 obj-y += sata.o
 obj-y += sdram.o
 obj-y += usb_ehci.o
+obj-y += usb_xhci.o
arch/x86/cpu/ivybridge/usb_xhci.c new file +32 -0
new file mode 100644
index 0000000..4a32a7e
@@ -0,0 +1,32 @@
+/*
+ * From Coreboot
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/pci.h>
+#include <asm/arch/pch.h>
+
+void bd82x6x_usb_xhci_init(pci_dev_t dev)
+{
+	u32 reg32;
+
+	debug("XHCI: Setting up controller.. ");
+
+	/* lock overcurrent map */
+	reg32 = pci_read_config32(dev, 0x44);
+	reg32 |= 1;
+	pci_write_config32(dev, 0x44, reg32);
+
+	/* Enable clock gating */
+	reg32 = pci_read_config32(dev, 0x40);
+	reg32 &= ~((1 << 20) | (1 << 21));
+	reg32 |= (1 << 19) | (1 << 18) | (1 << 17);
+	reg32 |= (1 << 10) | (1 << 9) | (1 << 8);
+	reg32 |= (1 << 31); /* lock */
+	pci_write_config32(dev, 0x40, reg32);
+
+	debug("done.\n");
+}
arch/x86/include/asm/arch-ivybridge/bd82x6x.h +1 -0
index 2e6a079..6454dd9 100644
@@ -11,6 +11,7 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node);
 void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node);
 void bd82x6x_pci_init(pci_dev_t dev);
 void bd82x6x_usb_ehci_init(pci_dev_t dev);
+void bd82x6x_usb_xhci_init(pci_dev_t dev);
 int bd82x6x_init_pci_devices(void);
 int bd82x6x_init(void);
 
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#47 lore raw

PATCH 28/33 x86: Add Intel speedstep and turbo mode code

In reply to Simon Glass

Intel chips have a turbo mode where they can run faster for a short period until they reach thermal limits. Add code to adjust and query this feature.

---

 arch/x86/cpu/Makefile            |  1 +
 arch/x86/cpu/turbo.c             | 98 ++++++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/speedstep.h | 89 ++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/turbo.h     | 31 +++++++++++++
 4 files changed, 219 insertions(+)
 create mode 100644 arch/x86/cpu/turbo.c
 create mode 100644 arch/x86/include/asm/speedstep.h
 create mode 100644 arch/x86/include/asm/turbo.h
arch/x86/cpu/Makefile +1 -0
index 97f36d5..1327f08 100644
@@ -12,3 +12,4 @@ extra-y	= start.o
 obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o
 obj-y	+= interrupts.o cpu.o call64.o
 obj-$(CONFIG_PCI) += pci.o
+obj-y += turbo.o
arch/x86/cpu/turbo.c new file +98 -0

98 lines not on this page · raw message

arch/x86/include/asm/speedstep.h new file +89 -0

89 lines not on this page · raw message

arch/x86/include/asm/turbo.h new file +31 -0
new file mode 100644
index 0000000..bb0d4b4
@@ -0,0 +1,31 @@
+/*
+ * From coreboot file of the same name
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _ASM_TURBO_H
+#define _ASM_TURBO_H
+
+#define CPUID_LEAF_PM		6
+#define PM_CAP_TURBO_MODE	(1 << 1)
+
+#define MSR_IA32_MISC_ENABLES	0x1a0
+#define H_MISC_DISABLE_TURBO	(1 << 6)
+
+enum {
+	TURBO_UNKNOWN,
+	TURBO_UNAVAILABLE,
+	TURBO_DISABLED,
+	TURBO_ENABLED,
+};
+
+/* Return current turbo state */
+int turbo_get_state(void);
+
+/* Enable turbo */
+void turbo_enable(void);
+
+#endif
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#48 lore raw

PATCH 29/33 x86: Add LAPIC setup code

In reply to Simon Glass

Add code to set up the Local Advanced Peripheral Interrupt Controller.

---

 arch/x86/cpu/Makefile        |   1 +
 arch/x86/cpu/lapic.c         |  68 ++++++++++++++++++++++++
 arch/x86/include/asm/lapic.h | 123 +++++++++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/post.h  |   1 +
 4 files changed, 193 insertions(+)
 create mode 100644 arch/x86/cpu/lapic.c
arch/x86/cpu/Makefile +1 -0
index 1327f08..adfd258 100644
@@ -11,5 +11,6 @@
 extra-y	= start.o
 obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o
 obj-y	+= interrupts.o cpu.o call64.o
+obj-y += lapic.o
 obj-$(CONFIG_PCI) += pci.o
 obj-y += turbo.o
arch/x86/cpu/lapic.c new file +68 -0

68 lines not on this page · raw message

arch/x86/include/asm/lapic.h +123 -0

133 lines not on this page · raw message

arch/x86/include/asm/post.h +1 -0
index ce68839..6d2ae5d 100644
@@ -30,6 +30,7 @@
 #define POST_PRE_MRC		0x2e
 #define POST_MRC		0x2f
 #define POST_DRAM		0x2f
+#define POST_LAPIC		0x30
 
 #define POST_RAM_FAILURE	0xea
 
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#49 lore raw

PATCH 29/33 x86: Add LAPIC setup code

Hi Simon,

Quoted 49 lines · Simon Glass

Add code to set up the Local Advanced Peripheral Interrupt Controller.

---

 arch/x86/cpu/Makefile        |   1 +
 arch/x86/cpu/lapic.c         |  68 ++++++++++++++++++++++++
 arch/x86/include/asm/lapic.h | 123 +++++++++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/post.h  |   1 +
 4 files changed, 193 insertions(+)
 create mode 100644 arch/x86/cpu/lapic.c
arch/x86/cpu/Makefile +1 -0
index 1327f08..adfd258 100644
@@ -11,5 +11,6 @@
 extra-y        = start.o
 obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o
 obj-y  += interrupts.o cpu.o call64.o
+obj-y += lapic.o
 obj-$(CONFIG_PCI) += pci.o
 obj-y += turbo.o
arch/x86/cpu/lapic.c new file +20 -0
new file mode 100644
index 0000000..8191d84
@@ -0,0 +1,68 @@
+/*
+ * From coreboot file of same name
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/msr.h>
+#include <asm/io.h>
+#include <asm/lapic.h>
+#include <asm/post.h>
+
+void lapic_setup(void)
+{
+#if NEED_LAPIC == 1
+       /* Only Pentium Pro and later have those MSR stuff */
+       msr_t msr;

arch/x86/cpu/lapic.c line 30

Quoted 10 lines
arch/x86/cpu/lapic.c new file +10 -0
+
+       debug("Setting up local apic: ");
+
+       /* Enable the local apic */
+       msr = msr_read(LAPIC_BASE_MSR);
+       msr.lo |= LAPIC_BASE_MSR_ENABLE;
+       msr.lo &= ~LAPIC_BASE_MSR_ADDR_MASK;
+       msr.lo |= LAPIC_DEFAULT_BASE;
+       msr_write(LAPIC_BASE_MSR, msr);
+

Please replace above wih enable_lapic() which is already defined in lapic.h in your last patch series.

Quoted 24 lines
arch/x86/cpu/lapic.c new file +24 -0
+       /*
+        * Set Task Priority to 'accept all'.
+        */
+       lapic_write_around(LAPIC_TASKPRI,
+                          lapic_read_around(LAPIC_TASKPRI) & ~LAPIC_TPRI_MASK);
+
+       /* Put the local apic in virtual wire mode */
+       lapic_write_around(LAPIC_SPIV, (lapic_read_around(LAPIC_SPIV) &
+                               ~(LAPIC_VECTOR_MASK)) | LAPIC_SPIV_ENABLE);
+       lapic_write_around(LAPIC_LVT0, (lapic_read_around(LAPIC_LVT0) &
+                       ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER |
+                         LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY |
+                         LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 |
+                         LAPIC_DELIVERY_MODE_MASK)) |
+                       (LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING |
+                        LAPIC_DELIVERY_MODE_EXTINT));
+       lapic_write_around(LAPIC_LVT1, (lapic_read_around(LAPIC_LVT1) &
+                       ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER |
+                         LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY |
+                         LAPIC_SEND_PENDING | LAPIC_LVT_RESERVED_1 |
+                         LAPIC_DELIVERY_MODE_MASK)) |
+               (LAPIC_LVT_REMOTE_IRR | LAPIC_SEND_PENDING |
+                       LAPIC_DELIVERY_MODE_NMI));
+

arch/x86/cpu/lapic.c line 64

Quoted 10 lines
arch/x86/cpu/lapic.c new file +10 -0
+       debug("apic_id: 0x%02lx, ", lapicid());
+#else /* !NEED_LLAPIC */
+       /* Only Pentium Pro and later have those MSR stuff */
+       msr_t msr;
+
+       debug("Disabling local apic:");
+
+       msr = msr_read(LAPIC_BASE_MSR);
+       msr.lo &= ~LAPIC_BASE_MSR_ENABLE;
+       msr_write(LAPIC_BASE_MSR, msr);

Please replace above wih disable_lapic() which is already defined in lapic.h in your last patch series.

Quoted 31 lines
arch/x86/cpu/lapic.c new file +4 -0
+#endif /* !NEED_LAPIC */
+       debug("done.\n");
+       post_code(POST_LAPIC);
+}
arch/x86/include/asm/lapic.h +12 -0
index 948e643..ab00a18 100644
@@ -14,6 +14,13 @@
 #include <asm/msr.h>
 #include <asm/processor.h>
 
+/* See if I need to initialize the local apic */
+#if CONFIG_SMP || CONFIG_IOAPIC
+#  define NEED_LAPIC 1
+#else
+#  define NEED_LAPIC 0
+#endif
+
 static inline __attribute__((always_inline))
                unsigned long lapic_read(unsigned long reg)
 {
@@ -56,4 +63,120 @@ static inline __attribute__((always_inline)) unsigned long lapicid(void)
        return lapic_read(LAPIC_ID) >> 24;
 }
 
+#if !CONFIG_AP_IN_SIPI_WAIT
+/* If we need to go back to sipi wait, we use the long non-inlined version of
+ * this function in lapic_cpu_init.c
+ */
+static inline __attribute__((always_inline)) void stop_this_cpu(void)

arch/x86/include/asm/lapic.h static inline __attribute__((always_inline)) unsigned long lapicid(void) · line 80

Quoted 10 lines
arch/x86/include/asm/lapic.h +10 -0
+{
+       /* Called by an AP when it is ready to halt and wait for a new task */
+       for (;;)
+               cpu_hlt();
+}
+#else
+void stop_this_cpu(void);
+#endif
+
+#if !defined(__PRE_RAM__)

__PRE_RAM__ is a coreboot stuff. Please clean it up.

Quoted 107 lines
arch/x86/include/asm/lapic.h +101 -0
+
+#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), \
+                                                       sizeof(*(ptr))))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((struct __xchg_dummy *)(x))
+
+/*
+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
+ * Note 2: xchg has side effect, so that attribute volatile is necessary,
+ *       but generally the primitive is invalid, *ptr is output argument. --ANK
+ */
+static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
+                                  int size)
+{
+       switch (size) {
+       case 1:
+               __asm__ __volatile__("xchgb %b0,%1"
+                       : "=q" (x)
+                       : "m" (*__xg(ptr)), "0" (x)
+                       : "memory");
+               break;
+       case 2:
+               __asm__ __volatile__("xchgw %w0,%1"
+                       : "=r" (x)
+                       : "m" (*__xg(ptr)), "0" (x)
+                       : "memory");
+               break;
+       case 4:
+               __asm__ __volatile__("xchgl %0,%1"
+                       : "=r" (x)
+                       : "m" (*__xg(ptr)), "0" (x)
+                       : "memory");
+               break;
+       }
+
+       return x;
+}
+
+static inline void lapic_write_atomic(unsigned long reg, unsigned long v)
+{
+       (void)xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE + reg), v);
+}
+
+
+#ifdef X86_GOOD_APIC
+# define FORCE_READ_AROUND_WRITE 0
+# define lapic_read_around(x) lapic_read(x)
+# define lapic_write_around(x, y) lapic_write((x), (y))
+#else
+# define FORCE_READ_AROUND_WRITE 1
+# define lapic_read_around(x) lapic_read(x)
+# define lapic_write_around(x, y) lapic_write_atomic((x), (y))
+#endif
+
+static inline int lapic_remote_read(int apicid, int reg, unsigned long *pvalue)
+{
+       int timeout;
+       unsigned long status;
+       int result;
+       lapic_wait_icr_idle();
+       lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid));
+       lapic_write_around(LAPIC_ICR, LAPIC_DM_REMRD | (reg >> 4));
+       timeout = 0;
+       do {
+               status = lapic_read(LAPIC_ICR) & LAPIC_ICR_RR_MASK;
+       } while (status == LAPIC_ICR_RR_INPROG && timeout++ < 1000);
+
+       result = -1;
+       if (status == LAPIC_ICR_RR_VALID) {
+               *pvalue = lapic_read(LAPIC_RRR);
+               result = 0;
+       }
+       return result;
+}
+
+
+void lapic_setup(void);
+
+#if CONFIG_SMP
+struct device;
+int start_cpu(struct device *cpu);
+#endif /* CONFIG_SMP */
+
+#endif /* !__PRE_RAM__ */
+
+int boot_cpu(void);
+
+/**
+ * struct x86_cpu_priv - Information about a single CPU
+ *
+ * @apic_id: Advanced Programmable Interrupt Controller Identifier, which is
+ * just a number representing the CPU core
+ *
+ * TODO: Move this to driver model once lifecycle is understood
+ */
+struct x86_cpu_priv {
+       int apic_id;
+       int start_err;
+};
+
 #endif
arch/x86/include/asm/post.h +0 -0
index ce68839..6d2ae5d 100644

arch/x86/include/asm/post.h

Quoted 8 lines
arch/x86/include/asm/post.h +1 -1
@@ -30,6 +30,7 @@
 #define POST_PRE_MRC           0x2e
 #define POST_MRC               0x2f
 #define POST_DRAM              0x2f
+#define POST_LAPIC             0x30
 
 #define POST_RAM_FAILURE       0xea
 
--

Regards,
Bin

#50 lore raw

PATCH 30/33 x86: Add init for model 206AX CPU

In reply to Simon Glass

Add the setup code for the CPU so that it can be used at full speed.

---

 arch/x86/cpu/ivybridge/Makefile               |   1 +
 arch/x86/cpu/ivybridge/bd82x6x.c              |   6 +
 arch/x86/cpu/ivybridge/model_206ax.c          | 514 ++++++++++++++++++++++++++
 arch/x86/include/asm/arch-ivybridge/bd82x6x.h |   3 +
 arch/x86/include/asm/msr-index.h              |   2 +
 include/fdtdec.h                              |   1 +
 lib/fdtdec.c                                  |   1 +
 7 files changed, 528 insertions(+)
 create mode 100644 arch/x86/cpu/ivybridge/model_206ax.c
arch/x86/cpu/ivybridge/Makefile +1 -0
index aedc395..95491b5 100644
@@ -11,6 +11,7 @@ obj-y += early_init.o
 obj-y += early_me.o
 obj-y += lpc.o
 obj-y += me_status.o
+obj-y += model_206ax.o
 obj-y += microcode_intel.o
 obj-y += pch.o
 obj-y += pci.o
arch/x86/cpu/ivybridge/bd82x6x.c +6 -0
index 1fcbc28..1a3c036 100644
@@ -90,6 +90,7 @@ int bd82x6x_init_pci_devices(void)
 {
 	const void *blob = gd->fdt_blob;
 	struct pci_controller *hose;
+	struct x86_cpu_priv *cpu;
 	int sata_node;
 
 	hose = pci_bus_to_hose(0);
@@ -105,6 +106,11 @@ int bd82x6x_init_pci_devices(void)
 	bd82x6x_usb_ehci_init(PCH_EHCI1_DEV);
 	bd82x6x_usb_ehci_init(PCH_EHCI2_DEV);
 
+	cpu = calloc(1, sizeof(*cpu));
+	if (!cpu)
+		return -ENOMEM;
+	model_206ax_init(cpu);
+
 	return 0;
 }
 
arch/x86/cpu/ivybridge/model_206ax.c new file +514 -0

514 lines not on this page · raw message

arch/x86/include/asm/arch-ivybridge/bd82x6x.h +3 -0
index 6454dd9..96d51c2 100644
@@ -15,4 +15,7 @@ void bd82x6x_usb_xhci_init(pci_dev_t dev);
 int bd82x6x_init_pci_devices(void);
 int bd82x6x_init(void);
 
+struct x86_cpu_priv;
+int model_206ax_init(struct x86_cpu_priv *cpu);
+
 #endif
arch/x86/include/asm/msr-index.h +2 -0
index 6027d59..2cbb270 100644
@@ -326,6 +326,8 @@
 #define MSR_AMD_PERF_STATUS		0xc0010063
 #define MSR_AMD_PERF_CTL		0xc0010062
 
+#define MSR_PMG_CST_CONFIG_CTL		0x000000e2
+#define MSR_PMG_IO_CAPTURE_ADR		0x000000e4
 #define MSR_IA32_MPERF			0x000000e7
 #define MSR_IA32_APERF			0x000000e8
 
include/fdtdec.h +1 -0
index 0a0afce..b6e1d40 100644
@@ -121,6 +121,7 @@ enum fdt_compat_id {
 	COMPAT_INTEL_MICROCODE,		/* Intel microcode update */
 	COMPAT_MEMORY_SPD,		/* Memory SPD information */
 	COMPAT_INTEL_PANTHERPOINT_AHCI,	/* Intel Pantherpoint AHCI */
+	COMPAT_INTEL_MODEL_206AX,	/* Intel Model 206AX CPU */
 
 	COMPAT_COUNT,
 };
lib/fdtdec.c +1 -0
index 8865a26..2f2b467 100644
@@ -76,6 +76,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(INTEL_MICROCODE, "intel,microcode"),
 	COMPAT(MEMORY_SPD, "memory-spd"),
 	COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"),
+	COMPAT(INTEL_MODEL_206AX, "intel,model-206ax"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#51 lore raw

PATCH 31/33 x86: Drop some msr functions that we don't support

In reply to Simon Glass

These are not available in U-Boot as yet, so drop them.

---

 arch/x86/include/asm/msr.h | 11 -----------
 1 file changed, 11 deletions(-)
arch/x86/include/asm/msr.h +0 -11
index df43983..1955a75 100644
@@ -229,17 +229,6 @@ do {                                                            \
 struct msr *msrs_alloc(void);
 void msrs_free(struct msr *msrs);
 
-#ifdef CONFIG_SMP
-int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
-int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
-void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
-void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
-int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
-int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
-int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
-int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
-
-#endif  /* CONFIG_SMP */
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 #endif /* _ASM_X86_MSR_H */
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#52 lore raw

PATCH 32/33 x86: ivybridge: Add northbridge init functions

In reply to Simon Glass

Add init for the northbridge, another part of the platform controller hub.

---

 arch/x86/cpu/ivybridge/Makefile                   |   1 +
 arch/x86/cpu/ivybridge/bd82x6x.c                  |   2 +
 arch/x86/cpu/ivybridge/northbridge.c              | 188 ++++++++++++++++++++++
 arch/x86/include/asm/arch-ivybridge/model_206ax.h |   4 +
 arch/x86/include/asm/arch-ivybridge/sandybridge.h |  13 +-
 5 files changed, 207 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/cpu/ivybridge/northbridge.c
arch/x86/cpu/ivybridge/Makefile +1 -0
index 95491b5..1296a78 100644
@@ -13,6 +13,7 @@ obj-y += lpc.o
 obj-y += me_status.o
 obj-y += model_206ax.o
 obj-y += microcode_intel.o
+obj-y += northbridge.o
 obj-y += pch.o
 obj-y += pci.o
 obj-y += report_platform.o
arch/x86/cpu/ivybridge/bd82x6x.c +2 -0
index 1a3c036..739f979 100644
@@ -128,6 +128,8 @@ int bd82x6x_init(void)
 
 	bd82x6x_pci_init(PCH_DEV);
 	bd82x6x_sata_enable(PCH_SATA_DEV, blob, sata_node);
+	northbridge_enable(PCH_DEV);
+	northbridge_init(PCH_DEV);
 
 	return 0;
 }
arch/x86/cpu/ivybridge/northbridge.c new file +188 -0

188 lines not on this page · raw message

arch/x86/include/asm/arch-ivybridge/model_206ax.h +4 -0
index 8281d7a..7b4f2e7 100644
@@ -79,4 +79,8 @@
 #define PSS_LATENCY_TRANSITION		10
 #define PSS_LATENCY_BUSMASTER		10
 
+/* Configure power limits for turbo mode */
+void set_power_limits(u8 power_limit_1_time);
+int cpu_config_tdp_levels(void);
+
 #endif
arch/x86/include/asm/arch-ivybridge/sandybridge.h +12 -1
index 114ee19..cf7457f 100644
@@ -97,11 +97,22 @@
 /*
  * MCHBAR
  */
-#define MCHBAR_REG(reg)		(DEFAULT_RCBA + (reg))
+#define MCHBAR_REG(reg)		(DEFAULT_MCHBAR + (reg))
 
 #define SSKPD		0x5d14	/* 16bit (scratchpad) */
 #define BIOS_RESET_CPL	0x5da8	/* 8bit */
 
+/*
+ * DMIBAR
+ */
+
+#define DMIBAR_REG(x)	(DEFAULT_DMIBAR + x)
+
+int bridge_silicon_revision(void);
+
+void northbridge_enable(pci_dev_t dev);
+void northbridge_init(pci_dev_t dev);
+
 void report_platform_info(void);
 
 void sandybridge_early_init(int chipset_type);
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#53 lore raw

PATCH 33/33 x86: config: Enable SPI for chromebook_link

In reply to Simon Glass

Enable SPI so that the SPI flash can be used.

---

 include/configs/chromebook_link.h | 4 ----
 1 file changed, 4 deletions(-)
include/configs/chromebook_link.h +0 -4
index 86429cf..6b57b28 100644
@@ -46,10 +46,6 @@
  */
 #undef CONFIG_VIDEO
 #undef CONFIG_CFB_CONSOLE
-#undef CONFIG_ICH_SPI
-#undef CONFIG_SPI
-#undef CONFIG_CMD_SPI
-#undef CONFIG_CMD_SF
 
 #define CONFIG_PCI_MEM_BUS	0xe0000000
 #define CONFIG_PCI_MEM_PHYS	CONFIG_PCI_MEM_BUS
Signature · 1 line
2.1.0.rc2.206.gedb03e5