blob: 6d351a311728edf57daeda45a9fd4cd2ab58e4b9 [file] [log] [blame]
Martin Roth5474eb12018-05-26 19:22:33 -06001/*
2 * This file is part of the coreboot project.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Stefan Reinauerb15975b2011-10-21 12:57:59 -070014#include <console/console.h>
15#include <arch/io.h>
16#include <stdint.h>
17#include <device/device.h>
18#include <device/pci.h>
19#include <cpu/cpu.h>
20#include <stdlib.h>
21#include <string.h>
Kyösti Mälkki0a0d5e82011-10-31 14:18:33 +020022#include "e7505.h"
Stefan Reinauerb15975b2011-10-21 12:57:59 -070023#include <cbmem.h>
Vladimir Serbinenkoc7310d92014-09-01 09:45:05 +020024#include <arch/acpi.h>
25
26unsigned long acpi_fill_mcfg(unsigned long current)
27{
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020028 /* Just a dummy */
29 return current;
Vladimir Serbinenkoc7310d92014-09-01 09:45:05 +020030}
Stefan Reinauerb15975b2011-10-21 12:57:59 -070031
Kyösti Mälkki9e69c872018-06-02 15:35:27 +030032static void mch_domain_read_resources(struct device *dev)
Stefan Reinauerb15975b2011-10-21 12:57:59 -070033{
Kyösti Mälkki717b6e32018-05-17 14:16:03 +030034 int idx;
35 unsigned long tomk, tolmk;
36 unsigned long remapbasek, remaplimitk;
37 const unsigned long basek_4G = 4 * (GiB / KiB);
Elyes HAOUAS97e8b752018-05-09 17:39:47 +020038 struct device *mc_dev;
Stefan Reinauerb15975b2011-10-21 12:57:59 -070039
Kyösti Mälkki9e69c872018-06-02 15:35:27 +030040 pci_domain_read_resources(dev);
41
Kyösti Mälkki717b6e32018-05-17 14:16:03 +030042 mc_dev = dev_find_slot(0, PCI_DEVFN(0x0, 0));
43 if (!mc_dev)
44 die("Could not find MCH device\n");
Stefan Reinauerb15975b2011-10-21 12:57:59 -070045
Kyösti Mälkki717b6e32018-05-17 14:16:03 +030046 tolmk = pci_read_config16(mc_dev, TOLM) >> 11;
47 tolmk <<= 17;
Stefan Reinauerb15975b2011-10-21 12:57:59 -070048
Kyösti Mälkki717b6e32018-05-17 14:16:03 +030049 tomk = pci_read_config8(mc_dev, DRB_ROW_7);
50 tomk <<= 16;
Stefan Reinauerb15975b2011-10-21 12:57:59 -070051
Kyösti Mälkki717b6e32018-05-17 14:16:03 +030052 /* Remapped region with a 64 MiB granularity in register
53 definition. Limit is inclusive, so add one. */
54 remapbasek = pci_read_config16(mc_dev, REMAPBASE) & 0x3ff;
55 remapbasek <<= 16;
Stefan Reinauerb15975b2011-10-21 12:57:59 -070056
Kyösti Mälkki717b6e32018-05-17 14:16:03 +030057 remaplimitk = pci_read_config16(mc_dev, REMAPLIMIT) & 0x3ff;
58 remaplimitk += 1;
59 remaplimitk <<= 16;
Stefan Reinauerb15975b2011-10-21 12:57:59 -070060
Kyösti Mälkki717b6e32018-05-17 14:16:03 +030061 /* Report the memory regions */
62 idx = 10;
63 ram_resource(dev, idx++, 0, 640);
64 ram_resource(dev, idx++, 768, tolmk - 768);
65
66 if (tomk > basek_4G)
67 ram_resource(dev, idx++, basek_4G, tomk - basek_4G);
68
69 if (remaplimitk > remapbasek)
70 ram_resource(dev, idx++, remapbasek, remaplimitk - remapbasek);
Kyösti Mälkki9e69c872018-06-02 15:35:27 +030071}
72
73static void mch_domain_set_resources(struct device *dev)
74{
Stefan Reinauerb15975b2011-10-21 12:57:59 -070075 assign_resources(dev->link_list);
76}
77
Elyes HAOUAS97e8b752018-05-09 17:39:47 +020078static void intel_set_subsystem(struct device *dev,
79 unsigned vendor, unsigned device)
Kyösti Mälkki0a0d5e82011-10-31 14:18:33 +020080{
81 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
82 ((device & 0xffff) << 16) | (vendor & 0xffff));
83}
84
85static struct pci_operations intel_pci_ops = {
86 .set_subsystem = intel_set_subsystem,
87};
88
Stefan Reinauerb15975b2011-10-21 12:57:59 -070089static struct device_operations pci_domain_ops = {
Kyösti Mälkki9e69c872018-06-02 15:35:27 +030090 .read_resources = mch_domain_read_resources,
91 .set_resources = mch_domain_set_resources,
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020092 .enable_resources = NULL,
93 .init = NULL,
94 .scan_bus = pci_domain_scan_bus,
Kyösti Mälkki0a0d5e82011-10-31 14:18:33 +020095 .ops_pci = &intel_pci_ops,
Stefan Reinauerb15975b2011-10-21 12:57:59 -070096};
97
Elyes HAOUAS97e8b752018-05-09 17:39:47 +020098static void cpu_bus_init(struct device *dev)
Stefan Reinauerb15975b2011-10-21 12:57:59 -070099{
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +0200100 initialize_cpus(dev->link_list);
Stefan Reinauerb15975b2011-10-21 12:57:59 -0700101}
102
Stefan Reinauerb15975b2011-10-21 12:57:59 -0700103static struct device_operations cpu_bus_ops = {
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +0200104 .read_resources = DEVICE_NOOP,
105 .set_resources = DEVICE_NOOP,
106 .enable_resources = DEVICE_NOOP,
107 .init = cpu_bus_init,
108 .scan_bus = 0,
Stefan Reinauerb15975b2011-10-21 12:57:59 -0700109};
110
111static void enable_dev(struct device *dev)
112{
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +0200113 /* Set the operations if it is a special bus type */
114 if (dev->path.type == DEVICE_PATH_DOMAIN) {
115 dev->ops = &pci_domain_ops;
116 }
117 else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
118 dev->ops = &cpu_bus_ops;
119 }
Stefan Reinauerb15975b2011-10-21 12:57:59 -0700120}
121
Kyösti Mälkki0a0d5e82011-10-31 14:18:33 +0200122struct chip_operations northbridge_intel_e7505_ops = {
123 CHIP_NAME("Intel E7505 Northbridge")
Stefan Reinauerb15975b2011-10-21 12:57:59 -0700124 .enable_dev = enable_dev,
125};