Subversion Repositories Kolibri OS

Rev

Rev 2005 | Rev 3120 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2005 Rev 2997
Line 23... Line 23...
23
 *
23
 *
24
 * Authors: Dave Airlie
24
 * Authors: Dave Airlie
25
 *          Alex Deucher
25
 *          Alex Deucher
26
 *          Jerome Glisse
26
 *          Jerome Glisse
27
 */
27
 */
28
#include "drmP.h"
28
#include 
29
#include "radeon_reg.h"
29
#include "radeon_reg.h"
30
#include "radeon.h"
30
#include "radeon.h"
31
#include "atom.h"
31
#include "atom.h"
Line 32... Line 32...
32
 
32
 
Line 97... Line 97...
97
	memcpy(rdev->bios, bios, size);
97
	memcpy(rdev->bios, bios, size);
98
//    pci_unmap_rom(rdev->pdev, bios);
98
//    pci_unmap_rom(rdev->pdev, bios);
99
	return true;
99
	return true;
100
}
100
}
Line -... Line 101...
-
 
101
 
101
 
102
#ifdef CONFIG_ACPI
102
/* ATRM is used to get the BIOS on the discrete cards in
103
/* ATRM is used to get the BIOS on the discrete cards in
103
 * dual-gpu systems.
104
 * dual-gpu systems.
-
 
105
 */
-
 
106
/* retrieve the ROM in 4k blocks */
-
 
107
#define ATRM_BIOS_PAGE 4096
-
 
108
/**
-
 
109
 * radeon_atrm_call - fetch a chunk of the vbios
-
 
110
 *
-
 
111
 * @atrm_handle: acpi ATRM handle
-
 
112
 * @bios: vbios image pointer
-
 
113
 * @offset: offset of vbios image data to fetch
-
 
114
 * @len: length of vbios image data to fetch
-
 
115
 *
-
 
116
 * Executes ATRM to fetch a chunk of the discrete
-
 
117
 * vbios image on PX systems (all asics).
-
 
118
 * Returns the length of the buffer fetched.
-
 
119
 */
-
 
120
static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
-
 
121
			    int offset, int len)
-
 
122
{
-
 
123
	acpi_status status;
-
 
124
	union acpi_object atrm_arg_elements[2], *obj;
-
 
125
	struct acpi_object_list atrm_arg;
-
 
126
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
-
 
127
 
-
 
128
	atrm_arg.count = 2;
-
 
129
	atrm_arg.pointer = &atrm_arg_elements[0];
-
 
130
 
-
 
131
	atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
-
 
132
	atrm_arg_elements[0].integer.value = offset;
-
 
133
 
-
 
134
	atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
-
 
135
	atrm_arg_elements[1].integer.value = len;
-
 
136
 
-
 
137
	status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
-
 
138
	if (ACPI_FAILURE(status)) {
-
 
139
		printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
-
 
140
		return -ENODEV;
-
 
141
	}
-
 
142
 
-
 
143
	obj = (union acpi_object *)buffer.pointer;
-
 
144
	memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
-
 
145
	len = obj->buffer.length;
-
 
146
	kfree(buffer.pointer);
-
 
147
	return len;
-
 
148
}
104
 */
149
 
105
static bool radeon_atrm_get_bios(struct radeon_device *rdev)
150
static bool radeon_atrm_get_bios(struct radeon_device *rdev)
106
{
151
{
107
	int ret;
152
	int ret;
108
	int size = 256 * 1024;
153
	int size = 256 * 1024;
-
 
154
	int i;
-
 
155
	struct pci_dev *pdev = NULL;
-
 
156
	acpi_handle dhandle, atrm_handle;
-
 
157
	acpi_status status;
Line -... Line 158...
-
 
158
	bool found = false;
-
 
159
 
-
 
160
	/* ATRM is for the discrete card only */
-
 
161
	if (rdev->flags & RADEON_IS_IGP)
-
 
162
		return false;
109
	int i;
163
 
-
 
164
	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
-
 
165
		dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
-
 
166
		if (!dhandle)
-
 
167
			continue;
-
 
168
 
-
 
169
		status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
-
 
170
		if (!ACPI_FAILURE(status)) {
-
 
171
			found = true;
-
 
172
			break;
-
 
173
		}
-
 
174
	}
110
 
175
 
Line 111... Line 176...
111
	if (!radeon_atrm_supported(rdev->pdev))
176
	if (!found)
112
		return false;
177
		return false;
113
 
178
 
114
	rdev->bios = kmalloc(size, GFP_KERNEL);
179
	rdev->bios = kmalloc(size, GFP_KERNEL);
115
	if (!rdev->bios) {
180
	if (!rdev->bios) {
Line 116... Line 181...
116
		DRM_ERROR("Unable to allocate bios\n");
181
		DRM_ERROR("Unable to allocate bios\n");
117
		return false;
182
		return false;
-
 
183
	}
118
	}
184
 
119
 
185
	for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
120
	for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
186
		ret = radeon_atrm_call(atrm_handle,
121
		ret = radeon_atrm_get_bios_chunk(rdev->bios,
187
				       rdev->bios,
122
						 (i * ATRM_BIOS_PAGE),
188
						 (i * ATRM_BIOS_PAGE),
Line 123... Line 189...
123
						 ATRM_BIOS_PAGE);
189
						 ATRM_BIOS_PAGE);
124
		if (ret <= 0)
190
		if (ret < ATRM_BIOS_PAGE)
125
			break;
191
			break;
126
	}
