Merge "ARM: dts: msm: switch to RPMh controlled clocks for sdm845" into msm-4.9
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index 341f5cb..cd851bc 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -199,7 +199,7 @@
 	if (IS_ERR_OR_NULL(dir)) {
 		rc = PTR_ERR(dir);
 		pr_err("[DSI_%d] debugfs create dir failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto error;
 	}
 
@@ -211,7 +211,7 @@
 	if (IS_ERR_OR_NULL(state_file)) {
 		rc = PTR_ERR(state_file);
 		pr_err("[DSI_%d] state file failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto error_remove_dir;
 	}
 
@@ -223,7 +223,7 @@
 	if (IS_ERR_OR_NULL(reg_dump)) {
 		rc = PTR_ERR(reg_dump);
 		pr_err("[DSI_%d] reg dump file failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto error_remove_dir;
 	}
 
@@ -251,14 +251,14 @@
 	case DSI_CTRL_OP_POWER_STATE_CHANGE:
 		if (state->power_state == op_state) {
 			pr_debug("[%d] No change in state, pwr_state=%d\n",
-			       dsi_ctrl->index, op_state);
+			       dsi_ctrl->cell_index, op_state);
 			rc = -EINVAL;
 		} else if (state->power_state == DSI_CTRL_POWER_VREG_ON) {
 			if ((state->cmd_engine_state == DSI_CTRL_ENGINE_ON) ||
 			    (state->vid_engine_state == DSI_CTRL_ENGINE_ON) ||
 			    (state->controller_state == DSI_CTRL_ENGINE_ON)) {
 				pr_debug("[%d]State error: op=%d: %d, %d, %d\n",
-				       dsi_ctrl->index,
+				       dsi_ctrl->cell_index,
 				       op_state,
 				       state->cmd_engine_state,
 				       state->vid_engine_state,
@@ -270,12 +270,12 @@
 	case DSI_CTRL_OP_CMD_ENGINE:
 		if (state->cmd_engine_state == op_state) {
 			pr_debug("[%d] No change in state, cmd_state=%d\n",
-			       dsi_ctrl->index, op_state);
+			       dsi_ctrl->cell_index, op_state);
 			rc = -EINVAL;
 		} else if ((state->power_state != DSI_CTRL_POWER_VREG_ON) ||
 			   (state->controller_state != DSI_CTRL_ENGINE_ON)) {
 			pr_debug("[%d]State error: op=%d: %d, %d\n",
-			       dsi_ctrl->index,
+			       dsi_ctrl->cell_index,
 			       op,
 			       state->power_state,
 			       state->controller_state);
@@ -285,12 +285,12 @@
 	case DSI_CTRL_OP_VID_ENGINE:
 		if (state->vid_engine_state == op_state) {
 			pr_debug("[%d] No change in state, cmd_state=%d\n",
-			       dsi_ctrl->index, op_state);
+			       dsi_ctrl->cell_index, op_state);
 			rc = -EINVAL;
 		} else if ((state->power_state != DSI_CTRL_POWER_VREG_ON) ||
 			   (state->controller_state != DSI_CTRL_ENGINE_ON)) {
 			pr_debug("[%d]State error: op=%d: %d, %d\n",
-			       dsi_ctrl->index,
+			       dsi_ctrl->cell_index,
 			       op,
 			       state->power_state,
 			       state->controller_state);
@@ -300,11 +300,11 @@
 	case DSI_CTRL_OP_HOST_ENGINE:
 		if (state->controller_state == op_state) {
 			pr_debug("[%d] No change in state, ctrl_state=%d\n",
-			       dsi_ctrl->index, op_state);
+			       dsi_ctrl->cell_index, op_state);
 			rc = -EINVAL;
 		} else if (state->power_state != DSI_CTRL_POWER_VREG_ON) {
 			pr_debug("[%d]State error (link is off): op=%d:, %d\n",
-			       dsi_ctrl->index,
+			       dsi_ctrl->cell_index,
 			       op_state,
 			       state->power_state);
 			rc = -EINVAL;
@@ -312,7 +312,7 @@
 			   ((state->cmd_engine_state != DSI_CTRL_ENGINE_OFF) ||
 			    (state->vid_engine_state != DSI_CTRL_ENGINE_OFF))) {
 			pr_debug("[%d]State error (eng on): op=%d: %d, %d\n",
-				  dsi_ctrl->index,
+				  dsi_ctrl->cell_index,
 				  op_state,
 				  state->cmd_engine_state,
 				  state->vid_engine_state);
@@ -324,7 +324,7 @@
 		    (state->host_initialized != true) ||
 		    (state->cmd_engine_state != DSI_CTRL_ENGINE_ON)) {
 			pr_debug("[%d]State error: op=%d: %d, %d, %d\n",
-			       dsi_ctrl->index,
+			       dsi_ctrl->cell_index,
 			       op,
 			       state->power_state,
 			       state->host_initialized,
@@ -335,23 +335,23 @@
 	case DSI_CTRL_OP_HOST_INIT:
 		if (state->host_initialized == op_state) {
 			pr_debug("[%d] No change in state, host_init=%d\n",
-			       dsi_ctrl->index, op_state);
+			       dsi_ctrl->cell_index, op_state);
 			rc = -EINVAL;
 		} else if (state->power_state != DSI_CTRL_POWER_VREG_ON) {
 			pr_debug("[%d]State error: op=%d: %d\n",
-			       dsi_ctrl->index, op, state->power_state);
+			       dsi_ctrl->cell_index, op, state->power_state);
 			rc = -EINVAL;
 		}
 		break;
 	case DSI_CTRL_OP_TPG:
 		if (state->tpg_enabled == op_state) {
 			pr_debug("[%d] No change in state, tpg_enabled=%d\n",
-			       dsi_ctrl->index, op_state);
+			       dsi_ctrl->cell_index, op_state);
 			rc = -EINVAL;
 		} else if ((state->power_state != DSI_CTRL_POWER_VREG_ON) ||
 			   (state->controller_state != DSI_CTRL_ENGINE_ON)) {
 			pr_debug("[%d]State error: op=%d: %d, %d\n",
-			       dsi_ctrl->index,
+			       dsi_ctrl->cell_index,
 			       op,
 			       state->power_state,
 			       state->controller_state);
@@ -361,14 +361,14 @@
 	case DSI_CTRL_OP_PHY_SW_RESET:
 		if (state->power_state != DSI_CTRL_POWER_VREG_ON) {
 			pr_debug("[%d]State error: op=%d: %d\n",
-			       dsi_ctrl->index, op, state->power_state);
+			       dsi_ctrl->cell_index, op, state->power_state);
 			rc = -EINVAL;
 		}
 		break;
 	case DSI_CTRL_OP_ASYNC_TIMING:
 		if (state->vid_engine_state != op_state) {
 			pr_err("[%d] Unexpected engine state vid_state=%d\n",
-			       dsi_ctrl->index, op_state);
+			       dsi_ctrl->cell_index, op_state);
 			rc = -EINVAL;
 		}
 		break;
@@ -771,7 +771,7 @@
 	dsi_ctrl->clk_freq.esc_clk_rate = config->esc_clk_rate_hz;
 
 	rc = dsi_clk_set_link_frequencies(clk_handle, dsi_ctrl->clk_freq,
-					dsi_ctrl->index);
+					dsi_ctrl->cell_index);
 	if (rc)
 		pr_err("Failed to update link frequencies\n");
 
@@ -933,7 +933,7 @@
 		pr_debug("INT STATUS = %x, retry = %d\n", status, retry);
 		if (retry == 0)
 			pr_err("[DSI_%d]Command transfer failed\n",
-			       dsi_ctrl->index);
+			       dsi_ctrl->cell_index);
 
 		dsi_ctrl->hw.ops.reset_cmd_fifo(&dsi_ctrl->hw);
 	}
@@ -1207,7 +1207,7 @@
 		index = 0;
 	}
 
-	dsi_ctrl->index = index;
+	dsi_ctrl->cell_index = index;
 
 	dsi_ctrl->name = of_get_property(pdev->dev.of_node, "label", NULL);
 	if (!dsi_ctrl->name)
@@ -1233,7 +1233,7 @@
 
 	dsi_ctrl->version = version;
 	rc = dsi_catalog_ctrl_setup(&dsi_ctrl->hw, dsi_ctrl->version,
-				    dsi_ctrl->index);
+				    dsi_ctrl->cell_index);
 	if (rc) {
 		pr_err("Catalog does not support version (%d)\n",
 		       dsi_ctrl->version);
@@ -1410,7 +1410,7 @@
 	rc = dsi_ctrl_debugfs_init(dsi_ctrl, parent);
 	if (rc) {
 		pr_err("[DSI_%d] failed to init debug fs, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto error;
 	}
 
@@ -1488,13 +1488,13 @@
 	rc = dsi_ctrl_check_state(dsi_ctrl, DSI_CTRL_OP_PHY_SW_RESET, 0x0);
 	if (rc) {
 		pr_err("[DSI_%d] Controller state check failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto error;
 	}
 
 	dsi_ctrl->hw.ops.phy_sw_reset(&dsi_ctrl->hw);
 
-	pr_debug("[DSI_%d] PHY soft reset done\n", dsi_ctrl->index);
+	pr_debug("[DSI_%d] PHY soft reset done\n", dsi_ctrl->cell_index);
 	dsi_ctrl_update_state(dsi_ctrl, DSI_CTRL_OP_PHY_SW_RESET, 0x0);
 error:
 	mutex_unlock(&dsi_ctrl->ctrl_lock);
@@ -1528,7 +1528,7 @@
 			DSI_CTRL_ENGINE_ON);
 	if (rc) {
 		pr_err("[DSI_%d] Controller state check failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto exit;
 	}
 
@@ -1642,7 +1642,7 @@
 	rc = dsi_ctrl_check_state(dsi_ctrl, DSI_CTRL_OP_HOST_INIT, 0x1);
 	if (rc) {
 		pr_err("[DSI_%d] Controller state check failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto error;
 	}
 
@@ -1676,7 +1676,8 @@
 
 	/* Perform a soft reset before enabling dsi controller */
 	dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw);
-	pr_debug("[DSI_%d]Host initialization complete\n", dsi_ctrl->index);
+	pr_debug("[DSI_%d]Host initialization complete\n",
+		dsi_ctrl->cell_index);
 	dsi_ctrl_update_state(dsi_ctrl, DSI_CTRL_OP_HOST_INIT, 0x1);
 error:
 	mutex_unlock(&dsi_ctrl->ctrl_lock);
@@ -1692,7 +1693,7 @@
 	dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw);
 	mutex_unlock(&dsi_ctrl->ctrl_lock);
 
-	pr_debug("[DSI_%d]Soft reset complete\n", dsi_ctrl->index);
+	pr_debug("[DSI_%d]Soft reset complete\n", dsi_ctrl->cell_index);
 	return 0;
 }
 
@@ -1719,12 +1720,13 @@
 	rc = dsi_ctrl_check_state(dsi_ctrl, DSI_CTRL_OP_HOST_INIT, 0x0);
 	if (rc) {
 		pr_err("[DSI_%d] Controller state check failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		pr_err("driver state check failed, rc=%d\n", rc);
 		goto error;
 	}
 
-	pr_debug("[DSI_%d] Host deinitization complete\n", dsi_ctrl->index);
+	pr_debug("[DSI_%d] Host deinitization complete\n",
+		dsi_ctrl->cell_index);
 	dsi_ctrl_update_state(dsi_ctrl, DSI_CTRL_OP_HOST_INIT, 0x0);
 error:
 	mutex_unlock(&dsi_ctrl->ctrl_lock);
@@ -1771,7 +1773,7 @@
 		}
 	}
 
