coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
boardid.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /*
4  * The boardid.c should provide board_id, sku_id, and ram_code.
5  * board_id is provided by ec/google/chromeec/ec_boardid.c.
6  * sku_id and ram_code are defined in this file.
7  */
8 
9 #include <assert.h>
10 #include <boardid.h>
11 #include <console/console.h>
12 #include <delay.h>
13 #include <device/i2c_simple.h>
15 #include <ec/google/chromeec/ec.h>
16 #include <soc/auxadc_common.h>
17 #include <soc/i2c.h>
18 #include <soc/pmic_wrap_common.h>
19 
20 /* For CBI un-provisioned/corrupted Flapjack board. */
21 #define FLAPJACK_UNDEF_SKU_ID 0
22 
23 #define ADC_LEVELS 12
24 
25 enum {
26  LCM_ID_CHANNEL = 2, /* ID of LCD Module on schematics. */
29 };
30 
31 static const int ram_voltages[ADC_LEVELS] = {
32  /* ID : Voltage (unit: uV) */
33  /* 0 : */ 74000,
34  /* 1 : */ 212000,
35  /* 2 : */ 319000,
36  /* 3 : */ 429000,
37  /* 4 : */ 542000,
38  /* 5 : */ 666000,
39  /* 6 : */ 781000,
40  /* 7 : */ 900000,
41  /* 8 : */ 1023000,
42  /* 9 : */ 1137000,
43  /* 10 : */ 1240000,
44  /* 11 : */ 1343000,
45 };
46 
47 static const int lcm_voltages[ADC_LEVELS] = {
48  /* ID : Voltage (unit: uV) */
49  /* 0 : */ 0,
50  /* 1 : */ 283000,
51  /* 2 : */ 394000,
52  /* 3 : */ 503000,
53  /* 4 : */ 608000,
54  /* 5 : */ 712000,
55  /* 6 : */ 823000,
56  /* 7 : */ 937000,
57  /* 8 : */ 1046000,
58  /* 9 : */ 1155000,
59  /* 10 : */ 1277000,
60  /* 11 : */ 1434000,
61 };
62 
63 static const int *adc_voltages[] = {
66  [SKU_ID_CHANNEL] = ram_voltages, /* SKU ID is sharing RAM voltages. */
67 };
68 
69 static uint32_t get_adc_index(unsigned int channel)
70 {
71  int value = auxadc_get_voltage_uv(channel);
72 
73  assert(channel < ARRAY_SIZE(adc_voltages));
74  const int *voltages = adc_voltages[channel];
75  assert(voltages);
76 
77  /* Find the closest voltage */
78  uint32_t id;
79  for (id = 0; id < ADC_LEVELS - 1; id++)
80  if (value < (voltages[id] + voltages[id + 1]) / 2)
81  break;
82  printk(BIOS_DEBUG, "ADC[%d]: Raw value=%d ID=%d\n", channel, value, id);
83  return id;
84 }
85 
87  uint8_t *data, uint16_t len)
88 {
89  struct i2c_msg seg[2];
90  uint8_t address[2];
91 
92  address[0] = offset >> 8;
93  address[1] = offset & 0xff;
94 
95  seg[0].flags = 0;
96  seg[0].slave = slave;
97  seg[0].buf = address;
98  seg[0].len = sizeof(address);
99  seg[1].flags = I2C_M_RD;
100  seg[1].slave = slave;
101  seg[1].buf = data;
102  seg[1].len = len;
103 
104  return i2c_transfer(bus, seg, ARRAY_SIZE(seg));
105 }
106 
107 /* Regulator for world facing camera. */
108 #define PMIC_LDO_VCAMIO_CON0 0x1cb0
109 
110 #define CROS_CAMERA_INFO_OFFSET 0x1f80
111 #define MT8183_FORMAT 0x8183
112 #define KODAMA_PID 0x00c7
113 
114 /* Returns the ID for world facing camera. */
115 static uint8_t wfc_id(void)
116 {
117  if (!CONFIG(BOARD_GOOGLE_KODAMA))
118  return 0;
119 
120  int i, ret;
121  uint8_t bus = 2;
122  uint8_t dev_addr = 0x50; /* at24c32/64 device address */
123 
124  struct cros_camera_info data = {0};
125 
126  const uint16_t sensor_pids[] = {
127  [0] = 0x5965, /* OV5965 */
128  [1] = 0x5035, /* GC5035 */
129  };
130 
132 
133  /* Turn on camera sensor EEPROM */
135  udelay(270);
136 
138  (uint8_t *)&data, sizeof(data));
140 
141  if (ret) {
143  "Failed to read from EEPROM; using default WFC id 0\n");
144  return 0;
145  }
146 
147  if (check_cros_camera_info(&data)) {
149  "Failed to check camera info; using default WFC id 0\n");
150  return 0;
151  }
152 
153  if (data.data_format != MT8183_FORMAT) {
154  printk(BIOS_ERR, "Incompatible camera format: %#04x\n",
155  data.data_format);
156  return 0;
157  }
158  if (data.module_pid != KODAMA_PID) {
159  printk(BIOS_ERR, "Incompatible module pid: %#04x\n",
160  data.module_pid);
161  return 0;
162  }
163 
164  printk(BIOS_DEBUG, "Camera sensor pid: %#04x\n", data.sensor_pid);
165 
166  for (i = 0; i < ARRAY_SIZE(sensor_pids); i++) {
167  if (data.sensor_pid == sensor_pids[i]) {
168  printk(BIOS_INFO, "Detected WFC id: %d\n", i);
169  return i;
170  }
171  }
172 
173  printk(BIOS_WARNING, "Unknown WFC id; using default id 0\n");
174  return 0;
175 }
176 
177 /* Returns the ID for LCD module (type of panel). */
178 static uint8_t lcm_id(void)
179 {
180  /* LCM is unused on Jacuzzi followers. */
181  if (CONFIG(BOARD_GOOGLE_JACUZZI_COMMON))
182  return CONFIG_BOARD_OVERRIDE_LCM_ID;
183 
185 }
186 
188 {
189  static uint32_t cached_sku_id = BOARD_ID_INIT;
190 
191  if (cached_sku_id != BOARD_ID_INIT)
192  return cached_sku_id;
193 
194  /* On Flapjack, getting the SKU via CBI. */
195  if (CONFIG(BOARD_GOOGLE_FLAPJACK)) {
196  if (google_chromeec_cbi_get_sku_id(&cached_sku_id))
197  cached_sku_id = FLAPJACK_UNDEF_SKU_ID;
198  return cached_sku_id;
199  }
200 
201  /* Quirk for Kukui: All Rev1/Sku0 had incorrectly set SKU_ID=1. */
202  if (CONFIG(BOARD_GOOGLE_KUKUI)) {
203  if (board_id() == 1) {
204  cached_sku_id = 0;
205  return cached_sku_id;
206  }
207  }
208 
209  /*
210  * The SKU (later used for device tree matching) is combined from:
211  * World facing camera (WFC) ID.
212  * ADC2[4bit/H] = straps on LCD module (type of panel).
213  * ADC4[4bit/L] = SKU ID from board straps.
214  */
215  cached_sku_id = (wfc_id() << 8 |
216  lcm_id() << 4 |
218 
219  return cached_sku_id;
220 }
221 
223 {
224  static uint32_t cached_ram_code = BOARD_ID_INIT;
225 
226  if (cached_ram_code == BOARD_ID_INIT) {
227  cached_ram_code = get_adc_index(RAM_ID_CHANNEL);
228  /* Model-specific offset - see sdram_configs.c for details. */
229  cached_ram_code += CONFIG_BOARD_SDRAM_TABLE_OFFSET;
230  }
231  return cached_ram_code;
232 }
pte_t value
Definition: mmu.c:91
#define assert(statement)
Definition: assert.h:74
unsigned int auxadc_get_voltage_uv(unsigned int channel)
Definition: auxadc.c:58
#define BOARD_ID_INIT
Definition: boardid.h:11
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define printk(level,...)
Definition: stdlib.h:16
int check_cros_camera_info(const struct cros_camera_info *info)
Definition: cros_camera.c:9
@ CONFIG
Definition: dsi_common.h:201
int google_chromeec_cbi_get_sku_id(uint32_t *id)
Definition: ec.c:839
uint32_t board_id(void)
board_id() - Get the board version
Definition: boardid.c:6
static size_t offset
Definition: flashconsole.c:16
uint64_t address
Definition: fw_cfg_if.h:0
static int i2c_transfer(unsigned int bus, struct i2c_msg *segments, int count)
Definition: i2c_simple.h:42
#define I2C_M_RD
Definition: i2c.h:34
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
uint32_t sku_id(void)
Definition: boardid.c:65
uint32_t ram_code(void)
Definition: boardid.c:78
static const int lcm_voltages[ADC_LEVELS]
Definition: boardid.c:47
#define KODAMA_PID
Definition: boardid.c:112
#define CROS_CAMERA_INFO_OFFSET
Definition: boardid.c:110
static uint8_t eeprom_random_read(uint8_t bus, uint8_t slave, uint16_t offset, uint8_t *data, uint16_t len)
Definition: boardid.c:86
static const int * adc_voltages[]
Definition: boardid.c:63
#define FLAPJACK_UNDEF_SKU_ID
Definition: boardid.c:21
@ SKU_ID_CHANNEL
Definition: boardid.c:28
@ LCM_ID_CHANNEL
Definition: boardid.c:26
@ RAM_ID_CHANNEL
Definition: boardid.c:27
static const int ram_voltages[ADC_LEVELS]
Definition: boardid.c:31
static uint32_t get_adc_index(unsigned int channel)
Definition: boardid.c:69
static uint8_t lcm_id(void)
Definition: boardid.c:178
#define PMIC_LDO_VCAMIO_CON0
Definition: boardid.c:108
static uint8_t wfc_id(void)
Definition: boardid.c:115
#define MT8183_FORMAT
Definition: boardid.c:111
#define ADC_LEVELS
Definition: boardid.c:23
static s32 pwrap_write(u16 addr, u16 wdata)
void mtk_i2c_bus_init(uint8_t bus)
Definition: i2c.c:65
static struct spi_slave slave
Definition: spiconsole.c:7
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
Definition: device.h:76
uint16_t sensor_pid
Definition: cros_camera.h:21
uint16_t data_format
Definition: cros_camera.h:17
uint16_t module_pid
Definition: cros_camera.h:18
struct i2c_msg - an I2C transaction segment beginning with START @addr: Slave address,...
Definition: i2c.h:32
uint16_t len
Definition: i2c.h:39
uint16_t slave
Definition: i2c.h:38
uint16_t flags
Definition: i2c.h:33
uint8_t * buf
Definition: i2c.h:40
void udelay(uint32_t us)
Definition: udelay.c:15