mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-12-19 02:03:06 +00:00
isp: Allocate heap carveout
Allocating this in m1n1 means we can treat it as a reserved-memory node and deal with knowing the size in m1n1, instead of the kernel. It also means we can deal with the firmware version dependency mess here. Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
parent
02c03a73b0
commit
668ea16c09
2 changed files with 129 additions and 2 deletions
130
src/isp.c
130
src/isp.c
|
@ -2,9 +2,23 @@
|
||||||
|
|
||||||
#include "adt.h"
|
#include "adt.h"
|
||||||
#include "dart.h"
|
#include "dart.h"
|
||||||
|
#include "firmware.h"
|
||||||
#include "pmgr.h"
|
#include "pmgr.h"
|
||||||
|
#include "soc.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define ISP_ASC_VERSION 0x1800000
|
||||||
|
|
||||||
|
#define ISP_VER_T8103 0xb0090
|
||||||
|
#define ISP_VER_T6000 0xb3091
|
||||||
|
#define ISP_VER_T8112 0xc1090
|
||||||
|
#define ISP_VER_T6020 0xc3091
|
||||||
|
|
||||||
|
// PMGR offset to enable to get the version info to work
|
||||||
|
#define ISP_PMGR_T8103 0x4018
|
||||||
|
#define ISP_PMGR_T6000 0x8
|
||||||
|
#define ISP_PMGR_T6020 0x4008
|
||||||
|
|
||||||
/* ISP DART has some quirks we must work around */
|
/* ISP DART has some quirks we must work around */
|
||||||
|
|
||||||
#define DART_T8020_ENABLED_STREAMS 0xfc
|
#define DART_T8020_ENABLED_STREAMS 0xfc
|
||||||
|
@ -66,6 +80,20 @@ static void isp_ctrr_init_t6000(u64 base, const struct dart_tunables *config, u3
|
||||||
write32(base + 0x13c, val);
|
write32(base + 0x13c, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isp_initialized = false;
|
||||||
|
static u64 heap_phys, heap_iova, heap_size, heap_top;
|
||||||
|
|
||||||
|
int isp_get_heap(u64 *phys, u64 *iova, u64 *size)
|
||||||
|
{
|
||||||
|
if (!isp_initialized)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*phys = heap_phys;
|
||||||
|
*iova = heap_iova;
|
||||||
|
*size = heap_size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int isp_init(void)
|
int isp_init(void)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -73,11 +101,13 @@ int isp_init(void)
|
||||||
const char *isp_path = "/arm-io/isp";
|
const char *isp_path = "/arm-io/isp";
|
||||||
const char *dart_path = "/arm-io/dart-isp";
|
const char *dart_path = "/arm-io/dart-isp";
|
||||||
|
|
||||||
int adt_path[8];
|
int adt_path[8], adt_isp_path[8];
|
||||||
|
int isp_node = adt_path_offset_trace(adt, isp_path, adt_isp_path);
|
||||||
int node = adt_path_offset_trace(adt, dart_path, adt_path);
|
int node = adt_path_offset_trace(adt, dart_path, adt_path);
|
||||||
if (node < 0) {
|
if (node < 0 || isp_node < 0) {
|
||||||
isp_path = "/arm-io/isp0";
|
isp_path = "/arm-io/isp0";
|
||||||
dart_path = "/arm-io/dart-isp0";
|
dart_path = "/arm-io/dart-isp0";
|
||||||
|
isp_node = adt_path_offset_trace(adt, isp_path, adt_isp_path);
|
||||||
node = adt_path_offset_trace(adt, dart_path, adt_path);
|
node = adt_path_offset_trace(adt, dart_path, adt_path);
|
||||||
}
|
}
|
||||||
if (node < 0)
|
if (node < 0)
|
||||||
|
@ -86,6 +116,100 @@ int isp_init(void)
|
||||||
if (pmgr_adt_power_enable(isp_path) < 0)
|
if (pmgr_adt_power_enable(isp_path) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
u64 isp_base;
|
||||||
|
u64 pmgr_base;
|
||||||
|
err = adt_get_reg(adt, adt_isp_path, "reg", 0, &isp_base, NULL);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = adt_get_reg(adt, adt_isp_path, "reg", 1, &pmgr_base, NULL);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
u32 pmgr_off;
|
||||||
|
switch (chip_id) {
|
||||||
|
case T8103:
|
||||||
|
case T8112:
|
||||||
|
pmgr_off = ISP_PMGR_T8103;
|
||||||
|
break;
|
||||||
|
case T6000 ... T6002:
|
||||||
|
pmgr_off = ISP_PMGR_T6000;
|
||||||
|
break;
|
||||||
|
case T6020 ... T6022:
|
||||||
|
pmgr_off = ISP_PMGR_T6020;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("isp: Unsupported SoC\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = pmgr_set_mode(pmgr_base + pmgr_off, PMGR_PS_ACTIVE);
|
||||||
|
if (err) {
|
||||||
|
printf("isp: Failed to power on\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 ver_rev = read32(isp_base + ISP_ASC_VERSION);
|
||||||
|
printf("isp: Version 0x%x\n", ver_rev);
|
||||||
|
|
||||||
|
pmgr_set_mode(pmgr_base + pmgr_off, PMGR_PS_PWRGATE);
|
||||||
|
|
||||||
|
/* TODO: confirm versions */
|
||||||
|
switch (ver_rev) {
|
||||||
|
case ISP_VER_T8103:
|
||||||
|
case ISP_VER_T8112:
|
||||||
|
switch (os_firmware.version) {
|
||||||
|
case V12_3 ... V12_4:
|
||||||
|
heap_top = 0x1800000;
|
||||||
|
break;
|
||||||
|
case V13_5:
|
||||||
|
heap_top = 0x1000000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("isp: unsupported firmware\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ISP_VER_T6000:
|
||||||
|
switch (os_firmware.version) {
|
||||||
|
case V12_3:
|
||||||
|
heap_top = 0xe00000;
|
||||||
|
break;
|
||||||
|
case V13_5:
|
||||||
|
heap_top = 0xf00000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("isp: unsupported firmware\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ISP_VER_T6020:
|
||||||
|
switch (os_firmware.version) {
|
||||||
|
case V13_5:
|
||||||
|
heap_top = 0xf00000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("isp: unsupported firmware\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("isp: unknown revision 0x%x\n", ver_rev);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct adt_segment_ranges *seg;
|
||||||
|
u32 segments_len;
|
||||||
|
|
||||||
|
seg = adt_getprop(adt, isp_node, "segment-ranges", &segments_len);
|
||||||
|
unsigned int count = segments_len / sizeof(*seg);
|
||||||
|
|
||||||
|
heap_iova = seg[count - 1].iova + seg[count - 1].size;
|
||||||
|
heap_size = heap_top - heap_iova;
|
||||||
|
heap_phys = top_of_memory_alloc(heap_size);
|
||||||
|
|
||||||
|
printf("isp: Heap: 0x%lx..0x%lx (0x%lx @ 0x%lx)\n", heap_iova, heap_top, heap_size, heap_phys);
|
||||||
|
|
||||||
enum dart_type_t type;
|
enum dart_type_t type;
|
||||||
const char *type_s;
|
const char *type_s;
|
||||||
if (adt_is_compatible(adt, node, "dart,t8020")) {
|
if (adt_is_compatible(adt, node, "dart,t8020")) {
|
||||||
|
@ -137,6 +261,8 @@ int isp_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isp_initialized = true;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
pmgr_adt_power_disable(isp_path);
|
pmgr_adt_power_disable(isp_path);
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -6,5 +6,6 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
int isp_init(void);
|
int isp_init(void);
|
||||||
|
int isp_get_heap(u64 *phys, u64 *iova, u64 *size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue