diff --git a/u-boot/board/rockchip/nanopi6/board.c b/u-boot/board/rockchip/nanopi6/board.c index 468d80a301e..cc4a0dd15d4 100644 --- a/u-boot/board/rockchip/nanopi6/board.c +++ b/u-boot/board/rockchip/nanopi6/board.c @@ -15,6 +15,11 @@ #include #include +#include +#include +#include +#include + #include "hwrev.h" DECLARE_GLOBAL_DATA_PTR; @@ -193,3 +198,55 @@ int rk_board_late_init(void) return 0; } #endif + +int rk_board_panel_detect(struct udevice *dev) +{ + struct udevice *i2c_bus, *nvm_dev; + struct ofnode_phandle_args args; + const struct device_node *np; + const char *panel_name; + u8 chip, addr, nlen; + u8 buf[128] = { 0 }; + u32 status = 1; + int ret; + + panel_name = dev_read_string(dev, "panel-name"); + if (!panel_name) + return 0; + + ret = dev_read_phandle_with_args(dev, "nvmems", NULL, 3, 0, &args); + if (ret) + return 0; + + chip = args.args[0]; + addr = args.args[1]; + nlen = args.args[2]; + if (!chip || !addr) + return 0; + + if (uclass_get_device_by_ofnode(UCLASS_I2C, args.node, &i2c_bus)) + return 0; + + if (i2c_get_chip(i2c_bus, chip, 1, &nvm_dev)) + return 0; + + if (nlen >= sizeof(buf)) + nlen = sizeof(buf) - 1; + + ret = dm_i2c_read(nvm_dev, addr, buf, nlen); + if (!ret) { + debug("panel: nvmem name %s\n", buf); + nlen = strchrnul(panel_name, ',') - panel_name; + if (!strncmp((char *)buf, panel_name, nlen)) + return 1; + } + + np = ofnode_to_np(dev->node); + if (!ofnode_read_u32(dev->node, "nvmem-status", &status)) { + do_fixup_by_path_u32((void *)gd->fdt_blob, np->full_name, + "nvmem-status", 0, 1); + } + + /* read fail or name mismatch */ + return -ENODEV; +} diff --git a/u-boot/drivers/core/of_access.c b/u-boot/drivers/core/of_access.c index 4fc72c7a920..da78bde28ab 100644 --- a/u-boot/drivers/core/of_access.c +++ b/u-boot/drivers/core/of_access.c @@ -744,13 +744,14 @@ struct device_node *of_parse_phandle(const struct device_node *np, int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name, - int index, struct of_phandle_args *out_args) + int cell_count, int index, + struct of_phandle_args *out_args) { if (index < 0) return -EINVAL; - return __of_parse_phandle_with_args(np, list_name, cells_name, 0, - index, out_args); + return __of_parse_phandle_with_args(np, list_name, cells_name, + cell_count, index, out_args); } int of_count_phandle_with_args(const struct device_node *np, diff --git a/u-boot/drivers/core/ofnode.c b/u-boot/drivers/core/ofnode.c index 1e1e7fce8ae..2fbf51fadd7 100644 --- a/u-boot/drivers/core/ofnode.c +++ b/u-boot/drivers/core/ofnode.c @@ -356,7 +356,9 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name, int ret; ret = of_parse_phandle_with_args(ofnode_to_np(node), - list_name, cells_name, index, &args); + list_name, cells_name, + cell_count, index, + &args); if (ret) return ret; ofnode_from_of_phandle_args(&args, out_args); diff --git a/u-boot/drivers/video/drm/rockchip_connector.c b/u-boot/drivers/video/drm/rockchip_connector.c index 2eb8319b5c5..2e2e068e07b 100644 --- a/u-boot/drivers/video/drm/rockchip_connector.c +++ b/u-boot/drivers/video/drm/rockchip_connector.c @@ -118,12 +118,24 @@ int rockchip_connector_init(struct display_state *state) return ret; } +__weak int rk_board_panel_detect(struct udevice *dev) +{ + return 0; +} static bool rockchip_connector_path_detect(struct rockchip_connector *conn, struct display_state *state) { int ret; + if (conn->panel) { + ret = rk_board_panel_detect(conn->panel->dev); + if (ret == -ENODEV) { + printf("%s disconnected\n", conn->dev->name); + return false; + } + } + if (conn->funcs->detect) { ret = conn->funcs->detect(conn, state); if (!ret) { diff --git a/u-boot/drivers/video/drm/rockchip_display.c b/u-boot/drivers/video/drm/rockchip_display.c index 6d291a08fb8..e38ec19c620 100644 --- a/u-boot/drivers/video/drm/rockchip_display.c +++ b/u-boot/drivers/video/drm/rockchip_display.c @@ -1002,6 +1002,9 @@ static int display_logo(struct display_state *state) if (crtc_state->src_rect.h >= vdisplay) { crtc_state->crtc_rect.y = 0; crtc_state->crtc_rect.h = vdisplay; + } else if (crtc_state->src_rect.w > hdisplay) { + crtc_state->crtc_rect.h = (crtc_state->src_rect.h * hdisplay) / crtc_state->src_rect.w; + crtc_state->crtc_rect.y = (vdisplay - crtc_state->crtc_rect.h) / 2; } else { crtc_state->crtc_rect.y = (vdisplay - crtc_state->src_rect.h) / 2; crtc_state->crtc_rect.h = crtc_state->src_rect.h; diff --git a/u-boot/include/dm/of_access.h b/u-boot/include/dm/of_access.h index c7717dc9a9d..8da38a0f808 100644 --- a/u-boot/include/dm/of_access.h +++ b/u-boot/include/dm/of_access.h @@ -389,6 +389,7 @@ struct device_node *of_parse_phandle(const struct device_node *np, * @np: pointer to a device tree node containing a list * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count + * @cells_count: Cell count to use if @cells_name is NULL * @index: index of a phandle to parse out * @out_args: optional pointer to output arguments structure (will be filled) * @return 0 on success (with @out_args filled out if not NULL), -ENOENT if @@ -422,7 +423,8 @@ struct device_node *of_parse_phandle(const struct device_node *np, */ int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name, - int index, struct of_phandle_args *out_args); + int cells_count, int index, + struct of_phandle_args *out_args); /** * of_count_phandle_with_args() - Count the number of phandle in a list