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:
		
				
					committed by
					
						 Kyösti Mälkki
						Kyösti Mälkki
					
				
			
			
				
	
			
			
			
						parent
						
							faafbfb81e
						
					
				
				
					commit
					d8ec973fd2
				
			| @@ -80,7 +80,7 @@ void main(unsigned long bist) | ||||
| 	ram_check((1 << 24), 0x80); | ||||
| 	ram_check((512 + 256 - 1) << 20, 0x80); | ||||
| 	ram_check(0x80c0000, 0x80); | ||||
| 	tolm = ((pci_read_config16(MCU, 0x84) & 0xfff0) >> 4) << 20; | ||||
| 	tolm = vx900_get_tolm () << 20; | ||||
| 	if (tolm > (1 * (u32) GiB)) | ||||
| 		ram_check(1024 << 10, 0x80); | ||||
| 	if (tolm > (2 * (u32) GiB)) | ||||
| @@ -88,10 +88,13 @@ void main(unsigned long bist) | ||||
|  | ||||
| 	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 */ | ||||
| #if IS_ENABLED(CONFIG_EARLY_CBMEM_INIT) | ||||
| 	cbmem_recovery(0); | ||||
| #endif | ||||
|  | ||||
| 	/* FIXME: See if this is needed or take this out please */ | ||||
| 	/* Disable Memcard and SDIO */ | ||||
| 	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_SMBUS | ||||
| 	select HAVE_HARD_RESET | ||||
| 	select LATE_CBMEM_INIT | ||||
|  | ||||
| if NORTHBRIDGE_VIA_VX900 | ||||
|  | ||||
|   | ||||
| @@ -21,6 +21,7 @@ romstage-y += early_smbus.c | ||||
| romstage-y += early_vx900.c | ||||
| romstage-y += early_host_bus_ctl.c | ||||
| romstage-y += raminit_ddr3.c | ||||
| romstage-y += memmap.c | ||||
| romstage-y += ./../../../device/dram/ddr3.c | ||||
| romstage-y += ./../../../southbridge/via/common/early_smbus_delay.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 += sata.c | ||||
| ramstage-y += lpc.c | ||||
| ramstage-y += memmap.c | ||||
|  | ||||
| # 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 | ||||
|   | ||||
| @@ -23,9 +23,6 @@ | ||||
|  | ||||
| #include "vx900.h" | ||||
|  | ||||
| #define CHROME_9_HD_MIN_FB_SIZE   8 | ||||
| #define CHROME_9_HD_MAX_FB_SIZE 512 | ||||
|  | ||||
| /** | ||||
|  * @file chrome9hd.c | ||||
|  * | ||||
| @@ -60,77 +57,6 @@ | ||||
|  *    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 | ||||
|  * | ||||
| @@ -213,18 +139,10 @@ static void chrome9hd_set_sid_vid(u16 vendor, u16 device) | ||||
|  | ||||
| static void chrome9hd_handle_uma(device_t dev) | ||||
| { | ||||
| 	/* Mirror mirror, shiny glass, tell me that is not my ass */ | ||||
| 	u32 fb_size = chrome9hd_fb_size() >> 20; | ||||
| 	u8 fb_pow = vx900_get_chrome9hd_fb_pow(); | ||||
|  | ||||
| 	u8 fb_pow = 0; | ||||
| 	while (fb_size >> fb_pow) | ||||
| 		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); | ||||
| 	if (fb_pow == 0) | ||||
| 		return; | ||||
|  | ||||
| 	/* 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 | ||||
|   | ||||
							
								
								
									
										128
									
								
								src/northbridge/via/vx900/memmap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/northbridge/via/vx900/memmap.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||
|  | ||||
| 	/* 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); | ||||
| 	/* Remap above 4G if needed */ | ||||
| 	full_tolmk = MIN(full_tolmk, pci_tolm >> 10); | ||||
| @@ -253,7 +253,7 @@ static void vx900_set_resources(device_t dev) | ||||
| 	       full_tolmk >> 10); | ||||
|  | ||||
| 	/* 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); | ||||
|  | ||||
| 	/* Can't use the framebuffer as system RAM, sorry */ | ||||
| @@ -279,8 +279,6 @@ static void vx900_set_resources(device_t dev) | ||||
| 	if (tor) | ||||
| 		ram_resource(dev, idx++, RAM_4GB >> 10, (tor - RAM_4GB) >> 10); | ||||
|  | ||||
| 	set_late_cbmem_top(tolmk << 10); | ||||
|  | ||||
| 	printk(BIOS_DEBUG, "======================================================\n"); | ||||
| 	assign_resources(dev->link_list); | ||||
| } | ||||
|   | ||||
| @@ -31,7 +31,10 @@ | ||||
|  | ||||
| #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); | ||||
| uint64_t get_uma_memory_base(void); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user