From patchwork Sun Jun 16 13:29:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Masney X-Patchwork-Id: 10997447 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 718381398 for ; Sun, 16 Jun 2019 14:03:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 62317286E2 for ; Sun, 16 Jun 2019 14:03:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 56BF8286EE; Sun, 16 Jun 2019 14:03:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0BF27286E2 for ; Sun, 16 Jun 2019 14:03:13 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 515D289262; Sun, 16 Jun 2019 14:02:44 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from onstation.org (onstation.org [52.200.56.107]) by gabe.freedesktop.org (Postfix) with ESMTPS id 65DDC89127; Sun, 16 Jun 2019 13:29:47 +0000 (UTC) Received: from localhost.localdomain (c-98-239-145-235.hsd1.wv.comcast.net [98.239.145.235]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: masneyb) by onstation.org (Postfix) with ESMTPSA id 004503E9CF; Sun, 16 Jun 2019 13:29:45 +0000 (UTC) From: Brian Masney To: agross@kernel.org, david.brown@linaro.org, robdclark@gmail.com, sean@poorly.run, robh+dt@kernel.org Subject: [PATCH 1/6] dt-bindings: soc: qcom: add On Chip MEMory (OCMEM) bindings Date: Sun, 16 Jun 2019 09:29:25 -0400 Message-Id: <20190616132930.6942-2-masneyb@onstation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190616132930.6942-1-masneyb@onstation.org> References: <20190616132930.6942-1-masneyb@onstation.org> MIME-Version: 1.0 X-Mailman-Approved-At: Sun, 16 Jun 2019 14:01:48 +0000 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=onstation.org; s=default; t=1560691786; bh=irgUB032exacl9EYA4xT+dfR2io7zD/c3uZsKSwgy5I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OYoKc4HqpLshtGnVB7kd7XWU+6L07I0PT7ssQvmpyTma5MSXOAKSCL5arcC1EkP2b kW8jRyta7vpWqvCWgs+Mz2uBN+4/uRtnYDwtp5kmGhz98EawK7u4C7x0c1JopNbB8t +VUAh/E/+yeAG/TQP09owKC+zqjKpLrb0Eyd6BYc= X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, jonathan@marek.ca, airlied@linux.ie, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, bjorn.andersson@linaro.org, freedreno@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add device tree bindings for the On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs. Signed-off-by: Brian Masney --- .../bindings/soc/qcom/qcom,ocmem.yaml | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,ocmem.yaml diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,ocmem.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,ocmem.yaml new file mode 100644 index 000000000000..5e3ae6311a16 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,ocmem.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/qcom/qcom,ocmem.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs. + +maintainers: + - Brian Masney + +description: | + The On Chip Memory (OCMEM) allocator allows various clients to allocate memory + from OCMEM based on performance, latency and power requirements. This is + typically used by the GPU, camera/video, and audio components on some + Snapdragon SoCs. + +properties: + compatible: + const: qcom,ocmem-msm8974 + + reg: + items: + - description: Control registers + - description: OCMEM address range + + reg-names: + items: + - const: ocmem_ctrl_physical + - const: ocmem_physical + + clocks: + items: + - description: Core clock + - description: Interface clock + + clock-names: + items: + - const: core + - const: iface + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + +examples: + - | + #include + #include + + ocmem: ocmem@fdd00000 { + compatible = "qcom,ocmem-msm8974"; + + reg = <0xfdd00000 0x2000>, + <0xfec00000 0x180000>; + reg-names = "ocmem_ctrl_physical", + "ocmem_physical"; + + clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, + <&mmcc OCMEMCX_OCMEMNOC_CLK>; + clock-names = "core", + "iface"; + }; From patchwork Sun Jun 16 13:29:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Masney X-Patchwork-Id: 10997459 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3F62114B6 for ; Sun, 16 Jun 2019 14:03:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 31137286E2 for ; Sun, 16 Jun 2019 14:03:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2564E286EE; Sun, 16 Jun 2019 14:03:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CC6D8286E2 for ; Sun, 16 Jun 2019 14:03:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4DFF4892DE; Sun, 16 Jun 2019 14:02:50 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from onstation.org (onstation.org [52.200.56.107]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7C8528917E; Sun, 16 Jun 2019 13:29:47 +0000 (UTC) Received: from localhost.localdomain (c-98-239-145-235.hsd1.wv.comcast.net [98.239.145.235]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: masneyb) by onstation.org (Postfix) with ESMTPSA id 74C163EA08; Sun, 16 Jun 2019 13:29:46 +0000 (UTC) From: Brian Masney To: agross@kernel.org, david.brown@linaro.org, robdclark@gmail.com, sean@poorly.run, robh+dt@kernel.org Subject: [PATCH 2/6] dt-bindings: display: msm: gmu: add optional ocmem property Date: Sun, 16 Jun 2019 09:29:26 -0400 Message-Id: <20190616132930.6942-3-masneyb@onstation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190616132930.6942-1-masneyb@onstation.org> References: <20190616132930.6942-1-masneyb@onstation.org> MIME-Version: 1.0 X-Mailman-Approved-At: Sun, 16 Jun 2019 14:01:48 +0000 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=onstation.org; s=default; t=1560691786; bh=9la9rGA+VNucWpe2JoLlGvFG3lx2LubbW/TmbFF+fH8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VU+cpI9z+k+iSfXw3RgNYJ3yBU9flQoNiqpnn/h4j8WT9/myas6AvUvMr9XovJtvX sYUrXdS8e1UwLv1w8Zl9VJockEuMLCI964F/PYRJd9Yz/fcfgixS9pCqkQl5PLXZQg 6d+vi9MagZ0qsRSZrIaCRslvPSHJGFIxTH/6NMAA= X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, jonathan@marek.ca, airlied@linux.ie, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, bjorn.andersson@linaro.org, freedreno@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Some A3xx and A4xx Adreno GPUs do not have GMEM inside the GPU core and must use the On Chip MEMory (OCMEM) in order to be functional. Add the optional ocmem property to the Adreno Graphics Management Unit bindings. Signed-off-by: Brian Masney --- Documentation/devicetree/bindings/display/msm/gmu.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/gmu.txt b/Documentation/devicetree/bindings/display/msm/gmu.txt index 90af5b0a56a9..c746b95e95d4 100644 --- a/Documentation/devicetree/bindings/display/msm/gmu.txt +++ b/Documentation/devicetree/bindings/display/msm/gmu.txt @@ -31,6 +31,10 @@ Required properties: - iommus: phandle to the adreno iommu - operating-points-v2: phandle to the OPP operating points +Optional properties: +- ocmem: phandle to the On Chip Memory (OCMEM) that's present on some Snapdragon + SoCs. See Documentation/devicetree/bindings/soc/qcom/qcom,ocmem.yaml. + Example: / { From patchwork Sun Jun 16 13:29:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Masney X-Patchwork-Id: 10997453 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 43C1E14B6 for ; Sun, 16 Jun 2019 14:03:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3251A286EC for ; Sun, 16 Jun 2019 14:03:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2663528714; Sun, 16 Jun 2019 14:03:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B049A286EC for ; Sun, 16 Jun 2019 14:03:21 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2BD09892A6; Sun, 16 Jun 2019 14:02:48 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from onstation.org (onstation.org [52.200.56.107]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3DF97890D2; Sun, 16 Jun 2019 13:29:48 +0000 (UTC) Received: from localhost.localdomain (c-98-239-145-235.hsd1.wv.comcast.net [98.239.145.235]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: masneyb) by onstation.org (Postfix) with ESMTPSA id EAA6B3EA09; Sun, 16 Jun 2019 13:29:46 +0000 (UTC) From: Brian Masney To: agross@kernel.org, david.brown@linaro.org, robdclark@gmail.com, sean@poorly.run, robh+dt@kernel.org Subject: [PATCH 3/6] firmware: qcom: scm: add support to restore secure config Date: Sun, 16 Jun 2019 09:29:27 -0400 Message-Id: <20190616132930.6942-4-masneyb@onstation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190616132930.6942-1-masneyb@onstation.org> References: <20190616132930.6942-1-masneyb@onstation.org> MIME-Version: 1.0 X-Mailman-Approved-At: Sun, 16 Jun 2019 14:01:48 +0000 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=onstation.org; s=default; t=1560691787; bh=IvihjvxJrpflaZx8L6IactS1thBLIM/+BYBN9VVX/oE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HK+XvpQX8trVvroDCRyK56lSu0KgsbaSsefd8SPk6qv2oMdAFMXfbUyMfNib26j4j nR3xOCe7NlhD1i2stlnjDRV6YYC+v0g7j9/p5E0CRb5II9FczIo1iWUkekdtszh5St cWXKBCCNfXmWw9JasfMm9MguyjZ1CxEU2JwDG410= X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, jonathan@marek.ca, airlied@linux.ie, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, bjorn.andersson@linaro.org, freedreno@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Rob Clark Add support to restore the secure configuration that is needed by the On Chip MEMory (OCMEM) that is present on some Snapdragon devices. Signed-off-by: Rob Clark [masneyb@onstation.org: ported to latest kernel; minor reformatting.] Signed-off-by: Brian Masney --- Rob's last version of this patch: https://patchwork.kernel.org/patch/7340701/ drivers/firmware/qcom_scm-32.c | 21 +++++++++++++++++++++ drivers/firmware/qcom_scm-64.c | 6 ++++++ drivers/firmware/qcom_scm.c | 23 +++++++++++++++++++++++ drivers/firmware/qcom_scm.h | 6 ++++++ include/linux/qcom_scm.h | 13 +++++++++++++ 5 files changed, 69 insertions(+) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 215061c581e1..089b47124933 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -442,6 +442,27 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, req, req_cnt * sizeof(*req), resp, sizeof(*resp)); } +int __qcom_scm_restore_sec_config(struct device *dev, u32 sec_id, + u32 ctx_bank_num) +{ + struct msm_scm_sec_cfg { + __le32 id; + __le32 ctx_bank_num; + } cfg; + int ret, scm_ret = 0; + + cfg.id = cpu_to_le32(sec_id); + cfg.ctx_bank_num = cpu_to_le32(sec_id); + + ret = qcom_scm_call(dev, QCOM_SCM_MP_SVC, QCOM_SCM_MP_RESTORE_SEC_CFG, + &cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret)); + + if (ret || scm_ret) + return ret ? ret : -EINVAL; + + return 0; +} + void __qcom_scm_init(void) { } diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 91d5ad7cf58b..b6b78da7f9c9 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -241,6 +241,12 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, return ret; } +int __qcom_scm_restore_sec_config(struct device *dev, u32 sec_id, + u32 ctx_bank_num) +{ + return -ENOTSUPP; +} + void __qcom_scm_init(void) { u64 cmd; diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 2ddc118dba1b..5495ef994c5d 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -170,6 +170,29 @@ int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) } EXPORT_SYMBOL(qcom_scm_hdcp_req); +/** + * qcom_scm_restore_sec_config_available() - Check if secure environment + * supports restore security config interface. + * + * Return true if restore-cfg interface is supported, false if not. + */ +bool qcom_scm_restore_sec_config_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_MP_SVC, + QCOM_SCM_MP_RESTORE_SEC_CFG); +} +EXPORT_SYMBOL(qcom_scm_restore_sec_config_available); + +/** + * qcom_scm_restore_sec_config() - call restore-cfg interface + */ +int qcom_scm_restore_sec_config(struct device *dev, + enum qcom_scm_sec_dev_id sec_id) +{ + return __qcom_scm_restore_sec_config(dev, sec_id, 0); +} +EXPORT_SYMBOL(qcom_scm_restore_sec_config); + /** * qcom_scm_pas_supported() - Check if the peripheral authentication service is * available for the given peripherial diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 99506bd873c0..bccc7d10c5c2 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -42,6 +42,12 @@ extern int __qcom_scm_hdcp_req(struct device *dev, extern void __qcom_scm_init(void); +#define QCOM_SCM_MP_SVC 0xc +#define QCOM_SCM_MP_RESTORE_SEC_CFG 0x2 + +extern int __qcom_scm_restore_sec_config(struct device *dev, u32 sec_id, + u32 ctx_bank_num); + #define QCOM_SCM_SVC_PIL 0x2 #define QCOM_SCM_PAS_INIT_IMAGE_CMD 0x1 #define QCOM_SCM_PAS_MEM_SETUP_CMD 0x2 diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 3f12cc77fb58..b5c0afaca955 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -24,6 +24,16 @@ struct qcom_scm_vmperm { int perm; }; +enum qcom_scm_sec_dev_id { + QCOM_SCM_MDSS_DEV_ID = 1, + QCOM_SCM_OCMEM_DEV_ID = 5, + QCOM_SCM_PCIE0_DEV_ID = 11, + QCOM_SCM_PCIE1_DEV_ID = 12, + QCOM_SCM_GFX_DEV_ID = 18, + QCOM_SCM_UFS_DEV_ID = 19, + QCOM_SCM_ICE_DEV_ID = 20, +}; + #define QCOM_SCM_VMID_HLOS 0x3 #define QCOM_SCM_VMID_MSS_MSA 0xF #define QCOM_SCM_VMID_WLAN 0x18 @@ -41,6 +51,9 @@ extern bool qcom_scm_is_available(void); extern bool qcom_scm_hdcp_available(void); extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp); +extern bool qcom_scm_restore_sec_config_available(void); +extern int qcom_scm_restore_sec_config(struct device *dev, + enum qcom_scm_sec_dev_id sec_id); extern bool qcom_scm_pas_supported(u32 peripheral); extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size); From patchwork Sun Jun 16 13:29:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Masney X-Patchwork-Id: 10997431 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0F6E414C0 for ; Sun, 16 Jun 2019 14:02:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F3702286E2 for ; Sun, 16 Jun 2019 14:02:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E802D286EE; Sun, 16 Jun 2019 14:02:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 72993286E2 for ; Sun, 16 Jun 2019 14:02:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 626BC89216; Sun, 16 Jun 2019 14:01:52 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from onstation.org (onstation.org [52.200.56.107]) by gabe.freedesktop.org (Postfix) with ESMTPS id BEE5F890D2; Sun, 16 Jun 2019 13:29:48 +0000 (UTC) Received: from localhost.localdomain (c-98-239-145-235.hsd1.wv.comcast.net [98.239.145.235]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: masneyb) by onstation.org (Postfix) with ESMTPSA id 6DD9C3EA0A; Sun, 16 Jun 2019 13:29:47 +0000 (UTC) From: Brian Masney To: agross@kernel.org, david.brown@linaro.org, robdclark@gmail.com, sean@poorly.run, robh+dt@kernel.org Subject: [PATCH 4/6] firmware: qcom: scm: add OCMEM lock/unlock interface Date: Sun, 16 Jun 2019 09:29:28 -0400 Message-Id: <20190616132930.6942-5-masneyb@onstation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190616132930.6942-1-masneyb@onstation.org> References: <20190616132930.6942-1-masneyb@onstation.org> MIME-Version: 1.0 X-Mailman-Approved-At: Sun, 16 Jun 2019 14:01:48 +0000 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=onstation.org; s=default; t=1560691787; bh=isipdNYHDnaIS6jjZEJA5zLRVmwZ0AOYiIPvP0S5Wfo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SZJBVaDpRG6xG/C9yu4pzslFSmshNR2wm1TmMl+k5E/w0W0OePSMnVbrEBdRkhmlN pj44EzoHG3x7BUvVxHC4lLO9k3QObqWyGPPG3uZeRM+wmuawOYfBZcebmX2v8/7U6B kw7UkN9u5DgSJjId+bewz39LPNbKrhUX1eTye7gE= X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, jonathan@marek.ca, airlied@linux.ie, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, bjorn.andersson@linaro.org, freedreno@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Rob Clark Add support for the OCMEM lock/unlock interface that is needed by the On Chip MEMory (OCMEM) that is present on some Snapdragon devices. Signed-off-by: Rob Clark [masneyb@onstation.org: ported to latest kernel; minor reformatting.] Signed-off-by: Brian Masney Reviewed-by: Bjorn Andersson --- Rob's last version of this patch: https://patchwork.kernel.org/patch/7340711/ drivers/firmware/qcom_scm-32.c | 35 +++++++++++++++++++++++++++++ drivers/firmware/qcom_scm-64.c | 12 ++++++++++ drivers/firmware/qcom_scm.c | 40 ++++++++++++++++++++++++++++++++++ drivers/firmware/qcom_scm.h | 9 ++++++++ include/linux/qcom_scm.h | 15 +++++++++++++ 5 files changed, 111 insertions(+) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 089b47124933..0100c82b9c00 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -463,6 +463,41 @@ int __qcom_scm_restore_sec_config(struct device *dev, u32 sec_id, return 0; } +int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, u32 size, + u32 mode) +{ + struct ocmem_tz_lock { + __le32 id; + __le32 offset; + __le32 size; + __le32 mode; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + request.mode = cpu_to_le32(mode); + + return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_LOCK_CMD, + &request, sizeof(request), NULL, 0); +} + +int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size) +{ + struct ocmem_tz_unlock { + __le32 id; + __le32 offset; + __le32 size; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + + return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_UNLOCK_CMD, + &request, sizeof(request), NULL, 0); +} + void __qcom_scm_init(void) { } diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index b6b78da7f9c9..2674d6d3cdde 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -247,6 +247,18 @@ int __qcom_scm_restore_sec_config(struct device *dev, u32 sec_id, return -ENOTSUPP; } +int __qcom_scm_ocmem_lock(struct device *dev, uint32_t id, uint32_t offset, + uint32_t size, uint32_t mode) +{ + return -ENOTSUPP; +} + +int __qcom_scm_ocmem_unlock(struct device *dev, uint32_t id, uint32_t offset, + uint32_t size) +{ + return -ENOTSUPP; +} + void __qcom_scm_init(void) { u64 cmd; diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 5495ef994c5d..85afb54defd4 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -193,6 +193,46 @@ int qcom_scm_restore_sec_config(struct device *dev, } EXPORT_SYMBOL(qcom_scm_restore_sec_config); +/** + * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available + */ +bool qcom_scm_ocmem_lock_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_OCMEM_SVC, + QCOM_SCM_OCMEM_LOCK_CMD); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock_available); + +/** + * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM + * region to the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + * @mode: access mode (WIDE/NARROW) + */ +int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size, + u32 mode) +{ + return __qcom_scm_ocmem_lock(__scm->dev, id, offset, size, mode); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock); + +/** + * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM + * region from the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + */ +int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size) +{ + return __qcom_scm_ocmem_unlock(__scm->dev, id, offset, size); +} +EXPORT_SYMBOL(qcom_scm_ocmem_unlock); + /** * qcom_scm_pas_supported() - Check if the peripheral authentication service is * available for the given peripherial diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index bccc7d10c5c2..387e3c4e33c5 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -48,6 +48,15 @@ extern void __qcom_scm_init(void); extern int __qcom_scm_restore_sec_config(struct device *dev, u32 sec_id, u32 ctx_bank_num); +#define QCOM_SCM_OCMEM_SVC 0xf +#define QCOM_SCM_OCMEM_LOCK_CMD 0x1 +#define QCOM_SCM_OCMEM_UNLOCK_CMD 0x2 + +extern int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, + u32 size, u32 mode); +extern int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, + u32 size); + #define QCOM_SCM_SVC_PIL 0x2 #define QCOM_SCM_PAS_INIT_IMAGE_CMD 0x1 #define QCOM_SCM_PAS_MEM_SETUP_CMD 0x2 diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index b5c0afaca955..977c01aa524a 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -34,6 +34,16 @@ enum qcom_scm_sec_dev_id { QCOM_SCM_ICE_DEV_ID = 20, }; +enum qcom_scm_ocmem_client { + QCOM_SCM_OCMEM_UNUSED_ID = 0x0, + QCOM_SCM_OCMEM_GRAPHICS_ID, + QCOM_SCM_OCMEM_VIDEO_ID, + QCOM_SCM_OCMEM_LP_AUDIO_ID, + QCOM_SCM_OCMEM_SENSORS_ID, + QCOM_SCM_OCMEM_OTHER_OS_ID, + QCOM_SCM_OCMEM_DEBUG_ID, +}; + #define QCOM_SCM_VMID_HLOS 0x3 #define QCOM_SCM_VMID_MSS_MSA 0xF #define QCOM_SCM_VMID_WLAN 0x18 @@ -54,6 +64,11 @@ extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, extern bool qcom_scm_restore_sec_config_available(void); extern int qcom_scm_restore_sec_config(struct device *dev, enum qcom_scm_sec_dev_id sec_id); +extern bool qcom_scm_ocmem_lock_available(void); +extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, + u32 size, u32 mode); +extern int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, + u32 size); extern bool qcom_scm_pas_supported(u32 peripheral); extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size); From patchwork Sun Jun 16 13:29:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Masney X-Patchwork-Id: 10997429 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3580D1398 for ; Sun, 16 Jun 2019 14:02:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 23979286EC for ; Sun, 16 Jun 2019 14:02:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1805628714; Sun, 16 Jun 2019 14:02:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 120D5286EC for ; Sun, 16 Jun 2019 14:02:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id ACDE389208; Sun, 16 Jun 2019 14:01:51 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from onstation.org (onstation.org [52.200.56.107]) by gabe.freedesktop.org (Postfix) with ESMTPS id 512A58917E; Sun, 16 Jun 2019 13:29:49 +0000 (UTC) Received: from localhost.localdomain (c-98-239-145-235.hsd1.wv.comcast.net [98.239.145.235]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: masneyb) by onstation.org (Postfix) with ESMTPSA id 360573E93E; Sun, 16 Jun 2019 13:29:47 +0000 (UTC) From: Brian Masney To: agross@kernel.org, david.brown@linaro.org, robdclark@gmail.com, sean@poorly.run, robh+dt@kernel.org Subject: [PATCH 5/6] soc: qcom: add OCMEM driver Date: Sun, 16 Jun 2019 09:29:29 -0400 Message-Id: <20190616132930.6942-6-masneyb@onstation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190616132930.6942-1-masneyb@onstation.org> References: <20190616132930.6942-1-masneyb@onstation.org> MIME-Version: 1.0 X-Mailman-Approved-At: Sun, 16 Jun 2019 14:01:48 +0000 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=onstation.org; s=default; t=1560691788; bh=3lYpop7VdT95zdg6bDKjM5aBmjTfcXUGw9vMX/ODVa0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gpA/zqIR7Mv86/vMmFfriZzvqCr2XN+l7x/ssuWREFu+ZAurW9JNLbIQ30+CoRzXi MARKpk2Hh5BAdOEQVV0N6VN35pdFVIsWyQtLoq5oES5skL85RGQkP2u6E4xrBzEFSg QUolUGRDzkkFf25BjuPfnPXz2rvHraJX/Dtu7/E4= X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, jonathan@marek.ca, airlied@linux.ie, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, bjorn.andersson@linaro.org, freedreno@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Rob Clark The OCMEM driver handles allocation and configuration of the On Chip MEMory that is present on some Snapdragon SoCs. Devices which have OCMEM do not have GMEM inside the GPU core, so the GPU must instead use OCMEM to be functional. Since currently the GPU is the only OCMEM user with an upstream driver, this is just a minimal implementation sufficient for statically allocating to the GPU it's chunk of OCMEM. Signed-off-by: Rob Clark Co-developed-by: Brian Masney Signed-off-by: Brian Masney --- Changes since Rob's last version of this patch: https://patchwork.kernel.org/patch/7379801/ - reformatted driver to allow multiple instances - updated logging of error paths during device probing - remove unused psgsc_ctrl - remove _clk from clock names - propagate error code from devm_ioremap_resource() - use device_get_match_data() - SPDX license tags - remove QCOM_SMD in Kconfig - select ARCH_QCOM in Kconfig - select QCOM_SCM in Kconfig - longer description in Kconfig drivers/soc/qcom/Kconfig | 10 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/ocmem.c | 402 +++++++++++++++++++++++++++++++++++ drivers/soc/qcom/ocmem.xml.h | 86 ++++++++ include/soc/qcom/ocmem.h | 34 +++ 5 files changed, 533 insertions(+) create mode 100644 drivers/soc/qcom/ocmem.c create mode 100644 drivers/soc/qcom/ocmem.xml.h create mode 100644 include/soc/qcom/ocmem.h diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 880cf0290962..998d94d60a3c 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -62,6 +62,16 @@ config QCOM_MDT_LOADER tristate select QCOM_SCM +config QCOM_OCMEM + tristate "Qualcomm On Chip Memory (OCMEM) driver" + depends on ARCH_QCOM + select QCOM_SCM + help + The On Chip Memory (OCMEM) allocator allows various clients to + allocate memory from OCMEM based on performance, latency and power + requirements. This is typically used by the GPU, camera/video, and + audio components on some Snapdragon SoCs. + config QCOM_PM bool "Qualcomm Power Management" depends on ARCH_QCOM && !ARM64 diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index ffe519b0cb66..76ac469f548c 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o obj-$(CONFIG_QCOM_GLINK_SSR) += glink_ssr.o obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o +obj-$(CONFIG_QCOM_OCMEM) += ocmem.o obj-$(CONFIG_QCOM_PM) += spm.o obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o qmi_helpers-y += qmi_encdec.o qmi_interface.o diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c new file mode 100644 index 000000000000..5ebf5031b6c5 --- /dev/null +++ b/drivers/soc/qcom/ocmem.c @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2019 Brian Masney + * Copyright (C) 2015 Red Hat. Author: Rob Clark + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "ocmem.xml.h" + +enum region_mode { + WIDE_MODE = 0x0, + THIN_MODE, + MODE_DEFAULT = WIDE_MODE, +}; + +struct ocmem_region { + bool interleaved; + enum region_mode mode; + unsigned int num_macros; + enum ocmem_macro_state macro_state[4]; + unsigned long macro_size; + unsigned long region_size; +}; + +struct ocmem_config { + uint8_t num_regions; + uint32_t macro_size; +}; + +struct ocmem { + struct device *dev; + const struct ocmem_config *config; + struct resource *ocmem_mem; + struct clk *core_clk; + struct clk *iface_clk; + void __iomem *mmio; + unsigned int num_ports; + unsigned int num_macros; + bool interleaved; + struct ocmem_region *regions; +}; + +#define FIELD(val, name) (((val) & name ## __MASK) >> name ## __SHIFT) + +static inline void ocmem_write(struct ocmem *ocmem, u32 reg, u32 data) +{ + writel(data, ocmem->mmio + reg); +} + +static inline u32 ocmem_read(struct ocmem *ocmem, u32 reg) +{ + return readl(ocmem->mmio + reg); +} + +static int ocmem_clk_enable(struct ocmem *ocmem) +{ + int ret; + + ret = clk_prepare_enable(ocmem->core_clk); + if (ret) { + dev_info(ocmem->dev, "Fail to enable core clk\n"); + return ret; + } + + ret = clk_prepare_enable(ocmem->iface_clk); + if (ret) { + dev_info(ocmem->dev, "Fail to enable iface clk\n"); + return ret; + } + + return 0; +} + +static void ocmem_clk_disable(struct ocmem *ocmem) +{ + clk_disable_unprepare(ocmem->iface_clk); + clk_disable_unprepare(ocmem->core_clk); +} + +static int ocmem_dev_remove(struct platform_device *pdev) +{ + struct ocmem *ocmem = platform_get_drvdata(pdev); + + ocmem_clk_disable(ocmem); + + return 0; +} + +static void update_ocmem(struct ocmem *ocmem) +{ + uint32_t region_mode_ctrl = 0x0; + unsigned int pos = 0, i = 0; + + if (!qcom_scm_ocmem_lock_available()) { + for (i = 0; i < ocmem->config->num_regions; i++) { + struct ocmem_region *region = &ocmem->regions[i]; + + pos = i << 2; + if (region->mode == THIN_MODE) + region_mode_ctrl |= BIT(pos); + } + + dev_dbg(ocmem->dev, "ocmem_region_mode_control %x\n", + region_mode_ctrl); + ocmem_write(ocmem, REG_OCMEM_REGION_MODE_CTL, region_mode_ctrl); + } + + for (i = 0; i < ocmem->config->num_regions; i++) { + struct ocmem_region *region = &ocmem->regions[i]; + u32 data; + + data = OCMEM_PSGSC_CTL_MACRO0_MODE(region->macro_state[0]) | + OCMEM_PSGSC_CTL_MACRO1_MODE(region->macro_state[1]) | + OCMEM_PSGSC_CTL_MACRO2_MODE(region->macro_state[2]) | + OCMEM_PSGSC_CTL_MACRO3_MODE(region->macro_state[3]); + + ocmem_write(ocmem, REG_OCMEM_PSGSC_CTL(i), data); + } +} + +static unsigned long phys_to_offset(struct ocmem *ocmem, + unsigned long addr) +{ + if (addr < ocmem->ocmem_mem->start || addr >= ocmem->ocmem_mem->end) + return 0; + + return addr - ocmem->ocmem_mem->start; +} + +static unsigned long device_address(struct ocmem *ocmem, + enum ocmem_client client, + unsigned long addr) +{ + /* TODO, gpu uses phys_to_offset, but others do not.. */ + return phys_to_offset(ocmem, addr); +} + +static void update_range(struct ocmem *ocmem, struct ocmem_buf *buf, + enum ocmem_macro_state mstate, enum region_mode rmode) +{ + unsigned long offset = 0; + int i, j; + + /* + * TODO probably should assert somewhere that range is aligned + * to macro boundaries.. + */ + + for (i = 0; i < ocmem->config->num_regions; i++) { + struct ocmem_region *region = &ocmem->regions[i]; + + if (buf->offset <= offset && offset < buf->offset + buf->len) + region->mode = rmode; + + for (j = 0; j < region->num_macros; j++) { + if (buf->offset <= offset && + offset < buf->offset + buf->len) + region->macro_state[j] = mstate; + + offset += region->macro_size; + } + } + + update_ocmem(ocmem); +} + +struct ocmem *of_get_ocmem(struct device *dev) +{ + struct platform_device *pdev; + struct device_node *devnode; + + devnode = of_parse_phandle(dev->of_node, "ocmem", 0); + if (!devnode) { + dev_err(dev, "Cannot look up ocmem phandle\n"); + return NULL; + } + + pdev = of_find_device_by_node(devnode); + if (!pdev) { + dev_err(dev, "Cannot find device node %s\n", devnode->name); + return NULL; + } + + return platform_get_drvdata(pdev); +} +EXPORT_SYMBOL(of_get_ocmem); + +struct ocmem_buf *ocmem_allocate(struct ocmem *ocmem, enum ocmem_client client, + unsigned long size) +{ + struct ocmem_buf *buf; + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + buf->offset = 0; + buf->addr = device_address(ocmem, client, buf->offset); + buf->len = size; + + update_range(ocmem, buf, CORE_ON, WIDE_MODE); + + if (qcom_scm_ocmem_lock_available()) { + int ret; + + ret = qcom_scm_ocmem_lock(QCOM_SCM_OCMEM_GRAPHICS_ID, + buf->offset, buf->len, WIDE_MODE); + if (ret) + dev_err(ocmem->dev, "could not lock: %d\n", ret); + } else { + if (client == OCMEM_GRAPHICS) { + ocmem_write(ocmem, REG_OCMEM_GFX_MPU_START, + buf->offset); + ocmem_write(ocmem, REG_OCMEM_GFX_MPU_END, + buf->offset + buf->len); + } + } + + return buf; +} +EXPORT_SYMBOL(ocmem_allocate); + +void ocmem_free(struct ocmem *ocmem, enum ocmem_client client, + struct ocmem_buf *buf) +{ + update_range(ocmem, buf, CLK_OFF, MODE_DEFAULT); + + if (qcom_scm_ocmem_lock_available()) { + int ret; + + ret = qcom_scm_ocmem_unlock(QCOM_SCM_OCMEM_GRAPHICS_ID, + buf->offset, buf->len); + if (ret) + dev_err(ocmem->dev, "could not unlock: %d\n", ret); + } else { + if (client == OCMEM_GRAPHICS) { + ocmem_write(ocmem, REG_OCMEM_GFX_MPU_START, 0x0); + ocmem_write(ocmem, REG_OCMEM_GFX_MPU_END, 0x0); + } + } + + kfree(buf); +} +EXPORT_SYMBOL(ocmem_free); + +static int ocmem_dev_probe(struct platform_device *pdev) +{ + struct ocmem *ocmem; + uint32_t reg, num_banks, region_size; + struct device *dev = &pdev->dev; + struct resource *res; + int i, j, ret; + + if (!qcom_scm_is_available()) + return -EPROBE_DEFER; + + ocmem = devm_kzalloc(dev, sizeof(*ocmem), GFP_KERNEL); + if (!ocmem) + return -ENOMEM; + + ocmem->dev = dev; + ocmem->config = device_get_match_data(dev); + + ocmem->core_clk = devm_clk_get(dev, "core"); + if (IS_ERR(ocmem->core_clk)) { + if (PTR_ERR(ocmem->core_clk) != -EPROBE_DEFER) + dev_err(dev, "Unable to get the core clock\n"); + + return PTR_ERR(ocmem->core_clk); + } + + ocmem->iface_clk = devm_clk_get(dev, "iface"); + if (IS_ERR(ocmem->iface_clk)) { + if (PTR_ERR(ocmem->iface_clk) != -EPROBE_DEFER) + dev_err(dev, "Unable to get the iface clock\n"); + + return PTR_ERR(ocmem->iface_clk); + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "ocmem_ctrl_physical"); + if (!res) { + dev_err(dev, "Could not get ocmem_ctrl_physical region\n"); + return -ENXIO; + } + + ocmem->mmio = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(ocmem->mmio)) { + dev_err(&pdev->dev, + "Failed to ioremap ocmem_ctrl_physical resource\n"); + return PTR_ERR(ocmem->mmio); + } + + ocmem->ocmem_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "ocmem_physical"); + if (!ocmem->ocmem_mem) { + dev_err(dev, "Could not get ocmem_physical region\n"); + return -ENXIO; + } + + /* The core clock is synchronous with graphics */ + WARN_ON(clk_set_rate(ocmem->core_clk, 1000) < 0); + + ret = ocmem_clk_enable(ocmem); + if (ret) + return ret; + + if (qcom_scm_restore_sec_config_available()) { + dev_dbg(dev, "configuring scm\n"); + ret = qcom_scm_restore_sec_config(&pdev->dev, + QCOM_SCM_OCMEM_DEV_ID); + if (ret) { + dev_err(dev, "Could not enable secure configuration\n"); + goto err_clk_disable; + } + } + + reg = ocmem_read(ocmem, REG_OCMEM_HW_PROFILE); + ocmem->num_ports = FIELD(reg, OCMEM_HW_PROFILE_NUM_PORTS); + ocmem->num_macros = FIELD(reg, OCMEM_HW_PROFILE_NUM_MACROS); + ocmem->interleaved = !!(reg & OCMEM_HW_PROFILE_INTERLEAVING); + + num_banks = ocmem->num_ports / 2; + region_size = ocmem->config->macro_size * num_banks; + + dev_info(dev, "%u ports, %u regions, %u macros, %sinterleaved\n", + ocmem->num_ports, ocmem->config->num_regions, + ocmem->num_macros, ocmem->interleaved ? "" : "not "); + + ocmem->regions = devm_kcalloc(dev, ocmem->config->num_regions, + sizeof(struct ocmem_region), GFP_KERNEL); + if (!ocmem->regions) { + ret = -ENOMEM; + goto err_clk_disable; + } + + for (i = 0; i < ocmem->config->num_regions; i++) { + struct ocmem_region *region = &ocmem->regions[i]; + + if (WARN_ON(num_banks > ARRAY_SIZE(region->macro_state))) { + ret = -EINVAL; + goto err_clk_disable; + } + + region->mode = MODE_DEFAULT; + region->num_macros = num_banks; + + if (i == (ocmem->config->num_regions - 1) && + reg & OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE) { + region->macro_size = ocmem->config->macro_size / 2; + region->region_size = region_size / 2; + } else { + region->macro_size = ocmem->config->macro_size; + region->region_size = region_size; + } + + for (j = 0; j < ARRAY_SIZE(region->macro_state); j++) + region->macro_state[j] = CLK_OFF; + } + + platform_set_drvdata(pdev, ocmem); + + return 0; + +err_clk_disable: + ocmem_clk_disable(ocmem); + return ret; +} + +static const struct ocmem_config ocmem_8974_config = { + .num_regions = 3, + .macro_size = SZ_128K, +}; + +static const struct of_device_id ocmem_of_match[] = { + { .compatible = "qcom,ocmem-msm8974", .data = &ocmem_8974_config }, + { } +}; + +MODULE_DEVICE_TABLE(of, ocmem_of_match); + +static struct platform_driver ocmem_driver = { + .probe = ocmem_dev_probe, + .remove = ocmem_dev_remove, + .driver = { + .name = "ocmem", + .of_match_table = ocmem_of_match, + }, +}; + +module_platform_driver(ocmem_driver); diff --git a/drivers/soc/qcom/ocmem.xml.h b/drivers/soc/qcom/ocmem.xml.h new file mode 100644 index 000000000000..b4bfb85d1e33 --- /dev/null +++ b/drivers/soc/qcom/ocmem.xml.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef OCMEM_XML +#define OCMEM_XML + +/* Autogenerated file, DO NOT EDIT manually! + +This file was generated by the rules-ng-ng headergen tool in this git repository: +http://github.com/freedreno/envytools/ +git clone https://github.com/freedreno/envytools.git + +The rules-ng-ng source files this header was generated from are: +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00) + +Copyright (C) 2013-2015 by the following authors: +- Rob Clark (robclark) +*/ + +enum ocmem_macro_state { + PASSTHROUGH = 0, + PERI_ON = 1, + CORE_ON = 2, + CLK_OFF = 4, +}; + +#define REG_OCMEM_HW_VERSION 0x00000000 + +#define REG_OCMEM_HW_PROFILE 0x00000004 +#define OCMEM_HW_PROFILE_NUM_PORTS__MASK 0x0000000f +#define OCMEM_HW_PROFILE_NUM_PORTS__SHIFT 0 +static inline uint32_t OCMEM_HW_PROFILE_NUM_PORTS(uint32_t val) +{ + return ((val) << OCMEM_HW_PROFILE_NUM_PORTS__SHIFT) & OCMEM_HW_PROFILE_NUM_PORTS__MASK; +} +#define OCMEM_HW_PROFILE_NUM_MACROS__MASK 0x00003f00 +#define OCMEM_HW_PROFILE_NUM_MACROS__SHIFT 8 +static inline uint32_t OCMEM_HW_PROFILE_NUM_MACROS(uint32_t val) +{ + return ((val) << OCMEM_HW_PROFILE_NUM_MACROS__SHIFT) & OCMEM_HW_PROFILE_NUM_MACROS__MASK; +} +#define OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE 0x00010000 +#define OCMEM_HW_PROFILE_INTERLEAVING 0x00020000 + +#define REG_OCMEM_GEN_STATUS 0x0000000c + +#define REG_OCMEM_PSGSC_STATUS 0x00000038 + +static inline uint32_t REG_OCMEM_PSGSC(uint32_t i0) { return 0x0000003c + 0x1*i0; } + +static inline uint32_t REG_OCMEM_PSGSC_CTL(uint32_t i0) { return 0x0000003c + 0x1*i0; } +#define OCMEM_PSGSC_CTL_MACRO0_MODE__MASK 0x00000007 +#define OCMEM_PSGSC_CTL_MACRO0_MODE__SHIFT 0 +static inline uint32_t OCMEM_PSGSC_CTL_MACRO0_MODE(enum ocmem_macro_state val) +{ + return ((val) << OCMEM_PSGSC_CTL_MACRO0_MODE__SHIFT) & OCMEM_PSGSC_CTL_MACRO0_MODE__MASK; +} +#define OCMEM_PSGSC_CTL_MACRO1_MODE__MASK 0x00000070 +#define OCMEM_PSGSC_CTL_MACRO1_MODE__SHIFT 4 +static inline uint32_t OCMEM_PSGSC_CTL_MACRO1_MODE(enum ocmem_macro_state val) +{ + return ((val) << OCMEM_PSGSC_CTL_MACRO1_MODE__SHIFT) & OCMEM_PSGSC_CTL_MACRO1_MODE__MASK; +} +#define OCMEM_PSGSC_CTL_MACRO2_MODE__MASK 0x00000700 +#define OCMEM_PSGSC_CTL_MACRO2_MODE__SHIFT 8 +static inline uint32_t OCMEM_PSGSC_CTL_MACRO2_MODE(enum ocmem_macro_state val) +{ + return ((val) << OCMEM_PSGSC_CTL_MACRO2_MODE__SHIFT) & OCMEM_PSGSC_CTL_MACRO2_MODE__MASK; +} +#define OCMEM_PSGSC_CTL_MACRO3_MODE__MASK 0x00007000 +#define OCMEM_PSGSC_CTL_MACRO3_MODE__SHIFT 12 +static inline uint32_t OCMEM_PSGSC_CTL_MACRO3_MODE(enum ocmem_macro_state val) +{ + return ((val) << OCMEM_PSGSC_CTL_MACRO3_MODE__SHIFT) & OCMEM_PSGSC_CTL_MACRO3_MODE__MASK; +} + +#define REG_OCMEM_REGION_MODE_CTL 0x00001000 +#define OCMEM_REGION_MODE_CTL_REG0_THIN 0x00000001 +#define OCMEM_REGION_MODE_CTL_REG1_THIN 0x00000002 +#define OCMEM_REGION_MODE_CTL_REG2_THIN 0x00000004 +#define OCMEM_REGION_MODE_CTL_REG3_THIN 0x00000008 + +#define REG_OCMEM_GFX_MPU_START 0x00001004 + +#define REG_OCMEM_GFX_MPU_END 0x00001008 + +#endif /* OCMEM_XML */ diff --git a/include/soc/qcom/ocmem.h b/include/soc/qcom/ocmem.h new file mode 100644 index 000000000000..e56ce220096d --- /dev/null +++ b/include/soc/qcom/ocmem.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2015 Red Hat + * Author: Rob Clark + */ + +#ifndef __OCMEM_H__ +#define __OCMEM_H__ + +enum ocmem_client { + /* GMEM clients */ + OCMEM_GRAPHICS = 0x0, + /* + * TODO add more once ocmem_allocate() is clever enough to + * deal with multiple clients. + */ + OCMEM_CLIENT_MAX, +}; + +struct ocmem; + +struct ocmem_buf { + unsigned long offset; + unsigned long addr; + unsigned long len; +}; + +struct ocmem *of_get_ocmem(struct device *dev); +struct ocmem_buf *ocmem_allocate(struct ocmem *ocmem, enum ocmem_client client, + unsigned long size); +void ocmem_free(struct ocmem *ocmem, enum ocmem_client client, + struct ocmem_buf *buf); + +#endif /* __OCMEM_H__ */ From patchwork Sun Jun 16 13:29:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Masney X-Patchwork-Id: 10997445 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E0B1414B6 for ; Sun, 16 Jun 2019 14:03:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D0A5D286E2 for ; Sun, 16 Jun 2019 14:03:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C5164286EE; Sun, 16 Jun 2019 14:03:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 121C6286E2 for ; Sun, 16 Jun 2019 14:03:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B32B389266; Sun, 16 Jun 2019 14:02:44 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from onstation.org (onstation.org [52.200.56.107]) by gabe.freedesktop.org (Postfix) with ESMTPS id CDA21890D2; Sun, 16 Jun 2019 13:29:49 +0000 (UTC) Received: from localhost.localdomain (c-98-239-145-235.hsd1.wv.comcast.net [98.239.145.235]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: masneyb) by onstation.org (Postfix) with ESMTPSA id D0CC73EA08; Sun, 16 Jun 2019 13:29:48 +0000 (UTC) From: Brian Masney To: agross@kernel.org, david.brown@linaro.org, robdclark@gmail.com, sean@poorly.run, robh+dt@kernel.org Subject: [PATCH 6/6] drm/msm/gpu: add ocmem init/cleanup functions Date: Sun, 16 Jun 2019 09:29:30 -0400 Message-Id: <20190616132930.6942-7-masneyb@onstation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190616132930.6942-1-masneyb@onstation.org> References: <20190616132930.6942-1-masneyb@onstation.org> MIME-Version: 1.0 X-Mailman-Approved-At: Sun, 16 Jun 2019 14:01:48 +0000 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=onstation.org; s=default; t=1560691789; bh=CSLNc2AZQ+DKJM8zhPJfB5kaUTVkbzr63wYAVnTySDw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XT/5RFcPn+qnHug2377aw+yuXF1oz/RFzp8HS58pi62jZFONJxTX245PNHSif8/TZ qoG7lxAqdfZN89iCgCz5e/F96HXJZd4Gego49M+81cHWv/kOaEeIGuQQqaF+eHwdOL Puo0zzB95OOVHWfY1QMXz7tsEVfygSjxhGPx3DKg= X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, jonathan@marek.ca, airlied@linux.ie, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, bjorn.andersson@linaro.org, freedreno@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP The files a3xx_gpu.c and a4xx_gpu.c have ifdefs for the OCMEM support that was missing upstream. Add two new functions (adreno_gpu_ocmem_init and adreno_gpu_ocmem_cleanup) that removes some duplicated code. We also need to change the ifdef check for CONFIG_MSM_OCMEM to CONFIG_QCOM_OCMEM now that OCMEM support is upstream. Signed-off-by: Brian Masney --- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 33 +++++++------------- drivers/gpu/drm/msm/adreno/a3xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 30 ++++++------------ drivers/gpu/drm/msm/adreno/a4xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 41 +++++++++++++++++++++++++ drivers/gpu/drm/msm/adreno/adreno_gpu.h | 10 ++++++ 6 files changed, 74 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index c3b4bc6e4155..72720bb2aca1 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -17,10 +17,6 @@ * this program. If not, see . */ -#ifdef CONFIG_MSM_OCMEM -# include -#endif - #include "a3xx_gpu.h" #define A3XX_INT0_MASK \ @@ -206,9 +202,9 @@ static int a3xx_hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x00000000); /* Set the OCMEM base address for A330, etc */ - if (a3xx_gpu->ocmem_hdl) { + if (a3xx_gpu->ocmem.hdl) { gpu_write(gpu, REG_A3XX_RB_GMEM_BASE_ADDR, - (unsigned int)(a3xx_gpu->ocmem_base >> 14)); + (unsigned int)(a3xx_gpu->ocmem.base >> 14)); } /* Turn on performance counters: */ @@ -329,10 +325,7 @@ static void a3xx_destroy(struct msm_gpu *gpu) adreno_gpu_cleanup(adreno_gpu); -#ifdef CONFIG_MSM_OCMEM - if (a3xx_gpu->ocmem_base) - ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl); -#endif + adreno_gpu_ocmem_cleanup(&a3xx_gpu->ocmem); kfree(a3xx_gpu); } @@ -507,17 +500,10 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) /* if needed, allocate gmem: */ if (adreno_is_a330(adreno_gpu)) { -#ifdef CONFIG_MSM_OCMEM - /* TODO this is different/missing upstream: */ - struct ocmem_buf *ocmem_hdl = - ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem); - - a3xx_gpu->ocmem_hdl = ocmem_hdl; - a3xx_gpu->ocmem_base = ocmem_hdl->addr; - adreno_gpu->gmem = ocmem_hdl->len; - DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024, - a3xx_gpu->ocmem_base); -#endif + ret = adreno_gpu_ocmem_init(&adreno_gpu->base.pdev->dev, + adreno_gpu, &a3xx_gpu->ocmem); + if (ret) + goto fail; } if (!gpu->aspace) { @@ -530,11 +516,14 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) */ DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); ret = -ENXIO; - goto fail; + goto fail_cleanup_ocmem; } return gpu; +fail_cleanup_ocmem: + adreno_gpu_ocmem_cleanup(&a3xx_gpu->ocmem); + fail: if (a3xx_gpu) a3xx_destroy(&a3xx_gpu->base.base); diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h index ab60dc9e344e..727c34f38f9e 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h @@ -30,8 +30,7 @@ struct a3xx_gpu { struct adreno_gpu base; /* if OCMEM is used for GMEM: */ - uint32_t ocmem_base; - void *ocmem_hdl; + struct adreno_ocmem ocmem; }; #define to_a3xx_gpu(x) container_of(x, struct a3xx_gpu, base) diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index ab2b752566d8..b8f825107796 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -2,9 +2,6 @@ /* Copyright (c) 2014 The Linux Foundation. All rights reserved. */ #include "a4xx_gpu.h" -#ifdef CONFIG_MSM_OCMEM -# include -#endif #define A4XX_INT0_MASK \ (A4XX_INT0_RBBM_AHB_ERROR | \ @@ -188,7 +185,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu) (1 << 30) | 0xFFFF); gpu_write(gpu, REG_A4XX_RB_GMEM_BASE_ADDR, - (unsigned int)(a4xx_gpu->ocmem_base >> 14)); + (unsigned int)(a4xx_gpu->ocmem.base >> 14)); /* Turn on performance counters: */ gpu_write(gpu, REG_A4XX_RBBM_PERFCTR_CTL, 0x01); @@ -318,10 +315,7 @@ static void a4xx_destroy(struct msm_gpu *gpu) adreno_gpu_cleanup(adreno_gpu); -#ifdef CONFIG_MSM_OCMEM - if (a4xx_gpu->ocmem_base) - ocmem_free(OCMEM_GRAPHICS, a4xx_gpu->ocmem_hdl); -#endif + adreno_gpu_ocmem_cleanup(&a4xx_gpu->ocmem); kfree(a4xx_gpu); } @@ -578,17 +572,10 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) /* if needed, allocate gmem: */ if (adreno_is_a4xx(adreno_gpu)) { -#ifdef CONFIG_MSM_OCMEM - /* TODO this is different/missing upstream: */ - struct ocmem_buf *ocmem_hdl = - ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem); - - a4xx_gpu->ocmem_hdl = ocmem_hdl; - a4xx_gpu->ocmem_base = ocmem_hdl->addr; - adreno_gpu->gmem = ocmem_hdl->len; - DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024, - a4xx_gpu->ocmem_base); -#endif + ret = adreno_gpu_ocmem_init(dev->dev, adreno_gpu, + &a4xx_gpu->ocmem); + if (ret) + goto fail; } if (!gpu->aspace) { @@ -601,11 +588,14 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) */ DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); ret = -ENXIO; - goto fail; + goto fail_cleanup_ocmem; } return gpu; +fail_cleanup_ocmem: + adreno_gpu_ocmem_cleanup(&a4xx_gpu->ocmem); + fail: if (a4xx_gpu) a4xx_destroy(&a4xx_gpu->base.base); diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.h b/drivers/gpu/drm/msm/adreno/a4xx_gpu.h index d506311ee240..a01448cba2ea 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.h @@ -16,8 +16,7 @@ struct a4xx_gpu { struct adreno_gpu base; /* if OCMEM is used for GMEM: */ - uint32_t ocmem_base; - void *ocmem_hdl; + struct adreno_ocmem ocmem; }; #define to_a4xx_gpu(x) container_of(x, struct a4xx_gpu, base) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 6f7f4114afcf..e0a9409c8a32 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -29,6 +29,10 @@ #include "msm_gem.h" #include "msm_mmu.h" +#ifdef CONFIG_QCOM_OCMEM +# include +#endif + static bool zap_available = true; static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname, @@ -897,6 +901,43 @@ static int adreno_get_pwrlevels(struct device *dev, return 0; } +int adreno_gpu_ocmem_init(struct device *dev, struct adreno_gpu *adreno_gpu, + struct adreno_ocmem *adreno_ocmem) +{ +#ifdef CONFIG_QCOM_OCMEM + struct ocmem_buf *ocmem_hdl; + struct ocmem *ocmem; + + ocmem = of_get_ocmem(dev); + if (!ocmem) { + /* This is an optional property so return success. */ + return 0; + } + + ocmem_hdl = ocmem_allocate(ocmem, OCMEM_GRAPHICS, adreno_gpu->gmem); + if (IS_ERR(ocmem_hdl)) + return PTR_ERR(ocmem_hdl); + + adreno_ocmem->ocmem = ocmem; + adreno_ocmem->base = ocmem_hdl->addr; + adreno_ocmem->hdl = ocmem_hdl; + adreno_gpu->gmem = ocmem_hdl->len; + DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024, + adreno_ocmem->base); +#endif + + return 0; +} + +void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem) +{ +#ifdef CONFIG_QCOM_OCMEM + if (adreno_ocmem->base) + ocmem_free(adreno_ocmem->ocmem, OCMEM_GRAPHICS, + adreno_ocmem->hdl); +#endif +} + int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_gpu *adreno_gpu, const struct adreno_gpu_funcs *funcs, int nr_rings) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 0925606ec9b5..1cd11570323b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -136,6 +136,12 @@ struct adreno_gpu { }; #define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base) +struct adreno_ocmem { + struct ocmem *ocmem; + uint32_t base; + void *hdl; +}; + /* platform config data (ie. from DT, or pdata) */ struct adreno_platform_config { struct adreno_rev rev; @@ -241,6 +247,10 @@ void adreno_dump(struct msm_gpu *gpu); void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords); struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu); +int adreno_gpu_ocmem_init(struct device *dev, struct adreno_gpu *adreno_gpu, + struct adreno_ocmem *ocmem); +void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *ocmem); + int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs, int nr_rings);