-	pr_debug("[DSI_%d]Host config updated\n", ctrl->index);
+	pr_debug("[DSI_%d]Host config updated\n", ctrl->cell_index);
 	memcpy(&ctrl->host_config, config, sizeof(ctrl->host_config));
 error:
 	mutex_unlock(&ctrl->ctrl_lock);
@@ -1834,7 +1836,7 @@
 	rc = dsi_ctrl_check_state(dsi_ctrl, DSI_CTRL_OP_CMD_TX, 0x0);
 	if (rc) {
 		pr_err("[DSI_%d] Controller state check failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto error;
 	}
 
@@ -1895,7 +1897,7 @@
 		pr_debug("INT STATUS = %x, retry = %d\n", status, retry);
 		if (retry == 0)
 			pr_err("[DSI_%d]Command transfer failed\n",
-			       dsi_ctrl->index);
+			       dsi_ctrl->cell_index);
 	}
 
 	mutex_unlock(&dsi_ctrl->ctrl_lock);
@@ -1928,7 +1930,7 @@
 				  state);
 	if (rc) {
 		pr_err("[DSI_%d] Controller state check failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto error;
 	}
 
@@ -1936,19 +1938,19 @@
 		rc = dsi_ctrl_enable_supplies(dsi_ctrl, true);
 		if (rc) {
 			pr_err("[%d]failed to enable voltage supplies, rc=%d\n",
-			       dsi_ctrl->index, rc);
+			       dsi_ctrl->cell_index, rc);
 			goto error;
 		}
 	} else if (state == DSI_CTRL_POWER_VREG_OFF) {
 		rc = dsi_ctrl_enable_supplies(dsi_ctrl, false);
 		if (rc) {
 			pr_err("[%d]failed to disable vreg supplies, rc=%d\n",
-			       dsi_ctrl->index, rc);
+			       dsi_ctrl->cell_index, rc);
 			goto error;
 		}
 	}
 
