1 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include <console/console.h>
7 #include <device/pnp.h>
8 #include <ec/google/common/mec.h>
14 #include "ec_commands.h"
17 * Read bytes from a given LPC-mapped address.
19 * @port: Base read address
20 * @length: Number of bytes to read
21 * @dest: Destination buffer
22 * @csum: Optional parameter, sums data read
24 static void read_bytes(u16 port
, unsigned int length
, u8
*dest
, u8
*csum
)
28 #if CONFIG(EC_GOOGLE_CHROMEEC_MEC)
29 /* Access desired range though EMI interface */
30 if (port
>= MEC_EMI_RANGE_START
&& port
<= MEC_EMI_RANGE_END
) {
31 u8 ret
= mec_io_bytes(MEC_IO_READ
, MEC_EMI_BASE
,
32 port
- MEC_EMI_RANGE_START
,
40 for (i
= 0; i
< length
; ++i
) {
41 dest
[i
] = inb(port
+ i
);
47 /* Read single byte and return byte read */
48 static inline u8
read_byte(u16 port
)
51 read_bytes(port
, 1, &byte
, NULL
);
55 #if CONFIG(EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO)
56 /* Read singe byte and return byte read using indexed IO*/
57 static inline u8
read_byte_indexed_io(u8 offset
)
59 outb(offset
, CONFIG_EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO_PORT
);
60 return inb(CONFIG_EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO_PORT
+ 1);
65 * Write bytes to a given LPC-mapped address.
67 * @port: Base write address
68 * @length: Number of bytes to write
69 * @msg: Write data buffer
70 * @csum: Optional parameter, sums data written
72 static void write_bytes(u16 port
, unsigned int length
, u8
*msg
, u8
*csum
)
76 #if CONFIG(EC_GOOGLE_CHROMEEC_MEC)
77 /* Access desired range though EMI interface */
78 if (port
>= MEC_EMI_RANGE_START
&& port
<= MEC_EMI_RANGE_END
) {
79 u8 ret
= mec_io_bytes(MEC_IO_WRITE
, MEC_EMI_BASE
,
80 port
- MEC_EMI_RANGE_START
,
88 for (i
= 0; i
< length
; ++i
) {
89 outb(msg
[i
], port
+ i
);
95 /* Write single byte and return byte written */
96 static inline u8
write_byte(u8 val
, u16 port
)
99 write_bytes(port
, 1, &byte
, NULL
);
103 static int google_chromeec_status_check(u16 port
, u8 mask
, u8 cond
)
105 struct stopwatch timeout_sw
;
106 /* One second is more than plenty for any EC operation to complete */
107 const uint64_t ec_status_timeout_us
= 1 * USECS_PER_SEC
;
108 /* Wait 1 usec between read attempts */
109 const uint64_t ec_status_read_period_us
= 1;
111 stopwatch_init_usecs_expire(&timeout_sw
, ec_status_timeout_us
);
113 if ((read_byte(port
) & mask
) == cond
)
115 udelay(ec_status_read_period_us
);
116 } while (!stopwatch_expired(&timeout_sw
));
120 static int google_chromeec_wait_ready(u16 port
)
122 return google_chromeec_status_check(port
,
123 EC_LPC_CMDR_PENDING
|
124 EC_LPC_CMDR_BUSY
, 0);
127 #if CONFIG(EC_GOOGLE_CHROMEEC_ACPI_MEMMAP)
128 /* Read memmap data through ACPI port 66/62 */
129 static int read_memmap(u8
*data
, u8 offset
)
131 if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD
)) {
132 printk(BIOS_ERR
, "Timeout waiting for EC ready!\n");
136 /* Issue the ACPI read command */
137 write_byte(EC_CMD_ACPI_READ
, EC_LPC_ADDR_ACPI_CMD
);
139 if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD
)) {
140 printk(BIOS_ERR
, "Timeout waiting for EC READ_EVENT!\n");
144 /* Write data address */
145 write_byte(offset
+ EC_ACPI_MEM_MAPPED_BEGIN
, EC_LPC_ADDR_ACPI_DATA
);
147 if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD
)) {
148 printk(BIOS_ERR
, "Timeout waiting for EC DATA!\n");
152 *data
= read_byte(EC_LPC_ADDR_ACPI_DATA
);
157 static int google_chromeec_command_version(void)
161 #if CONFIG(EC_GOOGLE_CHROMEEC_ACPI_MEMMAP)
162 if (read_memmap(&id1
, EC_MEMMAP_ID
) ||
163 read_memmap(&id2
, EC_MEMMAP_ID
+ 1) ||
164 read_memmap(&flags
, EC_MEMMAP_HOST_CMD_FLAGS
)) {
165 printk(BIOS_ERR
, "Error reading memmap data.\n");
168 #elif CONFIG(EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO)
169 id1
= read_byte_indexed_io(EC_MEMMAP_ID
);
170 id2
= read_byte_indexed_io(EC_MEMMAP_ID
+ 1);
171 flags
= read_byte_indexed_io(EC_MEMMAP_HOST_CMD_FLAGS
);
173 id1
= read_byte(EC_LPC_ADDR_MEMMAP
+ EC_MEMMAP_ID
);
174 id2
= read_byte(EC_LPC_ADDR_MEMMAP
+ EC_MEMMAP_ID
+ 1);
175 flags
= read_byte(EC_LPC_ADDR_MEMMAP
+ EC_MEMMAP_HOST_CMD_FLAGS
);
178 if (id1
!= 'E' || id2
!= 'C') {
179 printk(BIOS_ERR
, "Missing Chromium EC memory map.\n");
183 if (flags
& EC_HOST_CMD_FLAG_VERSION_3
) {
184 return EC_HOST_CMD_FLAG_VERSION_3
;
185 } else if (flags
& EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED
) {
186 return EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED
;
188 printk(BIOS_ERR
, "Chromium EC command version unsupported\n");
192 static int google_chromeec_command_v3(struct chromeec_command
*cec_command
)
194 struct ec_host_request rq
;
195 struct ec_host_response rs
;
200 if (cec_command
->cmd_size_in
+ sizeof(rq
) > EC_LPC_HOST_PACKET_SIZE
) {
201 printk(BIOS_ERR
, "EC cannot send %zu bytes\n",
202 cec_command
->cmd_size_in
+ sizeof(rq
));
206 if (cec_command
->cmd_size_out
> EC_LPC_HOST_PACKET_SIZE
) {
207 printk(BIOS_ERR
, "EC cannot receive %d bytes\n",
208 cec_command
->cmd_size_out
);
212 if (google_chromeec_wait_ready(EC_LPC_ADDR_HOST_CMD
)) {
213 printk(BIOS_ERR
, "Timeout waiting for EC start command %d!\n",
214 cec_command
->cmd_code
);
218 /* Fill in request packet */
219 rq
.struct_version
= EC_HOST_REQUEST_VERSION
;
221 rq
.command
= cec_command
->cmd_code
|
222 EC_CMD_PASSTHRU_OFFSET(cec_command
->cmd_dev_index
);
223 rq
.command_version
= cec_command
->cmd_version
;
225 rq
.data_len
= cec_command
->cmd_size_in
;
227 /* Copy data and start checksum */
228 write_bytes(EC_LPC_ADDR_HOST_PACKET
+ sizeof(rq
),
229 cec_command
->cmd_size_in
,
230 (u8
*)cec_command
->cmd_data_in
,
233 /* Finish checksum */
234 for (i
= 0, d
= (const u8
*)&rq
; i
< sizeof(rq
); i
++, d
++)
237 /* Write checksum field so the entire packet sums to 0 */
241 write_bytes(EC_LPC_ADDR_HOST_PACKET
, sizeof(rq
), (u8
*)&rq
, NULL
);
243 /* Start the command */
244 write_byte(EC_COMMAND_PROTOCOL_3
, EC_LPC_ADDR_HOST_CMD
);
246 if (google_chromeec_wait_ready(EC_LPC_ADDR_HOST_CMD
)) {
247 printk(BIOS_ERR
, "Timeout waiting for EC process command %d!\n",
248 cec_command
->cmd_code
);
253 cec_command
->cmd_code
= read_byte(EC_LPC_ADDR_HOST_DATA
);
254 if (cec_command
->cmd_code
) {
255 printk(BIOS_SPEW
, "EC returned error result code %d\n",
256 cec_command
->cmd_code
);
260 /* Read back response header and start checksum */
262 read_bytes(EC_LPC_ADDR_HOST_PACKET
, sizeof(rs
), (u8
*)&rs
, &csum
);
264 if (rs
.struct_version
!= EC_HOST_RESPONSE_VERSION
) {
265 printk(BIOS_ERR
, "EC response version mismatch (%d != %d)\n",
266 rs
.struct_version
, EC_HOST_RESPONSE_VERSION
);
271 printk(BIOS_ERR
, "EC response reserved is %d, should be 0\n",
276 if (rs
.data_len
> cec_command
->cmd_size_out
) {
277 printk(BIOS_ERR
, "EC returned too much data (%d > %d)\n",
278 rs
.data_len
, cec_command
->cmd_size_out
);
282 /* Read back data and update checksum */
283 read_bytes(EC_LPC_ADDR_HOST_PACKET
+ sizeof(rs
),
285 cec_command
->cmd_data_out
,
288 /* Verify checksum */
290 printk(BIOS_ERR
, "EC response has invalid checksum\n");
297 static int google_chromeec_command_v1(struct chromeec_command
*cec_command
)
299 struct ec_lpc_host_args args
;
300 u8 cmd_code
= cec_command
->cmd_code
;
304 args
.flags
= EC_HOST_ARGS_FLAG_FROM_HOST
;
305 args
.command_version
= cec_command
->cmd_version
;
306 args
.data_size
= cec_command
->cmd_size_in
;
308 /* Initialize checksum */
309 csum
= cmd_code
+ args
.flags
+ args
.command_version
+ args
.data_size
;
311 write_bytes(EC_LPC_ADDR_HOST_PARAM
,
312 cec_command
->cmd_size_in
,
313 (u8
*)cec_command
->cmd_data_in
,
316 /* Finalize checksum and write args */
317 args
.checksum
= csum
;
318 write_bytes(EC_LPC_ADDR_HOST_ARGS
, sizeof(args
), (u8
*)&args
, NULL
);
320 /* Issue the command */
321 write_byte(cmd_code
, EC_LPC_ADDR_HOST_CMD
);
323 if (google_chromeec_wait_ready(EC_LPC_ADDR_HOST_CMD
)) {
324 printk(BIOS_ERR
, "Timeout waiting for EC process command %d!\n",
325 cec_command
->cmd_code
);
330 cec_command
->cmd_code
= read_byte(EC_LPC_ADDR_HOST_DATA
);
331 if (cec_command
->cmd_code
)
335 read_bytes(EC_LPC_ADDR_HOST_ARGS
, sizeof(args
), (u8
*)&args
, NULL
);
338 * If EC didn't modify args flags, then somehow we sent a new-style
339 * command to an old EC, which means it would have read its params
340 * from the wrong place.
342 if (!(args
.flags
& EC_HOST_ARGS_FLAG_TO_HOST
)) {
343 printk(BIOS_ERR
, "EC protocol mismatch\n");
347 if (args
.data_size
> cec_command
->cmd_size_out
) {
348 printk(BIOS_ERR
, "EC returned too much data\n");
351 cec_command
->cmd_size_out
= args
.data_size
;
353 /* Start calculating response checksum */
354 csum
= cmd_code
+ args
.flags
+ args
.command_version
+ args
.data_size
;
356 /* Read data, if any */
357 read_bytes(EC_LPC_ADDR_HOST_PARAM
,
359 cec_command
->cmd_data_out
,
362 /* Verify checksum */
363 if (args
.checksum
!= csum
) {
364 printk(BIOS_ERR
, "EC response has invalid checksum\n");
371 /* Return the byte of EC switch states */
372 uint8_t google_chromeec_get_switches(void)
374 #if CONFIG(EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO)
375 return read_byte_indexed_io(EC_MEMMAP_SWITCHES
);
377 return read_byte(EC_LPC_ADDR_MEMMAP
+ EC_MEMMAP_SWITCHES
);
381 void google_chromeec_ioport_range(uint16_t *out_base
, size_t *out_size
)
386 if (CONFIG(EC_GOOGLE_CHROMEEC_MEC
)) {
390 base
= EC_HOST_CMD_REGION0
;
391 size
= 2 * EC_HOST_CMD_REGION_SIZE
;
392 /* Make sure MEMMAP region follows host cmd region. */
393 assert(base
+ size
== EC_LPC_ADDR_MEMMAP
);
394 size
+= EC_MEMMAP_SIZE
;
401 int google_chromeec_command(struct chromeec_command
*cec_command
)
403 static int command_version
;
405 if (command_version
<= 0)
406 command_version
= google_chromeec_command_version();
408 switch (command_version
) {
409 case EC_HOST_CMD_FLAG_VERSION_3
:
410 return google_chromeec_command_v3(cec_command
);
411 case EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED
:
412 return google_chromeec_command_v1(cec_command
);
417 static void lpc_ec_init(struct device
*dev
)
422 google_chromeec_init();
426 * Declare the IO ports that we are using:
428 * All ECs (not explicitly declared):
429 * 0x60/0x64, 0x62/0x66, 0x80, 0x200->0x207
431 * mec1322: 0x800->0x807
432 * All others: 0x800->0x9ff
434 * EC_GOOGLE_CHROMEEC_ACPI_MEMMAP is only used for MEC ECs.
436 static void lpc_ec_read_resources(struct device
*dev
)
438 unsigned int idx
= 0;
439 struct resource
* res
;
443 google_chromeec_ioport_range(&base
, &size
);
444 res
= new_resource(dev
, idx
++);
447 res
->flags
= IORESOURCE_IO
| IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
450 static struct device_operations ops
= {
452 .read_resources
= lpc_ec_read_resources
,
453 .set_resources
= noop_set_resources
,
454 .scan_bus
= scan_static_bus
,
455 #if CONFIG(HAVE_ACPI_TABLES)
456 .acpi_name
= google_chromeec_acpi_name
,
457 .acpi_fill_ssdt
= google_chromeec_fill_ssdt_generator
,
461 static struct pnp_info pnp_dev_info
[] = {
465 static void enable_dev(struct device
*dev
)
467 pnp_enable_devices(dev
, &ops
, ARRAY_SIZE(pnp_dev_info
), pnp_dev_info
);
470 struct chip_operations ec_google_chromeec_ops
= {
471 .name
= "Google Chrome EC",
472 .enable_dev
= enable_dev
,
475 static int google_chromeec_data_ready(u16 port
)
477 return google_chromeec_status_check(port
, EC_LPC_CMDR_DATA
,
481 enum host_event_code
google_chromeec_get_event(void)
483 if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD
)) {
484 printk(BIOS_ERR
, "Timeout waiting for EC ready!\n");
485 return EC_HOST_EVENT_NONE
;
488 /* Issue the ACPI query-event command */
489 write_byte(EC_CMD_ACPI_QUERY_EVENT
, EC_LPC_ADDR_ACPI_CMD
);
491 if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD
)) {
492 printk(BIOS_ERR
, "Timeout waiting for EC QUERY_EVENT!\n");
493 return EC_HOST_EVENT_NONE
;
496 if (google_chromeec_data_ready(EC_LPC_ADDR_ACPI_CMD
)) {
497 printk(BIOS_ERR
, "Timeout waiting for data ready!\n");
498 return EC_HOST_EVENT_NONE
;
501 /* Event (or 0 if none) is returned directly in the data byte */
502 return read_byte(EC_LPC_ADDR_ACPI_DATA
);