r600g: enable thread offloading
[mesa.git] / src / gallium / winsys / r600 / drm / r600_drm.c
index 469f1446d051af86e87c5694fea4df301bb72c5d..7d5583fd287d2aadacc1b91ee0b21fad0892897d 100644 (file)
  *      Corbin Simpson <MostAwesomeDude@gmail.com>
  *      Joakim Sindholt <opensource@zhasha.com>
  */
-#include <sys/ioctl.h>
-#include "util/u_inlines.h"
-#include "util/u_debug.h"
-#include "radeon_priv.h"
-#include "r600_screen.h"
-#include "r600_texture.h"
-#include "r600_public.h"
+
+#include "r600_priv.h"
 #include "r600_drm_public.h"
-#include "state_tracker/drm_driver.h"
+#include "util/u_memory.h"
+#include <errno.h>
+
+#ifndef RADEON_INFO_NUM_TILE_PIPES
+#define RADEON_INFO_NUM_TILE_PIPES 0xb
+#endif
+
+#ifndef RADEON_INFO_BACKEND_MAP
+#define RADEON_INFO_BACKEND_MAP 0xd
+#endif
+
+enum radeon_family r600_get_family(struct radeon *r600)
+{
+       return r600->family;
+}
+
+enum chip_class r600_get_family_class(struct radeon *radeon)
+{
+       return radeon->chip_class;
+}
+
+struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon)
+{
+       return &radeon->tiling_info;
+}
+
+unsigned r600_get_clock_crystal_freq(struct radeon *radeon)
+{
+       return radeon->info.r600_clock_crystal_freq;
+}
+
+unsigned r600_get_num_backends(struct radeon *radeon)
+{
+       return radeon->info.r600_num_backends;
+}
+
+unsigned r600_get_num_tile_pipes(struct radeon *radeon)
+{
+       return radeon->info.r600_num_tile_pipes;
+}
+
+unsigned r600_get_backend_map(struct radeon *radeon)
+{
+       return radeon->info.r600_backend_map;
+}
+
+unsigned r600_get_minor_version(struct radeon *radeon)
+{
+       return radeon->info.drm_minor;
+}
+
+static int r600_interpret_tiling(struct radeon *radeon, uint32_t tiling_config)
+{
+       switch ((tiling_config & 0xe) >> 1) {
+       case 0:
+               radeon->tiling_info.num_channels = 1;
+               break;
+       case 1:
+               radeon->tiling_info.num_channels = 2;
+               break;
+       case 2:
+               radeon->tiling_info.num_channels = 4;
+               break;
+       case 3:
+               radeon->tiling_info.num_channels = 8;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch ((tiling_config & 0x30) >> 4) {
+       case 0:
+               radeon->tiling_info.num_banks = 4;
+               break;
+       case 1:
+               radeon->tiling_info.num_banks = 8;
+               break;
+       default:
+               return -EINVAL;
+
+       }
+       switch ((tiling_config & 0xc0) >> 6) {
+       case 0:
+               radeon->tiling_info.group_bytes = 256;
+               break;
+       case 1:
+               radeon->tiling_info.group_bytes = 512;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int eg_interpret_tiling(struct radeon *radeon, uint32_t tiling_config)
+{
+       switch (tiling_config & 0xf) {
+       case 0:
+               radeon->tiling_info.num_channels = 1;
+               break;
+       case 1:
+               radeon->tiling_info.num_channels = 2;
+               break;
+       case 2:
+               radeon->tiling_info.num_channels = 4;
+               break;
+       case 3:
+               radeon->tiling_info.num_channels = 8;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch ((tiling_config & 0xf0) >> 4) {
+       case 0:
+               radeon->tiling_info.num_banks = 4;
+               break;
+       case 1:
+               radeon->tiling_info.num_banks = 8;
+               break;
+       case 2:
+               radeon->tiling_info.num_banks = 16;
+               break;
+       default:
+               return -EINVAL;
+
+       }
+
+       switch ((tiling_config & 0xf00) >> 8) {
+       case 0:
+               radeon->tiling_info.group_bytes = 256;
+               break;
+       case 1:
+               radeon->tiling_info.group_bytes = 512;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
 
-struct radeon *r600_drm_winsys_create(int drmfd)
+static int radeon_drm_get_tiling(struct radeon *radeon)
 {
-       return radeon_new(drmfd, 0);
+       uint32_t tiling_config = radeon->info.r600_tiling_config;
+
+       if (!tiling_config)
+               return 0;
+
+       if (radeon->chip_class == R600 || radeon->chip_class == R700) {
+               return r600_interpret_tiling(radeon, tiling_config);
+       } else {
+               return eg_interpret_tiling(radeon, tiling_config);
+       }
 }
 
-boolean r600_buffer_get_handle(struct radeon *rw,
-                              struct pipe_resource *buf,
-                              struct winsys_handle *whandle)
+struct radeon *radeon_create(struct radeon_winsys *ws)
 {
-       struct drm_gem_flink flink;
-       struct r600_buffer* rbuffer;
-       int r;
+       struct radeon *radeon = CALLOC_STRUCT(radeon);
+       if (radeon == NULL) {
+               return NULL;
+       }
+
+       radeon->ws = ws;
+       ws->query_info(ws, &radeon->info);
 
-       rbuffer = (struct r600_buffer*)buf;
-       if (!rbuffer->flink) {
-               flink.handle = rbuffer->bo->handle;
-               r = ioctl(rw->fd, DRM_IOCTL_GEM_FLINK, &flink);
-               if (r) {
-                       return FALSE;
-               }
-               rbuffer->flink = flink.name;
+       radeon->family = radeon_family_from_device(radeon->info.pci_id);
+       if (radeon->family == CHIP_UNKNOWN) {
+               fprintf(stderr, "Unknown chipset 0x%04X\n", radeon->info.pci_id);
+               return radeon_destroy(radeon);
        }
-       whandle->handle = rbuffer->flink;
-       return TRUE;
+       /* setup class */
+       switch (radeon->family) {
+       case CHIP_R600:
+       case CHIP_RV610:
+       case CHIP_RV630:
+       case CHIP_RV670:
+       case CHIP_RV620:
+       case CHIP_RV635:
+       case CHIP_RS780:
+       case CHIP_RS880:
+               radeon->chip_class = R600;
+               /* set default group bytes, overridden by tiling info ioctl */
+               radeon->tiling_info.group_bytes = 256;
+               break;
+       case CHIP_RV770:
+       case CHIP_RV730:
+       case CHIP_RV710:
+       case CHIP_RV740:
+               radeon->chip_class = R700;
+               /* set default group bytes, overridden by tiling info ioctl */
+               radeon->tiling_info.group_bytes = 256;
+               break;
+       case CHIP_CEDAR:
+       case CHIP_REDWOOD:
+       case CHIP_JUNIPER:
+       case CHIP_CYPRESS:
+       case CHIP_HEMLOCK:
+       case CHIP_PALM:
+       case CHIP_SUMO:
+       case CHIP_SUMO2:
+       case CHIP_BARTS:
+       case CHIP_TURKS:
+       case CHIP_CAICOS:
+               radeon->chip_class = EVERGREEN;
+               /* set default group bytes, overridden by tiling info ioctl */
+               radeon->tiling_info.group_bytes = 512;
+               break;
+       case CHIP_CAYMAN:
+               radeon->chip_class = CAYMAN;
+               /* set default group bytes, overridden by tiling info ioctl */
+               radeon->tiling_info.group_bytes = 512;
+               break;
+       default:
+               fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",
+                       __func__, radeon->info.pci_id);
+               break;
+       }
+
+       if (radeon_drm_get_tiling(radeon))
+               return NULL;
+
+       return radeon;
+}
+
+struct radeon *radeon_destroy(struct radeon *radeon)
+{
+       if (radeon == NULL)
+               return NULL;
+
+       FREE(radeon);
+       return NULL;
 }