-	pr_debug("[DSI_%d] Power state updated to %d\n", dsi_ctrl->index,
+	pr_debug("[DSI_%d] Power state updated to %d\n", dsi_ctrl->cell_index,
 		 state);
 	dsi_ctrl_update_state(dsi_ctrl, DSI_CTRL_OP_POWER_STATE_CHANGE, state);
 error:
@@ -1980,7 +1982,7 @@
 	rc = dsi_ctrl_check_state(dsi_ctrl, DSI_CTRL_OP_TPG, on);
 	if (rc) {
 		pr_err("[DSI_%d] Controller state check failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto error;
 	}
 
@@ -1999,7 +2001,8 @@
 	}
 	dsi_ctrl->hw.ops.test_pattern_enable(&dsi_ctrl->hw, on);
 
-	pr_debug("[DSI_%d]Set test pattern state=%d\n", dsi_ctrl->index, on);
+	pr_debug("[DSI_%d]Set test pattern state=%d\n",
+		dsi_ctrl->cell_index, on);
 	dsi_ctrl_update_state(dsi_ctrl, DSI_CTRL_OP_TPG, on);
 error:
 	mutex_unlock(&dsi_ctrl->ctrl_lock);
@@ -2031,7 +2034,7 @@
 	rc = dsi_ctrl_check_state(dsi_ctrl, DSI_CTRL_OP_HOST_ENGINE, state);
 	if (rc) {
 		pr_err("[DSI_%d] Controller state check failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto error;
 	}
 
@@ -2040,7 +2043,7 @@
 	else
 		dsi_ctrl->hw.ops.ctrl_en(&dsi_ctrl->hw, false);
 
-	pr_debug("[DSI_%d] Set host engine state = %d\n", dsi_ctrl->index,
+	pr_debug("[DSI_%d] Set host engine state = %d\n", dsi_ctrl->cell_index,
 		 state);
 	dsi_ctrl_update_state(dsi_ctrl, DSI_CTRL_OP_HOST_ENGINE, state);
 error:
@@ -2073,7 +2076,7 @@
 	rc = dsi_ctrl_check_state(dsi_ctrl, DSI_CTRL_OP_CMD_ENGINE, state);
 	if (rc) {
 		pr_err("[DSI_%d] Controller state check failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto error;
 	}
 
@@ -2082,7 +2085,7 @@
 	else
 		dsi_ctrl->hw.ops.cmd_engine_en(&dsi_ctrl->hw, false);
 
-	pr_debug("[DSI_%d] Set cmd engine state = %d\n", dsi_ctrl->index,
+	pr_debug("[DSI_%d] Set cmd engine state = %d\n", dsi_ctrl->cell_index,
 		 state);
 	dsi_ctrl_update_state(dsi_ctrl, DSI_CTRL_OP_CMD_ENGINE, state);
 error:
@@ -2116,7 +2119,7 @@
 	rc = dsi_ctrl_check_state(dsi_ctrl, DSI_CTRL_OP_VID_ENGINE, state);
 	if (rc) {
 		pr_err("[DSI_%d] Controller state check failed, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		goto error;
 	}
 
@@ -2127,7 +2130,7 @@
 	if (!on)
 		dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw);
 
-	pr_debug("[DSI_%d] Set video engine state = %d\n", dsi_ctrl->index,
+	pr_debug("[DSI_%d] Set video engine state = %d\n", dsi_ctrl->cell_index,
 		 state);
 	dsi_ctrl_update_state(dsi_ctrl, DSI_CTRL_OP_VID_ENGINE, state);
 error:
@@ -2162,10 +2165,10 @@
 
 	if (rc) {
 		pr_err("[DSI_%d] Ulps state change(%d) failed, rc=%d\n",
-			dsi_ctrl->index, enable, rc);
+			dsi_ctrl->cell_index, enable, rc);
 		goto error;
 	}
-	pr_debug("[DSI_%d] ULPS state = %d\n", dsi_ctrl->index, enable);
+	pr_debug("[DSI_%d] ULPS state = %d\n", dsi_ctrl->cell_index, enable);
 
 error:
 	mutex_unlock(&dsi_ctrl->ctrl_lock);
@@ -2201,11 +2204,12 @@
 
 	rc = dsi_enable_io_clamp(dsi_ctrl, enable, ulps_enabled);
 	if (rc) {
-		pr_err("[DSI_%d] Failed to enable IO clamp\n", dsi_ctrl->index);
+		pr_err("[DSI_%d] Failed to enable IO clamp\n",
+			dsi_ctrl->cell_index);
 		goto error;
 	}
 
-	pr_debug("[DSI_%d] Clamp state = %d\n", dsi_ctrl->index, enable);
+	pr_debug("[DSI_%d] Clamp state = %d\n", dsi_ctrl->cell_index, enable);
 error:
 	mutex_unlock(&dsi_ctrl->ctrl_lock);
 	return rc;
@@ -2235,7 +2239,7 @@
 	rc = dsi_clk_update_parent(source_clks, &dsi_ctrl->clk_info.rcg_clks);
 	if (rc) {
 		pr_err("[DSI_%d]Failed to update link clk parent, rc=%d\n",
-		       dsi_ctrl->index, rc);
+		       dsi_ctrl->cell_index, rc);
 		(void)dsi_clk_update_parent(&dsi_ctrl->clk_info.pll_op_clks,
 					    &dsi_ctrl->clk_info.rcg_clks);
 		goto error;
@@ -2244,7 +2248,7 @@
 	dsi_ctrl->clk_info.pll_op_clks.byte_clk = source_clks->byte_clk;
 	dsi_ctrl->clk_info.pll_op_clks.pixel_clk = source_clks->pixel_clk;
 
-	pr_debug("[DSI_%d] Source clocks are updated\n", dsi_ctrl->index);
+	pr_debug("[DSI_%d] Source clocks are updated\n", dsi_ctrl->cell_index);
 
 error:
 	mutex_unlock(&dsi_ctrl->ctrl_lock);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
index fc95a9a..f8adbea 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
@@ -167,7 +167,7 @@
 /**
  * struct dsi_ctrl - DSI controller object
  * @pdev:                Pointer to platform device.
- * @index:               Instance id.
+ * @cell_index:          Instance cell id.
  * @name:                Name of the controller instance.
  * @refcount:            ref counter.
  * @ctrl_lock:           Mutex for hardware and object access.
@@ -188,7 +188,7 @@
  */
 struct dsi_ctrl {
 	struct platform_device *pdev;
-	u32 index;
+	u32 cell_index;
 	const char *name;
 	u32 refcount;
 	struct mutex ctrl_lock;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index d70693b..aa3152f 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -2282,7 +2282,7 @@
 			sizeof(struct dsi_link_clk_info));
 		info.bus_handle[i] =
 			display_ctrl->ctrl->axi_bus_info.bus_handle;
-		info.ctrl_index[i] = display_ctrl->ctrl->index;
+		info.ctrl_index[i] = display_ctrl->ctrl->cell_index;
 	}
 
 	info.pre_clkoff_cb = dsi_pre_clkoff_cb;
@@ -2688,7 +2688,7 @@
 
 	info->num_of_h_tiles = display->ctrl_count;
 	for (i = 0; i < info->num_of_h_tiles; i++)
-		info->h_tile_instance[i] = display->ctrl[i].ctrl->index;
+		info->h_tile_instance[i] = display->ctrl[i].ctrl->cell_index;
 
 	info->is_connected = true;
 	info->is_primary = true;
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 272e122..48bccd9 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -505,8 +505,7 @@
 	dbg_power_ctrl.handle = &priv->phandle;
 	dbg_power_ctrl.client = priv->pclient;
 	dbg_power_ctrl.enable_fn = msm_power_enable_wrapper;
-	ret = sde_dbg_init(ddev->primary->debugfs_root, &pdev->dev,
-			&dbg_power_ctrl);
+	ret = sde_dbg_init(&pdev->dev, &dbg_power_ctrl);
 	if (ret) {
 		dev_err(dev, "failed to init sde dbg: %d\n", ret);
 		goto fail;
@@ -605,6 +604,12 @@
 	if (ret)
 		goto fail;
 
+	ret = sde_dbg_debugfs_register(ddev->primary->debugfs_root);
+	if (ret) {
+		dev_err(dev, "failed to reg sde dbg debugfs: %d\n", ret);
+		goto fail;
+	}
+
 	/* perform subdriver post initialization */
 	if (kms && kms->funcs && kms->funcs->postinit) {
 		ret = kms->funcs->postinit(kms);
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index 46491fb..0e5342f 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -495,6 +495,11 @@
 	return sde_connector_init_debugfs(connector);
 }
 
+static void sde_connector_early_unregister(struct drm_connector *connector)
+{
+	/* debugfs under connector->debugfs are deleted by drm_debugfs */
+}
+
 static const struct drm_connector_funcs sde_connector_ops = {
 	.dpms =                   drm_atomic_helper_connector_dpms,
 	.reset =                  sde_connector_atomic_reset,
@@ -507,6 +512,7 @@
 	.atomic_get_property =    sde_connector_atomic_get_property,
 	.set_property =           sde_connector_set_property,
 	.late_register =          sde_connector_late_register,
+	.early_unregister =       sde_connector_early_unregister,
 };
 
 static int sde_connector_get_modes(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/msm/sde/sde_core_irq.c b/drivers/gpu/drm/msm/sde/sde_core_irq.c
index 67b577b..71a8bdf 100644
--- a/drivers/gpu/drm/msm/sde/sde_core_irq.c
+++ b/drivers/gpu/drm/msm/sde/sde_core_irq.c
@@ -386,7 +386,7 @@
 		atomic_set(&sde_kms->irq_obj.irq_counts[i], 0);
 	}
 
-	sde_debugfs_core_irq_init(sde_kms, sde_kms->debugfs_root);
+	sde_debugfs_core_irq_init(sde_kms, sde_debugfs_get_root(sde_kms));
 }
 
 int sde_core_irq_postinstall(struct sde_kms *sde_kms)
diff --git a/drivers/gpu/drm/msm/sde/sde_core_perf.c b/drivers/gpu/drm/msm/sde/sde_core_perf.c
index 7a68f91..307c617 100644
--- a/drivers/gpu/drm/msm/sde/sde_core_perf.c
+++ b/drivers/gpu/drm/msm/sde/sde_core_perf.c
@@ -456,13 +456,13 @@
 	.write = _sde_core_perf_mode_write,
 };
 
-static void sde_debugfs_core_perf_destroy(struct sde_core_perf *perf)
+static void sde_core_perf_debugfs_destroy(struct sde_core_perf *perf)
 {
 	debugfs_remove_recursive(perf->debugfs_root);
 	perf->debugfs_root = NULL;
 }
 
-static int sde_debugfs_core_perf_init(struct sde_core_perf *perf,
+int sde_core_perf_debugfs_init(struct sde_core_perf *perf,
 		struct dentry *parent)
 {
 	struct sde_mdss_cfg *catalog = perf->catalog;
@@ -499,11 +499,11 @@
 	return 0;
 }
 #else
-static void sde_debugfs_core_perf_destroy(struct sde_core_perf *perf)
+static void sde_core_perf_debugfs_destroy(struct sde_core_perf *perf)
 {
 }
 
-static int sde_debugfs_core_perf_init(struct sde_core_perf *perf,
+int sde_core_perf_debugfs_init(struct sde_core_perf *perf,
 		struct dentry *parent)
 {
 	return 0;
@@ -517,7 +517,7 @@
 		return;
 	}
 
-	sde_debugfs_core_perf_destroy(perf);
+	sde_core_perf_debugfs_destroy(perf);
 	perf->max_core_clk_rate = 0;
 	perf->core_clk = NULL;
 	mutex_destroy(&perf->perf_lock);
@@ -532,11 +532,9 @@
 		struct sde_mdss_cfg *catalog,
 		struct sde_power_handle *phandle,
 		struct sde_power_client *pclient,
-		char *clk_name,
-		struct dentry *debugfs_parent)
+		char *clk_name)
 {
-	if (!perf || !catalog || !phandle || !pclient ||
-			!clk_name || !debugfs_parent) {
+	if (!perf || !dev || !catalog || !phandle || !pclient || !clk_name) {
 		SDE_ERROR("invalid parameters\n");
 		return -EINVAL;
 	}
@@ -560,8 +558,6 @@
 		goto err;
 	}
 
-	sde_debugfs_core_perf_init(perf, debugfs_parent);
-
 	return 0;
 
 err:
diff --git a/drivers/gpu/drm/msm/sde/sde_core_perf.h b/drivers/gpu/drm/msm/sde/sde_core_perf.h
index e5dd9b6..20e4eb5 100644
--- a/drivers/gpu/drm/msm/sde/sde_core_perf.h
+++ b/drivers/gpu/drm/msm/sde/sde_core_perf.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,8 +10,8 @@
  * GNU General Public License for more details.
  */
 
-#ifndef __SDE_CORE_PERF_H__
-#define __SDE_CORE_PERF_H__
+#ifndef _SDE_CORE_PERF_H_
+#define _SDE_CORE_PERF_H_
 
 #include <linux/types.h>
 #include <linux/dcache.h>
@@ -111,14 +111,20 @@
  * @phandle: Pointer to power handle
  * @pclient: Pointer to power client
  * @clk_name: core clock name
- * @debugfs_parent: Pointer to parent debugfs
  */
 int sde_core_perf_init(struct sde_core_perf *perf,
 		struct drm_device *dev,
 		struct sde_mdss_cfg *catalog,
 		struct sde_power_handle *phandle,
 		struct sde_power_client *pclient,
-		char *clk_name,
-		struct dentry *debugfs_parent);
+		char *clk_name);
 
-#endif /* __SDE_CORE_PERF_H__ */
+/**
+ * sde_core_perf_debugfs_init - initialize debugfs for core performance context
+ * @perf: Pointer to core performance context
+ * @debugfs_parent: Pointer to parent debugfs
+ */
+int sde_core_perf_debugfs_init(struct sde_core_perf *perf,
+		struct dentry *parent);
+
+#endif /* _SDE_CORE_PERF_H_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 76c1212..2666990 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -72,7 +72,6 @@
 	msm_property_destroy(&sde_crtc->property_info);
 	sde_cp_crtc_destroy_properties(crtc);
 
-	debugfs_remove_recursive(sde_crtc->debugfs_root);
 	mutex_destroy(&sde_crtc->crtc_lock);
 	sde_fence_deinit(&sde_crtc->output_fence);
 
@@ -1843,30 +1842,7 @@
 {
 	return single_open(file, _sde_debugfs_status_show, inode->i_private);
 }
-#endif
 
-static const struct drm_crtc_funcs sde_crtc_funcs = {
-	.set_config = drm_atomic_helper_set_config,
-	.destroy = sde_crtc_destroy,
-	.page_flip = drm_atomic_helper_page_flip,
-	.set_property = sde_crtc_set_property,
-	.atomic_set_property = sde_crtc_atomic_set_property,
-	.atomic_get_property = sde_crtc_atomic_get_property,
-	.reset = sde_crtc_reset,
-	.atomic_duplicate_state = sde_crtc_duplicate_state,
-	.atomic_destroy_state = sde_crtc_destroy_state,
-};
-
-static const struct drm_crtc_helper_funcs sde_crtc_helper_funcs = {
-	.mode_fixup = sde_crtc_mode_fixup,
-	.disable = sde_crtc_disable,
-	.enable = sde_crtc_enable,
-	.atomic_check = sde_crtc_atomic_check,
-	.atomic_begin = sde_crtc_atomic_begin,
-	.atomic_flush = sde_crtc_atomic_flush,
-};
-
-#ifdef CONFIG_DEBUG_FS
 #define DEFINE_SDE_DEBUGFS_SEQ_FOPS(__prefix)				\
 static int __prefix ## _open(struct inode *inode, struct file *file)	\
 {									\
@@ -1897,9 +1873,11 @@
 }
 DEFINE_SDE_DEBUGFS_SEQ_FOPS(sde_crtc_debugfs_state);
 
-static void _sde_crtc_init_debugfs(struct sde_crtc *sde_crtc,
-		struct sde_kms *sde_kms)
+static int _sde_crtc_init_debugfs(struct drm_crtc *crtc)
 {
+	struct sde_crtc *sde_crtc;
+	struct sde_kms *sde_kms;
+
 	static const struct file_operations debugfs_status_fops = {
 		.open =		_sde_debugfs_status_open,
 		.read =		seq_read,
@@ -1907,27 +1885,84 @@
 		.release =	single_release,
 	};
 
-	if (sde_crtc && sde_kms) {
-		sde_crtc->debugfs_root = debugfs_create_dir(sde_crtc->name,
-				sde_debugfs_get_root(sde_kms));
-		if (sde_crtc->debugfs_root) {
-			/* don't error check these */
-			debugfs_create_file("status", 0444,
-					sde_crtc->debugfs_root,
-					sde_crtc, &debugfs_status_fops);
-			debugfs_create_file("state", 0644,
-					sde_crtc->debugfs_root,
-					&sde_crtc->base,
-					&sde_crtc_debugfs_state_fops);
-		}
-	}
+	if (!crtc)
+		return -EINVAL;
+	sde_crtc = to_sde_crtc(crtc);
+
+	sde_kms = _sde_crtc_get_kms(crtc);
+	if (!sde_kms)
+		return -EINVAL;
+
+	sde_crtc->debugfs_root = debugfs_create_dir(sde_crtc->name,
+			sde_debugfs_get_root(sde_kms));
+	if (!sde_crtc->debugfs_root)
+		return -ENOMEM;
+
+	/* don't error check these */
+	debugfs_create_file("status", 0444,
+			sde_crtc->debugfs_root,
+			sde_crtc, &debugfs_status_fops);
+	debugfs_create_file("state", 0644,
+			sde_crtc->debugfs_root,
+			&sde_crtc->base,
+			&sde_crtc_debugfs_state_fops);
+
+	return 0;
+}
+
+static void _sde_crtc_destroy_debugfs(struct drm_crtc *crtc)
+{
+	struct sde_crtc *sde_crtc;
+
+	if (!crtc)
+		return;
+	sde_crtc = to_sde_crtc(crtc);
+	debugfs_remove_recursive(sde_crtc->debugfs_root);
 }
 #else
-static void _sde_crtc_init_debugfs(struct sde_crtc *sde_crtc,
-		struct sde_kms *sde_kms)
+static int _sde_crtc_init_debugfs(struct drm_crtc *crtc)
 {
+	return 0;
 }
-#endif
+
+static void _sde_crtc_destroy_debugfs(struct drm_crtc *crtc)
+{
+	return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static int sde_crtc_late_register(struct drm_crtc *crtc)
+{
+	return _sde_crtc_init_debugfs(crtc);
+}
+
+static void sde_crtc_early_unregister(struct drm_crtc *crtc)
+{
+	_sde_crtc_destroy_debugfs(crtc);
+}
+
+static const struct drm_crtc_funcs sde_crtc_funcs = {
+	.set_config = drm_atomic_helper_set_config,
+	.destroy = sde_crtc_destroy,
+	.page_flip = drm_atomic_helper_page_flip,
+	.set_property = sde_crtc_set_property,
+	.atomic_set_property = sde_crtc_atomic_set_property,
+	.atomic_get_property = sde_crtc_atomic_get_property,
+	.reset = sde_crtc_reset,
+	.atomic_duplicate_state = sde_crtc_duplicate_state,
+	.atomic_destroy_state = sde_crtc_destroy_state,
+	.late_register = sde_crtc_late_register,
+	.early_unregister = sde_crtc_early_unregister,
+};
+
+static const struct drm_crtc_helper_funcs sde_crtc_helper_funcs = {
+	.mode_fixup = sde_crtc_mode_fixup,
+	.disable = sde_crtc_disable,
+	.enable = sde_crtc_enable,
+	.atomic_check = sde_crtc_atomic_check,
+	.atomic_begin = sde_crtc_atomic_begin,
+	.atomic_flush = sde_crtc_atomic_flush,
+};
 
 /* initialize crtc */
 struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_plane *plane)
@@ -1974,9 +2009,6 @@
 	mutex_init(&sde_crtc->crtc_lock);
 	sde_fence_init(&sde_crtc->output_fence, sde_crtc->name, crtc->base.id);
 
-	/* initialize debugfs support */
-	_sde_crtc_init_debugfs(sde_crtc, kms);
-
 	/* create CRTC properties */
 	msm_property_init(&sde_crtc->property_info, &crtc->base, dev,
 			priv->crtc_property, sde_crtc->property_data,
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index 27b1f25..a845f4d 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -183,7 +183,6 @@
 	mutex_unlock(&sde_enc->enc_lock);
 
 	drm_encoder_cleanup(drm_enc);
-	debugfs_remove_recursive(sde_enc->debugfs_root);
 	mutex_destroy(&sde_enc->enc_lock);
 
 	kfree(sde_enc);
@@ -446,11 +445,6 @@
 
 	SDE_EVT32(DRMID(drm_enc));
 
-	if (atomic_xchg(&sde_enc->frame_done_timeout, 0)) {
-		SDE_ERROR("enc%d timeout pending\n", drm_enc->base.id);
-		del_timer_sync(&sde_enc->frame_done_timer);
-	}
-
 	for (i = 0; i < sde_enc->num_phys_encs; i++) {
 		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
 
@@ -461,6 +455,12 @@
 		}
 	}
 
+	/* after phys waits for frame-done, should be no more frames pending */
+	if (atomic_xchg(&sde_enc->frame_done_timeout, 0)) {
+		SDE_ERROR("enc%d timeout pending\n", drm_enc->base.id);
+		del_timer_sync(&sde_enc->frame_done_timer);
+	}
+
 	if (sde_enc->cur_master && sde_enc->cur_master->ops.disable)
 		sde_enc->cur_master->ops.disable(sde_enc->cur_master);
 
@@ -472,17 +472,6 @@
 	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
 }
 
-static const struct drm_encoder_helper_funcs sde_encoder_helper_funcs = {
-	.mode_set = sde_encoder_virt_mode_set,
-	.disable = sde_encoder_virt_disable,
-	.enable = sde_encoder_virt_enable,
-	.atomic_check = sde_encoder_virt_atomic_check,
-};
-
-static const struct drm_encoder_funcs sde_encoder_funcs = {
-		.destroy = sde_encoder_destroy,
-};
-
 static enum sde_intf sde_encoder_get_intf(struct sde_mdss_cfg *catalog,
 		enum sde_intf_type type, u32 controller_id)
 {
@@ -978,6 +967,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_DEBUG_FS
 static int _sde_encoder_debugfs_status_open(struct inode *inode,
 		struct file *file)
 {
@@ -1086,9 +1076,12 @@
 	return len;
 }
 
-static void _sde_encoder_init_debugfs(struct drm_encoder *drm_enc,
-	struct sde_encoder_virt *sde_enc, struct sde_kms *sde_kms)
+static int _sde_encoder_init_debugfs(struct drm_encoder *drm_enc)
 {
+	struct sde_encoder_virt *sde_enc;
+	struct msm_drm_private *priv;
+	struct sde_kms *sde_kms;
+
 	static const struct file_operations debugfs_status_fops = {
 		.open =		_sde_encoder_debugfs_status_open,
 		.read =		seq_read,
@@ -1104,25 +1097,62 @@
 
 	char name[SDE_NAME_SIZE];
 
-	if (!drm_enc || !sde_enc || !sde_kms) {
+	if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
 		SDE_ERROR("invalid encoder or kms\n");
-		return;
+		return -EINVAL;
 	}
 
+	sde_enc = to_sde_encoder_virt(drm_enc);
+	priv = drm_enc->dev->dev_private;
+	sde_kms = to_sde_kms(priv->kms);
+
 	snprintf(name, SDE_NAME_SIZE, "encoder%u", drm_enc->base.id);
 
 	/* create overall sub-directory for the encoder */
 	sde_enc->debugfs_root = debugfs_create_dir(name,
 					sde_debugfs_get_root(sde_kms));
-	if (sde_enc->debugfs_root) {
-		/* don't error check these */
-		debugfs_create_file("status", 0644,
-			sde_enc->debugfs_root, sde_enc, &debugfs_status_fops);
+	if (!sde_enc->debugfs_root)
+		return -ENOMEM;
 
-		debugfs_create_file("misr_data", 0644,
-			sde_enc->debugfs_root, drm_enc, &debugfs_misr_fops);
+	/* don't error check these */
+	debugfs_create_file("status", 0644,
+		sde_enc->debugfs_root, sde_enc, &debugfs_status_fops);
 
-	}
+	debugfs_create_file("misr_data", 0644,
+		sde_enc->debugfs_root, drm_enc, &debugfs_misr_fops);
+
+	return 0;
+}
+
+static void _sde_encoder_destroy_debugfs(struct drm_encoder *drm_enc)
+{
+	struct sde_encoder_virt *sde_enc;
+
+	if (!drm_enc)
+		return;
+
+	sde_enc = to_sde_encoder_virt(drm_enc);
+	debugfs_remove_recursive(sde_enc->debugfs_root);
+}
+#else
+static int _sde_encoder_init_debugfs(struct drm_encoder *drm_enc)
+{
+	return 0;
+}
+
+static _sde_encoder_destroy_debugfs(struct drm_encoder *drm_enc)
+{
+}
+#endif
+
+static int sde_encoder_late_register(struct drm_encoder *encoder)
+{
+	return _sde_encoder_init_debugfs(encoder);
+}
+
+static void sde_encoder_early_unregister(struct drm_encoder *encoder)
+{
+	_sde_encoder_destroy_debugfs(encoder);
 }
 
 static int sde_encoder_virt_add_phys_encs(
@@ -1359,6 +1389,19 @@
 			SDE_ENCODER_FRAME_EVENT_ERROR);
 }
 
+static const struct drm_encoder_helper_funcs sde_encoder_helper_funcs = {
+	.mode_set = sde_encoder_virt_mode_set,
+	.disable = sde_encoder_virt_disable,
+	.enable = sde_encoder_virt_enable,
+	.atomic_check = sde_encoder_virt_atomic_check,
+};
+
+static const struct drm_encoder_funcs sde_encoder_funcs = {
+		.destroy = sde_encoder_destroy,
+		.late_register = sde_encoder_late_register,
+		.early_unregister = sde_encoder_early_unregister,
+};
+
 struct drm_encoder *sde_encoder_init(
 		struct drm_device *dev,
 		struct msm_display_info *disp_info)
@@ -1393,8 +1436,6 @@
 	setup_timer(&sde_enc->frame_done_timer, sde_encoder_frame_done_timeout,
 			(unsigned long) sde_enc);
 
-	_sde_encoder_init_debugfs(drm_enc, sde_enc, sde_kms);
-
 	snprintf(name, SDE_NAME_SIZE, "rsc_enc%u", drm_enc->base.id);
 	sde_enc->rsc_client = sde_rsc_client_create(SDE_RSC_INDEX, name,
 					disp_info->is_primary);
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
index d8f096c..22cec11 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
@@ -89,6 +89,7 @@
 /**
  * struct sde_encoder_phys_ops - Interface the physical encoders provide to
  *	the containing virtual encoder.
+ * @late_register:		DRM Call. Add Userspace interfaces, debugfs.
  * @is_master:			Whether this phys_enc is the current master
  *				encoder. Can be switched at enable time. Based
  *				on split_role and current mode (CMD/VID).
@@ -117,6 +118,8 @@
  */
 
 struct sde_encoder_phys_ops {
+	int (*late_register)(struct sde_encoder_phys *encoder,
+			struct dentry *debugfs_root);
 	bool (*is_master)(struct sde_encoder_phys *encoder);
 	bool (*mode_fixup)(struct sde_encoder_phys *encoder,
 			const struct drm_display_mode *mode,
@@ -281,8 +284,6 @@
  * @wb_dev:		Pointer to writeback device
  * @start_time:		Start time of writeback latest request
  * @end_time:		End time of writeback latest request
- * @wb_name:		Name of this writeback device
- * @debugfs_root:	Root entry of writeback debugfs
  */
 struct sde_encoder_phys_wb {
 	struct sde_encoder_phys base;
@@ -302,10 +303,6 @@
 	struct sde_wb_device *wb_dev;
 	ktime_t start_time;
 	ktime_t end_time;
-#ifdef CONFIG_DEBUG_FS
-	char wb_name[SDE_ENCODER_NAME_MAX];
-	struct dentry *debugfs_root;
-#endif
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
index 13fe9bd..75eddc0 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
@@ -918,69 +918,45 @@
 #ifdef CONFIG_DEBUG_FS
 /**
  * sde_encoder_phys_wb_init_debugfs - initialize writeback encoder debugfs
- * @phys_enc:	Pointer to physical encoder
- * @sde_kms:	Pointer to SDE KMS object
+ * @phys_enc:		Pointer to physical encoder
+ * @debugfs_root:	Pointer to virtual encoder's debugfs_root dir
  */
 static int sde_encoder_phys_wb_init_debugfs(
-		struct sde_encoder_phys *phys_enc, struct sde_kms *kms)
+		struct sde_encoder_phys *phys_enc, struct dentry *debugfs_root)
 {
 	struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc);
 
-	if (!phys_enc || !kms || !wb_enc->hw_wb)
+	if (!phys_enc || !wb_enc->hw_wb || !debugfs_root)
 		return -EINVAL;
 
-	snprintf(wb_enc->wb_name, ARRAY_SIZE(wb_enc->wb_name), "encoder_wb%d",
-			wb_enc->hw_wb->idx - WB_0);
-
-	wb_enc->debugfs_root =
-		debugfs_create_dir(wb_enc->wb_name,
-				sde_debugfs_get_root(kms));
-	if (!wb_enc->debugfs_root) {
-		SDE_ERROR("failed to create debugfs\n");
-		return -ENOMEM;
-	}
-
 	if (!debugfs_create_u32("wbdone_timeout", 0644,
-			wb_enc->debugfs_root, &wb_enc->wbdone_timeout)) {
+			debugfs_root, &wb_enc->wbdone_timeout)) {
 		SDE_ERROR("failed to create debugfs/wbdone_timeout\n");
 		return -ENOMEM;
 	}
 
 	if (!debugfs_create_u32("bypass_irqreg", 0644,
-			wb_enc->debugfs_root, &wb_enc->bypass_irqreg)) {
+			debugfs_root, &wb_enc->bypass_irqreg)) {
 		SDE_ERROR("failed to create debugfs/bypass_irqreg\n");
 		return -ENOMEM;
 	}
 
 	return 0;
 }
-
-/**
- * sde_encoder_phys_wb_destroy_debugfs - destroy writeback encoder debugfs
- * @phys_enc:	Pointer to physical encoder
- */
-static void sde_encoder_phys_wb_destroy_debugfs(
-		struct sde_encoder_phys *phys_enc)
-{
-	struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc);
-
-	if (!phys_enc)
-		return;
-
-	debugfs_remove_recursive(wb_enc->debugfs_root);
-}
 #else
 static int sde_encoder_phys_wb_init_debugfs(
-		struct sde_encoder_phys *phys_enc, struct sde_kms *kms)
+		struct sde_encoder_phys *phys_enc, struct dentry *debugfs_root)
 {
 	return 0;
 }
