/*! * This function is directly exported. * * @param found_device * @param pdev * * @return igd_driver_h * @return NULL on failure */ igd_driver_h igd_driver_init( igd_init_info_t *init_info ) { igd_context_t *context; os_pci_dev_t pdev = (os_pci_dev_t)NULL; os_pci_dev_t vga_disable_dev; iegd_pci_t *found_device; int ret; int i; EMGD_TRACE_ENTER; /* Allocate a context */ context = (void *) OS_ALLOC(sizeof(igd_context_t)); fixme_vbios_context = context; if(!context) { EMGD_ERROR_EXIT("igd_driver_init failed to create context"); return NULL; } OS_MEMSET(context, 0, sizeof(igd_context_t)); /* Search VGA devices for a supported one */ ret = detect_device(&found_device, &pdev); if(ret) { OS_FREE(context); return NULL; } /* * Some platforms (currently only Atom E6xx) use two PCI devices (the * second device being for SDVO) and this causes the VGA arbiter to get * involved. Legacy VGA decoding must be disabled for all PCI devices * except one, otherwise the VGA arbiter will prevent DRI usage in the * X server. */ for (i = 0; i < MAX_LEGACY_VGA_DISABLE; i++) { vga_disable_dev = os_pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_SDVO_TNC, 0xFFFF, 0, 0, NULL); if (vga_disable_dev) { printk(KERN_INFO "VGA arbiter detected; disabling legacy VGA" " decoding on SDVO device\n"); os_pci_disable_legacy_vga_decoding(vga_disable_dev); os_pci_free_device(vga_disable_dev); } } context->device_context.did = found_device->device_id; init_dispatch = (init_dispatch_t *)dispatch_acquire(context, init_dispatch_table); if(!init_dispatch) { EMGD_ERROR_EXIT("No dispatch found for listed device"); return NULL; } ret = init_dispatch->query(context, init_dispatch, pdev, &init_info->bus, &init_info->slot, &init_info->func); if(ret) { OS_FREE(context); EMGD_ERROR_EXIT("Device Dependent Query Failed"); return NULL; } /* init info */ init_info->vendor_id = found_device->vendor_id; init_info->device_id = found_device->device_id; init_info->name = init_dispatch->name; init_info->chipset = init_dispatch->chipset; init_info->default_pd_list = init_dispatch->default_pd_list; EMGD_TRACE_EXIT; return (igd_driver_h)context; }
/*! * This function is used to initialize any module/dsp * module specific structures or tables etc. * * @param context SS level igd_context. * * @return 0 on success. * @return -IGD_INVAL or -IGD_ERROR_NODEV on failure */ int mode_init(igd_context_t *context) { igd_dispatch_t *dispatch = &context->dispatch; inter_module_dispatch_t *md; EMGD_TRACE_ENTER; EMGD_DEBUG("Allocating a mode context..."); /* Clear the allocated memory for mode context */ OS_MEMSET((void *)mode_context, 0, sizeof(mode_context_t)); /* Set the pointer to igd level context */ mode_context->context = context; mode_context->first_alter = TRUE; mode_context->display_color = context->mod_dispatch.init_params->display_color; mode_context->ref_freq = context->mod_dispatch.init_params->ref_freq; mode_context->tuning_wa = context->mod_dispatch.init_params->tuning_wa; /* Get mode's dispatch table */ mode_context->dispatch = (mode_dispatch_t *) dispatch_acquire(context, mode_dispatch); if(!mode_context->dispatch) { EMGD_ERROR_EXIT("Unsupported Device"); return -IGD_ERROR_NODEV; } md = &context->mod_dispatch; /* Set the fw_info to 0 */ mode_context->fw_info = NULL; /* Hook up the IGD dispatch table entires for mode */ dispatch->get_EDID_block = igd_get_EDID_block; dispatch->power_display = igd_power_display; dispatch->query_mode_list = igd_query_mode_list; dispatch->alter_displays = igd_alter_displays; OPT_MICRO_CALL(full_mode_init(context, mode_context)); /* Hook up inter-module dispatch functions */ md->mode_get_gpio_sets = mode_context->dispatch->get_gpio_sets; md->mode_reset_plane_pipe_ports = mode_context->dispatch->reset_plane_pipe_ports; md->filter_modes = mode_context->dispatch->filter_modes; /* Hook up Core specific IGD dispatch table entries */ dispatch->set_palette_entries = mode_context->dispatch->full->set_palette_entries; dispatch->set_palette_entry = mode_context->dispatch->set_palette_entry; dispatch->get_palette_entry = mode_context->dispatch->get_palette_entry; dispatch->wait_vblank = mode_context->dispatch->wait_vblank; /* Initialize dsp module */ if (dsp_init(context)) { EMGD_ERROR("dsp_init() failed."); return -IGD_INVAL; } /* Initialze port interface (pi) module */ if (pi_init(context)) { EMGD_ERROR_EXIT("pi_init() failed."); if(md->dsp_shutdown) { md->dsp_shutdown(context); } return -IGD_ERROR_INVAL; } if (mode_context->dispatch->full && md->reg_get_mod_state) { /* Save mode state */ module_state_h *state = NULL; unsigned long *flags = NULL; md->reg_get_mod_state(REG_MODE_STATE, &state, &flags); md->mode_save(context, state, flags); } /* Initialize the Display Configuration List */ /* FIXME: This should be done in dsp init */ dsp_dc_init(context); EMGD_TRACE_EXIT; return 0; }