diff --git a/include/linux/sde_io_util.h b/include/linux/sde_io_util.h index 312488fce5..e9b257c774 100644 --- a/include/linux/sde_io_util.h +++ b/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); diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 70be011f31..046fbf7af5 100644 --- a/msm/dsi/dsi_display.c +++ b/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; } diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 1715087e0b..3f3a717b75 100644 --- a/msm/dsi/dsi_panel.c +++ b/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; diff --git a/msm/dsi/dsi_panel.h b/msm/dsi/dsi_panel.h index 614cc2787c..2c88f960df 100644 --- a/msm/dsi/dsi_panel.h +++ b/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); diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 5bcbd457cd..95a8d2d1a9 100644 --- a/msm/sde/sde_kms.c +++ b/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"); diff --git a/msm/sde_io_util.c b/msm/sde_io_util.c index d86bcacfdb..0d1ec68332 100644 --- a/msm/sde_io_util.c +++ b/msm/sde_io_util.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -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;