diff options
Diffstat (limited to 'include/linux/ssb')
-rw-r--r-- | include/linux/ssb/ssb.h | 50 | ||||
-rw-r--r-- | include/linux/ssb/ssb_driver_chipcommon.h | 7 | ||||
-rw-r--r-- | include/linux/ssb/ssb_driver_gige.h | 174 | ||||
-rw-r--r-- | include/linux/ssb/ssb_driver_pci.h | 19 |
4 files changed, 243 insertions, 7 deletions
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index db53defde5ee..50dfd0dc4093 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h | |||
@@ -72,10 +72,18 @@ struct ssb_device; | |||
72 | /* Lowlevel read/write operations on the device MMIO. | 72 | /* Lowlevel read/write operations on the device MMIO. |
73 | * Internal, don't use that outside of ssb. */ | 73 | * Internal, don't use that outside of ssb. */ |
74 | struct ssb_bus_ops { | 74 | struct ssb_bus_ops { |
75 | u8 (*read8)(struct ssb_device *dev, u16 offset); | ||
75 | u16 (*read16)(struct ssb_device *dev, u16 offset); | 76 | u16 (*read16)(struct ssb_device *dev, u16 offset); |
76 | u32 (*read32)(struct ssb_device *dev, u16 offset); | 77 | u32 (*read32)(struct ssb_device *dev, u16 offset); |
78 | void (*write8)(struct ssb_device *dev, u16 offset, u8 value); | ||
77 | void (*write16)(struct ssb_device *dev, u16 offset, u16 value); | 79 | void (*write16)(struct ssb_device *dev, u16 offset, u16 value); |
78 | void (*write32)(struct ssb_device *dev, u16 offset, u32 value); | 80 | void (*write32)(struct ssb_device *dev, u16 offset, u32 value); |
81 | #ifdef CONFIG_SSB_BLOCKIO | ||
82 | void (*block_read)(struct ssb_device *dev, void *buffer, | ||
83 | size_t count, u16 offset, u8 reg_width); | ||
84 | void (*block_write)(struct ssb_device *dev, const void *buffer, | ||
85 | size_t count, u16 offset, u8 reg_width); | ||
86 | #endif | ||
79 | }; | 87 | }; |
80 | 88 | ||
81 | 89 | ||
@@ -247,9 +255,9 @@ struct ssb_bus { | |||
247 | /* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */ | 255 | /* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */ |
248 | struct pcmcia_device *host_pcmcia; | 256 | struct pcmcia_device *host_pcmcia; |
249 | 257 | ||
250 | #ifdef CONFIG_SSB_PCIHOST | 258 | #ifdef CONFIG_SSB_SPROM |
251 | /* Mutex to protect the SPROM writing. */ | 259 | /* Mutex to protect the SPROM writing. */ |
252 | struct mutex pci_sprom_mutex; | 260 | struct mutex sprom_mutex; |
253 | #endif | 261 | #endif |
254 | 262 | ||
255 | /* ID information about the Chip. */ | 263 | /* ID information about the Chip. */ |
@@ -262,9 +270,6 @@ struct ssb_bus { | |||
262 | struct ssb_device devices[SSB_MAX_NR_CORES]; | 270 | struct ssb_device devices[SSB_MAX_NR_CORES]; |
263 | u8 nr_devices; | 271 | u8 nr_devices; |
264 | 272 | ||
265 | /* Reference count. Number of suspended devices. */ | ||
266 | u8 suspend_cnt; | ||
267 | |||
268 | /* Software ID number for this bus. */ | 273 | /* Software ID number for this bus. */ |
269 | unsigned int busnumber; | 274 | unsigned int busnumber; |
270 | 275 | ||
@@ -336,6 +341,13 @@ extern int ssb_bus_pcmciabus_register(struct ssb_bus *bus, | |||
336 | 341 | ||
337 | extern void ssb_bus_unregister(struct ssb_bus *bus); | 342 | extern void ssb_bus_unregister(struct ssb_bus *bus); |
338 | 343 | ||
344 | /* Suspend a SSB bus. | ||
345 | * Call this from the parent bus suspend routine. */ | ||
346 | extern int ssb_bus_suspend(struct ssb_bus *bus); | ||
347 | /* Resume a SSB bus. | ||
348 | * Call this from the parent bus resume routine. */ | ||
349 | extern int ssb_bus_resume(struct ssb_bus *bus); | ||
350 | |||
339 | extern u32 ssb_clockspeed(struct ssb_bus *bus); | 351 | extern u32 ssb_clockspeed(struct ssb_bus *bus); |
340 | 352 | ||
341 | /* Is the device enabled in hardware? */ | 353 | /* Is the device enabled in hardware? */ |
@@ -348,6 +360,10 @@ void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags); | |||
348 | 360 | ||
349 | 361 | ||
350 | /* Device MMIO register read/write functions. */ | 362 | /* Device MMIO register read/write functions. */ |
363 | static inline u8 ssb_read8(struct ssb_device *dev, u16 offset) | ||
364 | { | ||
365 | return dev->ops->read8(dev, offset); | ||
366 | } | ||
351 | static inline u16 ssb_read16(struct ssb_device *dev, u16 offset) | 367 | static inline u16 ssb_read16(struct ssb_device *dev, u16 offset) |
352 | { | 368 | { |
353 | return dev->ops->read16(dev, offset); | 369 | return dev->ops->read16(dev, offset); |
@@ -356,6 +372,10 @@ static inline u32 ssb_read32(struct ssb_device *dev, u16 offset) | |||
356 | { | 372 | { |
357 | return dev->ops->read32(dev, offset); | 373 | return dev->ops->read32(dev, offset); |
358 | } | 374 | } |
375 | static inline void ssb_write8(struct ssb_device *dev, u16 offset, u8 value) | ||
376 | { | ||
377 | dev->ops->write8(dev, offset, value); | ||
378 | } | ||
359 | static inline void ssb_write16(struct ssb_device *dev, u16 offset, u16 value) | 379 | static inline void ssb_write16(struct ssb_device *dev, u16 offset, u16 value) |
360 | { | 380 | { |
361 | dev->ops->write16(dev, offset, value); | 381 | dev->ops->write16(dev, offset, value); |
@@ -364,6 +384,19 @@ static inline void ssb_write32(struct ssb_device *dev, u16 offset, u32 value) | |||
364 | { | 384 | { |
365 | dev->ops->write32(dev, offset, value); | 385 | dev->ops->write32(dev, offset, value); |
366 | } | 386 | } |
387 | #ifdef CONFIG_SSB_BLOCKIO | ||
388 | static inline void ssb_block_read(struct ssb_device *dev, void *buffer, | ||
389 | size_t count, u16 offset, u8 reg_width) | ||
390 | { | ||
391 | dev->ops->block_read(dev, buffer, count, offset, reg_width); | ||
392 | } | ||
393 | |||
394 | static inline void ssb_block_write(struct ssb_device *dev, const void *buffer, | ||
395 | size_t count, u16 offset, u8 reg_width) | ||
396 | { | ||
397 | dev->ops->block_write(dev, buffer, count, offset, reg_width); | ||
398 | } | ||
399 | #endif /* CONFIG_SSB_BLOCKIO */ | ||
367 | 400 | ||
368 | 401 | ||
369 | /* Translation (routing) bits that need to be ORed to DMA | 402 | /* Translation (routing) bits that need to be ORed to DMA |
@@ -416,5 +449,12 @@ extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl); | |||
416 | extern u32 ssb_admatch_base(u32 adm); | 449 | extern u32 ssb_admatch_base(u32 adm); |
417 | extern u32 ssb_admatch_size(u32 adm); | 450 | extern u32 ssb_admatch_size(u32 adm); |
418 | 451 | ||
452 | /* PCI device mapping and fixup routines. | ||
453 | * Called from the architecture pcibios init code. | ||
454 | * These are only available on SSB_EMBEDDED configurations. */ | ||
455 | #ifdef CONFIG_SSB_EMBEDDED | ||
456 | int ssb_pcibios_plat_dev_init(struct pci_dev *dev); | ||
457 | int ssb_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); | ||
458 | #endif /* CONFIG_SSB_EMBEDDED */ | ||
419 | 459 | ||
420 | #endif /* LINUX_SSB_H_ */ | 460 | #endif /* LINUX_SSB_H_ */ |
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h index 536851b946f6..7d7e03dcf77c 100644 --- a/include/linux/ssb/ssb_driver_chipcommon.h +++ b/include/linux/ssb/ssb_driver_chipcommon.h | |||
@@ -367,8 +367,7 @@ static inline bool ssb_chipco_available(struct ssb_chipcommon *cc) | |||
367 | 367 | ||
368 | extern void ssb_chipcommon_init(struct ssb_chipcommon *cc); | 368 | extern void ssb_chipcommon_init(struct ssb_chipcommon *cc); |
369 | 369 | ||
370 | #include <linux/pm.h> | 370 | extern void ssb_chipco_suspend(struct ssb_chipcommon *cc); |
371 | extern void ssb_chipco_suspend(struct ssb_chipcommon *cc, pm_message_t state); | ||
372 | extern void ssb_chipco_resume(struct ssb_chipcommon *cc); | 371 | extern void ssb_chipco_resume(struct ssb_chipcommon *cc); |
373 | 372 | ||
374 | extern void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc, | 373 | extern void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc, |
@@ -390,6 +389,10 @@ extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, | |||
390 | extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, | 389 | extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, |
391 | u32 ticks); | 390 | u32 ticks); |
392 | 391 | ||
392 | void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value); | ||
393 | |||
394 | u32 ssb_chipco_irq_status(struct ssb_chipcommon *cc, u32 mask); | ||
395 | |||
393 | /* Chipcommon GPIO pin access. */ | 396 | /* Chipcommon GPIO pin access. */ |
394 | u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask); | 397 | u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask); |
395 | u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value); | 398 | u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value); |
diff --git a/include/linux/ssb/ssb_driver_gige.h b/include/linux/ssb/ssb_driver_gige.h new file mode 100644 index 000000000000..01fbdf5fef22 --- /dev/null +++ b/include/linux/ssb/ssb_driver_gige.h | |||
@@ -0,0 +1,174 @@ | |||
1 | #ifndef LINUX_SSB_DRIVER_GIGE_H_ | ||
2 | #define LINUX_SSB_DRIVER_GIGE_H_ | ||
3 | |||
4 | #include <linux/ssb/ssb.h> | ||
5 | #include <linux/pci.h> | ||
6 | #include <linux/spinlock.h> | ||
7 | |||
8 | |||
9 | #ifdef CONFIG_SSB_DRIVER_GIGE | ||
10 | |||
11 | |||
12 | #define SSB_GIGE_PCIIO 0x0000 /* PCI I/O Registers (1024 bytes) */ | ||
13 | #define SSB_GIGE_RESERVED 0x0400 /* Reserved (1024 bytes) */ | ||
14 | #define SSB_GIGE_PCICFG 0x0800 /* PCI config space (256 bytes) */ | ||
15 | #define SSB_GIGE_SHIM_FLUSHSTAT 0x0C00 /* PCI to OCP: Flush status control (32bit) */ | ||
16 | #define SSB_GIGE_SHIM_FLUSHRDA 0x0C04 /* PCI to OCP: Flush read address (32bit) */ | ||
17 | #define SSB_GIGE_SHIM_FLUSHTO 0x0C08 /* PCI to OCP: Flush timeout counter (32bit) */ | ||
18 | #define SSB_GIGE_SHIM_BARRIER 0x0C0C /* PCI to OCP: Barrier register (32bit) */ | ||
19 | #define SSB_GIGE_SHIM_MAOCPSI 0x0C10 /* PCI to OCP: MaocpSI Control (32bit) */ | ||
20 | #define SSB_GIGE_SHIM_SIOCPMA 0x0C14 /* PCI to OCP: SiocpMa Control (32bit) */ | ||
21 | |||
22 | /* TM Status High flags */ | ||
23 | #define SSB_GIGE_TMSHIGH_RGMII 0x00010000 /* Have an RGMII PHY-bus */ | ||
24 | /* TM Status Low flags */ | ||
25 | #define SSB_GIGE_TMSLOW_TXBYPASS 0x00080000 /* TX bypass (no delay) */ | ||
26 | #define SSB_GIGE_TMSLOW_RXBYPASS 0x00100000 /* RX bypass (no delay) */ | ||
27 | #define SSB_GIGE_TMSLOW_DLLEN 0x01000000 /* Enable DLL controls */ | ||
28 | |||
29 | /* Boardflags (low) */ | ||
30 | #define SSB_GIGE_BFL_ROBOSWITCH 0x0010 | ||
31 | |||
32 | |||
33 | #define SSB_GIGE_MEM_RES_NAME "SSB Broadcom 47xx GigE memory" | ||
34 | #define SSB_GIGE_IO_RES_NAME "SSB Broadcom 47xx GigE I/O" | ||
35 | |||
36 | struct ssb_gige { | ||
37 | struct ssb_device *dev; | ||
38 | |||
39 | spinlock_t lock; | ||
40 | |||
41 | /* True, if the device has an RGMII bus. | ||
42 | * False, if the device has a GMII bus. */ | ||
43 | bool has_rgmii; | ||
44 | |||
45 | /* The PCI controller device. */ | ||
46 | struct pci_controller pci_controller; | ||
47 | struct pci_ops pci_ops; | ||
48 | struct resource mem_resource; | ||
49 | struct resource io_resource; | ||
50 | }; | ||
51 | |||
52 | /* Check whether a PCI device is a SSB Gigabit Ethernet core. */ | ||
53 | extern bool pdev_is_ssb_gige_core(struct pci_dev *pdev); | ||
54 | |||
55 | /* Convert a pci_dev pointer to a ssb_gige pointer. */ | ||
56 | static inline struct ssb_gige * pdev_to_ssb_gige(struct pci_dev *pdev) | ||
57 | { | ||
58 | if (!pdev_is_ssb_gige_core(pdev)) | ||
59 | return NULL; | ||
60 | return container_of(pdev->bus->ops, struct ssb_gige, pci_ops); | ||
61 | } | ||
62 | |||
63 | /* Returns whether the PHY is connected by an RGMII bus. */ | ||
64 | static inline bool ssb_gige_is_rgmii(struct pci_dev *pdev) | ||
65 | { | ||
66 | struct ssb_gige *dev = pdev_to_ssb_gige(pdev); | ||
67 | return (dev ? dev->has_rgmii : 0); | ||
68 | } | ||
69 | |||
70 | /* Returns whether we have a Roboswitch. */ | ||
71 | static inline bool ssb_gige_have_roboswitch(struct pci_dev *pdev) | ||
72 | { | ||
73 | struct ssb_gige *dev = pdev_to_ssb_gige(pdev); | ||
74 | if (dev) | ||
75 | return !!(dev->dev->bus->sprom.boardflags_lo & | ||
76 | SSB_GIGE_BFL_ROBOSWITCH); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | /* Returns whether we can only do one DMA at once. */ | ||
81 | static inline bool ssb_gige_one_dma_at_once(struct pci_dev *pdev) | ||
82 | { | ||
83 | struct ssb_gige *dev = pdev_to_ssb_gige(pdev); | ||
84 | if (dev) | ||
85 | return ((dev->dev->bus->chip_id == 0x4785) && | ||
86 | (dev->dev->bus->chip_rev < 2)); | ||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | /* Returns whether we must flush posted writes. */ | ||
91 | static inline bool ssb_gige_must_flush_posted_writes(struct pci_dev *pdev) | ||
92 | { | ||
93 | struct ssb_gige *dev = pdev_to_ssb_gige(pdev); | ||
94 | if (dev) | ||
95 | return (dev->dev->bus->chip_id == 0x4785); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | extern char * nvram_get(const char *name); | ||
100 | /* Get the device MAC address */ | ||
101 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) | ||
102 | { | ||
103 | #ifdef CONFIG_BCM947XX | ||
104 | char *res = nvram_get("et0macaddr"); | ||
105 | if (res) | ||
106 | memcpy(macaddr, res, 6); | ||
107 | #endif | ||
108 | } | ||
109 | |||
110 | extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev, | ||
111 | struct pci_dev *pdev); | ||
112 | extern int ssb_gige_map_irq(struct ssb_device *sdev, | ||
113 | const struct pci_dev *pdev); | ||
114 | |||
115 | /* The GigE driver is not a standalone module, because we don't have support | ||
116 | * for unregistering the driver. So we could not unload the module anyway. */ | ||
117 | extern int ssb_gige_init(void); | ||
118 | static inline void ssb_gige_exit(void) | ||
119 | { | ||
120 | /* Currently we can not unregister the GigE driver, | ||
121 | * because we can not unregister the PCI bridge. */ | ||
122 | BUG(); | ||
123 | } | ||
124 | |||
125 | |||
126 | #else /* CONFIG_SSB_DRIVER_GIGE */ | ||
127 | /* Gigabit Ethernet driver disabled */ | ||
128 | |||
129 | |||
130 | static inline int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev, | ||
131 | struct pci_dev *pdev) | ||
132 | { | ||
133 | return -ENOSYS; | ||
134 | } | ||
135 | static inline int ssb_gige_map_irq(struct ssb_device *sdev, | ||
136 | const struct pci_dev *pdev) | ||
137 | { | ||
138 | return -ENOSYS; | ||
139 | } | ||
140 | static inline int ssb_gige_init(void) | ||
141 | { | ||
142 | return 0; | ||
143 | } | ||
144 | static inline void ssb_gige_exit(void) | ||
145 | { | ||
146 | } | ||
147 | |||
148 | static inline bool pdev_is_ssb_gige_core(struct pci_dev *pdev) | ||
149 | { | ||
150 | return 0; | ||
151 | } | ||
152 | static inline struct ssb_gige * pdev_to_ssb_gige(struct pci_dev *pdev) | ||
153 | { | ||
154 | return NULL; | ||
155 | } | ||
156 | static inline bool ssb_gige_is_rgmii(struct pci_dev *pdev) | ||
157 | { | ||
158 | return 0; | ||
159 | } | ||
160 | static inline bool ssb_gige_have_roboswitch(struct pci_dev *pdev) | ||
161 | { | ||
162 | return 0; | ||
163 | } | ||
164 | static inline bool ssb_gige_one_dma_at_once(struct pci_dev *pdev) | ||
165 | { | ||
166 | return 0; | ||
167 | } | ||
168 | static inline bool ssb_gige_must_flush_posted_writes(struct pci_dev *pdev) | ||
169 | { | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | #endif /* CONFIG_SSB_DRIVER_GIGE */ | ||
174 | #endif /* LINUX_SSB_DRIVER_GIGE_H_ */ | ||
diff --git a/include/linux/ssb/ssb_driver_pci.h b/include/linux/ssb/ssb_driver_pci.h index 5e25bac4ed31..41e330e51c2a 100644 --- a/include/linux/ssb/ssb_driver_pci.h +++ b/include/linux/ssb/ssb_driver_pci.h | |||
@@ -1,6 +1,11 @@ | |||
1 | #ifndef LINUX_SSB_PCICORE_H_ | 1 | #ifndef LINUX_SSB_PCICORE_H_ |
2 | #define LINUX_SSB_PCICORE_H_ | 2 | #define LINUX_SSB_PCICORE_H_ |
3 | 3 | ||
4 | #include <linux/types.h> | ||
5 | |||
6 | struct pci_dev; | ||
7 | |||
8 | |||
4 | #ifdef CONFIG_SSB_DRIVER_PCICORE | 9 | #ifdef CONFIG_SSB_DRIVER_PCICORE |
5 | 10 | ||
6 | /* PCI core registers. */ | 11 | /* PCI core registers. */ |
@@ -88,6 +93,9 @@ extern void ssb_pcicore_init(struct ssb_pcicore *pc); | |||
88 | extern int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, | 93 | extern int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, |
89 | struct ssb_device *dev); | 94 | struct ssb_device *dev); |
90 | 95 | ||
96 | int ssb_pcicore_plat_dev_init(struct pci_dev *d); | ||
97 | int ssb_pcicore_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); | ||
98 | |||
91 | 99 | ||
92 | #else /* CONFIG_SSB_DRIVER_PCICORE */ | 100 | #else /* CONFIG_SSB_DRIVER_PCICORE */ |
93 | 101 | ||
@@ -107,5 +115,16 @@ int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, | |||
107 | return 0; | 115 | return 0; |
108 | } | 116 | } |
109 | 117 | ||
118 | static inline | ||
119 | int ssb_pcicore_plat_dev_init(struct pci_dev *d) | ||
120 | { | ||
121 | return -ENODEV; | ||
122 | } | ||
123 | static inline | ||
124 | int ssb_pcicore_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
125 | { | ||
126 | return -ENODEV; | ||
127 | } | ||
128 | |||
110 | #endif /* CONFIG_SSB_DRIVER_PCICORE */ | 129 | #endif /* CONFIG_SSB_DRIVER_PCICORE */ |
111 | #endif /* LINUX_SSB_PCICORE_H_ */ | 130 | #endif /* LINUX_SSB_PCICORE_H_ */ |