Commit d4827fcd4c1b04c338e4019e412f495aa4231d24

Authored by Tom Rini

Merge https://gitlab.denx.de/u-boot/custodians/u-boot-x86

- Various minor fixes for x86
- Switch to ACPI mode on Intel edison
- Support run-time configuration for NS16550 driver
- Update coreboot and slimbootloader serial drivers to use NS16550
run-time configuration
- ICH SPI driver fixes to hardware sequencing erase case
- Move ITSS from Apollo Lake to a more generic location
- Intel GPIO driver bug fixes
- Move to vs2017-win2016 platform build host for Azure pipelines

Showing 28 changed files Side-by-side Diff

.azure-pipelines.yml
1 1 variables:
2   - windows_vm: vs2015-win2012r2
  2 + windows_vm: vs2017-win2016
3 3 ubuntu_vm: ubuntu-18.04
4 4 ci_runner_image: trini/u-boot-gitlab-ci-runner:bionic-20200112-17Jan2020
5 5 # Add '-u 0' options for Azure pipelines, otherwise we get "permission
... ... @@ -709,6 +709,12 @@
709 709 hex
710 710 default 0x10000
711 711  
  712 +config HAVE_ITSS
  713 + bool "Enable ITSS"
  714 + help
  715 + Select this to include the driver for the Interrupt Timer
  716 + Subsystem (ITSS) which is found on several Intel devices.
  717 +
712 718 menu "System tables"
713 719 depends on !EFI && !SYS_COREBOOT
714 720  
arch/x86/cpu/apollolake/Kconfig
... ... @@ -39,6 +39,7 @@
39 39 imply HAVE_X86_FIT
40 40 imply INTEL_GPIO
41 41 imply SMP
  42 + imply HAVE_ITSS
42 43  
43 44 if INTEL_APOLLOLAKE
44 45  
arch/x86/cpu/apollolake/Makefile
... ... @@ -19,7 +19,6 @@
19 19 endif
20 20  
21 21 obj-y += hostbridge.o
22   -obj-y += itss.o
23 22 obj-y += lpc.o
24 23 obj-y += p2sb.o
25 24 obj-y += pch.o
arch/x86/cpu/apollolake/itss.c
1   -// SPDX-License-Identifier: GPL-2.0
2   -/*
3   - * Something to do with Interrupts, but I don't know what ITSS stands for
4   - *
5   - * Copyright (C) 2017 Intel Corporation.
6   - * Copyright (C) 2017 Siemens AG
7   - * Copyright 2019 Google LLC
8   - *
9   - * Taken from coreboot itss.c
10   - */
11   -
12   -#include <common.h>
13   -#include <dm.h>
14   -#include <dt-structs.h>
15   -#include <irq.h>
16   -#include <p2sb.h>
17   -#include <spl.h>
18   -#include <asm/arch/itss.h>
19   -
20   -struct apl_itss_platdata {
21   -#if CONFIG_IS_ENABLED(OF_PLATDATA)
22   - /* Put this first since driver model will copy the data here */
23   - struct dtd_intel_apl_itss dtplat;
24   -#endif
25   -};
26   -
27   -/* struct pmc_route - Routing for PMC to GPIO */
28   -struct pmc_route {
29   - u32 pmc;
30   - u32 gpio;
31   -};
32   -
33   -struct apl_itss_priv {
34   - struct pmc_route *route;
35   - uint route_count;
36   - u32 irq_snapshot[NUM_IPC_REGS];
37   -};
38   -
39   -static int apl_set_polarity(struct udevice *dev, uint irq, bool active_low)
40   -{
41   - u32 mask;
42   - uint reg;
43   -
44   - if (irq > ITSS_MAX_IRQ)
45   - return -EINVAL;
46   -
47   - reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * (irq / IRQS_PER_IPC);
48   - mask = 1 << (irq % IRQS_PER_IPC);
49   -
50   - pcr_clrsetbits32(dev, reg, mask, active_low ? mask : 0);
51   -
52   - return 0;
53   -}
54   -
55   -#ifndef CONFIG_TPL_BUILD
56   -static int apl_snapshot_polarities(struct udevice *dev)
57   -{
58   - struct apl_itss_priv *priv = dev_get_priv(dev);
59   - const int start = GPIO_IRQ_START;
60   - const int end = GPIO_IRQ_END;
61   - int reg_start;
62   - int reg_end;
63   - int i;
64   -
65   - reg_start = start / IRQS_PER_IPC;
66   - reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
67   -
68   - for (i = reg_start; i < reg_end; i++) {
69   - uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
70   -
71   - priv->irq_snapshot[i] = pcr_read32(dev, reg);
72   - }
73   -
74   - return 0;
75   -}
76   -
77   -static void show_polarities(struct udevice *dev, const char *msg)
78   -{
79   - int i;
80   -
81   - log_info("ITSS IRQ Polarities %s:\n", msg);
82   - for (i = 0; i < NUM_IPC_REGS; i++) {
83   - uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
84   -
85   - log_info("IPC%d: 0x%08x\n", i, pcr_read32(dev, reg));
86   - }
87   -}
88   -
89   -static int apl_restore_polarities(struct udevice *dev)
90   -{
91   - struct apl_itss_priv *priv = dev_get_priv(dev);
92   - const int start = GPIO_IRQ_START;
93   - const int end = GPIO_IRQ_END;
94   - int reg_start;
95   - int reg_end;
96   - int i;
97   -
98   - show_polarities(dev, "Before");
99   -
100   - reg_start = start / IRQS_PER_IPC;
101   - reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
102   -
103   - for (i = reg_start; i < reg_end; i++) {
104   - u32 mask;
105   - u16 reg;
106   - int irq_start;
107   - int irq_end;
108   -
109   - irq_start = i * IRQS_PER_IPC;
110   - irq_end = min(irq_start + IRQS_PER_IPC - 1, ITSS_MAX_IRQ);
111   -
112   - if (start > irq_end)
113   - continue;
114   - if (end < irq_start)
115   - break;
116   -
117   - /* Track bits within the bounds of of the register */
118   - irq_start = max(start, irq_start) % IRQS_PER_IPC;
119   - irq_end = min(end, irq_end) % IRQS_PER_IPC;
120   -
121   - /* Create bitmask of the inclusive range of start and end */
122   - mask = (((1U << irq_end) - 1) | (1U << irq_end));
123   - mask &= ~((1U << irq_start) - 1);
124   -
125   - reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
126   - pcr_clrsetbits32(dev, reg, mask, mask & priv->irq_snapshot[i]);
127   - }
128   -
129   - show_polarities(dev, "After");
130   -
131   - return 0;
132   -}
133   -#endif
134   -
135   -static int apl_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
136   -{
137   - struct apl_itss_priv *priv = dev_get_priv(dev);
138   - struct pmc_route *route;
139   - int i;
140   -
141   - for (i = 0, route = priv->route; i < priv->route_count; i++, route++) {
142   - if (pmc_gpe_num == route->pmc)
143   - return route->gpio;
144   - }
145   -
146   - return -ENOENT;
147   -}
148   -
149   -static int apl_itss_ofdata_to_platdata(struct udevice *dev)
150   -{
151   - struct apl_itss_priv *priv = dev_get_priv(dev);
152   - int ret;
153   -
154   -#if CONFIG_IS_ENABLED(OF_PLATDATA)
155   - struct apl_itss_platdata *plat = dev_get_platdata(dev);
156   - struct dtd_intel_apl_itss *dtplat = &plat->dtplat;
157   -
158   - /*
159   - * It would be nice to do this in the bind() method, but with
160   - * of-platdata binding happens in the order that DM finds things in the
161   - * linker list (i.e. alphabetical order by driver name). So the GPIO
162   - * device may well be bound before its parent (p2sb), and this call
163   - * will fail if p2sb is not bound yet.
164   - *
165   - * TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc
166   - */
167   - ret = p2sb_set_port_id(dev, dtplat->intel_p2sb_port_id);
168   - if (ret)
169   - return log_msg_ret("Could not set port id", ret);
170   - priv->route = (struct pmc_route *)dtplat->intel_pmc_routes;
171   - priv->route_count = ARRAY_SIZE(dtplat->intel_pmc_routes) /
172   - sizeof(struct pmc_route);
173   -#else
174   - int size;
175   -
176   - size = dev_read_size(dev, "intel,pmc-routes");
177   - if (size < 0)
178   - return size;
179   - priv->route = malloc(size);
180   - if (!priv->route)
181   - return -ENOMEM;
182   - ret = dev_read_u32_array(dev, "intel,pmc-routes", (u32 *)priv->route,
183   - size / sizeof(fdt32_t));
184   - if (ret)
185   - return log_msg_ret("Cannot read pmc-routes", ret);
186   - priv->route_count = size / sizeof(struct pmc_route);
187   -#endif
188   -
189   - return 0;
190   -}
191   -
192   -static const struct irq_ops apl_itss_ops = {
193   - .route_pmc_gpio_gpe = apl_route_pmc_gpio_gpe,
194   - .set_polarity = apl_set_polarity,
195   -#ifndef CONFIG_TPL_BUILD
196   - .snapshot_polarities = apl_snapshot_polarities,
197   - .restore_polarities = apl_restore_polarities,
198   -#endif
199   -};
200   -
201   -static const struct udevice_id apl_itss_ids[] = {
202   - { .compatible = "intel,apl-itss"},
203   - { }
204   -};
205   -
206   -U_BOOT_DRIVER(apl_itss_drv) = {
207   - .name = "intel_apl_itss",
208   - .id = UCLASS_IRQ,
209   - .of_match = apl_itss_ids,
210   - .ops = &apl_itss_ops,
211   - .ofdata_to_platdata = apl_itss_ofdata_to_platdata,
212   - .platdata_auto_alloc_size = sizeof(struct apl_itss_platdata),
213   - .priv_auto_alloc_size = sizeof(struct apl_itss_priv),
214   -};
arch/x86/cpu/i386/cpu.c
... ... @@ -136,10 +136,14 @@
136 136 /* DS: data, read/write, 4 GB, base 0 */
137 137 gdt_addr[X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff);
138 138  
139   - /* FS: data, read/write, 4 GB, base (Global Data Pointer) */
  139 + /*
  140 + * FS: data, read/write, sizeof (Global Data Pointer),
  141 + * base (Global Data Pointer)
  142 + */