-static void sde_encoder_phys_wb_destroy_debugfs(
-		struct sde_encoder_phys *phys_enc)
-{
-}
 #endif
 
+static int sde_encoder_phys_wb_late_register(struct sde_encoder_phys *phys_enc,
+		struct dentry *debugfs_root)
+{
+	return sde_encoder_phys_wb_init_debugfs(phys_enc, debugfs_root);
+}
+
 /**
  * sde_encoder_phys_wb_destroy - destroy writeback encoder
  * @phys_enc:	Pointer to physical encoder
@@ -995,8 +971,6 @@
 	if (!phys_enc)
 		return;
 
-	sde_encoder_phys_wb_destroy_debugfs(phys_enc);
-
 	kfree(wb_enc);
 }
 
@@ -1006,6 +980,7 @@
  */
 static void sde_encoder_phys_wb_init_ops(struct sde_encoder_phys_ops *ops)
 {
+	ops->late_register = sde_encoder_phys_wb_late_register;
 	ops->is_master = sde_encoder_phys_wb_is_master;
 	ops->mode_set = sde_encoder_phys_wb_mode_set;
 	ops->enable = sde_encoder_phys_wb_enable;
@@ -1103,18 +1078,11 @@
 	phys_enc->enc_spinlock = p->enc_spinlock;
 	INIT_LIST_HEAD(&wb_enc->irq_cb.list);
 
-	ret = sde_encoder_phys_wb_init_debugfs(phys_enc, p->sde_kms);
-	if (ret) {
-		SDE_ERROR("failed to init debugfs %d\n", ret);
-		goto fail_debugfs_init;
-	}
-
 	SDE_DEBUG("Created sde_encoder_phys_wb for wb %d\n",
 			wb_enc->hw_wb->idx - WB_0);
 
 	return phys_enc;
 
-fail_debugfs_init:
 fail_wb_init:
 fail_wb_check:
 fail_mdp_init:
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 39b8863..1a177d1 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -273,35 +273,35 @@
 
 void *sde_debugfs_get_root(struct sde_kms *sde_kms)
 {
-	return sde_kms ? sde_kms->debugfs_root : 0;
+	return sde_kms ? sde_kms->dev->primary->debugfs_root : 0;
 }
 
 static int _sde_debugfs_init(struct sde_kms *sde_kms)
 {
 	void *p;
+	int rc;
+	void *debugfs_root;
 
 	p = sde_hw_util_get_log_mask_ptr();
 
 	if (!sde_kms || !p)
 		return -EINVAL;
 
-	if (sde_kms->dev && sde_kms->dev->primary)
-		sde_kms->debugfs_root = sde_kms->dev->primary->debugfs_root;
-	else
-		sde_kms->debugfs_root = debugfs_create_dir(SDE_DEBUGFS_DIR, 0);
+	debugfs_root = sde_debugfs_get_root(sde_kms);
+	if (!debugfs_root)
+		return -EINVAL;
 
 	/* allow debugfs_root to be NULL */
-	debugfs_create_x32(SDE_DEBUGFS_HWMASKNAME,
-			0644, sde_kms->debugfs_root, p);
+	debugfs_create_x32(SDE_DEBUGFS_HWMASKNAME, 0644, debugfs_root, p);
 
-	/* create common folder for debug information */
-	sde_kms->debugfs_debug = debugfs_create_dir("debug",
-			sde_kms->debugfs_root);
-	if (!sde_kms->debugfs_debug)
-		SDE_ERROR("failed to create debugfs debug directory\n");
+	sde_debugfs_danger_init(sde_kms, debugfs_root);
+	sde_debugfs_vbif_init(sde_kms, debugfs_root);
 
-	sde_debugfs_danger_init(sde_kms, sde_kms->debugfs_debug);
-	sde_debugfs_vbif_init(sde_kms, sde_kms->debugfs_debug);
+	rc = sde_core_perf_debugfs_init(&sde_kms->perf, debugfs_root);
+	if (rc) {
+		SDE_ERROR("failed to init perf %d\n", rc);
+		return rc;
+	}
 
 	return 0;
 }
@@ -312,13 +312,19 @@
 	if (sde_kms) {
 		sde_debugfs_vbif_destroy(sde_kms);
 		sde_debugfs_danger_destroy(sde_kms);
-		debugfs_remove_recursive(sde_kms->debugfs_debug);
-		sde_kms->debugfs_debug = 0;
-		debugfs_remove_recursive(sde_kms->debugfs_root);
-		sde_kms->debugfs_root = 0;
 	}
 }
 #else
