X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fwinsys%2Fr600%2Fdrm%2Fr600_drm.c;h=311324f4f7135c2c3c00cf9b239fdd134cbbb847;hb=d79a4a612bae66581caf21a74bd745ec51a18e80;hp=c9de95ffc027fea1bfb1f945db79f5defa05b7d2;hpb=cd6a31cd4a9ea6deef4778c2eaef2d47240c3a6e;p=mesa.git diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c index c9de95ffc02..311324f4f71 100644 --- a/src/gallium/winsys/r600/drm/r600_drm.c +++ b/src/gallium/winsys/r600/drm/r600_drm.c @@ -30,6 +30,7 @@ #include #include "util/u_inlines.h" #include "util/u_debug.h" +#include "util/u_hash_table.h" #include #include "r600.h" #include "r600_priv.h" @@ -40,9 +41,49 @@ #ifndef RADEON_INFO_TILING_CONFIG #define RADEON_INFO_TILING_CONFIG 0x6 #endif + +#ifndef RADEON_INFO_CLOCK_CRYSTAL_FREQ +#define RADEON_INFO_CLOCK_CRYSTAL_FREQ 0x9 +#endif + +#ifndef RADEON_INFO_NUM_BACKENDS +#define RADEON_INFO_NUM_BACKENDS 0xa +#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->clock_crystal_freq; +} + +unsigned r600_get_num_backends(struct radeon *radeon) +{ + return radeon->num_backends; +} + +unsigned r600_get_minor_version(struct radeon *radeon) +{ + return radeon->minor_version; +} + + static int radeon_get_device(struct radeon *radeon) { - struct drm_radeon_info info; + struct drm_radeon_info info = {}; int r; radeon->device = 0; @@ -53,20 +94,8 @@ static int radeon_get_device(struct radeon *radeon) return r; } -static int radeon_drm_get_tiling(struct radeon *radeon) +static int r600_interpret_tiling(struct radeon *radeon, uint32_t tiling_config) { - struct drm_radeon_info info; - int r; - uint32_t tiling_config; - - info.request = RADEON_INFO_TILING_CONFIG; - info.value = (uintptr_t)&tiling_config; - r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info, - sizeof(struct drm_radeon_info)); - - if (r) - return r; - switch ((tiling_config & 0xe) >> 1) { case 0: radeon->tiling_info.num_channels = 1; @@ -108,10 +137,127 @@ static int radeon_drm_get_tiling(struct radeon *radeon) return 0; } -struct radeon *radeon_new(int fd, unsigned device) +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; + } + + radeon->tiling_info.num_banks = (tiling_config & 0xf0) >> 4; + + 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; +} + +static int radeon_drm_get_tiling(struct radeon *radeon) +{ + struct drm_radeon_info info; + int r; + uint32_t tiling_config = 0; + + info.request = RADEON_INFO_TILING_CONFIG; + info.value = (uintptr_t)&tiling_config; + r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info, + sizeof(struct drm_radeon_info)); + + if (r) + return 0; + + if (radeon->chip_class == R600 || radeon->chip_class == R700) { + r = r600_interpret_tiling(radeon, tiling_config); + } else { + r = eg_interpret_tiling(radeon, tiling_config); + } + return r; +} + +static int radeon_get_clock_crystal_freq(struct radeon *radeon) +{ + struct drm_radeon_info info; + uint32_t clock_crystal_freq; + int r; + + info.request = RADEON_INFO_CLOCK_CRYSTAL_FREQ; + info.value = (uintptr_t)&clock_crystal_freq; + r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info, + sizeof(struct drm_radeon_info)); + if (r) + return r; + + radeon->clock_crystal_freq = clock_crystal_freq; + return 0; +} + + +static int radeon_get_num_backends(struct radeon *radeon) +{ + struct drm_radeon_info info; + uint32_t num_backends; + int r; + + info.request = RADEON_INFO_NUM_BACKENDS; + info.value = (uintptr_t)&num_backends; + r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info, + sizeof(struct drm_radeon_info)); + if (r) + return r; + + radeon->num_backends = num_backends; + return 0; +} + + +static int radeon_init_fence(struct radeon *radeon) +{ + radeon->fence = 1; + radeon->fence_bo = r600_bo(radeon, 4096, 0, 0, 0); + if (radeon->fence_bo == NULL) { + return -ENOMEM; + } + radeon->cfence = r600_bo_map(radeon, radeon->fence_bo, PB_USAGE_UNSYNCHRONIZED, NULL); + *radeon->cfence = 0; + return 0; +} + +#define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x))) + +static unsigned handle_hash(void *key) +{ + return PTR_TO_UINT(key); +} + +static int handle_compare(void *key1, void *key2) +{ + return PTR_TO_UINT(key1) != PTR_TO_UINT(key2); +} + +static struct radeon *radeon_new(int fd, unsigned device) { struct radeon *radeon; int r; + drmVersionPtr version; radeon = calloc(1, sizeof(*radeon)); if (radeon == NULL) { @@ -120,70 +266,32 @@ struct radeon *radeon_new(int fd, unsigned device) radeon->fd = fd; radeon->device = device; radeon->refcount = 1; - if (fd >= 0) { - r = radeon_get_device(radeon); - if (r) { - fprintf(stderr, "Failed to get device id\n"); - return radeon_decref(radeon); - } + + version = drmGetVersion(radeon->fd); + if (version->version_major != 2) { + fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is " + "only compatible with 2.x.x\n", __FUNCTION__, + version->version_major, version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + exit(1); + } + + radeon->minor_version = version->version_minor; + + drmFreeVersion(version); + + r = radeon_get_device(radeon); + if (r) { + fprintf(stderr, "Failed to get device id\n"); + return radeon_decref(radeon); } + radeon->family = radeon_family_from_device(radeon->device); if (radeon->family == CHIP_UNKNOWN) { fprintf(stderr, "Unknown chipset 0x%04X\n", radeon->device); return radeon_decref(radeon); } - 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: - case CHIP_RV770: - case CHIP_RV730: - case CHIP_RV710: - case CHIP_RV740: - case CHIP_CEDAR: - case CHIP_REDWOOD: - case CHIP_JUNIPER: - case CHIP_CYPRESS: - case CHIP_HEMLOCK: - break; - case CHIP_R100: - case CHIP_RV100: - case CHIP_RS100: - case CHIP_RV200: - case CHIP_RS200: - case CHIP_R200: - case CHIP_RV250: - case CHIP_RS300: - case CHIP_RV280: - case CHIP_R300: - case CHIP_R350: - case CHIP_RV350: - case CHIP_RV380: - case CHIP_R420: - case CHIP_R423: - case CHIP_RV410: - case CHIP_RS400: - case CHIP_RS480: - case CHIP_RS600: - case CHIP_RS690: - case CHIP_RS740: - case CHIP_RV515: - case CHIP_R520: - case CHIP_RV530: - case CHIP_RV560: - case CHIP_RV570: - case CHIP_R580: - default: - fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n", - __func__, radeon->device); - break; - } - /* setup class */ switch (radeon->family) { case CHIP_R600: @@ -195,19 +303,29 @@ struct radeon *radeon_new(int fd, unsigned device) 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_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; default: fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n", @@ -215,16 +333,27 @@ struct radeon *radeon_new(int fd, unsigned device) break; } - if (radeon->chip_class == R600 || radeon->chip_class == R700) { - if (radeon_drm_get_tiling(radeon)) - return NULL; - } - radeon->kman = radeon_bo_pbmgr_create(radeon); - if (!radeon->kman) + if (radeon_drm_get_tiling(radeon)) + return NULL; + + /* get the GPU counter frequency, failure is non fatal */ + radeon_get_clock_crystal_freq(radeon); + + if (radeon->minor_version >= 9) + radeon_get_num_backends(radeon); + + radeon->bomgr = r600_bomgr_create(radeon, 1000000); + if (radeon->bomgr == NULL) { return NULL; - radeon->cman = pb_cache_manager_create(radeon->kman, 100000); - if (!radeon->cman) + } + r = radeon_init_fence(radeon); + if (r) { + radeon_decref(radeon); return NULL; + } + + radeon->bo_handles = util_hash_table_create(handle_hash, handle_compare); + pipe_mutex_init(radeon->bo_handles_mutex); return radeon; } @@ -241,14 +370,14 @@ struct radeon *radeon_decref(struct radeon *radeon) return NULL; } - if (radeon->cman) - radeon->cman->destroy(radeon->cman); - - if (radeon->kman) - radeon->kman->destroy(radeon->kman); + util_hash_table_destroy(radeon->bo_handles); + pipe_mutex_destroy(radeon->bo_handles_mutex); + if (radeon->fence_bo) { + r600_bo_reference(radeon, &radeon->fence_bo, NULL); + } - if (radeon->fd >= 0) - drmClose(radeon->fd); + if (radeon->bomgr) + r600_bomgr_destroy(radeon->bomgr); free(radeon); return NULL;