[U-Boot] [PATCH v2 0/8] x86: Support off-chip graphics card on Intel Crown Bay

Previously when I started to look at the graphics support on Intel Crown Bay, I tried to debug IGD and off-chip graphics card but none of their vgabios can run under U-Boot. Later with a bug fixed in the 16-bit real mode and 32-bit protected mode switch, IGD vgabios can run successfully but these two PCIe graphics cards I have at hand still don't work.
With recent bug fixes as an attempt to support SeaBIOS, I started to look at them again, and this time finally got both of them work. It turns out we need completely disable IGD on TunnelCreek chipset, and also get i8254 timer counter 1 set up corretly.
This series also fixes several nits in the i8259/i8254 codes.
In case someone is interested, the two PCIe graphics card I used for testing are: 1: XGI Technology Inc., vendor ID 0x18ca, device ID 0x0027 2: Matrox Electronics Systems Ltd., vendor ID 0x102b, device ID 0x2527
Changes in v2: - Add help for the Kconfig options
Bin Meng (8): x86: Rename CONFIG_SYS_NUM_IRQS to SYS_NUM_IRQS x86: Remove dead codes wrapped by PARANOID_IRQ_TRIGGERS x86: Fix cosmetic issues in the i8254 and i8259 codes x86: Initialize i8254 timer counter 1 x86: Rename pcat_ to i8254 and i8259 accordingly x86: Move CONFIG_8259_PIC and CONFIG_8254_TIMER to Kconfig x86: queensbay: Really disable IGD x86: Move timer_init() call a bit earlier
arch/x86/Kconfig | 15 +++++++++ arch/x86/cpu/interrupts.c | 2 +- arch/x86/cpu/queensbay/tnc.c | 26 ++++++++++++---- arch/x86/include/asm/arch-queensbay/tnc.h | 7 ++--- arch/x86/include/asm/i8254.h | 43 ++++++++++++-------------- arch/x86/include/asm/i8259.h | 31 ++++++++++--------- arch/x86/include/asm/interrupt.h | 2 ++ arch/x86/include/asm/u-boot-x86.h | 2 +- arch/x86/lib/Makefile | 4 +-- arch/x86/lib/i8254.c | 37 +++++++++++++++++++++++ arch/x86/lib/{pcat_interrupts.c => i8259.c} | 47 ++++++++--------------------- arch/x86/lib/interrupts.c | 10 +++--- arch/x86/lib/pcat_timer.c | 27 ----------------- arch/x86/lib/tsc_timer.c | 6 ++-- common/board_f.c | 2 +- common/board_r.c | 3 +- include/configs/x86-common.h | 3 -- 17 files changed, 141 insertions(+), 126 deletions(-) create mode 100644 arch/x86/lib/i8254.c rename arch/x86/lib/{pcat_interrupts.c => i8259.c} (70%) delete mode 100644 arch/x86/lib/pcat_timer.c

