blob: 5f196d5c515d319c30aca7e5afb0ec826e81f6cd [file] [log] [blame]
Joseph Smith6a1dc862008-03-09 13:24:46 +00001/*
2 * This file is part of the coreboot project.
3 *
Joseph Smith0d7a9962010-03-17 03:18:29 +00004 * Copyright (C) 2008-2010 Joseph Smith <joe@settoplinux.org>
Joseph Smith6a1dc862008-03-09 13:24:46 +00005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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.
Joseph Smith6a1dc862008-03-09 13:24:46 +000015 */
16
17#include <console/console.h>
18#include <arch/io.h>
19#include <stdint.h>
20#include <device/device.h>
21#include <device/pci.h>
22#include <device/pci_ids.h>
Stefan Reinauerfd611f92013-02-27 23:45:20 +010023#include <cbmem.h>
Stefan Reinauerbe7f7982009-03-13 15:42:27 +000024#include <cpu/cpu.h>
Joseph Smith6a1dc862008-03-09 13:24:46 +000025#include <stdlib.h>
26#include <string.h>
Joseph Smith6a1dc862008-03-09 13:24:46 +000027#include "i82830.h"
28
29static void northbridge_init(device_t dev)
30{
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000031 printk(BIOS_SPEW, "Northbridge init\n");
Joseph Smith6a1dc862008-03-09 13:24:46 +000032}
33
34static struct device_operations northbridge_operations = {
35 .read_resources = pci_dev_read_resources,
36 .set_resources = pci_dev_set_resources,
37 .enable_resources = pci_dev_enable_resources,
38 .init = northbridge_init,
39 .enable = 0,
40 .ops_pci = 0,
41};
42
Stefan Reinauer63630502010-02-22 09:28:15 +000043static const struct pci_driver northbridge_driver __pci_driver = {
Joseph Smith6a1dc862008-03-09 13:24:46 +000044 .ops = &northbridge_operations,
45 .vendor = PCI_VENDOR_ID_INTEL,
46 .device = 0x3575,
47};
48
Joseph Smith6a1dc862008-03-09 13:24:46 +000049static void pci_domain_set_resources(device_t dev)
50{
51 device_t mc_dev;
Joseph Smith6a1dc862008-03-09 13:24:46 +000052 int igd_memory = 0;
Kyösti Mälkkif7bfc342013-10-18 11:02:46 +030053 uint64_t uma_memory_base = 0, uma_memory_size = 0;
Joseph Smith6a1dc862008-03-09 13:24:46 +000054
Myles Watson894a3472010-06-09 22:41:35 +000055 mc_dev = dev->link_list->children;
Stefan Reinauer1abf46c2010-04-13 21:31:42 +000056 if (!mc_dev)
57 return;
Joseph Smith6a1dc862008-03-09 13:24:46 +000058
Kyösti Mälkki6ff1d362012-07-27 08:42:20 +030059 unsigned long tomk, tomk_stolen;
Stefan Reinauer1abf46c2010-04-13 21:31:42 +000060 int idx;
Joseph Smith6a1dc862008-03-09 13:24:46 +000061
Stefan Reinauer1abf46c2010-04-13 21:31:42 +000062 if (CONFIG_VIDEO_MB == 512) {
63 igd_memory = (CONFIG_VIDEO_MB);
64 printk(BIOS_DEBUG, "%dKB IGD UMA\n", igd_memory >> 10);
65 } else {
66 igd_memory = (CONFIG_VIDEO_MB * 1024);
67 printk(BIOS_DEBUG, "%dMB IGD UMA\n", igd_memory >> 10);
68 }
Joseph Smith0d7a9962010-03-17 03:18:29 +000069
Stefan Reinauer1abf46c2010-04-13 21:31:42 +000070 /* Get the value of the highest DRB. This tells the end of
71 * the physical memory. The units are ticks of 32MB
72 * i.e. 1 means 32MB.
73 */
74 tomk = ((unsigned long)pci_read_config8(mc_dev, DRB + 3)) << 15;
Kyösti Mälkki6ff1d362012-07-27 08:42:20 +030075 tomk_stolen = tomk - igd_memory;
Joseph Smith6a1dc862008-03-09 13:24:46 +000076
Stefan Reinauer1abf46c2010-04-13 21:31:42 +000077 /* For reserving UMA memory in the memory map */
Kyösti Mälkki6ff1d362012-07-27 08:42:20 +030078 uma_memory_base = tomk_stolen * 1024ULL;
Stefan Reinauer1abf46c2010-04-13 21:31:42 +000079 uma_memory_size = igd_memory * 1024ULL;
Kyösti Mälkki6ff1d362012-07-27 08:42:20 +030080 printk(BIOS_DEBUG, "Available memory: %ldKB\n", tomk_stolen);
Joseph Smith6a1dc862008-03-09 13:24:46 +000081
Stefan Reinauer1abf46c2010-04-13 21:31:42 +000082 /* Report the memory regions. */
83 idx = 10;
84 ram_resource(dev, idx++, 0, 640);
Kyösti Mälkki6ff1d362012-07-27 08:42:20 +030085 ram_resource(dev, idx++, 768, tomk - 768);
86 uma_resource(dev, idx++, uma_memory_base >> 10, uma_memory_size >> 10);
Stefan Reinauer1abf46c2010-04-13 21:31:42 +000087
Myles Watson894a3472010-06-09 22:41:35 +000088 assign_resources(dev->link_list);
Stefan Reinauerb5fb0c52009-04-30 13:58:42 +000089
Kyösti Mälkki42f46512013-06-27 08:20:09 +030090 set_top_of_ram(tomk_stolen * 1024);
Joseph Smith6a1dc862008-03-09 13:24:46 +000091}
92
Joseph Smith6a1dc862008-03-09 13:24:46 +000093static struct device_operations pci_domain_ops = {
94 .read_resources = pci_domain_read_resources,
95 .set_resources = pci_domain_set_resources,
Myles Watson7eac4452010-06-17 16:16:56 +000096 .enable_resources = NULL,
97 .init = NULL,
Joseph Smith6a1dc862008-03-09 13:24:46 +000098 .scan_bus = pci_domain_scan_bus,
Kyösti Mälkki33e5df32013-07-03 10:51:34 +030099 .ops_pci_bus = pci_bus_default_ops,
Joseph Smith6a1dc862008-03-09 13:24:46 +0000100};
101
102static void cpu_bus_init(device_t dev)
103{
Myles Watson894a3472010-06-09 22:41:35 +0000104 initialize_cpus(dev->link_list);
Joseph Smith6a1dc862008-03-09 13:24:46 +0000105}
106
Joseph Smith6a1dc862008-03-09 13:24:46 +0000107static struct device_operations cpu_bus_ops = {
Edward O'Callaghan9f744622014-10-31 08:12:34 +1100108 .read_resources = DEVICE_NOOP,
109 .set_resources = DEVICE_NOOP,
110 .enable_resources = DEVICE_NOOP,
Joseph Smith6a1dc862008-03-09 13:24:46 +0000111 .init = cpu_bus_init,
112 .scan_bus = 0,
113};
114
115static void enable_dev(struct device *dev)
116{
117 struct device_path;
118
119 /* Set the operations if it is a special bus type. */
Stefan Reinauer4aff4452013-02-12 14:17:15 -0800120 if (dev->path.type == DEVICE_PATH_DOMAIN) {
Joseph Smith6a1dc862008-03-09 13:24:46 +0000121 dev->ops = &pci_domain_ops;
Stefan Reinauer0aa37c42013-02-12 15:20:54 -0800122 } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
Joseph Smith6a1dc862008-03-09 13:24:46 +0000123 dev->ops = &cpu_bus_ops;
124 }
125}
126
127struct chip_operations northbridge_intel_i82830_ops = {
128 CHIP_NAME("Intel 82830 Northbridge")
129 .enable_dev = enable_dev,
130};