Skip to content

Commit

Permalink
revert kgsl changes
Browse files Browse the repository at this point in the history
might have to start over again, pain
  • Loading branch information
SolDev69 committed Nov 29, 2023
1 parent 45d6be5 commit daa0ed8
Showing 1 changed file with 9 additions and 279 deletions.
288 changes: 9 additions & 279 deletions src/gallium/drivers/freedreno/freedreno_screen.c
Original file line number Diff line number Diff line change
@@ -1,273 +1,3 @@
// kgsl_pipe.c
#include "freedreno/drm/kgsl/kgsl_priv.h"
#include "freedreno/drm/freedreno_ringbuffer_sp.h"

/* TODO this function is borrowed from turnip, can it be shared in some way? */
int
kgsl_pipe_safe_ioctl(int fd, unsigned long request, void *arg)
{
int ret;

do {
ret = ioctl(fd, request, arg);
} while (ret == -1 && (errno == EINTR || errno == EAGAIN));

return ret;
}

/* TODO this function is borrowed from turnip, can it be shared in some way?
* safe_ioctl is not enough as restarted waits would not adjust the timeout
* which could lead to waiting substantially longer than requested
*/
static int
wait_timestamp_safe(int fd,
unsigned int context_id,
unsigned int timestamp,
int64_t timeout_ms)
{
int64_t start_time = os_time_get_nano();
struct kgsl_device_waittimestamp_ctxtid wait = {
.context_id = context_id,
.timestamp = timestamp,
.timeout = timeout_ms,
};

while (true) {
int ret = kgsl_pipe_safe_ioctl(fd, IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID, &wait);

if (ret == -1 && (errno == EINTR || errno == EAGAIN)) {
int64_t current_time = os_time_get_nano();

/* update timeout to consider time that has passed since the start */
timeout_ms -= (current_time - start_time) / 1000000;
if (timeout_ms <= 0) {
errno = ETIME;
return -1;
}

wait.timeout = (unsigned int) timeout_ms;
start_time = current_time;
} else {
return ret;
}
}
}

int
kgsl_get_prop(int fd, unsigned int type, void *value, size_t size)
{
struct kgsl_device_getproperty getprop = {
.type = type,
.value = value,
.sizebytes = size,
};

return kgsl_pipe_safe_ioctl(fd, IOCTL_KGSL_DEVICE_GETPROPERTY, &getprop);
}

static int
kgsl_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param,
uint64_t *value)
{
struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(pipe);
switch (param) {
case FD_DEVICE_ID:
case FD_GPU_ID:
*value = kgsl_pipe->dev_id.gpu_id;
return 0;
case FD_GMEM_SIZE:
*value = kgsl_pipe->gmem_size;
return 0;
case FD_GMEM_BASE:
*value = kgsl_pipe->gmem_base;
return 0;
case FD_CHIP_ID:
*value = kgsl_pipe->dev_id.chip_id;
return 0;
case FD_NR_PRIORITIES:
/* Take from kgsl kmd source code, if device is a4xx or newer
* it has KGSL_PRIORITY_MAX_RB_LEVELS=4 priorities otherwise it just has one.
* https://android.googlesource.com/kernel/msm/+/refs/tags/android-13.0.0_r0.21/drivers/gpu/msm/kgsl.h#56
*/
*value = kgsl_pipe->dev_id.gpu_id >= 400 ? 4 : 1;
return 0;
case FD_MAX_FREQ:
/* Explicity fault on MAX_FREQ as we don't have a way to convert
* timestamp values from KGSL into time values. If we use the default
* path an error message would be generated when this is simply an
* unsupported feature.
*/
return -1;
default:
ERROR_MSG("invalid param id: %d", param);
return -1;
}
}

static int
kgsl_pipe_set_param(struct fd_pipe *pipe, uint32_t param, uint64_t value)
{
ERROR_MSG("kgsl_pipe_set_param not implemented");
return -1;
}

static int
kgsl_pipe_wait(struct fd_pipe *pipe, const struct fd_fence *fence, uint64_t timeout)
{
struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(pipe);
return wait_timestamp_safe(pipe->dev->fd, kgsl_pipe->queue_id, fence->kfence, timeout);
}

