2 *-----------------------------------------------------------------------------
5 *-----------------------------------------------------------------------------
6 * Copyright (c) 2002-2010, Intel Corporation.
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 *-----------------------------------------------------------------------------
29 *-----------------------------------------------------------------------------
32 #define MODULE_NAME hal.init
41 #include <igd_errno.h>
50 #include <plb/context.h>
52 #include "../cmn/init_dispatch.h"
53 #include "linux/pci_regs.h"
55 * @addtogroup core_group
59 static int bus_master_enable_plb(platform_context_plb_t *platform_context);
60 static int full_config_vga_plb(igd_context_t *context,
61 init_dispatch_t *dispatch);
62 static int get_stolen_mem_plb(igd_context_t *context, unsigned long *pages);
64 int full_get_param_plb(igd_context_t *context,
66 unsigned long *value);
74 * @return -IGD_ERROR_NODEV on failure
75 * @return 0 on success
77 int get_revision_id_plb(igd_context_t *context,
83 if(OS_PCI_READ_CONFIG_8(vga_dev, PCI_RID,
84 (unsigned char *)&context->device_context.rid)) {
85 EMGD_ERROR_EXIT("Error occured reading RID");
86 return -IGD_ERROR_NODEV;
89 EMGD_DEBUG(" rid = 0x%lx", context->device_context.rid);
100 * @return 1 on failure
101 * @return 0 on success
103 int full_config_plb(igd_context_t *context,
104 init_dispatch_t *dispatch)
106 unsigned long /* FIXME - reserved_mem, */ graphics_frequency ;
107 platform_context_plb_t *platform_context;
112 platform_context = (platform_context_plb_t *)context->platform_context;
115 _msvdx_base = 0x50000;
118 * Enable bus mastering for platforms whose BIOS did not perform this
121 ret = bus_master_enable_plb(platform_context);
123 EMGD_ERROR("Error: Enabling bus master");
127 ret = full_config_vga_plb(context, dispatch);
129 EMGD_ERROR_EXIT("Config VGA Failed");
133 get_stolen_mem_plb(context, &context->device_context.reserved_mem);
135 #if 0 /* FIXME - WHY IS THIS RETURNING 0 AND SETTING reserved_mem TO 0 ALSO? */
136 /* Get mem reservation param if it exists */
137 if(!full_get_param_plb(context, IGD_PARAM_MEM_RESERVATION,
139 context->device_context.reserved_mem = reserved_mem;
143 /* Get graphics frequency param if it exists */
144 if(!full_get_param_plb(context, IGD_PARAM_GFX_FREQ,
145 &graphics_frequency)) {
146 context->device_context.gfx_freq = (unsigned short)graphics_frequency;
155 * @param platform_context
157 * @return -1 on failure
158 * @return 0 on success
160 static int bus_master_enable_plb(platform_context_plb_t *platform_context){
166 ret = OS_PCI_READ_CONFIG_8(platform_context->pcidev0, PCI_COMMAND_MASTER, &tmp);
168 EMGD_ERROR_EXIT("PCI read of bus master");
173 * Get Bit 2, 1, and 0 and see if it is == 1
174 * all 3 bits has to be enabled. This is to enable register read/write
175 * in the case of a PCI card being added
177 if((tmp & 0x7) != 0x7 ) {
180 ret = OS_PCI_WRITE_CONFIG_8(platform_context->pcidev0, PCI_COMMAND_MASTER, tmp);
182 EMGD_ERROR_EXIT("PCI write of bus master");
196 * @return -IGD_ERROR_NODEV on failure
197 * @return 0 on success
199 static int full_config_vga_plb(igd_context_t *context,
200 init_dispatch_t *dispatch)
202 platform_context_plb_t *platform_context =
203 (platform_context_plb_t *)context->platform_context;
207 if(OS_PCI_READ_CONFIG_32(platform_context->pcidev0,
208 PLB_PCI_MMADR, (void*)&context->device_context.mmadr)) {
209 EMGD_ERROR_EXIT("Reading MMADR");
210 return -IGD_ERROR_NODEV;
213 context->device_context.mmadr &= 0xfffffff9;
214 context->device_context.virt_mmadr =
215 OS_MAP_IO_TO_MEM_NOCACHE(context->device_context.mmadr, PLB_MMIO_SIZE);
217 if (!context->device_context.virt_mmadr) {
218 EMGD_ERROR_EXIT("Failed to map MMADR");
219 return -IGD_ERROR_NODEV;
222 EMGD_DEBUG("mmadr mapped %dKB @ (phys):0x%lx (virt):%p",
224 context->device_context.mmadr,
225 context->device_context.virt_mmadr);
227 /* PCI Interrupt Line */
228 if(OS_PCI_READ_CONFIG_8(platform_context->pcidev0,
229 PCI_INTERRUPT_LINE, (void*)&platform_context->irq)) {
230 platform_context->irq = 0;
238 * Get the # of pages used for video memory. This does not use information from
239 * the scratch register, since this is done later if it exists.
244 * @return -IGD_ERROR_INVAL on failure
245 * @return 0 on success
247 static int get_stolen_mem_plb(igd_context_t *context, unsigned long *pages)
249 platform_context_plb_t *platform_context;
250 os_pci_dev_t vga_dev;
251 unsigned short gmch_ctl;
252 unsigned long stolen_mem; /* in bytes */
257 platform_context = (platform_context_plb_t *)context->platform_context;
258 vga_dev = platform_context->pcidev0;
260 ret = OS_PCI_READ_CONFIG_16(vga_dev, PLB_PCI_GC, &gmch_ctl);
262 EMGD_ERROR_EXIT("Unable to read PLB_PCI_GC");
263 return -IGD_ERROR_INVAL;
266 switch (gmch_ctl & 0x70) {
272 stolen_mem = 1*1024*1024;
276 stolen_mem = 4*1024*1024;
280 stolen_mem = 8*1024*1024;
284 stolen_mem = 16*1024*1024;
288 stolen_mem = 32*1024*1024;
292 stolen_mem = 48*1024*1024;
295 stolen_mem = 64*1024*1024;
298 EMGD_ERROR_EXIT("Unknown Stolen Memory Size");
299 return -IGD_ERROR_INVAL;
304 * Subtract off the size of the GTT which is
305 * (number of entries in DWORDS) * 4 to get it into bytes
307 stolen_mem -= context->device_context.gatt_pages*4;
308 /* Subtract off 1 page for the scratch page */
309 stolen_mem -= 4*1024;
312 /* Convert to the # of pages available for stolen memory */
313 *pages = stolen_mem / 4096;
315 EMGD_DEBUG("Stolen memory: 0x%lx pages", *pages);
327 * @return -IGD_ERROR_INVAL on failure
328 * @return 0 on success
330 int full_get_param_plb(igd_context_t *context,
332 unsigned long *value)
336 unsigned long control_reg;
340 EMGD_DEBUG("ID: 0x%lx", id);
342 /* Scratch registers used as below:
346 * Bits 31-16 - EID Firmware identifier 0xE1DF
347 * Bits 15-00 - Tell what data is present.
348 * Here are bits for what we are using know:
350 * Bit 1 - List of ports for which displays are attached
351 * Bit 2 - Memory reservation
352 * If any of the above bits is set that mean data is followed
353 * in the next registers.
357 * Bits 07-00 - Panel Id
358 * Bits 11-08 - Port list
359 * Information for Port list: If any of the bit is set means,
360 * a display is attached to that port as follows:
362 * Bit 09 - DVOA/Internal LVDS
368 * Bits 15-00 - Reserved Memory value in number of 4k size pages
370 mmio = context->device_context.virt_mmadr;
371 control_reg = EMGD_READ32(EMGD_MMIO(mmio) + 0x71410);
375 case IGD_PARAM_PANEL_ID:
377 * Check for Embedded firmware
379 if ((control_reg>>16) != 0xE1DF) {
380 EMGD_DEBUG("No Embedded vBIOS found");
382 return -IGD_ERROR_INVAL;
386 * The panel id bit must be set in the control register
387 * to indicate valid panel (config) ID value.
389 if (control_reg & 0x1) {
390 *value = EMGD_READ32(EMGD_MMIO(mmio) + 0x71414) & 0xFF;
392 /* we cannot allow for config id = 0 */
393 ret = -IGD_ERROR_INVAL;
396 EMGD_DEBUG("Panel ID read failed: Incorrect Operation");
397 ret = -IGD_ERROR_INVAL;
400 case IGD_PARAM_MEM_RESERVATION:
402 * Check for Embedded firmware
404 if ((control_reg>>16) != 0xE1DF) {
405 EMGD_DEBUG("No Embedded vBIOS found");
407 return -IGD_ERROR_INVAL;
411 * The mem reservation bit must be set in the control register
412 * to indicate valid mem reservation value.
414 if (control_reg & 0x4) {
415 *value = (EMGD_READ32(EMGD_MMIO(mmio) + 0x71418) & 0xFFFF);
417 EMGD_DEBUG("Mem Reservation read failed: Incorrect Operation");
418 ret = -IGD_ERROR_INVAL;
422 ret = -IGD_ERROR_INVAL;
436 void full_shutdown_plb(igd_context_t *context)
438 platform_context_plb_t *platform_context =
439 (platform_context_plb_t *)context->platform_context;
443 /* unmap registers */
444 if(context->device_context.virt_mmadr) {
445 EMGD_DEBUG("Unmapping Gfx registers and GTT Table...");
446 OS_UNMAP_IO_FROM_MEM((void *) context->device_context.virt_mmadr,
448 OS_UNMAP_IO_FROM_MEM((void *)context->device_context.virt_gttadr,
449 context->device_context.gatt_pages * 4);
451 printk(KERN_ERR "Unmapping MMIO space failed.\n");
454 if (platform_context) {
455 OS_PCI_FREE_DEVICE(platform_context->pcidev0);