Skip to content

Commit

Permalink
Merge branch 'msm-next' of git://people.freedesktop.org/~robclark/lin…
Browse files Browse the repository at this point in the history
…ux into drm-next

The big things this time around are:
1) support for hw cursor on newer mdp5 devices (snapdragon 820+,
tested on db820c)
2) dsi encoder cleanup
3) gpu dt bindings cleanup so we can get the gpu nodes merged upstream

* 'msm-next' of git://people.freedesktop.org/~robclark/linux: (32 commits)
  drm/msm: return -EFAULT if copy_from_user() fails
  drm/msm/dsi: Add PHY/PLL for 8x96
  drm/msm/dsi: Add new method to calculate 14nm PHY timings
  drm/msm/dsi: Move PHY operations out of host
  drm/msm/dsi: Reset both PHYs before clock operation for dual DSI
  drm/msm/dsi: Pass down use case to PHY
  drm/msm/dsi: Return more timings from PHY to host
  drm/msm/dsi: Add a PHY op that initializes version specific stuff
  drm/msm/dsi: Add 8x96 info in dsi_cfg
  drm/msm/dsi: Don't error if a DSI host doesn't have a device connected
  drm/msm/mdp5: Add support for legacy cursor updates
  drm/msm/mdp5: Refactor mdp5_plane_atomic_check
  drm/msm/mdp5: Add cursor planes
  drm/msm/mdp5: Misc cursor plane bits
  drm/msm/mdp5: Configure COLOR3_OUT propagation
  drm/msm/mdp5: Use plane helpers to configure src/dst rectangles
  drm/msm/mdp5: Prepare CRTC/LM for empty stages
  drm/msm/mdp5: Create only as many CRTCs as we need
  drm/msm/mdp5: cfg: Change count to unsigned int
  drm/msm/mdp5: Create single encoder per interface (INTF)
  ...
  • Loading branch information
Dave Airlie committed Feb 7, 2017
2 parents 538f1dc + 21c42da commit 26d7f34
Show file tree
Hide file tree
Showing 45 changed files with 2,712 additions and 556 deletions.
38 changes: 12 additions & 26 deletions Documentation/devicetree/bindings/display/msm/gpu.txt
Original file line number Diff line number Diff line change
@@ -1,52 +1,38 @@
Qualcomm adreno/snapdragon GPU

Required properties:
- compatible: "qcom,adreno-3xx"
- compatible: "qcom,adreno-XYZ.W", "qcom,adreno"
for example: "qcom,adreno-306.0", "qcom,adreno"
Note that you need to list the less specific "qcom,adreno" (since this
is what the device is matched on), in addition to the more specific
with the chip-id.
- reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt signal from the gpu.
- clocks: device clocks
See ../clocks/clock-bindings.txt for details.
- clock-names: the following clocks are required:
* "core_clk"
* "iface_clk"
* "mem_iface_clk"
- qcom,chipid: gpu chip-id. Note this may become optional for future
devices if we can reliably read the chipid from hw
- qcom,gpu-pwrlevels: list of operating points
- compatible: "qcom,gpu-pwrlevels"
- for each qcom,gpu-pwrlevel:
- qcom,gpu-freq: requested gpu clock speed
- NOTE: downstream android driver defines additional parameters to
configure memory bandwidth scaling per OPP.
* "core"
* "iface"
* "mem_iface"

Example:

/ {
...

gpu: qcom,kgsl-3d0@4300000 {
compatible = "qcom,adreno-3xx";
compatible = "qcom,adreno-320.2", "qcom,adreno";
reg = <0x04300000 0x20000>;
reg-names = "kgsl_3d0_reg_memory";
interrupts = <GIC_SPI 80 0>;
interrupt-names = "kgsl_3d0_irq";
clock-names =
"core_clk",
"iface_clk",
"mem_iface_clk";
"core",
"iface",
"mem_iface";
clocks =
<&mmcc GFX3D_CLK>,
<&mmcc GFX3D_AHB_CLK>,
<&mmcc MMSS_IMEM_AHB_CLK>;
qcom,chipid = <0x03020100>;
qcom,gpu-pwrlevels {
compatible = "qcom,gpu-pwrlevels";
qcom,gpu-pwrlevel@0 {
qcom,gpu-freq = <450000000>;
};
qcom,gpu-pwrlevel@1 {
qcom,gpu-freq = <27000000>;
};
};
};
};
7 changes: 7 additions & 0 deletions drivers/gpu/drm/msm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,10 @@ config DRM_MSM_DSI_28NM_8960_PHY
help
Choose this option if the 28nm DSI PHY 8960 variant is used on the
platform.