+static int _sde_debugfs_init(struct sde_kms *sde_kms)
+{
+	return 0;
+}
+
+static void _sde_debugfs_destroy(struct sde_kms *sde_kms)
+{
+	return 0;
+}
+
 static void sde_debugfs_danger_destroy(struct sde_kms *sde_kms,
 		struct dentry *parent)
 {
@@ -818,6 +824,7 @@
 {
 	struct sde_kms *sde_kms = to_sde_kms(kms);
 	struct drm_device *dev;
+	int rc;
 
 	if (!sde_kms || !sde_kms->dev || !sde_kms->dev->dev) {
 		SDE_ERROR("invalid sde_kms\n");
@@ -826,7 +833,11 @@
 
 	dev = sde_kms->dev;
 
-	return 0;
+	rc = _sde_debugfs_init(sde_kms);
+	if (rc)
+		SDE_ERROR("sde_debugfs init failed: %d\n", rc);
+
+	return rc;
 }
 
 static long sde_kms_round_pixclk(struct msm_kms *kms, unsigned long rate,
@@ -1218,19 +1229,8 @@
 		goto power_error;
 	}
 
-	/*
-	 * NOTE: Calling sde_debugfs_init here so that the drm_minor device for
-	 *       'primary' is already created.
-	 */
-	rc = _sde_debugfs_init(sde_kms);
-	if (rc) {
-		SDE_ERROR("sde_debugfs init failed: %d\n", rc);
-		goto power_error;
-	}
-
 	rc = sde_core_perf_init(&sde_kms->perf, dev, sde_kms->catalog,
-			&priv->phandle, priv->pclient, "core_clk_src",
-			sde_kms->debugfs_debug);
+			&priv->phandle, priv->pclient, "core_clk_src");
 	if (rc) {
 		SDE_ERROR("failed to init perf %d\n", rc);
 		goto perf_err;
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h
index bf1c12f..1acdf00 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.h
+++ b/drivers/gpu/drm/msm/sde/sde_kms.h
@@ -126,8 +126,6 @@
 	struct sde_power_client *core_client;
 
 	/* directory entry for debugfs */
-	void *debugfs_root;
-	struct dentry *debugfs_debug;
 	struct dentry *debugfs_danger;
 	struct dentry *debugfs_vbif;
 
@@ -235,7 +233,7 @@
 		void *parent, struct sde_debugfs_regset32 *regset);
 
 /**
- * sde_debugfs_get_root - Return root directory entry for SDE's debugfs
+ * sde_debugfs_get_root - Return root directory entry for KMS's debugfs
  *
  * The return value should be passed as the 'parent' argument to subsequent
  * debugfs create calls.
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index 9dc13a2..908926c 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -2269,8 +2269,6 @@
 	if (psde) {
 		_sde_plane_set_qos_ctrl(plane, false, SDE_PLANE_QOS_PANIC_CTRL);
 
-		debugfs_remove_recursive(psde->debugfs_root);
-
 		if (psde->blob_info)
 			drm_property_unreference_blob(psde->blob_info);
 		msm_property_destroy(&psde->property_info);
@@ -2399,35 +2397,7 @@
 	plane->state = &pstate->base;
 }
 
-static const struct drm_plane_funcs sde_plane_funcs = {
-		.update_plane = drm_atomic_helper_update_plane,
-		.disable_plane = drm_atomic_helper_disable_plane,
-		.destroy = sde_plane_destroy,
-		.set_property = sde_plane_set_property,
-		.atomic_set_property = sde_plane_atomic_set_property,
-		.atomic_get_property = sde_plane_atomic_get_property,
-		.reset = sde_plane_reset,
-		.atomic_duplicate_state = sde_plane_duplicate_state,
-		.atomic_destroy_state = sde_plane_destroy_state,
-};
-
-static const struct drm_plane_helper_funcs sde_plane_helper_funcs = {
-		.prepare_fb = sde_plane_prepare_fb,
-		.cleanup_fb = sde_plane_cleanup_fb,
-		.atomic_check = sde_plane_atomic_check,
-		.atomic_update = sde_plane_atomic_update,
-};
-
-enum sde_sspp sde_plane_pipe(struct drm_plane *plane)
-{
-	return plane ? to_sde_plane(plane)->pipe : SSPP_NONE;
-}
-
-bool is_sde_plane_virtual(struct drm_plane *plane)
-{
-	return plane ? to_sde_plane(plane)->is_virtual : false;
-}
-
+#ifdef CONFIG_DEBUG_FS
 static ssize_t _sde_plane_danger_read(struct file *file,
 			char __user *buff, size_t count, loff_t *ppos)
 {
@@ -2520,72 +2490,161 @@
 	.write = _sde_plane_danger_write,
 };
 
-static void _sde_plane_init_debugfs(struct sde_plane *psde, struct sde_kms *kms)
+static int _sde_plane_init_debugfs(struct drm_plane *plane)
 {
+	struct sde_plane *psde;
+	struct sde_kms *kms;
+	struct msm_drm_private *priv;
 	const struct sde_sspp_sub_blks *sblk = 0;
 	const struct sde_sspp_cfg *cfg = 0;
 
+	if (!plane || !plane->dev) {
+		SDE_ERROR("invalid arguments\n");
+		return -EINVAL;
+	}
+
+	priv = plane->dev->dev_private;
+	if (!priv || !priv->kms) {
+		SDE_ERROR("invalid KMS reference\n");
+		return -EINVAL;
+	}
+
+	kms = to_sde_kms(priv->kms);
+	psde = to_sde_plane(plane);
+
 	if (psde && psde->pipe_hw)
 		cfg = psde->pipe_hw->cap;
 	if (cfg)
 		sblk = cfg->sblk;
 
-	if (kms && sblk) {
-		/* create overall sub-directory for the pipe */
-		psde->debugfs_root =
-			debugfs_create_dir(psde->pipe_name,
-					sde_debugfs_get_root(kms));
-		if (psde->debugfs_root) {
-			/* don't error check these */
-			debugfs_create_x32("features", 0644,
-					psde->debugfs_root, &psde->features);
+	if (!sblk)
+		return 0;
 
-			/* add register dump support */
-			sde_debugfs_setup_regset32(&psde->debugfs_src,
-					sblk->src_blk.base + cfg->base,
-					sblk->src_blk.len,
-					kms);
-			sde_debugfs_create_regset32("src_blk", 0444,
-					psde->debugfs_root, &psde->debugfs_src);
+	/* create overall sub-directory for the pipe */
+	psde->debugfs_root =
+		debugfs_create_dir(psde->pipe_name,
+				sde_debugfs_get_root(kms));
 
-			sde_debugfs_setup_regset32(&psde->debugfs_scaler,
-					sblk->scaler_blk.base + cfg->base,
-					sblk->scaler_blk.len,
-					kms);
-			sde_debugfs_create_regset32("scaler_blk", 0444,
-					psde->debugfs_root,
-					&psde->debugfs_scaler);
+	if (!psde->debugfs_root)
+		return -ENOMEM;
 
-			sde_debugfs_setup_regset32(&psde->debugfs_csc,
-					sblk->csc_blk.base + cfg->base,
-					sblk->csc_blk.len,
-					kms);
-			sde_debugfs_create_regset32("csc_blk", 0444,
-					psde->debugfs_root, &psde->debugfs_csc);
+	/* don't error check these */
+	debugfs_create_x32("features", 0644,
+			psde->debugfs_root, &psde->features);
 
-			debugfs_create_u32("xin_id",
-					0444,
-					psde->debugfs_root,
-					(u32 *) &cfg->xin_id);
-			debugfs_create_u32("clk_ctrl",
-					0444,
-					psde->debugfs_root,
-					(u32 *) &cfg->clk_ctrl);
-			debugfs_create_x32("creq_vblank",
-					0644,
-					psde->debugfs_root,
-					(u32 *) &sblk->creq_vblank);
-			debugfs_create_x32("danger_vblank",
-					0644,
-					psde->debugfs_root,
-					(u32 *) &sblk->danger_vblank);
+	/* add register dump support */
+	sde_debugfs_setup_regset32(&psde->debugfs_src,
+			sblk->src_blk.base + cfg->base,
+			sblk->src_blk.len,
+			kms);
+	sde_debugfs_create_regset32("src_blk", 0444,
+			psde->debugfs_root, &psde->debugfs_src);
 
-			debugfs_create_file("disable_danger",
-					0644,
-					psde->debugfs_root,
-					kms, &sde_plane_danger_enable);
-		}
+	if (cfg->features & BIT(SDE_SSPP_SCALER_QSEED3) ||
+			cfg->features & BIT(SDE_SSPP_SCALER_QSEED2)) {
+		sde_debugfs_setup_regset32(&psde->debugfs_scaler,
+				sblk->scaler_blk.base + cfg->base,
+				sblk->scaler_blk.len,
+				kms);
+		sde_debugfs_create_regset32("scaler_blk", 0444,
+				psde->debugfs_root,
+				&psde->debugfs_scaler);
 	}
+
+	if (cfg->features & BIT(SDE_SSPP_CSC) ||
+			cfg->features & BIT(SDE_SSPP_CSC_10BIT)) {
+		sde_debugfs_setup_regset32(&psde->debugfs_csc,
+				sblk->csc_blk.base + cfg->base,
+				sblk->csc_blk.len,
+				kms);
+		sde_debugfs_create_regset32("csc_blk", 0444,
+				psde->debugfs_root, &psde->debugfs_csc);
+	}
+
+	debugfs_create_u32("xin_id",
+			0444,
+			psde->debugfs_root,
+			(u32 *) &cfg->xin_id);
+	debugfs_create_u32("clk_ctrl",
+			0444,
+			psde->debugfs_root,
+			(u32 *) &cfg->clk_ctrl);
+	debugfs_create_x32("creq_vblank",
+			0644,
+			psde->debugfs_root,
+			(u32 *) &sblk->creq_vblank);
+	debugfs_create_x32("danger_vblank",
+			0644,
+			psde->debugfs_root,
+			(u32 *) &sblk->danger_vblank);
+
+	debugfs_create_file("disable_danger",
+			0644,
+			psde->debugfs_root,
+			kms, &sde_plane_danger_enable);
+
+	return 0;
+}
+
+static void _sde_plane_destroy_debugfs(struct drm_plane *plane)
+{
+	struct sde_plane *psde;
+
+	if (!plane)
+		return;
+	psde = to_sde_plane(plane);
+
+	debugfs_remove_recursive(psde->debugfs_root);
+}
+#else
+static int _sde_plane_init_debugfs(struct drm_plane *plane)
+{
+	return 0;
+}
+static void _sde_plane_destroy_debugfs(struct drm_plane *plane)
+{
+}
+#endif
+
+static int sde_plane_late_register(struct drm_plane *plane)
+{
+	return _sde_plane_init_debugfs(plane);
+}
+
+static void sde_plane_early_unregister(struct drm_plane *plane)
+{
+	_sde_plane_destroy_debugfs(plane);
+}
+
+static const struct drm_plane_funcs sde_plane_funcs = {
+		.update_plane = drm_atomic_helper_update_plane,
+		.disable_plane = drm_atomic_helper_disable_plane,
+		.destroy = sde_plane_destroy,
+		.set_property = sde_plane_set_property,
+		.atomic_set_property = sde_plane_atomic_set_property,
+		.atomic_get_property = sde_plane_atomic_get_property,
+		.reset = sde_plane_reset,
+		.atomic_duplicate_state = sde_plane_duplicate_state,
+		.atomic_destroy_state = sde_plane_destroy_state,
+		.late_register = sde_plane_late_register,
+		.early_unregister = sde_plane_early_unregister,
+};
+
+static const struct drm_plane_helper_funcs sde_plane_helper_funcs = {
+		.prepare_fb = sde_plane_prepare_fb,
+		.cleanup_fb = sde_plane_cleanup_fb,
+		.atomic_check = sde_plane_atomic_check,
+		.atomic_update = sde_plane_atomic_update,
+};
+
+enum sde_sspp sde_plane_pipe(struct drm_plane *plane)
+{
+	return plane ? to_sde_plane(plane)->pipe : SSPP_NONE;
+}
+
+bool is_sde_plane_virtual(struct drm_plane *plane)
+{
+	return plane ? to_sde_plane(plane)->is_virtual : false;
 }
 
 /* initialize plane */