140 143 new_gd->arch.gd_addr = new_gd;
141   - gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0xc093,
142   - (ulong)&new_gd->arch.gd_addr, 0xfffff);
  144 + gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0x8093,
  145 + (ulong)&new_gd->arch.gd_addr,
  146 + sizeof(new_gd->arch.gd_addr) - 1);
143 147  
144 148 /* 16-bit CS: code, read/execute, 64 kB, base 0 */
145 149 gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x009b, 0, 0x0ffff);
arch/x86/cpu/intel_common/Makefile
... ... @@ -27,6 +27,7 @@
27 27 endif
28 28 endif
29 29 obj-y += pch.o
  30 +obj-$(CONFIG_HAVE_ITSS) += itss.o
30 31  
31 32 ifdef CONFIG_SPL
32 33 ifndef CONFIG_SPL_BUILD
arch/x86/cpu/intel_common/itss.c
  1 +// SPDX-License-Identifier: GPL-2.0
  2 +/*
  3 + * Interrupt Timer Subsystem
  4 + *
  5 + * Copyright (C) 2017 Intel Corporation.
  6 + * Copyright (C) 2017 Siemens AG
  7 + * Copyright 2019 Google LLC
  8 + *
  9 + * Taken from coreboot itss.c
  10 + */
  11 +
  12 +#include <common.h>
  13 +#include <dm.h>
  14 +#include <dt-structs.h>
  15 +#include <irq.h>
  16 +#include <p2sb.h>
  17 +#include <spl.h>
  18 +#include <asm/itss.h>
  19 +
  20 +struct itss_platdata {
  21 +#if CONFIG_IS_ENABLED(OF_PLATDATA)
  22 + /* Put this first since driver model will copy the data here */
  23 + struct dtd_intel_itss dtplat;
  24 +#endif
  25 +};
  26 +
  27 +/* struct pmc_route - Routing for PMC to GPIO */
  28 +struct pmc_route {
  29 + u32 pmc;
  30 + u32 gpio;
  31 +};
  32 +
  33 +struct itss_priv {
  34 + struct pmc_route *route;
  35 + uint route_count;
  36 + u32 irq_snapshot[NUM_IPC_REGS];
  37 +};
  38 +
  39 +static int set_polarity(struct udevice *dev, uint irq, bool active_low)
  40 +{
  41 + u32 mask;
  42 + uint reg;
  43 +
  44 + if (irq > ITSS_MAX_IRQ)
  45 + return -EINVAL;
  46 +
  47 + reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * (irq / IRQS_PER_IPC);
  48 + mask = 1 << (irq % IRQS_PER_IPC);
  49 +
  50 + pcr_clrsetbits32(dev, reg, mask, active_low ? mask : 0);
  51 +
  52 + return 0;
  53 +}
  54 +
  55 +#ifndef CONFIG_TPL_BUILD
  56 +static int snapshot_polarities(struct udevice *dev)
  57 +{
  58 + struct itss_priv *priv = dev_get_priv(dev);
  59 + const int start = GPIO_IRQ_START;
  60 + const int end = GPIO_IRQ_END;
  61 + int reg_start;
  62 + int reg_end;
  63 + int i;
  64 +
  65 + reg_start = start / IRQS_PER_IPC;
  66 + reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
  67 +
  68 + for (i = reg_start; i < reg_end; i++) {
  69 + uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
  70 +
  71 + priv->irq_snapshot[i] = pcr_read32(dev, reg);
  72 + }
  73 +
  74 + return 0;
  75 +}
  76 +
  77 +static void show_polarities(struct udevice *dev, const char *msg)
  78 +{
  79 + int i;
  80 +
  81 + log_info("ITSS IRQ Polarities %s:\n", msg);
  82 + for (i = 0; i < NUM_IPC_REGS; i++) {
  83 + uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
  84 +
  85 + log_info("IPC%d: 0x%08x\n", i, pcr_read32(dev, reg));
  86 + }
  87 +}
  88 +
  89 +static int restore_polarities(struct udevice *dev)
  90 +{
  91 + struct itss_priv *priv = dev_get_priv(dev);
  92 + const int start = GPIO_IRQ_START;
  93 + const int end = GPIO_IRQ_END;
  94 + int reg_start;
  95 + int reg_end;
  96 + int i;
  97 +
  98 + show_polarities(dev, "Before");
  99 +
  100 + reg_start = start / IRQS_PER_IPC;
  101 + reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
  102 +
  103 + for (i = reg_start; i < reg_end; i++) {
  104 + u32 mask;
  105 + u16 reg;
  106 + int irq_start;
  107 + int irq_end;
  108 +
  109 + irq_start = i * IRQS_PER_IPC;
  110 + irq_end = min(irq_start + IRQS_PER_IPC - 1, ITSS_MAX_IRQ);
  111 +
  112 + if (start > irq_end)
  113 + continue;
  114 + if (end < irq_start)
  115 + break;
  116 +
  117 + /* Track bits within the bounds of of the register */
  118 + irq_start = max(start, irq_start) % IRQS_PER_IPC;
  119 + irq_end = min(end, irq_end) % IRQS_PER_IPC;
  120 +
  121 + /* Create bitmask of the inclusive range of start and end */
  122 + mask = (((1U << irq_end) - 1) | (1U << irq_end));
  123 + mask &= ~((1U << irq_start) - 1);
  124 +
  125 + reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
  126 + pcr_clrsetbits32(dev, reg, mask, mask & priv->irq_snapshot[i]);
  127 + }
  128 +
  129 + show_polarities(dev, "After");
  130 +
  131 + return 0;
  132 +}
  133 +#endif
  134 +
  135 +static int route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
  136 +{
  137 + struct itss_priv *priv = dev_get_priv(dev);
  138 + struct pmc_route *route;
  139 + int i;
  140 +
  141 + for (i = 0, route = priv->route; i < priv->route_count; i++, route++) {
  142 + if (pmc_gpe_num == route->pmc)
  143 + return route->gpio;
  144 + }
  145 +
  146 + return -ENOENT;
  147 +}
  148 +
  149 +static int itss_ofdata_to_platdata(struct udevice *dev)
  150 +{
  151 + struct itss_priv *priv = dev_get_priv(dev);
  152 + int ret;
  153 +
  154 +#if CONFIG_IS_ENABLED(OF_PLATDATA)
  155 + struct itss_platdata *plat = dev_get_platdata(dev);
  156 + struct dtd_intel_itss *dtplat = &plat->dtplat;
  157 +
  158 + /*
  159 + * It would be nice to do this in the bind() method, but with
  160 + * of-platdata binding happens in the order that DM finds things in the
  161 + * linker list (i.e. alphabetical order by driver name). So the GPIO
  162 + * device may well be bound before its parent (p2sb), and this call
  163 + * will fail if p2sb is not bound yet.
  164 + *
  165 + * TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc
  166 + */
  167 + ret = p2sb_set_port_id(dev, dtplat->intel_p2sb_port_id);
  168 + if (ret)
  169 + return log_msg_ret("Could not set port id", ret);
  170 + priv->route = (struct pmc_route *)dtplat->intel_pmc_routes;
  171 + priv->route_count = ARRAY_SIZE(dtplat->intel_pmc_routes) /
  172 + sizeof(struct pmc_route);
  173 +#else
  174 + int size;
  175 +
  176 + size = dev_read_size(dev, "intel,pmc-routes");
  177 + if (size < 0)
  178 + return size;
  179 + priv->route = malloc(size);
  180 + if (!priv->route)
  181 + return -ENOMEM;
  182 + ret = dev_read_u32_array(dev, "intel,pmc-routes", (u32 *)priv->route,
  183 + size / sizeof(fdt32_t));
  184 + if (ret)
  185 + return log_msg_ret("Cannot read pmc-routes", ret);
  186 + priv->route_count = size / sizeof(struct pmc_route);
  187 +#endif
  188 +
  189 + return 0;
  190 +}
  191 +
  192 +static const struct irq_ops itss_ops = {
  193 + .route_pmc_gpio_gpe = route_pmc_gpio_gpe,
  194 + .set_polarity = set_polarity,
  195 +#ifndef CONFIG_TPL_BUILD
  196 + .snapshot_polarities = snapshot_polarities,
  197 + .restore_polarities = restore_polarities,
  198 +#endif
  199 +};
  200 +
  201 +static const struct udevice_id itss_ids[] = {
  202 + { .compatible = "intel,itss"},
  203 + { }
  204 +};
  205 +
  206 +U_BOOT_DRIVER(itss_drv) = {
  207 + .name = "intel_itss",
  208 + .id = UCLASS_IRQ,
  209 + .of_match = itss_ids,
  210 + .ops = &itss_ops,
  211 + .ofdata_to_platdata = itss_ofdata_to_platdata,
  212 + .platdata_auto_alloc_size = sizeof(struct itss_platdata),
  213 + .priv_auto_alloc_size = sizeof(struct itss_priv),
  214 +};
