coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mainboard.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <string.h>
4 #include <types.h>
5 #include <device/device.h>
6 #include <console/console.h>
8 #include <option.h>
9 #include <superio/hwm5_conf.h>
11 
12 /* Hardware Monitor */
13 
14 static u16 hwm_base = 0xa00;
15 
16 #define FAN_CRUISE_CONTROL_DISABLED 0
17 #define FAN_CRUISE_CONTROL_SPEED 1
18 #define FAN_CRUISE_CONTROL_THERMAL 2
19 #define FAN_SPEED_5625 0
20 
21 struct fan_speed {
22  u8 fan_in;
23  u16 fan_speed;
24 };
25 
26 /* FANIN Target Speed Register */
27 /* FANIN = 337500 / RPM */
28 struct fan_speed fan_speeds[] = {
29  { 0x3c, 5625 }, { 0x41, 5192 }, { 0x47, 4753 }, { 0x4e, 4326 },
30  { 0x56, 3924 }, { 0x5f, 3552 }, { 0x69, 3214 }, { 0x74, 2909 },
31  { 0x80, 2636 }, { 0x8d, 2393 }, { 0x9b, 2177 }, { 0xaa, 1985 },
32  { 0xba, 1814 }, { 0xcb, 1662 }, { 0xdd, 1527 }, { 0xf0, 1406 }
33 };
34 
35 struct temperature {
38 };
39 
40 struct temperature temperatures[] = {
41  { 30, 86 }, { 33, 91 }, { 36, 96 }, { 39, 102 },
42  { 42, 107 }, { 45, 113 }, { 48, 118 }, { 51, 123 },
43  { 54, 129 }, { 57, 134 }, { 60, 140 }, { 63, 145 },
44  { 66, 150 }, { 69, 156 }, { 72, 161 }, { 75, 167 }
45 };
46 
47 static void hwm_setup(void)
48 {
49  unsigned int cpufan_control = 0, sysfan_control = 0;
50  unsigned int cpufan_speed = 0, sysfan_speed = 0;
51  unsigned int cpufan_temperature = 0, sysfan_temperature = 0;
52 
53  cpufan_control = get_uint_option("cpufan_cruise_control", FAN_CRUISE_CONTROL_DISABLED);
54  cpufan_speed = get_uint_option("cpufan_speed", FAN_SPEED_5625);
55 
56  sysfan_control = get_uint_option("sysfan_cruise_control", FAN_CRUISE_CONTROL_DISABLED);
57  sysfan_speed = get_uint_option("sysfan_speed", FAN_SPEED_5625);
58 
60  pnp_write_hwm5_index(hwm_base, 0x59, 0x20); /* Diode Selection */
61  pnp_write_hwm5_index(hwm_base, 0x5d, 0x0f); /* All Sensors Diode, not Thermistor */
62 
64  pnp_write_hwm5_index(hwm_base, 0x54, 0xf1); /* SYSTIN temperature offset */
65  pnp_write_hwm5_index(hwm_base, 0x55, 0x19); /* CPUTIN temperature offset */
66  pnp_write_hwm5_index(hwm_base, 0x56, 0xfc); /* AUXTIN temperature offset */
67 
68  nuvoton_hwm_select_bank(hwm_base, 0x80); /* Default */
69 
70  u8 fan_config = 0;
71  /* 00 FANOUT is Manual Mode */
72  /* 01 FANOUT is Thermal Cruise Mode */
73  /* 10 FANOUT is Fan Speed Cruise Mode */
74  switch (cpufan_control) {
75  case FAN_CRUISE_CONTROL_SPEED: fan_config |= (2 << 4); break;
76  case FAN_CRUISE_CONTROL_THERMAL: fan_config |= (1 << 4); break;
77  }
78  switch (sysfan_control) {
79  case FAN_CRUISE_CONTROL_SPEED: fan_config |= (2 << 2); break;
80  case FAN_CRUISE_CONTROL_THERMAL: fan_config |= (1 << 2); break;
81  }
82  /* This register must be written first */
83  pnp_write_hwm5_index(hwm_base, 0x04, fan_config);
84 
85  switch (cpufan_control) {
86  case FAN_CRUISE_CONTROL_SPEED: /* CPUFANIN target speed */
87  printk(BIOS_DEBUG, "Fan Cruise Control setting CPU fan to %d RPM\n",
88  fan_speeds[cpufan_speed].fan_speed);
89  pnp_write_hwm5_index(hwm_base, 0x06, fan_speeds[cpufan_speed].fan_in);
90  break;
91  case FAN_CRUISE_CONTROL_THERMAL: /* CPUFANIN target temperature */
92  printk(BIOS_DEBUG, "Fan Cruise Control setting CPU fan to activation at %d deg C/%d deg F\n",
93  temperatures[cpufan_temperature].deg_celsius,
94  temperatures[cpufan_temperature].deg_fahrenheit);
96  temperatures[cpufan_temperature].deg_celsius);
97  break;
98  }
99 
100  switch (sysfan_control) {
101  case FAN_CRUISE_CONTROL_SPEED: /* SYSFANIN target speed */
102  printk(BIOS_DEBUG, "Fan Cruise Control setting system fan to %d RPM\n",
103  fan_speeds[sysfan_speed].fan_speed);
104  pnp_write_hwm5_index(hwm_base, 0x05, fan_speeds[sysfan_speed].fan_in);
105  break;
106  case FAN_CRUISE_CONTROL_THERMAL: /* SYSFANIN target temperature */
107  printk(BIOS_DEBUG, "Fan Cruise Control setting system fan to activation at %d deg C/%d deg F\n",
108  temperatures[sysfan_temperature].deg_celsius,
109  temperatures[sysfan_temperature].deg_fahrenheit);
111  temperatures[sysfan_temperature].deg_celsius);
112  break;
113  }
114 
115  pnp_write_hwm5_index(hwm_base, 0x0e, 0x02); /* Fan Output Step Down Time */
116  pnp_write_hwm5_index(hwm_base, 0x0f, 0x02); /* Fan Output Step Up Time */
117 
118  pnp_write_hwm5_index(hwm_base, 0x47, 0xaf); /* FAN divisor register */
119  pnp_write_hwm5_index(hwm_base, 0x4b, 0x84); /* AUXFANIN speed divisor */
120 
121  pnp_write_hwm5_index(hwm_base, 0x40, 0x01); /* Init, but no SMI# */
122 }
123 
124 /* mainboard_enable is executed as first thing after */
125 /* enumerate_buses(). */
126 
127 static void mainboard_enable(struct device *dev)
128 {
130  hwm_setup();
131 }
132 
133 static void mainboard_init(void *chip_info)
134 {
135  int i;
136  struct device *dev;
137 
138  for (i = 1; i <= 3; i++) {
139  char cmos_option_name[] = "ethernetx";
140  snprintf(cmos_option_name, sizeof(cmos_option_name),
141  "ethernet%01d", i);
142  unsigned int ethernet_disable = get_uint_option(cmos_option_name, 0);
143  if (!ethernet_disable)
144  continue;
145  printk(BIOS_DEBUG, "Disabling Ethernet NIC #%d\n", i);
146  dev = pcidev_on_root(28, i - 1);
147  if (dev == NULL) {
149  "Disabling Ethernet NIC: Cannot find 00:1c.%d!\n",
150  i - 1);
151  continue;
152  }
153  dev->enabled = 0;
154  }
155 }
156 
158  .init = mainboard_init,
159  .enable_dev = mainboard_enable,
160 };
struct chip_operations mainboard_ops
Definition: mainboard.c:19
#define printk(level,...)
Definition: stdlib.h:16
DEVTREE_CONST struct device * pcidev_on_root(uint8_t dev, uint8_t fn)
Definition: device_const.c:260
void install_intel_vga_int15_handler(int active_lfp_, int pfit_, int display_, int panel_type_)
Definition: int15.c:101
@ GMA_INT15_BOOT_DISPLAY_DEFAULT
Definition: int15.h:6
@ GMA_INT15_ACTIVE_LFP_INT_LVDS
Definition: int15.h:25
@ GMA_INT15_PANEL_FIT_DEFAULT
Definition: int15.h:17
static void pnp_write_hwm5_index(u16 base, u8 reg, u8 value)
Definition: hwm5_conf.h:43
static void nuvoton_hwm_select_bank(const u16 base, const u8 bank)
Definition: hwm.h:13
struct temperature temperatures[]
Definition: mainboard.c:40
static void hwm_setup(void)
Definition: mainboard.c:47
static u16 hwm_base
Definition: mainboard.c:14
#define FAN_CRUISE_CONTROL_THERMAL
Definition: mainboard.c:18
#define FAN_SPEED_5625
Definition: mainboard.c:19
#define FAN_CRUISE_CONTROL_DISABLED
Definition: mainboard.c:16
static void mainboard_init(void *chip_info)
Definition: mainboard.c:133
#define FAN_CRUISE_CONTROL_SPEED
Definition: mainboard.c:17
static void mainboard_enable(struct device *dev)
Definition: mainboard.c:127
struct fan_speed fan_speeds[]
Definition: mainboard.c:28
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
unsigned int get_uint_option(const char *name, const unsigned int fallback)
Definition: option.c:116
#define NULL
Definition: stddef.h:19
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
void(* init)(void *chip_info)
Definition: device.h:25
Definition: device.h:107
unsigned int enabled
Definition: device.h:122
u16 fan_speed
Definition: superio_hwm.c:25
u8 deg_fahrenheit
Definition: superio_hwm.c:39
int snprintf(char *buf, size_t size, const char *fmt,...)
Note: This file is only for POSIX compatibility, and is meant to be chain-included via string....
Definition: vsprintf.c:35