192
	}
127
 
193
 
128
	if (i == 0 || rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) {
194
	if (i == 0 || rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) {
-
 
195
		kfree(rdev->bios);
-
 
196
		return false;
-
 
197
	}
-
 
198
	return true;
-
 
199
}
-
 
200
#else
Line 129... Line 201...
129
		kfree(rdev->bios);
201
static bool radeon_atrm_get_bios(struct radeon_device *rdev)
130
		return false;
202
{
131
	}
203
    return false;
132
	return true;
204
}
Line 475... Line 547...
475
		return avivo_read_disabled_bios(rdev);
547
		return avivo_read_disabled_bios(rdev);
476
	else
548
	else
477
		return legacy_read_disabled_bios(rdev);
549
		return legacy_read_disabled_bios(rdev);
478
}
550
}
Line -... Line 551...
-
 
551
 
-
 
552
#ifdef CONFIG_ACPI
-
 
553
static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
-
 
554
{
-
 
555
	bool ret = false;
-
 
556
	struct acpi_table_header *hdr;
-
 
557
	acpi_size tbl_size;
-
 
558
	UEFI_ACPI_VFCT *vfct;
-
 
559
	GOP_VBIOS_CONTENT *vbios;
-
 
560
	VFCT_IMAGE_HEADER *vhdr;
-
 
561
 
-
 
562
	if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size)))
-
 
563
		return false;
-
 
564
	if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
-
 
565
		DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
-
 
566
		goto out_unmap;
-
 
567
	}
-
 
568
 
-
 
569
	vfct = (UEFI_ACPI_VFCT *)hdr;
-
 
570
	if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
-
 
571
		DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
-
 
572
		goto out_unmap;
-
 
573
	}
-
 
574
 
-
 
575
	vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
-
 
576
	vhdr = &vbios->VbiosHeader;
-
 
577
	DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
-
 
578
			vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
-
 
579
			vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
-
 
580
 
-
 
581
	if (vhdr->PCIBus != rdev->pdev->bus->number ||
-
 
582
	    vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
-
 
583
	    vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
-
 
584
	    vhdr->VendorID != rdev->pdev->vendor ||
-
 
585
	    vhdr->DeviceID != rdev->pdev->device) {
-
 
586
		DRM_INFO("ACPI VFCT table is not for this card\n");
-
 
587
		goto out_unmap;
-
 
588
	};
-
 
589
 
-
 
590
	if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
-
 
591
		DRM_ERROR("ACPI VFCT image truncated\n");
-
 
592
		goto out_unmap;
-
 
593
	}
-
 
594
 
-
 
595
	rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
-
 
596
	ret = !!rdev->bios;
-
 
597
 
-
 
598
out_unmap:
-
 
599
	return ret;
-
 
600
}
-
 
601
#else
-
 
602
static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
-
 
603
{
-
 
604
	return false;
-
 
605
}
Line 479... Line 606...
479
 
606
#endif
480
 
607
 
481
bool radeon_get_bios(struct radeon_device *rdev)
608
bool radeon_get_bios(struct radeon_device *rdev)
482
{
609
{
Line 483... Line 610...
483
	bool r;
610
	bool r;
484
	uint16_t tmp;
611
	uint16_t tmp;
-
 
612
 
-
 
613
	r = radeon_atrm_get_bios(rdev);
485
 
614
	if (r == false)
486
	r = radeon_atrm_get_bios(rdev);
615
		r = radeon_acpi_vfct_bios(rdev);
487
	if (r == false)
616
	if (r == false)
488
		r = igp_read_bios_from_vram(rdev);
617
		r = igp_read_bios_from_vram(rdev);
489
		if (r == false)
618
    if (r == false)