From d0b2f91bede3bd5e3d24dd6803e56eee959c1797 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Thu, 20 Oct 2016 00:10:27 -0300 Subject: Linux-libre 4.8.2-gnu --- drivers/gpu/drm/msm/dsi/dsi.c | 2 +- drivers/gpu/drm/msm/dsi/dsi_cfg.c | 8 +++ drivers/gpu/drm/msm/dsi/dsi_cfg.h | 2 + drivers/gpu/drm/msm/dsi/dsi_host.c | 69 ++++++++++++++++++------- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 32 ++++++++++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 2 + drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c | 4 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 4 ++ drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 2 + 9 files changed, 101 insertions(+), 24 deletions(-) (limited to 'drivers/gpu/drm/msm/dsi') diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index 6edcd6f57..ec572f838 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -29,7 +29,7 @@ static int dsi_get_phy(struct msm_dsi *msm_dsi) struct platform_device *phy_pdev; struct device_node *phy_node; - phy_node = of_parse_phandle(pdev->dev.of_node, "qcom,dsi-phy", 0); + phy_node = of_parse_phandle(pdev->dev.of_node, "phys", 0); if (!phy_node) { dev_err(&pdev->dev, "cannot find phy device\n"); return -ENXIO; diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c index 93c1ee094..63436d8ee 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c @@ -29,6 +29,8 @@ static const struct msm_dsi_config apq8064_dsi_cfg = { }, .bus_clk_names = dsi_v2_bus_clk_names, .num_bus_clks = ARRAY_SIZE(dsi_v2_bus_clk_names), + .io_start = { 0x4700000, 0x5800000 }, + .num_dsi = 2, }; static const char * const dsi_6g_bus_clk_names[] = { @@ -48,6 +50,8 @@ static const struct msm_dsi_config msm8974_apq8084_dsi_cfg = { }, .bus_clk_names = dsi_6g_bus_clk_names, .num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names), + .io_start = { 0xfd922800, 0xfd922b00 }, + .num_dsi = 2, }; static const char * const dsi_8916_bus_clk_names[] = { @@ -66,6 +70,8 @@ static const struct msm_dsi_config msm8916_dsi_cfg = { }, .bus_clk_names = dsi_8916_bus_clk_names, .num_bus_clks = ARRAY_SIZE(dsi_8916_bus_clk_names), + .io_start = { 0x1a98000 }, + .num_dsi = 1, }; static const struct msm_dsi_config msm8994_dsi_cfg = { @@ -84,6 +90,8 @@ static const struct msm_dsi_config msm8994_dsi_cfg = { }, .bus_clk_names = dsi_6g_bus_clk_names, .num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names), + .io_start = { 0xfd998000, 0xfd9a0000 }, + .num_dsi = 2, }; static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = { diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h b/drivers/gpu/drm/msm/dsi/dsi_cfg.h index a68c83674..eeacc3232 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h @@ -34,6 +34,8 @@ struct msm_dsi_config { struct dsi_reg_config reg_cfg; const char * const *bus_clk_names; const int num_bus_clks; + const resource_size_t io_start[DSI_MAX]; + const int num_dsi; }; struct msm_dsi_cfg_handler { diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index a3e47ad83..f05ed0e1f 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1066,7 +1066,7 @@ static int dsi_cmd_dma_add(struct msm_dsi_host *msm_host, } if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) { - data = msm_gem_vaddr(msm_host->tx_gem_obj); + data = msm_gem_get_vaddr(msm_host->tx_gem_obj); if (IS_ERR(data)) { ret = PTR_ERR(data); pr_err("%s: get vaddr failed, %d\n", __func__, ret); @@ -1094,6 +1094,9 @@ static int dsi_cmd_dma_add(struct msm_dsi_host *msm_host, if (packet.size < len) memset(data + packet.size, 0xff, len - packet.size); + if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) + msm_gem_put_vaddr(msm_host->tx_gem_obj); + return len; } @@ -1543,7 +1546,7 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, u32 lane_map[4]; int ret, i, len, num_lanes; - prop = of_find_property(ep, "qcom,data-lane-map", &len); + prop = of_find_property(ep, "data-lanes", &len); if (!prop) { dev_dbg(dev, "failed to find data lane mapping\n"); return -EINVAL; @@ -1558,7 +1561,7 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, msm_host->num_data_lanes = num_lanes; - ret = of_property_read_u32_array(ep, "qcom,data-lane-map", lane_map, + ret = of_property_read_u32_array(ep, "data-lanes", lane_map, num_lanes); if (ret) { dev_err(dev, "failed to read lane data\n"); @@ -1573,8 +1576,19 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, const int *swap = supported_data_lane_swaps[i]; int j; + /* + * the data-lanes array we get from DT has a logical->physical + * mapping. The "data lane swap" register field represents + * supported configurations in a physical->logical mapping. + * Translate the DT mapping to what we understand and find a + * configuration that works. + */ for (j = 0; j < num_lanes; j++) { - if (swap[j] != lane_map[j]) + if (lane_map[j] < 0 || lane_map[j] > 3) + dev_err(dev, "bad physical lane entry %u\n", + lane_map[j]); + + if (swap[lane_map[j]] != j) break; } @@ -1594,20 +1608,13 @@ static int dsi_host_parse_dt(struct msm_dsi_host *msm_host) struct device_node *endpoint, *device_node; int ret; - ret = of_property_read_u32(np, "qcom,dsi-host-index", &msm_host->id); - if (ret) { - dev_err(dev, "%s: host index not specified, ret=%d\n", - __func__, ret); - return ret; - } - /* - * Get the first endpoint node. In our case, dsi has one output port - * to which the panel is connected. Don't return an error if a port - * isn't defined. It's possible that there is nothing connected to - * the dsi output. + * Get the endpoint of the output port of the DSI host. In our case, + * this is mapped to port number with reg = 1. Don't return an error if + * the remote endpoint isn't defined. It's possible that there is + * nothing connected to the dsi output. */ - endpoint = of_graph_get_next_endpoint(np, NULL); + endpoint = of_graph_get_endpoint_by_regs(np, 1, -1); if (!endpoint) { dev_dbg(dev, "%s: no endpoint\n", __func__); return 0; @@ -1648,6 +1655,25 @@ err: return ret; } +static int dsi_host_get_id(struct msm_dsi_host *msm_host) +{ + struct platform_device *pdev = msm_host->pdev; + const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg; + struct resource *res; + int i; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dsi_ctrl"); + if (!res) + return -EINVAL; + + for (i = 0; i < cfg->num_dsi; i++) { + if (cfg->io_start[i] == res->start) + return i; + } + + return -EINVAL; +} + int msm_dsi_host_init(struct msm_dsi *msm_dsi) { struct msm_dsi_host *msm_host = NULL; @@ -1684,6 +1710,13 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) goto fail; } + msm_host->id = dsi_host_get_id(msm_host); + if (msm_host->id < 0) { + ret = msm_host->id; + pr_err("%s: unable to identify DSI host index\n", __func__); + goto fail; + } + /* fixup base address by io offset */ msm_host->ctrl_base += msm_host->cfg_hnd->cfg->io_offset; @@ -2245,9 +2278,9 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, } msm_host->mode = drm_mode_duplicate(msm_host->dev, mode); - if (IS_ERR(msm_host->mode)) { + if (!msm_host->mode) { pr_err("%s: cannot duplicate mode\n", __func__); - return PTR_ERR(msm_host->mode); + return -ENOMEM; } return 0; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index e2f42d8ea..f39386ed7 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -271,6 +271,30 @@ static const struct of_device_id dsi_phy_dt_match[] = { {} }; +/* + * Currently, we only support one SoC for each PHY type. When we have multiple + * SoCs for the same PHY, we can try to make the index searching a bit more + * clever. + */ +static int dsi_phy_get_id(struct msm_dsi_phy *phy) +{ + struct platform_device *pdev = phy->pdev; + const struct msm_dsi_phy_cfg *cfg = phy->cfg; + struct resource *res; + int i; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dsi_phy"); + if (!res) + return -EINVAL; + + for (i = 0; i < cfg->num_dsi_phy; i++) { + if (cfg->io_start[i] == res->start) + return i; + } + + return -EINVAL; +} + static int dsi_phy_driver_probe(struct platform_device *pdev) { struct msm_dsi_phy *phy; @@ -289,10 +313,10 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) phy->cfg = match->data; phy->pdev = pdev; - ret = of_property_read_u32(dev->of_node, - "qcom,dsi-phy-index", &phy->id); - if (ret) { - dev_err(dev, "%s: PHY index not specified, %d\n", + phy->id = dsi_phy_get_id(phy); + if (phy->id < 0) { + ret = phy->id; + dev_err(dev, "%s: couldn't identify PHY index, %d\n", __func__, ret); goto fail; } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index 0d54ed003..f24a85439 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -38,6 +38,8 @@ struct msm_dsi_phy_cfg { * Fill default H/W values in illegal cells, eg. cell {0, 1}. */ bool src_pll_truthtable[DSI_MAX][DSI_MAX]; + const resource_size_t io_start[DSI_MAX]; + const int num_dsi_phy; }; extern const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c index f4bc11af8..c757e2070 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c @@ -145,6 +145,8 @@ const struct msm_dsi_phy_cfg dsi_phy_20nm_cfgs = { .ops = { .enable = dsi_20nm_phy_enable, .disable = dsi_20nm_phy_disable, - } + }, + .io_start = { 0xfd998300, 0xfd9a0300 }, + .num_dsi_phy = 2, }; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index 96d1852af..63d7fba31 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -145,6 +145,8 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs = { .enable = dsi_28nm_phy_enable, .disable = dsi_28nm_phy_disable, }, + .io_start = { 0xfd922b00, 0xfd923100 }, + .num_dsi_phy = 2, }; const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = { @@ -160,5 +162,7 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = { .enable = dsi_28nm_phy_enable, .disable = dsi_28nm_phy_disable, }, + .io_start = { 0x1a98500 }, + .num_dsi_phy = 1, }; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index 213355a3e..7bdb9de54 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -192,4 +192,6 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs = { .enable = dsi_28nm_phy_enable, .disable = dsi_28nm_phy_disable, }, + .io_start = { 0x4700300, 0x5800300 }, + .num_dsi_phy = 2, }; -- cgit v1.2.3-54-g00ecf