blob: c70ffdb0609a762234de41cb6e756771d22460ef [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Frank Vibrans63e62b02011-02-14 18:38:14 +00002
Kerry Shefeed3292011-08-18 18:03:44 +08003#include <console/console.h>
Frank Vibrans63e62b02011-02-14 18:38:14 +00004#include <device/pci.h>
Martin Roth3aef7b42012-12-05 15:50:32 -07005#include <device/pci_def.h>
Patrick Georgi2c2e78d2012-02-16 18:54:37 +01006#include <arch/ioapic.h>
Frank Vibrans63e62b02011-02-14 18:38:14 +00007#include "lpc.h"
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02008#include <device/pci_ops.h>
Frank Vibrans63e62b02011-02-14 18:38:14 +00009
Elyes HAOUAS1a4abb72018-05-19 16:49:20 +020010void lpc_read_resources(struct device *dev)
Frank Vibrans63e62b02011-02-14 18:38:14 +000011{
12 struct resource *res;
13
Elyes HAOUASbfc255a2020-03-07 13:05:14 +010014 printk(BIOS_DEBUG, "SB800 - Lpc.c - %s - Start.\n", __func__);
Frank Vibrans63e62b02011-02-14 18:38:14 +000015 /* Get the normal pci resources of this device */
16 pci_dev_read_resources(dev); /* We got one for APIC, or one more for TRAP */
17
Frank Vibrans63e62b02011-02-14 18:38:14 +000018 /* Add an extra subtractive resource for both memory and I/O. */
19 res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
20 res->base = 0;
21 res->size = 0x1000;
22 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
23 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
24
25 res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
26 res->base = 0xff800000;
27 res->size = 0x00800000; /* 8 MB for flash */
28 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
29 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
30
Dave Frodinac1b8752014-06-05 14:30:22 -060031 /* Add a memory resource for the SPI BAR. */
Kyösti Mälkki27d62992022-05-24 20:25:58 +030032 fixed_mem_resource_kb(dev, 2, SPI_BASE_ADDRESS / 1024, 1, IORESOURCE_SUBTRACTIVE);
Dave Frodinac1b8752014-06-05 14:30:22 -060033
Patrick Georgi2c2e78d2012-02-16 18:54:37 +010034 res = new_resource(dev, 3);
35 res->base = IO_APIC_ADDR;
Frank Vibrans63e62b02011-02-14 18:38:14 +000036 res->size = 0x00001000;
37 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
38
39 compact_resources(dev);
Elyes HAOUASbfc255a2020-03-07 13:05:14 +010040 printk(BIOS_DEBUG, "SB800 - Lpc.c - %s - End.\n", __func__);
Frank Vibrans63e62b02011-02-14 18:38:14 +000041}
42
43void lpc_set_resources(struct device *dev)
44{
45 struct resource *res;
46
Elyes HAOUASbfc255a2020-03-07 13:05:14 +010047 printk(BIOS_DEBUG, "SB800 - Lpc.c - %s - Start.\n", __func__);
Martin Roth3aef7b42012-12-05 15:50:32 -070048
49 /* Special case. SPI Base Address. The SpiRomEnable should STAY set. */
Dave Frodinac1b8752014-06-05 14:30:22 -060050 res = find_resource(dev, 2);
51 pci_write_config32(dev, SPIROM_BASE_ADDRESS_REGISTER, res->base | SPI_ROM_ENABLE);
Martin Roth3aef7b42012-12-05 15:50:32 -070052
Frank Vibrans63e62b02011-02-14 18:38:14 +000053 pci_dev_set_resources(dev);
54
Elyes HAOUASbfc255a2020-03-07 13:05:14 +010055 printk(BIOS_DEBUG, "SB800 - Lpc.c - %s - End.\n", __func__);
Frank Vibrans63e62b02011-02-14 18:38:14 +000056}
57
58/**
59 * @brief Enable resources for children devices
60 *
Martin Roth3c3a50c2014-12-16 20:50:26 -070061 * @param dev the device whose children's resources are to be enabled
Frank Vibrans63e62b02011-02-14 18:38:14 +000062 *
63 */
Elyes HAOUAS1a4abb72018-05-19 16:49:20 +020064void lpc_enable_childrens_resources(struct device *dev)
Frank Vibrans63e62b02011-02-14 18:38:14 +000065{
66 struct bus *link;
67 u32 reg, reg_x;
68 int var_num = 0;
69 u16 reg_var[3];
70
Elyes HAOUASbfc255a2020-03-07 13:05:14 +010071 printk(BIOS_DEBUG, "SB800 - Lpc.c - %s - Start.\n", __func__);
Frank Vibrans63e62b02011-02-14 18:38:14 +000072 reg = pci_read_config32(dev, 0x44);
73 reg_x = pci_read_config32(dev, 0x48);
74
75 for (link = dev->link_list; link; link = link->next) {
Elyes HAOUAS1a4abb72018-05-19 16:49:20 +020076 struct device *child;
Frank Vibrans63e62b02011-02-14 18:38:14 +000077 for (child = link->children; child;
78 child = child->sibling) {
79 if (child->enabled
80 && (child->path.type == DEVICE_PATH_PNP)) {
81 struct resource *res;
82 for (res = child->resource_list; res; res = res->next) {
Paul Menzel621abec2017-09-09 11:26:24 +020083 u32 base; /* don't need long long */
Frank Vibrans63e62b02011-02-14 18:38:14 +000084 if (!(res->flags & IORESOURCE_IO))
85 continue;
86 base = res->base;
Frank Vibrans63e62b02011-02-14 18:38:14 +000087/*
Paul Menzel482f8222017-09-09 11:05:21 +020088 printk(BIOS_DEBUG, "sb800 lpc decode:%s,
89 base=0x%08x, end=0x%08x\n",
Paul Menzel621abec2017-09-09 11:26:24 +020090 dev_path(child), base,
91 resource_end(res));
Frank Vibrans63e62b02011-02-14 18:38:14 +000092*/
93 switch (base) {
94 case 0x60: /* KB */
95 case 0x64: /* MS */
96 reg |= (1 << 29);
97 break;
98 case 0x3f8: /* COM1 */
99 reg |= (1 << 6);
100 break;
101 case 0x2f8: /* COM2 */
102 reg |= (1 << 7);
103 break;
Martin Roth3c3a50c2014-12-16 20:50:26 -0700104 case 0x378: /* Parallel 1 */
Frank Vibrans63e62b02011-02-14 18:38:14 +0000105 reg |= (1 << 0);
106 break;
107 case 0x3f0: /* FD0 */
108 reg |= (1 << 26);
109 break;
Martin Roth3c3a50c2014-12-16 20:50:26 -0700110 case 0x220: /* Audio 0 */
Frank Vibrans63e62b02011-02-14 18:38:14 +0000111 reg |= (1 << 8);
112 break;
113 case 0x300: /* Midi 0 */
114 reg |= (1 << 18);
115 break;
116 case 0x400:
117 reg_x |= (1 << 16);
118 break;
119 case 0x480:
120 reg_x |= (1 << 17);
121 break;
122 case 0x500:
123 reg_x |= (1 << 18);
124 break;
125 case 0x580:
126 reg_x |= (1 << 19);
127 break;
128 case 0x4700:
129 reg_x |= (1 << 22);
130 break;
131 case 0xfd60:
132 reg_x |= (1 << 23);
133 break;
134 default:
135 if (var_num >= 3)
136 continue; /* only 3 var ; compact them ? */
137 switch (var_num) {
138 case 0:
139 reg_x |= (1 << 2);
140 break;
141 case 1:
142 reg_x |= (1 << 24);
143 break;
144 case 2:
145 reg_x |= (1 << 25);
146 break;
147 }
148 reg_var[var_num++] =
149 base & 0xffff;
150 }
151 }
152 }
153 }
154 }
155 pci_write_config32(dev, 0x44, reg);
156 pci_write_config32(dev, 0x48, reg_x);
157 /* Set WideIO for as many IOs found (fall through is on purpose) */
158 switch (var_num) {
Jacob Garbera9bf88b2019-06-25 12:46:35 -0600159 case 3:
Frank Vibrans63e62b02011-02-14 18:38:14 +0000160 pci_write_config16(dev, 0x90, reg_var[2]);
Arthur Heymansfff20212021-03-15 14:56:16 +0100161 __fallthrough;
Jacob Garbera9bf88b2019-06-25 12:46:35 -0600162 case 2:
Frank Vibrans63e62b02011-02-14 18:38:14 +0000163 pci_write_config16(dev, 0x66, reg_var[1]);
Arthur Heymansfff20212021-03-15 14:56:16 +0100164 __fallthrough;
Jacob Garbera9bf88b2019-06-25 12:46:35 -0600165 case 1:
Frank Vibrans63e62b02011-02-14 18:38:14 +0000166 //pci_write_config16(dev, 0x64, reg_var[0]); //cause filo can not find sata
167 break;
168 }
Elyes HAOUASbfc255a2020-03-07 13:05:14 +0100169 printk(BIOS_DEBUG, "SB800 - Lpc.c - %s - End.\n", __func__);
Frank Vibrans63e62b02011-02-14 18:38:14 +0000170}