浏览代码

Merge "disp: msm: dsi: add parsing logic for panel gpio pins/address"

qctecmdr 4 年之前
父节点
当前提交
ead6a35953
共有 6 个文件被更改,包括 152 次插入0 次删除
  1. 2 0
      include/linux/sde_io_util.h
  2. 10 0
      msm/dsi/dsi_display.c
  3. 81 0
      msm/dsi/dsi_panel.c
  4. 3 0
      msm/dsi/dsi_panel.h
  5. 6 0
      msm/sde/sde_kms.c
  6. 50 0
      msm/sde_io_util.c

+ 2 - 0
include/linux/sde_io_util.h

@@ -88,6 +88,8 @@ void msm_dss_iounmap(struct dss_io_data *io_data);
 int msm_dss_get_io_mem(struct platform_device *pdev,
 		       struct list_head *mem_list);
 void msm_dss_clean_io_mem(struct list_head *mem_list);
+int msm_dss_get_pmic_io_mem(struct platform_device *pdev,
+		       struct list_head *mem_list);
 int msm_dss_get_io_irq(struct platform_device *pdev,
 		       struct list_head *irq_list, u32 label);
 void msm_dss_clean_io_irq(struct list_head *irq_list);

+ 10 - 0
msm/dsi/dsi_display.c

@@ -5216,12 +5216,22 @@ error:
 static int dsi_display_get_io_resources(struct msm_io_res *io_res, void *data)
 {
 	int rc = 0;
+	struct dsi_display *display;
+
+	if (!data)
+		return -EINVAL;
 
 	rc = dsi_ctrl_get_io_resources(io_res);
 	if (rc)
 		goto end;
 
 	rc = dsi_phy_get_io_resources(io_res);
+	if (rc)
+		goto end;
+
+	display = (struct dsi_display *)data;
+	rc = dsi_panel_get_io_resources(display->panel, io_res);
+
 end:
 	return rc;
 }

+ 81 - 0
msm/dsi/dsi_panel.c

@@ -2044,6 +2044,87 @@ error:
 	return rc;
 }
 
+int dsi_panel_get_io_resources(struct dsi_panel *panel,
+		struct msm_io_res *io_res)
+{
+	struct list_head temp_head;
+	struct msm_io_mem_entry *io_mem, *pos, *tmp;
+	struct list_head *mem_list = &io_res->mem;
+	int i, rc = 0, address_count, pin_count;
+	u32 *pins = NULL, *address = NULL;
+	u32 base, size;
+	struct dsi_parser_utils *utils = &panel->utils;
+
+	INIT_LIST_HEAD(&temp_head);
+
+	address_count = utils->count_u32_elems(utils->data,
+				"qcom,dsi-panel-gpio-address");
+	if (address_count != 2) {
+		DSI_DEBUG("panel gpio address not defined\n");
+		return 0;
+	}
+
+	address =  kzalloc(sizeof(u32) * address_count, GFP_KERNEL);
+	if (!address)
+		return -ENOMEM;
+
+	rc = utils->read_u32_array(utils->data, "qcom,dsi-panel-gpio-address",
+				address, address_count);
+	if (rc) {
+		DSI_ERR("panel gpio address not defined correctly\n");
+		goto end;
+	}
+	base = address[0];
+	size = address[1];
+
+	pin_count = utils->count_u32_elems(utils->data,
+				"qcom,dsi-panel-gpio-pins");
+	if (pin_count < 0) {
+		DSI_ERR("panel gpio pins not defined\n");
+		rc = pin_count;
+		goto end;
+	}
+
+	pins =  kzalloc(sizeof(u32) * pin_count, GFP_KERNEL);
+	if (!pins) {
+		rc = -ENOMEM;
+		goto end;
+	}
+
+	rc = utils->read_u32_array(utils->data, "qcom,dsi-panel-gpio-pins",
+				pins, pin_count);
+	if (rc) {
+		DSI_ERR("panel gpio pins not defined correctly\n");
+		goto end;
+	}
+
+	for (i = 0; i < pin_count; i++) {
+		io_mem = kzalloc(sizeof(*io_mem), GFP_KERNEL);
+		if (!io_mem) {
+			rc = -ENOMEM;
+			goto parse_fail;
+		}
+
+		io_mem->base = base + (pins[i] * size);
+		io_mem->size = size;
+
+		list_add(&io_mem->list, &temp_head);
+	}
+
+	list_splice(&temp_head, mem_list);
+	goto end;
+
+parse_fail:
+	list_for_each_entry_safe(pos, tmp, &temp_head, list) {
+		list_del(&pos->list);
+		kzfree(pos);
+	}
+end:
+	kzfree(pins);
+	kzfree(address);
+	return rc;
+}
+
 static int dsi_panel_parse_gpios(struct dsi_panel *panel)
 {
 	int rc = 0;

+ 3 - 0
msm/dsi/dsi_panel.h

@@ -364,6 +364,9 @@ int dsi_panel_parse_esd_reg_read_configs(struct dsi_panel *panel);
 
 void dsi_panel_ext_bridge_put(struct dsi_panel *panel);
 
+int dsi_panel_get_io_resources(struct dsi_panel *panel,
+		struct msm_io_res *io_res);
+
 void dsi_panel_calc_dsi_transfer_time(struct dsi_host_common_cfg *config,
 		struct dsi_display_mode *mode, u32 frame_threshold_us);
 

+ 6 - 0
msm/sde/sde_kms.c

@@ -4122,6 +4122,12 @@ int sde_kms_get_io_resources(struct sde_kms *sde_kms, struct msm_io_res *io_res)
 		return rc;
 	}
 
