mb/google/brya: Create rull variant
[coreboot2.git] / src / mainboard / google / kukui / boardid.c
blob117475680f1d95c72b81ecd2f70bb92f85ab1374
1 /* SPDX-License-Identifier: GPL-2.0-only */
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 */
9 #include <assert.h>
10 #include <boardid.h>
11 #include <console/console.h>
12 #include <delay.h>
13 #include <device/i2c_simple.h>
14 #include <drivers/camera/cros_camera.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>
20 /* For CBI un-provisioned/corrupted Flapjack board. */
21 #define FLAPJACK_UNDEF_SKU_ID 0
23 #define ADC_LEVELS 12
25 enum {
26 LCM_ID_CHANNEL = 2, /* ID of LCD Module on schematics. */
27 RAM_ID_CHANNEL = 3,
28 SKU_ID_CHANNEL = 4,
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,
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,
63 static const int *adc_voltages[] = {
64 [LCM_ID_CHANNEL] = lcm_voltages,
65 [RAM_ID_CHANNEL] = ram_voltages,
66 [SKU_ID_CHANNEL] = ram_voltages, /* SKU ID is sharing RAM voltages. */
69 static uint32_t get_adc_index(unsigned int channel)
71 int value = auxadc_get_voltage_uv(channel);
73 assert(channel < ARRAY_SIZE(adc_voltages));
74 const int *voltages = adc_voltages[channel];
75 assert(voltages);
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;
86 static uint8_t eeprom_random_read(uint8_t bus, uint8_t slave, uint16_t offset,
87 uint8_t *data, uint16_t len)
89 struct i2c_msg seg[2];
90 uint8_t address[2];
92 address[0] = offset >> 8;
93 address[1] = offset & 0xff;
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;
104 return i2c_transfer(bus, seg, ARRAY_SIZE(seg));
107 /* Regulator for world facing camera. */
108 #define PMIC_LDO_VCAMIO_CON0 0x1cb0
110 #define CROS_CAMERA_INFO_OFFSET 0x1f80
111 #define MT8183_FORMAT 0x8183
112 #define KODAMA_PID 0x00c7
114 /* Returns the ID for world facing camera. */
115 static uint8_t wfc_id(void)
117 if (!CONFIG(BOARD_GOOGLE_KODAMA))
118 return 0;
120 int i, ret;
121 uint8_t bus = 2;
122 uint8_t dev_addr = 0x50; /* at24c32/64 device address */
124 struct cros_camera_info data = {0};
126 const uint16_t sensor_pids[] = {
127 [0] = 0x5965, /* OV5965 */
128 [1] = 0x5035, /* GC5035 */
131 mtk_i2c_bus_init(bus);
133 /* Turn on camera sensor EEPROM */
134 pwrap_write(PMIC_LDO_VCAMIO_CON0, 0x1);
135 udelay(270);
137 ret = eeprom_random_read(bus, dev_addr, CROS_CAMERA_INFO_OFFSET,
138 (uint8_t *)&data, sizeof(data));
139 pwrap_write(PMIC_LDO_VCAMIO_CON0, 0x0);
141 if (ret) {
142 printk(BIOS_ERR,
143 "Failed to read from EEPROM; using default WFC id 0\n");
144 return 0;
147 if (check_cros_camera_info(&data)) {
148 printk(BIOS_ERR,
149 "Failed to check camera info; using default WFC id 0\n");
150 return 0;
153 if (data.data_format != MT8183_FORMAT) {
154 printk(BIOS_ERR, "Incompatible camera format: %#04x\n",
155 data.data_format);
156 return 0;
158 if (data.module_pid != KODAMA_PID) {
159 printk(BIOS_ERR, "Incompatible module pid: %#04x\n",
160 data.module_pid);
161 return 0;
164 printk(BIOS_DEBUG, "Camera sensor pid: %#04x\n", data.sensor_pid);
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;
173 printk(BIOS_WARNING, "Unknown WFC id; using default id 0\n");
174 return 0;
177 /* Returns the ID for LCD module (type of panel). */
178 static uint8_t lcm_id(void)
180 /* LCM is unused on Jacuzzi followers. */
181 if (CONFIG(BOARD_GOOGLE_JACUZZI_COMMON))
182 return CONFIG_BOARD_OVERRIDE_LCM_ID;
184 return get_adc_index(LCM_ID_CHANNEL);
187 uint32_t sku_id(void)
189 static uint32_t cached_sku_id = BOARD_ID_INIT;
191 if (cached_sku_id != BOARD_ID_INIT)
192 return cached_sku_id;
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;
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;
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.
215 cached_sku_id = (wfc_id() << 8 |
216 lcm_id() << 4 |
217 get_adc_index(SKU_ID_CHANNEL));
219 return cached_sku_id;
222 uint32_t ram_code(void)
224 static uint32_t cached_ram_code = BOARD_ID_INIT;
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;
231 return cached_ram_code;