Received: by 10.223.148.5 with SMTP id 5csp6334147wrq; Wed, 17 Jan 2018 12:22:22 -0800 (PST) X-Google-Smtp-Source: ACJfBoucXFGsFwI697e7za4KudG4oGJK9+KJaITsNf+0j/9FudzdHwqgXeUUCyJhkwB3szhsJgYB X-Received: by 10.84.240.69 with SMTP id h5mr9504457plt.418.1516220542357; Wed, 17 Jan 2018 12:22:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516220542; cv=none; d=google.com; s=arc-20160816; b=lL9I+UYPobKYcqhstxZz7qLBCCnUrUXR1s4dT4YYzQaiCAY9TdHBEM55HqK+AVgFdn zapDUvl2ew7qPV7yUVuLkarsY67bD6bICnD0AJ8/BD94xWeqz1KIUAlgHsrparZAuXcj GZ2RbzSReA33MWV+INt6LWrL3EML5HgM5/4ALQXMKbItogLjfSmME5TS73ojintPxW/o gSgtEc7U8SYhef03SGzufI5XCJcma1MSfqvcjEdQbeu2XmTEebWc15CwqesTHStWocgi K+UgF0bFmYQIcS56jEtBufJQDstExQkO8RjLbnxQUkcT9Ppqh4cFISlCRpyddRxBcvD6 dljA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:spamdiagnosticmetadata :spamdiagnosticoutput:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=XwoQK8EcapP0hbn1awRI8EYZzwlZOVLQj5KawIMCzME=; b=DIY4rMwb2LvgAGgN0AFKK9eTXFTzKv+GR+LbJPU5F6zuT98JdGl6pb/m8ff0PfWyl6 v2W6VqgjE8jXZJY/xm8agJfafOfL5GM6YWf4Awx9DXsI0m7bJ8XoT1IyEMH596ejQwTR fj6NLGsTLHIf15Sp9JVnPbWwy2RFTVCMc/ql/H95PdpddPXMqKoTKVPqgjHutAaMVGch 30WGIUtiIW9Uk2HQ8avicZkGMhsoOFvucLZDw9jn3b3Krukeqn2+JfvLkSEAzk7B7asv vwRPLwUDO6ptxo515F4s92TD2NMhe/0/wSRlSjjCHThmxX81ayeZGplI4jZLffeGDexM EbSw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@xilinx.onmicrosoft.com header.s=selector1-xilinx-com header.b=gH/mNNXj; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p5si4461570pgn.197.2018.01.17.12.22.07; Wed, 17 Jan 2018 12:22:22 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@xilinx.onmicrosoft.com header.s=selector1-xilinx-com header.b=gH/mNNXj; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753148AbeAQUVX (ORCPT + 99 others); Wed, 17 Jan 2018 15:21:23 -0500 Received: from mail-sn1nam02on0072.outbound.protection.outlook.com ([104.47.36.72]:23728 "EHLO NAM02-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752891AbeAQUVQ (ORCPT ); Wed, 17 Jan 2018 15:21:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=xilinx.onmicrosoft.com; s=selector1-xilinx-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=XwoQK8EcapP0hbn1awRI8EYZzwlZOVLQj5KawIMCzME=; b=gH/mNNXjICB6H0WUdhcvJZiENfvZxdk4YJjoofhNzzgMAqN4pTixTBYRfOEkWYTUT+tsbTSU4FuzX6H5LFoqB+ACyGJkoESpyMx219NZ+cyY8ZIxdmeEy2EhfZqAyWvaG57NwQA6iA0c2YYx3MO7/+IcbI2rXVdJtCyFhUTAfLk= Received: from MWHPR0201CA0066.namprd02.prod.outlook.com (10.167.160.43) by SN1PR02MB1343.namprd02.prod.outlook.com (10.162.0.149) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.407.7; Wed, 17 Jan 2018 20:21:11 +0000 Received: from CY1NAM02FT004.eop-nam02.prod.protection.outlook.com (2a01:111:f400:7e45::208) by MWHPR0201CA0066.outlook.office365.com (2603:10b6:301:73::43) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.407.7 via Frontend Transport; Wed, 17 Jan 2018 20:21:10 +0000 Authentication-Results: spf=pass (sender IP is 149.199.60.83) smtp.mailfrom=xilinx.com; vger.kernel.org; dkim=none (message not signed) header.d=none;vger.kernel.org; dmarc=bestguesspass action=none header.from=xilinx.com; Received-SPF: Pass (protection.outlook.com: domain of xilinx.com designates 149.199.60.83 as permitted sender) receiver=protection.outlook.com; client-ip=149.199.60.83; helo=xsj-pvapsmtpgw01; Received: from xsj-pvapsmtpgw01 (149.199.60.83) by CY1NAM02FT004.mail.protection.outlook.com (10.152.74.112) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.428.12 via Frontend Transport; Wed, 17 Jan 2018 20:21:09 +0000 Received: from unknown-38-66.xilinx.com ([149.199.38.66] helo=xsj-pvapsmtp01) by xsj-pvapsmtpgw01 with esmtp (Exim 4.63) (envelope-from ) id 1ebuCq-00034B-A0; Wed, 17 Jan 2018 12:21:08 -0800 Received: from [127.0.0.1] (helo=localhost) by xsj-pvapsmtp01 with smtp (Exim 4.63) (envelope-from ) id 1ebuCq-0000qz-EV; Wed, 17 Jan 2018 12:21:08 -0800 Received: from xsj-pvapsmtp01 (smtp2.xilinx.com [149.199.38.66]) by xsj-smtp-dlp1.xlnx.xilinx.com (8.13.8/8.13.1) with ESMTP id w0HKKq6i017751; Wed, 17 Jan 2018 12:20:52 -0800 Received: from [172.19.2.91] (helo=xsjjollys50.xilinx.com) by xsj-pvapsmtp01 with esmtp (Exim 4.63) (envelope-from ) id 1ebuCa-0000nS-Bf; Wed, 17 Jan 2018 12:20:52 -0800 From: Jolly Shah To: , , , , , , , , , , CC: , , , , Jolly Shah Subject: [PATCH v2 2/4] drivers: firmware: xilinx: Add ZynqMP firmware driver Date: Wed, 17 Jan 2018 12:20:32 -0800 Message-ID: <1516220434-22204-3-git-send-email-jollys@xilinx.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516220434-22204-1-git-send-email-jollys@xilinx.com> References: <1516220434-22204-1-git-send-email-jollys@xilinx.com> X-RCIS-Action: ALLOW X-TM-AS-Product-Ver: IMSS-7.1.0.1224-8.2.0.1013-23600.005 X-TM-AS-User-Approved-Sender: Yes;Yes X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:149.199.60.83;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(396003)(39380400002)(39860400002)(346002)(376002)(2980300002)(438002)(199004)(189003)(37524003)(8676002)(478600001)(7416002)(356003)(72206003)(316002)(36386004)(2201001)(5890100001)(81156014)(63266004)(77096007)(305945005)(4326008)(39060400002)(76176011)(59450400001)(2906002)(107886003)(81166006)(50466002)(106002)(48376002)(5660300001)(7696005)(6666003)(9786002)(51416003)(53946003)(8936002)(2950100002)(36756003)(50226002)(54906003)(47776003)(110136005)(8746002)(26005)(106466001)(921003)(107986001)(1121003)(579004)(559001);DIR:OUT;SFP:1101;SCL:1;SRVR:SN1PR02MB1343;H:xsj-pvapsmtpgw01;FPR:;SPF:Pass;PTR:unknown-60-83.xilinx.com;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;CY1NAM02FT004;1:IJsKeLfo4DBj+4IBM8h1aoKK4CP/M+EN85u5ZuB9cFsI1VsBaZgimTNgYOwjXOKmME6MyZYBIi+oREFVmZA4YLsBem6bE60umYEewjMruV2DYFqOZtKipOSQKN7CMscJ MIME-Version: 1.0 Content-Type: text/plain X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 8ef1cd6f-f28b-4f98-0f71-08d55de7d90d X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(7020095)(4652020)(5600026)(4604075)(4608076)(2017052603307)(7153060);SRVR:SN1PR02MB1343; X-Microsoft-Exchange-Diagnostics: 1;SN1PR02MB1343;3:kJGqL1Wi8iGHMaOAEgmrNUMdepJRpeGaxjHtF2RV6rYe6FGFi1mOi4mOzJNG7/0Eunor7anDjydD6ARZEyGVJuJYIxOtrSHL+1Bgw7u5z20ecqaSkk9txo6TSu5DAYqNzItgm9ySzvEikPggQ+RCw7i5O9Z5FSUIFo5CjTOc+BStMwy5wW+wK9C44GTZwoBMOcAgo7THWTKw+vVDMNEx163hh/vMHDhkUfVgJ+UOeD40ZPGBWjMszXrVIfMcnN5EGL0eNWk/DfN6+F91DWXV7/l92vPpcUGjFhWyH2QeXjuTezz0Ya9Nf6BBl/6O9BMJvL5TO6eYgp5sXkQBqQv79NzKZulIV5kANul6QWzhYb4=;25:CCbEwpN4/oSVyy4s8pFMDs4hZAjdwqBhRoU2EPS0xIs3sJoo/I3rFSe2KH7cA5MSVrzz7XhJ/oQLJ/EbAU9XjqXhvij9/04uX5savgbJdT4FCARsyU9w/ZEirJBG0q0M2IphqHTp1UowNhPXvZAgQbntgkwyaVYqEwbHE60Ism+B74X8z4oU5oFjIs+Ph2XKRlrAAwmvZuvRU3JYONS2Uot/wBlwmswEheHQjSZKZ/gkuSljJjTrRxKZs7BL5Dwv4WmwOrEBkrF8V9DMD1oKq3uf6nRSCByoDiZjEZMryhTRcRhFfqk76R1EbsJxbBaSp/NpmzGawWMnebUmpAloIQ== X-MS-TrafficTypeDiagnostic: SN1PR02MB1343: X-Microsoft-Exchange-Diagnostics: 1;SN1PR02MB1343;31:HUVv2LgBpMcZTQrA3uOCij0Cekipzq4kUFQ+ii//bRBvZpnTYSh44Cq1mmgTnS4I1Ggkvs5q/vdaNTS9b8ULbAp/zVCinc43OzIG+R1K0/cX8H4ubkrg8y2nRsmWJQNm05nZkNFy7gFtPZC8PFPQojmLOwtyGSK67p8yttSwxuRd0CUx6iTy48P8kSZMnvtCHMFyM83yFsUH7/EzQQFonl44lGbQcD0rpoXq0BL7JNk=;20:y50xTl7/2ABXsd3tJvn0c8fQdryJlcl2LS9UEg1PTuIaL9WAFOxEzwdXJp9Rq9FmrhEkkMBUvffQS51izSOdGz4rmSmHRMfNyLRzzA9wl9ZtAyCVKELqMaFpn6T1IrOi22RsmU414FLi6gmB+08UjJKqup0uc8A4eY6yqV/dWRONUYwhxhlsLtV1sSzZ8x5/ygUzNrNAk+iz8ZvRH+zBgAcPPz/JZnCt2dOaEdz4V9mDHJW7DMd2qCCEQB5ss+PJ2oeGBgZ1RDmIN5tjXj1JKzNG0dFiKuwgKOi1efFHuyYX1Hue983lIEGv0+fIXLc43oJdcEkGqN19RyLzkYxYhNKEQTkChAjx0RSf0s351fqZ0diXEfivbwtcCaNZO6ika5M1xMOTGHvS8o0fk6tRpvL8fN+DrlLfbHUjhTFiwspX77s4TRN4tWSUQwezAK3/cJiqmAaVn3oXnpZ8OjNFKq3p9fOMRqFq/9Aq9XSuvvPqliReQ5ROIBW3ldBTfa8a Content-Transfer-Encoding: quoted-printable X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(192813158149592); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040470)(2401047)(8121501046)(5005006)(3002001)(10201501046)(93006095)(93004095)(3231023)(944501161)(6055026)(6041268)(20161123558120)(20161123560045)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(6072148)(201708071742011);SRVR:SN1PR02MB1343;BCL:0;PCL:0;RULEID:(100000803101)(100110400095);SRVR:SN1PR02MB1343; X-Microsoft-Exchange-Diagnostics: 1;SN1PR02MB1343;4:x3UwpIIEbJ30XILplWPtKKH6uM3WSU4l9zbZ0GQD10PVFrVuOeCYKm/0AqJ1yNVFDO4pYXrowY5qehhA6hMbqLTCa2IQWOs4OHF2VeZ4BevRl9MRcNyAZtT18F1aCRs8kC6FChfiaY8u5VSWSY87qvyby5JZT9Ir7Db8m1VZ3Z1Si7WlpN2rX/oyNo68pZBFMvhhxlVSoYXwxDteUdrK3BuHM/xlNlpavwSFuCaTYEX/xpIB3vjbeLuRfd6tX1svmJ6Vw8F1ek1R0xxtg8E+K6pbElGPZBHYqyMV3n8sz2awCNQtH9OT9Vow/iVr5goJ X-Forefront-PRVS: 0555EC8317 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;SN1PR02MB1343;23:pLVEZQydunjjeaw8TEum9fTcKTcp78aS3OmJsw/N/?= =?us-ascii?Q?YrrGPB1Arp7ifeEGmfPxFsb2jXzRpHLXFRTuLjqHq7v0/bD4ilx7Iq5TaNCa?= =?us-ascii?Q?Yx0q8HAvW0tX6rYZI7bRxHtYtBL91IYNlyvzLVsRnniNgH6xz16FV6Ijr6Go?= =?us-ascii?Q?AR47aeDH43Dflddm9EBFX8j/8LjacDO6DPWw4Q5wwXg4fHfXMSwln4XUB/KL?= =?us-ascii?Q?O9Qca/cfmT9yAYfUvmzDTrlDSphWCEcKPkcCzku8vETkI/qqh0/J3Z/2pLJg?= =?us-ascii?Q?kL76uiYSBG2VyJNcs+tiDwcQ7wk5R9SSJWoBWYN8SAXcpHxIb9tTDs6I1yfK?= =?us-ascii?Q?IggIdmrRbTXotME8Mpw8fcJxhRFW4n/vcXf5se35SDO72dpf+YVEyx635rBS?= =?us-ascii?Q?BG2UfEaSsCKld8C0uJ3MM0g6dgIeCRYgpksccSZi4Vv7NX1fzgvmygofoXnp?= =?us-ascii?Q?Vo4S13OXrydnMCZkQBmkv5rxEWfwpVZk0MpgPriLEZsi9UyFIdO4En7CNE1W?= =?us-ascii?Q?wFiD4pmk+x93zmun/mwFtO/vNh2ZB14/x+LQ0BQ++NSYm6KdG9xg6lzKriuZ?= =?us-ascii?Q?R3D85JF0kf9BYWDgKbr8sqZn6CibWe7oLF9ZlMQxlPm3Kga+WF9WTHI8Ysl+?= =?us-ascii?Q?zyq1MkPj214POMoNyiz97UQRCJvcXjkkpZf1O3FC76spYuMcecq+Z56To8E6?= =?us-ascii?Q?QrqYImx7o+O4JPTNsgmgrRriLNLSFLsHBTZtmYMZdCEAdsETTVpvj3LrSshr?= =?us-ascii?Q?3WneRqE15yHVn/+/Gt4KdohtHLWvsi76S+QX6vgjD4WXIWmwUruP1Kk880kC?= =?us-ascii?Q?cGms+Fi08PgyvMTIKSTybRdh4CBIVxdkGSi0cHwAG7Ijh3dWnGgb4yZTbkhJ?= =?us-ascii?Q?y2IPl58GKnwZyoHCQs2YnoUVCJDoYnFMMsojFT/RZTB+Z2FaY2IUXwyxy+aX?= =?us-ascii?Q?igRB5m066ANBODpBn9RvMQ3acyWFNV86JEJMHe/waceE9QJoOTb4iKk5Fv0x?= =?us-ascii?Q?MKihGVTlvkrQLMLJ8JSm/PCv65f80PHhWIgCRWARpOY/6+0R4usikFZqdxVM?= =?us-ascii?Q?zIa0fJpjaSy4OIjzuMsY3zxsYkDP5/EK8axYHnLZc2ve7wHnG365r0DMSMVR?= =?us-ascii?Q?IrgSxKa3X59QO9dbQJfoXJADIBPNbxqd2i7xU8ijA4N3123XKlFxn/IyKgt3?= =?us-ascii?Q?c7tKMU2QVluyViUym62daSShX46dAogxJ55Lun7CWa4mWxNEJmea8hmh1WBL?= =?us-ascii?Q?6sUqUVxxH0yw5LYqHE=3D?= X-Microsoft-Exchange-Diagnostics: 1;SN1PR02MB1343;6:gi2ZcPg6YbTYPZBNHnQOEYP0DhgXbrPEgLw1lcDklelkTrVvtLIeCDB8lIrRi5nF68+13zE4SPfFHNvz70KFf8n8or7Bale6jLn3oekXTJ4Q2TJHZTFkpd2r0OUR6ouPSkD0l9SK4cJRexY1Zbq6Gw9JYijb4suvOyyor5I+5qMO60xQr/nf+bAtIFwTp7M0mXDUwEI80mVN+ja8wkxuQeFEY5u9xiKQSokVSDO6YmPf5E7qX2dFAkIDXtF9nZtQm4CgVWnEdBVrh/2trF+RRGhCOXTf1G0f1tzIBwRTOd0s7YlBoawZAKSleRSu0B1w90TWN839AZepfVW/8sJlX3lWlI/MRBIv9HdbErQeDCc=;5:/ca5XGAYpYUut2A8tFp2FSuGUk8fPBBZl3VzDumYMAsDofYThRoGmBDLBH07LLgTvkUD8OWjCA/kxKsTdaNVX9MCcU1iHVkqQlyL1XN8IzDZ3nhFojukEWweO77/4STVUnXokQkTrs8ZYH0ljU3joYokbv53/FLDQ+EcTQtX5Cc=;24:+pLuWUmN2gXfU5Om6eZ8S2e04DoSdIqGCzPjZnWFuUmY+ieWF3DWCkJkaECDF45JaIZ2dCl8oj4HNcrU19ePxrub9szxbC7Uv4OxHiH76ko=;7:jShjMzsUH39RQzl6evqAOQ1vpcM7hUWdmKmKzDsutUrHnKeJaIPb3VzCZ/uHYyyyPYxX7pOOmytcwcjU9JgWKDqiXkfcf+AmmgxnAAFwdlV0OCEsGijiywpAkv0N8nIFPghPEGtTVfnyHPwL3tCPOdI2Eb5FPegc9zZc76N9gABMzbHDGh8EWRK1J5rxixiiJzAl83iq4mjw9JNYDNVrxomZDx5OIw3dFK7nTLSos55SML3loB0QeBR7BpIs30PB SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jan 2018 20:21:09.2195 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8ef1cd6f-f28b-4f98-0f71-08d55de7d90d X-MS-Exchange-CrossTenant-Id: 657af505-d5df-48d0-8300-c31994686c5c X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=657af505-d5df-48d0-8300-c31994686c5c;Ip=[149.199.60.83];Helo=[xsj-pvapsmtpgw01] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR02MB1343 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch is adding communication layer with firmware. Firmware driver provides an interface to firmware APIs. Interface APIs can be used by any driver to communicate to PMUFW(Platform Management Unit). All requests go through ATF. Signed-off-by: Jolly Shah Signed-off-by: Rajan Vaja --- arch/arm64/Kconfig.platforms | 1 + drivers/firmware/Kconfig | 1 + drivers/firmware/Makefile | 1 + drivers/firmware/xilinx/Kconfig | 4 + drivers/firmware/xilinx/Makefile | 4 + drivers/firmware/xilinx/zynqmp/Kconfig | 16 + drivers/firmware/xilinx/zynqmp/Makefile | 4 + drivers/firmware/xilinx/zynqmp/firmware.c | 987 ++++++++++++++++++++= ++++ include/linux/firmware/xilinx/zynqmp/firmware.h | 570 ++++++++++++++ 9 files changed, 1588 insertions(+) create mode 100644 drivers/firmware/xilinx/Kconfig create mode 100644 drivers/firmware/xilinx/Makefile create mode 100644 drivers/firmware/xilinx/zynqmp/Kconfig create mode 100644 drivers/firmware/xilinx/zynqmp/Makefile create mode 100644 drivers/firmware/xilinx/zynqmp/firmware.c create mode 100644 include/linux/firmware/xilinx/zynqmp/firmware.h diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 2401373..3dd3ae9 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -273,6 +273,7 @@ config ARCH_ZX config ARCH_ZYNQMP bool "Xilinx ZynqMP Family" + select ZYNQMP_FIRMWARE help This enables support for Xilinx ZynqMP Family diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index fa87a055..18fc2a8 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -249,5 +249,6 @@ source "drivers/firmware/google/Kconfig" source "drivers/firmware/efi/Kconfig" source "drivers/firmware/meson/Kconfig" source "drivers/firmware/tegra/Kconfig" +source "drivers/firmware/xilinx/Kconfig" endmenu diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index feaa890..43a24b5 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -30,3 +30,4 @@ obj-$(CONFIG_GOOGLE_FIRMWARE) +=3D google/ obj-$(CONFIG_EFI) +=3D efi/ obj-$(CONFIG_UEFI_CPER) +=3D efi/ obj-y +=3D tegra/ +obj-y +=3D xilinx/ diff --git a/drivers/firmware/xilinx/Kconfig b/drivers/firmware/xilinx/Kcon= fig new file mode 100644 index 0000000..eb4cdcf --- /dev/null +++ b/drivers/firmware/xilinx/Kconfig @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Kconfig for Xilinx firmwares + +source "drivers/firmware/xilinx/zynqmp/Kconfig" diff --git a/drivers/firmware/xilinx/Makefile b/drivers/firmware/xilinx/Mak= efile new file mode 100644 index 0000000..beff5dc --- /dev/null +++ b/drivers/firmware/xilinx/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Makefile for Xilinx firmwares + +obj-$(CONFIG_ARCH_ZYNQMP) +=3D zynqmp/ diff --git a/drivers/firmware/xilinx/zynqmp/Kconfig b/drivers/firmware/xili= nx/zynqmp/Kconfig new file mode 100644 index 0000000..8f7709d --- /dev/null +++ b/drivers/firmware/xilinx/zynqmp/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Kconfig for Xilinx zynqmp firmware + +menu "Zynq MPSoC Firmware Drivers" + depends on ARCH_ZYNQMP + +config ZYNQMP_FIRMWARE + bool "Enable Xilinx Zynq MPSoC firmware interface" + help + Firmware interface driver is used by different to + communicate with the firmware for various platform + management services. + Say yes to enable zynqmp firmware interface driver. + In doubt, say N + +endmenu diff --git a/drivers/firmware/xilinx/zynqmp/Makefile b/drivers/firmware/xil= inx/zynqmp/Makefile new file mode 100644 index 0000000..c3ec669 --- /dev/null +++ b/drivers/firmware/xilinx/zynqmp/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Makefile for Xilinx firmwares + +obj-$(CONFIG_ZYNQMP_FIRMWARE) +=3D firmware.o diff --git a/drivers/firmware/xilinx/zynqmp/firmware.c b/drivers/firmware/x= ilinx/zynqmp/firmware.c new file mode 100644 index 0000000..8ebacb6 --- /dev/null +++ b/drivers/firmware/xilinx/zynqmp/firmware.c @@ -0,0 +1,987 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Xilinx Zynq MPSoC Firmware layer + * + * Copyright (C) 2014-2018 Xilinx, Inc. + * + * Michal Simek + * Davorin Mista + * Jolly Shah + * Rajan Vaja + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * zynqmp_pm_ret_code - Convert PMU-FW error codes to Linux error codes + * @ret_status: PMUFW return code + * + * Return: corresponding Linux error code + */ +int zynqmp_pm_ret_code(u32 ret_status) +{ + switch (ret_status) { + case XST_PM_SUCCESS: + case XST_PM_DOUBLE_REQ: + return 0; + case XST_PM_NO_ACCESS: + return -EACCES; + case XST_PM_ABORT_SUSPEND: + return -ECANCELED; + case XST_PM_INTERNAL: + case XST_PM_CONFLICT: + case XST_PM_INVALID_NODE: + default: + return -EINVAL; + } +} + +static noinline int do_fw_call_fail(u64 arg0, u64 arg1, u64 arg2, + u32 *ret_payload) +{ + return -ENODEV; +} + +/* + * PM function call wrapper + * Invoke do_fw_call_smc or do_fw_call_hvc, depending on the configuration + */ +static int (*do_fw_call)(u64, u64, u64, u32 *ret_payload) =3D do_fw_call_f= ail; + +/** + * do_fw_call_smc - Call system-level power management layer (SMC) + * @arg0: Argument 0 to SMC call + * @arg1: Argument 1 to SMC call + * @arg2: Argument 2 to SMC call + * @ret_payload: Returned value array + * + * Return: Returns status, either success or error+reason + * + * Invoke power management function via SMC call (no hypervisor present) + */ +static noinline int do_fw_call_smc(u64 arg0, u64 arg1, u64 arg2, + u32 *ret_payload) +{ + struct arm_smccc_res res; + + arm_smccc_smc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res); + + if (ret_payload) { + ret_payload[0] =3D lower_32_bits(res.a0); + ret_payload[1] =3D upper_32_bits(res.a0); + ret_payload[2] =3D lower_32_bits(res.a1); + ret_payload[3] =3D upper_32_bits(res.a1); + ret_payload[4] =3D lower_32_bits(res.a2); + } + + return zynqmp_pm_ret_code((enum pm_ret_status)res.a0); +} + +/** + * do_fw_call_hvc - Call system-level power management layer (HVC) + * @arg0: Argument 0 to HVC call + * @arg1: Argument 1 to HVC call + * @arg2: Argument 2 to HVC call + * @ret_payload: Returned value array + * + * Return: Returns status, either success or error+reason + * + * Invoke power management function via HVC + * HVC-based for communication through hypervisor + * (no direct communication with ATF) + */ +static noinline int do_fw_call_hvc(u64 arg0, u64 arg1, u64 arg2, + u32 *ret_payload) +{ + struct arm_smccc_res res; + + arm_smccc_hvc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res); + + if (ret_payload) { + ret_payload[0] =3D lower_32_bits(res.a0); + ret_payload[1] =3D upper_32_bits(res.a0); + ret_payload[2] =3D lower_32_bits(res.a1); + ret_payload[3] =3D upper_32_bits(res.a1); + ret_payload[4] =3D lower_32_bits(res.a2); + } + + return zynqmp_pm_ret_code((enum pm_ret_status)res.a0); +} + +/** + * invoke_pm_fn - Invoke the system-level power management layer caller + * function depending on the configuration + * @pm_api_id: Requested PM-API call + * @arg0: Argument 0 to requested PM-API call + * @arg1: Argument 1 to requested PM-API call + * @arg2: Argument 2 to requested PM-API call + * @arg3: Argument 3 to requested PM-API call + * @ret_payload: Returned value array + * + * Return: Returns status, either success or error+reason + * + * Invoke power management function for SMC or HVC call, depending on + * configuration + * Following SMC Calling Convention (SMCCC) for SMC64: + * Pm Function Identifier, + * PM_SIP_SVC + PM_API_ID =3D + * ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) + * ((SMC_64) << FUNCID_CC_SHIFT) + * ((SIP_START) << FUNCID_OEN_SHIFT) + * ((PM_API_ID) & FUNCID_NUM_MASK)) + * + * PM_SIP_SVC - Registered ZynqMP SIP Service Call + * PM_API_ID - Power Management API ID + */ +int invoke_pm_fn(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3, + u32 *ret_payload) +{ + /* + * Added SIP service call Function Identifier + * Make sure to stay in x0 register + */ + u64 smc_arg[4]; + + smc_arg[0] =3D PM_SIP_SVC | pm_api_id; + smc_arg[1] =3D ((u64)arg1 << 32) | arg0; + smc_arg[2] =3D ((u64)arg3 << 32) | arg2; + + return do_fw_call(smc_arg[0], smc_arg[1], smc_arg[2], ret_payload); +} + +static u32 pm_api_version; + +/** + * zynqmp_pm_get_api_version - Get version number of PMU PM firmware + * @version: Returned version value + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_get_api_version(u32 *version) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + + if (!version) + return zynqmp_pm_ret_code(XST_PM_CONFLICT); + + /* Check is PM API version already verified */ + if (pm_api_version > 0) { + *version =3D pm_api_version; + return XST_PM_SUCCESS; + } + invoke_pm_fn(PM_GET_API_VERSION, 0, 0, 0, 0, ret_payload); + *version =3D ret_payload[1]; + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_get_chipid - Get silicon ID registers + * @idcode: IDCODE register + * @version: version register + * + * Return: Returns the status of the operation and the idcode and vers= ion + * registers in @idcode and @version. + */ +static int zynqmp_pm_get_chipid(u32 *idcode, u32 *version) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + + if (!idcode || !version) + return -EINVAL; + + invoke_pm_fn(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload); + *idcode =3D ret_payload[1]; + *version =3D ret_payload[2]; + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * get_set_conduit_method - Choose SMC or HVC based communication + * @np: Pointer to the device_node structure + * + * Use SMC or HVC-based functions to communicate with EL2/EL3 + */ +static int get_set_conduit_method(struct device_node *np) +{ + const char *method; + + if (of_property_read_string(np, "method", &method)) { + pr_warn("%s missing \"method\" property\n", __func__); + return -ENXIO; + } + + if (!strcmp("hvc", method)) { + do_fw_call =3D do_fw_call_hvc; + } else if (!strcmp("smc", method)) { + do_fw_call =3D do_fw_call_smc; + } else { + pr_warn("%s Invalid \"method\" property: %s\n", + __func__, method); + return -EINVAL; + } + + return 0; +} + +/** + * zynqmp_pm_reset_assert - Request setting of reset (1 - assert, 0 - rele= ase) + * @reset: Reset to be configured + * @assert_flag: Flag stating should reset be asserted (1) or + * released (0) + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset, + const enum zynqmp_pm_reset_action assert_flag) +{ + return invoke_pm_fn(PM_RESET_ASSERT, reset, assert_flag, 0, 0, NULL= ); +} + +/** + * zynqmp_pm_reset_get_status - Get status of the reset + * @reset: Reset whose status should be returned + * @status: Returned status + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, + u32 *status) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + + if (!status) + return zynqmp_pm_ret_code(XST_PM_CONFLICT); + + invoke_pm_fn(PM_RESET_GET_STATUS, reset, 0, 0, 0, ret_payload); + *status =3D ret_payload[1]; + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_fpga_load - Perform the fpga load + * @address: Address to write to + * @size: pl bitstream size + * @flags: + * BIT(0) - Bit-stream type. + * 0 - Full Bit-stream. + * 1 - Partial Bit-stream. + * BIT(1) - Authentication. + * 1 - Enable. + * 0 - Disable. + * BIT(2) - Encryption. + * 1 - Enable. + * 0 - Disable. + * NOTE - + * The current implementation supports only Full Bit-stream. + * + * This function provides access to xilfpga library to transfer + * the required bitstream into PL. + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_fpga_load(const u64 address, const u32 size, + const u32 flags) +{ + return invoke_pm_fn(PM_FPGA_LOAD, (u32)address, + ((u32)(address >> 32)), size, flags, NULL); +} + +/** + * zynqmp_pm_fpga_get_status - Read value from PCAP status register + * @value: Value to read + * + *This function provides access to the xilfpga library to get + *the PCAP status + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_fpga_get_status(u32 *value) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + + if (!value) + return -EINVAL; + + invoke_pm_fn(PM_FPGA_GET_STATUS, 0, 0, 0, 0, ret_payload); + *value =3D ret_payload[1]; + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_request_suspend - PM call to request for another PU or subsys= tem to + * be suspended gracefully. + * @node: Node ID of the targeted PU or subsystem + * @ack: Flag to specify whether acknowledge is requested + * @latency: Requested wakeup latency (not supported) + * @state: Requested state (not supported) + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_request_suspend(const u32 node, + const enum zynqmp_pm_request_ack ack, + const u32 latency, + const u32 state) +{ + return invoke_pm_fn(PM_REQUEST_SUSPEND, node, ack, + latency, state, NULL); +} + +/** + * zynqmp_pm_force_powerdown - PM call to request for another PU or subsys= tem to + * be powered down forcefully + * @target: Node ID of the targeted PU or subsystem + * @ack: Flag to specify whether acknowledge is requested + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_force_powerdown(const u32 target, + const enum zynqmp_pm_request_ack ack) +{ + return invoke_pm_fn(PM_FORCE_POWERDOWN, target, ack, 0, 0, NULL); +} + +/** + * zynqmp_pm_request_wakeup - PM call to wake up selected master or subsys= tem + * @node: Node ID of the master or subsystem + * @set_addr: Specifies whether the address argument is relevant + * @address: Address from which to resume when woken up + * @ack: Flag to specify whether acknowledge requested + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_request_wakeup(const u32 node, + const bool set_addr, + const u64 address, + const enum zynqmp_pm_request_ack ack) +{ + /* set_addr flag is encoded into 1st bit of address */ + return invoke_pm_fn(PM_REQUEST_WAKEUP, node, address | set_addr, + address >> 32, ack, NULL); +} + +/** + * zynqmp_pm_set_wakeup_source - PM call to specify the wakeup source + * while suspended + * @target: Node ID of the targeted PU or subsystem + * @wakeup_node:Node ID of the wakeup peripheral + * @enable: Enable or disable the specified peripheral as wake source + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_set_wakeup_source(const u32 target, + const u32 wakeup_node, + const u32 enable) +{ + return invoke_pm_fn(PM_SET_WAKEUP_SOURCE, target, + wakeup_node, enable, 0, NULL); +} + +/** + * zynqmp_pm_system_shutdown - PM call to request a system shutdown or res= tart + * @type: Shutdown or restart? 0 for shutdown, 1 for restart + * @subtype: Specifies which system should be restarted or shut down + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype) +{ + return invoke_pm_fn(PM_SYSTEM_SHUTDOWN, type, subtype, 0, 0, NULL); +} + +/** + * zynqmp_pm_request_node - PM call to request a node with specific capabi= lities + * @node: Node ID of the slave + * @capabilities: Requested capabilities of the slave + * @qos: Quality of service (not supported) + * @ack: Flag to specify whether acknowledge is requested + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_request_node(const u32 node, const u32 capabilities, + const u32 qos, + const enum zynqmp_pm_request_ack ack) +{ + return invoke_pm_fn(PM_REQUEST_NODE, node, capabilities, + qos, ack, NULL); +} + +/** + * zynqmp_pm_release_node - PM call to release a node + * @node: Node ID of the slave + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_release_node(const u32 node) +{ + return invoke_pm_fn(PM_RELEASE_NODE, node, 0, 0, 0, NULL); +} + +/** + * zynqmp_pm_set_requirement - PM call to set requirement for PM slaves + * @node: Node ID of the slave + * @capabilities: Requested capabilities of the slave + * @qos: Quality of service (not supported) + * @ack: Flag to specify whether acknowledge is requested + * + * This API function is to be used for slaves a PU already has requested + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilitie= s, + const u32 qos, + const enum zynqmp_pm_request_ack ack) +{ + return invoke_pm_fn(PM_SET_REQUIREMENT, node, capabilities, + qos, ack, NULL); +} + +/** + * zynqmp_pm_set_max_latency - PM call to set wakeup latency requirements + * @node: Node ID of the slave + * @latency: Requested maximum wakeup latency + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_set_max_latency(const u32 node, const u32 latency) +{ + return invoke_pm_fn(PM_SET_MAX_LATENCY, node, latency, 0, 0, NULL); +} + +/** + * zynqmp_pm_set_configuration - PM call to set system configuration + * @physical_addr: Physical 32-bit address of data structure in memory + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_set_configuration(const u32 physical_addr) +{ + return invoke_pm_fn(PM_SET_CONFIGURATION, physical_addr, 0, 0, 0, N= ULL); +} + +/** + * zynqmp_pm_get_node_status - PM call to request a node's current power s= tate + * @node: ID of the component or sub-system in question + * @status: Current operating state of the requested node + * @requirements: Current requirements asserted on the node, + * used for slave nodes only. + * @usage: Usage information, used for slave nodes only: + * 0 - No master is currently using the node + * 1 - Only requesting master is currently using the n= ode + * 2 - Only other masters are currently using the node + * 3 - Both the current and at least one other master + * is currently using the node + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_get_node_status(const u32 node, u32 *const status, + u32 *const requirements, u32 *const us= age) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + + if (!status) + return -EINVAL; + + invoke_pm_fn(PM_GET_NODE_STATUS, node, 0, 0, 0, ret_payload); + if (ret_payload[0] =3D=3D XST_PM_SUCCESS) { + *status =3D ret_payload[1]; + if (requirements) + *requirements =3D ret_payload[2]; + if (usage) + *usage =3D ret_payload[3]; + } + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_get_operating_characteristic - PM call to request operating + * characteristic information + * @node: Node ID of the slave + * @type: Type of the operating characteristic requested + * @result: Used to return the requsted operating characteristic + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_get_operating_characteristic(const u32 node, + const enum zynqmp_pm_opchar= _type + type, u32 *const result) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + + if (!result) + return -EINVAL; + + invoke_pm_fn(PM_GET_OPERATING_CHARACTERISTIC, + node, type, 0, 0, ret_payload); + if (ret_payload[0] =3D=3D XST_PM_SUCCESS) + *result =3D ret_payload[1]; + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_init_finalize - PM call to informi firmware that the caller m= aster + * has initialized its own power management + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_init_finalize(void) +{ + return invoke_pm_fn(PM_PM_INIT_FINALIZE, 0, 0, 0, 0, NULL); +} + +/** + * zynqmp_pm_get_callback_data - Get callback data from firmware + * @buf: Buffer to store payload data + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_get_callback_data(u32 *buf) +{ + return invoke_pm_fn(PM_GET_CALLBACK_DATA, 0, 0, 0, 0, buf); +} + +/** + * zynqmp_pm_set_suspend_mode - Set system suspend mode + * + * @mode: Mode to set for system suspend + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_set_suspend_mode(u32 mode) +{ + return invoke_pm_fn(PM_SET_SUSPEND_MODE, mode, 0, 0, 0, NULL); +} + +/** + * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash + * @address: Address of the data/ Address of output buffer where + * hash should be stored. + * @size: Size of the data. + * @flags: + * BIT(0) - Sha3 init (Here address and size inputs can be NULL) + * BIT(1) - Sha3 update (address should holds the ) + * BIT(2) - Sha3 final (address should hold the address of + * buffer to store hash) + * + * Return: Returns status, either success or error code. + */ +static int zynqmp_pm_sha_hash(const u64 address, const u32 size, + const u32 flags) +{ + u32 lower_32_bits =3D (u32)address; + u32 upper_32_bits =3D (u32)(address >> 32); + + return invoke_pm_fn(PM_SECURE_SHA, upper_32_bits, lower_32_bits, + size, flags, NULL); +} + +/** + * zynqmp_pm_rsa - Access RSA hardware to encrypt/decrypt the data with RS= A. + * @address: Address of the data + * @size: Size of the data. + * @flags: + * BIT(0) - Encryption/Decryption + * 0 - RSA decryption with private key + * 1 - RSA encryption with public key. + * + * Return: Returns status, either success or error code. + */ +static int zynqmp_pm_rsa(const u64 address, const u32 size, const u32 flag= s) +{ + u32 lower_32_bits =3D (u32)address; + u32 upper_32_bits =3D (u32)(address >> 32); + + return invoke_pm_fn(PM_SECURE_RSA, upper_32_bits, lower_32_bits, + size, flags, NULL); +} + +/** + * zynqmp_pm_pinctrl_request - Request Pin from firmware + * @pin: Pin number to request + * + * This function requests pin from firmware. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_pinctrl_request(const u32 pin) +{ + return invoke_pm_fn(PM_PINCTRL_REQUEST, pin, 0, 0, 0, NULL); +} + +/** + * zynqmp_pm_pinctrl_release - Inform firmware that Pin control is release= d + * @pin: Pin number to release + * + * This function release pin from firmware. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_pinctrl_release(const u32 pin) +{ + return invoke_pm_fn(PM_PINCTRL_RELEASE, pin, 0, 0, 0, NULL); +} + +/** + * zynqmp_pm_pinctrl_get_function() - Read function id set for the given p= in + * @pin: Pin number + * @node: Buffer to store node ID matching current function + * + * This function provides the function currently set for the given pin. + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_pinctrl_get_function(const u32 pin, u32 *node) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + + if (!node) + return -EINVAL; + + invoke_pm_fn(PM_PINCTRL_GET_FUNCTION, pin, 0, 0, 0, ret_payload); + *node =3D ret_payload[1]; + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_pinctrl_set_function - Set requested function for the pin + * @pin: Pin number + * @node: Node ID mapped with the requested function + * + * This function sets requested function for the given pin. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_pinctrl_set_function(const u32 pin, const u32 node) +{ + return invoke_pm_fn(PM_PINCTRL_SET_FUNCTION, pin, node, 0, 0, NULL)= ; +} + +/** + * zynqmp_pm_pinctrl_get_config - Get configuration parameter for the pin + * @pin: Pin number + * @param: Parameter to get + * @value: Buffer to store parameter value + * + * This function gets requested configuration parameter for the given pin. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_pinctrl_get_config(const u32 pin, const u32 param, + u32 *value) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + + if (!value) + return -EINVAL; + + invoke_pm_fn(PM_PINCTRL_CONFIG_PARAM_GET, pin, + param, 0, 0, ret_payload); + *value =3D ret_payload[1]; + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_pinctrl_set_config - Set configuration parameter for the pin + * @pin: Pin number + * @param: Parameter to set + * @value: Parameter value to set + * + * This function sets requested configuration parameter for the given pin. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param, + u32 value) +{ + return invoke_pm_fn(PM_PINCTRL_CONFIG_PARAM_SET, pin, + param, value, 0, NULL); +} + +/** + * zynqmp_pm_ioctl - PM IOCTL API for device control and configs + * @node_id: Node ID of the device + * @ioctl_id: ID of the requested IOCTL + * @arg1: Argument 1 to requested IOCTL call + * @arg2: Argument 2 to requested IOCTL call + * @out: Returned output value + * + * This function calls IOCTL to firmware for device control and configurat= ion. + */ +static int zynqmp_pm_ioctl(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, + u32 *out) +{ + return invoke_pm_fn(PM_IOCTL, node_id, ioctl_id, arg1, arg2, out); +} + +static int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *ou= t) +{ + return invoke_pm_fn(PM_QUERY_DATA, qdata.qid, qdata.arg1, + qdata.arg2, qdata.arg3, out); +} + +/** + * zynqmp_pm_clock_enable - Enable the clock for given id + * @clock_id: ID of the clock to be enabled + * + * This function is used by master to enable the clock + * including peripherals and PLL clocks. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_enable(u32 clock_id) +{ + return invoke_pm_fn(PM_CLOCK_ENABLE, clock_id, 0, 0, 0, NULL); +} + +/** + * zynqmp_pm_clock_disable - Disable the clock for given id + * @clock_id: ID of the clock to be disable + * + * This function is used by master to disable the clock + * including peripherals and PLL clocks. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_disable(u32 clock_id) +{ + return invoke_pm_fn(PM_CLOCK_DISABLE, clock_id, 0, 0, 0, NULL); +} + +/** + * zynqmp_pm_clock_getstate - Get the clock state for given id + * @clock_id: ID of the clock to be queried + * @state: 1/0 (Enabled/Disabled) + * + * This function is used by master to get the state of clock + * including peripherals and PLL clocks. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_getstate(u32 clock_id, u32 *state) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + + invoke_pm_fn(PM_CLOCK_GETSTATE, clock_id, 0, 0, 0, ret_payload); + *state =3D ret_payload[1]; + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_clock_setdivider - Set the clock divider for given id + * @clock_id: ID of the clock + * @div_type: TYPE_DIV1: div1 + * TYPE_DIV2: div2 + * @divider: divider value. + * + * This function is used by master to set divider for any clock + * to achieve desired rate. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_setdivider(u32 clock_id, u32 divider) +{ + return invoke_pm_fn(PM_CLOCK_SETDIVIDER, clock_id, divider, 0, 0, N= ULL); +} + +/** + * zynqmp_pm_clock_getdivider - Get the clock divider for given id + * @clock_id: ID of the clock + * @div_type: TYPE_DIV1: div1 + * TYPE_DIV2: div2 + * @divider: divider value. + * + * This function is used by master to get divider values + * for any clock. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_getdivider(u32 clock_id, u32 *divider) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + + invoke_pm_fn(PM_CLOCK_GETDIVIDER, clock_id, 0, 0, 0, ret_payload); + *divider =3D ret_payload[1]; + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_clock_setrate - Set the clock rate for given id + * @clock_id: ID of the clock + * @rate: rate value in hz + * + * This function is used by master to set rate for any clock. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_setrate(u32 clock_id, u32 rate) +{ + return invoke_pm_fn(PM_CLOCK_SETRATE, clock_id, rate, 0, 0, NULL); +} + +/** + * zynqmp_pm_clock_getrate - Get the clock rate for given id + * @clock_id: ID of the clock + * @rate: rate value in hz + * + * This function is used by master to get rate + * for any clock. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_getrate(u32 clock_id, u32 *rate) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + + invoke_pm_fn(PM_CLOCK_GETRATE, clock_id, 0, 0, 0, ret_payload); + *rate =3D ret_payload[1]; + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_clock_setparent - Set the clock parent for given id + * @clock_id: ID of the clock + * @parent_id: parent id + * + * This function is used by master to set parent for any clock. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_setparent(u32 clock_id, u32 parent_id) +{ + return invoke_pm_fn(PM_CLOCK_SETPARENT, clock_id, + parent_id, 0, 0, NULL); +} + +/** + * zynqmp_pm_clock_getparent - Get the clock parent for given id + * @clock_id: ID of the clock + * @parent_id: parent id + * + * This function is used by master to get parent index + * for any clock. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_getparent(u32 clock_id, u32 *parent_id) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + + invoke_pm_fn(PM_CLOCK_GETPARENT, clock_id, 0, 0, 0, ret_payload); + *parent_id =3D ret_payload[1]; + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +static const struct zynqmp_eemi_ops eemi_ops =3D { + .get_api_version =3D zynqmp_pm_get_api_version, + .get_chipid =3D zynqmp_pm_get_chipid, + .reset_assert =3D zynqmp_pm_reset_assert, + .reset_get_status =3D zynqmp_pm_reset_get_status, + .fpga_load =3D zynqmp_pm_fpga_load, + .fpga_get_status =3D zynqmp_pm_fpga_get_status, + .sha_hash =3D zynqmp_pm_sha_hash, + .rsa =3D zynqmp_pm_rsa, + .request_suspend =3D zynqmp_pm_request_suspend, + .force_powerdown =3D zynqmp_pm_force_powerdown, + .request_wakeup =3D zynqmp_pm_request_wakeup, + .set_wakeup_source =3D zynqmp_pm_set_wakeup_source, + .system_shutdown =3D zynqmp_pm_system_shutdown, + .request_node =3D zynqmp_pm_request_node, + .release_node =3D zynqmp_pm_release_node, + .set_requirement =3D zynqmp_pm_set_requirement, + .set_max_latency =3D zynqmp_pm_set_max_latency, + .set_configuration =3D zynqmp_pm_set_configuration, + .get_node_status =3D zynqmp_pm_get_node_status, + .get_operating_characteristic =3D zynqmp_pm_get_operating_character= istic, + .init_finalize =3D zynqmp_pm_init_finalize, + .get_callback_data =3D zynqmp_pm_get_callback_data, + .set_suspend_mode =3D zynqmp_pm_set_suspend_mode, + .ioctl =3D zynqmp_pm_ioctl, + .query_data =3D zynqmp_pm_query_data, + .pinctrl_request =3D zynqmp_pm_pinctrl_request, + .pinctrl_release =3D zynqmp_pm_pinctrl_release, + .pinctrl_get_function =3D zynqmp_pm_pinctrl_get_function, + .pinctrl_set_function =3D zynqmp_pm_pinctrl_set_function, + .pinctrl_get_config =3D zynqmp_pm_pinctrl_get_config, + .pinctrl_set_config =3D zynqmp_pm_pinctrl_set_config, + .clock_enable =3D zynqmp_pm_clock_enable, + .clock_disable =3D zynqmp_pm_clock_disable, + .clock_getstate =3D zynqmp_pm_clock_getstate, + .clock_setdivider =3D zynqmp_pm_clock_setdivider, + .clock_getdivider =3D zynqmp_pm_clock_getdivider, + .clock_setrate =3D zynqmp_pm_clock_setrate, + .clock_getrate =3D zynqmp_pm_clock_getrate, + .clock_setparent =3D zynqmp_pm_clock_setparent, + .clock_getparent =3D zynqmp_pm_clock_getparent, +}; + +/** + * get_eemi_ops - Get eemi ops functions + * + * Return: - pointer of eemi_ops structure + */ +const struct zynqmp_eemi_ops *get_eemi_ops(void) +{ + return &eemi_ops; +} +EXPORT_SYMBOL_GPL(get_eemi_ops); + +static int __init zynqmp_plat_init(void) +{ + struct device_node *np; + int ret =3D 0; + + np =3D of_find_compatible_node(NULL, NULL, "xlnx,zynqmp"); + if (!np) + return 0; + of_node_put(np); + + /* We're running on a ZynqMP machine, the PM node is mandatory. */ + np =3D of_find_compatible_node(NULL, NULL, "xlnx,zynqmp-firmware"); + if (!np) { + pr_warn("%s: pm node not found\n", __func__); + return -ENXIO; + } + + ret =3D get_set_conduit_method(np); + if (ret) { + of_node_put(np); + return ret; + } + + /* Check PM API version number */ + zynqmp_pm_get_api_version(&pm_api_version); + if (pm_api_version !=3D ZYNQMP_PM_VERSION) { + panic("%s power management API version error. Expected: v%d= .%d - Found: v%d.%d\n", + __func__, + ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR, + pm_api_version >> 16, pm_api_version & 0xffff); + } + + pr_info("%s Power management API v%d.%d\n", __func__, + ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR); + + of_node_put(np); + + return ret; +} + +early_initcall(zynqmp_plat_init); diff --git a/include/linux/firmware/xilinx/zynqmp/firmware.h b/include/linu= x/firmware/xilinx/zynqmp/firmware.h new file mode 100644 index 0000000..42d6e74 --- /dev/null +++ b/include/linux/firmware/xilinx/zynqmp/firmware.h @@ -0,0 +1,570 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Xilinx Zynq MPSoC Firmware layer + * + * Copyright (C) 2014-2018 Xilinx + * + * Michal Simek + * Davorin Mista + * Jolly Shah + * Rajan Vaja + */ + +#ifndef __SOC_ZYNQMP_FIRMWARE_H__ +#define __SOC_ZYNQMP_FIRMWARE_H__ + +#include + +#define ZYNQMP_PM_VERSION_MAJOR 1 +#define ZYNQMP_PM_VERSION_MINOR 0 + +#define ZYNQMP_PM_VERSION ((ZYNQMP_PM_VERSION_MAJOR << 16) | \ + ZYNQMP_PM_VERSION_MINOR) + +#define ZYNQMP_PM_MAX_LATENCY (~0U) +#define ZYNQMP_PM_MAX_QOS 100U + +/* SMC SIP service Call Function Identifier Prefix */ +#define PM_SIP_SVC 0xC2000000 +#define PM_GET_CALLBACK_DATA 0xa01 +#define PM_SET_SUSPEND_MODE 0xa02 + +/* Number of 32bits values in payload */ +#define PAYLOAD_ARG_CNT 5U + +/* Number of arguments for a callback */ +#define CB_ARG_CNT 4 + +/* Payload size (consists of callback API ID + arguments) */ +#define CB_PAYLOAD_SIZE (CB_ARG_CNT + 1) + +/* Global general storage register base address */ +#define GGS_BASEADDR (0xFFD80030U) +#define GSS_NUM_REGS (4) + +/* Persistent global general storage register base address */ +#define PGGS_BASEADDR (0xFFD80050U) +#define PGSS_NUM_REGS (4) + +/* Capabilities for RAM */ +#define ZYNQMP_PM_CAPABILITY_ACCESS 0x1U +#define ZYNQMP_PM_CAPABILITY_CONTEXT 0x2U +#define ZYNQMP_PM_CAPABILITY_WAKEUP 0x4U +#define ZYNQMP_PM_CAPABILITY_POWER 0x8U + +/* Clock APIs payload parameters */ +#define CLK_GET_NAME_RESP_LEN 16 +#define CLK_GET_TOPOLOGY_RESP_WORDS 3 +#define CLK_GET_FIXEDFACTOR_RESP_WORDS 2 +#define CLK_GET_PARENTS_RESP_WORDS 3 +#define CLK_GET_ATTR_RESP_WORDS 1 + +enum pm_api_id { + /* Miscellaneous API functions: */ + PM_GET_API_VERSION =3D 1, + PM_SET_CONFIGURATION, + PM_GET_NODE_STATUS, + PM_GET_OPERATING_CHARACTERISTIC, + PM_REGISTER_NOTIFIER, + /* API for suspending of PUs: */ + PM_REQUEST_SUSPEND, + PM_SELF_SUSPEND, + PM_FORCE_POWERDOWN, + PM_ABORT_SUSPEND, + PM_REQUEST_WAKEUP, + PM_SET_WAKEUP_SOURCE, + PM_SYSTEM_SHUTDOWN, + /* API for managing PM slaves: */ + PM_REQUEST_NODE, + PM_RELEASE_NODE, + PM_SET_REQUIREMENT, + PM_SET_MAX_LATENCY, + /* Direct control API functions: */ + PM_RESET_ASSERT, + PM_RESET_GET_STATUS, + PM_MMIO_WRITE, + PM_MMIO_READ, + PM_PM_INIT_FINALIZE, + PM_FPGA_LOAD, + PM_FPGA_GET_STATUS, + PM_GET_CHIPID, + /* ID 25 is been used by U-boot to process secure boot images */ + /* Secure library generic API functions */ + PM_SECURE_SHA =3D 26, + PM_SECURE_RSA, + /* Pin control API functions */ + PM_PINCTRL_REQUEST, + PM_PINCTRL_RELEASE, + PM_PINCTRL_GET_FUNCTION, + PM_PINCTRL_SET_FUNCTION, + PM_PINCTRL_CONFIG_PARAM_GET, + PM_PINCTRL_CONFIG_PARAM_SET, + /* PM IOCTL API */ + PM_IOCTL, + /* API to query information from firmware */ + PM_QUERY_DATA, + /* Clock control API functions */ + PM_CLOCK_ENABLE, + PM_CLOCK_DISABLE, + PM_CLOCK_GETSTATE, + PM_CLOCK_SETDIVIDER, + PM_CLOCK_GETDIVIDER, + PM_CLOCK_SETRATE, + PM_CLOCK_GETRATE, + PM_CLOCK_SETPARENT, + PM_CLOCK_GETPARENT, +}; + +/* PMU-FW return status codes */ +enum pm_ret_status { + XST_PM_SUCCESS =3D 0, + XST_PM_INTERNAL =3D 2000, + XST_PM_CONFLICT, + XST_PM_NO_ACCESS, + XST_PM_INVALID_NODE, + XST_PM_DOUBLE_REQ, + XST_PM_ABORT_SUSPEND, +}; + +enum zynqmp_pm_reset_action { + PM_RESET_ACTION_RELEASE, + PM_RESET_ACTION_ASSERT, + PM_RESET_ACTION_PULSE, +}; + +enum zynqmp_pm_reset { + ZYNQMP_PM_RESET_START =3D 999, + ZYNQMP_PM_RESET_PCIE_CFG, + ZYNQMP_PM_RESET_PCIE_BRIDGE, + ZYNQMP_PM_RESET_PCIE_CTRL, + ZYNQMP_PM_RESET_DP, + ZYNQMP_PM_RESET_SWDT_CRF, + ZYNQMP_PM_RESET_AFI_FM5, + ZYNQMP_PM_RESET_AFI_FM4, + ZYNQMP_PM_RESET_AFI_FM3, + ZYNQMP_PM_RESET_AFI_FM2, + ZYNQMP_PM_RESET_AFI_FM1, + ZYNQMP_PM_RESET_AFI_FM0, + ZYNQMP_PM_RESET_GDMA, + ZYNQMP_PM_RESET_GPU_PP1, + ZYNQMP_PM_RESET_GPU_PP0, + ZYNQMP_PM_RESET_GPU, + ZYNQMP_PM_RESET_GT, + ZYNQMP_PM_RESET_SATA, + ZYNQMP_PM_RESET_ACPU3_PWRON, + ZYNQMP_PM_RESET_ACPU2_PWRON, + ZYNQMP_PM_RESET_ACPU1_PWRON, + ZYNQMP_PM_RESET_ACPU0_PWRON, + ZYNQMP_PM_RESET_APU_L2, + ZYNQMP_PM_RESET_ACPU3, + ZYNQMP_PM_RESET_ACPU2, + ZYNQMP_PM_RESET_ACPU1, + ZYNQMP_PM_RESET_ACPU0, + ZYNQMP_PM_RESET_DDR, + ZYNQMP_PM_RESET_APM_FPD, + ZYNQMP_PM_RESET_SOFT, + ZYNQMP_PM_RESET_GEM0, + ZYNQMP_PM_RESET_GEM1, + ZYNQMP_PM_RESET_GEM2, + ZYNQMP_PM_RESET_GEM3, + ZYNQMP_PM_RESET_QSPI, + ZYNQMP_PM_RESET_UART0, + ZYNQMP_PM_RESET_UART1, + ZYNQMP_PM_RESET_SPI0, + ZYNQMP_PM_RESET_SPI1, + ZYNQMP_PM_RESET_SDIO0, + ZYNQMP_PM_RESET_SDIO1, + ZYNQMP_PM_RESET_CAN0, + ZYNQMP_PM_RESET_CAN1, + ZYNQMP_PM_RESET_I2C0, + ZYNQMP_PM_RESET_I2C1, + ZYNQMP_PM_RESET_TTC0, + ZYNQMP_PM_RESET_TTC1, + ZYNQMP_PM_RESET_TTC2, + ZYNQMP_PM_RESET_TTC3, + ZYNQMP_PM_RESET_SWDT_CRL, + ZYNQMP_PM_RESET_NAND, + ZYNQMP_PM_RESET_ADMA, + ZYNQMP_PM_RESET_GPIO, + ZYNQMP_PM_RESET_IOU_CC, + ZYNQMP_PM_RESET_TIMESTAMP, + ZYNQMP_PM_RESET_RPU_R50, + ZYNQMP_PM_RESET_RPU_R51, + ZYNQMP_PM_RESET_RPU_AMBA, + ZYNQMP_PM_RESET_OCM, + ZYNQMP_PM_RESET_RPU_PGE, + ZYNQMP_PM_RESET_USB0_CORERESET, + ZYNQMP_PM_RESET_USB1_CORERESET, + ZYNQMP_PM_RESET_USB0_HIBERRESET, + ZYNQMP_PM_RESET_USB1_HIBERRESET, + ZYNQMP_PM_RESET_USB0_APB, + ZYNQMP_PM_RESET_USB1_APB, + ZYNQMP_PM_RESET_IPI, + ZYNQMP_PM_RESET_APM_LPD, + ZYNQMP_PM_RESET_RTC, + ZYNQMP_PM_RESET_SYSMON, + ZYNQMP_PM_RESET_AFI_FM6, + ZYNQMP_PM_RESET_LPD_SWDT, + ZYNQMP_PM_RESET_FPD, + ZYNQMP_PM_RESET_RPU_DBG1, + ZYNQMP_PM_RESET_RPU_DBG0, + ZYNQMP_PM_RESET_DBG_LPD, + ZYNQMP_PM_RESET_DBG_FPD, + ZYNQMP_PM_RESET_APLL, + ZYNQMP_PM_RESET_DPLL, + ZYNQMP_PM_RESET_VPLL, + ZYNQMP_PM_RESET_IOPLL, + ZYNQMP_PM_RESET_RPLL, + ZYNQMP_PM_RESET_GPO3_PL_0, + ZYNQMP_PM_RESET_GPO3_PL_1, + ZYNQMP_PM_RESET_GPO3_PL_2, + ZYNQMP_PM_RESET_GPO3_PL_3, + ZYNQMP_PM_RESET_GPO3_PL_4, + ZYNQMP_PM_RESET_GPO3_PL_5, + ZYNQMP_PM_RESET_GPO3_PL_6, + ZYNQMP_PM_RESET_GPO3_PL_7, + ZYNQMP_PM_RESET_GPO3_PL_8, + ZYNQMP_PM_RESET_GPO3_PL_9, + ZYNQMP_PM_RESET_GPO3_PL_10, + ZYNQMP_PM_RESET_GPO3_PL_11, + ZYNQMP_PM_RESET_GPO3_PL_12, + ZYNQMP_PM_RESET_GPO3_PL_13, + ZYNQMP_PM_RESET_GPO3_PL_14, + ZYNQMP_PM_RESET_GPO3_PL_15, + ZYNQMP_PM_RESET_GPO3_PL_16, + ZYNQMP_PM_RESET_GPO3_PL_17, + ZYNQMP_PM_RESET_GPO3_PL_18, + ZYNQMP_PM_RESET_GPO3_PL_19, + ZYNQMP_PM_RESET_GPO3_PL_20, + ZYNQMP_PM_RESET_GPO3_PL_21, + ZYNQMP_PM_RESET_GPO3_PL_22, + ZYNQMP_PM_RESET_GPO3_PL_23, + ZYNQMP_PM_RESET_GPO3_PL_24, + ZYNQMP_PM_RESET_GPO3_PL_25, + ZYNQMP_PM_RESET_GPO3_PL_26, + ZYNQMP_PM_RESET_GPO3_PL_27, + ZYNQMP_PM_RESET_GPO3_PL_28, + ZYNQMP_PM_RESET_GPO3_PL_29, + ZYNQMP_PM_RESET_GPO3_PL_30, + ZYNQMP_PM_RESET_GPO3_PL_31, + ZYNQMP_PM_RESET_RPU_LS, + ZYNQMP_PM_RESET_PS_ONLY, + ZYNQMP_PM_RESET_PL, + ZYNQMP_PM_RESET_END +}; + +enum zynqmp_pm_request_ack { + ZYNQMP_PM_REQUEST_ACK_NO =3D 1, + ZYNQMP_PM_REQUEST_ACK_BLOCKING, + ZYNQMP_PM_REQUEST_ACK_NON_BLOCKING, +}; + +enum zynqmp_pm_abort_reason { + ZYNQMP_PM_ABORT_REASON_WAKEUP_EVENT =3D 100, + ZYNQMP_PM_ABORT_REASON_POWER_UNIT_BUSY, + ZYNQMP_PM_ABORT_REASON_NO_POWERDOWN, + ZYNQMP_PM_ABORT_REASON_UNKNOWN, +}; + +enum zynqmp_pm_suspend_reason { + ZYNQMP_PM_SUSPEND_REASON_POWER_UNIT_REQUEST =3D 201, + ZYNQMP_PM_SUSPEND_REASON_ALERT, + ZYNQMP_PM_SUSPEND_REASON_SYSTEM_SHUTDOWN, +}; + +enum zynqmp_pm_ram_state { + ZYNQMP_PM_RAM_STATE_OFF =3D 1, + ZYNQMP_PM_RAM_STATE_RETENTION, + ZYNQMP_PM_RAM_STATE_ON, +}; + +enum zynqmp_pm_opchar_type { + ZYNQMP_PM_OPERATING_CHARACTERISTIC_POWER =3D 1, + ZYNQMP_PM_OPERATING_CHARACTERISTIC_ENERGY, + ZYNQMP_PM_OPERATING_CHARACTERISTIC_TEMPERATURE, +}; + +enum pm_node_id { + NODE_UNKNOWN =3D 0, + NODE_APU, + NODE_APU_0, + NODE_APU_1, + NODE_APU_2, + NODE_APU_3, + NODE_RPU, + NODE_RPU_0, + NODE_RPU_1, + NODE_PLD, + NODE_FPD, + NODE_OCM_BANK_0, + NODE_OCM_BANK_1, + NODE_OCM_BANK_2, + NODE_OCM_BANK_3, + NODE_TCM_0_A, + NODE_TCM_0_B, + NODE_TCM_1_A, + NODE_TCM_1_B, + NODE_L2, + NODE_GPU_PP_0, + NODE_GPU_PP_1, + NODE_USB_0, + NODE_USB_1, + NODE_TTC_0, + NODE_TTC_1, + NODE_TTC_2, + NODE_TTC_3, + NODE_SATA, + NODE_ETH_0, + NODE_ETH_1, + NODE_ETH_2, + NODE_ETH_3, + NODE_UART_0, + NODE_UART_1, + NODE_SPI_0, + NODE_SPI_1, + NODE_I2C_0, + NODE_I2C_1, + NODE_SD_0, + NODE_SD_1, + NODE_DP, + NODE_GDMA, + NODE_ADMA, + NODE_NAND, + NODE_QSPI, + NODE_GPIO, + NODE_CAN_0, + NODE_CAN_1, + NODE_EXTERN, + NODE_APLL, + NODE_VPLL, + NODE_DPLL, + NODE_RPLL, + NODE_IOPLL, + NODE_DDR, + NODE_IPI_APU, + NODE_IPI_RPU_0, + NODE_GPU, + NODE_PCIE, + NODE_PCAP, + NODE_RTC, + NODE_LPD, + NODE_VCU, + NODE_IPI_RPU_1, + NODE_IPI_PL_0, + NODE_IPI_PL_1, + NODE_IPI_PL_2, + NODE_IPI_PL_3, + NODE_PL, + NODE_GEM_TSU, + NODE_SWDT_0, + NODE_SWDT_1, + NODE_CSU, + NODE_PJTAG, + NODE_TRACE, + NODE_TESTSCAN, + NODE_PMU, + NODE_MAX, +}; + +enum pm_pinctrl_config_param { + PM_PINCTRL_CONFIG_SLEW_RATE, + PM_PINCTRL_CONFIG_BIAS_STATUS, + PM_PINCTRL_CONFIG_PULL_CTRL, + PM_PINCTRL_CONFIG_SCHMITT_CMOS, + PM_PINCTRL_CONFIG_DRIVE_STRENGTH, + PM_PINCTRL_CONFIG_VOLTAGE_STATUS, + PM_PINCTRL_CONFIG_MAX, +}; + +enum pm_pinctrl_slew_rate { + PM_PINCTRL_SLEW_RATE_FAST, + PM_PINCTRL_SLEW_RATE_SLOW, +}; + +enum pm_pinctrl_bias_status { + PM_PINCTRL_BIAS_DISABLE, + PM_PINCTRL_BIAS_ENABLE, +}; + +enum pm_pinctrl_pull_ctrl { + PM_PINCTRL_BIAS_PULL_DOWN, + PM_PINCTRL_BIAS_PULL_UP, +}; + +enum pm_pinctrl_schmitt_cmos { + PM_PINCTRL_INPUT_TYPE_CMOS, + PM_PINCTRL_INPUT_TYPE_SCHMITT, +}; + +enum pm_pinctrl_drive_strength { + PM_PINCTRL_DRIVE_STRENGTH_2MA, + PM_PINCTRL_DRIVE_STRENGTH_4MA, + PM_PINCTRL_DRIVE_STRENGTH_8MA, + PM_PINCTRL_DRIVE_STRENGTH_12MA, +}; + +enum pm_ioctl_id { + IOCTL_GET_RPU_OPER_MODE, + IOCTL_SET_RPU_OPER_MODE, + IOCTL_RPU_BOOT_ADDR_CONFIG, + IOCTL_TCM_COMB_CONFIG, + IOCTL_SET_TAPDELAY_BYPASS, + IOCTL_SET_SGMII_MODE, + IOCTL_SD_DLL_RESET, + IOCTL_SET_SD_TAPDELAY, + /* Ioctl for clock driver */ + IOCTL_SET_PLL_FRAC_MODE, + IOCTL_GET_PLL_FRAC_MODE, + IOCTL_SET_PLL_FRAC_DATA, + IOCTL_GET_PLL_FRAC_DATA, + IOCTL_WRITE_GGS, + IOCTL_READ_GGS, + IOCTL_WRITE_PGGS, + IOCTL_READ_PGGS, +}; + +enum rpu_oper_mode { + PM_RPU_MODE_LOCKSTEP, + PM_RPU_MODE_SPLIT, +}; + +enum rpu_boot_mem { + PM_RPU_BOOTMEM_LOVEC, + PM_RPU_BOOTMEM_HIVEC, +}; + +enum rpu_tcm_comb { + PM_RPU_TCM_SPLIT, + PM_RPU_TCM_COMB, +}; + +enum tap_delay_signal_type { + PM_TAPDELAY_NAND_DQS_IN, + PM_TAPDELAY_NAND_DQS_OUT, + PM_TAPDELAY_QSPI, + PM_TAPDELAY_MAX, +}; + +enum tap_delay_bypass_ctrl { + PM_TAPDELAY_BYPASS_DISABLE, + PM_TAPDELAY_BYPASS_ENABLE, +}; + +enum sgmii_mode { + PM_SGMII_DISABLE, + PM_SGMII_ENABLE, +}; + +enum tap_delay_type { + PM_TAPDELAY_INPUT, + PM_TAPDELAY_OUTPUT, +}; + +enum dll_reset_type { + PM_DLL_RESET_ASSERT, + PM_DLL_RESET_RELEASE, + PM_DLL_RESET_PULSE, +}; + +enum topology_type { + TYPE_INVALID, + TYPE_MUX, + TYPE_PLL, + TYPE_FIXEDFACTOR, + TYPE_DIV1, + TYPE_DIV2, + TYPE_GATE, +}; + +enum pm_query_id { + PM_QID_INVALID, + PM_QID_CLOCK_GET_NAME, + PM_QID_CLOCK_GET_TOPOLOGY, + PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS, + PM_QID_CLOCK_GET_PARENTS, + PM_QID_CLOCK_GET_ATTRIBUTES, +}; + +struct zynqmp_pm_query_data { + u32 qid; + u32 arg1; + u32 arg2; + u32 arg3; +}; + +struct zynqmp_eemi_ops { + int (*get_api_version)(u32 *version); + int (*get_chipid)(u32 *idcode, u32 *version); + int (*reset_assert)(const enum zynqmp_pm_reset reset, + const enum zynqmp_pm_reset_action assert_flag); + int (*reset_get_status)(const enum zynqmp_pm_reset reset, u32 *stat= us); + int (*fpga_load)(const u64 address, const u32 size, const u32 flags= ); + int (*fpga_get_status)(u32 *value); + int (*sha_hash)(const u64 address, const u32 size, const u32 flags)= ; + int (*rsa)(const u64 address, const u32 size, const u32 flags); + int (*request_suspend)(const u32 node, + const enum zynqmp_pm_request_ack ack, + const u32 latency, + const u32 state); + int (*force_powerdown)(const u32 target, + const enum zynqmp_pm_request_ack ack); + int (*request_wakeup)(const u32 node, + const bool set_addr, + const u64 address, + const enum zynqmp_pm_request_ack ack); + int (*set_wakeup_source)(const u32 target, + const u32 wakeup_node, + const u32 enable); + int (*system_shutdown)(const u32 type, const u32 subtype); + int (*request_node)(const u32 node, + const u32 capabilities, + const u32 qos, + const enum zynqmp_pm_request_ack ack); + int (*release_node)(const u32 node); + int (*set_requirement)(const u32 node, + const u32 capabilities, + const u32 qos, + const enum zynqmp_pm_request_ack ack); + int (*set_max_latency)(const u32 node, const u32 latency); + int (*set_configuration)(const u32 physical_addr); + int (*get_node_status)(const u32 node, u32 *const status, + u32 *const requirements, u32 *const usage); + int (*get_operating_characteristic)(const u32 node, + const enum zynqmp_pm_opchar_typ= e + type, u32 *const result); + int (*init_finalize)(void); + int (*get_callback_data)(u32 *buf); + int (*set_suspend_mode)(u32 mode); + int (*ioctl)(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, u32 *ou= t); + int (*query_data)(struct zynqmp_pm_query_data qdata, u32 *out); + int (*pinctrl_request)(const u32 pin); + int (*pinctrl_release)(const u32 pin); + int (*pinctrl_get_function)(const u32 pin, u32 *node); + int (*pinctrl_set_function)(const u32 pin, const u32 node); + int (*pinctrl_get_config)(const u32 pin, const u32 param, u32 *valu= e); + int (*pinctrl_set_config)(const u32 pin, const u32 param, u32 value= ); + int (*clock_enable)(u32 clock_id); + int (*clock_disable)(u32 clock_id); + int (*clock_getstate)(u32 clock_id, u32 *state); + int (*clock_setdivider)(u32 clock_id, u32 divider); + int (*clock_getdivider)(u32 clock_id, u32 *divider); + int (*clock_setrate)(u32 clock_id, u32 rate); + int (*clock_getrate)(u32 clock_id, u32 *rate); + int (*clock_setparent)(u32 clock_id, u32 parent_id); + int (*clock_getparent)(u32 clock_id, u32 *parent_id); +}; + +/* + * Internal functions + */ +int invoke_pm_fn(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3, + u32 *ret_payload); +int zynqmp_pm_ret_code(u32 ret_status); + +#if IS_REACHABLE(CONFIG_ARCH_ZYNQMP) +const struct zynqmp_eemi_ops *get_eemi_ops(void); +#else +static inline struct zynqmp_eemi_ops *get_eemi_ops(void) { return NULL; } +#endif + +#endif /* __SOC_ZYNQMP_FIRMWARE_H__ */ -- 2.7.4 This email and any attachments are intended for the sole use of the named r= ecipient(s) and contain(s) confidential information that may be proprietary= , privileged or copyrighted under applicable law. If you are not the intend= ed recipient, do not read, copy, or forward this email message or any attac= hments. Delete this email message and any attachments immediately.