+	rc = msm_dss_get_pmic_io_mem(pdev, &io_res->mem);
+	if (rc) {
+		SDE_ERROR("failed to get io mem for pmic, rc:%d\n", rc);
+		return rc;
+	}
+
 	rc = msm_dss_get_io_irq(pdev, &io_res->irq, HH_IRQ_LABEL_SDE);
 	if (rc) {
 		SDE_ERROR("failed to get io irq for KMS");

+ 50 - 0
msm/sde_io_util.c

@@ -7,6 +7,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/regulator/consumer.h>
+#include <linux/soc/qcom/spmi-pmic-arb.h>
 #include <linux/delay.h>
 #include <linux/sde_io_util.h>
 #include <linux/sde_vm_event.h>
@@ -130,6 +131,55 @@ void msm_dss_iounmap(struct dss_io_data *io_data)
 } /* msm_dss_iounmap */
 EXPORT_SYMBOL(msm_dss_iounmap);
 
+int msm_dss_get_pmic_io_mem(struct platform_device *pdev,
+		struct list_head *mem_list)
+{
+	struct list_head temp_head;
+	struct msm_io_mem_entry *io_mem;
+	struct resource *res = NULL;
+	struct property *prop;
+	const __be32 *cur;
+	int rc = 0;
+	u32 val;
+
+	INIT_LIST_HEAD(&temp_head);
+
+	res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+	if (!res)
+		return -ENOMEM;
+
+	of_property_for_each_u32(pdev->dev.of_node, "qcom,pmic-arb-address",
+			prop, cur, val) {
+		rc = spmi_pmic_arb_map_address(&pdev->dev, val, res);
+		if (rc < 0) {
+			DEV_ERR("%pS - failed to map pmic address, rc:%d\n",
+						    __func__, rc);
+			goto parse_fail;
+		}
+
+		io_mem = kzalloc(sizeof(struct msm_io_mem_entry), GFP_KERNEL);
+		if (!io_mem) {
+			rc = -ENOMEM;
+			goto parse_fail;
+		}
+
+		io_mem->base = res->start;
+		io_mem->size = resource_size(res);
+
+		list_add(&io_mem->list, &temp_head);
+	}
+
+	list_splice(&temp_head, mem_list);
+	goto end;
+
+parse_fail:
+	msm_dss_clean_io_mem(&temp_head);
+end:
+	kzfree(res);
+	return rc;
+}
+EXPORT_SYMBOL(msm_dss_get_pmic_io_mem);
+
 int msm_dss_get_io_mem(struct platform_device *pdev, struct list_head *mem_list)
 {
 	struct list_head temp_head;