u-boot/board/qualcomm/dragonboard820c/dragonboard820c.c
Caleb Connolly 059d526af3
mach-snapdragon: generalise board support
Historically, Qualcomm boards have relied on heavy hardcoding in U-Boot,
in many cases to the specific SoC but also to the board itself (e.g.
memory map). This has been largely resolved by modernising the Qualcomm
drivers in U-Boot, however the board code still largely follows this
model.

This patch removes the board specific memory maps and duplicated board
init code, replacing it with generic init code.

The memory map is now built at runtime based on data read from DT, this
allows for the memory map to be provided without having to recompile
U-Boot. Support is also added for booting with appended DTBs, so that
the first-stage bootloader can populate the memory map for us.

The sdm845 specific init code is dropped entirely, it set an environment
variable depending on if a button was pressed, but this variable wasn't
used in U-Boot, and could be written to use the button command instead.

The KASLR detection is also dropped as with appended dtb, the kaslr seed
can be read directly from the DTB passed to U-Boot.

A new qcom_defconfig is added, with the aim of providing a generic
U-Boot configuration that will work on as many Qualcomm boards as
possible. It replaces the defconfig files for the Dragonboard 845c,
Galaxy S9, and QCS404 EVB. For now the db410c and 820c are excluded as
they still have some board code left.

Similarly, the config headers for db845c, starqltechn, and qcs404-evb
are replaced by a single qcom header.

The previously db410c-specific board_usb_init() function is made to be
generic and is added to mach-snapdragon. While we lack proper modelling
for USB configuration, using a well-known named pinctrl state is a
reasonably generic middleground, and works using upstream DT. This
function will do nothing unless the USB node has a pinctrl state named
"device", in which case it will be set when entering USB peripheral
mode.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Tested-by: Sumit Garg <sumit.garg@linaro.org> #qcs404
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
2024-03-01 14:44:37 +00:00

123 lines
2.7 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Board init file for Dragonboard 820C
*
* (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
*/
#include <button.h>
#include <cpu_func.h>
#include <init.h>
#include <env.h>
#include <asm/cache.h>
#include <asm/global_data.h>
#include <linux/arm-smccc.h>
#include <linux/psci.h>
#include <common.h>
#include <dm.h>
#include <asm/io.h>
#include <linux/bitops.h>
#include <asm/psci.h>
#include <asm/gpio.h>
#define TLMM_BASE_ADDR (0x1010000)
/* Strength (sdc1) */
#define SDC1_HDRV_PULL_CTL_REG (TLMM_BASE_ADDR + 0x0012D000)
DECLARE_GLOBAL_DATA_PTR;
static void sdhci_power_init(void)
{
const u32 TLMM_PULL_MASK = 0x3;
const u32 TLMM_HDRV_MASK = 0x7;
struct tlmm_cfg {
u32 bit; /* bit in the register */
u8 mask; /* mask clk/dat/cmd control */
u8 val;
};
/* bit offsets in the sdc tlmm register */
enum { SDC1_DATA_HDRV = 0,
SDC1_CMD_HDRV = 3,
SDC1_CLK_HDRV = 6,
SDC1_DATA_PULL = 9,
SDC1_CMD_PULL = 11,
SDC1_CLK_PULL = 13,
SDC1_RCLK_PULL = 15,
};
enum { TLMM_PULL_DOWN = 0x1,
TLMM_PULL_UP = 0x3,
TLMM_NO_PULL = 0x0,
};
enum { TLMM_CUR_VAL_10MA = 0x04,
TLMM_CUR_VAL_16MA = 0x07,
};
int i;
/* drive strength configs for sdhc pins */
const struct tlmm_cfg hdrv[] = {
{ SDC1_CLK_HDRV, TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK, },
{ SDC1_CMD_HDRV, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, },
{ SDC1_DATA_HDRV, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, },
};
/* pull configs for sdhc pins */
const struct tlmm_cfg pull[] = {
{ SDC1_CLK_PULL, TLMM_NO_PULL, TLMM_PULL_MASK, },
{ SDC1_CMD_PULL, TLMM_PULL_UP, TLMM_PULL_MASK, },
{ SDC1_DATA_PULL, TLMM_PULL_UP, TLMM_PULL_MASK, },
};
const struct tlmm_cfg rclk[] = {
{ SDC1_RCLK_PULL, TLMM_PULL_DOWN, TLMM_PULL_MASK,},
};
for (i = 0; i < ARRAY_SIZE(hdrv); i++)
clrsetbits_le32(SDC1_HDRV_PULL_CTL_REG,
hdrv[i].mask << hdrv[i].bit,
hdrv[i].val << hdrv[i].bit);
for (i = 0; i < ARRAY_SIZE(pull); i++)
clrsetbits_le32(SDC1_HDRV_PULL_CTL_REG,
pull[i].mask << pull[i].bit,
pull[i].val << pull[i].bit);
for (i = 0; i < ARRAY_SIZE(rclk); i++)
clrsetbits_le32(SDC1_HDRV_PULL_CTL_REG,
rclk[i].mask << rclk[i].bit,
rclk[i].val << rclk[i].bit);
}
void qcom_board_init(void)
{
sdhci_power_init();
}
/* Check for vol- button - if pressed - stop autoboot */
int misc_init_r(void)
{
struct udevice *btn;
int ret;
enum button_state_t state;
ret = button_get_by_label("pwrkey", &btn);
if (ret < 0) {
printf("Couldn't find power button!\n");
return ret;
}
state = button_get_state(btn);
if (state == BUTTON_ON) {
env_set("bootdelay", "-1");
printf("Power button pressed - dropping to console.\n");
}
return 0;
}