coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
nc_fpga.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <types.h>
4 #include <device/pci.h>
5 #include <device/pci_ids.h>
6 #include <device/pci_ops.h>
7 #include <device/pci_def.h>
8 #include <device/mmio.h>
9 #include <hwilib.h>
10 #include <bootstate.h>
11 
12 #include "nc_fpga.h"
13 
14 static void *nc_fpga_bar0;
15 
16 #define FPGA_SET_PARAM(src, dst) \
17 { \
18  uint32_t var; \
19  if (hwilib_get_field(src, (uint8_t *)&var, sizeof(var))) \
20  dst = ((typeof(dst))var); \
21 }
22 
23 static void init_temp_mon (void *base_adr)
24 {
25  uint32_t cc[5], i = 0;
26  uint8_t num = 0;
27  volatile fan_ctrl_t *ctrl = (fan_ctrl_t *)base_adr;
28 
29  /* Program sensor delay first. */
30  FPGA_SET_PARAM(FANSensorDelay, ctrl->sensordelay);
31  /* Program correction curve for every used sensor. */
32  if ((hwilib_get_field(FANSensorNum, &num, 1) != 1) ||
33  (num == 0) || (num > MAX_NUM_SENSORS))
34  return;
35  for (i = 0; i < num; i ++) {
36  if (hwilib_get_field(FANSensorCfg0 + i, (uint8_t *)&cc[0],
37  sizeof(cc)) == sizeof(cc)) {
38  ctrl->sensorcfg[cc[0]].rmin = cc[1] & 0xffff;
39  ctrl->sensorcfg[cc[0]].rmax = cc[2] & 0xffff;
40  ctrl->sensorcfg[cc[0]].nmin = cc[3] & 0xffff;
41  ctrl->sensorcfg[cc[0]].nmax = cc[4] & 0xffff;
42  }
43  }
44  ctrl->sensornum = num;
45 
46  /* Program sensor selection and temperature thresholds. */
47  FPGA_SET_PARAM(FANSensorSelect, ctrl->sensorselect);
48  FPGA_SET_PARAM(T_Warn, ctrl->t_warn);
49  FPGA_SET_PARAM(T_Crit, ctrl->t_crit);
50 }
51 
52 static void init_fan_ctrl (void *base_adr)
53 {
54  uint8_t mask = 0, freeze_disable = 0, fan_req = 0;
55  volatile fan_ctrl_t *ctrl = (fan_ctrl_t *)base_adr;
56 
57  /* Program all needed fields of FAN controller. */
58  FPGA_SET_PARAM(FANSamplingTime, ctrl->samplingtime);
59  FPGA_SET_PARAM(FANSetPoint, ctrl->setpoint);
60  FPGA_SET_PARAM(FANHystCtrl, ctrl->hystctrl);
61  FPGA_SET_PARAM(FANHystVal, ctrl->hystval);
62  FPGA_SET_PARAM(FANHystThreshold, ctrl->hystthreshold);
63  FPGA_SET_PARAM(FANKp, ctrl->kp);
64  FPGA_SET_PARAM(FANKi, ctrl->ki);
65  FPGA_SET_PARAM(FANKd, ctrl->kd);
66  FPGA_SET_PARAM(FANMaxSpeed, ctrl->fanmax);
67  FPGA_SET_PARAM(FANStartSpeed, ctrl->fanmin);
68  /* Set freeze and FAN configuration. */
69  if ((hwilib_get_field(FF_FanReq, &fan_req, 1) == 1) &&
70  (hwilib_get_field(FF_FreezeDis, &freeze_disable, 1) == 1)) {
71  if (!fan_req)
72  mask = 1;
73  else if (fan_req && !freeze_disable)
74  mask = 2;
75  else
76  mask = 3;
77  ctrl->fanmon = mask << 10;
78  }
79 }
80 
81 /** \brief This function is the driver entry point for the init phase
82  * of the PCI bus allocator. It will initialize all the needed parts
83  * of NC_FPGA.
84  * @param *dev Pointer to the used PCI device
85  * @return void Nothing is given back
86  */
87 static void nc_fpga_init(struct device *dev)
88 {
89  void *bar0_ptr = NULL;
90  uint8_t cmd_reg;
91  uint32_t cap = 0;
92 
93  /* All we need is mapped to BAR 0, get the address. */
94  bar0_ptr = (void *)(pci_read_config32(dev, PCI_BASE_ADDRESS_0) &
96  cmd_reg = pci_read_config8(dev, PCI_COMMAND);
97  /* Ensure BAR0 has a valid value. */
98  if (!bar0_ptr || !(cmd_reg & PCI_COMMAND_MEMORY))
99  return;
100  /* Ensure this is really a NC FPGA by checking magic register. */
101  if (read32(bar0_ptr + NC_MAGIC_OFFSET) != NC_FPGA_MAGIC)
102  return;
103  /* Save BAR0 address so that it can be used on all NC_FPGA devices to
104  set the FW_DONE bit before jumping to payload. */
105  nc_fpga_bar0 = bar0_ptr;
106  /* Open hwinfo block. */
107  if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
108  return;
109  /* Set up FAN controller and temperature monitor according to */
110  /* capability bits. */
111  cap = read32(bar0_ptr + NC_CAP1_OFFSET);
112  if (cap & (NC_CAP1_TEMP_MON | NC_CAP1_FAN_CTRL))
114  if (cap & NC_CAP1_FAN_CTRL)
116  if (cap & NC_CAP1_DSAVE_NMI_DELAY) {
117  uint16_t *dsave_ptr = (uint16_t *)(bar0_ptr + NC_DSAVE_OFFSET);
118  FPGA_SET_PARAM(NvramVirtTimeDsaveReset, *dsave_ptr);
119  }
120  if (cap & NC_CAP1_BL_BRIGHTNESS_CTRL) {
121  uint8_t *bl_bn_ptr =
122  (uint8_t *)(bar0_ptr + NC_BL_BRIGHTNESS_OFFSET);
123  uint8_t *bl_pwm_ptr = (uint8_t *)(bar0_ptr + NC_BL_PWM_OFFSET);
124  FPGA_SET_PARAM(BL_Brightness, *bl_bn_ptr);
125  FPGA_SET_PARAM(PF_PwmFreq, *bl_pwm_ptr);
126  }
127 }
128 
129 #if CONFIG(NC_FPGA_NOTIFY_CB_READY)
130 /* Set FW_DONE bit in FPGA before jumping to payload. */
131 static void set_fw_done(void *unused)
132 {
133  uint32_t reg;
134 
135  if (nc_fpga_bar0) {
137  reg |= NC_DIAG_FW_DONE;
139  }
140 }
141 
143 #endif
144 
145 static void nc_fpga_set_resources(struct device *dev)
146 {
148 
149  if (CONFIG(NC_FPGA_POST_CODE)) {
150  /* Re-initialize base address after set_resources for POST display
151  to work properly.*/
153  }
154 }
155 
156 
157 static struct device_operations nc_fpga_ops = {
159  .set_resources = nc_fpga_set_resources,
160  .enable_resources = pci_dev_enable_resources,
161  .init = nc_fpga_init,
162 };
163 
164 static const unsigned short nc_fpga_device_ids[] = { 0x4080, 0x4091, 0 };
165 
166 static const struct pci_driver nc_fpga_driver __pci_driver = {
167  .ops = &nc_fpga_ops,
168  .vendor = PCI_VID_SIEMENS,
169  .devices = nc_fpga_device_ids,
170 };
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define BOOT_STATE_INIT_ENTRY(state_, when_, func_, arg_)
Definition: bootstate.h:182
@ BS_PAYLOAD_BOOT
Definition: bootstate.h:89
@ BS_ON_ENTRY
Definition: bootstate.h:95
@ CB_SUCCESS
Call completed successfully.
Definition: cb_err.h:16
@ CONFIG
Definition: dsi_common.h:201
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline u8 pci_read_config8(const struct device *dev, u16 reg)
Definition: pci_ops.h:46
static void init_temp_mon(void *base_adr)
Definition: nc_fpga.c:23
static const unsigned short nc_fpga_device_ids[]
Definition: nc_fpga.c:164
static void * nc_fpga_bar0
Definition: nc_fpga.c:14
static struct device_operations nc_fpga_ops
Definition: nc_fpga.c:157
#define FPGA_SET_PARAM(src, dst)
Definition: nc_fpga.c:16
static void nc_fpga_set_resources(struct device *dev)
Definition: nc_fpga.c:145
static const struct pci_driver nc_fpga_driver __pci_driver
Definition: nc_fpga.c:166
static void nc_fpga_init(struct device *dev)
This function is the driver entry point for the init phase of the PCI bus allocator.
Definition: nc_fpga.c:87
static void init_fan_ctrl(void *base_adr)
Definition: nc_fpga.c:52
#define NC_FPGA_MAGIC
Definition: nc_fpga.h:9
void nc_fpga_remap(uint32_t new_mmio)
Definition: nc_fpga_early.c:34
#define NC_DSAVE_OFFSET
Definition: nc_fpga.h:15
#define NC_CAP1_TEMP_MON
Definition: nc_fpga.h:14
#define NC_MAGIC_OFFSET
Definition: nc_fpga.h:8
#define NC_BL_BRIGHTNESS_OFFSET
Definition: nc_fpga.h:18
#define NC_CAP1_BL_BRIGHTNESS_CTRL
Definition: nc_fpga.h:12
#define NC_DIAG_CTRL_OFFSET
Definition: nc_fpga.h:16
#define NC_FANMON_CTRL_OFFSET
Definition: nc_fpga.h:21
#define NC_BL_PWM_OFFSET
Definition: nc_fpga.h:19
#define MAX_NUM_SENSORS
Definition: nc_fpga.h:23
#define NC_CAP1_FAN_CTRL
Definition: nc_fpga.h:13
#define NC_DIAG_FW_DONE
Definition: nc_fpga.h:17
#define NC_CAP1_OFFSET
Definition: nc_fpga.h:10
#define NC_CAP1_DSAVE_NMI_DELAY
Definition: nc_fpga.h:11
#define PCI_BASE_ADDRESS_MEM_ATTR_MASK
Definition: pci_def.h:77
#define PCI_COMMAND_MEMORY
Definition: pci_def.h:12
#define PCI_BASE_ADDRESS_0
Definition: pci_def.h:63
#define PCI_COMMAND
Definition: pci_def.h:10
void pci_dev_enable_resources(struct device *dev)
Definition: pci_device.c:721
void pci_dev_read_resources(struct device *dev)
Definition: pci_device.c:534
void pci_dev_set_resources(struct device *dev)
Definition: pci_device.c:691
#define PCI_VID_SIEMENS
Definition: pci_ids.h:1491
static const int mask[4]
Definition: gpio.c:308
#define NULL
Definition: stddef.h:19
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107