xref: /openbmc/qemu/tests/qtest/qtest_aspeed.c (revision f0de6356)
1*f0de6356SStefan Berger /*
2*f0de6356SStefan Berger  * Aspeed i2c bus interface for reading from and writing to i2c device registers
3*f0de6356SStefan Berger  *
4*f0de6356SStefan Berger  * Copyright (c) 2023 IBM Corporation
5*f0de6356SStefan Berger  *
6*f0de6356SStefan Berger  * Authors:
7*f0de6356SStefan Berger  *   Stefan Berger <stefanb@linux.ibm.com>
8*f0de6356SStefan Berger  *
9*f0de6356SStefan Berger  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10*f0de6356SStefan Berger  * See the COPYING file in the top-level directory.
11*f0de6356SStefan Berger  */
12*f0de6356SStefan Berger 
13*f0de6356SStefan Berger #include "qemu/osdep.h"
14*f0de6356SStefan Berger 
15*f0de6356SStefan Berger #include "qtest_aspeed.h"
16*f0de6356SStefan Berger #include "hw/i2c/aspeed_i2c.h"
17*f0de6356SStefan Berger 
aspeed_i2c_startup(QTestState * s,uint32_t baseaddr,uint8_t slave_addr,uint8_t reg)18*f0de6356SStefan Berger static void aspeed_i2c_startup(QTestState *s, uint32_t baseaddr,
19*f0de6356SStefan Berger                                uint8_t slave_addr, uint8_t reg)
20*f0de6356SStefan Berger {
21*f0de6356SStefan Berger     uint32_t v;
22*f0de6356SStefan Berger     static int once;
23*f0de6356SStefan Berger 
24*f0de6356SStefan Berger     if (!once) {
25*f0de6356SStefan Berger         /* one time: enable master */
26*f0de6356SStefan Berger        qtest_writel(s, baseaddr + A_I2CC_FUN_CTRL, 0);
27*f0de6356SStefan Berger        v = qtest_readl(s, baseaddr + A_I2CC_FUN_CTRL) | A_I2CD_MASTER_EN;
28*f0de6356SStefan Berger        qtest_writel(s, baseaddr + A_I2CC_FUN_CTRL, v);
29*f0de6356SStefan Berger        once = 1;
30*f0de6356SStefan Berger     }
31*f0de6356SStefan Berger 
32*f0de6356SStefan Berger     /* select device */
33*f0de6356SStefan Berger     qtest_writel(s, baseaddr + A_I2CD_BYTE_BUF, slave_addr << 1);
34*f0de6356SStefan Berger     qtest_writel(s, baseaddr + A_I2CD_CMD,
35*f0de6356SStefan Berger                  A_I2CD_M_START_CMD | A_I2CD_M_RX_CMD);
36*f0de6356SStefan Berger 
37*f0de6356SStefan Berger     /* select the register to write to */
38*f0de6356SStefan Berger     qtest_writel(s, baseaddr + A_I2CD_BYTE_BUF, reg);
39*f0de6356SStefan Berger     qtest_writel(s, baseaddr + A_I2CD_CMD, A_I2CD_M_TX_CMD);
40*f0de6356SStefan Berger }
41*f0de6356SStefan Berger 
aspeed_i2c_read_n(QTestState * s,uint32_t baseaddr,uint8_t slave_addr,uint8_t reg,size_t nbytes)42*f0de6356SStefan Berger static uint32_t aspeed_i2c_read_n(QTestState *s,
43*f0de6356SStefan Berger                                   uint32_t baseaddr, uint8_t slave_addr,
44*f0de6356SStefan Berger                                   uint8_t reg, size_t nbytes)
45*f0de6356SStefan Berger {
46*f0de6356SStefan Berger     uint32_t res = 0;
47*f0de6356SStefan Berger     uint32_t v;
48*f0de6356SStefan Berger     size_t i;
49*f0de6356SStefan Berger 
50*f0de6356SStefan Berger     aspeed_i2c_startup(s, baseaddr, slave_addr, reg);
51*f0de6356SStefan Berger 
52*f0de6356SStefan Berger     for (i = 0; i < nbytes; i++) {
53*f0de6356SStefan Berger         qtest_writel(s, baseaddr + A_I2CD_CMD, A_I2CD_M_RX_CMD);
54*f0de6356SStefan Berger         v = qtest_readl(s, baseaddr + A_I2CD_BYTE_BUF) >> 8;
55*f0de6356SStefan Berger         res |= (v & 0xff) << (i * 8);
56*f0de6356SStefan Berger     }
57*f0de6356SStefan Berger 
58*f0de6356SStefan Berger     qtest_writel(s, baseaddr + A_I2CD_CMD, A_I2CD_M_STOP_CMD);
59*f0de6356SStefan Berger 
60*f0de6356SStefan Berger     return res;
61*f0de6356SStefan Berger }
62*f0de6356SStefan Berger 
aspeed_i2c_readl(QTestState * s,uint32_t baseaddr,uint8_t slave_addr,uint8_t reg)63*f0de6356SStefan Berger uint32_t aspeed_i2c_readl(QTestState *s,
64*f0de6356SStefan Berger                           uint32_t baseaddr, uint8_t slave_addr, uint8_t reg)
65*f0de6356SStefan Berger {
66*f0de6356SStefan Berger     return aspeed_i2c_read_n(s, baseaddr, slave_addr, reg, sizeof(uint32_t));
67*f0de6356SStefan Berger }
68*f0de6356SStefan Berger 
aspeed_i2c_readw(QTestState * s,uint32_t baseaddr,uint8_t slave_addr,uint8_t reg)69*f0de6356SStefan Berger uint16_t aspeed_i2c_readw(QTestState *s,
70*f0de6356SStefan Berger                           uint32_t baseaddr, uint8_t slave_addr, uint8_t reg)
71*f0de6356SStefan Berger {
72*f0de6356SStefan Berger     return aspeed_i2c_read_n(s, baseaddr, slave_addr, reg, sizeof(uint16_t));
73*f0de6356SStefan Berger }
74*f0de6356SStefan Berger 
aspeed_i2c_readb(QTestState * s,uint32_t baseaddr,uint8_t slave_addr,uint8_t reg)75*f0de6356SStefan Berger uint8_t aspeed_i2c_readb(QTestState *s,
76*f0de6356SStefan Berger                          uint32_t baseaddr, uint8_t slave_addr, uint8_t reg)
77*f0de6356SStefan Berger {
78*f0de6356SStefan Berger     return aspeed_i2c_read_n(s, baseaddr, slave_addr, reg, sizeof(uint8_t));
79*f0de6356SStefan Berger }
80*f0de6356SStefan Berger 
aspeed_i2c_write_n(QTestState * s,uint32_t baseaddr,uint8_t slave_addr,uint8_t reg,uint32_t v,size_t nbytes)81*f0de6356SStefan Berger static void aspeed_i2c_write_n(QTestState *s,
82*f0de6356SStefan Berger                                uint32_t baseaddr, uint8_t slave_addr,
83*f0de6356SStefan Berger                                uint8_t reg, uint32_t v, size_t nbytes)
84*f0de6356SStefan Berger {
85*f0de6356SStefan Berger     size_t i;
86*f0de6356SStefan Berger 
87*f0de6356SStefan Berger     aspeed_i2c_startup(s, baseaddr, slave_addr, reg);
88*f0de6356SStefan Berger 
89*f0de6356SStefan Berger     for (i = 0; i < nbytes; i++) {
90*f0de6356SStefan Berger         qtest_writel(s, baseaddr + A_I2CD_BYTE_BUF, v & 0xff);
91*f0de6356SStefan Berger         v >>= 8;
92*f0de6356SStefan Berger         qtest_writel(s, baseaddr + A_I2CD_CMD, A_I2CD_M_TX_CMD);
93*f0de6356SStefan Berger     }
94*f0de6356SStefan Berger 
95*f0de6356SStefan Berger     qtest_writel(s, baseaddr + A_I2CD_CMD, A_I2CD_M_STOP_CMD);
96*f0de6356SStefan Berger }
97*f0de6356SStefan Berger 
aspeed_i2c_writel(QTestState * s,uint32_t baseaddr,uint8_t slave_addr,uint8_t reg,uint32_t v)98*f0de6356SStefan Berger void aspeed_i2c_writel(QTestState *s,
99*f0de6356SStefan Berger                        uint32_t baseaddr, uint8_t slave_addr,
100*f0de6356SStefan Berger                        uint8_t reg, uint32_t v)
101*f0de6356SStefan Berger {
102*f0de6356SStefan Berger     aspeed_i2c_write_n(s, baseaddr, slave_addr, reg, v, sizeof(v));
103*f0de6356SStefan Berger }
104*f0de6356SStefan Berger 
aspeed_i2c_writew(QTestState * s,uint32_t baseaddr,uint8_t slave_addr,uint8_t reg,uint16_t v)105*f0de6356SStefan Berger void aspeed_i2c_writew(QTestState *s,
106*f0de6356SStefan Berger                        uint32_t baseaddr, uint8_t slave_addr,
107*f0de6356SStefan Berger                        uint8_t reg, uint16_t v)
108*f0de6356SStefan Berger {
109*f0de6356SStefan Berger     aspeed_i2c_write_n(s, baseaddr, slave_addr, reg, v, sizeof(v));
110*f0de6356SStefan Berger }
111*f0de6356SStefan Berger 
aspeed_i2c_writeb(QTestState * s,uint32_t baseaddr,uint8_t slave_addr,uint8_t reg,uint8_t v)112*f0de6356SStefan Berger void aspeed_i2c_writeb(QTestState *s,
113*f0de6356SStefan Berger                        uint32_t baseaddr, uint8_t slave_addr,
114*f0de6356SStefan Berger                        uint8_t reg, uint8_t v)
115*f0de6356SStefan Berger {
116*f0de6356SStefan Berger     aspeed_i2c_write_n(s, baseaddr, slave_addr, reg, v, sizeof(v));
117*f0de6356SStefan Berger }
118