linux/drivers/i2c/busses/i2c-amd-mp2.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
   2/*
   3 * AMD MP2 I2C adapter driver
   4 *
   5 * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
   6 *          Elie Morisse <syniurge@gmail.com>
   7 */
   8
   9#ifndef I2C_AMD_PCI_MP2_H
  10#define I2C_AMD_PCI_MP2_H
  11
  12#include <linux/i2c.h>
  13#include <linux/pci.h>
  14#include <linux/pm_runtime.h>
  15
  16#define PCI_DEVICE_ID_AMD_MP2   0x15E6
  17
  18struct amd_i2c_common;
  19struct amd_mp2_dev;
  20
  21enum {
  22        /* MP2 C2P Message Registers */
  23        AMD_C2P_MSG0 = 0x10500,                 /* MP2 Message for I2C0 */
  24        AMD_C2P_MSG1 = 0x10504,                 /* MP2 Message for I2C1 */
  25        AMD_C2P_MSG2 = 0x10508,                 /* DRAM Address Lo / Data 0 */
  26        AMD_C2P_MSG3 = 0x1050c,                 /* DRAM Address HI / Data 1 */
  27        AMD_C2P_MSG4 = 0x10510,                 /* Data 2 */
  28        AMD_C2P_MSG5 = 0x10514,                 /* Data 3 */
  29        AMD_C2P_MSG6 = 0x10518,                 /* Data 4 */
  30        AMD_C2P_MSG7 = 0x1051c,                 /* Data 5 */
  31        AMD_C2P_MSG8 = 0x10520,                 /* Data 6 */
  32        AMD_C2P_MSG9 = 0x10524,                 /* Data 7 */
  33
  34        /* MP2 P2C Message Registers */
  35        AMD_P2C_MSG0 = 0x10680,                 /* Do not use */
  36        AMD_P2C_MSG1 = 0x10684,                 /* I2C0 interrupt register */
  37        AMD_P2C_MSG2 = 0x10688,                 /* I2C1 interrupt register */
  38        AMD_P2C_MSG3 = 0x1068C,                 /* MP2 debug info */
  39        AMD_P2C_MSG_INTEN = 0x10690,            /* MP2 interrupt gen register */
  40        AMD_P2C_MSG_INTSTS = 0x10694,           /* Interrupt status */
  41};
  42
  43/* Command register data structures */
  44
  45#define i2c_none (-1)
  46enum i2c_cmd {
  47        i2c_read = 0,
  48        i2c_write,
  49        i2c_enable,
  50        i2c_disable,
  51        number_of_sensor_discovered,
  52        is_mp2_active,
  53        invalid_cmd = 0xF,
  54};
  55
  56enum speed_enum {
  57        speed100k = 0,
  58        speed400k = 1,
  59        speed1000k = 2,
  60        speed1400k = 3,
  61        speed3400k = 4
  62};
  63
  64enum mem_type {
  65        use_dram = 0,
  66        use_c2pmsg = 1,
  67};
  68
  69/**
  70 * union i2c_cmd_base : bit access of C2P commands
  71 * @i2c_cmd: bit 0..3 i2c R/W command
  72 * @bus_id: bit 4..7 i2c bus index
  73 * @slave_addr: bit 8..15 slave address
  74 * @length: bit 16..27 read/write length
  75 * @i2c_speed: bit 28..30 bus speed
  76 * @mem_type: bit 31 0-DRAM; 1-C2P msg o/p
  77 */
  78union i2c_cmd_base {
  79        u32 ul;
  80        struct {
  81                enum i2c_cmd i2c_cmd : 4;
  82                u8 bus_id : 4;
  83                u32 slave_addr : 8;
  84                u32 length : 12;
  85                enum speed_enum i2c_speed : 3;
  86                enum mem_type mem_type : 1;
  87        } s;
  88};
  89
  90enum response_type {
  91        invalid_response = 0,
  92        command_success = 1,
  93        command_failed = 2,
  94};
  95
  96enum status_type {
  97        i2c_readcomplete_event = 0,
  98        i2c_readfail_event = 1,
  99        i2c_writecomplete_event = 2,
 100        i2c_writefail_event = 3,
 101        i2c_busenable_complete = 4,
 102        i2c_busenable_failed = 5,
 103        i2c_busdisable_complete = 6,
 104        i2c_busdisable_failed = 7,
 105        invalid_data_length = 8,
 106        invalid_slave_address = 9,
 107        invalid_i2cbus_id = 10,
 108        invalid_dram_addr = 11,
 109        invalid_command = 12,
 110        mp2_active = 13,
 111        numberof_sensors_discovered_resp = 14,
 112        i2c_bus_notinitialized
 113};
 114
 115/**
 116 * union i2c_event : bit access of P2C events
 117 * @response: bit 0..1 i2c response type
 118 * @status: bit 2..6 status_type
 119 * @mem_type: bit 7 0-DRAM; 1-C2P msg o/p
 120 * @bus_id: bit 8..11 i2c bus id
 121 * @length: bit 12..23 message length
 122 * @slave_addr: bit 24-31 slave address
 123 */
 124union i2c_event {
 125        u32 ul;
 126        struct {
 127                enum response_type response : 2;
 128                enum status_type status : 5;
 129                enum mem_type mem_type : 1;
 130                u8 bus_id : 4;
 131                u32 length : 12;
 132                u32 slave_addr : 8;
 133        } r;
 134};
 135
 136/**
 137 * struct amd_i2c_common - per bus/i2c adapter context, shared
 138 *      between the pci and the platform driver
 139 * @eventval: MP2 event value set by the IRQ handler
 140 * @mp2_dev: MP2 pci device this adapter is part of
 141 * @msg: i2c message
 142 * @cmd_completion: function called by the IRQ handler to signal
 143 *                  the platform driver
 144 * @reqcmd: requested i2c command type
 145 * @cmd_success: set to true if the MP2 responded to a command with
 146 *               the expected status and response type
 147 * @bus_id: bus index
 148 * @i2c_speed: i2c bus speed determined by the slowest slave
 149 * @dma_buf: if msg length > 32, holds the DMA buffer virtual address
 150 * @dma_addr: if msg length > 32, holds the DMA buffer address
 151 */
 152struct amd_i2c_common {
 153        union i2c_event eventval;
 154        struct amd_mp2_dev *mp2_dev;
 155        struct i2c_msg *msg;
 156        void (*cmd_completion)(struct amd_i2c_common *i2c_common);
 157        enum i2c_cmd reqcmd;
 158        u8 cmd_success;
 159        u8 bus_id;
 160        enum speed_enum i2c_speed;
 161        u8 *dma_buf;
 162        dma_addr_t dma_addr;
 163#ifdef CONFIG_PM
 164        int (*suspend)(struct amd_i2c_common *i2c_common);
 165        int (*resume)(struct amd_i2c_common *i2c_common);
 166#endif /* CONFIG_PM */
 167};
 168
 169/**
 170 * struct amd_mp2_dev - per PCI device context
 171 * @pci_dev: PCI driver node
 172 * @busses: MP2 devices may have up to two busses,
 173 *          each bus corresponding to an i2c adapter
 174 * @mmio: iommapped registers
 175 * @c2p_lock: controls access to the C2P mailbox shared between
 176 *            the two adapters
 177 * @c2p_lock_busid: id of the adapter which locked c2p_lock
 178 */
 179struct amd_mp2_dev {
 180        struct pci_dev *pci_dev;
 181        struct amd_i2c_common *busses[2];
 182        void __iomem *mmio;
 183        struct mutex c2p_lock;
 184        u8 c2p_lock_busid;
 185        unsigned int probed;
 186};
 187
 188/* PCIe communication driver */
 189
 190int amd_mp2_rw(struct amd_i2c_common *i2c_common, enum i2c_cmd reqcmd);
 191int amd_mp2_bus_enable_set(struct amd_i2c_common *i2c_common, bool enable);
 192
 193void amd_mp2_process_event(struct amd_i2c_common *i2c_common);
 194
 195void amd_mp2_rw_timeout(struct amd_i2c_common *i2c_common);
 196
 197int amd_mp2_register_cb(struct amd_i2c_common *i2c_common);
 198int amd_mp2_unregister_cb(struct amd_i2c_common *i2c_common);
 199
 200struct amd_mp2_dev *amd_mp2_find_device(void);
 201
 202static inline void amd_mp2_pm_runtime_get(struct amd_mp2_dev *mp2_dev)
 203{
 204        pm_runtime_get_sync(&mp2_dev->pci_dev->dev);
 205}
 206
 207static inline void amd_mp2_pm_runtime_put(struct amd_mp2_dev *mp2_dev)
 208{
 209        pm_runtime_mark_last_busy(&mp2_dev->pci_dev->dev);
 210        pm_runtime_put_autosuspend(&mp2_dev->pci_dev->dev);
 211}
 212
 213#endif
 214