blob: fbbfc0e65e24ba4c0feedc04ec9129b563dbb0e5 [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>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +02009#include <common.h>
Simon Glassafb02152019-12-28 10:45:01 -070010#include <cpu_func.h>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020011#include <dm.h>
Caleb Connolly154ed1d2024-02-26 17:26:21 +000012#include <dm/pinctrl.h>
Simon Glass5e6201b2019-08-01 09:46:51 -060013#include <env.h>
Simon Glassa7b51302019-11-14 12:57:46 -070014#include <init.h>
Caleb Connolly878ffb62024-02-26 17:26:22 +000015#include <mmc.h>
Simon Glass274e0b02020-05-10 11:39:56 -060016#include <net.h>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020017#include <usb.h>
Simon Glass274e0b02020-05-10 11:39:56 -060018#include <asm/cache.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060019#include <asm/global_data.h>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020020#include <asm/gpio.h>
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +010021#include <fdt_support.h>
Simon Glassdbd79542020-05-10 11:40:11 -060022#include <linux/delay.h>
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020023
24DECLARE_GLOBAL_DATA_PTR;
25
Caleb Connolly878ffb62024-02-26 17:26:22 +000026/* UNSTUFF_BITS macro taken from Linux Kernel: drivers/mmc/core/sd.c */
27#define UNSTUFF_BITS(resp, start, size) \
28 ({ \
29 const int __size = size; \
30 const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \
31 const int __off = 3 - ((start) / 32); \
32 const int __shft = (start) & 31; \
33 u32 __res; \
34 \
35 __res = resp[__off] >> __shft; \
36 if (__size + __shft > 32) \
37 __res |= resp[__off - 1] << ((32 - __shft) % 32); \
38 __res & __mask; \
39 })
40
41static u32 msm_board_serial(void)
42{
43 struct mmc *mmc_dev;
44
45 mmc_dev = find_mmc_device(0);
46 if (!mmc_dev)
47 return 0;
48
49 if (mmc_init(mmc_dev))
50 return 0;
51
52 return UNSTUFF_BITS(mmc_dev->cid, 16, 32);
53}
54
55static void msm_generate_mac_addr(u8 *mac)
56{
57 /* use locally adminstrated pool */
58 mac[0] = 0x02;
59 mac[1] = 0x00;
60
61 /*
62 * Put the 32-bit serial number in the last 32-bit of the MAC address.
63 * Use big endian order so it is consistent with the serial number
64 * written as a hexadecimal string, e.g. 0x1234abcd -> 02:00:12:34:ab:cd
65 */
66 put_unaligned_be32(msm_board_serial(), &mac[2]);
67}
68
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020069/* Check for vol- button - if pressed - stop autoboot */
70int misc_init_r(void)
71{
Caleb Connolly89a90d02023-12-05 13:46:48 +000072 struct udevice *btn;
73 int ret;
74 enum button_state_t state;
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020075
Caleb Connolly89a90d02023-12-05 13:46:48 +000076 ret = button_get_by_label("vol_down", &btn);
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020077 if (ret < 0) {
Caleb Connolly89a90d02023-12-05 13:46:48 +000078 printf("Couldn't find power button!\n");
79 return ret;
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020080 }
81
Caleb Connolly89a90d02023-12-05 13:46:48 +000082 state = button_get_state(btn);
83 if (state == BUTTON_ON) {
Stephan Gerholda0d3b952021-07-14 10:56:25 +020084 env_set("preboot", "setenv preboot; fastboot 0");
Caleb Connolly89a90d02023-12-05 13:46:48 +000085 printf("vol_down pressed - Starting fastboot.\n");
Mateusz Kulikowskiee5e70d2016-03-31 23:12:33 +020086 }
87
88 return 0;
89}
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +010090
Caleb Connolly31385662024-02-26 17:26:25 +000091int qcom_late_init(void)
Ramon Fried63596f02018-09-21 13:35:46 +030092{
93 char serial[16];
94
95 memset(serial, 0, 16);
96 snprintf(serial, 13, "%x", msm_board_serial());
97 env_set("serial#", serial);
98 return 0;
99}
100
Ramon Friede82a31c2018-08-03 16:25:37 +0300101/* Fixup of DTB for Linux Kernel
102 * 1. Fixup installed DRAM.
103 * 2. Fixup WLAN/BT Mac address:
104 * First, check if MAC addresses for WLAN/BT exists as environemnt
105 * variables wlanaddr,btaddr. if not, generate a unique address.
106 */
107
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900108int ft_board_setup(void *blob, struct bd_info *bd)
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100109{
Ramon Friede82a31c2018-08-03 16:25:37 +0300110 u8 mac[ARP_HLEN];
111
Ramon Friede82a31c2018-08-03 16:25:37 +0300112 if (!eth_env_get_enetaddr("wlanaddr", mac)) {
113 msm_generate_mac_addr(mac);
Jorge Ramirez-Ortizf44f3012018-01-10 11:34:38 +0100114 };
115
Ramon Friede82a31c2018-08-03 16:25:37 +0300116 do_fixup_by_compat(blob, "qcom,wcnss-wlan",
117 "local-mac-address", mac, ARP_HLEN, 1);
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100118
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100119
Ramon Friede82a31c2018-08-03 16:25:37 +0300120 if (!eth_env_get_enetaddr("btaddr", mac)) {
121 msm_generate_mac_addr(mac);
122
123/* The BD address is same as WLAN MAC address but with
124 * least significant bit flipped.
125 */
126 mac[0] ^= 0x01;
127 };
Ramon Fried806549682018-07-31 12:29:58 +0300128
Ramon Friede82a31c2018-08-03 16:25:37 +0300129 do_fixup_by_compat(blob, "qcom,wcnss-bt",
130 "local-bd-address", mac, ARP_HLEN, 1);
Jorge Ramirez-Ortiz2cd3db92018-01-10 11:34:35 +0100131 return 0;
132}