blob: b4e45bb6f4f81932f3f33481a44f30d4718bc197 [file] [log] [blame]
Angel Pons5f249e62020-04-04 18:51:01 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Angel Pons5f249e62020-04-04 18:51:01 +02002
David Hendricks8cbd5692017-12-01 20:49:48 -08003/*
David Hendricks8cbd5692017-12-01 20:49:48 -08004 * This file consists of data imported from bdk-config.c
5 */
Elyes HAOUASbf0970e2019-03-21 11:10:03 +01006
David Hendricks8cbd5692017-12-01 20:49:48 -08007// coreboot
8#include <string.h>
9#include <assert.h>
10#include <device/i2c.h>
11#include <device/i2c_simple.h>
12#include <endian.h>
David Hendricks8cbd5692017-12-01 20:49:48 -080013#include <soc/timer.h>
14
15// BDK
16#include <libbdk-arch/bdk-numa.h>
17#include <libbdk-hal/bdk-config.h>
18#include <libbdk-hal/bdk-twsi.h>
19#include <libbdk-boot/bdk-watchdog.h>
20
21/**
22 * Do a twsi read from a 7 bit device address using an (optional)
23 * internal address. Up to 4 bytes can be read at a time.
24 *
25 * @param twsi_id which TWSI bus to use
26 * @param dev_addr Device address (7 bit)
27 * @param internal_addr
Elyes HAOUAScb103462019-01-03 09:38:52 +010028 * Internal address. Can be 0, 1 or 2 bytes in width
David Hendricks8cbd5692017-12-01 20:49:48 -080029 * @param num_bytes Number of data bytes to read (1-4)
30 * @param ia_width_bytes
Elyes HAOUAScb103462019-01-03 09:38:52 +010031 * Internal address size in bytes (0, 1, or 2)
David Hendricks8cbd5692017-12-01 20:49:48 -080032 *
33 * @return Read data, or -1 on failure
34 */
35int64_t bdk_twsix_read_ia(bdk_node_t node, int twsi_id, uint8_t dev_addr,
36 uint16_t internal_addr, int num_bytes,
37 int ia_width_bytes)
38{
39 struct i2c_msg seg[2];
40 u32 buf;
41
42 assert (num_bytes < 5);
43 assert (ia_width_bytes < 3);
44
45 seg[0].flags = 0;
46 seg[0].slave = dev_addr;
47 seg[0].buf = (u8 *)&internal_addr;
48 seg[0].len = ia_width_bytes;
49 seg[1].flags = I2C_M_RD;
50 seg[1].slave = dev_addr;
51 seg[1].buf = (u8 *)&buf;
52 seg[1].len = num_bytes;
53
54 if (i2c_transfer(twsi_id, seg, ARRAY_SIZE(seg)) < 0)
55 return -1;
56
57 return cpu_to_be32(buf);
58}
59
60/**
61 * Write 1-8 bytes to a TWSI device using an internal address.
62 *
63 * @param twsi_id which TWSI interface to use
64 * @param dev_addr TWSI device address (7 bit only)
65 * @param internal_addr
Elyes HAOUAScb103462019-01-03 09:38:52 +010066 * TWSI internal address (0, 8, or 16 bits)
David Hendricks8cbd5692017-12-01 20:49:48 -080067 * @param num_bytes Number of bytes to write (1-8)
68 * @param ia_width_bytes
Elyes HAOUAScb103462019-01-03 09:38:52 +010069 * internal address width, in bytes (0, 1, 2)
70 * @param data Data to write. Data is written MSB first on the twsi bus,
71 * and only the lower num_bytes bytes of the argument are
72 * valid. If a 2 byte write is done, only the low 2 bytes of
73 * the argument is used.
David Hendricks8cbd5692017-12-01 20:49:48 -080074 *
75 * @return Zero on success, -1 on error
76 */
77int bdk_twsix_write_ia(bdk_node_t node, int twsi_id, uint8_t dev_addr,
78 uint16_t internal_addr, int num_bytes,
79 int ia_width_bytes, uint64_t data)
80{
81 struct i2c_msg seg;
82 u8 buf[10];
83
84 assert (num_bytes <= 8);
85 assert (ia_width_bytes < 3);
86
87 memcpy(buf, &internal_addr, ia_width_bytes);
88 memcpy(&buf[ia_width_bytes], &data, num_bytes);
89
90 seg.flags = 0;
91 seg.slave = dev_addr;
92 seg.buf = buf;
93 seg.len = num_bytes + ia_width_bytes;
94
95 return platform_i2c_transfer(twsi_id, &seg, 1);
96}
97
98void bdk_watchdog_set(unsigned int timeout_ms)
99{
100 watchdog_set(0, timeout_ms);
101}
102
103void bdk_watchdog_poke(void)
104{
105 watchdog_poke(0);
106}
107
108void bdk_watchdog_disable(void)
109{
110 watchdog_disable(0);
111}
112
113int bdk_watchdog_is_running(void)
114{
115 return watchdog_is_running(0);
116}