drivers/media/platform/amlogic/c3/isp/c3-isp-stats.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/amlogic/c3/isp/c3-isp-stats.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/amlogic/c3/isp/c3-isp-stats.c
Extension
.c
Size
9123 bytes
Lines
327
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 OR MIT)
/*
 * Copyright (C) 2024 Amlogic, Inc. All rights reserved
 */

#include <linux/cleanup.h>
#include <linux/media/amlogic/c3-isp-config.h>
#include <linux/pm_runtime.h>

#include <media/v4l2-ioctl.h>
#include <media/v4l2-mc.h>
#include <media/videobuf2-dma-contig.h>

#include "c3-isp-common.h"
#include "c3-isp-regs.h"

/* Hardware configuration */

static void c3_isp_stats_cfg_dmawr_addr(struct c3_isp_stats *stats)
{
	u32 awb_dma_size = sizeof(struct c3_isp_awb_stats);
	u32 ae_dma_size = sizeof(struct c3_isp_ae_stats);
	u32 awb_dma_addr = stats->buff->dma_addr;
	u32 af_dma_addr;
	u32 ae_dma_addr;

	ae_dma_addr = awb_dma_addr + awb_dma_size;
	af_dma_addr = ae_dma_addr + ae_dma_size;

	c3_isp_update_bits(stats->isp, VIU_DMAWR_BADDR0,
			   VIU_DMAWR_BADDR0_AF_STATS_BASE_ADDR_MASK,
			   VIU_DMAWR_BADDR0_AF_STATS_BASE_ADDR(af_dma_addr));

	c3_isp_update_bits(stats->isp, VIU_DMAWR_BADDR1,
			   VIU_DMAWR_BADDR1_AWB_STATS_BASE_ADDR_MASK,
			   VIU_DMAWR_BADDR1_AWB_STATS_BASE_ADDR(awb_dma_addr));

	c3_isp_update_bits(stats->isp, VIU_DMAWR_BADDR2,
			   VIU_DMAWR_BADDR2_AE_STATS_BASE_ADDR_MASK,
			   VIU_DMAWR_BADDR2_AE_STATS_BASE_ADDR(ae_dma_addr));
}

static void c3_isp_stats_cfg_buff(struct c3_isp_stats *stats)
{
	stats->buff =
		list_first_entry_or_null(&stats->pending,
					 struct c3_isp_stats_buffer, list);
	if (stats->buff) {
		c3_isp_stats_cfg_dmawr_addr(stats);
		list_del(&stats->buff->list);
	}
}

void c3_isp_stats_pre_cfg(struct c3_isp_device *isp)
{
	struct c3_isp_stats *stats = &isp->stats;
	u32 dma_size;

	c3_isp_update_bits(stats->isp, ISP_AF_EN_CTRL,
			   ISP_AF_EN_CTRL_STAT_SEL_MASK,
			   ISP_AF_EN_CTRL_STAT_SEL_NEW);
	c3_isp_update_bits(stats->isp, ISP_AE_CTRL,
			   ISP_AE_CTRL_LUMA_MODE_MASK,
			   ISP_AE_CTRL_LUMA_MODE_FILTER);

	/* The unit of dma_size is 16 bytes */
	dma_size = sizeof(struct c3_isp_af_stats) / C3_ISP_DMA_SIZE_ALIGN_BYTES;
	c3_isp_update_bits(stats->isp, VIU_DMAWR_SIZE0,
			   VIU_DMAWR_SIZE0_AF_STATS_SIZE_MASK,
			   VIU_DMAWR_SIZE0_AF_STATS_SIZE(dma_size));

	dma_size = sizeof(struct c3_isp_awb_stats) /
		   C3_ISP_DMA_SIZE_ALIGN_BYTES;
	c3_isp_update_bits(stats->isp, VIU_DMAWR_SIZE0,
			   VIU_DMAWR_SIZE0_AWB_STATS_SIZE_MASK,
			   VIU_DMAWR_SIZE0_AWB_STATS_SIZE(dma_size));

	dma_size = sizeof(struct c3_isp_ae_stats) / C3_ISP_DMA_SIZE_ALIGN_BYTES;
	c3_isp_update_bits(stats->isp, VIU_DMAWR_SIZE1,
			   VIU_DMAWR_SIZE1_AE_STATS_SIZE_MASK,
			   VIU_DMAWR_SIZE1_AE_STATS_SIZE(dma_size));

	guard(spinlock_irqsave)(&stats->buff_lock);

	c3_isp_stats_cfg_buff(stats);
}

static int c3_isp_stats_querycap(struct file *file, void *fh,
				 struct v4l2_capability *cap)
{

Annotation

Implementation Notes