blob: 4925b53bb54a711b3045c02ef16efc8cb57361db [file] [log] [blame]
Bari Ari612163e32009-05-27 13:12:42 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2009 One Laptop per Child, Association, Inc.
5 *
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; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Bari Ari612163e32009-05-27 13:12:42 +000014 */
15
16/*
17 part of this file is from cx700 port, part of is from cn700 port,
18 */
19
20#include <console/console.h>
21#include <arch/io.h>
22#include <stdint.h>
23#include <device/device.h>
24#include <device/pci.h>
25#include <device/pci_ids.h>
26#include <stdlib.h>
27#include <string.h>
Bari Ari612163e32009-05-27 13:12:42 +000028#include <cpu/cpu.h>
Bari Ari612163e32009-05-27 13:12:42 +000029#include "vx800.h"
30
Myles Watsonbd4f2f82009-07-02 21:19:33 +000031/* !!FIXME!! This was meant to be a CONFIG option */
32#define VIACONFIG_TOP_SM_SIZE_MB 32 // Set frame buffer 32M for default
33/* !!FIXME!! I declared this to fix the build. */
34u8 acpi_sleep_type = 0;
35
Bari Ari612163e32009-05-27 13:12:42 +000036static void memctrl_init(device_t dev)
37{
38/*
Uwe Hermann8341f442009-05-27 13:46:37 +000039 set VGA in uma_ram_setting.c, not in this function.
Bari Ari612163e32009-05-27 13:12:42 +000040*/
41#if 0
42 pci_write_config8(dev, 0x85, 0x20);
43 pci_write_config8(dev, 0x86, 0x2d);
44
45 /* Set up VGA timers */
46 pci_write_config8(dev, 0xa2, 0x44);
47
48 /* Enable VGA with a 32mb framebuffer */
49 pci_write_config16(dev, 0xa0, 0xd000);
50
51 pci_write_config16(dev, 0xa4, 0x0010);
52
53 //b0: 60 aa aa 5a 0f 00 00 00 08
54 pci_write_config16(dev, 0xb0, 0xaa00);
55 pci_write_config8(dev, 0xb8, 0x08);
56#endif
57}
58
59static const struct device_operations memctrl_operations = {
Edward O'Callaghand2040732014-10-31 08:26:21 +110060 .read_resources = DEVICE_NOOP,
Bari Ari612163e32009-05-27 13:12:42 +000061 .init = memctrl_init,
62};
63
64static const struct pci_driver memctrl_driver __pci_driver = {
65 .ops = &memctrl_operations,
66 .vendor = PCI_VENDOR_ID_VIA,
67 .device = PCI_DEVICE_ID_VIA_VX855_MEMCTRL,
68};
69
Bari Ari612163e32009-05-27 13:12:42 +000070static void pci_domain_set_resources(device_t dev)
71{
Stefan Reinauer14e22772010-04-27 06:56:47 +000072 /*
Bari Ari612163e32009-05-27 13:12:42 +000073 * the order is important to find the correct ram size.
74 */
75 u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
76 device_t mc_dev;
77 u32 pci_tolm;
78 u8 reg;
79
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000080 printk(BIOS_SPEW, "Entering vx800 pci_domain_set_resources.\n");
Bari Ari612163e32009-05-27 13:12:42 +000081
Myles Watson894a3472010-06-09 22:41:35 +000082 pci_tolm = find_pci_tolm(dev->link_list);
Bari Ari612163e32009-05-27 13:12:42 +000083 mc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
84 PCI_DEVICE_ID_VIA_VX855_MEMCTRL, 0);
85
86 if (mc_dev) {
87 unsigned long tomk, tolmk;
88 unsigned char rambits;
89 u8 i, idx;
90
91 /*
92 * once the register value is not zero, the ramsize is
93 * this register's value multiply 64 * 1024 * 1024
94 */
95 for (rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
Bari Ari612163e32009-05-27 13:12:42 +000096 rambits = pci_read_config8(mc_dev, ramregs[i]);
97 if (rambits != 0)
98 break;
99 }
100/*
101Get memory size and frame buffer from northbridge's registers.
102if register with invalid value we set frame buffer size to 32M for default, but it won't happen.
103*/
104 reg = pci_read_config8(mc_dev, 0xa1);
105 reg &= 0x70;
106 reg = reg >> 4;
107 /* TOP 1M SM Memory */
108 if (reg == 0x0)
109 tomk = (((rambits << 6) - 32 - VIACONFIG_TOP_SM_SIZE_MB) * 1024); // Set frame buffer 32M for default
110 else
111 tomk =
112 (((rambits << 6) - (4 << reg) -
113 VIACONFIG_TOP_SM_SIZE_MB) * 1024);
114
Myles Watson08e0fb82010-03-22 16:33:25 +0000115 printk(BIOS_SPEW, "tomk is 0x%lx\n", tomk);
Bari Ari612163e32009-05-27 13:12:42 +0000116 /* Compute the Top Of Low Memory, in Kb */
117 tolmk = pci_tolm >> 10;
118 if (tolmk >= tomk) {
119 /* The PCI hole does does not overlap the memory. */
120 tolmk = tomk;
121 }
122 /* Report the memory regions */
123 idx = 10;
124 /* TODO: Hole needed? */
125 ram_resource(dev, idx++, 0, 640); /* first 640k */
126 /* Leave a hole for vga, 0xa0000 - 0xc0000 */
127 ram_resource(dev, idx++, 768, (tolmk - 768));
128 }
Myles Watson894a3472010-06-09 22:41:35 +0000129 assign_resources(dev->link_list);
Bari Ari612163e32009-05-27 13:12:42 +0000130}
131
Stefan Reinauer56a684a2010-04-07 15:40:26 +0000132static struct device_operations pci_domain_ops = {
Bari Ari612163e32009-05-27 13:12:42 +0000133 .read_resources = pci_domain_read_resources,
134 .set_resources = pci_domain_set_resources,
Vladimir Serbinenko6c71a682014-09-02 00:15:02 +0200135#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
136 .write_acpi_tables = acpi_write_hpet,
137#endif
Myles Watson7eac4452010-06-17 16:16:56 +0000138 .enable_resources = NULL,
139 .init = NULL,
Bari Ari612163e32009-05-27 13:12:42 +0000140 .scan_bus = pci_domain_scan_bus,
Kyösti Mälkki33e5df32013-07-03 10:51:34 +0300141 .ops_pci_bus = pci_bus_default_ops,
Bari Ari612163e32009-05-27 13:12:42 +0000142};
143
144static void cpu_bus_init(device_t dev)
145{
Myles Watson894a3472010-06-09 22:41:35 +0000146 initialize_cpus(dev->link_list);
Bari Ari612163e32009-05-27 13:12:42 +0000147}
148
Stefan Reinauer56a684a2010-04-07 15:40:26 +0000149static struct device_operations cpu_bus_ops = {
Edward O'Callaghand2040732014-10-31 08:26:21 +1100150 .read_resources = DEVICE_NOOP,
151 .set_resources = DEVICE_NOOP,
152 .enable_resources = DEVICE_NOOP,
Bari Ari612163e32009-05-27 13:12:42 +0000153 .init = cpu_bus_init,
154 .scan_bus = 0,
155};
156
157static void enable_dev(struct device *dev)
158{
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000159 printk(BIOS_SPEW, "In VX800 enable_dev for device %s.\n", dev_path(dev));
Bari Ari612163e32009-05-27 13:12:42 +0000160
161 /* Set the operations if it is a special bus type */
Stefan Reinauer4aff4452013-02-12 14:17:15 -0800162 if (dev->path.type == DEVICE_PATH_DOMAIN) {
Bari Ari612163e32009-05-27 13:12:42 +0000163 dev->ops = &pci_domain_ops;
Stefan Reinauer0aa37c42013-02-12 15:20:54 -0800164 } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
Bari Ari612163e32009-05-27 13:12:42 +0000165 dev->ops = &cpu_bus_ops;
166 }
167}
168
169struct chip_operations northbridge_via_vx800_ops = {
170 CHIP_NAME("VIA VX800 Chipset")
171 .enable_dev = enable_dev,
172};