aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorGeoff Levand <geoffrey.levand@am.sony.com>2007-06-15 17:52:02 -0400
committerPaul Mackerras <paulus@samba.org>2007-06-28 05:16:38 -0400
commit6bb5cf1025414fe00b20f3bef56135849e4ed3b8 (patch)
treed8cc37288ce123dc790af37f99b7bcc7c9e1872d /include
parent9263e85aa9e9d341ef238fffc040f586674d1709 (diff)
[POWERPC] PS3: System-bus rework
Rework the PS3 system bus to unify device support. - DMA region sizes must be a power of two - storage bus DMA updates: - Small fixes for the PS3 DMA core: o fix alignment bug o kill superfluous test o indentation o spelling o export ps3_dma_region_{create,free}() - ps3_dma_region_init(): o Add `addr' and `len' parameters, so you can create a DMA region that does not cover all memory (use `NULL' and `0' to cover all memory). This is needed because there are not sufficient IOMMU resources to have all DMA regions cover all memory. o Uninline - Added remove and shutdown routines to all drivers. - Added loadable module support to all drivers. - Added HV calls for iopte management (needed by sound driver). Signed-off-by: MOKUNO Masakazu <mokuno@sm.sony.co.jp> Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include')
-rw-r--r--include/asm-powerpc/lv1call.h3
-rw-r--r--include/asm-powerpc/ps3.h148
2 files changed, 101 insertions, 50 deletions
diff --git a/include/asm-powerpc/lv1call.h b/include/asm-powerpc/lv1call.h
index f733beeea63a..81713acf7529 100644
--- a/include/asm-powerpc/lv1call.h
+++ b/include/asm-powerpc/lv1call.h
@@ -238,6 +238,7 @@ LV1_CALL(destruct_virtual_address_space, 1, 0, 10 )
238LV1_CALL(configure_irq_state_bitmap, 3, 0, 11 ) 238LV1_CALL(configure_irq_state_bitmap, 3, 0, 11 )
239LV1_CALL(connect_irq_plug_ext, 5, 0, 12 ) 239LV1_CALL(connect_irq_plug_ext, 5, 0, 12 )
240LV1_CALL(release_memory, 1, 0, 13 ) 240LV1_CALL(release_memory, 1, 0, 13 )
241LV1_CALL(put_iopte, 5, 0, 15 )
241LV1_CALL(disconnect_irq_plug_ext, 3, 0, 17 ) 242LV1_CALL(disconnect_irq_plug_ext, 3, 0, 17 )
242LV1_CALL(construct_event_receive_port, 0, 1, 18 ) 243LV1_CALL(construct_event_receive_port, 0, 1, 18 )
243LV1_CALL(destruct_event_receive_port, 1, 0, 19 ) 244LV1_CALL(destruct_event_receive_port, 1, 0, 19 )
@@ -268,6 +269,8 @@ LV1_CALL(remove_repository_node, 4, 0, 93 )
268LV1_CALL(read_htab_entries, 2, 5, 95 ) 269LV1_CALL(read_htab_entries, 2, 5, 95 )
269LV1_CALL(set_dabr, 2, 0, 96 ) 270LV1_CALL(set_dabr, 2, 0, 96 )
270LV1_CALL(get_total_execution_time, 2, 1, 103 ) 271LV1_CALL(get_total_execution_time, 2, 1, 103 )
272LV1_CALL(allocate_io_segment, 3, 1, 116 )
273LV1_CALL(release_io_segment, 2, 0, 117 )
271LV1_CALL(construct_io_irq_outlet, 1, 1, 120 ) 274LV1_CALL(construct_io_irq_outlet, 1, 1, 120 )
272LV1_CALL(destruct_io_irq_outlet, 1, 0, 121 ) 275LV1_CALL(destruct_io_irq_outlet, 1, 0, 121 )
273LV1_CALL(map_htab, 1, 1, 122 ) 276LV1_CALL(map_htab, 1, 1, 122 )
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
index ac85d729f14f..4f753907bbf9 100644
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -49,18 +49,6 @@ enum ps3_param_av_multi_out {
49 49
50enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void); 50enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void);
51 51
52/**
53 * struct ps3_device_id - HV bus device identifier from the system repository
54 * @bus_id: HV bus id, {1..} (zero invalid)
55 * @dev_id: HV device id, {0..}
56 */
57
58struct ps3_device_id {
59 unsigned int bus_id;
60 unsigned int dev_id;
61};
62
63
64/* dma routines */ 52/* dma routines */
65 53
66enum ps3_dma_page_size { 54enum ps3_dma_page_size {
@@ -75,6 +63,8 @@ enum ps3_dma_region_type {
75 PS3_DMA_INTERNAL = 2, 63 PS3_DMA_INTERNAL = 2,
76}; 64};
77 65
66struct ps3_dma_region_ops;
67
78/** 68/**
79 * struct ps3_dma_region - A per device dma state variables structure 69 * struct ps3_dma_region - A per device dma state variables structure
80 * @did: The HV device id. 70 * @did: The HV device id.
@@ -82,21 +72,42 @@ enum ps3_dma_region_type {
82 * @region_type: The HV region type. 72 * @region_type: The HV region type.
83 * @bus_addr: The 'translated' bus address of the region. 73 * @bus_addr: The 'translated' bus address of the region.
84 * @len: The length in bytes of the region. 74 * @len: The length in bytes of the region.
75 * @offset: The offset from the start of memory of the region.
76 * @ioid: The IOID of the device who owns this region
85 * @chunk_list: Opaque variable used by the ioc page manager. 77 * @chunk_list: Opaque variable used by the ioc page manager.
78 * @region_ops: struct ps3_dma_region_ops - dma region operations
86 */ 79 */
87 80
88struct ps3_dma_region { 81struct ps3_dma_region {
89 struct ps3_device_id did; 82 struct ps3_system_bus_device *dev;
83 /* device variables */
84 const struct ps3_dma_region_ops *region_ops;
85 unsigned char ioid;
90 enum ps3_dma_page_size page_size; 86 enum ps3_dma_page_size page_size;
91 enum ps3_dma_region_type region_type; 87 enum ps3_dma_region_type region_type;
92 unsigned long bus_addr;
93 unsigned long len; 88 unsigned long len;
89 unsigned long offset;
90
91 /* driver variables (set by ps3_dma_region_create) */
92 unsigned long bus_addr;
94 struct { 93 struct {
95 spinlock_t lock; 94 spinlock_t lock;
96 struct list_head head; 95 struct list_head head;
97 } chunk_list; 96 } chunk_list;
98}; 97};
99 98
99struct ps3_dma_region_ops {
100 int (*create)(struct ps3_dma_region *);
101 int (*free)(struct ps3_dma_region *);
102 int (*map)(struct ps3_dma_region *,
103 unsigned long virt_addr,
104 unsigned long len,
105 unsigned long *bus_addr,
106 u64 iopte_pp);
107 int (*unmap)(struct ps3_dma_region *,
108 unsigned long bus_addr,
109 unsigned long len);
110};
100/** 111/**
101 * struct ps3_dma_region_init - Helper to initialize structure variables 112 * struct ps3_dma_region_init - Helper to initialize structure variables
102 * 113 *
@@ -104,18 +115,16 @@ struct ps3_dma_region {
104 * ps3_system_bus_device_register. 115 * ps3_system_bus_device_register.
105 */ 116 */
106 117
107static inline void ps3_dma_region_init(struct ps3_dma_region *r, 118struct ps3_system_bus_device;
108 const struct ps3_device_id* did, enum ps3_dma_page_size page_size, 119
109 enum ps3_dma_region_type region_type) 120int ps3_dma_region_init(struct ps3_system_bus_device *dev,
110{ 121 struct ps3_dma_region *r, enum ps3_dma_page_size page_size,
111 r->did = *did; 122 enum ps3_dma_region_type region_type, void *addr, unsigned long len);
112 r->page_size = page_size;
113 r->region_type = region_type;
114}
115int ps3_dma_region_create(struct ps3_dma_region *r); 123int ps3_dma_region_create(struct ps3_dma_region *r);
116int ps3_dma_region_free(struct ps3_dma_region *r); 124int ps3_dma_region_free(struct ps3_dma_region *r);
117int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr, 125int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr,
118 unsigned long len, unsigned long *bus_addr); 126 unsigned long len, unsigned long *bus_addr,
127 u64 iopte_pp);
119int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr, 128int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr,
120 unsigned long len); 129 unsigned long len);
121 130
@@ -126,6 +135,7 @@ enum ps3_mmio_page_size {
126 PS3_MMIO_64K = 16U 135 PS3_MMIO_64K = 16U
127}; 136};
128 137
138struct ps3_mmio_region_ops;
129/** 139/**
130 * struct ps3_mmio_region - a per device mmio state variables structure 140 * struct ps3_mmio_region - a per device mmio state variables structure
131 * 141 *
@@ -133,13 +143,18 @@ enum ps3_mmio_page_size {
133 */ 143 */
134 144
135struct ps3_mmio_region { 145struct ps3_mmio_region {
136 struct ps3_device_id did; 146 struct ps3_system_bus_device *dev;
147 const struct ps3_mmio_region_ops *mmio_ops;
137 unsigned long bus_addr; 148 unsigned long bus_addr;
138 unsigned long len; 149 unsigned long len;
139 enum ps3_mmio_page_size page_size; 150 enum ps3_mmio_page_size page_size;
140 unsigned long lpar_addr; 151 unsigned long lpar_addr;
141}; 152};
142 153
154struct ps3_mmio_region_ops {
155 int (*create)(struct ps3_mmio_region *);
156 int (*free)(struct ps3_mmio_region *);
157};
143/** 158/**
144 * struct ps3_mmio_region_init - Helper to initialize structure variables 159 * struct ps3_mmio_region_init - Helper to initialize structure variables
145 * 160 *
@@ -147,15 +162,9 @@ struct ps3_mmio_region {
147 * ps3_system_bus_device_register. 162 * ps3_system_bus_device_register.
148 */ 163 */
149 164
150static inline void ps3_mmio_region_init(struct ps3_mmio_region *r, 165int ps3_mmio_region_init(struct ps3_system_bus_device *dev,
151 const struct ps3_device_id* did, unsigned long bus_addr, 166 struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len,
152 unsigned long len, enum ps3_mmio_page_size page_size) 167 enum ps3_mmio_page_size page_size);
153{
154 r->did = *did;
155 r->bus_addr = bus_addr;
156 r->len = len;
157 r->page_size = page_size;
158}
159int ps3_mmio_region_create(struct ps3_mmio_region *r); 168int ps3_mmio_region_create(struct ps3_mmio_region *r);
160int ps3_free_mmio_region(struct ps3_mmio_region *r); 169int ps3_free_mmio_region(struct ps3_mmio_region *r);
161unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr); 170unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr);
@@ -188,11 +197,10 @@ int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
188 unsigned int class, unsigned int *virq); 197 unsigned int class, unsigned int *virq);
189int ps3_spe_irq_destroy(unsigned int virq); 198int ps3_spe_irq_destroy(unsigned int virq);
190 199
191int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, 200int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev,
192 const struct ps3_device_id *did, unsigned int interrupt_id, 201 enum ps3_cpu_binding cpu, unsigned int *virq);
193 unsigned int *virq); 202int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev,
194int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, 203 unsigned int virq);
195 unsigned int interrupt_id, unsigned int virq);
196 204
197/* lv1 result codes */ 205/* lv1 result codes */
198 206
@@ -290,11 +298,33 @@ static inline const char* ps3_result(int result)
290/* system bus routines */ 298/* system bus routines */
291 299
292enum ps3_match_id { 300enum ps3_match_id {
293 PS3_MATCH_ID_EHCI = 1, 301 PS3_MATCH_ID_EHCI = 1,
294 PS3_MATCH_ID_OHCI, 302 PS3_MATCH_ID_OHCI = 2,
295 PS3_MATCH_ID_GELIC, 303 PS3_MATCH_ID_GELIC = 3,
296 PS3_MATCH_ID_AV_SETTINGS, 304 PS3_MATCH_ID_AV_SETTINGS = 4,
297 PS3_MATCH_ID_SYSTEM_MANAGER, 305 PS3_MATCH_ID_SYSTEM_MANAGER = 5,
306 PS3_MATCH_ID_STOR_DISK = 6,
307 PS3_MATCH_ID_STOR_ROM = 7,
308 PS3_MATCH_ID_STOR_FLASH = 8,
309 PS3_MATCH_ID_SOUND = 9,
310 PS3_MATCH_ID_GRAPHICS = 10,
311};
312
313#define PS3_MODULE_ALIAS_EHCI "ps3:1"
314#define PS3_MODULE_ALIAS_OHCI "ps3:2"
315#define PS3_MODULE_ALIAS_GELIC "ps3:3"
316#define PS3_MODULE_ALIAS_AV_SETTINGS "ps3:4"
317#define PS3_MODULE_ALIAS_SYSTEM_MANAGER "ps3:5"
318#define PS3_MODULE_ALIAS_STOR_DISK "ps3:6"
319#define PS3_MODULE_ALIAS_STOR_ROM "ps3:7"
320#define PS3_MODULE_ALIAS_STOR_FLASH "ps3:8"
321#define PS3_MODULE_ALIAS_SOUND "ps3:9"
322#define PS3_MODULE_ALIAS_GRAPHICS "ps3:10"
323
324enum ps3_system_bus_device_type {
325 PS3_DEVICE_TYPE_IOC0 = 1,
326 PS3_DEVICE_TYPE_SB,
327 PS3_DEVICE_TYPE_VUART,
298}; 328};
299 329
300/** 330/**
@@ -303,14 +333,23 @@ enum ps3_match_id {
303 333
304struct ps3_system_bus_device { 334struct ps3_system_bus_device {
305 enum ps3_match_id match_id; 335 enum ps3_match_id match_id;
306 struct ps3_device_id did; 336 enum ps3_system_bus_device_type dev_type;
307 unsigned int interrupt_id; 337
308/* struct iommu_table *iommu_table; -- waiting for Ben's cleanups */ 338 unsigned int bus_id; /* SB */
309 struct ps3_dma_region *d_region; 339 unsigned int dev_id; /* SB */
310 struct ps3_mmio_region *m_region; 340 unsigned int interrupt_id; /* SB */
341 struct ps3_dma_region *d_region; /* SB, IOC0 */
342 struct ps3_mmio_region *m_region; /* SB, IOC0*/
343 unsigned int port_number; /* VUART */
344
345/* struct iommu_table *iommu_table; -- waiting for BenH's cleanups */
311 struct device core; 346 struct device core;
347 void *driver_priv; /* private driver variables */
312}; 348};
313 349
350int ps3_open_hv_device(struct ps3_system_bus_device *dev);
351int ps3_close_hv_device(struct ps3_system_bus_device *dev);
352
314/** 353/**
315 * struct ps3_system_bus_driver - a driver for a device on the system bus 354 * struct ps3_system_bus_driver - a driver for a device on the system bus
316 */ 355 */
@@ -320,6 +359,7 @@ struct ps3_system_bus_driver {
320 struct device_driver core; 359 struct device_driver core;
321 int (*probe)(struct ps3_system_bus_device *); 360 int (*probe)(struct ps3_system_bus_device *);
322 int (*remove)(struct ps3_system_bus_device *); 361 int (*remove)(struct ps3_system_bus_device *);
362 int (*shutdown)(struct ps3_system_bus_device *);
323/* int (*suspend)(struct ps3_system_bus_device *, pm_message_t); */ 363/* int (*suspend)(struct ps3_system_bus_device *, pm_message_t); */
324/* int (*resume)(struct ps3_system_bus_device *); */ 364/* int (*resume)(struct ps3_system_bus_device *); */
325}; 365};
@@ -327,16 +367,24 @@ struct ps3_system_bus_driver {
327int ps3_system_bus_device_register(struct ps3_system_bus_device *dev); 367int ps3_system_bus_device_register(struct ps3_system_bus_device *dev);
328int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv); 368int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv);
329void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv); 369void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv);
330static inline struct ps3_system_bus_driver *to_ps3_system_bus_driver( 370
371static inline struct ps3_system_bus_driver *ps3_drv_to_system_bus_drv(
331 struct device_driver *_drv) 372 struct device_driver *_drv)
332{ 373{
333 return container_of(_drv, struct ps3_system_bus_driver, core); 374 return container_of(_drv, struct ps3_system_bus_driver, core);
334} 375}
335static inline struct ps3_system_bus_device *to_ps3_system_bus_device( 376static inline struct ps3_system_bus_device *ps3_dev_to_system_bus_dev(
336 struct device *_dev) 377 struct device *_dev)
337{ 378{
338 return container_of(_dev, struct ps3_system_bus_device, core); 379 return container_of(_dev, struct ps3_system_bus_device, core);
339} 380}
381static inline struct ps3_system_bus_driver *
382 ps3_system_bus_dev_to_system_bus_drv(struct ps3_system_bus_device *_dev)
383{
384 BUG_ON(!_dev);
385 BUG_ON(!_dev->core.driver);
386 return ps3_drv_to_system_bus_drv(_dev->core.driver);
387}
340 388
341/** 389/**
342 * ps3_system_bus_set_drvdata - 390 * ps3_system_bus_set_drvdata -