@@ -2709,8 +2768,6 @@
 
 	mutex_init(&psde->lock);
 
-	_sde_plane_init_debugfs(psde, kms);
-
 	SDE_DEBUG("%s created for pipe %u\n", psde->pipe_name, pipe);
 	return plane;
 
diff --git a/drivers/gpu/drm/msm/sde/sde_vbif.c b/drivers/gpu/drm/msm/sde/sde_vbif.c
index fb6d9da..c0c8248 100644
--- a/drivers/gpu/drm/msm/sde/sde_vbif.c
+++ b/drivers/gpu/drm/msm/sde/sde_vbif.c
@@ -223,8 +223,7 @@
 	struct dentry *debugfs_vbif;
 	int i, j;
 
-	sde_kms->debugfs_vbif = debugfs_create_dir("vbif",
-			sde_kms->debugfs_root);
+	sde_kms->debugfs_vbif = debugfs_create_dir("vbif", debugfs_root);
 	if (!sde_kms->debugfs_vbif) {
 		SDE_ERROR("failed to create vbif debugfs\n");
 		return -EINVAL;
diff --git a/drivers/gpu/drm/msm/sde_dbg.c b/drivers/gpu/drm/msm/sde_dbg.c
index 4c7f3d2..4c1260b 100644
--- a/drivers/gpu/drm/msm/sde_dbg.c
+++ b/drivers/gpu/drm/msm/sde_dbg.c
@@ -2554,123 +2554,6 @@
 	.write = sde_evtlog_dump_write,
 };
 
