kboot: lock dart-disp0 to prevent accidental resets

This prevents older systems from resetting dart-disp0 on init when they
encounter device trees with DCP/disp nodes.

Signed-off-by: Janne Grunau <j@jannau.net>
This commit is contained in:
Janne Grunau 2022-09-23 17:53:57 +02:00 committed by Hector Martin
parent e5db7233a9
commit 7ae0aac831
3 changed files with 36 additions and 0 deletions

View file

@ -321,6 +321,31 @@ dart_dev_t *dart_init_adt(const char *path, int instance, int device, bool keep_
return dart; return dart;
} }
void dart_lock_adt(const char *path, int instance)
{
int dart_path[8];
int node = adt_path_offset_trace(adt, path, dart_path);
if (node < 0) {
printf("dart: Error getting DART node %s\n", path);
return;
}
u64 base;
if (adt_get_reg(adt, dart_path, "reg", instance, &base, NULL) < 0) {
printf("dart: Error getting DART %s base address.\n", path);
return;
}
if (adt_is_compatible(adt, node, "dart,t8020") || adt_is_compatible(adt, node, "dart,t6000")) {
if (!(read32(base + DART_T8020_CONFIG) & DART_T8020_CONFIG_LOCK))
set32(base + DART_T8020_CONFIG, DART_T8020_CONFIG_LOCK);
} else if (adt_is_compatible(adt, node, "dart,t8110")) {
printf("dart: dart %s, locking ignored for t8110\n", path);
} else {
printf("dart: dart %s at 0x%lx is of an unknown type\n", path, base);
}
}
dart_dev_t *dart_init_fdt(void *dt, u32 phandle, int device, bool keep_pts) dart_dev_t *dart_init_fdt(void *dt, u32 phandle, int device, bool keep_pts)
{ {
int node = fdt_node_offset_by_phandle(dt, phandle); int node = fdt_node_offset_by_phandle(dt, phandle);

View file

@ -18,6 +18,7 @@ enum dart_type_t {
dart_dev_t *dart_init(uintptr_t base, u8 device, bool keep_pts, enum dart_type_t type); dart_dev_t *dart_init(uintptr_t base, u8 device, bool keep_pts, enum dart_type_t type);
dart_dev_t *dart_init_adt(const char *path, int instance, int device, bool keep_pts); dart_dev_t *dart_init_adt(const char *path, int instance, int device, bool keep_pts);
void dart_lock_adt(const char *path, int instance);
dart_dev_t *dart_init_fdt(void *dt, u32 phandle, int device, bool keep_pts); dart_dev_t *dart_init_fdt(void *dt, u32 phandle, int device, bool keep_pts);
int dart_setup_pt_region(dart_dev_t *dart, const char *path, int device); int dart_setup_pt_region(dart_dev_t *dart, const char *path, int device);
int dart_map(dart_dev_t *dart, uintptr_t iova, void *bfr, size_t len); int dart_map(dart_dev_t *dart, uintptr_t iova, void *bfr, size_t len);

View file

@ -870,6 +870,14 @@ static int dt_set_atc_tunables(void)
return 0; return 0;
} }
static int dt_set_display(void)
{
/* lock dart-disp0 to prevent old software from resetting it */
dart_lock_adt("/arm-io/dart-disp0", 0);
return 0;
}
static int dt_disable_missing_devs(const char *adt_prefix, const char *dt_prefix, int max_devs) static int dt_disable_missing_devs(const char *adt_prefix, const char *dt_prefix, int max_devs)
{ {
int ret = -1; int ret = -1;
@ -1096,6 +1104,8 @@ int kboot_prepare_dt(void *fdt)
return -1; return -1;
if (dt_set_atc_tunables()) if (dt_set_atc_tunables())
return -1; return -1;
if (dt_set_display())
return -1;
if (dt_disable_missing_devs("usb-drd", "usb@", 8)) if (dt_disable_missing_devs("usb-drd", "usb@", 8))
return -1; return -1;
if (dt_disable_missing_devs("i2c", "i2c@", 8)) if (dt_disable_missing_devs("i2c", "i2c@", 8))