diff options
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atpx_handler.c | 56 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_bios.c | 80 |
3 files changed, 77 insertions, 74 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 99304194a65c..59a15315ae9f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -142,21 +142,6 @@ struct radeon_device; | |||
142 | /* | 142 | /* |
143 | * BIOS. | 143 | * BIOS. |
144 | */ | 144 | */ |
145 | #define ATRM_BIOS_PAGE 4096 | ||
146 | |||
147 | #if defined(CONFIG_VGA_SWITCHEROO) | ||
148 | bool radeon_atrm_supported(struct pci_dev *pdev); | ||
149 | int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len); | ||
150 | #else | ||
151 | static inline bool radeon_atrm_supported(struct pci_dev *pdev) | ||
152 | { | ||
153 | return false; | ||
154 | } | ||
155 | |||
156 | static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){ | ||
157 | return -EINVAL; | ||
158 | } | ||
159 | #endif | ||
160 | bool radeon_get_bios(struct radeon_device *rdev); | 145 | bool radeon_get_bios(struct radeon_device *rdev); |
161 | 146 | ||
162 | /* | 147 | /* |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 98724fcb0088..2a2cf0b88a28 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -30,57 +30,8 @@ static struct radeon_atpx_priv { | |||
30 | /* handle for device - and atpx */ | 30 | /* handle for device - and atpx */ |
31 | acpi_handle dhandle; | 31 | acpi_handle dhandle; |
32 | acpi_handle atpx_handle; | 32 | acpi_handle atpx_handle; |
33 | acpi_handle atrm_handle; | ||
34 | } radeon_atpx_priv; | 33 | } radeon_atpx_priv; |
35 | 34 | ||
36 | /* retrieve the ROM in 4k blocks */ | ||
37 | static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, | ||
38 | int offset, int len) | ||
39 | { | ||
40 | acpi_status status; | ||
41 | union acpi_object atrm_arg_elements[2], *obj; | ||
42 | struct acpi_object_list atrm_arg; | ||
43 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; | ||
44 | |||
45 | atrm_arg.count = 2; | ||
46 | atrm_arg.pointer = &atrm_arg_elements[0]; | ||
47 | |||
48 | atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; | ||
49 | atrm_arg_elements[0].integer.value = offset; | ||
50 | |||
51 | atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; | ||
52 | atrm_arg_elements[1].integer.value = len; | ||
53 | |||
54 | status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); | ||
55 | if (ACPI_FAILURE(status)) { | ||
56 | printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); | ||
57 | return -ENODEV; | ||
58 | } | ||
59 | |||
60 | obj = (union acpi_object *)buffer.pointer; | ||
61 | memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); | ||
62 | len = obj->buffer.length; | ||
63 | kfree(buffer.pointer); | ||
64 | return len; | ||
65 | } | ||
66 | |||
67 | bool radeon_atrm_supported(struct pci_dev *pdev) | ||
68 | { | ||
69 | /* get the discrete ROM only via ATRM */ | ||
70 | if (!radeon_atpx_priv.atpx_detected) | ||
71 | return false; | ||
72 | |||
73 | if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) | ||
74 | return false; | ||
75 | return true; | ||
76 | } | ||
77 | |||
78 | |||
79 | int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len) | ||
80 | { | ||
81 | return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len); | ||
82 | } | ||
83 | |||
84 | static int radeon_atpx_get_version(acpi_handle handle) | 35 | static int radeon_atpx_get_version(acpi_handle handle) |
85 | { | 36 | { |
86 | acpi_status status; | 37 | acpi_status status; |
@@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, | |||
198 | 149 | ||
199 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | 150 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) |
200 | { | 151 | { |
201 | acpi_handle dhandle, atpx_handle, atrm_handle; | 152 | acpi_handle dhandle, atpx_handle; |
202 | acpi_status status; | 153 | acpi_status status; |
203 | 154 | ||
204 | dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); | 155 | dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); |
@@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | |||
209 | if (ACPI_FAILURE(status)) | 160 | if (ACPI_FAILURE(status)) |
210 | return false; | 161 | return false; |
211 | 162 | ||
212 | status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); | ||
213 | if (ACPI_FAILURE(status)) | ||
214 | return false; | ||
215 | |||
216 | radeon_atpx_priv.dhandle = dhandle; | 163 | radeon_atpx_priv.dhandle = dhandle; |
217 | radeon_atpx_priv.atpx_handle = atpx_handle; | 164 | radeon_atpx_priv.atpx_handle = atpx_handle; |
218 | radeon_atpx_priv.atrm_handle = atrm_handle; | ||
219 | return true; | 165 | return true; |
220 | } | 166 | } |
221 | 167 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index ab0b2f7292ae..d306cc8fdeaa 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
@@ -99,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev) | |||
99 | return true; | 99 | return true; |
100 | } | 100 | } |
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. |
104 | */ | 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 | } | ||
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; |
109 | int i; | 154 | int i; |
155 | struct pci_dev *pdev = NULL; | ||
156 | acpi_handle dhandle, atrm_handle; | ||
157 | acpi_status status; | ||
158 | bool found = false; | ||
110 | 159 | ||
111 | if (!radeon_atrm_supported(rdev->pdev)) | 160 | /* ATRM is for the discrete card only */ |
161 | if (rdev->flags & RADEON_IS_IGP) | ||
162 | return false; | ||
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 | } | ||
175 | |||
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); |
@@ -118,9 +183,10 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) | |||
118 | } | 183 | } |
119 | 184 | ||
120 | for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { | 185 | for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { |
121 | ret = radeon_atrm_get_bios_chunk(rdev->bios, | 186 | ret = radeon_atrm_call(atrm_handle, |
122 | (i * ATRM_BIOS_PAGE), | 187 | rdev->bios, |
123 | ATRM_BIOS_PAGE); | 188 | (i * ATRM_BIOS_PAGE), |
189 | ATRM_BIOS_PAGE); | ||
124 | if (ret < ATRM_BIOS_PAGE) | 190 | if (ret < ATRM_BIOS_PAGE) |
125 | break; | 191 | break; |
126 | } | 192 | } |
@@ -131,6 +197,12 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) | |||
131 | } | 197 | } |
132 | return true; | 198 | return true; |
133 | } | 199 | } |
200 | #else | ||
201 | static inline bool radeon_atrm_get_bios(struct radeon_device *rdev) | ||
202 | { | ||
203 | return false; | ||
204 | } | ||
205 | #endif | ||
134 | 206 | ||
135 | static bool ni_read_disabled_bios(struct radeon_device *rdev) | 207 | static bool ni_read_disabled_bios(struct radeon_device *rdev) |
136 | { | 208 | { |