arch/x86/cpu/slimbootloader/serial.c
... ... @@ -34,18 +34,15 @@
34 34 data->stride,
35 35 data->clk);
36 36  
37   - /*
38   - * The data->type provides port io or mmio access type info,
39   - * but the access type will be controlled by
40   - * CONFIG_SYS_NS16550_PORT_MAPPED or CONFIG_SYS_NS16550_MEM32.
41   - *
42   - * TBD: ns16550 access type configuration in runtime.
43   - * ex) plat->access_type = data->type
44   - */
45 37 plat->base = data->base;
46 38 /* ns16550 uses reg_shift, then covert stride to shift */
47 39 plat->reg_shift = data->stride >> 1;
  40 + plat->reg_width = data->stride;
48 41 plat->clock = data->clk;
  42 + plat->fcr = UART_FCR_DEFVAL;
  43 + plat->flags = 0;
  44 + if (data->type == 1)
  45 + plat->flags |= NS16550_FLAG_IO;
49 46  
50 47 return 0;
51 48 }
arch/x86/cpu/start.S
... ... @@ -50,7 +50,7 @@
50 50 movl %cr0, %eax
51 51 orl $(X86_CR0_NW | X86_CR0_CD), %eax
52 52 movl %eax, %cr0
53   - wbinvd
  53 + invd
