cm.h (7482B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 */ 7 8 #ifndef _SOC_CM_H 9 #define _SOC_CM_H 10 11 #include <sal/types.h> 12 #include <sal/core/sync.h> 13 #include <soc/cmtypes.h> 14 #include <soc/cmdebug.h> 15 #include <soc/devids.h> 16 #include <soc/defs.h> /* for SOC_MAX_NUM_DEVICES */ 17 #ifdef INCLUDE_RCPU 18 #include <soc/rcpu.h> 19 #endif 20 /* 21 * Configuration Manager 22 * 23 * This interface is for the driver side only 24 * 25 * All driver access to the chip must be through this 26 * interface and this interface ONLY. 27 */ 28 29 /* Register Initialization */ 30 31 extern char *soc_cm_config_var_get(int dev, const char *name); 32 33 /* Device information */ 34 35 extern int soc_cm_get_id(int dev, uint16 *dev_id, uint8 *rev_id); 36 extern int soc_cm_get_id_driver(uint16 dev_id, uint8 rev_id, 37 uint16 *dev_id_driver, 38 uint8 *rev_id_driver); 39 extern const char *soc_cm_get_name(int dev); 40 extern uint32 soc_cm_get_dev_type(int dev); 41 extern const char *soc_cm_get_device_name(uint16 dev_id, uint8 rev_id); 42 extern int soc_cm_get_num_devices(void); 43 extern int soc_cm_get_endian(int dev, int *pio, int *packet, int *other); 44 extern sal_vaddr_t soc_cm_get_base_address(int unit); 45 46 #ifdef INCLUDE_RCPU 47 extern int soc_cm_get_rcpu_cfg(int dev, soc_rcpu_cfg_t *rcpu_cfg); 48 extern int soc_cm_set_rcpu_cfg(int dev, soc_rcpu_cfg_t *rcpu_cfg); 49 extern int soc_cm_set_rcpu_trans_tpr(int dev, rcpu_trans_ptr_t *rcpu_tp); 50 #endif /* INCLUDE_RCPU */ 51 52 /* Device interrupts */ 53 54 extern int 55 soc_cm_interrupt_connect(int unit, soc_cm_isr_func_t f, void *data); 56 57 extern int soc_cm_interrupt_enable(int unit); 58 extern void soc_cm_interrupt_disable(int unit); 59 extern int soc_cm_interrupt_disconnect(int unit); 60 61 /* Device Shared Memory Management */ 62 63 extern void *soc_cm_salloc(int unit, int size, const char *name); 64 extern void soc_cm_sfree(int unit, void *ptr); 65 extern int soc_cm_sflush(int unit, void *addr, int length); 66 extern int soc_cm_sinval(int unit, void *addr, int length); 67 68 /* Device PCI config read/write */ 69 70 extern uint32 soc_cm_pci_conf_read(int dev, uint32 addr); 71 extern void soc_cm_pci_conf_write(int dev, uint32 addr, uint32 data); 72 73 /* Device Address Translations */ 74 75 extern sal_paddr_t soc_cm_l2p(int unit, void *addr); 76 extern void *soc_cm_p2l(int unit, sal_paddr_t addr); 77 78 /* iProc Access */ 79 80 extern uint32 soc_cm_iproc_read(int dev, uint32 addr); 81 extern void soc_cm_iproc_write(int dev, uint32 addr, uint32 val); 82 83 84 extern void soc_cm_display_known_devices(void); 85 86 extern uint32 soc_cm_get_bus_type(int dev); 87 88 /* device registers access by I2C, given an internal device address */ 89 90 extern int soc_cm_i2c_device_read(int dev, uint32 addr, uint32 *value); 91 extern int soc_cm_i2c_device_write(int dev, uint32 addr, uint32 value); 92 93 /* Register Access */ 94 95 typedef struct { 96 soc_cm_dev_t dev; 97 soc_cm_device_vectors_t vectors; 98 } cm_device_t; 99 100 extern cm_device_t soc_cm_device[SOC_MAX_NUM_DEVICES]; 101 extern int soc_cm_device_count; 102 103 #define CMDEV(dev) soc_cm_device[dev] 104 #define CMVEC(dev) CMDEV(dev).vectors 105 typedef struct shared_block_s { 106 uint32 start_sentinel; /* value: 0xAABBCCDD */ 107 char *description; 108 int size; 109 int modified_size; 110 struct shared_block_s *prev; 111 struct shared_block_s *next; 112 /* Variable user data; size S = (size + 3) / 4 words. */ 113 uint32 user_data[1]; 114 /* Then sentinel follows user data at user_data[S]; value: 0xDDCCBBAA */ 115 } shared_block_t; 116 117 #ifdef BROADCOM_DEBUG 118 #define SHARED_GOOD_START(p) (p->start_sentinel == 0xaabbccdd) 119 #define SHARED_GOOD_END(p) (p->user_data[(p->size + 3) / 4] == 0xddccbbaa) 120 #define SHARED_GOOD_FREE(p) ((p->start_sentinel != 0xdeadbeef) || (p->user_data[(p->size + 3) / 4] != 0xdddddddd)) 121 #ifdef BROADCOM_DEBUG_RISKY 122 #define SHARED_GOOD_END_DEBUG(p) SHARED_GOOD_END(p) 123 #else 124 #define SHARED_GOOD_END_DEBUG(p) 1 125 #endif 126 extern int soc_cm_shared_good_range(int dev, shared_block_t *p); 127 extern void soc_cm_dump_info(int unit); 128 129 #endif 130 131 /* 132 * There are actually several different implementations that can be 133 * configured for CMREAD and CMWRITE (which are effectively, pci read 134 * and write). 135 * 136 * 1. If SOC_CM_MEMORY_BASE is defined, then that macro contains 137 * the constant base address of all pci devices. The macro 138 * SOC_CM_MEMORY_OFFSET will be multiplied by the device and added 139 * to the base to create the actual pci address. The cm vector 140 * base addresses will be checked against this. 141 * 2. If SOC_CM_MEMORY is defined then the cm vector base_address 142 * will be used as a directo derefence to access pci space 143 * 3. If SOC_CM_FUNCTION is defined then the cm vector read and 144 * write routines will be called. 145 * 4. If none of the above, then a runtime check of both the cm vector 146 * base_address and the read/write routines will happen. 147 */ 148 #ifdef KEYSTONE 149 /* 150 * Enforce PCIE transaction ordering. Commit the write transaction. 151 */ 152 #define _SSOC_CMREAD(_d,_a) ({__asm__ __volatile__("sync"); SOC_E_NONE;}) 153 #else 154 #define _SSOC_CMREAD(_d,_a) SOC_E_NONE 155 #endif 156 157 #ifdef SOC_CM_MEMORY_BASE 158 #ifdef EXTERN_SOC_CM_MEMORY_BASE 159 extern uint32 EXTERN_SOC_CM_MEMORY_BASE; 160 #endif 161 #define CMREAD(_d,_a) \ 162 (((VOL uint32 *)(SOC_CM_MEMORY_BASE+(SOC_CM_MEMORY_OFFSET*_d)))[(_a)/4]) 163 #define CMWRITE(_d,_a,_data) \ 164 ((CMREAD(_d,_a) = _data), _SSOC_CMREAD(_d,_a)) 165 #else 166 #ifdef SOC_CM_MEMORY 167 #define CMREAD(_d,_a) \ 168 (((VOL uint32 *)CMVEC(_d).base_address)[(_a)/4]) 169 #define CMWRITE(_d,_a,_data) \ 170 ((CMREAD(_d,_a) = _data), _SSOC_CMREAD(_d,_a)) 171 #else 172 #ifdef SOC_CM_FUNCTION 173 #define CMREAD(_d,_a) \ 174 (CMVEC(_d).read(&CMDEV(_d).dev, _a)) 175 #define CMWRITE(_d,_a,_data) \ 176 ((CMVEC(_d).write(&CMDEV(_d).dev, _a, _data)), _SSOC_CMREAD(_d,_a)) 177 #else 178 #define CMREAD(_d,_a) \ 179 (CMVEC(_d).base_address ? \ 180 ((VOL uint32 *)CMVEC(_d).base_address)[(_a)/4] : \ 181 CMVEC(_d).read(&CMDEV(_d).dev, _a)) 182 #define CMWRITE(_d,_a,_data) \ 183 (CMVEC(_d).base_address ? \ 184 ((void)(((VOL uint32 *)CMVEC(_d).base_address)[(_a)/4] = _data), _SSOC_CMREAD(_d,_a)) : \ 185 (CMVEC(_d).write(&CMDEV(_d).dev, _a, _data), _SSOC_CMREAD(_d,_a))) 186 #endif /* SOC_CM_FUNCTION */ 187 #endif /* SOC_CM_MEMORY */ 188 #endif /* SOC_CM_MEMORY_BASE */ 189 190 /* Absolute Read/Write */ 191 /* Bypasses any base_address, and R/W to the absolute address */ 192 #ifdef SOC_CM_MEMORY 193 #define CMAREAD(_d,_a) \ 194 (((VOL uint32 *)0)[(_a)/4]) 195 #define CMAWRITE(_d,_a,_data) \ 196 ((CMAREAD(_d,_a) = _data), _SSOC_CMREAD(_d,_a)) 197 #else 198 #ifdef SOC_CM_FUNCTION 199 #define CMAREAD(_d,_a) \ 200 (CMVEC(_d).read(&CMDEV(_d).dev, _a)) 201 #define CMAWRITE(_d,_a,_data) \ 202 ((CMVEC(_d).write(&CMDEV(_d).dev, _a, _data)), _SSOC_CMREAD(_d,_a)) 203 #else 204 #define CMAREAD(_d,_a) \ 205 (CMVEC(_d).base_address ? \ 206 ((VOL uint32 *)0)[(_a)/4] : \ 207 CMVEC(_d).read(&CMDEV(_d).dev, _a)) 208 #define CMAWRITE(_d,_a,_data) \ 209 (CMVEC(_d).base_address ? \ 210 ((void)(((VOL uint32 *)0)[(_a)/4] = _data), _SSOC_CMREAD(_d,_a)) : \ 211 (CMVEC(_d).write(&CMDEV(_d).dev, _a, _data), _SSOC_CMREAD(_d,_a))) 212 #endif /* SOC_CM_FUNCTION */ 213 #endif /* SOC_CM_MEMORY */ 214 215 #define CMCONFREAD(_d,_a) \ 216 (CMVEC(_d).pci_conf_read(&CMDEV(_d).dev, _a)) 217 #define CMCONFWRITE(_d,_a,_data) \ 218 (CMVEC(_d).pci_conf_write(&CMDEV(_d).dev, _a, _data)) 219 220 #endif /* !_SOC_CM_H */