blob: 0d282de9580dfe37476c0eef4e2678d786a6d1aa [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +02002/*
3 * Board init file for Dragonboard 410C
4 *
5 * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +02006 */
7
8#include <common.h>
Simon Glassafb02152019-12-28 10:45:01 -07009#include <cpu_func.h>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020010#include <dm.h>
Simon Glass5e6201b2019-08-01 09:46:51 -060011#include <env.h>
Simon Glassa7b51302019-11-14 12:57:46 -070012#include <init.h>
Simon Glass274e0b02020-05-10 11:39:56 -060013#include <net.h>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020014#include <usb.h>
Simon Glass274e0b02020-05-10 11:39:56 -060015#include <asm/cache.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060016#include <asm/global_data.h>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020017#include <asm/gpio.h>
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +010018#include <fdt_support.h>
Ramon Fried806549682018-07-31 12:29:58 +030019#include <asm/arch/dram.h>
Ramon Friede82a31c2018-08-03 16:25:37 +030020#include <asm/arch/misc.h>
Simon Glassdbd79542020-05-10 11:40:11 -060021#include <linux/delay.h>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020022
23DECLARE_GLOBAL_DATA_PTR;
24
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +010025/* pointer to the device tree ammended by the firmware */
Jorge Ramirez-Ortizf44f3012018-01-10 11:34:38 +010026extern void *fw_dtb;
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +010027
Jorge Ramirez-Ortizf44f3012018-01-10 11:34:38 +010028void *board_fdt_blob_setup(void)
29{
30 if (fdt_magic(fw_dtb) != FDT_MAGIC) {
31 printf("Firmware provided invalid dtb!\n");
32 return NULL;
33 }
34
35 return fw_dtb;
36}
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +010037
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020038int dram_init(void)
39{
40 gd->ram_size = PHYS_SDRAM_1_SIZE;
Jorge Ramirez-Ortizf44f3012018-01-10 11:34:38 +010041
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020042 return 0;
43}
44
Simon Glass2f949c32017-03-31 08:40:32 -060045int dram_init_banksize(void)
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020046{
47 gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
48 gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
Simon Glass2f949c32017-03-31 08:40:32 -060049
50 return 0;
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020051}
52
Ramon Friedbc866cc82018-09-21 13:35:43 +030053int board_usb_init(int index, enum usb_init_type init)
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020054{
55 static struct udevice *pmic_gpio;
56 static struct gpio_desc hub_reset, usb_sel;
57 int ret = 0, node;
58
59 if (!pmic_gpio) {
60 ret = uclass_get_device_by_name(UCLASS_GPIO,
61 "pm8916_gpios@c000",
62 &pmic_gpio);
63 if (ret < 0) {
64 printf("Failed to find pm8916_gpios@c000 node.\n");
65 return ret;
66 }
67 }
68
69 /* Try to request gpios needed to start usb host on dragonboard */
70 if (!dm_gpio_is_valid(&hub_reset)) {
Simon Glassdd79d6e2017-01-17 16:52:55 -070071 node = fdt_subnode_offset(gd->fdt_blob,
72 dev_of_offset(pmic_gpio),
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020073 "usb_hub_reset_pm");
74 if (node < 0) {
75 printf("Failed to find usb_hub_reset_pm dt node.\n");
76 return node;
77 }
Simon Glass1d9af1f2017-05-30 21:47:09 -060078 ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
79 "gpios", 0, &hub_reset, 0);
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020080 if (ret < 0) {
81 printf("Failed to request usb_hub_reset_pm gpio.\n");
82 return ret;
83 }
84 }
85
86 if (!dm_gpio_is_valid(&usb_sel)) {
Simon Glassdd79d6e2017-01-17 16:52:55 -070087 node = fdt_subnode_offset(gd->fdt_blob,
88 dev_of_offset(pmic_gpio),
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020089 "usb_sw_sel_pm");
90 if (node < 0) {
91 printf("Failed to find usb_sw_sel_pm dt node.\n");
92 return 0;
93 }
Simon Glass1d9af1f2017-05-30 21:47:09 -060094 ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
95 "gpios", 0, &usb_sel, 0);
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020096 if (ret < 0) {
97 printf("Failed to request usb_sw_sel_pm gpio.\n");
98 return ret;
99 }
100 }
101
Ramon Friedbc866cc82018-09-21 13:35:43 +0300102 if (init == USB_INIT_HOST) {
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +0200103 /* Start USB Hub */
104 dm_gpio_set_dir_flags(&hub_reset,
105 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
106 mdelay(100);
107 /* Switch usb to host connectors */
108 dm_gpio_set_dir_flags(&usb_sel,
109 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
110 mdelay(100);
111 } else { /* Device */
112 /* Disable hub */
113 dm_gpio_set_dir_flags(&hub_reset, GPIOD_IS_OUT);
114 /* Switch back to device connector */
115 dm_gpio_set_dir_flags(&usb_sel, GPIOD_IS_OUT);
116 }
117
118 return 0;
119}
120
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +0200121/* Check for vol- button - if pressed - stop autoboot */
122int misc_init_r(void)
123{
124 struct udevice *pon;
125 struct gpio_desc resin;
126 int node, ret;
127
128 ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8916_pon@800", &pon);
129 if (ret < 0) {
130 printf("Failed to find PMIC pon node. Check device tree\n");
131 return 0;
132 }
133
Simon Glassdd79d6e2017-01-17 16:52:55 -0700134 node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
135 "key_vol_down");
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +0200136 if (node < 0) {
137 printf("Failed to find key_vol_down node. Check device tree\n");
138 return 0;
139 }
140
Simon Glass1d9af1f2017-05-30 21:47:09 -0600141 if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
142 &resin, 0)) {
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +0200143 printf("Failed to request key_vol_down button.\n");
144 return 0;
145 }
146
147 if (dm_gpio_get_value(&resin)) {
Simon Glass6a38e412017-08-03 12:22:09 -0600148 env_set("bootdelay", "-1");
Ramon Frieddbc94102018-09-21 13:35:55 +0300149 env_set("bootcmd", "fastboot 0");
150 printf("key_vol_down pressed - Starting fastboot.\n");
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +0200151 }
152
153 return 0;
154}
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100155
156int board_init(void)
157{
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100158 return 0;
159}
160
Ramon Fried63596f02018-09-21 13:35:46 +0300161int board_late_init(void)
162{
163 char serial[16];
164
165 memset(serial, 0, 16);
166 snprintf(serial, 13, "%x", msm_board_serial());
167 env_set("serial#", serial);
168 return 0;
169}
170
Ramon Friede82a31c2018-08-03 16:25:37 +0300171/* Fixup of DTB for Linux Kernel
172 * 1. Fixup installed DRAM.
173 * 2. Fixup WLAN/BT Mac address:
174 * First, check if MAC addresses for WLAN/BT exists as environemnt
175 * variables wlanaddr,btaddr. if not, generate a unique address.
176 */
177
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900178int ft_board_setup(void *blob, struct bd_info *bd)
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100179{
Ramon Friede82a31c2018-08-03 16:25:37 +0300180 u8 mac[ARP_HLEN];
181
182 msm_fixup_memory(blob);
183
184 if (!eth_env_get_enetaddr("wlanaddr", mac)) {
185 msm_generate_mac_addr(mac);
Jorge Ramirez-Ortizf44f3012018-01-10 11:34:38 +0100186 };
187
Ramon Friede82a31c2018-08-03 16:25:37 +0300188 do_fixup_by_compat(blob, "qcom,wcnss-wlan",
189 "local-mac-address", mac, ARP_HLEN, 1);
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100190
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100191
Ramon Friede82a31c2018-08-03 16:25:37 +0300192 if (!eth_env_get_enetaddr("btaddr", mac)) {
193 msm_generate_mac_addr(mac);
194
195/* The BD address is same as WLAN MAC address but with
196 * least significant bit flipped.
197 */
198 mac[0] ^= 0x01;
199 };
Ramon Fried806549682018-07-31 12:29:58 +0300200
Ramon Friede82a31c2018-08-03 16:25:37 +0300201 do_fixup_by_compat(blob, "qcom,wcnss-bt",
202 "local-bd-address", mac, ARP_HLEN, 1);
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100203 return 0;
204}
Jorge Ramirez-Ortiz4154c9e2018-01-10 11:34:36 +0100205
Harald Seiler6f14d5f2020-12-15 16:47:52 +0100206void reset_cpu(void)
Jorge Ramirez-Ortiz4154c9e2018-01-10 11:34:36 +0100207{
208 psci_system_reset();
209}