cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

i2c.h (5447B)


      1/* SPDX-License-Identifier: MIT */
      2#ifndef __NVKM_I2C_H__
      3#define __NVKM_I2C_H__
      4#include <core/subdev.h>
      5#include <core/event.h>
      6
      7#include <subdev/bios.h>
      8#include <subdev/bios/i2c.h>
      9
     10struct nvkm_i2c_ntfy_req {
     11#define NVKM_I2C_PLUG                                                      0x01
     12#define NVKM_I2C_UNPLUG                                                    0x02
     13#define NVKM_I2C_IRQ                                                       0x04
     14#define NVKM_I2C_DONE                                                      0x08
     15#define NVKM_I2C_ANY                                                       0x0f
     16	u8 mask;
     17	u8 port;
     18};
     19
     20struct nvkm_i2c_ntfy_rep {
     21	u8 mask;
     22};
     23
     24struct nvkm_i2c_bus_probe {
     25	struct i2c_board_info dev;
     26	u8 udelay; /* set to 0 to use the standard delay */
     27};
     28
     29struct nvkm_i2c_bus {
     30	const struct nvkm_i2c_bus_func *func;
     31	struct nvkm_i2c_pad *pad;
     32#define NVKM_I2C_BUS_CCB(n) /* 'n' is ccb index */                           (n)
     33#define NVKM_I2C_BUS_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x100)
     34#define NVKM_I2C_BUS_PRI /* ccb primary comm. port */                        -1
     35#define NVKM_I2C_BUS_SEC /* ccb secondary comm. port */                      -2
     36	int id;
     37
     38	struct mutex mutex;
     39	struct list_head head;
     40	struct i2c_adapter i2c;
     41	u8 enabled;
     42};
     43
     44int nvkm_i2c_bus_acquire(struct nvkm_i2c_bus *);
     45void nvkm_i2c_bus_release(struct nvkm_i2c_bus *);
     46int nvkm_i2c_bus_probe(struct nvkm_i2c_bus *, const char *,
     47		       struct nvkm_i2c_bus_probe *,
     48		       bool (*)(struct nvkm_i2c_bus *,
     49			        struct i2c_board_info *, void *), void *);
     50
     51struct nvkm_i2c_aux {
     52	const struct nvkm_i2c_aux_func *func;
     53	struct nvkm_i2c_pad *pad;
     54#define NVKM_I2C_AUX_CCB(n) /* 'n' is ccb index */                           (n)
     55#define NVKM_I2C_AUX_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x100)
     56	int id;
     57
     58	struct mutex mutex;
     59	struct list_head head;
     60	struct i2c_adapter i2c;
     61	u8 enabled;
     62
     63	u32 intr;
     64};
     65
     66void nvkm_i2c_aux_monitor(struct nvkm_i2c_aux *, bool monitor);
     67int nvkm_i2c_aux_acquire(struct nvkm_i2c_aux *);
     68void nvkm_i2c_aux_release(struct nvkm_i2c_aux *);
     69int nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *, bool retry, u8 type,
     70		      u32 addr, u8 *data, u8 *size);
     71int nvkm_i2c_aux_lnk_ctl(struct nvkm_i2c_aux *, int link_nr, int link_bw,
     72			 bool enhanced_framing);
     73
     74struct nvkm_i2c {
     75	const struct nvkm_i2c_func *func;
     76	struct nvkm_subdev subdev;
     77
     78	struct list_head pad;
     79	struct list_head bus;
     80	struct list_head aux;
     81
     82	struct nvkm_event event;
     83};
     84
     85struct nvkm_i2c_bus *nvkm_i2c_bus_find(struct nvkm_i2c *, int);
     86struct nvkm_i2c_aux *nvkm_i2c_aux_find(struct nvkm_i2c *, int);
     87
     88int nv04_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
     89int nv4e_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
     90int nv50_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
     91int g94_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
     92int gf117_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
     93int gf119_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
     94int gk104_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
     95int gk110_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
     96int gm200_i2c_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_i2c **);
     97
     98static inline int
     99nvkm_rdi2cr(struct i2c_adapter *adap, u8 addr, u8 reg)
    100{
    101	u8 val;
    102	struct i2c_msg msgs[] = {
    103		{ .addr = addr, .flags = 0, .len = 1, .buf = &reg },
    104		{ .addr = addr, .flags = I2C_M_RD, .len = 1, .buf = &val },
    105	};
    106
    107	int ret = i2c_transfer(adap, msgs, ARRAY_SIZE(msgs));
    108	if (ret != 2)
    109		return -EIO;
    110
    111	return val;
    112}
    113
    114static inline int
    115nv_rd16i2cr(struct i2c_adapter *adap, u8 addr, u8 reg)
    116{
    117	u8 val[2];
    118	struct i2c_msg msgs[] = {
    119		{ .addr = addr, .flags = 0, .len = 1, .buf = &reg },
    120		{ .addr = addr, .flags = I2C_M_RD, .len = 2, .buf = val },
    121	};
    122
    123	int ret = i2c_transfer(adap, msgs, ARRAY_SIZE(msgs));
    124	if (ret != 2)
    125		return -EIO;
    126
    127	return val[0] << 8 | val[1];
    128}
    129
    130static inline int
    131nvkm_wri2cr(struct i2c_adapter *adap, u8 addr, u8 reg, u8 val)
    132{
    133	u8 buf[2] = { reg, val };
    134	struct i2c_msg msgs[] = {
    135		{ .addr = addr, .flags = 0, .len = 2, .buf = buf },
    136	};
    137
    138	int ret = i2c_transfer(adap, msgs, ARRAY_SIZE(msgs));
    139	if (ret != 1)
    140		return -EIO;
    141
    142	return 0;
    143}
    144
    145static inline int
    146nv_wr16i2cr(struct i2c_adapter *adap, u8 addr, u8 reg, u16 val)
    147{
    148	u8 buf[3] = { reg, val >> 8, val & 0xff};
    149	struct i2c_msg msgs[] = {
    150		{ .addr = addr, .flags = 0, .len = 3, .buf = buf },
    151	};
    152
    153	int ret = i2c_transfer(adap, msgs, ARRAY_SIZE(msgs));
    154	if (ret != 1)
    155		return -EIO;
    156
    157	return 0;
    158}
    159
    160static inline bool
    161nvkm_probe_i2c(struct i2c_adapter *adap, u8 addr)
    162{
    163	return nvkm_rdi2cr(adap, addr, 0) >= 0;
    164}
    165
    166static inline int
    167nvkm_rdaux(struct nvkm_i2c_aux *aux, u32 addr, u8 *data, u8 size)
    168{
    169	const u8 xfer = size;
    170	int ret = nvkm_i2c_aux_acquire(aux);
    171	if (ret == 0) {
    172		ret = nvkm_i2c_aux_xfer(aux, true, 9, addr, data, &size);
    173		WARN_ON(!ret && size != xfer);
    174		nvkm_i2c_aux_release(aux);
    175	}
    176	return ret;
    177}
    178
    179static inline int
    180nvkm_wraux(struct nvkm_i2c_aux *aux, u32 addr, u8 *data, u8 size)
    181{
    182	int ret = nvkm_i2c_aux_acquire(aux);
    183	if (ret == 0) {
    184		ret = nvkm_i2c_aux_xfer(aux, true, 8, addr, data, &size);
    185		nvkm_i2c_aux_release(aux);
    186	}
    187	return ret;
    188}
    189#endif