aboutsummaryrefslogtreecommitdiff
path: root/board/thead/light-c910/board.c
blob: 6ebbbb59eb868555ab3fdbba7f84dace80e5454d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
 * Author(s): Patrice Chotard, <patrice.chotard@st.com> for STMicroelectronics.
 */

#include <common.h>
#include <asm/io.h>
#include <dwc3-uboot.h>
#include <usb.h>
#include <cpu_func.h>
#include <asm/gpio.h>

#ifdef CONFIG_USB_DWC3
static struct dwc3_device dwc3_device_data = {
	.maximum_speed = USB_SPEED_SUPER,
	.dr_mode = USB_DR_MODE_PERIPHERAL,
	.index = 0,
};

int usb_gadget_handle_interrupts(int index)
{
	dwc3_uboot_handle_interrupt(index);
	return 0;
}

int board_usb_init(int index, enum usb_init_type init)
{
	dwc3_device_data.base = 0xFFE7040000UL;
	return dwc3_uboot_init(&dwc3_device_data);
}

int board_usb_cleanup(int index, enum usb_init_type init)
{
	dwc3_uboot_exit(index);
	return 0;
}

int g_dnl_board_usb_cable_connected(void)
{
	return 1;
}
#endif

#ifdef CONFIG_CMD_BOOT_SLAVE
#define E902_SYSREG_START	0xfffff48044
#define E902_SYSREG_RESET	0xfffff44024
#define E902_START_ADDRESS	0xFFEF8000
#define C910_E902_START_ADDRESS 0xFFFFEF8000
#define E902_IOPMP_BASE		0xFFFFC21000

#define C906_RST_ADDR_L		0xfffff48048
#define C906_RST_ADDR_H		0xfffff4804C
#define C906_START_ADDRESS_L	0x32000000
#define C906_START_ADDRESS_H	0x00
#define C910_C906_START_ADDRESS	0x0032000000
#define C906_CPR_IPCG_ADDRESS   0xFFCB000010
#define C906_IOCTL_GPIO_SEL_ADDRESS     0xFFCB01D000
#define C906_IOCTL_AF_SELH_ADDRESS      0xFFCB01D008
#define C906_RESET_REG                  0xfffff4403c


void set_slave_cpu_entry(phys_addr_t entry)
{
    writel(entry, (void *)E902_SYSREG_START);
}

void disable_slave_cpu(void)
{
    writel(0x0, (void *)E902_SYSREG_RESET);
}

void enable_slave_cpu(void)
{
    writel(0x3, (void *)E902_SYSREG_RESET);
}

void set_c906_cpu_entry(phys_addr_t entry_h, phys_addr_t entry_l)
{
	writel(entry_h, (volatile void *)C906_RST_ADDR_H);
	writel(entry_l, (volatile void *)C906_RST_ADDR_L);
}

void boot_audio(void)
{
        writel(0x37, (volatile void *)C906_RESET_REG);

        set_c906_cpu_entry(C906_START_ADDRESS_H, C906_START_ADDRESS_L);
        flush_cache((uintptr_t)C910_C906_START_ADDRESS, 0x20000);

        writel(0x7ffff1f, (volatile void *)C906_CPR_IPCG_ADDRESS);
        writel((1<<23) | (1<<24), (volatile void *)C906_IOCTL_GPIO_SEL_ADDRESS);
        writel(0, (volatile void *)C906_IOCTL_AF_SELH_ADDRESS);

        writel(0x3f, (volatile void *)C906_RESET_REG);
}

void boot_aon(void)
{
	writel(0xffffffff, (void *)(E902_IOPMP_BASE + 0xc0));
	disable_slave_cpu();
	set_slave_cpu_entry(E902_START_ADDRESS);
	flush_cache((uintptr_t)C910_E902_START_ADDRESS, 0x10000);
	enable_slave_cpu();
}

int do_bootslave(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	boot_aon();
	mdelay(100);
	boot_audio();
	return 0;
}
#endif

static void light_c910_set_gpio_output_high(void)
{
	ofnode node;
	struct gpio_desc select_gpio;

	printf("%s: trying to set gpio output high\n", __func__);

	node = ofnode_path("/config");
	if (!ofnode_valid(node)) {
		printf("%s: no /config node?\n", __func__);
		return;
	}

	if (gpio_request_by_name_nodev(node, "select-gpio", 0,
				       &select_gpio, GPIOD_IS_OUT)) {
		printf("%s: could not find a /config/select-gpio\n", __func__);
		return;
	}

	dm_gpio_set_value(&select_gpio, 1);
}

int misc_init_r(void)
{
	light_c910_set_gpio_output_high();

	return 0;
}