54 54  
55 55 /*
56 56 * Zero the BIST (Built-In Self Test) value since we don't have it.
arch/x86/cpu/start16.S
... ... @@ -28,7 +28,7 @@
28 28 movl %cr0, %eax
29 29 orl $(X86_CR0_NW | X86_CR0_CD), %eax
30 30 movl %eax, %cr0
31   - wbinvd
  31 + invd
32 32  
33 33 /* load the temporary Global Descriptor Table */
34 34 data32 cs lidt idt_ptr
arch/x86/dts/chromebook_coral.dts
... ... @@ -171,7 +171,7 @@
171 171  
172 172 itss {
173 173 u-boot,dm-pre-reloc;
174   - compatible = "intel,apl-itss";
  174 + compatible = "intel,itss";
175 175 intel,p2sb-port-id = <PID_ITSS>;
176 176 intel,pmc-routes = <
177 177 PMC_GPE_SW_31_0 GPIO_GPE_SW_31_0
arch/x86/dts/coreboot.dts
... ... @@ -8,7 +8,6 @@
8 8 /dts-v1/;
9 9  
10 10 /include/ "skeleton.dtsi"
11   -/include/ "serial.dtsi"
12 11 /include/ "keyboard.dtsi"
13 12 /include/ "pcspkr.dtsi"
14 13 /include/ "reset.dtsi"
... ... @@ -38,6 +37,11 @@
38 37 pci {
39 38 compatible = "pci-x86";
40 39 u-boot,dm-pre-reloc;
  40 + };
  41 +
  42 + serial: serial {
  43 + u-boot,dm-pre-reloc;
  44 + compatible = "coreboot-serial";
41 45 };
42 46  
43 47 coreboot-fb {
arch/x86/include/asm/arch-apollolake/itss.h
1   -/* SPDX-License-Identifier: GPL-2.0 */
2   -/*
3   - * Copyright (C) 2017 Intel Corporation.
4   - * Copyright 2019 Google LLC
5   - *
6   - * Modified from coreboot itss.h
7   - */
8   -
9   -#ifndef _ASM_ARCH_ITSS_H
10   -#define _ASM_ARCH_ITSS_H
11   -
12   -#define GPIO_IRQ_START 50
13   -#define GPIO_IRQ_END ITSS_MAX_IRQ
14   -
15   -#define ITSS_MAX_IRQ 119
16   -#define IRQS_PER_IPC 32
17   -#define NUM_IPC_REGS ((ITSS_MAX_IRQ + IRQS_PER_IPC - 1) / IRQS_PER_IPC)
18   -
19   -/* Max PXRC registers in ITSS */
20   -#define MAX_PXRC_CONFIG (PCR_ITSS_PIRQH_ROUT - PCR_ITSS_PIRQA_ROUT + 1)
21   -
22   -/* PIRQA Routing Control Register */
23   -#define PCR_ITSS_PIRQA_ROUT 0x3100
24   -/* PIRQB Routing Control Register */
25   -#define PCR_ITSS_PIRQB_ROUT 0x3101
26   -/* PIRQC Routing Control Register */
27   -#define PCR_ITSS_PIRQC_ROUT 0x3102
28   -/* PIRQD Routing Control Register */
29   -#define PCR_ITSS_PIRQD_ROUT 0x3103
30   -/* PIRQE Routing Control Register */
31   -#define PCR_ITSS_PIRQE_ROUT 0x3104
32   -/* PIRQF Routing Control Register */
33   -#define PCR_ITSS_PIRQF_ROUT 0x3105
34   -/* PIRQG Routing Control Register */
35   -#define PCR_ITSS_PIRQG_ROUT 0x3106
36   -/* PIRQH Routing Control Register */
37   -#define PCR_ITSS_PIRQH_ROUT 0x3107
38   -/* ITSS Interrupt polarity control */
39   -#define PCR_ITSS_IPC0_CONF 0x3200
40   -/* ITSS Power reduction control */
41   -#define PCR_ITSS_ITSSPRC 0x3300
42   -
43   -#endif /* _ASM_ARCH_ITSS_H */
arch/x86/include/asm/coreboot_tables.h
... ... @@ -97,6 +97,25 @@
97 97 u32 type;
98 98 u32 baseaddr;
99 99 u32 baud;
  100 + u32 regwidth;
  101 +
  102 + /*
  103 + * Crystal or input frequency to the chip containing the UART.
  104 + * Provide the board specific details to allow the payload to
  105 + * initialize the chip containing the UART and make independent
  106 + * decisions as to which dividers to select and their values
  107 + * to eventually arrive at the desired console baud-rate.
  108 + */
  109 + u32 input_hertz;
  110 +
  111 + /*
  112 + * UART PCI address: bus, device, function
  113 + * 1 << 31 - Valid bit, PCI UART in use
  114 + * Bus << 20
  115 + * Device << 15
  116 + * Function << 12
  117 + */
  118 + u32 uart_pci_addr;
100 119 };
101 120  
102 121 #define CB_TAG_CONSOLE 0x0010
arch/x86/include/asm/itss.h
  1 +/* SPDX-License-Identifier: GPL-2.0 */
  2 +/*
  3 + * Interrupt Timer Subsystem
  4 + *
  5 + * Copyright (C) 2017 Intel Corporation.
  6 + * Copyright 2019 Google LLC
  7 + *
  8 + * Modified from coreboot itss.h
  9 + */
  10 +
  11 +#ifndef _ASM_ARCH_ITSS_H
  12 +#define _ASM_ARCH_ITSS_H
  13 +
  14 +#define GPIO_IRQ_START 50
  15 +#define GPIO_IRQ_END ITSS_MAX_IRQ
  16 +
  17 +#define ITSS_MAX_IRQ 119
  18 +#define IRQS_PER_IPC 32
  19 +#define NUM_IPC_REGS ((ITSS_MAX_IRQ + IRQS_PER_IPC - 1) / IRQS_PER_IPC)
  20 +
  21 +/* Max PXRC registers in ITSS */
  22 +#define MAX_PXRC_CONFIG (PCR_ITSS_PIRQH_ROUT - PCR_ITSS_PIRQA_ROUT + 1)
  23 +
  24 +/* PIRQA Routing Control Register */
  25 +#define PCR_ITSS_PIRQA_ROUT 0x3100
  26 +/* PIRQB Routing Control Register */
  27 +#define PCR_ITSS_PIRQB_ROUT 0x3101
  28 +/* PIRQC Routing Control Register */
  29 +#define PCR_ITSS_PIRQC_ROUT 0x3102
  30 +/* PIRQD Routing Control Register */
  31 +#define PCR_ITSS_PIRQD_ROUT 0x3103
  32 +/* PIRQE Routing Control Register */
  33 +#define PCR_ITSS_PIRQE_ROUT 0x3104
  34 +/* PIRQF Routing Control Register */
  35 +#define PCR_ITSS_PIRQF_ROUT 0x3105
  36 +/* PIRQG Routing Control Register */
  37 +#define PCR_ITSS_PIRQG_ROUT 0x3106
  38 +/* PIRQH Routing Control Register */
  39 +#define PCR_ITSS_PIRQH_ROUT 0x3107
  40 +/* ITSS Interrupt polarity control */
  41 +#define PCR_ITSS_IPC0_CONF 0x3200
  42 +/* ITSS Power reduction control */
  43 +#define PCR_ITSS_ITSSPRC 0x3300
  44 +
  45 +#endif /* _ASM_ARCH_ITSS_H */
configs/edison_defconfig
... ... @@ -6,10 +6,10 @@
6 6 CONFIG_VENDOR_INTEL=y
7 7 CONFIG_TARGET_EDISON=y
8 8 CONFIG_SMP=y
  9 +CONFIG_GENERATE_ACPI_TABLE=y
9 10 CONFIG_BOARD_EARLY_INIT_R=y
10 11 CONFIG_LAST_STAGE_INIT=y
11 12 CONFIG_HUSH_PARSER=y
12   -# CONFIG_CMDLINE_EDITING is not set
13 13 CONFIG_CMD_CPU=y
14 14 CONFIG_CMD_ASKENV=y
15 15 CONFIG_CMD_GREPENV=y
doc/board/google/chromebook_coral.rst
... ... @@ -112,7 +112,7 @@
112 112  
113 113  
114 114 Boot flow - U-Boot post-relocation
115   ----------------------------------
  115 +----------------------------------
116 116  
117 117 U-Boot starts up normally, running near the top of RAM. After driver model is
118 118 running, arch_fsp_init_r() is called which loads and runs the FSP-S binary.
119 119  
120 120  
121 121  
122 122  
123 123  
124 124  
... ... @@ -142,54 +142,56 @@
142 142 -----------
143 143  
144 144 Bootstage is used through all phases of U-Boot to keep accurate timimgs for
145   -boot. Use 'bootstage report' in U-Boot to see the report, e.g.:
  145 +boot. Use 'bootstage report' in U-Boot to see the report, e.g.::
146 146  
147   -Timer summary in microseconds (16 records):
148   - Mark Elapsed Stage
149   - 0 0 reset
150   - 155,325 155,325 TPL
151   - 204,014 48,689 end TPL
152   - 204,385 371 SPL
153   - 738,633 534,248 end SPL
154   - 739,161 528 board_init_f
155   - 842,764 103,603 board_init_r
156   - 1,166,233 323,469 main_loop
157   - 1,166,283 50 id=175
  147 + Timer summary in microseconds (16 records):
  148 + Mark Elapsed Stage
  149 + 0 0 reset
  150 + 155,325 155,325 TPL
  151 + 204,014 48,689 end TPL
  152 + 204,385 371 SPL
  153 + 738,633 534,248 end SPL
  154 + 739,161 528 board_init_f
  155 + 842,764 103,603 board_init_r
  156 + 1,166,233 323,469 main_loop
  157 + 1,166,283 50 id=175
158 158  
159   -Accumulated time:
160   - 62 fast_spi
161   - 202 dm_r
162   - 7,779 dm_spl
163   - 15,555 dm_f
164   - 208,357 fsp-m
165   - 239,847 fsp-s
166   - 292,143 mmap_spi
  159 + Accumulated time:
  160 + 62 fast_spi
  161 + 202 dm_r
  162 + 7,779 dm_spl
  163 + 15,555 dm_f
  164 + 208,357 fsp-m
  165 + 239,847 fsp-s
  166 + 292,143 mmap_spi
167 167  
168   -CPU performance is about 3500 DMIPS:
  168 +CPU performance is about 3500 DMIPS::
169 169  
170   -=> dhry
171   -1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS
  170 + => dhry
  171 + 1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS
172 172  
173 173  
174 174 Partial memory map
175 175 ------------------
176 176  
177   -ffffffff Top of ROM (and last byte of 32-bit address space)
178   -ffff8000 TPL loaded here (from IFWI)
179   -ff000000 Bottom of ROM
180   -fefc000 Top of CAR region
181   -fef96000 Stack for FSP-M
182   -fef40000 59000 FSP-M
183   -fef11000 SPL loaded here
184   -fef10000 CONFIG_BLOBLIST_ADDR
185   -fef10000 Stack top in TPL, SPL and U-Boot before relocation
186   -fef00000 1000 CONFIG_BOOTSTAGE_STASH_ADDR
187   -fef00000 Base of CAR region
  177 +::
188 178  
189   - f0000 CONFIG_ROM_TABLE_ADDR
190   - 120000 BSS (defined in u-boot-spl.lds)
191   - 200000 FSP-S (which is run after U-Boot is relocated)
192   - 1110000 CONFIG_SYS_TEXT_BASE
  179 + ffffffff Top of ROM (and last byte of 32-bit address space)
  180 + ffff8000 TPL loaded here (from IFWI)
  181 + ff000000 Bottom of ROM
  182 + fefc000 Top of CAR region
  183 + fef96000 Stack for FSP-M
  184 + fef40000 59000 FSP-M
  185 + fef11000 SPL loaded here
  186 + fef10000 CONFIG_BLOBLIST_ADDR
  187 + fef10000 Stack top in TPL, SPL and U-Boot before relocation
  188 + fef00000 1000 CONFIG_BOOTSTAGE_STASH_ADDR
  189 + fef00000 Base of CAR region
  190 +
  191 + f0000 CONFIG_ROM_TABLE_ADDR
  192 + 120000 BSS (defined in u-boot-spl.lds)
  193 + 200000 FSP-S (which is run after U-Boot is relocated)
  194 + 1110000 CONFIG_SYS_TEXT_BASE
193 195  
194 196  
195 197 Supported peripherals
doc/board/intel/slimbootloader.rst
... ... @@ -111,35 +111,16 @@
111 111 Build Instruction for Slim Bootloader for LeafHill (APL) target
112 112 ---------------------------------------------------------------
113 113  
114   -LeafHill is using PCI UART2 device as a serial port.
115   -For MEM32 serial port, CONFIG_SYS_NS16550_MEM32 needs to be enabled in U-Boot.
  114 +Prepare U-Boot and Slim Bootloader as described at the beginning of this page.
  115 +Also, the PayloadId needs to be set for APL board.
116 116  
117   -1. Enable CONFIG_SYS_NS16550_MEM32 in U-Boot::
  117 +1. Update PayloadId. Let's use 'U-BT' as an example::
118 118  
119   - $ vi include/configs/slimbootloader.h
120   - +#define CONFIG_SYS_NS16550_MEM32
121   - #ifdef CONFIG_SYS_NS16550_MEM3
122   -
123   -2. Build U-Boot::
124   -
125   - $ make disclean
126   - $ make slimbootloader_defconfig
127   - $ make all
128   -
129   -3. Copy u-boot-dtb.bin to Slim Bootloader.
130   - Slim Bootloader looks for a payload from the specific location.
131   - Copy the build u-boot-dtb.bin to the expected location::
132   -
133   - $ mkdir -p <Slim Bootloader Dir>/PayloadPkg/PayloadBins/
134   - $ cp <U-Boot Dir>/u-boot-dtb.bin <Slim Bootloader Dir>/PayloadPkg/PayloadBins/u-boot-dtb.bin
135   -
136   -4. Update PayloadId. Let's use 'U-BT' as an example::
137   -
138 119 $ vi Platform/ApollolakeBoardPkg/CfgData/CfgData_Int_LeafHill.dlt
139 120 -GEN_CFG_DATA.PayloadId | 'AUTO
140 121 +GEN_CFG_DATA.PayloadId | 'U-BT'
141 122  
142   -5. Update payload text base.
  123 +2. Update payload text base.
143 124  
144 125 * PAYLOAD_EXE_BASE must be the same as U-Boot CONFIG_SYS_TEXT_BASE
145 126 in board/intel/slimbootloader/Kconfig.
146 127  
147 128  
... ... @@ -149,18 +130,18 @@
149 130 + self.PAYLOAD_LOAD_HIGH = 0
150 131 + self.PAYLOAD_EXE_BASE = 0x00100000
151 132  
152   -6. Build APL target. Make sure u-boot-dtb.bin and U-BT PayloadId
  133 +3. Build APL target. Make sure u-boot-dtb.bin and U-BT PayloadId
153 134 in build command. The output is Outputs/apl/Stitch_Components.zip::
154 135  
155 136 $ python BuildLoader.py build apl -p "OsLoader.efi:LLDR:Lz4;u-boot-dtb.bin:U-BT:Lzma"
156 137  
157   -7. Stitch IFWI.
  138 +4. Stitch IFWI.
158 139  
159 140 Refer to Apollolake_ page in Slim Bootloader document site::
160 141  
161 142 $ python Platform/ApollolakeBoardPkg/Script/StitchLoader.py -i <Existing IFWI> -s Outputs/apl/Stitch_Components.zip -o <Output IFWI>
162 143  
163   -8. Flash IFWI.
  144 +5. Flash IFWI.
164 145  
165 146 Use DediProg to flash IFWI. You should reach at U-Boot serial console.
166 147  
... ... @@ -175,7 +156,7 @@
175 156  
176 157 2. Build U-Boot::
177 158  
178   - $ make disclean
  159 + $ make distclean
179 160 $ make slimbootloader_defconfig
180 161 $ make all
181 162 $ strip u-boot (removing symbol for reduced size)
drivers/gpio/intel_gpio.c
... ... @@ -39,9 +39,9 @@
39 39 struct udevice *pinctrl = dev_get_parent(dev);
40 40 uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
41 41  
42   - pcr_clrsetbits32(dev, config_offset,
  42 + pcr_clrsetbits32(pinctrl, config_offset,
43 43 PAD_CFG0_MODE_MASK | PAD_CFG0_RX_STATE |
44   - PAD_CFG0_TX_DISABLE,
  44 + PAD_CFG0_TX_DISABLE | PAD_CFG0_TX_STATE,
45 45 PAD_CFG0_MODE_GPIO | PAD_CFG0_RX_DISABLE |
46 46 (value ? PAD_CFG0_TX_STATE : 0));
47 47  
48 48  
... ... @@ -59,9 +59,9 @@
59 59 if (!mode) {
60 60 rx_tx = reg & (PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE);
61 61 if (rx_tx == PAD_CFG0_TX_DISABLE)
62   - return mode & PAD_CFG0_RX_STATE_BIT ? 1 : 0;
  62 + return reg & PAD_CFG0_RX_STATE ? 1 : 0;
63 63 else if (rx_tx == PAD_CFG0_RX_DISABLE)
64   - return mode & PAD_CFG0_TX_STATE_BIT ? 1 : 0;
  64 + return reg & PAD_CFG0_TX_STATE ? 1 : 0;
65 65 }
66 66  
67 67 return 0;
... ... @@ -72,7 +72,7 @@
72 72 struct udevice *pinctrl = dev_get_parent(dev);
73 73 uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
74 74  
75   - pcr_clrsetbits32(dev, config_offset, PAD_CFG0_TX_STATE,
  75 + pcr_clrsetbits32(pinctrl, config_offset, PAD_CFG0_TX_STATE,
76 76 value ? PAD_CFG0_TX_STATE : 0);
77 77  
78 78 return 0;
drivers/pinctrl/intel/pinctrl.c
... ... @@ -25,7 +25,7 @@
25 25 #include <asm/intel_pinctrl.h>
26 26 #include <asm/intel_pinctrl_defs.h>
27 27 #include <asm/arch/gpio.h>
28   -#include <asm/arch/itss.h>
  28 +#include <asm/itss.h>
29 29 #include <dm/device-internal.h>
30 30 #include <dt-bindings/gpio/gpio.h>
31 31  
drivers/serial/Kconfig
... ... @@ -542,6 +542,17 @@
542 542 help
543 543 Select this to enable UART on BCM6345 SoCs.
544 544  
  545 +config COREBOOT_SERIAL
  546 + bool "Coreboot UART support"
  547 + depends on DM_SERIAL
  548 + default y if SYS_COREBOOT
  549 + select SYS_NS16550
  550 + help
  551 + Select this to enable a ns16550-style UART where the platform data
  552 + comes from the coreboot 'sysinfo' tables. This allows U-Boot to have
  553 + a serial console on any platform without needing to change the
  554 + device tree, etc.
  555 +
545 556 config FSL_LINFLEXUART
546 557 bool "Freescale Linflex UART support"
547 558 depends on DM_SERIAL
... ... @@ -600,6 +611,27 @@
600 611 CONFIG_SYS_NS16550_CLK defined in a legacy board header file will
601 612 be used. It can be a constant or a function to get clock, eg,
602 613 get_serial_clock().
  614 +
  615 +config NS16550_DYNAMIC
  616 + bool "Allow NS16550 to be configured at runtime"
  617 + default y if SYS_COREBOOT || SYS_SLIMBOOTLOADER
  618 + help
  619 + Enable this option to allow device-tree control of the driver.
  620 +
  621 + Normally this driver is controlled by the following options:
  622 +
  623 + CONFIG_SYS_NS16550_PORT_MAPPED - indicates that port I/O is used for
  624 + access. If not enabled, then the UART is memory-mapped.
  625 + CONFIG_SYS_NS16550_MEM32 - if memory-mapped, indicates that 32-bit
  626 + access should be used (instead of 8-bit)
  627 + CONFIG_SYS_NS16550_REG_SIZE - indicates register width and also
  628 + endianness. If positive, big-endian access is used. If negative,
  629 + little-endian is used.
  630 +
  631 + It is not a good practice for a driver to be statically configured,
  632 + since it prevents the same driver being used for different types of
  633 + UARTs in a system. This option avoids this problem at the cost of a
  634 + slightly increased code size.
603 635  
604 636 config INTEL_MID_SERIAL
605 637 bool "Intel MID platform UART support"
drivers/serial/Makefile
... ... @@ -35,6 +35,7 @@
35 35 obj-$(CONFIG_ARM_DCC) += arm_dcc.o
36 36 obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
37 37 obj-$(CONFIG_BCM6345_SERIAL) += serial_bcm6345.o
  38 +obj-$(CONFIG_COREBOOT_SERIAL) += serial_coreboot.o
38 39 obj-$(CONFIG_EFI_APP) += serial_efi.o
39 40 obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o
40 41 obj-$(CONFIG_MCFUART) += mcfuart.o
drivers/serial/ns16550.c
... ... @@ -93,19 +93,79 @@
93 93 #define CONFIG_SYS_NS16550_CLK 0
94 94 #endif
95 95  
  96 +/*
  97 + * Use this #ifdef for now since many platforms don't define in(), out(),
  98 + * out_le32(), etc. but we don't have #defines to indicate this.
  99 + *
  100 + * TODO(sjg@chromium.org): Add CONFIG options to indicate what I/O is available
  101 + * on a platform
  102 + */
  103 +#ifdef CONFIG_NS16550_DYNAMIC
  104 +static void serial_out_dynamic(struct ns16550_platdata *plat, u8 *addr,
  105 + int value)
  106 +{
  107 + if (plat->flags & NS16550_FLAG_IO) {
  108 + outb(value, addr);
  109 + } else if (plat->reg_width == 4) {
  110 + if (plat->flags & NS16550_FLAG_ENDIAN) {
  111 + if (plat->flags & NS16550_FLAG_BE)
  112 + out_be32(addr, value);
  113 + else
  114 + out_le32(addr, value);
  115 + } else {
  116 + writel(value, addr);
  117 + }
  118 + } else if (plat->flags & NS16550_FLAG_BE) {
  119 + writeb(value, addr + (1 << plat->reg_shift) - 1);
  120 + } else {
  121 + writeb(value, addr);
  122 + }
  123 +}
  124 +
  125 +static int serial_in_dynamic(struct ns16550_platdata *plat, u8 *addr)
  126 +{
  127 + if (plat->flags & NS16550_FLAG_IO) {
  128 + return inb(addr);
  129 + } else if (plat->reg_width == 4) {
  130 + if (plat->flags & NS16550_FLAG_ENDIAN) {
  131 + if (plat->flags & NS16550_FLAG_BE)
  132 + return in_be32(addr);
  133 + else
  134 + return in_le32(addr);
  135 + } else {
  136 + return readl(addr);
  137 + }
  138 + } else if (plat->flags & NS16550_FLAG_BE) {
  139 + return readb(addr + (1 << plat->reg_shift) - 1);
  140 + } else {
  141 + return readb(addr);
  142 + }
  143 +}
  144 +#else
  145 +static inline void serial_out_dynamic(struct ns16550_platdata *plat, u8 *addr,
  146 + int value)
  147 +{
  148 +}
  149 +
  150 +static inline int serial_in_dynamic(struct ns16550_platdata *plat, u8 *addr)
  151 +{
  152 + return 0;
  153 +}
  154 +
  155 +#endif /* CONFIG_NS16550_DYNAMIC */
  156 +
96 157 static void ns16550_writeb(NS16550_t port, int offset, int value)
97 158 {
98 159 struct ns16550_platdata *plat = port->plat;
99 160 unsigned char *addr;
100 161  
101 162 offset *= 1 << plat->reg_shift;
102   - addr = (unsigned char *)plat->base + offset;
  163 + addr = (unsigned char *)plat->base + offset + plat->reg_offset;
103 164  
104   - /*
105   - * As far as we know it doesn't make sense to support selection of
106   - * these options at run-time, so use the existing CONFIG options.
107   - */
108   - serial_out_shift(addr + plat->reg_offset, plat->reg_shift, value);
  165 + if (IS_ENABLED(CONFIG_NS16550_DYNAMIC))
  166 + serial_out_dynamic(plat, addr, value);
  167 + else
  168 + serial_out_shift(addr, plat->reg_shift, value);
109 169 }
110 170  
111 171 static int ns16550_readb(NS16550_t port, int offset)
112 172  
... ... @@ -114,9 +174,12 @@
114 174 unsigned char *addr;
115 175  
116 176 offset *= 1 << plat->reg_shift;
117   - addr = (unsigned char *)plat->base + offset;
  177 + addr = (unsigned char *)plat->base + offset + plat->reg_offset;
118 178  
119   - return serial_in_shift(addr + plat->reg_offset, plat->reg_shift);
  179 + if (IS_ENABLED(CONFIG_NS16550_DYNAMIC))
  180 + return serial_in_dynamic(plat, addr);
  181 + else
  182 + return serial_in_shift(addr, plat->reg_shift);
120 183 }
121 184  
122 185 static u32 ns16550_getfcr(NS16550_t port)
drivers/serial/serial_coreboot.c
  1 +// SPDX-License-Identifier: GPL-2.0+
  2 +/*
  3 + * UART support for U-Boot when launched from Coreboot
  4 + *
  5 + * Copyright 2019 Google LLC
  6 + */
  7 +
  8 +#include <common.h>
  9 +#include <dm.h>
  10 +#include <ns16550.h>
  11 +#include <serial.h>
  12 +#include <asm/arch/sysinfo.h>
  13 +
  14 +static int coreboot_ofdata_to_platdata(struct udevice *dev)
  15 +{
  16 + struct ns16550_platdata *plat = dev_get_platdata(dev);
  17 + struct cb_serial *cb_info = lib_sysinfo.serial;
  18 +
  19 + plat->base = cb_info->baseaddr;
  20 + plat->reg_shift = cb_info->regwidth == 4 ? 2 : 0;
  21 + plat->reg_width = cb_info->regwidth;
  22 + plat->clock = cb_info->input_hertz;
  23 + plat->fcr = UART_FCR_DEFVAL;
  24 + plat->flags = 0;
  25 + if (cb_info->type == CB_SERIAL_TYPE_IO_MAPPED)
  26 + plat->flags |= NS16550_FLAG_IO;
  27 +
  28 + return 0;
  29 +}
  30 +
  31 +static const struct udevice_id coreboot_serial_ids[] = {
  32 + { .compatible = "coreboot-serial" },
  33 + { },
  34 +};
  35 +
  36 +U_BOOT_DRIVER(coreboot_uart) = {
  37 + .name = "coreboot_uart",
  38 + .id = UCLASS_SERIAL,
  39 + .of_match = coreboot_serial_ids,
  40 + .priv_auto_alloc_size = sizeof(struct NS16550),
  41 + .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
  42 + .ofdata_to_platdata = coreboot_ofdata_to_platdata,
  43 + .probe = ns16550_serial_probe,
  44 + .ops = &ns16550_serial_ops,
  45 + .flags = DM_FLAG_PRE_RELOC,
  46 +};
... ... @@ -562,16 +562,8 @@
562 562 return 0; /* ignore */
563 563 case SPINOR_OP_BE_4K:
564 564 cycle = HSFSTS_CYCLE_4K_ERASE;
565   - while (len) {
566   - uint xfer_len = 0x1000;
567   -
568   - ret = exec_sync_hwseq_xfer(regs, cycle, offset, 0);
569   - if (ret)
570   - return ret;
571   - offset += xfer_len;
572   - len -= xfer_len;
573   - }
574   - return 0;
  565 + ret = exec_sync_hwseq_xfer(regs, cycle, offset, 0);
  566 + return ret;
575 567 default:
576 568 debug("Unknown cycle %x\n", op->cmd.opcode);
577 569 return -EINVAL;
include/configs/slimbootloader.h
... ... @@ -8,19 +8,6 @@
8 8  
9 9 #include <configs/x86-common.h>
10 10  
11   -/*
12   - * By default, CONFIG_SYS_NS16550_PORT_MAPPED is enabled for port io serial.
13   - * To use mmio base serial, enable CONFIG_SYS_NS16550_MEM32 and disable
14   - * CONFIG_SYS_NS16550_PORT_MAPPED until ns16550 driver supports serial port
15   - * configuration in run-time.
16   - *
17   - * #define CONFIG_SYS_NS16550_MEM32
18   - * #undef CONFIG_SYS_NS16550_PORT_MAPPED
19   - */
20   -#ifdef CONFIG_SYS_NS16550_MEM32
21   -#undef CONFIG_SYS_NS16550_PORT_MAPPED
22   -#endif
23   -
24 11 #define CONFIG_STD_DEVICES_SETTINGS \
25 12 "stdin=serial,i8042-kbd,usbkbd\0" \
26 13 "stdout=serial\0" \
... ... @@ -31,6 +31,9 @@
31 31 #define CONFIG_SYS_NS16550_REG_SIZE (-1)
32 32 #endif
33 33  
  34 +#ifdef CONFIG_NS16550_DYNAMIC
  35 +#define UART_REG(x) unsigned char x
  36 +#else
34 37 #if !defined(CONFIG_SYS_NS16550_REG_SIZE) || (CONFIG_SYS_NS16550_REG_SIZE == 0)
35 38 #error "Please define NS16550 registers size."
36 39 #elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_DM_SERIAL)
37 40  
38 41  
39 42  
40 43  
... ... @@ -44,14 +47,24 @@
44 47 unsigned char x; \
45 48 unsigned char postpad_##x[-CONFIG_SYS_NS16550_REG_SIZE - 1];
46 49 #endif
  50 +#endif /* CONFIG_NS16550_DYNAMIC */
47 51  
  52 +enum ns16550_flags {
  53 + NS16550_FLAG_IO = 1 << 0, /* Use I/O access (else mem-mapped) */
  54 + NS16550_FLAG_ENDIAN = 1 << 1, /* Use out_le/be_32() */
  55 + NS16550_FLAG_BE = 1 << 2, /* Big-endian access (else little) */
  56 +};
  57 +
48 58 /**
49 59 * struct ns16550_platdata - information about a NS16550 port
50 60 *
51 61 * @base: Base register address
52   - * @reg_width: IO accesses size of registers (in bytes)
  62 + * @reg_width: IO accesses size of registers (in bytes, 1 or 4)
53 63 * @reg_shift: Shift size of registers (0=byte, 1=16bit, 2=32bit...)
  64 + * @reg_offset: Offset to start of registers (normally 0)
54 65 * @clock: UART base clock speed in Hz
  66 + * @fcr: Offset of FCR register (normally UART_FCR_DEFVAL)
  67 + * @flags: A few flags (enum ns16550_flags)
55 68 * @bdf: PCI slot/function (pci_dev_t)
56 69 */
57 70 struct ns16550_platdata {
... ... @@ -61,6 +74,7 @@
61 74 int reg_offset;
62 75 int clock;
63 76 u32 fcr;
  77 + int flags;
64 78 #if defined(CONFIG_PCI) && defined(CONFIG_SPL)
65 79 int bdf;
66 80 #endif