From 8c3ccb3f6d5602e47536fa83d1a8b938cae06f11 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 19 Dec 2019 17:58:19 -0700 Subject: x86: Update coreboot serial table struct Since mid 2016, coreboot has additional fields in the serial struct that it passes down to U-Boot. Add these so we are in sync. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/include/asm/coreboot_tables.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/coreboot_tables.h b/arch/x86/include/asm/coreboot_tables.h index 2c54e24e02f..61de0077d72 100644 --- a/arch/x86/include/asm/coreboot_tables.h +++ b/arch/x86/include/asm/coreboot_tables.h @@ -97,6 +97,25 @@ struct cb_serial { u32 type; u32 baseaddr; u32 baud; + u32 regwidth; + + /* + * Crystal or input frequency to the chip containing the UART. + * Provide the board specific details to allow the payload to + * initialize the chip containing the UART and make independent + * decisions as to which dividers to select and their values + * to eventually arrive at the desired console baud-rate. + */ + u32 input_hertz; + + /* + * UART PCI address: bus, device, function + * 1 << 31 - Valid bit, PCI UART in use + * Bus << 20 + * Device << 15 + * Function << 12 + */ + u32 uart_pci_addr; }; #define CB_TAG_CONSOLE 0x0010 -- cgit v1.2.3 From b7c1e67a70b13fb8dbcb3b00532c2d2236afff49 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 19 Dec 2019 17:58:21 -0700 Subject: x86: Move coreboot over to use the coreboot UART Use this UART to improve the compatibility of U-Boot when used as a coreboot payload. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/dts/coreboot.dts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/dts/coreboot.dts b/arch/x86/dts/coreboot.dts index a88da6eafd6..38ddaafa198 100644 --- a/arch/x86/dts/coreboot.dts +++ b/arch/x86/dts/coreboot.dts @@ -8,7 +8,6 @@ /dts-v1/; /include/ "skeleton.dtsi" -/include/ "serial.dtsi" /include/ "keyboard.dtsi" /include/ "pcspkr.dtsi" /include/ "reset.dtsi" @@ -40,6 +39,11 @@ u-boot,dm-pre-reloc; }; + serial: serial { + u-boot,dm-pre-reloc; + compatible = "coreboot-serial"; + }; + coreboot-fb { compatible = "coreboot-fb"; }; -- cgit v1.2.3 From 18416ba1198afaae10b91552e8b0024cb84de2fa Mon Sep 17 00:00:00 2001 From: Park, Aiden Date: Wed, 18 Dec 2019 05:56:23 +0000 Subject: x86: serial: Use NS16550_DYNAMIC in Slim Bootloader Slim Bootloader provides serial port info in its HOB to support both IO or MMIO serial ports, but it's controlled by SYS_NS16550_MEM32 or SYS_NS16550_PORT_MAPPED in U-Boot. To support both serial port configurations dynamically at runtime, Slim Bootloader serial driver leverages NS16550_DYNAMIC. Signed-off-by: Aiden Park Reviewed-by: Bin Meng [bmeng: remove the obsolete comments for data->type] Signed-off-by: Bin Meng --- arch/x86/cpu/slimbootloader/serial.c | 13 +++++-------- include/configs/slimbootloader.h | 13 ------------- 2 files changed, 5 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/x86/cpu/slimbootloader/serial.c b/arch/x86/cpu/slimbootloader/serial.c index 7b44a59bffe..bab54b18df6 100644 --- a/arch/x86/cpu/slimbootloader/serial.c +++ b/arch/x86/cpu/slimbootloader/serial.c @@ -34,18 +34,15 @@ static int slimbootloader_serial_ofdata_to_platdata(struct udevice *dev) data->stride, data->clk); - /* - * The data->type provides port io or mmio access type info, - * but the access type will be controlled by - * CONFIG_SYS_NS16550_PORT_MAPPED or CONFIG_SYS_NS16550_MEM32. - * - * TBD: ns16550 access type configuration in runtime. - * ex) plat->access_type = data->type - */ plat->base = data->base; /* ns16550 uses reg_shift, then covert stride to shift */ plat->reg_shift = data->stride >> 1; + plat->reg_width = data->stride; plat->clock = data->clk; + plat->fcr = UART_FCR_DEFVAL; + plat->flags = 0; + if (data->type == 1) + plat->flags |= NS16550_FLAG_IO; return 0; } diff --git a/include/configs/slimbootloader.h b/include/configs/slimbootloader.h index e0011ed4461..b8169072cc8 100644 --- a/include/configs/slimbootloader.h +++ b/include/configs/slimbootloader.h @@ -8,19 +8,6 @@ #include -/* - * By default, CONFIG_SYS_NS16550_PORT_MAPPED is enabled for port io serial. - * To use mmio base serial, enable CONFIG_SYS_NS16550_MEM32 and disable - * CONFIG_SYS_NS16550_PORT_MAPPED until ns16550 driver supports serial port - * configuration in run-time. - * - * #define CONFIG_SYS_NS16550_MEM32 - * #undef CONFIG_SYS_NS16550_PORT_MAPPED - */ -#ifdef CONFIG_SYS_NS16550_MEM32 -#undef CONFIG_SYS_NS16550_PORT_MAPPED -#endif - #define CONFIG_STD_DEVICES_SETTINGS \ "stdin=serial,i8042-kbd,usbkbd\0" \ "stdout=serial\0" \ -- cgit v1.2.3 From 0d67fac29f3187e67f4fd3ef15f73e91be2fad12 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Jan 2020 20:08:44 +0900 Subject: x86: use invd instead of wbinvd in real mode start code I do not know why the boot code immediately after the system reset should write-back the cache content. I think the cache invalidation should be enough. I tested this commit with qemu-x86_defconfig, and it worked for me. Signed-off-by: Masahiro Yamada Reviewed-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng --- arch/x86/cpu/start.S | 2 +- arch/x86/cpu/start16.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index 01524635e9c..26cf995db2d 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -50,7 +50,7 @@ _x86boot_start: movl %cr0, %eax orl $(X86_CR0_NW | X86_CR0_CD), %eax movl %eax, %cr0 - wbinvd + invd /* * Zero the BIST (Built-In Self Test) value since we don't have it. diff --git a/arch/x86/cpu/start16.S b/arch/x86/cpu/start16.S index 54f4ff6662a..292e7505081 100644 --- a/arch/x86/cpu/start16.S +++ b/arch/x86/cpu/start16.S @@ -28,7 +28,7 @@ start16: movl %cr0, %eax orl $(X86_CR0_NW | X86_CR0_CD), %eax movl %eax, %cr0 - wbinvd + invd /* load the temporary Global Descriptor Table */ data32 cs lidt idt_ptr -- cgit v1.2.3 From 2fa863e9aa4e9d5638c6a8555a7d71dc38e79b90 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Jan 2020 20:13:42 +0900 Subject: x86: limit the fs segment to the pointer size The fs segment is only used to get the global data pointer. If it is accessed beyond sizeof(new_gd->arch.gd_addr), it is a bug. To specify the byte-granule limit size, drop the G bit, so the flag field is 0x8093 instead of 0xc093, and set the limit field to sizeof(new_gd->arch.gd_addr) - 1. Signed-off-by: Masahiro Yamada Reviewed-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng [bmeng: fixed the comments about FS segement] Signed-off-by: Bin Meng --- arch/x86/cpu/i386/cpu.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c index 1592b2c9d3b..c8da7f10e9b 100644 --- a/arch/x86/cpu/i386/cpu.c +++ b/arch/x86/cpu/i386/cpu.c @@ -136,10 +136,14 @@ void arch_setup_gd(gd_t *new_gd) /* DS: data, read/write, 4 GB, base 0 */ gdt_addr[X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff); - /* FS: data, read/write, 4 GB, base (Global Data Pointer) */ + /* + * FS: data, read/write, sizeof (Global Data Pointer), + * base (Global Data Pointer) + */ new_gd->arch.gd_addr = new_gd; - gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0xc093, - (ulong)&new_gd->arch.gd_addr, 0xfffff); + gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0x8093, + (ulong)&new_gd->arch.gd_addr, + sizeof(new_gd->arch.gd_addr) - 1); /* 16-bit CS: code, read/execute, 64 kB, base 0 */ gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x009b, 0, 0x0ffff); -- cgit v1.2.3 From 7d53b5a4ceaf86ecfe1bee097f27b49557e7cf7a Mon Sep 17 00:00:00 2001 From: Wolfgang Wallner Date: Wed, 22 Jan 2020 16:01:44 +0100 Subject: x86: apl: Add the term "Interrupt Timer Subsystem" to ITSS files ITSS stands for "Interrupt Timer Subsystem", so add that term to the description of the relevant files. Signed-off-by: Wolfgang Wallner Reviewed-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/apollolake/itss.c | 2 +- arch/x86/include/asm/arch-apollolake/itss.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/cpu/apollolake/itss.c b/arch/x86/cpu/apollolake/itss.c index 8789f8e6bb9..95c9ebddc12 100644 --- a/arch/x86/cpu/apollolake/itss.c +++ b/arch/x86/cpu/apollolake/itss.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Something to do with Interrupts, but I don't know what ITSS stands for + * Interrupt Timer Subsystem * * Copyright (C) 2017 Intel Corporation. * Copyright (C) 2017 Siemens AG diff --git a/arch/x86/include/asm/arch-apollolake/itss.h b/arch/x86/include/asm/arch-apollolake/itss.h index 1e295039745..c75d8fe8c26 100644 --- a/arch/x86/include/asm/arch-apollolake/itss.h +++ b/arch/x86/include/asm/arch-apollolake/itss.h @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* + * Interrupt Timer Subsystem + * * Copyright (C) 2017 Intel Corporation. * Copyright 2019 Google LLC * -- cgit v1.2.3 From 142c9751a6cb7e2f9d18847570bc01c5e991aeeb Mon Sep 17 00:00:00 2001 From: Wolfgang Wallner Date: Wed, 22 Jan 2020 16:01:45 +0100 Subject: x86: Move itss.h from Apollo Lake to the generic x86 include directory The code in this file is not specific to Apollo Lake. According to coreboot sources (where this code comes from), it is common to at least: * Apollo Lake * Cannon Lake * Ice Lake * Skylake Signed-off-by: Wolfgang Wallner Reviewed-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/apollolake/itss.c | 2 +- arch/x86/include/asm/arch-apollolake/itss.h | 45 ----------------------------- arch/x86/include/asm/itss.h | 45 +++++++++++++++++++++++++++++ drivers/pinctrl/intel/pinctrl.c | 2 +- 4 files changed, 47 insertions(+), 47 deletions(-) delete mode 100644 arch/x86/include/asm/arch-apollolake/itss.h create mode 100644 arch/x86/include/asm/itss.h (limited to 'arch') diff --git a/arch/x86/cpu/apollolake/itss.c b/arch/x86/cpu/apollolake/itss.c index 95c9ebddc12..ff7a83d618a 100644 --- a/arch/x86/cpu/apollolake/itss.c +++ b/arch/x86/cpu/apollolake/itss.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include struct apl_itss_platdata { #if CONFIG_IS_ENABLED(OF_PLATDATA) diff --git a/arch/x86/include/asm/arch-apollolake/itss.h b/arch/x86/include/asm/arch-apollolake/itss.h deleted file mode 100644 index c75d8fe8c26..00000000000 --- a/arch/x86/include/asm/arch-apollolake/itss.h +++ /dev/null @@ -1,45 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Interrupt Timer Subsystem - * - * Copyright (C) 2017 Intel Corporation. - * Copyright 2019 Google LLC - * - * Modified from coreboot itss.h - */ - -#ifndef _ASM_ARCH_ITSS_H -#define _ASM_ARCH_ITSS_H - -#define GPIO_IRQ_START 50 -#define GPIO_IRQ_END ITSS_MAX_IRQ - -#define ITSS_MAX_IRQ 119 -#define IRQS_PER_IPC 32 -#define NUM_IPC_REGS ((ITSS_MAX_IRQ + IRQS_PER_IPC - 1) / IRQS_PER_IPC) - -/* Max PXRC registers in ITSS */ -#define MAX_PXRC_CONFIG (PCR_ITSS_PIRQH_ROUT - PCR_ITSS_PIRQA_ROUT + 1) - -/* PIRQA Routing Control Register */ -#define PCR_ITSS_PIRQA_ROUT 0x3100 -/* PIRQB Routing Control Register */ -#define PCR_ITSS_PIRQB_ROUT 0x3101 -/* PIRQC Routing Control Register */ -#define PCR_ITSS_PIRQC_ROUT 0x3102 -/* PIRQD Routing Control Register */ -#define PCR_ITSS_PIRQD_ROUT 0x3103 -/* PIRQE Routing Control Register */ -#define PCR_ITSS_PIRQE_ROUT 0x3104 -/* PIRQF Routing Control Register */ -#define PCR_ITSS_PIRQF_ROUT 0x3105 -/* PIRQG Routing Control Register */ -#define PCR_ITSS_PIRQG_ROUT 0x3106 -/* PIRQH Routing Control Register */ -#define PCR_ITSS_PIRQH_ROUT 0x3107 -/* ITSS Interrupt polarity control */ -#define PCR_ITSS_IPC0_CONF 0x3200 -/* ITSS Power reduction control */ -#define PCR_ITSS_ITSSPRC 0x3300 - -#endif /* _ASM_ARCH_ITSS_H */ diff --git a/arch/x86/include/asm/itss.h b/arch/x86/include/asm/itss.h new file mode 100644 index 00000000000..c75d8fe8c26 --- /dev/null +++ b/arch/x86/include/asm/itss.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Interrupt Timer Subsystem + * + * Copyright (C) 2017 Intel Corporation. + * Copyright 2019 Google LLC + * + * Modified from coreboot itss.h + */ + +#ifndef _ASM_ARCH_ITSS_H +#define _ASM_ARCH_ITSS_H + +#define GPIO_IRQ_START 50 +#define GPIO_IRQ_END ITSS_MAX_IRQ + +#define ITSS_MAX_IRQ 119 +#define IRQS_PER_IPC 32 +#define NUM_IPC_REGS ((ITSS_MAX_IRQ + IRQS_PER_IPC - 1) / IRQS_PER_IPC) + +/* Max PXRC registers in ITSS */ +#define MAX_PXRC_CONFIG (PCR_ITSS_PIRQH_ROUT - PCR_ITSS_PIRQA_ROUT + 1) + +/* PIRQA Routing Control Register */ +#define PCR_ITSS_PIRQA_ROUT 0x3100 +/* PIRQB Routing Control Register */ +#define PCR_ITSS_PIRQB_ROUT 0x3101 +/* PIRQC Routing Control Register */ +#define PCR_ITSS_PIRQC_ROUT 0x3102 +/* PIRQD Routing Control Register */ +#define PCR_ITSS_PIRQD_ROUT 0x3103 +/* PIRQE Routing Control Register */ +#define PCR_ITSS_PIRQE_ROUT 0x3104 +/* PIRQF Routing Control Register */ +#define PCR_ITSS_PIRQF_ROUT 0x3105 +/* PIRQG Routing Control Register */ +#define PCR_ITSS_PIRQG_ROUT 0x3106 +/* PIRQH Routing Control Register */ +#define PCR_ITSS_PIRQH_ROUT 0x3107 +/* ITSS Interrupt polarity control */ +#define PCR_ITSS_IPC0_CONF 0x3200 +/* ITSS Power reduction control */ +#define PCR_ITSS_ITSSPRC 0x3300 + +#endif /* _ASM_ARCH_ITSS_H */ diff --git a/drivers/pinctrl/intel/pinctrl.c b/drivers/pinctrl/intel/pinctrl.c index 4875a3b0b52..5bf5d8b0e24 100644 --- a/drivers/pinctrl/intel/pinctrl.c +++ b/drivers/pinctrl/intel/pinctrl.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include -- cgit v1.2.3 From 43709fa0888cc80648939ae1588307334e6cc267 Mon Sep 17 00:00:00 2001 From: Wolfgang Wallner Date: Wed, 22 Jan 2020 16:01:46 +0100 Subject: x86: Move itss.c from Apollo Lake to a more generic location The Interrupt Timer Subsystem (ITSS) is not specific to Apollo Lake, so move it to a common location within arch/x86. Signed-off-by: Wolfgang Wallner Reviewed-by: Simon Glass Reviewed-by: Bin Meng [bmeng: conditionally build itss.c] Signed-off-by: Bin Meng --- arch/x86/cpu/apollolake/Makefile | 1 - arch/x86/cpu/apollolake/itss.c | 214 ------------------------------------- arch/x86/cpu/intel_common/Makefile | 3 + arch/x86/cpu/intel_common/itss.c | 214 +++++++++++++++++++++++++++++++++++++ 4 files changed, 217 insertions(+), 215 deletions(-) delete mode 100644 arch/x86/cpu/apollolake/itss.c create mode 100644 arch/x86/cpu/intel_common/itss.c (limited to 'arch') diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile index 1760df54d81..f99f2c64739 100644 --- a/arch/x86/cpu/apollolake/Makefile +++ b/arch/x86/cpu/apollolake/Makefile @@ -19,7 +19,6 @@ obj-y += fsp_s.o endif obj-y += hostbridge.o -obj-y += itss.o obj-y += lpc.o obj-y += p2sb.o obj-y += pch.o diff --git a/arch/x86/cpu/apollolake/itss.c b/arch/x86/cpu/apollolake/itss.c deleted file mode 100644 index ff7a83d618a..00000000000 --- a/arch/x86/cpu/apollolake/itss.c +++ /dev/null @@ -1,214 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Interrupt Timer Subsystem - * - * Copyright (C) 2017 Intel Corporation. - * Copyright (C) 2017 Siemens AG - * Copyright 2019 Google LLC - * - * Taken from coreboot itss.c - */ - -#include -#include -#include -#include -#include -#include -#include - -struct apl_itss_platdata { -#if CONFIG_IS_ENABLED(OF_PLATDATA) - /* Put this first since driver model will copy the data here */ - struct dtd_intel_apl_itss dtplat; -#endif -}; - -/* struct pmc_route - Routing for PMC to GPIO */ -struct pmc_route { - u32 pmc; - u32 gpio; -}; - -struct apl_itss_priv { - struct pmc_route *route; - uint route_count; - u32 irq_snapshot[NUM_IPC_REGS]; -}; - -static int apl_set_polarity(struct udevice *dev, uint irq, bool active_low) -{ - u32 mask; - uint reg; - - if (irq > ITSS_MAX_IRQ) - return -EINVAL; - - reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * (irq / IRQS_PER_IPC); - mask = 1 << (irq % IRQS_PER_IPC); - - pcr_clrsetbits32(dev, reg, mask, active_low ? mask : 0); - - return 0; -} - -#ifndef CONFIG_TPL_BUILD -static int apl_snapshot_polarities(struct udevice *dev) -{ - struct apl_itss_priv *priv = dev_get_priv(dev); - const int start = GPIO_IRQ_START; - const int end = GPIO_IRQ_END; - int reg_start; - int reg_end; - int i; - - reg_start = start / IRQS_PER_IPC; - reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC; - - for (i = reg_start; i < reg_end; i++) { - uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i; - - priv->irq_snapshot[i] = pcr_read32(dev, reg); - } - - return 0; -} - -static void show_polarities(struct udevice *dev, const char *msg) -{ - int i; - - log_info("ITSS IRQ Polarities %s:\n", msg); - for (i = 0; i < NUM_IPC_REGS; i++) { - uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i; - - log_info("IPC%d: 0x%08x\n", i, pcr_read32(dev, reg)); - } -} - -static int apl_restore_polarities(struct udevice *dev) -{ - struct apl_itss_priv *priv = dev_get_priv(dev); - const int start = GPIO_IRQ_START; - const int end = GPIO_IRQ_END; - int reg_start; - int reg_end; - int i; - - show_polarities(dev, "Before"); - - reg_start = start / IRQS_PER_IPC; - reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC; - - for (i = reg_start; i < reg_end; i++) { - u32 mask; - u16 reg; - int irq_start; - int irq_end; - - irq_start = i * IRQS_PER_IPC; - irq_end = min(irq_start + IRQS_PER_IPC - 1, ITSS_MAX_IRQ); - - if (start > irq_end) - continue; - if (end < irq_start) - break; - - /* Track bits within the bounds of of the register */ - irq_start = max(start, irq_start) % IRQS_PER_IPC; - irq_end = min(end, irq_end) % IRQS_PER_IPC; - - /* Create bitmask of the inclusive range of start and end */ - mask = (((1U << irq_end) - 1) | (1U << irq_end)); - mask &= ~((1U << irq_start) - 1); - - reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i; - pcr_clrsetbits32(dev, reg, mask, mask & priv->irq_snapshot[i]); - } - - show_polarities(dev, "After"); - - return 0; -} -#endif - -static int apl_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num) -{ - struct apl_itss_priv *priv = dev_get_priv(dev); - struct pmc_route *route; - int i; - - for (i = 0, route = priv->route; i < priv->route_count; i++, route++) { - if (pmc_gpe_num == route->pmc) - return route->gpio; - } - - return -ENOENT; -} - -static int apl_itss_ofdata_to_platdata(struct udevice *dev) -{ - struct apl_itss_priv *priv = dev_get_priv(dev); - int ret; - -#if CONFIG_IS_ENABLED(OF_PLATDATA) - struct apl_itss_platdata *plat = dev_get_platdata(dev); - struct dtd_intel_apl_itss *dtplat = &plat->dtplat; - - /* - * It would be nice to do this in the bind() method, but with - * of-platdata binding happens in the order that DM finds things in the - * linker list (i.e. alphabetical order by driver name). So the GPIO - * device may well be bound before its parent (p2sb), and this call - * will fail if p2sb is not bound yet. - * - * TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc - */ - ret = p2sb_set_port_id(dev, dtplat->intel_p2sb_port_id); - if (ret) - return log_msg_ret("Could not set port id", ret); - priv->route = (struct pmc_route *)dtplat->intel_pmc_routes; - priv->route_count = ARRAY_SIZE(dtplat->intel_pmc_routes) / - sizeof(struct pmc_route); -#else - int size; - - size = dev_read_size(dev, "intel,pmc-routes"); - if (size < 0) - return size; - priv->route = malloc(size); - if (!priv->route) - return -ENOMEM; - ret = dev_read_u32_array(dev, "intel,pmc-routes", (u32 *)priv->route, - size / sizeof(fdt32_t)); - if (ret) - return log_msg_ret("Cannot read pmc-routes", ret); - priv->route_count = size / sizeof(struct pmc_route); -#endif - - return 0; -} - -static const struct irq_ops apl_itss_ops = { - .route_pmc_gpio_gpe = apl_route_pmc_gpio_gpe, - .set_polarity = apl_set_polarity, -#ifndef CONFIG_TPL_BUILD - .snapshot_polarities = apl_snapshot_polarities, - .restore_polarities = apl_restore_polarities, -#endif -}; - -static const struct udevice_id apl_itss_ids[] = { - { .compatible = "intel,apl-itss"}, - { } -}; - -U_BOOT_DRIVER(apl_itss_drv) = { - .name = "intel_apl_itss", - .id = UCLASS_IRQ, - .of_match = apl_itss_ids, - .ops = &apl_itss_ops, - .ofdata_to_platdata = apl_itss_ofdata_to_platdata, - .platdata_auto_alloc_size = sizeof(struct apl_itss_platdata), - .priv_auto_alloc_size = sizeof(struct apl_itss_priv), -}; diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile index cc4e1c962b9..1e7a72f2baf 100644 --- a/arch/x86/cpu/intel_common/Makefile +++ b/arch/x86/cpu/intel_common/Makefile @@ -27,6 +27,9 @@ obj-y += microcode.o endif endif obj-y += pch.o +ifdef CONFIG_INTEL_APOLLOLAKE +obj-y += itss.o +endif ifdef CONFIG_SPL ifndef CONFIG_SPL_BUILD diff --git a/arch/x86/cpu/intel_common/itss.c b/arch/x86/cpu/intel_common/itss.c new file mode 100644 index 00000000000..ff7a83d618a --- /dev/null +++ b/arch/x86/cpu/intel_common/itss.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Interrupt Timer Subsystem + * + * Copyright (C) 2017 Intel Corporation. + * Copyright (C) 2017 Siemens AG + * Copyright 2019 Google LLC + * + * Taken from coreboot itss.c + */ + +#include +#include +#include +#include +#include +#include +#include + +struct apl_itss_platdata { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + /* Put this first since driver model will copy the data here */ + struct dtd_intel_apl_itss dtplat; +#endif +}; + +/* struct pmc_route - Routing for PMC to GPIO */ +struct pmc_route { + u32 pmc; + u32 gpio; +}; + +struct apl_itss_priv { + struct pmc_route *route; + uint route_count; + u32 irq_snapshot[NUM_IPC_REGS]; +}; + +static int apl_set_polarity(struct udevice *dev, uint irq, bool active_low) +{ + u32 mask; + uint reg; + + if (irq > ITSS_MAX_IRQ) + return -EINVAL; + + reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * (irq / IRQS_PER_IPC); + mask = 1 << (irq % IRQS_PER_IPC); + + pcr_clrsetbits32(dev, reg, mask, active_low ? mask : 0); + + return 0; +} + +#ifndef CONFIG_TPL_BUILD +static int apl_snapshot_polarities(struct udevice *dev) +{ + struct apl_itss_priv *priv = dev_get_priv(dev); + const int start = GPIO_IRQ_START; + const int end = GPIO_IRQ_END; + int reg_start; + int reg_end; + int i; + + reg_start = start / IRQS_PER_IPC; + reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC; + + for (i = reg_start; i < reg_end; i++) { + uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i; + + priv->irq_snapshot[i] = pcr_read32(dev, reg); + } + + return 0; +} + +static void show_polarities(struct udevice *dev, const char *msg) +{ + int i; + + log_info("ITSS IRQ Polarities %s:\n", msg); + for (i = 0; i < NUM_IPC_REGS; i++) { + uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i; + + log_info("IPC%d: 0x%08x\n", i, pcr_read32(dev, reg)); + } +} + +static int apl_restore_polarities(struct udevice *dev) +{ + struct apl_itss_priv *priv = dev_get_priv(dev); + const int start = GPIO_IRQ_START; + const int end = GPIO_IRQ_END; + int reg_start; + int reg_end; + int i; + + show_polarities(dev, "Before"); + + reg_start = start / IRQS_PER_IPC; + reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC; + + for (i = reg_start; i < reg_end; i++) { + u32 mask; + u16 reg; + int irq_start; + int irq_end; + + irq_start = i * IRQS_PER_IPC; + irq_end = min(irq_start + IRQS_PER_IPC - 1, ITSS_MAX_IRQ); + + if (start > irq_end) + continue; + if (end < irq_start) + break; + + /* Track bits within the bounds of of the register */ + irq_start = max(start, irq_start) % IRQS_PER_IPC; + irq_end = min(end, irq_end) % IRQS_PER_IPC; + + /* Create bitmask of the inclusive range of start and end */ + mask = (((1U << irq_end) - 1) | (1U << irq_end)); + mask &= ~((1U << irq_start) - 1); + + reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i; + pcr_clrsetbits32(dev, reg, mask, mask & priv->irq_snapshot[i]); + } + + show_polarities(dev, "After"); + + return 0; +} +#endif + +static int apl_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num) +{ + struct apl_itss_priv *priv = dev_get_priv(dev); + struct pmc_route *route; + int i; + + for (i = 0, route = priv->route; i < priv->route_count; i++, route++) { + if (pmc_gpe_num == route->pmc) + return route->gpio; + } + + return -ENOENT; +} + +static int apl_itss_ofdata_to_platdata(struct udevice *dev) +{ + struct apl_itss_priv *priv = dev_get_priv(dev); + int ret; + +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct apl_itss_platdata *plat = dev_get_platdata(dev); + struct dtd_intel_apl_itss *dtplat = &plat->dtplat; + + /* + * It would be nice to do this in the bind() method, but with + * of-platdata binding happens in the order that DM finds things in the + * linker list (i.e. alphabetical order by driver name). So the GPIO + * device may well be bound before its parent (p2sb), and this call + * will fail if p2sb is not bound yet. + * + * TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc + */ + ret = p2sb_set_port_id(dev, dtplat->intel_p2sb_port_id); + if (ret) + return log_msg_ret("Could not set port id", ret); + priv->route = (struct pmc_route *)dtplat->intel_pmc_routes; + priv->route_count = ARRAY_SIZE(dtplat->intel_pmc_routes) / + sizeof(struct pmc_route); +#else + int size; + + size = dev_read_size(dev, "intel,pmc-routes"); + if (size < 0) + return size; + priv->route = malloc(size); + if (!priv->route) + return -ENOMEM; + ret = dev_read_u32_array(dev, "intel,pmc-routes", (u32 *)priv->route, + size / sizeof(fdt32_t)); + if (ret) + return log_msg_ret("Cannot read pmc-routes", ret); + priv->route_count = size / sizeof(struct pmc_route); +#endif + + return 0; +} + +static const struct irq_ops apl_itss_ops = { + .route_pmc_gpio_gpe = apl_route_pmc_gpio_gpe, + .set_polarity = apl_set_polarity, +#ifndef CONFIG_TPL_BUILD + .snapshot_polarities = apl_snapshot_polarities, + .restore_polarities = apl_restore_polarities, +#endif +}; + +static const struct udevice_id apl_itss_ids[] = { + { .compatible = "intel,apl-itss"}, + { } +}; + +U_BOOT_DRIVER(apl_itss_drv) = { + .name = "intel_apl_itss", + .id = UCLASS_IRQ, + .of_match = apl_itss_ids, + .ops = &apl_itss_ops, + .ofdata_to_platdata = apl_itss_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct apl_itss_platdata), + .priv_auto_alloc_size = sizeof(struct apl_itss_priv), +}; -- cgit v1.2.3 From 1d5bf32f0feaac806f85f128befd619cc81e7e08 Mon Sep 17 00:00:00 2001 From: Wolfgang Wallner Date: Mon, 3 Feb 2020 14:06:45 +0100 Subject: x86: itss: Add a Kconfig option to enable/disable ITSS driver Add a Kconfig option to support enabling/disabling the inclusion of the ITSS driver depending on the platform. Atuomatically select the ITSS driver when building for Apollo Lake. Signed-off-by: Wolfgang Wallner Reviewed-by: Simon Glass Reviewed-by: Bin Meng [bmeng: squashed in http://patchwork.ozlabs.org/patch/1232761/] Signed-off-by: Bin Meng --- arch/x86/Kconfig | 6 ++++++ arch/x86/cpu/apollolake/Kconfig | 1 + arch/x86/cpu/intel_common/Makefile | 4 +--- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 89b93e5de25..b733d2264ef 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -709,6 +709,12 @@ config ROM_TABLE_SIZE hex default 0x10000 +config HAVE_ITSS + bool "Enable ITSS" + help + Select this to include the driver for the Interrupt Timer + Subsystem (ITSS) which is found on several Intel devices. + menu "System tables" depends on !EFI && !SYS_COREBOOT diff --git a/arch/x86/cpu/apollolake/Kconfig b/arch/x86/cpu/apollolake/Kconfig index fcff176c27d..a760e0ac68e 100644 --- a/arch/x86/cpu/apollolake/Kconfig +++ b/arch/x86/cpu/apollolake/Kconfig @@ -39,6 +39,7 @@ config INTEL_APOLLOLAKE imply HAVE_X86_FIT imply INTEL_GPIO imply SMP + imply HAVE_ITSS if INTEL_APOLLOLAKE diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile index 1e7a72f2baf..e22c70781d6 100644 --- a/arch/x86/cpu/intel_common/Makefile +++ b/arch/x86/cpu/intel_common/Makefile @@ -27,9 +27,7 @@ obj-y += microcode.o endif endif obj-y += pch.o -ifdef CONFIG_INTEL_APOLLOLAKE -obj-y += itss.o -endif +obj-$(CONFIG_HAVE_ITSS) += itss.o ifdef CONFIG_SPL ifndef CONFIG_SPL_BUILD -- cgit v1.2.3 From 03fe85a27b23c609233100ccbab1617d78a73d84 Mon Sep 17 00:00:00 2001 From: Wolfgang Wallner Date: Wed, 22 Jan 2020 16:01:47 +0100 Subject: x86: itss: Remove apl-prefix The Interrupt Timer Subsystem (ITSS) is not specific to Apollo Lake, so remove the apl-prefix of the implemented functions/structures/... Signed-off-by: Wolfgang Wallner Reviewed-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/intel_common/itss.c | 56 +++++++++++++++++++-------------------- arch/x86/dts/chromebook_coral.dts | 2 +- 2 files changed, 29 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/x86/cpu/intel_common/itss.c b/arch/x86/cpu/intel_common/itss.c index ff7a83d618a..9df51adecc1 100644 --- a/arch/x86/cpu/intel_common/itss.c +++ b/arch/x86/cpu/intel_common/itss.c @@ -17,10 +17,10 @@ #include #include -struct apl_itss_platdata { +struct itss_platdata { #if CONFIG_IS_ENABLED(OF_PLATDATA) /* Put this first since driver model will copy the data here */ - struct dtd_intel_apl_itss dtplat; + struct dtd_intel_itss dtplat; #endif }; @@ -30,13 +30,13 @@ struct pmc_route { u32 gpio; }; -struct apl_itss_priv { +struct itss_priv { struct pmc_route *route; uint route_count; u32 irq_snapshot[NUM_IPC_REGS]; }; -static int apl_set_polarity(struct udevice *dev, uint irq, bool active_low) +static int set_polarity(struct udevice *dev, uint irq, bool active_low) { u32 mask; uint reg; @@ -53,9 +53,9 @@ static int apl_set_polarity(struct udevice *dev, uint irq, bool active_low) } #ifndef CONFIG_TPL_BUILD -static int apl_snapshot_polarities(struct udevice *dev) +static int snapshot_polarities(struct udevice *dev) { - struct apl_itss_priv *priv = dev_get_priv(dev); + struct itss_priv *priv = dev_get_priv(dev); const int start = GPIO_IRQ_START; const int end = GPIO_IRQ_END; int reg_start; @@ -86,9 +86,9 @@ static void show_polarities(struct udevice *dev, const char *msg) } } -static int apl_restore_polarities(struct udevice *dev) +static int restore_polarities(struct udevice *dev) { - struct apl_itss_priv *priv = dev_get_priv(dev); + struct itss_priv *priv = dev_get_priv(dev); const int start = GPIO_IRQ_START; const int end = GPIO_IRQ_END; int reg_start; @@ -132,9 +132,9 @@ static int apl_restore_polarities(struct udevice *dev) } #endif -static int apl_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num) +static int route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num) { - struct apl_itss_priv *priv = dev_get_priv(dev); + struct itss_priv *priv = dev_get_priv(dev); struct pmc_route *route; int i; @@ -146,14 +146,14 @@ static int apl_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num) return -ENOENT; } -static int apl_itss_ofdata_to_platdata(struct udevice *dev) +static int itss_ofdata_to_platdata(struct udevice *dev) { - struct apl_itss_priv *priv = dev_get_priv(dev); + struct itss_priv *priv = dev_get_priv(dev); int ret; #if CONFIG_IS_ENABLED(OF_PLATDATA) - struct apl_itss_platdata *plat = dev_get_platdata(dev); - struct dtd_intel_apl_itss *dtplat = &plat->dtplat; + struct itss_platdata *plat = dev_get_platdata(dev); + struct dtd_intel_itss *dtplat = &plat->dtplat; /* * It would be nice to do this in the bind() method, but with @@ -189,26 +189,26 @@ static int apl_itss_ofdata_to_platdata(struct udevice *dev) return 0; } -static const struct irq_ops apl_itss_ops = { - .route_pmc_gpio_gpe = apl_route_pmc_gpio_gpe, - .set_polarity = apl_set_polarity, +static const struct irq_ops itss_ops = { + .route_pmc_gpio_gpe = route_pmc_gpio_gpe, + .set_polarity = set_polarity, #ifndef CONFIG_TPL_BUILD - .snapshot_polarities = apl_snapshot_polarities, - .restore_polarities = apl_restore_polarities, + .snapshot_polarities = snapshot_polarities, + .restore_polarities = restore_polarities, #endif }; -static const struct udevice_id apl_itss_ids[] = { - { .compatible = "intel,apl-itss"}, +static const struct udevice_id itss_ids[] = { + { .compatible = "intel,itss"}, { } }; -U_BOOT_DRIVER(apl_itss_drv) = { - .name = "intel_apl_itss", +U_BOOT_DRIVER(itss_drv) = { + .name = "intel_itss", .id = UCLASS_IRQ, - .of_match = apl_itss_ids, - .ops = &apl_itss_ops, - .ofdata_to_platdata = apl_itss_ofdata_to_platdata, - .platdata_auto_alloc_size = sizeof(struct apl_itss_platdata), - .priv_auto_alloc_size = sizeof(struct apl_itss_priv), + .of_match = itss_ids, + .ops = &itss_ops, + .ofdata_to_platdata = itss_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct itss_platdata), + .priv_auto_alloc_size = sizeof(struct itss_priv), }; diff --git a/arch/x86/dts/chromebook_coral.dts b/arch/x86/dts/chromebook_coral.dts index 24fcbb50631..a1820fa1870 100644 --- a/arch/x86/dts/chromebook_coral.dts +++ b/arch/x86/dts/chromebook_coral.dts @@ -171,7 +171,7 @@ itss { u-boot,dm-pre-reloc; - compatible = "intel,apl-itss"; + compatible = "intel,itss"; intel,p2sb-port-id = ; intel,pmc-routes = < PMC_GPE_SW_31_0 GPIO_GPE_SW_31_0 -- cgit v1.2.3