From 557c24d082b6ecb9bfe5407b77ae43fa7650a5dc Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 17 Feb 2023 11:02:20 +0000 Subject: [PATCH] add eDP LVDS PCIE WIFI6 --- u-boot/arch/arm/mach-rockchip/kernel_dtb.c | 497 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 497 insertions(+), 0 deletions(-) diff --git a/u-boot/arch/arm/mach-rockchip/kernel_dtb.c b/u-boot/arch/arm/mach-rockchip/kernel_dtb.c old mode 100644 new mode 100755 index 2f24cfa..3d3aa6a --- a/u-boot/arch/arm/mach-rockchip/kernel_dtb.c +++ b/u-boot/arch/arm/mach-rockchip/kernel_dtb.c @@ -16,6 +16,500 @@ DECLARE_GLOBAL_DATA_PTR; + +#if 1 +struct display_fixup_data { + int type; + + int delay_prepare; + int delay_enable; + int delay_disable; + int delay_unprepare; + int delay_reset; + int delay_init; + int size_width; + int size_height; + + int clock_frequency; + int hactive; + int hfront_porch; + int hsync_len; + int hback_porch; + int vactive; + int vfront_porch; + int vsync_len; + int vback_porch; + int hsync_active; + int vsync_active; + int de_active; + int pixelclk_active; + + /* for DSI Panel */ + int flags; + int format; + int lanes; + int init_cmd_length; + u8 *init_cmd; + + int nodka_lvds; +}; +enum { + PANEL_TYPE_DSI, + PANEL_TYPE_EDP, + PANEL_TYPE_LVDS, +}; + +#define CUSTOM_PARTITION_NAME "baseparameter" +#define LCD_PARAM_MAX_COUNT 27 + +int lcdParam[LCD_PARAM_MAX_COUNT]; +char param_buf_temp[4*1024] = {0}; + +void set_lcdparam_test_edp(struct display_fixup_data *data) +{ + + data->type = PANEL_TYPE_DSI; + data->delay_prepare = 100; + data->delay_enable = 100; + data->delay_disable = 100; + data->delay_unprepare = 100; + data->delay_reset = 100; + data->delay_init = 100; + data->size_width = 240; + data->size_height = 300; + data->clock_frequency = 60000000; + data->hactive = 1024; + data->hfront_porch = 12; + data->hsync_len = 16; + data->hback_porch = 48; + data->vactive = 600; + data->vfront_porch = 8; + data->vsync_len = 4; + data->vback_porch = 8; + data->hsync_active = 0; + data->vsync_active = 0; + data->de_active = 0; + data->pixelclk_active = 0; + data->flags = 0; + data->format = 0; + data->lanes = 4; + *(data->init_cmd + 0) = 0x05; + *(data->init_cmd + 1) = 0x00; + *(data->init_cmd + 2) = 0x01; + *(data->init_cmd + 3) = 0x01; + + *(data->init_cmd + 4) = 0x05; + *(data->init_cmd + 5) = 0x00; + *(data->init_cmd + 6) = 0x01; + *(data->init_cmd + 7) = 0x02; + + *(data->init_cmd + 8) = 0x05; + *(data->init_cmd + 9) = 0x00; + *(data->init_cmd + 10) = 0x01; + *(data->init_cmd + 11) = 0x03; + + *(data->init_cmd + 12) = 0x05; + *(data->init_cmd + 13) = 0x00; + *(data->init_cmd + 14) = 0x01; + *(data->init_cmd + 15) = 0x05; + +} + +int get_lcdparam_info_from_custom_partition(struct display_fixup_data *data) +{ + + struct blk_desc *dev_desc; + disk_partition_t part_info; + char *boot_partname = CUSTOM_PARTITION_NAME; + int ret,i; + + dev_desc = rockchip_get_bootdev(); + if (!dev_desc) { + printf("%s: dev_desc is NULL!\n", __func__); + return -ENODEV; + } + + ret = part_get_info_by_name(dev_desc, boot_partname, &part_info); + if (ret < 0) { + printf("%s: failed to get %s part, ret=%d\n", + __func__, boot_partname, ret); + /* RKIMG can support part table without 'boot' */ + return -1; + } + + printf("block num: %lu, name %s ,type %s,block size :%lu\n",part_info.size,part_info.name,part_info.type,part_info.blksz); + + ret = blk_dread(dev_desc, part_info.start + 512, 1, param_buf_temp); + if (ret != 1) { + printf("%s: failed to read screen parameter, ret=%d\n", + __func__, ret); + return -1; + } + + for (i = 0; i < LCD_PARAM_MAX_COUNT; i++) { + lcdParam[i] = param_buf_temp[i * 4]; + lcdParam[i] = (lcdParam[i] << 8) + param_buf_temp[i * 4 + 1]; + lcdParam[i] = (lcdParam[i] << 8) + param_buf_temp[i * 4 + 2]; + lcdParam[i] = (lcdParam[i] << 8) + param_buf_temp[i * 4 + 3]; + if(lcdParam[i] < 0){ + lcdParam[i] = -lcdParam[i]; + } + if(lcdParam[i] > 100000 && i != 9){ + lcdParam[i] = 0; + } + printf("--get-- lcd_param %d\n",lcdParam[i]); + } + + if(lcdParam[14] == 0 || lcdParam[10] == 0){ + return -1; + } + printf("-get- crc32 = 0X%02X%02X%02X%02X\n", + param_buf_temp[LCD_PARAM_MAX_COUNT * 4], param_buf_temp[LCD_PARAM_MAX_COUNT * 4 + 1], + param_buf_temp[LCD_PARAM_MAX_COUNT * 4 + 2], param_buf_temp[LCD_PARAM_MAX_COUNT * 4 + 3]); + + data->type = lcdParam[0]; + data->delay_prepare = lcdParam[4]; + data->delay_enable = lcdParam[2]; + data->delay_disable = lcdParam[3]; + data->delay_unprepare = lcdParam[1]; + data->delay_reset = lcdParam[5]; + data->delay_init = lcdParam[6]; + data->size_width = lcdParam[7]; + data->size_height = lcdParam[8]; + data->clock_frequency = lcdParam[9]; + data->hactive = lcdParam[10]; + data->hfront_porch = lcdParam[11]; + data->hsync_len = lcdParam[12]; + data->hback_porch = lcdParam[13]; + data->vactive = lcdParam[14]; + data->vfront_porch = lcdParam[15]; + data->vsync_len = lcdParam[16]; + data->vback_porch = lcdParam[17]; + data->hsync_active = lcdParam[18]; + data->vsync_active = lcdParam[19]; + data->de_active = lcdParam[20]; + data->pixelclk_active = lcdParam[21]; + data->flags = lcdParam[22]; + data->format = lcdParam[23]; + data->lanes = lcdParam[24]; + data->init_cmd_length = lcdParam[25] = 16; + data->nodka_lvds = lcdParam[26]; + data->init_cmd = malloc(sizeof(*(data->init_cmd)) * data->init_cmd_length); + for(i = 0; i < data->init_cmd_length; i++){ + *(data->init_cmd + i) = param_buf_temp[100 + i]; + // printf("init cmd = %x\n",param_buf_temp[100 + i]); + + } + +// set_lcdparam_test_edp(data); + + return 0; +} + +#endif + + +static int find_connector_node(const void *blob, int node) +{ + int phandle, remote; + int nodedepth; + + phandle = fdt_getprop_u32_default_node(blob, node, 0, + "remote-endpoint", -1); + remote = fdt_node_offset_by_phandle(blob, phandle); + nodedepth = fdt_node_depth(blob, remote); + + return fdt_supernode_atdepth_offset(blob, remote, + nodedepth - 3, NULL); +} + +static int get_panel_node(const void *blob, int conn_node) +{ + int panel, ports, port, ep, remote, ph, nodedepth; + + panel = fdt_subnode_offset(blob, conn_node, "panel"); + printf("panel_1=%d\n",panel); + if (panel > 0) { + return panel; + } + + ports = fdt_subnode_offset(blob, conn_node, "ports"); + if (ports < 0) + { + return -ENODEV; + } + + fdt_for_each_subnode(port, blob, ports) { + fdt_for_each_subnode(ep, blob, port) { + ph = fdt_getprop_u32_default_node(blob, ep, 0, + "remote-endpoint", 0); + if (!ph) + continue; + + remote = fdt_node_offset_by_phandle(blob, ph); + + nodedepth = fdt_node_depth(blob, remote); + if (nodedepth < 2) + continue; + + panel = fdt_supernode_atdepth_offset(blob, remote, + nodedepth - 2, + NULL); + break; + } + } + printf("panel_2=%d\n",panel); + return panel; +} + +static int fdt_fixup_node_status(void *blob, int node, enum fdt_status status) +{ + int ret; + +// printf("My fixup %s %d\n", fdt_get_name(blob, node, NULL), status); + +set_status: + ret = fdt_set_node_status(blob, node, status, 0); + if (ret == -FDT_ERR_NOSPACE) { + ret = fdt_increase_size(blob, 512); + if (!ret) + goto set_status; + else + goto err_size; + } else if (ret < 0) { + printf("Can't set node status: %s\n", fdt_strerror(ret)); + return ret; + } + + return 0; + +err_size: + printf("Can't increase blob size: %s\n", fdt_strerror(ret)); + return ret; +} + +static int fdt_fixup_panel_init_sequence(void *fdt, int node,const struct display_fixup_data *data) +{ + #if 0 + u8 init_buf[] = {0x05, 0x00, 0x01, 0x78, 0x15, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x01, 0x14,0x39, 0x01, 0x03, 0x02, 0x29, 0x11}; + u8 exit_buf[] = {0x05, 0x64, 0x01, 0x29, 0x05, 0x64, 0x01, 0x11}; + #endif + int ret; + +add_seq: + ret = fdt_setprop(fdt, node, "panel-init-sequence", data->init_cmd, data->init_cmd_length); + if (ret == -FDT_ERR_NOSPACE) { + printf(" init sequence FDT_ERR_NOSPACE\n"); + ret = fdt_increase_size(fdt, data->init_cmd_length * 4);//gln the length needs precision + if (!ret) + goto add_seq; + else + goto err_size; + } else if (ret < 0) { + printf("Can't add property: %s\n", fdt_strerror(ret)); + return ret; + } + +#if 0 +add_init_seq: + ret = fdt_setprop(fdt, node, "panel-init-sequence", init_buf, sizeof(init_buf)); + if (ret == -FDT_ERR_NOSPACE) { + printf(" init sequence FDT_ERR_NOSPACE\n"); + ret = fdt_increase_size(fdt, 512);//gln the length needs precision + if (!ret) + goto add_init_seq; + else + goto err_size; + } else if (ret < 0) { + printf("Can't add property: %s\n", fdt_strerror(ret)); + return ret; + } +add_exit_seq: + ret = fdt_setprop(fdt, node, "panel-exit-sequence", exit_buf, sizeof(exit_buf)); + if (ret == -FDT_ERR_NOSPACE) { + printf(" init sequence FDT_ERR_NOSPACE\n"); + ret = fdt_increase_size(fdt, 512);//gln the length needs precision + if (!ret) + goto add_exit_seq; + else + goto err_size; + } else if (ret < 0) { + printf("Can't add property: %s\n", fdt_strerror(ret)); + return ret; + } +#endif + + return 0; + +err_size: + printf("Can't increase blob size: %s\n", fdt_strerror(ret)); + return ret; +} + +static int fdt_fixup_setprop_u32(void *fdt, int node, const char *name, u32 data) +{ + int ret; + +set_prop: + ret = fdt_setprop_u32(fdt, node, name, data); + if (ret == -FDT_ERR_NOSPACE) { + ret = fdt_increase_size(fdt, 512); + if (!ret) + goto set_prop; + else + goto err_size; + } else if (ret < 0) { + printf("Can't add property: %s\n", fdt_strerror(ret)); + return ret; + } + + return 0; + +err_size: + printf("Can't increase blob size: %s\n", fdt_strerror(ret)); + return ret; +} + +static void fdt_fixup_display_timing(void *blob, int node, + const struct display_fixup_data *data) +{ + fdt_fixup_setprop_u32(blob, node, "clock-frequency", data->clock_frequency); + fdt_fixup_setprop_u32(blob, node, "hactive", data->hactive); + fdt_fixup_setprop_u32(blob, node, "hfront-porch", data->hfront_porch); + fdt_fixup_setprop_u32(blob, node, "hsync-len", data->hsync_len); + fdt_fixup_setprop_u32(blob, node, "hback-porch", data->hback_porch); + fdt_fixup_setprop_u32(blob, node, "vactive", data->vactive); + fdt_fixup_setprop_u32(blob, node, "vfront-porch", data->vfront_porch); + fdt_fixup_setprop_u32(blob, node, "vsync-len", data->vsync_len); + fdt_fixup_setprop_u32(blob, node, "vback-porch", data->vback_porch); + fdt_fixup_setprop_u32(blob, node, "hsync-active", data->hsync_active); + fdt_fixup_setprop_u32(blob, node, "vsync-active", data->vsync_active); + fdt_fixup_setprop_u32(blob, node, "de-active", data->de_active); + fdt_fixup_setprop_u32(blob, node, "pixelclk-active", data->pixelclk_active); +} + +static void fdt_fixup_panel_node(void *blob, int node, const char *name, + const struct display_fixup_data *data) +{ + if (!strcmp(name, "dsi")) { + fdt_setprop_u32(blob, node, "dsi,flags", data->flags); + fdt_setprop_u32(blob, node, "dsi,format", data->format); + fdt_setprop_u32(blob, node, "dsi,lanes", data->lanes); + fdt_fixup_panel_init_sequence(blob, node,data); + } + fdt_fixup_setprop_u32(blob, node, "prepare-delay-ms", data->delay_prepare); + fdt_fixup_setprop_u32(blob, node, "enable-delay-ms", data->delay_enable); + fdt_fixup_setprop_u32(blob, node, "disable-delay-ms", data->delay_disable); + fdt_fixup_setprop_u32(blob, node, "unprepare-delay-ms", data->delay_unprepare); + fdt_fixup_setprop_u32(blob, node, "reset-delay-ms", data->delay_reset); + fdt_fixup_setprop_u32(blob, node, "init-delay-ms", data->delay_init); + fdt_fixup_setprop_u32(blob, node, "width-mm", data->size_width); + fdt_fixup_setprop_u32(blob, node, "height-mm", data->size_height); + +} +static void fdt_fixup_nodka_lvds(void *blob, int node, + const struct display_fixup_data *data) +{ + if ( data->nodka_lvds != 0 ) + fdt_fixup_setprop_u32(blob, node, "nodka-lvds", data->nodka_lvds); +} + + +static int fdt_fixup_display_sub_route(void *blob, const char *name, + enum fdt_status status, + const struct display_fixup_data *data) +{ + int route, phandle, connect, connector, panel, dt, timing, route_lvds; + char path[64]; + char path_lvds[16] = "/panel"; + int ret; + sprintf(path, "/display-subsystem/route/route-%s", name); + + + route = fdt_path_offset(blob, path); + printf("route : %d \n",route); + if (route < 0) + return route; + + route_lvds = fdt_path_offset(blob, path_lvds); + if (route_lvds < 0) + { + printf("can not get route_lvds = %d\n",route_lvds); + return route_lvds; + } + /* fixup lvds gpio channel*/ + fdt_fixup_nodka_lvds(blob, route_lvds, data); + + /* fixup route status */ + ret = fdt_fixup_node_status(blob, route, status); + if (ret < 0) + return ret; + phandle = fdt_getprop_u32_default_node(blob, route, 0, "connect", -1); + if (phandle < 0) + return phandle; + connect = fdt_node_offset_by_phandle(blob, phandle); + if (connect < 0) + return connect; + connector = find_connector_node(blob, connect); + if (connector < 0) + return connector; + /* fixup connector status */ + ret = fdt_fixup_node_status(blob, connector, status); + if (ret < 0) + return ret; + if (status != FDT_STATUS_OKAY) { + return 0; + } + panel = get_panel_node(blob, connector); + if (panel < 0) + return panel; + /* fixup panel info */ + fdt_fixup_panel_node(blob, panel, name, data); + dt = fdt_subnode_offset(blob, panel, "display-timings"); + if (dt < 0) { + return dt; + } + timing = fdt_subnode_offset(blob, dt, "timing"); + if (timing < 0) { + phandle = fdt_getprop_u32_default_node(blob, dt, 0, "native-mode", -1); + if (phandle < 0) + return phandle; + + timing = fdt_node_offset_by_phandle(blob, phandle); + if (timing < 0) + return timing; + } + + /* fixup panel display timing */ + fdt_fixup_display_timing(blob, timing, data); + return 0; +} + +static void fdt_fixup_display_route(void *blob, const struct display_fixup_data *data) +{ + if (data->type == PANEL_TYPE_DSI) { + fdt_fixup_display_sub_route(blob, "dsi", FDT_STATUS_OKAY, data); + fdt_fixup_display_sub_route(blob, "edp", FDT_STATUS_DISABLED, data); + fdt_fixup_display_sub_route(blob, "lvds", FDT_STATUS_DISABLED, data); + } else if (data->type == PANEL_TYPE_EDP) { + fdt_fixup_display_sub_route(blob, "dsi", FDT_STATUS_DISABLED, data); + fdt_fixup_display_sub_route(blob, "edp", FDT_STATUS_OKAY, data); + fdt_fixup_display_sub_route(blob, "lvds", FDT_STATUS_DISABLED, data); + } else if (data->type == PANEL_TYPE_LVDS) { + fdt_fixup_display_sub_route(blob, "lvds", FDT_STATUS_OKAY, data); + fdt_fixup_display_sub_route(blob, "dsi", FDT_STATUS_DISABLED, data); + fdt_fixup_display_sub_route(blob, "edp", FDT_STATUS_DISABLED, data); + } +} + + + + + + + + + #ifdef CONFIG_USING_KERNEL_DTB_V2 static int dm_rm_kernel_dev(void) { @@ -301,6 +795,7 @@ #endif ulong fdt_addr = 0; int ret = -ENODEV; + struct display_fixup_data fix_data; printf("DM: v%d\n", IS_ENABLED(CONFIG_USING_KERNEL_DTB_V2) ? 2 : 1); @@ -372,6 +867,8 @@ phandles_fixup_cru((void *)gd->fdt_blob); phandles_fixup_gpio((void *)gd->fdt_blob, (void *)ufdt_blob); #endif + if (!get_lcdparam_info_from_custom_partition(&fix_data)) + fdt_fixup_display_route((void *)fdt_addr, &fix_data); gd->flags |= GD_FLG_KDTB_READY; gd->of_root_f = gd->of_root; -- Gitblit v1.6.2