summaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-octeon-core.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-octeon-core.h')
-rw-r--r--drivers/i2c/busses/i2c-octeon-core.h53
1 files changed, 41 insertions, 12 deletions
diff --git a/drivers/i2c/busses/i2c-octeon-core.h b/drivers/i2c/busses/i2c-octeon-core.h
index 9bb9f64fdd..7af01864da 100644
--- a/drivers/i2c/busses/i2c-octeon-core.h
+++ b/drivers/i2c/busses/i2c-octeon-core.h
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/atomic.h>
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
@@ -7,6 +8,7 @@
#include <linux/i2c-smbus.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/pci.h>
/* Controller command patterns */
#define SW_TWSI_V BIT_ULL(63) /* Valid bit */
@@ -71,6 +73,7 @@
#define STAT_SLAVE_ACK 0xC8
#define STAT_AD2W_ACK 0xD0
#define STAT_AD2W_NAK 0xD8
+#define STAT_WDOG_TOUT 0xF0
#define STAT_IDLE 0xF8
/* TWSI_INT values */
@@ -92,11 +95,21 @@ struct octeon_i2c_reg_offset {
unsigned int sw_twsi;
unsigned int twsi_int;
unsigned int sw_twsi_ext;
+ unsigned int mode;
};
-#define SW_TWSI(x) (x->roff.sw_twsi)
-#define TWSI_INT(x) (x->roff.twsi_int)
-#define SW_TWSI_EXT(x) (x->roff.sw_twsi_ext)
+#define OCTEON_REG_SW_TWSI(x) ((x)->roff.sw_twsi)
+#define OCTEON_REG_TWSI_INT(x) ((x)->roff.twsi_int)
+#define OCTEON_REG_SW_TWSI_EXT(x) ((x)->roff.sw_twsi_ext)
+#define OCTEON_REG_MODE(x) ((x)->roff.mode)
+
+/* Set REFCLK_SRC and HS_MODE in TWSX_MODE register */
+#define TWSX_MODE_REFCLK_SRC BIT(4)
+#define TWSX_MODE_HS_MODE BIT(0)
+#define TWSX_MODE_HS_MASK (TWSX_MODE_REFCLK_SRC | TWSX_MODE_HS_MODE)
+
+/* Set BUS_MON_RST to reset bus monitor */
+#define BUS_MON_RST_MASK BIT(3)
struct octeon_i2c {
wait_queue_head_t queue;
@@ -134,16 +147,16 @@ static inline void octeon_i2c_writeq_flush(u64 val, void __iomem *addr)
* @eop_reg: Register selector
* @data: Value to be written
*
- * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
+ * The I2C core registers are accessed indirectly via the OCTEON_REG_SW_TWSI CSR.
*/
static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8 data)
{
int tries = 1000;
u64 tmp;
- __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI(i2c));
+ __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
do {
- tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ tmp = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
if (--tries < 0)
return;
} while ((tmp & SW_TWSI_V) != 0);
@@ -169,9 +182,9 @@ static inline int octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg,
int tries = 1000;
u64 tmp;
- __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI(i2c));
+ __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
do {
- tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ tmp = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
if (--tries < 0) {
/* signal that the returned data is invalid */
if (error)
@@ -191,24 +204,40 @@ static inline int octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg,
octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT, NULL)
/**
- * octeon_i2c_read_int - read the TWSI_INT register
+ * octeon_i2c_read_int - read the OCTEON_REG_TWSI_INT register
* @i2c: The struct octeon_i2c
*
* Returns the value of the register.
*/
static inline u64 octeon_i2c_read_int(struct octeon_i2c *i2c)
{
- return __raw_readq(i2c->twsi_base + TWSI_INT(i2c));
+ return __raw_readq(i2c->twsi_base + OCTEON_REG_TWSI_INT(i2c));
}
/**
- * octeon_i2c_write_int - write the TWSI_INT register
+ * octeon_i2c_write_int - write the OCTEON_REG_TWSI_INT register
* @i2c: The struct octeon_i2c
* @data: Value to be written
*/
static inline void octeon_i2c_write_int(struct octeon_i2c *i2c, u64 data)
{
- octeon_i2c_writeq_flush(data, i2c->twsi_base + TWSI_INT(i2c));
+ octeon_i2c_writeq_flush(data, i2c->twsi_base + OCTEON_REG_TWSI_INT(i2c));
+}
+
+#define IS_LS_FREQ(twsi_freq) ((twsi_freq) <= 400000)
+#define PCI_SUBSYS_DEVID_9XXX 0xB
+#define PCI_SUBSYS_MASK GENMASK(15, 12)
+/**
+ * octeon_i2c_is_otx2 - check for chip ID
+ * @pdev: PCI dev structure
+ *
+ * Returns true if the device is an OcteonTX2, false otherwise.
+ */
+static inline bool octeon_i2c_is_otx2(struct pci_dev *pdev)
+{
+ u32 chip_id = FIELD_GET(PCI_SUBSYS_MASK, pdev->subsystem_device);
+
+ return (chip_id == PCI_SUBSYS_DEVID_9XXX);
}
/* Prototypes */