Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp235068pxj; Wed, 16 Jun 2021 00:53:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy0PfYROZDqxHfOv8lZsFUypANYMp3ZjrVbo3l1BoSxWOunlty6hwJLJXxmibs6vS12FT+4 X-Received: by 2002:a17:906:9381:: with SMTP id l1mr1816293ejx.553.1623830037108; Wed, 16 Jun 2021 00:53:57 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1623830037; cv=pass; d=google.com; s=arc-20160816; b=NcMg3a5G26Sfk86Ar0cGH6/I4zhbOYHzKOjaWYBdGX1WHtXbx3jZzHN4gRPX95i9Ue 7ws2nQtesScfPiLSAT/vbuE632aCZeQVVL2tJE71uNCrnS9gximOnZxqyeLwbAGNty1R wSepAarH8JtIUp5w8fUGl+tV14xLviuj64pAKlPxYbFabiDhAg5upwCBgt1CIE564saP i31RvAut7TJsi9c7a0U7XhLjp9EgCF3cSudNWzbCWcQW+9pRzc9+Lu4I2P7lY19MSZI+ lPdaMlQCJFP/GvAKwFVhXCRWsBqbmC5MpSmJdb9nOegsZg8iLQ1/KBppQmz5U9WoYToJ l24w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:in-reply-to:content-disposition :references:message-id:subject:cc:to:from:date:dkim-signature; bh=nfI7upG9u6rdCFVZo3/6NURQ9OIyExiwIiEWo94Kpf0=; b=KZkIYFebLcF/+ouhCFaN3F0rCQ2Xb1a0NMlATUuFAx8Kui/0WeammK7mNbu+6j6rJo BnNuDWlGz7DVMaiJ95rF8ifYUk8ppVPOH9y54z1mtktC1/nmNCcC1g67L9A2UvIvMwRr pNwn+H8otUUZdcOoMLpwW551D8CW3t70D3jIIdBSPjw0eoSooFP2mrUei+6+wDISSf0B A1OZ6c4iClpQB/eSMWBN5v+HHtT2hwncSss8vNqGczRB/4FyKkfnHUxJb0JNWCjUwAz4 Kkgiw7q4unEJ5eshdoTEK5nkHQo74nZMwoaTj8UauA05LsbULfMhhCu6HEfe7dp9dDSf xJVg== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@Analogixsemi.onmicrosoft.com header.s=selector2-Analogixsemi-onmicrosoft-com header.b=zcgRgwhX; arc=pass (i=1 spf=pass spfdomain=analogixsemi.com dkim=pass dkdomain=analogixsemi.com dmarc=pass fromdomain=analogixsemi.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=analogixsemi.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id p21si1725070ejn.49.2021.06.16.00.53.34; Wed, 16 Jun 2021 00:53:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-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=@Analogixsemi.onmicrosoft.com header.s=selector2-Analogixsemi-onmicrosoft-com header.b=zcgRgwhX; arc=pass (i=1 spf=pass spfdomain=analogixsemi.com dkim=pass dkdomain=analogixsemi.com dmarc=pass fromdomain=analogixsemi.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=analogixsemi.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231481AbhFPHxM (ORCPT + 99 others); Wed, 16 Jun 2021 03:53:12 -0400 Received: from mail-mw2nam12on2098.outbound.protection.outlook.com ([40.107.244.98]:50073 "EHLO NAM12-MW2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S231453AbhFPHxL (ORCPT ); Wed, 16 Jun 2021 03:53:11 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=S1ftR7X9oBmKxYg7XFb+29/UGn/9tQh40CTnSty63O7cqucTrvmD70uJC+dC0dpttbcP4Fgmbk6iuXI4qpTXazPfZT8AGztd5D4cmV8gxVsqDRdu2KcTE6EU8Dp/TpIgzP4vtzUrrcqaC2pBcoThm+eTfUgUOecTq3RKqC3/+ORV68ioR37JMGwrXt6fN5o6V365GcxUHl5hSOyJLpcPVf/5iLKdLp78/1wmv5VuQzoKO8XApSG3+kMNtT2PW1Yngv1dtQZO6oLTtVdCI4fxVx1WrJ2MqRcLuagk7xKDHVcMfqFgQX4tWjstOGqolNzPL/sCnLz7kJxGHl0ymDaxAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=nfI7upG9u6rdCFVZo3/6NURQ9OIyExiwIiEWo94Kpf0=; b=B4NzRp7tyqrhjyA7An5eUigvOdHUAPFtLmfxB6PgO7GMt7j0NR/daLJVGox3Z/sXvfOTkpoSEjXiNfK50GQlmR6NgeDj0feoW4ytKLNm5Rxi7X4Y+NjZ1lIoCOkbNY9EANtgjHSacVAGnCQyWt5qnQa7/9xjVLnziL3esJEH0kkvOaUHvV3ZCYxWiuZl/1b7HStQwDhh2tZhE/Q0Agy4moqxTjYOBaUPvY6qpCuv2MmO2hCBTKN8VJZc3xPoNjxAsFQfO/LbnF54BhEnlk6Ie+nHV5+e70IBLeTXDzX5U2O6SX1MFv5xASXReL4mvu/WovBRPK0Lqx8DeNoXMyepRw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=analogixsemi.com; dmarc=pass action=none header.from=analogixsemi.com; dkim=pass header.d=analogixsemi.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Analogixsemi.onmicrosoft.com; s=selector2-Analogixsemi-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=nfI7upG9u6rdCFVZo3/6NURQ9OIyExiwIiEWo94Kpf0=; b=zcgRgwhXJFoZ0hb4Fx+qzbBT1sttnLPilm/f6A30lN8zS4rVSnuiGG+p9RmvTtRTBZKYuJeCm4jh4pSiXtmkOoh4iDwcNHqtcx2WzxGUc66M5RSIS9ulxxw24bMxM0mqbpP0P5ASvKMsfAR5w/kg6vJyVs7Syn83NVf3BP6/dfM= Authentication-Results: driverdev.osuosl.org; dkim=none (message not signed) header.d=none;driverdev.osuosl.org; dmarc=none action=none header.from=analogixsemi.com; Received: from BY5PR04MB6739.namprd04.prod.outlook.com (2603:10b6:a03:229::8) by BYAPR04MB4582.namprd04.prod.outlook.com (2603:10b6:a03:13::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4219.22; Wed, 16 Jun 2021 07:51:04 +0000 Received: from BY5PR04MB6739.namprd04.prod.outlook.com ([fe80::5c0e:fbe5:2bd6:ec6]) by BY5PR04MB6739.namprd04.prod.outlook.com ([fe80::5c0e:fbe5:2bd6:ec6%3]) with mapi id 15.20.4219.026; Wed, 16 Jun 2021 07:51:04 +0000 Date: Wed, 16 Jun 2021 15:50:59 +0800 From: Xin Ji To: Robert Foss , Nicolas Boichat , Andrzej Hajda Cc: Neil Armstrong , Laurent Pinchart , Jonas Karlman , Dan Carpenter , David Airlie , Daniel Vetter , Boris Brezillon , Sam Ravnborg , Hsin-Yi Wang , Torsten Duwe , Vasily Khoruzhick , Marek Szyprowski , Sheng Pan , Bernie Liang , Zhen Li , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, devel@driverdev.osuosl.org Subject: [PATCH v8 3/4] drm/bridge: anx7625: add MIPI DPI input feature Message-ID: References: Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Originating-IP: [60.251.58.79] X-ClientProxiedBy: HK2PR02CA0164.apcprd02.prod.outlook.com (2603:1096:201:1f::24) To BY5PR04MB6739.namprd04.prod.outlook.com (2603:10b6:a03:229::8) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from anxtwsw-Precision-3640-Tower (60.251.58.79) by HK2PR02CA0164.apcprd02.prod.outlook.com (2603:1096:201:1f::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4242.16 via Frontend Transport; Wed, 16 Jun 2021 07:51:03 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b899306c-f839-4fac-e2c4-08d9309b7df9 X-MS-TrafficTypeDiagnostic: BYAPR04MB4582: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:66; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ax8R428WP+kH1hyScDol86Icg/5cZ0FX/mfZtE7x0D20OsYUH/lG4Q3dOw+UWLkHpmwrLecnlCBnI3Zg4U4EhFo22X87P+oFhoSadk/QtmO5pnnbOm8jtNgT8AG7MIIem6JGxaB6ai25q0HTi9ScOF8H6igKUcSVeAXC9b0nN+5wjvc02bvvcXlbRo4dA3u2EZDSZ4Rva0g5Mkqm4NA2qvXu/C5FHCmrBMIGBIZeLZRqi+/YWd9p/cQiBbi9LjfHo6VjLgf3TzQCpE4rhtSuDO6HO1D1n92X0F8M9jMDQLikD5/Xfw4OpPLiyJHBes9r84n00wId8+pFWukrtYX+zgeVTnrzQhpqbS4GEnhPjrkwCxRJPW3kf+yWI5cHtV4hBBrUgutDdiZZbuecYrSjMt6mpt9AGOejVbDDNI4QXl2ocwCNC08U/HBF15PLoE50hSx7sx1huDGDEovPmD7DTpdjhPHd1bhiEc6+Iii9BtLuLGkOsHb73vzwR7yOHjONBnsfKQf6/3fljCWfA4yNA39rFvZ6WJjGF0BXRfwudoNmHqxHeeGzbdjCMMUfJLs4blvoEPqcWSh9HxXTrFKLkvzpKy36c/8s5d4yVXTl72qErob2F9KqGWLtAWizcx9HlZ2gbqGAImaE0ywlQBs3mk2YAPrwtcDYqaoRMogRXoQ= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BY5PR04MB6739.namprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(39840400004)(346002)(376002)(366004)(396003)(136003)(52116002)(16526019)(5660300002)(316002)(478600001)(38350700002)(2616005)(4326008)(8676002)(6496006)(66946007)(55236004)(54906003)(110136005)(956004)(30864003)(83380400001)(8936002)(6486002)(26005)(38100700002)(36756003)(186003)(86362001)(66556008)(6666004)(66476007)(2906002)(7416002);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?OD2W2Xac/PJCrX8dyg/myPzRR/Hn+iNQFVbVCuY9Fv5TWjni8yHjZ1vCOuQI?= =?us-ascii?Q?4/ptfdTtd0gH/Q2cJIo9+wNjbo9wdPSvgZtmUZ541TYNHInBmhutn8vE++fh?= =?us-ascii?Q?9ZT7NAW07LMUEgP8HVJ5kB412KnNLaMgV7Z4wXz+RZDuUunQtSfYVQjVO0Vw?= =?us-ascii?Q?t8CIzrQtuipWochC7qdXPTMJy4mWrdj8A+gYJIvVRmPjlL6hMGiuuP6o/xzE?= =?us-ascii?Q?7KLzxbGBf6JUKnE82tsbiv/6XJcF2NucUA9Hs68tkJNHnZK7BRNBsRf2L8jj?= =?us-ascii?Q?/ojUnS/Uk155P0+axJCZucElj4qMngdjQonZi9THrbwSpizYKzZ1nNGKjZ7S?= =?us-ascii?Q?RDcxLETsJfd2HfuTthRcppogRSlUoFVxwnY+VSob590+puffBLqjk6wtd2Jc?= =?us-ascii?Q?QRS2bZOb56JE7AzkBPnwdGYuHAbFC23VSE2Z/Hgbj7ywBN5xuKJHgQCXbESO?= =?us-ascii?Q?7GKLPlL1Jv9UFCGeLT8xsI+9rBaoRt5PrPjg9c2mLA2nr4FtjhuRiT1QKJIz?= =?us-ascii?Q?RBIxNj8djpeqTVSCuSDPGY2/r1dOqFCXfu/Iyw7BRAUDmXFo7XGgDyuSgV74?= =?us-ascii?Q?FpZOhOsL7BCv95Mf4cYjcSTEfH5KfFqMQCqYur74/ImqFpcbZ5RdPh+SyP4u?= =?us-ascii?Q?7ItPQJXIXMuzSkFygJLqHNRxAEJE+mnEg8OMa9PeMxedZ3AEMnuU4Qhewbck?= =?us-ascii?Q?1LY83NeNAtQ7bf9SYn2AxwkewrykA+tjq1hyqp9m5hiGWhb5pLqoYuGMeAbf?= =?us-ascii?Q?HlPkOkb73jJONmL06OcCaYuzuGxLI3kDoYtorvsvxdHSawOZi1IrqfWqmFCw?= =?us-ascii?Q?AkDTEfSJebtxbYkOHWrB3wn522XnCdStmmJyY3klIRXW03JEO4LyXQsNxan1?= =?us-ascii?Q?CJdwp99k2+6lhX0/kL3xpVQ9tEFz/De3877f3ke/TNuNyEM3YC428G3KXPbW?= =?us-ascii?Q?ctC5Kk0lTrPy4E1OAaI3ChVG6bkZZNrJY8nBjRFqY75ygMNn5VKMHpibxGW+?= =?us-ascii?Q?x7mRHo18Dpy0FVXpqWV0HbRh86HRbyQTo8VZW0aMhTKvdlxhCtzvZNsEQqmk?= =?us-ascii?Q?AB77RG+uDqdjBiYTDcerpJIpquImAIZlC4Yk20ux1MJCzguVFHm0oHvFz6+a?= =?us-ascii?Q?yUIAwBI0lSyGX3PwhRbIjrP5W7G9/p88g63auwyuP0uvskRW+sncGdq08ZN/?= =?us-ascii?Q?ugBy/ByojU1Po4GtKUv9MPceN0U3XmMMgHE2i1GRPqTAB+dLHiy/NBEUIftO?= =?us-ascii?Q?EMuJi6hkMAFrFMlbg8gkxRJlyGCO5TTOq5J8m52dky+u0A6cMqNU/OM3E1mI?= =?us-ascii?Q?eSbW2qvbeJcA9t7OsaQLp5sD?= X-OriginatorOrg: analogixsemi.com X-MS-Exchange-CrossTenant-Network-Message-Id: b899306c-f839-4fac-e2c4-08d9309b7df9 X-MS-Exchange-CrossTenant-AuthSource: BY5PR04MB6739.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Jun 2021 07:51:04.3468 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b099b0b4-f26c-4cf5-9a0f-d5be9acab205 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: g62GuFNp6VAD0A+gismJ/GZvBT7WtbvsLAeCt9zxNPPC/H0I1zDG1qWnnMVimFBRsrp2pcqePBkbAJh+UJjg+g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR04MB4582 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The basic anx7625 driver only support MIPI DSI rx signal input. This patch add MIPI DPI rx input configuration support, after apply this patch, the driver can support DSI rx or DPI rx by adding 'bus-type' in DT. Reviewed-by: Robert Foss Signed-off-by: Xin Ji --- drivers/gpu/drm/bridge/analogix/anx7625.c | 245 ++++++++++++++++------ drivers/gpu/drm/bridge/analogix/anx7625.h | 18 +- 2 files changed, 203 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 048080e75016..fb2301a92704 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -152,18 +152,18 @@ static int anx7625_write_and(struct anx7625_data *ctx, return anx7625_reg_write(ctx, client, offset, (val & (mask))); } -static int anx7625_write_and_or(struct anx7625_data *ctx, - struct i2c_client *client, - u8 offset, u8 and_mask, u8 or_mask) +static int anx7625_config_bit_matrix(struct anx7625_data *ctx) { - int val; + int i, ret; - val = anx7625_reg_read(ctx, client, offset); - if (val < 0) - return val; + ret = anx7625_write_or(ctx, ctx->i2c.tx_p2_client, + AUDIO_CONTROL_REGISTER, 0x80); + for (i = 0; i < 13; i++) + ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, + VIDEO_BIT_MATRIX_12 + i, + 0x18 + i); - return anx7625_reg_write(ctx, client, - offset, (val & and_mask) | (or_mask)); + return ret; } static int anx7625_read_ctrl_status_p0(struct anx7625_data *ctx) @@ -221,38 +221,6 @@ static int anx7625_video_mute_control(struct anx7625_data *ctx, return ret; } -static int anx7625_config_audio_input(struct anx7625_data *ctx) -{ - struct device *dev = &ctx->client->dev; - int ret; - - /* Channel num */ - ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, - AUDIO_CHANNEL_STATUS_6, I2S_CH_2 << 5); - - /* FS */ - ret |= anx7625_write_and_or(ctx, ctx->i2c.tx_p2_client, - AUDIO_CHANNEL_STATUS_4, - 0xf0, AUDIO_FS_48K); - /* Word length */ - ret |= anx7625_write_and_or(ctx, ctx->i2c.tx_p2_client, - AUDIO_CHANNEL_STATUS_5, - 0xf0, AUDIO_W_LEN_24_24MAX); - /* I2S */ - ret |= anx7625_write_or(ctx, ctx->i2c.tx_p2_client, - AUDIO_CHANNEL_STATUS_6, I2S_SLAVE_MODE); - ret |= anx7625_write_and(ctx, ctx->i2c.tx_p2_client, - AUDIO_CONTROL_REGISTER, ~TDM_TIMING_MODE); - /* Audio change flag */ - ret |= anx7625_write_or(ctx, ctx->i2c.rx_p0_client, - AP_AV_STATUS, AP_AUDIO_CHG); - - if (ret < 0) - DRM_DEV_ERROR(dev, "fail to config audio.\n"); - - return ret; -} - /* Reduction of fraction a/b */ static void anx7625_reduction_of_a_fraction(unsigned long *a, unsigned long *b) { @@ -412,7 +380,7 @@ static int anx7625_dsi_video_timing_config(struct anx7625_data *ctx) ret |= anx7625_write_and(ctx, ctx->i2c.rx_p1_client, MIPI_LANE_CTRL_0, 0xfc); ret |= anx7625_write_or(ctx, ctx->i2c.rx_p1_client, - MIPI_LANE_CTRL_0, 3); + MIPI_LANE_CTRL_0, ctx->pdata.mipi_lanes - 1); /* Htotal */ htotal = ctx->dt.hactive.min + ctx->dt.hfront_porch.min + @@ -597,6 +565,76 @@ static int anx7625_dsi_config(struct anx7625_data *ctx) return ret; } +static int anx7625_api_dpi_config(struct anx7625_data *ctx) +{ + struct device *dev = &ctx->client->dev; + u16 freq = ctx->dt.pixelclock.min / 1000; + int ret; + + /* configure pixel clock */ + ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, + PIXEL_CLOCK_L, freq & 0xFF); + ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, + PIXEL_CLOCK_H, (freq >> 8)); + + /* set DPI mode */ + /* set to DPI PLL module sel */ + ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p1_client, + MIPI_DIGITAL_PLL_9, 0x20); + /* power down MIPI */ + ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p1_client, + MIPI_LANE_CTRL_10, 0x08); + /* enable DPI mode */ + ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p1_client, + MIPI_DIGITAL_PLL_18, 0x1C); + /* set first edge */ + ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, + VIDEO_CONTROL_0, 0x06); + if (ret < 0) + DRM_DEV_ERROR(dev, "IO error : dpi phy set failed.\n"); + + return ret; +} + +static int anx7625_dpi_config(struct anx7625_data *ctx) +{ + struct device *dev = &ctx->client->dev; + int ret; + + DRM_DEV_DEBUG_DRIVER(dev, "config dpi\n"); + + /* DSC disable */ + ret = anx7625_write_and(ctx, ctx->i2c.rx_p0_client, + R_DSC_CTRL_0, ~DSC_EN); + if (ret < 0) { + DRM_DEV_ERROR(dev, "IO error : disable dsc failed.\n"); + return ret; + } + + ret = anx7625_config_bit_matrix(ctx); + if (ret < 0) { + DRM_DEV_ERROR(dev, "config bit matrix failed.\n"); + return ret; + } + + ret = anx7625_api_dpi_config(ctx); + if (ret < 0) { + DRM_DEV_ERROR(dev, "mipi phy(dpi) setup failed.\n"); + return ret; + } + + /* set MIPI RX EN */ + ret = anx7625_write_or(ctx, ctx->i2c.rx_p0_client, + AP_AV_STATUS, AP_MIPI_RX_EN); + /* clear mute flag */ + ret |= anx7625_write_and(ctx, ctx->i2c.rx_p0_client, + AP_AV_STATUS, (u8)~AP_MIPI_MUTE); + if (ret < 0) + DRM_DEV_ERROR(dev, "IO error : enable mipi rx failed.\n"); + + return ret; +} + static void anx7625_dp_start(struct anx7625_data *ctx) { int ret; @@ -607,9 +645,10 @@ static void anx7625_dp_start(struct anx7625_data *ctx) return; } - anx7625_config_audio_input(ctx); - - ret = anx7625_dsi_config(ctx); + if (ctx->pdata.is_dpi) + ret = anx7625_dpi_config(ctx); + else + ret = anx7625_dsi_config(ctx); if (ret < 0) DRM_DEV_ERROR(dev, "MIPI phy setup error.\n"); @@ -1047,6 +1086,7 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx) return; } + ctx->hpd_status = 1; ctx->hpd_high_cnt++; /* Not support HDCP */ @@ -1056,8 +1096,10 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx) ret |= anx7625_write_or(ctx, ctx->i2c.rx_p1_client, 0xec, 0x10); /* Interrupt for DRM */ ret |= anx7625_write_or(ctx, ctx->i2c.rx_p1_client, 0xff, 0x01); - if (ret < 0) + if (ret < 0) { + DRM_DEV_ERROR(dev, "fail to setting HDCP/auth\n"); return; + } ret = anx7625_reg_read(ctx, ctx->i2c.rx_p1_client, 0x86); if (ret < 0) @@ -1076,6 +1118,10 @@ static void anx7625_hpd_polling(struct anx7625_data *ctx) int ret, val; struct device *dev = &ctx->client->dev; + /* Interrupt mode, no need poll HPD status, just return */ + if (ctx->pdata.intp_irq) + return; + ret = readx_poll_timeout(anx7625_read_hpd_status_p0, ctx, val, ((val & HPD_STATUS) || (val < 0)), @@ -1103,6 +1149,21 @@ static void anx7625_remove_edid(struct anx7625_data *ctx) ctx->slimport_edid_p.edid_block_num = -1; } +static void anx7625_dp_adjust_swing(struct anx7625_data *ctx) +{ + int i; + + for (i = 0; i < ctx->pdata.dp_lane0_swing_reg_cnt; i++) + anx7625_reg_write(ctx, ctx->i2c.tx_p1_client, + DP_TX_LANE0_SWING_REG0 + i, + ctx->pdata.lane0_reg_data[i] & 0xFF); + + for (i = 0; i < ctx->pdata.dp_lane1_swing_reg_cnt; i++) + anx7625_reg_write(ctx, ctx->i2c.tx_p1_client, + DP_TX_LANE1_SWING_REG0 + i, + ctx->pdata.lane1_reg_data[i] & 0xFF); +} + static void dp_hpd_change_handler(struct anx7625_data *ctx, bool on) { struct device *dev = &ctx->client->dev; @@ -1118,9 +1179,8 @@ static void dp_hpd_change_handler(struct anx7625_data *ctx, bool on) } else { DRM_DEV_DEBUG_DRIVER(dev, " HPD high\n"); anx7625_start_dp_work(ctx); + anx7625_dp_adjust_swing(ctx); } - - ctx->hpd_status = 1; } static int anx7625_hpd_change_detect(struct anx7625_data *ctx) @@ -1197,20 +1257,72 @@ static irqreturn_t anx7625_intr_hpd_isr(int irq, void *data) return IRQ_HANDLED; } +static int anx7625_get_swing_setting(struct device *dev, + struct anx7625_platform_data *pdata) +{ + int num_regs; + + if (of_get_property(dev->of_node, + "analogix,lane0-swing", &num_regs)) { + if (num_regs > DP_TX_SWING_REG_CNT) + num_regs = DP_TX_SWING_REG_CNT; + + pdata->dp_lane0_swing_reg_cnt = num_regs; + of_property_read_u32_array(dev->of_node, "analogix,lane0-swing", + pdata->lane0_reg_data, num_regs); + } + + if (of_get_property(dev->of_node, + "analogix,lane1-swing", &num_regs)) { + if (num_regs > DP_TX_SWING_REG_CNT) + num_regs = DP_TX_SWING_REG_CNT; + + pdata->dp_lane1_swing_reg_cnt = num_regs; + of_property_read_u32_array(dev->of_node, "analogix,lane1-swing", + pdata->lane1_reg_data, num_regs); + } + + return 0; +} + static int anx7625_parse_dt(struct device *dev, struct anx7625_platform_data *pdata) { - struct device_node *np = dev->of_node; + struct device_node *np = dev->of_node, *ep0; struct drm_panel *panel; int ret; + int bus_type, mipi_lanes; + anx7625_get_swing_setting(dev, pdata); + + pdata->is_dpi = 1; /* default dpi mode */ pdata->mipi_host_node = of_graph_get_remote_node(np, 0, 0); if (!pdata->mipi_host_node) { DRM_DEV_ERROR(dev, "fail to get internal panel.\n"); return -ENODEV; } - DRM_DEV_DEBUG_DRIVER(dev, "found dsi host node.\n"); + bus_type = 5; + mipi_lanes = MAX_LANES_SUPPORT; + ep0 = of_graph_get_endpoint_by_regs(np, 0, 0); + if (ep0) { + if (of_property_read_u32(ep0, "bus-type", &bus_type)) + bus_type = 0; + + mipi_lanes = of_property_count_u32_elems(ep0, "data-lanes"); + } + + if (bus_type == 5) /* bus type is Parallel(DSI) */ + pdata->is_dpi = 0; + + pdata->mipi_lanes = mipi_lanes; + if (pdata->mipi_lanes > MAX_LANES_SUPPORT || pdata->mipi_lanes <= 0) + pdata->mipi_lanes = MAX_LANES_SUPPORT; + + if (pdata->is_dpi) + DRM_DEV_DEBUG_DRIVER(dev, "found MIPI DPI host node.\n"); + else + DRM_DEV_DEBUG_DRIVER(dev, "found MIPI DSI host node.\n"); ret = drm_of_find_panel_or_bridge(np, 1, 0, &panel, NULL); if (ret < 0) { @@ -1273,9 +1385,13 @@ static enum drm_connector_status anx7625_sink_detect(struct anx7625_data *ctx) { struct device *dev = &ctx->client->dev; - DRM_DEV_DEBUG_DRIVER(dev, "sink detect, return connected\n"); + DRM_DEV_DEBUG_DRIVER(dev, "sink detect\n"); + + if (ctx->pdata.panel_bridge) + return connector_status_connected; - return connector_status_connected; + return ctx->hpd_status ? connector_status_connected : + connector_status_disconnected; } static int anx7625_attach_dsi(struct anx7625_data *ctx) @@ -1303,7 +1419,7 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx) return -EINVAL; } - dsi->lanes = 4; + dsi->lanes = ctx->pdata.mipi_lanes; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | @@ -1349,10 +1465,12 @@ static int anx7625_bridge_attach(struct drm_bridge *bridge, return -ENODEV; } - err = anx7625_attach_dsi(ctx); - if (err) { - DRM_DEV_ERROR(dev, "Fail to attach to dsi : %d\n", err); - return err; + if (!ctx->pdata.is_dpi) { + err = anx7625_attach_dsi(ctx); + if (err) { + DRM_DEV_ERROR(dev, "Fail to attach to dsi : %d\n", err); + return err; + } } if (ctx->pdata.panel_bridge) { @@ -1451,6 +1569,10 @@ static bool anx7625_bridge_mode_fixup(struct drm_bridge *bridge, DRM_DEV_DEBUG_DRIVER(dev, "drm mode fixup set\n"); + /* No need fixup for external monitor */ + if (!ctx->pdata.panel_bridge) + return true; + hsync = mode->hsync_end - mode->hsync_start; hfp = mode->hsync_start - mode->hdisplay; hbp = mode->htotal - mode->hsync_end; @@ -1827,8 +1949,13 @@ static int anx7625_i2c_probe(struct i2c_client *client, platform->bridge.funcs = &anx7625_bridge_funcs; platform->bridge.of_node = client->dev.of_node; - platform->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD; - platform->bridge.type = DRM_MODE_CONNECTOR_eDP; + platform->bridge.ops = DRM_BRIDGE_OP_EDID; + if (!platform->pdata.panel_bridge) + platform->bridge.ops |= DRM_BRIDGE_OP_HPD | + DRM_BRIDGE_OP_DETECT; + platform->bridge.type = platform->pdata.panel_bridge ? + DRM_MODE_CONNECTOR_eDP : + DRM_MODE_CONNECTOR_DisplayPort; drm_bridge_add(&platform->bridge); DRM_DEV_DEBUG_DRIVER(dev, "probe done\n"); diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index 034c3840028f..65db38e5da9a 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -141,12 +141,20 @@ #define HORIZONTAL_BACK_PORCH_H 0x22 /* Bit[7:4] are reserved */ /******** END of I2C Address 0x72 *********/ + +/***************************************************************/ +/* Register definition of device address 0x7a */ +#define DP_TX_SWING_REG_CNT 0x14 +#define DP_TX_LANE0_SWING_REG0 0x00 +#define DP_TX_LANE1_SWING_REG0 0x14 +/******** END of I2C Address 0x7a *********/ + /***************************************************************/ /* Register definition of device address 0x7e */ #define I2C_ADDR_7E_FLASH_CONTROLLER 0x7E -#define FLASH_LOAD_STA 0x05 +#define FLASH_LOAD_STA 0x05 #define FLASH_LOAD_STA_CHK BIT(7) #define XTAL_FRQ_SEL 0x3F @@ -347,12 +355,20 @@ struct s_edid_data { /***************** Display End *****************/ +#define MAX_LANES_SUPPORT 4 + struct anx7625_platform_data { struct gpio_desc *gpio_p_on; struct gpio_desc *gpio_reset; struct regulator_bulk_data supplies[3]; struct drm_bridge *panel_bridge; int intp_irq; + int is_dpi; + int mipi_lanes; + int dp_lane0_swing_reg_cnt; + int lane0_reg_data[DP_TX_SWING_REG_CNT]; + int dp_lane1_swing_reg_cnt; + int lane1_reg_data[DP_TX_SWING_REG_CNT]; u32 low_power_mode; struct device_node *mipi_host_node; }; -- 2.25.1