blob: bd2e213b3bca4e0ffa402e9ddfdebfc1b01bb34c [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
Caleb Connolly89a90d02023-12-05 13:46:48 +00008#include <button.h>
Simon Glassafb02152019-12-28 10:45:01 -07009#include <cpu_func.h>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020010#include <dm.h>
Caleb Connolly154ed1d2024-02-26 17:26:21 +000011#include <dm/pinctrl.h>
Simon Glass5e6201b2019-08-01 09:46:51 -060012#include <env.h>
Simon Glassa7b51302019-11-14 12:57:46 -070013#include <init.h>
Caleb Connolly878ffb62024-02-26 17:26:22 +000014#include <mmc.h>
Simon Glass274e0b02020-05-10 11:39:56 -060015#include <net.h>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020016#include <usb.h>
Simon Glass274e0b02020-05-10 11:39:56 -060017#include <asm/cache.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060018#include <asm/global_data.h>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020019#include <asm/gpio.h>
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +010020#include <fdt_support.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
Caleb Connolly878ffb62024-02-26 17:26:22 +000025/* UNSTUFF_BITS macro taken from Linux Kernel: drivers/mmc/core/sd.c */
26#define UNSTUFF_BITS(resp, start, size) \
27 ({ \
28 const int __size = size; \
29 const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \
30 const int __off = 3 - ((start) / 32); \
31 const int __shft = (start) & 31; \
32 u32 __res; \
33 \
34 __res = resp[__off] >> __shft; \
35 if (__size + __shft > 32) \
36 __res |= resp[__off - 1] << ((32 - __shft) % 32); \
37 __res & __mask; \
38 })
39
40static u32 msm_board_serial(void)
41{
42 struct mmc *mmc_dev;
43
44 mmc_dev = find_mmc_device(0);
45 if (!mmc_dev)
46 return 0;
47
48 if (mmc_init(mmc_dev))
49 return 0;
50
51 return UNSTUFF_BITS(mmc_dev->cid, 16, 32);
52}
53
54static void msm_generate_mac_addr(u8 *mac)
55{
56 /* use locally adminstrated pool */
57 mac[0] = 0x02;
58 mac[1] = 0x00;
59
60 /*
61 * Put the 32-bit serial number in the last 32-bit of the MAC address.
62 * Use big endian order so it is consistent with the serial number
63 * written as a hexadecimal string, e.g. 0x1234abcd -> 02:00:12:34:ab:cd
64 */
65 put_unaligned_be32(msm_board_serial(), &mac[2]);
66}
67
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020068/* Check for vol- button - if pressed - stop autoboot */
69int misc_init_r(void)
70{
Caleb Connolly89a90d02023-12-05 13:46:48 +000071 struct udevice *btn;
72 int ret;
73 enum button_state_t state;
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020074
Caleb Connolly89a90d02023-12-05 13:46:48 +000075 ret = button_get_by_label("vol_down", &btn);
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020076 if (ret < 0) {
Caleb Connolly89a90d02023-12-05 13:46:48 +000077 printf("Couldn't find power button!\n");
78 return ret;
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020079 }
80
Caleb Connolly89a90d02023-12-05 13:46:48 +000081 state = button_get_state(btn);
82 if (state == BUTTON_ON) {
Stephan Gerholda0d3b952021-07-14 10:56:25 +020083 env_set("preboot", "setenv preboot; fastboot 0");
Caleb Connolly89a90d02023-12-05 13:46:48 +000084 printf("vol_down pressed - Starting fastboot.\n");
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020085 }
86
87 return 0;
88}
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +010089
Caleb Connolly31385662024-02-26 17:26:25 +000090int qcom_late_init(void)
Ramon Fried63596f02018-09-21 13:35:46 +030091{
92 char serial[16];
93
94 memset(serial, 0, 16);
95 snprintf(serial, 13, "%x", msm_board_serial());
96 env_set("serial#", serial);
97 return 0;
98}
99
Ramon Friede82a31c2018-08-03 16:25:37 +0300100/* Fixup of DTB for Linux Kernel
101 * 1. Fixup installed DRAM.
102 * 2. Fixup WLAN/BT Mac address:
103 * First, check if MAC addresses for WLAN/BT exists as environemnt
104 * variables wlanaddr,btaddr. if not, generate a unique address.
105 */
106
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900107int ft_board_setup(void *blob, struct bd_info *bd)
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100108{
Ramon Friede82a31c2018-08-03 16:25:37 +0300109 u8 mac[ARP_HLEN];
110
Ramon Friede82a31c2018-08-03 16:25:37 +0300111 if (!eth_env_get_enetaddr("wlanaddr", mac)) {
112 msm_generate_mac_addr(mac);
Jorge Ramirez-Ortizf44f3012018-01-10 11:34:38 +0100113 };
114
Ramon Friede82a31c2018-08-03 16:25:37 +0300115 do_fixup_by_compat(blob, "qcom,wcnss-wlan",
116 "local-mac-address", mac, ARP_HLEN, 1);
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100117
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100118
Ramon Friede82a31c2018-08-03 16:25:37 +0300119 if (!eth_env_get_enetaddr("btaddr", mac)) {
120 msm_generate_mac_addr(mac);
121
122/* The BD address is same as WLAN MAC address but with
123 * least significant bit flipped.
124 */
125 mac[0] ^= 0x01;
126 };
Ramon Fried806549682018-07-31 12:29:58 +0300127
Ramon Friede82a31c2018-08-03 16:25:37 +0300128 do_fixup_by_compat(blob, "qcom,wcnss-bt",
129 "local-bd-address", mac, ARP_HLEN, 1);
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100130 return 0;
131}