CONFIG_SYS_NUM_IRQS is actually not something we can configure, but an architecture defined number of ISA IRQs. Move it from x86-common.h to asm/interrupt.h and rename it to SYS_NUM_IRQS.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
arch/x86/include/asm/interrupt.h | 2 ++ arch/x86/lib/interrupts.c | 10 +++++----- arch/x86/lib/pcat_interrupts.c | 10 +++------- include/configs/x86-common.h | 1 - 4 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/arch/x86/include/asm/interrupt.h b/arch/x86/include/asm/interrupt.h index fcd766b..95a4de0 100644 --- a/arch/x86/include/asm/interrupt.h +++ b/arch/x86/include/asm/interrupt.h @@ -13,6 +13,8 @@
#include <asm/types.h>
+#define SYS_NUM_IRQS 16 + /* Architecture defined exceptions */ enum x86_exception { EXC_DE = 0, diff --git a/arch/x86/lib/interrupts.c b/arch/x86/lib/interrupts.c index 146ad11..dd08402 100644 --- a/arch/x86/lib/interrupts.c +++ b/arch/x86/lib/interrupts.c @@ -39,7 +39,7 @@ struct irq_action { unsigned int count; };
-static struct irq_action irq_handlers[CONFIG_SYS_NUM_IRQS] = { {0} }; +static struct irq_action irq_handlers[SYS_NUM_IRQS] = { {0} }; static int spurious_irq_cnt; static int spurious_irq;
@@ -47,7 +47,7 @@ void irq_install_handler(int irq, interrupt_handler_t *handler, void *arg) { int status;
- if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) { + if (irq < 0 || irq >= SYS_NUM_IRQS) { printf("irq_install_handler: bad irq number %d\n", irq); return; } @@ -75,7 +75,7 @@ void irq_free_handler(int irq) { int status;
- if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) { + if (irq < 0 || irq >= SYS_NUM_IRQS) { printf("irq_free_handler: bad irq number %d\n", irq); return; } @@ -97,7 +97,7 @@ void do_irq(int hw_irq) { int irq = hw_irq - 0x20;
- if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) { + if (irq < 0 || irq >= SYS_NUM_IRQS) { printf("do_irq: bad irq number %d\n", irq); return; } @@ -130,7 +130,7 @@ int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("Interrupt-Information:\n"); printf("Nr Routine Arg Count\n");
- for (irq = 0; irq < CONFIG_SYS_NUM_IRQS; irq++) { + for (irq = 0; irq < SYS_NUM_IRQS; irq++) { if (irq_handlers[irq].handler != NULL) { printf("%02d %08lx %08lx %d\n", irq, diff --git a/arch/x86/lib/pcat_interrupts.c b/arch/x86/lib/pcat_interrupts.c index a9af87e..3704aaf 100644 --- a/arch/x86/lib/pcat_interrupts.c +++ b/arch/x86/lib/pcat_interrupts.c @@ -20,10 +20,6 @@ #include <asm/ibmpc.h> #include <asm/interrupt.h>
-#if CONFIG_SYS_NUM_IRQS != 16 -#error "CONFIG_SYS_NUM_IRQS must equal 16 if CONFIG_SYS_NUM_IRQS is defined" -#endif - int i8259_init(void) { u8 i; @@ -70,7 +66,7 @@ void mask_irq(int irq) { int imr_port;
- if (irq >= CONFIG_SYS_NUM_IRQS) + if (irq >= SYS_NUM_IRQS) return;
if (irq > 7) @@ -85,7 +81,7 @@ void unmask_irq(int irq) { int imr_port;
- if (irq >= CONFIG_SYS_NUM_IRQS) + if (irq >= SYS_NUM_IRQS) return;
if (irq > 7) @@ -98,7 +94,7 @@ void unmask_irq(int irq)
void specific_eoi(int irq) { - if (irq >= CONFIG_SYS_NUM_IRQS) + if (irq >= SYS_NUM_IRQS) return;
if (irq > 7) { diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index faadab8..2e90ef5 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -157,7 +157,6 @@ #define CONFIG_SYS_X86_TSC_TIMER #define CONFIG_SYS_PCAT_INTERRUPTS #define CONFIG_SYS_PCAT_TIMER -#define CONFIG_SYS_NUM_IRQS 16
#define CONFIG_SYS_STACK_SIZE (32 * 1024) #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE

Applied to u-boot-x86, thanks!

PARANOID_IRQ_TRIGGERS is not referenced anywhere in U-Boot. Remove these dead codes wrapped by it.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
arch/x86/lib/pcat_interrupts.c | 16 ---------------- 1 file changed, 16 deletions(-)
diff --git a/arch/x86/lib/pcat_interrupts.c b/arch/x86/lib/pcat_interrupts.c index 3704aaf..9780f46 100644 --- a/arch/x86/lib/pcat_interrupts.c +++ b/arch/x86/lib/pcat_interrupts.c @@ -127,20 +127,4 @@ void configure_irq_trigger(int int_num, bool is_level_triggered) 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)); - } - - 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 }

Applied to u-boot-x86, thanks!

This cleans up i8254 and i8259 codes to fix several cosmetic issues, like coding convention and some comments improvement.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
arch/x86/include/asm/i8254.h | 43 ++++++++++++++++++++---------------------- arch/x86/include/asm/i8259.h | 31 ++++++++++++++++-------------- arch/x86/lib/pcat_interrupts.c | 21 ++++++++++----------- arch/x86/lib/pcat_timer.c | 10 +++++----- 4 files changed, 52 insertions(+), 53 deletions(-)
diff --git a/arch/x86/include/asm/i8254.h b/arch/x86/include/asm/i8254.h index 4116de1..48e4df2 100644 --- a/arch/x86/include/asm/i8254.h +++ b/arch/x86/include/asm/i8254.h @@ -5,38 +5,35 @@ * SPDX-License-Identifier: GPL-2.0+ */
- /* i8254.h Intel 8254 PIT registers */
- #ifndef _ASMI386_I8254_H_ -#define _ASMI386_I8954_H_ 1 - +#define _ASMI386_I8954_H_
-#define PIT_T0 0x00 /* PIT channel 0 count/status */ -#define PIT_T1 0x01 /* PIT channel 1 count/status */ -#define PIT_T2 0x02 /* PIT channel 2 count/status */ -#define PIT_COMMAND 0x03 /* PIT mode control, latch and read back */ +#define PIT_T0 0x00 /* PIT channel 0 count/status */ +#define PIT_T1 0x01 /* PIT channel 1 count/status */ +#define PIT_T2 0x02 /* PIT channel 2 count/status */ +#define PIT_COMMAND 0x03 /* PIT mode control, latch and read back */
/* PIT Command Register Bit Definitions */
-#define PIT_CMD_CTR0 0x00 /* Select PIT counter 0 */ -#define PIT_CMD_CTR1 0x40 /* Select PIT counter 1 */ -#define PIT_CMD_CTR2 0x80 /* Select PIT counter 2 */ +#define PIT_CMD_CTR0 0x00 /* Select PIT counter 0 */ +#define PIT_CMD_CTR1 0x40 /* Select PIT counter 1 */ +#define PIT_CMD_CTR2 0x80 /* Select PIT counter 2 */
-#define PIT_CMD_LATCH 0x00 /* Counter Latch Command */ -#define PIT_CMD_LOW 0x10 /* Access counter bits 7-0 */ -#define PIT_CMD_HIGH 0x20 /* Access counter bits 15-8 */ -#define PIT_CMD_BOTH 0x30 /* Access counter bits 15-0 in two accesses */ +#define PIT_CMD_LATCH 0x00 /* Counter Latch Command */ +#define PIT_CMD_LOW 0x10 /* Access counter bits 7-0 */ +#define PIT_CMD_HIGH 0x20 /* Access counter bits 15-8 */ +#define PIT_CMD_BOTH 0x30 /* Access counter bits 15-0 in two accesses */
-#define PIT_CMD_MODE0 0x00 /* Select mode 0 */ -#define PIT_CMD_MODE1 0x02 /* Select mode 1 */ -#define PIT_CMD_MODE2 0x04 /* Select mode 2 */ -#define PIT_CMD_MODE3 0x06 /* Select mode 3 */ -#define PIT_CMD_MODE4 0x08 /* Select mode 4 */ -#define PIT_CMD_MODE5 0x0A /* Select mode 5 */ +#define PIT_CMD_MODE0 0x00 /* Select mode 0 */ +#define PIT_CMD_MODE1 0x02 /* Select mode 1 */ +#define PIT_CMD_MODE2 0x04 /* Select mode 2 */ +#define PIT_CMD_MODE3 0x06 /* Select mode 3 */ +#define PIT_CMD_MODE4 0x08 /* Select mode 4 */ +#define PIT_CMD_MODE5 0x0a /* Select mode 5 */
/* The clock frequency of the i8253/i8254 PIT */ -#define PIT_TICK_RATE 1193182ul +#define PIT_TICK_RATE 1193182
-#endif +#endif /* _ASMI386_I8954_H_ */ diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h index bc4033b..f216c23 100644 --- a/arch/x86/include/asm/i8259.h +++ b/arch/x86/include/asm/i8259.h @@ -8,11 +8,9 @@ /* i8259.h i8259 PIC Registers */
#ifndef _ASMI386_I8259_H_ -#define _ASMI386_I8959_H_ 1 - +#define _ASMI386_I8959_H_
/* PIC I/O mapped registers */ - #define IRR 0x0 /* Interrupt Request Register */ #define ISR 0x0 /* In-Service Register */ #define ICW1 0x0 /* Initialization Control Word 1 */ @@ -23,7 +21,7 @@ #define ICW4 0x1 /* Initialization Control Word 4 */ #define IMR 0x1 /* Interrupt Mask Register */
-/* bits for IRR, IMR, ISR and ICW3 */ +/* IRR, IMR, ISR and ICW3 bits */ #define IR7 0x80 /* IR7 */ #define IR6 0x40 /* IR6 */ #define IR5 0x20 /* IR5 */ @@ -33,7 +31,7 @@ #define IR1 0x02 /* IR1 */ #define IR0 0x01 /* IR0 */
-/* bits for SEOI */ +/* SEOI bits */ #define SEOI_IR7 0x07 /* IR7 */ #define SEOI_IR6 0x06 /* IR6 */ #define SEOI_IR5 0x05 /* IR5 */ @@ -49,9 +47,9 @@ #define OCW2_NOP 0x40 /* NOP */ #define OCW2_SEOI 0x60 /* Specific EOI */ #define OCW2_RSET 0x80 /* Rotate/set */ -#define OCW2_REOI 0xA0 /* Rotate on non specific EOI */ -#define OCW2_PSET 0xC0 /* Priority Set Command */ -#define OCW2_RSEOI 0xE0 /* Rotate on specific EOI */ +#define OCW2_REOI 0xa0 /* Rotate on non specific EOI */ +#define OCW2_PSET 0xc0 /* Priority Set Command */ +#define OCW2_RSEOI 0xe0 /* Rotate on specific EOI */
/* ICW1 bits */ #define ICW1_SEL 0x10 /* Select ICW1 */ @@ -60,15 +58,20 @@ #define ICW1_SNGL 0x02 /* Single PIC */ #define ICW1_EICW4 0x01 /* Expect initilization ICW4 */
-/* ICW2 is the starting vector number */ - -/* ICW2 is bit-mask of present slaves for a master device, - * or the slave ID for a slave device */ +/* + * ICW2 is the starting vector number + * + * ICW2 is bit-mask of present slaves for a master device, + * or the slave ID for a slave device + */
/* ICW4 bits */ -#define ICW4_AEOI 0x02 /* Automatic EOI Mode */ +#define ICW4_AEOI 0x02 /* Automatic EOI Mode */ #define ICW4_PM 0x01 /* Microprocessor Mode */
+#define ELCR1 0x4d0 +#define ELCR2 0x4d1 + int i8259_init(void);
-#endif +#endif /* _ASMI386_I8959_H_ */ diff --git a/arch/x86/lib/pcat_interrupts.c b/arch/x86/lib/pcat_interrupts.c index 9780f46..b9d0614 100644 --- a/arch/x86/lib/pcat_interrupts.c +++ b/arch/x86/lib/pcat_interrupts.c @@ -28,10 +28,11 @@ int i8259_init(void) outb(0xff, MASTER_PIC + IMR); outb(0xff, SLAVE_PIC + IMR);
- /* Master PIC */ - /* Place master PIC interrupts at INT20 */ - /* ICW3, One slave PIC is present */ - outb(ICW1_SEL|ICW1_EICW4, MASTER_PIC + ICW1); + /* + * Master PIC + * Place master PIC interrupts at INT20 + */ + outb(ICW1_SEL | ICW1_EICW4, MASTER_PIC + ICW1); outb(0x20, MASTER_PIC + ICW2); outb(IR2, MASTER_PIC + ICW3); outb(ICW4_PM, MASTER_PIC + ICW4); @@ -39,10 +40,11 @@ int i8259_init(void) for (i = 0; i < 8; i++) outb(OCW2_SEOI | i, MASTER_PIC + OCW2);
- /* Slave PIC */ - /* Place slave PIC interrupts at INT28 */ - /* Slave ID */ - outb(ICW1_SEL|ICW1_EICW4, SLAVE_PIC + ICW1); + /* + * Slave PIC + * Place slave PIC interrupts at INT28 + */ + outb(ICW1_SEL | ICW1_EICW4, SLAVE_PIC + ICW1); outb(0x28, SLAVE_PIC + ICW2); outb(0x02, SLAVE_PIC + ICW3); outb(ICW4_PM, SLAVE_PIC + ICW4); @@ -110,9 +112,6 @@ void specific_eoi(int irq) outb(OCW2_SEOI | irq, MASTER_PIC + OCW2); }
-#define ELCR1 0x4d0 -#define ELCR2 0x4d1 - void configure_irq_trigger(int int_num, bool is_level_triggered) { u16 int_bits = inb(ELCR1) | (((u16)inb(ELCR2)) << 8); diff --git a/arch/x86/lib/pcat_timer.c b/arch/x86/lib/pcat_timer.c index 3545a50..ce15818 100644 --- a/arch/x86/lib/pcat_timer.c +++ b/arch/x86/lib/pcat_timer.c @@ -9,17 +9,17 @@ #include <asm/io.h> #include <asm/i8254.h>
-#define TIMER2_VALUE 0x0a8e /* 440Hz */ +#define TIMER2_VALUE 0x0a8e /* 440Hz */
int pcat_timer_init(void) { /* - * initialize 2, used to drive the speaker - * (to start a beep: write 3 to port 0x61, - * to stop it again: write 0) + * Initialize counter 2, used to drive the speaker. + * To start a beep, set both bit0 and bit1 of port 0x61. + * To stop it, clear both bit0 and bit1 of port 0x61. */ outb(PIT_CMD_CTR2 | PIT_CMD_BOTH | PIT_CMD_MODE3, - PIT_BASE + PIT_COMMAND); + PIT_BASE + PIT_COMMAND); outb(TIMER2_VALUE & 0xff, PIT_BASE + PIT_T2); outb(TIMER2_VALUE >> 8, PIT_BASE + PIT_T2);

Applied to u-boot-x86, thanks!

Initialize counter 1, used to refresh request signal. This is required for legacy purpose as some codes like vgabios utilizes counter 1 to provide delay functionality.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
arch/x86/lib/pcat_timer.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/arch/x86/lib/pcat_timer.c b/arch/x86/lib/pcat_timer.c index ce15818..347cdda 100644 --- a/arch/x86/lib/pcat_timer.c +++ b/arch/x86/lib/pcat_timer.c @@ -9,11 +9,21 @@ #include <asm/io.h> #include <asm/i8254.h>
+#define TIMER1_VALUE 18 /* 15.6us */ #define TIMER2_VALUE 0x0a8e /* 440Hz */
int pcat_timer_init(void) { /* + * Initialize counter 1, used to refresh request signal. + * This is required for legacy purpose as some codes like + * vgabios utilizes counter 1 to provide delay functionality. + */ + outb(PIT_CMD_CTR1 | PIT_CMD_LOW | PIT_CMD_MODE2, + PIT_BASE + PIT_COMMAND); + outb(TIMER1_VALUE, PIT_BASE + PIT_T1); + + /* * Initialize counter 2, used to drive the speaker. * To start a beep, set both bit0 and bit1 of port 0x61. * To stop it, clear both bit0 and bit1 of port 0x61.

Applied to u-boot-x86, thanks!

Rename pcat_timer.c to i8254.c and pcat_interrupts.c to i8259.c, to match their header file names (i8254.h and i8259.h).
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
arch/x86/cpu/interrupts.c | 2 +- arch/x86/include/asm/u-boot-x86.h | 2 +- arch/x86/lib/Makefile | 4 ++-- arch/x86/lib/{pcat_timer.c => i8254.c} | 2 +- arch/x86/lib/{pcat_interrupts.c => i8259.c} | 0 arch/x86/lib/tsc_timer.c | 6 +++--- include/configs/x86-common.h | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) rename arch/x86/lib/{pcat_timer.c => i8254.c} (97%) rename arch/x86/lib/{pcat_interrupts.c => i8259.c} (100%)
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index addd26e..b00ddc0 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -252,7 +252,7 @@ int interrupt_init(void) /* Just in case... */ disable_interrupts();
-#ifdef CONFIG_SYS_PCAT_INTERRUPTS +#ifdef CONFIG_I8259_PIC /* Initialize the master/slave i8259 pic */ i8259_init(); #endif diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 1c459d5..dbf8e95 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -29,7 +29,7 @@ typedef void (timer_fnc_t) (void); int register_timer_isr (timer_fnc_t *isr_func); unsigned long get_tbclk_mhz(void); void timer_set_base(uint64_t base); -int pcat_timer_init(void); +int i8254_init(void);
/* cpu/.../interrupts.c */ int cpu_init_interrupts(void); diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 2f82a21..d676e2c 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -19,8 +19,8 @@ obj-y += lpc-uclass.o obj-y += mpspec.o obj-$(CONFIG_ENABLE_MRC_CACHE) += mrccache.o obj-y += cmd_mtrr.o -obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o -obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o +obj-$(CONFIG_I8259_PIC) += i8259.o +obj-$(CONFIG_I8254_TIMER) += i8254.o ifndef CONFIG_DM_PCI obj-$(CONFIG_PCI) += pci_type1.o endif diff --git a/arch/x86/lib/pcat_timer.c b/arch/x86/lib/i8254.c similarity index 97% rename from arch/x86/lib/pcat_timer.c rename to arch/x86/lib/i8254.c index 347cdda..46a4245 100644 --- a/arch/x86/lib/pcat_timer.c +++ b/arch/x86/lib/i8254.c @@ -12,7 +12,7 @@ #define TIMER1_VALUE 18 /* 15.6us */ #define TIMER2_VALUE 0x0a8e /* 440Hz */
-int pcat_timer_init(void) +int i8254_init(void) { /* * Initialize counter 1, used to refresh request signal. diff --git a/arch/x86/lib/pcat_interrupts.c b/arch/x86/lib/i8259.c similarity index 100% rename from arch/x86/lib/pcat_interrupts.c rename to arch/x86/lib/i8259.c diff --git a/arch/x86/lib/tsc_timer.c b/arch/x86/lib/tsc_timer.c index 0df1af2..e02b918 100644 --- a/arch/x86/lib/tsc_timer.c +++ b/arch/x86/lib/tsc_timer.c @@ -368,9 +368,9 @@ void __udelay(unsigned long usec)
int timer_init(void) { -#ifdef CONFIG_SYS_PCAT_TIMER - /* Set up the PCAT timer if required */ - pcat_timer_init(); +#ifdef CONFIG_I8254_TIMER + /* Set up the i8254 timer if required */ + i8254_init(); #endif
return 0; diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index 2e90ef5..58d2f42 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -155,8 +155,8 @@ */
#define CONFIG_SYS_X86_TSC_TIMER -#define CONFIG_SYS_PCAT_INTERRUPTS -#define CONFIG_SYS_PCAT_TIMER +#define CONFIG_I8259_PIC +#define CONFIG_I8254_TIMER
#define CONFIG_SYS_STACK_SIZE (32 * 1024) #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE

Applied to u-boot-x86, thanks!

Add Kconfig options for 8259 and 8254.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v2: - Add help for the Kconfig options
arch/x86/Kconfig | 15 +++++++++++++++ include/configs/x86-common.h | 2 -- 2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f92082d..8914be3 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -420,6 +420,21 @@ config PCIE_ECAM_SIZE so a default 0x10000000 size covers all of the 256 buses which is the maximum number of PCI buses as defined by the PCI specification.
+config I8259_PIC + bool + default y + help + Intel 8259 ISA compatible chipset incorporates two 8259 (master and + slave) interrupt controllers. Include this to have U-Boot set up + the interrupt correctly. + +config I8254_TIMER + bool + default y + help + Intel 8254 timer contains three counters which have fixed uses. + Include this to have U-Boot set up the timer correctly. + source "arch/x86/lib/efi/Kconfig"
endmenu diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index 58d2f42..ab9fa0b 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -155,8 +155,6 @@ */
#define CONFIG_SYS_X86_TSC_TIMER -#define CONFIG_I8259_PIC -#define CONFIG_I8254_TIMER
#define CONFIG_SYS_STACK_SIZE (32 * 1024) #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE

On 22 October 2015 at 20:13, Bin Meng bmeng.cn@gmail.com wrote:
Add Kconfig options for 8259 and 8254.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- Add help for the Kconfig options
arch/x86/Kconfig | 15 +++++++++++++++ include/configs/x86-common.h | 2 -- 2 files changed, 15 insertions(+), 2 deletions(-)
Acked-by: Simon Glass sjg@chromium.org

Applied to u-boot-x86, thanks!

According to Atom E6xx datasheet, setting VGA Disable (bit17) of Graphics Controller register (offset 0x50) prevents IGD (D2:F0) from reporting itself as a VGA display controller class in the PCI configuration space, and should also prevent it from responding to VGA legacy memory range and I/O addresses.
However test result shows that with just VGA Disable bit set and a PCIe graphics card connected to one of the PCIe controllers on the E6xx, accessing the VGA legacy space still causes system hang. After a number of attempts, it turns out besides VGA Disable bit, the SDVO (D3:F0) device should be disabled to make it work.
To simplify, use the Function Disable register (offset 0xc4) to disable both IGD (D2:F0) and SDVO (D3:F0) devices. Now these two devices will be completely disabled (invisible in the PCI configuration space) unless a system reset is performed.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
arch/x86/cpu/queensbay/tnc.c | 26 ++++++++++++++++++++------ arch/x86/include/asm/arch-queensbay/tnc.h | 7 +++---- 2 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index 0c02a44..933d189 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -25,12 +25,26 @@ static void unprotect_spi_flash(void)
static void __maybe_unused disable_igd(void) { - u32 gc; - - gc = x86_pci_read_config32(TNC_IGD, IGD_GC); - gc &= ~GMS_MASK; - gc |= VGA_DISABLE; - x86_pci_write_config32(TNC_IGD, IGD_GC, gc); + /* + * According to Atom E6xx datasheet, setting VGA Disable (bit17) + * of Graphics Controller register (offset 0x50) prevents IGD + * (D2:F0) from reporting itself as a VGA display controller + * class in the PCI configuration space, and should also prevent + * it from responding to VGA legacy memory range and I/O addresses. + * + * However test result shows that with just VGA Disable bit set and + * a PCIe graphics card connected to one of the PCIe controllers on + * the E6xx, accessing the VGA legacy space still causes system hang. + * After a number of attempts, it turns out besides VGA Disable bit, + * the SDVO (D3:F0) device should be disabled to make it work. + * + * To simplify, use the Function Disable register (offset 0xc4) + * to disable both IGD (D2:F0) and SDVO (D3:F0) devices. Now these + * two devices will be completely disabled (invisible in the PCI + * configuration space) unless a system reset is performed. + */ + x86_pci_write_config32(TNC_IGD, IGD_FD, FUNC_DISABLE); + x86_pci_write_config32(TNC_SDVO, IGD_FD, FUNC_DISABLE); }
int arch_cpu_init(void) diff --git a/arch/x86/include/asm/arch-queensbay/tnc.h b/arch/x86/include/asm/arch-queensbay/tnc.h index 2365394..8477d92 100644 --- a/arch/x86/include/asm/arch-queensbay/tnc.h +++ b/arch/x86/include/asm/arch-queensbay/tnc.h @@ -7,10 +7,9 @@ #ifndef _X86_ARCH_TNC_H_ #define _X86_ARCH_TNC_H_
-/* IGD Control Register */ -#define IGD_GC 0x50 -#define VGA_DISABLE 0x00020000 -#define GMS_MASK 0x00700000 +/* IGD Function Disable Register */ +#define IGD_FD 0xc4 +#define FUNC_DISABLE 0x00000001
/* Memory BAR Enable */ #define MEM_BAR_EN 0x00000001

Applied to u-boot-x86, thanks!

Currently timer_init() is called in board_r.c which is quite late. Some vgabios execution requires we set up the i8254 timer correctly, but video initialization comes before timer_init(). Move the call to board_f.c.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Acked-by: Simon Glass sjg@chromium.org
---
Changes in v2: None
common/board_f.c | 2 +- common/board_r.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/common/board_f.c b/common/board_f.c index 613332e..357b71e 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -794,7 +794,7 @@ static init_fnc_t init_sequence_f[] = { /* TODO: can we rename this to timer_init()? */ init_timebase, #endif -#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \ +#if defined(CONFIG_X86) || defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \ defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32) timer_init, /* initialize timer */ #endif diff --git a/common/board_r.c b/common/board_r.c index f8c1baa..7651c06 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -828,8 +828,7 @@ init_fnc_t init_sequence_r[] = { #if defined(CONFIG_ARM) || defined(CONFIG_AVR32) initr_enable_interrupts, #endif -#if defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) \ - || defined(CONFIG_M68K) +#if defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) || defined(CONFIG_M68K) timer_init, /* initialize timer */ #endif #if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)

Applied to u-boot-x86, thanks!
participants (2)
-
Bin Meng
-
Simon Glass