Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


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
C=96 H=97 G=96

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge