blob: 23e2ba378c3c18836a7ffaa579ec8a34e24281a7 [file] [log] [blame]
Marc Jones8ae8c882007-12-19 01:32:08 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Marc Jones8ae8c882007-12-19 01:32:08 +00003 *
Timothy Pearson82982a12015-01-23 20:26:31 -06004 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
Marc Jones8ae8c882007-12-19 01:32:08 +00005 * Copyright (C) 2007 Advanced Micro Devices, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Marc Jones8ae8c882007-12-19 01:32:08 +000015 */
16
Damien Zammit75a3d1f2016-11-28 00:29:10 +110017#include <inttypes.h>
18#include <console/console.h>
19#include <northbridge/amd/amdfam10/raminit.h>
20#include <northbridge/amd/amdfam10/amdfam10.h>
Marc Jones8ae8c882007-12-19 01:32:08 +000021
22#define RES_DEBUG 0
23
Damien Zammit75a3d1f2016-11-28 00:29:10 +110024void setup_resource_map(const u32 *register_values, u32 max)
Marc Jones8ae8c882007-12-19 01:32:08 +000025{
26 u32 i;
Marc Jones8ae8c882007-12-19 01:32:08 +000027
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +020028 for (i = 0; i < max; i += 3) {
Antonello Dettorif65ccb22016-09-03 10:45:33 +020029 pci_devfn_t dev;
Marc Jones8ae8c882007-12-19 01:32:08 +000030 u32 where;
31 u32 reg;
32
33 dev = register_values[i] & ~0xff;
34 where = register_values[i] & 0xff;
35 reg = pci_read_config32(dev, where);
36 reg &= register_values[i+1];
37 reg |= register_values[i+2];
38 pci_write_config32(dev, where, reg);
39 }
Marc Jones8ae8c882007-12-19 01:32:08 +000040}
41
42
Stefan Reinauer817d7542010-07-08 00:37:23 +000043void setup_resource_map_offset(const u32 *register_values, u32 max, u32 offset_pci_dev, u32 offset_io_base)
Marc Jones8ae8c882007-12-19 01:32:08 +000044{
45 u32 i;
Elyes HAOUASe0ee4c82016-10-04 20:58:03 +020046
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +020047 for (i = 0; i < max; i += 3) {
Antonello Dettorif65ccb22016-09-03 10:45:33 +020048 pci_devfn_t dev;
Marc Jones8ae8c882007-12-19 01:32:08 +000049 u32 where;
50 unsigned long reg;
51 dev = (register_values[i] & ~0xfff) + offset_pci_dev;
52 where = register_values[i] & 0xfff;
53 reg = pci_read_config32(dev, where);
54 reg &= register_values[i+1];
55 reg |= register_values[i+2] + offset_io_base;
56 pci_write_config32(dev, where, reg);
57 }
Marc Jones8ae8c882007-12-19 01:32:08 +000058}
59
Stefan Reinauer817d7542010-07-08 00:37:23 +000060void setup_resource_map_x_offset(const u32 *register_values, u32 max, u32 offset_pci_dev, u32 offset_io_base)
Marc Jones8ae8c882007-12-19 01:32:08 +000061{
62 u32 i;
63
Timothy Pearson82982a12015-01-23 20:26:31 -060064 if (IS_ENABLED(RES_DEBUG))
65 printk(BIOS_DEBUG, "setting up resource map ex offset....\n");
Marc Jones8ae8c882007-12-19 01:32:08 +000066
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +020067 for (i = 0; i < max; i += 4) {
Timothy Pearson82982a12015-01-23 20:26:31 -060068 if (IS_ENABLED(RES_DEBUG))
69 printk(BIOS_DEBUG, "%04x: %02x %08x <- & %08x | %08x\n",
70 i/4, register_values[i],
Elyes HAOUAS04f8fd92016-09-19 10:24:34 -060071 register_values[i+1] + ((register_values[i]==RES_PCI_IO) ? offset_pci_dev : 0),
Timothy Pearson82982a12015-01-23 20:26:31 -060072 register_values[i+2],
Elyes HAOUAS04f8fd92016-09-19 10:24:34 -060073 register_values[i+3] + (((register_values[i] & RES_PORT_IO_32) == RES_PORT_IO_32) ? offset_io_base : 0)
Timothy Pearson82982a12015-01-23 20:26:31 -060074 );
Marc Jones8ae8c882007-12-19 01:32:08 +000075 switch (register_values[i]) {
76 case RES_PCI_IO: //PCI
77 {
Antonello Dettorif65ccb22016-09-03 10:45:33 +020078 pci_devfn_t dev;
Marc Jones8ae8c882007-12-19 01:32:08 +000079 u32 where;
80 u32 reg;
81 dev = (register_values[i+1] & ~0xfff) + offset_pci_dev;
82 where = register_values[i+1] & 0xfff;
83 reg = pci_read_config32(dev, where);
Timothy Pearson82982a12015-01-23 20:26:31 -060084 if (IS_ENABLED(RES_DEBUG))
85 printk(BIOS_SPEW, "WAS: %08x\n", reg);
Marc Jones8ae8c882007-12-19 01:32:08 +000086 reg &= register_values[i+2];
87 reg |= register_values[i+3];
88 pci_write_config32(dev, where, reg);
Timothy Pearson82982a12015-01-23 20:26:31 -060089 if (IS_ENABLED(RES_DEBUG))
90 printk(BIOS_SPEW, "NOW: %08x\n", reg);
Marc Jones8ae8c882007-12-19 01:32:08 +000091 }
92 break;
93 case RES_PORT_IO_8: // io 8
94 {
95 u32 where;
96 u32 reg;
97 where = register_values[i+1] + offset_io_base;
98 reg = inb(where);
Timothy Pearson82982a12015-01-23 20:26:31 -060099 if (IS_ENABLED(RES_DEBUG))
100 printk(BIOS_SPEW, "WAS: %08x\n", reg);
Marc Jones8ae8c882007-12-19 01:32:08 +0000101 reg &= register_values[i+2];
102 reg |= register_values[i+3];
103 outb(reg, where);
Timothy Pearson82982a12015-01-23 20:26:31 -0600104 if (IS_ENABLED(RES_DEBUG))
105 printk(BIOS_SPEW, "NOW: %08x\n", reg);
Marc Jones8ae8c882007-12-19 01:32:08 +0000106 }
107 break;
108 case RES_PORT_IO_32: //io32
109 {
110 u32 where;
111 u32 reg;
112 where = register_values[i+1] + offset_io_base;
113 reg = inl(where);
Timothy Pearson82982a12015-01-23 20:26:31 -0600114 if (IS_ENABLED(RES_DEBUG))
115 printk(BIOS_SPEW, "WAS: %08x\n", reg);
Marc Jones8ae8c882007-12-19 01:32:08 +0000116 reg &= register_values[i+2];
117 reg |= register_values[i+3];
118 outl(reg, where);
Timothy Pearson82982a12015-01-23 20:26:31 -0600119 if (IS_ENABLED(RES_DEBUG))
120 printk(BIOS_SPEW, "NOW: %08x\n", reg);
Marc Jones8ae8c882007-12-19 01:32:08 +0000121 }
122 break;
Elyes HAOUASe0ee4c82016-10-04 20:58:03 +0200123 }
Marc Jones8ae8c882007-12-19 01:32:08 +0000124 }
125
Timothy Pearson82982a12015-01-23 20:26:31 -0600126 if (IS_ENABLED(RES_DEBUG))
127 printk(BIOS_DEBUG, "done.\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000128}
Stefan Reinauer817d7542010-07-08 00:37:23 +0000129
130void setup_resource_map_x(const u32 *register_values, u32 max)
Marc Jones8ae8c882007-12-19 01:32:08 +0000131{
132 u32 i;
133
Timothy Pearson82982a12015-01-23 20:26:31 -0600134 if (IS_ENABLED(RES_DEBUG))
135 printk(BIOS_DEBUG, "setting up resource map ex offset....\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000136
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200137 for (i = 0; i < max; i += 4) {
Timothy Pearson82982a12015-01-23 20:26:31 -0600138 if (IS_ENABLED(RES_DEBUG))
139 printk(BIOS_DEBUG, "%04x: %02x %08x <- & %08x | %08x\n",
140 i/4, register_values[i],register_values[i+1], register_values[i+2], register_values[i+3]);
Marc Jones8ae8c882007-12-19 01:32:08 +0000141 switch (register_values[i]) {
142 case RES_PCI_IO: //PCI
143 {
Antonello Dettorif65ccb22016-09-03 10:45:33 +0200144 pci_devfn_t dev;
Marc Jones8ae8c882007-12-19 01:32:08 +0000145 u32 where;
146 u32 reg;
147 dev = register_values[i+1] & ~0xff;
148 where = register_values[i+1] & 0xff;
149 reg = pci_read_config32(dev, where);
150 reg &= register_values[i+2];
151 reg |= register_values[i+3];
152 pci_write_config32(dev, where, reg);
153 }
154 break;
155 case RES_PORT_IO_8: // io 8
156 {
157 u32 where;
158 u32 reg;
159 where = register_values[i+1];
160 reg = inb(where);
161 reg &= register_values[i+2];
162 reg |= register_values[i+3];
163 outb(reg, where);
164 }
165 break;
166 case RES_PORT_IO_32: //io32
167 {
168 u32 where;
169 u32 reg;
170 where = register_values[i+1];
171 reg = inl(where);
172 reg &= register_values[i+2];
173 reg |= register_values[i+3];
174 outl(reg, where);
175 }
176 break;
Elyes HAOUASe0ee4c82016-10-04 20:58:03 +0200177 }
Marc Jones8ae8c882007-12-19 01:32:08 +0000178 }
179
Timothy Pearson82982a12015-01-23 20:26:31 -0600180 if (IS_ENABLED(RES_DEBUG))
181 printk(BIOS_DEBUG, "done.\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000182}