* 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;
}