aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-12-01 13:43:46 -0500
committerDave Airlie <airlied@redhat.com>2009-12-01 23:00:06 -0500
commitd8f60cfc93452d0554f6a701aa8e3236cbee4636 (patch)
treed6048658b42bdd9443f424755cd85f855e1477ba /drivers/gpu
parent50dafba685c0f12c23d315820370b32d9ba64db7 (diff)
drm/radeon/kms: Add support for interrupts on r6xx/r7xx chips (v3)
This enables the use of interrupts on r6xx/r7xx hardware. Interrupts are implemented via a ring buffer. The GPU adds interrupts vectors to the ring and the host reads them off in the interrupt handler. The interrupt controller requires firmware like the CP. This firmware must be installed and accessble to the firmware loader for interrupts to function. MSIs don't seem to work on my RS780. They work fine on all my discrete cards. I'm not sure about other RS780s or RS880s. I've disabled MSIs on RS780 and RS880, but it would probably be worth checking on some other systems. v2 - fix some checkpatch.pl problems; re-read the disp int status reg if we restart the ih; v3 - remove the irq handler if r600_irq_init() fails; remove spinlock in r600_ih_ring_fini(); move ih rb overflow check to r600_get_ih_wptr(); move irq ack to separate function; Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/r600.c561
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c4
-rw-r--r--drivers/gpu/drm/radeon/r600d.h159
-rw-r--r--drivers/gpu/drm/radeon/radeon.h26
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c38
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c12
-rw-r--r--drivers/gpu/drm/radeon/rv770.c24
10 files changed, 754 insertions, 75 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 3dbd93e44345..5067ab7fdced 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -38,8 +38,10 @@
38 38
39#define PFP_UCODE_SIZE 576 39#define PFP_UCODE_SIZE 576
40#define PM4_UCODE_SIZE 1792 40#define PM4_UCODE_SIZE 1792
41#define RLC_UCODE_SIZE 768
41#define R700_PFP_UCODE_SIZE 848 42#define R700_PFP_UCODE_SIZE 848
42#define R700_PM4_UCODE_SIZE 1360 43#define R700_PM4_UCODE_SIZE 1360
44#define R700_RLC_UCODE_SIZE 1024
43 45
44/* Firmware Names */ 46/* Firmware Names */
45MODULE_FIRMWARE("radeon/R600_pfp.bin"); 47MODULE_FIRMWARE("radeon/R600_pfp.bin");
@@ -62,6 +64,8 @@ MODULE_FIRMWARE("radeon/RV730_pfp.bin");
62MODULE_FIRMWARE("radeon/RV730_me.bin"); 64MODULE_FIRMWARE("radeon/RV730_me.bin");
63MODULE_FIRMWARE("radeon/RV710_pfp.bin"); 65MODULE_FIRMWARE("radeon/RV710_pfp.bin");
64MODULE_FIRMWARE("radeon/RV710_me.bin"); 66MODULE_FIRMWARE("radeon/RV710_me.bin");
67MODULE_FIRMWARE("radeon/R600_rlc.bin");
68MODULE_FIRMWARE("radeon/R700_rlc.bin");
65 69
66int r600_debugfs_mc_info_init(struct radeon_device *rdev); 70int r600_debugfs_mc_info_init(struct radeon_device *rdev);
67 71
@@ -1114,11 +1118,12 @@ void r600_cp_stop(struct radeon_device *rdev)
1114 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); 1118 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
1115} 1119}
1116 1120
1117int r600_cp_init_microcode(struct radeon_device *rdev) 1121int r600_init_microcode(struct radeon_device *rdev)
1118{ 1122{
1119 struct platform_device *pdev; 1123 struct platform_device *pdev;
1120 const char *chip_name; 1124 const char *chip_name;
1121 size_t pfp_req_size, me_req_size; 1125 const char *rlc_chip_name;
1126 size_t pfp_req_size, me_req_size, rlc_req_size;
1122 char fw_name[30]; 1127 char fw_name[30];
1123 int err; 1128 int err;
1124 1129
@@ -1132,30 +1137,62 @@ int r600_cp_init_microcode(struct radeon_device *rdev)
1132 } 1137 }
1133 1138
1134 switch (rdev->family) { 1139 switch (rdev->family) {
1135 case CHIP_R600: chip_name = "R600"; break; 1140 case CHIP_R600:
1136 case CHIP_RV610: chip_name = "RV610"; break; 1141 chip_name = "R600";
1137 case CHIP_RV630: chip_name = "RV630"; break; 1142 rlc_chip_name = "R600";
1138 case CHIP_RV620: chip_name = "RV620"; break; 1143 break;
1139 case CHIP_RV635: chip_name = "RV635"; break; 1144 case CHIP_RV610:
1140 case CHIP_RV670: chip_name = "RV670"; break; 1145 chip_name = "RV610";
1146 rlc_chip_name = "R600";
1147 break;
1148 case CHIP_RV630:
1149 chip_name = "RV630";
1150 rlc_chip_name = "R600";
1151 break;
1152 case CHIP_RV620:
1153 chip_name = "RV620";
1154 rlc_chip_name = "R600";
1155 break;
1156 case CHIP_RV635:
1157 chip_name = "RV635";
1158 rlc_chip_name = "R600";
1159 break;
1160 case CHIP_RV670:
1161 chip_name = "RV670";
1162 rlc_chip_name = "R600";
1163 break;
1141 case CHIP_RS780: 1164 case CHIP_RS780:
1142 case CHIP_RS880: chip_name = "RS780"; break; 1165 case CHIP_RS880:
1143 case CHIP_RV770: chip_name = "RV770"; break; 1166 chip_name = "RS780";
1167 rlc_chip_name = "R600";
1168 break;
1169 case CHIP_RV770:
1170 chip_name = "RV770";
1171 rlc_chip_name = "R700";
1172 break;
1144 case CHIP_RV730: 1173 case CHIP_RV730:
1145 case CHIP_RV740: chip_name = "RV730"; break; 1174 case CHIP_RV740:
1146 case CHIP_RV710: chip_name = "RV710"; break; 1175 chip_name = "RV730";
1176 rlc_chip_name = "R700";
1177 break;
1178 case CHIP_RV710:
1179 chip_name = "RV710";
1180 rlc_chip_name = "R700";
1181 break;
1147 default: BUG(); 1182 default: BUG();
1148 } 1183 }
1149 1184
1150 if (rdev->family >= CHIP_RV770) { 1185 if (rdev->family >= CHIP_RV770) {
1151 pfp_req_size = R700_PFP_UCODE_SIZE * 4; 1186 pfp_req_size = R700_PFP_UCODE_SIZE * 4;
1152 me_req_size = R700_PM4_UCODE_SIZE * 4; 1187 me_req_size = R700_PM4_UCODE_SIZE * 4;
1188 rlc_req_size = R700_RLC_UCODE_SIZE * 4;
1153 } else { 1189 } else {
1154 pfp_req_size = PFP_UCODE_SIZE * 4; 1190 pfp_req_size = PFP_UCODE_SIZE * 4;
1155 me_req_size = PM4_UCODE_SIZE * 12; 1191 me_req_size = PM4_UCODE_SIZE * 12;
1192 rlc_req_size = RLC_UCODE_SIZE * 4;
1156 } 1193 }
1157 1194
1158 DRM_INFO("Loading %s CP Microcode\n", chip_name); 1195 DRM_INFO("Loading %s Microcode\n", chip_name);
1159 1196
1160 snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); 1197 snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
1161 err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); 1198 err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
@@ -1179,6 +1216,18 @@ int r600_cp_init_microcode(struct radeon_device *rdev)
1179 rdev->me_fw->size, fw_name); 1216 rdev->me_fw->size, fw_name);
1180 err = -EINVAL; 1217 err = -EINVAL;
1181 } 1218 }
1219
1220 snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
1221 err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
1222 if (err)
1223 goto out;
1224 if (rdev->rlc_fw->size != rlc_req_size) {
1225 printk(KERN_ERR
1226 "r600_rlc: Bogus length %zu in firmware \"%s\"\n",
1227 rdev->rlc_fw->size, fw_name);
1228 err = -EINVAL;
1229 }
1230
1182out: 1231out:
1183 platform_device_unregister(pdev); 1232 platform_device_unregister(pdev);
1184 1233
@@ -1191,6 +1240,8 @@ out:
1191 rdev->pfp_fw = NULL; 1240 rdev->pfp_fw = NULL;
1192 release_firmware(rdev->me_fw); 1241 release_firmware(rdev->me_fw);
1193 rdev->me_fw = NULL; 1242 rdev->me_fw = NULL;
1243 release_firmware(rdev->rlc_fw);
1244 rdev->rlc_fw = NULL;
1194 } 1245 }
1195 return err; 1246 return err;
1196} 1247}
@@ -1437,10 +1488,14 @@ int r600_wb_enable(struct radeon_device *rdev)
1437void r600_fence_ring_emit(struct radeon_device *rdev, 1488void r600_fence_ring_emit(struct radeon_device *rdev,
1438 struct radeon_fence *fence) 1489 struct radeon_fence *fence)
1439{ 1490{
1491 /* Also consider EVENT_WRITE_EOP. it handles the interrupts + timestamps + events */
1440 /* Emit fence sequence & fire IRQ */ 1492 /* Emit fence sequence & fire IRQ */
1441 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 1493 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1442 radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); 1494 radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
1443 radeon_ring_write(rdev, fence->seq); 1495 radeon_ring_write(rdev, fence->seq);
1496 /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */
1497 radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0));
1498 radeon_ring_write(rdev, RB_INT_STAT);
1444} 1499}
1445 1500
1446int r600_copy_dma(struct radeon_device *rdev, 1501int r600_copy_dma(struct radeon_device *rdev,
@@ -1463,18 +1518,6 @@ int r600_copy_blit(struct radeon_device *rdev,
1463 return 0; 1518 return 0;
1464} 1519}
1465 1520
1466int r600_irq_process(struct radeon_device *rdev)
1467{
1468 /* FIXME: implement */
1469 return 0;
1470}
1471
1472int r600_irq_set(struct radeon_device *rdev)
1473{
1474 /* FIXME: implement */
1475 return 0;
1476}
1477
1478int r600_set_surface_reg(struct radeon_device *rdev, int reg, 1521int r600_set_surface_reg(struct radeon_device *rdev, int reg,
1479 uint32_t tiling_flags, uint32_t pitch, 1522 uint32_t tiling_flags, uint32_t pitch,
1480 uint32_t offset, uint32_t obj_size) 1523 uint32_t offset, uint32_t obj_size)
@@ -1527,6 +1570,16 @@ int r600_startup(struct radeon_device *rdev)
1527 return r; 1570 return r;
1528 } 1571 }
1529 1572
1573 /* Enable IRQ */
1574 rdev->irq.sw_int = true;
1575 r = r600_irq_init(rdev);
1576 if (r) {
1577 DRM_ERROR("radeon: IH init failed (%d).\n", r);
1578 radeon_irq_kms_fini(rdev);
1579 return r;
1580 }
1581 r600_irq_set(rdev);
1582
1530 r = radeon_ring_init(rdev, rdev->cp.ring_size); 1583 r = radeon_ring_init(rdev, rdev->cp.ring_size);
1531 if (r) 1584 if (r)
1532 return r; 1585 return r;
@@ -1661,11 +1714,19 @@ int r600_init(struct radeon_device *rdev)
1661 r = radeon_object_init(rdev); 1714 r = radeon_object_init(rdev);
1662 if (r) 1715 if (r)
1663 return r; 1716 return r;
1717
1718 r = radeon_irq_kms_init(rdev);
1719 if (r)
1720 return r;
1721
1664 rdev->cp.ring_obj = NULL; 1722 rdev->cp.ring_obj = NULL;
1665 r600_ring_init(rdev, 1024 * 1024); 1723 r600_ring_init(rdev, 1024 * 1024);
1666 1724
1667 if (!rdev->me_fw || !rdev->pfp_fw) { 1725 rdev->ih.ring_obj = NULL;
1668 r = r600_cp_init_microcode(rdev); 1726 r600_ih_ring_init(rdev, 64 * 1024);
1727
1728 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
1729 r = r600_init_microcode(rdev);
1669 if (r) { 1730 if (r) {
1670 DRM_ERROR("Failed to load firmware!\n"); 1731 DRM_ERROR("Failed to load firmware!\n");
1671 return r; 1732 return r;
@@ -1712,6 +1773,8 @@ void r600_fini(struct radeon_device *rdev)
1712 r600_suspend(rdev); 1773 r600_suspend(rdev);
1713 1774
1714 r600_blit_fini(rdev); 1775 r600_blit_fini(rdev);
1776 r600_irq_fini(rdev);
1777 radeon_irq_kms_fini(rdev);
1715 radeon_ring_fini(rdev); 1778 radeon_ring_fini(rdev);
1716 r600_wb_fini(rdev); 1779 r600_wb_fini(rdev);
1717 r600_pcie_gart_fini(rdev); 1780 r600_pcie_gart_fini(rdev);
@@ -1806,8 +1869,452 @@ int r600_ib_test(struct radeon_device *rdev)
1806 return r; 1869 return r;
1807} 1870}
1808 1871
1872/*
1873 * Interrupts
1874 *
1875 * Interrupts use a ring buffer on r6xx/r7xx hardware. It works pretty
1876 * the same as the CP ring buffer, but in reverse. Rather than the CPU
1877 * writing to the ring and the GPU consuming, the GPU writes to the ring
1878 * and host consumes. As the host irq handler processes interrupts, it
1879 * increments the rptr. When the rptr catches up with the wptr, all the
1880 * current interrupts have been processed.
1881 */
1882
1883void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size)
1884{
1885 u32 rb_bufsz;
1886
1887 /* Align ring size */
1888 rb_bufsz = drm_order(ring_size / 4);
1889 ring_size = (1 << rb_bufsz) * 4;
1890 rdev->ih.ring_size = ring_size;
1891 rdev->ih.align_mask = 4 - 1;
1892}
1893
1894static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size)
1895{
1896 int r;
1897
1898 rdev->ih.ring_size = ring_size;
1899 /* Allocate ring buffer */
1900 if (rdev->ih.ring_obj == NULL) {
1901 r = radeon_object_create(rdev, NULL, rdev->ih.ring_size,
1902 true,
1903 RADEON_GEM_DOMAIN_GTT,
1904 false,
1905 &rdev->ih.ring_obj);
1906 if (r) {
1907 DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r);
1908 return r;
1909 }
1910 r = radeon_object_pin(rdev->ih.ring_obj,
1911 RADEON_GEM_DOMAIN_GTT,
1912 &rdev->ih.gpu_addr);
1913 if (r) {
1914 DRM_ERROR("radeon: failed to pin ih ring buffer (%d).\n", r);
1915 return r;
1916 }
1917 r = radeon_object_kmap(rdev->ih.ring_obj,
1918 (void **)&rdev->ih.ring);
1919 if (r) {
1920 DRM_ERROR("radeon: failed to map ih ring buffer (%d).\n", r);
1921 return r;
1922 }
1923 }
1924 rdev->ih.ptr_mask = (rdev->cp.ring_size / 4) - 1;
1925 rdev->ih.rptr = 0;
1926
1927 return 0;
1928}
1929
1930static void r600_ih_ring_fini(struct radeon_device *rdev)
1931{
1932 if (rdev->ih.ring_obj) {
1933 radeon_object_kunmap(rdev->ih.ring_obj);
1934 radeon_object_unpin(rdev->ih.ring_obj);
1935 radeon_object_unref(&rdev->ih.ring_obj);
1936 rdev->ih.ring = NULL;
1937 rdev->ih.ring_obj = NULL;
1938 }
1939}
1940
1941static void r600_rlc_stop(struct radeon_device *rdev)
1942{
1943
1944 if (rdev->family >= CHIP_RV770) {
1945 /* r7xx asics need to soft reset RLC before halting */
1946 WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC);
1947 RREG32(SRBM_SOFT_RESET);
1948 udelay(15000);
1949 WREG32(SRBM_SOFT_RESET, 0);
1950 RREG32(SRBM_SOFT_RESET);
1951 }
1952
1953 WREG32(RLC_CNTL, 0);
1954}
1955
1956static void r600_rlc_start(struct radeon_device *rdev)
1957{
1958 WREG32(RLC_CNTL, RLC_ENABLE);
1959}
1960
1961static int r600_rlc_init(struct radeon_device *rdev)
1962{
1963 u32 i;
1964 const __be32 *fw_data;
1965
1966 if (!rdev->rlc_fw)
1967 return -EINVAL;
1968
1969 r600_rlc_stop(rdev);
1970
1971 WREG32(RLC_HB_BASE, 0);
1972 WREG32(RLC_HB_CNTL, 0);
1973 WREG32(RLC_HB_RPTR, 0);
1974 WREG32(RLC_HB_WPTR, 0);
1975 WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
1976 WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
1977 WREG32(RLC_MC_CNTL, 0);
1978 WREG32(RLC_UCODE_CNTL, 0);
1979
1980 fw_data = (const __be32 *)rdev->rlc_fw->data;
1981 if (rdev->family >= CHIP_RV770) {
1982 for (i = 0; i < R700_RLC_UCODE_SIZE; i++) {
1983 WREG32(RLC_UCODE_ADDR, i);
1984 WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
1985 }
1986 } else {
1987 for (i = 0; i < RLC_UCODE_SIZE; i++) {
1988 WREG32(RLC_UCODE_ADDR, i);
1989 WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
1990 }
1991 }
1992 WREG32(RLC_UCODE_ADDR, 0);
1993
1994 r600_rlc_start(rdev);
1995
1996 return 0;
1997}
1998
1999static void r600_enable_interrupts(struct radeon_device *rdev)
2000{
2001 u32 ih_cntl = RREG32(IH_CNTL);
2002 u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
2003
2004 ih_cntl |= ENABLE_INTR;
2005 ih_rb_cntl |= IH_RB_ENABLE;
2006 WREG32(IH_CNTL, ih_cntl);
2007 WREG32(IH_RB_CNTL, ih_rb_cntl);
2008 rdev->ih.enabled = true;
2009}
2010
2011static void r600_disable_interrupts(struct radeon_device *rdev)
2012{
2013 u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
2014 u32 ih_cntl = RREG32(IH_CNTL);
2015
2016 ih_rb_cntl &= ~IH_RB_ENABLE;
2017 ih_cntl &= ~ENABLE_INTR;
2018 WREG32(IH_RB_CNTL, ih_rb_cntl);
2019 WREG32(IH_CNTL, ih_cntl);
2020 /* set rptr, wptr to 0 */
2021 WREG32(IH_RB_RPTR, 0);
2022 WREG32(IH_RB_WPTR, 0);
2023 rdev->ih.enabled = false;
2024 rdev->ih.wptr = 0;
2025 rdev->ih.rptr = 0;
2026}
2027
2028int r600_irq_init(struct radeon_device *rdev)
2029{
2030 int ret = 0;
2031 int rb_bufsz;
2032 u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
2033
2034 /* allocate ring */
2035 ret = r600_ih_ring_alloc(rdev, rdev->ih.ring_size);
2036 if (ret)
2037 return ret;
2038
2039 /* disable irqs */
2040 r600_disable_interrupts(rdev);
2041
2042 /* init rlc */
2043 ret = r600_rlc_init(rdev);
2044 if (ret) {
2045 r600_ih_ring_fini(rdev);
2046 return ret;
2047 }
2048
2049 /* setup interrupt control */
2050 /* set dummy read address to ring address */
2051 WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8);
2052 interrupt_cntl = RREG32(INTERRUPT_CNTL);
2053 /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi
2054 * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN
2055 */
2056 interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
2057 /* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */
2058 interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
2059 WREG32(INTERRUPT_CNTL, interrupt_cntl);
2060
2061 WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8);
2062 rb_bufsz = drm_order(rdev->ih.ring_size / 4);
2063
2064 ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE |
2065 IH_WPTR_OVERFLOW_CLEAR |
2066 (rb_bufsz << 1));
2067 /* WPTR writeback, not yet */
2068 /*ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;*/
2069 WREG32(IH_RB_WPTR_ADDR_LO, 0);
2070 WREG32(IH_RB_WPTR_ADDR_HI, 0);
2071
2072 WREG32(IH_RB_CNTL, ih_rb_cntl);
2073
2074 /* set rptr, wptr to 0 */
2075 WREG32(IH_RB_RPTR, 0);
2076 WREG32(IH_RB_WPTR, 0);
2077
2078 /* Default settings for IH_CNTL (disabled at first) */
2079 ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10);
2080 /* RPTR_REARM only works if msi's are enabled */
2081 if (rdev->msi_enabled)
2082 ih_cntl |= RPTR_REARM;
2083
2084#ifdef __BIG_ENDIAN
2085 ih_cntl |= IH_MC_SWAP(IH_MC_SWAP_32BIT);
2086#endif
2087 WREG32(IH_CNTL, ih_cntl);
2088
2089 /* force the active interrupt state to all disabled */
2090 WREG32(CP_INT_CNTL, 0);
2091 WREG32(GRBM_INT_CNTL, 0);
2092 WREG32(DxMODE_INT_MASK, 0);
2093
2094 /* enable irqs */
2095 r600_enable_interrupts(rdev);
2096
2097 return ret;
2098}
2099
2100void r600_irq_fini(struct radeon_device *rdev)
2101{
2102 r600_disable_interrupts(rdev);
2103 r600_rlc_stop(rdev);
2104 r600_ih_ring_fini(rdev);
2105}
2106
2107int r600_irq_set(struct radeon_device *rdev)
2108{
2109 uint32_t cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
2110 uint32_t mode_int = 0;
2111
2112 /* don't enable anything if the ih is disabled */
2113 if (!rdev->ih.enabled)
2114 return 0;
2115
2116 if (rdev->irq.sw_int) {
2117 DRM_DEBUG("r600_irq_set: sw int\n");
2118 cp_int_cntl |= RB_INT_ENABLE;
2119 }
2120 if (rdev->irq.crtc_vblank_int[0]) {
2121 DRM_DEBUG("r600_irq_set: vblank 0\n");
2122 mode_int |= D1MODE_VBLANK_INT_MASK;
2123 }
2124 if (rdev->irq.crtc_vblank_int[1]) {
2125 DRM_DEBUG("r600_irq_set: vblank 1\n");
2126 mode_int |= D2MODE_VBLANK_INT_MASK;
2127 }
2128
2129 WREG32(CP_INT_CNTL, cp_int_cntl);
2130 WREG32(DxMODE_INT_MASK, mode_int);
2131
2132 return 0;
2133}
2134
2135static inline void r600_irq_ack(struct radeon_device *rdev, u32 disp_int)
2136{
2137
2138 if (disp_int & LB_D1_VBLANK_INTERRUPT)
2139 WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
2140 if (disp_int & LB_D1_VLINE_INTERRUPT)
2141 WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
2142 if (disp_int & LB_D2_VBLANK_INTERRUPT)
2143 WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
2144 if (disp_int & LB_D2_VLINE_INTERRUPT)
2145 WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
2146
2147}
2148
2149void r600_irq_disable(struct radeon_device *rdev)
2150{
2151 u32 disp_int;
2152
2153 r600_disable_interrupts(rdev);
2154 /* Wait and acknowledge irq */
2155 mdelay(1);
2156 if (ASIC_IS_DCE3(rdev))
2157 disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS);
2158 else
2159 disp_int = RREG32(DISP_INTERRUPT_STATUS);
2160 r600_irq_ack(rdev, disp_int);
2161}
2162
2163static inline u32 r600_get_ih_wptr(struct radeon_device *rdev)
2164{
2165 u32 wptr, tmp;
2166
2167 /* XXX use writeback */
2168 wptr = RREG32(IH_RB_WPTR);
2169
2170 if (wptr & RB_OVERFLOW) {
2171 WARN_ON(1);
2172 /* XXX deal with overflow */
2173 DRM_ERROR("IH RB overflow\n");
2174 tmp = RREG32(IH_RB_CNTL);
2175 tmp |= IH_WPTR_OVERFLOW_CLEAR;
2176 WREG32(IH_RB_CNTL, tmp);
2177 }
2178 wptr = wptr & WPTR_OFFSET_MASK;
1809 2179
2180 return wptr;
2181}
1810 2182
2183/* r600 IV Ring
2184 * Each IV ring entry is 128 bits:
2185 * [7:0] - interrupt source id
2186 * [31:8] - reserved
2187 * [59:32] - interrupt source data
2188 * [127:60] - reserved
2189 *
2190 * The basic interrupt vector entries
2191 * are decoded as follows:
2192 * src_id src_data description
2193 * 1 0 D1 Vblank
2194 * 1 1 D1 Vline
2195 * 5 0 D2 Vblank
2196 * 5 1 D2 Vline
2197 * 19 0 FP Hot plug detection A
2198 * 19 1 FP Hot plug detection B
2199 * 19 2 DAC A auto-detection
2200 * 19 3 DAC B auto-detection
2201 * 176 - CP_INT RB
2202 * 177 - CP_INT IB1
2203 * 178 - CP_INT IB2
2204 * 181 - EOP Interrupt
2205 * 233 - GUI Idle
2206 *
2207 * Note, these are based on r600 and may need to be
2208 * adjusted or added to on newer asics
2209 */
2210
2211int r600_irq_process(struct radeon_device *rdev)
2212{
2213 u32 wptr = r600_get_ih_wptr(rdev);
2214 u32 rptr = rdev->ih.rptr;
2215 u32 src_id, src_data;
2216 u32 last_entry = rdev->ih.ring_size - 16;
2217 u32 ring_index, disp_int;
2218 unsigned long flags;
2219
2220 DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
2221
2222 spin_lock_irqsave(&rdev->ih.lock, flags);
2223
2224 if (rptr == wptr) {
2225 spin_unlock_irqrestore(&rdev->ih.lock, flags);
2226 return IRQ_NONE;
2227 }
2228 if (rdev->shutdown) {
2229 spin_unlock_irqrestore(&rdev->ih.lock, flags);
2230 return IRQ_NONE;
2231 }
2232
2233restart_ih:
2234 /* display interrupts */
2235 if (ASIC_IS_DCE3(rdev))
2236 disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS);
2237 else
2238 disp_int = RREG32(DISP_INTERRUPT_STATUS);
2239 r600_irq_ack(rdev, disp_int);
2240
2241 rdev->ih.wptr = wptr;
2242 while (rptr != wptr) {
2243 /* wptr/rptr are in bytes! */
2244 ring_index = rptr / 4;
2245 src_id = rdev->ih.ring[ring_index] & 0xff;
2246 src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff;
2247
2248 switch (src_id) {
2249 case 1: /* D1 vblank/vline */
2250 switch (src_data) {
2251 case 0: /* D1 vblank */
2252 if (disp_int & LB_D1_VBLANK_INTERRUPT) {
2253 drm_handle_vblank(rdev->ddev, 0);
2254 disp_int &= ~LB_D1_VBLANK_INTERRUPT;
2255 DRM_DEBUG("IH: D1 vblank\n");
2256 }
2257 break;
2258 case 1: /* D1 vline */
2259 if (disp_int & LB_D1_VLINE_INTERRUPT) {
2260 disp_int &= ~LB_D1_VLINE_INTERRUPT;
2261 DRM_DEBUG("IH: D1 vline\n");
2262 }
2263 break;
2264 default:
2265 DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
2266 break;
2267 }
2268 break;
2269 case 5: /* D2 vblank/vline */
2270 switch (src_data) {
2271 case 0: /* D2 vblank */
2272 if (disp_int & LB_D2_VBLANK_INTERRUPT) {
2273 drm_handle_vblank(rdev->ddev, 1);
2274 disp_int &= ~LB_D2_VBLANK_INTERRUPT;
2275 DRM_DEBUG("IH: D2 vblank\n");
2276 }
2277 break;
2278 case 1: /* D1 vline */
2279 if (disp_int & LB_D2_VLINE_INTERRUPT) {
2280 disp_int &= ~LB_D2_VLINE_INTERRUPT;
2281 DRM_DEBUG("IH: D2 vline\n");
2282 }
2283 break;
2284 default:
2285 DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
2286 break;
2287 }
2288 break;
2289 case 176: /* CP_INT in ring buffer */
2290 case 177: /* CP_INT in IB1 */
2291 case 178: /* CP_INT in IB2 */
2292 DRM_DEBUG("IH: CP int: 0x%08x\n", src_data);
2293 radeon_fence_process(rdev);
2294 break;
2295 case 181: /* CP EOP event */
2296 DRM_DEBUG("IH: CP EOP\n");
2297 break;
2298 default:
2299 DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
2300 break;
2301 }
2302
2303 /* wptr/rptr are in bytes! */
2304 if (rptr == last_entry)
2305 rptr = 0;
2306 else
2307 rptr += 16;
2308 }
2309 /* make sure wptr hasn't changed while processing */
2310 wptr = r600_get_ih_wptr(rdev);
2311 if (wptr != rdev->ih.wptr)
2312 goto restart_ih;
2313 rdev->ih.rptr = rptr;
2314 WREG32(IH_RB_RPTR, rdev->ih.rptr);
2315 spin_unlock_irqrestore(&rdev->ih.lock, flags);
2316 return IRQ_HANDLED;
2317}
1811 2318
1812/* 2319/*
1813 * Debugfs info 2320 * Debugfs info
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index dbf716e1fbf3..c20909c34e8a 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -569,9 +569,9 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
569 ring_size = num_loops * dwords_per_loop; 569 ring_size = num_loops * dwords_per_loop;
570 /* set default + shaders */ 570 /* set default + shaders */
571 ring_size += 40; /* shaders + def state */ 571 ring_size += 40; /* shaders + def state */
572 ring_size += 3; /* fence emit for VB IB */ 572 ring_size += 5; /* fence emit for VB IB */
573 ring_size += 5; /* done copy */ 573 ring_size += 5; /* done copy */
574 ring_size += 3; /* fence emit for done copy */ 574 ring_size += 5; /* fence emit for done copy */
575 r = radeon_ring_lock(rdev, ring_size); 575 r = radeon_ring_lock(rdev, ring_size);
576 WARN_ON(r); 576 WARN_ON(r);
577 577
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index b7f4ce2270bc..61ccde5637d7 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -456,7 +456,163 @@
456#define WAIT_2D_IDLECLEAN_bit (1 << 16) 456#define WAIT_2D_IDLECLEAN_bit (1 << 16)
457#define WAIT_3D_IDLECLEAN_bit (1 << 17) 457#define WAIT_3D_IDLECLEAN_bit (1 << 17)
458 458
459 459#define IH_RB_CNTL 0x3e00
460# define IH_RB_ENABLE (1 << 0)
461# define IH_IB_SIZE(x) ((x) << 1) /* log2 */
462# define IH_RB_FULL_DRAIN_ENABLE (1 << 6)
463# define IH_WPTR_WRITEBACK_ENABLE (1 << 8)
464# define IH_WPTR_WRITEBACK_TIMER(x) ((x) << 9) /* log2 */
465# define IH_WPTR_OVERFLOW_ENABLE (1 << 16)
466# define IH_WPTR_OVERFLOW_CLEAR (1 << 31)
467#define IH_RB_BASE 0x3e04
468#define IH_RB_RPTR 0x3e08
469#define IH_RB_WPTR 0x3e0c
470# define RB_OVERFLOW (1 << 0)
471# define WPTR_OFFSET_MASK 0x3fffc
472#define IH_RB_WPTR_ADDR_HI 0x3e10
473#define IH_RB_WPTR_ADDR_LO 0x3e14
474#define IH_CNTL 0x3e18
475# define ENABLE_INTR (1 << 0)
476# define IH_MC_SWAP(x) ((x) << 2)
477# define IH_MC_SWAP_NONE 0
478# define IH_MC_SWAP_16BIT 1
479# define IH_MC_SWAP_32BIT 2
480# define IH_MC_SWAP_64BIT 3
481# define RPTR_REARM (1 << 4)
482# define MC_WRREQ_CREDIT(x) ((x) << 15)
483# define MC_WR_CLEAN_CNT(x) ((x) << 20)
484
485#define RLC_CNTL 0x3f00
486# define RLC_ENABLE (1 << 0)
487#define RLC_HB_BASE 0x3f10
488#define RLC_HB_CNTL 0x3f0c
489#define RLC_HB_RPTR 0x3f20
490#define RLC_HB_WPTR 0x3f1c
491#define RLC_HB_WPTR_LSB_ADDR 0x3f14
492#define RLC_HB_WPTR_MSB_ADDR 0x3f18
493#define RLC_MC_CNTL 0x3f44
494#define RLC_UCODE_CNTL 0x3f48
495#define RLC_UCODE_ADDR 0x3f2c
496#define RLC_UCODE_DATA 0x3f30
497
498#define SRBM_SOFT_RESET 0xe60
499# define SOFT_RESET_RLC (1 << 13)
500
501#define CP_INT_CNTL 0xc124
502# define CNTX_BUSY_INT_ENABLE (1 << 19)
503# define CNTX_EMPTY_INT_ENABLE (1 << 20)
504# define SCRATCH_INT_ENABLE (1 << 25)
505# define TIME_STAMP_INT_ENABLE (1 << 26)
506# define IB2_INT_ENABLE (1 << 29)
507# define IB1_INT_ENABLE (1 << 30)
508# define RB_INT_ENABLE (1 << 31)
509#define CP_INT_STATUS 0xc128
510# define SCRATCH_INT_STAT (1 << 25)
511# define TIME_STAMP_INT_STAT (1 << 26)
512# define IB2_INT_STAT (1 << 29)
513# define IB1_INT_STAT (1 << 30)
514# define RB_INT_STAT (1 << 31)
515
516#define GRBM_INT_CNTL 0x8060
517# define RDERR_INT_ENABLE (1 << 0)
518# define WAIT_COUNT_TIMEOUT_INT_ENABLE (1 << 1)
519# define GUI_IDLE_INT_ENABLE (1 << 19)
520
521#define INTERRUPT_CNTL 0x5468
522# define IH_DUMMY_RD_OVERRIDE (1 << 0)
523# define IH_DUMMY_RD_EN (1 << 1)
524# define IH_REQ_NONSNOOP_EN (1 << 3)
525# define GEN_IH_INT_EN (1 << 8)
526#define INTERRUPT_CNTL2 0x546c
527
528#define D1MODE_VBLANK_STATUS 0x6534
529#define D2MODE_VBLANK_STATUS 0x6d34
530# define DxMODE_VBLANK_OCCURRED (1 << 0)
531# define DxMODE_VBLANK_ACK (1 << 4)
532# define DxMODE_VBLANK_STAT (1 << 12)
533# define DxMODE_VBLANK_INTERRUPT (1 << 16)
534# define DxMODE_VBLANK_INTERRUPT_TYPE (1 << 17)
535#define D1MODE_VLINE_STATUS 0x653c
536#define D2MODE_VLINE_STATUS 0x6d3c
537# define DxMODE_VLINE_OCCURRED (1 << 0)
538# define DxMODE_VLINE_ACK (1 << 4)
539# define DxMODE_VLINE_STAT (1 << 12)
540# define DxMODE_VLINE_INTERRUPT (1 << 16)
541# define DxMODE_VLINE_INTERRUPT_TYPE (1 << 17)
542#define DxMODE_INT_MASK 0x6540
543# define D1MODE_VBLANK_INT_MASK (1 << 0)
544# define D1MODE_VLINE_INT_MASK (1 << 4)
545# define D2MODE_VBLANK_INT_MASK (1 << 8)
546# define D2MODE_VLINE_INT_MASK (1 << 12)
547#define DCE3_DISP_INTERRUPT_STATUS 0x7ddc
548# define DC_HPD1_INTERRUPT (1 << 18)
549# define DC_HPD2_INTERRUPT (1 << 19)
550#define DISP_INTERRUPT_STATUS 0x7edc
551# define LB_D1_VLINE_INTERRUPT (1 << 2)
552# define LB_D2_VLINE_INTERRUPT (1 << 3)
553# define LB_D1_VBLANK_INTERRUPT (1 << 4)
554# define LB_D2_VBLANK_INTERRUPT (1 << 5)
555# define DACA_AUTODETECT_INTERRUPT (1 << 16)
556# define DACB_AUTODETECT_INTERRUPT (1 << 17)
557# define DC_HOT_PLUG_DETECT1_INTERRUPT (1 << 18)
558# define DC_HOT_PLUG_DETECT2_INTERRUPT (1 << 19)
559# define DC_I2C_SW_DONE_INTERRUPT (1 << 20)
560# define DC_I2C_HW_DONE_INTERRUPT (1 << 21)
561#define DCE3_DISP_INTERRUPT_STATUS_CONTINUE 0x7de8
562# define DC_HPD4_INTERRUPT (1 << 14)
563# define DC_HPD4_RX_INTERRUPT (1 << 15)
564# define DC_HPD3_INTERRUPT (1 << 28)
565# define DC_HPD1_RX_INTERRUPT (1 << 29)
566# define DC_HPD2_RX_INTERRUPT (1 << 30)
567#define DCE3_DISP_INTERRUPT_STATUS_CONTINUE2 0x7dec
568# define DC_HPD3_RX_INTERRUPT (1 << 0)
569# define DIGA_DP_VID_STREAM_DISABLE_INTERRUPT (1 << 1)
570# define DIGA_DP_STEER_FIFO_OVERFLOW_INTERRUPT (1 << 2)
571# define DIGB_DP_VID_STREAM_DISABLE_INTERRUPT (1 << 3)
572# define DIGB_DP_STEER_FIFO_OVERFLOW_INTERRUPT (1 << 4)
573# define AUX1_SW_DONE_INTERRUPT (1 << 5)
574# define AUX1_LS_DONE_INTERRUPT (1 << 6)
575# define AUX2_SW_DONE_INTERRUPT (1 << 7)
576# define AUX2_LS_DONE_INTERRUPT (1 << 8)
577# define AUX3_SW_DONE_INTERRUPT (1 << 9)
578# define AUX3_LS_DONE_INTERRUPT (1 << 10)
579# define AUX4_SW_DONE_INTERRUPT (1 << 11)
580# define AUX4_LS_DONE_INTERRUPT (1 << 12)
581# define DIGA_DP_FAST_TRAINING_COMPLETE_INTERRUPT (1 << 13)
582# define DIGB_DP_FAST_TRAINING_COMPLETE_INTERRUPT (1 << 14)
583/* DCE 3.2 */
584# define AUX5_SW_DONE_INTERRUPT (1 << 15)
585# define AUX5_LS_DONE_INTERRUPT (1 << 16)
586# define AUX6_SW_DONE_INTERRUPT (1 << 17)
587# define AUX6_LS_DONE_INTERRUPT (1 << 18)
588# define DC_HPD5_INTERRUPT (1 << 19)
589# define DC_HPD5_RX_INTERRUPT (1 << 20)
590# define DC_HPD6_INTERRUPT (1 << 21)
591# define DC_HPD6_RX_INTERRUPT (1 << 22)
592
593#define DCE3_DACA_AUTODETECT_INT_CONTROL 0x7038
594#define DCE3_DACB_AUTODETECT_INT_CONTROL 0x7138
595#define DACA_AUTODETECT_INT_CONTROL 0x7838
596#define DACB_AUTODETECT_INT_CONTROL 0x7a38
597# define DACx_AUTODETECT_ACK (1 << 0)
598# define DACx_AUTODETECT_INT_ENABLE (1 << 16)
599
600#define DC_HOT_PLUG_DETECT1_INT_CONTROL 0x7d08
601#define DC_HOT_PLUG_DETECT2_INT_CONTROL 0x7d18
602#define DC_HOT_PLUG_DETECT3_INT_CONTROL 0x7d2c
603# define DC_HOT_PLUG_DETECTx_INT_ACK (1 << 0)
604# define DC_HOT_PLUG_DETECTx_INT_POLARITY (1 << 8)
605# define DC_HOT_PLUG_DETECTx_INT_EN (1 << 16)
606/* DCE 3.2 */
607#define DC_HPD1_INT_CONTROL 0x7d04
608#define DC_HPD2_INT_CONTROL 0x7d10
609#define DC_HPD3_INT_CONTROL 0x7d1c
610#define DC_HPD4_INT_CONTROL 0x7d28
611# define DC_HPDx_INT_ACK (1 << 0)
612# define DC_HPDx_INT_POLARITY (1 << 8)
613# define DC_HPDx_INT_EN (1 << 16)
614# define DC_HPDx_RX_INT_ACK (1 << 20)
615# define DC_HPDx_RX_INT_EN (1 << 24)
460 616
461/* 617/*
462 * PM4 618 * PM4
@@ -500,7 +656,6 @@
500#define PACKET3_WAIT_REG_MEM 0x3C 656#define PACKET3_WAIT_REG_MEM 0x3C
501#define PACKET3_MEM_WRITE 0x3D 657#define PACKET3_MEM_WRITE 0x3D
502#define PACKET3_INDIRECT_BUFFER 0x32 658#define PACKET3_INDIRECT_BUFFER 0x32
503#define PACKET3_CP_INTERRUPT 0x40
504#define PACKET3_SURFACE_SYNC 0x43 659#define PACKET3_SURFACE_SYNC 0x43
505# define PACKET3_CB0_DEST_BASE_ENA (1 << 6) 660# define PACKET3_CB0_DEST_BASE_ENA (1 << 6)
506# define PACKET3_TC_ACTION_ENA (1 << 23) 661# define PACKET3_TC_ACTION_ENA (1 << 23)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 15b9e03bb589..0b8dad604ad8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -399,6 +399,23 @@ struct radeon_cp {
399 bool ready; 399 bool ready;
400}; 400};
401 401
402/*
403 * R6xx+ IH ring
404 */
405struct r600_ih {
406 struct radeon_object *ring_obj;
407 volatile uint32_t *ring;
408 unsigned rptr;
409 unsigned wptr;
410 unsigned wptr_old;
411 unsigned ring_size;
412 uint64_t gpu_addr;
413 uint32_t align_mask;
414 uint32_t ptr_mask;
415 spinlock_t lock;
416 bool enabled;
417};
418
402struct r600_blit { 419struct r600_blit {
403 struct radeon_object *shader_obj; 420 struct radeon_object *shader_obj;
404 u64 shader_gpu_addr; 421 u64 shader_gpu_addr;
@@ -792,8 +809,10 @@ struct radeon_device {
792 struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES]; 809 struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
793 const struct firmware *me_fw; /* all family ME firmware */ 810 const struct firmware *me_fw; /* all family ME firmware */
794 const struct firmware *pfp_fw; /* r6/700 PFP firmware */ 811 const struct firmware *pfp_fw; /* r6/700 PFP firmware */
812 const struct firmware *rlc_fw; /* r6/700 RLC firmware */
795 struct r600_blit r600_blit; 813 struct r600_blit r600_blit;
796 int msi_enabled; /* msi enabled */ 814 int msi_enabled; /* msi enabled */
815 struct r600_ih ih; /* r6/700 interrupt ring */
797}; 816};
798 817
799int radeon_device_init(struct radeon_device *rdev, 818int radeon_device_init(struct radeon_device *rdev,
@@ -1108,7 +1127,12 @@ extern void r600_wb_disable(struct radeon_device *rdev);
1108extern void r600_scratch_init(struct radeon_device *rdev); 1127extern void r600_scratch_init(struct radeon_device *rdev);
1109extern int r600_blit_init(struct radeon_device *rdev); 1128extern int r600_blit_init(struct radeon_device *rdev);
1110extern void r600_blit_fini(struct radeon_device *rdev); 1129extern void r600_blit_fini(struct radeon_device *rdev);
1111extern int r600_cp_init_microcode(struct radeon_device *rdev); 1130extern int r600_init_microcode(struct radeon_device *rdev);
1112extern int r600_gpu_reset(struct radeon_device *rdev); 1131extern int r600_gpu_reset(struct radeon_device *rdev);
1132/* r600 irq */
1133extern int r600_irq_init(struct radeon_device *rdev);
1134extern void r600_irq_fini(struct radeon_device *rdev);
1135extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size);
1136extern int r600_irq_set(struct radeon_device *rdev);
1113 1137
1114#endif 1138#endif
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index c7a7f84fe3ec..755f50555c3d 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -480,6 +480,7 @@ static struct radeon_asic r600_asic = {
480 .ring_ib_execute = &r600_ring_ib_execute, 480 .ring_ib_execute = &r600_ring_ib_execute,
481 .irq_set = &r600_irq_set, 481 .irq_set = &r600_irq_set,
482 .irq_process = &r600_irq_process, 482 .irq_process = &r600_irq_process,
483 .get_vblank_counter = &rs600_get_vblank_counter,
483 .fence_ring_emit = &r600_fence_ring_emit, 484 .fence_ring_emit = &r600_fence_ring_emit,
484 .cs_parse = &r600_cs_parse, 485 .cs_parse = &r600_cs_parse,
485 .copy_blit = &r600_copy_blit, 486 .copy_blit = &r600_copy_blit,
@@ -520,6 +521,7 @@ static struct radeon_asic rv770_asic = {
520 .ring_ib_execute = &r600_ring_ib_execute, 521 .ring_ib_execute = &r600_ring_ib_execute,
521 .irq_set = &r600_irq_set, 522 .irq_set = &r600_irq_set,
522 .irq_process = &r600_irq_process, 523 .irq_process = &r600_irq_process,
524 .get_vblank_counter = &rs600_get_vblank_counter,
523 .fence_ring_emit = &r600_fence_ring_emit, 525 .fence_ring_emit = &r600_fence_ring_emit,
524 .cs_parse = &r600_cs_parse, 526 .cs_parse = &r600_cs_parse,
525 .copy_blit = &r600_copy_blit, 527 .copy_blit = &r600_copy_blit,
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index c43a690aedc6..c962f34c92af 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -562,6 +562,8 @@ int radeon_device_init(struct radeon_device *rdev,
562 mutex_init(&rdev->cs_mutex); 562 mutex_init(&rdev->cs_mutex);
563 mutex_init(&rdev->ib_pool.mutex); 563 mutex_init(&rdev->ib_pool.mutex);
564 mutex_init(&rdev->cp.mutex); 564 mutex_init(&rdev->cp.mutex);
565 if (rdev->family >= CHIP_R600)
566 spin_lock_init(&rdev->ih.lock);
565 rwlock_init(&rdev->fence_drv.lock); 567 rwlock_init(&rdev->fence_drv.lock);
566 INIT_LIST_HEAD(&rdev->gem.objects); 568 INIT_LIST_HEAD(&rdev->gem.objects);
567 569
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index 350962e0f346..e13785282a82 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -1104,7 +1104,6 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
1104# define R600_IT_WAIT_REG_MEM 0x00003C00 1104# define R600_IT_WAIT_REG_MEM 0x00003C00
1105# define R600_IT_MEM_WRITE 0x00003D00 1105# define R600_IT_MEM_WRITE 0x00003D00
1106# define R600_IT_INDIRECT_BUFFER 0x00003200 1106# define R600_IT_INDIRECT_BUFFER 0x00003200
1107# define R600_IT_CP_INTERRUPT 0x00004000
1108# define R600_IT_SURFACE_SYNC 0x00004300 1107# define R600_IT_SURFACE_SYNC 0x00004300
1109# define R600_CB0_DEST_BASE_ENA (1 << 6) 1108# define R600_CB0_DEST_BASE_ENA (1 << 6)
1110# define R600_TC_ACTION_ENA (1 << 23) 1109# define R600_TC_ACTION_ENA (1 << 23)
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 3beb26d74719..ab2a8b16836c 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -168,37 +168,6 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
168 return signaled; 168 return signaled;
169} 169}
170 170
171int r600_fence_wait(struct radeon_fence *fence, bool intr, bool lazy)
172{
173 struct radeon_device *rdev;
174 int ret = 0;
175
176 rdev = fence->rdev;
177
178 __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
179
180 while (1) {
181 if (radeon_fence_signaled(fence))
182 break;
183
184 if (time_after_eq(jiffies, fence->timeout)) {
185 ret = -EBUSY;
186 break;
187 }
188
189 if (lazy)
190 schedule_timeout(1);
191
192 if (intr && signal_pending(current)) {
193 ret = -ERESTARTSYS;
194 break;
195 }
196 }
197 __set_current_state(TASK_RUNNING);
198 return ret;
199}
200
201
202int radeon_fence_wait(struct radeon_fence *fence, bool intr) 171int radeon_fence_wait(struct radeon_fence *fence, bool intr)
203{ 172{
204 struct radeon_device *rdev; 173 struct radeon_device *rdev;
@@ -216,13 +185,6 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
216 return 0; 185 return 0;
217 } 186 }
218 187
219 if (rdev->family >= CHIP_R600) {
220 r = r600_fence_wait(fence, intr, 0);
221 if (r == -ERESTARTSYS)
222 return -EBUSY;
223 return r;
224 }
225
226retry: 188retry:
227 cur_jiffies = jiffies; 189 cur_jiffies = jiffies;
228 timeout = HZ / 100; 190 timeout = HZ / 100;
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index a0fe6232dcb6..84f8a6fb0da3 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -94,10 +94,18 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
94 } 94 }
95 /* enable msi */ 95 /* enable msi */
96 rdev->msi_enabled = 0; 96 rdev->msi_enabled = 0;
97 if (rdev->family >= CHIP_RV380) { 97 /* MSIs don't seem to work on my rs780;
98 * not sure about rs880 or other rs780s.
99 * Needs more investigation.
100 */
101 if ((rdev->family >= CHIP_RV380) &&
102 (rdev->family != CHIP_RS780) &&
103 (rdev->family != CHIP_RS880)) {
98 int ret = pci_enable_msi(rdev->pdev); 104 int ret = pci_enable_msi(rdev->pdev);
99 if (!ret) 105 if (!ret) {
100 rdev->msi_enabled = 1; 106 rdev->msi_enabled = 1;
107 DRM_INFO("radeon: using MSI.\n");
108 }
101 } 109 }
102 drm_irq_install(rdev->ddev); 110 drm_irq_install(rdev->ddev);
103 rdev->irq.installed = true; 111 rdev->irq.installed = true;
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index f54628475456..479684bda7e2 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -887,6 +887,16 @@ static int rv770_startup(struct radeon_device *rdev)
887 return r; 887 return r;
888 } 888 }
889 889
890 /* Enable IRQ */
891 rdev->irq.sw_int = true;
892 r = r600_irq_init(rdev);
893 if (r) {
894 DRM_ERROR("radeon: IH init failed (%d).\n", r);
895 radeon_irq_kms_fini(rdev);
896 return r;
897 }
898 r600_irq_set(rdev);
899
890 r = radeon_ring_init(rdev, rdev->cp.ring_size); 900 r = radeon_ring_init(rdev, rdev->cp.ring_size);
891 if (r) 901 if (r)
892 return r; 902 return r;
@@ -1005,11 +1015,19 @@ int rv770_init(struct radeon_device *rdev)
1005 r = radeon_object_init(rdev); 1015 r = radeon_object_init(rdev);
1006 if (r) 1016 if (r)
1007 return r; 1017 return r;
1018
1019 r = radeon_irq_kms_init(rdev);
1020 if (r)
1021 return r;
1022
1008 rdev->cp.ring_obj = NULL; 1023 rdev->cp.ring_obj = NULL;
1009 r600_ring_init(rdev, 1024 * 1024); 1024 r600_ring_init(rdev, 1024 * 1024);
1010 1025
1011 if (!rdev->me_fw || !rdev->pfp_fw) { 1026 rdev->ih.ring_obj = NULL;
1012 r = r600_cp_init_microcode(rdev); 1027 r600_ih_ring_init(rdev, 64 * 1024);
1028
1029 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
1030 r = r600_init_microcode(rdev);
1013 if (r) { 1031 if (r) {
1014 DRM_ERROR("Failed to load firmware!\n"); 1032 DRM_ERROR("Failed to load firmware!\n");
1015 return r; 1033 return r;
@@ -1055,6 +1073,8 @@ void rv770_fini(struct radeon_device *rdev)
1055 rv770_suspend(rdev); 1073 rv770_suspend(rdev);
1056 1074
1057 r600_blit_fini(rdev); 1075 r600_blit_fini(rdev);
1076 r600_irq_fini(rdev);
1077 radeon_irq_kms_fini(rdev);
1058 radeon_ring_fini(rdev); 1078 radeon_ring_fini(rdev);
1059 r600_wb_fini(rdev); 1079 r600_wb_fini(rdev);
1060 rv770_pcie_gart_fini(rdev); 1080 rv770_pcie_gart_fini(rdev);