From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oa1-f42.google.com (mail-oa1-f42.google.com [209.85.160.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E8C29367F39 for ; Mon, 29 Jun 2026 16:03:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.42 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782748991; cv=none; b=XeLCr0eBD+Cesy0Bn5a+aoihi6Zi4Y23x7G0Zao1srMfqU1lrdoJGfHhaYZ7oPPp29uDQUczNItE0Y8exSBs15Dv5pvA6Bz4HAJvo0BOeokSQ4AQeq4oSupNJkRB059iswbiPeE5Z4gvVQyoA/iaRfmrWKzkw33PWK4AzpbdIDE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782748991; c=relaxed/simple; bh=4pBA8FIoNu9D+BaaBupYPp0BfX2tDfj8P9Iu7ahk2WA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VGKQe7g4NwDl7jfFL10DQfs2p5unuF6XhpNx9/aWx0Dh5NTz5xsUCZi3TQw0SQnEIDz/zGlAAM2Y0KdtrAlNdEDjpyOfLkA60fCZDlmh7mNRHjLG40MkTA9bOnKsHA5zWmgHNvBLcVKdPvZYQO3dJC+/fChZgg4l+FRpK1ogF0k= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=fEGMUqRk; arc=none smtp.client-ip=209.85.160.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fEGMUqRk" Received: by mail-oa1-f42.google.com with SMTP id 586e51a60fabf-448b69cfc6dso667918fac.3 for ; Mon, 29 Jun 2026 09:03:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782748989; x=1783353789; darn=vger.kernel.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=PWGDfvnrOcYCIiY6CoqWWfOA/XRmgdkxSQUH6NuLVJY=; b=fEGMUqRkjsgL1gR9gQP3wtXHEQLRpxBiN48fy3YAhX459POtjoYMnF5V36CvR8NYB1 igtHlfElTv+L886KV5HsuLoJCyLBO4Vafon0wbt6HK39p2kc5dvy2VwGc+lZzcjpL+Sk 1GWrzTASR5Pv1hYe2mQ3e864o44GimQrGeZDGjf1Bq/bein1kUtQ0txiaWt0xliUDmb0 htySL8EOr4kH1Y1xOECxmJ/NdwACNMi7XnH0pFdXQnvUjfvRagXfPkZEhLJz/sYP/VNs /ccAwxrjVn+XIF51A4ye7plKcKT6o32zd5nxJsAr1aeoShi8DmaFzVkw6SQMra2IdWtw Pt+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782748989; x=1783353789; 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=PWGDfvnrOcYCIiY6CoqWWfOA/XRmgdkxSQUH6NuLVJY=; b=fmtwezVfZaOQ+kh6reWHOLB84vfHs6vZNHcNQflgYm1U0+MI9AQOC8cngE0U4T8408 ObpBHHdPsKsHxnuKBzhE8mVlAZ4zAqa+oDM3OSC6oZ0PChEep5sJuCozYYQ2sFvRJEkp ODgdP4+p2RThemjqU5FA9wXTLiIiOCB2D/6HF+fPwK8q0f1QYQ/n8BCJ5/qREdbMsi30 2yZE3x3cUhAFphiTYWq6cams2/iNF1aSqOMu8piwaoVn5lvf24q6rs3W2VklT2VOrB2T suQxplujAyWDGG+PcuxDD2I1iguA36C2ISULsUJVuo7bMZYKONmzmRcvYEweDIHrod/w qktw== X-Gm-Message-State: AOJu0Yz5RNSRoD+YIg20tc4ZLGIbs4serp8RsTTdgQaSAtf3oTNduOnk SmviSS51fpU7TuqWNoneQIZfXT9jTsIake668Nm6rqHBo5A+CMbTkwjb X-Gm-Gg: AfdE7cn0NisXM6YmypE9JIjvRQb21b8BYkD2ErF+4FxkLcVQVoiVCfZQfRsbcP7PQ83 z5IJhFZi19JX8SaQTnXZ45KxZUjrujau6F0uQP+9q8HYLfAsBMdUSRxtojVeS/Y+tpEhabZSvTL +ysk77DEzzR+IbuPvGg6c4AWHpu9LF1MUNrjTv6UPFneEQjfadGJGn7qgIATOkyldCKGaRki2YR Dl/oXIrr+VvIdW8M1rYEWXlAwfFp2Crb+83kNohUxB7J8s1bZUo0ZoOiOi+U6RW/x24p/UBfRwl Du5/eizvGhZBA12CCYOqb92hVVvyUwROLLRTKS3lI/g3o+8vB4ttZCGO8CWGhUoPvSDCrYTH4/w +UP9l7AHVdcFnJ0Gt4XvbNyX9PlaT9mUBa/bsi+D9XSNFYO+eYu9E9llAm7p3y8fwWf+4NOKBgQ rtUT8/MVMYzRh6lnt2A8+EPMFZMcbVYf50TQA4MdqjIAi14v8cclQRPHrNA16/ew== X-Received: by 2002:a05:6871:7c01:b0:448:558e:84f1 with SMTP id 586e51a60fabf-448dcaa4efcmr81233fac.43.1782748988423; Mon, 29 Jun 2026 09:03:08 -0700 (PDT) Received: from father (76-224-4-192.lightspeed.clmboh.sbcglobal.net. [76.224.4.192]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-448db9370c9sm145868fac.1.2026.06.29.09.03.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Jun 2026 09:03:07 -0700 (PDT) From: hoff.benjamin.k@gmail.com To: mchehab@kernel.org, hverkuil+cisco@kernel.org Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org Subject: [PATCH v2 1/5] media: hws: program video DMA through remap windows Date: Mon, 29 Jun 2026 12:03:00 -0400 Message-ID: <20260629160304.154046-2-hoff.benjamin.k@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629160304.154046-1-hoff.benjamin.k@gmail.com> References: <20260629160304.154046-1-hoff.benjamin.k@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Ben Hoff Video capture DMA setup uses the BAR remap table plus per-channel device buffer offsets. Drop the stale direct writes to the legacy DMA address register and share the remap slot offset between probe-time seeding and runtime programming. --- drivers/media/pci/hws/hws_irq.c | 6 ++---- drivers/media/pci/hws/hws_pci.c | 11 +++++------ drivers/media/pci/hws/hws_reg.h | 11 ++++++----- drivers/media/pci/hws/hws_video.c | 31 +++++++------------------------ drivers/media/pci/hws/hws_video.h | 2 -- 5 files changed, 20 insertions(+), 41 deletions(-) diff --git a/drivers/media/pci/hws/hws_irq.c b/drivers/media/pci/hws/hws_irq.c index eebb4b8a5cd5..a79cc10720d7 100644 --- a/drivers/media/pci/hws/hws_irq.c +++ b/drivers/media/pci/hws/hws_irq.c @@ -60,7 +60,7 @@ static int hws_arm_next(struct hws_pcie_dev *hws, u32 ch) dev_dbg(&hws->pdev->dev, "arm_next(ch=%u): picked buffer %p\n", ch, buf); - /* Publish descriptor(s) before doorbell/MMIO kicks. */ + /* Publish descriptor(s) before MMIO capture updates. */ wmb(); /* Avoid MMIO during suspend */ @@ -79,13 +79,11 @@ static int hws_arm_next(struct hws_pcie_dev *hws, u32 ch) return -EBUSY; } - /* Also program the DMA address register directly */ + /* Program the video DMA window for the selected buffer. */ { dma_addr_t dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); hws_program_dma_for_addr(hws, ch, dma_addr); - iowrite32(lower_32_bits(dma_addr), - hws->bar0_base + HWS_REG_DMA_ADDR(ch)); } dev_dbg(&hws->pdev->dev, "arm_next(ch=%u): programmed buffer %p\n", ch, diff --git a/drivers/media/pci/hws/hws_pci.c b/drivers/media/pci/hws/hws_pci.c index 30bb7d34465b..10af6c30566a 100644 --- a/drivers/media/pci/hws/hws_pci.c +++ b/drivers/media/pci/hws/hws_pci.c @@ -315,12 +315,11 @@ static void hws_seed_channel(struct hws_pcie_dev *hws, int ch) lo &= PCI_E_BAR_ADD_MASK; - /* Program 64-bit BAR remap entry for this channel (table @ 0x208 + ch * 8) */ - writel_relaxed(hi, hws->bar0_base + - PCI_ADDR_TABLE_BASE + 0x208 + ch * 8); - writel_relaxed(lo, hws->bar0_base + - PCI_ADDR_TABLE_BASE + 0x208 + ch * 8 + - PCIE_BARADDROFSIZE); + /* Program 64-bit BAR remap entry for this channel. */ + writel_relaxed(hi, hws->bar0_base + PCI_ADDR_TABLE_BASE + + HWS_VIDEO_REMAP_SLOT_OFF(ch)); + writel_relaxed(lo, hws->bar0_base + PCI_ADDR_TABLE_BASE + + HWS_VIDEO_REMAP_SLOT_OFF(ch) + PCIE_BARADDROFSIZE); /* Program capture engine per-channel base/half */ writel_relaxed((ch + 1) * PCIEBAR_AXI_BASE + pci_addr, diff --git a/drivers/media/pci/hws/hws_reg.h b/drivers/media/pci/hws/hws_reg.h index e4fb4af44434..344cb8d011a9 100644 --- a/drivers/media/pci/hws/hws_reg.h +++ b/drivers/media/pci/hws/hws_reg.h @@ -87,11 +87,12 @@ #define HWS_REG_HDCP_STATUS (CVBS_IN_BASE + 8 * PCIE_BARADDROFSIZE) #define HWS_REG_DMA_MAX_SIZE (CVBS_IN_BASE + 9 * PCIE_BARADDROFSIZE) -/* Buffer addresses (written once during init/reset). */ -/* Base of host-visible buffer. */ -#define HWS_REG_VBUF1_ADDR (CVBS_IN_BASE + 25 * PCIE_BARADDROFSIZE) -/* Per-channel DMA address. */ -#define HWS_REG_DMA_ADDR(ch) (CVBS_IN_BASE + (26 + (ch)) * PCIE_BARADDROFSIZE) +/* + * Video DMA setup uses one BAR remap-table slot per capture channel. The + * remap-table slot supplies the host DMA page, while CVBS_IN_BUF_BASE + + * ch * 4 supplies the device-side buffer offset within that page. + */ +#define HWS_VIDEO_REMAP_SLOT_OFF(ch) (0x208 + ((ch) * 8)) /* Per-channel live buffer toggles (read-only). */ #define HWS_REG_VBUF_TOGGLE(ch) (CVBS_IN_BASE + (32 + (ch)) * PCIE_BARADDROFSIZE) diff --git a/drivers/media/pci/hws/hws_video.c b/drivers/media/pci/hws/hws_video.c index 18e4bc6901d3..b1af81d1368a 100644 --- a/drivers/media/pci/hws/hws_video.c +++ b/drivers/media/pci/hws/hws_video.c @@ -26,7 +26,6 @@ #include "hws_irq.h" #include "hws_v4l2_ioctl.h" -#define HWS_REMAP_SLOT_OFF(ch) (0x208 + (ch) * 8) /* one 64-bit slot per ch */ #define HWS_BUF_BASE_OFF(ch) (CVBS_IN_BUF_BASE + (ch) * PCIE_BARADDROFSIZE) #define HWS_HALF_SZ_OFF(ch) (CVBS_IN_BUF_BASE2 + (ch) * PCIE_BARADDROFSIZE) @@ -59,21 +58,13 @@ module_param_named(dma_window_verify, dma_window_verify, bool, 0644); MODULE_PARM_DESC(dma_window_verify, "Read back DMA window registers after programming (debug)"); -void hws_set_dma_doorbell(struct hws_pcie_dev *hws, unsigned int ch, - dma_addr_t dma, const char *tag) -{ - iowrite32(lower_32_bits(dma), hws->bar0_base + HWS_REG_DMA_ADDR(ch)); - dev_dbg(&hws->pdev->dev, "dma_doorbell ch%u: dma=0x%llx tag=%s\n", ch, - (u64)dma, tag ? tag : ""); -} - static void hws_program_dma_window(struct hws_video *vid, dma_addr_t dma) { const u32 addr_mask = PCI_E_BAR_ADD_MASK; const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK; struct hws_pcie_dev *hws = vid->parent; unsigned int ch = vid->channel_index; - u32 table_off = HWS_REMAP_SLOT_OFF(ch); + u32 table_off = HWS_VIDEO_REMAP_SLOT_OFF(ch); u32 lo = lower_32_bits(dma); u32 hi = upper_32_bits(dma); u32 pci_addr = lo & addr_low_mask; @@ -170,8 +161,6 @@ void hws_prime_next_locked(struct hws_video *vid) vid->next_prepared = next; dma = vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0); hws_program_dma_for_addr(hws, vid->channel_index, dma); - iowrite32(lower_32_bits(dma), - hws->bar0_base + HWS_REG_DMA_ADDR(vid->channel_index)); dev_dbg(&hws->pdev->dev, "ch%u pre-armed next buffer %p dma=0x%llx\n", vid->channel_index, next, (u64)dma); @@ -183,7 +172,7 @@ static bool hws_force_no_signal_frame(struct hws_video *v, const char *tag) unsigned long flags; struct hwsvideo_buffer *buf = NULL, *next = NULL; bool have_next = false; - bool doorbell = false; + bool programmed = false; if (!v) return false; @@ -239,12 +228,11 @@ static bool hws_force_no_signal_frame(struct hws_video *v, const char *tag) if (have_next && next) { dma_addr_t dma = vb2_dma_contig_plane_dma_addr(&next->vb.vb2_buf, 0); + hws_program_dma_for_addr(hws, v->channel_index, dma); - hws_set_dma_doorbell(hws, v->channel_index, dma, - tag ? tag : "nosignal_zero"); - doorbell = true; + programmed = true; } - if (doorbell) { + if (programmed) { wmb(); /* ensure descriptors visible before enabling capture */ hws_enable_video_capture(hws, v->channel_index, true); } @@ -534,7 +522,6 @@ static void hws_seed_dma_windows(struct hws_pcie_dev *hws) { const u32 addr_mask = PCI_E_BAR_ADD_MASK; const u32 addr_low_mask = PCI_E_BAR_ADD_LOWMASK; - u32 table = 0x208; /* one 64-bit entry per channel */ unsigned int ch; if (!hws || !hws->bar0_base) @@ -544,7 +531,7 @@ static void hws_seed_dma_windows(struct hws_pcie_dev *hws) if (!hws->cur_max_video_ch || hws->cur_max_video_ch > hws->max_channels) hws->cur_max_video_ch = hws->max_channels; - for (ch = 0; ch < hws->cur_max_video_ch; ch++, table += 8) { + for (ch = 0; ch < hws->cur_max_video_ch; ch++) { if (!hws->scratch_vid[ch].cpu) continue; @@ -554,6 +541,7 @@ static void hws_seed_dma_windows(struct hws_pcie_dev *hws) u32 lo = lower_32_bits(p) & addr_mask; u32 hi = upper_32_bits(p); u32 pci_addr_low = lower_32_bits(p) & addr_low_mask; + u32 table = HWS_VIDEO_REMAP_SLOT_OFF(ch); writel_relaxed(hi, hws->bar0_base + PCI_ADDR_TABLE_BASE + @@ -1128,8 +1116,6 @@ static void hws_buffer_queue(struct vb2_buffer *vb) dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); hws_program_dma_for_addr(vid->parent, vid->channel_index, dma_addr); - iowrite32(lower_32_bits(dma_addr), - hws->bar0_base + HWS_REG_DMA_ADDR(vid->channel_index)); wmb(); /* ensure descriptors visible before enabling capture */ hws_enable_video_capture(hws, vid->channel_index, true); @@ -1214,9 +1200,6 @@ static int hws_start_streaming(struct vb2_queue *q, unsigned int count) dma_addr = vb2_dma_contig_plane_dma_addr(prog_vb2, 0); hws_program_dma_for_addr(hws, v->channel_index, dma_addr); - iowrite32(lower_32_bits(dma_addr), - hws->bar0_base + - HWS_REG_DMA_ADDR(v->channel_index)); dev_dbg(&hws->pdev->dev, "start_streaming: ch=%u programmed buffer %p dma=0x%08x\n", v->channel_index, to_program, diff --git a/drivers/media/pci/hws/hws_video.h b/drivers/media/pci/hws/hws_video.h index 4feaf5b2f5a9..fcd3eca0b0c3 100644 --- a/drivers/media/pci/hws/hws_video.h +++ b/drivers/media/pci/hws/hws_video.h @@ -20,8 +20,6 @@ void hws_init_video_sys(struct hws_pcie_dev *hws, bool enable); void hws_program_dma_for_addr(struct hws_pcie_dev *hws, unsigned int ch, dma_addr_t dma); -void hws_set_dma_doorbell(struct hws_pcie_dev *hws, unsigned int ch, - dma_addr_t dma, const char *tag); int hws_video_quiesce(struct hws_pcie_dev *hws, const char *reason); void hws_video_pm_resume(struct hws_pcie_dev *hws); -- 2.54.0