Loading drivers/gpu/drm/msm/dp/dp_panel.c +83 −67 Original line number Diff line number Diff line Loading @@ -543,6 +543,87 @@ static void _tu_valid_boundary_calc(struct tu_algo_data *tu) } } static void _dp_calc_boundary(struct tu_algo_data *tu) { s64 temp1_fp = 0, temp2_fp = 0; do { tu->err_fp = drm_fixp_from_fraction(1000, 1); temp1_fp = drm_fixp_div(tu->lclk_fp, tu->pclk_fp); temp2_fp = drm_fixp_from_fraction( tu->delay_start_link_extra_pixclk, 1); temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp); if (temp1_fp) tu->extra_buffer_margin = drm_fixp2int_ceil(temp1_fp); else tu->extra_buffer_margin = 0; temp1_fp = drm_fixp_from_fraction(tu->bpp, 8); temp1_fp = drm_fixp_mul(tu->lwidth_fp, temp1_fp); if (temp1_fp) tu->n_symbols = drm_fixp2int_ceil(temp1_fp); else tu->n_symbols = 0; for (tu->tu_size = 32; tu->tu_size <= 64; tu->tu_size++) { for (tu->i_upper_boundary_count = 1; tu->i_upper_boundary_count <= 15; tu->i_upper_boundary_count++) { for (tu->i_lower_boundary_count = 1; tu->i_lower_boundary_count <= 15; tu->i_lower_boundary_count++) { _tu_valid_boundary_calc(tu); } } } tu->delay_start_link_extra_pixclk--; } while (!tu->boundary_moderation_en && tu->boundary_mod_lower_err == 1 && tu->delay_start_link_extra_pixclk != 0); } static void _dp_calc_extra_bytes(struct tu_algo_data *tu) { u64 temp = 0; s64 temp1_fp = 0, temp2_fp = 0; temp1_fp = drm_fixp_from_fraction(tu->tu_size_desired, 1); temp2_fp = drm_fixp_mul(tu->original_ratio_fp, temp1_fp); temp1_fp = drm_fixp_from_fraction(tu->valid_boundary_link, 1); temp2_fp = temp1_fp - temp2_fp; temp1_fp = drm_fixp_from_fraction(tu->n_tus + 1, 1); temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp); temp = drm_fixp2int(temp2_fp); if (temp && temp2_fp) tu->extra_bytes = drm_fixp2int_ceil(temp2_fp); else tu->extra_bytes = 0; temp1_fp = drm_fixp_from_fraction(tu->extra_bytes, 1); temp2_fp = drm_fixp_from_fraction(8, tu->bpp); temp1_fp = drm_fixp_mul(temp1_fp, temp2_fp); if (temp1_fp) tu->extra_pclk_cycles = drm_fixp2int_ceil(temp1_fp); else tu->extra_pclk_cycles = drm_fixp2int(temp1_fp); temp1_fp = drm_fixp_div(tu->lclk_fp, tu->pclk_fp); temp2_fp = drm_fixp_from_fraction(tu->extra_pclk_cycles, 1); temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp); if (temp1_fp) tu->extra_pclk_cycles_in_link_clk = drm_fixp2int_ceil(temp1_fp); else tu->extra_pclk_cycles_in_link_clk = drm_fixp2int(temp1_fp); } static void _dp_panel_calc_tu(struct dp_tu_calc_input *in, struct dp_vc_tu_mapping_table *tu_table) { Loading Loading @@ -662,36 +743,7 @@ static void _dp_panel_calc_tu(struct dp_tu_calc_input *in, pr_info("Info: n_sym = %d, num_of_tus = %d\n", tu.valid_boundary_link, tu.n_tus); temp1_fp = drm_fixp_from_fraction(tu.tu_size_desired, 1); temp2_fp = drm_fixp_mul(tu.original_ratio_fp, temp1_fp); temp1_fp = drm_fixp_from_fraction(tu.valid_boundary_link, 1); temp2_fp = temp1_fp - temp2_fp; temp1_fp = drm_fixp_from_fraction(tu.n_tus + 1, 1); temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp); temp = drm_fixp2int(temp2_fp); if (temp && temp2_fp) tu.extra_bytes = drm_fixp2int_ceil(temp2_fp); else tu.extra_bytes = 0; temp1_fp = drm_fixp_from_fraction(tu.extra_bytes, 1); temp2_fp = drm_fixp_from_fraction(8, tu.bpp); temp1_fp = drm_fixp_mul(temp1_fp, temp2_fp); if (temp1_fp) tu.extra_pclk_cycles = drm_fixp2int_ceil(temp1_fp); else tu.extra_pclk_cycles = drm_fixp2int(temp1_fp); temp1_fp = drm_fixp_div(tu.lclk_fp, tu.pclk_fp); temp2_fp = drm_fixp_from_fraction(tu.extra_pclk_cycles, 1); temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp); if (temp1_fp) tu.extra_pclk_cycles_in_link_clk = drm_fixp2int_ceil(temp1_fp); else tu.extra_pclk_cycles_in_link_clk = drm_fixp2int(temp1_fp); _dp_calc_extra_bytes(&tu); tu.filler_size = tu.tu_size_desired - tu.valid_boundary_link; Loading Loading @@ -748,44 +800,8 @@ static void _dp_panel_calc_tu(struct dp_tu_calc_input *in, (tu.even_distribution_legacy == 0) || (DP_BRUTE_FORCE == 1))) || (tu.min_hblank_violated == 1)) { do { tu.err_fp = drm_fixp_from_fraction(1000, 1); temp1_fp = drm_fixp_div(tu.lclk_fp, tu.pclk_fp); temp2_fp = drm_fixp_from_fraction( tu.delay_start_link_extra_pixclk, 1); temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp); if (temp1_fp) tu.extra_buffer_margin = drm_fixp2int_ceil(temp1_fp); else tu.extra_buffer_margin = 0; temp1_fp = drm_fixp_from_fraction(tu.bpp, 8); temp1_fp = drm_fixp_mul(tu.lwidth_fp, temp1_fp); if (temp1_fp) tu.n_symbols = drm_fixp2int_ceil(temp1_fp); else tu.n_symbols = 0; for (tu.tu_size = 32; tu.tu_size <= 64; tu.tu_size++) { for (tu.i_upper_boundary_count = 1; tu.i_upper_boundary_count <= 15; tu.i_upper_boundary_count++) { for (tu.i_lower_boundary_count = 1; tu.i_lower_boundary_count <= 15; tu.i_lower_boundary_count++) { _tu_valid_boundary_calc(&tu); } } } tu.delay_start_link_extra_pixclk--; } while (!tu.boundary_moderation_en && tu.boundary_mod_lower_err == 1 && tu.delay_start_link_extra_pixclk != 0); _dp_calc_boundary(&tu); if (tu.boundary_moderation_en) { temp1_fp = drm_fixp_from_fraction( Loading drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c +40 −28 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include <linux/of.h> Loading Loading @@ -837,24 +837,11 @@ static int dsi_clk_update_link_clk_state(struct dsi_clk_mngr *mngr, return rc; } static int dsi_update_clk_state(struct dsi_clk_mngr *mngr, struct dsi_core_clks *c_clks, u32 c_state, struct dsi_link_clks *l_clks, u32 l_state) static int dsi_update_core_clks(struct dsi_clk_mngr *mngr, struct dsi_core_clks *c_clks) { int rc = 0; bool l_c_on = false; if (!mngr) return -EINVAL; pr_debug("c_state = %d, l_state = %d\n", c_clks ? c_state : -1, l_clks ? l_state : -1); /* * Below is the sequence to toggle DSI clocks: * 1. For ON sequence, Core clocks before link clocks * 2. For OFF sequence, Link clocks before core clocks. */ if (c_clks && (c_state == DSI_CLK_ON)) { if (mngr->core_clk_state == DSI_CLK_OFF) { rc = mngr->pre_clkon_cb(mngr->priv_data, DSI_CORE_CLK, Loading @@ -881,8 +868,33 @@ static int dsi_update_clk_state(struct dsi_clk_mngr *mngr, pr_err("post clk on cb failed, rc = %d\n", rc); } mngr->core_clk_state = DSI_CLK_ON; error: return rc; } static int dsi_update_clk_state(struct dsi_clk_mngr *mngr, struct dsi_core_clks *c_clks, u32 c_state, struct dsi_link_clks *l_clks, u32 l_state) { int rc = 0; bool l_c_on = false; if (!mngr) return -EINVAL; pr_debug("c_state = %d, l_state = %d\n", c_clks ? c_state : -1, l_clks ? l_state : -1); /* * Below is the sequence to toggle DSI clocks: * 1. For ON sequence, Core clocks before link clocks * 2. For OFF sequence, Link clocks before core clocks. */ if (c_clks && (c_state == DSI_CLK_ON)) rc = dsi_update_core_clks(mngr, c_clks); if (rc) goto error; if (l_clks) { if (l_state == DSI_CLK_ON) { rc = dsi_clk_update_link_clk_state(mngr, l_clks, Loading drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c +114 −102 Original line number Diff line number Diff line Loading @@ -1100,108 +1100,18 @@ int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl, return rc; } static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl, const struct mipi_dsi_msg *msg, struct dsi_ctrl_cmd_dma_fifo_info *cmd, struct dsi_ctrl_cmd_dma_info *cmd_mem, u32 flags) { int rc = 0, ret = 0; struct mipi_dsi_packet packet; struct dsi_ctrl_cmd_dma_fifo_info cmd; struct dsi_ctrl_cmd_dma_info cmd_mem; u32 hw_flags = 0; u32 length = 0; u8 *buffer = NULL; u32 cnt = 0, line_no = 0x1; u8 *cmdbuf; u32 line_no = 0x1; struct dsi_mode_info *timing; struct dsi_ctrl_hw_ops dsi_hw_ops = dsi_ctrl->hw.ops; /* Select the tx mode to transfer the command */ dsi_message_setup_tx_mode(dsi_ctrl, msg->tx_len, &flags); /* Validate the mode before sending the command */ rc = dsi_message_validate_tx_mode(dsi_ctrl, msg->tx_len, &flags); if (rc) { pr_err(" Cmd tx validation failed, cannot transfer cmd\n"); rc = -ENOTSUPP; goto error; } if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) { cmd_mem.offset = dsi_ctrl->cmd_buffer_iova; cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ? true : false; cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ? true : false; cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? true : false; cmd_mem.datatype = msg->type; cmd_mem.length = msg->tx_len; dsi_ctrl->cmd_len = msg->tx_len; memcpy(dsi_ctrl->vaddr, msg->tx_buf, msg->tx_len); pr_debug(" non-embedded mode , size of command =%zd\n", msg->tx_len); goto kickoff; } rc = mipi_dsi_create_packet(&packet, msg); if (rc) { pr_err("Failed to create message packet, rc=%d\n", rc); goto error; } rc = dsi_ctrl_copy_and_pad_cmd(dsi_ctrl, &packet, &buffer, &length); if (rc) { pr_err("[%s] failed to copy message, rc=%d\n", dsi_ctrl->name, rc); goto error; } if ((msg->flags & MIPI_DSI_MSG_LASTCOMMAND)) buffer[3] |= BIT(7);//set the last cmd bit in header. if (flags & DSI_CTRL_CMD_FETCH_MEMORY) { /* Embedded mode config is selected */ cmd_mem.offset = dsi_ctrl->cmd_buffer_iova; cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ? true : false; cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ? true : false; cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? true : false; cmdbuf = (u8 *)(dsi_ctrl->vaddr); msm_gem_sync(dsi_ctrl->tx_cmd_buf); for (cnt = 0; cnt < length; cnt++) cmdbuf[dsi_ctrl->cmd_len + cnt] = buffer[cnt]; dsi_ctrl->cmd_len += length; if (!(msg->flags & MIPI_DSI_MSG_LASTCOMMAND)) { goto error; } else { cmd_mem.length = dsi_ctrl->cmd_len; dsi_ctrl->cmd_len = 0; } } else if (flags & DSI_CTRL_CMD_FIFO_STORE) { cmd.command = (u32 *)buffer; cmd.size = length; cmd.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ? true : false; cmd.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ? true : false; cmd.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? true : false; } kickoff: /* check if custom dma scheduling line needed */ if ((dsi_ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE) && (flags & DSI_CTRL_CMD_CUSTOM_DMA_SCHED)) Loading Loading @@ -1229,17 +1139,17 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) { dsi_hw_ops.kickoff_command_non_embedded_mode( &dsi_ctrl->hw, &cmd_mem, cmd_mem, hw_flags); } else { dsi_hw_ops.kickoff_command( &dsi_ctrl->hw, &cmd_mem, cmd_mem, hw_flags); } } else if (flags & DSI_CTRL_CMD_FIFO_STORE) { dsi_hw_ops.kickoff_fifo_command(&dsi_ctrl->hw, &cmd, cmd, hw_flags); } } Loading @@ -1257,17 +1167,17 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) { dsi_hw_ops.kickoff_command_non_embedded_mode( &dsi_ctrl->hw, &cmd_mem, cmd_mem, hw_flags); } else { dsi_hw_ops.kickoff_command( &dsi_ctrl->hw, &cmd_mem, cmd_mem, hw_flags); } } else if (flags & DSI_CTRL_CMD_FIFO_STORE) { dsi_hw_ops.kickoff_fifo_command(&dsi_ctrl->hw, &cmd, cmd, hw_flags); } Loading Loading @@ -1314,6 +1224,108 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, dsi_ctrl->cmd_len = 0; } } } static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, const struct mipi_dsi_msg *msg, u32 flags) { int rc = 0; struct mipi_dsi_packet packet; struct dsi_ctrl_cmd_dma_fifo_info cmd; struct dsi_ctrl_cmd_dma_info cmd_mem; u32 length = 0; u8 *buffer = NULL; u32 cnt = 0; u8 *cmdbuf; /* Select the tx mode to transfer the command */ dsi_message_setup_tx_mode(dsi_ctrl, msg->tx_len, &flags); /* Validate the mode before sending the command */ rc = dsi_message_validate_tx_mode(dsi_ctrl, msg->tx_len, &flags); if (rc) { pr_err(" Cmd tx validation failed, cannot transfer cmd\n"); rc = -ENOTSUPP; goto error; } if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) { cmd_mem.offset = dsi_ctrl->cmd_buffer_iova; cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ? true : false; cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ? true : false; cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? true : false; cmd_mem.datatype = msg->type; cmd_mem.length = msg->tx_len; dsi_ctrl->cmd_len = msg->tx_len; memcpy(dsi_ctrl->vaddr, msg->tx_buf, msg->tx_len); pr_debug(" non-embedded mode , size of command =%zd\n", msg->tx_len); goto kickoff; } rc = mipi_dsi_create_packet(&packet, msg); if (rc) { pr_err("Failed to create message packet, rc=%d\n", rc); goto error; } rc = dsi_ctrl_copy_and_pad_cmd(dsi_ctrl, &packet, &buffer, &length); if (rc) { pr_err("[%s] failed to copy message, rc=%d\n", dsi_ctrl->name, rc); goto error; } if ((msg->flags & MIPI_DSI_MSG_LASTCOMMAND)) buffer[3] |= BIT(7);//set the last cmd bit in header. if (flags & DSI_CTRL_CMD_FETCH_MEMORY) { /* Embedded mode config is selected */ cmd_mem.offset = dsi_ctrl->cmd_buffer_iova; cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ? true : false; cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ? true : false; cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? true : false; cmdbuf = (u8 *)(dsi_ctrl->vaddr); msm_gem_sync(dsi_ctrl->tx_cmd_buf); for (cnt = 0; cnt < length; cnt++) cmdbuf[dsi_ctrl->cmd_len + cnt] = buffer[cnt]; dsi_ctrl->cmd_len += length; if (!(msg->flags & MIPI_DSI_MSG_LASTCOMMAND)) { goto error; } else { cmd_mem.length = dsi_ctrl->cmd_len; dsi_ctrl->cmd_len = 0; } } else if (flags & DSI_CTRL_CMD_FIFO_STORE) { cmd.command = (u32 *)buffer; cmd.size = length; cmd.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ? true : false; cmd.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ? true : false; cmd.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? true : false; } kickoff: dsi_kickoff_msg_tx(dsi_ctrl, msg, &cmd, &cmd_mem, flags); error: if (buffer) devm_kfree(&dsi_ctrl->pdev->dev, buffer); Loading Loading
drivers/gpu/drm/msm/dp/dp_panel.c +83 −67 Original line number Diff line number Diff line Loading @@ -543,6 +543,87 @@ static void _tu_valid_boundary_calc(struct tu_algo_data *tu) } } static void _dp_calc_boundary(struct tu_algo_data *tu) { s64 temp1_fp = 0, temp2_fp = 0; do { tu->err_fp = drm_fixp_from_fraction(1000, 1); temp1_fp = drm_fixp_div(tu->lclk_fp, tu->pclk_fp); temp2_fp = drm_fixp_from_fraction( tu->delay_start_link_extra_pixclk, 1); temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp); if (temp1_fp) tu->extra_buffer_margin = drm_fixp2int_ceil(temp1_fp); else tu->extra_buffer_margin = 0; temp1_fp = drm_fixp_from_fraction(tu->bpp, 8); temp1_fp = drm_fixp_mul(tu->lwidth_fp, temp1_fp); if (temp1_fp) tu->n_symbols = drm_fixp2int_ceil(temp1_fp); else tu->n_symbols = 0; for (tu->tu_size = 32; tu->tu_size <= 64; tu->tu_size++) { for (tu->i_upper_boundary_count = 1; tu->i_upper_boundary_count <= 15; tu->i_upper_boundary_count++) { for (tu->i_lower_boundary_count = 1; tu->i_lower_boundary_count <= 15; tu->i_lower_boundary_count++) { _tu_valid_boundary_calc(tu); } } } tu->delay_start_link_extra_pixclk--; } while (!tu->boundary_moderation_en && tu->boundary_mod_lower_err == 1 && tu->delay_start_link_extra_pixclk != 0); } static void _dp_calc_extra_bytes(struct tu_algo_data *tu) { u64 temp = 0; s64 temp1_fp = 0, temp2_fp = 0; temp1_fp = drm_fixp_from_fraction(tu->tu_size_desired, 1); temp2_fp = drm_fixp_mul(tu->original_ratio_fp, temp1_fp); temp1_fp = drm_fixp_from_fraction(tu->valid_boundary_link, 1); temp2_fp = temp1_fp - temp2_fp; temp1_fp = drm_fixp_from_fraction(tu->n_tus + 1, 1); temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp); temp = drm_fixp2int(temp2_fp); if (temp && temp2_fp) tu->extra_bytes = drm_fixp2int_ceil(temp2_fp); else tu->extra_bytes = 0; temp1_fp = drm_fixp_from_fraction(tu->extra_bytes, 1); temp2_fp = drm_fixp_from_fraction(8, tu->bpp); temp1_fp = drm_fixp_mul(temp1_fp, temp2_fp); if (temp1_fp) tu->extra_pclk_cycles = drm_fixp2int_ceil(temp1_fp); else tu->extra_pclk_cycles = drm_fixp2int(temp1_fp); temp1_fp = drm_fixp_div(tu->lclk_fp, tu->pclk_fp); temp2_fp = drm_fixp_from_fraction(tu->extra_pclk_cycles, 1); temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp); if (temp1_fp) tu->extra_pclk_cycles_in_link_clk = drm_fixp2int_ceil(temp1_fp); else tu->extra_pclk_cycles_in_link_clk = drm_fixp2int(temp1_fp); } static void _dp_panel_calc_tu(struct dp_tu_calc_input *in, struct dp_vc_tu_mapping_table *tu_table) { Loading Loading @@ -662,36 +743,7 @@ static void _dp_panel_calc_tu(struct dp_tu_calc_input *in, pr_info("Info: n_sym = %d, num_of_tus = %d\n", tu.valid_boundary_link, tu.n_tus); temp1_fp = drm_fixp_from_fraction(tu.tu_size_desired, 1); temp2_fp = drm_fixp_mul(tu.original_ratio_fp, temp1_fp); temp1_fp = drm_fixp_from_fraction(tu.valid_boundary_link, 1); temp2_fp = temp1_fp - temp2_fp; temp1_fp = drm_fixp_from_fraction(tu.n_tus + 1, 1); temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp); temp = drm_fixp2int(temp2_fp); if (temp && temp2_fp) tu.extra_bytes = drm_fixp2int_ceil(temp2_fp); else tu.extra_bytes = 0; temp1_fp = drm_fixp_from_fraction(tu.extra_bytes, 1); temp2_fp = drm_fixp_from_fraction(8, tu.bpp); temp1_fp = drm_fixp_mul(temp1_fp, temp2_fp); if (temp1_fp) tu.extra_pclk_cycles = drm_fixp2int_ceil(temp1_fp); else tu.extra_pclk_cycles = drm_fixp2int(temp1_fp); temp1_fp = drm_fixp_div(tu.lclk_fp, tu.pclk_fp); temp2_fp = drm_fixp_from_fraction(tu.extra_pclk_cycles, 1); temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp); if (temp1_fp) tu.extra_pclk_cycles_in_link_clk = drm_fixp2int_ceil(temp1_fp); else tu.extra_pclk_cycles_in_link_clk = drm_fixp2int(temp1_fp); _dp_calc_extra_bytes(&tu); tu.filler_size = tu.tu_size_desired - tu.valid_boundary_link; Loading Loading @@ -748,44 +800,8 @@ static void _dp_panel_calc_tu(struct dp_tu_calc_input *in, (tu.even_distribution_legacy == 0) || (DP_BRUTE_FORCE == 1))) || (tu.min_hblank_violated == 1)) { do { tu.err_fp = drm_fixp_from_fraction(1000, 1); temp1_fp = drm_fixp_div(tu.lclk_fp, tu.pclk_fp); temp2_fp = drm_fixp_from_fraction( tu.delay_start_link_extra_pixclk, 1); temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp); if (temp1_fp) tu.extra_buffer_margin = drm_fixp2int_ceil(temp1_fp); else tu.extra_buffer_margin = 0; temp1_fp = drm_fixp_from_fraction(tu.bpp, 8); temp1_fp = drm_fixp_mul(tu.lwidth_fp, temp1_fp); if (temp1_fp) tu.n_symbols = drm_fixp2int_ceil(temp1_fp); else tu.n_symbols = 0; for (tu.tu_size = 32; tu.tu_size <= 64; tu.tu_size++) { for (tu.i_upper_boundary_count = 1; tu.i_upper_boundary_count <= 15; tu.i_upper_boundary_count++) { for (tu.i_lower_boundary_count = 1; tu.i_lower_boundary_count <= 15; tu.i_lower_boundary_count++) { _tu_valid_boundary_calc(&tu); } } } tu.delay_start_link_extra_pixclk--; } while (!tu.boundary_moderation_en && tu.boundary_mod_lower_err == 1 && tu.delay_start_link_extra_pixclk != 0); _dp_calc_boundary(&tu); if (tu.boundary_moderation_en) { temp1_fp = drm_fixp_from_fraction( Loading
drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c +40 −28 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include <linux/of.h> Loading Loading @@ -837,24 +837,11 @@ static int dsi_clk_update_link_clk_state(struct dsi_clk_mngr *mngr, return rc; } static int dsi_update_clk_state(struct dsi_clk_mngr *mngr, struct dsi_core_clks *c_clks, u32 c_state, struct dsi_link_clks *l_clks, u32 l_state) static int dsi_update_core_clks(struct dsi_clk_mngr *mngr, struct dsi_core_clks *c_clks) { int rc = 0; bool l_c_on = false; if (!mngr) return -EINVAL; pr_debug("c_state = %d, l_state = %d\n", c_clks ? c_state : -1, l_clks ? l_state : -1); /* * Below is the sequence to toggle DSI clocks: * 1. For ON sequence, Core clocks before link clocks * 2. For OFF sequence, Link clocks before core clocks. */ if (c_clks && (c_state == DSI_CLK_ON)) { if (mngr->core_clk_state == DSI_CLK_OFF) { rc = mngr->pre_clkon_cb(mngr->priv_data, DSI_CORE_CLK, Loading @@ -881,8 +868,33 @@ static int dsi_update_clk_state(struct dsi_clk_mngr *mngr, pr_err("post clk on cb failed, rc = %d\n", rc); } mngr->core_clk_state = DSI_CLK_ON; error: return rc; } static int dsi_update_clk_state(struct dsi_clk_mngr *mngr, struct dsi_core_clks *c_clks, u32 c_state, struct dsi_link_clks *l_clks, u32 l_state) { int rc = 0; bool l_c_on = false; if (!mngr) return -EINVAL; pr_debug("c_state = %d, l_state = %d\n", c_clks ? c_state : -1, l_clks ? l_state : -1); /* * Below is the sequence to toggle DSI clocks: * 1. For ON sequence, Core clocks before link clocks * 2. For OFF sequence, Link clocks before core clocks. */ if (c_clks && (c_state == DSI_CLK_ON)) rc = dsi_update_core_clks(mngr, c_clks); if (rc) goto error; if (l_clks) { if (l_state == DSI_CLK_ON) { rc = dsi_clk_update_link_clk_state(mngr, l_clks, Loading
drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c +114 −102 Original line number Diff line number Diff line Loading @@ -1100,108 +1100,18 @@ int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl, return rc; } static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl, const struct mipi_dsi_msg *msg, struct dsi_ctrl_cmd_dma_fifo_info *cmd, struct dsi_ctrl_cmd_dma_info *cmd_mem, u32 flags) { int rc = 0, ret = 0; struct mipi_dsi_packet packet; struct dsi_ctrl_cmd_dma_fifo_info cmd; struct dsi_ctrl_cmd_dma_info cmd_mem; u32 hw_flags = 0; u32 length = 0; u8 *buffer = NULL; u32 cnt = 0, line_no = 0x1; u8 *cmdbuf; u32 line_no = 0x1; struct dsi_mode_info *timing; struct dsi_ctrl_hw_ops dsi_hw_ops = dsi_ctrl->hw.ops; /* Select the tx mode to transfer the command */ dsi_message_setup_tx_mode(dsi_ctrl, msg->tx_len, &flags); /* Validate the mode before sending the command */ rc = dsi_message_validate_tx_mode(dsi_ctrl, msg->tx_len, &flags); if (rc) { pr_err(" Cmd tx validation failed, cannot transfer cmd\n"); rc = -ENOTSUPP; goto error; } if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) { cmd_mem.offset = dsi_ctrl->cmd_buffer_iova; cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ? true : false; cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ? true : false; cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? true : false; cmd_mem.datatype = msg->type; cmd_mem.length = msg->tx_len; dsi_ctrl->cmd_len = msg->tx_len; memcpy(dsi_ctrl->vaddr, msg->tx_buf, msg->tx_len); pr_debug(" non-embedded mode , size of command =%zd\n", msg->tx_len); goto kickoff; } rc = mipi_dsi_create_packet(&packet, msg); if (rc) { pr_err("Failed to create message packet, rc=%d\n", rc); goto error; } rc = dsi_ctrl_copy_and_pad_cmd(dsi_ctrl, &packet, &buffer, &length); if (rc) { pr_err("[%s] failed to copy message, rc=%d\n", dsi_ctrl->name, rc); goto error; } if ((msg->flags & MIPI_DSI_MSG_LASTCOMMAND)) buffer[3] |= BIT(7);//set the last cmd bit in header. if (flags & DSI_CTRL_CMD_FETCH_MEMORY) { /* Embedded mode config is selected */ cmd_mem.offset = dsi_ctrl->cmd_buffer_iova; cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ? true : false; cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ? true : false; cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? true : false; cmdbuf = (u8 *)(dsi_ctrl->vaddr); msm_gem_sync(dsi_ctrl->tx_cmd_buf); for (cnt = 0; cnt < length; cnt++) cmdbuf[dsi_ctrl->cmd_len + cnt] = buffer[cnt]; dsi_ctrl->cmd_len += length; if (!(msg->flags & MIPI_DSI_MSG_LASTCOMMAND)) { goto error; } else { cmd_mem.length = dsi_ctrl->cmd_len; dsi_ctrl->cmd_len = 0; } } else if (flags & DSI_CTRL_CMD_FIFO_STORE) { cmd.command = (u32 *)buffer; cmd.size = length; cmd.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ? true : false; cmd.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ? true : false; cmd.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? true : false; } kickoff: /* check if custom dma scheduling line needed */ if ((dsi_ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE) && (flags & DSI_CTRL_CMD_CUSTOM_DMA_SCHED)) Loading Loading @@ -1229,17 +1139,17 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) { dsi_hw_ops.kickoff_command_non_embedded_mode( &dsi_ctrl->hw, &cmd_mem, cmd_mem, hw_flags); } else { dsi_hw_ops.kickoff_command( &dsi_ctrl->hw, &cmd_mem, cmd_mem, hw_flags); } } else if (flags & DSI_CTRL_CMD_FIFO_STORE) { dsi_hw_ops.kickoff_fifo_command(&dsi_ctrl->hw, &cmd, cmd, hw_flags); } } Loading @@ -1257,17 +1167,17 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) { dsi_hw_ops.kickoff_command_non_embedded_mode( &dsi_ctrl->hw, &cmd_mem, cmd_mem, hw_flags); } else { dsi_hw_ops.kickoff_command( &dsi_ctrl->hw, &cmd_mem, cmd_mem, hw_flags); } } else if (flags & DSI_CTRL_CMD_FIFO_STORE) { dsi_hw_ops.kickoff_fifo_command(&dsi_ctrl->hw, &cmd, cmd, hw_flags); } Loading Loading @@ -1314,6 +1224,108 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, dsi_ctrl->cmd_len = 0; } } } static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, const struct mipi_dsi_msg *msg, u32 flags) { int rc = 0; struct mipi_dsi_packet packet; struct dsi_ctrl_cmd_dma_fifo_info cmd; struct dsi_ctrl_cmd_dma_info cmd_mem; u32 length = 0; u8 *buffer = NULL; u32 cnt = 0; u8 *cmdbuf; /* Select the tx mode to transfer the command */ dsi_message_setup_tx_mode(dsi_ctrl, msg->tx_len, &flags); /* Validate the mode before sending the command */ rc = dsi_message_validate_tx_mode(dsi_ctrl, msg->tx_len, &flags); if (rc) { pr_err(" Cmd tx validation failed, cannot transfer cmd\n"); rc = -ENOTSUPP; goto error; } if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) { cmd_mem.offset = dsi_ctrl->cmd_buffer_iova; cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ? true : false; cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ? true : false; cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? true : false; cmd_mem.datatype = msg->type; cmd_mem.length = msg->tx_len; dsi_ctrl->cmd_len = msg->tx_len; memcpy(dsi_ctrl->vaddr, msg->tx_buf, msg->tx_len); pr_debug(" non-embedded mode , size of command =%zd\n", msg->tx_len); goto kickoff; } rc = mipi_dsi_create_packet(&packet, msg); if (rc) { pr_err("Failed to create message packet, rc=%d\n", rc); goto error; } rc = dsi_ctrl_copy_and_pad_cmd(dsi_ctrl, &packet, &buffer, &length); if (rc) { pr_err("[%s] failed to copy message, rc=%d\n", dsi_ctrl->name, rc); goto error; } if ((msg->flags & MIPI_DSI_MSG_LASTCOMMAND)) buffer[3] |= BIT(7);//set the last cmd bit in header. if (flags & DSI_CTRL_CMD_FETCH_MEMORY) { /* Embedded mode config is selected */ cmd_mem.offset = dsi_ctrl->cmd_buffer_iova; cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ? true : false; cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ? true : false; cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? true : false; cmdbuf = (u8 *)(dsi_ctrl->vaddr); msm_gem_sync(dsi_ctrl->tx_cmd_buf); for (cnt = 0; cnt < length; cnt++) cmdbuf[dsi_ctrl->cmd_len + cnt] = buffer[cnt]; dsi_ctrl->cmd_len += length; if (!(msg->flags & MIPI_DSI_MSG_LASTCOMMAND)) { goto error; } else { cmd_mem.length = dsi_ctrl->cmd_len; dsi_ctrl->cmd_len = 0; } } else if (flags & DSI_CTRL_CMD_FIFO_STORE) { cmd.command = (u32 *)buffer; cmd.size = length; cmd.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ? true : false; cmd.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ? true : false; cmd.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? true : false; } kickoff: dsi_kickoff_msg_tx(dsi_ctrl, msg, &cmd, &cmd_mem, flags); error: if (buffer) devm_kfree(&dsi_ctrl->pdev->dev, buffer); Loading