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
);
56 * Write bytes to a given LPC-mapped address.
58 * @port: Base write address
59 * @length: Number of bytes to write
60 * @msg: Write data buffer
61 * @csum: Optional parameter, sums data written
63 static void write_bytes(u16 port
, unsigned int length
, u8
*msg
, u8
*csum
)
67 #if CONFIG(EC_GOOGLE_CHROMEEC_MEC)
68 /* Access desired range though EMI interface */
69 if (port
>= MEC_EMI_RANGE_START
&& port
<= MEC_EMI_RANGE_END
) {
70 u8 ret
= mec_io_bytes(MEC_IO_WRITE
, MEC_EMI_BASE
,
71 port
- MEC_EMI_RANGE_START
,
79 for (i
= 0; i
< length
; ++i
) {
80 outb(msg
[i
], port
+ i
);
86 /* Write single byte and return byte written */
87 static inline u8
write_byte(u8 val
, u16 port
)
90 write_bytes(port
, 1, &byte
, NULL
);
94 static int google_chromeec_status_check(u16 port
, u8 mask
, u8 cond
)
96 struct stopwatch timeout_sw
;
97 /* One second is more than plenty for any EC operation to complete */
98 const uint64_t ec_status_timeout_us
= 1 * USECS_PER_SEC
;
99 /* Wait 1 usec between read attempts */
100 const uint64_t ec_status_read_period_us
= 1;
102 stopwatch_init_usecs_expire(&timeout_sw
, ec_status_timeout_us
);
104 if ((read_byte(port
) & mask
) == cond
)
106 udelay(ec_status_read_period_us
);
107 } while (!stopwatch_expired(&timeout_sw
));
111 static int google_chromeec_wait_ready(u16 port
)
113 return google_chromeec_status_check(port
,
114 EC_LPC_CMDR_PENDING
|
115 EC_LPC_CMDR_BUSY
, 0);
118 #if CONFIG(EC_GOOGLE_CHROMEEC_ACPI_MEMMAP)
119 /* Read memmap data through ACPI port 66/62 */
120 static int read_memmap(u8
*data
, u8 offset
)
122 if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD
)) {
123 printk(BIOS_ERR
, "Timeout waiting for EC ready!\n");
127 /* Issue the ACPI read command */
128 write_byte(EC_CMD_ACPI_READ
, EC_LPC_ADDR_ACPI_CMD
);
130 if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD
)) {
131 printk(BIOS_ERR
, "Timeout waiting for EC READ_EVENT!\n");
135 /* Write data address */
136 write_byte(offset
+ EC_ACPI_MEM_MAPPED_BEGIN
, EC_LPC_ADDR_ACPI_DATA
);
138 if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD
)) {
139 printk(BIOS_ERR
, "Timeout waiting for EC DATA!\n");
143 *data
= read_byte(EC_LPC_ADDR_ACPI_DATA
);
148 static int google_chromeec_command_version(void)
152 #if CONFIG(EC_GOOGLE_CHROMEEC_ACPI_MEMMAP)
153 if (read_memmap(&id1
, EC_MEMMAP_ID
) ||
154 read_memmap(&id2
, EC_MEMMAP_ID
+ 1) ||
155 read_memmap(&flags
, EC_MEMMAP_HOST_CMD_FLAGS
)) {
156 printk(BIOS_ERR
, "Error reading memmap data.\n");
160 id1
= read_byte(EC_LPC_ADDR_MEMMAP
+ EC_MEMMAP_ID
);
161 id2
= read_byte(EC_LPC_ADDR_MEMMAP
+ EC_MEMMAP_ID
+ 1);
162 flags
= read_byte(EC_LPC_ADDR_MEMMAP
+ EC_MEMMAP_HOST_CMD_FLAGS
);
165 if (id1
!= 'E' || id2
!= 'C') {
166 printk(BIOS_ERR
, "Missing Chromium EC memory map.\n");
170 if (flags
& EC_HOST_CMD_FLAG_VERSION_3
) {
171 return EC_HOST_CMD_FLAG_VERSION_3
;
172 } else if (flags
& EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED
) {
173 return EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED
;
175 printk(BIOS_ERR
, "Chromium EC command version unsupported\n");
179 static int google_chromeec_command_v3(struct chromeec_command
*cec_command
)
181 struct ec_host_request rq
;
182 struct ec_host_response rs
;
187 if (cec_command
->cmd_size_in
+ sizeof(rq
) > EC_LPC_HOST_PACKET_SIZE
) {
188 printk(BIOS_ERR
, "EC cannot send %zu bytes\n",
189 cec_command
->cmd_size_in
+ sizeof(rq
));
193 if (cec_command
->cmd_size_out
> EC_LPC_HOST_PACKET_SIZE
) {
194 printk(BIOS_ERR
, "EC cannot receive %d bytes\n",
195 cec_command
->cmd_size_out
);
199 if (google_chromeec_wait_ready(EC_LPC_ADDR_HOST_CMD
)) {
200 printk(BIOS_ERR
, "Timeout waiting for EC start command %d!\n",
201 cec_command
->cmd_code
);
205 /* Fill in request packet */
206 rq
.struct_version
= EC_HOST_REQUEST_VERSION
;
208 rq
.command
= cec_command
->cmd_code
|
209 EC_CMD_PASSTHRU_OFFSET(cec_command
->cmd_dev_index
);
210 rq
.command_version
= cec_command
->cmd_version
;
212 rq
.data_len
= cec_command
->cmd_size_in
;
214 /* Copy data and start checksum */
215 write_bytes(EC_LPC_ADDR_HOST_PACKET
+ sizeof(rq
),
216 cec_command
->cmd_size_in
,
217 (u8
*)cec_command
->cmd_data_in
,
220 /* Finish checksum */
221 for (i
= 0, d
= (const u8
*)&rq
; i
< sizeof(rq
); i
++, d
++)
224 /* Write checksum field so the entire packet sums to 0 */
228 write_bytes(EC_LPC_ADDR_HOST_PACKET
, sizeof(rq
), (u8
*)&rq
, NULL
);
230 /* Start the command */
231 write_byte(EC_COMMAND_PROTOCOL_3
, EC_LPC_ADDR_HOST_CMD
);
233 if (google_chromeec_wait_ready(EC_LPC_ADDR_HOST_CMD
)) {
234 printk(BIOS_ERR
, "Timeout waiting for EC process command %d!\n",
235 cec_command
->cmd_code
);
240 cec_command
->cmd_code
= read_byte(EC_LPC_ADDR_HOST_DATA
);
241 if (cec_command
->cmd_code
) {
242 printk(BIOS_SPEW
, "EC returned error result code %d\n",
243 cec_command
->cmd_code
);
247 /* Read back response header and start checksum */
249 read_bytes(EC_LPC_ADDR_HOST_PACKET
, sizeof(rs
), (u8
*)&rs
, &csum
);
251 if (rs
.struct_version
!= EC_HOST_RESPONSE_VERSION
) {
252 printk(BIOS_ERR
, "EC response version mismatch (%d != %d)\n",
253 rs
.struct_version
, EC_HOST_RESPONSE_VERSION
);
258 printk(BIOS_ERR
, "EC response reserved is %d, should be 0\n",
263 if (rs
.data_len
> cec_command
->cmd_size_out
) {
264 printk(BIOS_ERR
, "EC returned too much data (%d > %d)\n",
265 rs
.data_len
, cec_command
->cmd_size_out
);
269 /* Read back data and update checksum */
270 read_bytes(EC_LPC_ADDR_HOST_PACKET
+ sizeof(rs
),
272 cec_command
->cmd_data_out
,
275 /* Verify checksum */
277 printk(BIOS_ERR
, "EC response has invalid checksum\n");
284 static int google_chromeec_command_v1(struct chromeec_command
*cec_command
)
286 struct ec_lpc_host_args args
;
287 u8 cmd_code
= cec_command
->cmd_code
;
291 args
.flags
= EC_HOST_ARGS_FLAG_FROM_HOST
;
292 args
.command_version
= cec_command
->cmd_version
;
293 args
.data_size
= cec_command
->cmd_size_in
;
295 /* Initialize checksum */
296 csum
= cmd_code
+ args
.flags
+ args
.command_version
+ args
.data_size
;
298 write_bytes(EC_LPC_ADDR_HOST_PARAM
,
299 cec_command
->cmd_size_in
,
300 (u8
*)cec_command
->cmd_data_in
,
303 /* Finalize checksum and write args */
304 args
.checksum
= csum
;
305 write_bytes(EC_LPC_ADDR_HOST_ARGS
, sizeof(args
), (u8
*)&args
, NULL
);
307 /* Issue the command */
308 write_byte(cmd_code
, EC_LPC_ADDR_HOST_CMD
);
310 if (google_chromeec_wait_ready(EC_LPC_ADDR_HOST_CMD
)) {
311 printk(BIOS_ERR
, "Timeout waiting for EC process command %d!\n",
312 cec_command
->cmd_code
);
317 cec_command
->cmd_code
= read_byte(EC_LPC_ADDR_HOST_DATA
);
318 if (cec_command
->cmd_code
)
322 read_bytes(EC_LPC_ADDR_HOST_ARGS
, sizeof(args
), (u8
*)&args
, NULL
);
325 * If EC didn't modify args flags, then somehow we sent a new-style
326 * command to an old EC, which means it would have read its params
327 * from the wrong place.
329 if (!(args
.flags
& EC_HOST_ARGS_FLAG_TO_HOST
)) {
330 printk(BIOS_ERR
, "EC protocol mismatch\n");
334 if (args
.data_size
> cec_command
->cmd_size_out
) {
335 printk(BIOS_ERR
, "EC returned too much data\n");
338 cec_command
->cmd_size_out
= args
.data_size
;
340 /* Start calculating response checksum */
341 csum
= cmd_code
+ args
.flags
+ args
.command_version
+ args
.data_size
;
343 /* Read data, if any */
344 read_bytes(EC_LPC_ADDR_HOST_PARAM
,
346 cec_command
->cmd_data_out
,
349 /* Verify checksum */
350 if (args
.checksum
!= csum
) {
351 printk(BIOS_ERR
, "EC response has invalid checksum\n");
358 /* Return the byte of EC switch states */
359 uint8_t google_chromeec_get_switches(void)
361 return read_byte(EC_LPC_ADDR_MEMMAP
+ EC_MEMMAP_SWITCHES
);
364 void google_chromeec_ioport_range(uint16_t *out_base
, size_t *out_size
)
369 if (CONFIG(EC_GOOGLE_CHROMEEC_MEC
)) {
373 base
= EC_HOST_CMD_REGION0
;
374 size
= 2 * EC_HOST_CMD_REGION_SIZE
;
375 /* Make sure MEMMAP region follows host cmd region. */
376 assert(base
+ size
== EC_LPC_ADDR_MEMMAP
);
377 size
+= EC_MEMMAP_SIZE
;
384 int google_chromeec_command(struct chromeec_command
*cec_command
)
386 static int command_version
;
388 if (command_version
<= 0)
389 command_version
= google_chromeec_command_version();
391 switch (command_version
) {
392 case EC_HOST_CMD_FLAG_VERSION_3
:
393 return google_chromeec_command_v3(cec_command
);
394 case EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED
:
395 return google_chromeec_command_v1(cec_command
);
400 static void lpc_ec_init(struct device
*dev
)
405 google_chromeec_init();
409 * Declare the IO ports that we are using:
411 * All ECs (not explicitly declared):
412 * 0x60/0x64, 0x62/0x66, 0x80, 0x200->0x207
414 * mec1322: 0x800->0x807
415 * All others: 0x800->0x9ff
417 * EC_GOOGLE_CHROMEEC_ACPI_MEMMAP is only used for MEC ECs.
419 static void lpc_ec_read_resources(struct device
*dev
)
421 unsigned int idx
= 0;
422 struct resource
* res
;
426 google_chromeec_ioport_range(&base
, &size
);
427 res
= new_resource(dev
, idx
++);
430 res
->flags
= IORESOURCE_IO
| IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
433 static struct device_operations ops
= {
435 .read_resources
= lpc_ec_read_resources
,
436 .set_resources
= noop_set_resources
,
437 .scan_bus
= scan_static_bus
,
438 #if CONFIG(HAVE_ACPI_TABLES)
439 .acpi_name
= google_chromeec_acpi_name
,
440 .acpi_fill_ssdt
= google_chromeec_fill_ssdt_generator
,
444 static struct pnp_info pnp_dev_info
[] = {
448 static void enable_dev(struct device
*dev
)
450 pnp_enable_devices(dev
, &ops
, ARRAY_SIZE(pnp_dev_info
), pnp_dev_info
);
453 struct chip_operations ec_google_chromeec_ops
= {
454 .name
= "Google Chrome EC",
455 .enable_dev
= enable_dev
,
458 static int google_chromeec_data_ready(u16 port
)
460 return google_chromeec_status_check(port
, EC_LPC_CMDR_DATA
,
464 enum host_event_code
google_chromeec_get_event(void)
466 if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD
)) {
467 printk(BIOS_ERR
, "Timeout waiting for EC ready!\n");
468 return EC_HOST_EVENT_NONE
;
471 /* Issue the ACPI query-event command */
472 write_byte(EC_CMD_ACPI_QUERY_EVENT
, EC_LPC_ADDR_ACPI_CMD
);
474 if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD
)) {
475 printk(BIOS_ERR
, "Timeout waiting for EC QUERY_EVENT!\n");
476 return EC_HOST_EVENT_NONE
;
479 if (google_chromeec_data_ready(EC_LPC_ADDR_ACPI_CMD
)) {
480 printk(BIOS_ERR
, "Timeout waiting for data ready!\n");
481 return EC_HOST_EVENT_NONE
;
484 /* Event (or 0 if none) is returned directly in the data byte */
485 return read_byte(EC_LPC_ADDR_ACPI_DATA
);