317 lines
9.9 KiB
C
317 lines
9.9 KiB
C
#include <common.h>
|
|
#include <boot_rkimg.h>
|
|
#include <dm.h>
|
|
#include <malloc.h>
|
|
#include <linux/libfdt.h>
|
|
#include <fdt_support.h>
|
|
#include <fdtdec.h>
|
|
#include <of_live.h>
|
|
#include <dm/root.h>
|
|
#include <dm/of_access.h>
|
|
#include <dm/lists.h>
|
|
#include <asm/arch/hotkey.h>
|
|
#include <environment.h>
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
static int of_set_property_by_path(char *path, char *prop, void *value, int prop_len, int no)
|
|
{
|
|
struct device_node *node;
|
|
struct property *node_prop;
|
|
struct udevice *pdev;
|
|
int ret;
|
|
int len = 0;
|
|
|
|
node = of_find_node_opts_by_path(path, NULL);
|
|
if(node){
|
|
node_prop = of_find_property(node, prop, &len);
|
|
if(node_prop){
|
|
node_prop->length = (prop_len > len)?len:prop_len;
|
|
memcpy(node_prop->value, value, node_prop->length);
|
|
}
|
|
node_prop = of_find_property(node, prop, &len);
|
|
if(!strncmp(value, "okay", 4)){
|
|
if(strcmp(path, "/syscon@fdc60000/lvds")){
|
|
lists_bind_fdt(gd->dm_root,np_to_ofnode(node), NULL);
|
|
} else {
|
|
ret = uclass_get_device_by_name(UCLASS_SYSCON, "syscon@fdc60000", &pdev);
|
|
if(ret){
|
|
printf("can't find lvds parent device\n");
|
|
return -1;
|
|
}
|
|
lists_bind_fdt(pdev, np_to_ofnode(node), NULL);
|
|
}
|
|
|
|
if(strcmp(path, "/syscon@fdc60000/rgb")){
|
|
lists_bind_fdt(gd->dm_root,np_to_ofnode(node), NULL);
|
|
} else {
|
|
ret = uclass_get_device_by_name(UCLASS_SYSCON, "syscon@fdc60000", &pdev);
|
|
if(ret){
|
|
printf("can't find rgb parent device\n");
|
|
return -1;
|
|
}
|
|
lists_bind_fdt(pdev, np_to_ofnode(node), NULL);
|
|
}
|
|
}
|
|
} else {
|
|
printf("%s not found\n", path);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int forlinx_fixup_display(void)
|
|
{
|
|
|
|
char *vp0, *vp1,*vp2;
|
|
const char *prop;
|
|
int control_node, need_save = 0;
|
|
|
|
|
|
vp0 = env_get("video_hdmi");
|
|
vp1 = env_get("video_mipi_edp");
|
|
vp2 = env_get("video_lvds_rgb");
|
|
|
|
if(vp0 == NULL || !strncmp(vp0, "off", 3)){
|
|
printf("hdmi default off\n");
|
|
}
|
|
|
|
if(vp1 == NULL || !strncmp(vp1, "off", 3)){
|
|
printf("mipi or edp default off\n");
|
|
}
|
|
|
|
if(vp2 == NULL || !strncmp(vp2, "off", 3)){
|
|
printf("lvds or rgb default off\n");
|
|
}
|
|
|
|
control_node = fdt_path_offset(gd->fdt_blob, "/forlinx_control");
|
|
if(control_node > 0){
|
|
if(fdtdec_get_is_enabled((void*)gd->fdt_blob, control_node)){
|
|
printf("Display force mode in dtb\n");
|
|
prop = fdt_getprop((void*)gd->fdt_blob, control_node, "video-hdmi", NULL);
|
|
if(prop){
|
|
if(strcmp(vp0, prop))
|
|
need_save = 1;
|
|
env_set("video_hdmi", prop);
|
|
}
|
|
prop = fdt_getprop((void*)gd->fdt_blob, control_node, "video-mipi-edp", NULL);
|
|
if(prop){
|
|
if(strcmp(vp1, prop))
|
|
need_save = 1;
|
|
env_set("video_mipi_edp", prop);
|
|
}
|
|
prop = fdt_getprop((void*)gd->fdt_blob, control_node, "video-lvds-rgb", NULL);
|
|
if(prop){
|
|
if(strcmp(vp2, prop))
|
|
need_save = 1;
|
|
env_set("video_lvds_rgb", prop);
|
|
}
|
|
}
|
|
|
|
if(need_save){
|
|
printf("save uboot default display by kernel force\n");
|
|
env_save();
|
|
}
|
|
|
|
vp0 = env_get("video_hdmi");
|
|
vp1 = env_get("video_mipi_edp");
|
|
vp2 = env_get("video_lvds_rgb");
|
|
}
|
|
|
|
|
|
|
|
if(!strncmp(vp0, "hdmi", 4)){
|
|
of_set_property_by_path("/display-subsystem/route/route-hdmi", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/hdmi@fe0a0000/ports/port/endpoint@0", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/hdmi@fe0a0000", "status", "okay", 5, 1);
|
|
}
|
|
|
|
|
|
if(!strncmp(vp1, "mipi", 4)){
|
|
of_set_property_by_path("/display-subsystem/route/route-dsi1", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/dsi@fe070000/ports/port@0/endpoint@1", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/dsi@fe070000", "status", "okay", 5, 1);
|
|
}
|
|
|
|
|
|
if(!strncmp(vp1, "edp", 3)){
|
|
of_set_property_by_path("/edp@fe0c0000", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/edp@fe0c0000/ports/port@0/endpoint@1", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/display-subsystem/route/route-edp", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/edp-phy@fdcb0000", "status", "okay", 5, 1);
|
|
}
|
|
|
|
if(!strncmp(vp2, "lvds", 4)){
|
|
of_set_property_by_path("/syscon@fdc60000/lvds", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/syscon@fdc60000/lvds/ports/port@0/endpoint@2", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/display-subsystem/route/route-lvds", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/i2c@fe5b0000/gt9xx-lvds@5d", "status", "okay", 5, 1);
|
|
|
|
of_set_property_by_path("/i2c@fe5b0000/gt9xx-rgb@14", "status", "disabled", 9, 1);
|
|
}
|
|
|
|
if(!strncmp(vp2, "rgb", 3)){
|
|
of_set_property_by_path("/syscon@fdc60000/rgb", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/syscon@fdc60000/rgb/ports/port@0/endpoint@2", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/display-subsystem/route/route-rgb", "status", "okay", 5, 1);
|
|
of_set_property_by_path("/i2c@fe5b0000/gt9xx-rgb@14", "status", "okay", 5, 1);
|
|
|
|
of_set_property_by_path("/spi@fe630000", "status", "disabled", 9, 1);
|
|
of_set_property_by_path("/serial@fe670000", "status", "disabled", 9, 1);
|
|
of_set_property_by_path("/serial@fe680000", "status", "disabled", 9, 1);
|
|
of_set_property_by_path("/serial@fe690000", "status", "disabled", 9, 1);
|
|
of_set_property_by_path("/ethernet@fe2a0000", "status", "disabled", 9, 1);
|
|
of_set_property_by_path("/ethernet@fe010000", "status", "disabled", 9, 1);
|
|
of_set_property_by_path("/i2c@fe5b0000/gt9xx-lvds@5d", "status", "disabled", 9, 1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int forlinx_fixup_fdt(const void *fdt)
|
|
{
|
|
char *vp0 = NULL;
|
|
char *vp1 = NULL;
|
|
char *vp2 = NULL;
|
|
|
|
vp0 = env_get("video_hdmi");
|
|
vp1 = env_get("video_mipi_edp");
|
|
vp2 = env_get("video_lvds_rgb");
|
|
|
|
if(vp0 == NULL || !strncmp(vp0, "off", 3)){
|
|
printf("hdmi default off\n");
|
|
}
|
|
|
|
if(vp1 == NULL || !strncmp(vp1, "off", 3)){
|
|
printf("dsi edp default off\n");
|
|
}
|
|
|
|
if(vp2 == NULL || !strncmp(vp2, "off", 3)){
|
|
printf("lvds rgb default off\n");
|
|
}
|
|
|
|
if(!strncmp(vp0, "hdmi", 4)){
|
|
do_fixup_by_path((void*)fdt, "/display-subsystem/route/route-hdmi", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/hdmi@fe0a0000/ports/port/endpoint@0", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/hdmi@fe0a0000", "status", "okay", 5, 1);
|
|
}
|
|
|
|
|
|
if(!strncmp(vp1, "dsi", 3)){
|
|
do_fixup_by_path((void*)fdt, "/display-subsystem/route/route-dsi1", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/dsi@fe070000/ports/port@0/endpoint@1", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/dsi@fe070000", "status", "okay", 5, 1);
|
|
}
|
|
|
|
|
|
if(!strncmp(vp1, "edp", 3)){
|
|
do_fixup_by_path((void*)fdt, "/edp@fe0c0000", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/edp@fe0c0000/ports/port@0/endpoint@1", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/display-subsystem/route/route-edp", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/edp-phy@fdcb0000", "status", "okay", 5, 1);
|
|
}
|
|
|
|
if(!strncmp(vp2, "lvds", 4)){
|
|
do_fixup_by_path((void*)fdt, "/syscon@fdc60000/lvds", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/syscon@fdc60000/lvds/ports/port@0/endpoint@2", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/display-subsystem/route/route-lvds", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/i2c@fe5b0000/gt9xx-lvds@5d", "status", "okay", 5, 1);
|
|
|
|
of_set_property_by_path("/i2c@fe5b0000/gt9xx-rgb@14", "status", "disabled", 9, 1);
|
|
}
|
|
|
|
if(!strncmp(vp2, "rgb", 3)){
|
|
do_fixup_by_path((void*)fdt, "/syscon@fdc60000/rgb", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/syscon@fdc60000/rgb/ports/port@0/endpoint@2", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/display-subsystem/route/route-rgb", "status", "okay", 5, 1);
|
|
do_fixup_by_path((void*)fdt, "/i2c@fe5b0000/gt9xx-rgb@14", "status", "okay", 5, 1);
|
|
|
|
|
|
of_set_property_by_path("/spi@fe630000", "status", "disabled", 9, 1);
|
|
of_set_property_by_path("/serial@fe670000", "status", "disabled", 9, 1);
|
|
of_set_property_by_path("/serial@fe680000", "status", "disabled", 9, 1);
|
|
of_set_property_by_path("/serial@fe690000", "status", "disabled", 9, 1);
|
|
of_set_property_by_path("/ethernet@fe2a0000", "status", "disabled", 9, 1);
|
|
of_set_property_by_path("/ethernet@fe010000", "status", "disabled", 9, 1);
|
|
of_set_property_by_path("/i2c@fe5b0000/gt9xx-lvds@5d", "status", "disabled", 9, 1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void board_display_select(void)
|
|
{
|
|
int c = 0;
|
|
char *vp0, *vp1, *vp2;
|
|
|
|
while(1){
|
|
vp0 = env_get("video_hdmi");
|
|
vp1 = env_get("video_mipi_edp");
|
|
vp2 = env_get("video_lvds_rgb");
|
|
printf(
|
|
"---------------------------------------------\n"
|
|
"hdmi==>%s mipi_edp==>%s lvds_rgb=>%s\n"
|
|
"Select display\n"
|
|
"0:Exit\n"
|
|
"1:hdmi display %s\n"
|
|
"2:mipi_edp display %s\n"
|
|
"3:lvds_rgb display %s\n"
|
|
"---------------------------------------------\n"
|
|
, vp0, vp1, vp2, vp0, vp1, vp2
|
|
);
|
|
c = getc();
|
|
switch(c){
|
|
case '0':
|
|
return;
|
|
case '1':
|
|
if(!strcmp(vp0, "hdmi"))
|
|
env_set("video_hdmi", "off");
|
|
else
|
|
env_set("video_hdmi", "hdmi");
|
|
|
|
break;
|
|
case '2':
|
|
if(!strcmp(vp1, "mipi"))
|
|
env_set("video_mipi_edp", "edp");
|
|
else if(!strcmp(vp1, "edp"))
|
|
env_set("video_mipi_edp", "off");
|
|
else
|
|
env_set("video_mipi_edp", "mipi");
|
|
break;
|
|
case '3':
|
|
if(!strcmp(vp2, "lvds"))
|
|
env_set("video_lvds_rgb", "rgb");
|
|
else if(!strcmp(vp2, "rgb"))
|
|
env_set("video_lvds_rgb", "off");
|
|
else
|
|
env_set("video_lvds_rgb", "lvds");
|
|
break;
|
|
}
|
|
env_save();
|
|
}
|
|
}
|
|
|
|
void ctrl_menu_show(void)
|
|
{
|
|
int c = 0;
|
|
while(1){
|
|
printf(
|
|
"---------------------------------------------\n"
|
|
"0:Exit to console\n"
|
|
"1:Reboot\n"
|
|
"2:Display type\n"
|
|
"---------------------------------------------\n"
|
|
);
|
|
c = getc();
|
|
switch(c){
|
|
case '0':
|
|
return ;
|
|
case '1':
|
|
run_command("reset", 0);
|
|
case '2':
|
|
board_display_select();
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|