1 /* 2 * Board init file for Dragonboard 820C 3 * 4 * (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <asm/arch/sysmap-apq8096.h> 10 #include <linux/arm-smccc.h> 11 #include <linux/psci.h> 12 #include <common.h> 13 #include <dm.h> 14 #include <asm/io.h> 15 #include <linux/bitops.h> 16 #include <asm/psci.h> 17 #include <asm/gpio.h> 18 19 DECLARE_GLOBAL_DATA_PTR; 20 21 int dram_init(void) 22 { 23 gd->ram_size = PHYS_SDRAM_SIZE; 24 25 return 0; 26 } 27 28 int dram_init_banksize(void) 29 { 30 gd->bd->bi_dram[0].start = PHYS_SDRAM_1; 31 gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; 32 33 gd->bd->bi_dram[1].start = PHYS_SDRAM_2; 34 gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; 35 36 return 0; 37 } 38 39 static void sdhci_power_init(void) 40 { 41 const u32 TLMM_PULL_MASK = 0x3; 42 const u32 TLMM_HDRV_MASK = 0x7; 43 44 struct tlmm_cfg { 45 u32 bit; /* bit in the register */ 46 u8 mask; /* mask clk/dat/cmd control */ 47 u8 val; 48 }; 49 50 /* bit offsets in the sdc tlmm register */ 51 enum { SDC1_DATA_HDRV = 0, 52 SDC1_CMD_HDRV = 3, 53 SDC1_CLK_HDRV = 6, 54 SDC1_DATA_PULL = 9, 55 SDC1_CMD_PULL = 11, 56 SDC1_CLK_PULL = 13, 57 SDC1_RCLK_PULL = 15, 58 }; 59 60 enum { TLMM_PULL_DOWN = 0x1, 61 TLMM_PULL_UP = 0x3, 62 TLMM_NO_PULL = 0x0, 63 }; 64 65 enum { TLMM_CUR_VAL_10MA = 0x04, 66 TLMM_CUR_VAL_16MA = 0x07, 67 }; 68 int i; 69 70 /* drive strength configs for sdhc pins */ 71 const struct tlmm_cfg hdrv[] = { 72 73 { SDC1_CLK_HDRV, TLMM_CUR_VAL_16MA, TLMM_HDRV_MASK, }, 74 { SDC1_CMD_HDRV, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, }, 75 { SDC1_DATA_HDRV, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK, }, 76 }; 77 78 /* pull configs for sdhc pins */ 79 const struct tlmm_cfg pull[] = { 80 81 { SDC1_CLK_PULL, TLMM_NO_PULL, TLMM_PULL_MASK, }, 82 { SDC1_CMD_PULL, TLMM_PULL_UP, TLMM_PULL_MASK, }, 83 { SDC1_DATA_PULL, TLMM_PULL_UP, TLMM_PULL_MASK, }, 84 }; 85 86 const struct tlmm_cfg rclk[] = { 87 88 { SDC1_RCLK_PULL, TLMM_PULL_DOWN, TLMM_PULL_MASK,}, 89 }; 90 91 for (i = 0; i < ARRAY_SIZE(hdrv); i++) 92 clrsetbits_le32(SDC1_HDRV_PULL_CTL_REG, 93 hdrv[i].mask << hdrv[i].bit, 94 hdrv[i].val << hdrv[i].bit); 95 96 for (i = 0; i < ARRAY_SIZE(pull); i++) 97 clrsetbits_le32(SDC1_HDRV_PULL_CTL_REG, 98 pull[i].mask << pull[i].bit, 99 pull[i].val << pull[i].bit); 100 101 for (i = 0; i < ARRAY_SIZE(rclk); i++) 102 clrsetbits_le32(SDC1_HDRV_PULL_CTL_REG, 103 rclk[i].mask << rclk[i].bit, 104 rclk[i].val << rclk[i].bit); 105 } 106 107 static void show_psci_version(void) 108 { 109 struct arm_smccc_res res; 110 111 arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res); 112 113 printf("PSCI: v%ld.%ld\n", 114 PSCI_VERSION_MAJOR(res.a0), 115 PSCI_VERSION_MINOR(res.a0)); 116 } 117 118 int board_init(void) 119 { 120 sdhci_power_init(); 121 show_psci_version(); 122 123 return 0; 124 } 125 126 void reset_cpu(ulong addr) 127 { 128 psci_system_reset(); 129 } 130 131 /* Check for vol- button - if pressed - stop autoboot */ 132 int misc_init_r(void) 133 { 134 struct udevice *pon; 135 struct gpio_desc resin; 136 int node, ret; 137 138 ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8994_pon@800", &pon); 139 if (ret < 0) { 140 printf("Failed to find PMIC pon node. Check device tree\n"); 141 return 0; 142 } 143 144 node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon), 145 "key_vol_down"); 146 if (node < 0) { 147 printf("Failed to find key_vol_down node. Check device tree\n"); 148 return 0; 149 } 150 151 if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0, 152 &resin, 0)) { 153 printf("Failed to request key_vol_down button.\n"); 154 return 0; 155 } 156 157 if (dm_gpio_get_value(&resin)) { 158 env_set("bootdelay", "-1"); 159 printf("Power button pressed - dropping to console.\n"); 160 } 161 162 return 0; 163 } 164