vx900: Move to EARLY_CBMEM_INIT
To calculate the CBMEM address we need to determine the framebuffer size early in the ROMSTAGE. We now do the calculation before cbmem_recovery() and configure the memory controller right away. If the calculation was done from cbmem_top() instead, we'd loose some logging that seems useful, since printk() would recurse to cbmem_top() too with CONSOLE_CBMEM enabled. If we didn't configure the memory controller at this point, we'd need to store the result somewhere else. However, CAR_GLOBAL is not practical at this point, because calling car_get_var() from cbmem_top() would recurse back to cbmem_top(). Change-Id: Ib9ae0f97f9f769a20a610f8d76f14165fb924042 Signed-off-by: Lubomir Rintel <lkundrak@v3.sk> Reviewed-on: https://review.coreboot.org/25798 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
This commit is contained in:
parent
faafbfb81e
commit
d8ec973fd2
|
@ -80,7 +80,7 @@ void main(unsigned long bist)
|
||||||
ram_check((1 << 24), 0x80);
|
ram_check((1 << 24), 0x80);
|
||||||
ram_check((512 + 256 - 1) << 20, 0x80);
|
ram_check((512 + 256 - 1) << 20, 0x80);
|
||||||
ram_check(0x80c0000, 0x80);
|
ram_check(0x80c0000, 0x80);
|
||||||
tolm = ((pci_read_config16(MCU, 0x84) & 0xfff0) >> 4) << 20;
|
tolm = vx900_get_tolm () << 20;
|
||||||
if (tolm > (1 * (u32) GiB))
|
if (tolm > (1 * (u32) GiB))
|
||||||
ram_check(1024 << 10, 0x80);
|
ram_check(1024 << 10, 0x80);
|
||||||
if (tolm > (2 * (u32) GiB))
|
if (tolm > (2 * (u32) GiB))
|
||||||
|
@ -88,10 +88,13 @@ void main(unsigned long bist)
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "We passed RAM verify\n");
|
printk(BIOS_DEBUG, "We passed RAM verify\n");
|
||||||
|
|
||||||
|
/* FIXME: read fb_size from CMOS, but until that is implemented, start
|
||||||
|
* from 512MB */
|
||||||
|
vx900_set_chrome9hd_fb_size (512);
|
||||||
|
|
||||||
/* We got RAM working, now we can write the timestamps to RAM */
|
/* We got RAM working, now we can write the timestamps to RAM */
|
||||||
#if IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)
|
|
||||||
cbmem_recovery(0);
|
cbmem_recovery(0);
|
||||||
#endif
|
|
||||||
/* FIXME: See if this is needed or take this out please */
|
/* FIXME: See if this is needed or take this out please */
|
||||||
/* Disable Memcard and SDIO */
|
/* Disable Memcard and SDIO */
|
||||||
pci_mod_config8(LPC, 0x51, 0, (1 << 7) | (1 << 4));
|
pci_mod_config8(LPC, 0x51, 0, (1 << 7) | (1 << 4));
|
||||||
|
|
|
@ -21,7 +21,6 @@ config NORTHBRIDGE_VIA_VX900
|
||||||
select HAVE_DEBUG_RAM_SETUP
|
select HAVE_DEBUG_RAM_SETUP
|
||||||
select HAVE_DEBUG_SMBUS
|
select HAVE_DEBUG_SMBUS
|
||||||
select HAVE_HARD_RESET
|
select HAVE_HARD_RESET
|
||||||
select LATE_CBMEM_INIT
|
|
||||||
|
|
||||||
if NORTHBRIDGE_VIA_VX900
|
if NORTHBRIDGE_VIA_VX900
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ romstage-y += early_smbus.c
|
||||||
romstage-y += early_vx900.c
|
romstage-y += early_vx900.c
|
||||||
romstage-y += early_host_bus_ctl.c
|
romstage-y += early_host_bus_ctl.c
|
||||||
romstage-y += raminit_ddr3.c
|
romstage-y += raminit_ddr3.c
|
||||||
|
romstage-y += memmap.c
|
||||||
romstage-y += ./../../../device/dram/ddr3.c
|
romstage-y += ./../../../device/dram/ddr3.c
|
||||||
romstage-y += ./../../../southbridge/via/common/early_smbus_delay.c
|
romstage-y += ./../../../southbridge/via/common/early_smbus_delay.c
|
||||||
romstage-y += ./../../../southbridge/via/common/early_smbus_is_busy.c
|
romstage-y += ./../../../southbridge/via/common/early_smbus_is_busy.c
|
||||||
|
@ -36,6 +37,7 @@ ramstage-y += chrome9hd.c
|
||||||
ramstage-y += traf_ctrl.c
|
ramstage-y += traf_ctrl.c
|
||||||
ramstage-y += sata.c
|
ramstage-y += sata.c
|
||||||
ramstage-y += lpc.c
|
ramstage-y += lpc.c
|
||||||
|
ramstage-y += memmap.c
|
||||||
|
|
||||||
# The buildsystem only includes this file if CONFIG_VGA is selected.
|
# The buildsystem only includes this file if CONFIG_VGA is selected.
|
||||||
# We need to do some VGA I/O before the VGA can be initialized. We can make good
|
# We need to do some VGA I/O before the VGA can be initialized. We can make good
|
||||||
|
|
|
@ -23,9 +23,6 @@
|
||||||
|
|
||||||
#include "vx900.h"
|
#include "vx900.h"
|
||||||
|
|
||||||
#define CHROME_9_HD_MIN_FB_SIZE 8
|
|
||||||
#define CHROME_9_HD_MAX_FB_SIZE 512
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file chrome9hd.c
|
* @file chrome9hd.c
|
||||||
*
|
*
|
||||||
|
@ -60,77 +57,6 @@
|
||||||
* useful considering we only have 8GB (33 bits) of memory-mapped space.
|
* useful considering we only have 8GB (33 bits) of memory-mapped space.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Helper to determine the framebuffer size */
|
|
||||||
u32 chrome9hd_fb_size(void)
|
|
||||||
{
|
|
||||||
static u32 fb_size = 0;
|
|
||||||
u8 reg8, ranksize;
|
|
||||||
u32 size_mb, tom_mb, max_size_mb;
|
|
||||||
int i;
|
|
||||||
/* We do some PCI and CMOS IO to find our value, so if we've already
|
|
||||||
* found it, save some time */
|
|
||||||
if (fb_size != 0)
|
|
||||||
return fb_size;
|
|
||||||
/* FIXME: read fb_size from CMOS, but until that is implemented, start
|
|
||||||
* from 512MB */
|
|
||||||
size_mb = 512;
|
|
||||||
|
|
||||||
/* The minimum framebuffer size is 8MB. */
|
|
||||||
size_mb = MAX(size_mb, CHROME_9_HD_MIN_FB_SIZE);
|
|
||||||
|
|
||||||
const device_t mcu = dev_find_device(PCI_VENDOR_ID_VIA,
|
|
||||||
PCI_DEVICE_ID_VIA_VX900_MEMCTRL,
|
|
||||||
0);
|
|
||||||
/*
|
|
||||||
* We have two limitations on the maximum framebuffer size:
|
|
||||||
* 1) (Sanity) No more that 1/4 of system RAM
|
|
||||||
* 2) (Hardware limitation) No larger than DRAM in last rank
|
|
||||||
* Check both of these limitations and apply them to our framebuffer */
|
|
||||||
tom_mb = (pci_read_config16(mcu, 0x88) & 0x07ff) << (24 - 20);
|
|
||||||
max_size_mb = tom_mb >> 2;
|
|
||||||
if (size_mb > max_size_mb) {
|
|
||||||
printk(BIOS_ALERT, "The framebuffer size of %dMB is larger"
|
|
||||||
" than 1/4 of available memory.\n"
|
|
||||||
" Limiting framebuffer to %dMB\n", size_mb, max_size_mb);
|
|
||||||
size_mb = max_size_mb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now handle limitation #2
|
|
||||||
* Look at the ending address of the memory ranks, from last to first,
|
|
||||||
* until we find one that is not zero. That is our last rank, and its
|
|
||||||
* size is the limit of our framebuffer. */
|
|
||||||
/* FIXME: This has a bug. If we remap memory above 4G, we consider the
|
|
||||||
* memory hole as part of our RAM. Thus if we install 3G, with a TOLM of
|
|
||||||
* 2.5G, our TOM will be at 5G and we'll assume we have 5G RAM instead
|
|
||||||
* of the actual 3.5G */
|
|
||||||
for (i = VX900_MAX_MEM_RANKS - 1; i > -1; i--) {
|
|
||||||
reg8 = pci_read_config8(mcu, 0x40 + i);
|
|
||||||
if (reg8 == 0)
|
|
||||||
continue;
|
|
||||||
/* We've reached the last populated rank */
|
|
||||||
ranksize = reg8 - pci_read_config8(mcu, 0x48 + i);
|
|
||||||
max_size_mb = ranksize << 6;
|
|
||||||
/* That's it. We got what we needed. */
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
if (size_mb > max_size_mb) {
|
|
||||||
printk(BIOS_ALERT, "The framebuffer size of %dMB is larger"
|
|
||||||
" than size of the last DRAM rank.\n"
|
|
||||||
" Limiting framebuffer to %dMB\n", size_mb, max_size_mb);
|
|
||||||
size_mb = max_size_mb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now round the framebuffer size to the closest power of 2 */
|
|
||||||
u8 fb_pow = 0;
|
|
||||||
while (size_mb >> fb_pow)
|
|
||||||
fb_pow++;
|
|
||||||
fb_pow--;
|
|
||||||
size_mb = (1 << fb_pow);
|
|
||||||
/* We store the framebuffer size in bytes, for simplicity */
|
|
||||||
fb_size = size_mb << 20;
|
|
||||||
return fb_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vx900_int15
|
* vx900_int15
|
||||||
*
|
*
|
||||||
|
@ -213,18 +139,10 @@ static void chrome9hd_set_sid_vid(u16 vendor, u16 device)
|
||||||
|
|
||||||
static void chrome9hd_handle_uma(device_t dev)
|
static void chrome9hd_handle_uma(device_t dev)
|
||||||
{
|
{
|
||||||
/* Mirror mirror, shiny glass, tell me that is not my ass */
|
u8 fb_pow = vx900_get_chrome9hd_fb_pow();
|
||||||
u32 fb_size = chrome9hd_fb_size() >> 20;
|
|
||||||
|
|
||||||
u8 fb_pow = 0;
|
if (fb_pow == 0)
|
||||||
while (fb_size >> fb_pow)
|
return;
|
||||||
fb_pow++;
|
|
||||||
fb_pow--;
|
|
||||||
|
|
||||||
/* Step 6 - Let MCU know the framebuffer size */
|
|
||||||
device_t mcu = dev_find_device(PCI_VENDOR_ID_VIA,
|
|
||||||
PCI_DEVICE_ID_VIA_VX900_MEMCTRL, 0);
|
|
||||||
pci_mod_config8(mcu, 0xa1, 7 << 4, (fb_pow - 2) << 4);
|
|
||||||
|
|
||||||
/* Step 7 - Let GFX know the framebuffer size (through PCI and IOCTL)
|
/* Step 7 - Let GFX know the framebuffer size (through PCI and IOCTL)
|
||||||
* The size we set here affects the behavior of BAR2, and the amount of
|
* The size we set here affects the behavior of BAR2, and the amount of
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
|
||||||
|
* Copyright (C) 2018 Lubomir Rintel <lkundrak@v3.sk>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __SIMPLE_DEVICE__
|
||||||
|
|
||||||
|
#include "vx900.h"
|
||||||
|
|
||||||
|
#include <device/pci.h>
|
||||||
|
#include <cbmem.h>
|
||||||
|
|
||||||
|
#define MCU PCI_DEV(0, 0, 3)
|
||||||
|
|
||||||
|
#define CHROME_9_HD_MIN_FB_SIZE 8
|
||||||
|
#define CHROME_9_HD_MAX_FB_SIZE 512
|
||||||
|
|
||||||
|
/* Helper to determine the framebuffer size */
|
||||||
|
void vx900_set_chrome9hd_fb_size(u32 size_mb)
|
||||||
|
{
|
||||||
|
u8 reg8, ranksize;
|
||||||
|
u32 tom_mb, max_size_mb;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* The minimum framebuffer size is 8MB. */
|
||||||
|
size_mb = MAX(size_mb, CHROME_9_HD_MIN_FB_SIZE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have two limitations on the maximum framebuffer size:
|
||||||
|
* 1) (Sanity) No more that 1/4 of system RAM
|
||||||
|
* 2) (Hardware limitation) No larger than DRAM in last rank
|
||||||
|
* Check both of these limitations and apply them to our framebuffer */
|
||||||
|
tom_mb = (pci_read_config16(MCU, 0x88) & 0x07ff) << (24 - 20);
|
||||||
|
max_size_mb = tom_mb >> 2;
|
||||||
|
if (size_mb > max_size_mb) {
|
||||||
|
printk(BIOS_ALERT, "The framebuffer size of %dMB is larger"
|
||||||
|
" than 1/4 of available memory.\n"
|
||||||
|
" Limiting framebuffer to %dMB\n", size_mb, max_size_mb);
|
||||||
|
size_mb = max_size_mb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now handle limitation #2
|
||||||
|
* Look at the ending address of the memory ranks, from last to first,
|
||||||
|
* until we find one that is not zero. That is our last rank, and its
|
||||||
|
* size is the limit of our framebuffer. */
|
||||||
|
/* FIXME: This has a bug. If we remap memory above 4G, we consider the
|
||||||
|
* memory hole as part of our RAM. Thus if we install 3G, with a TOLM of
|
||||||
|
* 2.5G, our TOM will be at 5G and we'll assume we have 5G RAM instead
|
||||||
|
* of the actual 3.5G */
|
||||||
|
for (i = VX900_MAX_MEM_RANKS - 1; i > -1; i--) {
|
||||||
|
reg8 = pci_read_config8(MCU, 0x40 + i);
|
||||||
|
if (reg8 == 0)
|
||||||
|
continue;
|
||||||
|
/* We've reached the last populated rank */
|
||||||
|
ranksize = reg8 - pci_read_config8(MCU, 0x48 + i);
|
||||||
|
max_size_mb = ranksize << 6;
|
||||||
|
/* That's it. We got what we needed. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (size_mb > max_size_mb) {
|
||||||
|
printk(BIOS_ALERT, "The framebuffer size of %dMB is larger"
|
||||||
|
" than size of the last DRAM rank.\n"
|
||||||
|
" Limiting framebuffer to %dMB\n", size_mb, max_size_mb);
|
||||||
|
size_mb = max_size_mb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now round the framebuffer size to the closest power of 2 */
|
||||||
|
u8 fb_pow = 0;
|
||||||
|
while (size_mb >> fb_pow)
|
||||||
|
fb_pow++;
|
||||||
|
fb_pow--;
|
||||||
|
size_mb = (1 << fb_pow);
|
||||||
|
|
||||||
|
pci_mod_config8(MCU, 0xa1, 7 << 4, (fb_pow - 2) << 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gets the configured framebuffer size as a power of 2 */
|
||||||
|
u8 vx900_get_chrome9hd_fb_pow(void)
|
||||||
|
{
|
||||||
|
u8 fb_pow = (pci_read_config8(MCU, 0xa1) >> 4) & 7;
|
||||||
|
|
||||||
|
if (fb_pow > 0)
|
||||||
|
fb_pow += 2;
|
||||||
|
|
||||||
|
return fb_pow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gets the configured framebuffer size in MB */
|
||||||
|
u32 vx900_get_chrome9hd_fb_size(void)
|
||||||
|
{
|
||||||
|
u8 size = vx900_get_chrome9hd_fb_pow();
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1 << size;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 vx900_get_tolm(void)
|
||||||
|
{
|
||||||
|
return (pci_read_config16(MCU, 0x84) & 0xfff0) >> 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *cbmem_top(void)
|
||||||
|
{
|
||||||
|
uintptr_t tolm;
|
||||||
|
uintptr_t fb_size;
|
||||||
|
|
||||||
|
tolm = vx900_get_tolm ();
|
||||||
|
fb_size = vx900_get_chrome9hd_fb_size ();
|
||||||
|
|
||||||
|
if (tolm > 0xfc0 || tolm <= 0x3ff || fb_size == 0x0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (void *)((tolm - fb_size) << 20);
|
||||||
|
}
|
|
@ -245,7 +245,7 @@ static void vx900_set_resources(device_t dev)
|
||||||
printk(BIOS_SPEW, "Found top of memory at %dMB\n", tomk >> 10);
|
printk(BIOS_SPEW, "Found top of memory at %dMB\n", tomk >> 10);
|
||||||
|
|
||||||
/* Do the same for top of low RAM */
|
/* Do the same for top of low RAM */
|
||||||
vx900_tolm = (pci_read_config16(mcu, 0x84) & 0xfff0) >> 4;
|
vx900_tolm = vx900_get_tolm();
|
||||||
full_tolmk = vx900_tolm << (20 - 10);
|
full_tolmk = vx900_tolm << (20 - 10);
|
||||||
/* Remap above 4G if needed */
|
/* Remap above 4G if needed */
|
||||||
full_tolmk = MIN(full_tolmk, pci_tolm >> 10);
|
full_tolmk = MIN(full_tolmk, pci_tolm >> 10);
|
||||||
|
@ -253,7 +253,7 @@ static void vx900_set_resources(device_t dev)
|
||||||
full_tolmk >> 10);
|
full_tolmk >> 10);
|
||||||
|
|
||||||
/* What about the framebuffer for the integrated GPU? */
|
/* What about the framebuffer for the integrated GPU? */
|
||||||
fbufk = chrome9hd_fb_size() >> 10;
|
fbufk = vx900_get_chrome9hd_fb_size() << (20 - 10);
|
||||||
printk(BIOS_SPEW, "Integrated graphics buffer: %dMB\n", fbufk >> 10);
|
printk(BIOS_SPEW, "Integrated graphics buffer: %dMB\n", fbufk >> 10);
|
||||||
|
|
||||||
/* Can't use the framebuffer as system RAM, sorry */
|
/* Can't use the framebuffer as system RAM, sorry */
|
||||||
|
@ -279,8 +279,6 @@ static void vx900_set_resources(device_t dev)
|
||||||
if (tor)
|
if (tor)
|
||||||
ram_resource(dev, idx++, RAM_4GB >> 10, (tor - RAM_4GB) >> 10);
|
ram_resource(dev, idx++, RAM_4GB >> 10, (tor - RAM_4GB) >> 10);
|
||||||
|
|
||||||
set_late_cbmem_top(tolmk << 10);
|
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "======================================================\n");
|
printk(BIOS_DEBUG, "======================================================\n");
|
||||||
assign_resources(dev->link_list);
|
assign_resources(dev->link_list);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,10 @@
|
||||||
|
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
|
||||||
u32 chrome9hd_fb_size(void);
|
u32 vx900_get_tolm(void);
|
||||||
|
void vx900_set_chrome9hd_fb_size(u32 size_mb);
|
||||||
|
u8 vx900_get_chrome9hd_fb_pow(void);
|
||||||
|
u32 vx900_get_chrome9hd_fb_size(void);
|
||||||
u8 vx900_int15_get_5f18_bl(void);
|
u8 vx900_int15_get_5f18_bl(void);
|
||||||
uint64_t get_uma_memory_base(void);
|
uint64_t get_uma_memory_base(void);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue