Commit 4a91b05f authored by Linus Torvalds's avatar Linus Torvalds

DRI CVS merge: separate out driver-ioctl's into driver headers

parent 2ffe5f2f
...@@ -84,6 +84,10 @@ typedef unsigned int drm_magic_t; ...@@ -84,6 +84,10 @@ typedef unsigned int drm_magic_t;
/* Warning: If you change this structure, make sure you change /* Warning: If you change this structure, make sure you change
* XF86DRIClipRectRec in the server as well */ * XF86DRIClipRectRec in the server as well */
/* KW: Actually it's illegal to change either for
* backwards-compatibility reasons.
*/
typedef struct drm_clip_rect { typedef struct drm_clip_rect {
unsigned short x1; unsigned short x1;
unsigned short y1; unsigned short y1;
...@@ -99,15 +103,6 @@ typedef struct drm_tex_region { ...@@ -99,15 +103,6 @@ typedef struct drm_tex_region {
unsigned int age; unsigned int age;
} drm_tex_region_t; } drm_tex_region_t;
/* Seperate include files for the i810/mga/r128 specific structures */
#include "mga_drm.h"
#include "i810_drm.h"
#include "r128_drm.h"
#include "radeon_drm.h"
#include "sis_drm.h"
#include "i830_drm.h"
#include "gamma_drm.h"
typedef struct drm_version { typedef struct drm_version {
int version_major; /* Major version */ int version_major; /* Major version */
int version_minor; /* Minor version */ int version_minor; /* Minor version */
...@@ -428,95 +423,8 @@ typedef struct drm_scatter_gather { ...@@ -428,95 +423,8 @@ typedef struct drm_scatter_gather {
#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t) #define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t) #define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
/* MGA specific ioctls */ /* Device specfic ioctls should only be in their respective headers
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) * The device specific ioctl range is 0x40 to 0x79. */
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t) #define DRM_COMMAND_BASE 0x40
#define DRM_IOCTL_MGA_RESET DRM_IO( 0x42)
#define DRM_IOCTL_MGA_SWAP DRM_IO( 0x43)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x44, drm_mga_clear_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x45, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t)
/* i810 specific ioctls */
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43)
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
#define DRM_IOCTL_I810_OV0INFO DRM_IOR( 0x49, drm_i810_overlay_t)
#define DRM_IOCTL_I810_FSTATUS DRM_IO ( 0x4a)
#define DRM_IOCTL_I810_OV0FLIP DRM_IO ( 0x4b)
#define DRM_IOCTL_I810_MC DRM_IOW( 0x4c, drm_i810_mc_t)
#define DRM_IOCTL_I810_RSTATUS DRM_IO ( 0x4d )
/* Rage 128 specific ioctls */
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t)
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t)
/* Radeon specific ioctls */
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41)
#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t)
#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43)
#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45)
#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t)
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52)
/* Gamma specific ioctls */
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
#define DRM_IOCTL_GAMMA_COPY DRM_IOW( 0x41, drm_gamma_copy_t)
/* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t)
#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t)
#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t)
#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t)
#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49)
#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50)
/* I830 specific ioctls */
#define DRM_IOCTL_I830_INIT DRM_IOW( 0x40, drm_i830_init_t)
#define DRM_IOCTL_I830_VERTEX DRM_IOW( 0x41, drm_i830_vertex_t)
#define DRM_IOCTL_I830_CLEAR DRM_IOW( 0x42, drm_i830_clear_t)
#define DRM_IOCTL_I830_FLUSH DRM_IO ( 0x43)
#define DRM_IOCTL_I830_GETAGE DRM_IO ( 0x44)
#define DRM_IOCTL_I830_GETBUF DRM_IOWR(0x45, drm_i830_dma_t)
#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46)
#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t)
#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48)
#endif #endif
...@@ -555,7 +555,7 @@ static int DRM(alloc_queue)(drm_device_t *dev) ...@@ -555,7 +555,7 @@ static int DRM(alloc_queue)(drm_device_t *dev)
/* Allocate a new queue */ /* Allocate a new queue */
down(&dev->struct_sem); down(&dev->struct_sem);
queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES); queue = DRM(alloc)(sizeof(*queue), DRM_MEM_QUEUES);
memset(queue, 0, sizeof(*queue)); memset(queue, 0, sizeof(*queue));
atomic_set(&queue->use_count, 1); atomic_set(&queue->use_count, 1);
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "gamma.h" #include "gamma.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "gamma_drm.h"
#include "gamma_drv.h" #include "gamma_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
......
...@@ -48,6 +48,16 @@ typedef struct _drm_gamma_sarea { ...@@ -48,6 +48,16 @@ typedef struct _drm_gamma_sarea {
int vertex_prim; int vertex_prim;
} drm_gamma_sarea_t; } drm_gamma_sarea_t;
/* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmGamma.h)
*/
/* Gamma specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
#define DRM_IOCTL_GAMMA_COPY DRM_IOW( 0x41, drm_gamma_copy_t)
typedef struct drm_gamma_copy { typedef struct drm_gamma_copy {
unsigned int DMAOutputAddress; unsigned int DMAOutputAddress;
unsigned int DMAOutputCount; unsigned int DMAOutputCount;
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <linux/config.h> #include <linux/config.h>
#include "gamma.h" #include "gamma.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "gamma_drm.h"
#include "gamma_drv.h" #include "gamma_drv.h"
#define DRIVER_AUTHOR "VA Linux Systems Inc." #define DRIVER_AUTHOR "VA Linux Systems Inc."
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "i810.h" #include "i810.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "i810_drm.h"
#include "i810_drv.h" #include "i810_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h> #include <linux/delay.h>
......
...@@ -168,14 +168,34 @@ typedef struct _drm_i810_sarea { ...@@ -168,14 +168,34 @@ typedef struct _drm_i810_sarea {
} drm_i810_sarea_t; } drm_i810_sarea_t;
/* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmMga.h)
*/
/* i810 specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43)
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
#define DRM_IOCTL_I810_OV0INFO DRM_IOR( 0x49, drm_i810_overlay_t)
#define DRM_IOCTL_I810_FSTATUS DRM_IO ( 0x4a)
#define DRM_IOCTL_I810_OV0FLIP DRM_IO ( 0x4b)
#define DRM_IOCTL_I810_MC DRM_IOW( 0x4c, drm_i810_mc_t)
#define DRM_IOCTL_I810_RSTATUS DRM_IO ( 0x4d )
typedef struct _drm_i810_clear { typedef struct _drm_i810_clear {
int clear_color; int clear_color;
int clear_depth; int clear_depth;
int flags; int flags;
} drm_i810_clear_t; } drm_i810_clear_t;
/* These may be placeholders if we have more cliprects than /* These may be placeholders if we have more cliprects than
* I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to * I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to
* false, indicating that the buffer will be dispatched again with a * false, indicating that the buffer will be dispatched again with a
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#include <linux/config.h> #include <linux/config.h>
#include "i810.h" #include "i810.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "i810_drm.h"
#include "i810_drv.h" #include "i810_drv.h"
#define DRIVER_AUTHOR "VA Linux Systems Inc." #define DRIVER_AUTHOR "VA Linux Systems Inc."
......
...@@ -34,10 +34,11 @@ ...@@ -34,10 +34,11 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "i830.h" #include "i830.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "i830_drm.h"
#include "i830_drv.h" #include "i830_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pagemap.h>
/* in case we don't have a 2.3.99-pre6 kernel or later: */ /* in case we don't have a 2.3.99-pre6 kernel or later: */
#ifndef VM_DONTCOPY #ifndef VM_DONTCOPY
...@@ -58,7 +59,6 @@ ...@@ -58,7 +59,6 @@
do { \ do { \
int _head; \ int _head; \
int _tail; \ int _tail; \
int _i; \
do { \ do { \
_head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; \ _head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; \
_tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; \ _tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; \
...@@ -370,8 +370,6 @@ static int i830_wait_ring(drm_device_t *dev, int n) ...@@ -370,8 +370,6 @@ static int i830_wait_ring(drm_device_t *dev, int n)
end = jiffies + (HZ*3); end = jiffies + (HZ*3);
while (ring->space < n) { while (ring->space < n) {
int i;
ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
ring->space = ring->head - (ring->tail+8); ring->space = ring->head - (ring->tail+8);
if (ring->space < 0) ring->space += ring->Size; if (ring->space < 0) ring->space += ring->Size;
...@@ -387,7 +385,6 @@ static int i830_wait_ring(drm_device_t *dev, int n) ...@@ -387,7 +385,6 @@ static int i830_wait_ring(drm_device_t *dev, int n)
DRM_ERROR("lockup\n"); DRM_ERROR("lockup\n");
goto out_wait_ring; goto out_wait_ring;
} }
udelay(1); udelay(1);
} }
......
...@@ -201,6 +201,19 @@ typedef struct _drm_i830_sarea { ...@@ -201,6 +201,19 @@ typedef struct _drm_i830_sarea {
int vertex_prim; int vertex_prim;
} drm_i830_sarea_t; } drm_i830_sarea_t;
/* I830 specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_I830_INIT DRM_IOW( 0x40, drm_i830_init_t)
#define DRM_IOCTL_I830_VERTEX DRM_IOW( 0x41, drm_i830_vertex_t)
#define DRM_IOCTL_I830_CLEAR DRM_IOW( 0x42, drm_i830_clear_t)
#define DRM_IOCTL_I830_FLUSH DRM_IO ( 0x43)
#define DRM_IOCTL_I830_GETAGE DRM_IO ( 0x44)
#define DRM_IOCTL_I830_GETBUF DRM_IOWR(0x45, drm_i830_dma_t)
#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46)
#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t)
#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48)
typedef struct _drm_i830_clear { typedef struct _drm_i830_clear {
int clear_color; int clear_color;
int clear_depth; int clear_depth;
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include <linux/config.h> #include <linux/config.h>
#include "i830.h" #include "i830.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "i830_drm.h"
#include "i830_drv.h" #include "i830_drv.h"
#define DRIVER_AUTHOR "VA Linux Systems Inc." #define DRIVER_AUTHOR "VA Linux Systems Inc."
......
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "mga.h" #include "mga.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "mga_drm.h"
#include "mga_drv.h" #include "mga_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
/* WARNING: If you change any of these defines, make sure to change the /* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (mga_sarea.h) * defines in the Xserver file (mga_sarea.h)
*/ */
#ifndef __MGA_SAREA_DEFINES__ #ifndef __MGA_SAREA_DEFINES__
#define __MGA_SAREA_DEFINES__ #define __MGA_SAREA_DEFINES__
...@@ -225,6 +226,20 @@ typedef struct _drm_mga_sarea { ...@@ -225,6 +226,20 @@ typedef struct _drm_mga_sarea {
/* WARNING: If you change any of these defines, make sure to change the /* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmMga.h) * defines in the Xserver file (xf86drmMga.h)
*/ */
/* MGA specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t)
#define DRM_IOCTL_MGA_RESET DRM_IO( 0x42)
#define DRM_IOCTL_MGA_SWAP DRM_IO( 0x43)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x44, drm_mga_clear_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x45, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t)
typedef struct _drm_mga_warp_index { typedef struct _drm_mga_warp_index {
int installed; int installed;
unsigned long phys_addr; unsigned long phys_addr;
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <linux/config.h> #include <linux/config.h>
#include "mga.h" #include "mga.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "mga_drm.h"
#include "mga_drv.h" #include "mga_drv.h"
#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." #define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc."
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "mga.h" #include "mga.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "mga_drm.h"
#include "mga_drv.h" #include "mga_drv.h"
#include "drm.h" #include "drm.h"
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "mga.h" #include "mga.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "mga_drm.h"
#include "mga_drv.h" #include "mga_drv.h"
#include "mga_ucode.h" #include "mga_ucode.h"
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "r128.h" #include "r128.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "r128_drm.h"
#include "r128_drv.h" #include "r128_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
......
...@@ -170,6 +170,27 @@ typedef struct drm_r128_sarea { ...@@ -170,6 +170,27 @@ typedef struct drm_r128_sarea {
/* WARNING: If you change any of these defines, make sure to change the /* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmR128.h) * defines in the Xserver file (xf86drmR128.h)
*/ */
/* Rage 128 specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t)
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t)
typedef struct drm_r128_init { typedef struct drm_r128_init {
enum { enum {
R128_INIT_CCE = 0x01, R128_INIT_CCE = 0x01,
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <linux/config.h> #include <linux/config.h>
#include "r128.h" #include "r128.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "r128_drm.h"
#include "r128_drv.h" #include "r128_drv.h"
#include "ati_pcigart.h" #include "ati_pcigart.h"
......
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
#ifndef __R128_DRV_H__ #ifndef __R128_DRV_H__
#define __R128_DRV_H__ #define __R128_DRV_H__
#define GET_RING_HEAD( ring ) le32_to_cpu( *(ring)->head ) #define GET_RING_HEAD(ring) readl( (volatile u32 *) (ring)->head )
#define SET_RING_HEAD( ring, val ) *(ring)->head = cpu_to_le32( val ) #define SET_RING_HEAD(ring,val) writel( (val), (volatile u32 *) (ring)->head )
typedef struct drm_r128_freelist { typedef struct drm_r128_freelist {
unsigned int age; unsigned int age;
...@@ -384,44 +384,11 @@ extern int r128_cce_indirect( struct inode *inode, struct file *filp, ...@@ -384,44 +384,11 @@ extern int r128_cce_indirect( struct inode *inode, struct file *filp,
#define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
#define R128_ADDR(reg) (R128_BASE( reg ) + reg) #define R128_ADDR(reg) (R128_BASE( reg ) + reg)
#define R128_DEREF(reg) *(volatile u32 *)R128_ADDR( reg ) #define R128_READ(reg) readl( (volatile u32 *) R128_ADDR(reg) )
#ifdef __alpha__ #define R128_WRITE(reg,val) writel( (val), (volatile u32 *) R128_ADDR(reg) )
#define R128_READ(reg) (_R128_READ((u32 *)R128_ADDR(reg)))
static inline u32 _R128_READ(u32 *addr)
{
mb();
return *(volatile u32 *)addr;
}
#define R128_WRITE(reg,val) \
do { \
wmb(); \
R128_DEREF(reg) = val; \
} while (0)
#else
#define R128_READ(reg) le32_to_cpu( R128_DEREF( reg ) )
#define R128_WRITE(reg,val) \
do { \
R128_DEREF( reg ) = cpu_to_le32( val ); \
} while (0)
#endif
#define R128_DEREF8(reg) *(volatile u8 *)R128_ADDR( reg ) #define R128_READ8(reg) readb( (volatile u8 *) R128_ADDR(reg) )
#ifdef __alpha__ #define R128_WRITE8(reg,val) writeb( (val), (volatile u8 *) R128_ADDR(reg) )
#define R128_READ8(reg) _R128_READ8((u8 *)R128_ADDR(reg))
static inline u8 _R128_READ8(u8 *addr)
{
mb();
return *(volatile u8 *)addr;
}
#define R128_WRITE8(reg,val) \
do { \
wmb(); \
R128_DEREF8(reg) = val; \
} while (0)
#else
#define R128_READ8(reg) R128_DEREF8( reg )
#define R128_WRITE8(reg,val) do { R128_DEREF8( reg ) = val; } while (0)
#endif
#define R128_WRITE_PLL(addr,val) \ #define R128_WRITE_PLL(addr,val) \
do { \ do { \
...@@ -493,7 +460,11 @@ do { \ ...@@ -493,7 +460,11 @@ do { \
* Ring control * Ring control
*/ */
#if defined(__powerpc__)
#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring )
#else
#define r128_flush_write_combine() mb() #define r128_flush_write_combine() mb()
#endif
#define R128_VERBOSE 0 #define R128_VERBOSE 0
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "r128.h" #include "r128.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "r128_drm.h"
#include "r128_drv.h" #include "r128_drv.h"
#include "drm.h" #include "drm.h"
#include <linux/delay.h> #include <linux/delay.h>
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "radeon.h" #include "radeon.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "radeon_drm.h"
#include "radeon_drv.h" #include "radeon_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
...@@ -38,7 +40,7 @@ ...@@ -38,7 +40,7 @@
#define RADEON_FIFO_DEBUG 0 #define RADEON_FIFO_DEBUG 0
#if defined(__alpha__) #if defined(__alpha__) || defined(__powerpc__)
# define PCIGART_ENABLED # define PCIGART_ENABLED
#else #else
# undef PCIGART_ENABLED # undef PCIGART_ENABLED
...@@ -631,7 +633,11 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, ...@@ -631,7 +633,11 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
} }
/* Set ring buffer size */ /* Set ring buffer size */
#ifdef __BIG_ENDIAN
RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT );
#else
RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
#endif
radeon_do_wait_for_idle( dev_priv ); radeon_do_wait_for_idle( dev_priv );
......
...@@ -301,6 +301,29 @@ typedef struct { ...@@ -301,6 +301,29 @@ typedef struct {
* *
* KW: actually it's illegal to change any of this (backwards compatibility). * KW: actually it's illegal to change any of this (backwards compatibility).
*/ */
/* Radeon specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41)
#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t)
#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43)
#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45)
#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t)
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52)
typedef struct drm_radeon_init { typedef struct drm_radeon_init {
enum { enum {
RADEON_INIT_CP = 0x01, RADEON_INIT_CP = 0x01,
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include <linux/config.h> #include <linux/config.h>
#include "radeon.h" #include "radeon.h"
#include "drmP.h" #include "drmP.h"
#include "drm.h"
#include "radeon_drm.h"
#include "radeon_drv.h" #include "radeon_drv.h"
#include "ati_pcigart.h" #include "ati_pcigart.h"
...@@ -37,11 +39,11 @@ ...@@ -37,11 +39,11 @@
#define DRIVER_NAME "radeon" #define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon" #define DRIVER_DESC "ATI Radeon"
#define DRIVER_DATE "20020521" #define DRIVER_DATE "20020611"
#define DRIVER_MAJOR 1 #define DRIVER_MAJOR 1
#define DRIVER_MINOR 3 #define DRIVER_MINOR 3
#define DRIVER_PATCHLEVEL 0 #define DRIVER_PATCHLEVEL 1
/* Interface history: /* Interface history:
* *
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
#ifndef __RADEON_DRV_H__ #ifndef __RADEON_DRV_H__
#define __RADEON_DRV_H__ #define __RADEON_DRV_H__
#define GET_RING_HEAD(ring) readl( (volatile u32 *) (ring)->head )
#define SET_RING_HEAD(ring,val) writel( (val), (volatile u32 *) (ring)->head )
typedef struct drm_radeon_freelist { typedef struct drm_radeon_freelist {
unsigned int age; unsigned int age;
drm_buf_t *buf; drm_buf_t *buf;
...@@ -141,7 +144,7 @@ extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ); ...@@ -141,7 +144,7 @@ extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n );
static inline void static inline void
radeon_update_ring_snapshot( drm_radeon_ring_buffer_t *ring ) radeon_update_ring_snapshot( drm_radeon_ring_buffer_t *ring )
{ {
ring->space = (*(volatile int *)ring->head - ring->tail) * sizeof(u32); ring->space = (GET_RING_HEAD(ring) - ring->tail) * sizeof(u32);
if ( ring->space <= 0 ) if ( ring->space <= 0 )
ring->space += ring->size; ring->space += ring->size;
} }
...@@ -249,6 +252,12 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp, ...@@ -249,6 +252,12 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp,
# define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4) # define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4)
# define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5) # define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5)
#define RADEON_RBBM_GUICNTL 0x172c
# define RADEON_HOST_DATA_SWAP_NONE (0 << 0)
# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0)
# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0)
# define RADEON_HOST_DATA_SWAP_HDW (3 << 0)
#define RADEON_MC_AGP_LOCATION 0x014c #define RADEON_MC_AGP_LOCATION 0x014c
#define RADEON_MC_FB_LOCATION 0x0148 #define RADEON_MC_FB_LOCATION 0x0148
#define RADEON_MCLK_CNTL 0x0012 #define RADEON_MCLK_CNTL 0x0012
...@@ -424,6 +433,7 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp, ...@@ -424,6 +433,7 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp,
#define RADEON_CP_RB_BASE 0x0700 #define RADEON_CP_RB_BASE 0x0700
#define RADEON_CP_RB_CNTL 0x0704 #define RADEON_CP_RB_CNTL 0x0704
# define RADEON_BUF_SWAP_32BIT (2 << 16)
#define RADEON_CP_RB_RPTR_ADDR 0x070c #define RADEON_CP_RB_RPTR_ADDR 0x070c
#define RADEON_CP_RB_RPTR 0x0710 #define RADEON_CP_RB_RPTR 0x0710
#define RADEON_CP_RB_WPTR 0x0714 #define RADEON_CP_RB_WPTR 0x0714
...@@ -533,41 +543,11 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp, ...@@ -533,41 +543,11 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp,
#define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
#define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg) #define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg)
#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR( reg ) #define RADEON_READ(reg) readl( (volatile u32 *) RADEON_ADDR(reg) )
#ifdef __alpha__ #define RADEON_WRITE(reg,val) writel( (val), (volatile u32 *) RADEON_ADDR(reg) )
#define RADEON_READ(reg) (_RADEON_READ((u32 *)RADEON_ADDR( reg )))
static inline u32 _RADEON_READ(u32 *addr)
{
mb();
return *(volatile u32 *)addr;
}
#define RADEON_WRITE(reg,val) \
do { \
wmb(); \
RADEON_DEREF(reg) = val; \
} while (0)
#else
#define RADEON_READ(reg) RADEON_DEREF( reg )
#define RADEON_WRITE(reg, val) do { RADEON_DEREF( reg ) = val; } while (0)
#endif
#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR( reg ) #define RADEON_READ8(reg) readb( (volatile u8 *) RADEON_ADDR(reg) )
#ifdef __alpha__ #define RADEON_WRITE8(reg,val) writeb( (val), (volatile u8 *) RADEON_ADDR(reg) )
#define RADEON_READ8(reg) _RADEON_READ8((u8 *)RADEON_ADDR( reg ))
static inline u8 _RADEON_READ8(u8 *addr)
{
mb();
return *(volatile u8 *)addr;
}
#define RADEON_WRITE8(reg,val) \
do { \
wmb(); \
RADEON_DEREF8( reg ) = val; \
} while (0)
#else
#define RADEON_READ8(reg) RADEON_DEREF8( reg )
#define RADEON_WRITE8(reg, val) do { RADEON_DEREF8( reg ) = val; } while (0)
#endif
#define RADEON_WRITE_PLL( addr, val ) \ #define RADEON_WRITE_PLL( addr, val ) \
do { \ do { \
...@@ -664,6 +644,15 @@ do { \ ...@@ -664,6 +644,15 @@ do { \
goto __ring_space_done; \ goto __ring_space_done; \
udelay( 1 ); \ udelay( 1 ); \
} \ } \
DRM_ERROR( "ring space check from memory failed, reading register...\n" ); \
/* If ring space check fails from RAM, try reading the \
register directly */ \
ring->space = 4 * ( RADEON_READ( RADEON_CP_RB_RPTR ) - ring->tail ); \
if ( ring->space <= 0 ) \
ring->space += ring->size; \
if ( ring->space >= ring->high_mark ) \
goto __ring_space_done; \
\
DRM_ERROR( "ring space check failed!\n" ); \ DRM_ERROR( "ring space check failed!\n" ); \
return -EBUSY; \ return -EBUSY; \
} \ } \
...@@ -701,7 +690,11 @@ do { \ ...@@ -701,7 +690,11 @@ do { \
* Ring control * Ring control
*/ */
#if defined(__powerpc__)
#define radeon_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring )
#else
#define radeon_flush_write_combine() mb() #define radeon_flush_write_combine() mb()
#endif
#define RADEON_VERBOSE 0 #define RADEON_VERBOSE 0
...@@ -738,6 +731,7 @@ do { \ ...@@ -738,6 +731,7 @@ do { \
} while (0) } while (0)
#define COMMIT_RING() do { \ #define COMMIT_RING() do { \
radeon_flush_write_combine(); \
RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
} while (0) } while (0)
......
...@@ -30,8 +30,9 @@ ...@@ -30,8 +30,9 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "radeon.h" #include "radeon.h"
#include "drmP.h" #include "drmP.h"
#include "radeon_drv.h"
#include "drm.h" #include "drm.h"
#include "radeon_drm.h"
#include "radeon_drv.h"
#include <linux/delay.h> #include <linux/delay.h>
...@@ -669,7 +670,6 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev, ...@@ -669,7 +670,6 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev,
int i = 0; int i = 0;
RING_LOCALS; RING_LOCALS;
DRM_DEBUG("%s: hwprim 0x%x vfmt 0x%x %d..%d %d verts\n", DRM_DEBUG("%s: hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
__FUNCTION__, __FUNCTION__,
prim->prim, prim->prim,
...@@ -684,7 +684,6 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev, ...@@ -684,7 +684,6 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev,
return; return;
} }
do { do {
/* Emit the next cliprect */ /* Emit the next cliprect */
if ( i < nbox ) { if ( i < nbox ) {
...@@ -906,6 +905,16 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev, ...@@ -906,6 +905,16 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
ADVANCE_RING(); ADVANCE_RING();
#ifdef __BIG_ENDIAN
/* The Mesa texture functions provide the data in little endian as the
* chip wants it, but we need to compensate for the fact that the CP
* ring gets byte-swapped
*/
BEGIN_RING( 2 );
OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT );
ADVANCE_RING();
#endif
/* Make a copy of the parameters in case we have to update them /* Make a copy of the parameters in case we have to update them
* for a multi-pass texture blit. * for a multi-pass texture blit.
*/ */
...@@ -1081,6 +1090,7 @@ static int radeon_do_init_pageflip( drm_device_t *dev ) ...@@ -1081,6 +1090,7 @@ static int radeon_do_init_pageflip( drm_device_t *dev )
dev_priv->page_flipping = 1; dev_priv->page_flipping = 1;
dev_priv->current_page = 0; dev_priv->current_page = 0;
dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
return 0; return 0;
} }
...@@ -1095,6 +1105,7 @@ int radeon_do_cleanup_pageflip( drm_device_t *dev ) ...@@ -1095,6 +1105,7 @@ int radeon_do_cleanup_pageflip( drm_device_t *dev )
dev_priv->page_flipping = 0; dev_priv->page_flipping = 0;
dev_priv->current_page = 0; dev_priv->current_page = 0;
dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
return 0; return 0;
} }
...@@ -1585,15 +1596,15 @@ static int radeon_emit_packets( ...@@ -1585,15 +1596,15 @@ static int radeon_emit_packets(
drm_radeon_cmd_header_t header, drm_radeon_cmd_header_t header,
drm_radeon_cmd_buffer_t *cmdbuf ) drm_radeon_cmd_buffer_t *cmdbuf )
{ {
int sz = packet[(int)header.packet.packet_id].len; int id = (int)header.packet.packet_id;
int reg = packet[(int)header.packet.packet_id].start; int sz = packet[id].len;
int reg = packet[id].start;
int *data = (int *)cmdbuf->buf; int *data = (int *)cmdbuf->buf;
RING_LOCALS; RING_LOCALS;
if (sz * sizeof(int) > cmdbuf->bufsz) if (sz * sizeof(int) > cmdbuf->bufsz)
return -EINVAL; return -EINVAL;
BEGIN_RING(sz+1); BEGIN_RING(sz+1);
OUT_RING( CP_PACKET0( reg, (sz-1) ) ); OUT_RING( CP_PACKET0( reg, (sz-1) ) );
OUT_RING_USER_TABLE( data, sz ); OUT_RING_USER_TABLE( data, sz );
......
...@@ -2,6 +2,16 @@ ...@@ -2,6 +2,16 @@
#ifndef _sis_drm_public_h_ #ifndef _sis_drm_public_h_
#define _sis_drm_public_h_ #define _sis_drm_public_h_
/* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t)
#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t)
#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t)
#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t)
#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49)
#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50)
typedef struct { typedef struct {
int context; int context;
unsigned int offset; unsigned int offset;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment