summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2020-03-08 00:44:49 +0100
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2020-03-08 00:44:49 +0100
commitb16d3d60b112c8cb90ebcd7ae97a5d2207d6f43c (patch)
tree9d741e4a5f1cad574a901636a8ba81f1b7fb6a41 /drivers
parent13afff494b3380314bcbee716fed98ec8a802a78 (diff)
parent860ec89b125a6d90729fec87262ebc6596428efe (diff)
Merge tag 'rel_imx_4.14.98_2.3.1_patch' into 4.14-2.3.x-imx
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/imx/clk-imx8qm.c24
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-crtc.c90
-rw-r--r--drivers/gpu/imx/dpu/dpu-framegen.c2
-rw-r--r--drivers/mxc/vpu_malone/vpu_b0.h2
-rw-r--r--drivers/mxc/vpu_malone/vpu_mu.c2
-rw-r--r--drivers/soc/imx/pm-domains.c12
6 files changed, 114 insertions, 18 deletions
diff --git a/drivers/clk/imx/clk-imx8qm.c b/drivers/clk/imx/clk-imx8qm.c
index 8df69317f656..5c480168f86d 100644
--- a/drivers/clk/imx/clk-imx8qm.c
+++ b/drivers/clk/imx/clk-imx8qm.c
@@ -884,19 +884,19 @@ static int imx8qm_clk_probe(struct platform_device *pdev)
clks[IMX8QM_HSIO_PCIE_X1_PER_CLK] = imx_clk_gate2_scu("hsio_pcie_x1_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PCIE_X1_CRR3_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B));
clks[IMX8QM_HSIO_PCIE_X2_PER_CLK] = imx_clk_gate2_scu("hsio_pcie_x2_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PCIE_X2_CRR2_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_A));
clks[IMX8QM_HSIO_SATA_PER_CLK] = imx_clk_gate2_scu("hsio_sata_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_SATA_CRR4_LPCG), 16, FUNCTION_NAME(PD_HSIO_SATA_0));
- clks[IMX8QM_HSIO_PHY_X1_PER_CLK] = imx_clk_gate2_scu("hsio_phy_x1_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X1_CRR1_LPCG), 16, FUNCTION_NAME(PD_HSIO_SATA_0));
- clks[IMX8QM_HSIO_PHY_X2_PER_CLK] = imx_clk_gate2_scu("hsio_phy_x2_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X2_CRR0_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_A));
- clks[IMX8QM_HSIO_MISC_PER_CLK] = imx_clk_gate2_scu("hsio_misc_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_MISC_LPCG), 16, FUNCTION_NAME(PD_HSIO));
- clks[IMX8QM_HSIO_PHY_X1_APB_CLK] = imx_clk_gate2_scu("hsio_phy_x1_apb_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X1_LPCG), 16, FUNCTION_NAME(PD_HSIO_SATA_0));
- clks[IMX8QM_HSIO_PHY_X2_APB_0_CLK] = imx_clk_gate2_scu("hsio_phy_x2_apb_0_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X2_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_A));
- clks[IMX8QM_HSIO_PHY_X2_APB_1_CLK] = imx_clk_gate2_scu("hsio_phy_x2_apb_1_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X2_LPCG), 20, FUNCTION_NAME(PD_HSIO_PCIE_A));
+ clks[IMX8QM_HSIO_PHY_X1_PER_CLK] = imx_clk_gate2_scu("hsio_phy_x1_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X1_CRR1_LPCG), 16, FUNCTION_NAME(PD_HSIO_SERDES_1));
+ clks[IMX8QM_HSIO_PHY_X2_PER_CLK] = imx_clk_gate2_scu("hsio_phy_x2_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X2_CRR0_LPCG), 16, FUNCTION_NAME(PD_HSIO_SERDES_0));
+ clks[IMX8QM_HSIO_MISC_PER_CLK] = imx_clk_gate2_scu("hsio_misc_per_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_MISC_LPCG), 16, FUNCTION_NAME(PD_HSIO_GPIO));
+ clks[IMX8QM_HSIO_PHY_X1_APB_CLK] = imx_clk_gate2_scu("hsio_phy_x1_apb_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X1_LPCG), 16, FUNCTION_NAME(PD_HSIO_SERDES_1));
+ clks[IMX8QM_HSIO_PHY_X2_APB_0_CLK] = imx_clk_gate2_scu("hsio_phy_x2_apb_0_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X2_LPCG), 16, FUNCTION_NAME(PD_HSIO_SERDES_0));
+ clks[IMX8QM_HSIO_PHY_X2_APB_1_CLK] = imx_clk_gate2_scu("hsio_phy_x2_apb_1_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_PHY_X2_LPCG), 20, FUNCTION_NAME(PD_HSIO_SERDES_0));
clks[IMX8QM_HSIO_SATA_CLK] = imx_clk_gate2_scu("hsio_sata_clk", "axi_hsio_clk_root", LPCG_ADDR(HSIO_SATA_LPCG), 16, FUNCTION_NAME(PD_HSIO_SATA_0));
- clks[IMX8QM_HSIO_GPIO_CLK] = imx_clk_gate2_scu("hsio_gpio_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_GPIO_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_A));
- clks[IMX8QM_HSIO_PHY_X1_PCLK] = imx_clk_gate2_scu("hsio_phy_x1_pclk", "dummy", LPCG_ADDR(HSIO_PHY_X1_LPCG), 0, FUNCTION_NAME(PD_HSIO_SATA_0));
- clks[IMX8QM_HSIO_PHY_X2_PCLK_0] = imx_clk_gate2_scu("hsio_phy_x2_pclk_0", "dummy", LPCG_ADDR(HSIO_PHY_X2_LPCG), 0, FUNCTION_NAME(PD_HSIO_PCIE_A));
- clks[IMX8QM_HSIO_PHY_X2_PCLK_1] = imx_clk_gate2_scu("hsio_phy_x2_pclk_1", "dummy", LPCG_ADDR(HSIO_PHY_X2_LPCG), 4, FUNCTION_NAME(PD_HSIO_PCIE_B));
- clks[IMX8QM_HSIO_SATA_EPCS_RX_CLK] = imx_clk_gate2_scu("hsio_sata_epcs_rx_clk", "dummy", LPCG_ADDR(HSIO_PHY_X1_LPCG), 8, FUNCTION_NAME(PD_HSIO_SATA_0));
- clks[IMX8QM_HSIO_SATA_EPCS_TX_CLK] = imx_clk_gate2_scu("hsio_sata_epcs_tx_clk", "dummy", LPCG_ADDR(HSIO_PHY_X1_LPCG), 4, FUNCTION_NAME(PD_HSIO_SATA_0));
+ clks[IMX8QM_HSIO_GPIO_CLK] = imx_clk_gate2_scu("hsio_gpio_clk", "per_hsio_clk_root", LPCG_ADDR(HSIO_GPIO_LPCG), 16, FUNCTION_NAME(PD_HSIO_GPIO));
+ clks[IMX8QM_HSIO_PHY_X1_PCLK] = imx_clk_gate2_scu("hsio_phy_x1_pclk", "dummy", LPCG_ADDR(HSIO_PHY_X1_LPCG), 0, FUNCTION_NAME(PD_HSIO_SERDES_1));
+ clks[IMX8QM_HSIO_PHY_X2_PCLK_0] = imx_clk_gate2_scu("hsio_phy_x2_pclk_0", "dummy", LPCG_ADDR(HSIO_PHY_X2_LPCG), 0, FUNCTION_NAME(PD_HSIO_SERDES_0));
+ clks[IMX8QM_HSIO_PHY_X2_PCLK_1] = imx_clk_gate2_scu("hsio_phy_x2_pclk_1", "dummy", LPCG_ADDR(HSIO_PHY_X2_LPCG), 4, FUNCTION_NAME(PD_HSIO_SERDES_0));
+ clks[IMX8QM_HSIO_SATA_EPCS_RX_CLK] = imx_clk_gate2_scu("hsio_sata_epcs_rx_clk", "dummy", LPCG_ADDR(HSIO_PHY_X1_LPCG), 8, FUNCTION_NAME(PD_HSIO_SERDES_1));
+ clks[IMX8QM_HSIO_SATA_EPCS_TX_CLK] = imx_clk_gate2_scu("hsio_sata_epcs_tx_clk", "dummy", LPCG_ADDR(HSIO_PHY_X1_LPCG), 4, FUNCTION_NAME(PD_HSIO_SERDES_1));
/* CM40 */
clks[IMX8QM_CM40_I2C_DIV] = imx_clk_divider_scu("cm40_i2c_div", SC_R_M4_0_I2C, SC_PM_CLK_PER);
diff --git a/drivers/gpu/drm/imx/dpu/dpu-crtc.c b/drivers/gpu/drm/imx/dpu/dpu-crtc.c
index 4ace85979756..890e0210c9a4 100644
--- a/drivers/gpu/drm/imx/dpu/dpu-crtc.c
+++ b/drivers/gpu/drm/imx/dpu/dpu-crtc.c
@@ -293,6 +293,12 @@ static void dpu_crtc_atomic_disable(struct drm_crtc *crtc,
to_imx_crtc_state(old_crtc_state);
struct dpu_crtc_state *dcstate = to_dpu_crtc_state(imx_crtc_state);
struct drm_display_mode *adjusted_mode = &old_crtc_state->adjusted_mode;
+ struct dpu_plane *dplane = to_dpu_plane(crtc->primary);
+ struct dpu_plane_res *res = &dplane->grp->res;
+ struct dpu_plane_state *dpstate;
+ struct dpu_fetchunit *fu;
+ unsigned long flags;
+ int i;
if (dcstate->crc.source != DPU_CRC_SRC_NONE)
dpu_crtc_disable_crc_source(crtc, dcstate->use_pc);
@@ -303,10 +309,60 @@ static void dpu_crtc_atomic_disable(struct drm_crtc *crtc,
framegen_disable_pixel_link(dpu_crtc->m_fg);
framegen_disable_pixel_link(dpu_crtc->s_fg);
+ /* don't relinquish CPU until DPRC repeat_en is disabled */
+ local_irq_save(flags);
+ preempt_disable();
+ /*
+ * Sync to FrameGen frame counter moving so that
+ * FrameGen can be disabled in the next frame.
+ */
+ framegen_wait_for_frame_counter_moving(dpu_crtc->m_fg);
+
/* First turn off the master stream, second the slave stream. */
framegen_disable(dpu_crtc->m_fg);
framegen_disable(dpu_crtc->s_fg);
+ /*
+ * There is one frame leftover after FrameGen disablement.
+ * Sync to FrameGen frame counter moving so that
+ * DPRC repeat_en can be disabled in the next frame.
+ */
+ framegen_wait_for_frame_counter_moving(dpu_crtc->m_fg);
+
+ for (i = 0; i < dpu_crtc->hw_plane_num; i++) {
+ dpu_block_id_t source;
+ bool aux_source_flag;
+ bool use_prefetch;
+
+ dpstate = dcstate->dpu_plane_states[i];
+ if (!dpstate)
+ continue;
+
+ aux_source_flag = false;
+again:
+ source = aux_source_flag ? dpstate->aux_source :
+ dpstate->source;
+ use_prefetch = aux_source_flag ?
+ dpstate->use_aux_prefetch :
+ dpstate->use_prefetch;
+ fu = source_to_fu(res, source);
+ if (!fu) {
+ local_irq_restore(flags);
+ preempt_enable();
+ return;
+ }
+
+ if (fu->dprc && use_prefetch)
+ dprc_disable_repeat_en(fu->dprc);
+
+ if (dpstate->need_aux_source && !aux_source_flag) {
+ aux_source_flag = true;
+ goto again;
+ }
+ }
+ local_irq_restore(flags);
+ preempt_enable();
+
framegen_wait_done(dpu_crtc->m_fg, adjusted_mode);
framegen_wait_done(dpu_crtc->s_fg, adjusted_mode);
@@ -314,7 +370,41 @@ static void dpu_crtc_atomic_disable(struct drm_crtc *crtc,
dpu_crtc->aux_fg : dpu_crtc->fg);
} else {
framegen_disable_pixel_link(dpu_crtc->fg);
+
+ /* don't relinquish CPU until DPRC repeat_en is disabled */
+ local_irq_save(flags);
+ preempt_disable();
+ /*
+ * Sync to FrameGen frame counter moving so that
+ * FrameGen can be disabled in the next frame.
+ */
+ framegen_wait_for_frame_counter_moving(dpu_crtc->fg);
framegen_disable(dpu_crtc->fg);
+ /*
+ * There is one frame leftover after FrameGen disablement.
+ * Sync to FrameGen frame counter moving so that
+ * DPRC repeat_en can be disabled in the next frame.
+ */
+ framegen_wait_for_frame_counter_moving(dpu_crtc->fg);
+
+ for (i = 0; i < dpu_crtc->hw_plane_num; i++) {
+ dpstate = dcstate->dpu_plane_states[i];
+ if (!dpstate)
+ continue;
+
+ fu = source_to_fu(res, dpstate->source);
+ if (!fu) {
+ local_irq_restore(flags);
+ preempt_enable();
+ return;
+ }
+
+ if (fu->dprc && dpstate->use_prefetch)
+ dprc_disable_repeat_en(fu->dprc);
+ }
+ local_irq_restore(flags);
+ preempt_enable();
+
framegen_wait_done(dpu_crtc->fg, adjusted_mode);
framegen_disable_clock(dpu_crtc->fg);
}
diff --git a/drivers/gpu/imx/dpu/dpu-framegen.c b/drivers/gpu/imx/dpu/dpu-framegen.c
index fc445abb7932..9b91cf4e95dd 100644
--- a/drivers/gpu/imx/dpu/dpu-framegen.c
+++ b/drivers/gpu/imx/dpu/dpu-framegen.c
@@ -543,7 +543,7 @@ EXPORT_SYMBOL_GPL(framegen_read_timestamp);
void framegen_wait_for_frame_counter_moving(struct dpu_framegen *fg)
{
u32 frame_index, line_index, last_frame_index;
- unsigned long timeout = jiffies + msecs_to_jiffies(50);
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
framegen_read_timestamp(fg, &frame_index, &line_index);
do {
diff --git a/drivers/mxc/vpu_malone/vpu_b0.h b/drivers/mxc/vpu_malone/vpu_b0.h
index 8feaf498cf6a..e1e0949e5237 100644
--- a/drivers/mxc/vpu_malone/vpu_b0.h
+++ b/drivers/mxc/vpu_malone/vpu_b0.h
@@ -508,6 +508,8 @@ struct vpu_ctx {
#define V4L2_NXP_FRAME_VERTICAL_ALIGN 512
#define V4L2_NXP_FRAME_HORIZONTAL_ALIGN 512
+#define VPU_IMX_DECODER_FUSE_OFFSET 14
+
pSTREAM_BUFFER_DESCRIPTOR_TYPE get_str_buffer_desc(struct vpu_ctx *ctx);
u_int32 got_free_space(u_int32 wptr, u_int32 rptr, u_int32 start, u_int32 end);
int copy_buffer_to_stream(struct vpu_ctx *ctx, void *buffer, uint32_t length);
diff --git a/drivers/mxc/vpu_malone/vpu_mu.c b/drivers/mxc/vpu_malone/vpu_mu.c
index 06dabcf68794..80ea02d6d0d1 100644
--- a/drivers/mxc/vpu_malone/vpu_mu.c
+++ b/drivers/mxc/vpu_malone/vpu_mu.c
@@ -156,7 +156,7 @@ int vpu_sc_check_fuse(struct vpu_dev *dev,
return ret;
}
- val = (fuse >> 2) & 0x3UL;
+ val = (fuse >> VPU_IMX_DECODER_FUSE_OFFSET) & 0x3UL;
if (val == 0x1UL) {
for (i = 0; i < table_size; i++)
if (pformat_table[i].fourcc == VPU_PIX_FMT_HEVC)
diff --git a/drivers/soc/imx/pm-domains.c b/drivers/soc/imx/pm-domains.c
index f75854a42054..c762accaace9 100644
--- a/drivers/soc/imx/pm-domains.c
+++ b/drivers/soc/imx/pm-domains.c
@@ -126,9 +126,10 @@ static int imx8_pd_power(struct generic_pm_domain *domain, bool power_on)
*/
while (!list_empty(&cur_domain->slave_links)) {
struct gpd_link *link;
-
pd = container_of(cur_domain, struct imx8_pm_domain, pd);
- if ((cur_domain == domain) || (!cur_domain->device_count)) {
+ if ((cur_domain == domain) ||
+ ((!cur_domain->device_count) &&
+ (atomic_read(&cur_domain->sd_count) <= 1))) {
sci_err = sc_pm_set_resource_power_mode(pm_ipc_handle,
pd->rsrc_id,
(pd_state) ? SC_PM_PW_MODE_OFF : SC_PM_PW_MODE_LP);
@@ -137,7 +138,8 @@ static int imx8_pd_power(struct generic_pm_domain *domain, bool power_on)
pd->rsrc_id, sci_err);
return -EINVAL;
}
- }
+ } else
+ break;
list_for_each_entry(link, &cur_domain->slave_links, slave_node)
master = link->master;
@@ -147,7 +149,9 @@ static int imx8_pd_power(struct generic_pm_domain *domain, bool power_on)
/* Fix the state for the top parent or a node that has no slave domains */
pd = container_of(cur_domain, struct imx8_pm_domain, pd);
if ((cur_domain == domain) ||
- ((pd->rsrc_id != SC_R_NONE) && (!cur_domain->device_count))) {
+ ((pd->rsrc_id != SC_R_NONE) &&
+ (!cur_domain->device_count) &&
+ (atomic_read(&cur_domain->sd_count) <= 1))) {
sci_err = sc_pm_set_resource_power_mode(pm_ipc_handle,
pd->rsrc_id,
(pd_state) ? SC_PM_PW_MODE_OFF : SC_PM_PW_MODE_LP);