Skip to content

Commit f4d6d20

Browse files
eilnmarcan
andcommitted
isp: ISP init module
Co-authored-by: Hector Martin <[email protected]> Signed-off-by: Hector Martin <[email protected]> Signed-off-by: Eileen Yoon <[email protected]>
1 parent f89e33c commit f4d6d20

4 files changed

Lines changed: 171 additions & 0 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ OBJECTS := \
110110
i2c.o \
111111
iodev.o \
112112
iova.o \
113+
isp.o \
113114
kboot.o \
114115
main.o \
115116
mcc.o \

src/isp.c

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/* SPDX-License-Identifier: MIT */
2+
3+
#include "adt.h"
4+
#include "dart.h"
5+
#include "firmware.h"
6+
#include "isp.h"
7+
#include "pmgr.h"
8+
#include "soc.h"
9+
#include "utils.h"
10+
11+
#define ISP_ASC_VERSION 0x1800000
12+
13+
#define ISP_VER_T8103 0xb0090
14+
#define ISP_VER_T6000 0xb3091
15+
#define ISP_VER_T8112 0xc1090
16+
#define ISP_VER_T6020 0xc3091
17+
18+
// PMGR offset to enable to get the version info to work
19+
#define ISP_PMGR_T8103 0x4018
20+
#define ISP_PMGR_T6000 0x8
21+
#define ISP_PMGR_T6020 0x4008
22+
23+
static bool isp_initialized = false;
24+
static u64 heap_phys, heap_iova, heap_size, heap_top;
25+
26+
int isp_get_heap(u64 *phys, u64 *iova, u64 *size)
27+
{
28+
if (!isp_initialized)
29+
return -1;
30+
31+
*phys = heap_phys;
32+
*iova = heap_iova;
33+
*size = heap_size;
34+
return 0;
35+
}
36+
37+
int isp_init(void)
38+
{
39+
int err = 0;
40+
41+
const char *isp_path = "/arm-io/isp";
42+
const char *dart_path = "/arm-io/dart-isp";
43+
44+
int adt_path[8], adt_isp_path[8];
45+
int isp_node = adt_path_offset_trace(adt, isp_path, adt_isp_path);
46+
int node = adt_path_offset_trace(adt, dart_path, adt_path);
47+
if (node < 0 || isp_node < 0) {
48+
isp_path = "/arm-io/isp0";
49+
dart_path = "/arm-io/dart-isp0";
50+
isp_node = adt_path_offset_trace(adt, isp_path, adt_isp_path);
51+
node = adt_path_offset_trace(adt, dart_path, adt_path);
52+
}
53+
if (node < 0)
54+
return 0;
55+
56+
if (pmgr_adt_power_enable(isp_path) < 0)
57+
return -1;
58+
59+
u64 isp_base;
60+
u64 pmgr_base;
61+
err = adt_get_reg(adt, adt_isp_path, "reg", 0, &isp_base, NULL);
62+
if (err)
63+
return err;
64+
65+
err = adt_get_reg(adt, adt_isp_path, "reg", 1, &pmgr_base, NULL);
66+
if (err)
67+
return err;
68+
69+
u32 pmgr_off;
70+
switch (chip_id) {
71+
case T8103:
72+
case T8112:
73+
pmgr_off = ISP_PMGR_T8103;
74+
break;
75+
case T6000 ... T6002:
76+
pmgr_off = ISP_PMGR_T6000;
77+
break;
78+
case T6020 ... T6022:
79+
pmgr_off = ISP_PMGR_T6020;
80+
break;
81+
default:
82+
printf("isp: Unsupported SoC\n");
83+
return -1;
84+
}
85+
86+
err = pmgr_set_mode(pmgr_base + pmgr_off, PMGR_PS_ACTIVE);
87+
if (err) {
88+
printf("isp: Failed to power on\n");
89+
return err;
90+
}
91+
92+
u32 ver_rev = read32(isp_base + ISP_ASC_VERSION);
93+
printf("isp: Version 0x%x\n", ver_rev);
94+
95+
pmgr_set_mode(pmgr_base + pmgr_off, PMGR_PS_PWRGATE);
96+
97+
/* TODO: confirm versions */
98+
switch (ver_rev) {
99+
case ISP_VER_T8103:
100+
case ISP_VER_T8112:
101+
switch (os_firmware.version) {
102+
case V12_3 ... V12_4:
103+
heap_top = 0x1800000;
104+
break;
105+
case V13_5:
106+
heap_top = 0x1000000;
107+
break;
108+
default:
109+
printf("isp: unsupported firmware\n");
110+
return -1;
111+
}
112+
break;
113+
case ISP_VER_T6000:
114+
switch (os_firmware.version) {
115+
case V12_3:
116+
heap_top = 0xe00000;
117+
break;
118+
case V13_5:
119+
heap_top = 0xf00000;
120+
break;
121+
default:
122+
printf("isp: unsupported firmware\n");
123+
return -1;
124+
}
125+
break;
126+
case ISP_VER_T6020:
127+
switch (os_firmware.version) {
128+
case V13_5:
129+
heap_top = 0xf00000;
130+
break;
131+
default:
132+
printf("isp: unsupported firmware\n");
133+
return -1;
134+
}
135+
break;
136+
default:
137+
printf("isp: unknown revision 0x%x\n", ver_rev);
138+
return -1;
139+
}
140+
141+
const struct adt_segment_ranges *seg;
142+
u32 segments_len;
143+
144+
seg = adt_getprop(adt, isp_node, "segment-ranges", &segments_len);
145+
unsigned int count = segments_len / sizeof(*seg);
146+
147+
heap_iova = seg[count - 1].iova + seg[count - 1].size;
148+
heap_size = heap_top - heap_iova;
149+
heap_phys = top_of_memory_alloc(heap_size);
150+
151+
printf("isp: Heap: 0x%lx..0x%lx (0x%lx @ 0x%lx)\n", heap_iova, heap_top, heap_size, heap_phys);
152+
153+
isp_initialized = true;
154+
155+
pmgr_adt_power_disable(isp_path);
156+
return err;
157+
}

src/isp.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* SPDX-License-Identifier: MIT */
2+
3+
#ifndef ISP_H
4+
#define ISP_H
5+
6+
#include "types.h"
7+
8+
int isp_init(void);
9+
int isp_get_heap(u64 *phys, u64 *iova, u64 *size);
10+
11+
#endif

src/kboot.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "devicetree.h"
1111
#include "exception.h"
1212
#include "firmware.h"
13+
#include "isp.h"
1314
#include "malloc.h"
1415
#include "mcc.h"
1516
#include "memory.h"
@@ -2254,6 +2255,7 @@ int kboot_boot(void *kernel)
22542255
usb_init();
22552256
pcie_init();
22562257
dapf_init_all();
2258+
isp_init();
22572259

22582260
printf("Setting SMP mode to WFE...\n");
22592261
smp_set_wfe_mode(true);

0 commit comments

Comments
 (0)