xref: /haiku/src/add-ons/accelerants/radeon_hd/bios.cpp (revision 6fe3a560bd59bd07d7ce35d36ae8f8ad2a1eb2bd)
10ceb8395SAlexander von Gluck IV /*
20ceb8395SAlexander von Gluck IV  * Copyright 2011, Haiku, Inc. All Rights Reserved.
30ceb8395SAlexander von Gluck IV  * Distributed under the terms of the MIT License.
40ceb8395SAlexander von Gluck IV  *
50ceb8395SAlexander von Gluck IV  * Authors:
60ceb8395SAlexander von Gluck IV  *		Alexander von Gluck IV, kallisti5@unixzen.com
70ceb8395SAlexander von Gluck IV  */
80ceb8395SAlexander von Gluck IV 
90ceb8395SAlexander von Gluck IV 
100ceb8395SAlexander von Gluck IV #include "bios.h"
110ceb8395SAlexander von Gluck IV 
1261cf7133SAlexander von Gluck IV #include <Debug.h>
1361cf7133SAlexander von Gluck IV 
140ceb8395SAlexander von Gluck IV #include "accelerant.h"
150ceb8395SAlexander von Gluck IV #include "accelerant_protos.h"
160ceb8395SAlexander von Gluck IV 
170ceb8395SAlexander von Gluck IV 
180ceb8395SAlexander von Gluck IV #undef TRACE
190ceb8395SAlexander von Gluck IV 
200ceb8395SAlexander von Gluck IV #define TRACE_ATOM
210ceb8395SAlexander von Gluck IV #ifdef TRACE_ATOM
2212c25669SAlexander von Gluck IV #   define TRACE(x...) _sPrintf("radeon_hd: " x)
230ceb8395SAlexander von Gluck IV #else
2412c25669SAlexander von Gluck IV #   define TRACE(x...) ;
250ceb8395SAlexander von Gluck IV #endif
260ceb8395SAlexander von Gluck IV 
2751360674SAlexander von Gluck IV 
281d5cfc64SAlexander von Gluck IV atom_context* gAtomContext;
2951360674SAlexander von Gluck IV 
3051360674SAlexander von Gluck IV 
31d77ff85eSAlexander von Gluck IV void
radeon_bios_init_scratch()32d77ff85eSAlexander von Gluck IV radeon_bios_init_scratch()
33d77ff85eSAlexander von Gluck IV {
34d77ff85eSAlexander von Gluck IV 	radeon_shared_info &info = *gInfo->shared_info;
35d77ff85eSAlexander von Gluck IV 
3653aac744SAlexander von Gluck IV 	uint32 biosScratch2;
3753aac744SAlexander von Gluck IV 	uint32 biosScratch6;
38d77ff85eSAlexander von Gluck IV 
39359b926fSAlexander von Gluck IV 	if (info.chipsetID >= RADEON_R600) {
4093aac98dSAlexander von Gluck IV 		biosScratch2 = Read32(OUT, R600_SCRATCH_REG2);
4193aac98dSAlexander von Gluck IV 		biosScratch6 = Read32(OUT, R600_SCRATCH_REG6);
42d77ff85eSAlexander von Gluck IV 	} else {
4353aac744SAlexander von Gluck IV 		biosScratch2 = Read32(OUT, RADEON_BIOS_2_SCRATCH);
4453aac744SAlexander von Gluck IV 		biosScratch6 = Read32(OUT, RADEON_BIOS_6_SCRATCH);
45d77ff85eSAlexander von Gluck IV 	}
46d77ff85eSAlexander von Gluck IV 
47*6fe3a560SPascal Abresch 	biosScratch2 |= ATOM_S2_VRI_BRIGHT_ENABLE;
48*6fe3a560SPascal Abresch 		// bios should not control backlight
4953aac744SAlexander von Gluck IV 	biosScratch6 |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH;
50d77ff85eSAlexander von Gluck IV 		// bios shouldn't handle mode switching
51d77ff85eSAlexander von Gluck IV 
52359b926fSAlexander von Gluck IV 	if (info.chipsetID >= RADEON_R600) {
5393aac98dSAlexander von Gluck IV 		Write32(OUT, R600_SCRATCH_REG2, biosScratch2);
5493aac98dSAlexander von Gluck IV 		Write32(OUT, R600_SCRATCH_REG6, biosScratch6);
55d77ff85eSAlexander von Gluck IV 	} else {
5653aac744SAlexander von Gluck IV 		Write32(OUT, RADEON_BIOS_2_SCRATCH, biosScratch2);
5753aac744SAlexander von Gluck IV 		Write32(OUT, RADEON_BIOS_6_SCRATCH, biosScratch6);
58d77ff85eSAlexander von Gluck IV 	}
59d77ff85eSAlexander von Gluck IV }
60d77ff85eSAlexander von Gluck IV 
61d77ff85eSAlexander von Gluck IV 
62d3e8b642SAlexander von Gluck IV bool
radeon_bios_isposted()63d3e8b642SAlexander von Gluck IV radeon_bios_isposted()
64d3e8b642SAlexander von Gluck IV {
65d3e8b642SAlexander von Gluck IV 	// aka, is primary graphics card that POST loaded
66d3e8b642SAlexander von Gluck IV 
67d3e8b642SAlexander von Gluck IV 	radeon_shared_info &info = *gInfo->shared_info;
68d3e8b642SAlexander von Gluck IV 	uint32 reg;
69d3e8b642SAlexander von Gluck IV 
70359b926fSAlexander von Gluck IV 	if (info.chipsetID == RADEON_PALM) {
71d3e8b642SAlexander von Gluck IV 		// palms
72d3e8b642SAlexander von Gluck IV 		reg = Read32(OUT, EVERGREEN_CRTC_CONTROL
73d3e8b642SAlexander von Gluck IV 			+ EVERGREEN_CRTC0_REGISTER_OFFSET)
74d3e8b642SAlexander von Gluck IV 			| Read32(OUT, EVERGREEN_CRTC_CONTROL
75d3e8b642SAlexander von Gluck IV 			+ EVERGREEN_CRTC1_REGISTER_OFFSET);
76dc223cc5SAlexander von Gluck IV 		if ((reg & EVERGREEN_CRTC_MASTER_EN) != 0)
77d3e8b642SAlexander von Gluck IV 			return true;
78359b926fSAlexander von Gluck IV 	} else if (info.chipsetID >= RADEON_CEDAR) {
79d3e8b642SAlexander von Gluck IV 		// evergreen or higher
80d3e8b642SAlexander von Gluck IV 		reg = Read32(OUT, EVERGREEN_CRTC_CONTROL
81d3e8b642SAlexander von Gluck IV 				+ EVERGREEN_CRTC0_REGISTER_OFFSET)
82d3e8b642SAlexander von Gluck IV 			| Read32(OUT, EVERGREEN_CRTC_CONTROL
83d3e8b642SAlexander von Gluck IV 				+ EVERGREEN_CRTC1_REGISTER_OFFSET)
84d3e8b642SAlexander von Gluck IV 			| Read32(OUT, EVERGREEN_CRTC_CONTROL
85d3e8b642SAlexander von Gluck IV 				+ EVERGREEN_CRTC2_REGISTER_OFFSET)
86d3e8b642SAlexander von Gluck IV 			| Read32(OUT, EVERGREEN_CRTC_CONTROL
87d3e8b642SAlexander von Gluck IV 				+ EVERGREEN_CRTC3_REGISTER_OFFSET)
88d3e8b642SAlexander von Gluck IV 			| Read32(OUT, EVERGREEN_CRTC_CONTROL
89d3e8b642SAlexander von Gluck IV 				+ EVERGREEN_CRTC4_REGISTER_OFFSET)
90d3e8b642SAlexander von Gluck IV 			| Read32(OUT, EVERGREEN_CRTC_CONTROL
91d3e8b642SAlexander von Gluck IV 				+ EVERGREEN_CRTC5_REGISTER_OFFSET);
92dc223cc5SAlexander von Gluck IV 		if ((reg & EVERGREEN_CRTC_MASTER_EN) != 0)
93d3e8b642SAlexander von Gluck IV 			return true;
94e35c1f2dSAlexander von Gluck IV 	} else if (info.chipsetID >= RADEON_RS600) {
95d3e8b642SAlexander von Gluck IV 		// avivio through r700
96bbd90770SAlexander von Gluck IV 		reg = Read32(OUT, AVIVO_D1CRTC_CONTROL)
97bbd90770SAlexander von Gluck IV 			| Read32(OUT, AVIVO_D2CRTC_CONTROL);
98dc223cc5SAlexander von Gluck IV 		if ((reg & AVIVO_CRTC_EN) != 0) {
99d3e8b642SAlexander von Gluck IV 			return true;
100d3e8b642SAlexander von Gluck IV 		}
101e35c1f2dSAlexander von Gluck IV 	} else {
102e35c1f2dSAlexander von Gluck IV 		// early cards
103e35c1f2dSAlexander von Gluck IV 		reg = Read32(OUT, RADEON_CRTC_GEN_CNTL)
104e35c1f2dSAlexander von Gluck IV 			| Read32(OUT, RADEON_CRTC2_GEN_CNTL);
105e35c1f2dSAlexander von Gluck IV 		if ((reg & RADEON_CRTC_EN) != 0)
106e35c1f2dSAlexander von Gluck IV 			return true;
107d3e8b642SAlexander von Gluck IV 	}
108d3e8b642SAlexander von Gluck IV 
109e35c1f2dSAlexander von Gluck IV 	// also check memory size incase crt controlers are disabled
110e35c1f2dSAlexander von Gluck IV 	if (info.chipsetID >= RADEON_R600)
111e35c1f2dSAlexander von Gluck IV 		reg = Read32(OUT, R600_CONFIG_MEMSIZE);
112e35c1f2dSAlexander von Gluck IV 	else
113e35c1f2dSAlexander von Gluck IV 		reg = Read32(OUT, RADEON_CONFIG_MEMSIZE);
114e35c1f2dSAlexander von Gluck IV 
115e35c1f2dSAlexander von Gluck IV 	if (reg)
116e35c1f2dSAlexander von Gluck IV 		return true;
117e35c1f2dSAlexander von Gluck IV 
118d3e8b642SAlexander von Gluck IV 	return false;
119d3e8b642SAlexander von Gluck IV }
120d3e8b642SAlexander von Gluck IV 
121d3e8b642SAlexander von Gluck IV 
12251360674SAlexander von Gluck IV status_t
radeon_init_bios(uint8 * bios)1235cf44ddaSAlexander von Gluck IV radeon_init_bios(uint8* bios)
1241d5cfc64SAlexander von Gluck IV {
1251d5cfc64SAlexander von Gluck IV 	radeon_shared_info &info = *gInfo->shared_info;
1261d5cfc64SAlexander von Gluck IV 
1275cf44ddaSAlexander von Gluck IV 	if (info.has_rom == false) {
1285cf44ddaSAlexander von Gluck IV 		TRACE("%s: called even though has_rom == false\n", __func__);
1295cf44ddaSAlexander von Gluck IV 		return B_ERROR;
1301d5cfc64SAlexander von Gluck IV 	}
1311d5cfc64SAlexander von Gluck IV 
132a8232073SAlexander von Gluck IV 	#ifdef TRACE_ATOM
133a8232073SAlexander von Gluck IV 	radeon_dump_bios();
134a8232073SAlexander von Gluck IV 	#endif
135a8232073SAlexander von Gluck IV 
13651360674SAlexander von Gluck IV 	struct card_info* atom_card_info
13751360674SAlexander von Gluck IV 		= (card_info*)malloc(sizeof(card_info));
13851360674SAlexander von Gluck IV 
13951360674SAlexander von Gluck IV 	if (!atom_card_info)
14051360674SAlexander von Gluck IV 		return B_NO_MEMORY;
14151360674SAlexander von Gluck IV 
14211390ce0SAlexander von Gluck IV 	atom_card_info->reg_read = Read32Cail;
14311390ce0SAlexander von Gluck IV 	atom_card_info->reg_write = Write32Cail;
14451360674SAlexander von Gluck IV 
145f66a1a8dSAlexander von Gluck IV 	// use MMIO instead of PCI I/O BAR
14611390ce0SAlexander von Gluck IV 	atom_card_info->ioreg_read = Read32Cail;
14711390ce0SAlexander von Gluck IV 	atom_card_info->ioreg_write = Write32Cail;
148f66a1a8dSAlexander von Gluck IV 
14951360674SAlexander von Gluck IV 	atom_card_info->mc_read = _read32;
15051360674SAlexander von Gluck IV 	atom_card_info->mc_write = _write32;
15151360674SAlexander von Gluck IV 	atom_card_info->pll_read = _read32;
15251360674SAlexander von Gluck IV 	atom_card_info->pll_write = _write32;
15351360674SAlexander von Gluck IV 
1541d5cfc64SAlexander von Gluck IV 	// Point AtomBIOS parser to card bios and malloc gAtomContext
155f0b0d6cbSAlexander von Gluck IV 	gAtomContext = atom_parse(atom_card_info, bios);
15651360674SAlexander von Gluck IV 
1571d5cfc64SAlexander von Gluck IV 	if (gAtomContext == NULL) {
158ef2909a1SAlexander von Gluck IV 		TRACE("%s: couldn't parse system AtomBIOS\n", __func__);
159ef2909a1SAlexander von Gluck IV 		return B_ERROR;
160ef2909a1SAlexander von Gluck IV 	}
161ef2909a1SAlexander von Gluck IV 
16281e071b7SAlexander von Gluck IV 	if ((gAtomContext->exec_sem = create_sem(1, "AtomBIOS_exec"))
16381e071b7SAlexander von Gluck IV 		< B_NO_ERROR) {
16481e071b7SAlexander von Gluck IV 		TRACE("%s: couldn't create semaphore for AtomBIOS exec thread!\n",
16581e071b7SAlexander von Gluck IV 			__func__);
16681e071b7SAlexander von Gluck IV 		return B_ERROR;
16781e071b7SAlexander von Gluck IV 	}
16881e071b7SAlexander von Gluck IV 
169d77ff85eSAlexander von Gluck IV 	radeon_bios_init_scratch();
17077e8ac07SAlexander von Gluck IV 	atom_allocate_fb_scratch(gAtomContext);
17151360674SAlexander von Gluck IV 
172d3e8b642SAlexander von Gluck IV 	// post card atombios if needed
173936aec74SAlexander von Gluck IV 	if (radeon_bios_isposted() == false) {
174d3e8b642SAlexander von Gluck IV 		TRACE("%s: init AtomBIOS for this card as it is not not posted\n",
175d3e8b642SAlexander von Gluck IV 			__func__);
176d3e8b642SAlexander von Gluck IV 		// radeon_gpu_reset();	// <= r500 only?
1770cd93754SAlexander von Gluck IV 		atom_asic_init(gAtomContext);
178d3e8b642SAlexander von Gluck IV 	} else {
179d3e8b642SAlexander von Gluck IV 		TRACE("%s: AtomBIOS is already posted\n",
180d3e8b642SAlexander von Gluck IV 			__func__);
181d3e8b642SAlexander von Gluck IV 	}
1820cd93754SAlexander von Gluck IV 
18351360674SAlexander von Gluck IV 	return B_OK;
18451360674SAlexander von Gluck IV }
185a8232073SAlexander von Gluck IV 
186a8232073SAlexander von Gluck IV 
187a8232073SAlexander von Gluck IV status_t
radeon_dump_bios()188a8232073SAlexander von Gluck IV radeon_dump_bios()
189a8232073SAlexander von Gluck IV {
190a8232073SAlexander von Gluck IV 	// For debugging use, dump card AtomBIOS
191a8232073SAlexander von Gluck IV 	radeon_shared_info &info = *gInfo->shared_info;
192a8232073SAlexander von Gluck IV 
193a8232073SAlexander von Gluck IV 	TRACE("%s: Dumping AtomBIOS as ATOM_DEBUG is set...\n",
194a8232073SAlexander von Gluck IV 		__func__);
195a8232073SAlexander von Gluck IV 
196a8232073SAlexander von Gluck IV 	FILE* fp;
197a8232073SAlexander von Gluck IV 	char filename[255];
198f73f5d4cSIngo Weinhold 	sprintf(filename, "/boot/system/cache/tmp/radeon_hd_bios_1002_%" B_PRIx32
199359b926fSAlexander von Gluck IV 		"_%" B_PRIu32 ".bin", info.pciID, info.deviceIndex);
200a8232073SAlexander von Gluck IV 
201a8232073SAlexander von Gluck IV 	fp = fopen(filename, "wb");
202a8232073SAlexander von Gluck IV 	if (fp == NULL) {
203a8232073SAlexander von Gluck IV 		TRACE("%s: Cannot create AtomBIOS blob at %s\n", __func__, filename);
204a8232073SAlexander von Gluck IV 		return B_ERROR;
205a8232073SAlexander von Gluck IV 	}
206a8232073SAlexander von Gluck IV 
207a8232073SAlexander von Gluck IV 	fwrite(gInfo->rom, info.rom_size, 1, fp);
208a8232073SAlexander von Gluck IV 
209a8232073SAlexander von Gluck IV 	fclose(fp);
210a8232073SAlexander von Gluck IV 
211a8232073SAlexander von Gluck IV 	TRACE("%s: AtomBIOS dumped to %s\n", __func__, filename);
212a8232073SAlexander von Gluck IV 
213a8232073SAlexander von Gluck IV 	return B_OK;
214a8232073SAlexander von Gluck IV }
215