diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-21 13:48:00 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-21 13:48:00 -0700 |
commit | 266c73b77706f2d05b4a3e70a5bb702ed35431d6 (patch) | |
tree | 381461b90a8bd10c0c36b0cdbb2e6e4bbf6c5e87 /drivers/gpu/drm/msm/dsi/dsi_host.c | |
parent | 2c856e14dad8cb1b085ae1f30c5e125c6d46019b (diff) | |
parent | 568d7c764ae01f3706085ac8f0d8a8ac7e826bd7 (diff) | |
download | blackbird-obmc-linux-266c73b77706f2d05b4a3e70a5bb702ed35431d6.tar.gz blackbird-obmc-linux-266c73b77706f2d05b4a3e70a5bb702ed35431d6.zip |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"This is the main drm pull request for 4.6 kernel.
Overall the coolest thing here for me is the nouveau maxwell signed
firmware support from NVidia, it's taken a long while to extract this
from them.
I also wish the ARM vendors just designed one set of display IP, ARM
display block proliferation is definitely increasing.
Core:
- drm_event cleanups
- Internal API cleanup making mode_fixup optional.
- Apple GMUX vga switcheroo support.
- DP AUX testing interface
Panel:
- Refactoring of DSI core for use over more transports.
New driver:
- ARM hdlcd driver
i915:
- FBC/PSR (framebuffer compression, panel self refresh) enabled by default.
- Ongoing atomic display support work
- Ongoing runtime PM work
- Pixel clock limit checks
- VBT DSI description support
- GEM fixes
- GuC firmware scheduler enhancements
amdkfd:
- Deferred probing fixes to avoid make file or link ordering.
amdgpu/radeon:
- ACP support for i2s audio support.
- Command Submission/GPU scheduler/GPUVM optimisations
- Initial GPU reset support for amdgpu
vmwgfx:
- Support for DX10 gen mipmaps
- Pageflipping and other fixes.
exynos:
- Exynos5420 SoC support for FIMD
- Exynos5422 SoC support for MIPI-DSI
nouveau:
- GM20x secure boot support - adds acceleration for Maxwell GPUs.
- GM200 support
- GM20B clock driver support
- Power sensors work
etnaviv:
- Correctness fixes for GPU cache flushing
- Better support for i.MX6 systems.
imx-drm:
- VBlank IRQ support
- Fence support
- OF endpoint support
msm:
- HDMI support for 8996 (snapdragon 820)
- Adreno 430 support
- Timestamp queries support
virtio-gpu:
- Fixes for Android support.
rockchip:
- Add support for Innosilicion HDMI
rcar-du:
- Support for 4 crtcs
- R8A7795 support
- RCar Gen 3 support
omapdrm:
- HDMI interlace output support
- dma-buf import support
- Refactoring to remove a lot of legacy code.
tilcdc:
- Rewrite of pageflipping code
- dma-buf support
- pinctrl support
vc4:
- HDMI modesetting bug fixes
- Significant 3D performance improvement.
fsl-dcu (FreeScale):
- Lots of fixes
tegra:
- Two small fixes
sti:
- Atomic support for planes
- Improved HDMI support"
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (1063 commits)
drm/amdgpu: release_pages requires linux/pagemap.h
drm/sti: restore mode_fixup callback
drm/amdgpu/gfx7: add MTYPE definition
drm/amdgpu: removing BO_VAs shouldn't be interruptible
drm/amd/powerplay: show uvd/vce power gate enablement for tonga.
drm/amd/powerplay: show uvd/vce power gate info for fiji
drm/amdgpu: use sched fence if possible
drm/amdgpu: move ib.fence to job.fence
drm/amdgpu: give a fence param to ib_free
drm/amdgpu: include the right version of gmc header files for iceland
drm/radeon: fix indentation.
drm/amd/powerplay: add uvd/vce dpm enabling flag to fix the performance issue for CZ
drm/amdgpu: switch back to 32bit hw fences v2
drm/amdgpu: remove amdgpu_fence_is_signaled
drm/amdgpu: drop the extra fence range check v2
drm/amdgpu: signal fences directly in amdgpu_fence_process
drm/amdgpu: cleanup amdgpu_fence_wait_empty v2
drm/amdgpu: keep all fences in an RCU protected array v2
drm/amdgpu: add number of hardware submissions to amdgpu_fence_driver_init_ring
drm/amdgpu: RCU protected amd_sched_fence_release
...
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi_host.c')
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi_host.c | 118 |
1 files changed, 96 insertions, 22 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 48f9967b4a1b..4282ec6bbaaf 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -163,6 +163,10 @@ struct msm_dsi_host { enum mipi_dsi_pixel_format format; unsigned long mode_flags; + /* lane data parsed via DT */ + int dlane_swap; + int num_data_lanes; + u32 dma_cmd_ctrl_restore; bool registered; @@ -845,19 +849,10 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable, data = DSI_CTRL_CLK_EN; DBG("lane number=%d", msm_host->lanes); - if (msm_host->lanes == 2) { - data |= DSI_CTRL_LANE1 | DSI_CTRL_LANE2; - /* swap lanes for 2-lane panel for better performance */ - dsi_write(msm_host, REG_DSI_LANE_SWAP_CTRL, - DSI_LANE_SWAP_CTRL_DLN_SWAP_SEL(LANE_SWAP_1230)); - } else { - /* Take 4 lanes as default */ - data |= DSI_CTRL_LANE0 | DSI_CTRL_LANE1 | DSI_CTRL_LANE2 | - DSI_CTRL_LANE3; - /* Do not swap lanes for 4-lane panel */ - dsi_write(msm_host, REG_DSI_LANE_SWAP_CTRL, - DSI_LANE_SWAP_CTRL_DLN_SWAP_SEL(LANE_SWAP_0123)); - } + data |= ((DSI_CTRL_LANE0 << msm_host->lanes) - DSI_CTRL_LANE0); + + dsi_write(msm_host, REG_DSI_LANE_SWAP_CTRL, + DSI_LANE_SWAP_CTRL_DLN_SWAP_SEL(msm_host->dlane_swap)); if (!(flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) dsi_write(msm_host, REG_DSI_LANE_CTRL, @@ -1479,13 +1474,14 @@ static int dsi_host_attach(struct mipi_dsi_host *host, struct msm_dsi_host *msm_host = to_msm_dsi_host(host); int ret; + if (dsi->lanes > msm_host->num_data_lanes) + return -EINVAL; + msm_host->channel = dsi->channel; msm_host->lanes = dsi->lanes; msm_host->format = dsi->format; msm_host->mode_flags = dsi->mode_flags; - WARN_ON(dsi->dev.of_node != msm_host->device_node); - /* Some gpios defined in panel DT need to be controlled by host */ ret = dsi_host_init_panel_gpios(msm_host, &dsi->dev); if (ret) @@ -1534,6 +1530,75 @@ static struct mipi_dsi_host_ops dsi_host_ops = { .transfer = dsi_host_transfer, }; +/* + * List of supported physical to logical lane mappings. + * For example, the 2nd entry represents the following mapping: + * + * "3012": Logic 3->Phys 0; Logic 0->Phys 1; Logic 1->Phys 2; Logic 2->Phys 3; + */ +static const int supported_data_lane_swaps[][4] = { + { 0, 1, 2, 3 }, + { 3, 0, 1, 2 }, + { 2, 3, 0, 1 }, + { 1, 2, 3, 0 }, + { 0, 3, 2, 1 }, + { 1, 0, 3, 2 }, + { 2, 1, 0, 3 }, + { 3, 2, 1, 0 }, +}; + +static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, + struct device_node *ep) +{ + struct device *dev = &msm_host->pdev->dev; + struct property *prop; + u32 lane_map[4]; + int ret, i, len, num_lanes; + + prop = of_find_property(ep, "qcom,data-lane-map", &len); + if (!prop) { + dev_dbg(dev, "failed to find data lane mapping\n"); + return -EINVAL; + } + + num_lanes = len / sizeof(u32); + + if (num_lanes < 1 || num_lanes > 4) { + dev_err(dev, "bad number of data lanes\n"); + return -EINVAL; + } + + msm_host->num_data_lanes = num_lanes; + + ret = of_property_read_u32_array(ep, "qcom,data-lane-map", lane_map, + num_lanes); + if (ret) { + dev_err(dev, "failed to read lane data\n"); + return ret; + } + + /* + * compare DT specified physical-logical lane mappings with the ones + * supported by hardware + */ + for (i = 0; i < ARRAY_SIZE(supported_data_lane_swaps); i++) { + const int *swap = supported_data_lane_swaps[i]; + int j; + + for (j = 0; j < num_lanes; j++) { + if (swap[j] != lane_map[j]) + break; + } + + if (j == num_lanes) { + msm_host->dlane_swap = i; + return 0; + } + } + + return -EINVAL; +} + static int dsi_host_parse_dt(struct msm_dsi_host *msm_host) { struct device *dev = &msm_host->pdev->dev; @@ -1560,17 +1625,21 @@ static int dsi_host_parse_dt(struct msm_dsi_host *msm_host) return 0; } + ret = dsi_host_parse_lane_data(msm_host, endpoint); + if (ret) { + dev_err(dev, "%s: invalid lane configuration %d\n", + __func__, ret); + goto err; + } + /* Get panel node from the output port's endpoint data */ device_node = of_graph_get_remote_port_parent(endpoint); if (!device_node) { dev_err(dev, "%s: no valid device\n", __func__); - of_node_put(endpoint); - return -ENODEV; + ret = -ENODEV; + goto err; } - of_node_put(endpoint); - of_node_put(device_node); - msm_host->device_node = device_node; if (of_property_read_bool(np, "syscon-sfpb")) { @@ -1579,11 +1648,16 @@ static int dsi_host_parse_dt(struct msm_dsi_host *msm_host) if (IS_ERR(msm_host->sfpb)) { dev_err(dev, "%s: failed to get sfpb regmap\n", __func__); - return PTR_ERR(msm_host->sfpb); + ret = PTR_ERR(msm_host->sfpb); } } - return 0; + of_node_put(device_node); + +err: + of_node_put(endpoint); + + return ret; } int msm_dsi_host_init(struct msm_dsi *msm_dsi) |