1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #define __SIMPLE_DEVICE__
4
5 #include <arch/io.h>
6 #include <device/pnp.h>
7 #include <device/pnp_ops.h>
8 #include <types.h>
9
10 #include "ec.h"
11
12 /* 10.7.2 ENABLE CONFIG MODE */
pnp_enter_conf_state(const pnp_devfn_t dev)13 static void pnp_enter_conf_state(const pnp_devfn_t dev)
14 {
15 const u16 port = dev >> 8;
16 outb(0x55, port);
17 }
18
19 /* 10.7.3 DISABLE CONFIG MODE */
pnp_exit_conf_state(const pnp_devfn_t dev)20 static void pnp_exit_conf_state(const pnp_devfn_t dev)
21 {
22 const u16 port = dev >> 8;
23 outb(0xaa, port);
24 }
25
ec_espi_io_program_iobase(const u16 port,const u8 iobase_index,const u16 base)26 void ec_espi_io_program_iobase(const u16 port, const u8 iobase_index, const u16 base)
27 {
28 const pnp_devfn_t dev = PNP_DEV(port, LDN_ESPI_IO_COMPONENT);
29
30 pnp_enter_conf_state(dev);
31 pnp_set_logical_device(dev);
32 pnp_write_config(dev, iobase_index + 2, (base & 0x00ff) >> 0); /* Addr LSB */
33 pnp_write_config(dev, iobase_index + 3, (base & 0xff00) >> 8); /* Addr MSB */
34 pnp_write_config(dev, iobase_index + 0, base != 0x0000); /* Valid bit */
35 pnp_exit_conf_state(dev);
36 }
37
38 /* TABLE 14-5: RUNTIME REGISTER SUMMARY */
39 #define HOST_EC_MBOX 0x00
40 #define EC_HOST_MBOX 0x01
41 #define EC_ADDRESS_LSB 0x02
42 #define EC_ADDRESS_MSB 0x03
43 #define EC_DATA_BYTE(n) (0x04 + (n) % sizeof(u32))
44 #define INTERRUPT_SOURCE_LSB 0x08
45 #define INTERRUPT_SOURCE_MSB 0x09
46 #define INTERRUPT_MASK_LSB 0x0a
47 #define INTERRUPT_MASK_MSB 0x0b
48 #define APPLICATION_ID 0x0c
49
50 /* 14.8.3 ACCESS TYPES */
51 enum emi_access_type {
52 EMI_ACCESS_8_BIT = 0,
53 EMI_ACCESS_16_BIT = 1,
54 EMI_ACCESS_32_BIT = 2,
55 EMI_ACCESS_32_BIT_AUTO_INC = 3,
56 };
57
ec_emi_read(u8 * dest,const u16 base,const u8 region,const u16 offset,const u16 length)58 void ec_emi_read(u8 *dest, const u16 base, const u8 region, const u16 offset, const u16 length)
59 {
60 const u16 addr = ((region & 1) << 15) | (offset & 0x7ffc) | EMI_ACCESS_32_BIT_AUTO_INC;
61
62 outb((addr & 0x00ff) >> 0, base + EC_ADDRESS_LSB);
63 outb((addr & 0xff00) >> 8, base + EC_ADDRESS_MSB);
64
65 /* EC_ADDRESS auto-increment happens when accessing EC_DATA_BYTE_3 */
66 for (u16 i = 0; i < length; i++)
67 dest[i] = inb(base + EC_DATA_BYTE(offset + i));
68 }
69