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