1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Intel OnChip System Fabric MailBox access support 4 */ 5 6#ifndef IOSF_MBI_SYMS_H 7#define IOSF_MBI_SYMS_H 8 9#include <linux/notifier.h> 10 11#define MBI_MCR_OFFSET 0xD0 12#define MBI_MDR_OFFSET 0xD4 13#define MBI_MCRX_OFFSET 0xD8 14 15#define MBI_RD_MASK 0xFEFFFFFF 16#define MBI_WR_MASK 0X01000000 17 18#define MBI_MASK_HI 0xFFFFFF00 19#define MBI_MASK_LO 0x000000FF 20#define MBI_ENABLE 0xF0 21 22/* IOSF SB read/write opcodes */ 23#define MBI_MMIO_READ 0x00 24#define MBI_MMIO_WRITE 0x01 25#define MBI_CFG_READ 0x04 26#define MBI_CFG_WRITE 0x05 27#define MBI_CR_READ 0x06 28#define MBI_CR_WRITE 0x07 29#define MBI_REG_READ 0x10 30#define MBI_REG_WRITE 0x11 31#define MBI_ESRAM_READ 0x12 32#define MBI_ESRAM_WRITE 0x13 33 34/* Baytrail available units */ 35#define BT_MBI_UNIT_AUNIT 0x00 36#define BT_MBI_UNIT_SMC 0x01 37#define BT_MBI_UNIT_CPU 0x02 38#define BT_MBI_UNIT_BUNIT 0x03 39#define BT_MBI_UNIT_PMC 0x04 40#define BT_MBI_UNIT_GFX 0x06 41#define BT_MBI_UNIT_SMI 0x0C 42#define BT_MBI_UNIT_USB 0x43 43#define BT_MBI_UNIT_SATA 0xA3 44#define BT_MBI_UNIT_PCIE 0xA6 45 46/* Quark available units */ 47#define QRK_MBI_UNIT_HBA 0x00 48#define QRK_MBI_UNIT_HB 0x03 49#define QRK_MBI_UNIT_RMU 0x04 50#define QRK_MBI_UNIT_MM 0x05 51#define QRK_MBI_UNIT_SOC 0x31 52 53/* Action values for the pmic_bus_access_notifier functions */ 54#define MBI_PMIC_BUS_ACCESS_BEGIN 1 55#define MBI_PMIC_BUS_ACCESS_END 2 56 57#if IS_ENABLED(CONFIG_IOSF_MBI) 58 59bool iosf_mbi_available(void); 60 61/** 62 * iosf_mbi_read() - MailBox Interface read command 63 * @port: port indicating subunit being accessed 64 * @opcode: port specific read or write opcode 65 * @offset: register address offset 66 * @mdr: register data to be read 67 * 68 * Locking is handled by spinlock - cannot sleep. 69 * Return: Nonzero on error 70 */ 71int iosf_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr); 72 73/** 74 * iosf_mbi_write() - MailBox unmasked write command 75 * @port: port indicating subunit being accessed 76 * @opcode: port specific read or write opcode 77 * @offset: register address offset 78 * @mdr: register data to be written 79 * 80 * Locking is handled by spinlock - cannot sleep. 81 * Return: Nonzero on error 82 */ 83int iosf_mbi_write(u8 port, u8 opcode, u32 offset, u32 mdr); 84 85/** 86 * iosf_mbi_modify() - MailBox masked write command 87 * @port: port indicating subunit being accessed 88 * @opcode: port specific read or write opcode 89 * @offset: register address offset 90 * @mdr: register data being modified 91 * @mask: mask indicating bits in mdr to be modified 92 * 93 * Locking is handled by spinlock - cannot sleep. 94 * Return: Nonzero on error 95 */ 96int iosf_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask); 97 98/** 99 * iosf_mbi_punit_acquire() - Acquire access to the P-Unit 100 * 101 * One some systems the P-Unit accesses the PMIC to change various voltages 102 * through the same bus as other kernel drivers use for e.g. battery monitoring. 103 * 104 * If a driver sends requests to the P-Unit which require the P-Unit to access 105 * the PMIC bus while another driver is also accessing the PMIC bus various bad 106 * things happen. 107 * 108 * Call this function before sending requests to the P-Unit which may make it 109 * access the PMIC, be it through iosf_mbi* functions or through other means. 110 * This function will block all kernel access to the PMIC I2C bus, so that the 111 * P-Unit can safely access the PMIC over the shared I2C bus. 112 * 113 * Note on these systems the i2c-bus driver will request a sempahore from the 114 * P-Unit for exclusive access to the PMIC bus when i2c drivers are accessing 115 * it, but this does not appear to be sufficient, we still need to avoid making 116 * certain P-Unit requests during the access window to avoid problems. 117 * 118 * This function locks a mutex, as such it may sleep. 119 */ 120void iosf_mbi_punit_acquire(void); 121 122/** 123 * iosf_mbi_punit_release() - Release access to the P-Unit 124 */ 125void iosf_mbi_punit_release(void); 126 127/** 128 * iosf_mbi_block_punit_i2c_access() - Block P-Unit accesses to the PMIC bus 129 * 130 * Call this function to block P-Unit access to the PMIC I2C bus, so that the 131 * kernel can safely access the PMIC over the shared I2C bus. 132 * 133 * This function acquires the P-Unit bus semaphore and notifies 134 * pmic_bus_access_notifier listeners that they may no longer access the 135 * P-Unit in a way which may cause it to access the shared I2C bus. 136 * 137 * Note this function may be called multiple times and the bus will not 138 * be released until iosf_mbi_unblock_punit_i2c_access() has been called the 139 * same amount of times. 140 * 141 * Return: Nonzero on error 142 */ 143int iosf_mbi_block_punit_i2c_access(void); 144 145/* 146 * iosf_mbi_unblock_punit_i2c_access() - Release PMIC I2C bus block 147 * 148 * Release i2c access block gotten through iosf_mbi_block_punit_i2c_access(). 149 */ 150void iosf_mbi_unblock_punit_i2c_access(void); 151 152/** 153 * iosf_mbi_register_pmic_bus_access_notifier - Register PMIC bus notifier 154 * 155 * This function can be used by drivers which may need to acquire P-Unit 156 * managed resources from interrupt context, where iosf_mbi_punit_acquire() 157 * can not be used. 158 * 159 * This function allows a driver to register a notifier to get notified (in a 160 * process context) before other drivers start accessing the PMIC bus. 161 * 162 * This allows the driver to acquire any resources, which it may need during 163 * the window the other driver is accessing the PMIC, before hand. 164 * 165 * @nb: notifier_block to register 166 */ 167int iosf_mbi_register_pmic_bus_access_notifier(struct notifier_block *nb); 168 169/** 170 * iosf_mbi_register_pmic_bus_access_notifier - Unregister PMIC bus notifier 171 * 172 * @nb: notifier_block to unregister 173 */ 174int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb); 175 176/** 177 * iosf_mbi_unregister_pmic_bus_access_notifier_unlocked - Unregister PMIC bus 178 * notifier, unlocked 179 * 180 * Like iosf_mbi_unregister_pmic_bus_access_notifier(), but for use when the 181 * caller has already called iosf_mbi_punit_acquire() itself. 182 * 183 * @nb: notifier_block to unregister 184 */ 185int iosf_mbi_unregister_pmic_bus_access_notifier_unlocked( 186 struct notifier_block *nb); 187 188/** 189 * iosf_mbi_assert_punit_acquired - Assert that the P-Unit has been acquired. 190 */ 191void iosf_mbi_assert_punit_acquired(void); 192 193#else /* CONFIG_IOSF_MBI is not enabled */ 194static inline 195bool iosf_mbi_available(void) 196{ 197 return false; 198} 199 200static inline 201int iosf_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr) 202{ 203 WARN(1, "IOSF_MBI driver not available"); 204 return -EPERM; 205} 206 207static inline 208int iosf_mbi_write(u8 port, u8 opcode, u32 offset, u32 mdr) 209{ 210 WARN(1, "IOSF_MBI driver not available"); 211 return -EPERM; 212} 213 214static inline 215int iosf_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask) 216{ 217 WARN(1, "IOSF_MBI driver not available"); 218 return -EPERM; 219} 220 221static inline void iosf_mbi_punit_acquire(void) {} 222static inline void iosf_mbi_punit_release(void) {} 223 224static inline 225int iosf_mbi_register_pmic_bus_access_notifier(struct notifier_block *nb) 226{ 227 return 0; 228} 229 230static inline 231int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb) 232{ 233 return 0; 234} 235 236static inline int 237iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(struct notifier_block *nb) 238{ 239 return 0; 240} 241 242static inline 243int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v) 244{ 245 return 0; 246} 247 248static inline void iosf_mbi_assert_punit_acquired(void) {} 249 250#endif /* CONFIG_IOSF_MBI */ 251 252#endif /* IOSF_MBI_SYMS_H */ 253