From patchwork Mon Apr 24 18:59:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 13222500 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01359C77B78 for ; Mon, 24 Apr 2023 19:00:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232251AbjDXTAB (ORCPT ); Mon, 24 Apr 2023 15:00:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54804 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231681AbjDXTAA (ORCPT ); Mon, 24 Apr 2023 15:00:00 -0400 Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 085B35B81 for ; Mon, 24 Apr 2023 11:59:58 -0700 (PDT) Received: by mail-ed1-x52a.google.com with SMTP id 4fb4d7f45d1cf-506c04dd879so8324400a12.3 for ; Mon, 24 Apr 2023 11:59:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ragnatech-se.20221208.gappssmtp.com; s=20221208; t=1682362796; x=1684954796; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=S3HMfUX0hKXutl63WtepWnzJmhRd3jEgXA+lFtA0IvU=; b=gp29EeTnq5CaZDUwi9OLi8eI0JUOTlUZLKDFDogBlVTHyj5RwqoY338RcHbreOIVEJ xd2NOpnOs393RWr/Vvo5o+Kvri1yriujUkAL98x5V9RDjeXEbJseOuTX7Tjz+YU/WfTO 2AQ347VvAekRqXt9CB2c3i6D9eZbn0Lu1SGelWW9X5GZkSlpSKuwOdzPv0M3U2kEeMMW RX32roVfaQgHtoQkrdeuc1ySINpxdAxPR8WXmmWB6PDMtSt4RTCgVZA0YOP0hrXfVzXR 9IN0qA1lN+jawdaKKR09a3hAUP5wTmrJwNK2UlAtQiCeNA4ohup5egQL8v/sgqUIui7h X2ug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682362796; x=1684954796; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=S3HMfUX0hKXutl63WtepWnzJmhRd3jEgXA+lFtA0IvU=; b=jkmlXzmY/wFF99prVdY+KJ/6m2j/4orORJ6wdQBekMk9T9e1+owPq1DSKPUjmV01Ug 99BLmtopxzPvZlAfgtZrQe+yoU9AkKJkhVYm2Oy+YcqTbmPJlr5zy5kMg3CBtMT0gBji FDQOCr0b5DKHYW3uJD9sh6eNqmD5S2Ol9maWE9jtGH/Gw6IJ3j5y8gF79j0QkC1+c0nJ 7Wb7/4maHCSDDDtfCu41bFutMz6DvNbczNN0/XVnbifFfuSHFClkp8CbPW+79mDLuXcg z76PaAXirt6eAcz24e4wGl9FScu+EETK0NBdlyuzFeyNkcMME/5HMEbjHjH8K9ceyeBS FRAw== X-Gm-Message-State: AAQBX9fM3pmmetTago9/R1qU1jze2w5N3IPlAv0fKJrv7w8nEhxFOwU7 YkfIGJID5CkFZ25cs+pzruLV7g== X-Google-Smtp-Source: AKy350YfkJ4UQM4b06vOXsE7iG32E4owcaqbAWAal5HJzx9Pclg2L7cx2yLWViuQxgS2ffMaL3jFJQ== X-Received: by 2002:a17:907:674a:b0:953:64f4:e42e with SMTP id qm10-20020a170907674a00b0095364f4e42emr10618935ejc.5.1682362796432; Mon, 24 Apr 2023 11:59:56 -0700 (PDT) Received: from sleipner.berto.se (p54ac52fc.dip0.t-ipconnect.de. [84.172.82.252]) by smtp.googlemail.com with ESMTPSA id ke15-20020a17090798ef00b0095328ce9c8bsm5849818ejc.67.2023.04.24.11.59.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Apr 2023 11:59:55 -0700 (PDT) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: Hans Verkuil , linux-media@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, =?utf-8?q?Niklas_S=C3=B6derlund?= Subject: [PATCH v2 1/3] media: rcar-csi2: Prepare for Gen4 support Date: Mon, 24 Apr 2023 20:59:32 +0200 Message-Id: <20230424185934.438059-2-niklas.soderlund+renesas@ragnatech.se> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230424185934.438059-1-niklas.soderlund+renesas@ragnatech.se> References: <20230424185934.438059-1-niklas.soderlund+renesas@ragnatech.se> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Prepare the driver for supporting R-Car Gen4. The starting of the receiver and how to enter standby differs between Gen3 and Gen4, create function pointers in the device info structure to control the different behavior. Signed-off-by: Niklas Söderlund --- * Changes since v1 - Rebased to latest media-tree. --- .../platform/renesas/rcar-vin/rcar-csi2.c | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c index 5dbd0daa8735..05ea1723f04b 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c @@ -483,6 +483,8 @@ enum rcar_csi2_pads { struct rcar_csi2_info { int (*init_phtw)(struct rcar_csi2 *priv, unsigned int mbps); int (*phy_post_init)(struct rcar_csi2 *priv); + int (*start_receiver)(struct rcar_csi2 *priv); + void (*enter_standby)(struct rcar_csi2 *priv); const struct rcsi2_mbps_reg *hsfreqrange; unsigned int csi0clkfreqrange; unsigned int num_channels; @@ -533,10 +535,17 @@ static void rcsi2_write(struct rcar_csi2 *priv, unsigned int reg, u32 data) iowrite32(data, priv->base + reg); } -static void rcsi2_enter_standby(struct rcar_csi2 *priv) +static void rcsi2_enter_standby_gen3(struct rcar_csi2 *priv) { rcsi2_write(priv, PHYCNT_REG, 0); rcsi2_write(priv, PHTC_REG, PHTC_TESTCLR); +} + +static void rcsi2_enter_standby(struct rcar_csi2 *priv) +{ + if (priv->info->enter_standby) + priv->info->enter_standby(priv); + reset_control_assert(priv->rstc); usleep_range(100, 150); pm_runtime_put(priv->dev); @@ -674,7 +683,7 @@ static int rcsi2_get_active_lanes(struct rcar_csi2 *priv, return 0; } -static int rcsi2_start_receiver(struct rcar_csi2 *priv) +static int rcsi2_start_receiver_gen3(struct rcar_csi2 *priv) { const struct rcar_csi2_format *format; u32 phycnt, vcdt = 0, vcdt2 = 0, fld = 0; @@ -821,7 +830,7 @@ static int rcsi2_start(struct rcar_csi2 *priv) if (ret < 0) return ret; - ret = rcsi2_start_receiver(priv); + ret = priv->info->start_receiver(priv); if (ret) { rcsi2_enter_standby(priv); return ret; @@ -1363,6 +1372,8 @@ static int rcsi2_probe_resources(struct rcar_csi2 *priv, static const struct rcar_csi2_info rcar_csi2_info_r8a7795 = { .init_phtw = rcsi2_init_phtw_h3_v3h_m3n, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_h3_v3h_m3n, .csi0clkfreqrange = 0x20, .num_channels = 4, @@ -1371,6 +1382,8 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7795 = { static const struct rcar_csi2_info rcar_csi2_info_r8a7795es2 = { .init_phtw = rcsi2_init_phtw_h3es2, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_h3_v3h_m3n, .csi0clkfreqrange = 0x20, .num_channels = 4, @@ -1378,17 +1391,23 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7795es2 = { }; static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = { + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_m3w, .num_channels = 4, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77961 = { + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_m3w, .num_channels = 4, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = { .init_phtw = rcsi2_init_phtw_h3_v3h_m3n, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_h3_v3h_m3n, .csi0clkfreqrange = 0x20, .num_channels = 4, @@ -1398,11 +1417,15 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = { static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = { .init_phtw = rcsi2_init_phtw_v3m_e3, .phy_post_init = rcsi2_phy_post_init_v3m_e3, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .num_channels = 4, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = { .init_phtw = rcsi2_init_phtw_h3_v3h_m3n, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_h3_v3h_m3n, .csi0clkfreqrange = 0x20, .clear_ulps = true, @@ -1411,11 +1434,15 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = { static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = { .init_phtw = rcsi2_init_phtw_v3m_e3, .phy_post_init = rcsi2_phy_post_init_v3m_e3, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .num_channels = 2, }; static const struct rcar_csi2_info rcar_csi2_info_r8a779a0 = { .init_phtw = rcsi2_init_phtw_v3u, + .start_receiver = rcsi2_start_receiver_gen3, + .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_v3u, .csi0clkfreqrange = 0x20, .clear_ulps = true, From patchwork Mon Apr 24 18:59:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 13222501 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7F9EDC7618E for ; Mon, 24 Apr 2023 19:00:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232269AbjDXTAC (ORCPT ); Mon, 24 Apr 2023 15:00:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54810 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232021AbjDXTAA (ORCPT ); Mon, 24 Apr 2023 15:00:00 -0400 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 AA58C618B for ; Mon, 24 Apr 2023 11:59:58 -0700 (PDT) Received: by mail-ej1-x62a.google.com with SMTP id a640c23a62f3a-956ff2399b1so805343266b.3 for ; Mon, 24 Apr 2023 11:59:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ragnatech-se.20221208.gappssmtp.com; s=20221208; t=1682362797; x=1684954797; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=oSAEsHoeHMQpdL6ZvKRgqolxUDUSXbgcAbdiPtPGo8Q=; b=Is+cXx5sm+47ciRaUWgY2Pdic27EQ2jSa+3/9sZhlAD20D9majU4DQEa/YPoI0dBf4 IkWs5ysr6bshdGgEpK/Z1w0ix8CHLB2i1sOi7dtY2h3Qd/3BnGVJ1oqeq2nnCOEiz/yJ 1+T3MosJ67x5gq1wpkGup0oycJ7o0j1u81HHs4M9vzuAPz/RugwFpCIegmQ7+dO/i77u ONTuLt5K3zRxHmev4Z6+vwVrEtz+wNQfbYp2YH9sHuUV9Ctl8WLGxfwqVj9jV0YKjwPD nbiAqb0FfdUOL+dTK0pP3rtvLgPbIkeGytFAc0F/f+hj2CkYc7oUB/t6wMfQHxasZ8fx QeRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682362797; x=1684954797; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oSAEsHoeHMQpdL6ZvKRgqolxUDUSXbgcAbdiPtPGo8Q=; b=CTKZbQ2TOUZ2xqksAS4olDrw0sZQNcERDL4wJbdAJtSyMgTec9DaKWyYL2fHgXw3rW Yl4bNYfWU1EreCHL0w/gT6sGGQbP7iKRF1oUORuhjP91p7OumGDyPRJOfGje3rJH9nQT 65to/zEtibspDBc/ojvEUP/uz4CWVzGRwYwrq6HLFMoxPppnZcCUC+Nw97OnMyUeSGkd /NrjbYBd4zkngXfB/ZhlwiJs3K5bVH4nQ/J8tTutek0Ph9GbawB/zIYl1TaPLAYPUxLB qF+XrrDT/bkSOA2bi9W8/EPy4NNKCWaDyqpBjaZZkxkF7O4q8dffJtgzpKcut0JXYVH+ Z6yQ== X-Gm-Message-State: AAQBX9enS8p1EbbIbg+e4g5M0Hru+x3NUsrkZKTorcLsDW+/9okDKjKL cB7EfguJHuJ7tUSD7FgKydMAvA== X-Google-Smtp-Source: AKy350bOfndYMFBEYE5c5l63k+2U1lEAh1zJkHPhQ1k/2KSyzHgRhDp8b3hh2yPsfdUFBPEugshXIQ== X-Received: by 2002:a17:906:f6d8:b0:957:12a6:a00f with SMTP id jo24-20020a170906f6d800b0095712a6a00fmr10165051ejb.21.1682362797086; Mon, 24 Apr 2023 11:59:57 -0700 (PDT) Received: from sleipner.berto.se (p54ac52fc.dip0.t-ipconnect.de. [84.172.82.252]) by smtp.googlemail.com with ESMTPSA id ke15-20020a17090798ef00b0095328ce9c8bsm5849818ejc.67.2023.04.24.11.59.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Apr 2023 11:59:56 -0700 (PDT) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: Hans Verkuil , linux-media@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, =?utf-8?q?Niklas_S=C3=B6derlund?= Subject: [PATCH v2 2/3] media: rcar-csi2: Prepare for C-PHY support Date: Mon, 24 Apr 2023 20:59:33 +0200 Message-Id: <20230424185934.438059-3-niklas.soderlund+renesas@ragnatech.se> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230424185934.438059-1-niklas.soderlund+renesas@ragnatech.se> References: <20230424185934.438059-1-niklas.soderlund+renesas@ragnatech.se> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Gen4 will support both D-PHY and C-PHY, while Gen3 only supports D-PHY. Add two flags to the device information structure to be able to record what each SoC supports. Extend the device node parsing to accept both CSI_2 D-PHY and C-PHY buses, while at the same time taking the SoC support into account. Signed-off-by: Niklas Söderlund --- * Changes since v1 - Rebased to latest media-tree. --- .../platform/renesas/rcar-vin/rcar-csi2.c | 70 +++++++++++++++---- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c index 05ea1723f04b..f200fc2bc959 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c @@ -490,6 +490,8 @@ struct rcar_csi2_info { unsigned int num_channels; bool clear_ulps; bool use_isp; + bool support_dphy; + bool support_cphy; }; struct rcar_csi2 { @@ -511,6 +513,7 @@ struct rcar_csi2 { struct v4l2_mbus_framefmt mf; int stream_count; + bool cphy; unsigned short lanes; unsigned char lane_swap[4]; }; @@ -665,9 +668,17 @@ static int rcsi2_get_active_lanes(struct rcar_csi2 *priv, return ret; } - if (mbus_config.type != V4L2_MBUS_CSI2_DPHY) { - dev_err(priv->dev, "Unsupported media bus type %u\n", - mbus_config.type); + switch (mbus_config.type) { + case V4L2_MBUS_CSI2_CPHY: + if (!priv->cphy) + return -EINVAL; + break; + case V4L2_MBUS_CSI2_DPHY: + if (priv->cphy) + return -EINVAL; + break; + default: + dev_err(priv->dev, "Unsupported media bus type %u\n", mbus_config.type); return -EINVAL; } @@ -1025,15 +1036,41 @@ static int rcsi2_parse_v4l2(struct rcar_csi2 *priv, if (vep->base.port || vep->base.id) return -ENOTCONN; - if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) { - dev_err(priv->dev, "Unsupported bus: %u\n", vep->bus_type); - return -EINVAL; - } - priv->lanes = vep->bus.mipi_csi2.num_data_lanes; - if (priv->lanes != 1 && priv->lanes != 2 && priv->lanes != 4) { - dev_err(priv->dev, "Unsupported number of data-lanes: %u\n", - priv->lanes); + + switch (vep->bus_type) { + case V4L2_MBUS_CSI2_DPHY: + if (!priv->info->support_dphy) { + dev_err(priv->dev, "D-PHY not supported\n"); + return -EINVAL; + } + + if (priv->lanes != 1 && priv->lanes != 2 && priv->lanes != 4) { + dev_err(priv->dev, + "Unsupported number of data-lanes for D-PHY: %u\n", + priv->lanes); + return -EINVAL; + } + + priv->cphy = false; + break; + case V4L2_MBUS_CSI2_CPHY: + if (!priv->info->support_cphy) { + dev_err(priv->dev, "C-PHY not supported\n"); + return -EINVAL; + } + + if (priv->lanes != 3) { + dev_err(priv->dev, + "Unsupported number of data-lanes for C-PHY: %u\n", + priv->lanes); + return -EINVAL; + } + + priv->cphy = true; + break; + default: + dev_err(priv->dev, "Unsupported bus: %u\n", vep->bus_type); return -EINVAL; } @@ -1057,7 +1094,7 @@ static int rcsi2_parse_dt(struct rcar_csi2 *priv) struct fwnode_handle *fwnode; struct fwnode_handle *ep; struct v4l2_fwnode_endpoint v4l2_ep = { - .bus_type = V4L2_MBUS_CSI2_DPHY + .bus_type = V4L2_MBUS_UNKNOWN, }; int ret; @@ -1378,6 +1415,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7795 = { .csi0clkfreqrange = 0x20, .num_channels = 4, .clear_ulps = true, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a7795es2 = { @@ -1388,6 +1426,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7795es2 = { .csi0clkfreqrange = 0x20, .num_channels = 4, .clear_ulps = true, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = { @@ -1395,6 +1434,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = { .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_m3w, .num_channels = 4, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77961 = { @@ -1402,6 +1442,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77961 = { .enter_standby = rcsi2_enter_standby_gen3, .hsfreqrange = hsfreqrange_m3w, .num_channels = 4, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = { @@ -1412,6 +1453,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = { .csi0clkfreqrange = 0x20, .num_channels = 4, .clear_ulps = true, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = { @@ -1420,6 +1462,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = { .start_receiver = rcsi2_start_receiver_gen3, .enter_standby = rcsi2_enter_standby_gen3, .num_channels = 4, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = { @@ -1429,6 +1472,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = { .hsfreqrange = hsfreqrange_h3_v3h_m3n, .csi0clkfreqrange = 0x20, .clear_ulps = true, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = { @@ -1437,6 +1481,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = { .start_receiver = rcsi2_start_receiver_gen3, .enter_standby = rcsi2_enter_standby_gen3, .num_channels = 2, + .support_dphy = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a779a0 = { @@ -1447,6 +1492,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a779a0 = { .csi0clkfreqrange = 0x20, .clear_ulps = true, .use_isp = true, + .support_dphy = true, }; static const struct of_device_id rcar_csi2_of_table[] = { From patchwork Mon Apr 24 18:59:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 13222502 X-Patchwork-Delegate: kieran@bingham.xyz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 099B6C77B7F for ; Mon, 24 Apr 2023 19:00:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231751AbjDXTAD (ORCPT ); Mon, 24 Apr 2023 15:00:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54820 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231681AbjDXTAC (ORCPT ); Mon, 24 Apr 2023 15:00:02 -0400 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 88CFA6591 for ; Mon, 24 Apr 2023 11:59:59 -0700 (PDT) Received: by mail-ej1-x632.google.com with SMTP id a640c23a62f3a-94f1a6e66c9so864787766b.2 for ; Mon, 24 Apr 2023 11:59:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ragnatech-se.20221208.gappssmtp.com; s=20221208; t=1682362798; x=1684954798; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5BkrnFvpa5z4Dpdn5vvYGKxLRAfUOmv0juyCLSOg6qs=; b=mRqVGIVQnycF05THgQDQoJSdhVfeSJqNV06wPuFcyCq3d3HJ6mA8PGckgVQv7dGn6w l6CyyH3uuIVZa9l3GyzbaryHmdMvnl0ttGVBzjXCdtkMBd5Hh2pgRHx1iJN4VPJ68IQi dDrhCuwUv1LA+w6C+70Q5y7JSV0KWDybIqLPgAPWHhOZSCbDEGwj6rFWAu/pc1cBQf11 sAsOwBDRuux34pHqUDQ49RMk+rzPv51b9OIRms0tAiMPT2FNPcN133TMJivKV+2OFGrH ip+iw8baBO9qQKS3n1HiqpvsFgR+vk+YE3NqymFjHAFvbAKO985toP0Vg0eNptDhXawv 2q1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682362798; x=1684954798; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5BkrnFvpa5z4Dpdn5vvYGKxLRAfUOmv0juyCLSOg6qs=; b=EyXDa9o5RsSKaFB/gU3sTFVj19C36WowUdjYnVoX2Mhyz4NhAhmLhCtdHplwEsQBFP iIGj4ikkYoDpu/3LpeuyvpJwb+q2dmEx7rpbv6myJ5WTR+m7e2ohBhmsm3awetwXdmPZ wtqpDGNGyCoq19ZgPSba1tYeotBgBsyPd/sI9DGQyZwHghSiFvshZ3KBpgC5KG4f+uzy O80LjD0zGv/6fjiWNmbBmpZskLZ7Zrpb1mZU+kkPqXjm9vg63n2AtTpV6EoI5hLrP/bI Yv6Yl+VZtUkatg8gHXkRxA5DfyVZ4cXGLorB6FYYr5IAXURx3hxpgvEPKqDCnK75qm+Z 9fTA== X-Gm-Message-State: AAQBX9fNbE9vrqRJxf9UD0ZT46F49Q6ar+oyEthK1HVzI3xWoal1T1bH 7dzEq+8C8WWhOox56txIFYecXNZaevWvfEhWu8E= X-Google-Smtp-Source: AKy350ahJxiMKk9vG5WpUH1SraruqyFWDhiES09TMr+z9Y0DfKoXPZ5xZnaCq0aX96cI/yBJUpxUnA== X-Received: by 2002:a17:906:f11a:b0:94e:5780:23f9 with SMTP id gv26-20020a170906f11a00b0094e578023f9mr10910161ejb.48.1682362797827; Mon, 24 Apr 2023 11:59:57 -0700 (PDT) Received: from sleipner.berto.se (p54ac52fc.dip0.t-ipconnect.de. [84.172.82.252]) by smtp.googlemail.com with ESMTPSA id ke15-20020a17090798ef00b0095328ce9c8bsm5849818ejc.67.2023.04.24.11.59.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Apr 2023 11:59:57 -0700 (PDT) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: Hans Verkuil , linux-media@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, =?utf-8?q?Niklas_S=C3=B6derlund?= Subject: [PATCH v2 3/3] media: rcar-csi2: Add support for C-PHY on R-Car V4H Date: Mon, 24 Apr 2023 20:59:34 +0200 Message-Id: <20230424185934.438059-4-niklas.soderlund+renesas@ragnatech.se> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230424185934.438059-1-niklas.soderlund+renesas@ragnatech.se> References: <20230424185934.438059-1-niklas.soderlund+renesas@ragnatech.se> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add support for C-PHY on R-Car V4H. While the V4H supports both D-PHY and C-PHY this patch only adds support for the C-PHY mode due to lack of documentation and hardware to test on. The V4H is the first Gen4 device that is enabled in the rcar-csi2 driver. There is much overlap with the Gen3 driver, the primary difference is in how the receiver is started. The V4H have a much larger register space and some addresses overlap with Gen3. Signed-off-by: Niklas Söderlund --- * Changes since v1 - Rebased to latest media-tree. --- .../platform/renesas/rcar-vin/rcar-csi2.c | 288 ++++++++++++++++++ 1 file changed, 288 insertions(+) diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c index f200fc2bc959..02352db05299 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c @@ -133,6 +133,111 @@ struct rcar_csi2; #define PHYFRX_FORCERX_MODE_1 BIT(1) #define PHYFRX_FORCERX_MODE_0 BIT(0) +/* V4H BASE registers */ +#define V4H_N_LANES_REG 0x0004 +#define V4H_CSI2_RESETN_REG 0x0008 +#define V4H_PHY_MODE_REG 0x001c +#define V4H_PHY_SHUTDOWNZ_REG 0x0040 +#define V4H_DPHY_RSTZ_REG 0x0044 +#define V4H_FLDC_REG 0x0804 +#define V4H_FLDD_REG 0x0808 +#define V4H_IDIC_REG 0x0810 +#define V4H_PHY_EN_REG 0x2000 + +#define V4H_ST_PHYST_REG 0x2814 +#define V4H_ST_PHYST_ST_PHY_READY BIT(31) +#define V4H_ST_PHYST_ST_STOPSTATE_3 BIT(3) +#define V4H_ST_PHYST_ST_STOPSTATE_2 BIT(2) +#define V4H_ST_PHYST_ST_STOPSTATE_1 BIT(1) +#define V4H_ST_PHYST_ST_STOPSTATE_0 BIT(0) + +/* V4H PPI registers */ +#define V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(n) (0x21800 + ((n) * 2)) /* n = 0 - 9 */ +#define V4H_PPI_STARTUP_RW_COMMON_STARTUP_1_1_REG 0x21822 +#define V4H_PPI_CALIBCTRL_RW_COMMON_BG_0_REG 0x2184c +#define V4H_PPI_RW_LPDCOCAL_TIMEBASE_REG 0x21c02 +#define V4H_PPI_RW_LPDCOCAL_NREF_REG 0x21c04 +#define V4H_PPI_RW_LPDCOCAL_NREF_RANGE_REG 0x21c06 +#define V4H_PPI_RW_LPDCOCAL_TWAIT_CONFIG_REG 0x21c0a +#define V4H_PPI_RW_LPDCOCAL_VT_CONFIG_REG 0x21c0c +#define V4H_PPI_RW_LPDCOCAL_COARSE_CFG_REG 0x21c10 +#define V4H_PPI_RW_COMMON_CFG_REG 0x21c6c +#define V4H_PPI_RW_TERMCAL_CFG_0_REG 0x21c80 +#define V4H_PPI_RW_OFFSETCAL_CFG_0_REG 0x21ca0 + +/* V4H CORE registers */ +#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(n) (0x22040 + ((n) * 2)) /* n = 0 - 15 */ +#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_REG(n) (0x22440 + ((n) * 2)) /* n = 0 - 15 */ +#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_REG(n) (0x22840 + ((n) * 2)) /* n = 0 - 15 */ +#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_REG(n) (0x22c40 + ((n) * 2)) /* n = 0 - 15 */ +#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_REG(n) (0x23040 + ((n) * 2)) /* n = 0 - 15 */ +#define V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(n) (0x23840 + ((n) * 2)) /* n = 0 - 11 */ +#define V4H_CORE_DIG_RW_COMMON_REG(n) (0x23880 + ((n) * 2)) /* n = 0 - 15 */ +#define V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(n) (0x239e0 + ((n) * 2)) /* n = 0 - 3 */ +#define V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG 0x2a400 +#define V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG 0x2a60c + +/* V4H C-PHY */ +#define V4H_CORE_DIG_RW_TRIO0_REG(n) (0x22100 + ((n) * 2)) /* n = 0 - 3 */ +#define V4H_CORE_DIG_RW_TRIO1_REG(n) (0x22500 + ((n) * 2)) /* n = 0 - 3 */ +#define V4H_CORE_DIG_RW_TRIO2_REG(n) (0x22900 + ((n) * 2)) /* n = 0 - 3 */ +#define V4H_CORE_DIG_CLANE_0_RW_LP_0_REG 0x2a080 +#define V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(n) (0x2a100 + ((n) * 2)) /* n = 0 - 6 */ +#define V4H_CORE_DIG_CLANE_1_RW_LP_0_REG 0x2a480 +#define V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(n) (0x2a500 + ((n) * 2)) /* n = 0 - 6 */ +#define V4H_CORE_DIG_CLANE_2_RW_LP_0_REG 0x2a880 +#define V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(n) (0x2a900 + ((n) * 2)) /* n = 0 - 6 */ + +struct rcsi2_cphy_setting { + u16 msps; + u16 rx2; + u16 trio0; + u16 trio1; + u16 trio2; + u16 lane27; + u16 lane29; +}; + +static const struct rcsi2_cphy_setting cphy_setting_table_r8a779g0[] = { + { .msps = 80, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0134, .trio2 = 0x6a, .lane27 = 0x0000, .lane29 = 0x0a24 }, + { .msps = 100, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x00f5, .trio2 = 0x55, .lane27 = 0x0000, .lane29 = 0x0a24 }, + { .msps = 200, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0077, .trio2 = 0x2b, .lane27 = 0x0000, .lane29 = 0x0a44 }, + { .msps = 300, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x004d, .trio2 = 0x1d, .lane27 = 0x0000, .lane29 = 0x0a44 }, + { .msps = 400, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0038, .trio2 = 0x16, .lane27 = 0x0000, .lane29 = 0x0a64 }, + { .msps = 500, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x002b, .trio2 = 0x12, .lane27 = 0x0000, .lane29 = 0x0a64 }, + { .msps = 600, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0023, .trio2 = 0x0f, .lane27 = 0x0000, .lane29 = 0x0a64 }, + { .msps = 700, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x001d, .trio2 = 0x0d, .lane27 = 0x0000, .lane29 = 0x0a84 }, + { .msps = 800, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0018, .trio2 = 0x0c, .lane27 = 0x0000, .lane29 = 0x0a84 }, + { .msps = 900, .rx2 = 0x38, .trio0 = 0x024a, .trio1 = 0x0015, .trio2 = 0x0b, .lane27 = 0x0000, .lane29 = 0x0a84 }, + { .msps = 1000, .rx2 = 0x3e, .trio0 = 0x024a, .trio1 = 0x0012, .trio2 = 0x0a, .lane27 = 0x0400, .lane29 = 0x0a84 }, + { .msps = 1100, .rx2 = 0x44, .trio0 = 0x024a, .trio1 = 0x000f, .trio2 = 0x09, .lane27 = 0x0800, .lane29 = 0x0a84 }, + { .msps = 1200, .rx2 = 0x4a, .trio0 = 0x024a, .trio1 = 0x000e, .trio2 = 0x08, .lane27 = 0x0c00, .lane29 = 0x0a84 }, + { .msps = 1300, .rx2 = 0x51, .trio0 = 0x024a, .trio1 = 0x000c, .trio2 = 0x08, .lane27 = 0x0c00, .lane29 = 0x0aa4 }, + { .msps = 1400, .rx2 = 0x57, .trio0 = 0x024a, .trio1 = 0x000b, .trio2 = 0x07, .lane27 = 0x1000, .lane29 = 0x0aa4 }, + { .msps = 1500, .rx2 = 0x5d, .trio0 = 0x044a, .trio1 = 0x0009, .trio2 = 0x07, .lane27 = 0x1000, .lane29 = 0x0aa4 }, + { .msps = 1600, .rx2 = 0x63, .trio0 = 0x044a, .trio1 = 0x0008, .trio2 = 0x07, .lane27 = 0x1400, .lane29 = 0x0aa4 }, + { .msps = 1700, .rx2 = 0x6a, .trio0 = 0x044a, .trio1 = 0x0007, .trio2 = 0x06, .lane27 = 0x1400, .lane29 = 0x0aa4 }, + { .msps = 1800, .rx2 = 0x70, .trio0 = 0x044a, .trio1 = 0x0007, .trio2 = 0x06, .lane27 = 0x1400, .lane29 = 0x0aa4 }, + { .msps = 1900, .rx2 = 0x76, .trio0 = 0x044a, .trio1 = 0x0006, .trio2 = 0x06, .lane27 = 0x1400, .lane29 = 0x0aa4 }, + { .msps = 2000, .rx2 = 0x7c, .trio0 = 0x044a, .trio1 = 0x0005, .trio2 = 0x06, .lane27 = 0x1800, .lane29 = 0x0aa4 }, + { .msps = 2100, .rx2 = 0x83, .trio0 = 0x044a, .trio1 = 0x0005, .trio2 = 0x05, .lane27 = 0x1800, .lane29 = 0x0aa4 }, + { .msps = 2200, .rx2 = 0x89, .trio0 = 0x064a, .trio1 = 0x0004, .trio2 = 0x05, .lane27 = 0x1800, .lane29 = 0x0aa4 }, + { .msps = 2300, .rx2 = 0x8f, .trio0 = 0x064a, .trio1 = 0x0003, .trio2 = 0x05, .lane27 = 0x1800, .lane29 = 0x0aa4 }, + { .msps = 2400, .rx2 = 0x95, .trio0 = 0x064a, .trio1 = 0x0003, .trio2 = 0x05, .lane27 = 0x1800, .lane29 = 0x0aa4 }, + { .msps = 2500, .rx2 = 0x9c, .trio0 = 0x064a, .trio1 = 0x0003, .trio2 = 0x05, .lane27 = 0x1c00, .lane29 = 0x0aa4 }, + { .msps = 2600, .rx2 = 0xa2, .trio0 = 0x064a, .trio1 = 0x0002, .trio2 = 0x05, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 2700, .rx2 = 0xa8, .trio0 = 0x064a, .trio1 = 0x0002, .trio2 = 0x05, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 2800, .rx2 = 0xae, .trio0 = 0x064a, .trio1 = 0x0002, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 2900, .rx2 = 0xb5, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 3000, .rx2 = 0xbb, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 3100, .rx2 = 0xc1, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 3200, .rx2 = 0xc7, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 3300, .rx2 = 0xce, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 3400, .rx2 = 0xd4, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { .msps = 3500, .rx2 = 0xda, .trio0 = 0x084a, .trio1 = 0x0001, .trio2 = 0x04, .lane27 = 0x1c00, .lane29 = 0x0ad4 }, + { /* sentinel */ }, +}; + struct phtw_value { u16 data; u16 code; @@ -538,6 +643,11 @@ static void rcsi2_write(struct rcar_csi2 *priv, unsigned int reg, u32 data) iowrite32(data, priv->base + reg); } +static void rcsi2_write16(struct rcar_csi2 *priv, unsigned int reg, u16 data) +{ + iowrite16(data, priv->base + reg); +} + static void rcsi2_enter_standby_gen3(struct rcar_csi2 *priv) { rcsi2_write(priv, PHYCNT_REG, 0); @@ -645,6 +755,10 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp, mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * bpp; do_div(mbps, lanes * 1000000); + /* Adjust for C-PHY */ + if (priv->cphy) + do_div(mbps, 2.8); + return mbps; } @@ -833,6 +947,170 @@ static int rcsi2_start_receiver_gen3(struct rcar_csi2 *priv) return 0; } +static int rcsi2_wait_phy_start_v4h(struct rcar_csi2 *priv, u32 match) +{ + unsigned int timeout; + u32 status; + + for (timeout = 0; timeout <= 10; timeout++) { + status = rcsi2_read(priv, V4H_ST_PHYST_REG); + if ((status & match) == match) + return 0; + + usleep_range(1000, 2000); + } + + return -ETIMEDOUT; +} + +static int rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int msps) +{ + const struct rcsi2_cphy_setting *conf; + + for (conf = cphy_setting_table_r8a779g0; conf->msps != 0; conf++) { + if (conf->msps > msps) + break; + } + + if (!conf->msps) { + dev_err(priv->dev, "Unsupported PHY speed for msps setting (%u Msps)", msps); + return -ERANGE; + } + + /* C-PHY specific */ + rcsi2_write16(priv, V4H_CORE_DIG_RW_COMMON_REG(7), 0x0155); + rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(7), 0x0068); + rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(8), 0x0010); + + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_LP_0_REG, 0x463c); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_LP_0_REG, 0x463c); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_LP_0_REG, 0x463c); + + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(0), 0x00d5); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(0), 0x00d5); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(0), 0x00d5); + + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(1), 0x0013); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(1), 0x0013); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(1), 0x0013); + + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(5), 0x0013); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(5), 0x0013); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(5), 0x0013); + + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(6), 0x000a); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(6), 0x000a); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(6), 0x000a); + + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(2), conf->rx2); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(2), conf->rx2); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(2), conf->rx2); + + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(2), 0x0001); + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_REG(2), 0); + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_REG(2), 0x0001); + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_REG(2), 0x0001); + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_REG(2), 0); + + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO0_REG(0), conf->trio0); + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO1_REG(0), conf->trio0); + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO2_REG(0), conf->trio0); + + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO0_REG(2), conf->trio2); + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO1_REG(2), conf->trio2); + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO2_REG(2), conf->trio2); + + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO0_REG(1), conf->trio1); + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO1_REG(1), conf->trio1); + rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO2_REG(1), conf->trio1); + + /* + * Configure pin-swap. + * TODO: This registers is not documented yet, the values should depend + * on the 'clock-lanes' and 'data-lanes' devicetree properties. + */ + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG, 0xf5); + rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG, 0x5000); + + /* Leave Shutdown mode */ + rcsi2_write(priv, V4H_DPHY_RSTZ_REG, BIT(0)); + rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, BIT(0)); + + /* Wait for calibration */ + if (rcsi2_wait_phy_start_v4h(priv, V4H_ST_PHYST_ST_PHY_READY)) { + dev_err(priv->dev, "PHY calibration failed\n"); + return -ETIMEDOUT; + } + + /* C-PHY setting - analog programing*/ + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(9), conf->lane29); + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(7), conf->lane27); + + return 0; +} + +static int rcsi2_start_receiver_v4h(struct rcar_csi2 *priv) +{ + const struct rcar_csi2_format *format; + unsigned int msps, lanes; + int ret; + + /* Calculate parameters */ + format = rcsi2_code_to_fmt(priv->mf.code); + + ret = rcsi2_get_active_lanes(priv, &lanes); + if (ret) + return ret; + + msps = rcsi2_calc_mbps(priv, format->bpp, lanes); + if (msps < 0) + return msps; + + /* Reset LINK and PHY*/ + rcsi2_write(priv, V4H_CSI2_RESETN_REG, 0); + rcsi2_write(priv, V4H_DPHY_RSTZ_REG, 0); + rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, 0); + + /* PHY static setting */ + rcsi2_write(priv, V4H_PHY_EN_REG, BIT(0)); + rcsi2_write(priv, V4H_FLDC_REG, 0); + rcsi2_write(priv, V4H_FLDD_REG, 0); + rcsi2_write(priv, V4H_IDIC_REG, 0); + rcsi2_write(priv, V4H_PHY_MODE_REG, BIT(0)); + rcsi2_write(priv, V4H_N_LANES_REG, lanes - 1); + + /* Reset CSI2 */ + rcsi2_write(priv, V4H_CSI2_RESETN_REG, BIT(0)); + + /* Registers static setting through APB */ + /* Common setting */ + rcsi2_write16(priv, V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(0), 0x1bfd); + rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_STARTUP_1_1_REG, 0x0233); + rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(6), 0x0027); + rcsi2_write16(priv, V4H_PPI_CALIBCTRL_RW_COMMON_BG_0_REG, 0x01f4); + rcsi2_write16(priv, V4H_PPI_RW_TERMCAL_CFG_0_REG, 0x0013); + rcsi2_write16(priv, V4H_PPI_RW_OFFSETCAL_CFG_0_REG, 0x0003); + rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_TIMEBASE_REG, 0x004f); + rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_NREF_REG, 0x0320); + rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_NREF_RANGE_REG, 0x000f); + rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_TWAIT_CONFIG_REG, 0xfe18); + rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_VT_CONFIG_REG, 0x0c3c); + rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_COARSE_CFG_REG, 0x0105); + rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(6), 0x1000); + rcsi2_write16(priv, V4H_PPI_RW_COMMON_CFG_REG, 0x0003); + + /* C-PHY settings */ + ret = rcsi2_c_phy_setting_v4h(priv, msps); + if (ret) + return ret; + + rcsi2_wait_phy_start_v4h(priv, V4H_ST_PHYST_ST_STOPSTATE_0 | + V4H_ST_PHYST_ST_STOPSTATE_1 | + V4H_ST_PHYST_ST_STOPSTATE_2); + + return 0; +} + static int rcsi2_start(struct rcar_csi2 *priv) { int ret; @@ -1495,6 +1773,12 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a779a0 = { .support_dphy = true, }; +static const struct rcar_csi2_info rcar_csi2_info_r8a779g0 = { + .start_receiver = rcsi2_start_receiver_v4h, + .use_isp = true, + .support_cphy = true, +}; + static const struct of_device_id rcar_csi2_of_table[] = { { .compatible = "renesas,r8a774a1-csi2", @@ -1544,6 +1828,10 @@ static const struct of_device_id rcar_csi2_of_table[] = { .compatible = "renesas,r8a779a0-csi2", .data = &rcar_csi2_info_r8a779a0, }, + { + .compatible = "renesas,r8a779g0-csi2", + .data = &rcar_csi2_info_r8a779g0, + }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, rcar_csi2_of_table);