static void
kgsl_pipe_destroy(struct fd_pipe *pipe)
{
struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(pipe);
struct kgsl_drawctxt_destroy req = {
.drawctxt_id = kgsl_pipe->queue_id,
};

fd_pipe_sp_ringpool_fini(pipe);
kgsl_pipe_safe_ioctl(pipe->dev->fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &req);
free(kgsl_pipe);
}

static int
kgsl_reset_status(struct fd_pipe *pipe, enum fd_reset_status *status)
{
struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(pipe);
uint32_t value = kgsl_pipe->queue_id;
int ret = kgsl_get_prop(pipe->dev->fd, KGSL_PROP_GPU_RESET_STAT, &value, sizeof(value));

if (!ret) {
switch (value) {
case KGSL_CTX_STAT_NO_ERROR:
*status = FD_RESET_NO_ERROR;
break;
case KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT:
*status = FD_RESET_GUILTY;
break;
case KGSL_CTX_STAT_INNOCENT_CONTEXT_RESET_EXT:
*status = FD_RESET_INNOCENT;
break;
case KGSL_CTX_STAT_UNKNOWN_CONTEXT_RESET_EXT:
default:
*status = FD_RESET_UNKNOWN;
break;
}
}

return ret;
}

static const struct fd_pipe_funcs pipe_funcs = {
.ringbuffer_new_object = fd_ringbuffer_sp_new_object,
.submit_new = kgsl_submit_sp_new,
.reset_status = kgsl_reset_status,
.flush = fd_pipe_sp_flush,
.wait = kgsl_pipe_wait,
.get_param = kgsl_pipe_get_param,
.set_param = kgsl_pipe_set_param,
.destroy = kgsl_pipe_destroy,
};

struct fd_pipe *kgsl_pipe_new(struct fd_device *dev, enum fd_pipe_id id,
uint32_t prio)
{
struct kgsl_pipe *kgsl_pipe = NULL;
struct fd_pipe *pipe = NULL;
kgsl_pipe = calloc(1, sizeof(*kgsl_pipe));
if (!kgsl_pipe) {
ERROR_MSG("allocation failed");
goto fail;
}

pipe = &kgsl_pipe->base;
pipe->dev = dev;
pipe->funcs = &pipe_funcs;

struct kgsl_devinfo info;
if(kgsl_get_prop(dev->fd, KGSL_PROP_DEVICE_INFO, &info, sizeof(info)))
goto fail;

uint64_t gmem_iova;
if(kgsl_get_prop(dev->fd, KGSL_PROP_UCHE_GMEM_VADDR, &gmem_iova, sizeof(gmem_iova)))
goto fail;

kgsl_pipe->dev_id.gpu_id =
((info.chip_id >> 24) & 0xff) * 100 +
((info.chip_id >> 16) & 0xff) * 10 +
((info.chip_id >> 8) & 0xff);

kgsl_pipe->dev_id.chip_id = info.chip_id;
kgsl_pipe->gmem_size = info.gmem_sizebytes;
kgsl_pipe->gmem_base = gmem_iova;

struct kgsl_drawctxt_create req = {
.flags = KGSL_CONTEXT_SAVE_GMEM |
KGSL_CONTEXT_NO_GMEM_ALLOC |
KGSL_CONTEXT_PREAMBLE,
};

int ret = kgsl_pipe_safe_ioctl(dev->fd, IOCTL_KGSL_DRAWCTXT_CREATE, &req);
if(ret)
goto fail;

kgsl_pipe->queue_id = req.drawctxt_id;

fd_pipe_sp_ringpool_init(pipe);

return pipe;
fail:
if (pipe)
fd_pipe_del(pipe);
return NULL;
}


static const struct fd_device_funcs funcs = {
.bo_new = kgsl_bo_new,
.pipe_new = kgsl_pipe_new,
.bo_from_handle = kgsl_bo_from_handle,
.bo_from_dmabuf = kgsl_bo_from_dmabuf,
.bo_close_handle = kgsl_bo_close_handle,
.destroy = kgsl_device_destroy,
};