-void sde_dbg_init_dbg_buses(u32 hwversion)
-{
-	static struct sde_dbg_base *dbg = &sde_dbg_base;
-	char debug_name[80] = "";
-
-	memset(&dbg->dbgbus_sde, 0, sizeof(dbg->dbgbus_sde));
-	memset(&dbg->dbgbus_vbif_rt, 0, sizeof(dbg->dbgbus_vbif_rt));
-
-	switch (hwversion) {
-	case SDE_HW_VER_300:
-	case SDE_HW_VER_301:
-		dbg->dbgbus_sde.entries = dbg_bus_sde_8998;
-		dbg->dbgbus_sde.cmn.entries_size = ARRAY_SIZE(dbg_bus_sde_8998);
-		dbg->dbgbus_sde.cmn.flags = DBGBUS_FLAGS_DSPP;
-
-		dbg->dbgbus_vbif_rt.entries = vbif_dbg_bus_msm8998;
-		dbg->dbgbus_vbif_rt.cmn.entries_size =
-				ARRAY_SIZE(vbif_dbg_bus_msm8998);
-		break;
-
-	case SDE_HW_VER_400:
-		dbg->dbgbus_sde.entries = dbg_bus_sde_sdm845;
-		dbg->dbgbus_sde.cmn.entries_size =
-				ARRAY_SIZE(dbg_bus_sde_sdm845);
-		dbg->dbgbus_sde.cmn.flags = DBGBUS_FLAGS_DSPP;
-
-		/* vbif is unchanged vs 8998 */
-		dbg->dbgbus_vbif_rt.entries = vbif_dbg_bus_msm8998;
-		dbg->dbgbus_vbif_rt.cmn.entries_size =
-				ARRAY_SIZE(vbif_dbg_bus_msm8998);
-		break;
-	default:
-		pr_err("unsupported chipset id %u\n", hwversion);
-		break;
-	}
-
-	if (dbg->dbgbus_sde.entries) {
-		dbg->dbgbus_sde.cmn.name = DBGBUS_NAME_SDE;
-		snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
-				dbg->dbgbus_sde.cmn.name);
-		dbg->dbgbus_sde.cmn.enable_mask = DEFAULT_DBGBUS_SDE;
-		debugfs_create_u32(debug_name, 0644, dbg->root,
-				&dbg->dbgbus_sde.cmn.enable_mask);
-	}
-
-	if (dbg->dbgbus_vbif_rt.entries) {
-		dbg->dbgbus_vbif_rt.cmn.name = DBGBUS_NAME_VBIF_RT;
-		snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
-				dbg->dbgbus_vbif_rt.cmn.name);
-		dbg->dbgbus_vbif_rt.cmn.enable_mask = DEFAULT_DBGBUS_VBIFRT;
-		debugfs_create_u32(debug_name, 0644, dbg->root,
-				&dbg->dbgbus_vbif_rt.cmn.enable_mask);
-	}
-}
-
-int sde_dbg_init(struct dentry *debugfs_root, struct device *dev,
-		struct sde_dbg_power_ctrl *power_ctrl)
-{
-	int i;
-
-	INIT_LIST_HEAD(&sde_dbg_base.reg_base_list);
-	sde_dbg_base.dev = dev;
-	sde_dbg_base.power_ctrl = *power_ctrl;
-
-
-	sde_dbg_base.evtlog = sde_evtlog_init();
-	if (IS_ERR_OR_NULL(sde_dbg_base.evtlog))
-		return PTR_ERR(sde_dbg_base.evtlog);
-
-	sde_dbg_base_evtlog = sde_dbg_base.evtlog;
-
-	sde_dbg_base.root = debugfs_create_dir("evt_dbg", debugfs_root);
-	if (IS_ERR_OR_NULL(sde_dbg_base.root)) {
-		pr_err("debugfs_create_dir fail, error %ld\n",
-		       PTR_ERR(sde_dbg_base.root));
-		sde_dbg_base.root = NULL;
-		return -ENODEV;
-	}
-
-	INIT_WORK(&sde_dbg_base.dump_work, _sde_dump_work);
-	sde_dbg_base.work_panic = false;
-
-	for (i = 0; i < SDE_EVTLOG_ENTRY; i++)
-		sde_dbg_base.evtlog->logs[i].counter = i;
-
-	debugfs_create_file("dump", 0644, sde_dbg_base.root, NULL,
-						&sde_evtlog_fops);
-	debugfs_create_u32("enable", 0644, sde_dbg_base.root,
-			&(sde_dbg_base.evtlog->enable));
-	debugfs_create_u32("panic", 0644, sde_dbg_base.root,
-			&sde_dbg_base.panic_on_err);
-	debugfs_create_u32("reg_dump", 0644, sde_dbg_base.root,
-			&sde_dbg_base.enable_reg_dump);
-
-	sde_dbg_base.panic_on_err = DEFAULT_PANIC;
-	sde_dbg_base.enable_reg_dump = DEFAULT_REGDUMP;
-
-	pr_info("evtlog_status: enable:%d, panic:%d, dump:%d\n",
-		sde_dbg_base.evtlog->enable, sde_dbg_base.panic_on_err,
-		sde_dbg_base.enable_reg_dump);
-
-	return 0;
-}
-
-/**
- * sde_dbg_destroy - destroy sde debug facilities
- */
-void sde_dbg_destroy(void)
-{
-	debugfs_remove_recursive(sde_dbg_base.root);
-	sde_dbg_base.root = 0;
-
-	sde_dbg_base_evtlog = NULL;
-	sde_evtlog_destroy(sde_dbg_base.evtlog);
-	sde_dbg_base.evtlog = NULL;
-}
-
 /**
  * sde_dbg_reg_base_release - release allocated reg dump file private data
  * @inode: debugfs inode
@@ -2894,45 +2777,173 @@
 	.write = sde_dbg_reg_base_reg_write,
 };
 
+int sde_dbg_debugfs_register(struct dentry *debugfs_root)
+{
+	static struct sde_dbg_base *dbg = &sde_dbg_base;
+	struct sde_dbg_reg_base *blk_base;
+	char debug_name[80] = "";
+
+	sde_dbg_base.root = debugfs_create_dir("evt_dbg", debugfs_root);
+	if (IS_ERR_OR_NULL(sde_dbg_base.root)) {
+		pr_err("debugfs_create_dir fail, error %ld\n",
+		       PTR_ERR(sde_dbg_base.root));
+		sde_dbg_base.root = NULL;
+		return -ENODEV;
+	}
+
+	debugfs_create_file("dump", 0644, sde_dbg_base.root, NULL,
+			&sde_evtlog_fops);
+	debugfs_create_u32("enable", 0644, sde_dbg_base.root,
+			&(sde_dbg_base.evtlog->enable));
+	debugfs_create_u32("panic", 0644, sde_dbg_base.root,
+			&sde_dbg_base.panic_on_err);
+	debugfs_create_u32("reg_dump", 0644, sde_dbg_base.root,
+			&sde_dbg_base.enable_reg_dump);
+
+
+	if (dbg->dbgbus_sde.entries) {
+		dbg->dbgbus_sde.cmn.name = DBGBUS_NAME_SDE;
+		snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
+				dbg->dbgbus_sde.cmn.name);
+		dbg->dbgbus_sde.cmn.enable_mask = DEFAULT_DBGBUS_SDE;
+		debugfs_create_u32(debug_name, 0644, dbg->root,
+				&dbg->dbgbus_sde.cmn.enable_mask);
+	}
+
+	if (dbg->dbgbus_vbif_rt.entries) {
+		dbg->dbgbus_vbif_rt.cmn.name = DBGBUS_NAME_VBIF_RT;
+		snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
+				dbg->dbgbus_vbif_rt.cmn.name);
+		dbg->dbgbus_vbif_rt.cmn.enable_mask = DEFAULT_DBGBUS_VBIFRT;
+		debugfs_create_u32(debug_name, 0644, dbg->root,
+				&dbg->dbgbus_vbif_rt.cmn.enable_mask);
+	}
+
+	list_for_each_entry(blk_base, &dbg->reg_base_list, reg_base_head) {
+		snprintf(debug_name, sizeof(debug_name), "%s_off",
+				blk_base->name);
+		debugfs_create_file(debug_name, 0644, dbg->root, blk_base,
+				&sde_off_fops);
+
+		snprintf(debug_name, sizeof(debug_name), "%s_reg",
+				blk_base->name);
+		debugfs_create_file(debug_name, 0644, dbg->root, blk_base,
+				&sde_reg_fops);
+	}
+
+	return 0;
+}
+
+#if defined(CONFIG_DEBUG_FS)
+static void _sde_dbg_debugfs_destroy(void)
+{
+	debugfs_remove_recursive(sde_dbg_base.root);
+	sde_dbg_base.root = 0;
+}
+#else
+static void _sde_dbg_debugfs_destroy(void)
+{
+}
+#endif
+
+void sde_dbg_init_dbg_buses(u32 hwversion)
+{
+	static struct sde_dbg_base *dbg = &sde_dbg_base;
+
+	memset(&dbg->dbgbus_sde, 0, sizeof(dbg->dbgbus_sde));
+	memset(&dbg->dbgbus_vbif_rt, 0, sizeof(dbg->dbgbus_vbif_rt));
+
+	switch (hwversion) {
+	case SDE_HW_VER_300:
+	case SDE_HW_VER_301:
+		dbg->dbgbus_sde.entries = dbg_bus_sde_8998;
+		dbg->dbgbus_sde.cmn.entries_size = ARRAY_SIZE(dbg_bus_sde_8998);
+		dbg->dbgbus_sde.cmn.flags = DBGBUS_FLAGS_DSPP;
+
+		dbg->dbgbus_vbif_rt.entries = vbif_dbg_bus_msm8998;
+		dbg->dbgbus_vbif_rt.cmn.entries_size =
+				ARRAY_SIZE(vbif_dbg_bus_msm8998);
+		break;
+
+	case SDE_HW_VER_400:
+		dbg->dbgbus_sde.entries = dbg_bus_sde_sdm845;
+		dbg->dbgbus_sde.cmn.entries_size =
+				ARRAY_SIZE(dbg_bus_sde_sdm845);
+		dbg->dbgbus_sde.cmn.flags = DBGBUS_FLAGS_DSPP;
+
+		/* vbif is unchanged vs 8998 */
+		dbg->dbgbus_vbif_rt.entries = vbif_dbg_bus_msm8998;
+		dbg->dbgbus_vbif_rt.cmn.entries_size =
+				ARRAY_SIZE(vbif_dbg_bus_msm8998);
+		break;
+	default:
+		pr_err("unsupported chipset id %u\n", hwversion);
+		break;
+	}
+}
+
+int sde_dbg_init(struct device *dev, struct sde_dbg_power_ctrl *power_ctrl)
+{
+	if (!dev || !power_ctrl) {
+		pr_err("invalid params\n");
+		return -EINVAL;
+	}
+
+	INIT_LIST_HEAD(&sde_dbg_base.reg_base_list);
+	sde_dbg_base.dev = dev;
+	sde_dbg_base.power_ctrl = *power_ctrl;
+
+	sde_dbg_base.evtlog = sde_evtlog_init();
+	if (IS_ERR_OR_NULL(sde_dbg_base.evtlog))
+		return PTR_ERR(sde_dbg_base.evtlog);
+
+	sde_dbg_base_evtlog = sde_dbg_base.evtlog;
+
+	INIT_WORK(&sde_dbg_base.dump_work, _sde_dump_work);
+	sde_dbg_base.work_panic = false;
+	sde_dbg_base.panic_on_err = DEFAULT_PANIC;
+	sde_dbg_base.enable_reg_dump = DEFAULT_REGDUMP;
+
+	pr_info("evtlog_status: enable:%d, panic:%d, dump:%d\n",
+		sde_dbg_base.evtlog->enable, sde_dbg_base.panic_on_err,
+		sde_dbg_base.enable_reg_dump);
+
+	return 0;
+}
+
+/**
+ * sde_dbg_destroy - destroy sde debug facilities
+ */
+void sde_dbg_destroy(void)
+{
+	_sde_dbg_debugfs_destroy();
+	sde_dbg_base_evtlog = NULL;
+	sde_evtlog_destroy(sde_dbg_base.evtlog);
+	sde_dbg_base.evtlog = NULL;
+}
+
 int sde_dbg_reg_register_base(const char *name, void __iomem *base,
 		size_t max_offset)
 {
 	struct sde_dbg_base *dbg_base = &sde_dbg_base;
 	struct sde_dbg_reg_base *reg_base;
-	struct dentry *ent_off, *ent_reg;
-	char dn[80] = "";
-	int prefix_len = 0;
+
+	if (!name || !strlen(name)) {
+		pr_err("no debug name provided\n");
+		return -EINVAL;
+	}
 
 	reg_base = kzalloc(sizeof(*reg_base), GFP_KERNEL);
 	if (!reg_base)
 		return -ENOMEM;
 
-	if (name)
-		strlcpy(reg_base->name, name, sizeof(reg_base->name));
+	strlcpy(reg_base->name, name, sizeof(reg_base->name));
 	reg_base->base = base;
 	reg_base->max_offset = max_offset;
 	reg_base->off = 0;
 	reg_base->cnt = DEFAULT_BASE_REG_CNT;
 	reg_base->reg_dump = NULL;
 
-	if (name)
-		prefix_len = snprintf(dn, sizeof(dn), "%s_", name);
-	strlcpy(dn + prefix_len, "off", sizeof(dn) - prefix_len);
-	ent_off = debugfs_create_file(dn, 0644, dbg_base->root, reg_base,
-			&sde_off_fops);
-	if (IS_ERR_OR_NULL(ent_off)) {
-		pr_err("debugfs_create_file: offset fail\n");
-		goto off_fail;
-	}
-
-	strlcpy(dn + prefix_len, "reg", sizeof(dn) - prefix_len);
-	ent_reg = debugfs_create_file(dn, 0644, dbg_base->root, reg_base,
-			&sde_reg_fops);
-	if (IS_ERR_OR_NULL(ent_reg)) {
-		pr_err("debugfs_create_file: reg fail\n");
-		goto reg_fail;
-	}
-
 	/* Initialize list to make sure check for null list will be valid */
 	INIT_LIST_HEAD(&reg_base->sub_range_list);
 
@@ -2942,11 +2953,6 @@
 	list_add(&reg_base->reg_base_head, &dbg_base->reg_base_list);
 
 	return 0;
-reg_fail:
-	debugfs_remove(ent_off);
-off_fail:
-	kfree(reg_base);
-	return -ENODEV;
 }
 
 void sde_dbg_reg_register_dump_range(const char *base_name,
diff --git a/drivers/gpu/drm/msm/sde_dbg.h b/drivers/gpu/drm/msm/sde_dbg.h
index 59da9fd..7a940f4 100644
--- a/drivers/gpu/drm/msm/sde_dbg.h
+++ b/drivers/gpu/drm/msm/sde_dbg.h
@@ -64,7 +64,6 @@
 };
 
 struct sde_dbg_evtlog_log {
-	u32 counter;
 	s64 time;
 	const char *name;
 	int line;
@@ -185,14 +184,19 @@
 
 /**
  * sde_dbg_init - initialize global sde debug facilities: evtlog, regdump
- * @debugfs_root:	debugfs root in which to create sde debug entries
  * @dev:		device handle
  * @power_ctrl:		power control callback structure for enabling clocks
  *			during register dumping
  * Returns:		0 or -ERROR
  */
-int sde_dbg_init(struct dentry *debugfs_root, struct device *dev,
-		struct sde_dbg_power_ctrl *power_ctrl);
+int sde_dbg_init(struct device *dev, struct sde_dbg_power_ctrl *power_ctrl);
+
+/**
+ * sde_dbg_debugfs_register - register entries at the given debugfs dir
+ * @debugfs_root:	debugfs root in which to create sde debug entries
+ * Returns:	0 or -ERROR
+ */
+int sde_dbg_debugfs_register(struct dentry *debugfs_root);
 
 /**
  * sde_dbg_destroy - destroy the global sde debug facilities
@@ -275,12 +279,17 @@
 {
 }
 
-static inline int sde_dbg_init(struct dentry *debugfs_root, struct device *dev,
+static inline int sde_dbg_init(struct device *dev,
 		struct sde_dbg_power_ctrl *power_ctrl)
 {
 	return 0;
 }
 
+int sde_dbg_debugfs_register(struct dentry *debugfs_root)
+{
+	return 0;
+}
+
 static inline void sde_dbg_destroy(void)
 {
 }
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 4f5309d..302c306 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -2441,6 +2441,9 @@
 
 	if (vb) {
 		vbuf = to_vb2_v4l2_buffer(vb);
+		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DROP_FRAME ||
+			fill_buf_done->flags1 & HAL_BUFFERFLAG_DECODEONLY)
+			fill_buf_done->filled_len1 = 0;
 		vb->planes[0].bytesused = fill_buf_done->filled_len1;
 		vb->planes[0].data_offset = fill_buf_done->offset1;
 		if (vb->planes[0].data_offset > vb->planes[0].length)
@@ -2492,7 +2495,8 @@
 			vbuf->flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
 		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOSEQ)
 			vbuf->flags |= V4L2_QCOM_BUF_FLAG_EOSEQ;
-		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DECODEONLY)
+		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DECODEONLY ||
+			fill_buf_done->flags1 & HAL_BUFFERFLAG_DROP_FRAME)
 			vbuf->flags |= V4L2_QCOM_BUF_FLAG_DECODEONLY;
 		if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DATACORRUPT)
 			vbuf->flags |= V4L2_QCOM_BUF_DATA_CORRUPT;
@@ -2579,7 +2583,7 @@
 		goto err_seq_hdr_done;
 	}
 	vbuf = to_vb2_v4l2_buffer(vb);
-//	vb->timestamp = (u64) ns_to_timeval(0);
+	vb->timestamp = 0;
 
 	vb->planes[0].bytesused = fill_buf_done->filled_len1;
 	vb->planes[0].data_offset = fill_buf_done->offset1;