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

Pretty small pull this time around for msm.  Adds some useful debugfs
I'd been carrying around on a branch for a while, plus few fixes.  And
Kconfig update for the great ARCH_MSM -> ARCH_QCOM split.

* 'msm-next' of git://people.freedesktop.org/~robclark/linux:
  drm/msm: use correct gfp flag for vram allocation
  drm/msm/mdp5: fix error return value
  drm/msm: remove redundant private plane cleanup
  drm/msm: add perf logging debugfs
  drm/msm: add rd logging debugfs
  drm/msm: update for ARCH_MSM -> ARCH_QCOM
  drm/msm/hdmi: use gpio and HPD polling
  drm/msm/mdp5: fix crash in error/unload paths
  • Loading branch information
Dave Airlie committed Jun 4, 2014
2 parents 04381b9 + 543d301 commit 1c404d8
Show file tree
Hide file tree
Showing 16 changed files with 884 additions and 39 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/msm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ config DRM_MSM
tristate "MSM DRM"
depends on DRM
depends on MSM_IOMMU
depends on ARCH_MSM8960 || (ARM && COMPILE_TEST)
depends on ARCH_QCOM || (ARM && COMPILE_TEST)
select DRM_KMS_HELPER
select SHMEM
select TMPFS
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/msm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ msm-y := \
msm_gem_submit.o \
msm_gpu.o \
msm_iommu.o \
msm_perf.o \
msm_rd.o \
msm_ringbuffer.o

msm-$(CONFIG_DRM_MSM_FBDEV) += msm_fbdev.o
Expand Down
20 changes: 15 additions & 5 deletions drivers/gpu/drm/msm/adreno/a3xx_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,11 @@ static int a3xx_hw_init(struct msm_gpu *gpu)
/* Turn on performance counters: */
gpu_write(gpu, REG_A3XX_RBBM_PERFCTR_CTL, 0x01);

/* Set SP perfcounter 7 to count SP_FS_FULL_ALU_INSTRUCTIONS
* we will use this to augment our hang detection:
*/
gpu_write(gpu, REG_A3XX_SP_PERFCOUNTER7_SELECT,
SP_FS_FULL_ALU_INSTRUCTIONS);
/* Enable the perfcntrs that we use.. */
for (i = 0; i < gpu->num_perfcntrs; i++) {
const struct msm_gpu_perfcntr *perfcntr = &gpu->perfcntrs[i];
gpu_write(gpu, perfcntr->select_reg, perfcntr->select_val);
}

gpu_write(gpu, REG_A3XX_RBBM_INT_0_MASK, A3XX_INT0_MASK);

Expand Down Expand Up @@ -465,6 +465,13 @@ static const struct adreno_gpu_funcs funcs = {
},
};

static const struct msm_gpu_perfcntr perfcntrs[] = {
{ REG_A3XX_SP_PERFCOUNTER6_SELECT, REG_A3XX_RBBM_PERFCTR_SP_6_LO,
SP_ALU_ACTIVE_CYCLES, "ALUACTIVE" },
{ REG_A3XX_SP_PERFCOUNTER7_SELECT, REG_A3XX_RBBM_PERFCTR_SP_7_LO,
SP_FS_FULL_ALU_INSTRUCTIONS, "ALUFULL" },
};

struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
{
struct a3xx_gpu *a3xx_gpu = NULL;
Expand Down Expand Up @@ -504,6 +511,9 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
DBG("fast_rate=%u, slow_rate=%u, bus_freq=%u",
gpu->fast_rate, gpu->slow_rate, gpu->bus_freq);

gpu->perfcntrs = perfcntrs;
gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs);

ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, config->rev);
if (ret)
goto fail;
Expand Down
52 changes: 33 additions & 19 deletions drivers/gpu/drm/msm/hdmi/hdmi_connector.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,36 +247,49 @@ void hdmi_connector_irq(struct drm_connector *connector)
}
}

static enum drm_connector_status detect_reg(struct hdmi *hdmi)
{
uint32_t hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
connector_status_connected : connector_status_disconnected;
}

static enum drm_connector_status detect_gpio(struct hdmi *hdmi)
{
const struct hdmi_platform_config *config = hdmi->config;
return gpio_get_value(config->hpd_gpio) ?
connector_status_connected :
connector_status_disconnected;
}

