diff options
author | Dave Airlie <airlied@redhat.com> | 2008-11-27 23:22:24 -0500 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2008-12-29 02:47:22 -0500 |
commit | 7c1c2871a6a3a114853ec6836e9035ac1c0c7f7a (patch) | |
tree | 1b5debcc86ff20bd5e11b42ea5c52da42214e376 /drivers/gpu/drm/radeon/radeon_cp.c | |
parent | e7f7ab45ebcb54fd5f814ea15ea079e079662f67 (diff) |
drm: move to kref per-master structures.
This is step one towards having multiple masters sharing a drm
device in order to get fast-user-switching to work.
It splits out the information associated with the drm master
into a separate kref counted structure, and allocates this when
a master opens the device node. It also allows the current master
to abdicate (say while VT switched), and a new master to take over
the hardware.
It moves the Intel and radeon drivers to using the sarea from
within the new master structures.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_cp.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_cp.c | 73 |
1 files changed, 58 insertions, 15 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index dcebb4bee7aa..7b37a4906377 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include "drmP.h" | 32 | #include "drmP.h" |
33 | #include "drm.h" | 33 | #include "drm.h" |
34 | #include "drm_sarea.h" | ||
34 | #include "radeon_drm.h" | 35 | #include "radeon_drm.h" |
35 | #include "radeon_drv.h" | 36 | #include "radeon_drv.h" |
36 | #include "r300_reg.h" | 37 | #include "r300_reg.h" |
@@ -667,15 +668,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, | |||
667 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); | 668 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); |
668 | } /* PCIE cards appears to not need this */ | 669 | } /* PCIE cards appears to not need this */ |
669 | 670 | ||
670 | dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; | 671 | dev_priv->scratch[0] = 0; |
671 | RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); | 672 | RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); |
672 | 673 | ||
673 | dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; | 674 | dev_priv->scratch[1] = 0; |
674 | RADEON_WRITE(RADEON_LAST_DISPATCH_REG, | 675 | RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); |
675 | dev_priv->sarea_priv->last_dispatch); | ||
676 | 676 | ||
677 | dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; | 677 | dev_priv->scratch[2] = 0; |
678 | RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); | 678 | RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); |
679 | 679 | ||
680 | radeon_do_wait_for_idle(dev_priv); | 680 | radeon_do_wait_for_idle(dev_priv); |
681 | 681 | ||
@@ -871,9 +871,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) | |||
871 | } | 871 | } |
872 | } | 872 | } |
873 | 873 | ||
874 | static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) | 874 | static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, |
875 | struct drm_file *file_priv) | ||
875 | { | 876 | { |
876 | drm_radeon_private_t *dev_priv = dev->dev_private; | 877 | drm_radeon_private_t *dev_priv = dev->dev_private; |
878 | struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; | ||
877 | 879 | ||
878 | DRM_DEBUG("\n"); | 880 | DRM_DEBUG("\n"); |
879 | 881 | ||
@@ -998,8 +1000,8 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) | |||
998 | dev_priv->buffers_offset = init->buffers_offset; | 1000 | dev_priv->buffers_offset = init->buffers_offset; |
999 | dev_priv->gart_textures_offset = init->gart_textures_offset; | 1001 | dev_priv->gart_textures_offset = init->gart_textures_offset; |
1000 | 1002 | ||
1001 | dev_priv->sarea = drm_getsarea(dev); | 1003 | master_priv->sarea = drm_getsarea(dev); |
1002 | if (!dev_priv->sarea) { | 1004 | if (!master_priv->sarea) { |
1003 | DRM_ERROR("could not find sarea!\n"); | 1005 | DRM_ERROR("could not find sarea!\n"); |
1004 | radeon_do_cleanup_cp(dev); | 1006 | radeon_do_cleanup_cp(dev); |
1005 | return -EINVAL; | 1007 | return -EINVAL; |
@@ -1035,10 +1037,6 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) | |||
1035 | } | 1037 | } |
1036 | } | 1038 | } |
1037 | 1039 | ||
1038 | dev_priv->sarea_priv = | ||
1039 | (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle + | ||
1040 | init->sarea_priv_offset); | ||
1041 | |||
1042 | #if __OS_HAS_AGP | 1040 | #if __OS_HAS_AGP |
1043 | if (dev_priv->flags & RADEON_IS_AGP) { | 1041 | if (dev_priv->flags & RADEON_IS_AGP) { |
1044 | drm_core_ioremap(dev_priv->cp_ring, dev); | 1042 | drm_core_ioremap(dev_priv->cp_ring, dev); |
@@ -1329,7 +1327,7 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri | |||
1329 | case RADEON_INIT_CP: | 1327 | case RADEON_INIT_CP: |
1330 | case RADEON_INIT_R200_CP: | 1328 | case RADEON_INIT_R200_CP: |
1331 | case RADEON_INIT_R300_CP: | 1329 | case RADEON_INIT_R300_CP: |
1332 | return radeon_do_init_cp(dev, init); | 1330 | return radeon_do_init_cp(dev, init, file_priv); |
1333 | case RADEON_CLEANUP_CP: | 1331 | case RADEON_CLEANUP_CP: |
1334 | return radeon_do_cleanup_cp(dev); | 1332 | return radeon_do_cleanup_cp(dev); |
1335 | } | 1333 | } |
@@ -1768,6 +1766,51 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) | |||
1768 | return ret; | 1766 | return ret; |
1769 | } | 1767 | } |
1770 | 1768 | ||
1769 | int radeon_master_create(struct drm_device *dev, struct drm_master *master) | ||
1770 | { | ||
1771 | struct drm_radeon_master_private *master_priv; | ||
1772 | unsigned long sareapage; | ||
1773 | int ret; | ||
1774 | |||
1775 | master_priv = drm_calloc(1, sizeof(*master_priv), DRM_MEM_DRIVER); | ||
1776 | if (!master_priv) | ||
1777 | return -ENOMEM; | ||
1778 | |||
1779 | /* prebuild the SAREA */ | ||
1780 | sareapage = max(SAREA_MAX, PAGE_SIZE); | ||
1781 | ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK|_DRM_DRIVER, | ||
1782 | &master_priv->sarea); | ||
1783 | if (ret) { | ||
1784 | DRM_ERROR("SAREA setup failed\n"); | ||
1785 | return ret; | ||
1786 | } | ||
1787 | master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea); | ||
1788 | master_priv->sarea_priv->pfCurrentPage = 0; | ||
1789 | |||
1790 | master->driver_priv = master_priv; | ||
1791 | return 0; | ||
1792 | } | ||
1793 | |||
1794 | void radeon_master_destroy(struct drm_device *dev, struct drm_master *master) | ||
1795 | { | ||
1796 | struct drm_radeon_master_private *master_priv = master->driver_priv; | ||
1797 | |||
1798 | if (!master_priv) | ||
1799 | return; | ||
1800 | |||
1801 | if (master_priv->sarea_priv && | ||
1802 | master_priv->sarea_priv->pfCurrentPage != 0) | ||
1803 | radeon_cp_dispatch_flip(dev, master); | ||
1804 | |||
1805 | master_priv->sarea_priv = NULL; | ||
1806 | if (master_priv->sarea) | ||
1807 | drm_rmmap(dev, master_priv->sarea); | ||
1808 | |||
1809 | drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); | ||
1810 | |||
1811 | master->driver_priv = NULL; | ||
1812 | } | ||
1813 | |||
1771 | /* Create mappings for registers and framebuffer so userland doesn't necessarily | 1814 | /* Create mappings for registers and framebuffer so userland doesn't necessarily |
1772 | * have to find them. | 1815 | * have to find them. |
1773 | */ | 1816 | */ |