struct fd_device *
kgsl_device_new(int fd)
{
struct kgsl_device *kgsl_dev;
struct fd_device *dev;
struct kgsl_devinfo info;

/* Try to read the device info to detect if the FD is really KGSL */
if(kgsl_get_prop(fd, KGSL_PROP_DEVICE_INFO, &info, sizeof(info)))
return NULL;

kgsl_dev = calloc(1, sizeof(*kgsl_dev));
if (!kgsl_dev)
return NULL;

dev = &kgsl_dev->base;
dev->funcs = &funcs;
dev->fd = fd;
dev->version = FD_VERSION_ROBUSTNESS;
dev->features = FD_FEATURE_DIRECT_RESET | FD_FEATURE_IMPORT_DMABUF;

/* async submit_queue used for softpin deffered submits */
util_queue_init(&dev->submit_queue, "sq", 8, 1, 0, NULL);

dev->bo_size = sizeof(struct kgsl_bo);

return dev;
}

static void
kgsl_device_destroy(struct fd_device *dev)
{
}


/*
* Copyright (C) 2012 Rob Clark <[email protected]>
*
Expand Down Expand Up @@ -403,7 +133,7 @@ fd_screen_get_timestamp(struct pipe_screen *pscreen)

if (screen->has_timestamp) {
uint64_t n;
kgsl_pipe_get_param(screen->pipe, FD_TIMESTAMP, &n);
fd_pipe_get_param(screen->pipe, FD_TIMESTAMP, &n);
assert(screen->max_freq > 0);
return n * 1000000000 / screen->max_freq;
} else {
Expand Down Expand Up @@ -822,7 +552,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
if (fd_device_version(screen->dev) >= FD_VERSION_VA_SIZE) {
uint64_t va_size;

if (!kgsl_pipe_get_param(screen->pipe, FD_VA_SIZE, &va_size)) {
if (!fd_pipe_get_param(screen->pipe, FD_VA_SIZE, &va_size)) {
system_memory = MIN2(system_memory, va_size);
}
}
Expand Down Expand Up @@ -1278,7 +1008,7 @@ fd_screen_create(int fd,
const struct pipe_screen_config *config,
struct renderonly *ro)
{
struct fd_device *dev = kgsl_device_new(fd);
struct fd_device *dev = fd_device_new(fd);
if (!dev)
return NULL;

Expand All @@ -1304,20 +1034,20 @@ fd_screen_create(int fd,

// maybe this should be in context?
printf("Initializing pipe\n");
screen->pipe = kgsl_pipe_new(screen->dev, FD_PIPE_3D, 0);
screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D, 0);
if (!screen->pipe) {
printf("could not create 3d pipe\n");
goto fail;
}

if (kgsl_pipe_get_param(screen->pipe, FD_GMEM_SIZE, &val)) {
if (fd_pipe_get_param(screen->pipe, FD_GMEM_SIZE, &val)) {
printf("could not get GMEM size\n");
goto fail;
}
screen->gmemsize_bytes = debug_get_num_option("FD_MESA_GMEM", val);

if (fd_device_version(dev) >= FD_VERSION_GMEM_BASE) {
kgsl_pipe_get_param(screen->pipe, FD_GMEM_BASE, &screen->gmem_base);
fd_pipe_get_param(screen->pipe, FD_GMEM_BASE, &screen->gmem_base);
}

printf("setting max freq\n");
Expand All @@ -1327,14 +1057,14 @@ fd_screen_create(int fd,
screen->dev_id = fd_pipe_dev_id(screen->pipe);
printf("dev id pipe done\n");
printf("get gpu id\n");
if (kgsl_pipe_get_param(screen->pipe, FD_GPU_ID, &val)) {
if (fd_pipe_get_param(screen->pipe, FD_GPU_ID, &val)) {
printf("could not get gpu-id\n");
goto fail;
}
screen->gpu_id = val;
printf("get chip id\n");

if (kgsl_pipe_get_param(screen->pipe, FD_CHIP_ID, &val)) {
if (fd_pipe_get_param(screen->pipe, FD_CHIP_ID, &val)) {
printf("could not get chip-id\n");
/* older kernels may not have this property: */
unsigned core = screen->gpu_id / 100;
Expand All @@ -1349,7 +1079,7 @@ fd_screen_create(int fd,
printf("piping gen\n");
screen->gen = fd_dev_gen(screen->dev_id);
printf("get rings\n");
if (kgsl_pipe_get_param(screen->pipe, FD_NR_PRIORITIES, &val)) {
if (fd_pipe_get_param(screen->pipe, FD_NR_PRIORITIES, &val)) {
printf("could not get # of rings\n");
screen->priority_mask = 0;
} else {
Expand Down

0 comments on commit daa0ed8

Please sign in to comment.