183827f40a2d97261528087331b0bee6ce2cf27c5root/**************************************************************************
283827f40a2d97261528087331b0bee6ce2cf27c5root *
383827f40a2d97261528087331b0bee6ce2cf27c5root * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, Tx., USA
483827f40a2d97261528087331b0bee6ce2cf27c5root * All Rights Reserved.
583827f40a2d97261528087331b0bee6ce2cf27c5root * Copyright 2009 VMware, Inc., Palo Alto, CA., USA
683827f40a2d97261528087331b0bee6ce2cf27c5root * All Rights Reserved.
783827f40a2d97261528087331b0bee6ce2cf27c5root *
883827f40a2d97261528087331b0bee6ce2cf27c5root * Permission is hereby granted, free of charge, to any person obtaining a
983827f40a2d97261528087331b0bee6ce2cf27c5root * copy of this software and associated documentation files (the
1083827f40a2d97261528087331b0bee6ce2cf27c5root * "Software"), to deal in the Software without restriction, including
1183827f40a2d97261528087331b0bee6ce2cf27c5root * without limitation the rights to use, copy, modify, merge, publish,
1283827f40a2d97261528087331b0bee6ce2cf27c5root * distribute, sub license, and/or sell copies of the Software, and to
1383827f40a2d97261528087331b0bee6ce2cf27c5root * permit persons to whom the Software is furnished to do so, subject to
1483827f40a2d97261528087331b0bee6ce2cf27c5root * the following conditions:
1583827f40a2d97261528087331b0bee6ce2cf27c5root *
1683827f40a2d97261528087331b0bee6ce2cf27c5root * The above copyright notice and this permission notice (including the
1783827f40a2d97261528087331b0bee6ce2cf27c5root * next paragraph) shall be included in all copies or substantial portions
1883827f40a2d97261528087331b0bee6ce2cf27c5root * of the Software.
1983827f40a2d97261528087331b0bee6ce2cf27c5root *
2083827f40a2d97261528087331b0bee6ce2cf27c5root * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2183827f40a2d97261528087331b0bee6ce2cf27c5root * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2283827f40a2d97261528087331b0bee6ce2cf27c5root * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
2383827f40a2d97261528087331b0bee6ce2cf27c5root * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
2483827f40a2d97261528087331b0bee6ce2cf27c5root * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2583827f40a2d97261528087331b0bee6ce2cf27c5root * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2683827f40a2d97261528087331b0bee6ce2cf27c5root * USE OR OTHER DEALINGS IN THE SOFTWARE.
2783827f40a2d97261528087331b0bee6ce2cf27c5root *
2883827f40a2d97261528087331b0bee6ce2cf27c5root **************************************************************************/
2983827f40a2d97261528087331b0bee6ce2cf27c5root/*
3083827f40a2d97261528087331b0bee6ce2cf27c5root * Authors: Thomas Hellstr�m <thomas-at-tungstengraphics-dot-com>
3183827f40a2d97261528087331b0bee6ce2cf27c5root */
3283827f40a2d97261528087331b0bee6ce2cf27c5root#ifdef HAVE_CONFIG_H
3383827f40a2d97261528087331b0bee6ce2cf27c5root#include "config.h"
3483827f40a2d97261528087331b0bee6ce2cf27c5root#endif
3583827f40a2d97261528087331b0bee6ce2cf27c5root
3683827f40a2d97261528087331b0bee6ce2cf27c5root#include <xf86drm.h>
3783827f40a2d97261528087331b0bee6ce2cf27c5root#include <stdlib.h>
3883827f40a2d97261528087331b0bee6ce2cf27c5root#include <unistd.h>
3983827f40a2d97261528087331b0bee6ce2cf27c5root#include <errno.h>
4083827f40a2d97261528087331b0bee6ce2cf27c5root#include <sys/mman.h>
4177bfea2e6a3dc1e30a17780b48b7b231eef77255Thierry Strudel#include <drm/psb_ttm_placement_user.h>
4283827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_pool.h"
4383827f40a2d97261528087331b0bee6ce2cf27c5root#include "assert.h"
4483827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_priv.h"
4583827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_manager.h"
4683827f40a2d97261528087331b0bee6ce2cf27c5root
4783827f40a2d97261528087331b0bee6ce2cf27c5root#define DRMRESTARTCOMMANDWRITE(_fd, _val, _arg, _ret)			\
4883827f40a2d97261528087331b0bee6ce2cf27c5root	do {								\
4983827f40a2d97261528087331b0bee6ce2cf27c5root		(_ret) = drmCommandWrite(_fd, _val, &(_arg), sizeof(_arg)); \
5083827f40a2d97261528087331b0bee6ce2cf27c5root	} while ((_ret) == -EAGAIN || (_ret) == -ERESTART);		\
5183827f40a2d97261528087331b0bee6ce2cf27c5root
5283827f40a2d97261528087331b0bee6ce2cf27c5root#define DRMRESTARTCOMMANDWRITEREAD(_fd, _val, _arg, _ret)		\
5383827f40a2d97261528087331b0bee6ce2cf27c5root	do {								\
5483827f40a2d97261528087331b0bee6ce2cf27c5root		(_ret) = drmCommandWriteRead(_fd, _val, &(_arg), sizeof(_arg)); \
5583827f40a2d97261528087331b0bee6ce2cf27c5root	} while ((_ret) == -EAGAIN || (_ret) == -ERESTART);		\
5683827f40a2d97261528087331b0bee6ce2cf27c5root
5783827f40a2d97261528087331b0bee6ce2cf27c5root/*
5883827f40a2d97261528087331b0bee6ce2cf27c5root * Buffer pool implementation using DRM buffer objects as wsbm buffer objects.
5983827f40a2d97261528087331b0bee6ce2cf27c5root */
6083827f40a2d97261528087331b0bee6ce2cf27c5root
6183827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _TTMBuffer
6283827f40a2d97261528087331b0bee6ce2cf27c5root{
6383827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage buf;
6483827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmCond event;
6583827f40a2d97261528087331b0bee6ce2cf27c5root
6683827f40a2d97261528087331b0bee6ce2cf27c5root    /*
6783827f40a2d97261528087331b0bee6ce2cf27c5root     * Remains constant after creation.
6883827f40a2d97261528087331b0bee6ce2cf27c5root     */
6983827f40a2d97261528087331b0bee6ce2cf27c5root
7083827f40a2d97261528087331b0bee6ce2cf27c5root    uint64_t requestedSize;
7183827f40a2d97261528087331b0bee6ce2cf27c5root    uint64_t mapHandle;
7283827f40a2d97261528087331b0bee6ce2cf27c5root    uint64_t realSize;
7383827f40a2d97261528087331b0bee6ce2cf27c5root
7483827f40a2d97261528087331b0bee6ce2cf27c5root    /*
7583827f40a2d97261528087331b0bee6ce2cf27c5root     * Protected by the kernel lock.
7683827f40a2d97261528087331b0bee6ce2cf27c5root     */
7783827f40a2d97261528087331b0bee6ce2cf27c5root
7883827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmKernelBuf kBuf;
7983827f40a2d97261528087331b0bee6ce2cf27c5root
8083827f40a2d97261528087331b0bee6ce2cf27c5root    /*
8183827f40a2d97261528087331b0bee6ce2cf27c5root     * Protected by the mutex.
8283827f40a2d97261528087331b0bee6ce2cf27c5root     */
8383827f40a2d97261528087331b0bee6ce2cf27c5root
8483827f40a2d97261528087331b0bee6ce2cf27c5root    void *virtual;
8583827f40a2d97261528087331b0bee6ce2cf27c5root    int syncInProgress;
8683827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned readers;
8783827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned writers;
8883827f40a2d97261528087331b0bee6ce2cf27c5root};
8983827f40a2d97261528087331b0bee6ce2cf27c5root
9083827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _TTMPool
9183827f40a2d97261528087331b0bee6ce2cf27c5root{
9283827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufferPool pool;
9383827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned int pageSize;
9483827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned int devOffset;
9583827f40a2d97261528087331b0bee6ce2cf27c5root};
9683827f40a2d97261528087331b0bee6ce2cf27c5root
9783827f40a2d97261528087331b0bee6ce2cf27c5rootstatic inline struct _TTMPool *
9883827f40a2d97261528087331b0bee6ce2cf27c5rootttmGetPool(struct _TTMBuffer *dBuf)
9983827f40a2d97261528087331b0bee6ce2cf27c5root{
10083827f40a2d97261528087331b0bee6ce2cf27c5root    return containerOf(dBuf->buf.pool, struct _TTMPool, pool);
10183827f40a2d97261528087331b0bee6ce2cf27c5root}
10283827f40a2d97261528087331b0bee6ce2cf27c5root
10383827f40a2d97261528087331b0bee6ce2cf27c5rootstatic inline struct _TTMBuffer *
10483827f40a2d97261528087331b0bee6ce2cf27c5rootttmBuffer(struct _WsbmBufStorage *buf)
10583827f40a2d97261528087331b0bee6ce2cf27c5root{
10683827f40a2d97261528087331b0bee6ce2cf27c5root    return containerOf(buf, struct _TTMBuffer, buf);
10783827f40a2d97261528087331b0bee6ce2cf27c5root}
10883827f40a2d97261528087331b0bee6ce2cf27c5root
10983827f40a2d97261528087331b0bee6ce2cf27c5rootstatic struct _WsbmBufStorage *
11083827f40a2d97261528087331b0bee6ce2cf27c5rootpool_create(struct _WsbmBufferPool *pool,
11183827f40a2d97261528087331b0bee6ce2cf27c5root	    unsigned long size, uint32_t placement, unsigned alignment)
11283827f40a2d97261528087331b0bee6ce2cf27c5root{
11383827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMBuffer *dBuf = (struct _TTMBuffer *)
11483827f40a2d97261528087331b0bee6ce2cf27c5root	calloc(1, sizeof(*dBuf));
11583827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMPool *ttmPool = containerOf(pool, struct _TTMPool, pool);
11683827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
11783827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned pageSize = ttmPool->pageSize;
11883827f40a2d97261528087331b0bee6ce2cf27c5root    union ttm_pl_create_arg arg;
11983827f40a2d97261528087331b0bee6ce2cf27c5root
12083827f40a2d97261528087331b0bee6ce2cf27c5root    if (!dBuf)
12183827f40a2d97261528087331b0bee6ce2cf27c5root	return NULL;
12283827f40a2d97261528087331b0bee6ce2cf27c5root
12383827f40a2d97261528087331b0bee6ce2cf27c5root    if ((alignment > pageSize) && (alignment % pageSize))
12483827f40a2d97261528087331b0bee6ce2cf27c5root	goto out_err0;
12583827f40a2d97261528087331b0bee6ce2cf27c5root
12683827f40a2d97261528087331b0bee6ce2cf27c5root    ret = wsbmBufStorageInit(&dBuf->buf, pool);
12783827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret)
12883827f40a2d97261528087331b0bee6ce2cf27c5root	goto out_err0;
12983827f40a2d97261528087331b0bee6ce2cf27c5root
13083827f40a2d97261528087331b0bee6ce2cf27c5root    ret = WSBM_COND_INIT(&dBuf->event);
13183827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret)
13283827f40a2d97261528087331b0bee6ce2cf27c5root	goto out_err1;
13383827f40a2d97261528087331b0bee6ce2cf27c5root
13483827f40a2d97261528087331b0bee6ce2cf27c5root    arg.req.size = size;
13583827f40a2d97261528087331b0bee6ce2cf27c5root    arg.req.placement = placement;
13683827f40a2d97261528087331b0bee6ce2cf27c5root    arg.req.page_alignment = alignment / pageSize;
13783827f40a2d97261528087331b0bee6ce2cf27c5root
13883827f40a2d97261528087331b0bee6ce2cf27c5root    DRMRESTARTCOMMANDWRITEREAD(pool->fd, ttmPool->devOffset + TTM_PL_CREATE,
13983827f40a2d97261528087331b0bee6ce2cf27c5root			       arg, ret);
14083827f40a2d97261528087331b0bee6ce2cf27c5root
14183827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret)
14283827f40a2d97261528087331b0bee6ce2cf27c5root	goto out_err2;
14383827f40a2d97261528087331b0bee6ce2cf27c5root
14483827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->requestedSize = size;
14583827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->kBuf.gpuOffset = arg.rep.gpu_offset;
14683827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->mapHandle = arg.rep.map_handle;
14783827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->realSize = arg.rep.bo_size;
14883827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->kBuf.placement = arg.rep.placement;
14983827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->kBuf.handle = arg.rep.handle;
15083827f40a2d97261528087331b0bee6ce2cf27c5root
15183827f40a2d97261528087331b0bee6ce2cf27c5root    return &dBuf->buf;
15283827f40a2d97261528087331b0bee6ce2cf27c5root
15383827f40a2d97261528087331b0bee6ce2cf27c5root  out_err2:
15483827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_COND_FREE(&dBuf->event);
15583827f40a2d97261528087331b0bee6ce2cf27c5root  out_err1:
15683827f40a2d97261528087331b0bee6ce2cf27c5root    wsbmBufStorageTakedown(&dBuf->buf);
15783827f40a2d97261528087331b0bee6ce2cf27c5root  out_err0:
15883827f40a2d97261528087331b0bee6ce2cf27c5root    free(dBuf);
15983827f40a2d97261528087331b0bee6ce2cf27c5root    return NULL;
16083827f40a2d97261528087331b0bee6ce2cf27c5root}
16183827f40a2d97261528087331b0bee6ce2cf27c5root
16283827f40a2d97261528087331b0bee6ce2cf27c5rootstatic struct _WsbmBufStorage *
16383827f40a2d97261528087331b0bee6ce2cf27c5rootpool_reference(struct _WsbmBufferPool *pool, unsigned handle)
16483827f40a2d97261528087331b0bee6ce2cf27c5root{
16583827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMBuffer *dBuf = (struct _TTMBuffer *)calloc(1, sizeof(*dBuf));
16683827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMPool *ttmPool = containerOf(pool, struct _TTMPool, pool);
16783827f40a2d97261528087331b0bee6ce2cf27c5root    union ttm_pl_reference_arg arg;
16883827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
16983827f40a2d97261528087331b0bee6ce2cf27c5root
17083827f40a2d97261528087331b0bee6ce2cf27c5root    if (!dBuf)
17183827f40a2d97261528087331b0bee6ce2cf27c5root	return NULL;
17283827f40a2d97261528087331b0bee6ce2cf27c5root
17383827f40a2d97261528087331b0bee6ce2cf27c5root    ret = wsbmBufStorageInit(&dBuf->buf, pool);
17483827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret)
17583827f40a2d97261528087331b0bee6ce2cf27c5root	goto out_err0;
17683827f40a2d97261528087331b0bee6ce2cf27c5root
17783827f40a2d97261528087331b0bee6ce2cf27c5root    ret = WSBM_COND_INIT(&dBuf->event);
17883827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret)
17983827f40a2d97261528087331b0bee6ce2cf27c5root	goto out_err1;
18083827f40a2d97261528087331b0bee6ce2cf27c5root
18183827f40a2d97261528087331b0bee6ce2cf27c5root    arg.req.handle = handle;
18283827f40a2d97261528087331b0bee6ce2cf27c5root    ret = drmCommandWriteRead(pool->fd, ttmPool->devOffset + TTM_PL_REFERENCE,
18383827f40a2d97261528087331b0bee6ce2cf27c5root			      &arg, sizeof(arg));
18483827f40a2d97261528087331b0bee6ce2cf27c5root
18583827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret)
18683827f40a2d97261528087331b0bee6ce2cf27c5root	goto out_err2;
18783827f40a2d97261528087331b0bee6ce2cf27c5root
18883827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->requestedSize = arg.rep.bo_size;
18983827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->kBuf.gpuOffset = arg.rep.gpu_offset;
19083827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->mapHandle = arg.rep.map_handle;
19183827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->realSize = arg.rep.bo_size;
19283827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->kBuf.placement = arg.rep.placement;
19383827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->kBuf.handle = arg.rep.handle;
19483827f40a2d97261528087331b0bee6ce2cf27c5root    dBuf->kBuf.fence_type_mask = arg.rep.sync_object_arg;
19583827f40a2d97261528087331b0bee6ce2cf27c5root
19683827f40a2d97261528087331b0bee6ce2cf27c5root    return &dBuf->buf;
19783827f40a2d97261528087331b0bee6ce2cf27c5root
19883827f40a2d97261528087331b0bee6ce2cf27c5root  out_err2:
19983827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_COND_FREE(&dBuf->event);
20083827f40a2d97261528087331b0bee6ce2cf27c5root  out_err1:
20183827f40a2d97261528087331b0bee6ce2cf27c5root    wsbmBufStorageTakedown(&dBuf->buf);
20283827f40a2d97261528087331b0bee6ce2cf27c5root  out_err0:
20383827f40a2d97261528087331b0bee6ce2cf27c5root    free(dBuf);
20483827f40a2d97261528087331b0bee6ce2cf27c5root    return NULL;
20583827f40a2d97261528087331b0bee6ce2cf27c5root}
20683827f40a2d97261528087331b0bee6ce2cf27c5root
20783827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void
20883827f40a2d97261528087331b0bee6ce2cf27c5rootpool_destroy(struct _WsbmBufStorage **buf)
20983827f40a2d97261528087331b0bee6ce2cf27c5root{
21083827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMBuffer *dBuf = ttmBuffer(*buf);
21183827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMPool *ttmPool = ttmGetPool(dBuf);
21283827f40a2d97261528087331b0bee6ce2cf27c5root    struct ttm_pl_reference_req arg;
21383827f40a2d97261528087331b0bee6ce2cf27c5root
21483827f40a2d97261528087331b0bee6ce2cf27c5root    *buf = NULL;
21583827f40a2d97261528087331b0bee6ce2cf27c5root    if (dBuf->virtual != NULL) {
21683827f40a2d97261528087331b0bee6ce2cf27c5root	(void)munmap(dBuf->virtual, dBuf->requestedSize);
21783827f40a2d97261528087331b0bee6ce2cf27c5root	dBuf->virtual = NULL;
21883827f40a2d97261528087331b0bee6ce2cf27c5root    }
21983827f40a2d97261528087331b0bee6ce2cf27c5root    arg.handle = dBuf->kBuf.handle;
22083827f40a2d97261528087331b0bee6ce2cf27c5root    (void)drmCommandWrite(dBuf->buf.pool->fd,
22183827f40a2d97261528087331b0bee6ce2cf27c5root			  ttmPool->devOffset + TTM_PL_UNREF,
22283827f40a2d97261528087331b0bee6ce2cf27c5root			  &arg, sizeof(arg));
22383827f40a2d97261528087331b0bee6ce2cf27c5root
22483827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_COND_FREE(&dBuf->event);
22583827f40a2d97261528087331b0bee6ce2cf27c5root    wsbmBufStorageTakedown(&dBuf->buf);
22683827f40a2d97261528087331b0bee6ce2cf27c5root    free(dBuf);
22783827f40a2d97261528087331b0bee6ce2cf27c5root}
22883827f40a2d97261528087331b0bee6ce2cf27c5root
22983827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int
23083827f40a2d97261528087331b0bee6ce2cf27c5rootsyncforcpu_locked(struct _WsbmBufStorage *buf, unsigned mode)
23183827f40a2d97261528087331b0bee6ce2cf27c5root{
23283827f40a2d97261528087331b0bee6ce2cf27c5root    uint32_t kmode = 0;
23383827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMBuffer *dBuf = ttmBuffer(buf);
23483827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMPool *ttmPool = ttmGetPool(dBuf);
23583827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned int readers;
23683827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned int writers;
23783827f40a2d97261528087331b0bee6ce2cf27c5root    int ret = 0;
23883827f40a2d97261528087331b0bee6ce2cf27c5root
23983827f40a2d97261528087331b0bee6ce2cf27c5root    while (dBuf->syncInProgress)
24083827f40a2d97261528087331b0bee6ce2cf27c5root	WSBM_COND_WAIT(&dBuf->event, &buf->mutex);
24183827f40a2d97261528087331b0bee6ce2cf27c5root
24283827f40a2d97261528087331b0bee6ce2cf27c5root    readers = dBuf->readers;
24383827f40a2d97261528087331b0bee6ce2cf27c5root    writers = dBuf->writers;
24483827f40a2d97261528087331b0bee6ce2cf27c5root
24583827f40a2d97261528087331b0bee6ce2cf27c5root    if ((mode & WSBM_SYNCCPU_READ) && (++dBuf->readers == 1))
24683827f40a2d97261528087331b0bee6ce2cf27c5root	kmode |= TTM_PL_SYNCCPU_MODE_READ;
24783827f40a2d97261528087331b0bee6ce2cf27c5root
24883827f40a2d97261528087331b0bee6ce2cf27c5root    if ((mode & WSBM_SYNCCPU_WRITE) && (++dBuf->writers == 1))
24983827f40a2d97261528087331b0bee6ce2cf27c5root	kmode |= TTM_PL_SYNCCPU_MODE_WRITE;
25083827f40a2d97261528087331b0bee6ce2cf27c5root
25183827f40a2d97261528087331b0bee6ce2cf27c5root    if (kmode) {
25283827f40a2d97261528087331b0bee6ce2cf27c5root	struct ttm_pl_synccpu_arg arg;
25383827f40a2d97261528087331b0bee6ce2cf27c5root
25483827f40a2d97261528087331b0bee6ce2cf27c5root	if (mode & WSBM_SYNCCPU_DONT_BLOCK)
25583827f40a2d97261528087331b0bee6ce2cf27c5root	    kmode |= TTM_PL_SYNCCPU_MODE_NO_BLOCK;
25683827f40a2d97261528087331b0bee6ce2cf27c5root
25783827f40a2d97261528087331b0bee6ce2cf27c5root	dBuf->syncInProgress = 1;
25883827f40a2d97261528087331b0bee6ce2cf27c5root
25983827f40a2d97261528087331b0bee6ce2cf27c5root	/*
26083827f40a2d97261528087331b0bee6ce2cf27c5root	 * This might be a lengthy wait, so
26183827f40a2d97261528087331b0bee6ce2cf27c5root	 * release the mutex.
26283827f40a2d97261528087331b0bee6ce2cf27c5root	 */
26383827f40a2d97261528087331b0bee6ce2cf27c5root
26483827f40a2d97261528087331b0bee6ce2cf27c5root	WSBM_MUTEX_UNLOCK(&buf->mutex);
26583827f40a2d97261528087331b0bee6ce2cf27c5root
26683827f40a2d97261528087331b0bee6ce2cf27c5root	arg.handle = dBuf->kBuf.handle;
26783827f40a2d97261528087331b0bee6ce2cf27c5root	arg.access_mode = kmode;
26883827f40a2d97261528087331b0bee6ce2cf27c5root	arg.op = TTM_PL_SYNCCPU_OP_GRAB;
26983827f40a2d97261528087331b0bee6ce2cf27c5root
27083827f40a2d97261528087331b0bee6ce2cf27c5root	DRMRESTARTCOMMANDWRITE(dBuf->buf.pool->fd,
27183827f40a2d97261528087331b0bee6ce2cf27c5root			       ttmPool->devOffset + TTM_PL_SYNCCPU, arg, ret);
27283827f40a2d97261528087331b0bee6ce2cf27c5root
27383827f40a2d97261528087331b0bee6ce2cf27c5root	WSBM_MUTEX_LOCK(&buf->mutex);
27483827f40a2d97261528087331b0bee6ce2cf27c5root	dBuf->syncInProgress = 0;
27583827f40a2d97261528087331b0bee6ce2cf27c5root	WSBM_COND_BROADCAST(&dBuf->event);
27683827f40a2d97261528087331b0bee6ce2cf27c5root
27783827f40a2d97261528087331b0bee6ce2cf27c5root	if (ret) {
27883827f40a2d97261528087331b0bee6ce2cf27c5root	    dBuf->readers = readers;
27983827f40a2d97261528087331b0bee6ce2cf27c5root	    dBuf->writers = writers;
28083827f40a2d97261528087331b0bee6ce2cf27c5root	}
28183827f40a2d97261528087331b0bee6ce2cf27c5root    }
28283827f40a2d97261528087331b0bee6ce2cf27c5root
28383827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
28483827f40a2d97261528087331b0bee6ce2cf27c5root}
28583827f40a2d97261528087331b0bee6ce2cf27c5root
28683827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int
28783827f40a2d97261528087331b0bee6ce2cf27c5rootreleasefromcpu_locked(struct _WsbmBufStorage *buf, unsigned mode)
28883827f40a2d97261528087331b0bee6ce2cf27c5root{
28983827f40a2d97261528087331b0bee6ce2cf27c5root    uint32_t kmode = 0;
29083827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMBuffer *dBuf = ttmBuffer(buf);
29183827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMPool *ttmPool = ttmGetPool(dBuf);
29283827f40a2d97261528087331b0bee6ce2cf27c5root    int ret = 0;
29383827f40a2d97261528087331b0bee6ce2cf27c5root
29483827f40a2d97261528087331b0bee6ce2cf27c5root    while (dBuf->syncInProgress)
29583827f40a2d97261528087331b0bee6ce2cf27c5root	WSBM_COND_WAIT(&dBuf->event, &buf->mutex);
29683827f40a2d97261528087331b0bee6ce2cf27c5root
29783827f40a2d97261528087331b0bee6ce2cf27c5root    if ((mode & WSBM_SYNCCPU_READ) && (--dBuf->readers == 0))
29883827f40a2d97261528087331b0bee6ce2cf27c5root	kmode |= TTM_PL_SYNCCPU_MODE_READ;
29983827f40a2d97261528087331b0bee6ce2cf27c5root
30083827f40a2d97261528087331b0bee6ce2cf27c5root    if ((mode & WSBM_SYNCCPU_WRITE) && (--dBuf->writers == 0))
30183827f40a2d97261528087331b0bee6ce2cf27c5root	kmode |= TTM_PL_SYNCCPU_MODE_WRITE;
30283827f40a2d97261528087331b0bee6ce2cf27c5root
30383827f40a2d97261528087331b0bee6ce2cf27c5root    if (kmode) {
30483827f40a2d97261528087331b0bee6ce2cf27c5root	struct ttm_pl_synccpu_arg arg;
30583827f40a2d97261528087331b0bee6ce2cf27c5root
30683827f40a2d97261528087331b0bee6ce2cf27c5root	arg.handle = dBuf->kBuf.handle;
30783827f40a2d97261528087331b0bee6ce2cf27c5root	arg.access_mode = kmode;
30883827f40a2d97261528087331b0bee6ce2cf27c5root	arg.op = TTM_PL_SYNCCPU_OP_RELEASE;
30983827f40a2d97261528087331b0bee6ce2cf27c5root
31083827f40a2d97261528087331b0bee6ce2cf27c5root	DRMRESTARTCOMMANDWRITE(dBuf->buf.pool->fd,
31183827f40a2d97261528087331b0bee6ce2cf27c5root			       ttmPool->devOffset + TTM_PL_SYNCCPU, arg, ret);
31283827f40a2d97261528087331b0bee6ce2cf27c5root
31383827f40a2d97261528087331b0bee6ce2cf27c5root    }
31483827f40a2d97261528087331b0bee6ce2cf27c5root
31583827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
31683827f40a2d97261528087331b0bee6ce2cf27c5root}
31783827f40a2d97261528087331b0bee6ce2cf27c5root
31883827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int
31983827f40a2d97261528087331b0bee6ce2cf27c5rootpool_syncforcpu(struct _WsbmBufStorage *buf, unsigned mode)
32083827f40a2d97261528087331b0bee6ce2cf27c5root{
32183827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
32283827f40a2d97261528087331b0bee6ce2cf27c5root
32383827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_LOCK(&buf->mutex);
32483827f40a2d97261528087331b0bee6ce2cf27c5root    ret = syncforcpu_locked(buf, mode);
32583827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_UNLOCK(&buf->mutex);
32683827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
32783827f40a2d97261528087331b0bee6ce2cf27c5root}
32883827f40a2d97261528087331b0bee6ce2cf27c5root
32983827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void
33083827f40a2d97261528087331b0bee6ce2cf27c5rootpool_releasefromcpu(struct _WsbmBufStorage *buf, unsigned mode)
33183827f40a2d97261528087331b0bee6ce2cf27c5root{
33283827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_LOCK(&buf->mutex);
33383827f40a2d97261528087331b0bee6ce2cf27c5root    (void)releasefromcpu_locked(buf, mode);
33483827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_UNLOCK(&buf->mutex);
33583827f40a2d97261528087331b0bee6ce2cf27c5root}
33683827f40a2d97261528087331b0bee6ce2cf27c5root
33783827f40a2d97261528087331b0bee6ce2cf27c5root#ifdef ANDROID
3383795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel
3393795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel/* No header but syscall provided by bionic */
3403795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudelvoid*  __mmap2(void*, size_t, int, int, int, size_t);
3413795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel#define MMAP2_SHIFT 12 // 2**12 == 4096
3423795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel
34383827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void* _temp_mmap(void *addr, size_t size, int prot, int flags, int fd, long long offset)
34483827f40a2d97261528087331b0bee6ce2cf27c5root{
3453795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel    return __mmap2(addr, size, prot, flags, fd, (unsigned long)(offset >> MMAP2_SHIFT));
34683827f40a2d97261528087331b0bee6ce2cf27c5root}
3473795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel
34883827f40a2d97261528087331b0bee6ce2cf27c5root#endif
34983827f40a2d97261528087331b0bee6ce2cf27c5root
35083827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int
3513795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudelpool_map(struct _WsbmBufStorage *buf, unsigned mode __attribute__ ((unused)), void **virtual)
35283827f40a2d97261528087331b0bee6ce2cf27c5root{
35383827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMBuffer *dBuf = ttmBuffer(buf);
35483827f40a2d97261528087331b0bee6ce2cf27c5root    void *virt;
35583827f40a2d97261528087331b0bee6ce2cf27c5root    int ret = 0;
35683827f40a2d97261528087331b0bee6ce2cf27c5root
35783827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_LOCK(&buf->mutex);
35883827f40a2d97261528087331b0bee6ce2cf27c5root
35983827f40a2d97261528087331b0bee6ce2cf27c5root    /*
36083827f40a2d97261528087331b0bee6ce2cf27c5root     * mmaps are expensive, so we only really unmap if
36183827f40a2d97261528087331b0bee6ce2cf27c5root     * we destroy the buffer.
36283827f40a2d97261528087331b0bee6ce2cf27c5root     */
36383827f40a2d97261528087331b0bee6ce2cf27c5root
36483827f40a2d97261528087331b0bee6ce2cf27c5root    if (dBuf->virtual == NULL) {
36547d6391038ba17c88a9432de198585c65da6249bFei Jiang#if defined(__LP64__) || defined(_LP64) || defined(__LP64)
36683827f40a2d97261528087331b0bee6ce2cf27c5root	virt = mmap(0, dBuf->requestedSize,
36783827f40a2d97261528087331b0bee6ce2cf27c5root		    PROT_READ | PROT_WRITE, MAP_SHARED,
36883827f40a2d97261528087331b0bee6ce2cf27c5root		    buf->pool->fd, dBuf->mapHandle);
36983827f40a2d97261528087331b0bee6ce2cf27c5root#else
37083827f40a2d97261528087331b0bee6ce2cf27c5root	virt = _temp_mmap(0, dBuf->requestedSize,
37183827f40a2d97261528087331b0bee6ce2cf27c5root		    PROT_READ | PROT_WRITE, MAP_SHARED,
37283827f40a2d97261528087331b0bee6ce2cf27c5root		    buf->pool->fd, dBuf->mapHandle);
37383827f40a2d97261528087331b0bee6ce2cf27c5root#endif
37483827f40a2d97261528087331b0bee6ce2cf27c5root	if (virt == MAP_FAILED) {
37583827f40a2d97261528087331b0bee6ce2cf27c5root	    ret = -errno;
37683827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out_unlock;
37783827f40a2d97261528087331b0bee6ce2cf27c5root	}
37883827f40a2d97261528087331b0bee6ce2cf27c5root	dBuf->virtual = virt;
37983827f40a2d97261528087331b0bee6ce2cf27c5root    }
38083827f40a2d97261528087331b0bee6ce2cf27c5root
38183827f40a2d97261528087331b0bee6ce2cf27c5root    *virtual = dBuf->virtual;
38283827f40a2d97261528087331b0bee6ce2cf27c5root  out_unlock:
38383827f40a2d97261528087331b0bee6ce2cf27c5root
38483827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_UNLOCK(&buf->mutex);
38583827f40a2d97261528087331b0bee6ce2cf27c5root
38683827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
38783827f40a2d97261528087331b0bee6ce2cf27c5root}
38883827f40a2d97261528087331b0bee6ce2cf27c5root
38983827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void
3903795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudelpool_unmap(struct _WsbmBufStorage *buf __attribute__ ((unused)))
39183827f40a2d97261528087331b0bee6ce2cf27c5root{
39283827f40a2d97261528087331b0bee6ce2cf27c5root    ;
39383827f40a2d97261528087331b0bee6ce2cf27c5root}
39483827f40a2d97261528087331b0bee6ce2cf27c5root
39583827f40a2d97261528087331b0bee6ce2cf27c5rootstatic unsigned long
39683827f40a2d97261528087331b0bee6ce2cf27c5rootpool_offset(struct _WsbmBufStorage *buf)
39783827f40a2d97261528087331b0bee6ce2cf27c5root{
39883827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMBuffer *dBuf = ttmBuffer(buf);
39983827f40a2d97261528087331b0bee6ce2cf27c5root
40083827f40a2d97261528087331b0bee6ce2cf27c5root    return dBuf->kBuf.gpuOffset;
40183827f40a2d97261528087331b0bee6ce2cf27c5root}
40283827f40a2d97261528087331b0bee6ce2cf27c5root
40383827f40a2d97261528087331b0bee6ce2cf27c5rootstatic unsigned long
4043795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudelpool_poolOffset(struct _WsbmBufStorage *buf __attribute__ ((unused)))
40583827f40a2d97261528087331b0bee6ce2cf27c5root{
40683827f40a2d97261528087331b0bee6ce2cf27c5root    return 0;
40783827f40a2d97261528087331b0bee6ce2cf27c5root}
40883827f40a2d97261528087331b0bee6ce2cf27c5root
40983827f40a2d97261528087331b0bee6ce2cf27c5rootstatic uint32_t
41083827f40a2d97261528087331b0bee6ce2cf27c5rootpool_placement(struct _WsbmBufStorage *buf)
41183827f40a2d97261528087331b0bee6ce2cf27c5root{
41283827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMBuffer *dBuf = ttmBuffer(buf);
41383827f40a2d97261528087331b0bee6ce2cf27c5root
41483827f40a2d97261528087331b0bee6ce2cf27c5root    return dBuf->kBuf.placement;
41583827f40a2d97261528087331b0bee6ce2cf27c5root}
41683827f40a2d97261528087331b0bee6ce2cf27c5root
41783827f40a2d97261528087331b0bee6ce2cf27c5rootstatic unsigned long
41883827f40a2d97261528087331b0bee6ce2cf27c5rootpool_size(struct _WsbmBufStorage *buf)
41983827f40a2d97261528087331b0bee6ce2cf27c5root{
42083827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMBuffer *dBuf = ttmBuffer(buf);
42183827f40a2d97261528087331b0bee6ce2cf27c5root
42283827f40a2d97261528087331b0bee6ce2cf27c5root    return dBuf->realSize;
42383827f40a2d97261528087331b0bee6ce2cf27c5root}
42483827f40a2d97261528087331b0bee6ce2cf27c5root
42583827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void
4263795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudelpool_fence(struct _WsbmBufStorage *buf __attribute__ ((unused)),
4273795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel        struct _WsbmFenceObject *fence __attribute__ ((unused)))
42883827f40a2d97261528087331b0bee6ce2cf27c5root{
42983827f40a2d97261528087331b0bee6ce2cf27c5root    /*
43083827f40a2d97261528087331b0bee6ce2cf27c5root     * Noop. The kernel handles all fencing.
43183827f40a2d97261528087331b0bee6ce2cf27c5root     */
43283827f40a2d97261528087331b0bee6ce2cf27c5root}
43383827f40a2d97261528087331b0bee6ce2cf27c5root
43483827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int
43583827f40a2d97261528087331b0bee6ce2cf27c5rootpool_waitIdle(struct _WsbmBufStorage *buf, int lazy)
43683827f40a2d97261528087331b0bee6ce2cf27c5root{
43783827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMBuffer *dBuf = ttmBuffer(buf);
43883827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMPool *ttmPool = ttmGetPool(dBuf);
43983827f40a2d97261528087331b0bee6ce2cf27c5root    struct ttm_pl_waitidle_arg req;
44083827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufferPool *pool = buf->pool;
44183827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
44283827f40a2d97261528087331b0bee6ce2cf27c5root
44383827f40a2d97261528087331b0bee6ce2cf27c5root    req.handle = dBuf->kBuf.handle;
44483827f40a2d97261528087331b0bee6ce2cf27c5root    req.mode = (lazy) ? TTM_PL_WAITIDLE_MODE_LAZY : 0;
44583827f40a2d97261528087331b0bee6ce2cf27c5root
44683827f40a2d97261528087331b0bee6ce2cf27c5root    DRMRESTARTCOMMANDWRITE(pool->fd, ttmPool->devOffset + TTM_PL_WAITIDLE,
44783827f40a2d97261528087331b0bee6ce2cf27c5root			   req, ret);
44883827f40a2d97261528087331b0bee6ce2cf27c5root
44983827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
45083827f40a2d97261528087331b0bee6ce2cf27c5root}
45183827f40a2d97261528087331b0bee6ce2cf27c5root
45283827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void
45383827f40a2d97261528087331b0bee6ce2cf27c5rootpool_takedown(struct _WsbmBufferPool *pool)
45483827f40a2d97261528087331b0bee6ce2cf27c5root{
45583827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMPool *ttmPool = containerOf(pool, struct _TTMPool, pool);
45683827f40a2d97261528087331b0bee6ce2cf27c5root
45783827f40a2d97261528087331b0bee6ce2cf27c5root    free(ttmPool);
45883827f40a2d97261528087331b0bee6ce2cf27c5root}
45983827f40a2d97261528087331b0bee6ce2cf27c5root
46083827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int
46183827f40a2d97261528087331b0bee6ce2cf27c5rootpool_setStatus(struct _WsbmBufStorage *buf, uint32_t set_placement,
46283827f40a2d97261528087331b0bee6ce2cf27c5root	       uint32_t clr_placement)
46383827f40a2d97261528087331b0bee6ce2cf27c5root{
46483827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMBuffer *dBuf = ttmBuffer(buf);
46583827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMPool *ttmPool = ttmGetPool(dBuf);
46683827f40a2d97261528087331b0bee6ce2cf27c5root    union ttm_pl_setstatus_arg arg;
46783827f40a2d97261528087331b0bee6ce2cf27c5root    struct ttm_pl_setstatus_req *req = &arg.req;
46883827f40a2d97261528087331b0bee6ce2cf27c5root    struct ttm_pl_rep *rep = &arg.rep;
46983827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufferPool *pool = buf->pool;
47083827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
47183827f40a2d97261528087331b0bee6ce2cf27c5root
47283827f40a2d97261528087331b0bee6ce2cf27c5root    req->handle = dBuf->kBuf.handle;
47383827f40a2d97261528087331b0bee6ce2cf27c5root    req->set_placement = set_placement;
47483827f40a2d97261528087331b0bee6ce2cf27c5root    req->clr_placement = clr_placement;
47583827f40a2d97261528087331b0bee6ce2cf27c5root
47683827f40a2d97261528087331b0bee6ce2cf27c5root    DRMRESTARTCOMMANDWRITEREAD(pool->fd,
47783827f40a2d97261528087331b0bee6ce2cf27c5root			       ttmPool->devOffset + TTM_PL_SETSTATUS,
47883827f40a2d97261528087331b0bee6ce2cf27c5root			       arg, ret);
47983827f40a2d97261528087331b0bee6ce2cf27c5root
48083827f40a2d97261528087331b0bee6ce2cf27c5root    if (!ret) {
48183827f40a2d97261528087331b0bee6ce2cf27c5root	dBuf->kBuf.gpuOffset = rep->gpu_offset;
48283827f40a2d97261528087331b0bee6ce2cf27c5root	dBuf->kBuf.placement = rep->placement;
48383827f40a2d97261528087331b0bee6ce2cf27c5root    }
48483827f40a2d97261528087331b0bee6ce2cf27c5root
48583827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
48683827f40a2d97261528087331b0bee6ce2cf27c5root}
48783827f40a2d97261528087331b0bee6ce2cf27c5root
48883827f40a2d97261528087331b0bee6ce2cf27c5rootstatic struct _WsbmKernelBuf *
48983827f40a2d97261528087331b0bee6ce2cf27c5rootpool_kernel(struct _WsbmBufStorage *buf)
49083827f40a2d97261528087331b0bee6ce2cf27c5root{
49183827f40a2d97261528087331b0bee6ce2cf27c5root    return (void *)&ttmBuffer(buf)->kBuf;
49283827f40a2d97261528087331b0bee6ce2cf27c5root}
49383827f40a2d97261528087331b0bee6ce2cf27c5root
49483827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmBufferPool *
49583827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmTTMPoolInit(int fd, unsigned int devOffset)
49683827f40a2d97261528087331b0bee6ce2cf27c5root{
49783827f40a2d97261528087331b0bee6ce2cf27c5root    struct _TTMPool *ttmPool;
49883827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufferPool *pool;
49983827f40a2d97261528087331b0bee6ce2cf27c5root
50083827f40a2d97261528087331b0bee6ce2cf27c5root    ttmPool = (struct _TTMPool *)calloc(1, sizeof(*ttmPool));
50183827f40a2d97261528087331b0bee6ce2cf27c5root
50283827f40a2d97261528087331b0bee6ce2cf27c5root    if (!ttmPool)
50383827f40a2d97261528087331b0bee6ce2cf27c5root	return NULL;
50483827f40a2d97261528087331b0bee6ce2cf27c5root
50583827f40a2d97261528087331b0bee6ce2cf27c5root    ttmPool->pageSize = getpagesize();
50683827f40a2d97261528087331b0bee6ce2cf27c5root    ttmPool->devOffset = devOffset;
50783827f40a2d97261528087331b0bee6ce2cf27c5root    pool = &ttmPool->pool;
50883827f40a2d97261528087331b0bee6ce2cf27c5root
50983827f40a2d97261528087331b0bee6ce2cf27c5root    pool->fd = fd;
51083827f40a2d97261528087331b0bee6ce2cf27c5root    pool->map = &pool_map;
51183827f40a2d97261528087331b0bee6ce2cf27c5root    pool->unmap = &pool_unmap;
51283827f40a2d97261528087331b0bee6ce2cf27c5root    pool->syncforcpu = &pool_syncforcpu;
51383827f40a2d97261528087331b0bee6ce2cf27c5root    pool->releasefromcpu = &pool_releasefromcpu;
51483827f40a2d97261528087331b0bee6ce2cf27c5root    pool->destroy = &pool_destroy;
51583827f40a2d97261528087331b0bee6ce2cf27c5root    pool->offset = &pool_offset;
51683827f40a2d97261528087331b0bee6ce2cf27c5root    pool->poolOffset = &pool_poolOffset;
51783827f40a2d97261528087331b0bee6ce2cf27c5root    pool->placement = &pool_placement;
51883827f40a2d97261528087331b0bee6ce2cf27c5root    pool->size = &pool_size;
51983827f40a2d97261528087331b0bee6ce2cf27c5root    pool->create = &pool_create;
52083827f40a2d97261528087331b0bee6ce2cf27c5root    pool->fence = &pool_fence;
52183827f40a2d97261528087331b0bee6ce2cf27c5root    pool->kernel = &pool_kernel;
52283827f40a2d97261528087331b0bee6ce2cf27c5root    pool->validate = NULL;
52383827f40a2d97261528087331b0bee6ce2cf27c5root    pool->unvalidate = NULL;
52483827f40a2d97261528087331b0bee6ce2cf27c5root    pool->waitIdle = &pool_waitIdle;
52583827f40a2d97261528087331b0bee6ce2cf27c5root    pool->takeDown = &pool_takedown;
52683827f40a2d97261528087331b0bee6ce2cf27c5root    pool->createByReference = &pool_reference;
52783827f40a2d97261528087331b0bee6ce2cf27c5root    pool->setStatus = &pool_setStatus;
52883827f40a2d97261528087331b0bee6ce2cf27c5root    return pool;
52983827f40a2d97261528087331b0bee6ce2cf27c5root}
5308acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
5318acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiangstruct _WsbmBufStorage *
532ac747113d4f6739b1462ca7fb40f2091691e209bVinil Cheeramvelilttm_pool_ub_create(struct _WsbmBufferPool *pool, unsigned long size, uint32_t placement, unsigned alignment, const unsigned long *user_ptr, int fd)
5338acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang{
5348acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    struct _TTMBuffer *dBuf = (struct _TTMBuffer *)
5358acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang	    calloc(1, sizeof(*dBuf));
5368acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    struct _TTMPool *ttmPool = containerOf(pool, struct _TTMPool, pool);
5378acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    int ret;
5388acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    unsigned pageSize = ttmPool->pageSize;
5398acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    union ttm_pl_create_ub_arg arg;
5408acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
5418acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (!dBuf)
5428acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang	    return NULL;
5438acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
5448acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if ((alignment > pageSize) && (alignment % pageSize))
5458acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang	    goto out_err0;
5468acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
5478acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    ret = wsbmBufStorageInit(&dBuf->buf, pool);
5488acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (ret)
5498acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang	    goto out_err0;
5508acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
5518acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    ret = WSBM_COND_INIT(&dBuf->event);
5528acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (ret)
5538acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang	    goto out_err1;
5548acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
5558acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    arg.req.size = size;
5568acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    arg.req.placement = placement;
5578acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    arg.req.page_alignment = alignment / pageSize;
55864c7d270ac00ecc608e2f156ca15dfd30d9d0132Fei Jiang    arg.req.user_address = (unsigned long)user_ptr;
559ac747113d4f6739b1462ca7fb40f2091691e209bVinil Cheeramvelil    arg.req.fd = fd;
5608acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
5618acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    DRMRESTARTCOMMANDWRITEREAD(pool->fd, ttmPool->devOffset + TTM_PL_CREATE_UB,
5628acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang			       arg, ret);
5638acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (ret)
5648acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        goto out_err2;
5658acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
5668acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    dBuf->requestedSize = size;
5678acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    dBuf->kBuf.gpuOffset = arg.rep.gpu_offset;
5688acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    dBuf->mapHandle = arg.rep.map_handle;
5698acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    dBuf->realSize = arg.rep.bo_size;
5708acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    dBuf->kBuf.placement = arg.rep.placement;
5718acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    dBuf->kBuf.handle = arg.rep.handle;
5728acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
5738acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    return &dBuf->buf;
5748acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
5758acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang  out_err2:
5768acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    WSBM_COND_FREE(&dBuf->event);
5778acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang  out_err1:
5788acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    wsbmBufStorageTakedown(&dBuf->buf);
5798acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang  out_err0:
5808acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    free(dBuf);
5818acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    return NULL;
5828acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang}
5838acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
584