config DRM_MSM_DSI_14NM_PHY
bool "Enable DSI 14nm PHY driver in MSM DRM (used by MSM8996/APQ8096)"
depends on DRM_MSM_DSI
default y
help
Choose this option if DSI PHY on 8996 is used on the platform.
2 changes: 2 additions & 0 deletions drivers/gpu/drm/msm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,13 @@ msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \
msm-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/phy/dsi_phy_28nm.o
msm-$(CONFIG_DRM_MSM_DSI_20NM_PHY) += dsi/phy/dsi_phy_20nm.o
msm-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/phy/dsi_phy_28nm_8960.o
msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o

ifeq ($(CONFIG_DRM_MSM_DSI_PLL),y)
msm-y += dsi/pll/dsi_pll.o
msm-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/pll/dsi_pll_28nm.o
msm-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/pll/dsi_pll_28nm_8960.o
msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/pll/dsi_pll_14nm.o
endif

obj-$(CONFIG_DRM_MSM) += msm.o
21 changes: 19 additions & 2 deletions drivers/gpu/drm/msm/adreno/a5xx_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

#include "msm_gem.h"
#include "msm_mmu.h"
#include "a5xx_gpu.h"

extern bool hang_debug;
Expand Down Expand Up @@ -327,7 +328,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
/* Enable RBBM error reporting bits */
gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL0, 0x00000001);

if (adreno_gpu->quirks & ADRENO_QUIRK_FAULT_DETECT_MASK) {
if (adreno_gpu->info->quirks & ADRENO_QUIRK_FAULT_DETECT_MASK) {
/*
* Mask out the activity signals from RB1-3 to avoid false
* positives
Expand Down Expand Up @@ -381,7 +382,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)

gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, (0x400 << 11 | 0x300 << 22));

if (adreno_gpu->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI)
if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI)
gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8));

gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100);
Expand Down Expand Up @@ -573,6 +574,19 @@ static bool a5xx_idle(struct msm_gpu *gpu)
return true;
}

static int a5xx_fault_handler(void *arg, unsigned long iova, int flags)
{
struct msm_gpu *gpu = arg;
pr_warn_ratelimited("*** gpu fault: iova=%08lx, flags=%d (%u,%u,%u,%u)\n",
iova, flags,
gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(4)),
gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(5)),
gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(6)),
gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(7)));

return -EFAULT;
}

static void a5xx_cp_err_irq(struct msm_gpu *gpu)
{
u32 status = gpu_read(gpu, REG_A5XX_CP_INTERRUPT_STATUS);
Expand Down Expand Up @@ -884,5 +898,8 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
return ERR_PTR(ret);
}

if (gpu->aspace)
msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu, a5xx_fault_handler);

return gpu;
}
62 changes: 46 additions & 16 deletions drivers/gpu/drm/msm/adreno/adreno_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,14 @@ static const struct adreno_info gpulist[] = {
.gmem = (SZ_1M + SZ_512K),
.init = a4xx_gpu_init,
}, {
.rev = ADRENO_REV(5, 3, 0, ANY_ID),
.rev = ADRENO_REV(5, 3, 0, 2),
.revn = 530,
.name = "A530",
.pm4fw = "a530_pm4.fw",
.pfpfw = "a530_pfp.fw",
.gmem = SZ_1M,
.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
ADRENO_QUIRK_FAULT_DETECT_MASK,
.init = a5xx_gpu_init,
.gpmufw = "a530v3_gpmu.fw2",
},
Expand Down Expand Up @@ -181,22 +183,51 @@ static void set_gpu_pdev(struct drm_device *dev,
priv->gpu_pdev = pdev;
}

static const struct {
const char *str;
uint32_t flag;
} quirks[] = {
{ "qcom,gpu-quirk-two-pass-use-wfi", ADRENO_QUIRK_TWO_PASS_USE_WFI },
{ "qcom,gpu-quirk-fault-detect-mask", ADRENO_QUIRK_FAULT_DETECT_MASK },
};
static int find_chipid(struct device *dev, u32 *chipid)
{
struct device_node *node = dev->of_node;
const char *compat;
int ret;

/* first search the compat strings for qcom,adreno-XYZ.W: */
ret = of_property_read_string_index(node, "compatible", 0, &compat);
if (ret == 0) {
unsigned rev, patch;

if (sscanf(compat, "qcom,adreno-%u.%u", &rev, &patch) == 2) {
*chipid = 0;
*chipid |= (rev / 100) << 24; /* core */
rev %= 100;
*chipid |= (rev / 10) << 16; /* major */
rev %= 10;
*chipid |= rev << 8; /* minor */
*chipid |= patch;

return 0;
}
}

/* and if that fails, fall back to legacy "qcom,chipid" property: */
ret = of_property_read_u32(node, "qcom,chipid", chipid);
if (ret)
return ret;

dev_warn(dev, "Using legacy qcom,chipid binding!\n");
dev_warn(dev, "Use compatible qcom,adreno-%u%u%u.%u instead.\n",
(*chipid >> 24) & 0xff, (*chipid >> 16) & 0xff,
(*chipid >> 8) & 0xff, *chipid & 0xff);

return 0;
}

static int adreno_bind(struct device *dev, struct device *master, void *data)
{
static struct adreno_platform_config config = {};
struct device_node *child, *node = dev->of_node;
u32 val;
int ret, i;
int ret;

ret = of_property_read_u32(node, "qcom,chipid", &val);
ret = find_chipid(dev, &val);
if (ret) {
dev_err(dev, "could not find chipid: %d\n", ret);
return ret;
Expand Down Expand Up @@ -224,14 +255,12 @@ static int adreno_bind(struct device *dev, struct device *master, void *data)
}

if (!config.fast_rate) {
dev_err(dev, "could not find clk rates\n");
return -ENXIO;
dev_warn(dev, "could not find clk rates\n");
/* This is a safe low speed for all devices: */
config.fast_rate = 200000000;
config.slow_rate = 27000000;
}

for (i = 0; i < ARRAY_SIZE(quirks); i++)
if (of_property_read_bool(node, quirks[i].str))
config.quirks |= quirks[i].flag;

dev->platform_data = &config;
set_gpu_pdev(dev_get_drvdata(master), to_platform_device(dev));
return 0;
Expand Down Expand Up @@ -260,6 +289,7 @@ static int adreno_remove(struct platform_device *pdev)
}

static const struct of_device_id dt_match[] = {
{ .compatible = "qcom,adreno" },
{ .compatible = "qcom,adreno-3xx" },
/* for backwards compat w/ downstream kgsl DT files: */
{ .compatible = "qcom,kgsl-3d0" },
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/msm/adreno/adreno_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,6 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
adreno_gpu->gmem = adreno_gpu->info->gmem;
adreno_gpu->revn = adreno_gpu->info->revn;
adreno_gpu->rev = config->rev;
adreno_gpu->quirks = config->quirks;

gpu->fast_rate = config->fast_rate;
gpu->slow_rate = config->slow_rate;
Expand Down
4 changes: 1 addition & 3 deletions drivers/gpu/drm/msm/adreno/adreno_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct adreno_info {
const char *pm4fw, *pfpfw;
const char *gpmufw;
uint32_t gmem;
enum adreno_quirks quirks;
struct msm_gpu *(*init)(struct drm_device *dev);
};

Expand Down Expand Up @@ -116,8 +117,6 @@ struct adreno_gpu {
* code (a3xx_gpu.c) and stored in this common location.
*/
const unsigned int *reg_offsets;

uint32_t quirks;
};
#define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base)

Expand All @@ -128,7 +127,6 @@ struct adreno_platform_config {
#ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING
struct msm_bus_scale_pdata *bus_scale_table;
#endif
uint32_t quirks;
};

#define ADRENO_IDLE_TIMEOUT msecs_to_jiffies(1000)
Expand Down
18 changes: 6 additions & 12 deletions drivers/gpu/drm/msm/dsi/dsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi)
if (!msm_dsi || !msm_dsi_device_connected(msm_dsi))
return NULL;

return (msm_dsi->device_flags & MIPI_DSI_MODE_VIDEO) ?
msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID] :
msm_dsi->encoders[MSM_DSI_CMD_ENCODER_ID];
return msm_dsi->encoder;
}