static enum drm_connector_status hdmi_connector_detect(
struct drm_connector *connector, bool force)
{
struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
struct hdmi *hdmi = hdmi_connector->hdmi;
const struct hdmi_platform_config *config = hdmi->config;
uint32_t hpd_int_status;
enum drm_connector_status stat_gpio, stat_reg;
int retry = 20;

hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
do {
stat_gpio = detect_gpio(hdmi);
stat_reg = detect_reg(hdmi);

/* sense seems to in some cases be momentarily de-asserted, don't
* let that trick us into thinking the monitor is gone:
*/
while (retry-- && !(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED)) {
/* hdmi debounce logic seems to get stuck sometimes,
* read directly the gpio to get a second opinion:
*/
if (gpio_get_value(config->hpd_gpio)) {
DBG("gpio tells us we are connected!");
hpd_int_status |= HDMI_HPD_INT_STATUS_CABLE_DETECTED;
if (stat_gpio == stat_reg)
break;
}

mdelay(10);
hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
DBG("status=%08x", hpd_int_status);
} while (--retry);

/* the status we get from reading gpio seems to be more reliable,
* so trust that one the most if we didn't manage to get hdmi and
* gpio status to agree:
*/
if (stat_gpio != stat_reg) {
DBG("HDMI_HPD_INT_STATUS tells us: %d", stat_reg);
DBG("hpd gpio tells us: %d", stat_gpio);
}

return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
connector_status_connected : connector_status_disconnected;
return stat_gpio;
}

static void hdmi_connector_destroy(struct drm_connector *connector)
Expand Down Expand Up @@ -389,7 +402,8 @@ struct drm_connector *hdmi_connector_init(struct hdmi *hdmi)
DRM_MODE_CONNECTOR_HDMIA);
drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);

connector->polled = DRM_CONNECTOR_POLL_HPD;
connector->polled = DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT;

connector->interlace_allowed = 1;
connector->doublescan_allowed = 0;
Expand Down
2 changes: 0 additions & 2 deletions drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,6 @@ static void mdp4_crtc_destroy(struct drm_crtc *crtc)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);

mdp4_crtc->plane->funcs->destroy(mdp4_crtc->plane);

drm_crtc_cleanup(crtc);
drm_flip_work_cleanup(&mdp4_crtc->unref_fb_work);
drm_flip_work_cleanup(&mdp4_crtc->unref_cursor_work);
Expand Down
2 changes: 0 additions & 2 deletions drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,6 @@ static void mdp5_crtc_destroy(struct drm_crtc *crtc)
{
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);

mdp5_crtc->plane->funcs->destroy(mdp5_crtc->plane);

drm_crtc_cleanup(crtc);
drm_flip_work_cleanup(&mdp5_crtc->unref_fb_work);

Expand Down
22 changes: 16 additions & 6 deletions drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,22 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
goto fail;
}

ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus_clk") ||
get_clk(pdev, &mdp5_kms->ahb_clk, "iface_clk") ||
get_clk(pdev, &mdp5_kms->src_clk, "core_clk_src") ||
get_clk(pdev, &mdp5_kms->core_clk, "core_clk") ||
get_clk(pdev, &mdp5_kms->lut_clk, "lut_clk") ||
get_clk(pdev, &mdp5_kms->vsync_clk, "vsync_clk");
ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus_clk");
if (ret)
goto fail;
ret = get_clk(pdev, &mdp5_kms->ahb_clk, "iface_clk");
if (ret)
goto fail;
ret = get_clk(pdev, &mdp5_kms->src_clk, "core_clk_src");
if (ret)
goto fail;
ret = get_clk(pdev, &mdp5_kms->core_clk, "core_clk");
if (ret)
goto fail;
ret = get_clk(pdev, &mdp5_kms->lut_clk, "lut_clk");
if (ret)
goto fail;
ret = get_clk(pdev, &mdp5_kms->vsync_clk, "vsync_clk");
if (ret)
goto fail;

Expand Down
5 changes: 4 additions & 1 deletion drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,11 @@ static int mdp5_plane_disable(struct drm_plane *plane)
static void mdp5_plane_destroy(struct drm_plane *plane)
{
struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane);
struct msm_drm_private *priv = plane->dev->dev_private;

if (priv->kms)
mdp5_plane_disable(plane);

mdp5_plane_disable(plane);
drm_plane_cleanup(plane);

