예제 #1
0
/*!
 * 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;
}
예제 #2
0
/*!
 * 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;
}