1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Board init file for Dragonboard 820C
4 *
5 * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
6 */
7
8#include <button.h>
9#include <cpu_func.h>
10#include <init.h>
11#include <env.h>
12#include <asm/cache.h>
13#include <asm/global_data.h>
14#include <linux/arm-smccc.h>
15#include <linux/psci.h>
16#include <common.h>
17#include <dm.h>
18#include <asm/io.h>
19#include <linux/bitops.h>
20#include <asm/psci.h>
21#include <asm/gpio.h>
22
23#define TLMM_BASE_ADDR                  (0x1010000)
24
25/* Strength (sdc1) */
26#define SDC1_HDRV_PULL_CTL_REG          (TLMM_BASE_ADDR + 0x0012D000)
27
28DECLARE_GLOBAL_DATA_PTR;
29
30static void sdhci_power_init(void)
31{
32	const u32 TLMM_PULL_MASK = 0x3;
33	const u32 TLMM_HDRV_MASK = 0x7;
34
35	struct tlmm_cfg {
36		u32 bit;  /* bit in the register      */
37		u8 mask;  /* mask clk/dat/cmd control */
38		u8 val;
39	};
40
41	/* bit offsets in the sdc tlmm register */
42	enum {  SDC1_DATA_HDRV = 0,
43		SDC1_CMD_HDRV  = 3,
44		SDC1_CLK_HDRV  = 6,
45		SDC1_DATA_PULL = 9,
46		SDC1_CMD_PULL  = 11,
47		SDC1_CLK_PULL  = 13,
48		SDC1_RCLK_PULL = 15,
49	};
50
51	enum {  TLMM_PULL_DOWN	 = 0x1,
52		TLMM_PULL_UP   = 0x3,
53		TLMM_NO_PULL   = 0x0,
54	};
55
56	enum {  TLMM_CUR_VAL_10MA = 0x04,
57		TLMM_CUR_VAL_16MA = 0x07,
58	};
59	int i;
60
61	/* drive strength configs for sdhc pins */
62	const struct tlmm_cfg hdrv[] = {
63
64		{ SDC1_CLK_HDRV,  TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK, },
65		{ SDC1_CMD_HDRV,  TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, },
66		{ SDC1_DATA_HDRV, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, },
67	};
68
69	/* pull configs for sdhc pins */
70	const struct tlmm_cfg pull[] = {
71
72		{ SDC1_CLK_PULL,  TLMM_NO_PULL, TLMM_PULL_MASK, },
73		{ SDC1_CMD_PULL,  TLMM_PULL_UP, TLMM_PULL_MASK, },
74		{ SDC1_DATA_PULL, TLMM_PULL_UP, TLMM_PULL_MASK, },
75	};
76
77	const struct tlmm_cfg rclk[] = {
78
79		{ SDC1_RCLK_PULL, TLMM_PULL_DOWN, TLMM_PULL_MASK,},
80	};
81
82	for (i = 0; i < ARRAY_SIZE(hdrv); i++)
83		clrsetbits_le32(SDC1_HDRV_PULL_CTL_REG,
84				hdrv[i].mask << hdrv[i].bit,
85			hdrv[i].val  << hdrv[i].bit);
86
87	for (i = 0; i < ARRAY_SIZE(pull); i++)
88		clrsetbits_le32(SDC1_HDRV_PULL_CTL_REG,
89				pull[i].mask << pull[i].bit,
90			pull[i].val  << pull[i].bit);
91
92	for (i = 0; i < ARRAY_SIZE(rclk); i++)
93		clrsetbits_le32(SDC1_HDRV_PULL_CTL_REG,
94				rclk[i].mask << rclk[i].bit,
95			rclk[i].val  << rclk[i].bit);
96}
97
98void qcom_board_init(void)
99{
100	sdhci_power_init();
101}
102
103/* Check for vol- button - if pressed - stop autoboot */
104int misc_init_r(void)
105{
106	struct udevice *btn;
107	int ret;
108	enum button_state_t state;
109
110	ret = button_get_by_label("pwrkey", &btn);
111	if (ret < 0) {
112		printf("Couldn't find power button!\n");
113		return ret;
114	}
115
116	state = button_get_state(btn);
117	if (state == BUTTON_ON) {
118		env_set("bootdelay", "-1");
119		printf("Power button pressed - dropping to console.\n");
120	}
121
122	return 0;
123}
124