drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c
Extension
.c
Size
7170 bytes
Lines
289
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2022 MediaTek Inc.
 * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
 */

#include <linux/remoteproc.h>
#include <linux/remoteproc/mtk_scp.h>
#include "mtk-mdp3-vpu.h"
#include "mtk-mdp3-core.h"

#define MDP_VPU_MESSAGE_TIMEOUT 500U

static inline struct mdp_dev *vpu_to_mdp(struct mdp_vpu_dev *vpu)
{
	return container_of(vpu, struct mdp_dev, vpu);
}

static int mdp_vpu_shared_mem_alloc(struct mdp_vpu_dev *vpu)
{
	struct device *dev;

	if (IS_ERR_OR_NULL(vpu))
		goto err_return;

	dev = scp_get_device(vpu->scp);

	if (!vpu->param) {
		vpu->param = dma_alloc_wc(dev, vpu->param_size,
					  &vpu->param_addr, GFP_KERNEL);
		if (!vpu->param)
			goto err_return;
	}

	if (!vpu->work) {
		vpu->work = dma_alloc_wc(dev, vpu->work_size,
					 &vpu->work_addr, GFP_KERNEL);
		if (!vpu->work)
			goto err_free_param;
	}

	if (!vpu->config) {
		vpu->config = dma_alloc_wc(dev, vpu->config_size,
					   &vpu->config_addr, GFP_KERNEL);
		if (!vpu->config)
			goto err_free_work;
	}

	return 0;

err_free_work:
	dma_free_wc(dev, vpu->work_size, vpu->work, vpu->work_addr);
	vpu->work = NULL;
err_free_param:
	dma_free_wc(dev, vpu->param_size, vpu->param, vpu->param_addr);
	vpu->param = NULL;
err_return:
	return -ENOMEM;
}

void mdp_vpu_shared_mem_free(struct mdp_vpu_dev *vpu)
{
	struct device *dev;

	if (IS_ERR_OR_NULL(vpu))
		return;

	dev = scp_get_device(vpu->scp);

	if (vpu->param && vpu->param_addr)
		dma_free_wc(dev, vpu->param_size, vpu->param, vpu->param_addr);

	if (vpu->work && vpu->work_addr)
		dma_free_wc(dev, vpu->work_size, vpu->work, vpu->work_addr);

	if (vpu->config && vpu->config_addr)
		dma_free_wc(dev, vpu->config_size, vpu->config, vpu->config_addr);
}

static void mdp_vpu_ipi_handle_init_ack(void *data, unsigned int len,
					void *priv)
{
	struct mdp_ipi_init_msg *msg = (struct mdp_ipi_init_msg *)data;
	struct mdp_vpu_dev *vpu =
		(struct mdp_vpu_dev *)(unsigned long)msg->drv_data;

	if (!vpu->work_size)
		vpu->work_size = msg->work_size;

	vpu->status = msg->status;

Annotation

Implementation Notes