Loading drivers/gpu/drm/msm/dp/dp_catalog.c +59 −31 Original line number Diff line number Diff line Loading @@ -45,6 +45,11 @@ #define DP_INTR_MASK2 (DP_INTERRUPT_STATUS2 << 2) #define DP_INTERRUPT_STATUS5 \ (DP_INTR_MST_DP0_VCPF_SENT | DP_INTR_MST_DP0_VCPF_SENT) #define DP_INTR_MASK5 (DP_INTERRUPT_STATUS5 << 2) #define dp_catalog_fill_io(x) { \ catalog->io.x = parser->get_io(parser, #x); \ } Loading Loading @@ -726,11 +731,13 @@ static void dp_catalog_ctrl_config_ctrl(struct dp_catalog_ctrl *ctrl) catalog = dp_catalog_get_priv(ctrl); io_data = catalog->io.dp_link; cfg = dp_read(catalog, io_data, DP_CONFIGURATION_CTRL); cfg = dp_read(catalog, io_data, DP_MAINLINK_CTRL); cfg |= 0x02000000; dp_write(catalog, io_data, DP_CONFIGURATION_CTRL, cfg); dp_write(catalog, io_data, DP_MAINLINK_CTRL, cfg); pr_debug("DP_CONFIGURATION_CTRL=0x%x\n", cfg); pr_debug("DP_MAINLINK_CTRL=0x%x\n", cfg); dp_write(catalog, io_data, DP_MAINLINK_LEVELS, 0xa08); } static void dp_catalog_panel_config_ctrl(struct dp_catalog_panel *panel, Loading Loading @@ -780,7 +787,7 @@ static void dp_catalog_ctrl_lane_mapping(struct dp_catalog_ctrl *ctrl) static void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog_ctrl *ctrl, bool enable) { u32 mainlink_ctrl; u32 mainlink_ctrl, reg; struct dp_catalog_private *catalog; struct dp_io_data *io_data; Loading @@ -793,13 +800,18 @@ static void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog_ctrl *ctrl, io_data = catalog->io.dp_link; if (enable) { dp_write(catalog, io_data, DP_MAINLINK_CTRL, 0x02000000); reg = dp_read(catalog, io_data, DP_MAINLINK_CTRL); mainlink_ctrl = reg & ~(0x03); dp_write(catalog, io_data, DP_MAINLINK_CTRL, mainlink_ctrl); wmb(); /* make sure mainlink is turned off before reset */ dp_write(catalog, io_data, DP_MAINLINK_CTRL, 0x02000002); mainlink_ctrl = reg | 0x02; dp_write(catalog, io_data, DP_MAINLINK_CTRL, mainlink_ctrl); wmb(); /* make sure mainlink entered reset */ dp_write(catalog, io_data, DP_MAINLINK_CTRL, 0x02000000); mainlink_ctrl = reg & ~(0x03); dp_write(catalog, io_data, DP_MAINLINK_CTRL, mainlink_ctrl); wmb(); /* make sure mainlink reset done */ dp_write(catalog, io_data, DP_MAINLINK_CTRL, 0x02000001); mainlink_ctrl = reg | 0x01; dp_write(catalog, io_data, DP_MAINLINK_CTRL, mainlink_ctrl); wmb(); /* make sure mainlink turned on */ } else { mainlink_ctrl = dp_read(catalog, io_data, DP_MAINLINK_CTRL); Loading Loading @@ -1115,9 +1127,11 @@ static void dp_catalog_ctrl_enable_irq(struct dp_catalog_ctrl *ctrl, if (enable) { dp_write(catalog, io_data, DP_INTR_STATUS, DP_INTR_MASK1); dp_write(catalog, io_data, DP_INTR_STATUS2, DP_INTR_MASK2); dp_write(catalog, io_data, DP_INTR_STATUS5, DP_INTR_MASK5); } else { dp_write(catalog, io_data, DP_INTR_STATUS, 0x00); dp_write(catalog, io_data, DP_INTR_STATUS2, 0x00); dp_write(catalog, io_data, DP_INTR_STATUS5, 0x00); } } Loading Loading @@ -1170,6 +1184,13 @@ static void dp_catalog_ctrl_get_interrupt(struct dp_catalog_ctrl *ctrl) ack <<= 1; ack |= DP_INTR_MASK2; dp_write(catalog, io_data, DP_INTR_STATUS2, ack); ctrl->isr5 = dp_read(catalog, io_data, DP_INTR_STATUS5); ctrl->isr5 &= ~DP_INTR_MASK5; ack = ctrl->isr5 & DP_INTERRUPT_STATUS5; ack <<= 1; ack |= DP_INTR_MASK5; dp_write(catalog, io_data, DP_INTR_STATUS5, ack); } static void dp_catalog_ctrl_phy_reset(struct dp_catalog_ctrl *ctrl) Loading Loading @@ -1788,7 +1809,7 @@ static void dp_catalog_config_spd_header(struct dp_catalog_panel *panel) { struct dp_catalog_private *catalog; struct dp_io_data *io_data; u32 value, new_value; u32 value, new_value, offset = 0; u8 parity_byte; if (!panel || panel->stream_id >= DP_STREAM_MAX) Loading @@ -1798,10 +1819,10 @@ static void dp_catalog_config_spd_header(struct dp_catalog_panel *panel) io_data = catalog->io.dp_link; if (panel->stream_id == DP_STREAM_1) io_data = io_data + (MMSS_DP1_GENERIC0_0 - MMSS_DP_GENERIC0_0); offset = MMSS_DP1_GENERIC0_0 - MMSS_DP_GENERIC0_0; /* Config header and parity byte 1 */ value = dp_read(catalog, io_data, MMSS_DP_GENERIC1_0); value = dp_read(catalog, io_data, MMSS_DP_GENERIC1_0 + offset); new_value = 0x83; parity_byte = dp_header_get_parity(new_value); Loading @@ -1809,10 +1830,10 @@ static void dp_catalog_config_spd_header(struct dp_catalog_panel *panel) | (parity_byte << PARITY_BYTE_1_BIT)); pr_debug("Header Byte 1: value = 0x%x, parity_byte = 0x%x\n", value, parity_byte); dp_write(catalog, io_data, MMSS_DP_GENERIC1_0, value); dp_write(catalog, io_data, MMSS_DP_GENERIC1_0 + offset, value); /* Config header and parity byte 2 */ value = dp_read(catalog, io_data, MMSS_DP_GENERIC1_1); value = dp_read(catalog, io_data, MMSS_DP_GENERIC1_1 + offset); new_value = 0x1b; parity_byte = dp_header_get_parity(new_value); Loading @@ -1820,10 +1841,10 @@ static void dp_catalog_config_spd_header(struct dp_catalog_panel *panel) | (parity_byte << PARITY_BYTE_2_BIT)); pr_debug("Header Byte 2: value = 0x%x, parity_byte = 0x%x\n", value, parity_byte); dp_write(catalog, io_data, MMSS_DP_GENERIC1_1, value); dp_write(catalog, io_data, MMSS_DP_GENERIC1_1 + offset, value); /* Config header and parity byte 3 */ value = dp_read(catalog, io_data, MMSS_DP_GENERIC1_1); value = dp_read(catalog, io_data, MMSS_DP_GENERIC1_1 + offset); new_value = (0x0 | (0x12 << 2)); parity_byte = dp_header_get_parity(new_value); Loading @@ -1831,7 +1852,7 @@ static void dp_catalog_config_spd_header(struct dp_catalog_panel *panel) | (parity_byte << PARITY_BYTE_3_BIT)); pr_debug("Header Byte 3: value = 0x%x, parity_byte = 0x%x\n", new_value, parity_byte); dp_write(catalog, io_data, MMSS_DP_GENERIC1_1, value); dp_write(catalog, io_data, MMSS_DP_GENERIC1_1 + offset, value); } static void dp_catalog_panel_config_spd(struct dp_catalog_panel *panel) Loading @@ -1840,6 +1861,7 @@ static void dp_catalog_panel_config_spd(struct dp_catalog_panel *panel) struct dp_io_data *io_data; u32 spd_cfg = 0, spd_cfg2 = 0; u8 *vendor = NULL, *product = NULL; u32 offset = 0; u32 sdp_cfg_off = 0; u32 sdp_cfg2_off = 0; u32 sdp_cfg3_off = 0; Loading Loading @@ -1871,39 +1893,45 @@ static void dp_catalog_panel_config_spd(struct dp_catalog_panel *panel) io_data = catalog->io.dp_link; if (panel->stream_id == DP_STREAM_1) io_data = io_data + (MMSS_DP1_GENERIC0_0 - MMSS_DP_GENERIC0_0); offset = MMSS_DP1_GENERIC0_0 - MMSS_DP_GENERIC0_0; dp_catalog_config_spd_header(panel); vendor = panel->spd_vendor_name; product = panel->spd_product_description; dp_write(catalog, io_data, MMSS_DP_GENERIC1_2, ((vendor[0] & 0x7f) | dp_write(catalog, io_data, MMSS_DP_GENERIC1_2 + offset, ((vendor[0] & 0x7f) | ((vendor[1] & 0x7f) << 8) | ((vendor[2] & 0x7f) << 16) | ((vendor[3] & 0x7f) << 24))); dp_write(catalog, io_data, MMSS_DP_GENERIC1_3, ((vendor[4] & 0x7f) | dp_write(catalog, io_data, MMSS_DP_GENERIC1_3 + offset, ((vendor[4] & 0x7f) | ((vendor[5] & 0x7f) << 8) | ((vendor[6] & 0x7f) << 16) | ((vendor[7] & 0x7f) << 24))); dp_write(catalog, io_data, MMSS_DP_GENERIC1_4, ((product[0] & 0x7f) | dp_write(catalog, io_data, MMSS_DP_GENERIC1_4 + offset, ((product[0] & 0x7f) | ((product[1] & 0x7f) << 8) | ((product[2] & 0x7f) << 16) | ((product[3] & 0x7f) << 24))); dp_write(catalog, io_data, MMSS_DP_GENERIC1_5, ((product[4] & 0x7f) | dp_write(catalog, io_data, MMSS_DP_GENERIC1_5 + offset, ((product[4] & 0x7f) | ((product[5] & 0x7f) << 8) | ((product[6] & 0x7f) << 16) | ((product[7] & 0x7f) << 24))); dp_write(catalog, io_data, MMSS_DP_GENERIC1_6, ((product[8] & 0x7f) | dp_write(catalog, io_data, MMSS_DP_GENERIC1_6 + offset, ((product[8] & 0x7f) | ((product[9] & 0x7f) << 8) | ((product[10] & 0x7f) << 16) | ((product[11] & 0x7f) << 24))); dp_write(catalog, io_data, MMSS_DP_GENERIC1_7, ((product[12] & 0x7f) | dp_write(catalog, io_data, MMSS_DP_GENERIC1_7 + offset, ((product[12] & 0x7f) | ((product[13] & 0x7f) << 8) | ((product[14] & 0x7f) << 16) | ((product[15] & 0x7f) << 24))); dp_write(catalog, io_data, MMSS_DP_GENERIC1_8, device_type); dp_write(catalog, io_data, MMSS_DP_GENERIC1_9, 0x00); dp_write(catalog, io_data, MMSS_DP_GENERIC1_8 + offset, device_type); dp_write(catalog, io_data, MMSS_DP_GENERIC1_9 + offset, 0x00); if (panel->stream_id == DP_STREAM_1) { sdp_cfg_off = MMSS_DP1_SDP_CFG - MMSS_DP_SDP_CFG; Loading drivers/gpu/drm/msm/dp/dp_catalog.h +4 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,9 @@ #define DP_INTR_FRAME_END BIT(6) #define DP_INTR_CRC_UPDATED BIT(9) #define DP_INTR_MST_DP0_VCPF_SENT BIT(0) #define DP_INTR_MST_DP1_VCPF_SENT BIT(3) #define DP_MAX_TIME_SLOTS 64 /* stream id */ Loading Loading @@ -93,6 +96,7 @@ struct dp_catalog_aux { struct dp_catalog_ctrl { u32 isr; u32 isr5; void (*state_ctrl)(struct dp_catalog_ctrl *ctrl, u32 state); void (*config_ctrl)(struct dp_catalog_ctrl *ctrl); Loading drivers/gpu/drm/msm/dp/dp_ctrl.c +97 −16 Original line number Diff line number Diff line Loading @@ -20,9 +20,14 @@ #include "dp_ctrl.h" #define DP_MST_DEBUG(fmt, ...) pr_debug(fmt, ##__VA_ARGS__) #define DP_CTRL_INTR_READY_FOR_VIDEO BIT(0) #define DP_CTRL_INTR_IDLE_PATTERN_SENT BIT(3) #define DP_CTRL_INTR_MST_DP0_VCPF_SENT BIT(0) #define DP_CTRL_INTR_MST_DP1_VCPF_SENT BIT(3) /* dp state ctrl */ #define ST_TRAIN_PATTERN_1 BIT(0) #define ST_TRAIN_PATTERN_2 BIT(1) Loading @@ -33,6 +38,10 @@ #define ST_CUSTOM_80_BIT_PATTERN BIT(6) #define ST_SEND_VIDEO BIT(7) #define ST_PUSH_IDLE BIT(8) #define MST_DP0_PUSH_VCPF BIT(12) #define MST_DP0_FORCE_VCPF BIT(13) #define MST_DP1_PUSH_VCPF BIT(14) #define MST_DP1_FORCE_VCPF BIT(15) #define MR_LINK_TRAINING1 0x8 #define MR_LINK_SYMBOL_ERM 0x80 Loading @@ -56,6 +65,7 @@ struct dp_ctrl_private { bool orientation; bool power_on; bool mst_mode; atomic_t aborted; Loading Loading @@ -101,10 +111,11 @@ static void dp_ctrl_state_ctrl(struct dp_ctrl_private *ctrl, u32 state) ctrl->catalog->state_ctrl(ctrl->catalog, state); } static void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl) static void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl, enum dp_stream_id strm) { int const idle_pattern_completion_timeout_ms = 3 * HZ / 100; struct dp_ctrl_private *ctrl; u32 state; if (!dp_ctrl) { pr_err("Invalid input data\n"); Loading @@ -118,6 +129,19 @@ static void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl) return; } if (!ctrl->mst_mode) { state = ST_PUSH_IDLE; goto trigger_idle; } if (strm >= DP_STREAM_MAX) { pr_err("mst push idle, invalid stream:%d\n", strm); return; } state = (strm == DP_STREAM_0) ? MST_DP0_PUSH_VCPF : MST_DP1_PUSH_VCPF; trigger_idle: reinit_completion(&ctrl->idle_comp); dp_ctrl_state_ctrl(ctrl, ST_PUSH_IDLE); Loading @@ -141,6 +165,7 @@ static void dp_ctrl_configure_source_link_params(struct dp_ctrl_private *ctrl, { if (enable) { ctrl->catalog->lane_mapping(ctrl->catalog); ctrl->catalog->mst_config(ctrl->catalog, ctrl->mst_mode); ctrl->catalog->config_ctrl(ctrl->catalog); ctrl->catalog->mainlink_ctrl(ctrl->catalog, true); } else { Loading Loading @@ -658,7 +683,7 @@ static int dp_ctrl_link_maintenance(struct dp_ctrl *dp_ctrl) ctrl->aux->state &= ~DP_STATE_LINK_MAINTENANCE_FAILED; ctrl->aux->state |= DP_STATE_LINK_MAINTENANCE_STARTED; ctrl->dp_ctrl.push_idle(&ctrl->dp_ctrl); ctrl->dp_ctrl.push_idle(&ctrl->dp_ctrl, DP_STREAM_0); ctrl->dp_ctrl.reset(&ctrl->dp_ctrl); do { Loading Loading @@ -727,7 +752,7 @@ static void dp_ctrl_process_phy_test_request(struct dp_ctrl *dp_ctrl) pr_debug("start\n"); ctrl->dp_ctrl.push_idle(&ctrl->dp_ctrl); ctrl->dp_ctrl.push_idle(&ctrl->dp_ctrl, DP_STREAM_0); /* * The global reset will need DP link ralated clocks to be * running. Add the global reset just before disabling the Loading @@ -736,7 +761,7 @@ static void dp_ctrl_process_phy_test_request(struct dp_ctrl *dp_ctrl) ctrl->dp_ctrl.reset(&ctrl->dp_ctrl); ctrl->dp_ctrl.off(&ctrl->dp_ctrl); ret = ctrl->dp_ctrl.on(&ctrl->dp_ctrl); ret = ctrl->dp_ctrl.on(&ctrl->dp_ctrl, ctrl->mst_mode); if (ret) pr_err("failed to enable DP controller\n"); Loading Loading @@ -809,6 +834,56 @@ static void dp_ctrl_reset(struct dp_ctrl *dp_ctrl) ctrl->catalog->reset(ctrl->catalog); } static int dp_ctrl_mst_stream_setup(struct dp_ctrl_private *ctrl, struct dp_panel *panel) { u32 x_int, y_frac_enum, lanes, bw_code; bool act_complete; if (!ctrl->mst_mode) { ctrl->catalog->state_ctrl(ctrl->catalog, ST_SEND_VIDEO); return 0; } DP_MST_DEBUG("mst stream channel allocation\n"); ctrl->catalog->channel_alloc(ctrl->catalog, panel->stream_id, panel->channel_start_slot, panel->channel_total_slots); lanes = ctrl->link->link_params.lane_count; bw_code = ctrl->link->link_params.bw_code; x_int = (u32)(lanes * panel->channel_total_slots); y_frac_enum = (u32)(256 * ((lanes * lanes * panel->channel_total_slots) - x_int)); ctrl->catalog->update_rg(ctrl->catalog, panel->stream_id, x_int, y_frac_enum); DP_MST_DEBUG("mst stream:%d, start_slot:%d, tot_slots:%d\n", panel->stream_id, panel->channel_start_slot, panel->channel_total_slots); DP_MST_DEBUG("mst lane_cnt:%d, bw:%d, x_int:%d, y_frac:%d\n", lanes, bw_code, x_int, y_frac_enum); ctrl->catalog->state_ctrl(ctrl->catalog, ST_SEND_VIDEO); ctrl->catalog->trigger_act(ctrl->catalog); msleep(20); /* needs 1 frame time */ ctrl->catalog->read_act_complete_sts(ctrl->catalog, &act_complete); if (!act_complete) pr_err("mst act trigger complete failed\n"); else DP_MST_DEBUG("mst ACT trigger complete SUCCESS\n"); return 0; } static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) { int rc = 0; Loading @@ -826,16 +901,16 @@ static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) if (rc) { pr_err("failure on stream clock enable\n"); goto end; } else { ctrl->catalog->state_ctrl(ctrl->catalog, ST_SEND_VIDEO); } rc = dp_ctrl_mst_stream_setup(ctrl, panel); if (rc) goto end; dp_ctrl_wait4video_ready(ctrl); link_ready = ctrl->catalog->mainlink_ready(ctrl->catalog); pr_debug("mainlink %s\n", link_ready ? "READY" : "NOT READY"); panel->hw_cfg(panel); } end: return rc; } Loading @@ -852,7 +927,7 @@ static void dp_ctrl_stream_off(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) dp_ctrl_disable_stream_clocks(ctrl, panel); } static int dp_ctrl_on(struct dp_ctrl *dp_ctrl) static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode) { int rc = 0; struct dp_ctrl_private *ctrl; Loading @@ -867,6 +942,8 @@ static int dp_ctrl_on(struct dp_ctrl *dp_ctrl) ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); atomic_set(&ctrl->aborted, 0); ctrl->mst_mode = mst_mode; rate = ctrl->panel->link_info.rate; ctrl->catalog->hpd_config(ctrl->catalog, true); Loading Loading @@ -915,8 +992,6 @@ static int dp_ctrl_on(struct dp_ctrl *dp_ctrl) if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) dp_ctrl_send_phy_test_pattern(ctrl); dp_ctrl_stream_on(dp_ctrl, ctrl->panel); ctrl->power_on = true; pr_debug("End-\n"); Loading @@ -934,8 +1009,6 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl) ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); dp_ctrl_stream_off(dp_ctrl, ctrl->panel); dp_ctrl_configure_source_link_params(ctrl, false); ctrl->catalog->reset(ctrl->catalog); Loading @@ -944,6 +1017,7 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl) dp_ctrl_disable_mainlink_clocks(ctrl); ctrl->mst_mode = false; ctrl->power_on = false; pr_debug("DP off done\n"); } Loading @@ -964,6 +1038,12 @@ static void dp_ctrl_isr(struct dp_ctrl *dp_ctrl) if (ctrl->catalog->isr & DP_CTRL_INTR_IDLE_PATTERN_SENT) dp_ctrl_idle_patterns_sent(ctrl); if (ctrl->catalog->isr5 & DP_CTRL_INTR_MST_DP0_VCPF_SENT) dp_ctrl_idle_patterns_sent(ctrl); if (ctrl->catalog->isr5 & DP_CTRL_INTR_MST_DP1_VCPF_SENT) dp_ctrl_idle_patterns_sent(ctrl); } struct dp_ctrl *dp_ctrl_get(struct dp_ctrl_in *in) Loading Loading @@ -996,6 +1076,7 @@ struct dp_ctrl *dp_ctrl_get(struct dp_ctrl_in *in) ctrl->link = in->link; ctrl->catalog = in->catalog; ctrl->dev = in->dev; ctrl->mst_mode = false; dp_ctrl = &ctrl->dp_ctrl; Loading drivers/gpu/drm/msm/dp/dp_ctrl.h +2 −2 Original line number Diff line number Diff line Loading @@ -25,10 +25,10 @@ struct dp_ctrl { int (*init)(struct dp_ctrl *dp_ctrl, bool flip, bool reset); void (*deinit)(struct dp_ctrl *dp_ctrl); int (*on)(struct dp_ctrl *dp_ctrl); int (*on)(struct dp_ctrl *dp_ctrl, bool mst_mode); void (*off)(struct dp_ctrl *dp_ctrl); void (*reset)(struct dp_ctrl *dp_ctrl); void (*push_idle)(struct dp_ctrl *dp_ctrl); void (*push_idle)(struct dp_ctrl *dp_ctrl, enum dp_stream_id strm); void (*abort)(struct dp_ctrl *dp_ctrl); void (*isr)(struct dp_ctrl *dp_ctrl); bool (*handle_sink_request)(struct dp_ctrl *dp_ctrl); Loading drivers/gpu/drm/msm/dp/dp_display.c +386 −40 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
drivers/gpu/drm/msm/dp/dp_catalog.c +59 −31 Original line number Diff line number Diff line Loading @@ -45,6 +45,11 @@ #define DP_INTR_MASK2 (DP_INTERRUPT_STATUS2 << 2) #define DP_INTERRUPT_STATUS5 \ (DP_INTR_MST_DP0_VCPF_SENT | DP_INTR_MST_DP0_VCPF_SENT) #define DP_INTR_MASK5 (DP_INTERRUPT_STATUS5 << 2) #define dp_catalog_fill_io(x) { \ catalog->io.x = parser->get_io(parser, #x); \ } Loading Loading @@ -726,11 +731,13 @@ static void dp_catalog_ctrl_config_ctrl(struct dp_catalog_ctrl *ctrl) catalog = dp_catalog_get_priv(ctrl); io_data = catalog->io.dp_link; cfg = dp_read(catalog, io_data, DP_CONFIGURATION_CTRL); cfg = dp_read(catalog, io_data, DP_MAINLINK_CTRL); cfg |= 0x02000000; dp_write(catalog, io_data, DP_CONFIGURATION_CTRL, cfg); dp_write(catalog, io_data, DP_MAINLINK_CTRL, cfg); pr_debug("DP_CONFIGURATION_CTRL=0x%x\n", cfg); pr_debug("DP_MAINLINK_CTRL=0x%x\n", cfg); dp_write(catalog, io_data, DP_MAINLINK_LEVELS, 0xa08); } static void dp_catalog_panel_config_ctrl(struct dp_catalog_panel *panel, Loading Loading @@ -780,7 +787,7 @@ static void dp_catalog_ctrl_lane_mapping(struct dp_catalog_ctrl *ctrl) static void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog_ctrl *ctrl, bool enable) { u32 mainlink_ctrl; u32 mainlink_ctrl, reg; struct dp_catalog_private *catalog; struct dp_io_data *io_data; Loading @@ -793,13 +800,18 @@ static void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog_ctrl *ctrl, io_data = catalog->io.dp_link; if (enable) { dp_write(catalog, io_data, DP_MAINLINK_CTRL, 0x02000000); reg = dp_read(catalog, io_data, DP_MAINLINK_CTRL); mainlink_ctrl = reg & ~(0x03); dp_write(catalog, io_data, DP_MAINLINK_CTRL, mainlink_ctrl); wmb(); /* make sure mainlink is turned off before reset */ dp_write(catalog, io_data, DP_MAINLINK_CTRL, 0x02000002); mainlink_ctrl = reg | 0x02; dp_write(catalog, io_data, DP_MAINLINK_CTRL, mainlink_ctrl); wmb(); /* make sure mainlink entered reset */ dp_write(catalog, io_data, DP_MAINLINK_CTRL, 0x02000000); mainlink_ctrl = reg & ~(0x03); dp_write(catalog, io_data, DP_MAINLINK_CTRL, mainlink_ctrl); wmb(); /* make sure mainlink reset done */ dp_write(catalog, io_data, DP_MAINLINK_CTRL, 0x02000001); mainlink_ctrl = reg | 0x01; dp_write(catalog, io_data, DP_MAINLINK_CTRL, mainlink_ctrl); wmb(); /* make sure mainlink turned on */ } else { mainlink_ctrl = dp_read(catalog, io_data, DP_MAINLINK_CTRL); Loading Loading @@ -1115,9 +1127,11 @@ static void dp_catalog_ctrl_enable_irq(struct dp_catalog_ctrl *ctrl, if (enable) { dp_write(catalog, io_data, DP_INTR_STATUS, DP_INTR_MASK1); dp_write(catalog, io_data, DP_INTR_STATUS2, DP_INTR_MASK2); dp_write(catalog, io_data, DP_INTR_STATUS5, DP_INTR_MASK5); } else { dp_write(catalog, io_data, DP_INTR_STATUS, 0x00); dp_write(catalog, io_data, DP_INTR_STATUS2, 0x00); dp_write(catalog, io_data, DP_INTR_STATUS5, 0x00); } } Loading Loading @@ -1170,6 +1184,13 @@ static void dp_catalog_ctrl_get_interrupt(struct dp_catalog_ctrl *ctrl) ack <<= 1; ack |= DP_INTR_MASK2; dp_write(catalog, io_data, DP_INTR_STATUS2, ack); ctrl->isr5 = dp_read(catalog, io_data, DP_INTR_STATUS5); ctrl->isr5 &= ~DP_INTR_MASK5; ack = ctrl->isr5 & DP_INTERRUPT_STATUS5; ack <<= 1; ack |= DP_INTR_MASK5; dp_write(catalog, io_data, DP_INTR_STATUS5, ack); } static void dp_catalog_ctrl_phy_reset(struct dp_catalog_ctrl *ctrl) Loading Loading @@ -1788,7 +1809,7 @@ static void dp_catalog_config_spd_header(struct dp_catalog_panel *panel) { struct dp_catalog_private *catalog; struct dp_io_data *io_data; u32 value, new_value; u32 value, new_value, offset = 0; u8 parity_byte; if (!panel || panel->stream_id >= DP_STREAM_MAX) Loading @@ -1798,10 +1819,10 @@ static void dp_catalog_config_spd_header(struct dp_catalog_panel *panel) io_data = catalog->io.dp_link; if (panel->stream_id == DP_STREAM_1) io_data = io_data + (MMSS_DP1_GENERIC0_0 - MMSS_DP_GENERIC0_0); offset = MMSS_DP1_GENERIC0_0 - MMSS_DP_GENERIC0_0; /* Config header and parity byte 1 */ value = dp_read(catalog, io_data, MMSS_DP_GENERIC1_0); value = dp_read(catalog, io_data, MMSS_DP_GENERIC1_0 + offset); new_value = 0x83; parity_byte = dp_header_get_parity(new_value); Loading @@ -1809,10 +1830,10 @@ static void dp_catalog_config_spd_header(struct dp_catalog_panel *panel) | (parity_byte << PARITY_BYTE_1_BIT)); pr_debug("Header Byte 1: value = 0x%x, parity_byte = 0x%x\n", value, parity_byte); dp_write(catalog, io_data, MMSS_DP_GENERIC1_0, value); dp_write(catalog, io_data, MMSS_DP_GENERIC1_0 + offset, value); /* Config header and parity byte 2 */ value = dp_read(catalog, io_data, MMSS_DP_GENERIC1_1); value = dp_read(catalog, io_data, MMSS_DP_GENERIC1_1 + offset); new_value = 0x1b; parity_byte = dp_header_get_parity(new_value); Loading @@ -1820,10 +1841,10 @@ static void dp_catalog_config_spd_header(struct dp_catalog_panel *panel) | (parity_byte << PARITY_BYTE_2_BIT)); pr_debug("Header Byte 2: value = 0x%x, parity_byte = 0x%x\n", value, parity_byte); dp_write(catalog, io_data, MMSS_DP_GENERIC1_1, value); dp_write(catalog, io_data, MMSS_DP_GENERIC1_1 + offset, value); /* Config header and parity byte 3 */ value = dp_read(catalog, io_data, MMSS_DP_GENERIC1_1); value = dp_read(catalog, io_data, MMSS_DP_GENERIC1_1 + offset); new_value = (0x0 | (0x12 << 2)); parity_byte = dp_header_get_parity(new_value); Loading @@ -1831,7 +1852,7 @@ static void dp_catalog_config_spd_header(struct dp_catalog_panel *panel) | (parity_byte << PARITY_BYTE_3_BIT)); pr_debug("Header Byte 3: value = 0x%x, parity_byte = 0x%x\n", new_value, parity_byte); dp_write(catalog, io_data, MMSS_DP_GENERIC1_1, value); dp_write(catalog, io_data, MMSS_DP_GENERIC1_1 + offset, value); } static void dp_catalog_panel_config_spd(struct dp_catalog_panel *panel) Loading @@ -1840,6 +1861,7 @@ static void dp_catalog_panel_config_spd(struct dp_catalog_panel *panel) struct dp_io_data *io_data; u32 spd_cfg = 0, spd_cfg2 = 0; u8 *vendor = NULL, *product = NULL; u32 offset = 0; u32 sdp_cfg_off = 0; u32 sdp_cfg2_off = 0; u32 sdp_cfg3_off = 0; Loading Loading @@ -1871,39 +1893,45 @@ static void dp_catalog_panel_config_spd(struct dp_catalog_panel *panel) io_data = catalog->io.dp_link; if (panel->stream_id == DP_STREAM_1) io_data = io_data + (MMSS_DP1_GENERIC0_0 - MMSS_DP_GENERIC0_0); offset = MMSS_DP1_GENERIC0_0 - MMSS_DP_GENERIC0_0; dp_catalog_config_spd_header(panel); vendor = panel->spd_vendor_name; product = panel->spd_product_description; dp_write(catalog, io_data, MMSS_DP_GENERIC1_2, ((vendor[0] & 0x7f) | dp_write(catalog, io_data, MMSS_DP_GENERIC1_2 + offset, ((vendor[0] & 0x7f) | ((vendor[1] & 0x7f) << 8) | ((vendor[2] & 0x7f) << 16) | ((vendor[3] & 0x7f) << 24))); dp_write(catalog, io_data, MMSS_DP_GENERIC1_3, ((vendor[4] & 0x7f) | dp_write(catalog, io_data, MMSS_DP_GENERIC1_3 + offset, ((vendor[4] & 0x7f) | ((vendor[5] & 0x7f) << 8) | ((vendor[6] & 0x7f) << 16) | ((vendor[7] & 0x7f) << 24))); dp_write(catalog, io_data, MMSS_DP_GENERIC1_4, ((product[0] & 0x7f) | dp_write(catalog, io_data, MMSS_DP_GENERIC1_4 + offset, ((product[0] & 0x7f) | ((product[1] & 0x7f) << 8) | ((product[2] & 0x7f) << 16) | ((product[3] & 0x7f) << 24))); dp_write(catalog, io_data, MMSS_DP_GENERIC1_5, ((product[4] & 0x7f) | dp_write(catalog, io_data, MMSS_DP_GENERIC1_5 + offset, ((product[4] & 0x7f) | ((product[5] & 0x7f) << 8) | ((product[6] & 0x7f) << 16) | ((product[7] & 0x7f) << 24))); dp_write(catalog, io_data, MMSS_DP_GENERIC1_6, ((product[8] & 0x7f) | dp_write(catalog, io_data, MMSS_DP_GENERIC1_6 + offset, ((product[8] & 0x7f) | ((product[9] & 0x7f) << 8) | ((product[10] & 0x7f) << 16) | ((product[11] & 0x7f) << 24))); dp_write(catalog, io_data, MMSS_DP_GENERIC1_7, ((product[12] & 0x7f) | dp_write(catalog, io_data, MMSS_DP_GENERIC1_7 + offset, ((product[12] & 0x7f) | ((product[13] & 0x7f) << 8) | ((product[14] & 0x7f) << 16) | ((product[15] & 0x7f) << 24))); dp_write(catalog, io_data, MMSS_DP_GENERIC1_8, device_type); dp_write(catalog, io_data, MMSS_DP_GENERIC1_9, 0x00); dp_write(catalog, io_data, MMSS_DP_GENERIC1_8 + offset, device_type); dp_write(catalog, io_data, MMSS_DP_GENERIC1_9 + offset, 0x00); if (panel->stream_id == DP_STREAM_1) { sdp_cfg_off = MMSS_DP1_SDP_CFG - MMSS_DP_SDP_CFG; Loading
drivers/gpu/drm/msm/dp/dp_catalog.h +4 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,9 @@ #define DP_INTR_FRAME_END BIT(6) #define DP_INTR_CRC_UPDATED BIT(9) #define DP_INTR_MST_DP0_VCPF_SENT BIT(0) #define DP_INTR_MST_DP1_VCPF_SENT BIT(3) #define DP_MAX_TIME_SLOTS 64 /* stream id */ Loading Loading @@ -93,6 +96,7 @@ struct dp_catalog_aux { struct dp_catalog_ctrl { u32 isr; u32 isr5; void (*state_ctrl)(struct dp_catalog_ctrl *ctrl, u32 state); void (*config_ctrl)(struct dp_catalog_ctrl *ctrl); Loading
drivers/gpu/drm/msm/dp/dp_ctrl.c +97 −16 Original line number Diff line number Diff line Loading @@ -20,9 +20,14 @@ #include "dp_ctrl.h" #define DP_MST_DEBUG(fmt, ...) pr_debug(fmt, ##__VA_ARGS__) #define DP_CTRL_INTR_READY_FOR_VIDEO BIT(0) #define DP_CTRL_INTR_IDLE_PATTERN_SENT BIT(3) #define DP_CTRL_INTR_MST_DP0_VCPF_SENT BIT(0) #define DP_CTRL_INTR_MST_DP1_VCPF_SENT BIT(3) /* dp state ctrl */ #define ST_TRAIN_PATTERN_1 BIT(0) #define ST_TRAIN_PATTERN_2 BIT(1) Loading @@ -33,6 +38,10 @@ #define ST_CUSTOM_80_BIT_PATTERN BIT(6) #define ST_SEND_VIDEO BIT(7) #define ST_PUSH_IDLE BIT(8) #define MST_DP0_PUSH_VCPF BIT(12) #define MST_DP0_FORCE_VCPF BIT(13) #define MST_DP1_PUSH_VCPF BIT(14) #define MST_DP1_FORCE_VCPF BIT(15) #define MR_LINK_TRAINING1 0x8 #define MR_LINK_SYMBOL_ERM 0x80 Loading @@ -56,6 +65,7 @@ struct dp_ctrl_private { bool orientation; bool power_on; bool mst_mode; atomic_t aborted; Loading Loading @@ -101,10 +111,11 @@ static void dp_ctrl_state_ctrl(struct dp_ctrl_private *ctrl, u32 state) ctrl->catalog->state_ctrl(ctrl->catalog, state); } static void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl) static void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl, enum dp_stream_id strm) { int const idle_pattern_completion_timeout_ms = 3 * HZ / 100; struct dp_ctrl_private *ctrl; u32 state; if (!dp_ctrl) { pr_err("Invalid input data\n"); Loading @@ -118,6 +129,19 @@ static void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl) return; } if (!ctrl->mst_mode) { state = ST_PUSH_IDLE; goto trigger_idle; } if (strm >= DP_STREAM_MAX) { pr_err("mst push idle, invalid stream:%d\n", strm); return; } state = (strm == DP_STREAM_0) ? MST_DP0_PUSH_VCPF : MST_DP1_PUSH_VCPF; trigger_idle: reinit_completion(&ctrl->idle_comp); dp_ctrl_state_ctrl(ctrl, ST_PUSH_IDLE); Loading @@ -141,6 +165,7 @@ static void dp_ctrl_configure_source_link_params(struct dp_ctrl_private *ctrl, { if (enable) { ctrl->catalog->lane_mapping(ctrl->catalog); ctrl->catalog->mst_config(ctrl->catalog, ctrl->mst_mode); ctrl->catalog->config_ctrl(ctrl->catalog); ctrl->catalog->mainlink_ctrl(ctrl->catalog, true); } else { Loading Loading @@ -658,7 +683,7 @@ static int dp_ctrl_link_maintenance(struct dp_ctrl *dp_ctrl) ctrl->aux->state &= ~DP_STATE_LINK_MAINTENANCE_FAILED; ctrl->aux->state |= DP_STATE_LINK_MAINTENANCE_STARTED; ctrl->dp_ctrl.push_idle(&ctrl->dp_ctrl); ctrl->dp_ctrl.push_idle(&ctrl->dp_ctrl, DP_STREAM_0); ctrl->dp_ctrl.reset(&ctrl->dp_ctrl); do { Loading Loading @@ -727,7 +752,7 @@ static void dp_ctrl_process_phy_test_request(struct dp_ctrl *dp_ctrl) pr_debug("start\n"); ctrl->dp_ctrl.push_idle(&ctrl->dp_ctrl); ctrl->dp_ctrl.push_idle(&ctrl->dp_ctrl, DP_STREAM_0); /* * The global reset will need DP link ralated clocks to be * running. Add the global reset just before disabling the Loading @@ -736,7 +761,7 @@ static void dp_ctrl_process_phy_test_request(struct dp_ctrl *dp_ctrl) ctrl->dp_ctrl.reset(&ctrl->dp_ctrl); ctrl->dp_ctrl.off(&ctrl->dp_ctrl); ret = ctrl->dp_ctrl.on(&ctrl->dp_ctrl); ret = ctrl->dp_ctrl.on(&ctrl->dp_ctrl, ctrl->mst_mode); if (ret) pr_err("failed to enable DP controller\n"); Loading Loading @@ -809,6 +834,56 @@ static void dp_ctrl_reset(struct dp_ctrl *dp_ctrl) ctrl->catalog->reset(ctrl->catalog); } static int dp_ctrl_mst_stream_setup(struct dp_ctrl_private *ctrl, struct dp_panel *panel) { u32 x_int, y_frac_enum, lanes, bw_code; bool act_complete; if (!ctrl->mst_mode) { ctrl->catalog->state_ctrl(ctrl->catalog, ST_SEND_VIDEO); return 0; } DP_MST_DEBUG("mst stream channel allocation\n"); ctrl->catalog->channel_alloc(ctrl->catalog, panel->stream_id, panel->channel_start_slot, panel->channel_total_slots); lanes = ctrl->link->link_params.lane_count; bw_code = ctrl->link->link_params.bw_code; x_int = (u32)(lanes * panel->channel_total_slots); y_frac_enum = (u32)(256 * ((lanes * lanes * panel->channel_total_slots) - x_int)); ctrl->catalog->update_rg(ctrl->catalog, panel->stream_id, x_int, y_frac_enum); DP_MST_DEBUG("mst stream:%d, start_slot:%d, tot_slots:%d\n", panel->stream_id, panel->channel_start_slot, panel->channel_total_slots); DP_MST_DEBUG("mst lane_cnt:%d, bw:%d, x_int:%d, y_frac:%d\n", lanes, bw_code, x_int, y_frac_enum); ctrl->catalog->state_ctrl(ctrl->catalog, ST_SEND_VIDEO); ctrl->catalog->trigger_act(ctrl->catalog); msleep(20); /* needs 1 frame time */ ctrl->catalog->read_act_complete_sts(ctrl->catalog, &act_complete); if (!act_complete) pr_err("mst act trigger complete failed\n"); else DP_MST_DEBUG("mst ACT trigger complete SUCCESS\n"); return 0; } static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) { int rc = 0; Loading @@ -826,16 +901,16 @@ static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) if (rc) { pr_err("failure on stream clock enable\n"); goto end; } else { ctrl->catalog->state_ctrl(ctrl->catalog, ST_SEND_VIDEO); } rc = dp_ctrl_mst_stream_setup(ctrl, panel); if (rc) goto end; dp_ctrl_wait4video_ready(ctrl); link_ready = ctrl->catalog->mainlink_ready(ctrl->catalog); pr_debug("mainlink %s\n", link_ready ? "READY" : "NOT READY"); panel->hw_cfg(panel); } end: return rc; } Loading @@ -852,7 +927,7 @@ static void dp_ctrl_stream_off(struct dp_ctrl *dp_ctrl, struct dp_panel *panel) dp_ctrl_disable_stream_clocks(ctrl, panel); } static int dp_ctrl_on(struct dp_ctrl *dp_ctrl) static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode) { int rc = 0; struct dp_ctrl_private *ctrl; Loading @@ -867,6 +942,8 @@ static int dp_ctrl_on(struct dp_ctrl *dp_ctrl) ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); atomic_set(&ctrl->aborted, 0); ctrl->mst_mode = mst_mode; rate = ctrl->panel->link_info.rate; ctrl->catalog->hpd_config(ctrl->catalog, true); Loading Loading @@ -915,8 +992,6 @@ static int dp_ctrl_on(struct dp_ctrl *dp_ctrl) if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) dp_ctrl_send_phy_test_pattern(ctrl); dp_ctrl_stream_on(dp_ctrl, ctrl->panel); ctrl->power_on = true; pr_debug("End-\n"); Loading @@ -934,8 +1009,6 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl) ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); dp_ctrl_stream_off(dp_ctrl, ctrl->panel); dp_ctrl_configure_source_link_params(ctrl, false); ctrl->catalog->reset(ctrl->catalog); Loading @@ -944,6 +1017,7 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl) dp_ctrl_disable_mainlink_clocks(ctrl); ctrl->mst_mode = false; ctrl->power_on = false; pr_debug("DP off done\n"); } Loading @@ -964,6 +1038,12 @@ static void dp_ctrl_isr(struct dp_ctrl *dp_ctrl) if (ctrl->catalog->isr & DP_CTRL_INTR_IDLE_PATTERN_SENT) dp_ctrl_idle_patterns_sent(ctrl); if (ctrl->catalog->isr5 & DP_CTRL_INTR_MST_DP0_VCPF_SENT) dp_ctrl_idle_patterns_sent(ctrl); if (ctrl->catalog->isr5 & DP_CTRL_INTR_MST_DP1_VCPF_SENT) dp_ctrl_idle_patterns_sent(ctrl); } struct dp_ctrl *dp_ctrl_get(struct dp_ctrl_in *in) Loading Loading @@ -996,6 +1076,7 @@ struct dp_ctrl *dp_ctrl_get(struct dp_ctrl_in *in) ctrl->link = in->link; ctrl->catalog = in->catalog; ctrl->dev = in->dev; ctrl->mst_mode = false; dp_ctrl = &ctrl->dp_ctrl; Loading
drivers/gpu/drm/msm/dp/dp_ctrl.h +2 −2 Original line number Diff line number Diff line Loading @@ -25,10 +25,10 @@ struct dp_ctrl { int (*init)(struct dp_ctrl *dp_ctrl, bool flip, bool reset); void (*deinit)(struct dp_ctrl *dp_ctrl); int (*on)(struct dp_ctrl *dp_ctrl); int (*on)(struct dp_ctrl *dp_ctrl, bool mst_mode); void (*off)(struct dp_ctrl *dp_ctrl); void (*reset)(struct dp_ctrl *dp_ctrl); void (*push_idle)(struct dp_ctrl *dp_ctrl); void (*push_idle)(struct dp_ctrl *dp_ctrl, enum dp_stream_id strm); void (*abort)(struct dp_ctrl *dp_ctrl); void (*isr)(struct dp_ctrl *dp_ctrl); bool (*handle_sink_request)(struct dp_ctrl *dp_ctrl); Loading
drivers/gpu/drm/msm/dp/dp_display.c +386 −40 File changed.Preview size limit exceeded, changes collapsed. Show changes