Commit e906d7bd authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-next' of git://people.freedesktop.org/~robclark/linux into drm-next

Merge the MSM driver from Rob Clark
* 'drm-next' of git://people.freedesktop.org/~robclark/linux:
  drm/msm: add basic hangcheck/recovery mechanism
  drm/msm: add a3xx gpu support
  drm/msm: add register definitions for gpu
  drm/msm: basic KMS driver for snapdragon
  drm/msm: add register definitions
parents acb46527 bd6f82d8
......@@ -223,3 +223,5 @@ source "drivers/gpu/drm/omapdrm/Kconfig"
source "drivers/gpu/drm/tilcdc/Kconfig"
source "drivers/gpu/drm/qxl/Kconfig"
source "drivers/gpu/drm/msm/Kconfig"
......@@ -54,4 +54,5 @@ obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
obj-$(CONFIG_DRM_OMAP) += omapdrm/
obj-$(CONFIG_DRM_TILCDC) += tilcdc/
obj-$(CONFIG_DRM_QXL) += qxl/
obj-$(CONFIG_DRM_MSM) += msm/
obj-y += i2c/
config DRM_MSM
tristate "MSM DRM"
depends on DRM
depends on ARCH_MSM
depends on ARCH_MSM8960
select DRM_KMS_HELPER
select SHMEM
select TMPFS
default y
help
DRM/KMS driver for MSM/snapdragon.
config DRM_MSM_FBDEV
bool "Enable legacy fbdev support for MSM modesetting driver"
depends on DRM_MSM
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
default y
help
Choose this option if you have a need for the legacy fbdev
support. Note that this support also provide the linux console
support on top of the MSM modesetting driver.
config DRM_MSM_REGISTER_LOGGING
bool "MSM DRM register logging"
depends on DRM_MSM
default n
help
Compile in support for logging register reads/writes in a format
that can be parsed by envytools demsm tool. If enabled, register
logging can be switched on via msm.reglog=y module param.
ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/msm
ifeq (, $(findstring -W,$(EXTRA_CFLAGS)))
ccflags-y += -Werror
endif
msm-y := \
adreno/adreno_gpu.o \
adreno/a3xx_gpu.o \
hdmi/hdmi.o \
hdmi/hdmi_connector.o \
hdmi/hdmi_i2c.o \
hdmi/hdmi_phy_8960.o \
hdmi/hdmi_phy_8x60.o \
mdp4/mdp4_crtc.o \
mdp4/mdp4_dtv_encoder.o \
mdp4/mdp4_format.o \
mdp4/mdp4_irq.o \
mdp4/mdp4_kms.o \
mdp4/mdp4_plane.o \
msm_connector.o \
msm_drv.o \
msm_fb.o \
msm_gem.o \
msm_gem_submit.o \
msm_gpu.o \
msm_ringbuffer.o
msm-$(CONFIG_DRM_MSM_FBDEV) += msm_fbdev.o
obj-$(CONFIG_DRM_MSM) += msm.o
NOTES about msm drm/kms driver:
In the current snapdragon SoC's, we have (at least) 3 different
display controller blocks at play:
+ MDP3 - ?? seems to be what is on geeksphone peak device
+ MDP4 - S3 (APQ8060, touchpad), S4-pro (APQ8064, nexus4 & ifc6410)
+ MDSS - snapdragon 800
(I don't have a completely clear picture on which display controller
maps to which part #)
Plus a handful of blocks around them for HDMI/DSI/etc output.
And on gpu side of things:
+ zero, one, or two 2d cores (z180)
+ and either a2xx or a3xx 3d core.
But, HDMI/DSI/etc blocks seem like they can be shared across multiple
display controller blocks. And I for sure don't want to have to deal
with N different kms devices from xf86-video-freedreno. Plus, it
seems like we can do some clever tricks like use GPU to trigger
pageflip after rendering completes (ie. have the kms/crtc code build
up gpu cmdstream to update scanout and write FLUSH register after).
So, the approach is one drm driver, with some modularity. Different
'struct msm_kms' implementations, depending on display controller.
And one or more 'struct msm_gpu' for the various different gpu sub-
modules.
(Second part is not implemented yet. So far this is just basic KMS
driver, and not exposing any custom ioctls to userspace for now.)
The kms module provides the plane, crtc, and encoder objects, and
loads whatever connectors are appropriate.
For MDP4, the mapping is:
plane -> PIPE{RGBn,VGn} \
crtc -> OVLP{n} + DMA{P,S,E} (??) |-> MDP "device"
encoder -> DTV/LCDC/DSI (within MDP4) /
connector -> HDMI/DSI/etc --> other device(s)
Since the irq's that drm core mostly cares about are vblank/framedone,
we'll let msm_mdp4_kms provide the irq install/uninstall/etc functions
and treat the MDP4 block's irq as "the" irq. Even though the connectors
may have their own irqs which they install themselves. For this reason
the display controller is the "master" device.
Each connector probably ends up being a separate device, just for the
logistics of finding/mapping io region, irq, etc. Idealy we would
have a better way than just stashing the platform device in a global
(ie. like DT super-node.. but I don't have any snapdragon hw yet that
is using DT).
Note that so far I've not been able to get any docs on the hw, and it
seems that access to such docs would prevent me from working on the
freedreno gallium driver. So there may be some mistakes in register
names (I had to invent a few, since no sufficient hint was given in
the downstream android fbdev driver), bitfield sizes, etc. My current
state of understanding the registers is given in the envytools rnndb
files at:
https://github.com/freedreno/envytools/tree/master/rnndb
(the mdp4/hdmi/dsi directories)
These files are used both for a parser tool (in the same tree) to
parse logged register reads/writes (both from downstream android fbdev
driver, and this driver with register logging enabled), as well as to
generate the register level headers.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __A3XX_GPU_H__
#define __A3XX_GPU_H__
#include "adreno_gpu.h"
#include "a3xx.xml.h"
struct a3xx_gpu {
struct adreno_gpu base;
struct platform_device *pdev;
};
#define to_a3xx_gpu(x) container_of(x, struct a3xx_gpu, base)
#endif /* __A3XX_GPU_H__ */
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ADRENO_GPU_H__
#define __ADRENO_GPU_H__
#include <linux/firmware.h>
#include "msm_gpu.h"
#include "adreno_common.xml.h"
#include "adreno_pm4.xml.h"
struct adreno_rev {
uint8_t core;
uint8_t major;
uint8_t minor;
uint8_t patchid;
};
#define ADRENO_REV(core, major, minor, patchid) \
((struct adreno_rev){ core, major, minor, patchid })
struct adreno_gpu_funcs {
struct msm_gpu_funcs base;
};
struct adreno_info;
struct adreno_rbmemptrs {
volatile uint32_t rptr;
volatile uint32_t wptr;
volatile uint32_t fence;
};
struct adreno_gpu {
struct msm_gpu base;
struct adreno_rev rev;
const struct adreno_info *info;
uint32_t revn; /* numeric revision name */
const struct adreno_gpu_funcs *funcs;
/* firmware: */
const struct firmware *pm4, *pfp;
/* ringbuffer rptr/wptr: */
// TODO should this be in msm_ringbuffer? I think it would be
// different for z180..
struct adreno_rbmemptrs *memptrs;
struct drm_gem_object *memptrs_bo;
uint32_t memptrs_iova;
};
#define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base)
/* platform config data (ie. from DT, or pdata) */
struct adreno_platform_config {
struct adreno_rev rev;
uint32_t fast_rate, slow_rate, bus_freq;
};
#define ADRENO_IDLE_TIMEOUT (20 * 1000)
static inline bool adreno_is_a3xx(struct adreno_gpu *gpu)
{
return (gpu->revn >= 300) && (gpu->revn < 400);
}
static inline bool adreno_is_a305(struct adreno_gpu *gpu)
{
return gpu->revn == 305;
}
static inline bool adreno_is_a320(struct adreno_gpu *gpu)
{
return gpu->revn == 320;
}
static inline bool adreno_is_a330(struct adreno_gpu *gpu)
{
return gpu->revn == 330;
}
int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value);
int adreno_hw_init(struct msm_gpu *gpu);
uint32_t adreno_last_fence(struct msm_gpu *gpu);
void adreno_recover(struct msm_gpu *gpu);
int adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
struct msm_file_private *ctx);
void adreno_flush(struct msm_gpu *gpu);
void adreno_idle(struct msm_gpu *gpu);
#ifdef CONFIG_DEBUG_FS
void adreno_show(struct msm_gpu *gpu, struct seq_file *m);
#endif
void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords);
int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs,
struct adreno_rev rev);
void adreno_gpu_cleanup(struct adreno_gpu *gpu);
/* ringbuffer helpers (the parts that are adreno specific) */
static inline void
OUT_PKT0(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt)
{
adreno_wait_ring(ring->gpu, cnt+1);
OUT_RING(ring, CP_TYPE0_PKT | ((cnt-1) << 16) | (regindx & 0x7FFF));
}
/* no-op packet: */
static inline void
OUT_PKT2(struct msm_ringbuffer *ring)
{
adreno_wait_ring(ring->gpu, 1);
OUT_RING(ring, CP_TYPE2_PKT);
}
static inline void
OUT_PKT3(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt)
{
adreno_wait_ring(ring->gpu, cnt+1);
OUT_RING(ring, CP_TYPE3_PKT | ((cnt-1) << 16) | ((opcode & 0xFF) << 8));
}
#endif /* __ADRENO_GPU_H__ */
This diff is collapsed.
This diff is collapsed.
#ifndef MMSS_CC_XML
#define MMSS_CC_XML
/* Autogenerated file, DO NOT EDIT manually!
This file was generated by the rules-ng-ng headergen tool in this git repository:
http://0x04.net/cgit/index.cgi/rules-ng-ng
git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 595 bytes, from 2013-07-05 19:21:12)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml ( 19332 bytes, from 2013-08-16 22:16:36)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 19288 bytes, from 2013-08-11 18:14:15)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
enum mmss_cc_clk {
CLK = 0,
PCLK = 1,
};
#define REG_MMSS_CC_AHB 0x00000008
static inline uint32_t __offset_CLK(enum mmss_cc_clk idx)
{
switch (idx) {
case CLK: return 0x0000004c;
case PCLK: return 0x00000130;
default: return INVALID_IDX(idx);
}
}
static inline uint32_t REG_MMSS_CC_CLK(enum mmss_cc_clk i0) { return 0x00000000 + __offset_CLK(i0); }
static inline uint32_t REG_MMSS_CC_CLK_CC(enum mmss_cc_clk i0) { return 0x00000000 + __offset_CLK(i0); }
#define MMSS_CC_CLK_CC_CLK_EN 0x00000001
#define MMSS_CC_CLK_CC_ROOT_EN 0x00000004
#define MMSS_CC_CLK_CC_MND_EN 0x00000020
#define MMSS_CC_CLK_CC_MND_MODE__MASK 0x000000c0
#define MMSS_CC_CLK_CC_MND_MODE__SHIFT 6
static inline uint32_t MMSS_CC_CLK_CC_MND_MODE(uint32_t val)
{
return ((val) << MMSS_CC_CLK_CC_MND_MODE__SHIFT) & MMSS_CC_CLK_CC_MND_MODE__MASK;
}
#define MMSS_CC_CLK_CC_PMXO_SEL__MASK 0x00000300
#define MMSS_CC_CLK_CC_PMXO_SEL__SHIFT 8
static inline uint32_t MMSS_CC_CLK_CC_PMXO_SEL(uint32_t val)
{
return ((val) << MMSS_CC_CLK_CC_PMXO_SEL__SHIFT) & MMSS_CC_CLK_CC_PMXO_SEL__MASK;
}
static inline uint32_t REG_MMSS_CC_CLK_MD(enum mmss_cc_clk i0) { return 0x00000004 + __offset_CLK(i0); }
#define MMSS_CC_CLK_MD_D__MASK 0x000000ff
#define MMSS_CC_CLK_MD_D__SHIFT 0
static inline uint32_t MMSS_CC_CLK_MD_D(uint32_t val)
{
return ((val) << MMSS_CC_CLK_MD_D__SHIFT) & MMSS_CC_CLK_MD_D__MASK;
}
#define MMSS_CC_CLK_MD_M__MASK 0x0000ff00
#define MMSS_CC_CLK_MD_M__SHIFT 8
static inline uint32_t MMSS_CC_CLK_MD_M(uint32_t val)
{
return ((val) << MMSS_CC_CLK_MD_M__SHIFT) & MMSS_CC_CLK_MD_M__MASK;
}
static inline uint32_t REG_MMSS_CC_CLK_NS(enum mmss_cc_clk i0) { return 0x00000008 + __offset_CLK(i0); }
#define MMSS_CC_CLK_NS_SRC__MASK 0x0000000f
#define MMSS_CC_CLK_NS_SRC__SHIFT 0
static inline uint32_t MMSS_CC_CLK_NS_SRC(uint32_t val)
{
return ((val) << MMSS_CC_CLK_NS_SRC__SHIFT) & MMSS_CC_CLK_NS_SRC__MASK;
}
#define MMSS_CC_CLK_NS_PRE_DIV_FUNC__MASK 0x00fff000
#define MMSS_CC_CLK_NS_PRE_DIV_FUNC__SHIFT 12
static inline uint32_t MMSS_CC_CLK_NS_PRE_DIV_FUNC(uint32_t val)
{
return ((val) << MMSS_CC_CLK_NS_PRE_DIV_FUNC__SHIFT) & MMSS_CC_CLK_NS_PRE_DIV_FUNC__MASK;
}
#define MMSS_CC_CLK_NS_VAL__MASK 0xff000000
#define MMSS_CC_CLK_NS_VAL__SHIFT 24
static inline uint32_t MMSS_CC_CLK_NS_VAL(uint32_t val)
{
return ((val) << MMSS_CC_CLK_NS_VAL__SHIFT) & MMSS_CC_CLK_NS_VAL__MASK;
}
#endif /* MMSS_CC_XML */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -16,3 +16,4 @@ header-y += sis_drm.h
header-y += tegra_drm.h
header-y += via_drm.h
header-y += vmwgfx_drm.h
header-y += msm_drm.h
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment