diff --git a/drivers/video/dw_mipi_dsi.c b/drivers/video/dw_mipi_dsi.c index a7e0784596a..95b945c6fbf 100644 --- a/drivers/video/dw_mipi_dsi.c +++ b/drivers/video/dw_mipi_dsi.c @@ -86,6 +86,7 @@ #define VID_MODE_TYPE_NON_BURST_SYNC_EVENTS 0x1 #define VID_MODE_TYPE_BURST 0x2 #define VID_MODE_TYPE_MASK 0x3 +#define ENABLE_LOW_POWER_CMD BIT(15) #define DSI_VID_PKT_SIZE 0x3c #define VID_PKT_SIZE(p) ((p) & 0x3fff) @@ -294,13 +295,28 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi, bool lpm = msg->flags & MIPI_DSI_MSG_USE_LPM; u32 val = 0; + /* + * TODO dw drv improvements + * largest packet sizes during hfp or during vsa/vpb/vfp + * should be computed according to byte lane, lane number and only + * if sending lp cmds in high speed is enable (PHY_TXREQUESTCLKHS) + */ + dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(16) + | INVACT_LPCMD_TIME(4)); + if (msg->flags & MIPI_DSI_MSG_REQ_ACK) val |= ACK_RQST_EN; if (lpm) val |= CMD_MODE_ALL_LP; - dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS); dsi_write(dsi, DSI_CMD_MODE_CFG, val); + + val = dsi_read(dsi, DSI_VID_MODE_CFG); + if (lpm) + val |= ENABLE_LOW_POWER_CMD; + else + val &= ~ENABLE_LOW_POWER_CMD; + dsi_write(dsi, DSI_VID_MODE_CFG, val); } static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val) @@ -464,17 +480,22 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi, unsigned long mode_flags) { const struct mipi_dsi_phy_ops *phy_ops = dsi->phy_ops; + u32 val; dsi_write(dsi, DSI_PWR_UP, RESET); if (mode_flags & MIPI_DSI_MODE_VIDEO) { dsi_write(dsi, DSI_MODE_CFG, ENABLE_VIDEO_MODE); dw_mipi_dsi_video_mode_config(dsi); - dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS); } else { dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); } + val = PHY_TXREQUESTCLKHS; + if (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) + val |= AUTO_CLKLANE_CTRL; + dsi_write(dsi, DSI_LPCLK_CTRL, val); + if (phy_ops->post_set_mode) phy_ops->post_set_mode(dsi->device, mode_flags); @@ -545,14 +566,6 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi, dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel)); dsi_write(dsi, DSI_DPI_COLOR_CODING, color); dsi_write(dsi, DSI_DPI_CFG_POL, val); - /* - * TODO dw drv improvements - * largest packet sizes during hfp or during vsa/vpb/vfp - * should be computed according to byte lane, lane number and only - * if sending lp cmds in high speed is enable (PHY_TXREQUESTCLKHS) - */ - dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4) - | INVACT_LPCMD_TIME(4)); } static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi) diff --git a/drivers/video/rockchip/dw_mipi_dsi_rockchip.c b/drivers/video/rockchip/dw_mipi_dsi_rockchip.c index 6d32c699415..462e85f47d6 100644 --- a/drivers/video/rockchip/dw_mipi_dsi_rockchip.c +++ b/drivers/video/rockchip/dw_mipi_dsi_rockchip.c @@ -528,8 +528,6 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, struct udevice *dev = device->dev; struct dw_rockchip_dsi_priv *dsi = dev_get_priv(dev); int bpp; - unsigned long mpclk, tmp; - unsigned int target_mbps = 1000; unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps; unsigned long best_freq = 0; unsigned long fvco_min, fvco_max, fin, fout; @@ -546,30 +544,28 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, struct display_timing *timings, return bpp; } - mpclk = DIV_ROUND_UP(timings->pixelclock.typ, 1000000); - if (mpclk) { - /* take 1 / 0.9, since mbps must big than bandwidth of RGB */ - tmp = (mpclk * (bpp / lanes) * 10 / 9); - if (tmp < max_mbps) - target_mbps = tmp; - else - dev_err(dsi->dsi_host, - "DPHY clock frequency is out of range\n"); - } + fout = timings->pixelclock.typ / MSEC_PER_SEC * bpp / lanes; + if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) + fout = fout * 12 / 10; + fout *= MSEC_PER_SEC; + + if (fout > max_mbps * USEC_PER_SEC) { + dev_err(dsi->dsi_host, "DPHY clock frequency is out of range\n"); + return -EINVAL; + } /* for external phy only the mipi_dphy_config is necessary */ if (generic_phy_valid(&dsi->phy)) { - phy_mipi_dphy_get_default_config(timings->pixelclock.typ * 10 / 8, + phy_mipi_dphy_get_default_config(fout / bpp * lanes, bpp, lanes, &dsi->phy_opts); - dsi->lane_mbps = target_mbps; + dsi->lane_mbps = DIV_ROUND_UP(fout, USEC_PER_SEC); *lane_mbps = dsi->lane_mbps; return 0; } fin = clk_get_rate(dsi->ref); - fout = target_mbps * USEC_PER_SEC; /* constraint: 5Mhz <= Fref / N <= 40MHz */ min_prediv = DIV_ROUND_UP(fin, 40 * USEC_PER_SEC);