Пример #1
0
/** \brief This function is the driver entry point for the init phase
 *         of the PCI bus allocator. It will initialize all the needed parts
 *         of NC_FPGA.
 * @param  *dev  Pointer to the used PCI device
 * @return void  Nothing is given back
 */
static void nc_fpga_init(struct device *dev)
{
	void *bar0_ptr = NULL;
	uint8_t cmd_reg;
	uint32_t cap = 0;

	/* All we need is mapped to BAR 0, get the address. */
	bar0_ptr = (void *)(pci_read_config32(dev, PCI_BASE_ADDRESS_0) &
				~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
	cmd_reg = pci_read_config8(dev, PCI_COMMAND);
	/* Ensure BAR0 has a valid value. */
	if (!bar0_ptr || !(cmd_reg & PCI_COMMAND_MEMORY))
		return;
	/* Ensure this is really a NC FPGA by checking magic register. */
	if (read32(bar0_ptr + NC_MAGIC_OFFSET) != NC_FPGA_MAGIC)
		return;
	/* Open hwinfo block. */
	if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
		return;
	/* Set up FAN controller and temperature monitor according to */
	/* capability bits. */
	cap = read32(bar0_ptr + NC_CAP1_OFFSET);
	if (cap & (NC_CAP1_TEMP_MON | NC_CAP1_FAN_CTRL))
		init_temp_mon(bar0_ptr + NC_FANMON_CTRL_OFFSET);
	if (cap & NC_CAP1_FAN_CTRL)
		init_fan_ctrl(bar0_ptr + NC_FANMON_CTRL_OFFSET);
}
Пример #2
0
static void wait_for_legacy_dev(void *unused)
{
	uint32_t legacy_delay, us_since_boot;
	struct stopwatch sw;

	/* Open main hwinfo block. */
	if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
		return;

	/* Get legacy delay parameter from hwinfo. */
	if (hwilib_get_field(LegacyDelay, (uint8_t *) &legacy_delay,
			      sizeof(legacy_delay)) != sizeof(legacy_delay))
		return;

	us_since_boot = get_us_since_boot();
	/* No need to wait if the time since boot is already long enough.*/
	if (us_since_boot > legacy_delay)
		return;
	stopwatch_init_msecs_expire(&sw, (legacy_delay - us_since_boot) / 1000);
	printk(BIOS_NOTICE, "Wait remaining %d of %d us for legacy devices...",
			legacy_delay - us_since_boot, legacy_delay);
	stopwatch_wait_until_expired(&sw);
	printk(BIOS_NOTICE, "done!\n");
}
Пример #3
0
/** \brief This functions sets up the DP2LVDS-converter to be used with the
 *         appropriate lcd panel
 * @param  *hwi_block	Filename in CBFS of the block to use as HW-Info
 * @return		0 on success or error code
 */
int ptn3460_init(char *hwi_block)
{
	struct ptn_3460_config cfg;
	int status;
	uint8_t disp_con = 0, color_depth = 0;
	uint8_t edid_data[0x80];
	uint8_t hwid[4], tcu31_hwid[4] = {7, 9, 2, 0};

	if (!hwi_block || hwilib_find_blocks(hwi_block) != CB_SUCCESS) {
		printk(BIOS_ERR, "LCD: Info block \"%s\" not found!\n",
			hwi_block);
		return 1;
	}

	status = i2c_init(PTN_I2C_CONTROLER);
	if (status)
		return (PTN_BUS_ERROR | status);

	/* Get all needed information from hwinfo block */
	if (hwilib_get_field(Edid, edid_data, 0x80) != sizeof(edid_data)) {
		printk(BIOS_ERR, "LCD: No EDID data available in %s\n",
			hwi_block);
		return 1;
	}
	if ((hwilib_get_field(PF_DisplCon, &disp_con, 1) != 1)) {
		printk(BIOS_ERR, "LCD: Missing panel features from %s\n",
			hwi_block);
		return 1;
	}
	if (hwilib_get_field(PF_Color_Depth ,&color_depth, 1) != 1) {
		printk(BIOS_ERR, "LCD: Missing panel features from %s\n",
			hwi_block);
		return 1;
	}
	if (hwilib_get_field(HWID, hwid, sizeof(hwid)) != sizeof(hwid)) {
		printk(BIOS_ERR, "LCD: Missing HW-ID from %s\n",
			hwi_block);
		return 1;
	}
	/* Here, all the desired information for setting up DP2LVDS converter*/
	/* are present. Inside the converter, table 6 will be used for */
	/* the timings. */
	if ((status = ptn3460_write_edid(6, edid_data)) != 0)
		return status;
	/* Select this table to be emulated */
	ptn_select_edid(6);
	/* Read PTN configuration data */
	status = i2c_read(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF,
			  (u8*)&cfg, PTN_CONFIG_LEN);
	if (status)
		return (PTN_BUS_ERROR | status);

	/* Set up configuration data according to the hwinfo blocks we get */
	cfg.dp_interface_ctrl = 0;
	cfg.lvds_interface_ctrl1 = 0x00;
	if (disp_con == PF_DISPLCON_LVDS_DUAL)
		cfg.lvds_interface_ctrl1 |= 0x0b; /* Turn on dual LVDS lane and clock */
	if (color_depth == PF_COLOR_DEPTH_6BIT)
		cfg.lvds_interface_ctrl1 |= 0x20; /* Use 18 bits per pixel */

	cfg.lvds_interface_ctrl2 = 0x03;  /* no clock spreading, 300 mV LVDS swing */
	if (memcmp(hwid, tcu31_hwid, sizeof(hwid)))
		cfg.lvds_interface_ctrl3 = 0x00;  /* no LVDS signal swap */
	else
		cfg.lvds_interface_ctrl3 = 0x01;  /* swap LVDS even and odd */
	cfg.t2_delay = 1;		  /* Delay T2 (VDD to LVDS active) by 16 ms */
	cfg.t3_timing = 10;		  /* 500 ms from LVDS to backlight active */
	cfg.t12_timing = 20;		  /* 1 second re-power delay */
	cfg.t4_timing = 3;		  /* 150 ms backlight off to LVDS inactive */
	cfg.t5_delay = 1;		  /* Delay T5 (LVDS to VDD inactive) by 16 ms */
	cfg.backlight_ctrl = 0;		  /* Enable backlight control */

	/* Write back configuration data to PTN3460 */
	status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF,
			   (u8*)&cfg, PTN_CONFIG_LEN);
	if (status)
		return (PTN_BUS_ERROR | status);
	else
		return PTN_NO_ERROR;
}