Merge tag 'qcom-next-20250324' of https://gitlab.denx.de/u-boot/custodians/u-boot-snapdragon into next
qcom-next-20230324: * msm8916 gets proper sysreset and spin-table support * The first new IPQ platform is added - the IPQ9574. The IPQ series are used in routers. The flashing process is also documented * mach-snapdragon gains the ability to boot with an internal FDT and still parse memory from an externally provided one * SC7280 gets a pinctrl driver and various clock driver improvements. * Qualcom clock drivers will now actually return an error when attempting to enable a clock which isn't described. * Qualcomm pinctrl drivers will now return an error when attempting to configure an invalid function mux
This commit is contained in:
@@ -1117,6 +1117,8 @@ config ARCH_SNAPDRAGON
|
||||
select OF_BOARD
|
||||
select SAVE_PREV_BL_FDT_ADDR
|
||||
select LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK
|
||||
select SYSRESET
|
||||
select SYSRESET_PSCI
|
||||
imply OF_UPSTREAM
|
||||
imply CMD_DM
|
||||
|
||||
|
25
arch/arm/dts/ipq9574-rdp433-u-boot.dtsi
Normal file
25
arch/arm/dts/ipq9574-rdp433-u-boot.dtsi
Normal file
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
/*
|
||||
* Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
/ {
|
||||
/* Will be removed when SMEM parsing is updated */
|
||||
memory@40000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x40000000 0x0 0x40000000>,
|
||||
<0x0 0x4a500000 0x0 0x00100000>;
|
||||
};
|
||||
};
|
||||
|
||||
&sdhc_1 {
|
||||
sdhci-caps-mask = <0x0 0x04000000>;
|
||||
sdhci-caps = <0x0 0x04000000>; /* SDHCI_CAN_VDD_180 */
|
||||
|
||||
/*
|
||||
* This reset is needed to clear out the settings done by
|
||||
* previous boot loader. Without this the SDHCI_RESET_ALL
|
||||
* reset done sdhci_init() times out.
|
||||
*/
|
||||
resets = <&gcc GCC_SDCC_BCR>;
|
||||
};
|
@@ -88,7 +88,29 @@ int dram_init_banksize(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qcom_parse_memory(const void *fdt)
|
||||
/**
|
||||
* The generic memory parsing code in U-Boot lacks a few things that we
|
||||
* need on Qualcomm:
|
||||
*
|
||||
* 1. It sets gd->ram_size and gd->ram_base to represent a single memory block
|
||||
* 2. setup_dest_addr() later relocates U-Boot to ram_base + ram_size, the end
|
||||
* of that first memory block.
|
||||
*
|
||||
* This results in all memory beyond U-Boot being unusable in Linux when booting
|
||||
* with EFI.
|
||||
*
|
||||
* Since the ranges in the memory node may be out of order, the only way for us
|
||||
* to correctly determine the relocation address for U-Boot is to parse all
|
||||
* memory regions and find the highest valid address.
|
||||
*
|
||||
* We can't use fdtdec_setup_memory_banksize() since it stores the result in
|
||||
* gd->bd, which is not yet allocated.
|
||||
*
|
||||
* @fdt: FDT blob to parse /memory node from
|
||||
*
|
||||
* Return: 0 on success or -ENODATA if /memory node is missing or incomplete
|
||||
*/
|
||||
static int qcom_parse_memory(const void *fdt)
|
||||
{
|
||||
int offset;
|
||||
const fdt64_t *memory;
|
||||
@@ -97,16 +119,12 @@ static void qcom_parse_memory(const void *fdt)
|
||||
int i, j, banks;
|
||||
|
||||
offset = fdt_path_offset(fdt, "/memory");
|
||||
if (offset < 0) {
|
||||
log_err("No memory node found in device tree!\n");
|
||||
return;
|
||||
}
|
||||
if (offset < 0)
|
||||
return -ENODATA;
|
||||
|
||||
memory = fdt_getprop(fdt, offset, "reg", &memsize);
|
||||
if (!memory) {
|
||||
log_err("No memory configuration was provided by the previous bootloader!\n");
|
||||
return;
|
||||
}
|
||||
if (!memory)
|
||||
return -ENODATA;
|
||||
|
||||
banks = min(memsize / (2 * sizeof(u64)), (ulong)CONFIG_NR_DRAM_BANKS);
|
||||
|
||||
@@ -119,7 +137,6 @@ static void qcom_parse_memory(const void *fdt)
|
||||
for (i = 0, j = 0; i < banks * 2; i += 2, j++) {
|
||||
prevbl_ddr_banks[j].start = get_unaligned_be64(&memory[i]);
|
||||
prevbl_ddr_banks[j].size = get_unaligned_be64(&memory[i + 1]);
|
||||
/* SM8650 boards sometimes have empty regions! */
|
||||
if (!prevbl_ddr_banks[j].size) {
|
||||
j--;
|
||||
continue;
|
||||
@@ -127,13 +144,16 @@ static void qcom_parse_memory(const void *fdt)
|
||||
ram_end = max(ram_end, prevbl_ddr_banks[j].start + prevbl_ddr_banks[j].size);
|
||||
}
|
||||
|
||||
if (!banks || !prevbl_ddr_banks[0].size)
|
||||
return -ENODATA;
|
||||
|
||||
/* Sort our RAM banks -_- */
|
||||
qsort(prevbl_ddr_banks, banks, sizeof(prevbl_ddr_banks[0]), ddr_bank_cmp);
|
||||
|
||||
gd->ram_base = prevbl_ddr_banks[0].start;
|
||||
gd->ram_size = ram_end - gd->ram_base;
|
||||
debug("ram_base = %#011lx, ram_size = %#011llx, ram_end = %#011llx\n",
|
||||
gd->ram_base, gd->ram_size, ram_end);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void show_psci_version(void)
|
||||
@@ -142,24 +162,56 @@ static void show_psci_version(void)
|
||||
|
||||
arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
|
||||
|
||||
/* Some older SoCs like MSM8916 don't always support PSCI */
|
||||
if ((int)res.a0 == PSCI_RET_NOT_SUPPORTED)
|
||||
return;
|
||||
|
||||
debug("PSCI: v%ld.%ld\n",
|
||||
PSCI_VERSION_MAJOR(res.a0),
|
||||
PSCI_VERSION_MINOR(res.a0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Most MSM8916 devices in the wild shipped without PSCI support, but the
|
||||
* upstream DTs pretend that PSCI exists. If that situation is detected here,
|
||||
* the /psci node is deleted. This is done very early to ensure the PSCI
|
||||
* firmware driver doesn't bind (which then binds a sysreset driver that won't
|
||||
* work).
|
||||
*/
|
||||
static void qcom_psci_fixup(void *fdt)
|
||||
{
|
||||
int offset, ret;
|
||||
struct arm_smccc_res res;
|
||||
|
||||
arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
|
||||
|
||||
if ((int)res.a0 != PSCI_RET_NOT_SUPPORTED)
|
||||
return;
|
||||
|
||||
offset = fdt_path_offset(fdt, "/psci");
|
||||
if (offset < 0)
|
||||
return;
|
||||
|
||||
debug("Found /psci DT node on device with no PSCI. Deleting.\n");
|
||||
ret = fdt_del_node(fdt, offset);
|
||||
if (ret)
|
||||
log_err("Failed to delete /psci node: %d\n", ret);
|
||||
}
|
||||
|
||||
/* We support booting U-Boot with an internal DT when running as a first-stage bootloader
|
||||
* or for supporting quirky devices where it's easier to leave the downstream DT in place
|
||||
* to improve ABL compatibility. Otherwise, we use the DT provided by ABL.
|
||||
*/
|
||||
int board_fdt_blob_setup(void **fdtp)
|
||||
{
|
||||
struct fdt_header *fdt;
|
||||
struct fdt_header *external_fdt, *internal_fdt;
|
||||
bool internal_valid, external_valid;
|
||||
int ret = 0;
|
||||
int ret = -ENODATA;
|
||||
|
||||
fdt = (struct fdt_header *)get_prev_bl_fdt_addr();
|
||||
external_valid = fdt && !fdt_check_header(fdt);
|
||||
internal_valid = !fdt_check_header(*fdtp);
|
||||
internal_fdt = (struct fdt_header *)*fdtp;
|
||||
external_fdt = (struct fdt_header *)get_prev_bl_fdt_addr();
|
||||
external_valid = external_fdt && !fdt_check_header(external_fdt);
|
||||
internal_valid = !fdt_check_header(internal_fdt);
|
||||
|
||||
/*
|
||||
* There is no point returning an error here, U-Boot can't do anything useful in this situation.
|
||||
@@ -167,31 +219,42 @@ int board_fdt_blob_setup(void **fdtp)
|
||||
*/
|
||||
if (!internal_valid && !external_valid)
|
||||
panic("Internal FDT is invalid and no external FDT was provided! (fdt=%#llx)\n",
|
||||
(phys_addr_t)fdt);
|
||||
(phys_addr_t)external_fdt);
|
||||
|
||||
/* Prefer memory information from internal DT if it's present */
|
||||
if (internal_valid)
|
||||
ret = qcom_parse_memory(internal_fdt);
|
||||
|
||||
if (ret < 0 && external_valid) {
|
||||
/* No internal FDT or it lacks a proper /memory node.
|
||||
* The previous bootloader handed us something, let's try that.
|
||||
*/
|
||||
if (internal_valid)
|
||||
debug("No memory info in internal FDT, falling back to external\n");
|
||||
|
||||
ret = qcom_parse_memory(external_fdt);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
panic("No valid memory ranges found!\n");
|
||||
|
||||
debug("ram_base = %#011lx, ram_size = %#011llx\n",
|
||||
gd->ram_base, gd->ram_size);
|
||||
|
||||
if (internal_valid) {
|
||||
debug("Using built in FDT\n");
|
||||
ret = -EEXIST;
|
||||
} else {
|
||||
debug("Using external FDT\n");
|
||||
/* So we can use it before returning */
|
||||
*fdtp = fdt;
|
||||
*fdtp = external_fdt;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the /memory node while we're here,
|
||||
* this makes it easy to do other things early.
|
||||
*/
|
||||
qcom_parse_memory(*fdtp);
|
||||
qcom_psci_fixup(*fdtp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void reset_cpu(void)
|
||||
{
|
||||
psci_system_reset();
|
||||
}
|
||||
|
||||
/*
|
||||
* Some Qualcomm boards require GPIO configuration when switching USB modes.
|
||||
* Support setting this configuration via pinctrl state.
|
||||
|
@@ -97,6 +97,7 @@ CONFIG_PINCTRL_QCOM_APQ8016=y
|
||||
CONFIG_PINCTRL_QCOM_APQ8096=y
|
||||
CONFIG_PINCTRL_QCOM_QCM2290=y
|
||||
CONFIG_PINCTRL_QCOM_QCS404=y
|
||||
CONFIG_PINCTRL_QCOM_SC7280=y
|
||||
CONFIG_PINCTRL_QCOM_SDM845=y
|
||||
CONFIG_PINCTRL_QCOM_SM6115=y
|
||||
CONFIG_PINCTRL_QCOM_SM8150=y
|
||||
@@ -120,6 +121,7 @@ CONFIG_QCOM_RPMH=y
|
||||
CONFIG_SPMI_MSM=y
|
||||
CONFIG_SYSINFO=y
|
||||
CONFIG_SYSINFO_SMBIOS=y
|
||||
CONFIG_SYSRESET_QCOM_PSHOLD=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_XHCI_DWC3=y
|
||||
|
83
configs/qcom_ipq9574_mmc_defconfig
Normal file
83
configs/qcom_ipq9574_mmc_defconfig
Normal file
@@ -0,0 +1,83 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SKIP_LOWLEVEL_INIT=y
|
||||
CONFIG_POSITION_INDEPENDENT=y
|
||||
CONFIG_SYS_INIT_SP_BSS_OFFSET=1572864
|
||||
CONFIG_ARCH_SNAPDRAGON=y
|
||||
CONFIG_NR_DRAM_BANKS=24
|
||||
CONFIG_DEFAULT_DEVICE_TREE="qcom/ipq9574-rdp433"
|
||||
CONFIG_SYS_LOAD_ADDR=0x50000000
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_VERBOSE=y
|
||||
# CONFIG_EFI_LOADER is not set
|
||||
# CONFIG_EFI_BINARY_EXEC is not set
|
||||
# CONFIG_EFI_VARIABLE_FILE_STORE is not set
|
||||
# CONFIG_PXE_UTILS is not set
|
||||
# CONFIG_BOOTSTD is not set
|
||||
# CONFIG_BOOTMETH_VBE is not set
|
||||
CONFIG_BOOTDELAY=2
|
||||
CONFIG_OF_BOARD_SETUP=y
|
||||
CONFIG_USE_PREBOOT=y
|
||||
CONFIG_SYS_CBSIZE=512
|
||||
CONFIG_LOG_MAX_LEVEL=9
|
||||
CONFIG_LOG_DEFAULT_LEVEL=4
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_PART=y
|
||||
CONFIG_OF_LIVE=y
|
||||
CONFIG_USE_DEFAULT_ENV_FILE=y
|
||||
CONFIG_DEFAULT_ENV_FILE="board/qualcomm/default.env"
|
||||
CONFIG_CLK=y
|
||||
CONFIG_CLK_QCOM_IPQ9574=y
|
||||
CONFIG_DFU_MMC=y
|
||||
CONFIG_DFU_SCSI=y
|
||||
CONFIG_SYS_DFU_DATA_BUF_SIZE=0x200000
|
||||
CONFIG_MSM_GPIO=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCONF=y
|
||||
CONFIG_PINCTRL_QCOM_IPQ9574=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_ADMA=y
|
||||
CONFIG_MMC_SDHCI_MSM=y
|
||||
CONFIG_DM_MDIO=y
|
||||
CONFIG_DM_ETH_PHY=y
|
||||
CONFIG_DWC_ETH_QOS=y
|
||||
CONFIG_DWC_ETH_QOS_QCOM=y
|
||||
CONFIG_RGMII=y
|
||||
CONFIG_PHY=y
|
||||
CONFIG_PHY_QCOM_QMP_UFS=y
|
||||
CONFIG_PHY_QCOM_QUSB2=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_MSM_SERIAL=y
|
||||
CONFIG_MSM_GENI_SERIAL=y
|
||||
CONFIG_SOC_QCOM=y
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_DEBUG_UART_ANNOUNCE=y
|
||||
CONFIG_DEBUG_UART_BASE=0x78b1000
|
||||
CONFIG_DEBUG_UART_MSM=y
|
||||
CONFIG_DEBUG_UART_CLOCK=1843200
|
||||
CONFIG_TEXT_BASE=0x4A240000
|
||||
CONFIG_REMAKE_ELF=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_VERBOSE=y
|
||||
CONFIG_BOOTSTD_FULL=y
|
||||
CONFIG_SYS_CBSIZE=1024
|
||||
CONFIG_SYS_PBSIZE=1024
|
||||
CONFIG_OF_LIVE=y
|
||||
CONFIG_MSM_SERIAL=y
|
||||
CONFIG_DM_EVENT=y
|
||||
CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_ENV_SIZE=0x40000
|
||||
CONFIG_ENV_OFFSET=0
|
||||
CONFIG_PARTITIONS=y
|
||||
CONFIG_PARTITION_UUIDS=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_PARTS=y
|
||||
CONFIG_HUSH_PARSER=y
|
||||
CONFIG_PARTITIONS=y
|
||||
CONFIG_EFI_PARTITION=y
|
||||
# CONFIG_I2C is not set
|
||||
# CONFIG_INPUT is not set
|
||||
# CONFIG_SCSI is not set
|
||||
# CONFIG_SPMI is not set
|
@@ -10,3 +10,4 @@ Qualcomm
|
||||
rb3gen2
|
||||
board
|
||||
debugging
|
||||
rdp
|
||||
|
55
doc/board/qualcomm/rdp.rst
Normal file
55
doc/board/qualcomm/rdp.rst
Normal file
@@ -0,0 +1,55 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
.. sectionauthor:: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
|
||||
Qualcomm Reference Design Platform (RDP)
|
||||
========================================
|
||||
|
||||
Qualcomm RDPs are development boards based on the Qualcomm IPQ series of
|
||||
SoCs. These SoCs are used as the application processors in WiFi router
|
||||
platforms. RDPs come in multiple variants with differences in storage
|
||||
medium (NOR, NAND, MMC), no. of USB and PCIe ports, n/w ports etc.
|
||||
|
||||
.. _Qualcomm's product page: https://www.qualcomm.com/products/internet-of-things/networking/wi-fi-networks/networking-pro-series/qualcomm-networking-pro-820-platform
|
||||
|
||||
Installation
|
||||
------------
|
||||
First, setup ``CROSS_COMPILE`` for aarch64. Then, build U-Boot for ``IPQ9574``::
|
||||
|
||||
$ export CROSS_COMPILE=<aarch64 toolchain prefix>
|
||||
$ make qcom_ipq9574_mmc_defconfig
|
||||
$ make -j8
|
||||
|
||||
This will build ``u-boot.elf`` in the configured output directory.
|
||||
|
||||
Although the RDPs do not have secure boot set up by default, the firmware still
|
||||
expects firmware ELF images to be "signed". The signature does not provide any
|
||||
security in this case, but it provides the firmware with some required metadata.
|
||||
|
||||
To "sign" ``u-boot.elf`` you can use e.g. `qtestsign`_::
|
||||
|
||||
$ qtestsign -v6 aboot -o u-boot.mbn u-boot.elf
|
||||
|
||||
Then install the resulting ``u-boot.mbn`` to the ``0:APPSBL`` partition
|
||||
on your device with::
|
||||
|
||||
IPQ9574# tftpboot path/to/u-boot.mbn
|
||||
IPQ9574# mmc part (note down the start & end block no.s of '0:APPSBL' partition)
|
||||
IPQ9574# mmc erase <start blk no> <count>
|
||||
IPQ9574# mmc write $fileaddr <blk no> <count>
|
||||
|
||||
U-Boot should be running after a reboot (``reset``).
|
||||
|
||||
.. WARNING
|
||||
Boards with newer software versions would automatically go the emergency
|
||||
download (EDL) mode if U-Boot is not functioning as expected. If its a
|
||||
runtime failure at Uboot, the system will get reset (due to watchdog)
|
||||
and XBL will try to boot from next bank and if Bank B also doesn't have
|
||||
a functional image and is not booting fine, then the system will enter
|
||||
EDL. A tool like bkerler's `edl`_ can be used for flashing with the
|
||||
firehose loader binary appropriate for the board.
|
||||
|
||||
Note that the support added is very basic. Restoring the original U-Boot
|
||||
on boards with older version of the software requires a debugger.
|
||||
|
||||
.. _qtestsign: https://github.com/msm8916-mainline/qtestsign
|
||||
.. _edl: https://github.com/bkerler/edl
|
@@ -50,6 +50,7 @@ static struct clk_ops stub_clk_ops = {
|
||||
|
||||
static const struct udevice_id stub_clk_ids[] = {
|
||||
{ .compatible = "qcom,rpmcc" },
|
||||
{ .compatible = "qcom,sc7280-rpmh-clk" },
|
||||
{ .compatible = "qcom,sm8150-rpmh-clk" },
|
||||
{ .compatible = "qcom,sm8250-rpmh-clk" },
|
||||
{ .compatible = "qcom,sm8550-rpmh-clk" },
|
||||
|
@@ -31,6 +31,14 @@ config CLK_QCOM_IPQ4019
|
||||
on the Snapdragon IPQ4019 SoC. This driver supports the clocks
|
||||
and resets exposed by the GCC hardware block.
|
||||
|
||||
config CLK_QCOM_IPQ9574
|
||||
bool "Qualcomm IPQ9574 GCC"
|
||||
select CLK_QCOM
|
||||
help
|
||||
Say Y here to enable support for the Global Clock Controller
|
||||
on the Snapdragon IPQ9574 SoC. This driver supports the clocks
|
||||
and resets exposed by the GCC hardware block.
|
||||
|
||||
config CLK_QCOM_QCM2290
|
||||
bool "Qualcomm QCM2290 GCC"
|
||||
select CLK_QCOM
|
||||
|
@@ -7,6 +7,7 @@ obj-$(CONFIG_CLK_QCOM_SDM845) += clock-sdm845.o
|
||||
obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o
|
||||
obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o
|
||||
obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipq4019.o
|
||||
obj-$(CONFIG_CLK_QCOM_IPQ9574) += clock-ipq9574.o
|
||||
obj-$(CONFIG_CLK_QCOM_QCM2290) += clock-qcm2290.o
|
||||
obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o
|
||||
obj-$(CONFIG_CLK_QCOM_SA8775P) += clock-sa8775p.o
|
||||
|
@@ -54,8 +54,9 @@ static struct vote_clk gcc_blsp1_ahb_clk = {
|
||||
};
|
||||
|
||||
static const struct gate_clk apq8016_clks[] = {
|
||||
GATE_CLK(GCC_USB_HS_AHB_CLK, 0x41008, 0x00000001),
|
||||
GATE_CLK(GCC_USB_HS_SYSTEM_CLK, 0x41004, 0x00000001),
|
||||
GATE_CLK(GCC_PRNG_AHB_CLK, 0x45004, BIT(8)),
|
||||
GATE_CLK(GCC_USB_HS_AHB_CLK, 0x41008, BIT(0)),
|
||||
GATE_CLK(GCC_USB_HS_SYSTEM_CLK, 0x41004, BIT(0)),
|
||||
};
|
||||
|
||||
/* SDHCI */
|
||||
@@ -139,15 +140,14 @@ static int apq8016_clk_enable(struct clk *clk)
|
||||
{
|
||||
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
|
||||
if (priv->data->num_clks < clk->id) {
|
||||
if (priv->data->num_clks < clk->id || !apq8016_clks[clk->id].reg) {
|
||||
log_warning("%s: unknown clk id %lu\n", __func__, clk->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug("%s: clk %s\n", __func__, apq8016_clks[clk->id].name);
|
||||
qcom_gate_clk_en(priv, clk->id);
|
||||
debug("%s: enabling clock %s\n", __func__, apq8016_clks[clk->id].name);
|
||||
|
||||
return 0;
|
||||
return qcom_gate_clk_en(priv, clk->id);
|
||||
}
|
||||
|
||||
static struct msm_clk_data apq8016_clk_data = {
|
||||
|
94
drivers/clk/qcom/clock-ipq9574.c
Normal file
94
drivers/clk/qcom/clock-ipq9574.c
Normal file
@@ -0,0 +1,94 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Clock drivers for Qualcomm ipq9574
|
||||
*
|
||||
* (C) Copyright 2025 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <dm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <dt-bindings/clock/qcom,ipq9574-gcc.h>
|
||||
#include <dt-bindings/reset/qcom,ipq9574-gcc.h>
|
||||
|
||||
#include "clock-qcom.h"
|
||||
|
||||
#define GCC_BLSP1_AHB_CBCR 0x1004
|
||||
#define GCC_BLSP1_UART3_APPS_CMD_RCGR 0x402C
|
||||
#define GCC_BLSP1_UART3_APPS_CBCR 0x4054
|
||||
|
||||
#define GCC_SDCC1_APPS_CBCR 0x3302C
|
||||
#define GCC_SDCC1_AHB_CBCR 0x33034
|
||||
#define GCC_SDCC1_APPS_CMD_RCGR 0x33004
|
||||
#define GCC_SDCC1_ICE_CORE_CBCR 0x33030
|
||||
|
||||
static ulong ipq9574_set_rate(struct clk *clk, ulong rate)
|
||||
{
|
||||
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
|
||||
switch (clk->id) {
|
||||
case GCC_BLSP1_UART3_APPS_CLK:
|
||||
clk_rcg_set_rate_mnd(priv->base, GCC_BLSP1_UART3_APPS_CMD_RCGR,
|
||||
0, 144, 15625, CFG_CLK_SRC_GPLL0, 16);
|
||||
return rate;
|
||||
case GCC_SDCC1_APPS_CLK:
|
||||
clk_rcg_set_rate_mnd(priv->base, GCC_SDCC1_APPS_CMD_RCGR,
|
||||
11, 0, 0, CFG_CLK_SRC_GPLL2, 16);
|
||||
return rate;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct gate_clk ipq9574_clks[] = {
|
||||
GATE_CLK(GCC_BLSP1_UART3_APPS_CLK, 0x4054, 0x00000001),
|
||||
GATE_CLK(GCC_BLSP1_AHB_CLK, 0x1004, 0x00000001),
|
||||
GATE_CLK(GCC_SDCC1_AHB_CLK, 0x33034, 0x00000001),
|
||||
GATE_CLK(GCC_SDCC1_APPS_CLK, 0x3302C, 0x00000001),
|
||||
GATE_CLK(GCC_SDCC1_ICE_CORE_CLK, 0x33030, 0x00000001),
|
||||
};
|
||||
|
||||
static int ipq9574_enable(struct clk *clk)
|
||||
{
|
||||
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
|
||||
debug("%s: clk %s\n", __func__, ipq9574_clks[clk->id].name);
|
||||
|
||||
if (!ipq9574_clks[clk->id].reg)
|
||||
return -EINVAL;
|
||||
|
||||
qcom_gate_clk_en(priv, clk->id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct qcom_reset_map ipq9574_gcc_resets[] = {
|
||||
[GCC_SDCC_BCR] = { 0x33000 },
|
||||
};
|
||||
|
||||
static struct msm_clk_data ipq9574_gcc_data = {
|
||||
.resets = ipq9574_gcc_resets,
|
||||
.num_resets = ARRAY_SIZE(ipq9574_gcc_resets),
|
||||
.enable = ipq9574_enable,
|
||||
.set_rate = ipq9574_set_rate,
|
||||
};
|
||||
|
||||
static const struct udevice_id gcc_ipq9574_of_match[] = {
|
||||
{
|
||||
.compatible = "qcom,ipq9574-gcc",
|
||||
.data = (ulong)&ipq9574_gcc_data,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(gcc_ipq9574) = {
|
||||
.name = "gcc_ipq9574",
|
||||
.id = UCLASS_NOP,
|
||||
.of_match = gcc_ipq9574_of_match,
|
||||
.bind = qcom_cc_bind,
|
||||
.flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
|
||||
};
|
@@ -134,9 +134,7 @@ static int qcm2290_enable(struct clk *clk)
|
||||
break;
|
||||
}
|
||||
|
||||
qcom_gate_clk_en(priv, clk->id);
|
||||
|
||||
return 0;
|
||||
return qcom_gate_clk_en(priv, clk->id);
|
||||
}
|
||||
|
||||
static const struct qcom_reset_map qcm2290_gcc_resets[] = {
|
||||
|
@@ -7,10 +7,12 @@
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define CFG_CLK_SRC_CXO (0 << 8)
|
||||
#define CFG_CLK_SRC_GPLL0 (1 << 8)
|
||||
#define CFG_CLK_SRC_GPLL0_AUX2 (2 << 8)
|
||||
#define CFG_CLK_SRC_GPLL2 (2 << 8)
|
||||
#define CFG_CLK_SRC_GPLL9 (2 << 8)
|
||||
#define CFG_CLK_SRC_GPLL0_ODD (3 << 8)
|
||||
#define CFG_CLK_SRC_GPLL6 (4 << 8)
|
||||
@@ -105,14 +107,19 @@ void clk_rcg_set_rate(phys_addr_t base, uint32_t cmd_rcgr, int div,
|
||||
int source);
|
||||
void clk_phy_mux_enable(phys_addr_t base, uint32_t cmd_rcgr, bool enabled);
|
||||
|
||||
static inline void qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id)
|
||||
static inline int qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id)
|
||||
{
|
||||
u32 val;
|
||||
if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0)
|
||||
return;
|
||||
if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0) {
|
||||
log_err("gcc@%#08llx: unknown clock ID %lu!\n",
|
||||
priv->base, id);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
val = readl(priv->base + priv->data->clks[id].reg);
|
||||
writel(val | priv->data->clks[id].en_val, priv->base + priv->data->clks[id].reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -73,9 +73,7 @@ static int sa8775p_enable(struct clk *clk)
|
||||
break;
|
||||
}
|
||||
|
||||
qcom_gate_clk_en(priv, clk->id);
|
||||
|
||||
return 0;
|
||||
return qcom_gate_clk_en(priv, clk->id);
|
||||
}
|
||||
|
||||
static const struct qcom_reset_map sa8775p_gcc_resets[] = {
|
||||
|
@@ -16,29 +16,64 @@
|
||||
|
||||
#include "clock-qcom.h"
|
||||
|
||||
#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf038
|
||||
#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf020
|
||||
#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf038
|
||||
#define USB30_SEC_MASTER_CLK_CMD_RCGR 0x9e020
|
||||
#define USB30_SEC_MOCK_UTMI_CLK_CMD_RCGR 0x9e038
|
||||
#define PCIE_1_AUX_CLK_CMD_RCGR 0x8d058
|
||||
#define PCIE1_PHY_RCHNG_CMD_RCGR 0x8d03c
|
||||
#define PCIE_1_PIPE_CLK_PHY_MUX 0x8d054
|
||||
|
||||
static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
|
||||
F(66666667, CFG_CLK_SRC_GPLL0_EVEN, 4.5, 0, 0),
|
||||
F(133333333, CFG_CLK_SRC_GPLL0, 4.5, 0, 0),
|
||||
F(200000000, CFG_CLK_SRC_GPLL0_ODD, 1, 0, 0),
|
||||
F(240000000, CFG_CLK_SRC_GPLL0, 2.5, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_gcc_usb30_sec_master_clk_src[] = {
|
||||
F(60000000, CFG_CLK_SRC_GPLL0_EVEN, 5, 0, 0),
|
||||
F(120000000, CFG_CLK_SRC_GPLL0_EVEN, 2.5, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static ulong sc7280_set_rate(struct clk *clk, ulong rate)
|
||||
{
|
||||
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct freq_tbl *freq;
|
||||
|
||||
if (clk->id < priv->data->num_clks)
|
||||
debug("%s: %s, requested rate=%ld\n", __func__, priv->data->clks[clk->id].name, rate);
|
||||
|
||||
switch (clk->id) {
|
||||
case GCC_USB30_PRIM_MOCK_UTMI_CLK:
|
||||
WARN(rate != 19200000, "Unexpected rate for USB30_PRIM_MOCK_UTMI_CLK: %lu\n", rate);
|
||||
clk_rcg_set_rate(priv->base, USB30_PRIM_MASTER_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO);
|
||||
return rate;
|
||||
case GCC_USB30_PRIM_MASTER_CLK:
|
||||
WARN(rate != 200000000, "Unexpected rate for USB30_PRIM_MASTER_CLK: %lu\n", rate);
|
||||
freq = qcom_find_freq(ftbl_gcc_usb30_prim_master_clk_src, rate);
|
||||
clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MASTER_CLK_CMD_RCGR,
|
||||
1, 0, 0, CFG_CLK_SRC_GPLL0_ODD, 8);
|
||||
clk_rcg_set_rate(priv->base, 0xf064, 0, 0);
|
||||
return rate;
|
||||
freq->pre_div, freq->m, freq->n, freq->src, 8);
|
||||
return freq->freq;
|
||||
case GCC_USB30_PRIM_MOCK_UTMI_CLK:
|
||||
clk_rcg_set_rate(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR, 1, 0);
|
||||
return 19200000;
|
||||
case GCC_USB3_PRIM_PHY_AUX_CLK_SRC:
|
||||
clk_rcg_set_rate(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR, 1, 0);
|
||||
return 19200000;
|
||||
case GCC_USB30_SEC_MASTER_CLK:
|
||||
freq = qcom_find_freq(ftbl_gcc_usb30_sec_master_clk_src, rate);
|
||||
clk_rcg_set_rate_mnd(priv->base, USB30_SEC_MASTER_CLK_CMD_RCGR,
|
||||
freq->pre_div, freq->m, freq->n, freq->src, 8);
|
||||
return freq->freq;
|
||||
case GCC_USB30_SEC_MOCK_UTMI_CLK:
|
||||
clk_rcg_set_rate(priv->base, USB30_SEC_MOCK_UTMI_CLK_CMD_RCGR, 1, 0);
|
||||
return 19200000;
|
||||
case GCC_USB3_SEC_PHY_AUX_CLK_SRC:
|
||||
clk_rcg_set_rate(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR, 1, 0);
|
||||
return 19200000;
|
||||
case GCC_PCIE1_PHY_RCHNG_CLK:
|
||||
clk_rcg_set_rate(priv->base, PCIE1_PHY_RCHNG_CMD_RCGR, 5, CFG_CLK_SRC_GPLL0_EVEN);
|
||||
return 100000000;
|
||||
default:
|
||||
return 0;
|
||||
return rate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,13 +85,35 @@ static const struct gate_clk sc7280_clks[] = {
|
||||
GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0xf01c, 1),
|
||||
GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0xf054, 1),
|
||||
GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0xf058, 1),
|
||||
GATE_CLK(GCC_CFG_NOC_USB3_SEC_AXI_CLK, 0x9e07c, 1),
|
||||
GATE_CLK(GCC_USB30_SEC_MASTER_CLK, 0x9e010, 1),
|
||||
GATE_CLK(GCC_AGGRE_USB3_SEC_AXI_CLK, 0x9e080, 1),
|
||||
GATE_CLK(GCC_USB30_SEC_SLEEP_CLK, 0x9e018, 1),
|
||||
GATE_CLK(GCC_USB30_SEC_MOCK_UTMI_CLK, 0x9e01c, 1),
|
||||
GATE_CLK(GCC_USB3_SEC_PHY_AUX_CLK, 0x9e054, 1),
|
||||
GATE_CLK(GCC_USB3_SEC_PHY_COM_AUX_CLK, 0x9e058, 1),
|
||||
GATE_CLK(GCC_PCIE_CLKREF_EN, 0x8c004, 1),
|
||||
GATE_CLK(GCC_PCIE_1_PIPE_CLK, 0x52000, BIT(30)),
|
||||
GATE_CLK(GCC_PCIE_1_AUX_CLK, 0x52000, BIT(29)),
|
||||
GATE_CLK(GCC_PCIE_1_CFG_AHB_CLK, 0x52000, BIT(28)),
|
||||
GATE_CLK(GCC_PCIE_1_MSTR_AXI_CLK, 0x52000, BIT(27)),
|
||||
GATE_CLK(GCC_PCIE_1_SLV_AXI_CLK, 0x52000, BIT(26)),
|
||||
GATE_CLK(GCC_PCIE_1_SLV_Q2A_AXI_CLK, 0x52000, BIT(25)),
|
||||
GATE_CLK(GCC_PCIE1_PHY_RCHNG_CLK, 0x52000, BIT(23)),
|
||||
GATE_CLK(GCC_DDRSS_PCIE_SF_CLK, 0x52000, BIT(19)),
|
||||
GATE_CLK(GCC_AGGRE_NOC_PCIE_TBU_CLK, 0x52000, BIT(18)),
|
||||
GATE_CLK(GCC_AGGRE_NOC_PCIE_1_AXI_CLK, 0x52000, BIT(11)),
|
||||
GATE_CLK(GCC_AGGRE_NOC_PCIE_CENTER_SF_AXI_CLK, 0x52008, BIT(28)),
|
||||
GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x52008, BIT(10)),
|
||||
GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x52008, BIT(11)),
|
||||
GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x52008, BIT(13)),
|
||||
};
|
||||
|
||||
static int sc7280_enable(struct clk *clk)
|
||||
{
|
||||
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
|
||||
if (priv->data->num_clks < clk->id) {
|
||||
if (priv->data->num_clks <= clk->id) {
|
||||
debug("%s: unknown clk id %lu\n", __func__, clk->id);
|
||||
return 0;
|
||||
}
|
||||
@@ -71,11 +128,32 @@ static int sc7280_enable(struct clk *clk)
|
||||
qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_AUX_CLK);
|
||||
qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK);
|
||||
break;
|
||||
case GCC_AGGRE_USB3_SEC_AXI_CLK:
|
||||
qcom_gate_clk_en(priv, GCC_USB30_SEC_MASTER_CLK);
|
||||
fallthrough;
|
||||
case GCC_USB30_SEC_MASTER_CLK:
|
||||
qcom_gate_clk_en(priv, GCC_USB3_SEC_PHY_AUX_CLK);
|
||||
qcom_gate_clk_en(priv, GCC_USB3_SEC_PHY_COM_AUX_CLK);
|
||||
break;
|
||||
case GCC_PCIE_1_PIPE_CLK:
|
||||
clk_phy_mux_enable(priv->base, PCIE_1_PIPE_CLK_PHY_MUX, true);
|
||||
break;
|
||||
case GCC_PCIE_1_AUX_CLK:
|
||||
clk_rcg_set_rate_mnd(priv->base, PCIE_1_AUX_CLK_CMD_RCGR, 1, 0, 0,
|
||||
CFG_CLK_SRC_CXO, 16);
|
||||
break;
|
||||
case GCC_QUPV3_WRAP0_S0_CLK:
|
||||
clk_rcg_set_rate_mnd(priv->base, 0x17010, 1, 0, 0, CFG_CLK_SRC_CXO, 16);
|
||||
break;
|
||||
case GCC_QUPV3_WRAP0_S1_CLK:
|
||||
clk_rcg_set_rate_mnd(priv->base, 0x17140, 1, 0, 0, CFG_CLK_SRC_CXO, 16);
|
||||
break;
|
||||
case GCC_QUPV3_WRAP0_S3_CLK:
|
||||
clk_rcg_set_rate_mnd(priv->base, 0x173a0, 1, 0, 0, CFG_CLK_SRC_CXO, 16);
|
||||
break;
|
||||
}
|
||||
|
||||
qcom_gate_clk_en(priv, clk->id);
|
||||
|
||||
return 0;
|
||||
return qcom_gate_clk_en(priv, clk->id);
|
||||
}
|
||||
|
||||
static const struct qcom_reset_map sc7280_gcc_resets[] = {
|
||||
@@ -100,6 +178,20 @@ static const struct qcom_reset_map sc7280_gcc_resets[] = {
|
||||
static const struct qcom_power_map sc7280_gdscs[] = {
|
||||
[GCC_UFS_PHY_GDSC] = { 0x77004 },
|
||||
[GCC_USB30_PRIM_GDSC] = { 0xf004 },
|
||||
[GCC_USB30_SEC_GDSC] = { 0x9e004 },
|
||||
[GCC_PCIE_1_GDSC] = { 0x8d004 },
|
||||
};
|
||||
|
||||
static const phys_addr_t sc7280_rcg_addrs[] = {
|
||||
0x10f020, // USB30_PRIM_MASTER_CLK_CMD_RCGR
|
||||
0x10f038, // USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR
|
||||
0x18d058, // PCIE_1_AUX_CLK_CMD_RCGR
|
||||
};
|
||||
|
||||
static const char *const sc7280_rcg_names[] = {
|
||||
"USB30_PRIM_MASTER_CLK_SRC",
|
||||
"USB30_PRIM_MOCK_UTMI_CLK_SRC",
|
||||
"GCC_PCIE_1_AUX_CLK_SRC",
|
||||
};
|
||||
|
||||
static struct msm_clk_data qcs404_gcc_data = {
|
||||
@@ -113,6 +205,10 @@ static struct msm_clk_data qcs404_gcc_data = {
|
||||
|
||||
.enable = sc7280_enable,
|
||||
.set_rate = sc7280_set_rate,
|
||||
|
||||
.dbg_rcg_addrs = sc7280_rcg_addrs,
|
||||
.num_rcgs = ARRAY_SIZE(sc7280_rcg_addrs),
|
||||
.dbg_rcg_names = sc7280_rcg_names,
|
||||
};
|
||||
|
||||
static const struct udevice_id gcc_sc7280_of_match[] = {
|
||||
|
@@ -162,9 +162,7 @@ static int sdm845_clk_enable(struct clk *clk)
|
||||
break;
|
||||
}
|
||||
|
||||
qcom_gate_clk_en(priv, clk->id);
|
||||
|
||||
return 0;
|
||||
return qcom_gate_clk_en(priv, clk->id);
|
||||
}
|
||||
|
||||
static const struct qcom_reset_map sdm845_gcc_resets[] = {
|
||||
|
@@ -146,9 +146,7 @@ static int sm6115_enable(struct clk *clk)
|
||||
break;
|
||||
}
|
||||
|
||||
qcom_gate_clk_en(priv, clk->id);
|
||||
|
||||
return 0;
|
||||
return qcom_gate_clk_en(priv, clk->id);
|
||||
}
|
||||
|
||||
static const struct qcom_reset_map sm6115_gcc_resets[] = {
|
||||
|
@@ -243,9 +243,7 @@ static int sm8150_clk_enable(struct clk *clk)
|
||||
break;
|
||||
};
|
||||
|
||||
qcom_gate_clk_en(priv, clk->id);
|
||||
|
||||
return 0;
|
||||
return qcom_gate_clk_en(priv, clk->id);
|
||||
}
|
||||
|
||||
static const struct qcom_reset_map sm8150_gcc_resets[] = {
|
||||
|
@@ -195,9 +195,7 @@ static int sm8250_enable(struct clk *clk)
|
||||
break;
|
||||
}
|
||||
|
||||
qcom_gate_clk_en(priv, clk->id);
|
||||
|
||||
return 0;
|
||||
return qcom_gate_clk_en(priv, clk->id);
|
||||
}
|
||||
|
||||
static const struct qcom_reset_map sm8250_gcc_resets[] = {
|
||||
|
@@ -220,9 +220,7 @@ static int sm8550_enable(struct clk *clk)
|
||||
break;
|
||||
}
|
||||
|
||||
qcom_gate_clk_en(priv, clk->id);
|
||||
|
||||
return 0;
|
||||
return qcom_gate_clk_en(priv, clk->id);
|
||||
}
|
||||
|
||||
static const struct qcom_reset_map sm8550_gcc_resets[] = {
|
||||
|
@@ -217,9 +217,7 @@ static int sm8650_enable(struct clk *clk)
|
||||
break;
|
||||
}
|
||||
|
||||
qcom_gate_clk_en(priv, clk->id);
|
||||
|
||||
return 0;
|
||||
return qcom_gate_clk_en(priv, clk->id);
|
||||
}
|
||||
|
||||
static const struct qcom_reset_map sm8650_gcc_resets[] = {
|
||||
|
@@ -174,9 +174,7 @@ static int x1e80100_enable(struct clk *clk)
|
||||
break;
|
||||
}
|
||||
|
||||
qcom_gate_clk_en(priv, clk->id);
|
||||
|
||||
return 0;
|
||||
return qcom_gate_clk_en(priv, clk->id);
|
||||
}
|
||||
|
||||
static const struct qcom_reset_map x1e80100_gcc_resets[] = {
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <malloc.h>
|
||||
#include <reset.h>
|
||||
#include <sdhci.h>
|
||||
#include <wait_bit.h>
|
||||
#include <asm/global_data.h>
|
||||
@@ -153,9 +154,18 @@ static int msm_sdc_probe(struct udevice *dev)
|
||||
const struct msm_sdhc_variant_info *var_info;
|
||||
struct sdhci_host *host = &prv->host;
|
||||
u32 core_version, core_minor, core_major;
|
||||
struct reset_ctl bcr_rst;
|
||||
u32 caps;
|
||||
int ret;
|
||||
|
||||
ret = reset_get_by_index(dev, 0, &bcr_rst);
|
||||
if (!ret) {
|
||||
reset_assert(&bcr_rst);
|
||||
udelay(200);
|
||||
reset_deassert(&bcr_rst);
|
||||
udelay(200);
|
||||
}
|
||||
|
||||
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B;
|
||||
|
||||
host->max_clk = 0;
|
||||
|
@@ -7,84 +7,98 @@ config PINCTRL_QCOM
|
||||
menu "Qualcomm pinctrl drivers"
|
||||
|
||||
config PINCTRL_QCOM_APQ8016
|
||||
bool "Qualcomm APQ8016 GCC"
|
||||
bool "Qualcomm APQ8016 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the MSM8916 / APQ8016
|
||||
Snapdragon 410 SoC, as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_APQ8096
|
||||
bool "Qualcomm APQ8096 GCC"
|
||||
bool "Qualcomm APQ8096 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the MSM8996 / APQ8096
|
||||
Snapdragon 820 SoC, as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_IPQ4019
|
||||
bool "Qualcomm IPQ4019 GCC"
|
||||
bool "Qualcomm IPQ4019 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the IPQ4019 SoC,
|
||||
as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_IPQ9574
|
||||
bool "Qualcomm IPQ9574 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the IPQ9574 SoC,
|
||||
as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_QCM2290
|
||||
bool "Qualcomm QCM2290 GCC"
|
||||
bool "Qualcomm QCM2290 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the Snapdragon QCM2290 SoC,
|
||||
as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_QCS404
|
||||
bool "Qualcomm QCS404 GCC"
|
||||
bool "Qualcomm QCS404 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the Snapdragon QCS404 SoC,
|
||||
as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_SC7280
|
||||
bool "Qualcomm SC7280/QCM6490 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the Snapdragon SC7280 SoC,
|
||||
as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_SDM845
|
||||
bool "Qualcomm SDM845 GCC"
|
||||
bool "Qualcomm SDM845 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the Snapdragon 845 SoC,
|
||||
as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_SM6115
|
||||
bool "Qualcomm SM6115 GCC"
|
||||
bool "Qualcomm SM6115 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the Snapdragon SM6115 SoC,
|
||||
as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_SM8150
|
||||
bool "Qualcomm SM8150 GCC"
|
||||
bool "Qualcomm SM8150 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the Snapdragon SM8150 SoC,
|
||||
as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_SM8250
|
||||
bool "Qualcomm SM8250 GCC"
|
||||
bool "Qualcomm SM8250 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the Snapdragon SM8250 SoC,
|
||||
as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_SM8550
|
||||
bool "Qualcomm SM8550 GCC"
|
||||
bool "Qualcomm SM8550 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the Snapdragon SM8550 SoC,
|
||||
as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_SM8650
|
||||
bool "Qualcomm SM8650 GCC"
|
||||
bool "Qualcomm SM8650 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the Snapdragon SM8650 SoC,
|
||||
as well as the associated GPIO driver.
|
||||
|
||||
config PINCTRL_QCOM_X1E80100
|
||||
bool "Qualcomm X1E80100 GCC"
|
||||
bool "Qualcomm X1E80100 Pinctrl"
|
||||
select PINCTRL_QCOM
|
||||
help
|
||||
Say Y here to enable support for pinctrl on the Snapdragon X1E80100 SoC,
|
||||
|
@@ -5,9 +5,11 @@
|
||||
obj-$(CONFIG_PINCTRL_QCOM) += pinctrl-qcom.o
|
||||
obj-$(CONFIG_PINCTRL_QCOM_APQ8016) += pinctrl-apq8016.o
|
||||
obj-$(CONFIG_PINCTRL_QCOM_IPQ4019) += pinctrl-ipq4019.o
|
||||
obj-$(CONFIG_PINCTRL_QCOM_IPQ9574) += pinctrl-ipq9574.o
|
||||
obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o
|
||||
obj-$(CONFIG_PINCTRL_QCOM_QCM2290) += pinctrl-qcm2290.o
|
||||
obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o
|
||||
obj-$(CONFIG_PINCTRL_QCOM_SC7280) += pinctrl-sc7280.o
|
||||
obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o
|
||||
obj-$(CONFIG_PINCTRL_QCOM_SM6115) += pinctrl-sm6115.o
|
||||
obj-$(CONFIG_PINCTRL_QCOM_SM8150) += pinctrl-sm8150.o
|
||||
|
@@ -50,8 +50,8 @@ static const char *apq8016_get_pin_name(struct udevice *dev,
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int apq8016_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
static int apq8016_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].val;
|
||||
}
|
||||
|
@@ -43,8 +43,8 @@ static const char *apq8096_get_pin_name(struct udevice *dev,
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int apq8096_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
static int apq8096_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].val;
|
||||
}
|
||||
|
@@ -311,8 +311,7 @@ static const char *ipq4019_get_pin_name(struct udevice *dev,
|
||||
return pin_name;
|
||||
}
|
||||
|
||||
static unsigned int ipq4019_get_function_mux(unsigned int pin,
|
||||
unsigned int selector)
|
||||
static int ipq4019_get_function_mux(unsigned int pin, unsigned int selector)
|
||||
{
|
||||
unsigned int i;
|
||||
const msm_pin_function *func = ipq4019_pin_functions + pin;
|
||||
|
226
drivers/pinctrl/qcom/pinctrl-ipq9574.c
Normal file
226
drivers/pinctrl/qcom/pinctrl-ipq9574.c
Normal file
@@ -0,0 +1,226 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* pinctrl driver for Qualcomm ipq9574
|
||||
*
|
||||
* (C) Copyright 2025 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
|
||||
#include "pinctrl-qcom.h"
|
||||
|
||||
#define MAX_PIN_NAME_LEN 32
|
||||
static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
|
||||
|
||||
enum ipq9574_functions {
|
||||
msm_mux_blsp0_spi,
|
||||
msm_mux_blsp0_uart,
|
||||
msm_mux_blsp1_i2c,
|
||||
msm_mux_blsp1_spi,
|
||||
msm_mux_blsp1_uart,
|
||||
msm_mux_blsp2_i2c,
|
||||
msm_mux_blsp2_spi,
|
||||
msm_mux_blsp2_uart,
|
||||
msm_mux_blsp3_i2c,
|
||||
msm_mux_blsp3_spi,
|
||||
msm_mux_blsp3_uart,
|
||||
msm_mux_blsp4_i2c,
|
||||
msm_mux_blsp4_spi,
|
||||
msm_mux_blsp4_uart,
|
||||
msm_mux_blsp5_i2c,
|
||||
msm_mux_blsp5_uart,
|
||||
msm_mux_gpio,
|
||||
msm_mux_mdc,
|
||||
msm_mux_mdio,
|
||||
msm_mux_pcie0_clk,
|
||||
msm_mux_pcie0_wake,
|
||||
msm_mux_pcie1_clk,
|
||||
msm_mux_pcie1_wake,
|
||||
msm_mux_pcie2_clk,
|
||||
msm_mux_pcie2_wake,
|
||||
msm_mux_pcie3_clk,
|
||||
msm_mux_pcie3_wake,
|
||||
msm_mux_qspi_data,
|
||||
msm_mux_qspi_clk,
|
||||
msm_mux_qspi_cs,
|
||||
msm_mux_sdc_data,
|
||||
msm_mux_sdc_clk,
|
||||
msm_mux_sdc_cmd,
|
||||
msm_mux_sdc_rclk,
|
||||
msm_mux_NA,
|
||||
};
|
||||
|
||||
#define MSM_PIN_FUNCTION(fname) \
|
||||
[msm_mux_##fname] = {#fname, msm_mux_##fname}
|
||||
|
||||
static const struct pinctrl_function msm_pinctrl_functions[] = {
|
||||
MSM_PIN_FUNCTION(blsp0_spi),
|
||||
MSM_PIN_FUNCTION(blsp0_uart),
|
||||
MSM_PIN_FUNCTION(blsp1_i2c),
|
||||
MSM_PIN_FUNCTION(blsp1_spi),
|
||||
MSM_PIN_FUNCTION(blsp1_uart),
|
||||
MSM_PIN_FUNCTION(blsp2_i2c),
|
||||
MSM_PIN_FUNCTION(blsp2_spi),
|
||||
MSM_PIN_FUNCTION(blsp2_uart),
|
||||
MSM_PIN_FUNCTION(blsp3_i2c),
|
||||
MSM_PIN_FUNCTION(blsp3_spi),
|
||||
MSM_PIN_FUNCTION(blsp3_uart),
|
||||
MSM_PIN_FUNCTION(blsp4_i2c),
|
||||
MSM_PIN_FUNCTION(blsp4_spi),
|
||||
MSM_PIN_FUNCTION(blsp4_uart),
|
||||
MSM_PIN_FUNCTION(blsp5_i2c),
|
||||
MSM_PIN_FUNCTION(blsp5_uart),
|
||||
MSM_PIN_FUNCTION(gpio),
|
||||
MSM_PIN_FUNCTION(mdc),
|
||||
MSM_PIN_FUNCTION(mdio),
|
||||
MSM_PIN_FUNCTION(pcie0_clk),
|
||||
MSM_PIN_FUNCTION(pcie0_wake),
|
||||
MSM_PIN_FUNCTION(pcie1_clk),
|
||||
MSM_PIN_FUNCTION(pcie1_wake),
|
||||
MSM_PIN_FUNCTION(pcie2_clk),
|
||||
MSM_PIN_FUNCTION(pcie2_wake),
|
||||
MSM_PIN_FUNCTION(pcie3_clk),
|
||||
MSM_PIN_FUNCTION(pcie3_wake),
|
||||
MSM_PIN_FUNCTION(qspi_data),
|
||||
MSM_PIN_FUNCTION(qspi_clk),
|
||||
MSM_PIN_FUNCTION(qspi_cs),
|
||||
MSM_PIN_FUNCTION(sdc_data),
|
||||
MSM_PIN_FUNCTION(sdc_clk),
|
||||
MSM_PIN_FUNCTION(sdc_cmd),
|
||||
MSM_PIN_FUNCTION(sdc_rclk),
|
||||
};
|
||||
|
||||
typedef unsigned int msm_pin_function[10];
|
||||
|
||||
#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9) \
|
||||
[id] = { msm_mux_gpio, /* gpio mode */ \
|
||||
msm_mux_##f1, \
|
||||
msm_mux_##f2, \
|
||||
msm_mux_##f3, \
|
||||
msm_mux_##f4, \
|
||||
msm_mux_##f5, \
|
||||
msm_mux_##f6, \
|
||||
msm_mux_##f7, \
|
||||
msm_mux_##f8, \
|
||||
msm_mux_##f9, \
|
||||
}
|
||||
|
||||
static const msm_pin_function ipq9574_pin_functions[] = {
|
||||
PINGROUP(0, sdc_data, qspi_data, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(1, sdc_data, qspi_data, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(2, sdc_data, qspi_data, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(3, sdc_data, qspi_data, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(4, sdc_cmd, qspi_cs, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(5, sdc_clk, qspi_clk, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(6, sdc_data, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(7, sdc_data, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(8, sdc_data, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(9, sdc_data, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(10, sdc_rclk, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(11, blsp0_spi, blsp0_uart, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(12, blsp0_spi, blsp0_uart, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(13, blsp0_spi, blsp0_uart, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(14, blsp0_spi, blsp0_uart, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(15, blsp3_spi, blsp3_i2c, blsp3_uart, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(16, blsp3_spi, blsp3_i2c, blsp3_uart, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(17, blsp3_spi, blsp3_uart, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(18, blsp3_spi, blsp3_uart, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(19, blsp3_spi, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(20, blsp3_spi, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(21, blsp3_spi, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(22, pcie0_clk, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(23, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(24, pcie0_wake, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(25, pcie1_clk, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(26, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(27, pcie1_wake, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(28, pcie2_clk, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(29, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(30, pcie2_wake, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(31, pcie3_clk, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(32, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(33, pcie3_wake, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(34, blsp2_uart, blsp2_i2c, blsp2_spi, blsp1_uart, NA, NA, NA, NA, NA),
|
||||
PINGROUP(35, blsp2_uart, blsp2_i2c, blsp2_spi, blsp1_uart, NA, NA, NA, NA, NA),
|
||||
PINGROUP(36, blsp1_uart, blsp1_i2c, blsp2_spi, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(37, blsp1_uart, blsp1_i2c, blsp2_spi, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(38, mdc, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(39, mdio, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(40, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(41, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(42, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(44, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(45, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(47, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(48, blsp5_i2c, blsp5_uart, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(49, blsp5_i2c, blsp5_uart, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(50, blsp4_uart, blsp4_i2c, blsp4_spi, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(51, blsp4_uart, blsp4_i2c, blsp4_spi, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(52, blsp4_uart, blsp4_spi, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(53, blsp4_uart, blsp4_spi, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(54, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(55, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(56, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(57, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(58, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(59, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(60, NA, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(61, blsp1_spi, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(62, blsp1_spi, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(63, blsp1_spi, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
PINGROUP(64, blsp1_spi, NA, NA, NA, NA, NA, NA, NA, NA),
|
||||
};
|
||||
|
||||
static const char *ipq9574_get_function_name(struct udevice *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].name;
|
||||
}
|
||||
|
||||
static const char *ipq9574_get_pin_name(struct udevice *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
|
||||
return pin_name;
|
||||
}
|
||||
|
||||
static int ipq9574_get_function_mux(unsigned int pin, unsigned int selector)
|
||||
{
|
||||
unsigned int i;
|
||||
const msm_pin_function *func = ipq9574_pin_functions + pin;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
if ((*func)[i] == selector)
|
||||
return i;
|
||||
|
||||
debug("Can't find requested function for pin:selector %u:%u\n",
|
||||
pin, selector);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct msm_pinctrl_data ipq9574_data = {
|
||||
.pin_data = {
|
||||
.pin_count = 65,
|
||||
},
|
||||
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
||||
.get_function_name = ipq9574_get_function_name,
|
||||
.get_function_mux = ipq9574_get_function_mux,
|
||||
.get_pin_name = ipq9574_get_pin_name,
|
||||
};
|
||||
|
||||
static const struct udevice_id msm_pinctrl_ids[] = {
|
||||
{ .compatible = "qcom,ipq9574-tlmm", .data = (ulong)&ipq9574_data },
|
||||
{ /* Sentinal */ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pinctrl_ipq9574) = {
|
||||
.name = "pinctrl_ipq9574",
|
||||
.id = UCLASS_NOP,
|
||||
.of_match = msm_pinctrl_ids,
|
||||
.ops = &msm_pinctrl_ops,
|
||||
.bind = msm_pinctrl_bind,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
@@ -38,7 +38,7 @@ static const char *qcm2290_get_pin_name(struct udevice *dev, unsigned int select
|
||||
return pin_name;
|
||||
}
|
||||
|
||||
static unsigned int qcm2290_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
|
||||
static int qcm2290_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].val;
|
||||
}
|
||||
|
@@ -92,7 +92,10 @@ static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
|
||||
unsigned int func_selector)
|
||||
{
|
||||
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
u32 func = priv->data->get_function_mux(pin_selector, func_selector);
|
||||
int func = priv->data->get_function_mux(pin_selector, func_selector);
|
||||
|
||||
if (func < 0)
|
||||
return func;
|
||||
|
||||
/* Always NOP for special pins, assume they're in the correct state */
|
||||
if (qcom_is_special_pin(&priv->data->pin_data, pin_selector))
|
||||
|
@@ -18,8 +18,7 @@ struct msm_pinctrl_data {
|
||||
int functions_count;
|
||||
const char *(*get_function_name)(struct udevice *dev,
|
||||
unsigned int selector);
|
||||
unsigned int (*get_function_mux)(unsigned int pin,
|
||||
unsigned int selector);
|
||||
int (*get_function_mux)(unsigned int pin, unsigned int selector);
|
||||
const char *(*get_pin_name)(struct udevice *dev,
|
||||
unsigned int selector);
|
||||
};
|
||||
|
@@ -93,8 +93,8 @@ static const char *qcs404_get_pin_name(struct udevice *dev,
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int qcs404_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
static int qcs404_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].val;
|
||||
}
|
||||
|
106
drivers/pinctrl/qcom/pinctrl-sc7280.c
Normal file
106
drivers/pinctrl/qcom/pinctrl-sc7280.c
Normal file
@@ -0,0 +1,106 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Qualcomm sc7280 pinctrl
|
||||
*
|
||||
* (C) Copyright 2024 Linaro Ltd.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
|
||||
#include "pinctrl-qcom.h"
|
||||
|
||||
#define WEST 0x00000000
|
||||
#define SOUTH 0x00400000
|
||||
#define NORTH 0x00800000
|
||||
|
||||
#define MAX_PIN_NAME_LEN 32
|
||||
static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
|
||||
|
||||
static const struct pinctrl_function msm_pinctrl_functions[] = {
|
||||
{ "qup05", 1 },
|
||||
{ "gpio", 0 },
|
||||
{ "pcie1_clkreqn", 3},
|
||||
};
|
||||
#define SDC_PINGROUP(pg_name, ctl, pull, drv) \
|
||||
{ \
|
||||
.name = pg_name, \
|
||||
.ctl_reg = ctl, \
|
||||
.io_reg = 0, \
|
||||
.pull_bit = pull, \
|
||||
.drv_bit = drv, \
|
||||
.oe_bit = -1, \
|
||||
.in_bit = -1, \
|
||||
.out_bit = -1, \
|
||||
}
|
||||
|
||||
#define UFS_RESET(pg_name, offset) \
|
||||
{ \
|
||||
.name = pg_name, \
|
||||
.ctl_reg = offset, \
|
||||
.io_reg = offset + 0x4, \
|
||||
.pull_bit = 3, \
|
||||
.drv_bit = 0, \
|
||||
.oe_bit = -1, \
|
||||
.in_bit = -1, \
|
||||
.out_bit = 0, \
|
||||
}
|
||||
|
||||
static const struct msm_special_pin_data sc7280_special_pins_data[] = {
|
||||
[0] = UFS_RESET("ufs_reset", SOUTH + 0xbe000),
|
||||
[1] = SDC_PINGROUP("sdc1_rclk", 0xb3004, 0, 6),
|
||||
[2] = SDC_PINGROUP("sdc1_clk", 0xb3000, 13, 6),
|
||||
[3] = SDC_PINGROUP("sdc1_cmd", 0xb3000, 11, 3),
|
||||
[4] = SDC_PINGROUP("sdc1_data", 0xb3000, 9, 0),
|
||||
[5] = SDC_PINGROUP("sdc2_clk", 0xb4000, 14, 6),
|
||||
[6] = SDC_PINGROUP("sdc2_cmd", 0xb4000, 11, 3),
|
||||
[7] = SDC_PINGROUP("sdc2_data", 0xb4000, 9, 0),
|
||||
};
|
||||
|
||||
static const char *sc7280_get_function_name(struct udevice *dev, unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].name;
|
||||
}
|
||||
|
||||
static const char *sc7280_get_pin_name(struct udevice *dev, unsigned int selector)
|
||||
{
|
||||
if (selector >= 175 && selector <= 182)
|
||||
snprintf(pin_name, MAX_PIN_NAME_LEN,
|
||||
sc7280_special_pins_data[selector - 175].name);
|
||||
else
|
||||
snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
|
||||
|
||||
return pin_name;
|
||||
}
|
||||
|
||||
static int sc7280_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].val;
|
||||
}
|
||||
|
||||
static struct msm_pinctrl_data sc7280_data = {
|
||||
.pin_data = {
|
||||
.pin_count = 183,
|
||||
.special_pins_start = 175,
|
||||
.special_pins_data = sc7280_special_pins_data,
|
||||
},
|
||||
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
||||
.get_function_name = sc7280_get_function_name,
|
||||
.get_function_mux = sc7280_get_function_mux,
|
||||
.get_pin_name = sc7280_get_pin_name,
|
||||
};
|
||||
|
||||
static const struct udevice_id msm_pinctrl_ids[] = {
|
||||
{
|
||||
.compatible = "qcom,sc7280-pinctrl",
|
||||
.data = (ulong)&sc7280_data
|
||||
},
|
||||
{ /* Sentinel */ } };
|
||||
|
||||
U_BOOT_DRIVER(pinctrl_sc7280) = {
|
||||
.name = "pinctrl_sc7280",
|
||||
.id = UCLASS_NOP,
|
||||
.of_match = msm_pinctrl_ids,
|
||||
.ops = &msm_pinctrl_ops,
|
||||
.bind = msm_pinctrl_bind,
|
||||
};
|
@@ -80,8 +80,8 @@ static const char *sdm845_get_pin_name(struct udevice *dev,
|
||||
return pin_name;
|
||||
}
|
||||
|
||||
static unsigned int sdm845_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
static int sdm845_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].val;
|
||||
}
|
||||
|
@@ -167,7 +167,7 @@ static const char *sm6115_get_pin_name(struct udevice *dev, unsigned int selecto
|
||||
return pin_name;
|
||||
}
|
||||
|
||||
static unsigned int sm6115_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
|
||||
static int sm6115_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].val;
|
||||
}
|
||||
|
@@ -123,8 +123,8 @@ static const char *sm8150_get_pin_name(struct udevice *dev,
|
||||
return pin_name;
|
||||
}
|
||||
|
||||
static unsigned int sm8150_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
static int sm8150_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].val;
|
||||
}
|
||||
|
@@ -99,7 +99,7 @@ static const char *sm8250_get_pin_name(struct udevice *dev, unsigned int selecto
|
||||
return pin_name;
|
||||
}
|
||||
|
||||
static unsigned int sm8250_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
|
||||
static int sm8250_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].val;
|
||||
}
|
||||
|
@@ -68,8 +68,8 @@ static const char *sm8550_get_pin_name(struct udevice *dev,
|
||||
return pin_name;
|
||||
}
|
||||
|
||||
static unsigned int sm8550_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
static int sm8550_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].val;
|
||||
}
|
||||
|
@@ -69,8 +69,8 @@ static const char *sm8650_get_pin_name(struct udevice *dev,
|
||||
return pin_name;
|
||||
}
|
||||
|
||||
static unsigned int sm8650_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
static int sm8650_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].val;
|
||||
}
|
||||
|
@@ -72,8 +72,8 @@ static const char *x1e80100_get_pin_name(struct udevice *dev,
|
||||
return pin_name;
|
||||
}
|
||||
|
||||
static unsigned int x1e80100_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
static int x1e80100_get_function_mux(__maybe_unused unsigned int pin,
|
||||
unsigned int selector)
|
||||
{
|
||||
return msm_pinctrl_functions[selector].val;
|
||||
}
|
||||
|
@@ -44,6 +44,11 @@ static int msm_rng_read(struct udevice *dev, void *data, size_t len)
|
||||
u32 *retdata = data;
|
||||
size_t maxsize;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = clk_enable(&priv->clk);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* calculate max size bytes to transfer back to caller */
|
||||
maxsize = min_t(size_t, MAX_HW_FIFO_SIZE, len);
|
||||
@@ -66,6 +71,8 @@ static int msm_rng_read(struct udevice *dev, void *data, size_t len)
|
||||
break;
|
||||
} while (currsize < maxsize);
|
||||
|
||||
clk_disable(&priv->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -76,7 +83,7 @@ static int msm_rng_enable(struct msm_rng_priv *priv, int enable)
|
||||
if (enable) {
|
||||
/* Enable PRNG only if it is not already enabled */
|
||||
val = readl_relaxed(priv->base + PRNG_CONFIG);
|
||||
if (val & PRNG_CONFIG_HW_ENABLE) {
|
||||
if (!(val & PRNG_CONFIG_HW_ENABLE)) {
|
||||
val = readl_relaxed(priv->base + PRNG_LFSR_CFG);
|
||||
val &= ~PRNG_LFSR_CFG_MASK;
|
||||
val |= PRNG_LFSR_CFG_CLOCKS;
|
||||
@@ -118,7 +125,9 @@ static int msm_rng_probe(struct udevice *dev)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return msm_rng_enable(priv, 1);
|
||||
ret = msm_rng_enable(priv, 1);
|
||||
clk_disable(&priv->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm_rng_remove(struct udevice *dev)
|
||||
|
@@ -242,7 +242,6 @@ config SYSRESET_RAA215300
|
||||
|
||||
config SYSRESET_QCOM_PSHOLD
|
||||
bool "Support sysreset for Qualcomm SoCs via PSHOLD"
|
||||
depends on ARCH_IPQ40XX
|
||||
help
|
||||
Add support for the system reboot on Qualcomm SoCs via PSHOLD.
|
||||
|
||||
|
Reference in New Issue
Block a user