superio/fintek: Add support for f81966d
This patch adds support for the Fintek f81966d SuperIO, which is very similar to the fintek/f81866d. Datasheet: - Name: F81966D/A, Release Date: Oct 2023, Version: V0.21P BUG=NA TEST=Customer platform with F81966D, verified with 'superiotool -de' Change-Id: Ibe3987b6e15eb07b92d7f5a7de2bd511de85e2f7 Signed-off-by: Harrie Paijmans <hpaijmans@eltan.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/87198 Reviewed-by: Erik van den Bogaert <ebogaert@eltan.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Frans Hendriks <fhendriks@eltan.com> Reviewed-by: Maxim Polyakov <max.senia.poliak@gmail.com>
This commit is contained in:
parent
ace8bb45f7
commit
2057751509
10 changed files with 575 additions and 0 deletions
|
|
@ -11,3 +11,4 @@ subdirs-y += f71869ad
|
|||
subdirs-y += f81865f
|
||||
subdirs-y += f81866d
|
||||
subdirs-y += f81803a
|
||||
subdirs-y += f81966d
|
||||
|
|
|
|||
5
src/superio/fintek/f81966d/Kconfig
Normal file
5
src/superio/fintek/f81966d/Kconfig
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
config SUPERIO_FINTEK_F81966D
|
||||
bool
|
||||
select SUPERIO_FINTEK_COMMON_PRE_RAM
|
||||
4
src/superio/fintek/f81966d/Makefile.mk
Normal file
4
src/superio/fintek/f81966d/Makefile.mk
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
ramstage-$(CONFIG_SUPERIO_FINTEK_F81966D) += f81966d_hwm.c f81966d_uart.c f81966d_gpio.c
|
||||
ramstage-$(CONFIG_SUPERIO_FINTEK_F81966D) += superio.c
|
||||
83
src/superio/fintek/f81966d/chip.h
Normal file
83
src/superio/fintek/f81966d/chip.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef SUPERIO_FINTEK_F81966D_CHIP_H
|
||||
#define SUPERIO_FINTEK_F81966D_CHIP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct superio_fintek_f81966d_config {
|
||||
/* AMD TSI */
|
||||
uint8_t hwm_amd_tsi_addr;
|
||||
uint8_t hwm_amd_tsi_control;
|
||||
|
||||
/* Fan control */
|
||||
uint8_t hwm_fan_select;
|
||||
uint8_t hwm_fan_mode;
|
||||
uint8_t hwm_fan3_control;
|
||||
uint8_t hwm_fan2_temp_map_select;
|
||||
|
||||
uint8_t hwm_fan2_bound1;
|
||||
uint8_t hwm_fan2_bound2;
|
||||
uint8_t hwm_fan2_bound3;
|
||||
uint8_t hwm_fan2_bound4;
|
||||
uint8_t hwm_fan2_seg1_speed;
|
||||
uint8_t hwm_fan2_seg2_speed;
|
||||
uint8_t hwm_fan2_seg3_speed;
|
||||
uint8_t hwm_fan2_seg4_speed;
|
||||
uint8_t hwm_fan2_seg5_speed;
|
||||
|
||||
/* Temp sensor type */
|
||||
uint8_t hwm_temp_sens_type;
|
||||
|
||||
/* gpio control, range bits [0:7] map to GPIOx0:GPIOx7 */
|
||||
uint8_t use_gpio0;
|
||||
uint8_t gpio0_enable;
|
||||
uint8_t gpio0_data;
|
||||
uint8_t gpio0_drive;
|
||||
|
||||
uint8_t use_gpio1;
|
||||
uint8_t gpio1_enable;
|
||||
uint8_t gpio1_data;
|
||||
uint8_t gpio1_drive;
|
||||
|
||||
uint8_t use_gpio2;
|
||||
uint8_t gpio2_enable;
|
||||
uint8_t gpio2_data;
|
||||
|
||||
uint8_t use_gpio3;
|
||||
uint8_t gpio3_enable;
|
||||
uint8_t gpio3_data;
|
||||
uint8_t gpio3_drive;
|
||||
|
||||
uint8_t use_gpio4;
|
||||
uint8_t gpio4_enable;
|
||||
uint8_t gpio4_data;
|
||||
uint8_t gpio4_drive;
|
||||
|
||||
uint8_t use_gpio5;
|
||||
uint8_t gpio5_enable;
|
||||
uint8_t gpio5_data;
|
||||
uint8_t gpio5_drive;
|
||||
|
||||
uint8_t use_gpio6;
|
||||
uint8_t gpio6_enable;
|
||||
uint8_t gpio6_data;
|
||||
uint8_t gpio6_drive;
|
||||
|
||||
uint8_t use_gpio7;
|
||||
uint8_t gpio7_enable;
|
||||
uint8_t gpio7_data;
|
||||
uint8_t gpio7_drive;
|
||||
|
||||
uint8_t use_gpio8;
|
||||
uint8_t gpio8_enable;
|
||||
uint8_t gpio8_data;
|
||||
uint8_t gpio8_drive;
|
||||
|
||||
uint8_t use_gpio9;
|
||||
uint8_t gpio9_enable;
|
||||
uint8_t gpio9_data;
|
||||
uint8_t gpio9_drive;
|
||||
};
|
||||
|
||||
#endif /* SUPERIO_FINTEK_F81966D_CHIP_H */
|
||||
92
src/superio/fintek/f81966d/f81966d.h
Normal file
92
src/superio/fintek/f81966d/f81966d.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef SUPERIO_FINTEK_F81966_H
|
||||
#define SUPERIO_FINTEK_F81966_H
|
||||
|
||||
/*
|
||||
* Datasheet:
|
||||
* - Name: F81966D/A, Release Date: Oct 2023, Version: V0.21P
|
||||
*/
|
||||
|
||||
/* General registers */
|
||||
#define LDN_REG 0x07
|
||||
#define PORT_SELECT_REGISTER 0x27
|
||||
#define MULTI_FUNC_SEL1_REG 0x28
|
||||
#define MULTI_FUNC_SEL3_REG 0x29
|
||||
#define GPIO_FUNC_SEL_REG 0x2A /* differs on bank: 0=11/10 1=13/12 2=15/14 3=17/16 */
|
||||
#define MULTI_FUNC_SEL4_REG 0x2B
|
||||
#define MULTI_FUNC_SEL5_REG 0x2C
|
||||
#define IRQ_SHARE_REGISTER 0xF0
|
||||
#define FIFO_SEL_MODE 0xF6
|
||||
|
||||
/* Logical Device Numbers (LDN) */
|
||||
#define F81966D_SP1 0x10 /* UART1 */
|
||||
#define F81966D_SP2 0x11 /* UART2 */
|
||||
#define F81966D_SP3 0x12 /* UART3 */
|
||||
#define F81966D_SP4 0x13 /* UART4 */
|
||||
#define F81966D_SP5 0x14 /* UART5 */
|
||||
#define F81966D_SP6 0x15 /* UART6 */
|
||||
#define F81966D_PP 0x03 /* Parallel Port */
|
||||
#define F81966D_HWM 0x04 /* Hardware Monitor */
|
||||
#define F81966D_KBC 0x05 /* Keyboard/Mouse */
|
||||
#define F81966D_GPIO 0x06 /* General Purpose I/O (GPIO) */
|
||||
#define F81966D_WDT 0x07 /* Watchdog */
|
||||
#define F81966D_PME 0x0A /* Power Management Events (PME) */
|
||||
#define F81966D_SPI 0x0F /* SPI */
|
||||
|
||||
/* Register addresses for HWM */
|
||||
/* Choose between AMD and Intel */
|
||||
#define HWM_AMD_TSI_ADDR 0x08
|
||||
#define HWM_AMD_TSI_CONTROL_REG 0x0A
|
||||
/* Set temp sensors type */
|
||||
#define TEMP_SENS_TYPE_REG 0x6B
|
||||
/* FAN prog sel */
|
||||
#define HWM_FAN3_CONTROL 0x9A
|
||||
#define HWM_FAN_SEL 0x94
|
||||
#define HWM_FAN_MODE 0x96
|
||||
#define HWM_FAN2_TEMP_MAP_SEL 0xBF
|
||||
/* Fan 2 - 4 Boundaries */
|
||||
#define HWM_FAN2_BOUND1 0xB6
|
||||
#define HWM_FAN2_BOUND2 0xB7
|
||||
#define HWM_FAN2_BOUND3 0xB8
|
||||
#define HWM_FAN2_BOUND4 0xB9
|
||||
/* Fan 2 - 5 Segment speeds */
|
||||
#define HWM_FAN2_SEG1_SPEED_COUNT 0xBA
|
||||
#define HWM_FAN2_SEG2_SPEED_COUNT 0xBB
|
||||
#define HWM_FAN2_SEG3_SPEED_COUNT 0xBC
|
||||
#define HWM_FAN2_SEG4_SPEED_COUNT 0xBD
|
||||
#define HWM_FAN2_SEG5_SPEED_COUNT 0xBE
|
||||
|
||||
/* Register addresses for GPIO */
|
||||
/* GPIO registers */
|
||||
#define GPIO0X_OUTPUT_ENABLE_REGISTER 0xF0
|
||||
#define GPIO1X_OUTPUT_ENABLE_REGISTER 0xE0
|
||||
#define GPIO2X_OUTPUT_ENABLE_REGISTER 0xD0
|
||||
#define GPIO3X_OUTPUT_ENABLE_REGISTER 0xC0
|
||||
#define GPIO4X_OUTPUT_ENABLE_REGISTER 0xB0
|
||||
#define GPIO5X_OUTPUT_ENABLE_REGISTER 0xA0
|
||||
#define GPIO6X_OUTPUT_ENABLE_REGISTER 0x90
|
||||
#define GPIO7X_OUTPUT_ENABLE_REGISTER 0x80
|
||||
#define GPIO8X_OUTPUT_ENABLE_REGISTER 0x88
|
||||
#define GPIO9X_OUTPUT_ENABLE_REGISTER 0x98
|
||||
#define GPIO0X_OUTPUT_DATA_REGISTER 0xF1
|
||||
#define GPIO1X_OUTPUT_DATA_REGISTER 0xE1
|
||||
#define GPIO2X_OUTPUT_DATA_REGISTER 0xD1
|
||||
#define GPIO3X_OUTPUT_DATA_REGISTER 0xC1
|
||||
#define GPIO4X_OUTPUT_DATA_REGISTER 0xB1
|
||||
#define GPIO5X_OUTPUT_DATA_REGISTER 0xA1
|
||||
#define GPIO6X_OUTPUT_DATA_REGISTER 0x91
|
||||
#define GPIO7X_OUTPUT_DATA_REGISTER 0x81
|
||||
#define GPIO8X_OUTPUT_DATA_REGISTER 0x89
|
||||
#define GPIO9X_OUTPUT_DATA_REGISTER 0x99
|
||||
#define GPIO0X_DRIVE_ENABLE_REGISTER 0xF3
|
||||
#define GPIO1X_DRIVE_ENABLE_REGISTER 0xE3
|
||||
#define GPIO3X_DRIVE_ENABLE_REGISTER 0xC3
|
||||
#define GPIO4X_DRIVE_ENABLE_REGISTER 0xB3
|
||||
#define GPIO5X_DRIVE_ENABLE_REGISTER 0xA3
|
||||
#define GPIO6X_DRIVE_ENABLE_REGISTER 0x93
|
||||
#define GPIO7X_DRIVE_ENABLE_REGISTER 0x83
|
||||
#define GPIO8X_DRIVE_ENABLE_REGISTER 0x8B
|
||||
#define GPIO9X_DRIVE_ENABLE_REGISTER 0x9B
|
||||
|
||||
#endif /* SUPERIO_FINTEK_F81966_H */
|
||||
182
src/superio/fintek/f81966d/f81966d_gpio.c
Normal file
182
src/superio/fintek/f81966d/f81966d_gpio.c
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pnp.h>
|
||||
#include "fintek_internal.h"
|
||||
#include "chip.h"
|
||||
#include "f81966d.h"
|
||||
|
||||
/*
|
||||
* Set the values for the register using the mask
|
||||
* The mask has the writable bits high so the write the bits [3:2] & [0] the mask would be
|
||||
* 0xd = 0b00001101.
|
||||
*/
|
||||
void set_reg(struct device *dev, u8 port, u8 mask, u8 val)
|
||||
{
|
||||
u8 tmp = pnp_read_config(dev, port);
|
||||
pnp_write_config(dev, port, (tmp & ~mask) | (val & mask));
|
||||
}
|
||||
|
||||
/*
|
||||
* Select a bank as indicated by the spec.
|
||||
* Write the BANKID and 0 registers in the same call.
|
||||
*/
|
||||
u8 select_bank(struct device *dev, u8 bank)
|
||||
{
|
||||
if (bank > 3) {
|
||||
printk(BIOS_WARNING, "%s: GPIO Bank not in range.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
/* write 0x27[3:2] = BANKID, 0x27[0] = 0 */
|
||||
set_reg(dev, PORT_SELECT_REGISTER, 0x0D, (bank << 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* F81966D_gpio_init enables all necessary registers for GPIO
|
||||
* Fintek needs to know if pins are used as GPIO or UART pins
|
||||
* Share interrupt usage needs to be enabled
|
||||
*/
|
||||
void f81966d_gpio_init(struct device *dev)
|
||||
{
|
||||
struct superio_fintek_f81966d_config *conf = dev->chip_info;
|
||||
struct resource *res = probe_resource(dev, PNP_IDX_IO0);
|
||||
u8 tmp;
|
||||
|
||||
if (!res) {
|
||||
printk(BIOS_WARNING, "%s: No GPIO resource found.\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
pnp_enter_conf_mode(dev);
|
||||
|
||||
if (conf->use_gpio0) {
|
||||
select_bank(dev, 0);
|
||||
set_reg(dev, MULTI_FUNC_SEL5_REG, 0x1F, 0x1F);
|
||||
set_reg(dev, MULTI_FUNC_SEL1_REG, 0x0C, 0x00);
|
||||
|
||||
select_bank(dev, 1);
|
||||
set_reg(dev, MULTI_FUNC_SEL5_REG, 0x44, 0x0);
|
||||
|
||||
set_reg(dev, GPIO0X_OUTPUT_ENABLE_REGISTER, 0xFF, conf->gpio0_enable);
|
||||
set_reg(dev, GPIO0X_OUTPUT_DATA_REGISTER, 0xFF, conf->gpio0_data);
|
||||
set_reg(dev, GPIO0X_DRIVE_ENABLE_REGISTER, 0xFF, conf->gpio0_drive);
|
||||
}
|
||||
|
||||
if (conf->use_gpio1) {
|
||||
select_bank(dev, 0);
|
||||
set_reg(dev, GPIO_FUNC_SEL_REG, 0x77, 0x000);
|
||||
set_reg(dev, MULTI_FUNC_SEL1_REG, 0x8C, 0x00);
|
||||
set_reg(dev, MULTI_FUNC_SEL5_REG, 0x10, 0x0);
|
||||
|
||||
select_bank(dev, 1);
|
||||
set_reg(dev, MULTI_FUNC_SEL5_REG, 0x21, 0x0);
|
||||
set_reg(dev, MULTI_FUNC_SEL1_REG, 0x0C, 0x00);
|
||||
set_reg(dev, GPIO_FUNC_SEL_REG, 0x77, 0x000);
|
||||
|
||||
select_bank(dev, 2);
|
||||
set_reg(dev, GPIO_FUNC_SEL_REG, 0x77, 0x000);
|
||||
|
||||
select_bank(dev, 3);
|
||||
set_reg(dev, GPIO_FUNC_SEL_REG, 0x77, 0x000);
|
||||
|
||||
set_reg(dev, GPIO1X_OUTPUT_ENABLE_REGISTER, 0xFF, conf->gpio1_enable);
|
||||
set_reg(dev, GPIO1X_OUTPUT_DATA_REGISTER, 0xFF, conf->gpio1_data);
|
||||
set_reg(dev, GPIO1X_DRIVE_ENABLE_REGISTER, 0xFF, conf->gpio1_drive);
|
||||
}
|
||||
|
||||
if (conf->use_gpio2) {
|
||||
select_bank(dev, 2);
|
||||
set_reg(dev, MULTI_FUNC_SEL5_REG, 0xFF, 0xFF);
|
||||
select_bank(dev, 1);
|
||||
set_reg(dev, MULTI_FUNC_SEL5_REG, 0x02, 0x0);
|
||||
|
||||
set_reg(dev, GPIO2X_OUTPUT_ENABLE_REGISTER, 0xFF, conf->gpio2_enable);
|
||||
set_reg(dev, GPIO2X_OUTPUT_DATA_REGISTER, 0xFF, conf->gpio2_data);
|
||||
}
|
||||
|
||||
if (conf->use_gpio3) {
|
||||
select_bank(dev, 0);
|
||||
set_reg(dev, MULTI_FUNC_SEL3_REG, 0x30, 0x00);
|
||||
|
||||
set_reg(dev, GPIO3X_OUTPUT_ENABLE_REGISTER, 0xFF, conf->gpio3_enable);
|
||||
set_reg(dev, GPIO3X_OUTPUT_DATA_REGISTER, 0xFF, conf->gpio3_data);
|
||||
set_reg(dev, GPIO3X_DRIVE_ENABLE_REGISTER, 0xFF, conf->gpio3_drive);
|
||||
}
|
||||
|
||||
if (conf->use_gpio4) {
|
||||
select_bank(dev, 0);
|
||||
set_reg(dev, MULTI_FUNC_SEL3_REG, 0xC0, 0x00);
|
||||
|
||||
set_reg(dev, GPIO4X_OUTPUT_ENABLE_REGISTER, 0xFF, conf->gpio4_enable);
|
||||
set_reg(dev, GPIO4X_OUTPUT_DATA_REGISTER, 0xFF, conf->gpio4_data);
|
||||
set_reg(dev, GPIO4X_DRIVE_ENABLE_REGISTER, 0xFF, conf->gpio4_drive);
|
||||
}
|
||||
|
||||
if (conf->use_gpio5) {
|
||||
set_reg(dev, PORT_SELECT_REGISTER, 0x02, 0x00);
|
||||
|
||||
select_bank(dev, 0);
|
||||
set_reg(dev, MULTI_FUNC_SEL1_REG, 0x03, 0x00);
|
||||
select_bank(dev, 1);
|
||||
set_reg(dev, MULTI_FUNC_SEL1_REG, 0x10, 0x00);
|
||||
|
||||
/* set in/output pins */
|
||||
set_reg(dev, GPIO5X_OUTPUT_ENABLE_REGISTER, 0xFF, conf->gpio5_enable);
|
||||
set_reg(dev, GPIO5X_OUTPUT_DATA_REGISTER, 0xFF, conf->gpio5_data);
|
||||
set_reg(dev, GPIO5X_DRIVE_ENABLE_REGISTER, 0xFF, conf->gpio5_drive);
|
||||
}
|
||||
|
||||
if (conf->use_gpio6) {
|
||||
select_bank(dev, 0);
|
||||
set_reg(dev, MULTI_FUNC_SEL1_REG, 0x0C, 0x00);
|
||||
set_reg(dev, MULTI_FUNC_SEL4_REG, 0xE0, 0xE0);
|
||||
|
||||
set_reg(dev, GPIO6X_OUTPUT_ENABLE_REGISTER, 0xFF, conf->gpio6_enable);
|
||||
set_reg(dev, GPIO6X_OUTPUT_DATA_REGISTER, 0xFF, conf->gpio6_data);
|
||||
set_reg(dev, GPIO6X_DRIVE_ENABLE_REGISTER, 0xFF, conf->gpio6_drive);
|
||||
}
|
||||
|
||||
if (conf->use_gpio7) {
|
||||
select_bank(dev, 0);
|
||||
set_reg(dev, MULTI_FUNC_SEL1_REG, 0x20, 0x20);
|
||||
set_reg(dev, MULTI_FUNC_SEL4_REG, 0x01, 0x00);
|
||||
|
||||
set_reg(dev, GPIO7X_OUTPUT_ENABLE_REGISTER, 0xFF, conf->gpio7_enable);
|
||||
set_reg(dev, GPIO7X_OUTPUT_DATA_REGISTER, 0xFF, conf->gpio7_data);
|
||||
set_reg(dev, GPIO7X_DRIVE_ENABLE_REGISTER, 0xFF, conf->gpio7_drive);
|
||||
}
|
||||
|
||||
if (conf->use_gpio8) {
|
||||
select_bank(dev, 0);
|
||||
set_reg(dev, MULTI_FUNC_SEL1_REG, 0x60, 0x20);
|
||||
|
||||
set_reg(dev, GPIO8X_OUTPUT_ENABLE_REGISTER, 0xFF, conf->gpio8_enable);
|
||||
set_reg(dev, GPIO8X_OUTPUT_DATA_REGISTER, 0xFF, conf->gpio8_data);
|
||||
set_reg(dev, GPIO8X_DRIVE_ENABLE_REGISTER, 0xFF, conf->gpio8_drive);
|
||||
}
|
||||
|
||||
if (conf->use_gpio9) {
|
||||
select_bank(dev, 0);
|
||||
set_reg(dev, MULTI_FUNC_SEL4_REG, 0x02, 0x00);
|
||||
select_bank(dev, 1);
|
||||
set_reg(dev, MULTI_FUNC_SEL5_REG, 0x80, 0x00);
|
||||
select_bank(dev, 3);
|
||||
set_reg(dev, MULTI_FUNC_SEL4_REG, 0xFF, 0xFF);
|
||||
|
||||
set_reg(dev, GPIO9X_OUTPUT_ENABLE_REGISTER, 0xFF, conf->gpio8_enable);
|
||||
set_reg(dev, GPIO9X_OUTPUT_DATA_REGISTER, 0xFF, conf->gpio8_data);
|
||||
set_reg(dev, GPIO9X_DRIVE_ENABLE_REGISTER, 0xFF, conf->gpio8_drive);
|
||||
}
|
||||
|
||||
/* Select GPIO in LDN register */
|
||||
pnp_write_config(dev, LDN_REG, dev->path.pnp.device & 0xFF);
|
||||
/* Set IRQ trigger mode from active low to high (Bit 3) */
|
||||
tmp = pnp_read_config(dev, FIFO_SEL_MODE);
|
||||
pnp_write_config(dev, FIFO_SEL_MODE, tmp | 0x8);
|
||||
/* Enable share interrupt (Bit 0) */
|
||||
pnp_write_config(dev, IRQ_SHARE_REGISTER, 0x01);
|
||||
|
||||
pnp_exit_conf_mode(dev);
|
||||
}
|
||||
56
src/superio/fintek/f81966d/f81966d_hwm.c
Normal file
56
src/superio/fintek/f81966d/f81966d_hwm.c
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/* Setup only for Fan2
|
||||
* TODO: Add support for Fan1 and Fan3
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pnp.h>
|
||||
#include <superio/hwm5_conf.h>
|
||||
#include "fintek_internal.h"
|
||||
#include "chip.h"
|
||||
#include "f81966d.h"
|
||||
|
||||
void f81966d_hwm_init(struct device *dev)
|
||||
{
|
||||
struct resource *res = probe_resource(dev, PNP_IDX_IO0);
|
||||
|
||||
if (!res) {
|
||||
printk(BIOS_WARNING, "Super I/O HWM: No HWM resource found.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const struct superio_fintek_f81966d_config *reg = dev->chip_info;
|
||||
u16 port = res->base;
|
||||
|
||||
/* Use AMD TSI */
|
||||
pnp_write_hwm5_index(port, HWM_AMD_TSI_ADDR, reg->hwm_amd_tsi_addr);
|
||||
pnp_write_hwm5_index(port, HWM_AMD_TSI_CONTROL_REG, reg->hwm_amd_tsi_control);
|
||||
|
||||
/* Set temp1 sensor to thermistor */
|
||||
pnp_write_hwm5_index(port, TEMP_SENS_TYPE_REG, reg->hwm_temp_sens_type);
|
||||
|
||||
/* Select FAN Type */
|
||||
pnp_write_hwm5_index(port, HWM_FAN_SEL, reg->hwm_fan_select);
|
||||
|
||||
/* Select FAN Mode*/
|
||||
pnp_write_hwm5_index(port, HWM_FAN_MODE, reg->hwm_fan_mode);
|
||||
|
||||
/* Set Boundaries */
|
||||
pnp_write_hwm5_index(port, HWM_FAN2_BOUND1, reg->hwm_fan2_bound1);
|
||||
pnp_write_hwm5_index(port, HWM_FAN2_BOUND2, reg->hwm_fan2_bound2);
|
||||
pnp_write_hwm5_index(port, HWM_FAN2_BOUND3, reg->hwm_fan2_bound3);
|
||||
pnp_write_hwm5_index(port, HWM_FAN2_BOUND4, reg->hwm_fan2_bound4);
|
||||
|
||||
/* Set Speed */
|
||||
pnp_write_hwm5_index(port, HWM_FAN2_SEG1_SPEED_COUNT, reg->hwm_fan2_seg1_speed);
|
||||
pnp_write_hwm5_index(port, HWM_FAN2_SEG2_SPEED_COUNT, reg->hwm_fan2_seg2_speed);
|
||||
pnp_write_hwm5_index(port, HWM_FAN2_SEG3_SPEED_COUNT, reg->hwm_fan2_seg3_speed);
|
||||
pnp_write_hwm5_index(port, HWM_FAN2_SEG4_SPEED_COUNT, reg->hwm_fan2_seg4_speed);
|
||||
pnp_write_hwm5_index(port, HWM_FAN2_SEG5_SPEED_COUNT, reg->hwm_fan2_seg5_speed);
|
||||
|
||||
/* Set Fan control freq */
|
||||
pnp_write_hwm5_index(port, HWM_FAN3_CONTROL, reg->hwm_fan3_control);
|
||||
pnp_write_hwm5_index(port, HWM_FAN2_TEMP_MAP_SEL, reg->hwm_fan2_temp_map_select);
|
||||
}
|
||||
55
src/superio/fintek/f81966d/f81966d_uart.c
Normal file
55
src/superio/fintek/f81966d/f81966d_uart.c
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pnp.h>
|
||||
#include "fintek_internal.h"
|
||||
#include "chip.h"
|
||||
#include "f81966d.h"
|
||||
|
||||
/*
|
||||
* F81966D_uart_init enables all necessary registers for UART 3/4
|
||||
* Fintek needs to know if pins are used as GPIO or UART pins
|
||||
* Share interrupt usage needs to be enabled
|
||||
*/
|
||||
void f81966d_uart_init(struct device *dev)
|
||||
{
|
||||
struct resource *res = probe_resource(dev, PNP_IDX_IO0);
|
||||
u8 tmp;
|
||||
|
||||
if (!res) {
|
||||
printk(BIOS_WARNING, "%s: No UART resource found.\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
pnp_enter_conf_mode(dev);
|
||||
|
||||
/*
|
||||
* Set Port Select Register (Bit 0) = 0
|
||||
* before accessing Multi Function Select 3 Register
|
||||
*/
|
||||
tmp = pnp_read_config(dev, PORT_SELECT_REGISTER);
|
||||
pnp_write_config(dev, PORT_SELECT_REGISTER, tmp & 0xFE);
|
||||
|
||||
/* Set UART 3 function (Bit 4/5), otherwise pin 36-43 are GPIO */
|
||||
if (dev->path.pnp.device == F81966D_SP3) {
|
||||
tmp = pnp_read_config(dev, MULTI_FUNC_SEL3_REG);
|
||||
pnp_write_config(dev, MULTI_FUNC_SEL3_REG, tmp | 0x30);
|
||||
}
|
||||
|
||||
/* Set UART 4 function (Bit 6/7), otherwise pin 44-51 are GPIO */
|
||||
if (dev->path.pnp.device == F81966D_SP4) {
|
||||
tmp = pnp_read_config(dev, MULTI_FUNC_SEL3_REG);
|
||||
pnp_write_config(dev, MULTI_FUNC_SEL3_REG, tmp | 0xC0);
|
||||
}
|
||||
|
||||
/* Select UART X in LDN register */
|
||||
pnp_write_config(dev, LDN_REG, dev->path.pnp.device & 0xff);
|
||||
/* Set IRQ trigger mode from active low to high (Bit 3) */
|
||||
tmp = pnp_read_config(dev, FIFO_SEL_MODE);
|
||||
pnp_write_config(dev, FIFO_SEL_MODE, tmp | 0x8);
|
||||
/* Enable share interrupt (Bit 0) */
|
||||
pnp_write_config(dev, IRQ_SHARE_REGISTER, 0x01);
|
||||
|
||||
pnp_exit_conf_mode(dev);
|
||||
}
|
||||
15
src/superio/fintek/f81966d/fintek_internal.h
Normal file
15
src/superio/fintek/f81966d/fintek_internal.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef SUPERIO_FINTEK_F81966D_INTERNAL_H
|
||||
#define SUPERIO_FINTEK_F81966D_INTERNAL_H
|
||||
|
||||
#include <device/pnp.h>
|
||||
|
||||
void f81966d_hwm_init(struct device *dev);
|
||||
void f81966d_uart_init(struct device *dev);
|
||||
void f81966d_gpio_init(struct device *dev);
|
||||
|
||||
void set_reg(struct device *dev, u8 port, u8 mask, u8 val);
|
||||
u8 select_bank(struct device *dev, u8 bank);
|
||||
|
||||
#endif /* SUPERIO_FINTEK_F81966D_INTERNAL_H */
|
||||
82
src/superio/fintek/f81966d/superio.c
Normal file
82
src/superio/fintek/f81966d/superio.c
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <device/device.h>
|
||||
#include <device/pnp.h>
|
||||
#include <superio/conf_mode.h>
|
||||
#include <pc80/keyboard.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "fintek_internal.h"
|
||||
#include "f81966d.h"
|
||||
|
||||
static void f81966d_init(struct device *dev)
|
||||
{
|
||||
if (!dev->enabled)
|
||||
return;
|
||||
|
||||
switch (dev->path.pnp.device) {
|
||||
case F81966D_KBC:
|
||||
pc_keyboard_init(NO_AUX_DEVICE);
|
||||
break;
|
||||
case F81966D_HWM:
|
||||
/* Fixing temp sensor read out and init Fan control */
|
||||
f81966d_hwm_init(dev);
|
||||
break;
|
||||
case F81966D_SP1:
|
||||
/* Enable Uart1 and IRQ share register */
|
||||
f81966d_uart_init(dev);
|
||||
break;
|
||||
case F81966D_SP2:
|
||||
/* Enable Uart2 and IRQ share register */
|
||||
f81966d_uart_init(dev);
|
||||
break;
|
||||
case F81966D_SP3:
|
||||
/* Enable Uart3 and IRQ share register */
|
||||
f81966d_uart_init(dev);
|
||||
break;
|
||||
case F81966D_SP4:
|
||||
/* Enable Uart4 and IRQ share register */
|
||||
f81966d_uart_init(dev);
|
||||
break;
|
||||
case F81966D_GPIO:
|
||||
/* Enable GPIO */
|
||||
f81966d_gpio_init(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct device_operations ops = {
|
||||
.read_resources = pnp_read_resources,
|
||||
.set_resources = pnp_set_resources,
|
||||
.enable_resources = pnp_enable_resources,
|
||||
.enable = pnp_alt_enable,
|
||||
.init = f81966d_init,
|
||||
.ops_pnp_mode = &pnp_conf_mode_8787_aa,
|
||||
};
|
||||
|
||||
static struct pnp_info pnp_dev_info[] = {
|
||||
/* TODO: some of the 0x7f8 values may need to be corrected. */
|
||||
{ NULL, F81966D_SP1, PNP_IO0 | PNP_IRQ0, 0x7f8, },
|
||||
{ NULL, F81966D_SP2, PNP_IO0 | PNP_IRQ0, 0x7f8, },
|
||||
{ NULL, F81966D_SP3, PNP_IO0 | PNP_IRQ0, 0x7f8, },
|
||||
{ NULL, F81966D_SP4, PNP_IO0 | PNP_IRQ0, 0x7f8, },
|
||||
{ NULL, F81966D_SP5, PNP_IO0 | PNP_IRQ0, 0x7f8, },
|
||||
{ NULL, F81966D_SP6, PNP_IO0 | PNP_IRQ0, 0x7f8, },
|
||||
{ NULL, F81966D_KBC, PNP_IO0 | PNP_IRQ0 | PNP_IRQ1, 0x07ff, },
|
||||
{ NULL, F81966D_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, 0x07f8, },
|
||||
{ NULL, F81966D_HWM, PNP_IO0 | PNP_IRQ0, 0xff8, },
|
||||
{ NULL, F81966D_GPIO, PNP_IO0, 0xff8, },
|
||||
{ NULL, F81966D_PME, },
|
||||
{ NULL, F81966D_WDT, },
|
||||
{ NULL, F81966D_SPI, },
|
||||
};
|
||||
|
||||
static void enable_dev(struct device *dev)
|
||||
{
|
||||
pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
|
||||
}
|
||||
|
||||
struct chip_operations superio_fintek_f81966d_ops = {
|
||||
.name = "Fintek F81966D-I Super I/O",
|
||||
.enable_dev = enable_dev
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue