diff options
| author | Alex Deucher <alexander.deucher@amd.com> | 2012-08-16 15:39:09 -0400 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2012-08-20 11:13:05 -0400 |
| commit | c61e2775873f603148e8e998a938721b7d222d24 (patch) | |
| tree | 9d953bc0602b93a77f5f8fce05fb119d4514e095 | |
| parent | 7c3906d04a4587dceaa78cc1ae6b14e6454ee02a (diff) | |
drm/radeon: split ATRM support out from the ATPX handler (v3)
There are systems that use ATRM, but not ATPX.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41265
V2: fix #ifdefs as per Greg's comments
V3: fix it harder
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
| -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 | { |
