adreno源码系列adreno_ringbuffer

Posted bubbleben

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了adreno源码系列adreno_ringbuffer相关的知识,希望对你有一定的参考价值。

int adreno_ringbuffer_init(struct adreno_device *adreno_dev)

	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	int i;
	int status = -ENOMEM;

	if (!adreno_is_a3xx(adreno_dev)) 
		unsigned int priv =
			KGSL_MEMDESC_RANDOM | KGSL_MEMDESC_PRIVILEGED;

		if (IS_ERR_OR_NULL(device->scratch)) 
            // 分配kgsl_device全局共享的大小为4k名称为scratch的内存
			device->scratch = kgsl_allocate_global(device,
				PAGE_SIZE, 0, 0, priv, "scratch");

			if (IS_ERR(device->scratch))
				return PTR_ERR(device->scratch);
		
	

	if (ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION))
        // 支持抢占: rb最多为4个
		adreno_dev->num_ringbuffers =
			ARRAY_SIZE(adreno_dev->ringbuffers);
	else
        // 不支持抢占:只有1个rb
		adreno_dev->num_ringbuffers = 1;

	for (i = 0; i < adreno_dev->num_ringbuffers; i++) 
        // 初始化每个rb
		status = _adreno_ringbuffer_init(adreno_dev, i);
		if (status) 
			adreno_ringbuffer_close(adreno_dev);
			return status;
		
	

    // adreno_device->cur_rb记录第一个rb
	adreno_dev->cur_rb = &(adreno_dev->ringbuffers[0]);

	if (ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) 
		const struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
		struct adreno_preemption *preempt = &adreno_dev->preempt;
		int ret;

		timer_setup(&preempt->timer, adreno_preemption_timer, 0);

		ret = gpudev->preemption_init(adreno_dev);
		WARN(ret, "adreno GPU preemption is disabled\\n");
	

	return 0;

1. _adreno_ringbuffer_init

static int _adreno_ringbuffer_init(struct adreno_device *adreno_dev,
		int id)

	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
    // 根据id获取指定adreno_ringbuffer
	struct adreno_ringbuffer *rb = &adreno_dev->ringbuffers[id];
	unsigned int priv = 0;

	/*
	 * Allocate mem for storing RB pagetables and commands to
	 * switch pagetable
	 */
	if (IS_ERR_OR_NULL(rb->pagetable_desc)) 
        // 分配adreno_ringbuffer全局共享的大小为4k偏移为16k名称为pagetable_desc的内存
		rb->pagetable_desc = kgsl_allocate_global(device, PAGE_SIZE,
			SZ_16K, 0, KGSL_MEMDESC_PRIVILEGED, "pagetable_desc");
		if (IS_ERR(rb->pagetable_desc))
			return PTR_ERR(rb->pagetable_desc);
	

	/* allocate a chunk of memory to create user profiling IB1s */
	if (IS_ERR_OR_NULL(rb->profile_desc))
        // 分配adreno_ringbuffer全局共享的大小为4k名称为profile_desc的内存
		rb->profile_desc = kgsl_allocate_global(device, PAGE_SIZE,
			0, KGSL_MEMFLAGS_GPUREADONLY, 0, "profile_desc");

	if (ADRENO_FEATURE(adreno_dev, ADRENO_APRIV))
		priv |= KGSL_MEMDESC_PRIVILEGED;

	if (IS_ERR_OR_NULL(rb->buffer_desc)) 
        // 分配adreno_ringbuffer全局共享的大小为32k偏移为4k名称为ringbuffer的内存
		rb->buffer_desc = kgsl_allocate_global(device, KGSL_RB_SIZE,
			SZ_4K, KGSL_MEMFLAGS_GPUREADONLY, priv, "ringbuffer");
		if (IS_ERR(rb->buffer_desc))
			return PTR_ERR(rb->buffer_desc);
	

	if (!list_empty(&rb->events.group))
		return 0;

	rb->id = id;
    // 将当前rb添加到kgsl_device的event_groups链表上
    // kgsl_event_group读取时间戳的方法:_rb_readtimestamp
	kgsl_add_event_group(device, &rb->events, NULL, _rb_readtimestamp, rb,
		"rb_events-%d", id);

    // 初始化rb的入队时间为0
	rb->timestamp = 0;
	init_waitqueue_head(&rb->ts_expire_waitq);

	spin_lock_init(&rb->preempt_lock);

	return 0;

以上是关于adreno源码系列adreno_ringbuffer的主要内容,如果未能解决你的问题,请参考以下文章

adreno源码系列adreno_dispatcher

adreno源码系列adreno_dispatcher

adreno源码系列启动kgsl

adreno源码系列启动kgsl

adreno源码系列打开kgsl

adreno源码系列打开kgsl