Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/media/platform/qcom/camss/   (Linux Kernel Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  camss-vfe-680.c   Sprache: C

 

// SPDX-License-Identifier: GPL-2.0
/*
 * camss-vfe-680.c
 *
 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v680
 *
 * Copyright (C) 2025 Linaro Ltd.
 */


#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>

#include "camss.h"
#include "camss-vfe.h"

#define VFE_TOP_IRQn_STATUS(vfe, n)  ((vfe_is_lite(vfe) ? 0x1c : 0x44) + (n) * 4)
#define VFE_TOP_IRQn_MASK(vfe, n)  ((vfe_is_lite(vfe) ? 0x24 : 0x34) + (n) * 4)
#define VFE_TOP_IRQn_CLEAR(vfe, n)  ((vfe_is_lite(vfe) ? 0x2c : 0x3c) + (n) * 4)
#define  VFE_IRQ1_SOF(vfe, n)  ((vfe_is_lite(vfe) ? BIT(2) : BIT(8)) << ((n) * 2))
#define  VFE_IRQ1_EOF(vfe, n)  ((vfe_is_lite(vfe) ? BIT(3) : BIT(9)) << ((n) * 2))
#define VFE_TOP_IRQ_CMD(vfe)   (vfe_is_lite(vfe) ? 0x38 : 0x30)
#define  VFE_TOP_IRQ_CMD_GLOBAL_CLEAR BIT(0)
#define VFE_TOP_DIAG_CONFIG   (vfe_is_lite(vfe) ? 0x40 : 0x50)

#define VFE_TOP_DEBUG_11(vfe)   (vfe_is_lite(vfe) ? 0x40 : 0xcc)
#define VFE_TOP_DEBUG_12(vfe)   (vfe_is_lite(vfe) ? 0x40 : 0xd0)
#define VFE_TOP_DEBUG_13(vfe)   (vfe_is_lite(vfe) ? 0x40 : 0xd4)

#define VFE_BUS_IRQn_MASK(vfe, n)  ((vfe_is_lite(vfe) ? 0x218 : 0xc18) + (n) * 4)
#define VFE_BUS_IRQn_CLEAR(vfe, n)  ((vfe_is_lite(vfe) ? 0x220 : 0xc20) + (n) * 4)
#define VFE_BUS_IRQn_STATUS(vfe, n)  ((vfe_is_lite(vfe) ? 0x228 : 0xc28) + (n) * 4)
#define VFE_BUS_IRQ_GLOBAL_CLEAR(vfe)  (vfe_is_lite(vfe) ? 0x230 : 0xc30)
#define VFE_BUS_WR_VIOLATION_STATUS(vfe) (vfe_is_lite(vfe) ? 0x264 : 0xc64)
#define VFE_BUS_WR_OVERFLOW_STATUS(vfe)  (vfe_is_lite(vfe) ? 0x268 : 0xc68)
#define VFE_BUS_WR_IMAGE_VIOLATION_STATUS(vfe) (vfe_is_lite(vfe) ? 0x270 : 0xc70)

#define VFE_BUS_WRITE_CLIENT_CFG(vfe, c) ((vfe_is_lite(vfe) ? 0x400 : 0xe00) + (c) * 0x100)
#define  VFE_BUS_WRITE_CLIENT_CFG_EN BIT(0)
#define VFE_BUS_IMAGE_ADDR(vfe, c)  ((vfe_is_lite(vfe) ? 0x404 : 0xe04) + (c) * 0x100)
#define VFE_BUS_FRAME_INCR(vfe, c)  ((vfe_is_lite(vfe) ? 0x408 : 0xe08) + (c) * 0x100)
#define VFE_BUS_IMAGE_CFG0(vfe, c)  ((vfe_is_lite(vfe) ? 0x40c : 0xe0c) + (c) * 0x100)
#define  VFE_BUS_IMAGE_CFG0_DATA(h, s) (((h) << 16) | ((s) >> 4))
#define WM_IMAGE_CFG_0_DEFAULT_WIDTH  (0xFFFF)

#define VFE_BUS_IMAGE_CFG1(vfe, c)  ((vfe_is_lite(vfe) ? 0x410 : 0xe10) + (c) * 0x100)
#define VFE_BUS_IMAGE_CFG2(vfe, c)  ((vfe_is_lite(vfe) ? 0x414 : 0xe14) + (c) * 0x100)
#define VFE_BUS_PACKER_CFG(vfe, c)  ((vfe_is_lite(vfe) ? 0x418 : 0xe18) + (c) * 0x100)
#define VFE_BUS_IRQ_SUBSAMPLE_PERIOD(vfe, c) ((vfe_is_lite(vfe) ? 0x430 : 0xe30) + (c) * 0x100)
#define VFE_BUS_IRQ_SUBSAMPLE_PATTERN(vfe, c) ((vfe_is_lite(vfe) ? 0x434 : 0xe34) + (c) * 0x100)
#define VFE_BUS_FRAMEDROP_PERIOD(vfe, c) ((vfe_is_lite(vfe) ? 0x438 : 0xe38) + (c) * 0x100)
#define VFE_BUS_FRAMEDROP_PATTERN(vfe, c) ((vfe_is_lite(vfe) ? 0x43c : 0xe3c) + (c) * 0x100)
#define VFE_BUS_MMU_PREFETCH_CFG(vfe, c) ((vfe_is_lite(vfe) ? 0x460 : 0xe60) + (c) * 0x100)
#define  VFE_BUS_MMU_PREFETCH_CFG_EN BIT(0)
#define VFE_BUS_MMU_PREFETCH_MAX_OFFSET(vfe, c) ((vfe_is_lite(vfe) ? 0x464 : 0xe64) + (c) * 0x100)
#define VFE_BUS_ADDR_STATUS0(vfe, c)  ((vfe_is_lite(vfe) ? 0x470 : 0xe70) + (c) * 0x100)

/*
 * TODO: differentiate the port id based on requested type of RDI, BHIST etc
 *
 * IFE write master IDs
 *
 * VIDEO_FULL_Y  0
 * VIDEO_FULL_C  1
 * VIDEO_DS_4:1  2
 * VIDEO_DS_16:1 3
 * DISPLAY_FULL_Y 4
 * DISPLAY_FULL_C 5
 * DISPLAY_DS_4:1 6
 * DISPLAY_DS_16:1 7
 * FD_Y   8
 * FD_C   9
 * PIXEL_RAW  10
 * STATS_BE0  11
 * STATS_BHIST0  12
 * STATS_TINTLESS_BG 13
 * STATS_AWB_BG  14
 * STATS_AWB_BFW 15
 * STATS_BAF  16
 * STATS_BHIST  17
 * STATS_RS  18
 * STATS_IHIST  19
 * SPARSE_PD  20
 * PDAF_V2.0_PD_DATA 21
 * PDAF_V2.0_SAD 22
 * LCR   23
 * RDI0   24
 * RDI1   25
 * RDI2   26
 * LTM_STATS  27
 *
 * IFE Lite write master IDs
 *
 * RDI0   0
 * RDI1   1
 * RDI2   2
 * RDI3   3
 * GAMMA  4
 * BE   5
 */


/* TODO: assign an ENUM in resources and use the provided master
 *       id directly for RDI, STATS, AWB_BG, BHIST.
 *       This macro only works because RDI is all we support right now.
 */

#define RDI_WM(n)   ((vfe_is_lite(vfe) ? 0 : 24) + (n))

static void vfe_global_reset(struct vfe_device *vfe)
{
 /* VFE680 has no global reset, simply report a completion */
 complete(&vfe->reset_complete);
}

/*
 * vfe_isr - VFE module interrupt handler
 * @irq: Interrupt line
 * @dev: VFE device
 *
 * Return IRQ_HANDLED on success
 */

static irqreturn_t vfe_isr(int irq, void *dev)
{
 return IRQ_HANDLED;
}

/*
 * vfe_halt - Trigger halt on VFE module and wait to complete
 * @vfe: VFE device
 *
 * Return 0 on success or a negative error code otherwise
 */

static int vfe_halt(struct vfe_device *vfe)
{
 /* rely on vfe_disable_output() to stop the VFE */
 return 0;
}

static void vfe_disable_irq(struct vfe_device *vfe)
{
 writel(0u, vfe->base + VFE_TOP_IRQn_MASK(vfe, 0));
 writel(0u, vfe->base + VFE_TOP_IRQn_MASK(vfe, 1));
 writel(0u, vfe->base + VFE_BUS_IRQn_MASK(vfe, 0));
 writel(0u, vfe->base + VFE_BUS_IRQn_MASK(vfe, 1));
}

static void vfe_wm_update(struct vfe_device *vfe, u8 rdi, u32 addr,
     struct vfe_line *line)
{
 u8 wm = RDI_WM(rdi);

 writel(addr, vfe->base + VFE_BUS_IMAGE_ADDR(vfe, wm));
}

static void vfe_wm_start(struct vfe_device *vfe, u8 rdi, struct vfe_line *line)
{
 struct v4l2_pix_format_mplane *pix =
  &line->video_out.active_fmt.fmt.pix_mp;
 u32 stride = pix->plane_fmt[0].bytesperline;
 u32 cfg;
 u8 wm;

 cfg = VFE_BUS_IMAGE_CFG0_DATA(pix->height, stride);
 wm = RDI_WM(rdi);

 writel(cfg, vfe->base + VFE_BUS_IMAGE_CFG0(vfe, wm));
 writel(0, vfe->base + VFE_BUS_IMAGE_CFG1(vfe, wm));
 writel(stride, vfe->base + VFE_BUS_IMAGE_CFG2(vfe, wm));
 writel(0, vfe->base + VFE_BUS_PACKER_CFG(vfe, wm));

 /* Set total frame increment value */
 writel(pix->plane_fmt[0].bytesperline * pix->height,
        vfe->base + VFE_BUS_FRAME_INCR(vfe, wm));

 /* MMU */
 writel(VFE_BUS_MMU_PREFETCH_CFG_EN, vfe->base + VFE_BUS_MMU_PREFETCH_CFG(vfe, wm));
 writel(~0u, vfe->base + VFE_BUS_MMU_PREFETCH_MAX_OFFSET(vfe, wm));

 /* no dropped frames, one irq per frame */
 writel(1, vfe->base + VFE_BUS_FRAMEDROP_PATTERN(vfe, wm));
 writel(0, vfe->base + VFE_BUS_FRAMEDROP_PERIOD(vfe, wm));
 writel(1, vfe->base + VFE_BUS_IRQ_SUBSAMPLE_PATTERN(vfe, wm));
 writel(0, vfe->base + VFE_BUS_IRQ_SUBSAMPLE_PERIOD(vfe, wm));

 /* We don't process IRQs for VFE in RDI mode at the moment */
 vfe_disable_irq(vfe);

 /* Enable WM */
 writel(VFE_BUS_WRITE_CLIENT_CFG_EN,
        vfe->base + VFE_BUS_WRITE_CLIENT_CFG(vfe, wm));

 dev_dbg(vfe->camss->dev, "RDI%d WM:%d width %d height %d stride %d\n",
  rdi, wm, pix->width, pix->height, stride);
}

static void vfe_wm_stop(struct vfe_device *vfe, u8 rdi)
{
 u8 wm = RDI_WM(rdi);

 writel(0, vfe->base + VFE_BUS_WRITE_CLIENT_CFG(vfe, wm));
}

static const struct camss_video_ops vfe_video_ops_680 = {
 .queue_buffer = vfe_queue_buffer_v2,
 .flush_buffers = vfe_flush_buffers,
};

static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
{
 vfe->video_ops = vfe_video_ops_680;
}

static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
{
 int port_id = line_id;

 camss_reg_update(vfe->camss, vfe->id, port_id, false);
}

static inline void vfe_reg_update_clear(struct vfe_device *vfe,
     enum vfe_line_id line_id)
{
 int port_id = line_id;

 camss_reg_update(vfe->camss, vfe->id, port_id, true);
}

const struct vfe_hw_ops vfe_ops_680 = {
 .global_reset = vfe_global_reset,
 .hw_version = vfe_hw_version,
 .isr = vfe_isr,
 .pm_domain_off = vfe_pm_domain_off,
 .pm_domain_on = vfe_pm_domain_on,
 .subdev_init = vfe_subdev_init,
 .vfe_disable = vfe_disable,
 .vfe_enable = vfe_enable_v2,
 .vfe_halt = vfe_halt,
 .vfe_wm_start = vfe_wm_start,
 .vfe_wm_stop = vfe_wm_stop,
 .vfe_buf_done = vfe_buf_done,
 .vfe_wm_update = vfe_wm_update,
 .reg_update = vfe_reg_update,
 .reg_update_clear = vfe_reg_update_clear,
};

Messung V0.5 in Prozent
C=97 H=95 G=95

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.