예제 #1
0
파일: nc_fpga.c 프로젝트: Oxyoptia/coreboot
static void init_fan_ctrl (void *base_adr)
{
	uint8_t mask = 0, freeze_mode = 0, fan_req = 0;
	volatile fan_ctrl_t *ctrl = (fan_ctrl_t *)base_adr;

	/* Program all needed fields of FAN controller. */
	FPGA_SET_PARAM(FANSensorSelect, ctrl->sensorselect);
	FPGA_SET_PARAM(T_Warn, ctrl->t_warn);
	FPGA_SET_PARAM(T_Crit, ctrl->t_crit);
	FPGA_SET_PARAM(FANSamplingTime, ctrl->samplingtime);
	FPGA_SET_PARAM(FANSetPoint, ctrl->setpoint);
	FPGA_SET_PARAM(FANHystCtrl, ctrl->hystctrl);
	FPGA_SET_PARAM(FANHystVal, ctrl->hystval);
	FPGA_SET_PARAM(FANHystThreshold, ctrl->hystthreshold);
	FPGA_SET_PARAM(FANKp, ctrl->kp);
	FPGA_SET_PARAM(FANKi, ctrl->ki);
	FPGA_SET_PARAM(FANKd, ctrl->kd);
	FPGA_SET_PARAM(FANMaxSpeed, ctrl->fanmax);
	/* Set freeze and FAN configuration. */
	if ((hwilib_get_field(FF_FanReq, &fan_req, 1) == 1) &&
	    (hwilib_get_field(FF_FreezeDis, &freeze_mode, 1) == 1)) {
		if (!fan_req)
			mask = 1;
		else if  (fan_req && freeze_mode)
			mask = 2;
		else
			mask = 3;
		ctrl->fanmon = mask << 10;
	}
}
예제 #2
0
파일: nc_fpga.c 프로젝트: Oxyoptia/coreboot
static void init_temp_mon (void *base_adr)
{
	uint32_t cc[5], i = 0;
	uint8_t num = 0;
	volatile fan_ctrl_t *ctrl = (fan_ctrl_t *)base_adr;

	/* Program sensor delay first. */
	FPGA_SET_PARAM(FANSensorDelay, ctrl->sensordelay);
	/* Program correction curve for every used sensor. */
	if (hwilib_get_field(FANSensorNum, &num, sizeof(num) != sizeof(num)) ||
	    (num == 0) || (num > MAX_NUM_SENSORS))
		return;
	for (i = 0; i < num; i ++) {
		if (hwilib_get_field(FANSensorCfg0 + i, (uint8_t *)&cc[0],
		    sizeof(cc)) == sizeof(cc)) {
			ctrl->sensorcfg[cc[0]].rmin = cc[1] & 0xffff;
			ctrl->sensorcfg[cc[0]].rmax = cc[2] & 0xffff;
			ctrl->sensorcfg[cc[0]].nmin = cc[3] & 0xffff;
			ctrl->sensorcfg[cc[0]].nmax = cc[4] & 0xffff;
		}
	}
	ctrl->sensornum = num;
}
예제 #3
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");
}
예제 #4
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;
}