static int dsi_get_phy(struct msm_dsi *msm_dsi)
Expand Down Expand Up @@ -187,14 +185,13 @@ void __exit msm_dsi_unregister(void)
}

int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
struct drm_encoder *encoders[MSM_DSI_ENCODER_NUM])
struct drm_encoder *encoder)
{
struct msm_drm_private *priv = dev->dev_private;
struct drm_bridge *ext_bridge;
int ret, i;
int ret;

if (WARN_ON(!encoders[MSM_DSI_VIDEO_ENCODER_ID] ||
!encoders[MSM_DSI_CMD_ENCODER_ID]))
if (WARN_ON(!encoder))
return -EINVAL;

msm_dsi->dev = dev;
Expand All @@ -205,6 +202,8 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
goto fail;
}

msm_dsi->encoder = encoder;

msm_dsi->bridge = msm_dsi_manager_bridge_init(msm_dsi->id);
if (IS_ERR(msm_dsi->bridge)) {
ret = PTR_ERR(msm_dsi->bridge);
Expand All @@ -213,11 +212,6 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
goto fail;
}

for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) {
encoders[i]->bridge = msm_dsi->bridge;
msm_dsi->encoders[i] = encoders[i];
}

/*
* check if the dsi encoder output is connected to a panel or an
* external bridge. We create a connector only if we're connected to a
Expand Down
Loading

0 comments on commit 26d7f34

Please sign in to comment.