From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 56454E67A95 for ; Tue, 3 Mar 2026 08:43:10 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 97D7F10E670; Tue, 3 Mar 2026 08:43:09 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Auz8iccx"; dkim-atps=neutral Received: from mail-lj1-f172.google.com (mail-lj1-f172.google.com [209.85.208.172]) by gabe.freedesktop.org (Postfix) with ESMTPS id 50A1E10E66C for ; Tue, 3 Mar 2026 08:43:04 +0000 (UTC) Received: by mail-lj1-f172.google.com with SMTP id 38308e7fff4ca-389fad34e2eso87326141fa.3 for ; Tue, 03 Mar 2026 00:43:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772527383; x=1773132183; darn=lists.freedesktop.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=f6KZvaBGZ/GU736NZrNzu56KlpQD0HwXdD7kW+frTF8=; b=Auz8iccx8CiIFMqBTpcv+vVip7L3XaRNUA1OnXkcsiI2iXUvZZQHqb2o1z6oGhKlRj IxgX7EiEKVHoB6hr6QDnlV+zwfwLumXEhm8IKrYuKo+PbMkOG3bSYQPuiPrCq0TbEPsP tE4LBmSbLgFYLjBgyTIrJ2BVcMOB76WVneyUqPJG1/SWAYQC/sovKhTIfr0p+2jkpyfu jDsfCqcjCx7VnB+IDE4PcREelaVrKH81nW9+7o9EVDrdg6f9QvJYgGIwBqBuwhrer+W4 3qSEYZ86dXajpGCBvBQ49fp9XIjEg5RGSn8ItGcXJ66erWgJCcSeCmVagOBjyvjVLFqw tGDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772527383; x=1773132183; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=f6KZvaBGZ/GU736NZrNzu56KlpQD0HwXdD7kW+frTF8=; b=k8bkZ7oG16cYHXeNau0JscAfTCSv0M2YWdnaFZX3hb8bMxGTAYexof6njji+rQ+7vJ 26vtLRLCeNS7+GmQVL8tIpcyF1jAnD8NDtznj8r9cy9s0DiRqpEDZ9lIkxLBzSkrqra7 WmBYa5hx8tztNIG6ZGgU9FpFid8fXkGDWW/EkoexHqz0QtURJSNvfmE8Ac3Hnuy96vKe STIG79C0PLqSSAneum+yhWPSV1xoG20yxX5A9A+OcHjPEiQx6206hVwKfD5W4d5h+zOL EXaxNwPLWjm13q1LbFetW4SpuBxZm8P4FsryUWQTXTiAqw57VJ48JB3rKIBEWVAr8r4y WJSg== X-Forwarded-Encrypted: i=1; AJvYcCXOvEd9qMhdQkZe3L302cSjDkSPI9DFAWssXbGxSOb7niaIt57fgDw/PmGYTjMjqtY8mjdBoZTJXZs=@lists.freedesktop.org X-Gm-Message-State: AOJu0YxFIhjOc0DCVWbrJaPipjf40BWOFdcJ+/3nv/zPzYMR9yltCgpB VjZFIPU2ACCE9+jLssre8aLlLFcIoieaVJSE32Pnz5lfcu5IUb+uM+eu X-Gm-Gg: ATEYQzxnyvg0JEo/wP3YGUevVtxjnqsidR7+seOvdZQ94YHAddicrpUX205A+YqutK8 9f8jnnmYwRgFclMX7Kn2AetDft8hw5FpgXpvWSKYFEyacsnqFiHT30Sn6J3nZJ1wZwL2Vu6UMXi UFmHSBvKj8Yk5yNKtjg/W4JnOlh3OYGM9GmXW80FZaoHsSo9nkf7YhD5/Ec5xgss76HZTJeBTrN ZhrfuTNhAV6gQ5FMZp3AWQCZaqDYu25cwze7b/1QMGxGIlt1DLqRntl/akqDjUdmUbFHQ57/dfT DRI+4CO6UjGnoaCXn6p9xmwiB7NkYwgbGlskUyREnRzMkvpkAkiV1A4cJYMH0di3HaAL/5ytCOo SeDwq3o1CQSioj21W7GxjbjJAL2Xtvu9DVKs71qaskBbrO5HQ9uXT0H3lqSGExFlDgJYmXRbDUj ETD3wK4CAU3velW3fWs0rec2I= X-Received: by 2002:a2e:94c4:0:b0:387:2df:f3ee with SMTP id 38308e7fff4ca-389ff34ee5amr91156871fa.33.1772527382459; Tue, 03 Mar 2026 00:43:02 -0800 (PST) Received: from xeon ([188.163.112.72]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-389f30227a9sm32599471fa.42.2026.03.03.00.43.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Mar 2026 00:43:01 -0800 (PST) From: Svyatoslav Ryhel To: Thierry Reding , Thierry Reding , Mikko Perttunen , David Airlie , Simona Vetter , Jonathan Hunter , Sowjanya Komatineni , Luca Ceresoli , Mauro Carvalho Chehab , Greg Kroah-Hartman , Hans Verkuil , Svyatoslav Ryhel Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org, linux-media@vger.kernel.org, linux-staging@lists.linux.dev Subject: [PATCH v7 09/15] staging: media: tegra-video: tegra20: add support for second output of VI Date: Tue, 3 Mar 2026 10:42:32 +0200 Message-ID: <20260303084239.15007-10-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260303084239.15007-1-clamor95@gmail.com> References: <20260303084239.15007-1-clamor95@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" VI in Tegra20/Tegra30 has 2 VI outputs with different set of supported formats. Convert output registers to macros for simpler work with both outputs since apart formats their layout matches. Tested-by: Luca Ceresoli # tegra20, parallel camera Signed-off-by: Svyatoslav Ryhel Reviewed-by: Mikko Perttunen --- drivers/staging/media/tegra-video/tegra20.c | 83 ++++++++++++--------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/drivers/staging/media/tegra-video/tegra20.c b/drivers/staging/media/tegra-video/tegra20.c index b2e706fa727b..c8afc6f2adf2 100644 --- a/drivers/staging/media/tegra-video/tegra20.c +++ b/drivers/staging/media/tegra-video/tegra20.c @@ -28,13 +28,19 @@ #define TEGRA20_MIN_HEIGHT 32U #define TEGRA20_MAX_HEIGHT 8190U +/* Tegra20/Tegra30 has 2 outputs in VI */ +enum tegra_vi_out { + TEGRA_VI_OUT_1 = 0, + TEGRA_VI_OUT_2 = 1, +}; + /* -------------------------------------------------------------------------- * Registers */ -#define TEGRA_VI_CONT_SYNCPT_OUT_1 0x0060 -#define VI_CONT_SYNCPT_OUT_1_CONTINUOUS_SYNCPT BIT(8) -#define VI_CONT_SYNCPT_OUT_1_SYNCPT_IDX_SFT 0 +#define TEGRA_VI_CONT_SYNCPT_OUT(n) (0x0060 + (n) * 4) +#define VI_CONT_SYNCPT_OUT_CONTINUOUS_SYNCPT BIT(8) +#define VI_CONT_SYNCPT_OUT_SYNCPT_IDX_SFT 0 #define TEGRA_VI_VI_INPUT_CONTROL 0x0088 #define VI_INPUT_FIELD_DETECT BIT(27) @@ -46,6 +52,7 @@ #define VI_INPUT_YUV_INPUT_FORMAT_YVYU (3 << VI_INPUT_YUV_INPUT_FORMAT_SFT) #define VI_INPUT_INPUT_FORMAT_SFT 2 /* bits [5:2] */ #define VI_INPUT_INPUT_FORMAT_YUV422 (0 << VI_INPUT_INPUT_FORMAT_SFT) +#define VI_INPUT_INPUT_FORMAT_BAYER (2 << VI_INPUT_INPUT_FORMAT_SFT) #define VI_INPUT_VIP_INPUT_ENABLE BIT(1) #define TEGRA_VI_VI_CORE_CONTROL 0x008c @@ -66,7 +73,7 @@ #define VI_VI_CORE_CONTROL_OUTPUT_TO_EPP_SFT 2 #define VI_VI_CORE_CONTROL_OUTPUT_TO_ISP_SFT 0 -#define TEGRA_VI_VI_FIRST_OUTPUT_CONTROL 0x0090 +#define TEGRA_VI_VI_OUTPUT_CONTROL(n) (0x0090 + (n) * 4) #define VI_OUTPUT_FORMAT_EXT BIT(22) #define VI_OUTPUT_V_DIRECTION BIT(20) #define VI_OUTPUT_H_DIRECTION BIT(19) @@ -80,6 +87,8 @@ #define VI_OUTPUT_OUTPUT_FORMAT_SFT 0 #define VI_OUTPUT_OUTPUT_FORMAT_YUV422POST (3 << VI_OUTPUT_OUTPUT_FORMAT_SFT) #define VI_OUTPUT_OUTPUT_FORMAT_YUV420PLANAR (6 << VI_OUTPUT_OUTPUT_FORMAT_SFT) +/* TEGRA_VI_OUT_2 supported formats */ +#define VI_OUTPUT_OUTPUT_FORMAT_VIP_BAYER_DIRECT (9 << VI_OUTPUT_OUTPUT_FORMAT_SFT) #define TEGRA_VI_VIP_H_ACTIVE 0x00a4 #define VI_VIP_H_ACTIVE_PERIOD_SFT 16 /* active pixels/line, must be even */ @@ -89,26 +98,26 @@ #define VI_VIP_V_ACTIVE_PERIOD_SFT 16 /* active lines */ #define VI_VIP_V_ACTIVE_START_SFT 0 -#define TEGRA_VI_VB0_START_ADDRESS_FIRST 0x00c4 -#define TEGRA_VI_VB0_BASE_ADDRESS_FIRST 0x00c8 +#define TEGRA_VI_VB0_START_ADDRESS(n) (0x00c4 + (n) * 44) +#define TEGRA_VI_VB0_BASE_ADDRESS(n) (0x00c8 + (n) * 44) #define TEGRA_VI_VB0_START_ADDRESS_U 0x00cc #define TEGRA_VI_VB0_BASE_ADDRESS_U 0x00d0 #define TEGRA_VI_VB0_START_ADDRESS_V 0x00d4 #define TEGRA_VI_VB0_BASE_ADDRESS_V 0x00d8 -#define TEGRA_VI_FIRST_OUTPUT_FRAME_SIZE 0x00e0 -#define VI_FIRST_OUTPUT_FRAME_HEIGHT_SFT 16 -#define VI_FIRST_OUTPUT_FRAME_WIDTH_SFT 0 +#define TEGRA_VI_OUTPUT_FRAME_SIZE(n) (0x00e0 + (n) * 24) +#define VI_OUTPUT_FRAME_HEIGHT_SFT 16 +#define VI_OUTPUT_FRAME_WIDTH_SFT 0 -#define TEGRA_VI_VB0_COUNT_FIRST 0x00e4 +#define TEGRA_VI_VB0_COUNT(n) (0x00e4 + (n) * 24) -#define TEGRA_VI_VB0_SIZE_FIRST 0x00e8 -#define VI_VB0_SIZE_FIRST_V_SFT 16 -#define VI_VB0_SIZE_FIRST_H_SFT 0 +#define TEGRA_VI_VB0_SIZE(n) (0x00e8 + (n) * 24) +#define VI_VB0_SIZE_V_SFT 16 +#define VI_VB0_SIZE_H_SFT 0 -#define TEGRA_VI_VB0_BUFFER_STRIDE_FIRST 0x00ec -#define VI_VB0_BUFFER_STRIDE_FIRST_CHROMA_SFT 30 -#define VI_VB0_BUFFER_STRIDE_FIRST_LUMA_SFT 0 +#define TEGRA_VI_VB0_BUFFER_STRIDE(n) (0x00ec + (n) * 24) +#define VI_VB0_BUFFER_STRIDE_CHROMA_SFT 30 +#define VI_VB0_BUFFER_STRIDE_LUMA_SFT 0 #define TEGRA_VI_H_LPF_CONTROL 0x0108 #define VI_H_LPF_CONTROL_CHROMA_SFT 16 @@ -136,7 +145,7 @@ #define VI_CAMERA_CONTROL_TEST_MODE BIT(1) #define VI_CAMERA_CONTROL_VIP_ENABLE BIT(0) -#define TEGRA_VI_VI_ENABLE 0x01a4 +#define TEGRA_VI_VI_ENABLE(n) (0x01a4 + (n) * 4) #define VI_VI_ENABLE_SW_FLOW_CONTROL_OUT1 BIT(1) #define VI_VI_ENABLE_FIRST_OUTPUT_TO_MEM_DISABLE BIT(0) @@ -366,8 +375,8 @@ static void tegra20_channel_vi_buffer_setup(struct tegra_vi_channel *chan, case V4L2_PIX_FMT_VYUY: case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YVYU: - tegra20_vi_write(chan, TEGRA_VI_VB0_BASE_ADDRESS_FIRST, base); - tegra20_vi_write(chan, TEGRA_VI_VB0_START_ADDRESS_FIRST, base + chan->start_offset); + tegra20_vi_write(chan, TEGRA_VI_VB0_BASE_ADDRESS(TEGRA_VI_OUT_1), base); + tegra20_vi_write(chan, TEGRA_VI_VB0_START_ADDRESS(TEGRA_VI_OUT_1), base + chan->start_offset); break; } } @@ -455,6 +464,7 @@ static void tegra20_camera_capture_setup(struct tegra_vi_channel *chan) int stride_l = chan->format.bytesperline; int stride_c = (output_fourcc == V4L2_PIX_FMT_YUV420 || output_fourcc == V4L2_PIX_FMT_YVU420) ? 1 : 0; + enum tegra_vi_out output_channel = TEGRA_VI_OUT_1; int main_output_format; int yuv_output_format; @@ -472,33 +482,33 @@ static void tegra20_camera_capture_setup(struct tegra_vi_channel *chan) /* Set up raise-on-edge, so we get an interrupt on end of frame. */ tegra20_vi_write(chan, TEGRA_VI_VI_RAISE, VI_VI_RAISE_ON_EDGE); - tegra20_vi_write(chan, TEGRA_VI_VI_FIRST_OUTPUT_CONTROL, + tegra20_vi_write(chan, TEGRA_VI_VI_OUTPUT_CONTROL(output_channel), (chan->vflip ? VI_OUTPUT_V_DIRECTION : 0) | (chan->hflip ? VI_OUTPUT_H_DIRECTION : 0) | yuv_output_format << VI_OUTPUT_YUV_OUTPUT_FORMAT_SFT | main_output_format << VI_OUTPUT_OUTPUT_FORMAT_SFT); /* Set up frame size */ - tegra20_vi_write(chan, TEGRA_VI_FIRST_OUTPUT_FRAME_SIZE, - height << VI_FIRST_OUTPUT_FRAME_HEIGHT_SFT | - width << VI_FIRST_OUTPUT_FRAME_WIDTH_SFT); + tegra20_vi_write(chan, TEGRA_VI_OUTPUT_FRAME_SIZE(output_channel), + height << VI_OUTPUT_FRAME_HEIGHT_SFT | + width << VI_OUTPUT_FRAME_WIDTH_SFT); /* First output memory enabled */ - tegra20_vi_write(chan, TEGRA_VI_VI_ENABLE, 0); + tegra20_vi_write(chan, TEGRA_VI_VI_ENABLE(output_channel), 0); /* Set the number of frames in the buffer */ - tegra20_vi_write(chan, TEGRA_VI_VB0_COUNT_FIRST, 1); + tegra20_vi_write(chan, TEGRA_VI_VB0_COUNT(output_channel), 1); /* Set up buffer frame size */ - tegra20_vi_write(chan, TEGRA_VI_VB0_SIZE_FIRST, - height << VI_VB0_SIZE_FIRST_V_SFT | - width << VI_VB0_SIZE_FIRST_H_SFT); + tegra20_vi_write(chan, TEGRA_VI_VB0_SIZE(output_channel), + height << VI_VB0_SIZE_V_SFT | + width << VI_VB0_SIZE_H_SFT); - tegra20_vi_write(chan, TEGRA_VI_VB0_BUFFER_STRIDE_FIRST, - stride_l << VI_VB0_BUFFER_STRIDE_FIRST_LUMA_SFT | - stride_c << VI_VB0_BUFFER_STRIDE_FIRST_CHROMA_SFT); + tegra20_vi_write(chan, TEGRA_VI_VB0_BUFFER_STRIDE(output_channel), + stride_l << VI_VB0_BUFFER_STRIDE_LUMA_SFT | + stride_c << VI_VB0_BUFFER_STRIDE_CHROMA_SFT); - tegra20_vi_write(chan, TEGRA_VI_VI_ENABLE, 0); + tegra20_vi_write(chan, TEGRA_VI_VI_ENABLE(output_channel), 0); } static int tegra20_vi_start_streaming(struct vb2_queue *vq, u32 count) @@ -587,7 +597,7 @@ const struct tegra_vi_soc tegra20_vi_soc = { .nformats = ARRAY_SIZE(tegra20_video_formats), .default_video_format = &tegra20_video_formats[0], .ops = &tegra20_vi_ops, - .vi_max_channels = 1, /* parallel input (VIP) */ + .vi_max_channels = 2, /* TEGRA_VI_OUT_1 and TEGRA_VI_OUT_2 */ .vi_max_clk_hz = 150000000, .has_h_v_flip = true, }; @@ -607,6 +617,7 @@ static int tegra20_vip_start_streaming(struct tegra_vip_channel *vip_chan) struct tegra_vi_channel *vi_chan = v4l2_get_subdev_hostdata(&vip_chan->subdev); int width = vi_chan->format.width; int height = vi_chan->format.height; + enum tegra_vi_out output_channel = TEGRA_VI_OUT_1; unsigned int main_input_format; unsigned int yuv_input_format; @@ -637,10 +648,10 @@ static int tegra20_vip_start_streaming(struct tegra_vip_channel *vip_chan) GENMASK(9, 2) << VI_DATA_INPUT_SFT); tegra20_vi_write(vi_chan, TEGRA_VI_PIN_INVERSION, 0); - tegra20_vi_write(vi_chan, TEGRA_VI_CONT_SYNCPT_OUT_1, - VI_CONT_SYNCPT_OUT_1_CONTINUOUS_SYNCPT | + tegra20_vi_write(vi_chan, TEGRA_VI_CONT_SYNCPT_OUT(output_channel), + VI_CONT_SYNCPT_OUT_CONTINUOUS_SYNCPT | host1x_syncpt_id(vi_chan->mw_ack_sp[0]) - << VI_CONT_SYNCPT_OUT_1_SYNCPT_IDX_SFT); + << VI_CONT_SYNCPT_OUT_SYNCPT_IDX_SFT); tegra20_vi_write(vi_chan, TEGRA_VI_CAMERA_CONTROL, VI_CAMERA_CONTROL_STOP_CAPTURE); -- 2.51.0