]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
626f048b MK |
2 | /* |
3 | * Board init file for Dragonboard 410C | |
4 | * | |
5 | * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> | |
626f048b MK |
6 | */ |
7 | ||
8 | #include <common.h> | |
9 | #include <dm.h> | |
10 | #include <usb.h> | |
11 | #include <asm/gpio.h> | |
e2beb872 | 12 | #include <fdt_support.h> |
626f048b MK |
13 | |
14 | DECLARE_GLOBAL_DATA_PTR; | |
15 | ||
e2beb872 | 16 | /* pointer to the device tree ammended by the firmware */ |
9337dfb4 | 17 | extern void *fw_dtb; |
e2beb872 | 18 | |
9337dfb4 JRO |
19 | void *board_fdt_blob_setup(void) |
20 | { | |
21 | if (fdt_magic(fw_dtb) != FDT_MAGIC) { | |
22 | printf("Firmware provided invalid dtb!\n"); | |
23 | return NULL; | |
24 | } | |
25 | ||
26 | return fw_dtb; | |
27 | } | |
e2beb872 | 28 | |
626f048b MK |
29 | int dram_init(void) |
30 | { | |
31 | gd->ram_size = PHYS_SDRAM_1_SIZE; | |
9337dfb4 | 32 | |
626f048b MK |
33 | return 0; |
34 | } | |
35 | ||
76b00aca | 36 | int dram_init_banksize(void) |
626f048b MK |
37 | { |
38 | gd->bd->bi_dram[0].start = PHYS_SDRAM_1; | |
39 | gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; | |
76b00aca SG |
40 | |
41 | return 0; | |
626f048b MK |
42 | } |
43 | ||
626f048b MK |
44 | int board_prepare_usb(enum usb_init_type type) |
45 | { | |
46 | static struct udevice *pmic_gpio; | |
47 | static struct gpio_desc hub_reset, usb_sel; | |
48 | int ret = 0, node; | |
49 | ||
50 | if (!pmic_gpio) { | |
51 | ret = uclass_get_device_by_name(UCLASS_GPIO, | |
52 | "pm8916_gpios@c000", | |
53 | &pmic_gpio); | |
54 | if (ret < 0) { | |
55 | printf("Failed to find pm8916_gpios@c000 node.\n"); | |
56 | return ret; | |
57 | } | |
58 | } | |
59 | ||
60 | /* Try to request gpios needed to start usb host on dragonboard */ | |
61 | if (!dm_gpio_is_valid(&hub_reset)) { | |
e160f7d4 SG |
62 | node = fdt_subnode_offset(gd->fdt_blob, |
63 | dev_of_offset(pmic_gpio), | |
626f048b MK |
64 | "usb_hub_reset_pm"); |
65 | if (node < 0) { | |
66 | printf("Failed to find usb_hub_reset_pm dt node.\n"); | |
67 | return node; | |
68 | } | |
150c5afe SG |
69 | ret = gpio_request_by_name_nodev(offset_to_ofnode(node), |
70 | "gpios", 0, &hub_reset, 0); | |
626f048b MK |
71 | if (ret < 0) { |
72 | printf("Failed to request usb_hub_reset_pm gpio.\n"); | |
73 | return ret; | |
74 | } | |
75 | } | |
76 | ||
77 | if (!dm_gpio_is_valid(&usb_sel)) { | |
e160f7d4 SG |
78 | node = fdt_subnode_offset(gd->fdt_blob, |
79 | dev_of_offset(pmic_gpio), | |
626f048b MK |
80 | "usb_sw_sel_pm"); |
81 | if (node < 0) { | |
82 | printf("Failed to find usb_sw_sel_pm dt node.\n"); | |
83 | return 0; | |
84 | } | |
150c5afe SG |
85 | ret = gpio_request_by_name_nodev(offset_to_ofnode(node), |
86 | "gpios", 0, &usb_sel, 0); | |
626f048b MK |
87 | if (ret < 0) { |
88 | printf("Failed to request usb_sw_sel_pm gpio.\n"); | |
89 | return ret; | |
90 | } | |
91 | } | |
92 | ||
93 | if (type == USB_INIT_HOST) { | |
94 | /* Start USB Hub */ | |
95 | dm_gpio_set_dir_flags(&hub_reset, | |
96 | GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); | |
97 | mdelay(100); | |
98 | /* Switch usb to host connectors */ | |
99 | dm_gpio_set_dir_flags(&usb_sel, | |
100 | GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); | |
101 | mdelay(100); | |
102 | } else { /* Device */ | |
103 | /* Disable hub */ | |
104 | dm_gpio_set_dir_flags(&hub_reset, GPIOD_IS_OUT); | |
105 | /* Switch back to device connector */ | |
106 | dm_gpio_set_dir_flags(&usb_sel, GPIOD_IS_OUT); | |
107 | } | |
108 | ||
109 | return 0; | |
110 | } | |
111 | ||
626f048b MK |
112 | /* Check for vol- button - if pressed - stop autoboot */ |
113 | int misc_init_r(void) | |
114 | { | |
115 | struct udevice *pon; | |
116 | struct gpio_desc resin; | |
117 | int node, ret; | |
118 | ||
119 | ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8916_pon@800", &pon); | |
120 | if (ret < 0) { | |
121 | printf("Failed to find PMIC pon node. Check device tree\n"); | |
122 | return 0; | |
123 | } | |
124 | ||
e160f7d4 SG |
125 | node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon), |
126 | "key_vol_down"); | |
626f048b MK |
127 | if (node < 0) { |
128 | printf("Failed to find key_vol_down node. Check device tree\n"); | |
129 | return 0; | |
130 | } | |
131 | ||
150c5afe SG |
132 | if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0, |
133 | &resin, 0)) { | |
626f048b MK |
134 | printf("Failed to request key_vol_down button.\n"); |
135 | return 0; | |
136 | } | |
137 | ||
138 | if (dm_gpio_get_value(&resin)) { | |
382bee57 | 139 | env_set("bootdelay", "-1"); |
626f048b MK |
140 | printf("Power button pressed - dropping to console.\n"); |
141 | } | |
142 | ||
143 | return 0; | |
144 | } | |
e2beb872 JRO |
145 | |
146 | int board_init(void) | |
147 | { | |
e2beb872 JRO |
148 | return 0; |
149 | } | |
150 | ||
151 | int ft_board_setup(void *blob, bd_t *bd) | |
152 | { | |
9337dfb4 JRO |
153 | int offset, len, i; |
154 | const char *mac; | |
155 | struct { | |
156 | const char *compatible; | |
157 | const char *property; | |
158 | } fix[] = { | |
159 | [0] = { | |
160 | /* update the kernel's dtb with wlan mac */ | |
161 | .compatible = "qcom,wcnss-wlan", | |
162 | .property = "local-mac-address", | |
163 | }, | |
164 | [1] = { | |
165 | /* update the kernel's dtb with bt mac */ | |
166 | .compatible = "qcom,wcnss-bt", | |
167 | .property = "local-bd-address", | |
168 | }, | |
169 | }; | |
170 | ||
171 | for (i = 0; i < sizeof(fix) / sizeof(fix[0]); i++) { | |
172 | offset = fdt_node_offset_by_compatible(gd->fdt_blob, -1, | |
173 | fix[i].compatible); | |
174 | if (offset < 0) | |
175 | continue; | |
176 | ||
177 | mac = fdt_getprop(gd->fdt_blob, offset, fix[i].property, &len); | |
178 | if (mac) | |
179 | do_fixup_by_compat(blob, fix[i].compatible, | |
180 | fix[i].property, mac, ARP_HLEN, 1); | |
181 | } | |
e2beb872 JRO |
182 | |
183 | return 0; | |
184 | } | |
0689eb74 JRO |
185 | |
186 | void reset_cpu(ulong addr) | |
187 | { | |
188 | psci_system_reset(); | |
189 | } |