diff --git a/arch/arm/boot/dts/rv1103g-evb-mcu-display-v11.dts b/arch/arm/boot/dts/rv1103g-evb-mcu-display-v11.dts index 5368752334bb..e62f08d7c060 100644 --- a/arch/arm/boot/dts/rv1103g-evb-mcu-display-v11.dts +++ b/arch/arm/boot/dts/rv1103g-evb-mcu-display-v11.dts @@ -91,22 +91,30 @@ status = "okay"; rockchip,data-sync-bypass; pinctrl-names = "default"; + /* + * rgb3x8_pins for RGB3x8(8bit) + * rgb565_pins for RGB565(16bit) + */ pinctrl-0 = <&rgb3x8_pins>; /* * 320x480 RGB/MCU screen K350C4516T */ mcu_panel: mcu-panel { + /* + * MEDIA_BUS_FMT_RGB888_3X8 for RGB3x8(8bit) + * MEDIA_BUS_FMT_RGB565_1X16 for RGB565(16bit) + */ bus-format = ; backlight = <&backlight>; enable-gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_LOW>; enable-delay-ms = <20>; reset-gpios = <&gpio3 RK_PD0 GPIO_ACTIVE_LOW>; - reset-value = <0>; reset-delay-ms = <10>; prepare-delay-ms = <20>; unprepare-delay-ms = <20>; disable-delay-ms = <20>; + init-delay-ms = <10>; width-mm = <217>; height-mm = <136>; @@ -161,23 +169,31 @@ 00 00 01 36 01 00 01 48 - 00 00 01 3a //interface pixel format - 01 00 01 77 // bpp cfg - // 3 11 - // 16 55 - // 18 66 - // 24 77 + 00 00 01 3a + 01 00 01 66 /* + * interface pixel format: + * 66 for RGB3x8(8bit) + * 55 for RGB565(16bit) + */ - 00 00 01 b0 //interface mode control + 00 00 01 b0 01 00 01 00 - 00 00 01 b1 //frame rate 60hz - 01 00 01 a0 + 00 00 01 b1 + 01 00 01 70 /* + * frame rate control: + * 70 (45hz) for RGB3x8(8bit) + * a0 (60hz) for RGB565(16bit) + */ 01 00 01 11 00 00 01 b4 01 00 01 02 00 00 01 B6 - 01 00 01 02 + 01 00 01 02 /* + * display function control: + * 32 for RGB + * 02 for MCU + */ 01 00 01 02 00 00 01 b7 @@ -211,7 +227,11 @@ native-mode = <&kd050fwfba002_timing>; kd050fwfba002_timing: timing0 { - clock-frequency = <73174500>; + /* + * 7840125 for frame rate 45Hz + * 10453500 for frame rate 60Hz + */ + clock-frequency = <7840125>; hactive = <320>; vactive = <480>; hback-porch = <10>; @@ -280,15 +300,15 @@ * mcu-rw-pend = <5>; * mcu-hold-mode = <0>; // default set to 0 * - * Ruduce all parameters because the max vop dclk - * is 74.25M in rv1106. + * To increase the frame rate, reduce all parameters because + * the max dclk rate of mcu is 150M in rv1103/rv1106. */ mcu-timing { - mcu-pix-total = <7>; + mcu-pix-total = <5>; mcu-cs-pst = <1>; - mcu-cs-pend = <6>; + mcu-cs-pend = <4>; mcu-rw-pst = <2>; - mcu-rw-pend = <5>; + mcu-rw-pend = <3>; mcu-hold-mode = <0>; // default set to 0 }; diff --git a/arch/arm/boot/dts/rv1106-evb-ext-mcu-v10.dtsi b/arch/arm/boot/dts/rv1106-evb-ext-mcu-v10.dtsi index d862112e99dd..2ab415b35d4f 100644 --- a/arch/arm/boot/dts/rv1106-evb-ext-mcu-v10.dtsi +++ b/arch/arm/boot/dts/rv1106-evb-ext-mcu-v10.dtsi @@ -81,6 +81,10 @@ status = "okay"; rockchip,data-sync-bypass; pinctrl-names = "default"; + /* + * rgb3x8_pins for RGB3x8(8bit) + * rgb565_pins for RGB565(16bit) + */ pinctrl-0 = <&rgb565_pins>; /* @@ -88,19 +92,19 @@ */ mcu_panel: mcu-panel { /* - * MEDIA_BUS_FMT_RGB888_3X8 for serial mcu - * MEDIA_BUS_FMT_RGB565_1X16 for parallel mcu + * MEDIA_BUS_FMT_RGB888_3X8 for RGB3x8(8bit) + * MEDIA_BUS_FMT_RGB565_1X16 for RGB565(16bit) */ bus-format = ; backlight = <&backlight>; enable-gpios = <&gpio1 RK_PA3 GPIO_ACTIVE_LOW>; enable-delay-ms = <20>; reset-gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_LOW>; - reset-value = <0>; reset-delay-ms = <10>; prepare-delay-ms = <20>; unprepare-delay-ms = <20>; disable-delay-ms = <20>; + init-delay-ms = <10>; width-mm = <217>; height-mm = <136>; @@ -155,23 +159,31 @@ 00 00 01 36 01 00 01 48 - 00 00 01 3a //interface pixel format - 01 00 01 55 // bpp cfg - // 3 11 - // 16 55 - // 18 66 - // 24 77 + 00 00 01 3a + 01 00 01 55 /* + * interface pixel format: + * 66 for RGB3x8(8bit) + * 55 for RGB565(16bit) + */ - 00 00 01 b0 //interface mode control + 00 00 01 b0 01 00 01 00 - 00 00 01 b1 //frame rate 60hz - 01 00 01 a0 + 00 00 01 b1 + 01 00 01 a0 /* + * frame rate control: + * 70 (45hz) for RGB3x8(8bit) + * a0 (60hz) for RGB565(16bit) + */ 01 00 01 11 00 00 01 b4 01 00 01 02 00 00 01 B6 - 01 00 01 02 + 01 00 01 02 /* + * display function control: + * 32 for RGB + * 02 for MCU + */ 01 00 01 02 00 00 01 b7 @@ -205,7 +217,11 @@ native-mode = <&kd050fwfba002_timing>; kd050fwfba002_timing: timing0 { - clock-frequency = <73174500>; + /* + * 7840125 for frame rate 45Hz + * 10453500 for frame rate 60Hz + */ + clock-frequency = <10453500>; hactive = <320>; vactive = <480>; hback-porch = <10>; @@ -274,15 +290,15 @@ * mcu-rw-pend = <5>; * mcu-hold-mode = <0>; // default set to 0 * - * Ruduce all parameters because the max vop dclk - * is 74.25M in rv1106. + * To increase the frame rate, reduce all parameters because + * the max dclk rate of mcu is 150M in rv1103/rv1106. */ mcu-timing { - mcu-pix-total = <7>; + mcu-pix-total = <5>; mcu-cs-pst = <1>; - mcu-cs-pend = <6>; + mcu-cs-pend = <4>; mcu-rw-pst = <2>; - mcu-rw-pend = <5>; + mcu-rw-pend = <3>; mcu-hold-mode = <0>; // default set to 0 }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts index da471a636103..54066eeb9826 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts @@ -11,6 +11,46 @@ model = "Rockchip RK3399 Excavator Board (Linux Opensource)"; compatible = "rockchip,rk3399-excavator-linux", "rockchip,rk3399"; + backlight: backlight { + compatible = "pwm-backlight"; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; + pwms = <&pwm0 0 25000 0>; + enable-gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>; + }; + vcc_lcd: vcc-lcd { compatible = "regulator-fixed"; regulator-name = "vcc_lcd"; @@ -20,7 +60,7 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; regulator-boot-on; - vin-supply = <&vcc5v0_sys>; + vin-supply = <&vcc_sys>; }; panel: panel { @@ -329,17 +369,6 @@ vref-supply = <&vccadc_ref>; }; -&backlight { - status = "okay"; - enable-gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>; -}; - -&cdn_dp { - status = "okay"; - extcon = <&fusb0>; - phys = <&tcphy0_dp>; -}; - &display_subsystem { status = "okay"; }; diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c index 342a94ec7adb..67b53a0b9f1a 100644 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.c +++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c @@ -68,7 +68,8 @@ struct rockchip_rgb_funcs { }; struct rockchip_rgb_data { - u32 max_dclk_rate; + u32 rgb_max_dclk_rate; + u32 mcu_max_dclk_rate; const struct rockchip_rgb_funcs *funcs; }; @@ -129,7 +130,9 @@ struct rockchip_mcu_panel { struct rockchip_rgb { u8 id; u32 max_dclk_rate; + u32 mcu_pix_total; struct device *dev; + struct device_node *np_mcu_panel; struct drm_panel *panel; struct drm_bridge *bridge; struct drm_connector connector; @@ -137,7 +140,6 @@ struct rockchip_rgb { struct phy *phy; struct regmap *grf; bool data_sync_bypass; - bool is_mcu_panel; bool phy_enabled; const struct rockchip_rgb_funcs *funcs; struct rockchip_drm_sub_dev sub_dev; @@ -332,7 +334,7 @@ static int rockchip_rgb_encoder_loader_protect(struct drm_encoder *encoder, { struct rockchip_rgb *rgb = encoder_to_rgb(encoder); - if (rgb->is_mcu_panel) { + if (rgb->np_mcu_panel) { struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(rgb->panel); mcu_panel->prepared = true; @@ -367,12 +369,23 @@ rockchip_rgb_encoder_mode_valid(struct drm_encoder *encoder, { struct rockchip_rgb *rgb = encoder_to_rgb(encoder); struct device *dev = rgb->dev; + struct drm_display_info *info = &rgb->connector.display_info; u32 request_clock = mode->clock; u32 max_clock = rgb->max_dclk_rate; + u32 bus_format; + + if (info->num_bus_formats) + bus_format = info->bus_formats[0]; + else + bus_format = MEDIA_BUS_FMT_RGB888_1X24; if (mode->flags & DRM_MODE_FLAG_DBLCLK) request_clock *= 2; + if (rgb->np_mcu_panel) + request_clock *= rockchip_drm_get_cycles_per_pixel(bus_format) * + (rgb->mcu_pix_total + 1); + if (max_clock != 0 && request_clock > max_clock) { DRM_DEV_ERROR(dev, "mode [%dx%d] clock %d is higher than max_clock %d\n", mode->hdisplay, mode->vdisplay, request_clock, max_clock); @@ -453,16 +466,18 @@ static int rockchip_mcu_panel_parse_cmd_seq(struct device *dev, return 0; } -static int rockchip_mcu_panel_init(struct rockchip_rgb *rgb, struct device_node *np_mcu_panel) +static int rockchip_mcu_panel_init(struct rockchip_rgb *rgb) { struct device *dev = rgb->dev; - struct device_node *port, *endpoint, *np_crtc, *remote; + struct device_node *np_mcu_panel = rgb->np_mcu_panel; + struct device_node *port, *endpoint, *np_crtc, *remote, *np_mcu_timing; struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(rgb->panel); struct drm_display_mode *mode; const void *data; int len; int ret; u32 bus_flags; + u32 val; mcu_panel->enable_gpio = devm_fwnode_gpiod_get_index(dev, &np_mcu_panel->fwnode, "enable", 0, GPIOD_ASIS, @@ -553,6 +568,8 @@ static int rockchip_mcu_panel_init(struct rockchip_rgb *rgb, struct device_node if (remote) { np_crtc = of_get_next_parent(remote); mcu_panel->np_crtc = np_crtc; + + of_node_put(np_crtc); break; } } @@ -562,6 +579,31 @@ static int rockchip_mcu_panel_init(struct rockchip_rgb *rgb, struct device_node DRM_DEV_ERROR(dev, "failed to find available crtc for mcu panel\n"); return -EINVAL; } + + np_mcu_timing = of_get_child_by_name(mcu_panel->np_crtc, "mcu-timing"); + if (!np_mcu_timing) { + np_crtc = of_get_parent(mcu_panel->np_crtc); + if (np_crtc) + np_mcu_timing = of_get_child_by_name(np_crtc, "mcu-timing"); + + if (!np_mcu_timing) { + DRM_DEV_ERROR(dev, "failed to find timing config for mcu panel\n"); + of_node_put(np_crtc); + return -EINVAL; + } + + of_node_put(np_crtc); + } + + ret = of_property_read_u32(np_mcu_timing, "mcu-pix-total", &val); + if (ret || val == 0) { + DRM_DEV_ERROR(dev, "failed to parse mcu_pix_total config\n"); + of_node_put(np_mcu_timing); + return -EINVAL; + } + rgb->mcu_pix_total = val; + + of_node_put(np_mcu_timing); } return 0; @@ -750,9 +792,10 @@ static const struct drm_panel_funcs rockchip_mcu_panel_funcs = { .get_modes = rockchip_mcu_panel_get_modes, }; -static struct backlight_device *rockchip_mcu_panel_find_backlight(struct device_node *np_mcu_panel) +static struct backlight_device *rockchip_mcu_panel_find_backlight(struct rockchip_rgb *rgb) { struct backlight_device *bd = NULL; + struct device_node *np_mcu_panel = rgb->np_mcu_panel; struct device_node *np = NULL; np = of_parse_phandle(np_mcu_panel, "backlight", 0); @@ -777,45 +820,35 @@ static int rockchip_rgb_bind(struct device *dev, struct device *master, struct drm_device *drm_dev = data; struct drm_encoder *encoder = &rgb->encoder; struct drm_connector *connector; - struct fwnode_handle *fwnode_mcu_panel; int ret; - fwnode_mcu_panel = device_get_named_child_node(dev, "mcu-panel"); - if (fwnode_mcu_panel) { + if (rgb->np_mcu_panel) { struct rockchip_mcu_panel *mcu_panel; - struct device_node *np_mcu_panel = to_of_node(fwnode_mcu_panel); mcu_panel = devm_kzalloc(dev, sizeof(*mcu_panel), GFP_KERNEL); if (!mcu_panel) { - of_node_put(np_mcu_panel); return -ENOMEM; } mcu_panel->drm_dev = drm_dev; rgb->panel = &mcu_panel->base; - ret = rockchip_mcu_panel_init(rgb, np_mcu_panel); + ret = rockchip_mcu_panel_init(rgb); if (ret < 0) { DRM_DEV_ERROR(dev, "failed to init mcu panel: %d\n", ret); - of_node_put(np_mcu_panel); return ret; } - rgb->panel->backlight = rockchip_mcu_panel_find_backlight(np_mcu_panel); + rgb->panel->backlight = rockchip_mcu_panel_find_backlight(rgb); if (!rgb->panel->backlight) { DRM_DEV_ERROR(dev, "failed to find backlight device"); - of_node_put(np_mcu_panel); return -EINVAL; } - of_node_put(np_mcu_panel); - drm_panel_init(&mcu_panel->base, dev, &rockchip_mcu_panel_funcs, DRM_MODE_CONNECTOR_DPI); drm_panel_add(&mcu_panel->base); - - rgb->is_mcu_panel = true; } else { ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, &rgb->panel, &rgb->bridge); @@ -908,6 +941,7 @@ static int rockchip_rgb_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct rockchip_rgb *rgb; const struct rockchip_rgb_data *rgb_data; + struct fwnode_handle *fwnode_mcu_panel; int ret, id; rgb = devm_kzalloc(&pdev->dev, sizeof(*rgb), GFP_KERNEL); @@ -918,18 +952,24 @@ static int rockchip_rgb_probe(struct platform_device *pdev) if (id < 0) id = 0; + rgb->data_sync_bypass = of_property_read_bool(dev->of_node, "rockchip,data-sync-bypass"); + + fwnode_mcu_panel = device_get_named_child_node(dev, "mcu-panel"); + if (fwnode_mcu_panel) + rgb->np_mcu_panel = to_of_node(fwnode_mcu_panel); + rgb_data = of_device_get_match_data(dev); if (rgb_data) { - rgb->max_dclk_rate = rgb_data->max_dclk_rate; rgb->funcs = rgb_data->funcs; + if (rgb->np_mcu_panel) + rgb->max_dclk_rate = rgb_data->mcu_max_dclk_rate; + else + rgb->max_dclk_rate = rgb_data->rgb_max_dclk_rate; } rgb->id = id; rgb->dev = dev; platform_set_drvdata(pdev, rgb); - rgb->data_sync_bypass = - of_property_read_bool(dev->of_node, "rockchip,data-sync-bypass"); - if (dev->parent && dev->parent->of_node) { rgb->grf = syscon_node_to_regmap(dev->parent->of_node); if (IS_ERR(rgb->grf)) { @@ -1070,7 +1110,8 @@ static const struct rockchip_rgb_funcs rv1106_rgb_funcs = { }; static const struct rockchip_rgb_data rv1106_rgb = { - .max_dclk_rate = 74250, + .rgb_max_dclk_rate = 74250, + .mcu_max_dclk_rate = 150000, .funcs = &rv1106_rgb_funcs, }; diff --git a/drivers/phy/rockchip/phy-rockchip-csi2-dphy.c b/drivers/phy/rockchip/phy-rockchip-csi2-dphy.c index 8cdff2ca355b..f06ff7b962b6 100644 --- a/drivers/phy/rockchip/phy-rockchip-csi2-dphy.c +++ b/drivers/phy/rockchip/phy-rockchip-csi2-dphy.c @@ -244,6 +244,7 @@ static int rockchip_csi2_dphy_attach_hw(struct csi2_dphy *dphy, int csi_idx, int return -EINVAL; } dphy_hw->dphy_dev[dphy_hw->dphy_dev_num] = dphy; + dphy_hw->dphy_dev_num++; dphy->phy_hw[index] = (void *)dphy_hw; dphy->csi_info.dphy_vendor[index] = PHY_VENDOR_INNO; mutex_unlock(&dphy_hw->mutex); diff --git a/drivers/video/rockchip/mpp/mpp_common.c b/drivers/video/rockchip/mpp/mpp_common.c index acc9b07b65c7..ce6bfbc5a881 100644 --- a/drivers/video/rockchip/mpp/mpp_common.c +++ b/drivers/video/rockchip/mpp/mpp_common.c @@ -715,10 +715,6 @@ mpp_reset_control_get(struct mpp_dev *mpp, enum MPP_RESET_TYPE type, const char group->resets[type] = rst; group->queue = mpp->queue; } - /* if reset not in the same queue, it means different device - * may reset in the same time, then rw_sem_on should set true. - */ - group->rw_sem_on |= (group->queue != mpp->queue) ? true : false; dev_info(mpp->dev, "reset_group->rw_sem_on=%d\n", group->rw_sem_on); up_write(&group->rw_sem); @@ -1005,6 +1001,10 @@ static int mpp_attach_service(struct mpp_dev *mpp, struct device *dev) return -ENODEV; } else { mpp->reset_group = mpp->srv->reset_groups[reset_group_node]; + if (!mpp->reset_group->queue) + mpp->reset_group->queue = queue; + if (mpp->reset_group->queue != mpp->queue) + mpp->reset_group->rw_sem_on = true; } }