2 * Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Axel Dörfler, axeld@pinc-software.de
7 * Alexander von Gluck, kallisti5@unixzen.com
11 #include "accelerant.h"
22 #include "accelerant_protos.h"
25 #include "connector.h"
27 #include "displayport.h"
35 #define TRACE_ACCELERANT
36 #ifdef TRACE_ACCELERANT
37 # define TRACE(x...) _sPrintf("radeon_hd: " x)
39 # define TRACE(x...) ;
43 struct accelerant_info
* gInfo
;
44 display_info
* gDisplay
[MAX_DISPLAY
];
45 connector_info
* gConnector
[ATOM_MAX_SUPPORTED_DEVICE
];
46 gpio_info
* gGPIOInfo
[MAX_GPIO_PINS
];
54 area_id
Clone(const char* name
, void** _address
,
55 uint32 spec
, uint32 protection
,
58 {return fArea
< 0 ? (status_t
)fArea
: B_OK
;}
66 AreaCloner::AreaCloner()
73 AreaCloner::~AreaCloner()
81 AreaCloner::Clone(const char* name
, void** _address
, uint32 spec
,
82 uint32 protection
, area_id sourceArea
)
84 fArea
= clone_area(name
, _address
, spec
, protection
, sourceArea
);
99 /*! This is the common accelerant_info initializer. It is called by
100 both, the first accelerant and all clones.
103 init_common(int device
, bool isClone
)
105 // initialize global accelerant info structure
107 gInfo
= (accelerant_info
*)malloc(sizeof(accelerant_info
));
112 memset(gInfo
, 0, sizeof(accelerant_info
));
114 // malloc memory for active display information
115 for (uint32 id
= 0; id
< MAX_DISPLAY
; id
++) {
116 gDisplay
[id
] = (display_info
*)malloc(sizeof(display_info
));
117 if (gDisplay
[id
] == NULL
)
119 memset(gDisplay
[id
], 0, sizeof(display_info
));
121 gDisplay
[id
]->regs
= (register_info
*)malloc(sizeof(register_info
));
122 if (gDisplay
[id
]->regs
== NULL
)
124 memset(gDisplay
[id
]->regs
, 0, sizeof(register_info
));
127 // malloc for possible physical card connectors
128 for (uint32 id
= 0; id
< ATOM_MAX_SUPPORTED_DEVICE
; id
++) {
129 gConnector
[id
] = (connector_info
*)malloc(sizeof(connector_info
));
131 if (gConnector
[id
] == NULL
)
133 memset(gConnector
[id
], 0, sizeof(connector_info
));
135 gConnector
[id
]->encoder
.pll
.id
= ATOM_PPLL_INVALID
;
138 // malloc for card gpio pin information
139 for (uint32 id
= 0; id
< MAX_GPIO_PINS
; id
++) {
140 gGPIOInfo
[id
] = (gpio_info
*)malloc(sizeof(gpio_info
));
142 if (gGPIOInfo
[id
] == NULL
)
144 memset(gGPIOInfo
[id
], 0, sizeof(gpio_info
));
147 gInfo
->is_clone
= isClone
;
148 gInfo
->device
= device
;
150 gInfo
->dpms_mode
= B_DPMS_ON
;
153 // get basic info from driver
155 radeon_get_private_data data
;
156 data
.magic
= RADEON_PRIVATE_DATA_MAGIC
;
158 if (ioctl(device
, RADEON_GET_PRIVATE_DATA
, &data
,
159 sizeof(radeon_get_private_data
)) != 0) {
164 AreaCloner sharedCloner
;
165 gInfo
->shared_info_area
= sharedCloner
.Clone("radeon hd shared info",
166 (void**)&gInfo
->shared_info
, B_ANY_ADDRESS
, B_READ_AREA
| B_WRITE_AREA
,
167 data
.shared_info_area
);
168 status_t status
= sharedCloner
.InitCheck();
171 TRACE("%s, failed to create shared area\n", __func__
);
175 AreaCloner regsCloner
;
176 gInfo
->regs_area
= regsCloner
.Clone("radeon hd regs",
177 (void**)&gInfo
->regs
, B_ANY_ADDRESS
, B_READ_AREA
| B_WRITE_AREA
,
178 gInfo
->shared_info
->registers_area
);
179 status
= regsCloner
.InitCheck();
182 TRACE("%s, failed to create mmio area\n", __func__
);
186 gInfo
->rom_area
= clone_area("radeon hd AtomBIOS",
187 (void**)&gInfo
->rom
, B_ANY_ADDRESS
, B_READ_AREA
| B_WRITE_AREA
,
188 gInfo
->shared_info
->rom_area
);
190 if (gInfo
->rom_area
< 0) {
191 TRACE("%s: Clone of AtomBIOS failed!\n", __func__
);
192 gInfo
->shared_info
->has_rom
= false;
195 if (gInfo
->rom
[0] != 0x55 || gInfo
->rom
[1] != 0xAA)
196 TRACE("%s: didn't find a VGA bios in cloned region!\n", __func__
);
205 /*! Clean up data common to both primary and cloned accelerant */
210 delete_area(gInfo
->regs_area
);
211 delete_area(gInfo
->shared_info_area
);
212 delete_area(gInfo
->rom_area
);
214 gInfo
->regs_area
= gInfo
->shared_info_area
= -1;
216 // close the file handle ONLY if we're the clone
218 close(gInfo
->device
);
223 for (uint32 id
= 0; id
< MAX_DISPLAY
; id
++) {
224 if (gDisplay
[id
] != NULL
) {
225 free(gDisplay
[id
]->regs
);
230 for (uint32 id
= 0; id
< ATOM_MAX_SUPPORTED_DEVICE
; id
++)
231 free(gConnector
[id
]);
233 for (uint32 id
= 0; id
< MAX_GPIO_PINS
; id
++)
238 // #pragma mark - public accelerant functions
241 /*! Init primary accelerant */
243 radeon_init_accelerant(int device
)
245 TRACE("%s enter\n", __func__
);
247 status_t status
= init_common(device
, false);
251 radeon_shared_info
&info
= *gInfo
->shared_info
;
253 init_lock(&info
.accelerant_lock
, "radeon hd accelerant");
254 init_lock(&info
.engine_lock
, "radeon hd engine");
256 radeon_init_bios(gInfo
->rom
);
258 // probe firmware information
261 // find GPIO pins from AtomBIOS
264 // find physical card connectors from AtomBIOS
265 status
= connector_probe();
267 if (status
!= B_OK
) {
268 TRACE("%s: falling back to legacy connector probe.\n", __func__
);
269 status
= connector_probe_legacy();
272 if (status
!= B_OK
) {
273 TRACE("%s: couldn't detect supported connectors!\n", __func__
);
277 // print found connectors
280 // setup encoders on each connector if needed
283 // program external pll clock
286 // setup link on any DisplayPort connectors
287 dp_setup_connectors();
289 // detect attached displays
290 status
= detect_displays();
291 //if (status != B_OK)
294 // print found displays
297 // create initial list of video modes
298 status
= create_mode_list();
299 //if (status != B_OK) {
300 // radeon_uninit_accelerant();
304 radeon_gpu_mc_setup();
306 // Set up data crunching + irq rings
307 radeon_gpu_ring_setup();
309 radeon_gpu_ring_boot(RADEON_QUEUE_TYPE_GFX_INDEX
);
311 TRACE("%s done\n", __func__
);
316 /*! This function is called for both, the primary accelerant and all of
320 radeon_uninit_accelerant(void)
322 TRACE("%s enter\n", __func__
);
324 gInfo
->mode_list
= NULL
;
326 radeon_shared_info
&info
= *gInfo
->shared_info
;
328 uninit_lock(&info
.accelerant_lock
);
329 uninit_lock(&info
.engine_lock
);
332 TRACE("%s done\n", __func__
);
337 radeon_get_accelerant_device_info(accelerant_device_info
* di
)
339 radeon_shared_info
&info
= *gInfo
->shared_info
;
341 di
->version
= B_ACCELERANT_VERSION
;
342 strcpy(di
->name
, info
.deviceName
);
345 sprintf(chipset
, "%s", gInfo
->shared_info
->chipsetName
);
346 strcpy(di
->chipset
, chipset
);
348 // add flags onto chipset name
349 if ((info
.chipsetFlags
& CHIP_IGP
) != 0)
350 strcat(di
->chipset
, " IGP");
351 if ((info
.chipsetFlags
& CHIP_MOBILE
) != 0)
352 strcat(di
->chipset
, " Mobile");
353 if ((info
.chipsetFlags
& CHIP_APU
) != 0)
354 strcat(di
->chipset
, " APU");
356 strcpy(di
->serial_no
, "None" );
358 di
->memory
= gInfo
->shared_info
->graphics_memory_size
;