Commit 26d7f34c authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'msm-next' of git://people.freedesktop.org/~robclark/linux 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)
  ...
parents 538f1dcd 21c42da1
Loading
Loading
Loading
Loading
+12 −26
Original line number Original line Diff line number Diff line
Qualcomm adreno/snapdragon GPU
Qualcomm adreno/snapdragon GPU


Required properties:
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.
- reg: Physical base address and length of the controller's registers.
- interrupts: The interrupt signal from the gpu.
- interrupts: The interrupt signal from the gpu.
- clocks: device clocks
- clocks: device clocks
  See ../clocks/clock-bindings.txt for details.
  See ../clocks/clock-bindings.txt for details.
- clock-names: the following clocks are required:
- clock-names: the following clocks are required:
  * "core_clk"
  * "core"
  * "iface_clk"
  * "iface"
  * "mem_iface_clk"
  * "mem_iface"
- 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.


Example:
Example:


@@ -25,28 +21,18 @@ Example:
	...
	...


	gpu: qcom,kgsl-3d0@4300000 {
	gpu: qcom,kgsl-3d0@4300000 {
		compatible = "qcom,adreno-3xx";
		compatible = "qcom,adreno-320.2", "qcom,adreno";
		reg = <0x04300000 0x20000>;
		reg = <0x04300000 0x20000>;
		reg-names = "kgsl_3d0_reg_memory";
		reg-names = "kgsl_3d0_reg_memory";
		interrupts = <GIC_SPI 80 0>;
		interrupts = <GIC_SPI 80 0>;
		interrupt-names = "kgsl_3d0_irq";
		interrupt-names = "kgsl_3d0_irq";
		clock-names =
		clock-names =
		    "core_clk",
		    "core",
		    "iface_clk",
		    "iface",
		    "mem_iface_clk";
		    "mem_iface";
		clocks =
		clocks =
		    <&mmcc GFX3D_CLK>,
		    <&mmcc GFX3D_CLK>,
		    <&mmcc GFX3D_AHB_CLK>,
		    <&mmcc GFX3D_AHB_CLK>,
		    <&mmcc MMSS_IMEM_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 −0
Original line number Original line Diff line number Diff line
@@ -72,3 +72,10 @@ config DRM_MSM_DSI_28NM_8960_PHY
	help
	help
	  Choose this option if the 28nm DSI PHY 8960 variant is used on the
	  Choose this option if the 28nm DSI PHY 8960 variant is used on the
	  platform.
	  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 −0
Original line number Original line Diff line number Diff line
@@ -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_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_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_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)
ifeq ($(CONFIG_DRM_MSM_DSI_PLL),y)
msm-y += dsi/pll/dsi_pll.o
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_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_28NM_8960_PHY) += dsi/pll/dsi_pll_28nm_8960.o
msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/pll/dsi_pll_14nm.o
endif
endif


obj-$(CONFIG_DRM_MSM)	+= msm.o
obj-$(CONFIG_DRM_MSM)	+= msm.o
+19 −2
Original line number Original line Diff line number Diff line
@@ -12,6 +12,7 @@
 */
 */


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


extern bool hang_debug;
extern bool hang_debug;
@@ -327,7 +328,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
	/* Enable RBBM error reporting bits */
	/* Enable RBBM error reporting bits */
	gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL0, 0x00000001);
	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
		 * Mask out the activity signals from RB1-3 to avoid false
		 * positives
		 * positives
@@ -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));
	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_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8));


	gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100);
	gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100);
@@ -573,6 +574,19 @@ static bool a5xx_idle(struct msm_gpu *gpu)
	return true;
	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)
static void a5xx_cp_err_irq(struct msm_gpu *gpu)
{
{
	u32 status = gpu_read(gpu, REG_A5XX_CP_INTERRUPT_STATUS);
	u32 status = gpu_read(gpu, REG_A5XX_CP_INTERRUPT_STATUS);
@@ -884,5 +898,8 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
		return ERR_PTR(ret);
		return ERR_PTR(ret);
	}
	}


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

	return gpu;
	return gpu;
}
}
+46 −16
Original line number Original line Diff line number Diff line
@@ -75,12 +75,14 @@ static const struct adreno_info gpulist[] = {
		.gmem  = (SZ_1M + SZ_512K),
		.gmem  = (SZ_1M + SZ_512K),
		.init  = a4xx_gpu_init,
		.init  = a4xx_gpu_init,
	}, {
	}, {
		.rev = ADRENO_REV(5, 3, 0, ANY_ID),
		.rev = ADRENO_REV(5, 3, 0, 2),
		.revn = 530,
		.revn = 530,
		.name = "A530",
		.name = "A530",
		.pm4fw = "a530_pm4.fw",
		.pm4fw = "a530_pm4.fw",
		.pfpfw = "a530_pfp.fw",
		.pfpfw = "a530_pfp.fw",
		.gmem = SZ_1M,
		.gmem = SZ_1M,
		.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
			ADRENO_QUIRK_FAULT_DETECT_MASK,
		.init = a5xx_gpu_init,
		.init = a5xx_gpu_init,
		.gpmufw = "a530v3_gpmu.fw2",
		.gpmufw = "a530v3_gpmu.fw2",
	},
	},
@@ -181,22 +183,51 @@ static void set_gpu_pdev(struct drm_device *dev,
	priv->gpu_pdev = pdev;
	priv->gpu_pdev = pdev;
}
}


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

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


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


	if (!config.fast_rate) {
	if (!config.fast_rate) {
		dev_err(dev, "could not find clk rates\n");
		dev_warn(dev, "could not find clk rates\n");
		return -ENXIO;
		/* 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;
	dev->platform_data = &config;
	set_gpu_pdev(dev_get_drvdata(master), to_platform_device(dev));
	set_gpu_pdev(dev_get_drvdata(master), to_platform_device(dev));
	return 0;
	return 0;
@@ -260,6 +289,7 @@ static int adreno_remove(struct platform_device *pdev)
}
}


static const struct of_device_id dt_match[] = {
static const struct of_device_id dt_match[] = {
	{ .compatible = "qcom,adreno" },
	{ .compatible = "qcom,adreno-3xx" },
	{ .compatible = "qcom,adreno-3xx" },
	/* for backwards compat w/ downstream kgsl DT files: */
	/* for backwards compat w/ downstream kgsl DT files: */
	{ .compatible = "qcom,kgsl-3d0" },
	{ .compatible = "qcom,kgsl-3d0" },
Loading