Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2223977/?format=api
{ "id": 2223977, "url": "http://patchwork.ozlabs.org/api/patches/2223977/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20260416053928.2834699-7-varadarajan.narayanan@oss.qualcomm.com/", "project": { "id": 18, "url": "http://patchwork.ozlabs.org/api/projects/18/?format=api", "name": "U-Boot", "link_name": "uboot", "list_id": "u-boot.lists.denx.de", "list_email": "u-boot@lists.denx.de", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260416053928.2834699-7-varadarajan.narayanan@oss.qualcomm.com>", "list_archive_url": null, "date": "2026-04-16T05:39:24", "name": "[v3,06/10] mach-snapdragon: Add initial support for IPQ5210 SPL", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "10ef221aa6674b5f0977cf302dbc7f7c67c65203", "submitter": { "id": 92283, "url": "http://patchwork.ozlabs.org/api/people/92283/?format=api", "name": "Varadarajan Narayanan", "email": "varadarajan.narayanan@oss.qualcomm.com" }, "delegate": { "id": 151538, "url": "http://patchwork.ozlabs.org/api/users/151538/?format=api", "username": "kcxt", "first_name": "Casey", "last_name": "Connolly", "email": "casey.connolly@linaro.org" }, "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20260416053928.2834699-7-varadarajan.narayanan@oss.qualcomm.com/mbox/", "series": [ { "id": 500162, "url": "http://patchwork.ozlabs.org/api/series/500162/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=500162", "date": "2026-04-16T05:39:18", "name": "Qualcomm IPQ5210 SoC bringup", "version": 3, "mbox": "http://patchwork.ozlabs.org/series/500162/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2223977/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2223977/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<u-boot-bounces@lists.denx.de>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256\n header.s=qcppdkim1 header.b=pHPLX9UU;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n header.a=rsa-sha256 header.s=google header.b=c7P4Qb8A;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)", "phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=oss.qualcomm.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de", "phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=qualcomm.com header.i=@qualcomm.com\n header.b=\"pHPLX9UU\";\n\tdkim=pass (2048-bit key;\n unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n header.b=\"c7P4Qb8A\";\n\tdkim-atps=neutral", "phobos.denx.de; dmarc=none (p=none dis=none)\n header.from=oss.qualcomm.com", "phobos.denx.de; spf=pass\n smtp.mailfrom=varadarajan.narayanan@oss.qualcomm.com" ], "Received": [ "from phobos.denx.de (phobos.denx.de\n [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fxJTR2f6qz1yG9\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 16 Apr 2026 23:17:31 +1000 (AEST)", "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 58D258426E;\n\tThu, 16 Apr 2026 15:16:30 +0200 (CEST)", "by phobos.denx.de (Postfix, from userid 109)\n id 431FA8407E; Thu, 16 Apr 2026 07:41:04 +0200 (CEST)", "from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com\n [205.220.168.131])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 6C23583C2B\n for <u-boot@lists.denx.de>; Thu, 16 Apr 2026 07:40:56 +0200 (CEST)", "from pps.filterd (m0279867.ppops.net [127.0.0.1])\n by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n 63G186tR3733589\n for <u-boot@lists.denx.de>; Thu, 16 Apr 2026 05:40:54 GMT", "from mail-pg1-f198.google.com (mail-pg1-f198.google.com\n [209.85.215.198])\n by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4djcqwjjfx-1\n (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT)\n for <u-boot@lists.denx.de>; Thu, 16 Apr 2026 05:40:54 +0000 (GMT)", "by mail-pg1-f198.google.com with SMTP id\n 41be03b00d2f7-c7424d91b2dso3918610a12.1\n for <u-boot@lists.denx.de>; Wed, 15 Apr 2026 22:40:54 -0700 (PDT)", "from hu-varada-blr.qualcomm.com\n (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19])\n by smtp.gmail.com with ESMTPSA id\n d2e1a72fcca58-82f673e3824sm3994496b3a.34.2026.04.15.22.40.41\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 15 Apr 2026 22:40:52 -0700 (PDT)" ], "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de", "X-Spam-Level": "", "X-Spam-Status": "No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED,\n RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED,\n SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2", "DKIM-Signature": [ "v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h=\n content-transfer-encoding:date:from:in-reply-to:message-id\n :mime-version:references:subject:to; s=qcppdkim1; bh=08kNtCX3fOv\n bLOppg5ROANX7w/R1VL+D7oeSsOK8p4c=; b=pHPLX9UUo97f67YXTlAvvyqorWG\n AJXzvkpf8vuav8G+n+epvf4On4ml2wSsnjMgxT8cr8Uwe4TBZhNvXwcEbMz/qk7Q\n VET5mB9MUj+A0F1ptyCOK+o+EY0M89ivaD8/WxGALUIf2c9hXceXVyJUK7suTFqG\n fArxXXAo9FO29EsYCoWmoGsT77lDcykEFN3dOFKdGh7AT4v5qrxVyT0X0yV+Wjip\n U9ooB1w7TBqNQ0CGKqX4pwZg35FrTdXEmfS22KXzTS+FPYvXgfyCycPPGZ6UMi3D\n GkgpekczAZWtuj2zCUTvWbKHdUBTSOywaFSYTGI6d2gIQJqZ8jR/Ki/eG/Q==", "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=oss.qualcomm.com; s=google; t=1776318054; x=1776922854; darn=lists.denx.de;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:to:from:from:to:cc:subject:date:message-id\n :reply-to; bh=08kNtCX3fOvbLOppg5ROANX7w/R1VL+D7oeSsOK8p4c=;\n b=c7P4Qb8AWTJYOFfT1HAWIZ5fuIhIBSW1p617diN65UdPiNb4oNxNab1/4Gbwy4hHa/\n wG8uvaBBRoNi2jRo2ghhWAqT+ANMRus5yJcAXux49Ausd1kohO+FtdJ1MnsU+Xq43UIC\n w+Z7rBu1kv2oBsuc7d7ds7eMUF77QKdXmBMnCTlsGnecE+oNNhSnCtexXVvWish7WLoN\n zuParUB/rwl3Yh+A9dJw9KyKblkekqvMWLYkOABWFesnErBr1vz2sleV3EctZRAymEm3\n h1vjBBZngpMK8pB7IVf1aPj/fAkMcvg5uevnIyMtkCSRx+31KiQ3JhEs5oW6IkUZFxnJ\n VbnA==" ], "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776318054; x=1776922854;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to\n :cc:subject:date:message-id:reply-to;\n bh=08kNtCX3fOvbLOppg5ROANX7w/R1VL+D7oeSsOK8p4c=;\n b=MjiCOGgCaloxIigO7GfioodVPlvySyJTI4Dkdx4RZ2T6jWH0smb9WO1jv3eBGtTBpI\n f7/FsUxyZhcJr3sFbaEIgT+e8/hqT7ZGV7VKm/+pXDjSVmVmhpARMyKGwYkHhgTyFpMF\n EbIAxEucA8T3/XLkCTgwiH+7QdI0SRS2SPcHZYFbOm0HLgwBy8ozzNo1qiZD7K6WmWCI\n 7GkyzA3JV8CH5H/1AyH1etkvthgEGE4rcxEyTCzxszEX1naUhnev0PZKhK0D0ePY6t21\n VFN3F9/SHN0Q/KMJPcGPBQcoqRHPiZCwTTMVPtm4/n0812oioD2KyV8zBbSgKqHJkcDi\n j/cg==", "X-Forwarded-Encrypted": "i=1;\n AFNElJ9VWScr50jo3azf8pN6YHMqiST3Bzf//7jmIVXvyX7X6beRv/JYowuWA/rMEBLtQ0fRZkZo7hA=@lists.denx.de", "X-Gm-Message-State": "AOJu0Yzcq3JmwX1a7x28aTwKRQWh9oi4X0zRm/ee1gBZwNbnGdjh4c89\n hZBscIJyILj8i5o1Xfp/OfcGUIlPPlETDICL2GN8v/CBQKUZI1JRpxiG1wn4hniAFzsmHiVlpkr\n 2r0DjmYHrfcHMVc7enpiFsQTFFLzAoDz/16v1Od2k+p/xWkMwDG1Y3H4+", "X-Gm-Gg": "AeBDiesJkP+xU3QKbx70hphKwC0+s7X+Bgq7dHc0fYgX0+k4MXeDFxVq7JCxxA+rKca\n gB84gfdVjd7R9rbjhNTq69hhWml9mP544CWlEGlMuO/WNWQUK5UPiGhkiiUTIEIea2FTCArSoml\n cG1ugciUgg9uC7bRfaiQGqnB1xWTgbA8nb8jGfrCFeIbwryvqfuoSmGakFdOnLxRGguDutTJXKA\n YAWc/hN6xZRznWs2NyWB8dvHBnPGvY96Rw7lNsN5mb93FS3fzKkw18tTeqQOvbCKwV6mkIIQxez\n cMlSW40SDRx/4+TGDQ8J5mluMbJ0hyxO3CWMODVV+CyJj5olv7KpPjcFyhz9eUAFdarSMkdfV7e\n vRjrWVMydI2ROCEOKFOH+O86EBYTUbvScVmKOBczMMVbVj2u2r6X8vRnzcanyz7gLVihqgc9Y5U\n aru+Y0Or+qp4zZZxeSFXJvfTN2beafPGaZ3syWr+x1N/au+Z2SlTo=", "X-Received": [ "by 2002:a05:6a00:84c:b0:82f:4cc9:186d with SMTP id\n d2e1a72fcca58-82f4cc936a7mr12374841b3a.46.1776318053449;\n Wed, 15 Apr 2026 22:40:53 -0700 (PDT)", "by 2002:a05:6a00:84c:b0:82f:4cc9:186d with SMTP id\n d2e1a72fcca58-82f4cc936a7mr12374792b3a.46.1776318052798;\n Wed, 15 Apr 2026 22:40:52 -0700 (PDT)" ], "From": "Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>", "To": "rayagonda.kokatanur@broadcom.com, trini@konsulko.com,\n casey.connolly@linaro.org, neil.armstrong@linaro.org,\n sumit.garg@kernel.org, peng.fan@nxp.com, jh80.chung@samsung.com,\n lukma@denx.de, tien.fong.chee@altera.com, tingting.meng@altera.com,\n anshuld@ti.com, alif.zakuan.yuslaimi@altera.com, alice.guo@nxp.com,\n quentin.schulz@cherry.de, ilias.apalodimas@linaro.org,\n varadarajan.narayanan@oss.qualcomm.com, sjg@chromium.org,\n mkorpershoek@kernel.org, h-salunke@ti.com, alchark@gmail.com,\n dario.binacchi@amarulasolutions.com, ye.li@nxp.com,\n andre.przywara@arm.com, dinesh.maniyam@altera.com,\n luca.weiss@fairphone.com, danila@jiaxyga.com,\n aswin.murugan@oss.qualcomm.com, balaji.selvanathan@oss.qualcomm.com,\n adrian@mainlining.org, n-francis@ti.com, wens@kernel.org,\n jamie.gibbons@microchip.com, justin@tidylabs.net,\n ycliang@andestech.com, david.wronek@mainlining.org,\n james.hilliard1@gmail.com, richard.genoud@bootlin.com,\n michael@amarulasolutions.com, philip.molloy@analog.com,\n sughosh.ganu@arm.com, u-boot@lists.denx.de, u-boot-qcom@groups.io", "Subject": "[PATCH v3 06/10] mach-snapdragon: Add initial support for IPQ5210 SPL", "Date": "Thu, 16 Apr 2026 11:09:24 +0530", "Message-Id": "<20260416053928.2834699-7-varadarajan.narayanan@oss.qualcomm.com>", "X-Mailer": "git-send-email 2.34.1", "In-Reply-To": "<20260416053928.2834699-1-varadarajan.narayanan@oss.qualcomm.com>", "References": "<20260416053928.2834699-1-varadarajan.narayanan@oss.qualcomm.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-Proofpoint-ORIG-GUID": "N3Un4Q5Q0n2f0KkCEw_f559XgDHqbQaw", "X-Proofpoint-GUID": "N3Un4Q5Q0n2f0KkCEw_f559XgDHqbQaw", "X-Authority-Analysis": "v=2.4 cv=XOIAjwhE c=1 sm=1 tr=0 ts=69e07666 cx=c_pps\n a=Qgeoaf8Lrialg5Z894R3/Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17\n a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22\n a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8\n a=pGLkceISAAAA:8 a=Z5pLIw-5wEmkYNezhjYA:9 a=O6mRQTBPUV7GYTyk:21\n a=x9snwWr2DeNwDh03kgHS:22", "X-Proofpoint-Spam-Details-Enc": "AW1haW4tMjYwNDE2MDA1MSBTYWx0ZWRfXzKloAcPSh7SG\n 8ZEMyB3q3+Hjn9Omn6T9h6dvQOyazXbtTFniDf+MNdEThHzpHBaU4vCoFX41MYll0f6jq+oF++1\n VE5cMk3E3ZtmpQu8go4Aol4SVI5o6dOTWLh5dKaKVpfgWaBbbk8DCw6ucDn5zQ4JAhdy+5hno9+\n d8WGbmQxfzFW016/slkGIRqNyZOsQoyE1ifSpTMLXv05le3dMNbzpE3z0F8KRob3tifMNEghUXu\n Br6jgqrxj1qQ9usk+kDy7U6AkJ80KQy7kN57oLVoo7AcF8z6H1NdAVqsVEUr4KHHEznJMZ+iS0k\n vwCUcK2xOjsUqv+TAj2bfqJlFNmbgUP8/DmSNae5pjTpJvLM54nLXpP/VPaByMZvSAG7NWoDcWp\n anEMiY+igoTpH5+AsphT7WxNocU3vKlQFwBchkdOlyFJ3UPZEwjmYwn8gnOUdqOJhPhF+bTltia\n EpKHLkl8xdKdhOBuc1Q==", "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49\n definitions=2026-04-16_01,2026-04-13_04,2025-10-01_01", "X-Proofpoint-Spam-Details": "rule=outbound_notspam policy=outbound score=0\n priorityscore=1501 adultscore=0 suspectscore=0 spamscore=0 malwarescore=0\n bulkscore=0 impostorscore=0 phishscore=0 clxscore=1015 lowpriorityscore=0\n classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0\n reason=mlx scancount=1 engine=8.22.0-2604070000 definitions=main-2604160051", "X-Mailman-Approved-At": "Thu, 16 Apr 2026 15:16:28 +0200", "X-BeenThere": "u-boot@lists.denx.de", "X-Mailman-Version": "2.1.39", "Precedence": "list", "List-Id": "U-Boot discussion <u-boot.lists.denx.de>", "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>", "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>", "List-Post": "<mailto:u-boot@lists.denx.de>", "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>", "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>", "Errors-To": "u-boot-bounces@lists.denx.de", "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>", "X-Virus-Scanned": "clamav-milter 0.103.8 at phobos.denx.de", "X-Virus-Status": "Clean" }, "content": "Add basic SPL infrastructure for IPQ5210 SoC. This handles basic serial\nconsole init, identifying the boot media, loading the additional\nfirmware binaries to setup DDR, TFA and eventually jump to U-Boot.\n\nSigned-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>\n---\nv3: Move SMEM updates to separate patch\n Loop upto if_tbl->num_entries instead of MAX_ENTRIES\n Remove invalid 'if (!fit)' check\n Return failure if qclib_post_process_from_spl fails\n\nv2: Remove couple of unused local variables\n---\n arch/arm/Kconfig | 5 +-\n arch/arm/mach-snapdragon/Makefile | 3 +\n arch/arm/mach-snapdragon/spl.c | 640 ++++++++++++++++++++++++++++++\n 3 files changed, 646 insertions(+), 2 deletions(-)\n create mode 100644 arch/arm/mach-snapdragon/spl.c", "diff": "diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig\nindex 03416c55265..54fa4cb2dac 100644\n--- a/arch/arm/Kconfig\n+++ b/arch/arm/Kconfig\n@@ -1135,12 +1135,13 @@ config ARCH_SNAPDRAGON\n \tselect SPMI\n \tselect BOARD_LATE_INIT\n \tselect OF_BOARD\n-\tselect SAVE_PREV_BL_FDT_ADDR if !ENABLE_ARM_SOC_BOOT0_HOOK\n-\tselect LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK\n+\tselect SAVE_PREV_BL_FDT_ADDR if !ENABLE_ARM_SOC_BOOT0_HOOK && !SPL\n+\tselect LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK && !SPL\n \tselect SYSRESET\n \tselect SYSRESET_PSCI\n \tselect ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR\n \tselect MMU_PGPROT\n+\tselect SUPPORT_SPL\n \timply OF_UPSTREAM\n \timply CMD_DM\n \timply DM_USB_GADGET\ndiff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile\nindex 343e825c6fd..70a2ce585f2 100644\n--- a/arch/arm/mach-snapdragon/Makefile\n+++ b/arch/arm/mach-snapdragon/Makefile\n@@ -2,6 +2,9 @@\n #\n # (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>\n \n+ifndef CONFIG_XPL_BUILD\n obj-y += board.o\n obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += capsule_update.o\n obj-$(CONFIG_OF_LIVE) += of_fixup.o\n+endif\n+obj-$(CONFIG_SPL_BUILD) += spl.o\ndiff --git a/arch/arm/mach-snapdragon/spl.c b/arch/arm/mach-snapdragon/spl.c\nnew file mode 100644\nindex 00000000000..8cc28bbee82\n--- /dev/null\n+++ b/arch/arm/mach-snapdragon/spl.c\n@@ -0,0 +1,640 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/*\n+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.\n+ */\n+#include <hang.h>\n+#include <cpu_func.h>\n+#include <init.h>\n+#include <image.h>\n+#include <spl.h>\n+#include <spl_load.h>\n+#include <asm/io.h>\n+#include <asm/system.h>\n+#include <asm/sections.h>\n+#include <atf_common.h>\n+#include <linux/err.h>\n+#include <dm/device-internal.h>\n+#include <part.h>\n+#include <blk.h>\n+#include <dm/uclass.h>\n+\n+DECLARE_GLOBAL_DATA_PTR;\n+\n+#define QCOM_SPL_TCSR_REG_ADDR\t\t0x195c100\n+#define QCOM_SPL_DLOAD_MASK\t\tBIT(4)\n+#define QCOM_SPL_DLOAD_SHFT\t\t0x4\n+\n+#define QCOM_SPL_IS_DLOAD_BIT_SET\t((readl(QCOM_SPL_TCSR_REG_ADDR) & \\\n+\t\t\t\t\tQCOM_SPL_DLOAD_MASK) >> \\\n+\t\t\t\t\tQCOM_SPL_DLOAD_SHFT)\n+\n+#define QCOM_SPL_FIT_IMG_PARTITION\t\"0:BOOTLDR\"\n+\n+#define MAGIC_KEY\t\t\t\"QCLIB_CB\"\n+#define MAX_ENTRIES\t\t\t0xF\n+#define IF_TABLE_VERSION\t\t0x1\n+#define QCCONFIG\t\t\t\"qc_config\"\n+#define QCSDI\t\t\t\t\"qcsdi\"\n+\n+/**\n+ * struct interface_table_entry - Meta data for blobs in QCLIB interface\n+ * @entry_name:\tName of the data blob (e.g., \"dcb_settings\").\n+ * @address:\tAddress of the data blob.\n+ * @size:\tSize of the data blob.\n+ * @attributes:\tAttributes for the blob (e.g., save to storage).\n+ */\n+struct interface_table_entry {\n+\tchar entry_name[24];\n+\tu64 address;\n+\tu32 size;\n+\tu32 attributes;\n+};\n+\n+/**\n+ * struct interface_table - QCLIB Interface table header\n+ * @magic_key:\t\tMagic key for validation (\"QCLIB_CB\").\n+ * @version:\t\tInterface table version.\n+ * @num_entries:\tNumber of valid entries.\n+ * @max_entries:\tMaximum allowable entries.\n+ * @global_attributes:\tFlags for global attributes (e.g., SDI path).\n+ * @reserved1:\t\tReserved for future use.\n+ * @reserved2:\t\tReserved for future use.\n+ * @if_table_entries:\tArray of interface table entries.\n+ */\n+struct interface_table {\n+\tchar magic_key[8];\n+\tu32 version;\n+\tu32 num_entries;\n+\tu32 max_entries;\n+\tu32 global_attributes;\n+\tu32 reserved1;\n+\tu32 reserved2;\n+\tstruct interface_table_entry if_table_entries[MAX_ENTRIES];\n+};\n+\n+/**\n+ * qcom_spl_jump_img_entry_t - Type definition for image entry point functions.\n+ * @arg1:\tFirst argument passed to the entry point.\n+ * @arg2:\tSecond argument passed to the entry point.\n+ */\n+typedef void (*qcom_spl_jump_img_entry_t)(void *arg1, void *arg2);\n+\n+/*\n+ * Global QCSDI address populated by qclib_post_process_from_spl\n+ * Placed in .data section to ensure it persists\n+ */\n+static u64 g_qcsdi_address __section(\".data\");\n+\n+/**\n+ * lowlevel_init() - Early low-level initialization.\n+ *\n+ * This function performs very early hardware initialization,\n+ * specifically disabling the MMU if enabled by PBL.\n+ */\n+void lowlevel_init(void)\n+{\n+\tunsigned long sctlr;\n+\n+\tsctlr = get_sctlr();\n+\tset_sctlr(sctlr & ~(CR_M));\t/* Early disable the MMU */\n+}\n+\n+/**\n+ * qcom_spl_error_handler() - Centralized SPL error handler.\n+ * @arg:\tGeneric argument (unused).\n+ *\n+ * This function is invoked upon critical errors during the SPL boot process.\n+ */\n+void qcom_spl_error_handler(void *arg)\n+{\n+\tpr_err(\"Entered the SPL Error Handler\\n\");\n+\thang();\n+}\n+\n+/**\n+ * qcom_spl_malloc_init_f() - Initialize malloc for SPL.\n+ *\n+ * This function initializes the malloc subsystem using the memory region\n+ */\n+void qcom_spl_malloc_init_f(void)\n+{\n+\tif (!CONFIG_IS_ENABLED(SYS_MALLOC_F))\n+\t\treturn;\n+\t/*\n+\t * Set up by crt0.S\n+\t */\n+\tassert(gd->malloc_base);\n+\tgd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);\n+\tgd->malloc_ptr = 0;\n+\n+\tmem_malloc_init(gd->malloc_base, gd->malloc_limit);\n+\tgd->flags |= GD_FLG_FULL_MALLOC_INIT;\n+}\n+\n+/**\n+ * qcom_spl_get_fit_img_entry_point() - Get entry point from FIT image node.\n+ * @fit:\tPointer to the FIT image blob.\n+ * @node:\tNode ID within the FIT image.\n+ * @entry_point:Pointer to store the retrieved entry point.\n+ *\n+ * Return: 0 on success, or a negative error code on failure.\n+ */\n+static int qcom_spl_get_fit_img_entry_point(void *fit, int node,\n+\t\t\t\t\t u64 *entry_point)\n+{\n+\tint ret;\n+\n+\tif (!fit) {\n+\t\tpr_err(\"FIT image blob is NULL\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tif (node <= 0) {\n+\t\tpr_err(\"Invalid FIT node ID %d\\n\", node);\n+\t\treturn -EINVAL;\n+\t}\n+\tif (!entry_point) {\n+\t\tpr_err(\"Entry point pointer is NULL\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = fit_image_get_entry(fit, node, (ulong *)entry_point);\n+\tif (ret) {\n+\t\tpr_debug(\"No entry point for node %d, trying load address\\n\",\n+\t\t\t node);\n+\t\tret = fit_image_get_load(fit, node, (ulong *)entry_point);\n+\t\tif (ret)\n+\t\t\tpr_err(\"No load address for node %d (%d)\\n\", node, ret);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+/**\n+ * qcom_spl_get_iftbl_entry_by_name() - Get an interface table entry by name.\n+ * @if_tbl:\tPointer to the QCLIB interface table.\n+ * @name:\tName of the entry to find.\n+ * @entry:\tPointer to a buffer where the found entry will be copied.\n+ *\n+ * Return: 0 on success, or a negative error code on failure.\n+ */\n+static int qcom_spl_get_iftbl_entry_by_name(struct interface_table *if_tbl,\n+\t\t\t\t\t char *name,\n+\t\t\t\t\t struct interface_table_entry *entry)\n+{\n+\tuint uc_index;\n+\n+\tif (!if_tbl) {\n+\t\tpr_err(\"Invalid interface table\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tif (!name) {\n+\t\tpr_err(\"Invalid name\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tif (!entry) {\n+\t\tpr_err(\"Invalid entry pointer\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (uc_index = 0; uc_index < if_tbl->num_entries; uc_index++) {\n+\t\tif (!strcmp(if_tbl->if_table_entries[uc_index].entry_name, name)) {\n+\t\t\tmemcpy(entry,\n+\t\t\t &if_tbl->if_table_entries[uc_index],\n+\t\t\t sizeof(struct interface_table_entry));\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\tpr_err(\"Interface table entry '%s' not found\\n\", name);\n+\n+\treturn -ENOENT;\n+}\n+\n+/**\n+ * qclib_post_process_from_spl() - Post-process QCLIB image from SPL FIT address\n+ *\n+ * This function performs the same operations as qclib_post_process() but\n+ * takes no arguments. It gets the FIT image from CONFIG_SPL_LOAD_FIT_ADDRESS\n+ * and finds the qclib_1 node automatically.\n+ *\n+ * Return: 0 on success, or a negative error code on failure.\n+ */\n+int qclib_post_process_from_spl(void)\n+{\n+\tint ret;\n+\tint entry_idx;\n+\tint images_node;\n+\tint qcconfig_node;\n+\tint qclib_node;\n+\tconst void *fit;\n+\tstruct interface_table if_tbl;\n+\tstruct interface_table_entry qcsdi_entry;\n+\tqcom_spl_jump_img_entry_t qclib_entry;\n+\tu64 entry_point;\n+\n+\t/* Get FIT image from SPL load address */\n+\tfit = (const void *)CONFIG_SPL_LOAD_FIT_ADDRESS;\n+\n+\tpr_debug(\"QCLIB post-processing from SPL: fit=%p\\n\", fit);\n+\n+\t/*\n+\t * Find \"images\" node in FIT (get it once and reuse)\n+\t */\n+\timages_node = fdt_subnode_offset(fit, 0, \"images\");\n+\tif (images_node < 0) {\n+\t\tpr_err(\"Failed to find images node in FIT\\n\");\n+\t\treturn -ENOENT;\n+\t}\n+\n+\t/*\n+\t * Find \"qcconfig_1\" image node\n+\t */\n+\tqcconfig_node = fdt_subnode_offset(fit, images_node, \"qcconfig_1\");\n+\tif (qcconfig_node < 0) {\n+\t\tpr_err(\"Failed to find qcconfig_1 node in FIT\\n\");\n+\t\treturn -ENOENT;\n+\t}\n+\n+\t/*\n+\t * Find \"qclib_1\" image node\n+\t */\n+\tqclib_node = fdt_subnode_offset(fit, images_node, \"qclib_1\");\n+\tif (qclib_node < 0) {\n+\t\tpr_err(\"Failed to find qclib_1 node in FIT\\n\");\n+\t\treturn -ENOENT;\n+\t}\n+\n+\t/*\n+\t * Initialize the local interface table\n+\t */\n+\tmemset(&if_tbl, 0, sizeof(struct interface_table));\n+\tmemcpy(if_tbl.magic_key, MAGIC_KEY, strlen(MAGIC_KEY));\n+\n+\tif_tbl.version = IF_TABLE_VERSION;\n+\tif_tbl.num_entries = 0;\n+\tif_tbl.max_entries = MAX_ENTRIES;\n+\n+\t/*\n+\t * Add QCCONFIG entry to the interface table\n+\t */\n+\tentry_idx = 0;\n+\tmemcpy(if_tbl.if_table_entries[entry_idx].entry_name,\n+\t QCCONFIG, strlen(QCCONFIG));\n+\n+\tret = qcom_spl_get_fit_img_entry_point((void *)fit,\n+\t\t\t\t\t qcconfig_node,\n+\t\t\t\t\t &if_tbl.if_table_entries[entry_idx].address);\n+\tif (ret) {\n+\t\tpr_err(\"Failed to get qcconfig_1 entry point (%d)\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\tif_tbl.if_table_entries[entry_idx].attributes = 0;\n+\tif_tbl.num_entries = entry_idx + 1;\n+\n+\t/*\n+\t * Add QCSDI entry to the interface table\n+\t */\n+\tentry_idx++;\n+\tmemcpy(if_tbl.if_table_entries[entry_idx].entry_name,\n+\t QCSDI, strlen(QCSDI));\n+\n+\tif_tbl.if_table_entries[entry_idx].address = 0;\n+\tif_tbl.if_table_entries[entry_idx].attributes = 0;\n+\tif_tbl.num_entries = entry_idx + 1;\n+\n+\t/*\n+\t * Get qclib_1 entry point\n+\t */\n+\tret = qcom_spl_get_fit_img_entry_point((void *)fit,\n+\t\t\t\t\t qclib_node,\n+\t\t\t\t\t &entry_point);\n+\tif (ret) {\n+\t\tpr_err(\"Failed to get qclib_1 entry point (%d)\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tqclib_entry = (qcom_spl_jump_img_entry_t)entry_point;\n+\n+\tpr_info(\"Jumping to qclib_1 at 0x%llx\\n\", entry_point);\n+\tqclib_entry(&if_tbl, NULL);\n+\n+\t/* Parse the interface table to extract QCSDI address */\n+\tret = qcom_spl_get_iftbl_entry_by_name(&if_tbl, QCSDI, &qcsdi_entry);\n+\tif (ret) {\n+\t\tpr_err(\"Failed to get QCSDI entry from interface table (%d)\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tg_qcsdi_address = qcsdi_entry.address;\n+\tpr_info(\"QCSDI address: 0x%llx\\n\", g_qcsdi_address);\n+\n+\treturn 0;\n+}\n+\n+\n+/**\n+ * spl_get_load_buffer() - Allocate a cache-aligned buffer for image loading.\n+ * @offset:\tOffset (unused, typically 0 for SPL).\n+ * @size:\tSize of the buffer to allocate.\n+ *\n+ * Return: Pointer to the allocated buffer, or NULL on failure.\n+ */\n+struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size)\n+{\n+\treturn (void *)(CONFIG_SPL_LOAD_FIT_ADDRESS);\n+}\n+\n+/**\n+ * board_spl_fit_buffer_addr() - Get the address of the FIT image buffer.\n+ * @fit_size:\tSize of the FIT image.\n+ * @sectors:\tNumber of sectors.\n+ * @bl_len:\tBlock length.\n+ *\n+ * Return: Address of the FIT image buffer.\n+ */\n+void *board_spl_fit_buffer_addr(ulong fit_size, int sectors, int bl_len)\n+{\n+\tvoid *buffer = spl_get_load_buffer(0, sectors * bl_len);\n+\n+\tif (!buffer) {\n+\t\tpr_err(\"Failed to get FIT load buffer\\n\");\n+\t\tqcom_spl_error_handler(NULL);\n+\t}\n+\n+\treturn buffer;\n+}\n+\n+/**\n+ * bl2_plat_get_bl31_params_v2() - Retrieve and fixup BL31 parameters.\n+ * @bl32_entry:\tEntry point for BL32 (OP-TEE).\n+ * @bl33_entry:\tEntry point for BL33 (U-Boot/kernel).\n+ * @fdt_addr:\tAddress of the Device Tree Blob (FDT).\n+ *\n+ * Return: Pointer to the populated BL31 parameters structure.\n+ */\n+struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry,\n+\t\t\t\t\t uintptr_t bl33_entry,\n+\t\t\t\t\t uintptr_t fdt_addr)\n+{\n+\tstruct bl_params *bl_params;\n+\tstruct bl_params_node *node;\n+\n+\t/*\n+\t * Populate the bl31 params with default values.\n+\t */\n+\tbl_params = bl2_plat_get_bl31_params_v2_default(bl32_entry, bl33_entry,\n+\t\t\t\t\t\t\tfdt_addr);\n+\n+\t/*\n+\t * Fixup the bl31 params based on platform requirements.\n+\t */\n+\tfor_each_bl_params_node(bl_params, node) {\n+\t\tif (node->image_id == ATF_BL31_IMAGE_ID) {\n+\t\t\t/*\n+\t\t\t * Pass QCSDI address to BL31 via arg0\n+\t\t\t * This address was populated by qclib_post_process()\n+\t\t\t */\n+\t\t\tif (g_qcsdi_address == 0)\n+\t\t\t\tpr_warn(\"QCSDI address not set, BL31 may not function correctly\\n\");\n+\n+\t\t\tnode->ep_info->args.arg0 = g_qcsdi_address;\n+\t\t\tpr_debug(\"Setting BL31 arg0 to QCSDI address: 0x%llx\\n\", g_qcsdi_address);\n+\t\t}\n+\t}\n+\n+\treturn bl_params;\n+}\n+\n+/**\n+ * qcom_spl_loader_pre_ddr() - SPL loader for pre-DDR stage.\n+ * @boot_device:Type of boot device.\n+ *\n+ * Return: 0 on success, or a negative error code on failure.\n+ */\n+static int qcom_spl_loader_pre_ddr(u8 boot_device)\n+{\n+\tstruct spl_image_loader *loader, *drv;\n+\tstruct spl_image_info spl_image = { 0 };\n+\tstruct spl_boot_device boot_dev = { .boot_device = boot_device, };\n+\tint ret = -ENODEV, n_ents;\n+\n+\tdrv = ll_entry_start(struct spl_image_loader, spl_image_loader);\n+\tn_ents = ll_entry_count(struct spl_image_loader, spl_image_loader);\n+\n+\tfor (loader = drv; loader && (loader != drv + n_ents); loader++) {\n+\t\tif (boot_device != loader->boot_device)\n+\t\t\tcontinue;\n+\n+\t\tret = loader->load_image(&spl_image, &boot_dev);\n+\t\tif (!ret)\n+\t\t\tbreak;\n+\n+\t\tprintf(\"%s: Error: %d\\n\", __func__, ret);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+/**\n+ * spl_find_partition_info() - Find partition information by name\n+ * @uclass_id: Device class ID (UCLASS_MMC)\n+ * @device_num: Device number within the class\n+ * @part_name: Name of the partition to find\n+ * @info: Pointer to store partition information\n+ *\n+ * This function provides partition lookup logic for MMC.\n+ * Return: Partition number on success, negative error code on failure\n+ */\n+static int spl_find_partition_info(enum uclass_id uclass_id, int device_num,\n+\t\t\t\t const char *part_name,\n+\t\t\t\t struct disk_partition *info)\n+{\n+\tint ret;\n+\tstruct blk_desc *desc;\n+\n+\tif (!part_name || !info) {\n+\t\tprintf(\"Invalid parameters for partition lookup\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/*\n+\t * Get block device descriptor\n+\t */\n+\tdesc = blk_get_devnum_by_uclass_id(uclass_id, device_num);\n+\tif (!desc) {\n+\t\tprintf(\"Block device not found for class %d, device %d\\n\",\n+\t\t uclass_id, device_num);\n+\t\treturn -ENODEV;\n+\t}\n+\n+\t/*\n+\t * Initialize partition table if needed\n+\t */\n+\tif (desc->part_type == PART_TYPE_UNKNOWN) {\n+\t\tprintf(\"Initializing partition table\\n\");\n+\t\t/*\n+\t\t * Prefer EFI/GPT\n+\t\t */\n+\t\tdesc->part_type = PART_TYPE_EFI;\n+\t}\n+\n+\t/*\n+\t * Find partition by name\n+\t */\n+\tret = part_get_info_by_name(desc, part_name, info);\n+\tif (ret < 0) {\n+\t\tprintf(\"Partition '%s' not found\\n\", part_name);\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tprintf(\"Found partition '%s' at partition number %d\\n\", part_name, ret);\n+\treturn ret;\n+}\n+\n+#if CONFIG_IS_ENABLED(MMC)\n+/**\n+ * spl_mmc_boot_mode() - Determine the boot mode for MMC\n+ * @mmc:\tPointer to the MMC device\n+ * @boot_device:\tBoot device ID\n+ *\n+ * Return: MMCSD_MODE_RAW to use raw partition access\n+ */\n+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)\n+{\n+\treturn MMCSD_MODE_RAW;\n+}\n+\n+/**\n+ * spl_mmc_boot_partition() - Determine which partition to boot from\n+ * @boot_device:\tBoot device ID\n+ *\n+ * Return: Partition number to boot from, or default partition on error\n+ */\n+int spl_mmc_boot_partition(const u32 boot_device)\n+{\n+\tint ret;\n+\tstruct disk_partition info;\n+\n+\t/*\n+\t * Use common partition lookup function\n+\t */\n+\tret = spl_find_partition_info(UCLASS_MMC, 0, QCOM_SPL_FIT_IMG_PARTITION, &info);\n+\tif (ret < 0) {\n+\t\tprintf(\"Using default MMC partition %d\\n\",\n+\t\t CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION);\n+\t\treturn CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+/**\n+ * spl_mmc_get_uboot_raw_sector() - Find the raw sector offset\n+ * @mmc:\tPointer to the MMC device\n+ * @raw_sect:\tSector\n+ *\n+ * Return: 0 if the image is at the starting of the partition without any offset.\n+ */\n+unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc, ulong raw_sect)\n+{\n+\treturn 0;\n+}\n+#endif /* CONFIG_IS_ENABLED(MMC) */\n+\n+/**\n+ * spl_boot_device() - Determine the boot device.\n+ *\n+ * Return: The mapped boot device type,\n+ *\t or BOOT_DEVICE_NONE if the device is invalid.\n+ */\n+u32 spl_boot_device(void)\n+{\n+\tif (IS_ENABLED(CONFIG_SPL_MMC)) {\n+\t\tprintf(\"Selected boot device: MMC\\n\");\n+\t\treturn BOOT_DEVICE_MMC1;\n+\t}\n+\n+\tpr_err(\"No boot device configured\\n\");\n+\treturn BOOT_DEVICE_NONE;\n+}\n+\n+#if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_FRAMEWORK_BOARD_INIT_F)\n+/**\n+ * board_init_f() - Main entry point for SPL.\n+ * @dummy:\tDummy argument (unused).\n+ */\n+void board_init_f(ulong dummy)\n+{\n+\tint ret;\n+\n+\tmemset(__bss_start, 0, __bss_end - __bss_start); /* Clear BSS */\n+\n+\tqcom_spl_malloc_init_f();\n+\n+\tret = spl_early_init();\n+\tif (ret) {\n+\t\tpr_debug(\"spl_early_init() failed (%d)\\n\", ret);\n+\t\tgoto fail;\n+\t}\n+\n+\tpreloader_console_init();\n+\n+\tret = qcom_spl_loader_pre_ddr(spl_boot_device());\n+\tif (ret) {\n+\t\tpr_debug(\"qcom_spl_loader_pre_ddr() failed (%d)\\n\", ret);\n+\t\tgoto fail;\n+\t}\n+\n+\tret = qclib_post_process_from_spl();\n+\tif (ret) {\n+\t\tpr_debug(\"qclib_post_process_from_spl() failed (%d)\\n\", ret);\n+\t\tgoto fail;\n+\t}\n+\n+\tboard_init_r(NULL, 0);\n+\n+fail:\n+\tif (ret)\n+\t\tqcom_spl_error_handler(NULL);\n+}\n+#endif /* CONFIG_SPL_BUILD && !defined(CONFIG_SPL_FRAMEWORK_BOARD_INIT_F) */\n+\n+int board_fit_config_name_match(const char *name)\n+{\n+\t/*\n+\t * SPL loads the pre-HLOS images from bootldr FIT image\n+\t * as below\n+\t *\n+\t * In board_init_f() - Matches \"pre-ddr\" configuration node and\n+\t * load the images mentioned in its <loadables>\n+\t *\n+\t * In board_init_r() - Matches \"post-ddr\" configuration node and\n+\t * load the images mentioned in its <loadables>\n+\t *\n+\t */\n+\tif (!(gd->flags & GD_FLG_SPL_INIT)) {\n+\t\tif (!strcmp(name, \"pre-ddr\")) {\n+\t\t\tprintf(\"Selected FIT Config: %s\\n\", name);\n+\t\t\treturn 0;\n+\t\t}\n+\t} else {\n+\t\tif (!strcmp(name, \"post-ddr\")) {\n+\t\t\tprintf(\"Selected FIT Config: %s\\n\", name);\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\n+\treturn -EINVAL;\n+}\n+\n+int board_fdt_blob_setup(void **fdtp)\n+{\n+\treturn 0;\n+}\n+\n+void reset_cpu(void)\n+{\n+\t/*\n+\t * Empty placeholder for arch/arm/lib/reset.c:do_reset(),\n+\t * to avoid \"undefined reference to `reset_cpu'\"\n+\t */\n+}\n", "prefixes": [ "v3", "06/10" ] }