From patchwork Thu Mar 4 12:03:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392737 Delivered-To: patch@linaro.org Received: by 2002:a17:906:a383:0:0:0:0 with SMTP id k3csp6374733ejz; Thu, 4 Mar 2021 14:26:43 -0800 (PST) X-Google-Smtp-Source: ABdhPJwZUvj9Fguva2F9nKdEpUj2BxiMHlaU3GjV6z/vhFGN9/I8W6ixpPdqwFLtD1K1upukcxCg X-Received: by 2002:a05:6402:b41:: with SMTP id bx1mr6791480edb.69.1614896803267; Thu, 04 Mar 2021 14:26:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614896803; cv=none; d=google.com; s=arc-20160816; b=UifqrgvS0XQIubXU3PPh3O3RunEV97f6dOwOkr5vN5cVSvMoogqra5khhgrJ2p5wp1 1BhU+mEMVXiFpFiVS8eWJHg08Ac2q+jYmzkPXk1NZOofU1xZLxES7rZCuWkIuCci7/0j 9JyYOz8joYT0jTMXsx0l734IHfWPIYeRIKilCwO8OmoR5AjcJhz42f+6fLFIr56hEtv2 B3S5/YA8Hfu8LrHwfBEOMJONo+5iNPMyWFb8PX24VcyJnwqVWU9y+gNKhn0RML9O+tyt peZNKShSizewOsAzHRKX9h6VJeOskCrkb8WzyGdFk/C+8E6gOZPL6NTjqd+i2BIMj7Uj gHzA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=SYdUbmFLa4CqUodf6s7urBxIMdr2sW5wzcZAOYTVefM=; b=amQan6Q1ItkrTboZ58F57qe9PXnxrib+ZMKVmxX1Kb09v4jvjGaAiSHxaBsYJWO81e fOEvEc852fsnBVFLvTfx6hqtXRTyD+waYT19ovejsasA2byFpjijL/UVZbQ7V6DI4lvv iV+xunqNhgAi4qaLYp43qbnH2kexRvhvIFghEujN44TL/9IDuMWbC6iUiNLvUykcSpmI wIB6NRdgpL4OsNjMYne9/dnjJw/EOjELYodacVGmtLzV00kNdC9GRVx1kb3ZgKbFLuGL XTegHHKtMoz6ZM2U3qBFbfiZ8xRj0YzhuCwp1jjnxVX+UpiGA5d/gp6zsGR/74v0DWia otUA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VB9bFJ82; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k6si527757edj.545.2021.03.04.14.26.43; Thu, 04 Mar 2021 14:26:43 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VB9bFJ82; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239814AbhCDMFh (ORCPT + 6 others); Thu, 4 Mar 2021 07:05:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239858AbhCDMF2 (ORCPT ); Thu, 4 Mar 2021 07:05:28 -0500 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 52417C0613D7 for ; Thu, 4 Mar 2021 04:04:48 -0800 (PST) Received: by mail-ed1-x52b.google.com with SMTP id b7so20950104edz.8 for ; Thu, 04 Mar 2021 04:04:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SYdUbmFLa4CqUodf6s7urBxIMdr2sW5wzcZAOYTVefM=; b=VB9bFJ82r2HxnR0kfnDjGv49wGbywPzI5rq76oxZC8ndoFOXpakVrg1XB5DRXV48G+ EWTwutPaWMWkHl/yGoc61UcoujiiMGauVmekXynMbBvK/GluIYOSuKFDUqRaZC4R1alf VEC/Zfgobnz7pDhELaf7rltRMN0NXDTS88ARL2SUL2I7e9sX4/bTXTAh9S7psli06HhW 1/qSsqaDTW0199U+bsZi56ila73XdDpDYcXv7seXBF2diKoiB46s1NfCdTtpfeTpAHe7 To5HmdDlFMN+HpdAlzO0IdYsM8w7jOdKO/+KAeJBRc5z/HpLzYL3BHF7b7iZmETAog/X oQqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SYdUbmFLa4CqUodf6s7urBxIMdr2sW5wzcZAOYTVefM=; b=FiGJeW3VmZeTC1ZOkZ1tKFKOQ4v8zYvHqFaAL3oBuZhkEc7eBxyHnp1KHie4oZp8W2 Pte00yzyAsz4YHVODg2QZH8woiLz8n0mXE23xJ+gIxC4zUbCDkdNhlLjX1iDHpIRnFUV G1JINJOq5XOGnCwk7VpukOIMy6DBCteutU/63k2HFL9yKt/RECF4/9bjsGyH6aB9jJ1I 692WUww6UKDu1kqy1y+UQHFD9mCvlrFufoAD64AtNl6QaK3eLK1PpQhlJWbVeffCmFze 2l2fgx7VqJD7q6rDrXpKhFjxcPkp58jx1r/9EXs3OdnFwRF2fQbKIoZRtPnzigjtTRla hzqA== X-Gm-Message-State: AOAM5307tSPMtzY6kxMOanm5AMpfjn9Zz1SPehImYUt56HRzQsbQ30rH l5rFqf0jruQBGarUcqmbDc1FkQ== X-Received: by 2002:a50:ec81:: with SMTP id e1mr3879534edr.0.1614859487094; Thu, 04 Mar 2021 04:04:47 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.04.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:04:46 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 01/22] media: camss: Fix vfe_isr_comp_done() documentation Date: Thu, 4 Mar 2021 13:03:06 +0100 Message-Id: <20210304120326.153966-2-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Function name in comment is wrong, and was changed to be the same as the actual function name. The comment was changed to kerneldoc format. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v1 - Bjorn: Fix function doc name & use kerneldoc format Changes since v5: - Nicolas: Fixed typo in commit message - Andrey: Added r-b drivers/media/platform/qcom/camss/camss-vfe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -- 2.27.0 diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index fae2b513b2f9..94c9ca7d5cbb 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -1076,8 +1076,8 @@ static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm) spin_unlock_irqrestore(&vfe->output_lock, flags); } -/* - * vfe_isr_wm_done - Process composite image done interrupt +/** + * vfe_isr_comp_done() - Process composite image done interrupt * @vfe: VFE Device * @comp: Composite image id */ From patchwork Thu Mar 4 12:03:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392758 Delivered-To: patch@linaro.org Received: by 2002:a17:906:a383:0:0:0:0 with SMTP id k3csp6380664ejz; Thu, 4 Mar 2021 14:34:22 -0800 (PST) X-Google-Smtp-Source: ABdhPJz65BGAJgu1C5v+m+szQJFGOAEGmP4Ap12IIOVT/am1wPXRxIMehJX75Lq5HXjv9XelEV5d X-Received: by 2002:a17:906:9714:: with SMTP id k20mr6505442ejx.519.1614896806680; Thu, 04 Mar 2021 14:26:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614896806; cv=none; d=google.com; s=arc-20160816; b=aR1GIzKgJ1qe18/s+uxoBY/ftlvZTWzRlJ0bHqWEBcibuI2btcNDAd1MWDZwCv58U2 nk4qj0HyslRAblkyZ+EcuXHPiVo1xRjzwn3v7Tj3zhM1WdxJh5Ri+BVkST4abo0Efyxo z4wJOFVPELUb/xAGjdvDgoxtvuQ+aveRwiR07BdoVtbKbS1u9bCovZ7l8Q8MzLZ2RKHO GWiKGT+276gVcHTpXLeQ41Rte58Zpma3+wjBBDCkLB1lLmBpajoitNM86/UXFPdSPMFF xCO8KW2/OeLkrSfLMuGk0h58tW+GsM1YiZtv2wRUZuZ5mVONd+TFpN/zHt5K5jLertKw OFdQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=hzjOsw+gZMqd2RylzSWRrirjORZcFF3uOV1qZMXwFSE=; b=Cb/fZtyDEXZl/11pZBFvIPGZK1q8b9LMOOn6Rj3S59xhzl4Ny+EuPnPOOZSVRaStPd dR+HO/UMhcZFu/TyN8ppnTlY8it5WNTua2MwhJbBY+PEVsbqtWUwUqI3LcM4PgVQNjCD qDCRq0ADl5b9jVubgTYGDRApMiG1bEun+REbeB2o6e5WJyMDyxD/RjCpjTPpf2kwz8xg 5C354fcDUm1ORH0szcVFr+UMCK2IdIbSXj57Wkbe8jUPFU5LKD/gz5FzZiVkMKOTtjb8 lQmq+mkXDGBMxvT94BtnOwOw6NlDtsfhKusSISSM1Z+7JqjkR4ywWYin6E7huHQmhVZW FhjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=cOig0olZ; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k6si527757edj.545.2021.03.04.14.26.46; Thu, 04 Mar 2021 14:26:46 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=cOig0olZ; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239815AbhCDMGJ (ORCPT + 6 others); Thu, 4 Mar 2021 07:06:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59858 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239856AbhCDMFj (ORCPT ); Thu, 4 Mar 2021 07:05:39 -0500 Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3E5E5C0613D9 for ; Thu, 4 Mar 2021 04:04:57 -0800 (PST) Received: by mail-ed1-x52f.google.com with SMTP id bd6so21221830edb.10 for ; Thu, 04 Mar 2021 04:04:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=hzjOsw+gZMqd2RylzSWRrirjORZcFF3uOV1qZMXwFSE=; b=cOig0olZK241cTC8s091pSXhHsUUF8f4jXtl4THVtokvO1oc/XH46Wg6SPFB1at20y cbD+XhKIestTtTqqURzLTSZtW1xhCiuDGSlSPnkr3ABqyQdfHHI778Ex4tDj9M9jJgrv 5wTXKBSA3D3LR8BKRiqI20tez2LlJCWEwmgQzpOJjJe/fqZX/Cx7dILk2ITMGWZq9svd eoUtLcMq5Mtieq1npKlSVQlifbl8mgFEK2U3ojJbVv4gnGlWpkJ+Gm5lM1V+9eZi0A1S NLvxTLT1Aeu8GX6O6Zmlssdu0QyGTeDXhw7U8h83OBJWF00is9pdUZbaZfi3VEoNKEPW gSAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=hzjOsw+gZMqd2RylzSWRrirjORZcFF3uOV1qZMXwFSE=; b=nn6n00DbyO2y5Sg16RZaGdoJ1KUErRy3C2AJ9EoOZepEDfCMSKr9G25dBrKFfhjJjq S7aZiOVRuMJbSzCElicpnoweLhbJEMtuyql4r3PC+zBBmG7cZqeA+J1W3bN7Tjt/DQnf kz/3lcZ10C4Ocyx0hTre0DOXWYdEUQ/5hosPCg7XNURlzxfNZu/9fFLGk0eF60pLELIU 9u5luMPkzPFy7zGR8gT+difDwnoIv+ePopy9PFz5ng0VMIMUkhB0TujENcQEhuvSjYry UVKvupRYkwx+DHv3FLWzRqasGjlJ7PMQjhiMFPdaxixy8z06hOoMTPCJq5ILpDQujDb+ I7ig== X-Gm-Message-State: AOAM531IyJlMzSfaNI4wLUPGfPBpx5x8uhMk3w8Nxzpi/JwDjYkGNT2x 1TVWMEdQcHFC2aw7Ass+73dB+g== X-Received: by 2002:a05:6402:2076:: with SMTP id bd22mr3863384edb.378.1614859495997; Thu, 04 Mar 2021 04:04:55 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.04.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:04:55 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 02/22] media: camss: Fix vfe_isr comment typo Date: Thu, 4 Mar 2021 13:03:07 +0100 Message-Id: <20210304120326.153966-3-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Comment refers to ISPIF, but this is incorrect. Only the VFE interrupts are handled by this function. Signed-off-by: Robert Foss Reviewed-by: Bjorn Andersson --- Changes since v1 - Bjorn: Add r-b drivers/media/platform/qcom/camss/camss-vfe-4-1.c | 2 +- drivers/media/platform/qcom/camss/camss-vfe-4-7.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) -- 2.27.0 diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c index 174a36be6f5d..a1b56b89130d 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c @@ -922,7 +922,7 @@ static void vfe_violation_read(struct vfe_device *vfe) } /* - * vfe_isr - ISPIF module interrupt handler + * vfe_isr - VFE module interrupt handler * @irq: Interrupt line * @dev: VFE device * diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c index b5704a2f119b..84c33b8f9fe3 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c @@ -1055,7 +1055,7 @@ static void vfe_violation_read(struct vfe_device *vfe) } /* - * vfe_isr - ISPIF module interrupt handler + * vfe_isr - VFE module interrupt handler * @irq: Interrupt line * @dev: VFE device * From patchwork Thu Mar 4 12:03:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 393792 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 975F0C433E6 for ; Thu, 4 Mar 2021 12:07:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 65A9A64F0B for ; Thu, 4 Mar 2021 12:07:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239895AbhCDMGn (ORCPT ); Thu, 4 Mar 2021 07:06:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60016 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239913AbhCDMGR (ORCPT ); Thu, 4 Mar 2021 07:06:17 -0500 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 50836C061764 for ; Thu, 4 Mar 2021 04:05:37 -0800 (PST) Received: by mail-ej1-x62a.google.com with SMTP id do6so48940360ejc.3 for ; Thu, 04 Mar 2021 04:05:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8e4PPUtgYSubDxzdU/QA0Sb+7wTbzZIX4nY3IAQXL6o=; b=b+Ik4tSIdjjXFBDtJHdZpZjpYoZ75tILu50BS8TA13Den5QErSSbkPLXicOXsy6eih RoMcqWIqL0nh29j7JabpIXN3ONuYOygfLbW8IqDq4SRoAoB01/s36k6Z9ZQMbf9K7I7N J2v5tYtMz0FSFMN+22bmg9tdLkYhWAl6ck+bK5xVMAp/63Z1yUDOqqaiwk3rGXdq99TO 2cOSY3a3L/W6u+yzsZmANmLSdvrDbLS1YU1DFtInVGgar8Cjb37rgDz0BDgsGcu9hVIj pET/3kqH2BlyrxA2bwGIhx18b461pbXrjM9ax3UWR0jkTqPugTYYbPvuTJqrE7TIBPI7 JHzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8e4PPUtgYSubDxzdU/QA0Sb+7wTbzZIX4nY3IAQXL6o=; b=VgKaqJELvwaiLWipZ9MAxnzR+myuP56d3PS8huguFQiskj+k0nA9yQG1txHirhYmHb QugN1JX0w/neZTAnFy4XdJDNsZ44MXNPuJqWmg8oZaVP1zeBvM11RZ7MCoBWwTnntQMc UsLCe0EM5mJWrFbrHTbbudsYNdjnOrGwW8SD/SosfAB0pTbKoyH40+WNgYp0YKkYAq1q Ms4XMK0Vii1PArK30BjQtmBsjRoB2kZUpwpVWeuWXAKc2llCu5CJ/gB82x+SDjv9WJ/Z Ll+7cHk6i/E0yGa7oKs10PCgiCNqzy8TUOWzQqZ7wKr9OJi5G7FPOuI19mA0OTgmrdk3 lrjQ== X-Gm-Message-State: AOAM532uSPVmZaGd2HuAQnfHQPZRHjjEAQrSWwDTWk9VZr7ARHda8BLp tc7/O4RL+ER54d6rIAM3rMAmlQ== X-Google-Smtp-Source: ABdhPJwYU88JLxec/eWcDh7B5kt3uF1xbGBE19bSZWATu6nii5HKVDj85hDwPbHHZ6xw3jC4NFyN7A== X-Received: by 2002:a17:906:d71:: with SMTP id s17mr3980257ejh.126.1614859536097; Thu, 04 Mar 2021 04:05:36 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:35 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek , Nicolas Boichat Subject: [PATCH v6 03/22] media: camss: Replace trace_printk() with dev_dbg() Date: Thu, 4 Mar 2021 13:03:09 +0100 Message-Id: <20210304120326.153966-4-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org trace_printk() should not be used in production code, since extra memory is used for special buffers whenever trace_puts() is used. Replace it with dev_dbg() which provides all of the desired debugging functionality. Signed-off-by: Robert Foss Suggested-by: Nicolas Boichat Reviewed-by: Nicolas Boichat --- Changes since v3: - Nicolas: Create this patch Changes since v4: - Nicolas: Add r-b drivers/media/platform/qcom/camss/camss-vfe-4-1.c | 5 +++-- drivers/media/platform/qcom/camss/camss-vfe-4-7.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c index a1b56b89130d..85b9bcbc7321 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c @@ -12,6 +12,7 @@ #include #include +#include "camss.h" #include "camss-vfe.h" #define VFE_0_HW_VERSION 0x000 @@ -936,8 +937,8 @@ static irqreturn_t vfe_isr(int irq, void *dev) vfe->ops->isr_read(vfe, &value0, &value1); - trace_printk("VFE: status0 = 0x%08x, status1 = 0x%08x\n", - value0, value1); + dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n", + value0, value1); if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK) vfe->isr_ops.reset_ack(vfe); diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c index 84c33b8f9fe3..f7e00a2de393 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c @@ -12,6 +12,7 @@ #include #include +#include "camss.h" #include "camss-vfe.h" #define VFE_0_HW_VERSION 0x000 @@ -1069,8 +1070,8 @@ static irqreturn_t vfe_isr(int irq, void *dev) vfe->ops->isr_read(vfe, &value0, &value1); - trace_printk("VFE: status0 = 0x%08x, status1 = 0x%08x\n", - value0, value1); + dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n", + value0, value1); if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK) vfe->isr_ops.reset_ack(vfe); From patchwork Thu Mar 4 12:03:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392912 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 870C4C4332E for ; Thu, 4 Mar 2021 12:07:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5F7D764F21 for ; Thu, 4 Mar 2021 12:07:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239971AbhCDMGo (ORCPT ); Thu, 4 Mar 2021 07:06:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60024 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239920AbhCDMGT (ORCPT ); Thu, 4 Mar 2021 07:06:19 -0500 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C53E9C0613D7 for ; Thu, 4 Mar 2021 04:05:38 -0800 (PST) Received: by mail-ej1-x631.google.com with SMTP id w17so972001ejc.6 for ; Thu, 04 Mar 2021 04:05:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=MrNAsI+lksN55P1mxUhC9GJybtgueSqHXzFIdFJpas8=; b=o37s/FxFXOSLE+73D3deZsq+RzFtc01V0JsX3ykLMA3Usyh7yG6slLHgKKfFAV0EUy +6c9lYwlc4F/cj4h248YwLSmO1TrF/sV2C8+RJKXEvWawEkHa8qn8GMro/6cXkze6xBx Uc7fgqUjZq9FWJExdnGYAYwtFBWHbQSly+x7m9x/99plshiQaC4XohJr/F/fptzx2Mkg VbW/Dischn1Rt57/b5D/pCrZOonWiPKrfXdYu6w5P/jX1FcwaiYQnR5iLWrj9yhMS2lA BwNK2jRbqtvvZw9utABldwh9K93Lo99bDQ8asK9k5TG0ABHD3bSG0mv4rQhwWrsX8IzU 3PpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=MrNAsI+lksN55P1mxUhC9GJybtgueSqHXzFIdFJpas8=; b=o+JKQsIqSUjFZGNKEhZn1Dz0wr9JxFcKLt420NrFAFKlYE6secV0mcYKnf3N8pjmE0 LZVL6RoRL1Uq97fHniIQlY+DNHDXudEmQ4Q4iOKyaQUgWOLzAoSOTU0JKtCvs4GCZRdR yyrVmkmWngeybe/P2tkGz3ikjaj3Zuze0FsoUUT6htIHYsvXhcbvo4fSIKr49zAtWA3i Bfjz86/PxrDCSGnJUlsxU7vln+/OtPNCEZAb7ZWlUSy08uqQypK9ZULf9yPVlynt8sPW wIFbZb7VIcVqDlpe9h+n9VVFTMa81h6NFYtGQKaRxbQ8K6KDXJvamr9wp93VhEQr16kV x5qg== X-Gm-Message-State: AOAM533gP9+H6aURvCLyq4CQKyHJWz5kD4nDeAHO1hu3bPswvyf7DolT dKrbO5LCfmN+PdH6AApT4UUiOQ== X-Google-Smtp-Source: ABdhPJwsRMy/dkEUr2PWym26wS6vzZ0RRkPgvmw3q2sv1o4CfTdjuuZB9YCeAPMmdswg9eSfW/4QJA== X-Received: by 2002:a17:906:23e9:: with SMTP id j9mr3775393ejg.78.1614859537516; Thu, 04 Mar 2021 04:05:37 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:37 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 04/22] media: camss: Add CAMSS_845 camss version Date: Thu, 4 Mar 2021 13:03:10 +0100 Message-Id: <20210304120326.153966-5-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add enum representing the SDM845 SOC, which incorporates version 170 of the Titan architecture ISP. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v5: - Andrey: Add r-b drivers/media/platform/qcom/camss/camss.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index 3a0484683cd6..46e986452824 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -66,6 +66,7 @@ enum camss_version { CAMSS_8x16, CAMSS_8x96, CAMSS_660, + CAMSS_845, }; struct camss { From patchwork Thu Mar 4 12:03:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392742 Delivered-To: patch@linaro.org Received: by 2002:a17:906:a383:0:0:0:0 with SMTP id k3csp6374938ejz; Thu, 4 Mar 2021 14:26:59 -0800 (PST) X-Google-Smtp-Source: ABdhPJwcKi/yqhhYQ1TXZV9ZWdzWx4K+9ohiKUSGayleHyyo7vZ8VfLmpBYK7f/x7nGgUwOatK5H X-Received: by 2002:a17:906:1c13:: with SMTP id k19mr6542086ejg.457.1614896819232; Thu, 04 Mar 2021 14:26:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614896819; cv=none; d=google.com; s=arc-20160816; b=P2GTlJ0i92ZsVUAcQbPQM4Nys2zdzZsEFFgMKhMUJrRnQx2kJ8FA/TdDNbTi56X6nz QIkCV/lG4jsfXXr51JjyB3hJGzInXQmBOubpoh5s+i+y9Ijf48pmF2+3SilSE9a4OeC6 KGljGY+OJiqq8l+rwzfY3BSfZMTKQlhA8aZ321INo3RyUA8GTaOdflOcfUbDw9TK+Umj Ib9JTMvSMQyLADjE60jxC+c6uOJkzWZVLsHBbpWi2kiOdDj6X4lXgI0qlSEpQjUeQ4Do rkDdBisXdXK3QBEat45FeWbANpg2/v2AKHH72gPMvHWK6QJvwUEyyjgb5PY+VYcItEKN LNHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=QOy8GMU3GIlVlgQwY/+BHT6r3Bja+cIciNTIXpsaE08=; b=Vz2l0Sjk1ypCJBYUrpVeWz5OghwAj3h23bKcw3DlsbReHYzjpA+xkYC+XvNDOs2eKY gliXF8+4XhvIIU+nPLjzjvdtRJw+UJZfpY5IHXI/hpPORvsraArqel0WTHtXyB5w/BtE Q2+6FTABDOq7EUPF7jKn/ihn3ShtmMMx38ff7DvMSNhjKjRTvFM8O6ELvOxPdTr6eJi5 yJcWBCTyXj1edwruV6bA4NdPjQ8vhJAstpiY1a6TMq5p8ZPbUYWWrWiQZdPP4Cd/2yqz WkM3rP8asNxWdWGBoInCT1Y8ruofnQuXbxFOwmPsys0e+usqXKe0ejjvscMSQnK/1djU aiLg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=lCeOpzMW; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k6si527757edj.545.2021.03.04.14.26.59; Thu, 04 Mar 2021 14:26:59 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=lCeOpzMW; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239919AbhCDMGq (ORCPT + 6 others); Thu, 4 Mar 2021 07:06:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60036 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239926AbhCDMGV (ORCPT ); Thu, 4 Mar 2021 07:06:21 -0500 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 68C61C0613DA for ; Thu, 4 Mar 2021 04:05:40 -0800 (PST) Received: by mail-ej1-x62a.google.com with SMTP id w1so48933153ejf.11 for ; Thu, 04 Mar 2021 04:05:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QOy8GMU3GIlVlgQwY/+BHT6r3Bja+cIciNTIXpsaE08=; b=lCeOpzMWf8SAsEM3mV04DGj2QDAXSjETZ9RA3UR1/ZM6/+u6pOFhVWz6I4hCK7bccz a8YttOx3JDnIQ8inm6rPbmZHD3ukvTHiujU0RUopm5wQhFHcozPf8d3nzGsuKZYEAkeM yZmzkZ0IJJg0dddT/8YL8aA3xQY9hVFOm6l8AvTRTdZX5WXXfo2kCuIDtoA5YJA8y+m5 1CK7K9gpwtwD56Y6gbX5ssxTP34RYFLIlIy0OdzTs6satGge3w+f8ilye8U/wixWjk45 nlq75RHYtn1c9NXBsZWpzdil0pgtV5qFuUzRGtltnUOepm+q6FX0JXwItPm6+xBcgkHY XwWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QOy8GMU3GIlVlgQwY/+BHT6r3Bja+cIciNTIXpsaE08=; b=OoHUGmgNeEZwp6VP/ON6RPCXC3fS0kArUO5D+Uj++XTd0G5I+why1AmKGln2vlPkPq +mC+zJgpp2wgDJyoHB72v9EeiUbiZJLfooQqbAxTIS29+2WjCt/xTmMXNPpGpS+vvbfR InmBf2QzCXDjkuyvAM2ih4Y0eNL0296vehYOdc1q/yzUNiLg53kUcoghgBkx8p9dqlIn jII9WqSPlQrjnLwJVB/HYq3z4aI7Rkd3Ftszoqf2BW0iZ0abUpALBsPLb5VA6W2h3Ap6 fk5G10wJfP1dOd547ZKo/aotBH5Ms8dDS/QR1idVwr5JHT5X6ftW/M581/fCsiIOCoIs G3Kw== X-Gm-Message-State: AOAM532YAClpYsCXpShnCK5JpwOrXM9kNbGIsy5lPFGRj58ilGvHPLY9 A70JS0Jy0IBb4OtCtUW6KNw7fg== X-Received: by 2002:a17:906:37db:: with SMTP id o27mr4004987ejc.60.1614859539094; Thu, 04 Mar 2021 04:05:39 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:38 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 05/22] media: camss: Make ISPIF subdevice optional Date: Thu, 4 Mar 2021 13:03:11 +0100 Message-Id: <20210304120326.153966-6-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This driver supports multiple architecture versions of the Qualcomm ISP. The CAMSS architecure which this driver is name after, and with the introduction of this series, the Titan architecture. The ISPIF is an IP-block that is only present in the CAMSS generation of the architecture. In order to support the Titan generation, make the ISPIF an optional subdevice. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v1: - Björn: Improved commit message - Björn: Use local 'dev' ptr instead of 'camss->dev' - Björn: Remove res/ispif NULL checks - Björn: Remove ispif NULL checks before calling msm_ispif_unregister_entities() - Andrey: Fixed incorrect allocation size Changes since v4: - Andrey: Remove !camss->ispif conditional from camss.c - Andrey: Fix !camss->ispif in camss-ispif.c - Move !camss->ispif check to msm_ispif_subdev_init() Changes since v5: - Andrey: Added r-b .../media/platform/qcom/camss/camss-ispif.c | 119 +++++++++++------- .../media/platform/qcom/camss/camss-ispif.h | 3 +- drivers/media/platform/qcom/camss/camss.c | 99 ++++++++++----- drivers/media/platform/qcom/camss/camss.h | 2 +- 4 files changed, 139 insertions(+), 84 deletions(-) -- 2.27.0 diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index adeb92808998..fc121da4ab0c 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -161,6 +161,7 @@ static const u32 ispif_formats_8x96[] = { static irqreturn_t ispif_isr_8x96(int irq, void *dev) { struct ispif_device *ispif = dev; + struct camss *camss = ispif->camss; u32 value0, value1, value2, value3, value4, value5; value0 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(0)); @@ -186,34 +187,34 @@ static irqreturn_t ispif_isr_8x96(int irq, void *dev) complete(&ispif->reset_complete[1]); if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE0 pix0 overflow\n"); if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE0 rdi0 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE0 rdi0 overflow\n"); if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE0 pix1 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE0 pix1 overflow\n"); if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE0 rdi1 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE0 rdi1 overflow\n"); if (unlikely(value2 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE0 rdi2 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE0 rdi2 overflow\n"); if (unlikely(value3 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE1 pix0 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE1 pix0 overflow\n"); if (unlikely(value3 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE1 rdi0 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE1 rdi0 overflow\n"); if (unlikely(value4 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE1 pix1 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE1 pix1 overflow\n"); if (unlikely(value4 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE1 rdi1 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE1 rdi1 overflow\n"); if (unlikely(value5 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE1 rdi2 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE1 rdi2 overflow\n"); return IRQ_HANDLED; } @@ -228,6 +229,7 @@ static irqreturn_t ispif_isr_8x96(int irq, void *dev) static irqreturn_t ispif_isr_8x16(int irq, void *dev) { struct ispif_device *ispif = dev; + struct camss *camss = ispif->camss; u32 value0, value1, value2; value0 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(0)); @@ -244,30 +246,32 @@ static irqreturn_t ispif_isr_8x16(int irq, void *dev) complete(&ispif->reset_complete[0]); if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE0 pix0 overflow\n"); if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE0 rdi0 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE0 rdi0 overflow\n"); if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE0 pix1 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE0 pix1 overflow\n"); if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE0 rdi1 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE0 rdi1 overflow\n"); if (unlikely(value2 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW)) - dev_err_ratelimited(to_device(ispif), "VFE0 rdi2 overflow\n"); + dev_err_ratelimited(camss->dev, "VFE0 rdi2 overflow\n"); return IRQ_HANDLED; } static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id) { + struct camss *camss = ispif->camss; + unsigned long time; u32 val; - if (vfe_id > (to_camss(ispif)->vfe_num - 1)) { - dev_err(to_device(ispif), + if (vfe_id > (camss->vfe_num - 1)) { + dev_err(camss->dev, "Error: asked reset for invalid VFE%d\n", vfe_id); return -ENOENT; } @@ -300,7 +304,7 @@ static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id) time = wait_for_completion_timeout(&ispif->reset_complete[vfe_id], msecs_to_jiffies(ISPIF_RESET_TIMEOUT_MS)); if (!time) { - dev_err(to_device(ispif), + dev_err(camss->dev, "ISPIF for VFE%d reset timeout\n", vfe_id); return -EIO; } @@ -316,30 +320,31 @@ static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id) */ static int ispif_reset(struct ispif_device *ispif, u8 vfe_id) { + struct camss *camss = ispif->camss; int ret; - ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE0); + ret = camss_pm_domain_on(camss, PM_DOMAIN_VFE0); if (ret < 0) return ret; - ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE1); + ret = camss_pm_domain_on(camss, PM_DOMAIN_VFE1); if (ret < 0) return ret; ret = camss_enable_clocks(ispif->nclocks_for_reset, ispif->clock_for_reset, - to_device(ispif)); + camss->dev); if (ret < 0) return ret; ret = ispif_vfe_reset(ispif, vfe_id); if (ret) - dev_dbg(to_device(ispif), "ISPIF Reset failed\n"); + dev_dbg(camss->dev, "ISPIF Reset failed\n"); camss_disable_clocks(ispif->nclocks_for_reset, ispif->clock_for_reset); - camss_pm_domain_off(to_camss(ispif), PM_DOMAIN_VFE0); - camss_pm_domain_off(to_camss(ispif), PM_DOMAIN_VFE1); + camss_pm_domain_off(camss, PM_DOMAIN_VFE0); + camss_pm_domain_off(camss, PM_DOMAIN_VFE1); return ret; } @@ -355,7 +360,7 @@ static int ispif_set_power(struct v4l2_subdev *sd, int on) { struct ispif_line *line = v4l2_get_subdevdata(sd); struct ispif_device *ispif = line->ispif; - struct device *dev = to_device(ispif); + struct device *dev = ispif->camss->dev; int ret = 0; mutex_lock(&ispif->power_lock); @@ -505,7 +510,7 @@ static int ispif_validate_intf_status(struct ispif_device *ispif, } if ((val & 0xf) != 0xf) { - dev_err(to_device(ispif), "%s: ispif is busy: 0x%x\n", + dev_err(ispif->camss->dev, "%s: ispif is busy: 0x%x\n", __func__, val); ret = -EBUSY; } @@ -552,7 +557,7 @@ static int ispif_wait_for_stop(struct ispif_device *ispif, ISPIF_TIMEOUT_SLEEP_US, ISPIF_TIMEOUT_ALL_US); if (ret < 0) - dev_err(to_device(ispif), "%s: ispif stop timeout\n", + dev_err(ispif->camss->dev, "%s: ispif stop timeout\n", __func__); return ret; @@ -800,6 +805,7 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable) { struct ispif_line *line = v4l2_get_subdevdata(sd); struct ispif_device *ispif = line->ispif; + struct camss *camss = ispif->camss; enum ispif_intf intf = line->interface; u8 csid = line->csid_id; u8 vfe = line->vfe_id; @@ -825,8 +831,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable) ispif_select_csid(ispif, intf, csid, vfe, 1); ispif_select_cid(ispif, intf, cid, vfe, 1); ispif_config_irq(ispif, intf, vfe, 1); - if (to_camss(ispif)->version == CAMSS_8x96 || - to_camss(ispif)->version == CAMSS_660) + if (camss->version == CAMSS_8x96 || + camss->version == CAMSS_660) ispif_config_pack(ispif, line->fmt[MSM_ISPIF_PAD_SINK].code, intf, cid, vfe, 1); @@ -843,8 +849,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable) return ret; mutex_lock(&ispif->config_lock); - if (to_camss(ispif)->version == CAMSS_8x96 || - to_camss(ispif)->version == CAMSS_660) + if (camss->version == CAMSS_8x96 || + camss->version == CAMSS_660) ispif_config_pack(ispif, line->fmt[MSM_ISPIF_PAD_SINK].code, intf, cid, vfe, 0); @@ -1088,26 +1094,32 @@ static int ispif_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) * * Return 0 on success or a negative error code otherwise */ -int msm_ispif_subdev_init(struct ispif_device *ispif, +int msm_ispif_subdev_init(struct camss *camss, const struct resources_ispif *res) { - struct device *dev = to_device(ispif); + struct device *dev = camss->dev; + struct ispif_device *ispif = camss->ispif; struct platform_device *pdev = to_platform_device(dev); struct resource *r; int i; int ret; + if (!camss->ispif) + return 0; + + ispif->camss = camss; + /* Number of ISPIF lines - same as number of CSID hardware modules */ - if (to_camss(ispif)->version == CAMSS_8x16) + if (camss->version == CAMSS_8x16) ispif->line_num = 2; - else if (to_camss(ispif)->version == CAMSS_8x96 || - to_camss(ispif)->version == CAMSS_660) + else if (camss->version == CAMSS_8x96 || + camss->version == CAMSS_660) ispif->line_num = 4; else return -EINVAL; - ispif->line = devm_kcalloc(dev, ispif->line_num, sizeof(*ispif->line), - GFP_KERNEL); + ispif->line = devm_kcalloc(dev, ispif->line_num, + sizeof(*ispif->line), GFP_KERNEL); if (!ispif->line) return -ENOMEM; @@ -1115,12 +1127,12 @@ int msm_ispif_subdev_init(struct ispif_device *ispif, ispif->line[i].ispif = ispif; ispif->line[i].id = i; - if (to_camss(ispif)->version == CAMSS_8x16) { + if (camss->version == CAMSS_8x16) { ispif->line[i].formats = ispif_formats_8x16; ispif->line[i].nformats = ARRAY_SIZE(ispif_formats_8x16); - } else if (to_camss(ispif)->version == CAMSS_8x96 || - to_camss(ispif)->version == CAMSS_660) { + } else if (camss->version == CAMSS_8x96 || + camss->version == CAMSS_660) { ispif->line[i].formats = ispif_formats_8x96; ispif->line[i].nformats = ARRAY_SIZE(ispif_formats_8x96); @@ -1157,15 +1169,16 @@ int msm_ispif_subdev_init(struct ispif_device *ispif, ispif->irq = r->start; snprintf(ispif->irq_name, sizeof(ispif->irq_name), "%s_%s", dev_name(dev), MSM_ISPIF_NAME); - if (to_camss(ispif)->version == CAMSS_8x16) + if (camss->version == CAMSS_8x16) ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x16, IRQF_TRIGGER_RISING, ispif->irq_name, ispif); - else if (to_camss(ispif)->version == CAMSS_8x96 || - to_camss(ispif)->version == CAMSS_660) + else if (camss->version == CAMSS_8x96 || + camss->version == CAMSS_660) ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x96, IRQF_TRIGGER_RISING, ispif->irq_name, ispif); else ret = -EINVAL; + if (ret < 0) { dev_err(dev, "request_irq failed: %d\n", ret); return ret; @@ -1331,10 +1344,15 @@ static const struct media_entity_operations ispif_media_ops = { int msm_ispif_register_entities(struct ispif_device *ispif, struct v4l2_device *v4l2_dev) { - struct device *dev = to_device(ispif); + struct camss *camss; int ret; int i; + if (!ispif) + return 0; + + camss = ispif->camss; + for (i = 0; i < ispif->line_num; i++) { struct v4l2_subdev *sd = &ispif->line[i].subdev; struct media_pad *pads = ispif->line[i].pads; @@ -1348,7 +1366,7 @@ int msm_ispif_register_entities(struct ispif_device *ispif, ret = ispif_init_formats(sd, NULL); if (ret < 0) { - dev_err(dev, "Failed to init format: %d\n", ret); + dev_err(camss->dev, "Failed to init format: %d\n", ret); goto error; } @@ -1360,13 +1378,15 @@ int msm_ispif_register_entities(struct ispif_device *ispif, ret = media_entity_pads_init(&sd->entity, MSM_ISPIF_PADS_NUM, pads); if (ret < 0) { - dev_err(dev, "Failed to init media entity: %d\n", ret); + dev_err(camss->dev, "Failed to init media entity: %d\n", + ret); goto error; } ret = v4l2_device_register_subdev(v4l2_dev, sd); if (ret < 0) { - dev_err(dev, "Failed to register subdev: %d\n", ret); + dev_err(camss->dev, "Failed to register subdev: %d\n", + ret); media_entity_cleanup(&sd->entity); goto error; } @@ -1393,6 +1413,9 @@ void msm_ispif_unregister_entities(struct ispif_device *ispif) { int i; + if (!ispif) + return; + mutex_destroy(&ispif->power_lock); mutex_destroy(&ispif->config_lock); diff --git a/drivers/media/platform/qcom/camss/camss-ispif.h b/drivers/media/platform/qcom/camss/camss-ispif.h index 4132174f7ea1..fdf28e68cc7d 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.h +++ b/drivers/media/platform/qcom/camss/camss-ispif.h @@ -63,11 +63,12 @@ struct ispif_device { struct mutex config_lock; unsigned int line_num; struct ispif_line *line; + struct camss *camss; }; struct resources_ispif; -int msm_ispif_subdev_init(struct ispif_device *ispif, +int msm_ispif_subdev_init(struct camss *camss, const struct resources_ispif *res); int msm_ispif_register_entities(struct ispif_device *ispif, diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 7c0f669f8aa6..5ac2dfc67c8b 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -745,10 +745,10 @@ static int camss_init_subdevices(struct camss *camss) } } - ret = msm_ispif_subdev_init(&camss->ispif, ispif_res); + ret = msm_ispif_subdev_init(camss, ispif_res); if (ret < 0) { dev_err(camss->dev, "Failed to init ispif sub-device: %d\n", - ret); + ret); return ret; } @@ -798,10 +798,11 @@ static int camss_register_entities(struct camss *camss) } } - ret = msm_ispif_register_entities(&camss->ispif, &camss->v4l2_dev); + ret = msm_ispif_register_entities(camss->ispif, + &camss->v4l2_dev); if (ret < 0) { dev_err(camss->dev, "Failed to register ispif entities: %d\n", - ret); + ret); goto err_reg_ispif; } @@ -835,43 +836,64 @@ static int camss_register_entities(struct camss *camss) } } - for (i = 0; i < camss->csid_num; i++) { - for (j = 0; j < camss->ispif.line_num; j++) { - ret = media_create_pad_link( - &camss->csid[i].subdev.entity, - MSM_CSID_PAD_SRC, - &camss->ispif.line[j].subdev.entity, - MSM_ISPIF_PAD_SINK, - 0); - if (ret < 0) { - dev_err(camss->dev, - "Failed to link %s->%s entities: %d\n", - camss->csid[i].subdev.entity.name, - camss->ispif.line[j].subdev.entity.name, - ret); - goto err_link; - } - } - } - - for (i = 0; i < camss->ispif.line_num; i++) - for (k = 0; k < camss->vfe_num; k++) - for (j = 0; j < ARRAY_SIZE(camss->vfe[k].line); j++) { + if (camss->ispif) { + for (i = 0; i < camss->csid_num; i++) { + for (j = 0; j < camss->ispif->line_num; j++) { ret = media_create_pad_link( - &camss->ispif.line[i].subdev.entity, - MSM_ISPIF_PAD_SRC, - &camss->vfe[k].line[j].subdev.entity, - MSM_VFE_PAD_SINK, + &camss->csid[i].subdev.entity, + MSM_CSID_PAD_SRC, + &camss->ispif->line[j].subdev.entity, + MSM_ISPIF_PAD_SINK, 0); if (ret < 0) { dev_err(camss->dev, "Failed to link %s->%s entities: %d\n", - camss->ispif.line[i].subdev.entity.name, - camss->vfe[k].line[j].subdev.entity.name, + camss->csid[i].subdev.entity.name, + camss->ispif->line[j].subdev.entity.name, ret); goto err_link; } } + } + + for (i = 0; i < camss->ispif->line_num; i++) + for (k = 0; k < camss->vfe_num; k++) + for (j = 0; j < ARRAY_SIZE(camss->vfe[k].line); j++) { + ret = media_create_pad_link( + &camss->ispif->line[i].subdev.entity, + MSM_ISPIF_PAD_SRC, + &camss->vfe[k].line[j].subdev.entity, + MSM_VFE_PAD_SINK, + 0); + if (ret < 0) { + dev_err(camss->dev, + "Failed to link %s->%s entities: %d\n", + camss->ispif->line[i].subdev.entity.name, + camss->vfe[k].line[j].subdev.entity.name, + ret); + goto err_link; + } + } + } else { + for (i = 0; i < camss->csid_num; i++) + for (k = 0; k < camss->vfe_num; k++) + for (j = 0; j < ARRAY_SIZE(camss->vfe[k].line); j++) { + ret = media_create_pad_link( + &camss->csid[i].subdev.entity, + MSM_CSID_PAD_SRC, + &camss->vfe[k].line[j].subdev.entity, + MSM_VFE_PAD_SINK, + 0); + if (ret < 0) { + dev_err(camss->dev, + "Failed to link %s->%s entities: %d\n", + camss->csid[i].subdev.entity.name, + camss->vfe[k].line[j].subdev.entity.name, + ret); + goto err_link; + } + } + } return 0; @@ -881,8 +903,8 @@ static int camss_register_entities(struct camss *camss) for (i--; i >= 0; i--) msm_vfe_unregister_entities(&camss->vfe[i]); - msm_ispif_unregister_entities(&camss->ispif); err_reg_ispif: + msm_ispif_unregister_entities(camss->ispif); i = camss->csid_num; err_reg_csid: @@ -913,7 +935,7 @@ static void camss_unregister_entities(struct camss *camss) for (i = 0; i < camss->csid_num; i++) msm_csid_unregister_entity(&camss->csid[i]); - msm_ispif_unregister_entities(&camss->ispif); + msm_ispif_unregister_entities(camss->ispif); for (i = 0; i < camss->vfe_num; i++) msm_vfe_unregister_entities(&camss->vfe[i]); @@ -1044,6 +1066,15 @@ static int camss_probe(struct platform_device *pdev) goto err_free; } + if (camss->version == CAMSS_8x16 || + camss->version == CAMSS_8x96) { + camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL); + if (!camss->ispif) { + ret = -ENOMEM; + goto err_free; + } + } + camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe), GFP_KERNEL); if (!camss->vfe) { diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index 46e986452824..b7ad8e9f68a8 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -79,7 +79,7 @@ struct camss { struct csiphy_device *csiphy; int csid_num; struct csid_device *csid; - struct ispif_device ispif; + struct ispif_device *ispif; int vfe_num; struct vfe_device *vfe; atomic_t ref_count; From patchwork Thu Mar 4 12:03:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 393787 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 575FCC15501 for ; Thu, 4 Mar 2021 12:07:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3650A64F21 for ; Thu, 4 Mar 2021 12:07:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239934AbhCDMGq (ORCPT ); Thu, 4 Mar 2021 07:06:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60052 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239931AbhCDMGY (ORCPT ); Thu, 4 Mar 2021 07:06:24 -0500 Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [IPv6:2a00:1450:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1ECA0C0613E2 for ; Thu, 4 Mar 2021 04:05:43 -0800 (PST) Received: by mail-ed1-x52d.google.com with SMTP id w9so18303335edt.13 for ; Thu, 04 Mar 2021 04:05:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=w9mn0HBqWO0FI+ftDhVbXmvfMYaYMPDMKPURE5IDLIU=; b=vxveE80L1z0nVEGDquD1JaQ2QM5WS8Wb/XhQFtvQwR1u5+yeh8V85EFCEUA92XF+z4 gxxPkV3BzQEBTp+9Uos/T+F7dxv+K/1hQPnOw6ptdDRmEj60VVR0leLJXoJQ5eVjj83E g3nx23lMh7N93UTLs8Yqqd3a86u4Im5hcviDOdZlt5zmVgJI3UjVMVDN5Vo5LdJtQLKt V503ze68PaV4EgkGZQnnlEOfs3KJ8eytqgnsOHQ0BHYhuQ9EfBv/nsjBJpnaIBAP2ItW ACfoD28gtSSkuKQ2VRCRhs4G0jhIj+5ucp3bxC93HXNIy+LY9fmniR2E/+lIDp5g1NZz +WnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=w9mn0HBqWO0FI+ftDhVbXmvfMYaYMPDMKPURE5IDLIU=; b=YYzAng/v3ny9a7nVPoHRot/wg8jq0+UrKOmt9IBIGBY89ZffDCwIIHAgBe0iHdQyFC BuYo5kqHp5xfuktHqN+6HZWOzQGp14IKTSOoQIV3y3pocLBNHhQwjMv+XtrjXVU8Fosf Mwy9HBNzS3VTxau0/QHI7Pwdmuby0Q0Bu67U4orj0iYGXYUWDeF0lfUEkFtt6b7eKMkC uWMVJxCH7XYuJxAad7DhBb9NJ5Mh6ylyNapIsR1FvSlEghRvkfiF/EmceSG8Arc6ax02 KLsNCUMJLhcjo2syQeG2bhGGaCEJHpBUrLqjrEFPagq+2f0oeP1btqRYKhxmrOsfDkaV TaoQ== X-Gm-Message-State: AOAM533tMgVaT5GeQnSWtufvfF7exoEasC2ZWfwFes33YA0oadCAJYhR fF79Q34xq8WqeZ9EUOQ3V9KMIA== X-Google-Smtp-Source: ABdhPJzmVIVfL5b7BJNufy90KeF6/XNpaxPjOngPCqfRTeoUkwGuHlsc5vONs0HgWheHjw6AL2LhdQ== X-Received: by 2002:aa7:c497:: with SMTP id m23mr3957776edq.74.1614859540907; Thu, 04 Mar 2021 04:05:40 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:40 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 06/22] media: camss: Refactor VFE HW version support Date: Thu, 4 Mar 2021 13:03:12 +0100 Message-Id: <20210304120326.153966-7-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org In order to support Qualcomm ISP hardware architectures that diverge from older architectures, the VFE subdevice driver needs to be refactored to better abstract the different ISP architectures. Gen1 represents the CAMSS ISP architecture. The ISP architecture developed after CAMSS, Titan, will be referred to as Gen2. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v1 - kernel test robot: Re-add chunk missing from vfe_output_update_pong_addr - Andrey: Fix file name error - Andrey: Change hardware version number in comment - Changed copyright year to 2021 for camss-vfe-4-8.c Changes since v3: - Nicolas: Replace trace_printk() with dev_dbg() - Removed spurious whitespace Changes since v4: - Andrey: Refactor to make PIX support optional Changes since v5: - Andrey: Fix function description - Andrey: Change RDI/PIX iteration to use vfe->line_num - Andrey: Added r-b drivers/media/platform/qcom/camss/Makefile | 2 + .../media/platform/qcom/camss/camss-vfe-4-1.c | 118 +- .../media/platform/qcom/camss/camss-vfe-4-7.c | 241 ++-- .../media/platform/qcom/camss/camss-vfe-4-8.c | 1166 +++++++++++++++++ .../platform/qcom/camss/camss-vfe-gen1.c | 763 +++++++++++ .../platform/qcom/camss/camss-vfe-gen1.h | 110 ++ drivers/media/platform/qcom/camss/camss-vfe.c | 790 +---------- drivers/media/platform/qcom/camss/camss-vfe.h | 121 +- drivers/media/platform/qcom/camss/camss.c | 4 +- 9 files changed, 2264 insertions(+), 1051 deletions(-) create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-4-8.c create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-gen1.c create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-gen1.h diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile index 63c1b1b2943c..940c0ae3e003 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -10,6 +10,8 @@ qcom-camss-objs += \ camss-ispif.o \ camss-vfe-4-1.o \ camss-vfe-4-7.o \ + camss-vfe-4-8.o \ + camss-vfe-gen1.o \ camss-vfe.o \ camss-video.o \ diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c index 85b9bcbc7321..81756d7fd5c2 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c @@ -14,6 +14,7 @@ #include "camss.h" #include "camss-vfe.h" +#include "camss-vfe-gen1.h" #define VFE_0_HW_VERSION 0x000 @@ -284,30 +285,6 @@ static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable) 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT); } -#define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N)) - -static int vfe_word_per_line(u32 format, u32 pixel_per_line) -{ - int val = 0; - - switch (format) { - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - val = CALC_WORD(pixel_per_line, 1, 8); - break; - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - val = CALC_WORD(pixel_per_line, 2, 8); - break; - } - - return val; -} - static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane, u16 *width, u16 *height, u16 *bytesperline) { @@ -666,20 +643,6 @@ static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line) writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG); } -static inline u8 vfe_calc_interp_reso(u16 input, u16 output) -{ - if (input / output >= 16) - return 0; - - if (input / output >= 8) - return 1; - - if (input / output >= 4) - return 2; - - return 3; -} - static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line) { u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; @@ -975,46 +938,63 @@ static irqreturn_t vfe_isr(int irq, void *dev) return IRQ_HANDLED; } -const struct vfe_hw_ops vfe_ops_4_1 = { - .hw_version_read = vfe_hw_version_read, + +const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_1 = { + .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi, + .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi, + .bus_enable_wr_if = vfe_bus_enable_wr_if, + .bus_reload_wm = vfe_bus_reload_wm, + .camif_wait_for_stop = vfe_camif_wait_for_stop, + .enable_irq_common = vfe_enable_irq_common, + .enable_irq_pix_line = vfe_enable_irq_pix_line, + .enable_irq_wm_line = vfe_enable_irq_wm_line, .get_ub_size = vfe_get_ub_size, - .global_reset = vfe_global_reset, - .halt_request = vfe_halt_request, .halt_clear = vfe_halt_clear, + .halt_request = vfe_halt_request, + .set_camif_cfg = vfe_set_camif_cfg, + .set_camif_cmd = vfe_set_camif_cmd, + .set_cgc_override = vfe_set_cgc_override, + .set_clamp_cfg = vfe_set_clamp_cfg, + .set_crop_cfg = vfe_set_crop_cfg, + .set_demux_cfg = vfe_set_demux_cfg, + .set_ds = vfe_set_ds, + .set_module_cfg = vfe_set_module_cfg, + .set_qos = vfe_set_qos, + .set_rdi_cid = vfe_set_rdi_cid, + .set_realign_cfg = vfe_set_realign_cfg, + .set_scale_cfg = vfe_set_scale_cfg, + .set_xbar_cfg = vfe_set_xbar_cfg, .wm_enable = vfe_wm_enable, .wm_frame_based = vfe_wm_frame_based, + .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status, .wm_line_based = vfe_wm_line_based, - .wm_set_framedrop_period = vfe_wm_set_framedrop_period, .wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern, - .wm_set_ub_cfg = vfe_wm_set_ub_cfg, - .bus_reload_wm = vfe_bus_reload_wm, + .wm_set_framedrop_period = vfe_wm_set_framedrop_period, .wm_set_ping_addr = vfe_wm_set_ping_addr, .wm_set_pong_addr = vfe_wm_set_pong_addr, - .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status, - .bus_enable_wr_if = vfe_bus_enable_wr_if, - .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi, .wm_set_subsample = vfe_wm_set_subsample, - .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi, - .set_xbar_cfg = vfe_set_xbar_cfg, - .set_realign_cfg = vfe_set_realign_cfg, - .set_rdi_cid = vfe_set_rdi_cid, - .reg_update = vfe_reg_update, - .reg_update_clear = vfe_reg_update_clear, - .enable_irq_wm_line = vfe_enable_irq_wm_line, - .enable_irq_pix_line = vfe_enable_irq_pix_line, - .enable_irq_common = vfe_enable_irq_common, - .set_demux_cfg = vfe_set_demux_cfg, - .set_scale_cfg = vfe_set_scale_cfg, - .set_crop_cfg = vfe_set_crop_cfg, - .set_clamp_cfg = vfe_set_clamp_cfg, - .set_qos = vfe_set_qos, - .set_ds = vfe_set_ds, - .set_cgc_override = vfe_set_cgc_override, - .set_camif_cfg = vfe_set_camif_cfg, - .set_camif_cmd = vfe_set_camif_cmd, - .set_module_cfg = vfe_set_module_cfg, - .camif_wait_for_stop = vfe_camif_wait_for_stop, + .wm_set_ub_cfg = vfe_wm_set_ub_cfg, +}; + +static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe) +{ + vfe->isr_ops = vfe_isr_ops_gen1; + vfe->ops_gen1 = &vfe_ops_gen1_4_1; + vfe->video_ops = vfe_video_ops_gen1; + + vfe->line_num = VFE_LINE_NUM_GEN1; +} + +const struct vfe_hw_ops vfe_ops_4_1 = { + .global_reset = vfe_global_reset, + .hw_version_read = vfe_hw_version_read, .isr_read = vfe_isr_read, - .violation_read = vfe_violation_read, .isr = vfe_isr, + .reg_update_clear = vfe_reg_update_clear, + .reg_update = vfe_reg_update, + .subdev_init = vfe_subdev_init, + .vfe_disable = vfe_gen1_disable, + .vfe_enable = vfe_gen1_enable, + .vfe_halt = vfe_gen1_halt, + .violation_read = vfe_violation_read, }; diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c index f7e00a2de393..5ecb87f1b047 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c @@ -14,6 +14,8 @@ #include "camss.h" #include "camss-vfe.h" +#include "camss-vfe-gen1.h" + #define VFE_0_HW_VERSION 0x000 @@ -258,7 +260,7 @@ static void vfe_hw_version_read(struct vfe_device *vfe, struct device *dev) dev_err(dev, "VFE HW Version = 0x%08x\n", hw_version); } -static u16 vfe47_get_ub_size(u8 vfe_id) +static u16 vfe_get_ub_size(u8 vfe_id) { if (vfe_id == 0) return MSM_VFE_VFE0_UB_SIZE_RDI; @@ -296,6 +298,8 @@ static void vfe_global_reset(struct vfe_device *vfe) VFE_0_GLOBAL_RESET_CMD_CORE; writel_relaxed(BIT(31), vfe->base + VFE_0_IRQ_MASK_0); + + /* Enforce barrier between IRQ mask setup and global reset */ wmb(); writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD); } @@ -311,7 +315,7 @@ static void vfe_halt_clear(struct vfe_device *vfe) writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD); } -static void vfe47_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) +static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) { if (enable) vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm), @@ -460,8 +464,12 @@ static void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm, static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm) { + /* Enforce barrier between any outstanding register write */ wmb(); + writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD); + + /* Use barrier to make sure bus reload is issued before anything else */ wmb(); } @@ -675,8 +683,12 @@ static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid) static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) { vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id); + + /* Enforce barrier between line update and commit */ wmb(); writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE); + + /* Make sure register update is issued before further reg writes */ wmb(); } @@ -780,20 +792,6 @@ static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line) writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG); } -static inline u8 vfe_calc_interp_reso(u16 input, u16 output) -{ - if (input / output >= 16) - return 0; - - if (input / output >= 8) - return 1; - - if (input / output >= 4) - return 2; - - return 3; -} - static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line) { u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; @@ -895,7 +893,7 @@ static void vfe_set_clamp_cfg(struct vfe_device *vfe) writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG); } -static void vfe47_set_qos(struct vfe_device *vfe) +static void vfe_set_qos(struct vfe_device *vfe) { u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG; u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG; @@ -910,7 +908,7 @@ static void vfe47_set_qos(struct vfe_device *vfe) writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7); } -static void vfe47_set_ds(struct vfe_device *vfe) +static void vfe_set_ds(struct vfe_device *vfe) { u32 val = VFE_0_BUS_BDG_DS_CFG_0_CFG; u32 val16 = VFE_0_BUS_BDG_DS_CFG_16_CFG; @@ -994,6 +992,8 @@ static void vfe_set_camif_cmd(struct vfe_device *vfe, u8 enable) cmd = VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS | VFE_0_CAMIF_CMD_NO_CHANGE; writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD); + + /* Make sure camif command is issued written before it is changed again */ wmb(); if (enable) @@ -1036,24 +1036,7 @@ static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev) return ret; } -static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1) -{ - *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0); - *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1); - writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0); - writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1); - - wmb(); - writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD); -} - -static void vfe_violation_read(struct vfe_device *vfe) -{ - u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS); - - pr_err_ratelimited("VFE: violation = 0x%08x\n", violation); -} /* * vfe_isr - VFE module interrupt handler @@ -1082,7 +1065,7 @@ static irqreturn_t vfe_isr(int irq, void *dev) if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK) vfe->isr_ops.halt_ack(vfe); - for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++) + for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i)) vfe->isr_ops.reg_update(vfe, i); @@ -1108,150 +1091,82 @@ static irqreturn_t vfe_isr(int irq, void *dev) return IRQ_HANDLED; } -const struct vfe_hw_ops vfe_ops_4_7 = { - .hw_version_read = vfe_hw_version_read, - .get_ub_size = vfe47_get_ub_size, - .global_reset = vfe_global_reset, - .halt_request = vfe_halt_request, - .halt_clear = vfe_halt_clear, - .wm_enable = vfe47_wm_enable, - .wm_frame_based = vfe_wm_frame_based, - .wm_line_based = vfe_wm_line_based, - .wm_set_framedrop_period = vfe_wm_set_framedrop_period, - .wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern, - .wm_set_ub_cfg = vfe_wm_set_ub_cfg, - .bus_reload_wm = vfe_bus_reload_wm, - .wm_set_ping_addr = vfe_wm_set_ping_addr, - .wm_set_pong_addr = vfe_wm_set_pong_addr, - .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status, - .bus_enable_wr_if = vfe_bus_enable_wr_if, - .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi, - .wm_set_subsample = vfe_wm_set_subsample, - .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi, - .set_xbar_cfg = vfe_set_xbar_cfg, - .set_realign_cfg = vfe_set_realign_cfg, - .set_rdi_cid = vfe_set_rdi_cid, - .reg_update = vfe_reg_update, - .reg_update_clear = vfe_reg_update_clear, - .enable_irq_wm_line = vfe_enable_irq_wm_line, - .enable_irq_pix_line = vfe_enable_irq_pix_line, - .enable_irq_common = vfe_enable_irq_common, - .set_demux_cfg = vfe_set_demux_cfg, - .set_scale_cfg = vfe_set_scale_cfg, - .set_crop_cfg = vfe_set_crop_cfg, - .set_clamp_cfg = vfe_set_clamp_cfg, - .set_qos = vfe47_set_qos, - .set_ds = vfe47_set_ds, - .set_cgc_override = vfe_set_cgc_override, - .set_camif_cfg = vfe_set_camif_cfg, - .set_camif_cmd = vfe_set_camif_cmd, - .set_module_cfg = vfe_set_module_cfg, - .camif_wait_for_stop = vfe_camif_wait_for_stop, - .isr_read = vfe_isr_read, - .violation_read = vfe_violation_read, - .isr = vfe_isr, -}; - -static u16 vfe48_get_ub_size(u8 vfe_id) +static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1) { - /* On VFE4.8 the ub-size is the same on both instances */ - return MSM_VFE_VFE0_UB_SIZE_RDI; -} + *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0); + *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1); -static void vfe48_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) -{ - if (enable) - writel_relaxed(2 << VFE48_0_BUS_IMAGE_MASTER_n_SHIFT(wm), - vfe->base + VFE48_0_BUS_IMAGE_MASTER_CMD); - else - writel_relaxed(1 << VFE48_0_BUS_IMAGE_MASTER_n_SHIFT(wm), - vfe->base + VFE48_0_BUS_IMAGE_MASTER_CMD); + writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0); + writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1); - /* The WM must be enabled before sending other commands */ + /* Enforce barrier between local & global IRQ clear */ wmb(); + writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD); } -static void vfe48_set_qos(struct vfe_device *vfe) -{ - u32 val = VFE48_0_BUS_BDG_QOS_CFG_0_CFG; - u32 val3 = VFE48_0_BUS_BDG_QOS_CFG_3_CFG; - u32 val4 = VFE48_0_BUS_BDG_QOS_CFG_4_CFG; - u32 val7 = VFE48_0_BUS_BDG_QOS_CFG_7_CFG; - - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2); - writel_relaxed(val3, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3); - writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4); - writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5); - writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6); - writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7); -} - -static void vfe48_set_ds(struct vfe_device *vfe) +static void vfe_violation_read(struct vfe_device *vfe) { - u32 val = VFE48_0_BUS_BDG_DS_CFG_0_CFG; - u32 val16 = VFE48_0_BUS_BDG_DS_CFG_16_CFG; + u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_0); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_1); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_2); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_3); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_4); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_5); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_6); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_7); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_8); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_9); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_10); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_11); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_12); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_13); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_14); - writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_15); - writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16); + pr_err_ratelimited("VFE: violation = 0x%08x\n", violation); } -const struct vfe_hw_ops vfe_ops_4_8 = { - .hw_version_read = vfe_hw_version_read, - .get_ub_size = vfe48_get_ub_size, - .global_reset = vfe_global_reset, - .halt_request = vfe_halt_request, +const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_7 = { + .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi, + .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi, + .bus_enable_wr_if = vfe_bus_enable_wr_if, + .bus_reload_wm = vfe_bus_reload_wm, + .camif_wait_for_stop = vfe_camif_wait_for_stop, + .enable_irq_common = vfe_enable_irq_common, + .enable_irq_pix_line = vfe_enable_irq_pix_line, + .enable_irq_wm_line = vfe_enable_irq_wm_line, + .get_ub_size = vfe_get_ub_size, .halt_clear = vfe_halt_clear, - .wm_enable = vfe48_wm_enable, + .halt_request = vfe_halt_request, + .set_camif_cfg = vfe_set_camif_cfg, + .set_camif_cmd = vfe_set_camif_cmd, + .set_cgc_override = vfe_set_cgc_override, + .set_clamp_cfg = vfe_set_clamp_cfg, + .set_crop_cfg = vfe_set_crop_cfg, + .set_demux_cfg = vfe_set_demux_cfg, + .set_ds = vfe_set_ds, + .set_module_cfg = vfe_set_module_cfg, + .set_qos = vfe_set_qos, + .set_rdi_cid = vfe_set_rdi_cid, + .set_realign_cfg = vfe_set_realign_cfg, + .set_scale_cfg = vfe_set_scale_cfg, + .set_xbar_cfg = vfe_set_xbar_cfg, + .wm_enable = vfe_wm_enable, .wm_frame_based = vfe_wm_frame_based, + .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status, .wm_line_based = vfe_wm_line_based, - .wm_set_framedrop_period = vfe_wm_set_framedrop_period, .wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern, - .wm_set_ub_cfg = vfe_wm_set_ub_cfg, - .bus_reload_wm = vfe_bus_reload_wm, + .wm_set_framedrop_period = vfe_wm_set_framedrop_period, .wm_set_ping_addr = vfe_wm_set_ping_addr, .wm_set_pong_addr = vfe_wm_set_pong_addr, - .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status, - .bus_enable_wr_if = vfe_bus_enable_wr_if, - .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi, .wm_set_subsample = vfe_wm_set_subsample, - .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi, - .set_xbar_cfg = vfe_set_xbar_cfg, - .set_realign_cfg = vfe_set_realign_cfg, - .set_rdi_cid = vfe_set_rdi_cid, - .reg_update = vfe_reg_update, - .reg_update_clear = vfe_reg_update_clear, - .enable_irq_wm_line = vfe_enable_irq_wm_line, - .enable_irq_pix_line = vfe_enable_irq_pix_line, - .enable_irq_common = vfe_enable_irq_common, - .set_demux_cfg = vfe_set_demux_cfg, - .set_scale_cfg = vfe_set_scale_cfg, - .set_crop_cfg = vfe_set_crop_cfg, - .set_clamp_cfg = vfe_set_clamp_cfg, - .set_qos = vfe48_set_qos, - .set_ds = vfe48_set_ds, - .set_cgc_override = vfe_set_cgc_override, - .set_camif_cfg = vfe_set_camif_cfg, - .set_camif_cmd = vfe_set_camif_cmd, - .set_module_cfg = vfe_set_module_cfg, - .camif_wait_for_stop = vfe_camif_wait_for_stop, + .wm_set_ub_cfg = vfe_wm_set_ub_cfg, +}; + +static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe) +{ + vfe->isr_ops = vfe_isr_ops_gen1; + vfe->ops_gen1 = &vfe_ops_gen1_4_7; + vfe->video_ops = vfe_video_ops_gen1; + + vfe->line_num = VFE_LINE_NUM_GEN1; +} + +const struct vfe_hw_ops vfe_ops_4_7 = { + .global_reset = vfe_global_reset, + .hw_version_read = vfe_hw_version_read, .isr_read = vfe_isr_read, - .violation_read = vfe_violation_read, .isr = vfe_isr, + .reg_update_clear = vfe_reg_update_clear, + .reg_update = vfe_reg_update, + .subdev_init = vfe_subdev_init, + .vfe_disable = vfe_gen1_disable, + .vfe_enable = vfe_gen1_enable, + .vfe_halt = vfe_gen1_halt, + .violation_read = vfe_violation_read, }; diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c new file mode 100644 index 000000000000..732b93b365d3 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c @@ -0,0 +1,1166 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-vfe-4-8.c + * + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.8 + * + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2021 Linaro Ltd. + */ + +#include +#include +#include + +#include "camss.h" +#include "camss-vfe.h" +#include "camss-vfe-gen1.h" + + +#define VFE_0_HW_VERSION 0x000 + +#define VFE_0_GLOBAL_RESET_CMD 0x018 +#define VFE_0_GLOBAL_RESET_CMD_CORE BIT(0) +#define VFE_0_GLOBAL_RESET_CMD_CAMIF BIT(1) +#define VFE_0_GLOBAL_RESET_CMD_BUS BIT(2) +#define VFE_0_GLOBAL_RESET_CMD_BUS_BDG BIT(3) +#define VFE_0_GLOBAL_RESET_CMD_REGISTER BIT(4) +#define VFE_0_GLOBAL_RESET_CMD_PM BIT(5) +#define VFE_0_GLOBAL_RESET_CMD_BUS_MISR BIT(6) +#define VFE_0_GLOBAL_RESET_CMD_TESTGEN BIT(7) +#define VFE_0_GLOBAL_RESET_CMD_DSP BIT(8) +#define VFE_0_GLOBAL_RESET_CMD_IDLE_CGC BIT(9) + +#define VFE_0_MODULE_LENS_EN 0x040 +#define VFE_0_MODULE_LENS_EN_DEMUX BIT(2) +#define VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE BIT(3) + +#define VFE_0_MODULE_ZOOM_EN 0x04c +#define VFE_0_MODULE_ZOOM_EN_SCALE_ENC BIT(1) +#define VFE_0_MODULE_ZOOM_EN_CROP_ENC BIT(2) +#define VFE_0_MODULE_ZOOM_EN_REALIGN_BUF BIT(9) + +#define VFE_0_CORE_CFG 0x050 +#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR 0x4 +#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB 0x5 +#define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY 0x6 +#define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY 0x7 +#define VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN BIT(4) + +#define VFE_0_IRQ_CMD 0x058 +#define VFE_0_IRQ_CMD_GLOBAL_CLEAR BIT(0) + +#define VFE_0_IRQ_MASK_0 0x05c +#define VFE_0_IRQ_MASK_0_CAMIF_SOF BIT(0) +#define VFE_0_IRQ_MASK_0_CAMIF_EOF BIT(1) +#define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n) BIT((n) + 5) +#define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n) \ + ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)) +#define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8) +#define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25) +#define VFE_0_IRQ_MASK_0_RESET_ACK BIT(31) +#define VFE_0_IRQ_MASK_1 0x060 +#define VFE_0_IRQ_MASK_1_CAMIF_ERROR BIT(0) +#define VFE_0_IRQ_MASK_1_VIOLATION BIT(7) +#define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK BIT(8) +#define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n) BIT((n) + 9) +#define VFE_0_IRQ_MASK_1_RDIn_SOF(n) BIT((n) + 29) + +#define VFE_0_IRQ_CLEAR_0 0x064 +#define VFE_0_IRQ_CLEAR_1 0x068 + +#define VFE_0_IRQ_STATUS_0 0x06c +#define VFE_0_IRQ_STATUS_0_CAMIF_SOF BIT(0) +#define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n) BIT((n) + 5) +#define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n) \ + ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n)) +#define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8) +#define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25) +#define VFE_0_IRQ_STATUS_0_RESET_ACK BIT(31) +#define VFE_0_IRQ_STATUS_1 0x070 +#define VFE_0_IRQ_STATUS_1_VIOLATION BIT(7) +#define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK BIT(8) +#define VFE_0_IRQ_STATUS_1_RDIn_SOF(n) BIT((n) + 29) + +#define VFE_0_IRQ_COMPOSITE_MASK_0 0x074 +#define VFE_0_VIOLATION_STATUS 0x07c + +#define VFE_0_BUS_CMD 0x80 +#define VFE_0_BUS_CMD_Mx_RLD_CMD(x) BIT(x) + +#define VFE_0_BUS_CFG 0x084 + +#define VFE_0_BUS_XBAR_CFG_x(x) (0x90 + 0x4 * ((x) / 2)) +#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN BIT(2) +#define VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN BIT(3) +#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTRA (0x1 << 4) +#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER (0x2 << 4) +#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA (0x3 << 4) +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT 8 +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA 0x0 +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 0xc +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 0xd +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 0xe + +#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n) (0x0a0 + 0x2c * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT 0 +#define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n) (0x0a4 + 0x2c * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n) (0x0ac + 0x2c * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n) (0x0b4 + 0x2c * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT 1 +#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT 2 +#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK (0x1f << 2) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n) (0x0b8 + 0x2c * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT 16 +#define VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(n) (0x0bc + 0x2c * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(n) (0x0c0 + 0x2c * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n) \ + (0x0c4 + 0x2c * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n) \ + (0x0c8 + 0x2c * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF 0xffffffff + +#define VFE_0_BUS_PING_PONG_STATUS 0x338 + +#define VFE_0_BUS_BDG_CMD 0x400 +#define VFE_0_BUS_BDG_CMD_HALT_REQ 1 + +#define VFE_0_BUS_BDG_QOS_CFG_0 0x404 +#define VFE_0_BUS_BDG_QOS_CFG_0_CFG 0xaaa5aaa5 +#define VFE_0_BUS_BDG_QOS_CFG_1 0x408 +#define VFE_0_BUS_BDG_QOS_CFG_2 0x40c +#define VFE_0_BUS_BDG_QOS_CFG_3 0x410 +#define VFE_0_BUS_BDG_QOS_CFG_3_CFG 0xaa55aaa5 +#define VFE_0_BUS_BDG_QOS_CFG_4 0x414 +#define VFE_0_BUS_BDG_QOS_CFG_4_CFG 0xaa55aa55 +#define VFE_0_BUS_BDG_QOS_CFG_5 0x418 +#define VFE_0_BUS_BDG_QOS_CFG_6 0x41c +#define VFE_0_BUS_BDG_QOS_CFG_7 0x420 +#define VFE_0_BUS_BDG_QOS_CFG_7_CFG 0x0005aa55 + +#define VFE_0_BUS_BDG_DS_CFG_0 0x424 +#define VFE_0_BUS_BDG_DS_CFG_0_CFG 0xcccc1111 +#define VFE_0_BUS_BDG_DS_CFG_1 0x428 +#define VFE_0_BUS_BDG_DS_CFG_2 0x42c +#define VFE_0_BUS_BDG_DS_CFG_3 0x430 +#define VFE_0_BUS_BDG_DS_CFG_4 0x434 +#define VFE_0_BUS_BDG_DS_CFG_5 0x438 +#define VFE_0_BUS_BDG_DS_CFG_6 0x43c +#define VFE_0_BUS_BDG_DS_CFG_7 0x440 +#define VFE_0_BUS_BDG_DS_CFG_8 0x444 +#define VFE_0_BUS_BDG_DS_CFG_9 0x448 +#define VFE_0_BUS_BDG_DS_CFG_10 0x44c +#define VFE_0_BUS_BDG_DS_CFG_11 0x450 +#define VFE_0_BUS_BDG_DS_CFG_12 0x454 +#define VFE_0_BUS_BDG_DS_CFG_13 0x458 +#define VFE_0_BUS_BDG_DS_CFG_14 0x45c +#define VFE_0_BUS_BDG_DS_CFG_15 0x460 +#define VFE_0_BUS_BDG_DS_CFG_16 0x464 +#define VFE_0_BUS_BDG_DS_CFG_16_CFG 0x00000110 + +#define VFE_0_RDI_CFG_x(x) (0x46c + (0x4 * (x))) +#define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT 28 +#define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK (0xf << 28) +#define VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT 4 +#define VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK (0xf << 4) +#define VFE_0_RDI_CFG_x_RDI_EN_BIT BIT(2) +#define VFE_0_RDI_CFG_x_MIPI_EN_BITS 0x3 + +#define VFE_0_CAMIF_CMD 0x478 +#define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY 0 +#define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY 1 +#define VFE_0_CAMIF_CMD_NO_CHANGE 3 +#define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS BIT(2) +#define VFE_0_CAMIF_CFG 0x47c +#define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN BIT(6) +#define VFE_0_CAMIF_FRAME_CFG 0x484 +#define VFE_0_CAMIF_WINDOW_WIDTH_CFG 0x488 +#define VFE_0_CAMIF_WINDOW_HEIGHT_CFG 0x48c +#define VFE_0_CAMIF_SUBSAMPLE_CFG 0x490 +#define VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN 0x498 +#define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN 0x49c +#define VFE_0_CAMIF_STATUS 0x4a4 +#define VFE_0_CAMIF_STATUS_HALT BIT(31) + +#define VFE_0_REG_UPDATE 0x4ac +#define VFE_0_REG_UPDATE_RDIn(n) BIT(1 + (n)) +#define VFE_0_REG_UPDATE_line_n(n) \ + ((n) == VFE_LINE_PIX ? 1 : VFE_0_REG_UPDATE_RDIn(n)) + +#define VFE_0_DEMUX_CFG 0x560 +#define VFE_0_DEMUX_CFG_PERIOD 0x3 +#define VFE_0_DEMUX_GAIN_0 0x564 +#define VFE_0_DEMUX_GAIN_0_CH0_EVEN (0x80 << 0) +#define VFE_0_DEMUX_GAIN_0_CH0_ODD (0x80 << 16) +#define VFE_0_DEMUX_GAIN_1 0x568 +#define VFE_0_DEMUX_GAIN_1_CH1 (0x80 << 0) +#define VFE_0_DEMUX_GAIN_1_CH2 (0x80 << 16) +#define VFE_0_DEMUX_EVEN_CFG 0x574 +#define VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV 0x9cac +#define VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU 0xac9c +#define VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY 0xc9ca +#define VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY 0xcac9 +#define VFE_0_DEMUX_ODD_CFG 0x578 +#define VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV 0x9cac +#define VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU 0xac9c +#define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY 0xc9ca +#define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY 0xcac9 + +#define VFE_0_SCALE_ENC_Y_CFG 0x91c +#define VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE 0x920 +#define VFE_0_SCALE_ENC_Y_H_PHASE 0x924 +#define VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE 0x934 +#define VFE_0_SCALE_ENC_Y_V_PHASE 0x938 +#define VFE_0_SCALE_ENC_CBCR_CFG 0x948 +#define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE 0x94c +#define VFE_0_SCALE_ENC_CBCR_H_PHASE 0x950 +#define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE 0x960 +#define VFE_0_SCALE_ENC_CBCR_V_PHASE 0x964 + +#define VFE_0_CROP_ENC_Y_WIDTH 0x974 +#define VFE_0_CROP_ENC_Y_HEIGHT 0x978 +#define VFE_0_CROP_ENC_CBCR_WIDTH 0x97c +#define VFE_0_CROP_ENC_CBCR_HEIGHT 0x980 + +#define VFE_0_CLAMP_ENC_MAX_CFG 0x984 +#define VFE_0_CLAMP_ENC_MAX_CFG_CH0 (0xff << 0) +#define VFE_0_CLAMP_ENC_MAX_CFG_CH1 (0xff << 8) +#define VFE_0_CLAMP_ENC_MAX_CFG_CH2 (0xff << 16) +#define VFE_0_CLAMP_ENC_MIN_CFG 0x988 +#define VFE_0_CLAMP_ENC_MIN_CFG_CH0 (0x0 << 0) +#define VFE_0_CLAMP_ENC_MIN_CFG_CH1 (0x0 << 8) +#define VFE_0_CLAMP_ENC_MIN_CFG_CH2 (0x0 << 16) + +#define VFE_0_REALIGN_BUF_CFG 0xaac +#define VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL BIT(2) +#define VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL BIT(3) +#define VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE BIT(4) + +#define VFE_0_BUS_IMAGE_MASTER_CMD 0xcec +#define VFE_0_BUS_IMAGE_MASTER_n_SHIFT(x) (2 * (x)) + +#define CAMIF_TIMEOUT_SLEEP_US 1000 +#define CAMIF_TIMEOUT_ALL_US 1000000 + +#define MSM_VFE_VFE0_UB_SIZE 2047 +#define MSM_VFE_VFE0_UB_SIZE_RDI (MSM_VFE_VFE0_UB_SIZE / 3) +#define MSM_VFE_VFE1_UB_SIZE 1535 +#define MSM_VFE_VFE1_UB_SIZE_RDI (MSM_VFE_VFE1_UB_SIZE / 3) + +static void vfe_hw_version_read(struct vfe_device *vfe, struct device *dev) +{ + u32 hw_version = readl_relaxed(vfe->base + VFE_0_HW_VERSION); + + dev_err(dev, "VFE HW Version = 0x%08x\n", hw_version); +} + +static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits) +{ + u32 bits = readl_relaxed(vfe->base + reg); + + writel_relaxed(bits & ~clr_bits, vfe->base + reg); +} + +static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits) +{ + u32 bits = readl_relaxed(vfe->base + reg); + + writel_relaxed(bits | set_bits, vfe->base + reg); +} + +static void vfe_global_reset(struct vfe_device *vfe) +{ + u32 reset_bits = VFE_0_GLOBAL_RESET_CMD_IDLE_CGC | + VFE_0_GLOBAL_RESET_CMD_DSP | + VFE_0_GLOBAL_RESET_CMD_TESTGEN | + VFE_0_GLOBAL_RESET_CMD_BUS_MISR | + VFE_0_GLOBAL_RESET_CMD_PM | + VFE_0_GLOBAL_RESET_CMD_REGISTER | + VFE_0_GLOBAL_RESET_CMD_BUS_BDG | + VFE_0_GLOBAL_RESET_CMD_BUS | + VFE_0_GLOBAL_RESET_CMD_CAMIF | + VFE_0_GLOBAL_RESET_CMD_CORE; + + writel_relaxed(BIT(31), vfe->base + VFE_0_IRQ_MASK_0); + + /* Enforce barrier between IRQ mask setup and global reset */ + wmb(); + writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD); +} + +static void vfe_halt_request(struct vfe_device *vfe) +{ + writel_relaxed(VFE_0_BUS_BDG_CMD_HALT_REQ, + vfe->base + VFE_0_BUS_BDG_CMD); +} + +static void vfe_halt_clear(struct vfe_device *vfe) +{ + writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD); +} + +static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable) +{ + if (enable) + vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm), + 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT); + else + vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm), + 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT); +} + +#define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N)) + +static int vfe_word_per_line_by_pixel(u32 format, u32 pixel_per_line) +{ + int val = 0; + + switch (format) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + val = CALC_WORD(pixel_per_line, 1, 8); + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: + val = CALC_WORD(pixel_per_line, 2, 8); + break; + } + + return val; +} + +static int vfe_word_per_line_by_bytes(u32 bytes_per_line) +{ + return CALC_WORD(bytes_per_line, 1, 8); +} + +static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane, + u16 *width, u16 *height, u16 *bytesperline) +{ + switch (pix->pixelformat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + *width = pix->width; + *height = pix->height; + *bytesperline = pix->plane_fmt[0].bytesperline; + if (plane == 1) + *height /= 2; + break; + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + *width = pix->width; + *height = pix->height; + *bytesperline = pix->plane_fmt[0].bytesperline; + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_UYVY: + *width = pix->width; + *height = pix->height; + *bytesperline = pix->plane_fmt[plane].bytesperline; + break; + + } +} + +static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm, + struct v4l2_pix_format_mplane *pix, + u8 plane, u32 enable) +{ + u32 reg; + + if (enable) { + u16 width = 0, height = 0, bytesperline = 0, wpl; + + vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline); + + wpl = vfe_word_per_line_by_pixel(pix->pixelformat, width); + + reg = height - 1; + reg |= ((wpl + 3) / 4 - 1) << 16; + + writel_relaxed(reg, vfe->base + + VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm)); + + wpl = vfe_word_per_line_by_bytes(bytesperline); + + reg = 0x3; + reg |= (height - 1) << 2; + reg |= ((wpl + 1) / 2) << 16; + + writel_relaxed(reg, vfe->base + + VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm)); + } else { + writel_relaxed(0, vfe->base + + VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm)); + writel_relaxed(0, vfe->base + + VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm)); + } +} + +static void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per) +{ + u32 reg; + + reg = readl_relaxed(vfe->base + + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm)); + + reg &= ~(VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK); + + reg |= (per << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT) + & VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK; + + writel_relaxed(reg, + vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm)); +} + +static void vfe_wm_set_framedrop_pattern(struct vfe_device *vfe, u8 wm, + u32 pattern) +{ + writel_relaxed(pattern, + vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm)); +} + +static void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm, + u16 offset, u16 depth) +{ + u32 reg; + + reg = (offset << VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT) | + depth; + writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm)); +} + +static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm) +{ + /* Enforce barrier between any outstanding register write */ + wmb(); + + writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD); + + /* Use barrier to make sure bus reload is issued before anything else */ + wmb(); +} + +static void vfe_wm_set_ping_addr(struct vfe_device *vfe, u8 wm, u32 addr) +{ + writel_relaxed(addr, + vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm)); +} + +static void vfe_wm_set_pong_addr(struct vfe_device *vfe, u8 wm, u32 addr) +{ + writel_relaxed(addr, + vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm)); +} + +static int vfe_wm_get_ping_pong_status(struct vfe_device *vfe, u8 wm) +{ + u32 reg; + + reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS); + + return (reg >> wm) & 0x1; +} + +static void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable) +{ + if (enable) + writel_relaxed(0x101, vfe->base + VFE_0_BUS_CFG); + else + writel_relaxed(0, vfe->base + VFE_0_BUS_CFG); +} + +static void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm, + enum vfe_line_id id) +{ + u32 reg; + + reg = VFE_0_RDI_CFG_x_MIPI_EN_BITS; + vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), reg); + + reg = VFE_0_RDI_CFG_x_RDI_EN_BIT; + reg |= ((3 * id) << VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT) & + VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK; + vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), reg); + + switch (id) { + case VFE_LINE_RDI0: + default: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + break; + case VFE_LINE_RDI1: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + break; + case VFE_LINE_RDI2: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + break; + } + + if (wm % 2 == 1) + reg <<= 16; + + vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg); +} + +static void vfe_wm_set_subsample(struct vfe_device *vfe, u8 wm) +{ + writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF, + vfe->base + + VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm)); +} + +static void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm, + enum vfe_line_id id) +{ + u32 reg; + + reg = VFE_0_RDI_CFG_x_RDI_EN_BIT; + vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), reg); + + switch (id) { + case VFE_LINE_RDI0: + default: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + break; + case VFE_LINE_RDI1: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + break; + case VFE_LINE_RDI2: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + break; + } + + if (wm % 2 == 1) + reg <<= 16; + + vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg); +} + +static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output, + u8 enable) +{ + struct vfe_line *line = container_of(output, struct vfe_line, output); + u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; + u32 reg; + + switch (p) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + + if (output->wm_idx[0] % 2 == 1) + reg <<= 16; + + if (enable) + vfe_reg_set(vfe, + VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), + reg); + else + vfe_reg_clr(vfe, + VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), + reg); + + reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN; + if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16) + reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA; + + if (output->wm_idx[1] % 2 == 1) + reg <<= 16; + + if (enable) + vfe_reg_set(vfe, + VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]), + reg); + else + vfe_reg_clr(vfe, + VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]), + reg); + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_UYVY: + reg = VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN; + reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN; + + if (p == V4L2_PIX_FMT_YUYV || p == V4L2_PIX_FMT_YVYU) + reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA; + + if (output->wm_idx[0] % 2 == 1) + reg <<= 16; + + if (enable) + vfe_reg_set(vfe, + VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), + reg); + else + vfe_reg_clr(vfe, + VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), + reg); + break; + default: + break; + } +} + +static void vfe_set_realign_cfg(struct vfe_device *vfe, struct vfe_line *line, + u8 enable) +{ + u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; + u32 val = VFE_0_MODULE_ZOOM_EN_REALIGN_BUF; + + if (p != V4L2_PIX_FMT_YUYV && p != V4L2_PIX_FMT_YVYU && + p != V4L2_PIX_FMT_VYUY && p != V4L2_PIX_FMT_UYVY) + return; + + if (enable) { + vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val); + } else { + vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val); + return; + } + + val = VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE; + + if (p == V4L2_PIX_FMT_UYVY || p == V4L2_PIX_FMT_YUYV) + val |= VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL; + else + val |= VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL; + + writel_relaxed(val, vfe->base + VFE_0_REALIGN_BUF_CFG); +} + +static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid) +{ + vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), + VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK); + + vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), + cid << VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT); +} + +static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) +{ + vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id); + + /* Enforce barrier between line update and commit */ + wmb(); + + writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE); + + /* Make sure register update is issued before further reg writes */ + wmb(); +} + +static inline void vfe_reg_update_clear(struct vfe_device *vfe, + enum vfe_line_id line_id) +{ + vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id); +} + +static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm, + enum vfe_line_id line_id, u8 enable) +{ + u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) | + VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id); + u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm) | + VFE_0_IRQ_MASK_1_RDIn_SOF(line_id); + + if (enable) { + vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); + vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); + } else { + vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0); + vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1); + } +} + +static void vfe_enable_irq_pix_line(struct vfe_device *vfe, u8 comp, + enum vfe_line_id line_id, u8 enable) +{ + struct vfe_output *output = &vfe->line[line_id].output; + unsigned int i; + u32 irq_en0; + u32 irq_en1; + u32 comp_mask = 0; + + irq_en0 = VFE_0_IRQ_MASK_0_CAMIF_SOF; + irq_en0 |= VFE_0_IRQ_MASK_0_CAMIF_EOF; + irq_en0 |= VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(comp); + irq_en0 |= VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id); + irq_en1 = VFE_0_IRQ_MASK_1_CAMIF_ERROR; + for (i = 0; i < output->wm_num; i++) { + irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW( + output->wm_idx[i]); + comp_mask |= (1 << output->wm_idx[i]) << comp * 8; + } + + if (enable) { + vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); + vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); + vfe_reg_set(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask); + } else { + vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0); + vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1); + vfe_reg_clr(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask); + } +} + +static void vfe_enable_irq_common(struct vfe_device *vfe) +{ + u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK; + u32 irq_en1 = VFE_0_IRQ_MASK_1_VIOLATION | + VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK; + + vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); + vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); +} + +static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line) +{ + u32 val, even_cfg, odd_cfg; + + writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG); + + val = VFE_0_DEMUX_GAIN_0_CH0_EVEN | VFE_0_DEMUX_GAIN_0_CH0_ODD; + writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0); + + val = VFE_0_DEMUX_GAIN_1_CH1 | VFE_0_DEMUX_GAIN_1_CH2; + writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1); + + switch (line->fmt[MSM_VFE_PAD_SINK].code) { + case MEDIA_BUS_FMT_YUYV8_2X8: + even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV; + odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV; + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU; + odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU; + break; + case MEDIA_BUS_FMT_UYVY8_2X8: + default: + even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY; + odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY; + break; + case MEDIA_BUS_FMT_VYUY8_2X8: + even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY; + odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY; + break; + } + + writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG); + writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG); +} + +static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line) +{ + u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; + u32 reg; + u16 input, output; + u8 interp_reso; + u32 phase_mult; + + writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG); + + input = line->fmt[MSM_VFE_PAD_SINK].width - 1; + output = line->compose.width - 1; + reg = (output << 16) | input; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE); + + interp_reso = vfe_calc_interp_reso(input, output); + phase_mult = input * (1 << (14 + interp_reso)) / output; + reg = (interp_reso << 28) | phase_mult; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE); + + input = line->fmt[MSM_VFE_PAD_SINK].height - 1; + output = line->compose.height - 1; + reg = (output << 16) | input; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE); + + interp_reso = vfe_calc_interp_reso(input, output); + phase_mult = input * (1 << (14 + interp_reso)) / output; + reg = (interp_reso << 28) | phase_mult; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE); + + writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG); + + input = line->fmt[MSM_VFE_PAD_SINK].width - 1; + output = line->compose.width / 2 - 1; + reg = (output << 16) | input; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE); + + interp_reso = vfe_calc_interp_reso(input, output); + phase_mult = input * (1 << (14 + interp_reso)) / output; + reg = (interp_reso << 28) | phase_mult; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE); + + input = line->fmt[MSM_VFE_PAD_SINK].height - 1; + output = line->compose.height - 1; + if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) + output = line->compose.height / 2 - 1; + reg = (output << 16) | input; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE); + + interp_reso = vfe_calc_interp_reso(input, output); + phase_mult = input * (1 << (14 + interp_reso)) / output; + reg = (interp_reso << 28) | phase_mult; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE); +} + +static void vfe_set_crop_cfg(struct vfe_device *vfe, struct vfe_line *line) +{ + u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; + u32 reg; + u16 first, last; + + first = line->crop.left; + last = line->crop.left + line->crop.width - 1; + reg = (first << 16) | last; + writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH); + + first = line->crop.top; + last = line->crop.top + line->crop.height - 1; + reg = (first << 16) | last; + writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT); + + first = line->crop.left / 2; + last = line->crop.left / 2 + line->crop.width / 2 - 1; + reg = (first << 16) | last; + writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH); + + first = line->crop.top; + last = line->crop.top + line->crop.height - 1; + if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) { + first = line->crop.top / 2; + last = line->crop.top / 2 + line->crop.height / 2 - 1; + } + reg = (first << 16) | last; + writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT); +} + +static void vfe_set_clamp_cfg(struct vfe_device *vfe) +{ + u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 | + VFE_0_CLAMP_ENC_MAX_CFG_CH1 | + VFE_0_CLAMP_ENC_MAX_CFG_CH2; + + writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG); + + val = VFE_0_CLAMP_ENC_MIN_CFG_CH0 | + VFE_0_CLAMP_ENC_MIN_CFG_CH1 | + VFE_0_CLAMP_ENC_MIN_CFG_CH2; + + writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG); +} + +static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable) +{ + /* empty */ +} + +static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line) +{ + u32 val; + + switch (line->fmt[MSM_VFE_PAD_SINK].code) { + case MEDIA_BUS_FMT_YUYV8_2X8: + val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR; + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB; + break; + case MEDIA_BUS_FMT_UYVY8_2X8: + default: + val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY; + break; + case MEDIA_BUS_FMT_VYUY8_2X8: + val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY; + break; + } + + val |= VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN; + writel_relaxed(val, vfe->base + VFE_0_CORE_CFG); + + val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1; + val |= (line->fmt[MSM_VFE_PAD_SINK].height - 1) << 16; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG); + + val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG); + + val = line->fmt[MSM_VFE_PAD_SINK].height - 1; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG); + + val = 0xffffffff; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG); + + val = 0xffffffff; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN); + + val = 0xffffffff; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN); + + val = VFE_0_RDI_CFG_x_MIPI_EN_BITS; + vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), val); + + val = VFE_0_CAMIF_CFG_VFE_OUTPUT_EN; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG); +} + +static void vfe_set_camif_cmd(struct vfe_device *vfe, u8 enable) +{ + u32 cmd; + + cmd = VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS | VFE_0_CAMIF_CMD_NO_CHANGE; + writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD); + + /* Make sure camif command is issued written before it is changed again */ + wmb(); + + if (enable) + cmd = VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY; + else + cmd = VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY; + + writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD); +} + +static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable) +{ + u32 val_lens = VFE_0_MODULE_LENS_EN_DEMUX | + VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE; + u32 val_zoom = VFE_0_MODULE_ZOOM_EN_SCALE_ENC | + VFE_0_MODULE_ZOOM_EN_CROP_ENC; + + if (enable) { + vfe_reg_set(vfe, VFE_0_MODULE_LENS_EN, val_lens); + vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom); + } else { + vfe_reg_clr(vfe, VFE_0_MODULE_LENS_EN, val_lens); + vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom); + } +} + +static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev) +{ + u32 val; + int ret; + + ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS, + val, + (val & VFE_0_CAMIF_STATUS_HALT), + CAMIF_TIMEOUT_SLEEP_US, + CAMIF_TIMEOUT_ALL_US); + if (ret < 0) + dev_err(dev, "%s: camif stop timeout\n", __func__); + + return ret; +} + +/* + * 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) +{ + struct vfe_device *vfe = dev; + u32 value0, value1; + int i, j; + + vfe->ops->isr_read(vfe, &value0, &value1); + + dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n", + value0, value1); + + if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK) + vfe->isr_ops.reset_ack(vfe); + + if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION) + vfe->ops->violation_read(vfe); + + if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK) + vfe->isr_ops.halt_ack(vfe); + + for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) + if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i)) + vfe->isr_ops.reg_update(vfe, i); + + if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF) + vfe->isr_ops.sof(vfe, VFE_LINE_PIX); + + for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) + if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i)) + vfe->isr_ops.sof(vfe, i); + + for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++) + if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) { + vfe->isr_ops.comp_done(vfe, i); + for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++) + if (vfe->wm_output_map[j] == VFE_LINE_PIX) + value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j); + } + + for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++) + if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i)) + vfe->isr_ops.wm_done(vfe, i); + + return IRQ_HANDLED; +} + +static u16 vfe_get_ub_size(u8 vfe_id) +{ + /* On VFE4.8 the ub-size is the same on both instances */ + return MSM_VFE_VFE0_UB_SIZE_RDI; +} + +static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) +{ + if (enable) + writel_relaxed(2 << VFE_0_BUS_IMAGE_MASTER_n_SHIFT(wm), + vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD); + else + writel_relaxed(1 << VFE_0_BUS_IMAGE_MASTER_n_SHIFT(wm), + vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD); + + /* The WM must be enabled before sending other commands */ + wmb(); +} + +static void vfe_set_qos(struct vfe_device *vfe) +{ + u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG; + u32 val3 = VFE_0_BUS_BDG_QOS_CFG_3_CFG; + u32 val4 = VFE_0_BUS_BDG_QOS_CFG_4_CFG; + u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG; + + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2); + writel_relaxed(val3, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3); + writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4); + writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5); + writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6); + writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7); +} + +static void vfe_set_ds(struct vfe_device *vfe) +{ + u32 val = VFE_0_BUS_BDG_DS_CFG_0_CFG; + u32 val16 = VFE_0_BUS_BDG_DS_CFG_16_CFG; + + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_0); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_1); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_2); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_3); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_4); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_5); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_6); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_7); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_8); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_9); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_10); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_11); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_12); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_13); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_14); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_15); + writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16); +} + +static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1) +{ + *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0); + *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1); + + writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0); + writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1); + + /* Enforce barrier between local & global IRQ clear */ + wmb(); + writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD); +} + +static void vfe_violation_read(struct vfe_device *vfe) +{ + u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS); + + pr_err_ratelimited("VFE: violation = 0x%08x\n", violation); +} + +const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_8 = { + .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi, + .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi, + .bus_enable_wr_if = vfe_bus_enable_wr_if, + .bus_reload_wm = vfe_bus_reload_wm, + .camif_wait_for_stop = vfe_camif_wait_for_stop, + .enable_irq_common = vfe_enable_irq_common, + .enable_irq_pix_line = vfe_enable_irq_pix_line, + .enable_irq_wm_line = vfe_enable_irq_wm_line, + .get_ub_size = vfe_get_ub_size, + .halt_clear = vfe_halt_clear, + .halt_request = vfe_halt_request, + .set_camif_cfg = vfe_set_camif_cfg, + .set_camif_cmd = vfe_set_camif_cmd, + .set_cgc_override = vfe_set_cgc_override, + .set_clamp_cfg = vfe_set_clamp_cfg, + .set_crop_cfg = vfe_set_crop_cfg, + .set_demux_cfg = vfe_set_demux_cfg, + .set_ds = vfe_set_ds, + .set_module_cfg = vfe_set_module_cfg, + .set_qos = vfe_set_qos, + .set_rdi_cid = vfe_set_rdi_cid, + .set_realign_cfg = vfe_set_realign_cfg, + .set_scale_cfg = vfe_set_scale_cfg, + .set_xbar_cfg = vfe_set_xbar_cfg, + .wm_enable = vfe_wm_enable, + .wm_frame_based = vfe_wm_frame_based, + .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status, + .wm_line_based = vfe_wm_line_based, + .wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern, + .wm_set_framedrop_period = vfe_wm_set_framedrop_period, + .wm_set_ping_addr = vfe_wm_set_ping_addr, + .wm_set_pong_addr = vfe_wm_set_pong_addr, + .wm_set_subsample = vfe_wm_set_subsample, + .wm_set_ub_cfg = vfe_wm_set_ub_cfg, +}; + +static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe) +{ + vfe->isr_ops = vfe_isr_ops_gen1; + vfe->ops_gen1 = &vfe_ops_gen1_4_8; + vfe->video_ops = vfe_video_ops_gen1; + + vfe->line_num = VFE_LINE_NUM_GEN1; +} + +const struct vfe_hw_ops vfe_ops_4_8 = { + .global_reset = vfe_global_reset, + .hw_version_read = vfe_hw_version_read, + .isr_read = vfe_isr_read, + .isr = vfe_isr, + .reg_update_clear = vfe_reg_update_clear, + .reg_update = vfe_reg_update, + .subdev_init = vfe_subdev_init, + .vfe_disable = vfe_gen1_disable, + .vfe_enable = vfe_gen1_enable, + .vfe_halt = vfe_gen1_halt, + .violation_read = vfe_violation_read, +}; diff --git a/drivers/media/platform/qcom/camss/camss-vfe-gen1.c b/drivers/media/platform/qcom/camss/camss-vfe-gen1.c new file mode 100644 index 000000000000..6737d9cf5150 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-vfe-gen1.c @@ -0,0 +1,763 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-vfe-gen1.c + * + * Qualcomm MSM Camera Subsystem - VFE Common functionality for Gen 1 versions of hw (4.1, 4.7..) + * + * Copyright (C) 2020 Linaro Ltd. + */ + + +#include "camss.h" +#include "camss-vfe.h" +#include "camss-vfe-gen1.h" + +/* Max number of frame drop updates per frame */ +#define VFE_FRAME_DROP_UPDATES 2 +#define VFE_NEXT_SOF_MS 500 + + +int vfe_gen1_halt(struct vfe_device *vfe) +{ + unsigned long time; + + return 0; + + reinit_completion(&vfe->halt_complete); + + vfe->ops_gen1->halt_request(vfe); + + time = wait_for_completion_timeout(&vfe->halt_complete, + msecs_to_jiffies(VFE_HALT_TIMEOUT_MS)); + if (!time) { + dev_err(vfe->camss->dev, "VFE halt timeout\n"); + return -EIO; + } + + return 0; +} + +static int vfe_disable_output(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output = &line->output; + const struct vfe_hw_ops *ops = vfe->ops; + unsigned long flags; + unsigned long time; + unsigned int i; + + spin_lock_irqsave(&vfe->output_lock, flags); + + output->gen1.wait_sof = 1; + spin_unlock_irqrestore(&vfe->output_lock, flags); + + time = wait_for_completion_timeout(&output->sof, msecs_to_jiffies(VFE_NEXT_SOF_MS)); + if (!time) + dev_err(vfe->camss->dev, "VFE sof timeout\n"); + + spin_lock_irqsave(&vfe->output_lock, flags); + for (i = 0; i < output->wm_num; i++) + vfe->ops_gen1->wm_enable(vfe, output->wm_idx[i], 0); + + ops->reg_update(vfe, line->id); + output->wait_reg_update = 1; + spin_unlock_irqrestore(&vfe->output_lock, flags); + + time = wait_for_completion_timeout(&output->reg_update, msecs_to_jiffies(VFE_NEXT_SOF_MS)); + if (!time) + dev_err(vfe->camss->dev, "VFE reg update timeout\n"); + + spin_lock_irqsave(&vfe->output_lock, flags); + + if (line->id != VFE_LINE_PIX) { + vfe->ops_gen1->wm_frame_based(vfe, output->wm_idx[0], 0); + vfe->ops_gen1->bus_disconnect_wm_from_rdi(vfe, output->wm_idx[0], line->id); + vfe->ops_gen1->enable_irq_wm_line(vfe, output->wm_idx[0], line->id, 0); + vfe->ops_gen1->set_cgc_override(vfe, output->wm_idx[0], 0); + spin_unlock_irqrestore(&vfe->output_lock, flags); + } else { + for (i = 0; i < output->wm_num; i++) { + vfe->ops_gen1->wm_line_based(vfe, output->wm_idx[i], NULL, i, 0); + vfe->ops_gen1->set_cgc_override(vfe, output->wm_idx[i], 0); + } + + vfe->ops_gen1->enable_irq_pix_line(vfe, 0, line->id, 0); + vfe->ops_gen1->set_module_cfg(vfe, 0); + vfe->ops_gen1->set_realign_cfg(vfe, line, 0); + vfe->ops_gen1->set_xbar_cfg(vfe, output, 0); + vfe->ops_gen1->set_camif_cmd(vfe, 0); + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + vfe->ops_gen1->camif_wait_for_stop(vfe, vfe->camss->dev); + } + + return 0; +} + +/* + * vfe_gen1_disable - Disable streaming on VFE line + * @line: VFE line + * + * Return 0 on success or a negative error code otherwise + */ +int vfe_gen1_disable(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + + vfe_disable_output(line); + + vfe_put_output(line); + + mutex_lock(&vfe->stream_lock); + + if (vfe->stream_count == 1) + vfe->ops_gen1->bus_enable_wr_if(vfe, 0); + + vfe->stream_count--; + + mutex_unlock(&vfe->stream_lock); + + return 0; +} + +static void vfe_output_init_addrs(struct vfe_device *vfe, + struct vfe_output *output, u8 sync, + struct vfe_line *line) +{ + u32 ping_addr; + u32 pong_addr; + unsigned int i; + + output->gen1.active_buf = 0; + + for (i = 0; i < output->wm_num; i++) { + if (output->buf[0]) + ping_addr = output->buf[0]->addr[i]; + else + ping_addr = 0; + + if (output->buf[1]) + pong_addr = output->buf[1]->addr[i]; + else + pong_addr = ping_addr; + + vfe->ops_gen1->wm_set_ping_addr(vfe, output->wm_idx[i], ping_addr); + vfe->ops_gen1->wm_set_pong_addr(vfe, output->wm_idx[i], pong_addr); + if (sync) + vfe->ops_gen1->bus_reload_wm(vfe, output->wm_idx[i]); + } +} + +static void vfe_output_frame_drop(struct vfe_device *vfe, + struct vfe_output *output, + u32 drop_pattern) +{ + u8 drop_period; + unsigned int i; + + /* We need to toggle update period to be valid on next frame */ + output->drop_update_idx++; + output->drop_update_idx %= VFE_FRAME_DROP_UPDATES; + drop_period = VFE_FRAME_DROP_VAL + output->drop_update_idx; + + for (i = 0; i < output->wm_num; i++) { + vfe->ops_gen1->wm_set_framedrop_period(vfe, output->wm_idx[i], drop_period); + vfe->ops_gen1->wm_set_framedrop_pattern(vfe, output->wm_idx[i], drop_pattern); + } + + vfe->ops->reg_update(vfe, container_of(output, struct vfe_line, output)->id); +} + +static int vfe_enable_output(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output = &line->output; + const struct vfe_hw_ops *ops = vfe->ops; + struct media_entity *sensor; + unsigned long flags; + unsigned int frame_skip = 0; + unsigned int i; + u16 ub_size; + + ub_size = vfe->ops_gen1->get_ub_size(vfe->id); + if (!ub_size) + return -EINVAL; + + sensor = camss_find_sensor(&line->subdev.entity); + if (sensor) { + struct v4l2_subdev *subdev = media_entity_to_v4l2_subdev(sensor); + + v4l2_subdev_call(subdev, sensor, g_skip_frames, &frame_skip); + /* Max frame skip is 29 frames */ + if (frame_skip > VFE_FRAME_DROP_VAL - 1) + frame_skip = VFE_FRAME_DROP_VAL - 1; + } + + spin_lock_irqsave(&vfe->output_lock, flags); + + ops->reg_update_clear(vfe, line->id); + + if (output->state != VFE_OUTPUT_RESERVED) { + dev_err(vfe->camss->dev, "Output is not in reserved state %d\n", output->state); + spin_unlock_irqrestore(&vfe->output_lock, flags); + return -EINVAL; + } + output->state = VFE_OUTPUT_IDLE; + + output->buf[0] = vfe_buf_get_pending(output); + output->buf[1] = vfe_buf_get_pending(output); + + if (!output->buf[0] && output->buf[1]) { + output->buf[0] = output->buf[1]; + output->buf[1] = NULL; + } + + if (output->buf[0]) + output->state = VFE_OUTPUT_SINGLE; + + if (output->buf[1]) + output->state = VFE_OUTPUT_CONTINUOUS; + + switch (output->state) { + case VFE_OUTPUT_SINGLE: + vfe_output_frame_drop(vfe, output, 1 << frame_skip); + break; + case VFE_OUTPUT_CONTINUOUS: + vfe_output_frame_drop(vfe, output, 3 << frame_skip); + break; + default: + vfe_output_frame_drop(vfe, output, 0); + break; + } + + output->sequence = 0; + output->gen1.wait_sof = 0; + output->wait_reg_update = 0; + reinit_completion(&output->sof); + reinit_completion(&output->reg_update); + + vfe_output_init_addrs(vfe, output, 0, line); + + if (line->id != VFE_LINE_PIX) { + vfe->ops_gen1->set_cgc_override(vfe, output->wm_idx[0], 1); + vfe->ops_gen1->enable_irq_wm_line(vfe, output->wm_idx[0], line->id, 1); + vfe->ops_gen1->bus_connect_wm_to_rdi(vfe, output->wm_idx[0], line->id); + vfe->ops_gen1->wm_set_subsample(vfe, output->wm_idx[0]); + vfe->ops_gen1->set_rdi_cid(vfe, line->id, 0); + vfe->ops_gen1->wm_set_ub_cfg(vfe, output->wm_idx[0], + (ub_size + 1) * output->wm_idx[0], ub_size); + vfe->ops_gen1->wm_frame_based(vfe, output->wm_idx[0], 1); + vfe->ops_gen1->wm_enable(vfe, output->wm_idx[0], 1); + vfe->ops_gen1->bus_reload_wm(vfe, output->wm_idx[0]); + } else { + ub_size /= output->wm_num; + for (i = 0; i < output->wm_num; i++) { + vfe->ops_gen1->set_cgc_override(vfe, output->wm_idx[i], 1); + vfe->ops_gen1->wm_set_subsample(vfe, output->wm_idx[i]); + vfe->ops_gen1->wm_set_ub_cfg(vfe, output->wm_idx[i], + (ub_size + 1) * output->wm_idx[i], ub_size); + vfe->ops_gen1->wm_line_based(vfe, output->wm_idx[i], + &line->video_out.active_fmt.fmt.pix_mp, i, 1); + vfe->ops_gen1->wm_enable(vfe, output->wm_idx[i], 1); + vfe->ops_gen1->bus_reload_wm(vfe, output->wm_idx[i]); + } + vfe->ops_gen1->enable_irq_pix_line(vfe, 0, line->id, 1); + vfe->ops_gen1->set_module_cfg(vfe, 1); + vfe->ops_gen1->set_camif_cfg(vfe, line); + vfe->ops_gen1->set_realign_cfg(vfe, line, 1); + vfe->ops_gen1->set_xbar_cfg(vfe, output, 1); + vfe->ops_gen1->set_demux_cfg(vfe, line); + vfe->ops_gen1->set_scale_cfg(vfe, line); + vfe->ops_gen1->set_crop_cfg(vfe, line); + vfe->ops_gen1->set_clamp_cfg(vfe); + vfe->ops_gen1->set_camif_cmd(vfe, 1); + } + + ops->reg_update(vfe, line->id); + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return 0; +} + +static int vfe_get_output(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output; + struct v4l2_format *f = &line->video_out.active_fmt; + unsigned long flags; + int i; + int wm_idx; + + spin_lock_irqsave(&vfe->output_lock, flags); + + output = &line->output; + if (output->state != VFE_OUTPUT_OFF) { + dev_err(vfe->camss->dev, "Output is running\n"); + goto error; + } + output->state = VFE_OUTPUT_RESERVED; + + output->gen1.active_buf = 0; + + switch (f->fmt.pix_mp.pixelformat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + output->wm_num = 2; + break; + default: + output->wm_num = 1; + break; + } + + for (i = 0; i < output->wm_num; i++) { + wm_idx = vfe_reserve_wm(vfe, line->id); + if (wm_idx < 0) { + dev_err(vfe->camss->dev, "Can not reserve wm\n"); + goto error_get_wm; + } + output->wm_idx[i] = wm_idx; + } + + output->drop_update_idx = 0; + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return 0; + +error_get_wm: + for (i--; i >= 0; i--) + vfe_release_wm(vfe, output->wm_idx[i]); + output->state = VFE_OUTPUT_OFF; +error: + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return -EINVAL; +} + +int vfe_gen1_enable(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + int ret; + + mutex_lock(&vfe->stream_lock); + + if (!vfe->stream_count) { + vfe->ops_gen1->enable_irq_common(vfe); + vfe->ops_gen1->bus_enable_wr_if(vfe, 1); + vfe->ops_gen1->set_qos(vfe); + vfe->ops_gen1->set_ds(vfe); + } + + vfe->stream_count++; + + mutex_unlock(&vfe->stream_lock); + + ret = vfe_get_output(line); + if (ret < 0) + goto error_get_output; + + ret = vfe_enable_output(line); + if (ret < 0) + goto error_enable_output; + + vfe->was_streaming = 1; + + return 0; + + +error_enable_output: + vfe_put_output(line); + +error_get_output: + mutex_lock(&vfe->stream_lock); + + if (vfe->stream_count == 1) + vfe->ops_gen1->bus_enable_wr_if(vfe, 0); + + vfe->stream_count--; + + mutex_unlock(&vfe->stream_lock); + + return ret; +} + +static void vfe_output_update_ping_addr(struct vfe_device *vfe, + struct vfe_output *output, u8 sync, + struct vfe_line *line) +{ + u32 addr; + unsigned int i; + + for (i = 0; i < output->wm_num; i++) { + if (output->buf[0]) + addr = output->buf[0]->addr[i]; + else + addr = 0; + + vfe->ops_gen1->wm_set_ping_addr(vfe, output->wm_idx[i], addr); + if (sync) + vfe->ops_gen1->bus_reload_wm(vfe, output->wm_idx[i]); + } +} + +static void vfe_output_update_pong_addr(struct vfe_device *vfe, + struct vfe_output *output, u8 sync, + struct vfe_line *line) +{ + u32 addr; + unsigned int i; + + for (i = 0; i < output->wm_num; i++) { + if (output->buf[1]) + addr = output->buf[1]->addr[i]; + else + addr = 0; + + vfe->ops_gen1->wm_set_pong_addr(vfe, output->wm_idx[i], addr); + if (sync) + vfe->ops_gen1->bus_reload_wm(vfe, output->wm_idx[i]); + + } + +} + +static void vfe_buf_update_wm_on_next(struct vfe_device *vfe, + struct vfe_output *output) +{ + switch (output->state) { + case VFE_OUTPUT_CONTINUOUS: + vfe_output_frame_drop(vfe, output, 3); + break; + case VFE_OUTPUT_SINGLE: + default: + dev_err_ratelimited(vfe->camss->dev, + "Next buf in wrong state! %d\n", + output->state); + break; + } +} + +static void vfe_buf_update_wm_on_last(struct vfe_device *vfe, + struct vfe_output *output) +{ + switch (output->state) { + case VFE_OUTPUT_CONTINUOUS: + output->state = VFE_OUTPUT_SINGLE; + vfe_output_frame_drop(vfe, output, 1); + break; + case VFE_OUTPUT_SINGLE: + output->state = VFE_OUTPUT_STOPPING; + vfe_output_frame_drop(vfe, output, 0); + break; + default: + dev_err_ratelimited(vfe->camss->dev, + "Last buff in wrong state! %d\n", + output->state); + break; + } +} + +static void vfe_buf_update_wm_on_new(struct vfe_device *vfe, + struct vfe_output *output, + struct camss_buffer *new_buf, + struct vfe_line *line) +{ + int inactive_idx; + + switch (output->state) { + case VFE_OUTPUT_SINGLE: + inactive_idx = !output->gen1.active_buf; + + if (!output->buf[inactive_idx]) { + output->buf[inactive_idx] = new_buf; + + if (inactive_idx) + vfe_output_update_pong_addr(vfe, output, 0, line); + else + vfe_output_update_ping_addr(vfe, output, 0, line); + + vfe_output_frame_drop(vfe, output, 3); + output->state = VFE_OUTPUT_CONTINUOUS; + } else { + vfe_buf_add_pending(output, new_buf); + dev_err_ratelimited(vfe->camss->dev, + "Inactive buffer is busy\n"); + } + break; + + case VFE_OUTPUT_IDLE: + if (!output->buf[0]) { + output->buf[0] = new_buf; + + vfe_output_init_addrs(vfe, output, 1, line); + vfe_output_frame_drop(vfe, output, 1); + + output->state = VFE_OUTPUT_SINGLE; + } else { + vfe_buf_add_pending(output, new_buf); + dev_err_ratelimited(vfe->camss->dev, + "Output idle with buffer set!\n"); + } + break; + + case VFE_OUTPUT_CONTINUOUS: + default: + vfe_buf_add_pending(output, new_buf); + break; + } +} + +/* + * vfe_isr_halt_ack - Process halt ack + * @vfe: VFE Device + */ +static void vfe_isr_halt_ack(struct vfe_device *vfe) +{ + complete(&vfe->halt_complete); + vfe->ops_gen1->halt_clear(vfe); +} + +/* + * vfe_isr_sof - Process start of frame interrupt + * @vfe: VFE Device + * @line_id: VFE line + */ +static void vfe_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id) +{ + struct vfe_output *output; + unsigned long flags; + + spin_lock_irqsave(&vfe->output_lock, flags); + output = &vfe->line[line_id].output; + if (output->gen1.wait_sof) { + output->gen1.wait_sof = 0; + complete(&output->sof); + } + spin_unlock_irqrestore(&vfe->output_lock, flags); +} + +/* + * vfe_isr_reg_update - Process reg update interrupt + * @vfe: VFE Device + * @line_id: VFE line + */ +static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) +{ + struct vfe_output *output; + struct vfe_line *line = &vfe->line[line_id]; + unsigned long flags; + + spin_lock_irqsave(&vfe->output_lock, flags); + vfe->ops->reg_update_clear(vfe, line_id); + + output = &line->output; + + if (output->wait_reg_update) { + output->wait_reg_update = 0; + complete(&output->reg_update); + spin_unlock_irqrestore(&vfe->output_lock, flags); + return; + } + + if (output->state == VFE_OUTPUT_STOPPING) { + /* Release last buffer when hw is idle */ + if (output->last_buffer) { + vb2_buffer_done(&output->last_buffer->vb.vb2_buf, + VB2_BUF_STATE_DONE); + output->last_buffer = NULL; + } + output->state = VFE_OUTPUT_IDLE; + + /* Buffers received in stopping state are queued in */ + /* dma pending queue, start next capture here */ + + output->buf[0] = vfe_buf_get_pending(output); + output->buf[1] = vfe_buf_get_pending(output); + + if (!output->buf[0] && output->buf[1]) { + output->buf[0] = output->buf[1]; + output->buf[1] = NULL; + } + + if (output->buf[0]) + output->state = VFE_OUTPUT_SINGLE; + + if (output->buf[1]) + output->state = VFE_OUTPUT_CONTINUOUS; + + switch (output->state) { + case VFE_OUTPUT_SINGLE: + vfe_output_frame_drop(vfe, output, 2); + break; + case VFE_OUTPUT_CONTINUOUS: + vfe_output_frame_drop(vfe, output, 3); + break; + default: + vfe_output_frame_drop(vfe, output, 0); + break; + } + + vfe_output_init_addrs(vfe, output, 1, &vfe->line[line_id]); + } + + spin_unlock_irqrestore(&vfe->output_lock, flags); +} + +/* + * vfe_isr_wm_done - Process write master done interrupt + * @vfe: VFE Device + * @wm: Write master id + */ +static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm) +{ + struct camss_buffer *ready_buf; + struct vfe_output *output; + dma_addr_t *new_addr; + unsigned long flags; + u32 active_index; + u64 ts = ktime_get_ns(); + unsigned int i; + + active_index = vfe->ops_gen1->wm_get_ping_pong_status(vfe, wm); + + spin_lock_irqsave(&vfe->output_lock, flags); + + if (vfe->wm_output_map[wm] == VFE_LINE_NONE) { + dev_err_ratelimited(vfe->camss->dev, + "Received wm done for unmapped index\n"); + goto out_unlock; + } + output = &vfe->line[vfe->wm_output_map[wm]].output; + + if (output->gen1.active_buf == active_index && 0) { + dev_err_ratelimited(vfe->camss->dev, + "Active buffer mismatch!\n"); + goto out_unlock; + } + output->gen1.active_buf = active_index; + + ready_buf = output->buf[!active_index]; + if (!ready_buf) { + dev_err_ratelimited(vfe->camss->dev, + "Missing ready buf %d %d!\n", + !active_index, output->state); + goto out_unlock; + } + + ready_buf->vb.vb2_buf.timestamp = ts; + ready_buf->vb.sequence = output->sequence++; + + /* Get next buffer */ + output->buf[!active_index] = vfe_buf_get_pending(output); + if (!output->buf[!active_index]) { + /* No next buffer - set same address */ + new_addr = ready_buf->addr; + vfe_buf_update_wm_on_last(vfe, output); + } else { + new_addr = output->buf[!active_index]->addr; + vfe_buf_update_wm_on_next(vfe, output); + } + + if (active_index) + for (i = 0; i < output->wm_num; i++) + vfe->ops_gen1->wm_set_ping_addr(vfe, output->wm_idx[i], new_addr[i]); + else + for (i = 0; i < output->wm_num; i++) + vfe->ops_gen1->wm_set_pong_addr(vfe, output->wm_idx[i], new_addr[i]); + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + if (output->state == VFE_OUTPUT_STOPPING) + output->last_buffer = ready_buf; + else + vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + + return; + +out_unlock: + spin_unlock_irqrestore(&vfe->output_lock, flags); +} + +/* + * vfe_queue_buffer - Add empty buffer + * @vid: Video device structure + * @buf: Buffer to be enqueued + * + * Add an empty buffer - depending on the current number of buffers it will be + * put in pending buffer queue or directly given to the hardware to be filled. + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_queue_buffer(struct camss_video *vid, struct camss_buffer *buf) +{ + struct vfe_line *line = container_of(vid, struct vfe_line, video_out); + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output; + unsigned long flags; + + output = &line->output; + + spin_lock_irqsave(&vfe->output_lock, flags); + + vfe_buf_update_wm_on_new(vfe, output, buf, line); + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return 0; +} + +inline u8 vfe_calc_interp_reso(u16 input, u16 output) +{ + if (input / output >= 16) + return 0; + + if (input / output >= 8) + return 1; + + if (input / output >= 4) + return 2; + + return 3; +} + +#define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N)) + +int vfe_word_per_line(u32 format, u32 width) +{ + int val = 0; + + switch (format) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + val = CALC_WORD(width, 1, 8); + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: + val = CALC_WORD(width, 2, 8); + break; + } + + return val; +} + +const struct vfe_isr_ops vfe_isr_ops_gen1 = { + .reset_ack = vfe_isr_reset_ack, + .halt_ack = vfe_isr_halt_ack, + .reg_update = vfe_isr_reg_update, + .sof = vfe_isr_sof, + .comp_done = vfe_isr_comp_done, + .wm_done = vfe_isr_wm_done, +}; + +const struct camss_video_ops vfe_video_ops_gen1 = { + .queue_buffer = vfe_queue_buffer, + .flush_buffers = vfe_flush_buffers, +}; diff --git a/drivers/media/platform/qcom/camss/camss-vfe-gen1.h b/drivers/media/platform/qcom/camss/camss-vfe-gen1.h new file mode 100644 index 000000000000..42e8a3333034 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-vfe-gen1.h @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * camss-vfe.h + * + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module + * + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2018 Linaro Ltd. + */ +#ifndef QC_MSM_CAMSS_VFE_GEN1_H +#define QC_MSM_CAMSS_VFE_GEN1_H + + +#include "camss-vfe.h" + + +enum vfe_line_id; +struct vfe_device; +struct vfe_line; +struct vfe_output; + +struct vfe_hw_ops_gen1 { + void (*bus_connect_wm_to_rdi)(struct vfe_device *vfe, u8 wm, enum vfe_line_id id); + void (*bus_disconnect_wm_from_rdi)(struct vfe_device *vfe, u8 wm, enum vfe_line_id id); + void (*bus_enable_wr_if)(struct vfe_device *vfe, u8 enable); + void (*bus_reload_wm)(struct vfe_device *vfe, u8 wm); + int (*camif_wait_for_stop)(struct vfe_device *vfe, struct device *dev); + void (*enable_irq_common)(struct vfe_device *vfe); + void (*enable_irq_wm_line)(struct vfe_device *vfe, u8 wm, enum vfe_line_id line_id, + u8 enable); + void (*enable_irq_pix_line)(struct vfe_device *vfe, u8 comp, enum vfe_line_id line_id, + u8 enable); + u16 (*get_ub_size)(u8 vfe_id); + void (*halt_clear)(struct vfe_device *vfe); + void (*halt_request)(struct vfe_device *vfe); + void (*set_camif_cfg)(struct vfe_device *vfe, struct vfe_line *line); + void (*set_camif_cmd)(struct vfe_device *vfe, u8 enable); + void (*set_cgc_override)(struct vfe_device *vfe, u8 wm, u8 enable); + void (*set_clamp_cfg)(struct vfe_device *vfe); + void (*set_crop_cfg)(struct vfe_device *vfe, struct vfe_line *line); + void (*set_demux_cfg)(struct vfe_device *vfe, struct vfe_line *line); + void (*set_ds)(struct vfe_device *vfe); + void (*set_module_cfg)(struct vfe_device *vfe, u8 enable); + void (*set_scale_cfg)(struct vfe_device *vfe, struct vfe_line *line); + void (*set_rdi_cid)(struct vfe_device *vfe, enum vfe_line_id id, u8 cid); + void (*set_realign_cfg)(struct vfe_device *vfe, struct vfe_line *line, u8 enable); + void (*set_qos)(struct vfe_device *vfe); + void (*set_xbar_cfg)(struct vfe_device *vfe, struct vfe_output *output, u8 enable); + void (*wm_frame_based)(struct vfe_device *vfe, u8 wm, u8 enable); + void (*wm_line_based)(struct vfe_device *vfe, u32 wm, struct v4l2_pix_format_mplane *pix, + u8 plane, u32 enable); + void (*wm_set_ub_cfg)(struct vfe_device *vfe, u8 wm, u16 offset, u16 depth); + void (*wm_set_subsample)(struct vfe_device *vfe, u8 wm); + void (*wm_set_framedrop_period)(struct vfe_device *vfe, u8 wm, u8 per); + void (*wm_set_framedrop_pattern)(struct vfe_device *vfe, u8 wm, u32 pattern); + void (*wm_set_ping_addr)(struct vfe_device *vfe, u8 wm, u32 addr); + void (*wm_set_pong_addr)(struct vfe_device *vfe, u8 wm, u32 addr); + int (*wm_get_ping_pong_status)(struct vfe_device *vfe, u8 wm); + void (*wm_enable)(struct vfe_device *vfe, u8 wm, u8 enable); +}; + +/* + * vfe_calc_interp_reso - Calculate interpolation mode + * @input: Input resolution + * @output: Output resolution + * + * Return interpolation mode + */ +inline u8 vfe_calc_interp_reso(u16 input, u16 output); + +/* + * vfe_gen1_disable - Disable streaming on VFE line + * @line: VFE line + * + * Return 0 on success or a negative error code otherwise + */ +int vfe_gen1_disable(struct vfe_line *line); + + +/* + * vfe_gen1_enable - Enable VFE module + * @line: VFE line + * + * Return 0 on success + */ +int vfe_gen1_enable(struct vfe_line *line); + +/* + * vfe_gen1_enable - Halt VFE module + * @vfe: VFE device + * + * Return 0 on success + */ +int vfe_gen1_halt(struct vfe_device *vfe); + +/* + * vfe_word_per_line - Calculate number of words per frame width + * @format: V4L2 format + * @width: Frame width + * + * Return number of words per frame width + */ +int vfe_word_per_line(u32 format, u32 width); + + +extern const struct vfe_isr_ops vfe_isr_ops_gen1; +extern const struct camss_video_ops vfe_video_ops_gen1; + + +#endif /* QC_MSM_CAMSS_VFE_GEN1_H */ diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 94c9ca7d5cbb..375843bd16af 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -26,22 +26,8 @@ #define MSM_VFE_NAME "msm_vfe" -#define vfe_line_array(ptr_line) \ - ((const struct vfe_line (*)[]) &(ptr_line[-(ptr_line->id)])) - -#define to_vfe(ptr_line) \ - container_of(vfe_line_array(ptr_line), struct vfe_device, line) - /* VFE reset timeout */ #define VFE_RESET_TIMEOUT_MS 50 -/* VFE halt timeout */ -#define VFE_HALT_TIMEOUT_MS 100 -/* Max number of frame drop updates per frame */ -#define VFE_FRAME_DROP_UPDATES 2 -/* Frame drop value. VAL + UPDATES - 1 should not exceed 31 */ -#define VFE_FRAME_DROP_VAL 30 - -#define VFE_NEXT_SOF_MS 500 #define SCALER_RATIO_MAX 16 @@ -294,35 +280,11 @@ static int vfe_reset(struct vfe_device *vfe) return 0; } -/* - * 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) -{ - unsigned long time; - - reinit_completion(&vfe->halt_complete); - - vfe->ops->halt_request(vfe); - - time = wait_for_completion_timeout(&vfe->halt_complete, - msecs_to_jiffies(VFE_HALT_TIMEOUT_MS)); - if (!time) { - dev_err(vfe->camss->dev, "VFE halt timeout\n"); - return -EIO; - } - - return 0; -} - static void vfe_init_outputs(struct vfe_device *vfe) { int i; - for (i = 0; i < ARRAY_SIZE(vfe->line); i++) { + for (i = 0; i < vfe->line_num; i++) { struct vfe_output *output = &vfe->line[i].output; output->state = VFE_OUTPUT_OFF; @@ -340,71 +302,7 @@ static void vfe_reset_output_maps(struct vfe_device *vfe) vfe->wm_output_map[i] = VFE_LINE_NONE; } -static void vfe_output_init_addrs(struct vfe_device *vfe, - struct vfe_output *output, u8 sync) -{ - u32 ping_addr; - u32 pong_addr; - unsigned int i; - - output->active_buf = 0; - - for (i = 0; i < output->wm_num; i++) { - if (output->buf[0]) - ping_addr = output->buf[0]->addr[i]; - else - ping_addr = 0; - - if (output->buf[1]) - pong_addr = output->buf[1]->addr[i]; - else - pong_addr = ping_addr; - - vfe->ops->wm_set_ping_addr(vfe, output->wm_idx[i], ping_addr); - vfe->ops->wm_set_pong_addr(vfe, output->wm_idx[i], pong_addr); - if (sync) - vfe->ops->bus_reload_wm(vfe, output->wm_idx[i]); - } -} - -static void vfe_output_update_ping_addr(struct vfe_device *vfe, - struct vfe_output *output, u8 sync) -{ - u32 addr; - unsigned int i; - - for (i = 0; i < output->wm_num; i++) { - if (output->buf[0]) - addr = output->buf[0]->addr[i]; - else - addr = 0; - - vfe->ops->wm_set_ping_addr(vfe, output->wm_idx[i], addr); - if (sync) - vfe->ops->bus_reload_wm(vfe, output->wm_idx[i]); - } -} - -static void vfe_output_update_pong_addr(struct vfe_device *vfe, - struct vfe_output *output, u8 sync) -{ - u32 addr; - unsigned int i; - - for (i = 0; i < output->wm_num; i++) { - if (output->buf[1]) - addr = output->buf[1]->addr[i]; - else - addr = 0; - - vfe->ops->wm_set_pong_addr(vfe, output->wm_idx[i], addr); - if (sync) - vfe->ops->bus_reload_wm(vfe, output->wm_idx[i]); - } - -} - -static int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id) +int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id) { int ret = -EBUSY; int i; @@ -420,7 +318,7 @@ static int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id) return ret; } -static int vfe_release_wm(struct vfe_device *vfe, u8 wm) +int vfe_release_wm(struct vfe_device *vfe, u8 wm) { if (wm >= ARRAY_SIZE(vfe->wm_output_map)) return -EINVAL; @@ -430,29 +328,7 @@ static int vfe_release_wm(struct vfe_device *vfe, u8 wm) return 0; } -static void vfe_output_frame_drop(struct vfe_device *vfe, - struct vfe_output *output, - u32 drop_pattern) -{ - u8 drop_period; - unsigned int i; - - /* We need to toggle update period to be valid on next frame */ - output->drop_update_idx++; - output->drop_update_idx %= VFE_FRAME_DROP_UPDATES; - drop_period = VFE_FRAME_DROP_VAL + output->drop_update_idx; - - for (i = 0; i < output->wm_num; i++) { - vfe->ops->wm_set_framedrop_period(vfe, output->wm_idx[i], - drop_period); - vfe->ops->wm_set_framedrop_pattern(vfe, output->wm_idx[i], - drop_pattern); - } - vfe->ops->reg_update(vfe, - container_of(output, struct vfe_line, output)->id); -} - -static struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output) +struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output) { struct camss_buffer *buffer = NULL; @@ -466,13 +342,8 @@ static struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output) return buffer; } -/* - * vfe_buf_add_pending - Add output buffer to list of pending - * @output: VFE output - * @buffer: Video buffer - */ -static void vfe_buf_add_pending(struct vfe_output *output, - struct camss_buffer *buffer) +void vfe_buf_add_pending(struct vfe_output *output, + struct camss_buffer *buffer) { INIT_LIST_HEAD(&buffer->queue); list_add_tail(&buffer->queue, &output->pending_bufs); @@ -495,149 +366,7 @@ static void vfe_buf_flush_pending(struct vfe_output *output, } } -static void vfe_buf_update_wm_on_next(struct vfe_device *vfe, - struct vfe_output *output) -{ - switch (output->state) { - case VFE_OUTPUT_CONTINUOUS: - vfe_output_frame_drop(vfe, output, 3); - break; - case VFE_OUTPUT_SINGLE: - default: - dev_err_ratelimited(vfe->camss->dev, - "Next buf in wrong state! %d\n", - output->state); - break; - } -} - -static void vfe_buf_update_wm_on_last(struct vfe_device *vfe, - struct vfe_output *output) -{ - switch (output->state) { - case VFE_OUTPUT_CONTINUOUS: - output->state = VFE_OUTPUT_SINGLE; - vfe_output_frame_drop(vfe, output, 1); - break; - case VFE_OUTPUT_SINGLE: - output->state = VFE_OUTPUT_STOPPING; - vfe_output_frame_drop(vfe, output, 0); - break; - default: - dev_err_ratelimited(vfe->camss->dev, - "Last buff in wrong state! %d\n", - output->state); - break; - } -} - -static void vfe_buf_update_wm_on_new(struct vfe_device *vfe, - struct vfe_output *output, - struct camss_buffer *new_buf) -{ - int inactive_idx; - - switch (output->state) { - case VFE_OUTPUT_SINGLE: - inactive_idx = !output->active_buf; - - if (!output->buf[inactive_idx]) { - output->buf[inactive_idx] = new_buf; - - if (inactive_idx) - vfe_output_update_pong_addr(vfe, output, 0); - else - vfe_output_update_ping_addr(vfe, output, 0); - - vfe_output_frame_drop(vfe, output, 3); - output->state = VFE_OUTPUT_CONTINUOUS; - } else { - vfe_buf_add_pending(output, new_buf); - dev_err_ratelimited(vfe->camss->dev, - "Inactive buffer is busy\n"); - } - break; - - case VFE_OUTPUT_IDLE: - if (!output->buf[0]) { - output->buf[0] = new_buf; - - vfe_output_init_addrs(vfe, output, 1); - - vfe_output_frame_drop(vfe, output, 1); - output->state = VFE_OUTPUT_SINGLE; - } else { - vfe_buf_add_pending(output, new_buf); - dev_err_ratelimited(vfe->camss->dev, - "Output idle with buffer set!\n"); - } - break; - - case VFE_OUTPUT_CONTINUOUS: - default: - vfe_buf_add_pending(output, new_buf); - break; - } -} - -static int vfe_get_output(struct vfe_line *line) -{ - struct vfe_device *vfe = to_vfe(line); - struct vfe_output *output; - struct v4l2_format *f = &line->video_out.active_fmt; - unsigned long flags; - int i; - int wm_idx; - - spin_lock_irqsave(&vfe->output_lock, flags); - - output = &line->output; - if (output->state != VFE_OUTPUT_OFF) { - dev_err(vfe->camss->dev, "Output is running\n"); - goto error; - } - output->state = VFE_OUTPUT_RESERVED; - - output->active_buf = 0; - - switch (f->fmt.pix_mp.pixelformat) { - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - output->wm_num = 2; - break; - default: - output->wm_num = 1; - break; - } - - for (i = 0; i < output->wm_num; i++) { - wm_idx = vfe_reserve_wm(vfe, line->id); - if (wm_idx < 0) { - dev_err(vfe->camss->dev, "Can not reserve wm\n"); - goto error_get_wm; - } - output->wm_idx[i] = wm_idx; - } - - output->drop_update_idx = 0; - - spin_unlock_irqrestore(&vfe->output_lock, flags); - - return 0; - -error_get_wm: - for (i--; i >= 0; i--) - vfe_release_wm(vfe, output->wm_idx[i]); - output->state = VFE_OUTPUT_OFF; -error: - spin_unlock_irqrestore(&vfe->output_lock, flags); - - return -EINVAL; -} - -static int vfe_put_output(struct vfe_line *line) +int vfe_put_output(struct vfe_line *line) { struct vfe_device *vfe = to_vfe(line); struct vfe_output *output = &line->output; @@ -655,454 +384,27 @@ static int vfe_put_output(struct vfe_line *line) return 0; } -static int vfe_enable_output(struct vfe_line *line) -{ - struct vfe_device *vfe = to_vfe(line); - struct vfe_output *output = &line->output; - const struct vfe_hw_ops *ops = vfe->ops; - struct media_entity *sensor; - unsigned long flags; - unsigned int frame_skip = 0; - unsigned int i; - u16 ub_size; - - ub_size = ops->get_ub_size(vfe->id); - if (!ub_size) - return -EINVAL; - - sensor = camss_find_sensor(&line->subdev.entity); - if (sensor) { - struct v4l2_subdev *subdev = - media_entity_to_v4l2_subdev(sensor); - - v4l2_subdev_call(subdev, sensor, g_skip_frames, &frame_skip); - /* Max frame skip is 29 frames */ - if (frame_skip > VFE_FRAME_DROP_VAL - 1) - frame_skip = VFE_FRAME_DROP_VAL - 1; - } - - spin_lock_irqsave(&vfe->output_lock, flags); - - ops->reg_update_clear(vfe, line->id); - - if (output->state != VFE_OUTPUT_RESERVED) { - dev_err(vfe->camss->dev, "Output is not in reserved state %d\n", - output->state); - spin_unlock_irqrestore(&vfe->output_lock, flags); - return -EINVAL; - } - output->state = VFE_OUTPUT_IDLE; - - output->buf[0] = vfe_buf_get_pending(output); - output->buf[1] = vfe_buf_get_pending(output); - - if (!output->buf[0] && output->buf[1]) { - output->buf[0] = output->buf[1]; - output->buf[1] = NULL; - } - - if (output->buf[0]) - output->state = VFE_OUTPUT_SINGLE; - - if (output->buf[1]) - output->state = VFE_OUTPUT_CONTINUOUS; - - switch (output->state) { - case VFE_OUTPUT_SINGLE: - vfe_output_frame_drop(vfe, output, 1 << frame_skip); - break; - case VFE_OUTPUT_CONTINUOUS: - vfe_output_frame_drop(vfe, output, 3 << frame_skip); - break; - default: - vfe_output_frame_drop(vfe, output, 0); - break; - } - - output->sequence = 0; - output->wait_sof = 0; - output->wait_reg_update = 0; - reinit_completion(&output->sof); - reinit_completion(&output->reg_update); - - vfe_output_init_addrs(vfe, output, 0); - - if (line->id != VFE_LINE_PIX) { - ops->set_cgc_override(vfe, output->wm_idx[0], 1); - ops->enable_irq_wm_line(vfe, output->wm_idx[0], line->id, 1); - ops->bus_connect_wm_to_rdi(vfe, output->wm_idx[0], line->id); - ops->wm_set_subsample(vfe, output->wm_idx[0]); - ops->set_rdi_cid(vfe, line->id, 0); - ops->wm_set_ub_cfg(vfe, output->wm_idx[0], - (ub_size + 1) * output->wm_idx[0], ub_size); - ops->wm_frame_based(vfe, output->wm_idx[0], 1); - ops->wm_enable(vfe, output->wm_idx[0], 1); - ops->bus_reload_wm(vfe, output->wm_idx[0]); - } else { - ub_size /= output->wm_num; - for (i = 0; i < output->wm_num; i++) { - ops->set_cgc_override(vfe, output->wm_idx[i], 1); - ops->wm_set_subsample(vfe, output->wm_idx[i]); - ops->wm_set_ub_cfg(vfe, output->wm_idx[i], - (ub_size + 1) * output->wm_idx[i], - ub_size); - ops->wm_line_based(vfe, output->wm_idx[i], - &line->video_out.active_fmt.fmt.pix_mp, - i, 1); - ops->wm_enable(vfe, output->wm_idx[i], 1); - ops->bus_reload_wm(vfe, output->wm_idx[i]); - } - ops->enable_irq_pix_line(vfe, 0, line->id, 1); - ops->set_module_cfg(vfe, 1); - ops->set_camif_cfg(vfe, line); - ops->set_realign_cfg(vfe, line, 1); - ops->set_xbar_cfg(vfe, output, 1); - ops->set_demux_cfg(vfe, line); - ops->set_scale_cfg(vfe, line); - ops->set_crop_cfg(vfe, line); - ops->set_clamp_cfg(vfe); - ops->set_camif_cmd(vfe, 1); - } - - ops->reg_update(vfe, line->id); - - spin_unlock_irqrestore(&vfe->output_lock, flags); - - return 0; -} - -static int vfe_disable_output(struct vfe_line *line) -{ - struct vfe_device *vfe = to_vfe(line); - struct vfe_output *output = &line->output; - const struct vfe_hw_ops *ops = vfe->ops; - unsigned long flags; - unsigned long time; - unsigned int i; - - spin_lock_irqsave(&vfe->output_lock, flags); - - output->wait_sof = 1; - spin_unlock_irqrestore(&vfe->output_lock, flags); - - time = wait_for_completion_timeout(&output->sof, - msecs_to_jiffies(VFE_NEXT_SOF_MS)); - if (!time) - dev_err(vfe->camss->dev, "VFE sof timeout\n"); - - spin_lock_irqsave(&vfe->output_lock, flags); - for (i = 0; i < output->wm_num; i++) - ops->wm_enable(vfe, output->wm_idx[i], 0); - - ops->reg_update(vfe, line->id); - output->wait_reg_update = 1; - spin_unlock_irqrestore(&vfe->output_lock, flags); - - time = wait_for_completion_timeout(&output->reg_update, - msecs_to_jiffies(VFE_NEXT_SOF_MS)); - if (!time) - dev_err(vfe->camss->dev, "VFE reg update timeout\n"); - - spin_lock_irqsave(&vfe->output_lock, flags); - - if (line->id != VFE_LINE_PIX) { - ops->wm_frame_based(vfe, output->wm_idx[0], 0); - ops->bus_disconnect_wm_from_rdi(vfe, output->wm_idx[0], - line->id); - ops->enable_irq_wm_line(vfe, output->wm_idx[0], line->id, 0); - ops->set_cgc_override(vfe, output->wm_idx[0], 0); - spin_unlock_irqrestore(&vfe->output_lock, flags); - } else { - for (i = 0; i < output->wm_num; i++) { - ops->wm_line_based(vfe, output->wm_idx[i], NULL, i, 0); - ops->set_cgc_override(vfe, output->wm_idx[i], 0); - } - - ops->enable_irq_pix_line(vfe, 0, line->id, 0); - ops->set_module_cfg(vfe, 0); - ops->set_realign_cfg(vfe, line, 0); - ops->set_xbar_cfg(vfe, output, 0); - - ops->set_camif_cmd(vfe, 0); - spin_unlock_irqrestore(&vfe->output_lock, flags); - - ops->camif_wait_for_stop(vfe, vfe->camss->dev); - } - - return 0; -} - -/* - * vfe_enable - Enable streaming on VFE line - * @line: VFE line - * - * Return 0 on success or a negative error code otherwise - */ -static int vfe_enable(struct vfe_line *line) -{ - struct vfe_device *vfe = to_vfe(line); - int ret; - - mutex_lock(&vfe->stream_lock); - - if (!vfe->stream_count) { - vfe->ops->enable_irq_common(vfe); - - vfe->ops->bus_enable_wr_if(vfe, 1); - - vfe->ops->set_qos(vfe); - - vfe->ops->set_ds(vfe); - } - - vfe->stream_count++; - - mutex_unlock(&vfe->stream_lock); - - ret = vfe_get_output(line); - if (ret < 0) - goto error_get_output; - - ret = vfe_enable_output(line); - if (ret < 0) - goto error_enable_output; - - vfe->was_streaming = 1; - - return 0; - - -error_enable_output: - vfe_put_output(line); - -error_get_output: - mutex_lock(&vfe->stream_lock); - - if (vfe->stream_count == 1) - vfe->ops->bus_enable_wr_if(vfe, 0); - - vfe->stream_count--; - - mutex_unlock(&vfe->stream_lock); - - return ret; -} - -/* - * vfe_disable - Disable streaming on VFE line - * @line: VFE line - * - * Return 0 on success or a negative error code otherwise - */ -static int vfe_disable(struct vfe_line *line) -{ - struct vfe_device *vfe = to_vfe(line); - - vfe_disable_output(line); - - vfe_put_output(line); - - mutex_lock(&vfe->stream_lock); - - if (vfe->stream_count == 1) - vfe->ops->bus_enable_wr_if(vfe, 0); - - vfe->stream_count--; - - mutex_unlock(&vfe->stream_lock); - - return 0; -} - -/* - * vfe_isr_sof - Process start of frame interrupt - * @vfe: VFE Device - * @line_id: VFE line - */ -static void vfe_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id) -{ - struct vfe_output *output; - unsigned long flags; - - spin_lock_irqsave(&vfe->output_lock, flags); - output = &vfe->line[line_id].output; - if (output->wait_sof) { - output->wait_sof = 0; - complete(&output->sof); - } - spin_unlock_irqrestore(&vfe->output_lock, flags); -} - -/* - * vfe_isr_reg_update - Process reg update interrupt - * @vfe: VFE Device - * @line_id: VFE line - */ -static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) -{ - struct vfe_output *output; - unsigned long flags; - - spin_lock_irqsave(&vfe->output_lock, flags); - vfe->ops->reg_update_clear(vfe, line_id); - - output = &vfe->line[line_id].output; - - if (output->wait_reg_update) { - output->wait_reg_update = 0; - complete(&output->reg_update); - spin_unlock_irqrestore(&vfe->output_lock, flags); - return; - } - - if (output->state == VFE_OUTPUT_STOPPING) { - /* Release last buffer when hw is idle */ - if (output->last_buffer) { - vb2_buffer_done(&output->last_buffer->vb.vb2_buf, - VB2_BUF_STATE_DONE); - output->last_buffer = NULL; - } - output->state = VFE_OUTPUT_IDLE; - - /* Buffers received in stopping state are queued in */ - /* dma pending queue, start next capture here */ - - output->buf[0] = vfe_buf_get_pending(output); - output->buf[1] = vfe_buf_get_pending(output); - - if (!output->buf[0] && output->buf[1]) { - output->buf[0] = output->buf[1]; - output->buf[1] = NULL; - } - - if (output->buf[0]) - output->state = VFE_OUTPUT_SINGLE; - - if (output->buf[1]) - output->state = VFE_OUTPUT_CONTINUOUS; - - switch (output->state) { - case VFE_OUTPUT_SINGLE: - vfe_output_frame_drop(vfe, output, 2); - break; - case VFE_OUTPUT_CONTINUOUS: - vfe_output_frame_drop(vfe, output, 3); - break; - default: - vfe_output_frame_drop(vfe, output, 0); - break; - } - - vfe_output_init_addrs(vfe, output, 1); - } - - spin_unlock_irqrestore(&vfe->output_lock, flags); -} - -/* - * vfe_isr_wm_done - Process write master done interrupt - * @vfe: VFE Device - * @wm: Write master id - */ -static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm) -{ - struct camss_buffer *ready_buf; - struct vfe_output *output; - dma_addr_t *new_addr; - unsigned long flags; - u32 active_index; - u64 ts = ktime_get_ns(); - unsigned int i; - - active_index = vfe->ops->wm_get_ping_pong_status(vfe, wm); - - spin_lock_irqsave(&vfe->output_lock, flags); - - if (vfe->wm_output_map[wm] == VFE_LINE_NONE) { - dev_err_ratelimited(vfe->camss->dev, - "Received wm done for unmapped index\n"); - goto out_unlock; - } - output = &vfe->line[vfe->wm_output_map[wm]].output; - - if (output->active_buf == active_index) { - dev_err_ratelimited(vfe->camss->dev, - "Active buffer mismatch!\n"); - goto out_unlock; - } - output->active_buf = active_index; - - ready_buf = output->buf[!active_index]; - if (!ready_buf) { - dev_err_ratelimited(vfe->camss->dev, - "Missing ready buf %d %d!\n", - !active_index, output->state); - goto out_unlock; - } - - ready_buf->vb.vb2_buf.timestamp = ts; - ready_buf->vb.sequence = output->sequence++; - - /* Get next buffer */ - output->buf[!active_index] = vfe_buf_get_pending(output); - if (!output->buf[!active_index]) { - /* No next buffer - set same address */ - new_addr = ready_buf->addr; - vfe_buf_update_wm_on_last(vfe, output); - } else { - new_addr = output->buf[!active_index]->addr; - vfe_buf_update_wm_on_next(vfe, output); - } - - if (active_index) - for (i = 0; i < output->wm_num; i++) - vfe->ops->wm_set_ping_addr(vfe, output->wm_idx[i], - new_addr[i]); - else - for (i = 0; i < output->wm_num; i++) - vfe->ops->wm_set_pong_addr(vfe, output->wm_idx[i], - new_addr[i]); - - spin_unlock_irqrestore(&vfe->output_lock, flags); - - if (output->state == VFE_OUTPUT_STOPPING) - output->last_buffer = ready_buf; - else - vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); - - return; - -out_unlock: - spin_unlock_irqrestore(&vfe->output_lock, flags); -} - /** * vfe_isr_comp_done() - Process composite image done interrupt * @vfe: VFE Device * @comp: Composite image id */ -static void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp) +void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp) { unsigned int i; for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) if (vfe->wm_output_map[i] == VFE_LINE_PIX) { - vfe_isr_wm_done(vfe, i); + vfe->isr_ops.wm_done(vfe, i); break; } } -static inline void vfe_isr_reset_ack(struct vfe_device *vfe) +void vfe_isr_reset_ack(struct vfe_device *vfe) { complete(&vfe->reset_complete); } -static inline void vfe_isr_halt_ack(struct vfe_device *vfe) -{ - complete(&vfe->halt_complete); - vfe->ops->halt_clear(vfe); -} - /* * vfe_set_clock_rates - Calculate and set clock rates on VFE module * @vfe: VFE device @@ -1112,11 +414,11 @@ static inline void vfe_isr_halt_ack(struct vfe_device *vfe) static int vfe_set_clock_rates(struct vfe_device *vfe) { struct device *dev = vfe->camss->dev; - u32 pixel_clock[MSM_VFE_LINE_NUM]; + u32 pixel_clock[VFE_LINE_NUM_MAX]; int i, j; int ret; - for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++) { + for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) { ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity, &pixel_clock[i]); if (ret) @@ -1131,7 +433,7 @@ static int vfe_set_clock_rates(struct vfe_device *vfe) u64 min_rate = 0; long rate; - for (j = VFE_LINE_RDI0; j <= VFE_LINE_PIX; j++) { + for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) { u32 tmp; u8 bpp; @@ -1194,11 +496,11 @@ static int vfe_set_clock_rates(struct vfe_device *vfe) */ static int vfe_check_clock_rates(struct vfe_device *vfe) { - u32 pixel_clock[MSM_VFE_LINE_NUM]; + u32 pixel_clock[VFE_LINE_NUM_MAX]; int i, j; int ret; - for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++) { + for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) { ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity, &pixel_clock[i]); if (ret) @@ -1213,7 +515,7 @@ static int vfe_check_clock_rates(struct vfe_device *vfe) u64 min_rate = 0; unsigned long rate; - for (j = VFE_LINE_RDI0; j <= VFE_LINE_PIX; j++) { + for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) { u32 tmp; u8 bpp; @@ -1318,7 +620,7 @@ static void vfe_put(struct vfe_device *vfe) } else if (vfe->power_count == 1) { if (vfe->was_streaming) { vfe->was_streaming = 0; - vfe_halt(vfe); + vfe->ops->vfe_halt(vfe); } camss_disable_clocks(vfe->nclocks, vfe->clock); pm_runtime_put_sync(vfe->camss->dev); @@ -1331,35 +633,6 @@ static void vfe_put(struct vfe_device *vfe) mutex_unlock(&vfe->power_lock); } -/* - * vfe_queue_buffer - Add empty buffer - * @vid: Video device structure - * @buf: Buffer to be enqueued - * - * Add an empty buffer - depending on the current number of buffers it will be - * put in pending buffer queue or directly given to the hardware to be filled. - * - * Return 0 on success or a negative error code otherwise - */ -static int vfe_queue_buffer(struct camss_video *vid, - struct camss_buffer *buf) -{ - struct vfe_line *line = container_of(vid, struct vfe_line, video_out); - struct vfe_device *vfe = to_vfe(line); - struct vfe_output *output; - unsigned long flags; - - output = &line->output; - - spin_lock_irqsave(&vfe->output_lock, flags); - - vfe_buf_update_wm_on_new(vfe, output, buf); - - spin_unlock_irqrestore(&vfe->output_lock, flags); - - return 0; -} - /* * vfe_flush_buffers - Return all vb2 buffers * @vid: Video device structure @@ -1370,8 +643,8 @@ static int vfe_queue_buffer(struct camss_video *vid, * * Return 0 on success or a negative error code otherwise */ -static int vfe_flush_buffers(struct camss_video *vid, - enum vb2_buffer_state state) +int vfe_flush_buffers(struct camss_video *vid, + enum vb2_buffer_state state) { struct vfe_line *line = container_of(vid, struct vfe_line, video_out); struct vfe_device *vfe = to_vfe(line); @@ -1442,12 +715,12 @@ static int vfe_set_stream(struct v4l2_subdev *sd, int enable) int ret; if (enable) { - ret = vfe_enable(line); + ret = vfe->ops->vfe_enable(line); if (ret < 0) dev_err(vfe->camss->dev, "Failed to enable vfe outputs\n"); } else { - ret = vfe_disable(line); + ret = vfe->ops->vfe_disable(line); if (ret < 0) dev_err(vfe->camss->dev, "Failed to disable vfe outputs\n"); @@ -1985,13 +1258,6 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, int i, j; int ret; - vfe->isr_ops.reset_ack = vfe_isr_reset_ack; - vfe->isr_ops.halt_ack = vfe_isr_halt_ack; - vfe->isr_ops.reg_update = vfe_isr_reg_update; - vfe->isr_ops.sof = vfe_isr_sof; - vfe->isr_ops.comp_done = vfe_isr_comp_done; - vfe->isr_ops.wm_done = vfe_isr_wm_done; - switch (camss->version) { case CAMSS_8x16: vfe->ops = &vfe_ops_4_1; @@ -2005,6 +1271,7 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, default: return -EINVAL; } + vfe->ops->subdev_init(dev, vfe); /* Memory */ @@ -2086,7 +1353,7 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, vfe->id = id; vfe->reg_update = 0; - for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++) { + for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) { struct vfe_line *l = &vfe->line[i]; l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; @@ -2209,11 +1476,6 @@ static const struct media_entity_operations vfe_media_ops = { .link_validate = v4l2_subdev_link_validate, }; -static const struct camss_video_ops camss_vfe_video_ops = { - .queue_buffer = vfe_queue_buffer, - .flush_buffers = vfe_flush_buffers, -}; - /* * msm_vfe_register_entities - Register subdev node for VFE module * @vfe: VFE device @@ -2236,7 +1498,7 @@ int msm_vfe_register_entities(struct vfe_device *vfe, int ret; int i; - for (i = 0; i < ARRAY_SIZE(vfe->line); i++) { + for (i = 0; i < vfe->line_num; i++) { char name[32]; sd = &vfe->line[i].subdev; @@ -2279,7 +1541,7 @@ int msm_vfe_register_entities(struct vfe_device *vfe, goto error_reg_subdev; } - video_out->ops = &camss_vfe_video_ops; + video_out->ops = &vfe->video_ops; video_out->bpl_alignment = 8; video_out->line_based = 0; if (i == VFE_LINE_PIX) { @@ -2343,7 +1605,7 @@ void msm_vfe_unregister_entities(struct vfe_device *vfe) mutex_destroy(&vfe->power_lock); mutex_destroy(&vfe->stream_lock); - for (i = 0; i < ARRAY_SIZE(vfe->line); i++) { + for (i = 0; i < vfe->line_num; i++) { struct v4l2_subdev *sd = &vfe->line[i].subdev; struct camss_video *video_out = &vfe->line[i].video_out; diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h index 5bce6736e4bb..aad5dc74c2c0 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.h +++ b/drivers/media/platform/qcom/camss/camss-vfe.h @@ -17,15 +17,28 @@ #include #include "camss-video.h" +#include "camss-vfe-gen1.h" + #define MSM_VFE_PAD_SINK 0 #define MSM_VFE_PAD_SRC 1 #define MSM_VFE_PADS_NUM 2 -#define MSM_VFE_LINE_NUM 4 #define MSM_VFE_IMAGE_MASTERS_NUM 7 #define MSM_VFE_COMPOSITE_IRQ_NUM 4 +/* VFE halt timeout */ +#define VFE_HALT_TIMEOUT_MS 100 +/* Frame drop value. VAL + UPDATES - 1 should not exceed 31 */ +#define VFE_FRAME_DROP_VAL 30 + +#define vfe_line_array(ptr_line) \ + ((const struct vfe_line (*)[]) &(ptr_line[-(ptr_line->id)])) + +#define to_vfe(ptr_line) \ + container_of(vfe_line_array(ptr_line), struct vfe_device, line) + + enum vfe_output_state { VFE_OUTPUT_OFF, VFE_OUTPUT_RESERVED, @@ -40,23 +53,30 @@ enum vfe_line_id { VFE_LINE_RDI0 = 0, VFE_LINE_RDI1 = 1, VFE_LINE_RDI2 = 2, - VFE_LINE_PIX = 3 + VFE_LINE_PIX = 3, + VFE_LINE_NUM_GEN1 = 4, + VFE_LINE_NUM_MAX = 4 }; struct vfe_output { u8 wm_num; u8 wm_idx[3]; - int active_buf; struct camss_buffer *buf[2]; struct camss_buffer *last_buffer; struct list_head pending_bufs; unsigned int drop_update_idx; + union { + struct { + int active_buf; + int wait_sof; + } gen1; + }; enum vfe_output_state state; unsigned int sequence; - int wait_sof; + int wait_reg_update; struct completion sof; struct completion reg_update; @@ -78,59 +98,19 @@ struct vfe_line { struct vfe_device; struct vfe_hw_ops { - void (*hw_version_read)(struct vfe_device *vfe, struct device *dev); - u16 (*get_ub_size)(u8 vfe_id); + void (*enable_irq_common)(struct vfe_device *vfe); void (*global_reset)(struct vfe_device *vfe); - void (*halt_request)(struct vfe_device *vfe); - void (*halt_clear)(struct vfe_device *vfe); - void (*wm_enable)(struct vfe_device *vfe, u8 wm, u8 enable); - void (*wm_frame_based)(struct vfe_device *vfe, u8 wm, u8 enable); - void (*wm_line_based)(struct vfe_device *vfe, u32 wm, - struct v4l2_pix_format_mplane *pix, - u8 plane, u32 enable); - void (*wm_set_framedrop_period)(struct vfe_device *vfe, u8 wm, u8 per); - void (*wm_set_framedrop_pattern)(struct vfe_device *vfe, u8 wm, - u32 pattern); - void (*wm_set_ub_cfg)(struct vfe_device *vfe, u8 wm, u16 offset, - u16 depth); - void (*bus_reload_wm)(struct vfe_device *vfe, u8 wm); - void (*wm_set_ping_addr)(struct vfe_device *vfe, u8 wm, u32 addr); - void (*wm_set_pong_addr)(struct vfe_device *vfe, u8 wm, u32 addr); - int (*wm_get_ping_pong_status)(struct vfe_device *vfe, u8 wm); - void (*bus_enable_wr_if)(struct vfe_device *vfe, u8 enable); - void (*bus_connect_wm_to_rdi)(struct vfe_device *vfe, u8 wm, - enum vfe_line_id id); - void (*wm_set_subsample)(struct vfe_device *vfe, u8 wm); - void (*bus_disconnect_wm_from_rdi)(struct vfe_device *vfe, u8 wm, - enum vfe_line_id id); - void (*set_xbar_cfg)(struct vfe_device *vfe, struct vfe_output *output, - u8 enable); - void (*set_rdi_cid)(struct vfe_device *vfe, enum vfe_line_id id, - u8 cid); - void (*set_realign_cfg)(struct vfe_device *vfe, struct vfe_line *line, - u8 enable); + void (*hw_version_read)(struct vfe_device *vfe, struct device *dev); + irqreturn_t (*isr)(int irq, void *dev); + void (*isr_read)(struct vfe_device *vfe, u32 *value0, u32 *value1); void (*reg_update)(struct vfe_device *vfe, enum vfe_line_id line_id); void (*reg_update_clear)(struct vfe_device *vfe, enum vfe_line_id line_id); - void (*enable_irq_wm_line)(struct vfe_device *vfe, u8 wm, - enum vfe_line_id line_id, u8 enable); - void (*enable_irq_pix_line)(struct vfe_device *vfe, u8 comp, - enum vfe_line_id line_id, u8 enable); - void (*enable_irq_common)(struct vfe_device *vfe); - void (*set_demux_cfg)(struct vfe_device *vfe, struct vfe_line *line); - void (*set_scale_cfg)(struct vfe_device *vfe, struct vfe_line *line); - void (*set_crop_cfg)(struct vfe_device *vfe, struct vfe_line *line); - void (*set_clamp_cfg)(struct vfe_device *vfe); - void (*set_qos)(struct vfe_device *vfe); - void (*set_ds)(struct vfe_device *vfe); - void (*set_cgc_override)(struct vfe_device *vfe, u8 wm, u8 enable); - void (*set_camif_cfg)(struct vfe_device *vfe, struct vfe_line *line); - void (*set_camif_cmd)(struct vfe_device *vfe, u8 enable); - void (*set_module_cfg)(struct vfe_device *vfe, u8 enable); - int (*camif_wait_for_stop)(struct vfe_device *vfe, struct device *dev); - void (*isr_read)(struct vfe_device *vfe, u32 *value0, u32 *value1); + void (*subdev_init)(struct device *dev, struct vfe_device *vfe); + int (*vfe_disable)(struct vfe_line *line); + int (*vfe_enable)(struct vfe_line *line); + int (*vfe_halt)(struct vfe_device *vfe); void (*violation_read)(struct vfe_device *vfe); - irqreturn_t (*isr)(int irq, void *dev); }; struct vfe_isr_ops { @@ -158,11 +138,14 @@ struct vfe_device { int stream_count; spinlock_t output_lock; enum vfe_line_id wm_output_map[MSM_VFE_IMAGE_MASTERS_NUM]; - struct vfe_line line[MSM_VFE_LINE_NUM]; + struct vfe_line line[VFE_LINE_NUM_MAX]; + u8 line_num; u32 reg_update; u8 was_streaming; const struct vfe_hw_ops *ops; + const struct vfe_hw_ops_gen1 *ops_gen1; struct vfe_isr_ops isr_ops; + struct camss_video_ops video_ops; }; struct resources; @@ -178,6 +161,38 @@ void msm_vfe_unregister_entities(struct vfe_device *vfe); void msm_vfe_get_vfe_id(struct media_entity *entity, u8 *id); void msm_vfe_get_vfe_line_id(struct media_entity *entity, enum vfe_line_id *id); + +/* + * vfe_buf_add_pending - Add output buffer to list of pending + * @output: VFE output + * @buffer: Video buffer + */ +void vfe_buf_add_pending(struct vfe_output *output, struct camss_buffer *buffer); + +struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output); + +/* + * vfe_disable - Disable streaming on VFE line + * @line: VFE line + * + * Return 0 on success or a negative error code otherwise + */ +int vfe_disable(struct vfe_line *line); + +int vfe_flush_buffers(struct camss_video *vid, enum vb2_buffer_state state); + +/* + * vfe_isr_comp_done - Process composite image done interrupt + * @vfe: VFE Device + * @comp: Composite image id + */ +void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp); + +void vfe_isr_reset_ack(struct vfe_device *vfe); +int vfe_put_output(struct vfe_line *line); +int vfe_release_wm(struct vfe_device *vfe, u8 wm); +int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id); + extern const struct vfe_hw_ops vfe_ops_4_1; extern const struct vfe_hw_ops vfe_ops_4_7; extern const struct vfe_hw_ops vfe_ops_4_8; diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 5ac2dfc67c8b..6c6f1e59ccd8 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -858,7 +858,7 @@ static int camss_register_entities(struct camss *camss) for (i = 0; i < camss->ispif->line_num; i++) for (k = 0; k < camss->vfe_num; k++) - for (j = 0; j < ARRAY_SIZE(camss->vfe[k].line); j++) { + for (j = 0; j < camss->vfe[k].line_num; j++) { ret = media_create_pad_link( &camss->ispif->line[i].subdev.entity, MSM_ISPIF_PAD_SRC, @@ -877,7 +877,7 @@ static int camss_register_entities(struct camss *camss) } else { for (i = 0; i < camss->csid_num; i++) for (k = 0; k < camss->vfe_num; k++) - for (j = 0; j < ARRAY_SIZE(camss->vfe[k].line); j++) { + for (j = 0; j < camss->vfe[k].line_num; j++) { ret = media_create_pad_link( &camss->csid[i].subdev.entity, MSM_CSID_PAD_SRC, From patchwork Thu Mar 4 12:03:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 393791 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86562C433E0 for ; Thu, 4 Mar 2021 12:07:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 41B2164F21 for ; Thu, 4 Mar 2021 12:07:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239960AbhCDMGl (ORCPT ); Thu, 4 Mar 2021 07:06:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239878AbhCDMGL (ORCPT ); Thu, 4 Mar 2021 07:06:11 -0500 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27723C0613DB for ; Thu, 4 Mar 2021 04:05:44 -0800 (PST) Received: by mail-ed1-x535.google.com with SMTP id w9so877273edc.11 for ; Thu, 04 Mar 2021 04:05:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rUkvG8owXlDHaT0HsTN7bJ3LtDHcOXQ6KQ/5ENbaYW8=; b=My/Puo302bqpVaUuFHeyj9xS/f37fR97dE2TKMZhyonii7YrD1HVqMvIdwL7KMI5lr KV5CNBHjtxb2AOUMhWP0I6GxwPuQz2rPKaLDCF2dpGBKEjcPLE2EIanNWFl1yrcMryqq L1tihDdqdGuhZ5I8rcYBlKhXvy04Hccl9XQM8uD4cawi4D01BBb08mnAsNH1Shp89Rh7 1cyBpmfXBBJnrp+cVgROJKkOxGgSVApJdz/qFIFC7fkvFyjH+4SmdhMEdYUf/w2P4Qik q67unEgBXUaYV2fUwftD58fpIyv2aCdy4J2rLMi7644oeq7fUnXFm/tBhhZPnYP8lvM6 Oszg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rUkvG8owXlDHaT0HsTN7bJ3LtDHcOXQ6KQ/5ENbaYW8=; b=jlMrvRgyrIoc3m6+lOYAgfVRaqJho8a4A9HDD3YKGq/K27IvyuETOK+aPjqO+Sphfx hU3gYPPdN7MifYgEuDJD5txOTGSQwoXO1kF41llyrt5sY40U2p9DGmP4oO0tlI3nlJ45 5eNYL9tuHIGG8UVrhPQ2tLN1DCK+3SZjRtZbOAkGFCjc43Yz0k1PvsmBLW1e9qz3uaIw D9WdfWdLwc+3LKmuOs2WZpwAMzpiZHfB++pXeJvBICFxjuFWhcxdRt8F5qWBWiogBFVq AW2v6xh9h9bTvUIwDsV/g5pGClnsGumy/y040PogVh9btHJ5ZEW4Smp3cFnXgxNUTaYH Jkew== X-Gm-Message-State: AOAM533WyaYozCYHBE4PhuitPbcydBRTWNn34egIma9rvYb1aDDJO93G FscQZuXZqlKP62HmfHm00X7/WA== X-Google-Smtp-Source: ABdhPJwZjWE4YhLO0mtL8qvDr3GFpVTCdTOeQs7sXLFp0aO4NR9TaqSQrFzyFVH851OEFpK4j38IAA== X-Received: by 2002:a05:6402:3083:: with SMTP id de3mr3908553edb.241.1614859542587; Thu, 04 Mar 2021 04:05:42 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:42 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 07/22] media: camss: Add support for VFE hardware version Titan 170 Date: Thu, 4 Mar 2021 13:03:13 +0100 Message-Id: <20210304120326.153966-8-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add register definitions for version 170 of the Titan architecture and implement support for the RDI output mode. The RDI mode as opposed to the PIX output mode for the VFE unit does not support any ISP functionality. This means essentially only supporting dumping the output of the whatever the CSI decoder receives from the sensor. For example will a sensor outputting YUV pixel format frames, only allow the VFE to dump those frames as they are received by the ISP to memory through the RDI interface. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v1: - Andrey: Remove commented out chunk - Remove left over WIP comments Changes since v4: - Andrey: Remove traces of PIX support - Andrey: Fix vfe_global_reset() overwriting reset command - Remove unused variable Changes since v5: - Andrey: Fix copy/paste issues in header - Andrey: Remove unecessary looping for 1 value drivers/media/platform/qcom/camss/Makefile | 1 + .../media/platform/qcom/camss/camss-vfe-170.c | 786 ++++++++++++++++++ drivers/media/platform/qcom/camss/camss-vfe.c | 47 +- drivers/media/platform/qcom/camss/camss-vfe.h | 26 +- .../media/platform/qcom/camss/camss-video.c | 52 ++ drivers/media/platform/qcom/camss/camss.c | 61 ++ 6 files changed, 953 insertions(+), 20 deletions(-) create mode 100644 drivers/media/platform/qcom/camss/camss-vfe-170.c diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile index 940c0ae3e003..052c4f405fa3 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -11,6 +11,7 @@ qcom-camss-objs += \ camss-vfe-4-1.o \ camss-vfe-4-7.o \ camss-vfe-4-8.o \ + camss-vfe-170.o \ camss-vfe-gen1.o \ camss-vfe.o \ camss-video.o \ diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c new file mode 100644 index 000000000000..9ab5964b1e99 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c @@ -0,0 +1,786 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-vfe-170.c + * + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v170 + * + * Copyright (C) 2020-2021 Linaro Ltd. + */ + +#include +#include +#include +#include + +#include "camss.h" +#include "camss-vfe.h" + +#define VFE_HW_VERSION (0x000) + +#define VFE_GLOBAL_RESET_CMD (0x018) +#define GLOBAL_RESET_CMD_CORE BIT(0) +#define GLOBAL_RESET_CMD_CAMIF BIT(1) +#define GLOBAL_RESET_CMD_BUS BIT(2) +#define GLOBAL_RESET_CMD_BUS_BDG BIT(3) +#define GLOBAL_RESET_CMD_REGISTER BIT(4) +#define GLOBAL_RESET_CMD_PM BIT(5) +#define GLOBAL_RESET_CMD_BUS_MISR BIT(6) +#define GLOBAL_RESET_CMD_TESTGEN BIT(7) +#define GLOBAL_RESET_CMD_DSP BIT(8) +#define GLOBAL_RESET_CMD_IDLE_CGC BIT(9) +#define GLOBAL_RESET_CMD_RDI0 BIT(10) +#define GLOBAL_RESET_CMD_RDI1 BIT(11) +#define GLOBAL_RESET_CMD_RDI2 BIT(12) +#define GLOBAL_RESET_CMD_RDI3 BIT(13) +#define GLOBAL_RESET_CMD_VFE_DOMAIN BIT(30) +#define GLOBAL_RESET_CMD_RESET_BYPASS BIT(31) + + +#define VFE_CORE_CFG (0x050) +#define CFG_PIXEL_PATTERN_YCBYCR (0x4) +#define CFG_PIXEL_PATTERN_YCRYCB (0x5) +#define CFG_PIXEL_PATTERN_CBYCRY (0x6) +#define CFG_PIXEL_PATTERN_CRYCBY (0x7) +#define CFG_COMPOSITE_REG_UPDATE_EN BIT(4) + +#define VFE_IRQ_CMD (0x058) +#define CMD_GLOBAL_CLEAR BIT(0) + +#define VFE_IRQ_MASK_0 (0x05c) +#define MASK_0_CAMIF_SOF BIT(0) +#define MASK_0_CAMIF_EOF BIT(1) +#define MASK_0_RDI_REG_UPDATE(n) BIT((n) + 5) +#define MASK_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8) +#define MASK_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25) +#define MASK_0_RESET_ACK BIT(31) + +#define VFE_IRQ_MASK_1 (0x060) +#define MASK_1_CAMIF_ERROR BIT(0) +#define MASK_1_VIOLATION BIT(7) +#define MASK_1_BUS_BDG_HALT_ACK BIT(8) +#define MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n) BIT((n) + 9) +#define MASK_1_RDI_SOF(n) BIT((n) + 29) + +#define VFE_IRQ_CLEAR_0 (0x064) +#define VFE_IRQ_CLEAR_1 (0x068) + +#define VFE_IRQ_STATUS_0 (0x06c) +#define STATUS_0_CAMIF_SOF BIT(0) +#define STATUS_0_RDI_REG_UPDATE(n) BIT((n) + 5) +#define STATUS_0_IMAGE_MASTER_PING_PONG(n) BIT((n) + 8) +#define STATUS_0_IMAGE_COMPOSITE_DONE(n) BIT((n) + 25) +#define STATUS_0_RESET_ACK BIT(31) + +#define VFE_IRQ_STATUS_1 (0x070) +#define STATUS_1_VIOLATION BIT(7) +#define STATUS_1_BUS_BDG_HALT_ACK BIT(8) +#define STATUS_1_RDI_SOF(n) BIT((n) + 27) + +#define VFE_VIOLATION_STATUS (0x07c) + +#define VFE_CAMIF_CMD (0x478) +#define CMD_CLEAR_CAMIF_STATUS BIT(2) + +#define VFE_CAMIF_CFG (0x47c) +#define CFG_VSYNC_SYNC_EDGE (0) +#define VSYNC_ACTIVE_HIGH (0) +#define VSYNC_ACTIVE_LOW (1) +#define CFG_HSYNC_SYNC_EDGE (1) +#define HSYNC_ACTIVE_HIGH (0) +#define HSYNC_ACTIVE_LOW (1) +#define CFG_VFE_SUBSAMPLE_ENABLE BIT(4) +#define CFG_BUS_SUBSAMPLE_ENABLE BIT(5) +#define CFG_VFE_OUTPUT_EN BIT(6) +#define CFG_BUS_OUTPUT_EN BIT(7) +#define CFG_BINNING_EN BIT(9) +#define CFG_FRAME_BASED_EN BIT(10) +#define CFG_RAW_CROP_EN BIT(22) + +// XXX different, don't exist in TITAN register docs +#define VFE_0_CAMIF_FRAME_CFG 0x484 +#define VFE_0_CAMIF_WINDOW_WIDTH_CFG 0x488 +#define VFE_0_CAMIF_WINDOW_HEIGHT_CFG 0x48c +#define VFE_0_CAMIF_SUBSAMPLE_CFG 0x490 +#define VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN 0x498 +#define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN 0x49c +#define VFE_0_CAMIF_STATUS 0x4a4 +#define VFE_0_CAMIF_STATUS_HALT BIT(31) +#define CAMIF_TIMEOUT_SLEEP_US 1000 +#define CAMIF_TIMEOUT_ALL_US 1000000 + +#define VFE_REG_UPDATE_CMD (0x4ac) +#define REG_UPDATE_RDI(n) BIT(1 + (n)) + + +#define VFE_BUS_IRQ_MASK(n) (0x2044 + (n) * 4) +#define VFE_BUS_IRQ_CLEAR(n) (0x2050 + (n) * 4) + +#define VFE_BUS_IRQ_STATUS(n) (0x205c + (n) * 4) +#define STATUS0_COMP_RESET_DONE BIT(0) +#define STATUS0_COMP_REG_UPDATE0_DONE BIT(1) +#define STATUS0_COMP_REG_UPDATE1_DONE BIT(2) +#define STATUS0_COMP_REG_UPDATE2_DONE BIT(3) +#define STATUS0_COMP_REG_UPDATE3_DONE BIT(4) +#define STATUS0_COMP_REG_UPDATE_DONE(n) BIT(n + 1) +#define STATUS0_COMP0_BUF_DONE BIT(5) +#define STATUS0_COMP1_BUF_DONE BIT(6) +#define STATUS0_COMP2_BUF_DONE BIT(7) +#define STATUS0_COMP3_BUF_DONE BIT(8) +#define STATUS0_COMP4_BUF_DONE BIT(9) +#define STATUS0_COMP5_BUF_DONE BIT(10) +#define STATUS0_COMP_BUF_DONE(n) BIT(n + 5) +#define STATUS0_COMP_ERROR BIT(11) +#define STATUS0_COMP_OVERWRITE BIT(12) +#define STATUS0_OVERFLOW BIT(13) +#define STATUS0_VIOLATION BIT(14) +/* WM_CLIENT_BUF_DONE defined for buffers 0:19 */ +#define STATUS1_WM_CLIENT_BUF_DONE(n) BIT(n) +#define STATUS1_EARLY_DONE BIT(24) +#define STATUS2_DUAL_COMP0_BUF_DONE BIT(0) +#define STATUS2_DUAL_COMP1_BUF_DONE BIT(1) +#define STATUS2_DUAL_COMP2_BUF_DONE BIT(2) +#define STATUS2_DUAL_COMP3_BUF_DONE BIT(3) +#define STATUS2_DUAL_COMP4_BUF_DONE BIT(4) +#define STATUS2_DUAL_COMP5_BUF_DONE BIT(5) +#define STATUS2_DUAL_COMP_BUF_DONE(n) BIT(n) +#define STATUS2_DUAL_COMP_ERROR BIT(6) +#define STATUS2_DUAL_COMP_OVERWRITE BIT(7) + +#define VFE_BUS_IRQ_CLEAR_GLOBAL (0x2068) + +#define VFE_BUS_WM_DEBUG_STATUS_CFG (0x226c) +#define DEBUG_STATUS_CFG_STATUS0(n) BIT(n) +#define DEBUG_STATUS_CFG_STATUS1(n) BIT(8+n) + +#define VFE_BUS_WM_ADDR_SYNC_FRAME_HEADER (0x2080) + +#define VFE_BUS_WM_ADDR_SYNC_NO_SYNC (0x2084) +#define BUS_VER2_MAX_CLIENTS (24) +#define WM_ADDR_NO_SYNC_DEFAULT_VAL \ + ((1 << BUS_VER2_MAX_CLIENTS) - 1) + +#define VFE_BUS_WM_CGC_OVERRIDE (0x200c) +#define WM_CGC_OVERRIDE_ALL (0xFFFFF) + +#define VFE_BUS_WM_TEST_BUS_CTRL (0x211c) + +#define VFE_BUS_WM_STATUS0(n) (0x2200 + (n) * 0x100) +#define VFE_BUS_WM_STATUS1(n) (0x2204 + (n) * 0x100) +#define VFE_BUS_WM_CFG(n) (0x2208 + (n) * 0x100) +#define WM_CFG_EN (0) +#define WM_CFG_MODE (1) +#define MODE_QCOM_PLAIN (0) +#define MODE_MIPI_RAW (1) +#define WM_CFG_VIRTUALFRAME (2) +#define VFE_BUS_WM_HEADER_ADDR(n) (0x220c + (n) * 0x100) +#define VFE_BUS_WM_HEADER_CFG(n) (0x2210 + (n) * 0x100) +#define VFE_BUS_WM_IMAGE_ADDR(n) (0x2214 + (n) * 0x100) +#define VFE_BUS_WM_IMAGE_ADDR_OFFSET(n) (0x2218 + (n) * 0x100) +#define VFE_BUS_WM_BUFFER_WIDTH_CFG(n) (0x221c + (n) * 0x100) +#define WM_BUFFER_DEFAULT_WIDTH (0xFF01) + +#define VFE_BUS_WM_BUFFER_HEIGHT_CFG(n) (0x2220 + (n) * 0x100) +#define VFE_BUS_WM_PACKER_CFG(n) (0x2224 + (n) * 0x100) + +#define VFE_BUS_WM_STRIDE(n) (0x2228 + (n) * 0x100) +#define WM_STRIDE_DEFAULT_STRIDE (0xFF01) + +#define VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(n) (0x2248 + (n) * 0x100) +#define VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(n) (0x224c + (n) * 0x100) +#define VFE_BUS_WM_FRAMEDROP_PERIOD(n) (0x2250 + (n) * 0x100) +#define VFE_BUS_WM_FRAMEDROP_PATTERN(n) (0x2254 + (n) * 0x100) +#define VFE_BUS_WM_FRAME_INC(n) (0x2258 + (n) * 0x100) +#define VFE_BUS_WM_BURST_LIMIT(n) (0x225c + (n) * 0x100) + + +static void vfe_hw_version_read(struct vfe_device *vfe, struct device *dev) +{ + u32 hw_version = readl_relaxed(vfe->base + VFE_HW_VERSION); + + u32 gen = (hw_version >> 28) & 0xF; + u32 rev = (hw_version >> 16) & 0xFFF; + u32 step = hw_version & 0xFFFF; + + dev_err(dev, "VFE HW Version = %u.%u.%u\n", gen, rev, step); +} + +static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits) +{ + u32 bits = readl_relaxed(vfe->base + reg); + + writel_relaxed(bits & ~clr_bits, vfe->base + reg); +} + +static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits) +{ + u32 bits = readl_relaxed(vfe->base + reg); + + writel_relaxed(bits | set_bits, vfe->base + reg); +} + +static void vfe_global_reset(struct vfe_device *vfe) +{ + u32 reset_bits = GLOBAL_RESET_CMD_CORE | + GLOBAL_RESET_CMD_CAMIF | + GLOBAL_RESET_CMD_BUS | + GLOBAL_RESET_CMD_BUS_BDG | + GLOBAL_RESET_CMD_REGISTER | + GLOBAL_RESET_CMD_TESTGEN | + GLOBAL_RESET_CMD_DSP | + GLOBAL_RESET_CMD_IDLE_CGC | + GLOBAL_RESET_CMD_RDI0 | + GLOBAL_RESET_CMD_RDI1 | + GLOBAL_RESET_CMD_RDI2; + + writel_relaxed(BIT(31), vfe->base + VFE_IRQ_MASK_0); + + /* Make sure IRQ mask has been written before resetting */ + wmb(); + + writel_relaxed(reset_bits, vfe->base + VFE_GLOBAL_RESET_CMD); +} + +static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line) +{ + u32 val; + + /*Set Debug Registers*/ + val = DEBUG_STATUS_CFG_STATUS0(1) | + DEBUG_STATUS_CFG_STATUS0(7); + writel_relaxed(val, vfe->base + VFE_BUS_WM_DEBUG_STATUS_CFG); + + /* BUS_WM_INPUT_IF_ADDR_SYNC_FRAME_HEADER */ + writel_relaxed(0, vfe->base + VFE_BUS_WM_ADDR_SYNC_FRAME_HEADER); + + /* no clock gating at bus input */ + val = WM_CGC_OVERRIDE_ALL; + writel_relaxed(val, vfe->base + VFE_BUS_WM_CGC_OVERRIDE); + + writel_relaxed(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL); + + /* if addr_no_sync has default value then config the addr no sync reg */ + val = WM_ADDR_NO_SYNC_DEFAULT_VAL; + writel_relaxed(val, vfe->base + VFE_BUS_WM_ADDR_SYNC_NO_SYNC); + + writel_relaxed(0xf, vfe->base + VFE_BUS_WM_BURST_LIMIT(wm)); + + val = WM_BUFFER_DEFAULT_WIDTH; + writel_relaxed(val, vfe->base + VFE_BUS_WM_BUFFER_WIDTH_CFG(wm)); + + val = 0; + writel_relaxed(val, vfe->base + VFE_BUS_WM_BUFFER_HEIGHT_CFG(wm)); + + val = 0; + writel_relaxed(val, vfe->base + VFE_BUS_WM_PACKER_CFG(wm)); // XXX 1 for PLAIN8? + + /* Configure stride for RDIs */ + //val = pix->plane_fmt[0].bytesperline; + val = WM_STRIDE_DEFAULT_STRIDE; + writel_relaxed(val, vfe->base + VFE_BUS_WM_STRIDE(wm)); + + /* Enable WM */ + val = 1 << WM_CFG_EN | + MODE_MIPI_RAW << WM_CFG_MODE; + writel_relaxed(val, vfe->base + VFE_BUS_WM_CFG(wm)); +} + +static void vfe_wm_stop(struct vfe_device *vfe, u8 wm) +{ + /* Disable WM */ + writel_relaxed(0, vfe->base + VFE_BUS_WM_CFG(wm)); +} + +static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u32 addr, + 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; + + writel_relaxed(addr, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm)); + writel_relaxed(stride * pix->height, vfe->base + VFE_BUS_WM_FRAME_INC(wm)); +} + +static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) +{ + vfe->reg_update |= REG_UPDATE_RDI(line_id); + + /* Enforce ordering between previous reg writes and reg update */ + wmb(); + + writel_relaxed(vfe->reg_update, vfe->base + VFE_REG_UPDATE_CMD); + + /* Enforce ordering between reg update and subsequent reg writes */ + wmb(); +} + +static inline void vfe_reg_update_clear(struct vfe_device *vfe, + enum vfe_line_id line_id) +{ + vfe->reg_update &= ~REG_UPDATE_RDI(line_id); +} + +static void vfe_enable_irq_common(struct vfe_device *vfe) +{ + vfe_reg_set(vfe, VFE_IRQ_MASK_0, ~0u); + vfe_reg_set(vfe, VFE_IRQ_MASK_1, ~0u); + + writel_relaxed(~0u, vfe->base + VFE_BUS_IRQ_MASK(0)); + writel_relaxed(~0u, vfe->base + VFE_BUS_IRQ_MASK(1)); + writel_relaxed(~0u, vfe->base + VFE_BUS_IRQ_MASK(2)); +} + +static void vfe_isr_halt_ack(struct vfe_device *vfe) +{ + complete(&vfe->halt_complete); +} + +static void vfe_isr_read(struct vfe_device *vfe, u32 *status0, u32 *status1) +{ + *status0 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_0); + *status1 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_1); + + writel_relaxed(*status0, vfe->base + VFE_IRQ_CLEAR_0); + writel_relaxed(*status1, vfe->base + VFE_IRQ_CLEAR_1); + + /* Enforce ordering between IRQ Clear and Global IRQ Clear */ + wmb(); + writel_relaxed(CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD); +} + +static void vfe_violation_read(struct vfe_device *vfe) +{ + u32 violation = readl_relaxed(vfe->base + VFE_VIOLATION_STATUS); + + pr_err_ratelimited("VFE: violation = 0x%08x\n", violation); +} + +/* + * 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) +{ + struct vfe_device *vfe = dev; + u32 status0, status1, vfe_bus_status[3]; + int i, wm; + + status0 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_0); + status1 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_1); + + writel_relaxed(status0, vfe->base + VFE_IRQ_CLEAR_0); + writel_relaxed(status1, vfe->base + VFE_IRQ_CLEAR_1); + + for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) { + vfe_bus_status[i] = readl_relaxed(vfe->base + VFE_BUS_IRQ_STATUS(i)); + writel_relaxed(vfe_bus_status[i], vfe->base + VFE_BUS_IRQ_CLEAR(i)); + } + + /* Enforce ordering between IRQ reading and interpretation */ + wmb(); + + writel_relaxed(CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD); + writel_relaxed(1, vfe->base + VFE_BUS_IRQ_CLEAR_GLOBAL); + + if (status0 & STATUS_0_RESET_ACK) + vfe->isr_ops.reset_ack(vfe); + + for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) + if (status0 & STATUS_0_RDI_REG_UPDATE(i)) + vfe->isr_ops.reg_update(vfe, i); + + for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) + if (status0 & STATUS_1_RDI_SOF(i)) + vfe->isr_ops.sof(vfe, i); + + for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++) + if (vfe_bus_status[0] & STATUS0_COMP_BUF_DONE(i)) + vfe->isr_ops.comp_done(vfe, i); + + for (wm = 0; wm < MSM_VFE_IMAGE_MASTERS_NUM; wm++) + if (status0 & BIT(9)) + if (vfe_bus_status[1] & STATUS1_WM_CLIENT_BUF_DONE(wm)) + vfe->isr_ops.wm_done(vfe, wm); + + 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) +{ + unsigned long time; + + return 0; + + reinit_completion(&vfe->halt_complete); + + time = wait_for_completion_timeout(&vfe->halt_complete, + msecs_to_jiffies(VFE_HALT_TIMEOUT_MS)); + if (!time) { + dev_err(vfe->camss->dev, "VFE halt timeout\n"); + return -EIO; + } + + return 0; +} + +static int vfe_get_output(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output; + unsigned long flags; + int wm_idx; + + spin_lock_irqsave(&vfe->output_lock, flags); + + output = &line->output; + if (output->state != VFE_OUTPUT_OFF) { + dev_err(vfe->camss->dev, "Output is running\n"); + goto error; + } + + output->wm_num = 1; + + wm_idx = vfe_reserve_wm(vfe, line->id); + if (wm_idx < 0) { + dev_err(vfe->camss->dev, "Can not reserve wm\n"); + goto error_get_wm; + } + output->wm_idx[0] = wm_idx; + + output->drop_update_idx = 0; + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return 0; + +error_get_wm: + vfe_release_wm(vfe, output->wm_idx[0]); + output->state = VFE_OUTPUT_OFF; +error: + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return -EINVAL; +} + +static int vfe_enable_output(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output = &line->output; + const struct vfe_hw_ops *ops = vfe->ops; + struct media_entity *sensor; + unsigned long flags; + unsigned int frame_skip = 0; + unsigned int i; + + sensor = camss_find_sensor(&line->subdev.entity); + if (sensor) { + struct v4l2_subdev *subdev = media_entity_to_v4l2_subdev(sensor); + + v4l2_subdev_call(subdev, sensor, g_skip_frames, &frame_skip); + /* Max frame skip is 29 frames */ + if (frame_skip > VFE_FRAME_DROP_VAL - 1) + frame_skip = VFE_FRAME_DROP_VAL - 1; + } + + spin_lock_irqsave(&vfe->output_lock, flags); + + ops->reg_update_clear(vfe, line->id); + + if (output->state != VFE_OUTPUT_OFF) { + dev_err(vfe->camss->dev, "Output is not in reserved state %d\n", + output->state); + spin_unlock_irqrestore(&vfe->output_lock, flags); + return -EINVAL; + } + + WARN_ON(output->gen2.active_num); + + output->state = VFE_OUTPUT_ON; + + output->sequence = 0; + output->wait_reg_update = 0; + reinit_completion(&output->reg_update); + + vfe_wm_start(vfe, output->wm_idx[0], line); + + for (i = 0; i < 2; i++) { + output->buf[i] = vfe_buf_get_pending(output); + if (!output->buf[i]) + break; + output->gen2.active_num++; + vfe_wm_update(vfe, output->wm_idx[0], output->buf[i]->addr[0], line); + } + + ops->reg_update(vfe, line->id); + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return 0; +} + +static int vfe_disable_output(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output = &line->output; + unsigned long flags; + unsigned int i; + bool done; + int timeout = 0; + + do { + spin_lock_irqsave(&vfe->output_lock, flags); + done = !output->gen2.active_num; + spin_unlock_irqrestore(&vfe->output_lock, flags); + usleep_range(10000, 20000); + + if (timeout++ == 100) { + dev_err(vfe->camss->dev, "VFE idle timeout - resetting\n"); + vfe_reset(vfe); + output->gen2.active_num = 0; + return 0; + } + } while (!done); + + spin_lock_irqsave(&vfe->output_lock, flags); + for (i = 0; i < output->wm_num; i++) + vfe_wm_stop(vfe, output->wm_idx[i]); + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return 0; +} + +/* + * vfe_enable - Enable streaming on VFE line + * @line: VFE line + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_enable(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + int ret; + + mutex_lock(&vfe->stream_lock); + + if (!vfe->stream_count) + vfe_enable_irq_common(vfe); + + vfe->stream_count++; + + mutex_unlock(&vfe->stream_lock); + + ret = vfe_get_output(line); + if (ret < 0) + goto error_get_output; + + ret = vfe_enable_output(line); + if (ret < 0) + goto error_enable_output; + + vfe->was_streaming = 1; + + return 0; + + +error_enable_output: + vfe_put_output(line); + +error_get_output: + mutex_lock(&vfe->stream_lock); + + vfe->stream_count--; + + mutex_unlock(&vfe->stream_lock); + + return ret; +} + +/* + * vfe_disable - Disable streaming on VFE line + * @line: VFE line + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_disable(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + + vfe_disable_output(line); + + vfe_put_output(line); + + mutex_lock(&vfe->stream_lock); + + vfe->stream_count--; + + mutex_unlock(&vfe->stream_lock); + + return 0; +} + +/* + * vfe_isr_sof - Process start of frame interrupt + * @vfe: VFE Device + * @line_id: VFE line + */ +static void vfe_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id) +{ + +} + +/* + * vfe_isr_reg_update - Process reg update interrupt + * @vfe: VFE Device + * @line_id: VFE line + */ +static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) +{ + struct vfe_output *output; + unsigned long flags; + + spin_lock_irqsave(&vfe->output_lock, flags); + vfe->ops->reg_update_clear(vfe, line_id); + + output = &vfe->line[line_id].output; + + if (output->wait_reg_update) { + output->wait_reg_update = 0; + complete(&output->reg_update); + } + + spin_unlock_irqrestore(&vfe->output_lock, flags); +} + +/* + * vfe_isr_wm_done - Process write master done interrupt + * @vfe: VFE Device + * @wm: Write master id + */ +static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm) +{ + struct vfe_line *line = &vfe->line[vfe->wm_output_map[wm]]; + struct camss_buffer *ready_buf; + struct vfe_output *output; + unsigned long flags; + u32 index; + u64 ts = ktime_get_ns(); + + spin_lock_irqsave(&vfe->output_lock, flags); + + if (vfe->wm_output_map[wm] == VFE_LINE_NONE) { + dev_err_ratelimited(vfe->camss->dev, + "Received wm done for unmapped index\n"); + goto out_unlock; + } + output = &vfe->line[vfe->wm_output_map[wm]].output; + + ready_buf = output->buf[0]; + if (!ready_buf) { + dev_err_ratelimited(vfe->camss->dev, + "Missing ready buf %d!\n", output->state); + goto out_unlock; + } + + ready_buf->vb.vb2_buf.timestamp = ts; + ready_buf->vb.sequence = output->sequence++; + + index = 0; + output->buf[0] = output->buf[1]; + if (output->buf[0]) + index = 1; + + output->buf[index] = vfe_buf_get_pending(output); + + if (output->buf[index]) + vfe_wm_update(vfe, output->wm_idx[0], output->buf[index]->addr[0], line); + else + output->gen2.active_num--; + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + + return; + +out_unlock: + spin_unlock_irqrestore(&vfe->output_lock, flags); +} + +/* + * vfe_queue_buffer - Add empty buffer + * @vid: Video device structure + * @buf: Buffer to be enqueued + * + * Add an empty buffer - depending on the current number of buffers it will be + * put in pending buffer queue or directly given to the hardware to be filled. + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_queue_buffer(struct camss_video *vid, + struct camss_buffer *buf) +{ + struct vfe_line *line = container_of(vid, struct vfe_line, video_out); + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output; + unsigned long flags; + + output = &line->output; + + spin_lock_irqsave(&vfe->output_lock, flags); + + if (output->state == VFE_OUTPUT_ON && output->gen2.active_num < 2) { + output->buf[output->gen2.active_num++] = buf; + vfe_wm_update(vfe, output->wm_idx[0], buf->addr[0], line); + } else { + vfe_buf_add_pending(output, buf); + } + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return 0; +} + +const struct vfe_isr_ops vfe_isr_ops_170 = { + .reset_ack = vfe_isr_reset_ack, + .halt_ack = vfe_isr_halt_ack, + .reg_update = vfe_isr_reg_update, + .sof = vfe_isr_sof, + .comp_done = vfe_isr_comp_done, + .wm_done = vfe_isr_wm_done, +}; + +static const struct camss_video_ops vfe_video_ops_170 = { + .queue_buffer = vfe_queue_buffer, + .flush_buffers = vfe_flush_buffers, +}; + +static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe) +{ + vfe->isr_ops = vfe_isr_ops_170; + vfe->video_ops = vfe_video_ops_170; + + vfe->line_num = VFE_LINE_NUM_GEN2; +} + +const struct vfe_hw_ops vfe_ops_170 = { + .global_reset = vfe_global_reset, + .hw_version_read = vfe_hw_version_read, + .isr_read = vfe_isr_read, + .isr = vfe_isr, + .reg_update_clear = vfe_reg_update_clear, + .reg_update = vfe_reg_update, + .subdev_init = vfe_subdev_init, + .vfe_disable = vfe_disable, + .vfe_enable = vfe_enable, + .vfe_halt = vfe_halt, + .violation_read = vfe_violation_read, +}; diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 375843bd16af..6fafeb8a5484 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -96,6 +96,32 @@ static const struct vfe_format formats_pix_8x96[] = { { MEDIA_BUS_FMT_YVYU8_2X8, 8 }, }; +static const struct vfe_format formats_rdi_845[] = { + { MEDIA_BUS_FMT_UYVY8_2X8, 8 }, + { MEDIA_BUS_FMT_VYUY8_2X8, 8 }, + { MEDIA_BUS_FMT_YUYV8_2X8, 8 }, + { MEDIA_BUS_FMT_YVYU8_2X8, 8 }, + { MEDIA_BUS_FMT_SBGGR8_1X8, 8 }, + { MEDIA_BUS_FMT_SGBRG8_1X8, 8 }, + { MEDIA_BUS_FMT_SGRBG8_1X8, 8 }, + { MEDIA_BUS_FMT_SRGGB8_1X8, 8 }, + { MEDIA_BUS_FMT_SBGGR10_1X10, 10 }, + { MEDIA_BUS_FMT_SGBRG10_1X10, 10 }, + { MEDIA_BUS_FMT_SGRBG10_1X10, 10 }, + { MEDIA_BUS_FMT_SRGGB10_1X10, 10 }, + { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16 }, + { MEDIA_BUS_FMT_SBGGR12_1X12, 12 }, + { MEDIA_BUS_FMT_SGBRG12_1X12, 12 }, + { MEDIA_BUS_FMT_SGRBG12_1X12, 12 }, + { MEDIA_BUS_FMT_SRGGB12_1X12, 12 }, + { MEDIA_BUS_FMT_SBGGR14_1X14, 14 }, + { MEDIA_BUS_FMT_SGBRG14_1X14, 14 }, + { MEDIA_BUS_FMT_SGRBG14_1X14, 14 }, + { MEDIA_BUS_FMT_SRGGB14_1X14, 14 }, + { MEDIA_BUS_FMT_Y10_1X10, 10 }, + { MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16 }, +}; + /* * vfe_get_bpp - map media bus format to bits per pixel * @formats: supported media bus formats array @@ -192,7 +218,8 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, return sink_code; } else if (vfe->camss->version == CAMSS_8x96 || - vfe->camss->version == CAMSS_660) + vfe->camss->version == CAMSS_660 || + vfe->camss->version == CAMSS_845) switch (sink_code) { case MEDIA_BUS_FMT_YUYV8_2X8: { @@ -256,13 +283,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, return 0; } -/* - * vfe_reset - Trigger reset on VFE module and wait to complete - * @vfe: VFE device - * - * Return 0 on success or a negative error code otherwise - */ -static int vfe_reset(struct vfe_device *vfe) +int vfe_reset(struct vfe_device *vfe) { unsigned long time; @@ -429,7 +450,8 @@ static int vfe_set_clock_rates(struct vfe_device *vfe) struct camss_clock *clock = &vfe->clock[i]; if (!strcmp(clock->name, "vfe0") || - !strcmp(clock->name, "vfe1")) { + !strcmp(clock->name, "vfe1") || + !strcmp(clock->name, "vfe_lite")) { u64 min_rate = 0; long rate; @@ -1268,6 +1290,10 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, case CAMSS_660: vfe->ops = &vfe_ops_4_8; break; + + case CAMSS_845: + vfe->ops = &vfe_ops_170; + break; default: return -EINVAL; } @@ -1379,6 +1405,9 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, l->formats = formats_rdi_8x96; l->nformats = ARRAY_SIZE(formats_rdi_8x96); } + } else if (camss->version == CAMSS_845) { + l->formats = formats_rdi_845; + l->nformats = ARRAY_SIZE(formats_rdi_845); } else { return -EINVAL; } diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h index aad5dc74c2c0..29b3d930ffc6 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.h +++ b/drivers/media/platform/qcom/camss/camss-vfe.h @@ -19,7 +19,6 @@ #include "camss-video.h" #include "camss-vfe-gen1.h" - #define MSM_VFE_PAD_SINK 0 #define MSM_VFE_PAD_SRC 1 #define MSM_VFE_PADS_NUM 2 @@ -38,14 +37,14 @@ #define to_vfe(ptr_line) \ container_of(vfe_line_array(ptr_line), struct vfe_device, line) - enum vfe_output_state { VFE_OUTPUT_OFF, VFE_OUTPUT_RESERVED, VFE_OUTPUT_SINGLE, VFE_OUTPUT_CONTINUOUS, VFE_OUTPUT_IDLE, - VFE_OUTPUT_STOPPING + VFE_OUTPUT_STOPPING, + VFE_OUTPUT_ON, }; enum vfe_line_id { @@ -53,6 +52,7 @@ enum vfe_line_id { VFE_LINE_RDI0 = 0, VFE_LINE_RDI1 = 1, VFE_LINE_RDI2 = 2, + VFE_LINE_NUM_GEN2 = 3, VFE_LINE_PIX = 3, VFE_LINE_NUM_GEN1 = 4, VFE_LINE_NUM_MAX = 4 @@ -73,6 +73,9 @@ struct vfe_output { int active_buf; int wait_sof; } gen1; + struct { + int active_num; + } gen2; }; enum vfe_output_state state; unsigned int sequence; @@ -171,14 +174,6 @@ void vfe_buf_add_pending(struct vfe_output *output, struct camss_buffer *buffer) struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output); -/* - * vfe_disable - Disable streaming on VFE line - * @line: VFE line - * - * Return 0 on success or a negative error code otherwise - */ -int vfe_disable(struct vfe_line *line); - int vfe_flush_buffers(struct camss_video *vid, enum vb2_buffer_state state); /* @@ -193,8 +188,17 @@ int vfe_put_output(struct vfe_line *line); int vfe_release_wm(struct vfe_device *vfe, u8 wm); int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id); +/* + * vfe_reset - Trigger reset on VFE module and wait to complete + * @vfe: VFE device + * + * Return 0 on success or a negative error code otherwise + */ +int vfe_reset(struct vfe_device *vfe); + extern const struct vfe_hw_ops vfe_ops_4_1; extern const struct vfe_hw_ops vfe_ops_4_7; extern const struct vfe_hw_ops vfe_ops_4_8; +extern const struct vfe_hw_ops vfe_ops_170; #endif /* QC_MSM_CAMSS_VFE_H */ diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c index 97cea7c4d769..f282275af626 100644 --- a/drivers/media/platform/qcom/camss/camss-video.c +++ b/drivers/media/platform/qcom/camss/camss-video.c @@ -133,6 +133,55 @@ static const struct camss_format_info formats_rdi_8x96[] = { { { 1, 1 } }, { { 1, 1 } }, { 16 } }, }; +static const struct camss_format_info formats_rdi_845[] = { + { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 1, + { { 1, 1 } }, { { 1, 1 } }, { 16 } }, + { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 1, + { { 1, 1 } }, { { 1, 1 } }, { 16 } }, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1, + { { 1, 1 } }, { { 1, 1 } }, { 16 } }, + { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 1, + { { 1, 1 } }, { { 1, 1 } }, { 16 } }, + { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1, + { { 1, 1 } }, { { 1, 1 } }, { 8 } }, + { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 1, + { { 1, 1 } }, { { 1, 1 } }, { 8 } }, + { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 1, + { { 1, 1 } }, { { 1, 1 } }, { 8 } }, + { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 1, + { { 1, 1 } }, { { 1, 1 } }, { 8 } }, + { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 10 } }, + { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 10 } }, + { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 10 } }, + { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 10 } }, + { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_PIX_FMT_SBGGR10, 1, + { { 1, 1 } }, { { 1, 1 } }, { 16 } }, + { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 12 } }, + { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 12 } }, + { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 12 } }, + { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 12 } }, + { MEDIA_BUS_FMT_SBGGR14_1X14, V4L2_PIX_FMT_SBGGR14P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 14 } }, + { MEDIA_BUS_FMT_SGBRG14_1X14, V4L2_PIX_FMT_SGBRG14P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 14 } }, + { MEDIA_BUS_FMT_SGRBG14_1X14, V4L2_PIX_FMT_SGRBG14P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 14 } }, + { MEDIA_BUS_FMT_SRGGB14_1X14, V4L2_PIX_FMT_SRGGB14P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 14 } }, + { MEDIA_BUS_FMT_Y10_1X10, V4L2_PIX_FMT_Y10P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 10 } }, + { MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, V4L2_PIX_FMT_Y10, 1, + { { 1, 1 } }, { { 1, 1 } }, { 16 } }, +}; + static const struct camss_format_info formats_pix_8x16[] = { { MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV12, 1, { { 1, 1 } }, { { 2, 3 } }, { 8 } }, @@ -960,6 +1009,9 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev, video->formats = formats_rdi_8x96; video->nformats = ARRAY_SIZE(formats_rdi_8x96); } + } else if (video->camss->version == CAMSS_845) { + video->formats = formats_rdi_845; + video->nformats = ARRAY_SIZE(formats_rdi_845); } else { ret = -EINVAL; goto error_video_register; diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 6c6f1e59ccd8..0e006def1996 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -465,6 +465,67 @@ static const struct resources vfe_res_660[] = { } }; +static const struct resources vfe_res_845[] = { + /* VFE0 */ + { + .regulator = { NULL }, + .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src", + "soc_ahb", "vfe0", "vfe0_axi", + "vfe0_src", "csi0", + "csi0_src"}, + .clock_rate = { { 0 }, + { 0 }, + { 80000000 }, + { 0 }, + { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, + { 0 }, + { 320000000 }, + { 19200000, 75000000, 384000000, 538666667 }, + { 384000000 } }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" } + }, + + /* VFE1 */ + { + .regulator = { NULL }, + .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src", + "soc_ahb", "vfe1", "vfe1_axi", + "vfe1_src", "csi1", + "csi1_src"}, + .clock_rate = { { 0 }, + { 0 }, + { 80000000 }, + { 0 }, + { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, + { 0 }, + { 320000000 }, + { 19200000, 75000000, 384000000, 538666667 }, + { 384000000 } }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" } + }, + + /* VFE-lite */ + { + .regulator = { NULL }, + .clock = { "camnoc_axi", "cpas_ahb", "slow_ahb_src", + "soc_ahb", "vfe_lite", + "vfe_lite_src", "csi2", + "csi2_src"}, + .clock_rate = { { 0 }, + { 0 }, + { 80000000 }, + { 0 }, + { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, + { 320000000 }, + { 19200000, 75000000, 384000000, 538666667 }, + { 384000000 } }, + .reg = { "vfe_lite" }, + .interrupt = { "vfe_lite" } + } +}; + /* * camss_add_clock_margin - Add margin to clock frequency rate * @rate: Clock frequency rate From patchwork Thu Mar 4 12:03:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392913 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D7E9AC43381 for ; Thu, 4 Mar 2021 12:07:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ABED264F47 for ; Thu, 4 Mar 2021 12:07:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239945AbhCDMGm (ORCPT ); Thu, 4 Mar 2021 07:06:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59954 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239918AbhCDMGS (ORCPT ); Thu, 4 Mar 2021 07:06:18 -0500 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 768EDC0613E9 for ; Thu, 4 Mar 2021 04:05:45 -0800 (PST) Received: by mail-ed1-x52b.google.com with SMTP id x9so2689190edd.0 for ; Thu, 04 Mar 2021 04:05:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=MB3dOJa39frP9xpZiMDFriIvbU9lQpyDrWXbisCqGu0=; b=T+mDDzm1wYz7eSQmaJjty9RDkXXDtHQ9w1yFZcqTLZkkwEp6metBtmQwi6O8P2shw1 zCNhtSm8pV6vwzs/a/dUzsYB+BzgF/thXu83m4PCI8y7n8DYJaiAWBlkBS57Us+Lon3P RkHZwagTSftlYe9Oes5rSUPaWD8j65IppIw/Ds7X8e09lmgELGrjb9uqJu7hVmfDM/97 0ZaR6P6UyPfjQo1qB8Dqfs0bdUA9/q5VgoOT2/Tp2YFPifVQHvmqDfEA456IsFXUatYe dc7oNaqwGFvl5cPhUYY0dUd6d3KZguF/b5HgBN/Tjy3B/22f0o2rtH4mOVKeapIuSnMh Uvvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=MB3dOJa39frP9xpZiMDFriIvbU9lQpyDrWXbisCqGu0=; b=CU2Yz2df9zcdb7pjtxMLCzH3Dm7zk4QddnVgywer4BH3pNUfql9lBGihOUGHbjL6EI g8PRrlvm/6IGtIK+jaZRyOfUrl8v8snjp9d2McUkSdyXdz/cH6H9DtIkn/87+vWOM5Wi CxHlqlvUI5V47qQ1naoeGkaKHFAUNkSb1vbYm+4mQvYXKXvNKvkkMBdD31zdUdY1EW3D mGUriR7Lt5HYo01YYJAA2dXqOkEW0CPXzlwDC+U7XVxFoALup+FVtlLwbDHyBq7SsBb3 qX9C9L3D+PSGQD+hFzsyi9waMRuEU9a2MEnIUqlNCL5iOHwU4EaOUhZBHULnM7bczQdr O0pA== X-Gm-Message-State: AOAM533yx73QHri5r64Cynava3lVAGkMqJ+EnZhznYusH3zzecx48yzQ 3KGARp/hrYpmykU9oit8eG2PwQ== X-Google-Smtp-Source: ABdhPJxy/xK/TtuZCRz+n34Uwzg69GXf8ZJcWKSDK+NdCh00p5XyEEou8wiRWatp45mYDKzDPFrVew== X-Received: by 2002:aa7:c5c4:: with SMTP id h4mr3765036eds.375.1614859544199; Thu, 04 Mar 2021 04:05:44 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:43 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 08/22] media: camss: Add missing format identifiers Date: Thu, 4 Mar 2021 13:03:14 +0100 Message-Id: <20210304120326.153966-9-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The CSI-2 spec defines format identifier for Data Type (DT), and how the Decode Format (DF) & Encode Format (EF) are implemented. The spec does however not define the DF, EF or Plain Format (PF) identifiers, as those are vendor specific. Plain formats describe the size of the pixels written by the RDI units to memory. PLAIN8 for example has the size 8 bits, and PLAIN32 32 bits. The appropriate Plain Format is determined by the Decode Format used. The smallest Plain Format that is able to contain a pixel of the used Decode Format is the appropriate one to use. As the vendor specific identifiers differ between hardware generations, split them out into separate headers. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v5 - Andrey: Gen 1 & Gen2 devices have different decode/encode/plain format definitions, list in separate headers - Andrey: Make commit msg more clear about what is in MIPI spec or not .../platform/qcom/camss/camss-csid-gen1.h | 27 +++++++++++++ .../platform/qcom/camss/camss-csid-gen2.h | 39 +++++++++++++++++++ .../media/platform/qcom/camss/camss-csid.c | 20 ++-------- .../media/platform/qcom/camss/camss-csid.h | 24 ++++++++++++ 4 files changed, 94 insertions(+), 16 deletions(-) create mode 100644 drivers/media/platform/qcom/camss/camss-csid-gen1.h create mode 100644 drivers/media/platform/qcom/camss/camss-csid-gen2.h diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen1.h b/drivers/media/platform/qcom/camss/camss-csid-gen1.h new file mode 100644 index 000000000000..80a2bc6efff6 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-csid-gen1.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * camss-csid-gen1.h + * + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module Generation 1 + * + * Copyright (C) 2021 Linaro Ltd. + */ +#ifndef QC_MSM_CAMSS_CSID_GEN1_H +#define QC_MSM_CAMSS_CSID_GEN1_H + +#define DECODE_FORMAT_UNCOMPRESSED_6_BIT 0x0 +#define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1 +#define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2 +#define DECODE_FORMAT_UNCOMPRESSED_12_BIT 0x3 +#define DECODE_FORMAT_DPCM_10_6_10 0x4 +#define DECODE_FORMAT_DPCM_10_8_10 0x5 +#define DECODE_FORMAT_DPCM_12_6_12 0x6 +#define DECODE_FORMAT_DPCM_12_8_12 0x7 +#define DECODE_FORMAT_UNCOMPRESSED_14_BIT 0x8 +#define DECODE_FORMAT_DPCM_14_8_14 0x9 +#define DECODE_FORMAT_DPCM_14_10_14 0xa + +#define PLAIN_FORMAT_PLAIN8 0x0 /* supports DPCM, UNCOMPRESSED_6/8_BIT */ +#define PLAIN_FORMAT_PLAIN16 0x1 /* supports DPCM, UNCOMPRESSED_10/16_BIT */ + +#endif /* QC_MSM_CAMSS_CSID_GEN1_H */ diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen2.h b/drivers/media/platform/qcom/camss/camss-csid-gen2.h new file mode 100644 index 000000000000..3a8ad001b3e8 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * camss-csid-gen1.h + * + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module Generation 1 + * + * Copyright (C) 2021 Linaro Ltd. + */ +#ifndef QC_MSM_CAMSS_CSID_GEN2_H +#define QC_MSM_CAMSS_CSID_GEN2_H + +#define DECODE_FORMAT_UNCOMPRESSED_6_BIT 0x0 +#define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1 +#define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2 +#define DECODE_FORMAT_UNCOMPRESSED_12_BIT 0x3 +#define DECODE_FORMAT_UNCOMPRESSED_14_BIT 0x4 +#define DECODE_FORMAT_UNCOMPRESSED_16_BIT 0x5 +#define DECODE_FORMAT_UNCOMPRESSED_20_BIT 0x6 +#define DECODE_FORMAT_DPCM_10_6_10 0x7 +#define DECODE_FORMAT_DPCM_10_8_10 0x8 +#define DECODE_FORMAT_DPCM_12_6_12 0x9 +#define DECODE_FORMAT_DPCM_12_8_12 0xa +#define DECODE_FORMAT_DPCM_14_8_14 0xb +#define DECODE_FORMAT_DPCM_14_10_14 0xc +#define DECODE_FORMAT_DPCM_12_10_12 0xd +#define DECODE_FORMAT_USER_DEFINED 0xe +#define DECODE_FORMAT_PAYLOAD_ONLY 0xf + +#define ENCODE_FORMAT_RAW_8_BIT 0x1 +#define ENCODE_FORMAT_RAW_10_BIT 0x2 +#define ENCODE_FORMAT_RAW_12_BIT 0x3 +#define ENCODE_FORMAT_RAW_14_BIT 0x4 +#define ENCODE_FORMAT_RAW_16_BIT 0x5 + +#define PLAIN_FORMAT_PLAIN8 0x0 /* supports DPCM, UNCOMPRESSED_6/8_BIT */ +#define PLAIN_FORMAT_PLAIN16 0x1 /* supports DPCM, UNCOMPRESSED_10/16_BIT */ +#define PLAIN_FORMAT_PLAIN32 0x2 /* supports UNCOMPRESSED_20_BIT */ + +#endif /* QC_MSM_CAMSS_CSID_GEN2_H */ diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index be3fe76f3dc3..697b51d6ad38 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -22,6 +22,7 @@ #include #include "camss-csid.h" +#include "camss-csid-gen1.h" #include "camss.h" #define MSM_CSID_NAME "msm_csid" @@ -37,8 +38,8 @@ #define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0) #define CAMSS_CSID_CID_n_CFG_RDI_EN BIT(1) #define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4 -#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (0 << 8) -#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (1 << 8) +#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (PLAIN_FORMAT_PLAIN8 << 8) +#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (PLAIN_FORMAT_PLAIN16 << 8) #define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9) #define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9) #define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10) @@ -59,22 +60,9 @@ #define CAMSS_CSID_TG_DT_n_CGG_2(v, n) \ (((v) == CAMSS_8x16 ? 0x0b4 : 0x0bc) + 0xc * (n)) -#define DATA_TYPE_EMBEDDED_DATA_8BIT 0x12 -#define DATA_TYPE_YUV422_8BIT 0x1e -#define DATA_TYPE_RAW_6BIT 0x28 -#define DATA_TYPE_RAW_8BIT 0x2a -#define DATA_TYPE_RAW_10BIT 0x2b -#define DATA_TYPE_RAW_12BIT 0x2c -#define DATA_TYPE_RAW_14BIT 0x2d - -#define DECODE_FORMAT_UNCOMPRESSED_6_BIT 0x0 -#define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1 -#define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2 -#define DECODE_FORMAT_UNCOMPRESSED_12_BIT 0x3 -#define DECODE_FORMAT_UNCOMPRESSED_14_BIT 0x8 - #define CSID_RESET_TIMEOUT_MS 500 + struct csid_format { u32 code; u8 data_type; diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h index 1824b3745e10..318c19bb26c9 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.h +++ b/drivers/media/platform/qcom/camss/camss-csid.h @@ -21,6 +21,30 @@ #define MSM_CSID_PAD_SRC 1 #define MSM_CSID_PADS_NUM 2 +#define DATA_TYPE_EMBEDDED_DATA_8BIT 0x12 +#define DATA_TYPE_YUV420_8BIT 0x18 +#define DATA_TYPE_YUV420_10BIT 0x19 +#define DATA_TYPE_YUV420_8BIT_LEGACY 0x1a +#define DATA_TYPE_YUV420_8BIT_SHIFTED 0x1c /* Chroma Shifted Pixel Sampling */ +#define DATA_TYPE_YUV420_10BIT_SHIFTED 0x1d /* Chroma Shifted Pixel Sampling */ +#define DATA_TYPE_YUV422_8BIT 0x1e +#define DATA_TYPE_YUV422_10BIT 0x1f +#define DATA_TYPE_RGB444 0x20 +#define DATA_TYPE_RGB555 0x21 +#define DATA_TYPE_RGB565 0x22 +#define DATA_TYPE_RGB666 0x23 +#define DATA_TYPE_RGB888 0x24 +#define DATA_TYPE_RAW_24BIT 0x27 +#define DATA_TYPE_RAW_6BIT 0x28 +#define DATA_TYPE_RAW_7BIT 0x29 +#define DATA_TYPE_RAW_8BIT 0x2a +#define DATA_TYPE_RAW_10BIT 0x2b +#define DATA_TYPE_RAW_12BIT 0x2c +#define DATA_TYPE_RAW_14BIT 0x2d +#define DATA_TYPE_RAW_16BIT 0x2e +#define DATA_TYPE_RAW_20BIT 0x2f + + enum csid_payload_mode { CSID_PAYLOAD_MODE_INCREMENTING = 0, CSID_PAYLOAD_MODE_ALTERNATING_55_AA = 1, From patchwork Thu Mar 4 12:03:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392741 Delivered-To: patch@linaro.org Received: by 2002:a17:906:a383:0:0:0:0 with SMTP id k3csp6374903ejz; Thu, 4 Mar 2021 14:26:56 -0800 (PST) X-Google-Smtp-Source: ABdhPJzN63TNCBviUkjyJLn+47kC/oDuc0EUVaZy+oK0IV13glWudQXVwcIT4cQQ0xZERzfcKv0D X-Received: by 2002:a17:906:228d:: with SMTP id p13mr6611097eja.412.1614896816623; Thu, 04 Mar 2021 14:26:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614896816; cv=none; d=google.com; s=arc-20160816; b=iHmkrPF/Iiz9JrUNQhEF4glVFIXl0XJzEHkN8N0WJkhbekc4vcQG6hclvXq6zr6wiQ 7QsUAv42Ln4Qb6HKOdH4eJQovs7yK9KIFmJ9M68KQOGCiGk+7gjmZU+Yisqq/HQ3ffmz TbxMwQXJ3sL0RglVCLbD1QP7h+SoqBXbahpk5meO+77QyY8Fp83b9AoQFPQ2/4nCqwsd 6KgvvS0b3yvcpCpx4j0vRWt41Vu63t96T2TitGJGuzZWjdrJnRLgII3D0eVnUmDSnU+N AEEbO7UZtgh/azXZmPaicDQt+p+CS8G3Y85CzKeVJQcPOWakDihIsJvADFiaP+8FY7OD iKow== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=tipz8mV12cfhNcCz1zUu0j86/0ykgLELwqow6S/hORI=; b=HzXpebB9EEDXUdNjQc4efYfInsFJl8hmODkHwLhb93LV35BjpjOMbNpKo+m/A1BAq+ NX2qwoqWwxFJ3oZo+Q4gT2mEmm8lvmqRVPMwiUYmj6QqyNn2axGbPa+0oV6/gI8ZOHek RSCzPRVay7yjHaCFA56cSZfD1S35OLLvXYvyyqz4hMOvByP15fHLCTE8BbrghPPrF5hy FnKO45vbfZCZCGyvmxB59gyFi/ngPqcjgCUamZ2Wwx06sh7CccPzjAWoDhq7jvAMIDQY urqlZWfmNwvDvHvhxiI39pD7iID/w+GN7+DjgyI3m2dtKpQG+7Zahuvu1z6EDolburw5 W3Vw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=EWmnl0bl; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k6si527757edj.545.2021.03.04.14.26.56; Thu, 04 Mar 2021 14:26:56 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=EWmnl0bl; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239972AbhCDMGp (ORCPT + 6 others); Thu, 4 Mar 2021 07:06:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59960 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239925AbhCDMGU (ORCPT ); Thu, 4 Mar 2021 07:06:20 -0500 Received: from mail-ej1-x633.google.com (mail-ej1-x633.google.com [IPv6:2a00:1450:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 75171C061756 for ; Thu, 4 Mar 2021 04:05:47 -0800 (PST) Received: by mail-ej1-x633.google.com with SMTP id ci14so29842264ejc.7 for ; Thu, 04 Mar 2021 04:05:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tipz8mV12cfhNcCz1zUu0j86/0ykgLELwqow6S/hORI=; b=EWmnl0blrHVVYIazPVi0m8N9poQiVuG1vHTMgC/4hp1h/cdm8J80pMxKUS62Y4x6FO gkD1/K2xpnERZ22uH/1k51Ibj/cWcBSfboNPnJlfzm5WTByrAdN9Ym2caZwZBOT0ejMP eqB0vh9C7Pu+R960hB5JtgKXm3XWfwm4cUF2BUep1tHTqp8CrvDYsa3z+t9iCjs0Qwix 8XgogWR/+IyvVuNUgxi2GWcCMLCR1nSmNAPmBewiNUAu2Edo3ljIUzdjWODx7nZ593PO piNZHOeTYCGWESDzvyZbtamnzZrTPhQJL1Ka6eCRnWpC+HC2mw2Y99uc3I0UGW2q/98a rneA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tipz8mV12cfhNcCz1zUu0j86/0ykgLELwqow6S/hORI=; b=sRHv4Jg4cHJiAf5XUqLwpLJncCTQpV6qNKhja+R6gMUTIIQXF4L0KvEMmlirdv6mP5 yKplxiTOF4PTIkmFwyBOuzE6/8R4W6NE2biV0+7H2KoVKCt1YXqT0Kx+wTFsHAhKW0mN EIWnLi3xDtKCQpqHTnCqMG2ALlxroxxgQW+HeGY/KOpsEdu2SogcCsJ3376LBlK3RFun TW4urwGxtIjLjEP1VyFXglE1um+Lwj/XGmezQ1v9rGR7beShBxCU8dbtiKc5Br6Fdjhb vO8bf7awjYScnxe/pjKXZUG4KR5i6pBjrybOc8CM2HT/vvEeBAkpwM9h34JEdoHdXcpL mE8Q== X-Gm-Message-State: AOAM532sd7GWqgl3WSxCWiTqinztCBkplvMdnIg5xKejyASuA4Eu4M2n w8C/TuArpalXVAgBsNNHb4ly2A== X-Received: by 2002:a17:906:3c50:: with SMTP id i16mr3897845ejg.175.1614859545838; Thu, 04 Mar 2021 04:05:45 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:45 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 09/22] media: camss: Refactor CSID HW version support Date: Thu, 4 Mar 2021 13:03:15 +0100 Message-Id: <20210304120326.153966-10-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org In order to support Qualcomm ISP hardware architectures that diverge from older architectures, the CSID subdevice drivers needs to be refactored to better abstract the different ISP hardware architectures. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v1 - kernel test robot: Add missing include, interrupt.h Changes since v4 - Andrey: Removed whitespace from some includes - Andrey: Removed unused enum Changes since v5: - Andrey: Fixed test pattern selection logic - Andrey: Align test mode enum values with v4l mode selection return values - Andrey: r-b - Move Titan 170 test modes to the the Titan 170 commit - Fixed test pattern boundary check drivers/media/platform/qcom/camss/Makefile | 2 + .../platform/qcom/camss/camss-csid-4-1.c | 329 ++++++++++ .../platform/qcom/camss/camss-csid-4-7.c | 405 ++++++++++++ .../media/platform/qcom/camss/camss-csid.c | 603 +----------------- .../media/platform/qcom/camss/camss-csid.h | 132 +++- 5 files changed, 888 insertions(+), 583 deletions(-) create mode 100644 drivers/media/platform/qcom/camss/camss-csid-4-1.c create mode 100644 drivers/media/platform/qcom/camss/camss-csid-4-7.c -- 2.27.0 diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile index 052c4f405fa3..cff388b653ba 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -4,6 +4,8 @@ qcom-camss-objs += \ camss.o \ camss-csid.o \ + camss-csid-4-1.o \ + camss-csid-4-7.o \ camss-csiphy-2ph-1-0.o \ camss-csiphy-3ph-1-0.o \ camss-csiphy.o \ diff --git a/drivers/media/platform/qcom/camss/camss-csid-4-1.c b/drivers/media/platform/qcom/camss/camss-csid-4-1.c new file mode 100644 index 000000000000..614cea8e3547 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-csid-4-1.c @@ -0,0 +1,329 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-csid-4-1.c + * + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module + * + * Copyright (C) 2020 Linaro Ltd. + */ + +#include +#include +#include +#include +#include + +#include "camss-csid.h" +#include "camss-csid-gen1.h" +#include "camss.h" + +#define CAMSS_CSID_HW_VERSION 0x0 +#define CAMSS_CSID_CORE_CTRL_0 0x004 +#define CAMSS_CSID_CORE_CTRL_1 0x008 +#define CAMSS_CSID_RST_CMD 0x00c +#define CAMSS_CSID_CID_LUT_VC_n(n) (0x010 + 0x4 * (n)) +#define CAMSS_CSID_CID_n_CFG(n) (0x020 + 0x4 * (n)) +#define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0) +#define CAMSS_CSID_CID_n_CFG_RDI_EN BIT(1) +#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4 +#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (PLAIN_FORMAT_PLAIN8 << 8) +#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (PLAIN_FORMAT_PLAIN16 << 8) +#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9) +#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9) +#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10) +#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING (1 << 10) +#define CAMSS_CSID_IRQ_CLEAR_CMD 0x060 +#define CAMSS_CSID_IRQ_MASK 0x064 +#define CAMSS_CSID_IRQ_STATUS 0x068 +#define CAMSS_CSID_TG_CTRL 0x0a0 +#define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436 +#define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437 +#define CAMSS_CSID_TG_VC_CFG 0x0a4 +#define CAMSS_CSID_TG_VC_CFG_H_BLANKING 0x3ff +#define CAMSS_CSID_TG_VC_CFG_V_BLANKING 0x7f +#define CAMSS_CSID_TG_DT_n_CGG_0(n) (0x0ac + 0xc * (n)) +#define CAMSS_CSID_TG_DT_n_CGG_1(n) (0x0b0 + 0xc * (n)) +#define CAMSS_CSID_TG_DT_n_CGG_2(n) (0x0b4 + 0xc * (n)) + + +static const struct csid_format csid_formats[] = { + { + MEDIA_BUS_FMT_UYVY8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_VYUY8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_YUYV8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_YVYU8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_SBGGR8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SBGGR10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SBGGR12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_Y10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, +}; + +static void csid_configure_stream(struct csid_device *csid, u8 enable) +{ + struct csid_testgen_config *tg = &csid->testgen; + u32 val; + + if (enable) { + struct v4l2_mbus_framefmt *input_format; + const struct csid_format *format; + u8 vc = 0; /* Virtual Channel 0 */ + u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */ + u8 dt_shift; + + if (tg->enabled) { + /* Config Test Generator */ + u32 num_lines, num_bytes_per_line; + + input_format = &csid->fmt[MSM_CSID_PAD_SRC]; + format = csid_get_fmt_entry(csid->formats, csid->nformats, + input_format->code); + num_bytes_per_line = input_format->width * format->bpp * format->spp / 8; + num_lines = input_format->height; + + /* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */ + /* 1:0 VC */ + val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) | + ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13); + writel_relaxed(val, csid->base + CAMSS_CSID_TG_VC_CFG); + + /* 28:16 bytes per lines, 12:0 num of lines */ + val = ((num_bytes_per_line & 0x1fff) << 16) | + (num_lines & 0x1fff); + writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_0(0)); + + /* 5:0 data type */ + val = format->data_type; + writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_1(0)); + + /* 2:0 output test pattern */ + val = tg->mode - 1; + writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_2(0)); + } else { + struct csid_phy_config *phy = &csid->phy; + + input_format = &csid->fmt[MSM_CSID_PAD_SINK]; + format = csid_get_fmt_entry(csid->formats, csid->nformats, + input_format->code); + + val = phy->lane_cnt - 1; + val |= phy->lane_assign << 4; + + writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_0); + + val = phy->csiphy_id << 17; + val |= 0x9; + + writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_1); + } + + /* Config LUT */ + + dt_shift = (cid % 4) * 8; + val = readl_relaxed(csid->base + CAMSS_CSID_CID_LUT_VC_n(vc)); + val &= ~(0xff << dt_shift); + val |= format->data_type << dt_shift; + writel_relaxed(val, csid->base + CAMSS_CSID_CID_LUT_VC_n(vc)); + + val = CAMSS_CSID_CID_n_CFG_ISPIF_EN; + val |= CAMSS_CSID_CID_n_CFG_RDI_EN; + val |= format->decode_format << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT; + val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP; + writel_relaxed(val, csid->base + CAMSS_CSID_CID_n_CFG(cid)); + + if (tg->enabled) { + val = CAMSS_CSID_TG_CTRL_ENABLE; + writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL); + } + } else { + if (tg->enabled) { + val = CAMSS_CSID_TG_CTRL_DISABLE; + writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL); + } + } +} + +static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val) +{ + if (val > 0 && val < csid->testgen.nmodes) + csid->testgen.mode = val; + + return 0; +} + +static u32 csid_hw_version(struct csid_device *csid) +{ + u32 hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION); + + dev_dbg(csid->camss->dev, "CSID HW Version = 0x%08x\n", hw_version); + + return hw_version; +} + +static irqreturn_t csid_isr(int irq, void *dev) +{ + struct csid_device *csid = dev; + u32 value; + + value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS); + writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD); + + if ((value >> 11) & 0x1) + complete(&csid->reset_complete); + + return IRQ_HANDLED; +} + +static int csid_reset(struct csid_device *csid) +{ + unsigned long time; + + reinit_completion(&csid->reset_complete); + + writel_relaxed(0x7fff, csid->base + CAMSS_CSID_RST_CMD); + + time = wait_for_completion_timeout(&csid->reset_complete, + msecs_to_jiffies(CSID_RESET_TIMEOUT_MS)); + if (!time) { + dev_err(csid->camss->dev, "CSID reset timeout\n"); + return -EIO; + } + + return 0; +} + +static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code, + unsigned int match_format_idx, u32 match_code) +{ + if (match_format_idx > 0) + return 0; + + return sink_code; +} + +static void csid_subdev_init(struct csid_device *csid) +{ + csid->formats = csid_formats; + csid->nformats = ARRAY_SIZE(csid_formats); + csid->testgen.modes = csid_testgen_modes; + csid->testgen.nmodes = CSID_PAYLOAD_MODE_NUM_SUPPORTED_4_1; +} + +const struct csid_hw_ops csid_ops_4_1 = { + .configure_stream = csid_configure_stream, + .configure_testgen_pattern = csid_configure_testgen_pattern, + .hw_version = csid_hw_version, + .isr = csid_isr, + .reset = csid_reset, + .src_pad_code = csid_src_pad_code, + .subdev_init = csid_subdev_init, +}; diff --git a/drivers/media/platform/qcom/camss/camss-csid-4-7.c b/drivers/media/platform/qcom/camss/camss-csid-4-7.c new file mode 100644 index 000000000000..07a53e50d391 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-csid-4-7.c @@ -0,0 +1,405 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-csid-4-7.c + * + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module + * + * Copyright (C) 2020 Linaro Ltd. + */ +#include +#include +#include +#include +#include + +#include "camss-csid.h" +#include "camss-csid-gen1.h" +#include "camss.h" + +#define CAMSS_CSID_HW_VERSION 0x0 +#define CAMSS_CSID_CORE_CTRL_0 0x004 +#define CAMSS_CSID_CORE_CTRL_1 0x008 +#define CAMSS_CSID_RST_CMD 0x010 +#define CAMSS_CSID_CID_LUT_VC_n(n) (0x014 + 0x4 * (n)) +#define CAMSS_CSID_CID_n_CFG(n) (0x024 + 0x4 * (n)) +#define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0) +#define CAMSS_CSID_CID_n_CFG_RDI_EN BIT(1) +#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4 +#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (PLAIN_FORMAT_PLAIN8 << 8) +#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (PLAIN_FORMAT_PLAIN16 << 8) +#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9) +#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9) +#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10) +#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING (1 << 10) +#define CAMSS_CSID_IRQ_CLEAR_CMD 0x064 +#define CAMSS_CSID_IRQ_MASK 0x068 +#define CAMSS_CSID_IRQ_STATUS 0x06c +#define CAMSS_CSID_TG_CTRL 0x0a8 +#define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436 +#define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437 +#define CAMSS_CSID_TG_VC_CFG 0x0ac +#define CAMSS_CSID_TG_VC_CFG_H_BLANKING 0x3ff +#define CAMSS_CSID_TG_VC_CFG_V_BLANKING 0x7f +#define CAMSS_CSID_TG_DT_n_CGG_0(n) (0x0b4 + 0xc * (n)) +#define CAMSS_CSID_TG_DT_n_CGG_1(n) (0x0b8 + 0xc * (n)) +#define CAMSS_CSID_TG_DT_n_CGG_2(n) (0x0bc + 0xc * (n)) + + +static const struct csid_format csid_formats[] = { + { + MEDIA_BUS_FMT_UYVY8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_VYUY8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_YUYV8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_YVYU8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_SBGGR8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SBGGR10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SBGGR12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SBGGR14_1X14, + DATA_TYPE_RAW_14BIT, + DECODE_FORMAT_UNCOMPRESSED_14_BIT, + 14, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG14_1X14, + DATA_TYPE_RAW_14BIT, + DECODE_FORMAT_UNCOMPRESSED_14_BIT, + 14, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG14_1X14, + DATA_TYPE_RAW_14BIT, + DECODE_FORMAT_UNCOMPRESSED_14_BIT, + 14, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB14_1X14, + DATA_TYPE_RAW_14BIT, + DECODE_FORMAT_UNCOMPRESSED_14_BIT, + 14, + 1, + }, + { + MEDIA_BUS_FMT_Y10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, +}; + +static void csid_configure_stream(struct csid_device *csid, u8 enable) +{ + struct csid_testgen_config *tg = &csid->testgen; + u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code; + u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code; + u32 val; + + if (enable) { + struct v4l2_mbus_framefmt *input_format; + const struct csid_format *format; + u8 vc = 0; /* Virtual Channel 0 */ + u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */ + u8 dt_shift; + + if (tg->enabled) { + /* Config Test Generator */ + u32 num_bytes_per_line, num_lines; + + input_format = &csid->fmt[MSM_CSID_PAD_SRC]; + format = csid_get_fmt_entry(csid->formats, csid->nformats, + input_format->code); + num_bytes_per_line = input_format->width * format->bpp * format->spp / 8; + num_lines = input_format->height; + + /* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */ + /* 1:0 VC */ + val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) | + ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13); + writel_relaxed(val, csid->base + CAMSS_CSID_TG_VC_CFG); + + /* 28:16 bytes per lines, 12:0 num of lines */ + val = ((num_bytes_per_line & 0x1fff) << 16) | + (num_lines & 0x1fff); + writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_0(0)); + + /* 5:0 data type */ + val = format->data_type; + writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_1(0)); + + /* 2:0 output test pattern */ + val = tg->mode - 1; + writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_2(0)); + } else { + struct csid_phy_config *phy = &csid->phy; + + input_format = &csid->fmt[MSM_CSID_PAD_SINK]; + format = csid_get_fmt_entry(csid->formats, csid->nformats, + input_format->code); + + val = phy->lane_cnt - 1; + val |= phy->lane_assign << 4; + + writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_0); + + val = phy->csiphy_id << 17; + val |= 0x9; + + writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_1); + } + + /* Config LUT */ + + dt_shift = (cid % 4) * 8; + + val = readl_relaxed(csid->base + CAMSS_CSID_CID_LUT_VC_n(vc)); + val &= ~(0xff << dt_shift); + val |= format->data_type << dt_shift; + writel_relaxed(val, csid->base + CAMSS_CSID_CID_LUT_VC_n(vc)); + + val = CAMSS_CSID_CID_n_CFG_ISPIF_EN; + val |= CAMSS_CSID_CID_n_CFG_RDI_EN; + val |= format->decode_format << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT; + val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP; + + if ((sink_code == MEDIA_BUS_FMT_SBGGR10_1X10 && + src_code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) || + (sink_code == MEDIA_BUS_FMT_Y10_1X10 && + src_code == MEDIA_BUS_FMT_Y10_2X8_PADHI_LE)) { + val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING; + val |= CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16; + val |= CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB; + } + + writel_relaxed(val, csid->base + CAMSS_CSID_CID_n_CFG(cid)); + + if (tg->enabled) { + val = CAMSS_CSID_TG_CTRL_ENABLE; + writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL); + } + } else { + if (tg->enabled) { + val = CAMSS_CSID_TG_CTRL_DISABLE; + writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL); + } + } +} + +static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val) +{ + if (val > 0 && val < csid->testgen.nmodes) + csid->testgen.mode = val; + + return 0; +} + +static u32 csid_hw_version(struct csid_device *csid) +{ + u32 hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION); + + dev_dbg(csid->camss->dev, "CSID HW Version = 0x%08x\n", hw_version); + + return hw_version; +} + +/* + * isr - CSID module interrupt service routine + * @irq: Interrupt line + * @dev: CSID device + * + * Return IRQ_HANDLED on success + */ +static irqreturn_t csid_isr(int irq, void *dev) +{ + struct csid_device *csid = dev; + u32 value; + + value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS); + writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD); + + if ((value >> 11) & 0x1) + complete(&csid->reset_complete); + + return IRQ_HANDLED; +} + +/* + * csid_reset - Trigger reset on CSID module and wait to complete + * @csid: CSID device + * + * Return 0 on success or a negative error code otherwise + */ +static int csid_reset(struct csid_device *csid) +{ + unsigned long time; + + reinit_completion(&csid->reset_complete); + + writel_relaxed(0x7fff, csid->base + CAMSS_CSID_RST_CMD); + + time = wait_for_completion_timeout(&csid->reset_complete, + msecs_to_jiffies(CSID_RESET_TIMEOUT_MS)); + if (!time) { + dev_err(csid->camss->dev, "CSID reset timeout\n"); + return -EIO; + } + + return 0; +} + +static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code, + unsigned int match_format_idx, u32 match_code) +{ + switch (sink_code) { + case MEDIA_BUS_FMT_SBGGR10_1X10: + { + u32 src_code[] = { + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, + }; + + return csid_find_code(src_code, ARRAY_SIZE(src_code), + match_format_idx, match_code); + } + case MEDIA_BUS_FMT_Y10_1X10: + { + u32 src_code[] = { + MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, + }; + + return csid_find_code(src_code, ARRAY_SIZE(src_code), + match_format_idx, match_code); + } + default: + if (match_format_idx > 0) + return 0; + + return sink_code; + } +} + +static void csid_subdev_init(struct csid_device *csid) +{ + csid->formats = csid_formats; + csid->nformats = ARRAY_SIZE(csid_formats); + csid->testgen.modes = csid_testgen_modes; + csid->testgen.nmodes = CSID_PAYLOAD_MODE_NUM_SUPPORTED_4_7; +} + +const struct csid_hw_ops csid_ops_4_7 = { + .configure_stream = csid_configure_stream, + .configure_testgen_pattern = csid_configure_testgen_pattern, + .hw_version = csid_hw_version, + .isr = csid_isr, + .reset = csid_reset, + .src_pad_code = csid_src_pad_code, + .subdev_init = csid_subdev_init, +}; diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 697b51d6ad38..a76ad213604e 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -27,392 +27,35 @@ #define MSM_CSID_NAME "msm_csid" -#define CAMSS_CSID_HW_VERSION 0x0 -#define CAMSS_CSID_CORE_CTRL_0 0x004 -#define CAMSS_CSID_CORE_CTRL_1 0x008 -#define CAMSS_CSID_RST_CMD(v) ((v) == CAMSS_8x16 ? 0x00c : 0x010) -#define CAMSS_CSID_CID_LUT_VC_n(v, n) \ - (((v) == CAMSS_8x16 ? 0x010 : 0x014) + 0x4 * (n)) -#define CAMSS_CSID_CID_n_CFG(v, n) \ - (((v) == CAMSS_8x16 ? 0x020 : 0x024) + 0x4 * (n)) -#define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0) -#define CAMSS_CSID_CID_n_CFG_RDI_EN BIT(1) -#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4 -#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (PLAIN_FORMAT_PLAIN8 << 8) -#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (PLAIN_FORMAT_PLAIN16 << 8) -#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9) -#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9) -#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10) -#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING (1 << 10) -#define CAMSS_CSID_IRQ_CLEAR_CMD(v) ((v) == CAMSS_8x16 ? 0x060 : 0x064) -#define CAMSS_CSID_IRQ_MASK(v) ((v) == CAMSS_8x16 ? 0x064 : 0x068) -#define CAMSS_CSID_IRQ_STATUS(v) ((v) == CAMSS_8x16 ? 0x068 : 0x06c) -#define CAMSS_CSID_TG_CTRL(v) ((v) == CAMSS_8x16 ? 0x0a0 : 0x0a8) -#define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436 -#define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437 -#define CAMSS_CSID_TG_VC_CFG(v) ((v) == CAMSS_8x16 ? 0x0a4 : 0x0ac) -#define CAMSS_CSID_TG_VC_CFG_H_BLANKING 0x3ff -#define CAMSS_CSID_TG_VC_CFG_V_BLANKING 0x7f -#define CAMSS_CSID_TG_DT_n_CGG_0(v, n) \ - (((v) == CAMSS_8x16 ? 0x0ac : 0x0b4) + 0xc * (n)) -#define CAMSS_CSID_TG_DT_n_CGG_1(v, n) \ - (((v) == CAMSS_8x16 ? 0x0b0 : 0x0b8) + 0xc * (n)) -#define CAMSS_CSID_TG_DT_n_CGG_2(v, n) \ - (((v) == CAMSS_8x16 ? 0x0b4 : 0x0bc) + 0xc * (n)) - -#define CSID_RESET_TIMEOUT_MS 500 - - -struct csid_format { - u32 code; - u8 data_type; - u8 decode_format; - u8 bpp; - u8 spp; /* bus samples per pixel */ -}; - -static const struct csid_format csid_formats_8x16[] = { - { - MEDIA_BUS_FMT_UYVY8_2X8, - DATA_TYPE_YUV422_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 2, - }, - { - MEDIA_BUS_FMT_VYUY8_2X8, - DATA_TYPE_YUV422_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 2, - }, - { - MEDIA_BUS_FMT_YUYV8_2X8, - DATA_TYPE_YUV422_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 2, - }, - { - MEDIA_BUS_FMT_YVYU8_2X8, - DATA_TYPE_YUV422_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 2, - }, - { - MEDIA_BUS_FMT_SBGGR8_1X8, - DATA_TYPE_RAW_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 1, - }, - { - MEDIA_BUS_FMT_SGBRG8_1X8, - DATA_TYPE_RAW_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 1, - }, - { - MEDIA_BUS_FMT_SGRBG8_1X8, - DATA_TYPE_RAW_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 1, - }, - { - MEDIA_BUS_FMT_SRGGB8_1X8, - DATA_TYPE_RAW_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 1, - }, - { - MEDIA_BUS_FMT_SBGGR10_1X10, - DATA_TYPE_RAW_10BIT, - DECODE_FORMAT_UNCOMPRESSED_10_BIT, - 10, - 1, - }, - { - MEDIA_BUS_FMT_SGBRG10_1X10, - DATA_TYPE_RAW_10BIT, - DECODE_FORMAT_UNCOMPRESSED_10_BIT, - 10, - 1, - }, - { - MEDIA_BUS_FMT_SGRBG10_1X10, - DATA_TYPE_RAW_10BIT, - DECODE_FORMAT_UNCOMPRESSED_10_BIT, - 10, - 1, - }, - { - MEDIA_BUS_FMT_SRGGB10_1X10, - DATA_TYPE_RAW_10BIT, - DECODE_FORMAT_UNCOMPRESSED_10_BIT, - 10, - 1, - }, - { - MEDIA_BUS_FMT_SBGGR12_1X12, - DATA_TYPE_RAW_12BIT, - DECODE_FORMAT_UNCOMPRESSED_12_BIT, - 12, - 1, - }, - { - MEDIA_BUS_FMT_SGBRG12_1X12, - DATA_TYPE_RAW_12BIT, - DECODE_FORMAT_UNCOMPRESSED_12_BIT, - 12, - 1, - }, - { - MEDIA_BUS_FMT_SGRBG12_1X12, - DATA_TYPE_RAW_12BIT, - DECODE_FORMAT_UNCOMPRESSED_12_BIT, - 12, - 1, - }, - { - MEDIA_BUS_FMT_SRGGB12_1X12, - DATA_TYPE_RAW_12BIT, - DECODE_FORMAT_UNCOMPRESSED_12_BIT, - 12, - 1, - }, - { - MEDIA_BUS_FMT_Y10_1X10, - DATA_TYPE_RAW_10BIT, - DECODE_FORMAT_UNCOMPRESSED_10_BIT, - 10, - 1, - }, -}; - -static const struct csid_format csid_formats_8x96[] = { - { - MEDIA_BUS_FMT_UYVY8_2X8, - DATA_TYPE_YUV422_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 2, - }, - { - MEDIA_BUS_FMT_VYUY8_2X8, - DATA_TYPE_YUV422_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 2, - }, - { - MEDIA_BUS_FMT_YUYV8_2X8, - DATA_TYPE_YUV422_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 2, - }, - { - MEDIA_BUS_FMT_YVYU8_2X8, - DATA_TYPE_YUV422_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 2, - }, - { - MEDIA_BUS_FMT_SBGGR8_1X8, - DATA_TYPE_RAW_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 1, - }, - { - MEDIA_BUS_FMT_SGBRG8_1X8, - DATA_TYPE_RAW_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 1, - }, - { - MEDIA_BUS_FMT_SGRBG8_1X8, - DATA_TYPE_RAW_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 1, - }, - { - MEDIA_BUS_FMT_SRGGB8_1X8, - DATA_TYPE_RAW_8BIT, - DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 8, - 1, - }, - { - MEDIA_BUS_FMT_SBGGR10_1X10, - DATA_TYPE_RAW_10BIT, - DECODE_FORMAT_UNCOMPRESSED_10_BIT, - 10, - 1, - }, - { - MEDIA_BUS_FMT_SGBRG10_1X10, - DATA_TYPE_RAW_10BIT, - DECODE_FORMAT_UNCOMPRESSED_10_BIT, - 10, - 1, - }, - { - MEDIA_BUS_FMT_SGRBG10_1X10, - DATA_TYPE_RAW_10BIT, - DECODE_FORMAT_UNCOMPRESSED_10_BIT, - 10, - 1, - }, - { - MEDIA_BUS_FMT_SRGGB10_1X10, - DATA_TYPE_RAW_10BIT, - DECODE_FORMAT_UNCOMPRESSED_10_BIT, - 10, - 1, - }, - { - MEDIA_BUS_FMT_SBGGR12_1X12, - DATA_TYPE_RAW_12BIT, - DECODE_FORMAT_UNCOMPRESSED_12_BIT, - 12, - 1, - }, - { - MEDIA_BUS_FMT_SGBRG12_1X12, - DATA_TYPE_RAW_12BIT, - DECODE_FORMAT_UNCOMPRESSED_12_BIT, - 12, - 1, - }, - { - MEDIA_BUS_FMT_SGRBG12_1X12, - DATA_TYPE_RAW_12BIT, - DECODE_FORMAT_UNCOMPRESSED_12_BIT, - 12, - 1, - }, - { - MEDIA_BUS_FMT_SRGGB12_1X12, - DATA_TYPE_RAW_12BIT, - DECODE_FORMAT_UNCOMPRESSED_12_BIT, - 12, - 1, - }, - { - MEDIA_BUS_FMT_SBGGR14_1X14, - DATA_TYPE_RAW_14BIT, - DECODE_FORMAT_UNCOMPRESSED_14_BIT, - 14, - 1, - }, - { - MEDIA_BUS_FMT_SGBRG14_1X14, - DATA_TYPE_RAW_14BIT, - DECODE_FORMAT_UNCOMPRESSED_14_BIT, - 14, - 1, - }, - { - MEDIA_BUS_FMT_SGRBG14_1X14, - DATA_TYPE_RAW_14BIT, - DECODE_FORMAT_UNCOMPRESSED_14_BIT, - 14, - 1, - }, - { - MEDIA_BUS_FMT_SRGGB14_1X14, - DATA_TYPE_RAW_14BIT, - DECODE_FORMAT_UNCOMPRESSED_14_BIT, - 14, - 1, - }, - { - MEDIA_BUS_FMT_Y10_1X10, - DATA_TYPE_RAW_10BIT, - DECODE_FORMAT_UNCOMPRESSED_10_BIT, - 10, - 1, - }, -}; -static u32 csid_find_code(u32 *code, unsigned int n_code, - unsigned int index, u32 req_code) +u32 csid_find_code(u32 *codes, unsigned int ncodes, + unsigned int match_format_idx, u32 match_code) { int i; - if (!req_code && (index >= n_code)) + if (!match_code && (match_format_idx >= ncodes)) return 0; - for (i = 0; i < n_code; i++) - if (req_code) { - if (req_code == code[i]) - return req_code; + for (i = 0; i < ncodes; i++) + if (match_code) { + if (codes[i] == match_code) + return match_code; } else { - if (i == index) - return code[i]; - } - - return code[0]; -} - -static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code, - unsigned int index, u32 src_req_code) -{ - if (csid->camss->version == CAMSS_8x16) { - if (index > 0) - return 0; - - return sink_code; - } else if (csid->camss->version == CAMSS_8x96 || - csid->camss->version == CAMSS_660) { - switch (sink_code) { - case MEDIA_BUS_FMT_SBGGR10_1X10: - { - u32 src_code[] = { - MEDIA_BUS_FMT_SBGGR10_1X10, - MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, - }; - - return csid_find_code(src_code, ARRAY_SIZE(src_code), - index, src_req_code); - } - case MEDIA_BUS_FMT_Y10_1X10: - { - u32 src_code[] = { - MEDIA_BUS_FMT_Y10_1X10, - MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, - }; - - return csid_find_code(src_code, ARRAY_SIZE(src_code), - index, src_req_code); + if (i == match_format_idx) + return codes[i]; } - default: - if (index > 0) - return 0; - return sink_code; - } - } else { - return 0; - } + return codes[0]; } -static const struct csid_format *csid_get_fmt_entry( +const struct csid_format *csid_get_fmt_entry( const struct csid_format *formats, - unsigned int nformat, + unsigned int nformats, u32 code) { unsigned int i; - for (i = 0; i < nformat; i++) + for (i = 0; i < nformats; i++) if (code == formats[i].code) return &formats[i]; @@ -421,28 +64,6 @@ static const struct csid_format *csid_get_fmt_entry( return &formats[0]; } -/* - * csid_isr - CSID module interrupt handler - * @irq: Interrupt line - * @dev: CSID device - * - * Return IRQ_HANDLED on success - */ -static irqreturn_t csid_isr(int irq, void *dev) -{ - struct csid_device *csid = dev; - enum camss_version ver = csid->camss->version; - u32 value; - - value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS(ver)); - writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD(ver)); - - if ((value >> 11) & 0x1) - complete(&csid->reset_complete); - - return IRQ_HANDLED; -} - /* * csid_set_clock_rates - Calculate and set clock rates on CSID module * @csiphy: CSID device @@ -509,31 +130,6 @@ static int csid_set_clock_rates(struct csid_device *csid) return 0; } -/* - * csid_reset - Trigger reset on CSID module and wait to complete - * @csid: CSID device - * - * Return 0 on success or a negative error code otherwise - */ -static int csid_reset(struct csid_device *csid) -{ - unsigned long time; - - reinit_completion(&csid->reset_complete); - - writel_relaxed(0x7fff, csid->base + - CAMSS_CSID_RST_CMD(csid->camss->version)); - - time = wait_for_completion_timeout(&csid->reset_complete, - msecs_to_jiffies(CSID_RESET_TIMEOUT_MS)); - if (!time) { - dev_err(csid->camss->dev, "CSID reset timeout\n"); - return -EIO; - } - - return 0; -} - /* * csid_set_power - Power on/off CSID module * @sd: CSID V4L2 subdevice @@ -548,8 +144,6 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) int ret; if (on) { - u32 hw_version; - ret = pm_runtime_get_sync(dev); if (ret < 0) { pm_runtime_put_sync(dev); @@ -578,7 +172,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) enable_irq(csid->irq); - ret = csid_reset(csid); + ret = csid->ops->reset(csid); if (ret < 0) { disable_irq(csid->irq); camss_disable_clocks(csid->nclocks, csid->clock); @@ -587,8 +181,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) return ret; } - hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION); - dev_dbg(dev, "CSID HW Version = 0x%08x\n", hw_version); + csid->ops->hw_version(csid); } else { disable_irq(csid->irq); camss_disable_clocks(csid->nclocks, csid->clock); @@ -611,16 +204,9 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) static int csid_set_stream(struct v4l2_subdev *sd, int enable) { struct csid_device *csid = v4l2_get_subdevdata(sd); - struct csid_testgen_config *tg = &csid->testgen; - enum camss_version ver = csid->camss->version; - u32 val; + int ret; if (enable) { - u8 vc = 0; /* Virtual Channel 0 */ - u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */ - u8 dt, dt_shift, df; - int ret; - ret = v4l2_ctrl_handler_setup(&csid->ctrls); if (ret < 0) { dev_err(csid->camss->dev, @@ -628,116 +214,13 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) return ret; } - if (!tg->enabled && + if (!csid->testgen.enabled && !media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK])) return -ENOLINK; - - if (tg->enabled) { - /* Config Test Generator */ - struct v4l2_mbus_framefmt *f = - &csid->fmt[MSM_CSID_PAD_SRC]; - const struct csid_format *format = csid_get_fmt_entry( - csid->formats, csid->nformats, f->code); - u32 num_bytes_per_line = - f->width * format->bpp * format->spp / 8; - u32 num_lines = f->height; - - /* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */ - /* 1:0 VC */ - val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) | - ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13); - writel_relaxed(val, csid->base + - CAMSS_CSID_TG_VC_CFG(ver)); - - /* 28:16 bytes per lines, 12:0 num of lines */ - val = ((num_bytes_per_line & 0x1fff) << 16) | - (num_lines & 0x1fff); - writel_relaxed(val, csid->base + - CAMSS_CSID_TG_DT_n_CGG_0(ver, 0)); - - dt = format->data_type; - - /* 5:0 data type */ - val = dt; - writel_relaxed(val, csid->base + - CAMSS_CSID_TG_DT_n_CGG_1(ver, 0)); - - /* 2:0 output test pattern */ - val = tg->payload_mode; - writel_relaxed(val, csid->base + - CAMSS_CSID_TG_DT_n_CGG_2(ver, 0)); - - df = format->decode_format; - } else { - struct v4l2_mbus_framefmt *f = - &csid->fmt[MSM_CSID_PAD_SINK]; - const struct csid_format *format = csid_get_fmt_entry( - csid->formats, csid->nformats, f->code); - struct csid_phy_config *phy = &csid->phy; - - val = phy->lane_cnt - 1; - val |= phy->lane_assign << 4; - - writel_relaxed(val, - csid->base + CAMSS_CSID_CORE_CTRL_0); - - val = phy->csiphy_id << 17; - val |= 0x9; - - writel_relaxed(val, - csid->base + CAMSS_CSID_CORE_CTRL_1); - - dt = format->data_type; - df = format->decode_format; - } - - /* Config LUT */ - - dt_shift = (cid % 4) * 8; - - val = readl_relaxed(csid->base + - CAMSS_CSID_CID_LUT_VC_n(ver, vc)); - val &= ~(0xff << dt_shift); - val |= dt << dt_shift; - writel_relaxed(val, csid->base + - CAMSS_CSID_CID_LUT_VC_n(ver, vc)); - - val = CAMSS_CSID_CID_n_CFG_ISPIF_EN; - val |= CAMSS_CSID_CID_n_CFG_RDI_EN; - val |= df << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT; - val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP; - - if (csid->camss->version == CAMSS_8x96 || - csid->camss->version == CAMSS_660) { - u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code; - u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code; - - if ((sink_code == MEDIA_BUS_FMT_SBGGR10_1X10 && - src_code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) || - (sink_code == MEDIA_BUS_FMT_Y10_1X10 && - src_code == MEDIA_BUS_FMT_Y10_2X8_PADHI_LE)) { - val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING; - val |= CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16; - val |= CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB; - } - } - - writel_relaxed(val, csid->base + - CAMSS_CSID_CID_n_CFG(ver, cid)); - - if (tg->enabled) { - val = CAMSS_CSID_TG_CTRL_ENABLE; - writel_relaxed(val, csid->base + - CAMSS_CSID_TG_CTRL(ver)); - } - } else { - if (tg->enabled) { - val = CAMSS_CSID_TG_CTRL_DISABLE; - writel_relaxed(val, csid->base + - CAMSS_CSID_TG_CTRL(ver)); - } } + csid->ops->configure_stream(csid, enable); + return 0; } @@ -806,7 +289,7 @@ static void csid_try_format(struct csid_device *csid, *fmt = *__csid_get_format(csid, cfg, MSM_CSID_PAD_SINK, which); - fmt->code = csid_src_pad_code(csid, fmt->code, 0, code); + fmt->code = csid->ops->src_pad_code(csid, fmt->code, 0, code); } else { /* Test generator is enabled, set format on source */ /* pad to allow test generator usage */ @@ -856,7 +339,7 @@ static int csid_enum_mbus_code(struct v4l2_subdev *sd, MSM_CSID_PAD_SINK, code->which); - code->code = csid_src_pad_code(csid, sink_fmt->code, + code->code = csid->ops->src_pad_code(csid, sink_fmt->code, code->index, 0); if (!code->code) return -EINVAL; @@ -992,15 +475,6 @@ static int csid_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) return csid_set_format(sd, fh ? fh->pad : NULL, &format); } -static const char * const csid_test_pattern_menu[] = { - "Disabled", - "Incrementing", - "Alternating 0x55/0xAA", - "All Zeros 0x00", - "All Ones 0xFF", - "Pseudo-random Data", -}; - /* * csid_set_test_pattern - Set test generator's pattern mode * @csid: CSID device @@ -1018,25 +492,7 @@ static int csid_set_test_pattern(struct csid_device *csid, s32 value) tg->enabled = !!value; - switch (value) { - case 1: - tg->payload_mode = CSID_PAYLOAD_MODE_INCREMENTING; - break; - case 2: - tg->payload_mode = CSID_PAYLOAD_MODE_ALTERNATING_55_AA; - break; - case 3: - tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ZEROES; - break; - case 4: - tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ONES; - break; - case 5: - tg->payload_mode = CSID_PAYLOAD_MODE_RANDOM; - break; - } - - return 0; + return csid->ops->configure_testgen_pattern(csid, value); } /* @@ -1085,17 +541,14 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, csid->id = id; if (camss->version == CAMSS_8x16) { - csid->formats = csid_formats_8x16; - csid->nformats = - ARRAY_SIZE(csid_formats_8x16); + csid->ops = &csid_ops_4_1; } else if (camss->version == CAMSS_8x96 || camss->version == CAMSS_660) { - csid->formats = csid_formats_8x96; - csid->nformats = - ARRAY_SIZE(csid_formats_8x96); + csid->ops = &csid_ops_4_7; } else { return -EINVAL; } + csid->ops->subdev_init(csid); /* Memory */ @@ -1118,7 +571,7 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, csid->irq = r->start; snprintf(csid->irq_name, sizeof(csid->irq_name), "%s_%s%d", dev_name(dev), MSM_CSID_NAME, csid->id); - ret = devm_request_irq(dev, csid->irq, csid_isr, + ret = devm_request_irq(dev, csid->irq, csid->ops->isr, IRQF_TRIGGER_RISING, csid->irq_name, csid); if (ret < 0) { dev_err(dev, "request_irq failed: %d\n", ret); @@ -1329,8 +782,8 @@ int msm_csid_register_entity(struct csid_device *csid, csid->testgen_mode = v4l2_ctrl_new_std_menu_items(&csid->ctrls, &csid_ctrl_ops, V4L2_CID_TEST_PATTERN, - ARRAY_SIZE(csid_test_pattern_menu) - 1, 0, 0, - csid_test_pattern_menu); + csid->testgen.nmodes, 0, 0, + csid->testgen.modes); if (csid->ctrls.error) { dev_err(dev, "Failed to init ctrl: %d\n", csid->ctrls.error); diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h index 318c19bb26c9..60933f436daa 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.h +++ b/drivers/media/platform/qcom/camss/camss-csid.h @@ -11,6 +11,7 @@ #define QC_MSM_CAMSS_CSID_H #include +#include #include #include #include @@ -44,19 +45,44 @@ #define DATA_TYPE_RAW_16BIT 0x2e #define DATA_TYPE_RAW_20BIT 0x2f +#define CSID_RESET_TIMEOUT_MS 500 -enum csid_payload_mode { - CSID_PAYLOAD_MODE_INCREMENTING = 0, - CSID_PAYLOAD_MODE_ALTERNATING_55_AA = 1, - CSID_PAYLOAD_MODE_ALL_ZEROES = 2, - CSID_PAYLOAD_MODE_ALL_ONES = 3, - CSID_PAYLOAD_MODE_RANDOM = 4, - CSID_PAYLOAD_MODE_USER_SPECIFIED = 5, + +enum csid_testgen_mode { + CSID_PAYLOAD_MODE_DISABLED = 0, + CSID_PAYLOAD_MODE_INCREMENTING = 1, + CSID_PAYLOAD_MODE_ALTERNATING_55_AA = 2, + CSID_PAYLOAD_MODE_ALL_ZEROES = 3, + CSID_PAYLOAD_MODE_ALL_ONES = 4, + CSID_PAYLOAD_MODE_RANDOM = 5, + CSID_PAYLOAD_MODE_USER_SPECIFIED = 6, + CSID_PAYLOAD_MODE_NUM_SUPPORTED_4_1 = 7, + CSID_PAYLOAD_MODE_NUM_SUPPORTED_4_7 = 7, +}; + +static const char * const csid_testgen_modes[] = { + "Disabled", + "Incrementing", + "Alternating 0x55/0xAA", + "All Zeros 0x00", + "All Ones 0xFF", + "Pseudo-random Data", + "User Specified", +}; + +struct csid_format { + u32 code; + u8 data_type; + u8 decode_format; + u8 bpp; + u8 spp; /* bus samples per pixel */ }; struct csid_testgen_config { + enum csid_testgen_mode mode; + const char * const*modes; + u8 nmodes; u8 enabled; - enum csid_payload_mode payload_mode; }; struct csid_phy_config { @@ -65,6 +91,65 @@ struct csid_phy_config { u32 lane_assign; }; +struct csid_device; + +struct csid_hw_ops { + /* + * configure_stream - Configures and starts CSID input stream + * @csid: CSID device + */ + void (*configure_stream)(struct csid_device *csid, u8 enable); + + /* + * configure_testgen_pattern - Validates and configures output pattern mode + * of test pattern generator + * @csid: CSID device + */ + int (*configure_testgen_pattern)(struct csid_device *csid, s32 val); + + /* + * hw_version - Read hardware version register from hardware + * @csid: CSID device + */ + u32 (*hw_version)(struct csid_device *csid); + + /* + * isr - CSID module interrupt service routine + * @irq: Interrupt line + * @dev: CSID device + * + * Return IRQ_HANDLED on success + */ + irqreturn_t (*isr)(int irq, void *dev); + + /* + * reset - Trigger reset on CSID module and wait to complete + * @csid: CSID device + * + * Return 0 on success or a negative error code otherwise + */ + int (*reset)(struct csid_device *csid); + + /* + * src_pad_code - Pick an output/src format based on the input/sink format + * @csid: CSID device + * @sink_code: The sink format of the input + * @match_format_idx: Request preferred index, as defined by subdevice csid_format. + * Set @match_code to 0 if used. + * @match_code: Request preferred code, set @match_format_idx to 0 if used + * + * Return 0 on failure or src format code otherwise + */ + u32 (*src_pad_code)(struct csid_device *csid, u32 sink_code, + unsigned int match_format_idx, u32 match_code); + + /* + * subdev_init - Initialize CSID device according for hardware revision + * @csid: CSID device + */ + void (*subdev_init)(struct csid_device *csid); +}; + struct csid_device { struct camss *camss; u8 id; @@ -84,10 +169,37 @@ struct csid_device { struct v4l2_ctrl *testgen_mode; const struct csid_format *formats; unsigned int nformats; + const struct csid_hw_ops *ops; }; struct resources; + +/* + * csid_find_code - Find a format code in an array using array index or format code + * @codes: Array of format codes + * @ncodes: Length of @code array + * @req_format_idx: Request preferred index, as defined by subdevice csid_format. + * Set @match_code to 0 if used. + * @match_code: Request preferred code, set @req_format_idx to 0 if used + * + * Return 0 on failure or format code otherwise + */ +u32 csid_find_code(u32 *codes, unsigned int ncode, + unsigned int match_format_idx, u32 match_code); + +/* + * csid_get_fmt_entry - Find csid_format entry with matching format code + * @formats: Array of format csid_format entries + * @nformats: Length of @nformats array + * @code: Desired format code + * + * Return formats[0] on failure to find code + */ +const struct csid_format *csid_get_fmt_entry(const struct csid_format *formats, + unsigned int nformats, + u32 code); + int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, const struct resources *res, u8 id); @@ -98,4 +210,8 @@ void msm_csid_unregister_entity(struct csid_device *csid); void msm_csid_get_csid_id(struct media_entity *entity, u8 *id); + +extern const struct csid_hw_ops csid_ops_4_1; +extern const struct csid_hw_ops csid_ops_4_7; + #endif /* QC_MSM_CAMSS_CSID_H */ From patchwork Thu Mar 4 12:03:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 393789 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 592A2C4160E for ; Thu, 4 Mar 2021 12:07:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 46D3C64F35 for ; Thu, 4 Mar 2021 12:07:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239931AbhCDMGr (ORCPT ); Thu, 4 Mar 2021 07:06:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60012 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239940AbhCDMGd (ORCPT ); Thu, 4 Mar 2021 07:06:33 -0500 Received: from mail-ej1-x630.google.com (mail-ej1-x630.google.com [IPv6:2a00:1450:4864:20::630]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B97FCC061788 for ; Thu, 4 Mar 2021 04:05:49 -0800 (PST) Received: by mail-ej1-x630.google.com with SMTP id jt13so48957466ejb.0 for ; Thu, 04 Mar 2021 04:05:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=VaQA9iDdTqS00vGb1sDWyncDncMA6buFadik4NPZwFI=; b=lB61DR/RmAuy384eJ/pIzjbdZtpBhXB2VZaC77tKV9RqXGZ3qQB7LxCMJO9CEgW4KH IdRdMSmP1Cj3IeFU9C+h0i+V4JFVB0k0fUErXJcJ7bgulCIu3OXq3CS30A5PYlBaO/9p Zdbrb0klllZ8bNoOXei5+J7ldYruacCTBETosP5G+aYxZjvBjF0Ro+AhPNyKmYosLEQd 6ncZeSUe0MTIJz6ce8xWQ8byKGzOMUpnsCNXZrzuJnOinYc3C8+f+Z2psWJr7rdOfN4S JClnuSL6ShB290X1jmt4LHCFkStb9KpT5d8hcYzf2cuc+WH2LNLufJOyoviwFSysOzqi 5Y3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=VaQA9iDdTqS00vGb1sDWyncDncMA6buFadik4NPZwFI=; b=g59XnRwSPwa1zHfA/iftWdS6CK0v+2K1y+ZwbkCJf8cX2yPFXfc7HmFprNzsHkW79R 4tGRZ+17NrXteJO3Lrwx7mjgBsP36+fE0oJKDdBUjbeEPsFl49LadwFNkFTHCwUtddDb z5HqIIK1J0+aycA03vfIKp7AHQO6MOUhg/xpUBCf9v6WG5osicHvcqzsPiYh+CpKOF33 2rnm38J0yU/lrbA4HjoZIBHmqnDzrXO+M+jefrpItDO64B7EvwH+WRNxVT4nIw1nuXXb NAK+5oNcAFm7UEWgjkZKKKNU4JcM1QcHSUj8SrYRMLUFVnGZAkia9Nl6pefFc4WTPuL8 kcEQ== X-Gm-Message-State: AOAM5329OaM1uUGT8E1uwHVdehNyAAfVU+B7dW+z4TpfdA35y8GXvK4s YzUBYHg7Oo2rqhC9J49OEtSn6A== X-Google-Smtp-Source: ABdhPJzhDSOMFDbaQFdsxy4UUfbG7OrF4rTk6GCN2pZf5IxWosL7r7eEXxVbEeNggU3xzdbxOsnj8A== X-Received: by 2002:a17:907:6005:: with SMTP id fs5mr3886688ejc.184.1614859548287; Thu, 04 Mar 2021 04:05:48 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:47 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 10/22] media: camss: Add support for CSID hardware version Titan 170 Date: Thu, 4 Mar 2021 13:03:16 +0100 Message-Id: <20210304120326.153966-11-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add register definitions for version 170 of the Titan architecture and implement support for the CSID subdevice. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v5: - Andrey: Fix test pattern selection logic - Andrey: Add r-b - Move Titan 170 specific test modes to this commit drivers/media/platform/qcom/camss/Makefile | 1 + .../platform/qcom/camss/camss-csid-170.c | 601 ++++++++++++++++++ .../media/platform/qcom/camss/camss-csid.c | 4 + .../media/platform/qcom/camss/camss-csid.h | 9 + .../media/platform/qcom/camss/camss-vfe-170.c | 1 - drivers/media/platform/qcom/camss/camss.c | 62 ++ 6 files changed, 677 insertions(+), 1 deletion(-) create mode 100644 drivers/media/platform/qcom/camss/camss-csid-170.c diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile index cff388b653ba..0752c46ea37b 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -6,6 +6,7 @@ qcom-camss-objs += \ camss-csid.o \ camss-csid-4-1.o \ camss-csid-4-7.o \ + camss-csid-170.o \ camss-csiphy-2ph-1-0.o \ camss-csiphy-3ph-1-0.o \ camss-csiphy.o \ diff --git a/drivers/media/platform/qcom/camss/camss-csid-170.c b/drivers/media/platform/qcom/camss/camss-csid-170.c new file mode 100644 index 000000000000..ee16efecd466 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-csid-170.c @@ -0,0 +1,601 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-csid-4-7.c + * + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module + * + * Copyright (C) 2020 Linaro Ltd. + */ +#include +#include +#include +#include +#include + +#include "camss-csid.h" +#include "camss-csid-gen2.h" +#include "camss.h" + +/* The CSID 2 IP-block is different from the others, + * and is of a bare-bones Lite version, with no PIX + * interface support. As a result of that it has an + * alternate register layout. + */ +#define IS_LITE (csid->id == 2 ? 1 : 0) + +#define CSID_HW_VERSION 0x0 +#define HW_VERSION_STEPPING 0 +#define HW_VERSION_REVISION 16 +#define HW_VERSION_GENERATION 28 + +#define CSID_RST_STROBES 0x10 +#define RST_STROBES 0 + +#define CSID_CSI2_RX_IRQ_STATUS 0x20 +#define CSID_CSI2_RX_IRQ_MASK 0x24 +#define CSID_CSI2_RX_IRQ_CLEAR 0x28 + +#define CSID_CSI2_RDIN_IRQ_STATUS(rdi) ((IS_LITE ? 0x30 : 0x40) \ + + 0x10 * (rdi)) +#define CSID_CSI2_RDIN_IRQ_MASK(rdi) ((IS_LITE ? 0x34 : 0x44) \ + + 0x10 * (rdi)) +#define CSID_CSI2_RDIN_IRQ_CLEAR(rdi) ((IS_LITE ? 0x38 : 0x48) \ + + 0x10 * (rdi)) +#define CSID_CSI2_RDIN_IRQ_SET(rdi) ((IS_LITE ? 0x3C : 0x4C) \ + + 0x10 * (rdi)) + +#define CSID_TOP_IRQ_STATUS 0x70 +#define TOP_IRQ_STATUS_RESET_DONE 0 +#define CSID_TOP_IRQ_MASK 0x74 +#define CSID_TOP_IRQ_CLEAR 0x78 +#define CSID_TOP_IRQ_SET 0x7C +#define CSID_IRQ_CMD 0x80 +#define IRQ_CMD_CLEAR 0 +#define IRQ_CMD_SET 4 + +#define CSID_CSI2_RX_CFG0 0x100 +#define CSI2_RX_CFG0_NUM_ACTIVE_LANES 0 +#define CSI2_RX_CFG0_DL0_INPUT_SEL 4 +#define CSI2_RX_CFG0_DL1_INPUT_SEL 8 +#define CSI2_RX_CFG0_DL2_INPUT_SEL 12 +#define CSI2_RX_CFG0_DL3_INPUT_SEL 16 +#define CSI2_RX_CFG0_PHY_NUM_SEL 20 +#define CSI2_RX_CFG0_PHY_TYPE_SEL 24 + +#define CSID_CSI2_RX_CFG1 0x104 +#define CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN 0 +#define CSI2_RX_CFG1_DE_SCRAMBLE_EN 1 +#define CSI2_RX_CFG1_VC_MODE 2 +#define CSI2_RX_CFG1_COMPLETE_STREAM_EN 4 +#define CSI2_RX_CFG1_COMPLETE_STREAM_FRAME_TIMING 5 +#define CSI2_RX_CFG1_MISR_EN 6 +#define CSI2_RX_CFG1_CGC_MODE 7 +#define CGC_MODE_DYNAMIC_GATING 0 +#define CGC_MODE_ALWAYS_ON 1 + +#define CSID_RDI_CFG0(rdi) ((IS_LITE ? 0x200 : 0x300) \ + + 0x100 * (rdi)) +#define RDI_CFG0_BYTE_CNTR_EN 0 +#define RDI_CFG0_FORMAT_MEASURE_EN 1 +#define RDI_CFG0_TIMESTAMP_EN 2 +#define RDI_CFG0_DROP_H_EN 3 +#define RDI_CFG0_DROP_V_EN 4 +#define RDI_CFG0_CROP_H_EN 5 +#define RDI_CFG0_CROP_V_EN 6 +#define RDI_CFG0_MISR_EN 7 +#define RDI_CFG0_CGC_MODE 8 +#define CGC_MODE_DYNAMIC 0 +#define CGC_MODE_ALWAYS_ON 1 +#define RDI_CFG0_PLAIN_ALIGNMENT 9 +#define PLAIN_ALIGNMENT_LSB 0 +#define PLAIN_ALIGNMENT_MSB 1 +#define RDI_CFG0_PLAIN_FORMAT 10 +#define RDI_CFG0_DECODE_FORMAT 12 +#define RDI_CFG0_DATA_TYPE 16 +#define RDI_CFG0_VIRTUAL_CHANNEL 22 +#define RDI_CFG0_DT_ID 27 +#define RDI_CFG0_EARLY_EOF_EN 29 +#define RDI_CFG0_PACKING_FORMAT 30 +#define RDI_CFG0_ENABLE 31 + +#define CSID_RDI_CFG1(rdi) ((IS_LITE ? 0x204 : 0x304)\ + + 0x100 * (rdi)) +#define RDI_CFG1_TIMESTAMP_STB_SEL 0 + +#define CSID_RDI_CTRL(rdi) ((IS_LITE ? 0x208 : 0x308)\ + + 0x100 * (rdi)) +#define RDI_CTRL_HALT_CMD 0 +#define ALT_CMD_RESUME_AT_FRAME_BOUNDARY 1 +#define RDI_CTRL_HALT_MODE 2 + +#define CSID_RDI_FRM_DROP_PATTERN(rdi) ((IS_LITE ? 0x20C : 0x30C)\ + + 0x100 * (rdi)) +#define CSID_RDI_FRM_DROP_PERIOD(rdi) ((IS_LITE ? 0x210 : 0x310)\ + + 0x100 * (rdi)) +#define CSID_RDI_IRQ_SUBSAMPLE_PATTERN(rdi) ((IS_LITE ? 0x214 : 0x314)\ + + 0x100 * (rdi)) +#define CSID_RDI_IRQ_SUBSAMPLE_PERIOD(rdi) ((IS_LITE ? 0x218 : 0x318)\ + + 0x100 * (rdi)) +#define CSID_RDI_RPP_PIX_DROP_PATTERN(rdi) ((IS_LITE ? 0x224 : 0x324)\ + + 0x100 * (rdi)) +#define CSID_RDI_RPP_PIX_DROP_PERIOD(rdi) ((IS_LITE ? 0x228 : 0x328)\ + + 0x100 * (rdi)) +#define CSID_RDI_RPP_LINE_DROP_PATTERN(rdi) ((IS_LITE ? 0x22C : 0x32C)\ + + 0x100 * (rdi)) +#define CSID_RDI_RPP_LINE_DROP_PERIOD(rdi) ((IS_LITE ? 0x230 : 0x330)\ + + 0x100 * (rdi)) + +#define CSID_TPG_CTRL 0x600 +#define TPG_CTRL_TEST_EN 0 +#define TPG_CTRL_FS_PKT_EN 1 +#define TPG_CTRL_FE_PKT_EN 2 +#define TPG_CTRL_NUM_ACTIVE_LANES 4 +#define TPG_CTRL_CYCLES_BETWEEN_PKTS 8 +#define TPG_CTRL_NUM_TRAIL_BYTES 20 + +#define CSID_TPG_VC_CFG0 0x604 +#define TPG_VC_CFG0_VC_NUM 0 +#define TPG_VC_CFG0_NUM_ACTIVE_SLOTS 8 +#define NUM_ACTIVE_SLOTS_0_ENABLED 0 +#define NUM_ACTIVE_SLOTS_0_1_ENABLED 1 +#define NUM_ACTIVE_SLOTS_0_1_2_ENABLED 2 +#define NUM_ACTIVE_SLOTS_0_1_3_ENABLED 3 +#define TPG_VC_CFG0_LINE_INTERLEAVING_MODE 10 +#define INTELEAVING_MODE_INTERLEAVED 0 +#define INTELEAVING_MODE_ONE_SHOT 1 +#define TPG_VC_CFG0_NUM_FRAMES 16 + +#define CSID_TPG_VC_CFG1 0x608 +#define TPG_VC_CFG1_H_BLANKING_COUNT 0 +#define TPG_VC_CFG1_V_BLANKING_COUNT 12 +#define TPG_VC_CFG1_V_BLANK_FRAME_WIDTH_SEL 24 + +#define CSID_TPG_LFSR_SEED 0x60C + +#define CSID_TPG_DT_n_CFG_0(n) (0x610 + (n) * 0xC) +#define TPG_DT_n_CFG_0_FRAME_HEIGHT 0 +#define TPG_DT_n_CFG_0_FRAME_WIDTH 16 + +#define CSID_TPG_DT_n_CFG_1(n) (0x614 + (n) * 0xC) +#define TPG_DT_n_CFG_1_DATA_TYPE 0 +#define TPG_DT_n_CFG_1_ECC_XOR_MASK 8 +#define TPG_DT_n_CFG_1_CRC_XOR_MASK 16 + +#define CSID_TPG_DT_n_CFG_2(n) (0x618 + (n) * 0xC) +#define TPG_DT_n_CFG_2_PAYLOAD_MODE 0 +#define TPG_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD 4 +#define TPG_DT_n_CFG_2_ENCODE_FORMAT 16 + +#define CSID_TPG_COLOR_BARS_CFG 0x640 +#define TPG_COLOR_BARS_CFG_UNICOLOR_BAR_EN 0 +#define TPG_COLOR_BARS_CFG_UNICOLOR_BAR_SEL 4 +#define TPG_COLOR_BARS_CFG_SPLIT_EN 5 +#define TPG_COLOR_BARS_CFG_ROTATE_PERIOD 8 + +#define CSID_TPG_COLOR_BOX_CFG 0x644 +#define TPG_COLOR_BOX_CFG_MODE 0 +#define TPG_COLOR_BOX_PATTERN_SEL 2 + + +static const struct csid_format csid_formats[] = { + { + MEDIA_BUS_FMT_UYVY8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_VYUY8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_YUYV8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_YVYU8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 2, + }, + { + MEDIA_BUS_FMT_SBGGR8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + 1, + }, + { + MEDIA_BUS_FMT_SBGGR10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_Y10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + 1, + }, + { + MEDIA_BUS_FMT_SBGGR12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + 1, + }, + { + MEDIA_BUS_FMT_SBGGR14_1X14, + DATA_TYPE_RAW_14BIT, + DECODE_FORMAT_UNCOMPRESSED_14_BIT, + 14, + 1, + }, + { + MEDIA_BUS_FMT_SGBRG14_1X14, + DATA_TYPE_RAW_14BIT, + DECODE_FORMAT_UNCOMPRESSED_14_BIT, + 14, + 1, + }, + { + MEDIA_BUS_FMT_SGRBG14_1X14, + DATA_TYPE_RAW_14BIT, + DECODE_FORMAT_UNCOMPRESSED_14_BIT, + 14, + 1, + }, + { + MEDIA_BUS_FMT_SRGGB14_1X14, + DATA_TYPE_RAW_14BIT, + DECODE_FORMAT_UNCOMPRESSED_14_BIT, + 14, + 1, + }, +}; + +static void csid_configure_stream(struct csid_device *csid, u8 enable) +{ + struct csid_testgen_config *tg = &csid->testgen; + u32 val; + u32 phy_sel = 0; + u8 lane_cnt = csid->phy.lane_cnt; + struct v4l2_mbus_framefmt *input_format = + &csid->fmt[MSM_CSID_PAD_SRC]; + const struct csid_format *format = csid_get_fmt_entry( + csid->formats, csid->nformats, input_format->code); + if (!lane_cnt) + lane_cnt = 4; + + if (!tg->enabled) + phy_sel = csid->phy.csiphy_id; + + if (enable) { + u8 vc = 0; /* Virtual Channel 0 */ + u8 dt_id = vc * 4; + + if (tg->enabled) { + /* Config Test Generator */ + vc = 0xa; + + /* configure one DT, infinite frames */ + val = vc << TPG_VC_CFG0_VC_NUM; + val |= INTELEAVING_MODE_ONE_SHOT << TPG_VC_CFG0_LINE_INTERLEAVING_MODE; + val |= 0 << TPG_VC_CFG0_NUM_FRAMES; + writel_relaxed(val, csid->base + CSID_TPG_VC_CFG0); + + val = 0x740 << TPG_VC_CFG1_H_BLANKING_COUNT; + val |= 0x3ff << TPG_VC_CFG1_V_BLANKING_COUNT; + writel_relaxed(val, csid->base + CSID_TPG_VC_CFG1); + + writel_relaxed(0x12345678, csid->base + CSID_TPG_LFSR_SEED); + + val = input_format->height & 0x1fff << TPG_DT_n_CFG_0_FRAME_HEIGHT; + val |= input_format->width & 0x1fff << TPG_DT_n_CFG_0_FRAME_WIDTH; + writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_0(0)); + + val = DATA_TYPE_RAW_10BIT << TPG_DT_n_CFG_1_DATA_TYPE; + writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_1(0)); + + val = tg->mode << TPG_DT_n_CFG_2_PAYLOAD_MODE; + val |= 0xBE << TPG_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD; + val |= format->decode_format << TPG_DT_n_CFG_2_ENCODE_FORMAT; + writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_2(0)); + + writel_relaxed(0, csid->base + CSID_TPG_COLOR_BARS_CFG); + + writel_relaxed(0, csid->base + CSID_TPG_COLOR_BOX_CFG); + } + + val = 1 << RDI_CFG0_BYTE_CNTR_EN; + val |= 1 << RDI_CFG0_FORMAT_MEASURE_EN; + val |= 1 << RDI_CFG0_TIMESTAMP_EN; + val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT; + val |= DATA_TYPE_RAW_10BIT << RDI_CFG0_DATA_TYPE; + val |= vc << RDI_CFG0_VIRTUAL_CHANNEL; + val |= dt_id << RDI_CFG0_DT_ID; + writel_relaxed(val, csid->base + CSID_RDI_CFG0(0)); + + /* CSID_TIMESTAMP_STB_POST_IRQ */ + val = 2 << RDI_CFG1_TIMESTAMP_STB_SEL; + writel_relaxed(val, csid->base + CSID_RDI_CFG1(0)); + + val = 1; + writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PERIOD(0)); + + val = 0; + writel_relaxed(0, csid->base + CSID_RDI_FRM_DROP_PATTERN(0)); + + val = 1; + writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(0)); + + val = 0; + writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PATTERN(0)); + + val = 1; + writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PERIOD(0)); + + val = 0; + writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PATTERN(0)); + + val = 1; + writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PERIOD(0)); + + val = 0; + writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PATTERN(0)); + + val = 0; + writel_relaxed(val, csid->base + CSID_RDI_CTRL(0)); + + val = readl_relaxed(csid->base + CSID_RDI_CFG0(0)); + val |= 1 << RDI_CFG0_ENABLE; + writel_relaxed(val, csid->base + CSID_RDI_CFG0(0)); + } + + if (tg->enabled) { + val = enable << TPG_CTRL_TEST_EN; + val |= 1 << TPG_CTRL_FS_PKT_EN; + val |= 1 << TPG_CTRL_FE_PKT_EN; + val |= (lane_cnt - 1) << TPG_CTRL_NUM_ACTIVE_LANES; + val |= 0x64 << TPG_CTRL_CYCLES_BETWEEN_PKTS; + val |= 0xA << TPG_CTRL_NUM_TRAIL_BYTES; + writel_relaxed(val, csid->base + CSID_TPG_CTRL); + } + + val = (lane_cnt - 1) << CSI2_RX_CFG0_NUM_ACTIVE_LANES; + val |= csid->phy.lane_assign << CSI2_RX_CFG0_DL0_INPUT_SEL; + val |= phy_sel << CSI2_RX_CFG0_PHY_NUM_SEL; + writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG0); + + + val = 1 << CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN; + val |= 1 << CSI2_RX_CFG1_MISR_EN; + writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1); // csi2_vc_mode_shift_val ? + + /* error irqs start at BIT(11) */ + writel_relaxed(~0u, csid->base + CSID_CSI2_RX_IRQ_MASK); + + /* RDI irq */ + writel_relaxed(~0u, csid->base + CSID_TOP_IRQ_MASK); + + val = 1 << RDI_CTRL_HALT_CMD; + writel_relaxed(val, csid->base + CSID_RDI_CTRL(0)); +} + +static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val) +{ + if (val > 0 && val < csid->testgen.nmodes) + csid->testgen.mode = val; + + return 0; +} + +/* + * csid_hw_version - CSID hardware version query + * @csid: CSID device + * + * Return HW version or error + */ +static u32 csid_hw_version(struct csid_device *csid) +{ + u32 hw_version; + u32 hw_gen; + u32 hw_rev; + u32 hw_step; + + hw_version = readl_relaxed(csid->base + CSID_HW_VERSION); + hw_gen = (hw_version >> HW_VERSION_GENERATION) & 0xF; + hw_rev = (hw_version >> HW_VERSION_REVISION) & 0xFFF; + hw_step = (hw_version >> HW_VERSION_STEPPING) & 0xFFFF; + dev_dbg(csid->camss->dev, "CSID HW Version = %u.%u.%u\n", + hw_gen, hw_rev, hw_step); + + return hw_version; +} + +/* + * csid_isr - CSID module interrupt service routine + * @irq: Interrupt line + * @dev: CSID device + * + * Return IRQ_HANDLED on success + */ +static irqreturn_t csid_isr(int irq, void *dev) +{ + struct csid_device *csid = dev; + u32 val; + u8 reset_done; + + val = readl_relaxed(csid->base + CSID_TOP_IRQ_STATUS); + writel_relaxed(val, csid->base + CSID_TOP_IRQ_CLEAR); + reset_done = val & BIT(TOP_IRQ_STATUS_RESET_DONE); + + val = readl_relaxed(csid->base + CSID_CSI2_RX_IRQ_STATUS); + writel_relaxed(val, csid->base + CSID_CSI2_RX_IRQ_CLEAR); + + val = readl_relaxed(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(0)); + writel_relaxed(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(0)); + + val = 1 << IRQ_CMD_CLEAR; + writel_relaxed(val, csid->base + CSID_IRQ_CMD); + + if (reset_done) + complete(&csid->reset_complete); + + return IRQ_HANDLED; +} + +/* + * csid_reset - Trigger reset on CSID module and wait to complete + * @csid: CSID device + * + * Return 0 on success or a negative error code otherwise + */ +static int csid_reset(struct csid_device *csid) +{ + unsigned long time; + u32 val; + + reinit_completion(&csid->reset_complete); + + writel_relaxed(1, csid->base + CSID_TOP_IRQ_CLEAR); + writel_relaxed(1, csid->base + CSID_IRQ_CMD); + writel_relaxed(1, csid->base + CSID_TOP_IRQ_MASK); + writel_relaxed(1, csid->base + CSID_IRQ_CMD); + + /* preserve registers */ + val = 0x1e << RST_STROBES; + writel_relaxed(val, csid->base + CSID_RST_STROBES); + + time = wait_for_completion_timeout(&csid->reset_complete, + msecs_to_jiffies(CSID_RESET_TIMEOUT_MS)); + if (!time) { + dev_err(csid->camss->dev, "CSID reset timeout\n"); + return -EIO; + } + + return 0; +} + +static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code, + unsigned int match_format_idx, u32 match_code) +{ + switch (sink_code) { + case MEDIA_BUS_FMT_SBGGR10_1X10: + { + u32 src_code[] = { + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, + }; + + return csid_find_code(src_code, ARRAY_SIZE(src_code), + match_format_idx, match_code); + } + case MEDIA_BUS_FMT_Y10_1X10: + { + u32 src_code[] = { + MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, + }; + + return csid_find_code(src_code, ARRAY_SIZE(src_code), + match_format_idx, match_code); + } + default: + if (match_format_idx > 0) + return 0; + + return sink_code; + } +} + +static void csid_subdev_init(struct csid_device *csid) +{ + csid->formats = csid_formats; + csid->nformats = ARRAY_SIZE(csid_formats); + csid->testgen.modes = csid_testgen_modes; + csid->testgen.nmodes = CSID_PAYLOAD_MODE_NUM_SUPPORTED_170; +} + +const struct csid_hw_ops csid_ops_170 = { + .configure_stream = csid_configure_stream, + .configure_testgen_pattern = csid_configure_testgen_pattern, + .hw_version = csid_hw_version, + .isr = csid_isr, + .reset = csid_reset, + .src_pad_code = csid_src_pad_code, + .subdev_init = csid_subdev_init, +}; diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index a76ad213604e..a5a94425923a 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -124,6 +124,8 @@ static int csid_set_clock_rates(struct csid_device *csid) dev_err(dev, "clk set rate failed: %d\n", ret); return ret; } + } else if (clock->nfreqs) { + clk_set_rate(clock->clk, clock->freq[0]); } } @@ -545,6 +547,8 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, } else if (camss->version == CAMSS_8x96 || camss->version == CAMSS_660) { csid->ops = &csid_ops_4_7; + } else if (camss->version == CAMSS_845) { + csid->ops = &csid_ops_170; } else { return -EINVAL; } diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h index 60933f436daa..892150e1f7a0 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.h +++ b/drivers/media/platform/qcom/camss/camss-csid.h @@ -58,6 +58,10 @@ enum csid_testgen_mode { CSID_PAYLOAD_MODE_USER_SPECIFIED = 6, CSID_PAYLOAD_MODE_NUM_SUPPORTED_4_1 = 7, CSID_PAYLOAD_MODE_NUM_SUPPORTED_4_7 = 7, + CSID_PAYLOAD_MODE_COMPLEX_PATTERN = 7, + CSID_PAYLOAD_MODE_COLOR_BOX = 8, + CSID_PAYLOAD_MODE_COLOR_BARS = 9, + CSID_PAYLOAD_MODE_NUM_SUPPORTED_170 = 10, }; static const char * const csid_testgen_modes[] = { @@ -68,6 +72,9 @@ static const char * const csid_testgen_modes[] = { "All Ones 0xFF", "Pseudo-random Data", "User Specified", + "Complex pattern", + "Color box", + "Color bars", }; struct csid_format { @@ -213,5 +220,7 @@ void msm_csid_get_csid_id(struct media_entity *entity, u8 *id); extern const struct csid_hw_ops csid_ops_4_1; extern const struct csid_hw_ops csid_ops_4_7; +extern const struct csid_hw_ops csid_ops_170; + #endif /* QC_MSM_CAMSS_CSID_H */ diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c index 9ab5964b1e99..ce1130108e01 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-170.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c @@ -274,7 +274,6 @@ static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line) writel_relaxed(val, vfe->base + VFE_BUS_WM_PACKER_CFG(wm)); // XXX 1 for PLAIN8? /* Configure stride for RDIs */ - //val = pix->plane_fmt[0].bytesperline; val = WM_STRIDE_DEFAULT_STRIDE; writel_relaxed(val, vfe->base + VFE_BUS_WM_STRIDE(wm)); diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 0e006def1996..0b1693c34fbc 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -465,6 +465,68 @@ static const struct resources vfe_res_660[] = { } }; +static const struct resources csid_res_845[] = { + /* CSID0 */ + { + .regulator = { "vdda-csi0" }, + .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", + "soc_ahb", "vfe0", "vfe0_src", + "vfe0_cphy_rx", "csi0", + "csi0_src" }, + .clock_rate = { { 0 }, + { 384000000 }, + { 80000000 }, + { 0 }, + { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, + { 320000000 }, + { 0 }, + { 19200000, 75000000, 384000000, 538666667 }, + { 384000000 } }, + .reg = { "csid0" }, + .interrupt = { "csid0" } + }, + + /* CSID1 */ + { + .regulator = { "vdda-csi1" }, + .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", + "soc_ahb", "vfe1", "vfe1_src", + "vfe1_cphy_rx", "csi1", + "csi1_src" }, + .clock_rate = { { 0 }, + { 384000000 }, + { 80000000 }, + { 0 }, + { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, + { 320000000 }, + { 0 }, + { 19200000, 75000000, 384000000, 538666667 }, + { 384000000 } }, + .reg = { "csid1" }, + .interrupt = { "csid1" } + }, + + /* CSID2 */ + { + .regulator = { "vdda-csi2" }, + .clock = { "cpas_ahb", "cphy_rx_src", "slow_ahb_src", + "soc_ahb", "vfe_lite", "vfe_lite_src", + "vfe_lite_cphy_rx", "csi2", + "csi2_src" }, + .clock_rate = { { 0 }, + { 384000000 }, + { 80000000 }, + { 0 }, + { 19200000, 100000000, 320000000, 404000000, 480000000, 600000000 }, + { 320000000 }, + { 0 }, + { 19200000, 75000000, 384000000, 538666667 }, + { 384000000 } }, + .reg = { "csid2" }, + .interrupt = { "csid2" } + } +}; + static const struct resources vfe_res_845[] = { /* VFE0 */ { From patchwork Thu Mar 4 12:03:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 393788 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6CB60C43142 for ; Thu, 4 Mar 2021 12:07:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 55E1064F2C for ; Thu, 4 Mar 2021 12:07:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240006AbhCDMGt (ORCPT ); Thu, 4 Mar 2021 07:06:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59954 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239946AbhCDMGd (ORCPT ); Thu, 4 Mar 2021 07:06:33 -0500 Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 29D70C061797 for ; Thu, 4 Mar 2021 04:05:52 -0800 (PST) Received: by mail-ed1-x52f.google.com with SMTP id w9so18304031edt.13 for ; Thu, 04 Mar 2021 04:05:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=3KgzaXgmhrp3mv+UzWb1dQfOfC9aT/ZQo2xat0EWUJk=; b=MAy58UoLtB60fzN/6VQSRWfTC7NbYRK2gjdx8vqk0rS4L4JXQbKf6r6lDxD51McKjI 9Pdy7Mc+T/4BOMSKAs0IZTYtGfXxnKQdMYp1tQc/52u2ipGJelETljgtgt6EVJflO1Je II4aBjA3Myisn7ucRYep1pAPcu92S6l9KRYfBlWVy70kH7xoPX7ZtWdWCxKeoe0rWxR2 pJLA5mWp0I7bYe4uat5+6D834CGo0+6ZuF7CM9WRJGFHTBQTKfTzyn1B9cUmZSZWkv+t W0GziAdiG1DOSRPUEJ5wGH+K1mmw8p3ZWOZpHhGuK45xey0I0FAV5HsVMxOQj8ZeFME7 2vTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3KgzaXgmhrp3mv+UzWb1dQfOfC9aT/ZQo2xat0EWUJk=; b=pyzb+pbNVKIfvLY4l6HH7ArRd0idkSQR0/z5TrmA1SPrsDrkL8JQFjRNb8AnleFWFa MdKxVcm45hhGegIOA8ef4RXAOHO31yD0dD6gXTMmlC+/jApxntLDiFjAauoEjdjLSb2L Q6O2UbmFgdn7sLgWNmf5lGqhRtC9zdr+BkPDk35sqUYfjHVHe/pUK/M6Bn85yWLugG2X VScwOwQzZjctLtdFSv1Zlhk68Q8W62GGU9x9xr67mInZvoi2NRjGkshvyRXl3ZAkkzQu mCVyWLEkq5MI2QAsJA51z0k3DVEZdxHxaEcxuf/MkseXvTXp1iW6eooXXDtDFAdtiUx/ QL4g== X-Gm-Message-State: AOAM533HSMK7JmmHNrbYks4l59BatHKpPxavgLHWq4FSo+sNNT+mQ8UX IERLwKoBo3BIbtJh0JTZP6K7bQ== X-Google-Smtp-Source: ABdhPJy9E8c+HnznXUvB8pdvZbIWKPBXedZ0J70L2uN6v6Lp1mH1ZFhrxMxMeP9WExS4X+yoqI6/EQ== X-Received: by 2002:aa7:d7da:: with SMTP id e26mr3959477eds.269.1614859550813; Thu, 04 Mar 2021 04:05:50 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:50 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 11/22] media: camss: Add support for CSIPHY hardware version Titan 170 Date: Thu, 4 Mar 2021 13:03:17 +0100 Message-Id: <20210304120326.153966-12-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add register definitions for version 170 of the Titan architecture and implement support for the CSIPHY subdevice. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v3 - Sakari: Make variable const Changes since v4 - kernel test robot: Fix warning related to const Changes since v5: - Andrey: Fix computed register value being overwritten .../qcom/camss/camss-csiphy-3ph-1-0.c | 181 ++++++++++++++++-- .../media/platform/qcom/camss/camss-csiphy.c | 66 +++++-- drivers/media/platform/qcom/camss/camss.c | 74 +++++++ 3 files changed, 289 insertions(+), 32 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index 97cb9de85031..791d1eca2ea2 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -47,6 +47,105 @@ #define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID BIT(1) #define CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(n) (0x8b0 + 0x4 * (n)) +#define CSIPHY_DEFAULT_PARAMS 0 +#define CSIPHY_LANE_ENABLE 1 +#define CSIPHY_SETTLE_CNT_LOWER_BYTE 2 +#define CSIPHY_SETTLE_CNT_HIGHER_BYTE 3 +#define CSIPHY_DNP_PARAMS 4 +#define CSIPHY_2PH_REGS 5 +#define CSIPHY_3PH_REGS 6 + +struct csiphy_reg_t { + int32_t reg_addr; + int32_t reg_data; + int32_t delay; + uint32_t csiphy_param_type; +}; + +static const struct +csiphy_reg_t lane_regs_sdm845[5][14] = { + { + {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0034, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x001C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0008, 0x00, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0060, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0064, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + }, + { + {0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0734, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x071C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x073C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0708, 0x14, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x070C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0760, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0764, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + }, + { + {0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0234, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x021C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0200, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0208, 0x00, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x020C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0260, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0264, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + }, + { + {0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0434, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x041C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0428, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0400, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0408, 0x00, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x040C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0460, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0464, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + }, + { + {0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0634, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x061C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0628, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0600, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0608, 0x00, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x060C, 0x00, 0x00, CSIPHY_DNP_PARAMS}, + {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0660, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0664, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + }, +}; + static void csiphy_hw_version_read(struct csiphy_device *csiphy, struct device *dev) { @@ -135,26 +234,13 @@ static u8 csiphy_settle_cnt_calc(u32 pixel_clock, u8 bpp, u8 num_lanes, return settle_cnt; } -static void csiphy_lanes_enable(struct csiphy_device *csiphy, - struct csiphy_config *cfg, - u32 pixel_clock, u8 bpp, u8 lane_mask) +static void csiphy_gen1_config_lanes(struct csiphy_device *csiphy, + struct csiphy_config *cfg, + u8 settle_cnt) { struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg; - u8 settle_cnt; - u8 val, l = 0; - int i; - - settle_cnt = csiphy_settle_cnt_calc(pixel_clock, bpp, c->num_data, - csiphy->timer_clk_rate); - - val = BIT(c->clk.pos); - for (i = 0; i < c->num_data; i++) - val |= BIT(c->data[i].pos * 2); - - writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(5)); - - val = CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B; - writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(6)); + int i, l = 0; + u8 val; for (i = 0; i <= c->num_data; i++) { if (i == c->num_data) @@ -208,6 +294,65 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy, val = CSIPHY_3PH_LNn_MISC1_IS_CLKLANE; writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_MISC1(l)); +} + +static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy, + u8 settle_cnt) +{ + int i, l; + u32 val; + + for (l = 0; l < 5; l++) { + for (i = 0; i < 14; i++) { + const struct csiphy_reg_t *r = &lane_regs_sdm845[l][i]; + + switch (r->csiphy_param_type) { + case CSIPHY_SETTLE_CNT_LOWER_BYTE: + val = settle_cnt & 0xff; + break; + case CSIPHY_DNP_PARAMS: + continue; + default: + val = r->reg_data; + break; + } + writel_relaxed(val, csiphy->base + r->reg_addr); + } + } +} + +static void csiphy_lanes_enable(struct csiphy_device *csiphy, + struct csiphy_config *cfg, + u32 pixel_clock, u8 bpp, u8 lane_mask) +{ + struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg; + u8 settle_cnt; + u8 val; + int i; + + settle_cnt = csiphy_settle_cnt_calc(pixel_clock, bpp, c->num_data, + csiphy->timer_clk_rate); + + val = BIT(c->clk.pos); + for (i = 0; i < c->num_data; i++) + val |= BIT(c->data[i].pos * 2); + + writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(5)); + + val = 1; + writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(6)); + + val = 0x02; + writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(7)); + + val = 0x00; + writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(0)); + + if (csiphy->camss->version == CAMSS_8x16 || + csiphy->camss->version == CAMSS_8x96) + csiphy_gen1_config_lanes(csiphy, cfg, settle_cnt); + else if (csiphy->camss->version == CAMSS_845) + csiphy_gen2_config_lanes(csiphy, settle_cnt); val = 0xff; writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(11)); diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 509c9a59c09c..e3fdc268050c 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -73,6 +73,30 @@ static const struct csiphy_format csiphy_formats_8x96[] = { { MEDIA_BUS_FMT_Y10_1X10, 10 }, }; +static const struct csiphy_format csiphy_formats_sdm845[] = { + { MEDIA_BUS_FMT_UYVY8_2X8, 8 }, + { MEDIA_BUS_FMT_VYUY8_2X8, 8 }, + { MEDIA_BUS_FMT_YUYV8_2X8, 8 }, + { MEDIA_BUS_FMT_YVYU8_2X8, 8 }, + { MEDIA_BUS_FMT_SBGGR8_1X8, 8 }, + { MEDIA_BUS_FMT_SGBRG8_1X8, 8 }, + { MEDIA_BUS_FMT_SGRBG8_1X8, 8 }, + { MEDIA_BUS_FMT_SRGGB8_1X8, 8 }, + { MEDIA_BUS_FMT_SBGGR10_1X10, 10 }, + { MEDIA_BUS_FMT_SGBRG10_1X10, 10 }, + { MEDIA_BUS_FMT_SGRBG10_1X10, 10 }, + { MEDIA_BUS_FMT_SRGGB10_1X10, 10 }, + { MEDIA_BUS_FMT_SBGGR12_1X12, 12 }, + { MEDIA_BUS_FMT_SGBRG12_1X12, 12 }, + { MEDIA_BUS_FMT_SGRBG12_1X12, 12 }, + { MEDIA_BUS_FMT_SRGGB12_1X12, 12 }, + { MEDIA_BUS_FMT_SBGGR14_1X14, 14 }, + { MEDIA_BUS_FMT_SGBRG14_1X14, 14 }, + { MEDIA_BUS_FMT_SGRBG14_1X14, 14 }, + { MEDIA_BUS_FMT_SRGGB14_1X14, 14 }, + { MEDIA_BUS_FMT_Y10_1X10, 10 }, +}; + /* * csiphy_get_bpp - map media bus format to bits per pixel * @formats: supported media bus formats array @@ -257,16 +281,20 @@ static int csiphy_stream_on(struct csiphy_device *csiphy) return -EINVAL; } - val = readl_relaxed(csiphy->base_clk_mux); - if (cfg->combo_mode && (lane_mask & 0x18) == 0x18) { - val &= ~0xf0; - val |= cfg->csid_id << 4; - } else { - val &= ~0xf; - val |= cfg->csid_id; + if (csiphy->base_clk_mux) { + val = readl_relaxed(csiphy->base_clk_mux); + if (cfg->combo_mode && (lane_mask & 0x18) == 0x18) { + val &= ~0xf0; + val |= cfg->csid_id << 4; + } else { + val &= ~0xf; + val |= cfg->csid_id; + } + writel_relaxed(val, csiphy->base_clk_mux); + + /* Enforce reg write ordering between clk mux & lane enabling */ + wmb(); } - writel_relaxed(val, csiphy->base_clk_mux); - wmb(); csiphy->ops->lanes_enable(csiphy, cfg, pixel_clock, bpp, lane_mask); @@ -557,6 +585,10 @@ int msm_csiphy_subdev_init(struct camss *camss, csiphy->ops = &csiphy_ops_3ph_1_0; csiphy->formats = csiphy_formats_8x96; csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x96); + } else if (camss->version == CAMSS_845) { + csiphy->ops = &csiphy_ops_3ph_1_0; + csiphy->formats = csiphy_formats_sdm845; + csiphy->nformats = ARRAY_SIZE(csiphy_formats_sdm845); } else { return -EINVAL; } @@ -570,11 +602,17 @@ int msm_csiphy_subdev_init(struct camss *camss, return PTR_ERR(csiphy->base); } - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[1]); - csiphy->base_clk_mux = devm_ioremap_resource(dev, r); - if (IS_ERR(csiphy->base_clk_mux)) { - dev_err(dev, "could not map memory\n"); - return PTR_ERR(csiphy->base_clk_mux); + if (camss->version == CAMSS_8x16 || + camss->version == CAMSS_8x96) { + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, + res->reg[1]); + csiphy->base_clk_mux = devm_ioremap_resource(dev, r); + if (IS_ERR(csiphy->base_clk_mux)) { + dev_err(dev, "could not map memory\n"); + return PTR_ERR(csiphy->base_clk_mux); + } + } else { + csiphy->base_clk_mux = NULL; } /* Interrupt */ diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 0b1693c34fbc..5d0479b5589c 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -465,6 +465,80 @@ static const struct resources vfe_res_660[] = { } }; +static const struct resources csiphy_res_845[] = { + /* CSIPHY0 */ + { + .regulator = { NULL }, + .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", + "cpas_ahb", "cphy_rx_src", "csiphy0", + "csiphy0_timer_src", "csiphy0_timer" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 19200000, 240000000, 269333333 } }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" } + }, + + /* CSIPHY1 */ + { + .regulator = { NULL }, + .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", + "cpas_ahb", "cphy_rx_src", "csiphy1", + "csiphy1_timer_src", "csiphy1_timer" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 19200000, 240000000, 269333333 } }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" } + }, + + /* CSIPHY2 */ + { + .regulator = { NULL }, + .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", + "cpas_ahb", "cphy_rx_src", "csiphy2", + "csiphy2_timer_src", "csiphy2_timer" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 19200000, 240000000, 269333333 } }, + .reg = { "csiphy2" }, + .interrupt = { "csiphy2" } + }, + + /* CSIPHY3 */ + { + .regulator = { NULL }, + .clock = { "camnoc_axi", "soc_ahb", "slow_ahb_src", + "cpas_ahb", "cphy_rx_src", "csiphy3", + "csiphy3_timer_src", "csiphy3_timer" }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 19200000, 240000000, 269333333 } }, + .reg = { "csiphy3" }, + .interrupt = { "csiphy3" } + } +}; + static const struct resources csid_res_845[] = { /* CSID0 */ { From patchwork Thu Mar 4 12:03:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392744 Delivered-To: patch@linaro.org Received: by 2002:a17:906:a383:0:0:0:0 with SMTP id k3csp6374970ejz; Thu, 4 Mar 2021 14:27:02 -0800 (PST) X-Google-Smtp-Source: ABdhPJxEDuGZkLwqXft8bvpf/EEftw1KUljLUk1prT70aQp7Z/jdW9WzEUE4B6MyLtc1+ZZQhOOK X-Received: by 2002:a05:6402:215:: with SMTP id t21mr6707714edv.363.1614896822223; Thu, 04 Mar 2021 14:27:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614896822; cv=none; d=google.com; s=arc-20160816; b=Ir2mdCpUhHuZKBE8oJGExB9Aw75cshUGWINvhJSm/8CFn1Ke9mQrFn2i+TlPGp6HKP YvTL0WytBQCDZmhVQFQCnsaVrjym//79LW7l97ZErxmcIdeZLdAzKpUGgKsUj61Twgoj yilMWyYB4Nw+xuoXDfOkfniMkJBNpCsADXIrDOC+ffoyuprtWrEfWJD62e0nFTbXO5P9 XedBarN8RPdLvPe6GCwgR4ytPBDf+62uQSlP7673hRfyAMdZYunhzlyTPFh78Si8ixIv W/Oke037JE7oVieQ1f7hPnlgLeTxvu7hB5R0bVXBxiabblSi3aT/ltSgQc+NxkeZwlBT TN6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=6WKSkdfJWQT6ScsStAWwBW6BE9cv0kXfab41hM2FrSw=; b=zjOnDmuPKl/H4fyai/h4J0c7Sn6XSAxUDOikESPuxI/InavLhGkqn36CDgLBFBWmB5 xlYyH5YBQn0cBWc8Mhd8XoBFpXLFHUP1H8ZUBZMhrJMtoaYZ/qH0ZmFNAGIVp+1OKfxo gsd00onY59SJ57BUwa24QyjFDx9nMazAIClnAr6Kwv+/jgd/aFECz6KNLA+N1oo9galY ERRjHB6BZF/QWRZWvHSSs5HomsY/YwKFRm4ywrjI+sd7WZVKjP+TECZj467/td3XTafy Rtx7sf6YUv1t7xipDFtdm6M6v5pmqFjDWgrFBtA3kli9VEIcWLQvhxnIa4AL/vBZzzLq Id3g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WPsfmGsc; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k6si527757edj.545.2021.03.04.14.27.02; Thu, 04 Mar 2021 14:27:02 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WPsfmGsc; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239933AbhCDMGs (ORCPT + 6 others); Thu, 4 Mar 2021 07:06:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60024 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239950AbhCDMGe (ORCPT ); Thu, 4 Mar 2021 07:06:34 -0500 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BD481C0617AB for ; Thu, 4 Mar 2021 04:05:53 -0800 (PST) Received: by mail-ed1-x533.google.com with SMTP id w9so878040edc.11 for ; Thu, 04 Mar 2021 04:05:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6WKSkdfJWQT6ScsStAWwBW6BE9cv0kXfab41hM2FrSw=; b=WPsfmGscBQG1qAq/ELu0hlEw9yRYPqfgL40a6c1NGZKpqKmrCJH+WyidDzlLDmqJio 7lBgyjKoqOV1R+NGP+8ePO94dCmiF2HbHi2CFL6UNNsrpuGBLiWgmCWiFV2en4UfjWoO SgWldqT4mfLURsCw9eIMS+dyTXoRgSlBGKxw3+hVYlIuy19vgvEFWrJqRbPO+jNLwGIf UlwzAXWsVxP2odgt+V2ZuRsRWbYbuax78bVrup0L88C5+VmM7JOMeTUs5Gp4rrSyKYje Ml6k3vPQ/0sg9I6/3myE5AQQhqGvlaRi06alIutSPwzjC6PAm35UM43EHKxXm4WMv8rn XEHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6WKSkdfJWQT6ScsStAWwBW6BE9cv0kXfab41hM2FrSw=; b=BE7EiPvj5Jj9fJ60vlT4m5z1SZz1h7h3bL7ewFAceIXIFVseBaB/AQsV929VpItI5o Y7uWb9wkongmIgPl+xhpS/FOtg6Z3v6Zj7Eg+e+KvwuMXYu9aa2pm03+a3BB7DsrRtZ8 8DgKQZ/uZujdV1axDUfzRN4RmwP4FO1dR+6iIoJsZRBM4ZQTQr+JHE74yejaf2Yng5fN 8DZmTRF82ND0WqheZRDGZSjp3pdXB9gairXo9/N+Kdo873/Wqjnj08y1SasXGSaQHc93 FJkhhAL0kruNl+0b6OpHxIgJIZWc1HSUCT2xnn10JkgDLRQNJzTfxKwGtCkc1GxF4isk b9uA== X-Gm-Message-State: AOAM531+84+bKvUmA9tV8NKVQBFWERe7p+1WGISpH/Zc8htbuMIyB5Xg KcQiDfQ2iR6Wa8HaX3EqAby+fQ== X-Received: by 2002:a05:6402:30a5:: with SMTP id df5mr4075052edb.24.1614859552385; Thu, 04 Mar 2021 04:05:52 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:51 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 12/22] media: camss: Remove per VFE power domain toggling Date: Thu, 4 Mar 2021 13:03:18 +0100 Message-Id: <20210304120326.153966-13-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org For Titan ISPs clocks fail to re-enable during vfe_get() after any vfe has been halted and its corresponding power domain power has been detached. Since all of the clocks depend on all of the PDs, per VFE PD detaching is no option for this generation of HW. Signed-off-by: Robert Foss --- Changes since v5: - Andrey: Bifurcated PD support into Gen1 & Gen2 paths .../media/platform/qcom/camss/camss-vfe-170.c | 21 +++++ .../media/platform/qcom/camss/camss-vfe-4-1.c | 19 ++++ .../media/platform/qcom/camss/camss-vfe-4-7.c | 39 ++++++++ .../media/platform/qcom/camss/camss-vfe-4-8.c | 34 +++++++ drivers/media/platform/qcom/camss/camss-vfe.c | 6 +- drivers/media/platform/qcom/camss/camss-vfe.h | 2 + drivers/media/platform/qcom/camss/camss.c | 94 +++++++++++++------ drivers/media/platform/qcom/camss/camss.h | 10 +- 8 files changed, 189 insertions(+), 36 deletions(-) -- 2.27.0 Reviewed-by: Andrey Konovalov diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c index ce1130108e01..99f27124ad3b 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-170.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c @@ -714,6 +714,25 @@ static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm) spin_unlock_irqrestore(&vfe->output_lock, flags); } +/* + * vfe_pm_domain_off - Disable power domains specific to this VFE. + * @vfe: VFE Device + */ +static void vfe_pm_domain_off(struct vfe_device *vfe) +{ + +} + + +/* + * vfe_pm_domain_on - Enable power domains specific to this VFE. + * @vfe: VFE Device + */ +static int vfe_pm_domain_on(struct vfe_device *vfe) +{ + return 0; +} + /* * vfe_queue_buffer - Add empty buffer * @vid: Video device structure @@ -775,6 +794,8 @@ const struct vfe_hw_ops vfe_ops_170 = { .hw_version_read = vfe_hw_version_read, .isr_read = vfe_isr_read, .isr = vfe_isr, + .pm_domain_off = vfe_pm_domain_off, + .pm_domain_on = vfe_pm_domain_on, .reg_update_clear = vfe_reg_update_clear, .reg_update = vfe_reg_update, .subdev_init = vfe_subdev_init, diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c index 81756d7fd5c2..9fc44be3ccb8 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c @@ -938,6 +938,23 @@ static irqreturn_t vfe_isr(int irq, void *dev) return IRQ_HANDLED; } +/* + * vfe_pm_domain_off - Disable power domains specific to this VFE. + * @vfe: VFE Device + */ +static void vfe_pm_domain_off(struct vfe_device *vfe) +{ + +} + +/* + * vfe_pm_domain_on - Enable power domains specific to this VFE. + * @vfe: VFE Device + */ +static int vfe_pm_domain_on(struct vfe_device *vfe) +{ + return 0; +} const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_1 = { .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi, @@ -990,6 +1007,8 @@ const struct vfe_hw_ops vfe_ops_4_1 = { .hw_version_read = vfe_hw_version_read, .isr_read = vfe_isr_read, .isr = vfe_isr, + .pm_domain_off = vfe_pm_domain_off, + .pm_domain_on = vfe_pm_domain_on, .reg_update_clear = vfe_reg_update_clear, .reg_update = vfe_reg_update, .subdev_init = vfe_subdev_init, diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c index 5ecb87f1b047..41cf150d9efe 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c @@ -8,6 +8,7 @@ * Copyright (C) 2015-2018 Linaro Ltd. */ +#include #include #include #include @@ -1104,6 +1105,42 @@ static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1) writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD); } +/* + * vfe_pm_domain_off - Disable power domains specific to this VFE. + * @vfe: VFE Device + */ +static void vfe_pm_domain_off(struct vfe_device *vfe) +{ + struct camss *camss; + + if (!vfe) + return; + + camss = vfe->camss; + + device_link_del(camss->genpd_link[vfe->id]); +} + +/* + * vfe_pm_domain_on - Enable power domains specific to this VFE. + * @vfe: VFE Device + */ +static int vfe_pm_domain_on(struct vfe_device *vfe) +{ + struct camss *camss = vfe->camss; + enum vfe_line_id id = vfe->id; + + camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id], DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); + + if (!camss->genpd_link[id]) { + dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", id); + return -EINVAL; + } + + return 0; +} + static void vfe_violation_read(struct vfe_device *vfe) { u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS); @@ -1162,6 +1199,8 @@ const struct vfe_hw_ops vfe_ops_4_7 = { .hw_version_read = vfe_hw_version_read, .isr_read = vfe_isr_read, .isr = vfe_isr, + .pm_domain_off = vfe_pm_domain_off, + .pm_domain_on = vfe_pm_domain_on, .reg_update_clear = vfe_reg_update_clear, .reg_update = vfe_reg_update, .subdev_init = vfe_subdev_init, diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c index 732b93b365d3..f368870ae36d 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c @@ -8,6 +8,7 @@ * Copyright (C) 2015-2021 Linaro Ltd. */ +#include #include #include #include @@ -1098,6 +1099,37 @@ static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1) writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD); } +/* + * vfe_pm_domain_off - Disable power domains specific to this VFE. + * @vfe: VFE Device + */ +static void vfe_pm_domain_off(struct vfe_device *vfe) +{ + struct camss *camss = vfe->camss; + + device_link_del(camss->genpd_link[vfe->id]); +} + +/* + * vfe_pm_domain_on - Enable power domains specific to this VFE. + * @vfe: VFE Device + */ +static int vfe_pm_domain_on(struct vfe_device *vfe) +{ + struct camss *camss = vfe->camss; + enum vfe_line_id id = vfe->id; + + camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id], DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); + + if (!camss->genpd_link[id]) { + dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", id); + return -EINVAL; + } + + return 0; +} + static void vfe_violation_read(struct vfe_device *vfe) { u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS); @@ -1156,6 +1188,8 @@ const struct vfe_hw_ops vfe_ops_4_8 = { .hw_version_read = vfe_hw_version_read, .isr_read = vfe_isr_read, .isr = vfe_isr, + .pm_domain_off = vfe_pm_domain_off, + .pm_domain_on = vfe_pm_domain_on, .reg_update_clear = vfe_reg_update_clear, .reg_update = vfe_reg_update, .subdev_init = vfe_subdev_init, diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 6fafeb8a5484..402f18729f9f 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -580,7 +580,7 @@ static int vfe_get(struct vfe_device *vfe) mutex_lock(&vfe->power_lock); if (vfe->power_count == 0) { - ret = camss_pm_domain_on(vfe->camss, vfe->id); + ret = vfe->ops->pm_domain_on(vfe); if (ret < 0) goto error_pm_domain; @@ -620,7 +620,7 @@ static int vfe_get(struct vfe_device *vfe) error_pm_runtime_get: pm_runtime_put_sync(vfe->camss->dev); - camss_pm_domain_off(vfe->camss, vfe->id); + vfe->ops->pm_domain_off(vfe); error_pm_domain: mutex_unlock(&vfe->power_lock); @@ -646,7 +646,7 @@ static void vfe_put(struct vfe_device *vfe) } camss_disable_clocks(vfe->nclocks, vfe->clock); pm_runtime_put_sync(vfe->camss->dev); - camss_pm_domain_off(vfe->camss, vfe->id); + vfe->ops->pm_domain_off(vfe); } vfe->power_count--; diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h index 29b3d930ffc6..05839a9f60f6 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.h +++ b/drivers/media/platform/qcom/camss/camss-vfe.h @@ -106,6 +106,8 @@ struct vfe_hw_ops { void (*hw_version_read)(struct vfe_device *vfe, struct device *dev); irqreturn_t (*isr)(int irq, void *dev); void (*isr_read)(struct vfe_device *vfe, u32 *value0, u32 *value1); + void (*pm_domain_off)(struct vfe_device *vfe); + int (*pm_domain_on)(struct vfe_device *vfe); void (*reg_update)(struct vfe_device *vfe, enum vfe_line_id line_id); void (*reg_update_clear)(struct vfe_device *vfe, enum vfe_line_id line_id); diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 5d0479b5589c..0a9388227c59 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -776,24 +776,24 @@ int camss_get_pixel_clock(struct media_entity *entity, u32 *pixel_clock) int camss_pm_domain_on(struct camss *camss, int id) { - if (camss->version == CAMSS_8x96 || - camss->version == CAMSS_660) { - camss->genpd_link[id] = device_link_add(camss->dev, - camss->genpd[id], DL_FLAG_STATELESS | - DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); + int ret = 0; + + if (id < camss->vfe_num) { + struct vfe_device *vfe = &camss->vfe[id]; - if (!camss->genpd_link[id]) - return -EINVAL; + ret = vfe->ops->pm_domain_on(vfe); } - return 0; + return ret; } void camss_pm_domain_off(struct camss *camss, int id) { - if (camss->version == CAMSS_8x96 || - camss->version == CAMSS_660) - device_link_del(camss->genpd_link[id]); + if (id < camss->vfe_num) { + struct vfe_device *vfe = &camss->vfe[id]; + + vfe->ops->pm_domain_off(vfe); + } } /* @@ -1207,6 +1207,48 @@ static const struct media_device_ops camss_media_ops = { .link_notify = v4l2_pipeline_link_notify, }; + +static int camss_configure_pd(struct camss *camss) +{ + int nbr_pm_domains = 0; + int last_pm_domain = 0; + int i; + int ret; + + if (camss->version == CAMSS_8x96 || + camss->version == CAMSS_660) + nbr_pm_domains = PM_DOMAIN_GEN1_COUNT; + + for (i = 0; i < nbr_pm_domains; i++) { + camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i); + if (IS_ERR(camss->genpd[i])) { + ret = PTR_ERR(camss->genpd[i]); + goto fail_pm; + } + + camss->genpd_link[i] = device_link_add(camss->dev, camss->genpd[i], + DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); + + if (!camss->genpd_link[i]) { + dev_pm_domain_detach(camss->genpd[i], true); + ret = -EINVAL; + goto fail_pm; + } + + last_pm_domain = i; + } + + return 0; + +fail_pm: + for (i = 0; i < last_pm_domain; i++) { + device_link_del(camss->genpd_link[i]); + dev_pm_domain_detach(camss->genpd[i], true); + } + + return ret; +} + /* * camss_probe - Probe CAMSS platform device * @pdev: Pointer to CAMSS platform device @@ -1339,20 +1381,10 @@ static int camss_probe(struct platform_device *pdev) } } - if (camss->version == CAMSS_8x96 || - camss->version == CAMSS_660) { - camss->genpd[PM_DOMAIN_VFE0] = dev_pm_domain_attach_by_id( - camss->dev, PM_DOMAIN_VFE0); - if (IS_ERR(camss->genpd[PM_DOMAIN_VFE0])) - return PTR_ERR(camss->genpd[PM_DOMAIN_VFE0]); - - camss->genpd[PM_DOMAIN_VFE1] = dev_pm_domain_attach_by_id( - camss->dev, PM_DOMAIN_VFE1); - if (IS_ERR(camss->genpd[PM_DOMAIN_VFE1])) { - dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE0], - true); - return PTR_ERR(camss->genpd[PM_DOMAIN_VFE1]); - } + ret = camss_configure_pd(camss); + if (ret < 0) { + dev_err(dev, "Failed to configure power domains: %d\n", ret); + return ret; } pm_runtime_enable(dev); @@ -1373,6 +1405,9 @@ static int camss_probe(struct platform_device *pdev) void camss_delete(struct camss *camss) { + int nbr_pm_domains = 0; + int i; + v4l2_device_unregister(&camss->v4l2_dev); media_device_unregister(&camss->media_dev); media_device_cleanup(&camss->media_dev); @@ -1380,9 +1415,12 @@ void camss_delete(struct camss *camss) pm_runtime_disable(camss->dev); if (camss->version == CAMSS_8x96 || - camss->version == CAMSS_660) { - dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE0], true); - dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE1], true); + camss->version == CAMSS_660) + nbr_pm_domains = PM_DOMAIN_GEN1_COUNT; + + for (i = 0; i < nbr_pm_domains; i++) { + device_link_del(camss->genpd_link[i]); + dev_pm_domain_detach(camss->genpd[i], true); } kfree(camss); diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index b7ad8e9f68a8..244991710879 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -57,9 +57,9 @@ struct resources_ispif { }; enum pm_domain { - PM_DOMAIN_VFE0, - PM_DOMAIN_VFE1, - PM_DOMAIN_COUNT + PM_DOMAIN_VFE0 = 0, + PM_DOMAIN_VFE1 = 1, + PM_DOMAIN_GEN1_COUNT = 2, /* CAMSS series of ISPs */ }; enum camss_version { @@ -83,8 +83,8 @@ struct camss { int vfe_num; struct vfe_device *vfe; atomic_t ref_count; - struct device *genpd[PM_DOMAIN_COUNT]; - struct device_link *genpd_link[PM_DOMAIN_COUNT]; + struct device *genpd[PM_DOMAIN_GEN1_COUNT]; + struct device_link *genpd_link[PM_DOMAIN_GEN1_COUNT]; }; struct camss_camera_interface { From patchwork Thu Mar 4 12:03:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392910 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D51EFC15505 for ; Thu, 4 Mar 2021 12:07:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A76E464F3F for ; Thu, 4 Mar 2021 12:07:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239946AbhCDMGt (ORCPT ); Thu, 4 Mar 2021 07:06:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60036 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239954AbhCDMGg (ORCPT ); Thu, 4 Mar 2021 07:06:36 -0500 Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [IPv6:2a00:1450:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 94C7EC0613A7 for ; Thu, 4 Mar 2021 04:05:55 -0800 (PST) Received: by mail-ed1-x52d.google.com with SMTP id b7so20955161edz.8 for ; Thu, 04 Mar 2021 04:05:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZzNAE8DcF9c7gV07r9a7AjhjR1cDYzLUD3bNmPF3IsA=; b=IoI4Z42ESsRI/IHOgWdbFDzDe3K8zFMLxJhPAj1yPeDFYKU5ai0630E6DGe9oytfaR Y39MkN2E3MxADtOfbqgqVs9ICcWheqVm0jFWzmjHCgFp/pW/h5HL4nz0aoYaFQVBOl3g M9PlKW4GBi2XW3upiswdjDjsu2Hc0d6Fw3/zOtxNyYvD/uaBSuJkx/swuxEjrXIdSbYb 7CDx6/LW2SQa26mnlw0JhU1H257isqP1LY9jcRemmusitsU6t5qUXX3wW/opp5jcDjKM o3RQXbTWQ7Dzbv2TZC5OLGsUD32ocNswHHjbljYKEMdmW+iem+vWSqwtfsKBOUWj6iZS zxpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZzNAE8DcF9c7gV07r9a7AjhjR1cDYzLUD3bNmPF3IsA=; b=dq6cbaBSR0L1ZzyN2/Nm/qMN6LDA/PFnCmvMve8IKEVb4xUuGgBr1f5o2+OR48Um+K EcPBWu/ZTfyVbW6KqtKORAF2XqImazVDvQFmb0fPsuPrXU3CFIHgj+v2yn3AjRH0sA5l pEF6EmqhoxCg/Mlv2/Mo4yGNMs1QrPZXLAu1I+CA0g2bAqmN7hH9uSvCPhIF7sNBwl9e t0NPv+Rk6fuDN+sZmdUL/x7H7gWAuKfFFTAhcH0Gs2V3pQDoDpSGej+rrvSeidDqg8Ss uL6Dh+PdHywyQKAVt5w1W1OmSs4qO2noOh0B+3WMi9ot08MOPrfgtX96qDveHRW/CXlj byJw== X-Gm-Message-State: AOAM530eF7lP4CufCP3/SFttdm23MLS8VUmPJVUInmBQzmg/DSIiUQfG SPqJEjSOKBk9ElKBVRQJIMwRKg== X-Google-Smtp-Source: ABdhPJwGXgGGQJj8dD5+wzj5VQ2Tq754qCjScfxg3Ey/rw9mC8F7pkpkQoDM+eqRmktGOufdisWrOQ== X-Received: by 2002:aa7:d54a:: with SMTP id u10mr3985931edr.316.1614859554370; Thu, 04 Mar 2021 04:05:54 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:53 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 13/22] media: camss: Enable SDM845 Date: Thu, 4 Mar 2021 13:03:19 +0100 Message-Id: <20210304120326.153966-14-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Enable support for SDM845 based Titan 170 ISPs. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v5 - Andrey: Add r-b drivers/media/platform/qcom/camss/camss.c | 17 +++++++++++++++++ drivers/media/platform/qcom/camss/camss.h | 6 ++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 0a9388227c59..7446f9c71b3a 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -916,6 +916,12 @@ static int camss_init_subdevices(struct camss *camss) csid_res = csid_res_660; ispif_res = &ispif_res_660; vfe_res = vfe_res_660; + } else if (camss->version == CAMSS_845) { + csiphy_res = csiphy_res_845; + csid_res = csid_res_845; + /* Titan VFEs don't have an ISPIF */ + ispif_res = NULL; + vfe_res = vfe_res_845; } else { return -EINVAL; } @@ -1218,6 +1224,8 @@ static int camss_configure_pd(struct camss *camss) if (camss->version == CAMSS_8x96 || camss->version == CAMSS_660) nbr_pm_domains = PM_DOMAIN_GEN1_COUNT; + else if (camss->version == CAMSS_845) + nbr_pm_domains = PM_DOMAIN_GEN2_COUNT; for (i = 0; i < nbr_pm_domains; i++) { camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i); @@ -1286,6 +1294,12 @@ static int camss_probe(struct platform_device *pdev) camss->csiphy_num = 3; camss->csid_num = 4; camss->vfe_num = 2; + } else if (of_device_is_compatible(dev->of_node, + "qcom,sdm845-camss")) { + camss->version = CAMSS_845; + camss->csiphy_num = 4; + camss->csid_num = 3; + camss->vfe_num = 3; } else { ret = -EINVAL; goto err_free; @@ -1417,6 +1431,8 @@ void camss_delete(struct camss *camss) if (camss->version == CAMSS_8x96 || camss->version == CAMSS_660) nbr_pm_domains = PM_DOMAIN_GEN1_COUNT; + else if (camss->version == CAMSS_845) + nbr_pm_domains = PM_DOMAIN_GEN2_COUNT; for (i = 0; i < nbr_pm_domains; i++) { device_link_del(camss->genpd_link[i]); @@ -1450,6 +1466,7 @@ static const struct of_device_id camss_dt_match[] = { { .compatible = "qcom,msm8916-camss" }, { .compatible = "qcom,msm8996-camss" }, { .compatible = "qcom,sdm660-camss" }, + { .compatible = "qcom,sdm845-camss" }, { } }; diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index 244991710879..a2994c9251f4 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -60,6 +60,8 @@ enum pm_domain { PM_DOMAIN_VFE0 = 0, PM_DOMAIN_VFE1 = 1, PM_DOMAIN_GEN1_COUNT = 2, /* CAMSS series of ISPs */ + PM_DOMAIN_VFELITE = 2, /* VFELITE / TOP GDSC */ + PM_DOMAIN_GEN2_COUNT = 3, /* Titan series of ISPs */ }; enum camss_version { @@ -83,8 +85,8 @@ struct camss { int vfe_num; struct vfe_device *vfe; atomic_t ref_count; - struct device *genpd[PM_DOMAIN_GEN1_COUNT]; - struct device_link *genpd_link[PM_DOMAIN_GEN1_COUNT]; + struct device *genpd[PM_DOMAIN_GEN2_COUNT]; + struct device_link *genpd_link[PM_DOMAIN_GEN2_COUNT]; }; struct camss_camera_interface { From patchwork Thu Mar 4 12:03:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392908 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 628F3C433E0 for ; Thu, 4 Mar 2021 12:08:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3B6D264F0B for ; Thu, 4 Mar 2021 12:08:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240134AbhCDMHN (ORCPT ); Thu, 4 Mar 2021 07:07:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239975AbhCDMGp (ORCPT ); Thu, 4 Mar 2021 07:06:45 -0500 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0F0DFC0613AC for ; Thu, 4 Mar 2021 04:05:57 -0800 (PST) Received: by mail-ed1-x52b.google.com with SMTP id x9so2690203edd.0 for ; Thu, 04 Mar 2021 04:05:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=66txG9h/Sa2HP95xfnmSwTYdKsDGArIGinZp+Se9eig=; b=ffbHqcSqyWccRmM2zvj59tMlN3K3bqIpX8y2PAirYKI4o32+Ddhkk4kPtbN18gF+V9 BMWCFO8FWSBgIXQMitujFEHBPtqX7M8RyUnosQR9IptSo7JYGScbUCr7FwAcQRrzoMDL YKzW+Oax1TVIzDzRNdalhTOWtksqWXthPp9cPAq29FJnbeBA/HZn8ZoaTglBWua91fmx aEfvuWZOZU/cWJYyQRRyDb3XMfYkBg+sbGaYljbxBbppK33IbsbWUJnz6+0YmqWXsFhQ y3NzBKbqhm/7VMInXtTmjsDc9J97pivkxZRa5wEkl/XzZMpJ9Cb61oLv4qdXIZO62z7r iaOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=66txG9h/Sa2HP95xfnmSwTYdKsDGArIGinZp+Se9eig=; b=d2Byt7WALySnIDQaZRYfJrZlzhbTIJipI9ZkJRmdm+Ohh3nK7YjG32656Jlaa0NqVr OQdoQSdSuqSG+dsg7GujpsxqcFN2fSCSeto1GnVGflaIBVHxeVC5UPJ7z5Wmyz9VkM/B 9dvWwuuu+dC1EK7KtjyCLrMfrE11Y7HxxjgRVa2me6AAQ6SE6BJtZxu+wGxyKOG6MYMH 84bAa/XuOsIlq/iAC1SDAwIhUIib7adeOPOSoxva1h1as1lCXimjF+wL2Rq/roqQoj9m N+V1BcNJVFYg3EnkKp5Ewb3csgJeOkxY0uov4tVWYdULbNQUoTQF0Ab0Kn89zZPRvvPK lYtg== X-Gm-Message-State: AOAM532mlQEZd91JzbFmpVhu+MVGX1mI+TsWx1zfarn36aUdWqI7to2a 9b+Yu+x1Jc7uii+y42uR/yY8Rg== X-Google-Smtp-Source: ABdhPJxFqPBr/Jw/mOSCWhyxCvpXQ+/kvbyh9FWALHjIe4SzTtYSlVjW/NqA+RbYZfqWtaYX95XblA== X-Received: by 2002:aa7:d44a:: with SMTP id q10mr3880520edr.278.1614859555799; Thu, 04 Mar 2021 04:05:55 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:55 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 14/22] dt-bindings: media: camss: Add qcom, msm8916-camss binding Date: Thu, 4 Mar 2021 13:03:20 +0100 Message-Id: <20210304120326.153966-15-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add bindings for qcom,msm8916-camss in order to support the camera subsystem on MSM8916. Signed-off-by: Robert Foss Reviewed-by: Rob Herring --- Changes since v2: - Remove redundant descriptions - Add power domain description - Make clock-lanes a constant - Add max & minItems to data-lanes - Remove ports requirement - endpoint & reg - Rework to conform to new port schema Changes since v4 - Rob: Added r-b .../bindings/media/qcom,msm8916-camss.yaml | 256 ++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml diff --git a/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml new file mode 100644 index 000000000000..304908072d72 --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml @@ -0,0 +1,256 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) + +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/media/qcom,msm8916-camss.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Qualcomm CAMSS ISP + +maintainers: + - Robert Foss + - Todor Tomov + +description: | + The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms + +properties: + compatible: + const: qcom,msm8916-camss + + clocks: + minItems: 19 + maxItems: 19 + + clock-names: + items: + - const: top_ahb + - const: ispif_ahb + - const: csiphy0_timer + - const: csiphy1_timer + - const: csi0_ahb + - const: csi0 + - const: csi0_phy + - const: csi0_pix + - const: csi0_rdi + - const: csi1_ahb + - const: csi1 + - const: csi1_phy + - const: csi1_pix + - const: csi1_rdi + - const: ahb + - const: vfe0 + - const: csi_vfe0 + - const: vfe_ahb + - const: vfe_axi + + interrupts: + minItems: 6 + maxItems: 6 + + interrupt-names: + items: + - const: csiphy0 + - const: csiphy1 + - const: csid0 + - const: csid1 + - const: ispif + - const: vfe0 + + iommus: + maxItems: 1 + + power-domains: + items: + - description: VFE GDSC - Video Front End, Global Distributed Switch Controller. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + description: + CSI input ports. + + properties: + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + items: + - const: 1 + + data-lanes: + description: + An array of physical data lanes indexes. + Position of an entry determines the logical + lane number, while the value of an entry + indicates physical lane index. Lane swapping + is supported. Physical lane indexes; + 0, 2, 3, 4. + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + port@1: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + items: + - const: 1 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + reg: + minItems: 9 + maxItems: 9 + + reg-names: + items: + - const: csiphy0 + - const: csiphy0_clk_mux + - const: csiphy1 + - const: csiphy1_clk_mux + - const: csid0 + - const: csid1 + - const: ispif + - const: csi_clk_mux + - const: vfe0 + + vdda-supply: + description: + Definition of the regulator used as analog power supply. + +required: + - clock-names + - clocks + - compatible + - interrupt-names + - interrupts + - iommus + - power-domains + - reg + - reg-names + - vdda-supply + +additionalProperties: false + +examples: + - | + #include + #include + + camss: camss@1b00000 { + compatible = "qcom,msm8916-camss"; + + clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>, + <&gcc GCC_CAMSS_ISPIF_AHB_CLK>, + <&gcc GCC_CAMSS_CSI0PHYTIMER_CLK>, + <&gcc GCC_CAMSS_CSI1PHYTIMER_CLK>, + <&gcc GCC_CAMSS_CSI0_AHB_CLK>, + <&gcc GCC_CAMSS_CSI0_CLK>, + <&gcc GCC_CAMSS_CSI0PHY_CLK>, + <&gcc GCC_CAMSS_CSI0PIX_CLK>, + <&gcc GCC_CAMSS_CSI0RDI_CLK>, + <&gcc GCC_CAMSS_CSI1_AHB_CLK>, + <&gcc GCC_CAMSS_CSI1_CLK>, + <&gcc GCC_CAMSS_CSI1PHY_CLK>, + <&gcc GCC_CAMSS_CSI1PIX_CLK>, + <&gcc GCC_CAMSS_CSI1RDI_CLK>, + <&gcc GCC_CAMSS_AHB_CLK>, + <&gcc GCC_CAMSS_VFE0_CLK>, + <&gcc GCC_CAMSS_CSI_VFE0_CLK>, + <&gcc GCC_CAMSS_VFE_AHB_CLK>, + <&gcc GCC_CAMSS_VFE_AXI_CLK>; + + clock-names = "top_ahb", + "ispif_ahb", + "csiphy0_timer", + "csiphy1_timer", + "csi0_ahb", + "csi0", + "csi0_phy", + "csi0_pix", + "csi0_rdi", + "csi1_ahb", + "csi1", + "csi1_phy", + "csi1_pix", + "csi1_rdi", + "ahb", + "vfe0", + "csi_vfe0", + "vfe_ahb", + "vfe_axi"; + + interrupts = , + , + , + , + , + ; + + interrupt-names = "csiphy0", + "csiphy1", + "csid0", + "csid1", + "ispif", + "vfe0"; + + iommus = <&apps_iommu 3>; + + power-domains = <&gcc VFE_GDSC>; + + reg = <0x01b0ac00 0x200>, + <0x01b00030 0x4>, + <0x01b0b000 0x200>, + <0x01b00038 0x4>, + <0x01b08000 0x100>, + <0x01b08400 0x100>, + <0x01b0a000 0x500>, + <0x01b00020 0x10>, + <0x01b10000 0x1000>; + + reg-names = "csiphy0", + "csiphy0_clk_mux", + "csiphy1", + "csiphy1_clk_mux", + "csid0", + "csid1", + "ispif", + "csi_clk_mux", + "vfe0"; + + vdda-supply = <®_2v8>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + }; + + }; From patchwork Thu Mar 4 12:03:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392747 Delivered-To: patch@linaro.org Received: by 2002:a17:906:a383:0:0:0:0 with SMTP id k3csp6375129ejz; Thu, 4 Mar 2021 14:27:14 -0800 (PST) X-Google-Smtp-Source: ABdhPJw/DrpDH1YvK1zNM1AWGbHHW/k82vA/K+OdOmmqilrUNHQJXP8jM7xrWntujvNPLUvmm/Iw X-Received: by 2002:a17:906:1d0f:: with SMTP id n15mr6490072ejh.553.1614896834189; Thu, 04 Mar 2021 14:27:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614896834; cv=none; d=google.com; s=arc-20160816; b=hRx0I527GG5cqoFvcDu9OawcrTC8xV8ovMoUMZt/IHx8J65tZqBRX/UVN51E9RDsZv mJGK7QUilIV1TFx6XIx0YRMmbXw2dVBl8NIdyMeK/spEh5NW8MUFEmYEsD+appNFwzOG Wi08srny0BR3L8dE1CjkYUrSfhcCCsriJ+oYkCPEjx1NK9iXYsjYd2qLrhSXfG15f/rS ya0maLLR1fcTTMOpEILU2yGvDjgM6sjGqEwW4JZMjsYLmrI5RL+qamrM6kVP2Myq14s7 oyGwMspaYslKOMzOwRU7Zi2Z7o12ysfbuGutecLcqgNbfMgmb/eA0rKRrpMALMYQV54a Uliw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=XUCuZpI4APd5cw/zyopVDFOJtJjTtpVVUOwXt4jTqnE=; b=lOoJd7Gtcsq6YhUqHaumjCSbpeV8wOXtHqxcNFcGE9woePzhOQaVz568Os3h44TIs2 ySbXP357r0cW9+69aHE+kG5l7gqAowvzBk7x7BnEHRtCuofDDya5sJG1NYFCI40KFQZx 9YiP8GrxorcTIHKkrvMLjcgoyqrMHVSkkF9J2c3IGig/u/pRteKpu/1VZPoNrR70KpeR f/2Vh7PApc5ZN+ZCW6NrQvFxYEcI1HBp8hqARoNo2H8blSmIv/eAJcQRGmze0FgmftGT HNIu4dtobJ3JMyTR7GqtWYaeYbzY2CZT8Y+X/DQfzJZ/t7n3fE5XRfWkSqaspsJVhT0H tmBQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=egPiLqC3; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k6si527757edj.545.2021.03.04.14.27.14; Thu, 04 Mar 2021 14:27:14 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=egPiLqC3; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239982AbhCDMHQ (ORCPT + 6 others); Thu, 4 Mar 2021 07:07:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60014 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239989AbhCDMGs (ORCPT ); Thu, 4 Mar 2021 07:06:48 -0500 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9489CC0613AF for ; Thu, 4 Mar 2021 04:05:58 -0800 (PST) Received: by mail-ed1-x535.google.com with SMTP id v13so18023344edw.9 for ; Thu, 04 Mar 2021 04:05:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XUCuZpI4APd5cw/zyopVDFOJtJjTtpVVUOwXt4jTqnE=; b=egPiLqC3gMG9oktufM3LbqssWw8D8Uma9bwcJwl7slhYqniMeYVt0AxG4+pdVo4C2Y cmAfkbSwPyhiU/jj/5xLC1a8k7vIYTsh6V1c2G/E2g+8Abrbzfm4KhvmkLfpZeTIiCqL 9YWJ1zUa/jJNoKxqUIZj2Pxzh9yT0vzQBy+4FK3nC9u5ZnXTrqgTVIMnDn5MkrjKYkoG RE+s0vZVexaGG2M6NW+XVJf9y2oSG0gZG9M+p966SWOL7icTWMWOPbvH+8NGVwQziYGc E6Ua1X0U9JuHhP8UK8yyJ5PuSRh5FGNCwPD0AE7IVrSjAOFuaN/fIY00o+2AZ2AJZE3z Bi1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XUCuZpI4APd5cw/zyopVDFOJtJjTtpVVUOwXt4jTqnE=; b=irghMyfJjUzPhcwI+1nk3qYZIqEAHbY12g0hzyn5LM5M46aJ1zbXN/uYdDHz5QhoEn vLVdo1YHxIxS1haGfGXfSBiLzU9m9x9ARxhIAzDjUmgJahuwz32uFbxQfuaKej7OecXO 6GXhLhaDmMz0u0J8rjxiWacQ6Ra5eTpTIQDtvRAzWBLaZsqAU05/cjHmrg6CrENNbFfz wMypSY4N7U2DT1FAlAE161MT16I6KUKZmZ6snBFVyecZCu4wjVaveyVKGyQjP4atjiSU UYBeOc0POIsQttvJBsyy1wZcVwUktRw5MwL2yPuwxQXFth3sQsXBXyesNko/BZ/uxl1V pw8A== X-Gm-Message-State: AOAM530I2Z3cZifU8Ua65Sh2dnDzSHWxha4m/8nF0XPU68grLp92Q4Qj EqypRT9uIxAr3Ngd6Ccr9gUGyhRhZEp5nb9O X-Received: by 2002:a50:ec81:: with SMTP id e1mr3886582edr.0.1614859557184; Thu, 04 Mar 2021 04:05:57 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:56 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 15/22] dt-bindings: media: camss: Add qcom, msm8996-camss binding Date: Thu, 4 Mar 2021 13:03:21 +0100 Message-Id: <20210304120326.153966-16-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add bindings for qcom,msm8996-camss in order to support the camera subsystem on MSM8996. Signed-off-by: Robert Foss Reviewed-by: Rob Herring --- Changes since v2 - Rob: Add new line at end of file - Rob: Remove redundant descriptions - Rob: Add power domain description - Rob: Make clock-lanes a constant - Rob: Rework to conform to new port schema - Add max & minItems to data-lanes - Remove ports requirement - endpoint & reg Changes since v4 - Rob: Added r-b .../bindings/media/qcom,msm8996-camss.yaml | 387 ++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml -- 2.27.0 diff --git a/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml new file mode 100644 index 000000000000..38be41e932f0 --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml @@ -0,0 +1,387 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) + +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/media/qcom,msm8996-camss.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Qualcomm CAMSS ISP + +maintainers: + - Robert Foss + - Todor Tomov + +description: | + The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms + +properties: + compatible: + const: qcom,msm8996-camss + + clocks: + minItems: 36 + maxItems: 36 + + clock-names: + items: + - const: top_ahb + - const: ispif_ahb + - const: csiphy0_timer + - const: csiphy1_timer + - const: csiphy2_timer + - const: csi0_ahb + - const: csi0 + - const: csi0_phy + - const: csi0_pix + - const: csi0_rdi + - const: csi1_ahb + - const: csi1 + - const: csi1_phy + - const: csi1_pix + - const: csi1_rdi + - const: csi2_ahb + - const: csi2 + - const: csi2_phy + - const: csi2_pix + - const: csi2_rdi + - const: csi3_ahb + - const: csi3 + - const: csi3_phy + - const: csi3_pix + - const: csi3_rdi + - const: ahb + - const: vfe0 + - const: csi_vfe0 + - const: vfe0_ahb + - const: vfe0_stream + - const: vfe1 + - const: csi_vfe1 + - const: vfe1_ahb + - const: vfe1_stream + - const: vfe_ahb + - const: vfe_axi + + interrupts: + minItems: 10 + maxItems: 10 + + interrupt-names: + items: + - const: csiphy0 + - const: csiphy1 + - const: csiphy2 + - const: csid0 + - const: csid1 + - const: csid2 + - const: csid3 + - const: ispif + - const: vfe0 + - const: vfe1 + + iommus: + maxItems: 4 + + power-domains: + items: + - description: VFE0 GDSC - Video Front End, Global Distributed Switch Controller. + - description: VFE1 GDSC - Video Front End, Global Distributed Switch Controller. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + description: + CSI input ports. + + properties: + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + items: + - const: 7 + + data-lanes: + description: + An array of physical data lanes indexes. + Position of an entry determines the logical + lane number, while the value of an entry + indicates physical lane index. Lane swapping + is supported. Physical lane indexes are; + 0, 1, 2, 3 + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + port@1: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + items: + - const: 7 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + port@2: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + items: + - const: 7 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + port@3: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + items: + - const: 7 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + reg: + minItems: 14 + maxItems: 14 + + reg-names: + items: + - const: csiphy0 + - const: csiphy0_clk_mux + - const: csiphy1 + - const: csiphy1_clk_mux + - const: csiphy2 + - const: csiphy2_clk_mux + - const: csid0 + - const: csid1 + - const: csid2 + - const: csid3 + - const: ispif + - const: csi_clk_mux + - const: vfe0 + - const: vfe1 + + vdda-supply: + description: + Definition of the regulator used as analog power supply. + +required: + - clock-names + - clocks + - compatible + - interrupt-names + - interrupts + - iommus + - power-domains + - reg + - reg-names + - vdda-supply + +additionalProperties: false + +examples: + - | + #include + #include + #include + + camss: camss@a00000 { + compatible = "qcom,msm8996-camss"; + + clocks = <&mmcc CAMSS_TOP_AHB_CLK>, + <&mmcc CAMSS_ISPIF_AHB_CLK>, + <&mmcc CAMSS_CSI0PHYTIMER_CLK>, + <&mmcc CAMSS_CSI1PHYTIMER_CLK>, + <&mmcc CAMSS_CSI2PHYTIMER_CLK>, + <&mmcc CAMSS_CSI0_AHB_CLK>, + <&mmcc CAMSS_CSI0_CLK>, + <&mmcc CAMSS_CSI0PHY_CLK>, + <&mmcc CAMSS_CSI0PIX_CLK>, + <&mmcc CAMSS_CSI0RDI_CLK>, + <&mmcc CAMSS_CSI1_AHB_CLK>, + <&mmcc CAMSS_CSI1_CLK>, + <&mmcc CAMSS_CSI1PHY_CLK>, + <&mmcc CAMSS_CSI1PIX_CLK>, + <&mmcc CAMSS_CSI1RDI_CLK>, + <&mmcc CAMSS_CSI2_AHB_CLK>, + <&mmcc CAMSS_CSI2_CLK>, + <&mmcc CAMSS_CSI2PHY_CLK>, + <&mmcc CAMSS_CSI2PIX_CLK>, + <&mmcc CAMSS_CSI2RDI_CLK>, + <&mmcc CAMSS_CSI3_AHB_CLK>, + <&mmcc CAMSS_CSI3_CLK>, + <&mmcc CAMSS_CSI3PHY_CLK>, + <&mmcc CAMSS_CSI3PIX_CLK>, + <&mmcc CAMSS_CSI3RDI_CLK>, + <&mmcc CAMSS_AHB_CLK>, + <&mmcc CAMSS_VFE0_CLK>, + <&mmcc CAMSS_CSI_VFE0_CLK>, + <&mmcc CAMSS_VFE0_AHB_CLK>, + <&mmcc CAMSS_VFE0_STREAM_CLK>, + <&mmcc CAMSS_VFE1_CLK>, + <&mmcc CAMSS_CSI_VFE1_CLK>, + <&mmcc CAMSS_VFE1_AHB_CLK>, + <&mmcc CAMSS_VFE1_STREAM_CLK>, + <&mmcc CAMSS_VFE_AHB_CLK>, + <&mmcc CAMSS_VFE_AXI_CLK>; + + clock-names = "top_ahb", + "ispif_ahb", + "csiphy0_timer", + "csiphy1_timer", + "csiphy2_timer", + "csi0_ahb", + "csi0", + "csi0_phy", + "csi0_pix", + "csi0_rdi", + "csi1_ahb", + "csi1", + "csi1_phy", + "csi1_pix", + "csi1_rdi", + "csi2_ahb", + "csi2", + "csi2_phy", + "csi2_pix", + "csi2_rdi", + "csi3_ahb", + "csi3", + "csi3_phy", + "csi3_pix", + "csi3_rdi", + "ahb", + "vfe0", + "csi_vfe0", + "vfe0_ahb", + "vfe0_stream", + "vfe1", + "csi_vfe1", + "vfe1_ahb", + "vfe1_stream", + "vfe_ahb", + "vfe_axi"; + + interrupts = , + , + , + , + , + , + , + , + , + ; + + interrupt-names = "csiphy0", + "csiphy1", + "csiphy2", + "csid0", + "csid1", + "csid2", + "csid3", + "ispif", + "vfe0", + "vfe1"; + + iommus = <&vfe_smmu 0>, + <&vfe_smmu 1>, + <&vfe_smmu 2>, + <&vfe_smmu 3>; + + power-domains = <&mmcc VFE0_GDSC>, + <&mmcc VFE1_GDSC>; + + reg = <0x00a34000 0x1000>, + <0x00a00030 0x4>, + <0x00a35000 0x1000>, + <0x00a00038 0x4>, + <0x00a36000 0x1000>, + <0x00a00040 0x4>, + <0x00a30000 0x100>, + <0x00a30400 0x100>, + <0x00a30800 0x100>, + <0x00a30c00 0x100>, + <0x00a31000 0x500>, + <0x00a00020 0x10>, + <0x00a10000 0x1000>, + <0x00a14000 0x1000>; + + reg-names = "csiphy0", + "csiphy0_clk_mux", + "csiphy1", + "csiphy1_clk_mux", + "csiphy2", + "csiphy2_clk_mux", + "csid0", + "csid1", + "csid2", + "csid3", + "ispif", + "csi_clk_mux", + "vfe0", + "vfe1"; + + vdda-supply = <®_2v8>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + }; + }; From patchwork Thu Mar 4 12:03:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 393786 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80924C43381 for ; Thu, 4 Mar 2021 12:08:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5C53064F36 for ; Thu, 4 Mar 2021 12:08:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239959AbhCDMHQ (ORCPT ); Thu, 4 Mar 2021 07:07:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60016 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239941AbhCDMGs (ORCPT ); Thu, 4 Mar 2021 07:06:48 -0500 Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [IPv6:2a00:1450:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B1D8C0613E1 for ; Thu, 4 Mar 2021 04:06:00 -0800 (PST) Received: by mail-ed1-x530.google.com with SMTP id w9so18304690edt.13 for ; Thu, 04 Mar 2021 04:06:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6Kj8P3my55OLbHJAir0E1Y8Sx90z6htWl26sYZ7geGE=; b=O9dNaF7FFhIGabvnzVegF26oD4fCFEeD91zbkrGG8Q/I0V3lVXxYaY3CauV00MMqA5 zc1YO9g6JaTbrkpWyQ/rJ8w023eQIxNZPHnds43Q1WkgphTWslME2LSAf7TkkhLRtLPf Yg4SvgJGnOImvrCtQvnQmcbfCFVQ/of+vEXgjFH57O2kmF2DiwiiWiQBJ9lUYm1c8NPJ b79uYHDwgqV9yuzkn5mBM1nxDj1i1lO0xh7WNLJwzUiAn2ZweUViilEBoet6Ln2HFRYg WhfFL21d9p7XJQVifiVyvoF30AavcwK0x0vDXReNHyBTRybMVksIv0B0ou+E3GdGwk7n V+0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6Kj8P3my55OLbHJAir0E1Y8Sx90z6htWl26sYZ7geGE=; b=dXeYUwtr3zKjwcZMVW3op35o+juLMgLoQ4RyHIE0Y+e/MEYBSe2IN3Gl7ab7C3cyql UL5LMaenMuQbVkVyEisfduupmNIzm0Tx1DboAiZS7cJWq/Ko8j2QUih1ESVZQppgyZbP 0sx3fk9OlTsY6Ge5h+c9KCfvxXcTcHCboqu1sKTvYFF4mi0Bmoh28oFdieYZ9EOhya+j TN56d7jcnmCOMXkBYuxfhdmSpRjL7yJkzjdt6PD/MI43tuKCJI3ufBh2X8Kmib6zmZcV LN7SqOWjTd3SKWCs3bJSBjxFanKhAOjzMaROeGB3LLvNhrbLoHlqLVVfDqs08bL3SiAS hU6Q== X-Gm-Message-State: AOAM530caEFcUX7knuWdsj1mAHX8n9BVOBAH4l3yL7PnzP6f8hcsmzMt OMlZsrTyyg0DtjBiSZi0bjT7WA== X-Google-Smtp-Source: ABdhPJwU0gTkyGpdUs7rUCjfJldCHbpEj17aA0MvqRltzoG6xnViE9Kj9wBGOndQ6gRIGhGrXKUv+A== X-Received: by 2002:a50:fe06:: with SMTP id f6mr3910358edt.349.1614859558849; Thu, 04 Mar 2021 04:05:58 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:58 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 16/22] dt-bindings: media: camss: Add qcom, sdm660-camss binding Date: Thu, 4 Mar 2021 13:03:22 +0100 Message-Id: <20210304120326.153966-17-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add bindings for qcom,sdm660-camss in order to support the camera subsystem on SDM630/660 and SDA variants. Signed-off-by: Robert Foss Reviewed-by: Rob Herring --- Changes since v2 - Rob: Add new line at end of file - Rob: Remove redundant descriptions - Rob: Add power domain description - Rob: Make clock-lanes a constant - Rob: Rework to conform to new port schema - Add max & minItems to data-lanes - Remove ports requirement - endpoint & reg - Added Angelo as binding maintainer - Removed Todor as binding maintainer Changes since v3 - Rob: Added r-b .../bindings/media/qcom,sdm660-camss.yaml | 398 ++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml diff --git a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml new file mode 100644 index 000000000000..841a1aafdd13 --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml @@ -0,0 +1,398 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) + +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/media/qcom,sdm660-camss.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Qualcomm CAMSS ISP + +maintainers: + - Robert Foss + - AngeloGioacchino Del Regno + +description: | + The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms + +properties: + compatible: + const: qcom,sdm660-camss + + clocks: + minItems: 42 + maxItems: 42 + + clock-names: + items: + - const: ahb + - const: cphy_csid0 + - const: cphy_csid1 + - const: cphy_csid2 + - const: cphy_csid3 + - const: csi0_ahb + - const: csi0 + - const: csi0_phy + - const: csi0_pix + - const: csi0_rdi + - const: csi1_ahb + - const: csi1 + - const: csi1_phy + - const: csi1_pix + - const: csi1_rdi + - const: csi2_ahb + - const: csi2 + - const: csi2_phy + - const: csi2_pix + - const: csi2_rdi + - const: csi3_ahb + - const: csi3 + - const: csi3_phy + - const: csi3_pix + - const: csi3_rdi + - const: csiphy0_timer + - const: csiphy1_timer + - const: csiphy2_timer + - const: csiphy_ahb2crif + - const: csi_vfe0 + - const: csi_vfe1 + - const: ispif_ahb + - const: throttle_axi + - const: top_ahb + - const: vfe0_ahb + - const: vfe0 + - const: vfe0_stream + - const: vfe1_ahb + - const: vfe1 + - const: vfe1_stream + - const: vfe_ahb + - const: vfe_axi + + interrupts: + minItems: 10 + maxItems: 10 + + interrupt-names: + items: + - const: csid0 + - const: csid1 + - const: csid2 + - const: csid3 + - const: csiphy0 + - const: csiphy1 + - const: csiphy2 + - const: ispif + - const: vfe0 + - const: vfe1 + + iommus: + maxItems: 4 + + power-domains: + items: + - description: VFE0 GDSC - Video Front End, Global Distributed Switch Controller. + - description: VFE1 GDSC - Video Front End, Global Distributed Switch Controller. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + description: + CSI input ports. + + properties: + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + items: + - const: 7 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + port@1: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + items: + - const: 7 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + port@2: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + items: + - const: 7 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + port@3: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + items: + - const: 7 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + reg: + minItems: 14 + maxItems: 14 + + reg-names: + items: + - const: csi_clk_mux + - const: csid0 + - const: csid1 + - const: csid2 + - const: csid3 + - const: csiphy0 + - const: csiphy0_clk_mux + - const: csiphy1 + - const: csiphy1_clk_mux + - const: csiphy2 + - const: csiphy2_clk_mux + - const: ispif + - const: vfe0 + - const: vfe1 + + vdda-supply: + description: + Definition of the regulator used as analog power supply. + +required: + - clock-names + - clocks + - compatible + - interrupt-names + - interrupts + - iommus + - power-domains + - reg + - reg-names + - vdda-supply + +additionalProperties: false + +examples: + - | + #include + #include + #include + + camss: camss@ca00000 { + compatible = "qcom,sdm660-camss"; + + clocks = <&mmcc CAMSS_AHB_CLK>, + <&mmcc CAMSS_CPHY_CSID0_CLK>, + <&mmcc CAMSS_CPHY_CSID1_CLK>, + <&mmcc CAMSS_CPHY_CSID2_CLK>, + <&mmcc CAMSS_CPHY_CSID3_CLK>, + <&mmcc CAMSS_CSI0_AHB_CLK>, + <&mmcc CAMSS_CSI0_CLK>, + <&mmcc CAMSS_CPHY_CSID0_CLK>, + <&mmcc CAMSS_CSI0PIX_CLK>, + <&mmcc CAMSS_CSI0RDI_CLK>, + <&mmcc CAMSS_CSI1_AHB_CLK>, + <&mmcc CAMSS_CSI1_CLK>, + <&mmcc CAMSS_CPHY_CSID1_CLK>, + <&mmcc CAMSS_CSI1PIX_CLK>, + <&mmcc CAMSS_CSI1RDI_CLK>, + <&mmcc CAMSS_CSI2_AHB_CLK>, + <&mmcc CAMSS_CSI2_CLK>, + <&mmcc CAMSS_CPHY_CSID2_CLK>, + <&mmcc CAMSS_CSI2PIX_CLK>, + <&mmcc CAMSS_CSI2RDI_CLK>, + <&mmcc CAMSS_CSI3_AHB_CLK>, + <&mmcc CAMSS_CSI3_CLK>, + <&mmcc CAMSS_CPHY_CSID3_CLK>, + <&mmcc CAMSS_CSI3PIX_CLK>, + <&mmcc CAMSS_CSI3RDI_CLK>, + <&mmcc CAMSS_CSI0PHYTIMER_CLK>, + <&mmcc CAMSS_CSI1PHYTIMER_CLK>, + <&mmcc CAMSS_CSI2PHYTIMER_CLK>, + <&mmcc CSIPHY_AHB2CRIF_CLK>, + <&mmcc CAMSS_CSI_VFE0_CLK>, + <&mmcc CAMSS_CSI_VFE1_CLK>, + <&mmcc CAMSS_ISPIF_AHB_CLK>, + <&mmcc THROTTLE_CAMSS_AXI_CLK>, + <&mmcc CAMSS_TOP_AHB_CLK>, + <&mmcc CAMSS_VFE0_AHB_CLK>, + <&mmcc CAMSS_VFE0_CLK>, + <&mmcc CAMSS_VFE0_STREAM_CLK>, + <&mmcc CAMSS_VFE1_AHB_CLK>, + <&mmcc CAMSS_VFE1_CLK>, + <&mmcc CAMSS_VFE1_STREAM_CLK>, + <&mmcc CAMSS_VFE_VBIF_AHB_CLK>, + <&mmcc CAMSS_VFE_VBIF_AXI_CLK>; + + clock-names = "ahb", + "cphy_csid0", + "cphy_csid1", + "cphy_csid2", + "cphy_csid3", + "csi0_ahb", + "csi0", + "csi0_phy", + "csi0_pix", + "csi0_rdi", + "csi1_ahb", + "csi1", + "csi1_phy", + "csi1_pix", + "csi1_rdi", + "csi2_ahb", + "csi2", + "csi2_phy", + "csi2_pix", + "csi2_rdi", + "csi3_ahb", + "csi3", + "csi3_phy", + "csi3_pix", + "csi3_rdi", + "csiphy0_timer", + "csiphy1_timer", + "csiphy2_timer", + "csiphy_ahb2crif", + "csi_vfe0", + "csi_vfe1", + "ispif_ahb", + "throttle_axi", + "top_ahb", + "vfe0_ahb", + "vfe0", + "vfe0_stream", + "vfe1_ahb", + "vfe1", + "vfe1_stream", + "vfe_ahb", + "vfe_axi"; + + interrupts = , + , + , + , + , + , + , + , + , + ; + + interrupt-names = "csid0", + "csid1", + "csid2", + "csid3", + "csiphy0", + "csiphy1", + "csiphy2", + "ispif", + "vfe0", + "vfe1"; + + iommus = <&mmss_smmu 0xc00>, + <&mmss_smmu 0xc01>, + <&mmss_smmu 0xc02>, + <&mmss_smmu 0xc03>; + + power-domains = <&mmcc CAMSS_VFE0_GDSC>, + <&mmcc CAMSS_VFE1_GDSC>; + + reg = <0x0ca00020 0x10>, + <0x0ca30000 0x100>, + <0x0ca30400 0x100>, + <0x0ca30800 0x100>, + <0x0ca30c00 0x100>, + <0x0c824000 0x1000>, + <0x0ca00120 0x4>, + <0x0c825000 0x1000>, + <0x0ca00124 0x4>, + <0x0c826000 0x1000>, + <0x0ca00128 0x4>, + <0x0ca31000 0x500>, + <0x0ca10000 0x1000>, + <0x0ca14000 0x1000>; + + reg-names = "csi_clk_mux", + "csid0", + "csid1", + "csid2", + "csid3", + "csiphy0", + "csiphy0_clk_mux", + "csiphy1", + "csiphy1_clk_mux", + "csiphy2", + "csiphy2_clk_mux", + "ispif", + "vfe0", + "vfe1"; + + vdda-supply = <®_2v8>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + }; + }; From patchwork Thu Mar 4 12:03:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392751 Delivered-To: patch@linaro.org Received: by 2002:a17:906:a383:0:0:0:0 with SMTP id k3csp6376013ejz; Thu, 4 Mar 2021 14:28:30 -0800 (PST) X-Google-Smtp-Source: ABdhPJycBa7SCIEbtuXwYHRzIrWOJyzwx/g7N/0xUBSUKC9fSJ+YQsZv8ghEVh+HUr7PZEA3E4pv X-Received: by 2002:aa7:cac6:: with SMTP id l6mr6831934edt.357.1614896833764; Thu, 04 Mar 2021 14:27:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614896833; cv=none; d=google.com; s=arc-20160816; b=x7cDUdkL/LuFtlOpZlQwag/AtT1Z09Sm7/JkvawJuwuKkNdE5mwJMATcOBdlskzDId 7vVAxtjwyigwARch6SlGqzZpkPurg4/jgvNZWOFBVPvx3y2RP9mRLNbx1Q1Iv10bT17r RhQ3ai4p0nPAL75UAyPH/9V+g4XTRRlkwXanNeATi/BDzpKzXPfAos8pNDauBTMGzxx/ 77oX8iO90yPJH+I1Ug/doPER6xnmsLmXCMdAdtcBuG5DDRIafgfJj6xqGcXqprfNdSgu AGSAM/xmEpo8k/vXn8J2PaHL0mEuwexcxwcFHOIoq/LTgITUaiI9ClEGiVPKkUpMlZZ/ AuBA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=JUJ2jq6713iMQIEcRjiRGKmQIbHU3n2p4NuVGkhg6QM=; b=ph1z4qIAHUztfnJrtfiiz9RLjYwNYZI+R/XSrB57c5kXcfMMCC5/iDiWokYIzulDP7 VCYGddddGbsJXptwshgzJr6gJwaEsiMQT9jAj1CAm+y3gvDDijQKKNCDE8A3xDIxD+Ox kvBrCcPbiWJ/Q/N86J7PwyRIuEwp9o6AP+1Qu55RUCzbW0dm4c6y3j7PPCxaW9xGj2je aB8b9bxoj3Qe7ijp/1FB501bibpdMTAIlWYRLoYrxWhtv+IkFdafE/C7LKw3CmdyfrLv Lz82nPAYSnzEoRU4Rj4zKlps9+CIXiFQdCDPdK62x4Z+JryS1fbLFLmlHbVSlQ+SMuMP 4h5g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="s3/M1HIg"; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k6si527757edj.545.2021.03.04.14.27.13; Thu, 04 Mar 2021 14:27:13 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="s3/M1HIg"; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240070AbhCDMHQ (ORCPT + 6 others); Thu, 4 Mar 2021 07:07:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60024 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239939AbhCDMGt (ORCPT ); Thu, 4 Mar 2021 07:06:49 -0500 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A12C5C0613B5 for ; Thu, 4 Mar 2021 04:06:01 -0800 (PST) Received: by mail-ej1-x631.google.com with SMTP id r17so48832696ejy.13 for ; Thu, 04 Mar 2021 04:06:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JUJ2jq6713iMQIEcRjiRGKmQIbHU3n2p4NuVGkhg6QM=; b=s3/M1HIg0Duymqa5mivqw4LK0ZCLd244HW6n4e6uTaZuFyoGNNgAbJg0Vi3bJkZ1sj w8r3nZV3WLWg259Sy32BVZRd+HNzFwAmRX5xzAjYpzymvjPPTY7Vrkcj41oypkZq6eVm xnaJOzJoloQJE+pRtLdS1GrEK0gGw0/ibB5eZiolD2pHdXHzOQpy4Cb0GCUykR09VC1d 0j7cmd3sMk/62bEP4FJ1cRk93TQgcZEkxNoiYJtTe+3gTskWzHwinQNH6buBYt6L13qD owGLbjgbY6PjOMppqCyuTRs419XZCWP/CW6ZXpr/RJId1y7LHEwoMwqeAXT/u3mL67yr X7Vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JUJ2jq6713iMQIEcRjiRGKmQIbHU3n2p4NuVGkhg6QM=; b=ttcwLWvbQ002SlaP2P0ipN9nkGBo4XQBiuvZTHUT9t49hgl8PJwEFhZLNA4EEuCF0C CeerfER4zHi15aEXS6GxJzE+Ec8yo0jUGhu6KmqpzhIxoh4lxTvOrx++ysvNCjQFvAiJ EpUaNJAOpJj5lgGk5M2+AkY0h7cMWFDSvy61AzO+8sNV8ie0YjxRdPsj/EwXpZDplM7W cvR8WuAXY+YHMvHxLGpIulDIfXCOAqmaZPwTgRoL/MNBjHQ/3QpGftUSMIbOxUbDC0KD xKt96NLP7QfrkfrdZE/iGEHpqeRBEhO2FCrQzaRGjQ99nVHzSfrOwPsamcKGBH90uzRa 7GuQ== X-Gm-Message-State: AOAM5330muLREq7P91d2fJZL8QuiHpvCZ74RatTMBBWneSIrdeajCRO/ D6xbXencgtZuCSxnM/0qh85MrQ== X-Received: by 2002:a17:907:75c7:: with SMTP id jl7mr3968733ejc.191.1614859560315; Thu, 04 Mar 2021 04:06:00 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.05.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:05:59 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 17/22] dt-bindings: media: camss: Add qcom, sdm845-camss binding Date: Thu, 4 Mar 2021 13:03:23 +0100 Message-Id: <20210304120326.153966-18-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add bindings for qcom,sdm845-camss in order to support the camera subsystem for SDM845. Signed-off-by: Robert Foss Reviewed-by: Rob Herring --- Changes since v2 - Rob: Removed extra empty lines at end of file - Rob: Add new line at end of file - Rob: Remove redundant descriptions - Rob: Add power domain description - Rob: Make clock-lanes a constant - Rob: Rework to conform to new port schema - Add max & minItems to data-lanes - Remove ports requirement - endpoint & reg - Add proper commit message - Remove Todor as binding maintainer Changes since v3 - Fixed ordering of IRQs Changes since v4 - Rob: Added r-b Changes since v5 - Force CSI clock to use pin 7 .../bindings/media/qcom,sdm845-camss.yaml | 371 ++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml -- 2.27.0 diff --git a/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml new file mode 100644 index 000000000000..9ca5dfa7f226 --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml @@ -0,0 +1,371 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) + +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/media/qcom,sdm845-camss.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Qualcomm CAMSS ISP + +maintainers: + - Robert Foss + +description: | + The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms + +properties: + compatible: + const: qcom,sdm845-camss + + clocks: + minItems: 36 + maxItems: 36 + + clock-names: + items: + - const: camnoc_axi + - const: cpas_ahb + - const: cphy_rx_src + - const: csi0 + - const: csi0_src + - const: csi1 + - const: csi1_src + - const: csi2 + - const: csi2_src + - const: csiphy0 + - const: csiphy0_timer + - const: csiphy0_timer_src + - const: csiphy1 + - const: csiphy1_timer + - const: csiphy1_timer_src + - const: csiphy2 + - const: csiphy2_timer + - const: csiphy2_timer_src + - const: csiphy3 + - const: csiphy3_timer + - const: csiphy3_timer_src + - const: gcc_camera_ahb + - const: gcc_camera_axi + - const: slow_ahb_src + - const: soc_ahb + - const: vfe0_axi + - const: vfe0 + - const: vfe0_cphy_rx + - const: vfe0_src + - const: vfe1_axi + - const: vfe1 + - const: vfe1_cphy_rx + - const: vfe1_src + - const: vfe_lite + - const: vfe_lite_cphy_rx + - const: vfe_lite_src + + interrupts: + minItems: 10 + maxItems: 10 + + interrupt-names: + items: + - const: csid0 + - const: csid1 + - const: csid2 + - const: csiphy0 + - const: csiphy1 + - const: csiphy2 + - const: csiphy3 + - const: vfe0 + - const: vfe1 + - const: vfe_lite + + iommus: + maxItems: 4 + + power-domains: + items: + - description: IFE0 GDSC - Image Front End, Global Distributed Switch Controller. + - description: IFE1 GDSC - Image Front End, Global Distributed Switch Controller. + - description: Titan GDSC - Titan ISP Block, Global Distributed Switch Controller. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + description: + CSI input ports. + + properties: + port@0: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + maxItems: 1 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + port@1: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + items: + - const: 7 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + port@2: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + maxItems: 1 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + port@3: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: + Input port for receiving CSI data. + + properties: + endpoint: + $ref: video-interfaces.yaml# + unevaluatedProperties: false + + properties: + clock-lanes: + maxItems: 1 + + data-lanes: + minItems: 1 + maxItems: 4 + + required: + - clock-lanes + - data-lanes + + reg: + minItems: 10 + maxItems: 10 + + reg-names: + items: + - const: csid0 + - const: csid1 + - const: csid2 + - const: csiphy0 + - const: csiphy1 + - const: csiphy2 + - const: csiphy3 + - const: vfe0 + - const: vfe1 + - const: vfe_lite + + vdda-supply: + description: + Definition of the regulator used as analog power supply. + +required: + - clock-names + - clocks + - compatible + - interrupt-names + - interrupts + - iommus + - power-domains + - reg + - reg-names + - vdda-supply + +additionalProperties: false + +examples: + - | + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + camss: camss@a00000 { + compatible = "qcom,sdm845-camss"; + + clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_0_CSID_CLK>, + <&clock_camcc CAM_CC_IFE_0_CSID_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_1_CSID_CLK>, + <&clock_camcc CAM_CC_IFE_1_CSID_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&clock_camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&clock_camcc CAM_CC_CSIPHY0_CLK>, + <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK>, + <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>, + <&clock_camcc CAM_CC_CSIPHY1_CLK>, + <&clock_camcc CAM_CC_CSI1PHYTIMER_CLK>, + <&clock_camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>, + <&clock_camcc CAM_CC_CSIPHY2_CLK>, + <&clock_camcc CAM_CC_CSI2PHYTIMER_CLK>, + <&clock_camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>, + <&clock_camcc CAM_CC_CSIPHY3_CLK>, + <&clock_camcc CAM_CC_CSI3PHYTIMER_CLK>, + <&clock_camcc CAM_CC_CSI3PHYTIMER_CLK_SRC>, + <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_AXI_CLK>, + <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_IFE_0_AXI_CLK>, + <&clock_camcc CAM_CC_IFE_0_CLK>, + <&clock_camcc CAM_CC_IFE_0_CPHY_RX_CLK>, + <&clock_camcc CAM_CC_IFE_0_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_1_AXI_CLK>, + <&clock_camcc CAM_CC_IFE_1_CLK>, + <&clock_camcc CAM_CC_IFE_1_CPHY_RX_CLK>, + <&clock_camcc CAM_CC_IFE_1_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_LITE_CLK>, + <&clock_camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&clock_camcc CAM_CC_IFE_LITE_CLK_SRC>; + + clock-names = "camnoc_axi", + "cpas_ahb", + "cphy_rx_src", + "csi0", + "csi0_src", + "csi1", + "csi1_src", + "csi2", + "csi2_src", + "csiphy0", + "csiphy0_timer", + "csiphy0_timer_src", + "csiphy1", + "csiphy1_timer", + "csiphy1_timer_src", + "csiphy2", + "csiphy2_timer", + "csiphy2_timer_src", + "csiphy3", + "csiphy3_timer", + "csiphy3_timer_src", + "gcc_camera_ahb", + "gcc_camera_axi", + "slow_ahb_src", + "soc_ahb", + "vfe0_axi", + "vfe0", + "vfe0_cphy_rx", + "vfe0_src", + "vfe1_axi", + "vfe1", + "vfe1_cphy_rx", + "vfe1_src", + "vfe_lite", + "vfe_lite_cphy_rx", + "vfe_lite_src"; + + interrupts = , + , + , + , + , + , + , + , + , + ; + + interrupt-names = "csid0", + "csid1", + "csid2", + "csiphy0", + "csiphy1", + "csiphy2", + "csiphy3", + "vfe0", + "vfe1", + "vfe_lite"; + + iommus = <&apps_smmu 0x0808 0x0>, + <&apps_smmu 0x0810 0x8>, + <&apps_smmu 0x0c08 0x0>, + <&apps_smmu 0x0c10 0x8>; + + power-domains = <&clock_camcc IFE_0_GDSC>, + <&clock_camcc IFE_1_GDSC>, + <&clock_camcc TITAN_TOP_GDSC>; + + reg = <0 0xacb3000 0 0x1000>, + <0 0xacba000 0 0x1000>, + <0 0xacc8000 0 0x1000>, + <0 0xac65000 0 0x1000>, + <0 0xac66000 0 0x1000>, + <0 0xac67000 0 0x1000>, + <0 0xac68000 0 0x1000>, + <0 0xacaf000 0 0x4000>, + <0 0xacb6000 0 0x4000>, + <0 0xacc4000 0 0x4000>; + + reg-names = "csid0", + "csid1", + "csid2", + "csiphy0", + "csiphy1", + "csiphy2", + "csiphy3", + "vfe0", + "vfe1", + "vfe_lite"; + + vdda-supply = <®_2v8>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; From patchwork Thu Mar 4 12:03:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392748 Delivered-To: patch@linaro.org Received: by 2002:a17:906:a383:0:0:0:0 with SMTP id k3csp6375166ejz; Thu, 4 Mar 2021 14:27:17 -0800 (PST) X-Google-Smtp-Source: ABdhPJyOInwA8oPYITW7h1UGWIwXkXXJe78MjRoqg0XCpSYwg2AQJfO4pGyh0DL8urI4qcwNqzc3 X-Received: by 2002:aa7:cd6a:: with SMTP id ca10mr6766781edb.7.1614896837345; Thu, 04 Mar 2021 14:27:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614896837; cv=none; d=google.com; s=arc-20160816; b=vzGw/gFNUp9cffAXUXPoWz/Eez2+PnwEWxYiFMIZ4TEptMOkfhIry7rJNbOpgAuXS2 bq/bWxkKEVlgQu0yPJjQm5g2/w3V/WVOhi/U6t2pyS7NgRARb5SFefdVN/pljgioEuEq zrieiXdt237f9JjwbZKzyIX2t5Js4po3lfCOagVp94dt+6rpSeSFoLKYb2mwzbdPCZqy Hir3emdAsV/cmFsrH6bua2V5Ywg2M3L4sRBt0vRGIeZ+itOFIohhEr4sUBSCoHv8JJn+ n3jsoJ67tJjHOkSLX/0CK2b92qN4Bi8DzYuRlIu//DGOWAW5tSkv3Eo71yC8TYg+2YcU EZoQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=apK0Xqu9SyxgA8SLHWaJUoaQIdInokTf4zpkT7+800M=; b=zl4xSWXX+VR16198xALnJkzTxlUpTqAGSIwHiL1L0AaXqAvNCep4Em93MqE3FUx8U9 ayqTi0LGSB1aibSnmeYYQJOrLH8DkBAJQykaOfa7/8v7YyKKa9aq5ZDWzjQFhSiUPkOo 6oTMpIOSOwEz94sKUBXPDrOUu9MvLjPaIo+IArmBVhqCua7lAz5rdOujnHHq9Osculbd bY3CuzzAKwNyOYX9ntQajVGau5QzSusn9JCxLiQu93P7lURAkUqtzMTgr5MglPeb9uDM LORciBupfjOP0MW5oGD5I7DVZCKhmdCNspj+Nzh42K7Q8dhe8EvyExf2dbZOUgulcFCJ jScA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KbbaeMzR; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k6si527757edj.545.2021.03.04.14.27.17; Thu, 04 Mar 2021 14:27:17 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KbbaeMzR; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239939AbhCDMHS (ORCPT + 6 others); Thu, 4 Mar 2021 07:07:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240027AbhCDMGv (ORCPT ); Thu, 4 Mar 2021 07:06:51 -0500 Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 514F4C0613B8 for ; Thu, 4 Mar 2021 04:06:03 -0800 (PST) Received: by mail-ej1-x62d.google.com with SMTP id p8so22566645ejb.10 for ; Thu, 04 Mar 2021 04:06:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=apK0Xqu9SyxgA8SLHWaJUoaQIdInokTf4zpkT7+800M=; b=KbbaeMzRJTd2uHHgBtwfePVPafBSJddg4SR/KVo2rfsLsOOxwFBudMEk22RkmGduYu tE8ujNTfOgzBW9Dlzacv4hNI7u8xFaz/MKwkK99RsW0B6ACtzjG9BCCXpX4+7pmZV0Bq s8bD9Y6vwDoEoJQAK2g3YWjWkbT05FRL12BYlntcZXM+IbBK5PiY8sRl44dMjJFUlbtM R7oUpQKfhKVYFlMI4hJ0il/OSmNTkA9CoHWun65AaWBL/3h/kF3EzDqeLAZ+lko/GcXq 5THrmxh5r/0QQwqKL/qKaunffuYgd/Gnp3IF+/4b9DZ3X9cUwC6SdlT5SSxrp+uBl+yM fA6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=apK0Xqu9SyxgA8SLHWaJUoaQIdInokTf4zpkT7+800M=; b=tTHNMHOKfJLQJsJMy5FswYmaaAH8I78sho+lGVZNmMPUu3AZN5RIdUqR70CDtou4GP GPFmP0cOODbCOo/9lkDowGZwPTYw+CoHJtD0A7U5esBz7kKLf1ekQXXGiZRrXif5hQfA cREm6ysRnRYZ0NL9xU0PNptAlr8okQ0Y8yBSzZKDQ2WwX68v5sQklmOK6wiNboX/QAvO WRYMyObuDLJB41BgBVKUSh90i7iXTwGhCZRso5QHdNN2zME+FXqWavbx5XJMn10q6VrW Fx77WExqUEMaBYJ30O0DT96DyCFR1TiZAiBCX5NotglPLBQVzIvwfqbmJqee0tnU3DLV ASYg== X-Gm-Message-State: AOAM533DOVGgZaAnxfZ3/GBzVoK3GkXX31i30bS2Sg8v30TzctfkJXRF msgo9LudnyJaDqBkdu2W3qwVIQ== X-Received: by 2002:a17:906:4410:: with SMTP id x16mr3866615ejo.446.1614859562000; Thu, 04 Mar 2021 04:06:02 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.06.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:06:01 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 18/22] MAINTAINERS: Change CAMSS documentation to use dtschema bindings Date: Thu, 4 Mar 2021 13:03:24 +0100 Message-Id: <20210304120326.153966-19-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Due to the complexity of describing multiple hardware generations in one document, switch to using separate dt-bindings. Signed-off-by: Robert Foss Reviewed-by: Rob Herring --- Changes since v4 - Rob: Added r-b MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.27.0 diff --git a/MAINTAINERS b/MAINTAINERS index 0da3255abb91..ed3894b653f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14687,7 +14687,7 @@ M: Todor Tomov L: linux-media@vger.kernel.org S: Maintained F: Documentation/admin-guide/media/qcom_camss.rst -F: Documentation/devicetree/bindings/media/qcom,camss.txt +F: Documentation/devicetree/bindings/media/*camss* F: drivers/media/platform/qcom/camss/ QUALCOMM CORE POWER REDUCTION (CPR) AVS DRIVER From patchwork Thu Mar 4 12:03:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392905 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2168DC4321A for ; Thu, 4 Mar 2021 12:08:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0D29164F37 for ; Thu, 4 Mar 2021 12:08:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240206AbhCDMHS (ORCPT ); Thu, 4 Mar 2021 07:07:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239949AbhCDMG6 (ORCPT ); Thu, 4 Mar 2021 07:06:58 -0500 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CD7E6C0613BB for ; Thu, 4 Mar 2021 04:06:04 -0800 (PST) Received: by mail-ej1-x635.google.com with SMTP id bm21so30059734ejb.4 for ; Thu, 04 Mar 2021 04:06:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LMNUhrCm4GqeH9EhW0fSihgI9Y1YP4V1fxlm0T8uDdM=; b=hoGiU7ulFpI6mcPJZQRN2fTU0C3ii4cihBkoloP9a8IAAoaTnghlBa8Tg5oufmFTuj zUA24PjWQ0CNjXSs2QqlQhZ6cj49hw4PT5WT9yoLB+2W6VlFYoClh5MIXHamQhLmo6QX 2BhiPcNRuSHDLz92661fvBRxHxhBKvce2fwHXwViaMOkPekYiKzfQLhOaZu3xzlBuUHt r8VzqPpSOOVGvep2Rad4Vz3n0P1B2tGkMYuh2J37ysIHar9TirSF1WwR298VS4zkLFcA YCnQlQmhp4VvKbX4qHzHDHNBP6KY6fjl3fVBeUjujPB1S3gOPmhibhZ9OxsV10Ki7BhA GxIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LMNUhrCm4GqeH9EhW0fSihgI9Y1YP4V1fxlm0T8uDdM=; b=a8OqEyJGN8n6vfkWufHBDaouGjP5HnMZm+maI2wTPmv4NRXL0b1rZJg7nUL7r4llVA tWUyT/vPn6chpe2Vi8Z6oXRpfJlLoujoM6rB+nrfa/EtoGS/x+IPFUw9Zw3K8EfU3l4u c8mEbXBFdJn/zsNRSvQfhaxpppk54X5NxQDzrgWcUY+kGugD31iDPt2vcvWtrsE9Xury vV9TiRk1EkWJCBCJguSHXLQ5Ev4E5a4F3Gc/ImIUAKFB3HmznbPulOVjO/pR3dy24V/K AQFn9FTUxs/iAspYwGcct5xM7ZH+OqeYVB2dCxZUW2qijwRdydL83pmbu4Y1WSE3Y6hi YoLg== X-Gm-Message-State: AOAM533wnPY0E+7EDUoyzEe/4OOUaP68kgyDtz8HsM86gtTtg+p7LKSH ngbhN54RAUksStEOSZ4YdVd7Ig== X-Google-Smtp-Source: ABdhPJxxLpSOJpScqyhlWYuO5mt4mGr9QaYZjapj2yXUdMRv1DPSqzY4OF68rFSZU2zk2uKT/18qTg== X-Received: by 2002:a17:906:3c50:: with SMTP id i16mr3899569ejg.175.1614859563555; Thu, 04 Mar 2021 04:06:03 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.06.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:06:03 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 19/22] media: dt-bindings: media: Remove qcom, camss documentation Date: Thu, 4 Mar 2021 13:03:25 +0100 Message-Id: <20210304120326.153966-20-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This documentation has been incorporated in dtschema dt-bindings for the devices supported by CAMSS and is no longer helpful. Signed-off-by: Robert Foss Reviewed-by: Rob Herring --- Changes since v4 - Rob: Added r-b .../devicetree/bindings/media/qcom,camss.txt | 236 ------------------ 1 file changed, 236 deletions(-) delete mode 100644 Documentation/devicetree/bindings/media/qcom,camss.txt diff --git a/Documentation/devicetree/bindings/media/qcom,camss.txt b/Documentation/devicetree/bindings/media/qcom,camss.txt deleted file mode 100644 index 498234629e21..000000000000 --- a/Documentation/devicetree/bindings/media/qcom,camss.txt +++ /dev/null @@ -1,236 +0,0 @@ -Qualcomm Camera Subsystem - -* Properties - -- compatible: - Usage: required - Value type: - Definition: Should contain one of: - - "qcom,msm8916-camss" - - "qcom,msm8996-camss" - - "qcom,sdm660-camss" -- reg: - Usage: required - Value type: - Definition: Register ranges as listed in the reg-names property. -- reg-names: - Usage: required - Value type: - Definition: Should contain the following entries: - - "csiphy0" - - "csiphy0_clk_mux" - - "csiphy1" - - "csiphy1_clk_mux" - - "csiphy2" (8996 only) - - "csiphy2_clk_mux" (8996 only) - - "csid0" - - "csid1" - - "csid2" (8996 only) - - "csid3" (8996 only) - - "ispif" - - "csi_clk_mux" - - "vfe0" - - "vfe1" (8996 only) -- interrupts: - Usage: required - Value type: - Definition: Interrupts as listed in the interrupt-names property. -- interrupt-names: - Usage: required - Value type: - Definition: Should contain the following entries: - - "csiphy0" - - "csiphy1" - - "csiphy2" (8996 only) - - "csid0" - - "csid1" - - "csid2" (8996 only) - - "csid3" (8996 only) - - "ispif" - - "vfe0" - - "vfe1" (8996 only) -- power-domains: - Usage: required - Value type: - Definition: A phandle and power domain specifier pairs to the - power domain which is responsible for collapsing - and restoring power to the peripheral. -- clocks: - Usage: required - Value type: - Definition: A list of phandle and clock specifier pairs as listed - in clock-names property. -- clock-names: - Usage: required - Value type: - Definition: Should contain the following entries: - - "top_ahb" - - "throttle_axi" (660 only) - - "ispif_ahb" - - "csiphy0_timer" - - "csiphy1_timer" - - "csiphy2_timer" (8996 only) - - "csiphy_ahb2crif" (660 only) - - "csi0_ahb" - - "csi0" - - "csi0_phy" - - "csi0_pix" - - "csi0_rdi" - - "cphy_csid0" (660 only) - - "csi1_ahb" - - "csi1" - - "csi1_phy" - - "csi1_pix" - - "csi1_rdi" - - "cphy_csid1" (660 only) - - "csi2_ahb" (8996 only) - - "csi2" (8996 only) - - "csi2_phy" (8996 only) - - "csi2_pix" (8996 only) - - "csi2_rdi" (8996 only) - - "cphy_csid2" (660 only) - - "csi3_ahb" (8996 only) - - "csi3" (8996 only) - - "csi3_phy" (8996 only) - - "csi3_pix" (8996 only) - - "csi3_rdi" (8996 only) - - "cphy_csid3" (660 only) - - "ahb" - - "vfe0" - - "csi_vfe0" - - "vfe0_ahb", (8996 only) - - "vfe0_stream", (8996 only) - - "vfe1", (8996 only) - - "csi_vfe1", (8996 only) - - "vfe1_ahb", (8996 only) - - "vfe1_stream", (8996 only) - - "vfe_ahb" - - "vfe_axi" -- vdda-supply: - Usage: required - Value type: - Definition: A phandle to voltage supply for CSI2. -- iommus: - Usage: required - Value type: - Definition: A list of phandle and IOMMU specifier pairs. - -* Nodes - -- ports: - Usage: required - Definition: As described in video-interfaces.txt in same directory. - Properties: - - reg: - Usage: required - Value type: - Definition: Selects CSI2 PHY interface - PHY0, PHY1 - or PHY2 (8996 only) - Endpoint node properties: - - clock-lanes: - Usage: required - Value type: - Definition: The physical clock lane index. On 8916 - the value must always be <1> as the physical - clock lane is lane 1. On 8996 the value must - always be <7> as the hardware supports D-PHY - and C-PHY, indexes are in a common set and - D-PHY physical clock lane is labeled as 7. - - data-lanes: - Usage: required - Value type: - Definition: An array of physical data lanes indexes. - Position of an entry determines the logical - lane number, while the value of an entry - indicates physical lane index. Lane swapping - is supported. Physical lane indexes for - 8916: 0, 2, 3, 4; for 8996: 0, 1, 2, 3. - -* An Example - - camss: camss@1b00000 { - compatible = "qcom,msm8916-camss"; - reg = <0x1b0ac00 0x200>, - <0x1b00030 0x4>, - <0x1b0b000 0x200>, - <0x1b00038 0x4>, - <0x1b08000 0x100>, - <0x1b08400 0x100>, - <0x1b0a000 0x500>, - <0x1b00020 0x10>, - <0x1b10000 0x1000>; - reg-names = "csiphy0", - "csiphy0_clk_mux", - "csiphy1", - "csiphy1_clk_mux", - "csid0", - "csid1", - "ispif", - "csi_clk_mux", - "vfe0"; - interrupts = , - , - , - , - , - ; - interrupt-names = "csiphy0", - "csiphy1", - "csid0", - "csid1", - "ispif", - "vfe0"; - power-domains = <&gcc VFE_GDSC>; - clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>, - <&gcc GCC_CAMSS_ISPIF_AHB_CLK>, - <&gcc GCC_CAMSS_CSI0PHYTIMER_CLK>, - <&gcc GCC_CAMSS_CSI1PHYTIMER_CLK>, - <&gcc GCC_CAMSS_CSI0_AHB_CLK>, - <&gcc GCC_CAMSS_CSI0_CLK>, - <&gcc GCC_CAMSS_CSI0PHY_CLK>, - <&gcc GCC_CAMSS_CSI0PIX_CLK>, - <&gcc GCC_CAMSS_CSI0RDI_CLK>, - <&gcc GCC_CAMSS_CSI1_AHB_CLK>, - <&gcc GCC_CAMSS_CSI1_CLK>, - <&gcc GCC_CAMSS_CSI1PHY_CLK>, - <&gcc GCC_CAMSS_CSI1PIX_CLK>, - <&gcc GCC_CAMSS_CSI1RDI_CLK>, - <&gcc GCC_CAMSS_AHB_CLK>, - <&gcc GCC_CAMSS_VFE0_CLK>, - <&gcc GCC_CAMSS_CSI_VFE0_CLK>, - <&gcc GCC_CAMSS_VFE_AHB_CLK>, - <&gcc GCC_CAMSS_VFE_AXI_CLK>; - clock-names = "top_ahb", - "ispif_ahb", - "csiphy0_timer", - "csiphy1_timer", - "csi0_ahb", - "csi0", - "csi0_phy", - "csi0_pix", - "csi0_rdi", - "csi1_ahb", - "csi1", - "csi1_phy", - "csi1_pix", - "csi1_rdi", - "ahb", - "vfe0", - "csi_vfe0", - "vfe_ahb", - "vfe_axi"; - vdda-supply = <&pm8916_l2>; - iommus = <&apps_iommu 3>; - ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; - csiphy0_ep: endpoint { - clock-lanes = <1>; - data-lanes = <0 2>; - remote-endpoint = <&ov5645_ep>; - }; - }; - }; - }; From patchwork Thu Mar 4 12:03:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392755 Delivered-To: patch@linaro.org Received: by 2002:a17:906:a383:0:0:0:0 with SMTP id k3csp6376258ejz; Thu, 4 Mar 2021 14:28:51 -0800 (PST) X-Google-Smtp-Source: ABdhPJwUJMY/w0BDRQrjNcRQ5yngwSJld/PpGgLlBolV/6zdY59cTWrj2sygckt72r1MckzMPjkD X-Received: by 2002:a50:ee10:: with SMTP id g16mr6634066eds.215.1614896839013; Thu, 04 Mar 2021 14:27:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614896839; cv=none; d=google.com; s=arc-20160816; b=b/oOveP0CGLspWkpv+U857uOMD7+wNnewJCypu/z8HI8EwXn/wyT52hfJ5n0zBOmmE +O4rTG59/i9fLLgVMfmzNMsisTb4OdJymJKXFCHSu9aSp16fYK1tSRHDj4qYup3Yij+W otz8ei9YTL+KUDbBc42eM8n7jC0eRL9woNoNXzsejgem8R/57bfDaAXP3f+UeDDsCsae EGeqAgr+LGTPGkmK0tIkWN/aImViGkIlqRWwZczlOfnHQcIV+dbSKewdWoCivsD9kKda 6ho/1jpic2ID6KjlxOScF/Gc+HXqRv3lV0KVmL0CA4lOJXClt2kBBFcDaGKsr+QcVEww 63KA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=7gB7AoMOiyCQb9quZTWnXT3iMQcjF/gibktg5jIRWV4=; b=yaQrDwzJJDcOUZMjT2mWrET7kQGa8mHmRhVghC63nOVoZUCXV3tkOW2jxciqbOc0iu c4WzqO7mLGgvpxtvHk6otrnjsNAetp6qSAEyqCb+/1EIe3rWODmSNOCpvSxv9emGRN5S 8Fk5TlR20ewJ4HuPGrnPTHciWPCegxqFOe/OzK/9U5t9CoZlkuP4UXCNWmB9st3V0i2O WHPiNrmDlTFbiTJoDwC7qkrYfG69kUVNeSkGWAN8/Ixr/eqy0AhJ6ZZPBF4I3Sn1Q2ic OitfXlhor70LNaWxiIXL1hIC2sJQ0LTiNhb/Pp46r++WEQWjT7eyWsEjkjfJFfoeCmSA CyFw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=v64pJ8M3; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k6si527757edj.545.2021.03.04.14.27.18; Thu, 04 Mar 2021 14:27:19 -0800 (PST) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=v64pJ8M3; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240032AbhCDMHT (ORCPT + 6 others); Thu, 4 Mar 2021 07:07:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60012 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240104AbhCDMHD (ORCPT ); Thu, 4 Mar 2021 07:07:03 -0500 Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [IPv6:2a00:1450:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 63BFBC0613BF for ; Thu, 4 Mar 2021 04:06:06 -0800 (PST) Received: by mail-ej1-x629.google.com with SMTP id ci14so29844412ejc.7 for ; Thu, 04 Mar 2021 04:06:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7gB7AoMOiyCQb9quZTWnXT3iMQcjF/gibktg5jIRWV4=; b=v64pJ8M3YDB+r6KM9ZQl+aVsu7WYQ0ZHFmse3A61Q19/oNYREkI0lffRf9+6ppv+pP 42fSWI1g+APc4Q2u9BQ27HvGDqDaVfD17gm004rNDtIXYhG6KTKnCm5X8kL+rxtSb1Sy uSOrxkD+gS69IbSdDKOKOheheIibus07gUx8VzJpOSlZ3jHQc6owYc7nSstnO8xpQ8Of F6F5x2ON+1bT5+8cdiTi//iitVHz+/huZjMU1zC4lYRGZezzE2m7DykNJxk3K1rxFnWq BNm/dD3tWw1xYoRseQjdcxK0OTrGPWLUcttQcjbJ6JmplGOl1r67Fr3bOc/O/yXLmckH TfZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7gB7AoMOiyCQb9quZTWnXT3iMQcjF/gibktg5jIRWV4=; b=GYbckWPFDG+2ZVUON1YsCn7bfTq16Xo9bfT6ctKokcj7VYq5I0x9dYMuA9YR2xaAZq B593RWdI/RTn0kYCqX4RfaK7DKDnG0j4Zij2q6KRN6PSCohFG2LpRvXfkeUyQbph+yOm 8n0VHbi724Pr9nwsJn1QOXTDKXAugVEEuCaXEpaxx1ytmMcznfkPgBYZw/K83gTtNiSL wpYfi4D5qeYOdyTU+dvQQ9GpBWILa0hFYGPv0D5BCEjS3jGsTvdJhtHGk44OsyRxzFdN VLs5n3OfK0EYigcHvLrpqB8zBEwdMp5kShXyiM85Gi/w68sCaemPUyodIw6clXYq1M1h EcuA== X-Gm-Message-State: AOAM531NV+VR0rRTzuPV2YanTbUNtuAGim7SHX+xX/aHkbDKzqHprcVo sJMvvlsL8oqBmj8PjynjTihTiA== X-Received: by 2002:a17:907:6005:: with SMTP id fs5mr3888299ejc.184.1614859565135; Thu, 04 Mar 2021 04:06:05 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.06.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:06:04 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 20/22] arm64: dts: sdm845: Add CAMSS ISP node Date: Thu, 4 Mar 2021 13:03:26 +0100 Message-Id: <20210304120326.153966-21-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add the camss dt node for sdm845. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v1 - Laurent: Fix subject - Laurent: Remove redundant regulator labels - Laurent: Remove empty line Changes since v3 - Fixed ordering of IRQs - Add newlines for better readability Changes since v5: - Andrey: Add r-b arch/arm64/boot/dts/qcom/sdm845.dtsi | 135 +++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) -- 2.27.0 diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index bcf888381f14..4fe93c69908a 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -3911,6 +3911,141 @@ videocc: clock-controller@ab00000 { #reset-cells = <1>; }; + camss: camss@a00000 { + compatible = "qcom,sdm845-camss"; + + reg = <0 0xacb3000 0 0x1000>, + <0 0xacba000 0 0x1000>, + <0 0xacc8000 0 0x1000>, + <0 0xac65000 0 0x1000>, + <0 0xac66000 0 0x1000>, + <0 0xac67000 0 0x1000>, + <0 0xac68000 0 0x1000>, + <0 0xacaf000 0 0x4000>, + <0 0xacb6000 0 0x4000>, + <0 0xacc4000 0 0x4000>; + reg-names = "csid0", + "csid1", + "csid2", + "csiphy0", + "csiphy1", + "csiphy2", + "csiphy3", + "vfe0", + "vfe1", + "vfe_lite"; + + interrupts = , + , + , + , + , + , + , + , + , + ; + interrupt-names = "csid0", + "csid1", + "csid2", + "csiphy0", + "csiphy1", + "csiphy2", + "csiphy3", + "vfe0", + "vfe1", + "vfe_lite"; + + power-domains = <&clock_camcc IFE_0_GDSC>, + <&clock_camcc IFE_1_GDSC>, + <&clock_camcc TITAN_TOP_GDSC>; + + clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>, + <&clock_camcc CAM_CC_CPAS_AHB_CLK>, + <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_0_CSID_CLK>, + <&clock_camcc CAM_CC_IFE_0_CSID_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_1_CSID_CLK>, + <&clock_camcc CAM_CC_IFE_1_CSID_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_LITE_CSID_CLK>, + <&clock_camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>, + <&clock_camcc CAM_CC_CSIPHY0_CLK>, + <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK>, + <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>, + <&clock_camcc CAM_CC_CSIPHY1_CLK>, + <&clock_camcc CAM_CC_CSI1PHYTIMER_CLK>, + <&clock_camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>, + <&clock_camcc CAM_CC_CSIPHY2_CLK>, + <&clock_camcc CAM_CC_CSI2PHYTIMER_CLK>, + <&clock_camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>, + <&clock_camcc CAM_CC_CSIPHY3_CLK>, + <&clock_camcc CAM_CC_CSI3PHYTIMER_CLK>, + <&clock_camcc CAM_CC_CSI3PHYTIMER_CLK_SRC>, + <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_AXI_CLK>, + <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>, + <&clock_camcc CAM_CC_SOC_AHB_CLK>, + <&clock_camcc CAM_CC_IFE_0_AXI_CLK>, + <&clock_camcc CAM_CC_IFE_0_CLK>, + <&clock_camcc CAM_CC_IFE_0_CPHY_RX_CLK>, + <&clock_camcc CAM_CC_IFE_0_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_1_AXI_CLK>, + <&clock_camcc CAM_CC_IFE_1_CLK>, + <&clock_camcc CAM_CC_IFE_1_CPHY_RX_CLK>, + <&clock_camcc CAM_CC_IFE_1_CLK_SRC>, + <&clock_camcc CAM_CC_IFE_LITE_CLK>, + <&clock_camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>, + <&clock_camcc CAM_CC_IFE_LITE_CLK_SRC>; + clock-names = "camnoc_axi", + "cpas_ahb", + "cphy_rx_src", + "csi0", + "csi0_src", + "csi1", + "csi1_src", + "csi2", + "csi2_src", + "csiphy0", + "csiphy0_timer", + "csiphy0_timer_src", + "csiphy1", + "csiphy1_timer", + "csiphy1_timer_src", + "csiphy2", + "csiphy2_timer", + "csiphy2_timer_src", + "csiphy3", + "csiphy3_timer", + "csiphy3_timer_src", + "gcc_camera_ahb", + "gcc_camera_axi", + "slow_ahb_src", + "soc_ahb", + "vfe0_axi", + "vfe0", + "vfe0_cphy_rx", + "vfe0_src", + "vfe1_axi", + "vfe1", + "vfe1_cphy_rx", + "vfe1_src", + "vfe_lite", + "vfe_lite_cphy_rx", + "vfe_lite_src"; + + iommus = <&apps_smmu 0x0808 0x0>, + <&apps_smmu 0x0810 0x8>, + <&apps_smmu 0x0c08 0x0>, + <&apps_smmu 0x0c10 0x8>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + }; + }; + cci: cci@ac4a000 { compatible = "qcom,sdm845-cci"; #address-cells = <1>; From patchwork Thu Mar 4 12:03:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 392904 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D0EB7C15504 for ; Thu, 4 Mar 2021 12:08:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B8A7C64F0B for ; Thu, 4 Mar 2021 12:08:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240099AbhCDMHV (ORCPT ); Thu, 4 Mar 2021 07:07:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59954 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240108AbhCDMHH (ORCPT ); Thu, 4 Mar 2021 07:07:07 -0500 Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BEB65C061222 for ; Thu, 4 Mar 2021 04:06:07 -0800 (PST) Received: by mail-ej1-x62d.google.com with SMTP id r17so48833567ejy.13 for ; Thu, 04 Mar 2021 04:06:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=45F+RVQGNOeOIqHAD42S1RQW90kRIpbUumPYEAuK2qw=; b=YbaOEWimUScRLtMtmVudJlYtARyqJDuzL0rzBNhn7Exjbmm5rh0ATdHRSXPgI1AO+o d0sPkSaxndAbEJsGrLZ4OmA0yxXh7haRztLEmNv0g9YNdkOvz/6+9MJnJjrdwRVftrIC UeQg2pApUq668NeWCEv6TvUHS6rD1EOVAJD8QI5AssEA10/1c5vuTEzIq9LrTnOsoMR1 YPvZ4NU+laCR30aVOBSwQtV/5a4m6SdazuY9T5fvfpPhDZGxQZXdMfBinraqph5POU4M 5443qpvAy5/AxcvACAvMNCOTafjxi6lD5uFoTIc1qr2dPjhhaLxHzYDQxfADyvMEyhzY oyhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=45F+RVQGNOeOIqHAD42S1RQW90kRIpbUumPYEAuK2qw=; b=A3hgaFzhmhnbja3XGDPJIgtf8I/uqqz9zSGwYZLrVOkrQ5S0duSzzNbfIJJwYXMWcx FBOirGMauRShDZ2KBpMH7HeYYulLZBtd/3gqIg3PZEEpj9OrKWcBcgunCwNZAnM+bhUe RW8v6ZL/Xxi1SPdWpt68WwOqY9u7kytyhnTlQ2oxVY9YEIgxR3RUgkRX4ASxRR/fBJWZ w7ZcqVFSmD0WckTSzsxD7SFQ+BXVxLVK8D0ARriJH3kSWwGwQeXiSuHod8wmXn5lR4k3 l7Zpg8YMcZUTwB88MAprcXlsUh/GYEScp6KYmZatlRolfdsTuX3TgQf2t5zTxKUnjzDA I+vw== X-Gm-Message-State: AOAM530oYO5NTOuiG6EeZtUo5ymZF2J3129WxcM/81yRe51+U3F3awz2 mQKfsd7bX7O9osFMfH+nLHR06A== X-Google-Smtp-Source: ABdhPJzW3QIh+CAEbIAYrDqqYMaGNPCc7KvAEOxiPd+BpOa8ivSgimxSb4CWVwosCOvnKUejs28biQ== X-Received: by 2002:a17:906:13c4:: with SMTP id g4mr3920304ejc.390.1614859566562; Thu, 04 Mar 2021 04:06:06 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.06.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:06:06 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 21/22] arm64: dts: sdm845-db845c: Configure regulators for camss node Date: Thu, 4 Mar 2021 13:03:27 +0100 Message-Id: <20210304120326.153966-22-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add regulator to camss device tree node. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v5 - Andrey: Add r-b arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index a943b3f353ce..5842ab65789c 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -1106,6 +1106,10 @@ &cci { status = "okay"; }; +&camss { + vdda-supply = <&vreg_l1a_0p875>; +}; + &cci_i2c0 { camera@10 { compatible = "ovti,ov8856"; From patchwork Thu Mar 4 12:03:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Foss X-Patchwork-Id: 393784 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60821C43142 for ; Thu, 4 Mar 2021 12:08:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4B4D464F36 for ; Thu, 4 Mar 2021 12:08:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239915AbhCDMHV (ORCPT ); Thu, 4 Mar 2021 07:07:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60024 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240112AbhCDMHH (ORCPT ); Thu, 4 Mar 2021 07:07:07 -0500 Received: from mail-ej1-x632.google.com (mail-ej1-x632.google.com [IPv6:2a00:1450:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C192C0611A2 for ; Thu, 4 Mar 2021 04:06:09 -0800 (PST) Received: by mail-ej1-x632.google.com with SMTP id mm21so48560542ejb.12 for ; Thu, 04 Mar 2021 04:06:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=L6kqHVgRXcGTejXZV+UwM9uyGX3tx7DzRfC3/Q/v2WM=; b=A8YAAwJbPf/mDfZEPle56kQyjHalh7PJYSM0ijYG4qQwZk5lPRSAhvvIx8CWCahSIr gjPmVtDOkfy7eOaiDJfdJLdI2yhdyKVVTKAbNZLT9Mg4EyD9G6S2fXRT9zxqfwp9jpYT 2IXKAiwfWaucGDGv1F4q5l++eipR134GvwLn1s2Rfh0TYSFsqI0pUTDd3LSBozATZHwS XfH7ThGKIG5bAQ20eFxqutHCbtBOXiCaNYezOBt/y++QHLXO440cGmL5AAajQ2xN5c+S dN3UiLcXw1P4sMUEqyp7Ml1leVxPUx/YFhLYp0c8xT2cJ1gUAt6xdOlzfRLXltLeMxJg NZJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=L6kqHVgRXcGTejXZV+UwM9uyGX3tx7DzRfC3/Q/v2WM=; b=be/wnyIlOPXtpljfSoX1jwDlXg2yD8QmfXDJyoXHCiROdr+iDZ1CrS9ykx2tAnsJC+ 38bvylujHxeWbvz/EviB6WWu8oJWpUN0JWIpLMmpgMkE+jIo62qBbTOMUjzva78Q91La b0qIXv1CQ86ulpmQZUvH2VY3Pq/CKhnqbTHVqOAQ/L72Srio3MnfxJ/1GP4xkwNtUh/B 2FJVZ4RvZy0+cskKVDiMLbnLv1DoiF/leNgTwLS6RLn63tmoXwsOAyNrHr/MX+9ps/bS 3bVMd8x1fgzEfp5PtqpSooQaijBh2dRj5hbrXZVB1ZHMZqJCHJL76Zb9tbiAczwrp45S tXPw== X-Gm-Message-State: AOAM532ZNfhc6MaS98fgoa8l1Nwymg/zWd/z8SAx2UM4ANEUAsVontHJ lrKH2zTVx5EWqPk+yqC5g/uRwA== X-Google-Smtp-Source: ABdhPJxZkDF6mr/G1/aQr7MK5ipPu4ir8YUy583pJz1UQL5iuV/1jAqlQga3cHnYIh9ezZKtKH6fwA== X-Received: by 2002:a17:906:f9db:: with SMTP id lj27mr3881177ejb.399.1614859568051; Thu, 04 Mar 2021 04:06:08 -0800 (PST) Received: from localhost.localdomain ([2a02:2450:102f:d6a:470a:340b:1b:29dd]) by smtp.gmail.com with ESMTPSA id cf6sm20464447edb.92.2021.03.04.04.06.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 04:06:07 -0800 (PST) From: Robert Foss To: agross@kernel.org, bjorn.andersson@linaro.org, robert.foss@linaro.org, todor.too@gmail.com, mchehab@kernel.org, robh+dt@kernel.org, angelogioacchino.delregno@somainline.org, linux-arm-msm@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, AngeloGioacchino Del Regno , Sakari Ailus , Andrey Konovalov Cc: Rob Herring , Tomasz Figa , Azam Sadiq Pasha Kapatrala Syed , Sarvesh Sridutt , Laurent Pinchart , Jonathan Marek Subject: [PATCH v6 22/22] arm64: dts: sdm845-db845c: Enable ov8856 sensor and connect to ISP Date: Thu, 4 Mar 2021 13:03:28 +0100 Message-Id: <20210304120326.153966-23-robert.foss@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210304120326.153966-1-robert.foss@linaro.org> References: <20210304120326.153966-1-robert.foss@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Enable camss & ov8856 DT nodes. Signed-off-by: Robert Foss Reviewed-by: Andrey Konovalov --- Changes since v5 - Andrey: Add r-b - Change CSI clock & data pins arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index 5842ab65789c..ca00be42fe67 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -1108,6 +1108,21 @@ &cci { &camss { vdda-supply = <&vreg_l1a_0p875>; + + status = "ok"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + csiphy0_ep: endpoint { + clock-lanes = <7>; + data-lanes = <0 1 2 3>; + remote-endpoint = <&ov8856_ep>; + }; + }; + }; }; &cci_i2c0 { @@ -1139,7 +1154,7 @@ camera@10 { avdd-supply = <&cam0_avdd_2v8>; dvdd-supply = <&cam0_dvdd_1v2>; - status = "disable"; + status = "ok"; port { ov8856_ep: endpoint { @@ -1147,7 +1162,7 @@ ov8856_ep: endpoint { link-frequencies = /bits/ 64 <360000000 180000000>; data-lanes = <1 2 3 4>; -// remote-endpoint = <&csiphy0_ep>; + remote-endpoint = <&csiphy0_ep>; }; }; };