kfree(mdp5_plane);
Expand Down
47 changes: 45 additions & 2 deletions drivers/gpu/drm/msm/msm_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
* is bogus, but non-null if allocation succeeded:
*/
p = dma_alloc_attrs(dev->dev, size,
&priv->vram.paddr, 0, &attrs);
&priv->vram.paddr, GFP_KERNEL, &attrs);
if (!p) {
dev_err(dev->dev, "failed to allocate VRAM\n");
priv->vram.paddr = 0;
Expand Down Expand Up @@ -299,6 +299,10 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
priv->fbdev = msm_fbdev_init(dev);
#endif

ret = msm_debugfs_late_init(dev);
if (ret)
goto fail;

drm_kms_helper_poll_init(dev);

return 0;
Expand Down Expand Up @@ -531,6 +535,41 @@ static struct drm_info_list msm_debugfs_list[] = {
{ "fb", show_locked, 0, msm_fb_show },
};

static int late_init_minor(struct drm_minor *minor)
{
int ret;

if (!minor)
return 0;

ret = msm_rd_debugfs_init(minor);
if (ret) {
dev_err(minor->dev->dev, "could not install rd debugfs\n");
return ret;
}

ret = msm_perf_debugfs_init(minor);
if (ret) {
dev_err(minor->dev->dev, "could not install perf debugfs\n");
return ret;
}

return 0;
}

int msm_debugfs_late_init(struct drm_device *dev)
{
int ret;
ret = late_init_minor(dev->primary);
if (ret)
return ret;
ret = late_init_minor(dev->render);
if (ret)
return ret;
ret = late_init_minor(dev->control);
return ret;
}

static int msm_debugfs_init(struct drm_minor *minor)
{
struct drm_device *dev = minor->dev;
Expand All @@ -545,13 +584,17 @@ static int msm_debugfs_init(struct drm_minor *minor)
return ret;
}

return ret;
return 0;
}

static void msm_debugfs_cleanup(struct drm_minor *minor)
{
drm_debugfs_remove_files(msm_debugfs_list,
ARRAY_SIZE(msm_debugfs_list), minor);
if (!minor->dev->dev_private)
return;
msm_rd_debugfs_cleanup(minor);
msm_perf_debugfs_cleanup(minor);
}
#endif

Expand Down
17 changes: 16 additions & 1 deletion drivers/gpu/drm/msm/msm_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include <asm/sizes.h>


#if defined(CONFIG_COMPILE_TEST) && !defined(CONFIG_ARCH_MSM)
#if defined(CONFIG_COMPILE_TEST) && !defined(CONFIG_ARCH_QCOM)
/* stubs we need for compile-test: */
static inline struct device *msm_iommu_get_ctx(const char *ctx_name)
{
Expand All @@ -55,6 +55,9 @@ static inline struct device *msm_iommu_get_ctx(const char *ctx_name)
struct msm_kms;
struct msm_gpu;
struct msm_mmu;
struct msm_rd_state;
struct msm_perf_state;
struct msm_gem_submit;

#define NUM_DOMAINS 2 /* one for KMS, then one per gpu core (?) */

Expand Down Expand Up @@ -82,6 +85,9 @@ struct msm_drm_private {
uint32_t next_fence, completed_fence;
wait_queue_head_t fence_event;

struct msm_rd_state *rd;
struct msm_perf_state *perf;

/* list of GEM objects: */
struct list_head inactive_list;

Expand Down Expand Up @@ -204,6 +210,15 @@ void __exit hdmi_unregister(void);
void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m);
void msm_gem_describe_objects(struct list_head *list, struct seq_file *m);
void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m);
int msm_debugfs_late_init(struct drm_device *dev);
int msm_rd_debugfs_init(struct drm_minor *minor);
void msm_rd_debugfs_cleanup(struct drm_minor *minor);
void msm_rd_dump_submit(struct msm_gem_submit *submit);
int msm_perf_debugfs_init(struct drm_minor *minor);
void msm_perf_debugfs_cleanup(struct drm_minor *minor);
#else
static inline int msm_debugfs_late_init(struct drm_device *dev) { return 0; }
static inline void msm_rd_dump_submit(struct msm_gem_submit *submit) {}
#endif

void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/msm/msm_gem.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ struct msm_gem_submit {
uint32_t type;
uint32_t size; /* in dwords */
uint32_t iova;
uint32_t idx; /* cmdstream buffer idx in bos[] */
} cmd[MAX_CMDS];
struct {
uint32_t flags;
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/msm/msm_gem_submit.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
submit->cmd[i].type = submit_cmd.type;
submit->cmd[i].size = submit_cmd.size / 4;
submit->cmd[i].iova = iova + submit_cmd.submit_offset;
submit->cmd[i].idx = submit_cmd.submit_idx;

if (submit->valid)
continue;
Expand Down
Loading

0 comments on commit 1c404d8

Please sign in to comment.