Merge tag 'drm-misc-next-2017-02-03' of git://anongit.freedesktop.org/git/drm-misc into drm-next
Final 4.11 feature pull request: - sii8520 bridge update from Andrzej - ->release callback, maybe somewhen in the future we'll even get drm_device lifetimes correct! (Chris Wilson) - drm_mm search improvements, and good docs for different search strategies now (Chris) - simplify fbdev emulation init parameters (Gabriel) - bunch of misc things all over ... and the first few patches from our small driver in drm-misc experiment: - cleanups for qxl and bochs from a few different people - dsi support for vc4 (not yet the panel driver, that's under discussion still) from Eric - meson rename to meson-drm to distinguish from other platform drivers (Neil Amstrong) * tag 'drm-misc-next-2017-02-03' of git://anongit.freedesktop.org/git/drm-misc: (47 commits) drm: kselftest for drm_mm and bottom-up allocation drm: Improve drm_mm search (and fix topdown allocation) with rbtrees drm: Fix build when FBDEV_EMULATION is disabled drm: Rely on mode_config data for fb_helper initialization drm: Provide a driver hook for drm_dev_release() drm: meson: rename driver name to meson-drm drm: meson: rename module name to meson-drm drm/bridge/sii8620: enable interlace modes drm/bridge/sii8620: enable MHL3 mode if possible drm/bridge/sii8620: add HSIC initialization code drm/bridge/sii8620: improve gen2 write burst IRQ routine drm/bridge/sii8620: send EMSC features on request drm/bridge/sii8620: rewrite hdmi start sequence drm/bridge/mhl: add MHL3 infoframe related definitions drm/bridge/sii8620: fix disconnect sequence drm/bridge/sii8620: split EDID read and write code drm/bridge/sii8620: add delay during cbus reset drm/bridge/sii8620: do not stop MHL output when TMDS input is stopped drm/bridge/sii8620: set gen2 write burst before sending MSC command drm/bridge/sii8620: abstract out sink detection code ...
This commit is contained in:
commit
31f408c8a8
|
@ -56,6 +56,18 @@ Required properties for V3D:
|
|||
- interrupts: The interrupt number
|
||||
See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
|
||||
|
||||
Required properties for DSI:
|
||||
- compatible: Should be "brcm,bcm2835-dsi0" or "brcm,bcm2835-dsi1"
|
||||
- reg: Physical base address and length of the DSI block's registers
|
||||
- interrupts: The interrupt number
|
||||
See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
|
||||
- clocks: a) phy: The DSI PLL clock feeding the DSI analog PHY
|
||||
b) escape: The DSI ESC clock from CPRMAN
|
||||
c) pixel: The DSI pixel clock from CPRMAN
|
||||
- clock-output-names:
|
||||
The 3 clocks output from the DSI analog PHY: dsi[01]_byte,
|
||||
dsi[01]_ddr2, and dsi[01]_ddr
|
||||
|
||||
[1] Documentation/devicetree/bindings/media/video-interfaces.txt
|
||||
|
||||
Example:
|
||||
|
@ -99,6 +111,29 @@ dpi: dpi@7e208000 {
|
|||
};
|
||||
};
|
||||
|
||||
dsi1: dsi@7e700000 {
|
||||
compatible = "brcm,bcm2835-dsi1";
|
||||
reg = <0x7e700000 0x8c>;
|
||||
interrupts = <2 12>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clocks = <&clocks BCM2835_PLLD_DSI1>,
|
||||
<&clocks BCM2835_CLOCK_DSI1E>,
|
||||
<&clocks BCM2835_CLOCK_DSI1P>;
|
||||
clock-names = "phy", "escape", "pixel";
|
||||
|
||||
clock-output-names = "dsi1_byte", "dsi1_ddr2", "dsi1_ddr";
|
||||
|
||||
pitouchscreen: panel@0 {
|
||||
compatible = "raspberrypi,touchscreen";
|
||||
reg = <0>;
|
||||
|
||||
<...>
|
||||
};
|
||||
};
|
||||
|
||||
vec: vec@7e806000 {
|
||||
compatible = "brcm,bcm2835-vec";
|
||||
reg = <0x7e806000 0x1000>;
|
||||
|
|
|
@ -291,10 +291,17 @@ To use :c:func:`drm_gem_mmap()`, drivers must fill the struct
|
|||
:c:type:`struct drm_driver <drm_driver>` gem_vm_ops field
|
||||
with a pointer to VM operations.
|
||||
|
||||
struct vm_operations_struct \*gem_vm_ops struct
|
||||
vm_operations_struct { void (\*open)(struct vm_area_struct \* area);
|
||||
void (\*close)(struct vm_area_struct \* area); int (\*fault)(struct
|
||||
vm_area_struct \*vma, struct vm_fault \*vmf); };
|
||||
The VM operations is a :c:type:`struct vm_operations_struct <vm_operations_struct>`
|
||||
made up of several fields, the more interesting ones being:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct vm_operations_struct {
|
||||
void (*open)(struct vm_area_struct * area);
|
||||
void (*close)(struct vm_area_struct * area);
|
||||
int (*fault)(struct vm_fault *vmf);
|
||||
};
|
||||
|
||||
|
||||
The open and close operations must update the GEM object reference
|
||||
count. Drivers can use the :c:func:`drm_gem_vm_open()` and
|
||||
|
|
|
@ -3970,6 +3970,7 @@ S: Maintained
|
|||
L: linux-media@vger.kernel.org
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
F: drivers/dma-buf/sync_*
|
||||
F: drivers/dma-buf/dma-fence*
|
||||
F: drivers/dma-buf/sw_sync.c
|
||||
F: include/linux/sync_file.h
|
||||
F: include/uapi/linux/sync_file.h
|
||||
|
|
|
@ -374,7 +374,6 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev)
|
|||
&amdgpu_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(adev->ddev, &rfbdev->helper,
|
||||
adev->mode_info.num_crtc,
|
||||
AMDGPUFB_CONN_LIMIT);
|
||||
if (ret) {
|
||||
kfree(rfbdev);
|
||||
|
|
|
@ -97,8 +97,7 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
|
|||
{
|
||||
struct amdgpu_gtt_mgr *mgr = man->priv;
|
||||
struct drm_mm_node *node = mem->mm_node;
|
||||
enum drm_mm_search_flags sflags = DRM_MM_SEARCH_BEST;
|
||||
enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT;
|
||||
enum drm_mm_insert_mode mode;
|
||||
unsigned long fpfn, lpfn;
|
||||
int r;
|
||||
|
||||
|
@ -115,15 +114,14 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
|
|||
else
|
||||
lpfn = man->size;
|
||||
|
||||
if (place && place->flags & TTM_PL_FLAG_TOPDOWN) {
|
||||
sflags = DRM_MM_SEARCH_BELOW;
|
||||
aflags = DRM_MM_CREATE_TOP;
|
||||
}
|
||||
mode = DRM_MM_INSERT_BEST;
|
||||
if (place && place->flags & TTM_PL_FLAG_TOPDOWN)
|
||||
mode = DRM_MM_INSERT_HIGH;
|
||||
|
||||
spin_lock(&mgr->lock);
|
||||
r = drm_mm_insert_node_in_range_generic(&mgr->mm, node, mem->num_pages,
|
||||
mem->page_alignment, 0,
|
||||
fpfn, lpfn, sflags, aflags);
|
||||
r = drm_mm_insert_node_in_range(&mgr->mm, node,
|
||||
mem->num_pages, mem->page_alignment, 0,
|
||||
fpfn, lpfn, mode);
|
||||
spin_unlock(&mgr->lock);
|
||||
|
||||
if (!r) {
|
||||
|
|
|
@ -97,8 +97,7 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
|
|||
struct amdgpu_vram_mgr *mgr = man->priv;
|
||||
struct drm_mm *mm = &mgr->mm;
|
||||
struct drm_mm_node *nodes;
|
||||
enum drm_mm_search_flags sflags = DRM_MM_SEARCH_DEFAULT;
|
||||
enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT;
|
||||
enum drm_mm_insert_mode mode;
|
||||
unsigned long lpfn, num_nodes, pages_per_node, pages_left;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
@ -121,10 +120,9 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
|
|||
if (!nodes)
|
||||
return -ENOMEM;
|
||||
|
||||
if (place->flags & TTM_PL_FLAG_TOPDOWN) {
|
||||
sflags = DRM_MM_SEARCH_BELOW;
|
||||
aflags = DRM_MM_CREATE_TOP;
|
||||
}
|
||||
mode = DRM_MM_INSERT_BEST;
|
||||
if (place->flags & TTM_PL_FLAG_TOPDOWN)
|
||||
mode = DRM_MM_INSERT_HIGH;
|
||||
|
||||
pages_left = mem->num_pages;
|
||||
|
||||
|
@ -135,13 +133,11 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
|
|||
|
||||
if (pages == pages_per_node)
|
||||
alignment = pages_per_node;
|
||||
else
|
||||
sflags |= DRM_MM_SEARCH_BEST;
|
||||
|
||||
r = drm_mm_insert_node_in_range_generic(mm, &nodes[i], pages,
|
||||
alignment, 0,
|
||||
place->fpfn, lpfn,
|
||||
sflags, aflags);
|
||||
r = drm_mm_insert_node_in_range(mm, &nodes[i],
|
||||
pages, alignment, 0,
|
||||
place->fpfn, lpfn,
|
||||
mode);
|
||||
if (unlikely(r))
|
||||
goto error;
|
||||
|
||||
|
|
|
@ -135,8 +135,7 @@ static int arcpgu_load(struct drm_device *drm)
|
|||
drm_kms_helper_poll_init(drm);
|
||||
|
||||
arcpgu->fbdev = drm_fbdev_cma_init(drm, 16,
|
||||
drm->mode_config.num_crtc,
|
||||
drm->mode_config.num_connector);
|
||||
drm->mode_config.num_connector);
|
||||
if (IS_ERR(arcpgu->fbdev)) {
|
||||
ret = PTR_ERR(arcpgu->fbdev);
|
||||
arcpgu->fbdev = NULL;
|
||||
|
|
|
@ -349,7 +349,7 @@ static int hdlcd_drm_bind(struct device *dev)
|
|||
drm_mode_config_reset(drm);
|
||||
drm_kms_helper_poll_init(drm);
|
||||
|
||||
hdlcd->fbdev = drm_fbdev_cma_init(drm, 32, drm->mode_config.num_crtc,
|
||||
hdlcd->fbdev = drm_fbdev_cma_init(drm, 32,
|
||||
drm->mode_config.num_connector);
|
||||
|
||||
if (IS_ERR(hdlcd->fbdev)) {
|
||||
|
|
|
@ -457,7 +457,7 @@ static int malidp_bind(struct device *dev)
|
|||
|
||||
drm_mode_config_reset(drm);
|
||||
|
||||
malidp->fbdev = drm_fbdev_cma_init(drm, 32, drm->mode_config.num_crtc,
|
||||
malidp->fbdev = drm_fbdev_cma_init(drm, 32,
|
||||
drm->mode_config.num_connector);
|
||||
|
||||
if (IS_ERR(malidp->fbdev)) {
|
||||
|
|
|
@ -137,7 +137,7 @@ int armada_fbdev_init(struct drm_device *dev)
|
|||
|
||||
drm_fb_helper_prepare(dev, fbh, &armada_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(dev, fbh, 1, 1);
|
||||
ret = drm_fb_helper_init(dev, fbh, 1);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to initialize drm fb helper\n");
|
||||
goto err_fb_helper;
|
||||
|
|
|
@ -148,8 +148,8 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
|
|||
return -ENOSPC;
|
||||
|
||||
mutex_lock(&priv->linear_lock);
|
||||
ret = drm_mm_insert_node(&priv->linear, node, size, align,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
ret = drm_mm_insert_node_generic(&priv->linear, node,
|
||||
size, align, 0, 0);
|
||||
mutex_unlock(&priv->linear_lock);
|
||||
if (ret) {
|
||||
kfree(node);
|
||||
|
|
|
@ -315,8 +315,7 @@ int ast_fbdev_init(struct drm_device *dev)
|
|||
|
||||
drm_fb_helper_prepare(dev, &afbdev->helper, &ast_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(dev, &afbdev->helper,
|
||||
1, 1);
|
||||
ret = drm_fb_helper_init(dev, &afbdev->helper, 1);
|
||||
if (ret)
|
||||
goto free;
|
||||
|
||||
|
|
|
@ -647,7 +647,6 @@ static int atmel_hlcdc_dc_load(struct drm_device *dev)
|
|||
platform_set_drvdata(pdev, dev);
|
||||
|
||||
dc->fbdev = drm_fbdev_cma_init(dev, 24,
|
||||
dev->mode_config.num_crtc,
|
||||
dev->mode_config.num_connector);
|
||||
if (IS_ERR(dc->fbdev))
|
||||
dc->fbdev = NULL;
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
|
||||
#include "bochs.h"
|
||||
|
||||
static int bochs_modeset = -1;
|
||||
module_param_named(modeset, bochs_modeset, int, 0444);
|
||||
MODULE_PARM_DESC(modeset, "enable/disable kernel modesetting");
|
||||
|
||||
static bool enable_fbdev = true;
|
||||
module_param_named(fbdev, enable_fbdev, bool, 0444);
|
||||
MODULE_PARM_DESC(fbdev, "register fbdev device");
|
||||
|
@ -214,6 +218,12 @@ static struct pci_driver bochs_pci_driver = {
|
|||
|
||||
static int __init bochs_init(void)
|
||||
{
|
||||
if (vgacon_text_force() && bochs_modeset == -1)
|
||||
return -EINVAL;
|
||||
|
||||
if (bochs_modeset == 0)
|
||||
return -EINVAL;
|
||||
|
||||
return drm_pci_init(&bochs_driver, &bochs_pci_driver);
|
||||
}
|
||||
|
||||
|
|
|
@ -169,8 +169,7 @@ int bochs_fbdev_init(struct bochs_device *bochs)
|
|||
drm_fb_helper_prepare(bochs->dev, &bochs->fb.helper,
|
||||
&bochs_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(bochs->dev, &bochs->fb.helper,
|
||||
1, 1);
|
||||
ret = drm_fb_helper_init(bochs->dev, &bochs->fb.helper, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -353,7 +353,7 @@
|
|||
#define REG_TTXNUMB 0x0116
|
||||
#define MSK_TTXNUMB_TTX_AFFCTRL_3_0 0xf0
|
||||
#define BIT_TTXNUMB_TTX_COM1_AT_SYNC_WAIT BIT(3)
|
||||
#define MSK_TTXNUMB_TTX_NUMBPS_2_0 0x07
|
||||
#define MSK_TTXNUMB_TTX_NUMBPS 0x07
|
||||
|
||||
/* TDM TX NUMSPISYM, default value: 0x04 */
|
||||
#define REG_TTXSPINUMS 0x0117
|
||||
|
@ -403,12 +403,16 @@
|
|||
|
||||
/* TDM RX Status 2nd, default value: 0x00 */
|
||||
#define REG_TRXSTA2 0x015c
|
||||
#define MSK_TDM_SYNCHRONIZED 0xc0
|
||||
#define VAL_TDM_SYNCHRONIZED 0x80
|
||||
|
||||
/* TDM RX INT Low, default value: 0x00 */
|
||||
#define REG_TRXINTL 0x0163
|
||||
|
||||
/* TDM RX INT High, default value: 0x00 */
|
||||
#define REG_TRXINTH 0x0164
|
||||
#define BIT_TDM_INTR_SYNC_DATA BIT(0)
|
||||
#define BIT_TDM_INTR_SYNC_WAIT BIT(1)
|
||||
|
||||
/* TDM RX INTMASK High, default value: 0x00 */
|
||||
#define REG_TRXINTMH 0x0166
|
||||
|
@ -429,12 +433,14 @@
|
|||
|
||||
/* HSIC Keeper, default value: 0x00 */
|
||||
#define REG_KEEPER 0x0181
|
||||
#define MSK_KEEPER_KEEPER_MODE_1_0 0x03
|
||||
#define MSK_KEEPER_MODE 0x03
|
||||
#define VAL_KEEPER_MODE_HOST 0
|
||||
#define VAL_KEEPER_MODE_DEVICE 2
|
||||
|
||||
/* HSIC Flow Control General, default value: 0x02 */
|
||||
#define REG_FCGC 0x0183
|
||||
#define BIT_FCGC_HSIC_FC_HOSTMODE BIT(1)
|
||||
#define BIT_FCGC_HSIC_FC_ENABLE BIT(0)
|
||||
#define BIT_FCGC_HSIC_HOSTMODE BIT(1)
|
||||
#define BIT_FCGC_HSIC_ENABLE BIT(0)
|
||||
|
||||
/* HSIC Flow Control CTR13, default value: 0xfc */
|
||||
#define REG_FCCTR13 0x0191
|
||||
|
@ -841,6 +847,8 @@
|
|||
#define MSK_MHL_DP_CTL7_DT_DRV_VBIAS_CASCTL 0xf0
|
||||
#define MSK_MHL_DP_CTL7_DT_DRV_IREF_CTL 0x0f
|
||||
|
||||
#define REG_MHL_DP_CTL8 0x0352
|
||||
|
||||
/* Tx Zone Ctl1, default value: 0x00 */
|
||||
#define REG_TX_ZONE_CTL1 0x0361
|
||||
#define VAL_TX_ZONE_CTL1_TX_ZONE_CTRL_MODE 0x08
|
||||
|
@ -1078,16 +1086,26 @@
|
|||
|
||||
/* TPI Info Frame Select, default value: 0x00 */
|
||||
#define REG_TPI_INFO_FSEL 0x06bf
|
||||
#define BIT_TPI_INFO_FSEL_TPI_INFO_EN BIT(7)
|
||||
#define BIT_TPI_INFO_FSEL_TPI_INFO_RPT BIT(6)
|
||||
#define BIT_TPI_INFO_FSEL_TPI_INFO_READ_FLAG BIT(5)
|
||||
#define MSK_TPI_INFO_FSEL_TPI_INFO_SEL 0x07
|
||||
#define BIT_TPI_INFO_FSEL_EN BIT(7)
|
||||
#define BIT_TPI_INFO_FSEL_RPT BIT(6)
|
||||
#define BIT_TPI_INFO_FSEL_READ_FLAG BIT(5)
|
||||
#define MSK_TPI_INFO_FSEL_PKT 0x07
|
||||
#define VAL_TPI_INFO_FSEL_AVI 0x00
|
||||
#define VAL_TPI_INFO_FSEL_SPD 0x01
|
||||
#define VAL_TPI_INFO_FSEL_AUD 0x02
|
||||
#define VAL_TPI_INFO_FSEL_MPG 0x03
|
||||
#define VAL_TPI_INFO_FSEL_GEN 0x04
|
||||
#define VAL_TPI_INFO_FSEL_GEN2 0x05
|
||||
#define VAL_TPI_INFO_FSEL_VSI 0x06
|
||||
|
||||
/* TPI Info Byte #0, default value: 0x00 */
|
||||
#define REG_TPI_INFO_B0 0x06c0
|
||||
|
||||
/* CoC Status, default value: 0x00 */
|
||||
#define REG_COC_STAT_0 0x0700
|
||||
#define BIT_COC_STAT_0_PLL_LOCKED BIT(7)
|
||||
#define MSK_COC_STAT_0_FSM_STATE 0x0f
|
||||
|
||||
#define REG_COC_STAT_1 0x0701
|
||||
#define REG_COC_STAT_2 0x0702
|
||||
#define REG_COC_STAT_3 0x0703
|
||||
|
@ -1282,14 +1300,14 @@
|
|||
|
||||
/* MDT Transmit Control, default value: 0x70 */
|
||||
#define REG_MDT_XMIT_CTRL 0x0588
|
||||
#define BIT_MDT_XMIT_CTRL_MDT_XMIT_EN BIT(7)
|
||||
#define BIT_MDT_XMIT_CTRL_MDT_XMIT_CMD_MERGE_EN BIT(6)
|
||||
#define BIT_MDT_XMIT_CTRL_MDT_XMIT_FIXED_BURST_LEN BIT(5)
|
||||
#define BIT_MDT_XMIT_CTRL_MDT_XMIT_FIXED_AID BIT(4)
|
||||
#define BIT_MDT_XMIT_CTRL_MDT_XMIT_SINGLE_RUN_EN BIT(3)
|
||||
#define BIT_MDT_XMIT_CTRL_MDT_CLR_ABORT_WAIT BIT(2)
|
||||
#define BIT_MDT_XMIT_CTRL_MDT_XFIFO_CLR_ALL BIT(1)
|
||||
#define BIT_MDT_XMIT_CTRL_MDT_XFIFO_CLR_CUR BIT(0)
|
||||
#define BIT_MDT_XMIT_CTRL_EN BIT(7)
|
||||
#define BIT_MDT_XMIT_CTRL_CMD_MERGE_EN BIT(6)
|
||||
#define BIT_MDT_XMIT_CTRL_FIXED_BURST_LEN BIT(5)
|
||||
#define BIT_MDT_XMIT_CTRL_FIXED_AID BIT(4)
|
||||
#define BIT_MDT_XMIT_CTRL_SINGLE_RUN_EN BIT(3)
|
||||
#define BIT_MDT_XMIT_CTRL_CLR_ABORT_WAIT BIT(2)
|
||||
#define BIT_MDT_XMIT_CTRL_XFIFO_CLR_ALL BIT(1)
|
||||
#define BIT_MDT_XMIT_CTRL_XFIFO_CLR_CUR BIT(0)
|
||||
|
||||
/* MDT Receive WRITE Port, default value: 0x00 */
|
||||
#define REG_MDT_XMIT_WRITE_PORT 0x0589
|
||||
|
|
|
@ -289,7 +289,7 @@ int cirrus_fbdev_init(struct cirrus_device *cdev)
|
|||
&cirrus_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(cdev->dev, &gfbdev->helper,
|
||||
cdev->num_crtc, CIRRUSFB_CONN_LIMIT);
|
||||
CIRRUSFB_CONN_LIMIT);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -307,9 +307,8 @@ static s64 __user *get_out_fence_for_crtc(struct drm_atomic_state *state,
|
|||
* @state: the CRTC whose incoming state to update
|
||||
* @mode: kernel-internal mode to use for the CRTC, or NULL to disable
|
||||
*
|
||||
* Set a mode (originating from the kernel) on the desired CRTC state. Does
|
||||
* not change any other state properties, including enable, active, or
|
||||
* mode_changed.
|
||||
* Set a mode (originating from the kernel) on the desired CRTC state and update
|
||||
* the enable property.
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, error code on failure. Cannot return -EDEADLK.
|
||||
|
|
|
@ -87,6 +87,30 @@
|
|||
* "GAMMA_LUT" property above.
|
||||
*/
|
||||
|
||||
/**
|
||||
* drm_color_lut_extract - clamp and round LUT entries
|
||||
* @user_input: input value
|
||||
* @bit_precision: number of bits the hw LUT supports
|
||||
*
|
||||
* Extract a degamma/gamma LUT value provided by user (in the form of
|
||||
* &drm_color_lut entries) and round it to the precision supported by the
|
||||
* hardware.
|
||||
*/
|
||||
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision)
|
||||
{
|
||||
uint32_t val = user_input;
|
||||
uint32_t max = 0xffff >> (16 - bit_precision);
|
||||
|
||||
/* Round only if we're not using full precision. */
|
||||
if (bit_precision < 16) {
|
||||
val += 1UL << (16 - bit_precision - 1);
|
||||
val >>= 16 - bit_precision;
|
||||
}
|
||||
|
||||
return clamp_val(val, 0, max);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_color_lut_extract);
|
||||
|
||||
/**
|
||||
* drm_crtc_enable_color_mgmt - enable color management properties
|
||||
* @crtc: DRM CRTC
|
||||
|
|
|
@ -207,3 +207,6 @@ int drm_mode_cursor2_ioctl(struct drm_device *dev,
|
|||
void *data, struct drm_file *file_priv);
|
||||
int drm_mode_page_flip_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
|
||||
/* drm_edid.c */
|
||||
void drm_mode_fixup_1366x768(struct drm_display_mode *mode);
|
||||
|
|
|
@ -465,7 +465,10 @@ static void drm_fs_inode_free(struct inode *inode)
|
|||
* that do embed &struct drm_device it must be placed first in the overall
|
||||
* structure, and the overall structure must be allocated using kmalloc(): The
|
||||
* drm core's release function unconditionally calls kfree() on the @dev pointer
|
||||
* when the final reference is released.
|
||||
* when the final reference is released. To override this behaviour, and so
|
||||
* allow embedding of the drm_device inside the driver's device struct at an
|
||||
* arbitrary offset, you must supply a &drm_driver.release callback and control
|
||||
* the finalization explicitly.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, or error code on failure.
|
||||
|
@ -552,6 +555,41 @@ err_free:
|
|||
}
|
||||
EXPORT_SYMBOL(drm_dev_init);
|
||||
|
||||
/**
|
||||
* drm_dev_fini - Finalize a dead DRM device
|
||||
* @dev: DRM device
|
||||
*
|
||||
* Finalize a dead DRM device. This is the converse to drm_dev_init() and
|
||||
* frees up all data allocated by it. All driver private data should be
|
||||
* finalized first. Note that this function does not free the @dev, that is
|
||||
* left to the caller.
|
||||
*
|
||||
* The ref-count of @dev must be zero, and drm_dev_fini() should only be called
|
||||
* from a &drm_driver.release callback.
|
||||
*/
|
||||
void drm_dev_fini(struct drm_device *dev)
|
||||
{
|
||||
drm_vblank_cleanup(dev);
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_GEM))
|
||||
drm_gem_destroy(dev);
|
||||
|
||||
drm_legacy_ctxbitmap_cleanup(dev);
|
||||
drm_ht_remove(&dev->map_hash);
|
||||
drm_fs_inode_free(dev->anon_inode);
|
||||
|
||||
drm_minor_free(dev, DRM_MINOR_PRIMARY);
|
||||
drm_minor_free(dev, DRM_MINOR_RENDER);
|
||||
drm_minor_free(dev, DRM_MINOR_CONTROL);
|
||||
|
||||
mutex_destroy(&dev->master_mutex);
|
||||
mutex_destroy(&dev->ctxlist_mutex);
|
||||
mutex_destroy(&dev->filelist_mutex);
|
||||
mutex_destroy(&dev->struct_mutex);
|
||||
kfree(dev->unique);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dev_fini);
|
||||
|
||||
/**
|
||||
* drm_dev_alloc - Allocate new DRM device
|
||||
* @driver: DRM driver to allocate device for
|
||||
|
@ -598,25 +636,12 @@ static void drm_dev_release(struct kref *ref)
|
|||
{
|
||||
struct drm_device *dev = container_of(ref, struct drm_device, ref);
|
||||
|
||||
drm_vblank_cleanup(dev);
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_GEM))
|
||||
drm_gem_destroy(dev);
|
||||
|
||||
drm_legacy_ctxbitmap_cleanup(dev);
|
||||
drm_ht_remove(&dev->map_hash);
|
||||
drm_fs_inode_free(dev->anon_inode);
|
||||
|
||||
drm_minor_free(dev, DRM_MINOR_PRIMARY);
|
||||
drm_minor_free(dev, DRM_MINOR_RENDER);
|
||||
drm_minor_free(dev, DRM_MINOR_CONTROL);
|
||||
|
||||
mutex_destroy(&dev->master_mutex);
|
||||
mutex_destroy(&dev->ctxlist_mutex);
|
||||
mutex_destroy(&dev->filelist_mutex);
|
||||
mutex_destroy(&dev->struct_mutex);
|
||||
kfree(dev->unique);
|
||||
kfree(dev);
|
||||
if (dev->driver->release) {
|
||||
dev->driver->release(dev);
|
||||
} else {
|
||||
drm_dev_fini(dev);
|
||||
kfree(dev);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#include <drm/drm_encoder.h>
|
||||
#include <drm/drm_displayid.h>
|
||||
|
||||
#include "drm_crtc_internal.h"
|
||||
|
||||
#define version_greater(edid, maj, min) \
|
||||
(((edid)->version > (maj)) || \
|
||||
((edid)->version == (maj) && (edid)->revision > (min)))
|
||||
|
@ -2153,7 +2155,7 @@ drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid,
|
|||
/* fix up 1366x768 mode from 1368x768;
|
||||
* GFT/CVT can't express 1366 width which isn't dividable by 8
|
||||
*/
|
||||
static void fixup_mode_1366x768(struct drm_display_mode *mode)
|
||||
void drm_mode_fixup_1366x768(struct drm_display_mode *mode)
|
||||
{
|
||||
if (mode->hdisplay == 1368 && mode->vdisplay == 768) {
|
||||
mode->hdisplay = 1366;
|
||||
|
@ -2177,7 +2179,7 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid,
|
|||
if (!newmode)
|
||||
return modes;
|
||||
|
||||
fixup_mode_1366x768(newmode);
|
||||
drm_mode_fixup_1366x768(newmode);
|
||||
if (!mode_in_range(newmode, edid, timing) ||
|
||||
!valid_inferred_mode(connector, newmode)) {
|
||||
drm_mode_destroy(dev, newmode);
|
||||
|
@ -2206,7 +2208,7 @@ drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,
|
|||
if (!newmode)
|
||||
return modes;
|
||||
|
||||
fixup_mode_1366x768(newmode);
|
||||
drm_mode_fixup_1366x768(newmode);
|
||||
if (!mode_in_range(newmode, edid, timing) ||
|
||||
!valid_inferred_mode(connector, newmode)) {
|
||||
drm_mode_destroy(dev, newmode);
|
||||
|
|
|
@ -489,15 +489,14 @@ static const struct drm_fb_helper_funcs drm_fb_cma_helper_funcs = {
|
|||
* drm_fbdev_cma_init_with_funcs() - Allocate and initializes a drm_fbdev_cma struct
|
||||
* @dev: DRM device
|
||||
* @preferred_bpp: Preferred bits per pixel for the device
|
||||
* @num_crtc: Number of CRTCs
|
||||
* @max_conn_count: Maximum number of connectors
|
||||
* @funcs: fb helper functions, in particular a custom dirty() callback
|
||||
*
|
||||
* Returns a newly allocated drm_fbdev_cma struct or a ERR_PTR.
|
||||
*/
|
||||
struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *dev,
|
||||
unsigned int preferred_bpp, unsigned int num_crtc,
|
||||
unsigned int max_conn_count, const struct drm_framebuffer_funcs *funcs)
|
||||
unsigned int preferred_bpp, unsigned int max_conn_count,
|
||||
const struct drm_framebuffer_funcs *funcs)
|
||||
{
|
||||
struct drm_fbdev_cma *fbdev_cma;
|
||||
struct drm_fb_helper *helper;
|
||||
|
@ -514,7 +513,7 @@ struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *dev,
|
|||
|
||||
drm_fb_helper_prepare(dev, helper, &drm_fb_cma_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(dev, helper, num_crtc, max_conn_count);
|
||||
ret = drm_fb_helper_init(dev, helper, max_conn_count);
|
||||
if (ret < 0) {
|
||||
dev_err(dev->dev, "Failed to initialize drm fb helper.\n");
|
||||
goto err_free;
|
||||
|
@ -554,11 +553,11 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_init_with_funcs);
|
|||
* Returns a newly allocated drm_fbdev_cma struct or a ERR_PTR.
|
||||
*/
|
||||
struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev,
|
||||
unsigned int preferred_bpp, unsigned int num_crtc,
|
||||
unsigned int max_conn_count)
|
||||
unsigned int preferred_bpp, unsigned int max_conn_count)
|
||||
{
|
||||
return drm_fbdev_cma_init_with_funcs(dev, preferred_bpp, num_crtc,
|
||||
max_conn_count, &drm_fb_cma_funcs);
|
||||
return drm_fbdev_cma_init_with_funcs(dev, preferred_bpp,
|
||||
max_conn_count,
|
||||
&drm_fb_cma_funcs);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(drm_fbdev_cma_init);
|
||||
|
||||
|
|
|
@ -712,7 +712,6 @@ EXPORT_SYMBOL(drm_fb_helper_prepare);
|
|||
* drm_fb_helper_init - initialize a drm_fb_helper structure
|
||||
* @dev: drm device
|
||||
* @fb_helper: driver-allocated fbdev helper structure to initialize
|
||||
* @crtc_count: maximum number of crtcs to support in this fbdev emulation
|
||||
* @max_conn_count: max connector count
|
||||
*
|
||||
* This allocates the structures for the fbdev helper with the given limits.
|
||||
|
@ -727,9 +726,10 @@ EXPORT_SYMBOL(drm_fb_helper_prepare);
|
|||
*/
|
||||
int drm_fb_helper_init(struct drm_device *dev,
|
||||
struct drm_fb_helper *fb_helper,
|
||||
int crtc_count, int max_conn_count)
|
||||
int max_conn_count)
|
||||
{
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_mode_config *config = &dev->mode_config;
|
||||
int i;
|
||||
|
||||
if (!drm_fbdev_emulation)
|
||||
|
@ -738,11 +738,11 @@ int drm_fb_helper_init(struct drm_device *dev,
|
|||
if (!max_conn_count)
|
||||
return -EINVAL;
|
||||
|
||||
fb_helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
|
||||
fb_helper->crtc_info = kcalloc(config->num_crtc, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
|
||||
if (!fb_helper->crtc_info)
|
||||
return -ENOMEM;
|
||||
|
||||
fb_helper->crtc_count = crtc_count;
|
||||
fb_helper->crtc_count = config->num_crtc;
|
||||
fb_helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_connector *), GFP_KERNEL);
|
||||
if (!fb_helper->connector_info) {
|
||||
kfree(fb_helper->crtc_info);
|
||||
|
@ -751,7 +751,7 @@ int drm_fb_helper_init(struct drm_device *dev,
|
|||
fb_helper->connector_info_alloc_count = dev->mode_config.num_connector;
|
||||
fb_helper->connector_count = 0;
|
||||
|
||||
for (i = 0; i < crtc_count; i++) {
|
||||
for (i = 0; i < fb_helper->crtc_count; i++) {
|
||||
fb_helper->crtc_info[i].mode_set.connectors =
|
||||
kcalloc(max_conn_count,
|
||||
sizeof(struct drm_connector *),
|
||||
|
|
|
@ -97,14 +97,6 @@
|
|||
* locking would be fully redundant.
|
||||
*/
|
||||
|
||||
static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm,
|
||||
u64 size,
|
||||
u64 alignment,
|
||||
unsigned long color,
|
||||
u64 start,
|
||||
u64 end,
|
||||
enum drm_mm_search_flags flags);
|
||||
|
||||
#ifdef CONFIG_DRM_DEBUG_MM
|
||||
#include <linux/stackdepot.h>
|
||||
|
||||
|
@ -226,69 +218,151 @@ static void drm_mm_interval_tree_add_node(struct drm_mm_node *hole_node,
|
|||
&drm_mm_interval_tree_augment);
|
||||
}
|
||||
|
||||
static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
|
||||
struct drm_mm_node *node,
|
||||
u64 size, u64 alignment,
|
||||
unsigned long color,
|
||||
u64 range_start, u64 range_end,
|
||||
enum drm_mm_allocator_flags flags)
|
||||
#define RB_INSERT(root, member, expr) do { \
|
||||
struct rb_node **link = &root.rb_node, *rb = NULL; \
|
||||
u64 x = expr(node); \
|
||||
while (*link) { \
|
||||
rb = *link; \
|
||||
if (x < expr(rb_entry(rb, struct drm_mm_node, member))) \
|
||||
link = &rb->rb_left; \
|
||||
else \
|
||||
link = &rb->rb_right; \
|
||||
} \
|
||||
rb_link_node(&node->member, rb, link); \
|
||||
rb_insert_color(&node->member, &root); \
|
||||
} while (0)
|
||||
|
||||
#define HOLE_SIZE(NODE) ((NODE)->hole_size)
|
||||
#define HOLE_ADDR(NODE) (__drm_mm_hole_node_start(NODE))
|
||||
|
||||
static void add_hole(struct drm_mm_node *node)
|
||||
{
|
||||
struct drm_mm *mm = hole_node->mm;
|
||||
u64 hole_start = drm_mm_hole_node_start(hole_node);
|
||||
u64 hole_end = drm_mm_hole_node_end(hole_node);
|
||||
u64 adj_start = hole_start;
|
||||
u64 adj_end = hole_end;
|
||||
struct drm_mm *mm = node->mm;
|
||||
|
||||
DRM_MM_BUG_ON(!drm_mm_hole_follows(hole_node) || node->allocated);
|
||||
node->hole_size =
|
||||
__drm_mm_hole_node_end(node) - __drm_mm_hole_node_start(node);
|
||||
DRM_MM_BUG_ON(!drm_mm_hole_follows(node));
|
||||
|
||||
if (mm->color_adjust)
|
||||
mm->color_adjust(hole_node, color, &adj_start, &adj_end);
|
||||
RB_INSERT(mm->holes_size, rb_hole_size, HOLE_SIZE);
|
||||
RB_INSERT(mm->holes_addr, rb_hole_addr, HOLE_ADDR);
|
||||
|
||||
adj_start = max(adj_start, range_start);
|
||||
adj_end = min(adj_end, range_end);
|
||||
list_add(&node->hole_stack, &mm->hole_stack);
|
||||
}
|
||||
|
||||
if (flags & DRM_MM_CREATE_TOP)
|
||||
adj_start = adj_end - size;
|
||||
static void rm_hole(struct drm_mm_node *node)
|
||||
{
|
||||
DRM_MM_BUG_ON(!drm_mm_hole_follows(node));
|
||||
|
||||
if (alignment) {
|
||||
u64 rem;
|
||||
list_del(&node->hole_stack);
|
||||
rb_erase(&node->rb_hole_size, &node->mm->holes_size);
|
||||
rb_erase(&node->rb_hole_addr, &node->mm->holes_addr);
|
||||
node->hole_size = 0;
|
||||
|
||||
div64_u64_rem(adj_start, alignment, &rem);
|
||||
if (rem) {
|
||||
if (flags & DRM_MM_CREATE_TOP)
|
||||
adj_start -= rem;
|
||||
else
|
||||
adj_start += alignment - rem;
|
||||
DRM_MM_BUG_ON(drm_mm_hole_follows(node));
|
||||
}
|
||||
|
||||
static inline struct drm_mm_node *rb_hole_size_to_node(struct rb_node *rb)
|
||||
{
|
||||
return rb_entry_safe(rb, struct drm_mm_node, rb_hole_size);
|
||||
}
|
||||
|
||||
static inline struct drm_mm_node *rb_hole_addr_to_node(struct rb_node *rb)
|
||||
{
|
||||
return rb_entry_safe(rb, struct drm_mm_node, rb_hole_addr);
|
||||
}
|
||||
|
||||
static inline u64 rb_hole_size(struct rb_node *rb)
|
||||
{
|
||||
return rb_entry(rb, struct drm_mm_node, rb_hole_size)->hole_size;
|
||||
}
|
||||
|
||||
static struct drm_mm_node *best_hole(struct drm_mm *mm, u64 size)
|
||||
{
|
||||
struct rb_node *best = NULL;
|
||||
struct rb_node **link = &mm->holes_size.rb_node;
|
||||
|
||||
while (*link) {
|
||||
struct rb_node *rb = *link;
|
||||
|
||||
if (size <= rb_hole_size(rb)) {
|
||||
link = &rb->rb_left;
|
||||
best = rb;
|
||||
} else {
|
||||
link = &rb->rb_right;
|
||||
}
|
||||
}
|
||||
|
||||
if (adj_start == hole_start) {
|
||||
hole_node->hole_follows = 0;
|
||||
list_del(&hole_node->hole_stack);
|
||||
return rb_hole_size_to_node(best);
|
||||
}
|
||||
|
||||
static struct drm_mm_node *find_hole(struct drm_mm *mm, u64 addr)
|
||||
{
|
||||
struct drm_mm_node *node = NULL;
|
||||
struct rb_node **link = &mm->holes_addr.rb_node;
|
||||
|
||||
while (*link) {
|
||||
u64 hole_start;
|
||||
|
||||
node = rb_hole_addr_to_node(*link);
|
||||
hole_start = __drm_mm_hole_node_start(node);
|
||||
|
||||
if (addr < hole_start)
|
||||
link = &node->rb_hole_addr.rb_left;
|
||||
else if (addr > hole_start + node->hole_size)
|
||||
link = &node->rb_hole_addr.rb_right;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
node->start = adj_start;
|
||||
node->size = size;
|
||||
node->mm = mm;
|
||||
node->color = color;
|
||||
node->allocated = 1;
|
||||
return node;
|
||||
}
|
||||
|
||||
list_add(&node->node_list, &hole_node->node_list);
|
||||
static struct drm_mm_node *
|
||||
first_hole(struct drm_mm *mm,
|
||||
u64 start, u64 end, u64 size,
|
||||
enum drm_mm_insert_mode mode)
|
||||
{
|
||||
if (RB_EMPTY_ROOT(&mm->holes_size))
|
||||
return NULL;
|
||||
|
||||
drm_mm_interval_tree_add_node(hole_node, node);
|
||||
switch (mode) {
|
||||
default:
|
||||
case DRM_MM_INSERT_BEST:
|
||||
return best_hole(mm, size);
|
||||
|
||||
DRM_MM_BUG_ON(node->start < range_start);
|
||||
DRM_MM_BUG_ON(node->start < adj_start);
|
||||
DRM_MM_BUG_ON(node->start + node->size > adj_end);
|
||||
DRM_MM_BUG_ON(node->start + node->size > range_end);
|
||||
case DRM_MM_INSERT_LOW:
|
||||
return find_hole(mm, start);
|
||||
|
||||
node->hole_follows = 0;
|
||||
if (__drm_mm_hole_node_start(node) < hole_end) {
|
||||
list_add(&node->hole_stack, &mm->hole_stack);
|
||||
node->hole_follows = 1;
|
||||
case DRM_MM_INSERT_HIGH:
|
||||
return find_hole(mm, end);
|
||||
|
||||
case DRM_MM_INSERT_EVICT:
|
||||
return list_first_entry_or_null(&mm->hole_stack,
|
||||
struct drm_mm_node,
|
||||
hole_stack);
|
||||
}
|
||||
}
|
||||
|
||||
save_stack(node);
|
||||
static struct drm_mm_node *
|
||||
next_hole(struct drm_mm *mm,
|
||||
struct drm_mm_node *node,
|
||||
enum drm_mm_insert_mode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
default:
|
||||
case DRM_MM_INSERT_BEST:
|
||||
return rb_hole_size_to_node(rb_next(&node->rb_hole_size));
|
||||
|
||||
case DRM_MM_INSERT_LOW:
|
||||
return rb_hole_addr_to_node(rb_next(&node->rb_hole_addr));
|
||||
|
||||
case DRM_MM_INSERT_HIGH:
|
||||
return rb_hole_addr_to_node(rb_prev(&node->rb_hole_addr));
|
||||
|
||||
case DRM_MM_INSERT_EVICT:
|
||||
node = list_next_entry(node, hole_stack);
|
||||
return &node->hole_stack == &mm->hole_stack ? NULL : node;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -317,21 +391,12 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node)
|
|||
return -ENOSPC;
|
||||
|
||||
/* Find the relevant hole to add our node to */
|
||||
hole = drm_mm_interval_tree_iter_first(&mm->interval_tree,
|
||||
node->start, ~(u64)0);
|
||||
if (hole) {
|
||||
if (hole->start < end)
|
||||
return -ENOSPC;
|
||||
} else {
|
||||
hole = list_entry(drm_mm_nodes(mm), typeof(*hole), node_list);
|
||||
}
|
||||
|
||||
hole = list_last_entry(&hole->node_list, typeof(*hole), node_list);
|
||||
if (!drm_mm_hole_follows(hole))
|
||||
hole = find_hole(mm, node->start);
|
||||
if (!hole)
|
||||
return -ENOSPC;
|
||||
|
||||
adj_start = hole_start = __drm_mm_hole_node_start(hole);
|
||||
adj_end = hole_end = __drm_mm_hole_node_end(hole);
|
||||
adj_end = hole_end = hole_start + hole->hole_size;
|
||||
|
||||
if (mm->color_adjust)
|
||||
mm->color_adjust(hole, node->color, &adj_start, &adj_end);
|
||||
|
@ -340,70 +405,130 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node)
|
|||
return -ENOSPC;
|
||||
|
||||
node->mm = mm;
|
||||
node->allocated = 1;
|
||||
|
||||
list_add(&node->node_list, &hole->node_list);
|
||||
|
||||
drm_mm_interval_tree_add_node(hole, node);
|
||||
node->allocated = true;
|
||||
node->hole_size = 0;
|
||||
|
||||
if (node->start == hole_start) {
|
||||
hole->hole_follows = 0;
|
||||
list_del(&hole->hole_stack);
|
||||
}
|
||||
|
||||
node->hole_follows = 0;
|
||||
if (end != hole_end) {
|
||||
list_add(&node->hole_stack, &mm->hole_stack);
|
||||
node->hole_follows = 1;
|
||||
}
|
||||
rm_hole(hole);
|
||||
if (node->start > hole_start)
|
||||
add_hole(hole);
|
||||
if (end < hole_end)
|
||||
add_hole(node);
|
||||
|
||||
save_stack(node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_reserve_node);
|
||||
|
||||
/**
|
||||
* drm_mm_insert_node_in_range_generic - ranged search for space and insert @node
|
||||
* drm_mm_insert_node_in_range - ranged search for space and insert @node
|
||||
* @mm: drm_mm to allocate from
|
||||
* @node: preallocate node to insert
|
||||
* @size: size of the allocation
|
||||
* @alignment: alignment of the allocation
|
||||
* @color: opaque tag value to use for this node
|
||||
* @start: start of the allowed range for this node
|
||||
* @end: end of the allowed range for this node
|
||||
* @sflags: flags to fine-tune the allocation search
|
||||
* @aflags: flags to fine-tune the allocation behavior
|
||||
* @range_start: start of the allowed range for this node
|
||||
* @range_end: end of the allowed range for this node
|
||||
* @mode: fine-tune the allocation search and placement
|
||||
*
|
||||
* The preallocated @node must be cleared to 0.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, -ENOSPC if there's no suitable hole.
|
||||
*/
|
||||
int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *node,
|
||||
u64 size, u64 alignment,
|
||||
unsigned long color,
|
||||
u64 start, u64 end,
|
||||
enum drm_mm_search_flags sflags,
|
||||
enum drm_mm_allocator_flags aflags)
|
||||
int drm_mm_insert_node_in_range(struct drm_mm * const mm,
|
||||
struct drm_mm_node * const node,
|
||||
u64 size, u64 alignment,
|
||||
unsigned long color,
|
||||
u64 range_start, u64 range_end,
|
||||
enum drm_mm_insert_mode mode)
|
||||
{
|
||||
struct drm_mm_node *hole_node;
|
||||
struct drm_mm_node *hole;
|
||||
u64 remainder_mask;
|
||||
|
||||
if (WARN_ON(size == 0))
|
||||
return -EINVAL;
|
||||
DRM_MM_BUG_ON(range_start >= range_end);
|
||||
|
||||
hole_node = drm_mm_search_free_in_range_generic(mm,
|
||||
size, alignment, color,
|
||||
start, end, sflags);
|
||||
if (!hole_node)
|
||||
if (unlikely(size == 0 || range_end - range_start < size))
|
||||
return -ENOSPC;
|
||||
|
||||
drm_mm_insert_helper(hole_node, node,
|
||||
size, alignment, color,
|
||||
start, end, aflags);
|
||||
return 0;
|
||||
if (alignment <= 1)
|
||||
alignment = 0;
|
||||
|
||||
remainder_mask = is_power_of_2(alignment) ? alignment - 1 : 0;
|
||||
for (hole = first_hole(mm, range_start, range_end, size, mode); hole;
|
||||
hole = next_hole(mm, hole, mode)) {
|
||||
u64 hole_start = __drm_mm_hole_node_start(hole);
|
||||
u64 hole_end = hole_start + hole->hole_size;
|
||||
u64 adj_start, adj_end;
|
||||
u64 col_start, col_end;
|
||||
|
||||
if (mode == DRM_MM_INSERT_LOW && hole_start >= range_end)
|
||||
break;
|
||||
|
||||
if (mode == DRM_MM_INSERT_HIGH && hole_end <= range_start)
|
||||
break;
|
||||
|
||||
col_start = hole_start;
|
||||
col_end = hole_end;
|
||||
if (mm->color_adjust)
|
||||
mm->color_adjust(hole, color, &col_start, &col_end);
|
||||
|
||||
adj_start = max(col_start, range_start);
|
||||
adj_end = min(col_end, range_end);
|
||||
|
||||
if (adj_end <= adj_start || adj_end - adj_start < size)
|
||||
continue;
|
||||
|
||||
if (mode == DRM_MM_INSERT_HIGH)
|
||||
adj_start = adj_end - size;
|
||||
|
||||
if (alignment) {
|
||||
u64 rem;
|
||||
|
||||
if (likely(remainder_mask))
|
||||
rem = adj_start & remainder_mask;
|
||||
else
|
||||
div64_u64_rem(adj_start, alignment, &rem);
|
||||
if (rem) {
|
||||
adj_start -= rem;
|
||||
if (mode != DRM_MM_INSERT_HIGH)
|
||||
adj_start += alignment;
|
||||
|
||||
if (adj_start < max(col_start, range_start) ||
|
||||
min(col_end, range_end) - adj_start < size)
|
||||
continue;
|
||||
|
||||
if (adj_end <= adj_start ||
|
||||
adj_end - adj_start < size)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
node->mm = mm;
|
||||
node->size = size;
|
||||
node->start = adj_start;
|
||||
node->color = color;
|
||||
node->hole_size = 0;
|
||||
|
||||
list_add(&node->node_list, &hole->node_list);
|
||||
drm_mm_interval_tree_add_node(hole, node);
|
||||
node->allocated = true;
|
||||
|
||||
rm_hole(hole);
|
||||
if (adj_start > hole_start)
|
||||
add_hole(hole);
|
||||
if (adj_start + size < hole_end)
|
||||
add_hole(node);
|
||||
|
||||
save_stack(node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOSPC;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_insert_node_in_range_generic);
|
||||
EXPORT_SYMBOL(drm_mm_insert_node_in_range);
|
||||
|
||||
/**
|
||||
* drm_mm_remove_node - Remove a memory node from the allocator.
|
||||
|
@ -421,93 +546,21 @@ void drm_mm_remove_node(struct drm_mm_node *node)
|
|||
DRM_MM_BUG_ON(!node->allocated);
|
||||
DRM_MM_BUG_ON(node->scanned_block);
|
||||
|
||||
prev_node =
|
||||
list_entry(node->node_list.prev, struct drm_mm_node, node_list);
|
||||
prev_node = list_prev_entry(node, node_list);
|
||||
|
||||
if (drm_mm_hole_follows(node)) {
|
||||
DRM_MM_BUG_ON(__drm_mm_hole_node_start(node) ==
|
||||
__drm_mm_hole_node_end(node));
|
||||
list_del(&node->hole_stack);
|
||||
} else {
|
||||
DRM_MM_BUG_ON(__drm_mm_hole_node_start(node) !=
|
||||
__drm_mm_hole_node_end(node));
|
||||
}
|
||||
|
||||
if (!drm_mm_hole_follows(prev_node)) {
|
||||
prev_node->hole_follows = 1;
|
||||
list_add(&prev_node->hole_stack, &mm->hole_stack);
|
||||
} else
|
||||
list_move(&prev_node->hole_stack, &mm->hole_stack);
|
||||
if (drm_mm_hole_follows(node))
|
||||
rm_hole(node);
|
||||
|
||||
drm_mm_interval_tree_remove(node, &mm->interval_tree);
|
||||
list_del(&node->node_list);
|
||||
node->allocated = 0;
|
||||
node->allocated = false;
|
||||
|
||||
if (drm_mm_hole_follows(prev_node))
|
||||
rm_hole(prev_node);
|
||||
add_hole(prev_node);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_remove_node);
|
||||
|
||||
static int check_free_hole(u64 start, u64 end, u64 size, u64 alignment)
|
||||
{
|
||||
if (end - start < size)
|
||||
return 0;
|
||||
|
||||
if (alignment) {
|
||||
u64 rem;
|
||||
|
||||
div64_u64_rem(start, alignment, &rem);
|
||||
if (rem)
|
||||
start += alignment - rem;
|
||||
}
|
||||
|
||||
return end >= start + size;
|
||||
}
|
||||
|
||||
static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm,
|
||||
u64 size,
|
||||
u64 alignment,
|
||||
unsigned long color,
|
||||
u64 start,
|
||||
u64 end,
|
||||
enum drm_mm_search_flags flags)
|
||||
{
|
||||
struct drm_mm_node *entry;
|
||||
struct drm_mm_node *best;
|
||||
u64 adj_start;
|
||||
u64 adj_end;
|
||||
u64 best_size;
|
||||
|
||||
DRM_MM_BUG_ON(mm->scan_active);
|
||||
|
||||
best = NULL;
|
||||
best_size = ~0UL;
|
||||
|
||||
__drm_mm_for_each_hole(entry, mm, adj_start, adj_end,
|
||||
flags & DRM_MM_SEARCH_BELOW) {
|
||||
u64 hole_size = adj_end - adj_start;
|
||||
|
||||
if (mm->color_adjust) {
|
||||
mm->color_adjust(entry, color, &adj_start, &adj_end);
|
||||
if (adj_end <= adj_start)
|
||||
continue;
|
||||
}
|
||||
|
||||
adj_start = max(adj_start, start);
|
||||
adj_end = min(adj_end, end);
|
||||
|
||||
if (!check_free_hole(adj_start, adj_end, size, alignment))
|
||||
continue;
|
||||
|
||||
if (!(flags & DRM_MM_SEARCH_BEST))
|
||||
return entry;
|
||||
|
||||
if (hole_size < best_size) {
|
||||
best = entry;
|
||||
best_size = hole_size;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_mm_replace_node - move an allocation from @old to @new
|
||||
* @old: drm_mm_node to remove from the allocator
|
||||
|
@ -521,18 +574,23 @@ void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new)
|
|||
{
|
||||
DRM_MM_BUG_ON(!old->allocated);
|
||||
|
||||
list_replace(&old->node_list, &new->node_list);
|
||||
list_replace(&old->hole_stack, &new->hole_stack);
|
||||
rb_replace_node(&old->rb, &new->rb, &old->mm->interval_tree);
|
||||
new->hole_follows = old->hole_follows;
|
||||
new->mm = old->mm;
|
||||
new->start = old->start;
|
||||
new->size = old->size;
|
||||
new->color = old->color;
|
||||
new->__subtree_last = old->__subtree_last;
|
||||
*new = *old;
|
||||
|
||||
old->allocated = 0;
|
||||
new->allocated = 1;
|
||||
list_replace(&old->node_list, &new->node_list);
|
||||
rb_replace_node(&old->rb, &new->rb, &old->mm->interval_tree);
|
||||
|
||||
if (drm_mm_hole_follows(old)) {
|
||||
list_replace(&old->hole_stack, &new->hole_stack);
|
||||
rb_replace_node(&old->rb_hole_size,
|
||||
&new->rb_hole_size,
|
||||
&old->mm->holes_size);
|
||||
rb_replace_node(&old->rb_hole_addr,
|
||||
&new->rb_hole_addr,
|
||||
&old->mm->holes_addr);
|
||||
}
|
||||
|
||||
old->allocated = false;
|
||||
new->allocated = true;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_replace_node);
|
||||
|
||||
|
@ -577,7 +635,7 @@ EXPORT_SYMBOL(drm_mm_replace_node);
|
|||
* @color: opaque tag value to use for the allocation
|
||||
* @start: start of the allowed range for the allocation
|
||||
* @end: end of the allowed range for the allocation
|
||||
* @flags: flags to specify how the allocation will be performed afterwards
|
||||
* @mode: fine-tune the allocation search and placement
|
||||
*
|
||||
* This simply sets up the scanning routines with the parameters for the desired
|
||||
* hole.
|
||||
|
@ -593,7 +651,7 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
|
|||
unsigned long color,
|
||||
u64 start,
|
||||
u64 end,
|
||||
unsigned int flags)
|
||||
enum drm_mm_insert_mode mode)
|
||||
{
|
||||
DRM_MM_BUG_ON(start >= end);
|
||||
DRM_MM_BUG_ON(!size || size > end - start);
|
||||
|
@ -608,7 +666,7 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
|
|||
scan->alignment = alignment;
|
||||
scan->remainder_mask = is_power_of_2(alignment) ? alignment - 1 : 0;
|
||||
scan->size = size;
|
||||
scan->flags = flags;
|
||||
scan->mode = mode;
|
||||
|
||||
DRM_MM_BUG_ON(end <= start);
|
||||
scan->range_start = start;
|
||||
|
@ -667,7 +725,7 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
|
|||
if (adj_end <= adj_start || adj_end - adj_start < scan->size)
|
||||
return false;
|
||||
|
||||
if (scan->flags == DRM_MM_CREATE_TOP)
|
||||
if (scan->mode == DRM_MM_INSERT_HIGH)
|
||||
adj_start = adj_end - scan->size;
|
||||
|
||||
if (scan->alignment) {
|
||||
|
@ -679,7 +737,7 @@ bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
|
|||
div64_u64_rem(adj_start, scan->alignment, &rem);
|
||||
if (rem) {
|
||||
adj_start -= rem;
|
||||
if (scan->flags != DRM_MM_CREATE_TOP)
|
||||
if (scan->mode != DRM_MM_INSERT_HIGH)
|
||||
adj_start += scan->alignment;
|
||||
if (adj_start < max(col_start, scan->range_start) ||
|
||||
min(col_end, scan->range_end) - adj_start < scan->size)
|
||||
|
@ -775,7 +833,7 @@ struct drm_mm_node *drm_mm_scan_color_evict(struct drm_mm_scan *scan)
|
|||
|
||||
hole = list_first_entry(&mm->hole_stack, typeof(*hole), hole_stack);
|
||||
hole_start = __drm_mm_hole_node_start(hole);
|
||||
hole_end = __drm_mm_hole_node_end(hole);
|
||||
hole_end = hole_start + hole->hole_size;
|
||||
|
||||
DRM_MM_BUG_ON(hole_start > scan->hit_start);
|
||||
DRM_MM_BUG_ON(hole_end < scan->hit_end);
|
||||
|
@ -802,21 +860,22 @@ void drm_mm_init(struct drm_mm *mm, u64 start, u64 size)
|
|||
{
|
||||
DRM_MM_BUG_ON(start + size <= start);
|
||||
|
||||
mm->color_adjust = NULL;
|
||||
|
||||
INIT_LIST_HEAD(&mm->hole_stack);
|
||||
mm->scan_active = 0;
|
||||
mm->interval_tree = RB_ROOT;
|
||||
mm->holes_size = RB_ROOT;
|
||||
mm->holes_addr = RB_ROOT;
|
||||
|
||||
/* Clever trick to avoid a special case in the free hole tracking. */
|
||||
INIT_LIST_HEAD(&mm->head_node.node_list);
|
||||
mm->head_node.allocated = 0;
|
||||
mm->head_node.hole_follows = 1;
|
||||
mm->head_node.allocated = false;
|
||||
mm->head_node.mm = mm;
|
||||
mm->head_node.start = start + size;
|
||||
mm->head_node.size = start - mm->head_node.start;
|
||||
list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack);
|
||||
mm->head_node.size = -size;
|
||||
add_hole(&mm->head_node);
|
||||
|
||||
mm->interval_tree = RB_ROOT;
|
||||
|
||||
mm->color_adjust = NULL;
|
||||
mm->scan_active = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_init);
|
||||
|
||||
|
@ -837,20 +896,17 @@ EXPORT_SYMBOL(drm_mm_takedown);
|
|||
|
||||
static u64 drm_mm_dump_hole(struct drm_printer *p, const struct drm_mm_node *entry)
|
||||
{
|
||||
u64 hole_start, hole_end, hole_size;
|
||||
u64 start, size;
|
||||
|
||||
if (entry->hole_follows) {
|
||||
hole_start = drm_mm_hole_node_start(entry);
|
||||
hole_end = drm_mm_hole_node_end(entry);
|
||||
hole_size = hole_end - hole_start;
|
||||
drm_printf(p, "%#018llx-%#018llx: %llu: free\n", hole_start,
|
||||
hole_end, hole_size);
|
||||
return hole_size;
|
||||
size = entry->hole_size;
|
||||
if (size) {
|
||||
start = drm_mm_hole_node_start(entry);
|
||||
drm_printf(p, "%#018llx-%#018llx: %llu: free\n",
|
||||
start, start + size, size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_mm_print - print allocator state
|
||||
* @mm: drm_mm allocator to print
|
||||
|
|
|
@ -1481,12 +1481,8 @@ drm_mode_create_from_cmdline_mode(struct drm_device *dev,
|
|||
|
||||
mode->type |= DRM_MODE_TYPE_USERDEF;
|
||||
/* fix up 1368x768: GFT/CVT can't express 1366 width due to alignment */
|
||||
if (cmd->xres == 1366 && mode->hdisplay == 1368) {
|
||||
mode->hdisplay = 1366;
|
||||
mode->hsync_start--;
|
||||
mode->hsync_end--;
|
||||
drm_mode_set_name(mode);
|
||||
}
|
||||
if (cmd->xres == 1366)
|
||||
drm_mode_fixup_1366x768(mode);
|
||||
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
|
||||
return mode;
|
||||
}
|
||||
|
|
|
@ -212,8 +212,7 @@ int drm_vma_offset_add(struct drm_vma_offset_manager *mgr,
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = drm_mm_insert_node(&mgr->vm_addr_space_mm, &node->vm_node,
|
||||
pages, 0, DRM_MM_SEARCH_DEFAULT);
|
||||
ret = drm_mm_insert_node(&mgr->vm_addr_space_mm, &node->vm_node, pages);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ static int etnaviv_iommu_find_iova(struct etnaviv_iommu *mmu,
|
|||
struct drm_mm_node *node, size_t size)
|
||||
{
|
||||
struct etnaviv_vram_mapping *free = NULL;
|
||||
enum drm_mm_insert_mode mode = DRM_MM_INSERT_LOW;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&mmu->lock);
|
||||
|
@ -119,9 +120,9 @@ static int etnaviv_iommu_find_iova(struct etnaviv_iommu *mmu,
|
|||
bool found;
|
||||
|
||||
ret = drm_mm_insert_node_in_range(&mmu->mm, node,
|
||||
size, 0, mmu->last_iova, ~0UL,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
|
||||
size, 0, 0,
|
||||
mmu->last_iova, U64_MAX,
|
||||
mode);
|
||||
if (ret != -ENOSPC)
|
||||
break;
|
||||
|
||||
|
@ -136,7 +137,7 @@ static int etnaviv_iommu_find_iova(struct etnaviv_iommu *mmu,
|
|||
}
|
||||
|
||||
/* Try to retire some entries */
|
||||
drm_mm_scan_init(&scan, &mmu->mm, size, 0, 0, 0);
|
||||
drm_mm_scan_init(&scan, &mmu->mm, size, 0, 0, mode);
|
||||
|
||||
found = 0;
|
||||
INIT_LIST_HEAD(&list);
|
||||
|
@ -188,6 +189,8 @@ static int etnaviv_iommu_find_iova(struct etnaviv_iommu *mmu,
|
|||
list_del_init(&m->scan_node);
|
||||
}
|
||||
|
||||
mode = DRM_MM_INSERT_EVICT;
|
||||
|
||||
/*
|
||||
* We removed enough mappings so that the new allocation will
|
||||
* succeed, retry the allocation one more time.
|
||||
|
|
|
@ -208,7 +208,6 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
|
|||
struct exynos_drm_fbdev *fbdev;
|
||||
struct exynos_drm_private *private = dev->dev_private;
|
||||
struct drm_fb_helper *helper;
|
||||
unsigned int num_crtc;
|
||||
int ret;
|
||||
|
||||
if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector)
|
||||
|
@ -225,9 +224,7 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
|
|||
|
||||
drm_fb_helper_prepare(dev, helper, &exynos_drm_fb_helper_funcs);
|
||||
|
||||
num_crtc = dev->mode_config.num_crtc;
|
||||
|
||||
ret = drm_fb_helper_init(dev, helper, num_crtc, MAX_CONNECTOR);
|
||||
ret = drm_fb_helper_init(dev, helper, MAX_CONNECTOR);
|
||||
if (ret < 0) {
|
||||
DRM_ERROR("failed to initialize drm fb helper.\n");
|
||||
goto err_init;
|
||||
|
|
|
@ -94,7 +94,7 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
|
|||
"Invalid legacyfb_depth. Defaulting to 24bpp\n");
|
||||
legacyfb_depth = 24;
|
||||
}
|
||||
fsl_dev->fbdev = drm_fbdev_cma_init(dev, legacyfb_depth, 1, 1);
|
||||
fsl_dev->fbdev = drm_fbdev_cma_init(dev, legacyfb_depth, 1);
|
||||
if (IS_ERR(fsl_dev->fbdev)) {
|
||||
ret = PTR_ERR(fsl_dev->fbdev);
|
||||
fsl_dev->fbdev = NULL;
|
||||
|
|
|
@ -564,7 +564,7 @@ int psb_fbdev_init(struct drm_device *dev)
|
|||
drm_fb_helper_prepare(dev, &fbdev->psb_fb_helper, &psb_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(dev, &fbdev->psb_fb_helper,
|
||||
dev_priv->ops->crtcs, INTELFB_CONN_LIMIT);
|
||||
INTELFB_CONN_LIMIT);
|
||||
if (ret)
|
||||
goto free;
|
||||
|
||||
|
|
|
@ -200,8 +200,7 @@ int hibmc_fbdev_init(struct hibmc_drm_private *priv)
|
|||
&hibmc_fbdev_helper_funcs);
|
||||
|
||||
/* Now just one crtc and one channel */
|
||||
ret = drm_fb_helper_init(priv->dev,
|
||||
&hifbdev->helper, 1, 1);
|
||||
ret = drm_fb_helper_init(priv->dev, &hifbdev->helper, 1);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to initialize fb helper: %d\n", ret);
|
||||
return ret;
|
||||
|
|
|
@ -59,8 +59,7 @@ static void kirin_fbdev_output_poll_changed(struct drm_device *dev)
|
|||
drm_fbdev_cma_hotplug_event(priv->fbdev);
|
||||
} else {
|
||||
priv->fbdev = drm_fbdev_cma_init(dev, 32,
|
||||
dev->mode_config.num_crtc,
|
||||
dev->mode_config.num_connector);
|
||||
dev->mode_config.num_connector);
|
||||
if (IS_ERR(priv->fbdev))
|
||||
priv->fbdev = NULL;
|
||||
}
|
||||
|
|
|
@ -69,12 +69,10 @@ insert_mappable_node(struct i915_ggtt *ggtt,
|
|||
struct drm_mm_node *node, u32 size)
|
||||
{
|
||||
memset(node, 0, sizeof(*node));
|
||||
return drm_mm_insert_node_in_range_generic(&ggtt->base.mm, node,
|
||||
size, 0,
|
||||
I915_COLOR_UNEVICTABLE,
|
||||
0, ggtt->mappable_end,
|
||||
DRM_MM_SEARCH_DEFAULT,
|
||||
DRM_MM_CREATE_DEFAULT);
|
||||
return drm_mm_insert_node_in_range(&ggtt->base.mm, node,
|
||||
size, 0, I915_COLOR_UNEVICTABLE,
|
||||
0, ggtt->mappable_end,
|
||||
DRM_MM_INSERT_LOW);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -109,6 +109,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
|
|||
}, **phase;
|
||||
struct i915_vma *vma, *next;
|
||||
struct drm_mm_node *node;
|
||||
enum drm_mm_insert_mode mode;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&vm->i915->drm.struct_mutex);
|
||||
|
@ -127,10 +128,14 @@ i915_gem_evict_something(struct i915_address_space *vm,
|
|||
* On each list, the oldest objects lie at the HEAD with the freshest
|
||||
* object on the TAIL.
|
||||
*/
|
||||
mode = DRM_MM_INSERT_BEST;
|
||||
if (flags & PIN_HIGH)
|
||||
mode = DRM_MM_INSERT_HIGH;
|
||||
if (flags & PIN_MAPPABLE)
|
||||
mode = DRM_MM_INSERT_LOW;
|
||||
drm_mm_scan_init_with_range(&scan, &vm->mm,
|
||||
min_size, alignment, cache_level,
|
||||
start, end,
|
||||
flags & PIN_HIGH ? DRM_MM_CREATE_TOP : 0);
|
||||
start, end, mode);
|
||||
|
||||
/* Retire before we search the active list. Although we have
|
||||
* reasonable accuracy in our retirement lists, we may have
|
||||
|
|
|
@ -436,12 +436,11 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
|
|||
PIN_MAPPABLE | PIN_NONBLOCK);
|
||||
if (IS_ERR(vma)) {
|
||||
memset(&cache->node, 0, sizeof(cache->node));
|
||||
ret = drm_mm_insert_node_in_range_generic
|
||||
ret = drm_mm_insert_node_in_range
|
||||
(&ggtt->base.mm, &cache->node,
|
||||
PAGE_SIZE, 0, I915_COLOR_UNEVICTABLE,
|
||||
0, ggtt->mappable_end,
|
||||
DRM_MM_SEARCH_DEFAULT,
|
||||
DRM_MM_CREATE_DEFAULT);
|
||||
DRM_MM_INSERT_LOW);
|
||||
if (ret) /* no inactive aperture space, use cpu reloc */
|
||||
return NULL;
|
||||
} else {
|
||||
|
|
|
@ -2748,12 +2748,10 @@ int i915_gem_init_ggtt(struct drm_i915_private *dev_priv)
|
|||
return ret;
|
||||
|
||||
/* Reserve a mappable slot for our lockless error capture */
|
||||
ret = drm_mm_insert_node_in_range_generic(&ggtt->base.mm,
|
||||
&ggtt->error_capture,
|
||||
PAGE_SIZE, 0,
|
||||
I915_COLOR_UNEVICTABLE,
|
||||
0, ggtt->mappable_end,
|
||||
0, 0);
|
||||
ret = drm_mm_insert_node_in_range(&ggtt->base.mm, &ggtt->error_capture,
|
||||
PAGE_SIZE, 0, I915_COLOR_UNEVICTABLE,
|
||||
0, ggtt->mappable_end,
|
||||
DRM_MM_INSERT_LOW);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -3663,7 +3661,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
|
|||
u64 size, u64 alignment, unsigned long color,
|
||||
u64 start, u64 end, unsigned int flags)
|
||||
{
|
||||
u32 search_flag, alloc_flag;
|
||||
enum drm_mm_insert_mode mode;
|
||||
u64 offset;
|
||||
int err;
|
||||
|
||||
|
@ -3684,13 +3682,11 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
|
|||
if (unlikely(round_up(start, alignment) > round_down(end - size, alignment)))
|
||||
return -ENOSPC;
|
||||
|
||||
if (flags & PIN_HIGH) {
|
||||
search_flag = DRM_MM_SEARCH_BELOW;
|
||||
alloc_flag = DRM_MM_CREATE_TOP;
|
||||
} else {
|
||||
search_flag = DRM_MM_SEARCH_DEFAULT;
|
||||
alloc_flag = DRM_MM_CREATE_DEFAULT;
|
||||
}
|
||||
mode = DRM_MM_INSERT_BEST;
|
||||
if (flags & PIN_HIGH)
|
||||
mode = DRM_MM_INSERT_HIGH;
|
||||
if (flags & PIN_MAPPABLE)
|
||||
mode = DRM_MM_INSERT_LOW;
|
||||
|
||||
/* We only allocate in PAGE_SIZE/GTT_PAGE_SIZE (4096) chunks,
|
||||
* so we know that we always have a minimum alignment of 4096.
|
||||
|
@ -3702,10 +3698,9 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
|
|||
if (alignment <= I915_GTT_MIN_ALIGNMENT)
|
||||
alignment = 0;
|
||||
|
||||
err = drm_mm_insert_node_in_range_generic(&vm->mm, node,
|
||||
size, alignment, color,
|
||||
start, end,
|
||||
search_flag, alloc_flag);
|
||||
err = drm_mm_insert_node_in_range(&vm->mm, node,
|
||||
size, alignment, color,
|
||||
start, end, mode);
|
||||
if (err != -ENOSPC)
|
||||
return err;
|
||||
|
||||
|
@ -3743,9 +3738,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
search_flag = DRM_MM_SEARCH_DEFAULT;
|
||||
return drm_mm_insert_node_in_range_generic(&vm->mm, node,
|
||||
size, alignment, color,
|
||||
start, end,
|
||||
search_flag, alloc_flag);
|
||||
return drm_mm_insert_node_in_range(&vm->mm, node,
|
||||
size, alignment, color,
|
||||
start, end, DRM_MM_INSERT_EVICT);
|
||||
}
|
||||
|
|
|
@ -55,9 +55,9 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
|
|||
return -ENODEV;
|
||||
|
||||
mutex_lock(&dev_priv->mm.stolen_lock);
|
||||
ret = drm_mm_insert_node_in_range(&dev_priv->mm.stolen, node, size,
|
||||
alignment, start, end,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
ret = drm_mm_insert_node_in_range(&dev_priv->mm.stolen, node,
|
||||
size, alignment, 0,
|
||||
start, end, DRM_MM_INSERT_BEST);
|
||||
mutex_unlock(&dev_priv->mm.stolen_lock);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -713,8 +713,7 @@ int intel_fbdev_init(struct drm_device *dev)
|
|||
if (!intel_fbdev_init_bios(dev, ifbdev))
|
||||
ifbdev->preferred_bpp = 32;
|
||||
|
||||
ret = drm_fb_helper_init(dev, &ifbdev->helper,
|
||||
INTEL_INFO(dev_priv)->num_pipes, 4);
|
||||
ret = drm_fb_helper_init(dev, &ifbdev->helper, 4);
|
||||
if (ret) {
|
||||
kfree(ifbdev);
|
||||
return ret;
|
||||
|
|
|
@ -389,8 +389,7 @@ static int imx_drm_bind(struct device *dev)
|
|||
dev_warn(dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n");
|
||||
legacyfb_depth = 16;
|
||||
}
|
||||
imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
|
||||
drm->mode_config.num_crtc, MAX_CRTC);
|
||||
imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth, MAX_CRTC);
|
||||
if (IS_ERR(imxdrm->fbhelper)) {
|
||||
ret = PTR_ERR(imxdrm->fbhelper);
|
||||
imxdrm->fbhelper = NULL;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
meson-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o
|
||||
meson-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o
|
||||
meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o
|
||||
meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o
|
||||
|
||||
obj-$(CONFIG_DRM_MESON) += meson.o
|
||||
obj-$(CONFIG_DRM_MESON) += meson-drm.o
|
||||
|
|
|
@ -279,7 +279,6 @@ static int meson_drv_probe(struct platform_device *pdev)
|
|||
drm->mode_config.funcs = &meson_mode_config_funcs;
|
||||
|
||||
priv->fbdev = drm_fbdev_cma_init(drm, 32,
|
||||
drm->mode_config.num_crtc,
|
||||
drm->mode_config.num_connector);
|
||||
if (IS_ERR(priv->fbdev)) {
|
||||
ret = PTR_ERR(priv->fbdev);
|
||||
|
@ -329,8 +328,7 @@ static struct platform_driver meson_drm_platform_driver = {
|
|||
.probe = meson_drv_probe,
|
||||
.remove = meson_drv_remove,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = DRIVER_NAME,
|
||||
.name = "meson-drm",
|
||||
.of_match_table = dt_match,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -286,7 +286,7 @@ int mgag200_fbdev_init(struct mga_device *mdev)
|
|||
drm_fb_helper_prepare(mdev->dev, &mfbdev->helper, &mga_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(mdev->dev, &mfbdev->helper,
|
||||
mdev->num_crtc, MGAG200FB_CONN_LIMIT);
|
||||
MGAG200FB_CONN_LIMIT);
|
||||
if (ret)
|
||||
goto err_fb_helper;
|
||||
|
||||
|
|
|
@ -201,8 +201,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
|
|||
|
||||
drm_fb_helper_prepare(dev, helper, &msm_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(dev, helper,
|
||||
priv->num_crtcs, priv->num_connectors);
|
||||
ret = drm_fb_helper_init(dev, helper, priv->num_connectors);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "could not init fbdev: ret=%d\n", ret);
|
||||
goto fail;
|
||||
|
|
|
@ -54,8 +54,7 @@ static struct page **get_pages_vram(struct drm_gem_object *obj,
|
|||
if (!p)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = drm_mm_insert_node(&priv->vram.mm, msm_obj->vram_node,
|
||||
npages, 0, DRM_MM_SEARCH_DEFAULT);
|
||||
ret = drm_mm_insert_node(&priv->vram.mm, msm_obj->vram_node, npages);
|
||||
if (ret) {
|
||||
drm_free_large(p);
|
||||
return ERR_PTR(ret);
|
||||
|
|
|
@ -45,8 +45,7 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace,
|
|||
if (WARN_ON(drm_mm_node_allocated(&vma->node)))
|
||||
return 0;
|
||||
|
||||
ret = drm_mm_insert_node(&aspace->mm, &vma->node, npages,
|
||||
0, DRM_MM_SEARCH_DEFAULT);
|
||||
ret = drm_mm_insert_node(&aspace->mm, &vma->node, npages);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
|
|||
|
||||
drm_kms_helper_poll_init(drm);
|
||||
|
||||
mxsfb->fbdev = drm_fbdev_cma_init(drm, 32, drm->mode_config.num_crtc,
|
||||
mxsfb->fbdev = drm_fbdev_cma_init(drm, 32,
|
||||
drm->mode_config.num_connector);
|
||||
if (IS_ERR(mxsfb->fbdev)) {
|
||||
mxsfb->fbdev = NULL;
|
||||
|
|
|
@ -507,8 +507,7 @@ nouveau_fbcon_init(struct drm_device *dev)
|
|||
|
||||
drm_fb_helper_prepare(dev, &fbcon->helper, &nouveau_fbcon_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(dev, &fbcon->helper,
|
||||
dev->mode_config.num_crtc, 4);
|
||||
ret = drm_fb_helper_init(dev, &fbcon->helper, 4);
|
||||
if (ret)
|
||||
goto free;
|
||||
|
||||
|
|
|
@ -263,8 +263,7 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
|
|||
|
||||
drm_fb_helper_prepare(dev, helper, &omap_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(dev, helper,
|
||||
priv->num_crtcs, priv->num_connectors);
|
||||
ret = drm_fb_helper_init(dev, helper, priv->num_connectors);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "could not init fbdev: ret=%d\n", ret);
|
||||
goto fail;
|
||||
|
|
|
@ -133,8 +133,8 @@ int qxl_debugfs_add_files(struct qxl_device *qdev,
|
|||
qdev->debugfs_count = i;
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
drm_debugfs_create_files(files, nfiles,
|
||||
qdev->ddev->primary->debugfs_root,
|
||||
qdev->ddev->primary);
|
||||
qdev->ddev.primary->debugfs_root,
|
||||
qdev->ddev.primary);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ void qxl_debugfs_remove_files(struct qxl_device *qdev)
|
|||
for (i = 0; i < qdev->debugfs_count; i++) {
|
||||
drm_debugfs_remove_files(qdev->debugfs[i].files,
|
||||
qdev->debugfs[i].num_files,
|
||||
qdev->ddev->primary);
|
||||
qdev->ddev.primary);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ static int qxl_display_copy_rom_client_monitors_config(struct qxl_device *qdev)
|
|||
|
||||
static void qxl_update_offset_props(struct qxl_device *qdev)
|
||||
{
|
||||
struct drm_device *dev = qdev->ddev;
|
||||
struct drm_device *dev = &qdev->ddev;
|
||||
struct drm_connector *connector;
|
||||
struct qxl_output *output;
|
||||
struct qxl_head *head;
|
||||
|
@ -156,7 +156,7 @@ static void qxl_update_offset_props(struct qxl_device *qdev)
|
|||
void qxl_display_read_client_monitors_config(struct qxl_device *qdev)
|
||||
{
|
||||
|
||||
struct drm_device *dev = qdev->ddev;
|
||||
struct drm_device *dev = &qdev->ddev;
|
||||
int status;
|
||||
|
||||
status = qxl_display_copy_rom_client_monitors_config(qdev);
|
||||
|
@ -174,10 +174,10 @@ void qxl_display_read_client_monitors_config(struct qxl_device *qdev)
|
|||
drm_modeset_lock_all(dev);
|
||||
qxl_update_offset_props(qdev);
|
||||
drm_modeset_unlock_all(dev);
|
||||
if (!drm_helper_hpd_irq_event(qdev->ddev)) {
|
||||
if (!drm_helper_hpd_irq_event(dev)) {
|
||||
/* notify that the monitor configuration changed, to
|
||||
adjust at the arbitrary resolution */
|
||||
drm_kms_helper_hotplug_event(qdev->ddev);
|
||||
drm_kms_helper_hotplug_event(dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1036,7 +1036,7 @@ static int qxl_mode_create_hotplug_mode_update_property(struct qxl_device *qdev)
|
|||
return 0;
|
||||
|
||||
qdev->hotplug_mode_update_property =
|
||||
drm_property_create_range(qdev->ddev, DRM_MODE_PROP_IMMUTABLE,
|
||||
drm_property_create_range(&qdev->ddev, DRM_MODE_PROP_IMMUTABLE,
|
||||
"hotplug_mode_update", 0, 1);
|
||||
|
||||
return 0;
|
||||
|
@ -1175,28 +1175,28 @@ int qxl_modeset_init(struct qxl_device *qdev)
|
|||
int i;
|
||||
int ret;
|
||||
|
||||
drm_mode_config_init(qdev->ddev);
|
||||
drm_mode_config_init(&qdev->ddev);
|
||||
|
||||
ret = qxl_create_monitors_object(qdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
qdev->ddev->mode_config.funcs = (void *)&qxl_mode_funcs;
|
||||
qdev->ddev.mode_config.funcs = (void *)&qxl_mode_funcs;
|
||||
|
||||
/* modes will be validated against the framebuffer size */
|
||||
qdev->ddev->mode_config.min_width = 320;
|
||||
qdev->ddev->mode_config.min_height = 200;
|
||||
qdev->ddev->mode_config.max_width = 8192;
|
||||
qdev->ddev->mode_config.max_height = 8192;
|
||||
qdev->ddev.mode_config.min_width = 320;
|
||||
qdev->ddev.mode_config.min_height = 200;
|
||||
qdev->ddev.mode_config.max_width = 8192;
|
||||
qdev->ddev.mode_config.max_height = 8192;
|
||||
|
||||
qdev->ddev->mode_config.fb_base = qdev->vram_base;
|
||||
qdev->ddev.mode_config.fb_base = qdev->vram_base;
|
||||
|
||||
drm_mode_create_suggested_offset_properties(qdev->ddev);
|
||||
drm_mode_create_suggested_offset_properties(&qdev->ddev);
|
||||
qxl_mode_create_hotplug_mode_update_property(qdev);
|
||||
|
||||
for (i = 0 ; i < qxl_num_crtc; ++i) {
|
||||
qdev_crtc_init(qdev->ddev, i);
|
||||
qdev_output_init(qdev->ddev, i);
|
||||
qdev_crtc_init(&qdev->ddev, i);
|
||||
qdev_output_init(&qdev->ddev, i);
|
||||
}
|
||||
|
||||
qdev->mode_info.mode_config_initialized = true;
|
||||
|
@ -1214,7 +1214,7 @@ void qxl_modeset_fini(struct qxl_device *qdev)
|
|||
|
||||
qxl_destroy_monitors_object(qdev);
|
||||
if (qdev->mode_info.mode_config_initialized) {
|
||||
drm_mode_config_cleanup(qdev->ddev);
|
||||
drm_mode_config_cleanup(&qdev->ddev);
|
||||
qdev->mode_info.mode_config_initialized = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,6 @@ static struct pci_driver qxl_pci_driver;
|
|||
static int
|
||||
qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
struct drm_device *drm;
|
||||
struct qxl_device *qdev;
|
||||
int ret;
|
||||
|
||||
|
@ -72,29 +71,19 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
return -EINVAL; /* TODO: ENODEV ? */
|
||||
}
|
||||
|
||||
drm = drm_dev_alloc(&qxl_driver, &pdev->dev);
|
||||
if (IS_ERR(drm))
|
||||
return -ENOMEM;
|
||||
|
||||
qdev = kzalloc(sizeof(struct qxl_device), GFP_KERNEL);
|
||||
if (!qdev) {
|
||||
ret = -ENOMEM;
|
||||
goto free_drm_device;
|
||||
}
|
||||
if (!qdev)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret)
|
||||
goto free_drm_device;
|
||||
goto free_dev;
|
||||
|
||||
drm->pdev = pdev;
|
||||
pci_set_drvdata(pdev, drm);
|
||||
drm->dev_private = qdev;
|
||||
|
||||
ret = qxl_device_init(qdev, drm, pdev, ent->driver_data);
|
||||
ret = qxl_device_init(qdev, &qxl_driver, pdev, ent->driver_data);
|
||||
if (ret)
|
||||
goto disable_pci;
|
||||
|
||||
ret = drm_vblank_init(drm, 1);
|
||||
ret = drm_vblank_init(&qdev->ddev, 1);
|
||||
if (ret)
|
||||
goto unload;
|
||||
|
||||
|
@ -102,10 +91,10 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (ret)
|
||||
goto vblank_cleanup;
|
||||
|
||||
drm_kms_helper_poll_init(qdev->ddev);
|
||||
drm_kms_helper_poll_init(&qdev->ddev);
|
||||
|
||||
/* Complete initialization. */
|
||||
ret = drm_dev_register(drm, ent->driver_data);
|
||||
ret = drm_dev_register(&qdev->ddev, ent->driver_data);
|
||||
if (ret)
|
||||
goto modeset_cleanup;
|
||||
|
||||
|
@ -114,14 +103,13 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
modeset_cleanup:
|
||||
qxl_modeset_fini(qdev);
|
||||
vblank_cleanup:
|
||||
drm_vblank_cleanup(drm);
|
||||
drm_vblank_cleanup(&qdev->ddev);
|
||||
unload:
|
||||
qxl_device_fini(qdev);
|
||||
disable_pci:
|
||||
pci_disable_device(pdev);
|
||||
free_drm_device:
|
||||
free_dev:
|
||||
kfree(qdev);
|
||||
kfree(drm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -242,9 +242,7 @@ void qxl_debugfs_remove_files(struct qxl_device *qdev);
|
|||
struct qxl_device;
|
||||
|
||||
struct qxl_device {
|
||||
struct device *dev;
|
||||
struct drm_device *ddev;
|
||||
struct pci_dev *pdev;
|
||||
struct drm_device ddev;
|
||||
unsigned long flags;
|
||||
|
||||
resource_size_t vram_base, vram_size;
|
||||
|
@ -336,8 +334,8 @@ __printf(2,3) void qxl_io_log(struct qxl_device *qdev, const char *fmt, ...);
|
|||
extern const struct drm_ioctl_desc qxl_ioctls[];
|
||||
extern int qxl_max_ioctl;
|
||||
|
||||
int qxl_device_init(struct qxl_device *qdev, struct drm_device *ddev,
|
||||
struct pci_dev *pdev, unsigned long flags);
|
||||
int qxl_device_init(struct qxl_device *qdev, struct drm_driver *drv,
|
||||
struct pci_dev *pdev, unsigned long flags);
|
||||
void qxl_device_fini(struct qxl_device *qdev);
|
||||
|
||||
int qxl_modeset_init(struct qxl_device *qdev);
|
||||
|
|
|
@ -268,7 +268,7 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev,
|
|||
|
||||
info->par = qfbdev;
|
||||
|
||||
qxl_framebuffer_init(qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj,
|
||||
qxl_framebuffer_init(&qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj,
|
||||
&qxlfb_fb_funcs);
|
||||
|
||||
fb = &qfbdev->qfb.base;
|
||||
|
@ -297,7 +297,7 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev,
|
|||
sizes->fb_height);
|
||||
|
||||
/* setup aperture base/size for vesafb takeover */
|
||||
info->apertures->ranges[0].base = qdev->ddev->mode_config.fb_base;
|
||||
info->apertures->ranges[0].base = qdev->ddev.mode_config.fb_base;
|
||||
info->apertures->ranges[0].size = qdev->vram_size;
|
||||
|
||||
info->fix.mmio_start = 0;
|
||||
|
@ -395,11 +395,10 @@ int qxl_fbdev_init(struct qxl_device *qdev)
|
|||
spin_lock_init(&qfbdev->delayed_ops_lock);
|
||||
INIT_LIST_HEAD(&qfbdev->delayed_ops);
|
||||
|
||||
drm_fb_helper_prepare(qdev->ddev, &qfbdev->helper,
|
||||
drm_fb_helper_prepare(&qdev->ddev, &qfbdev->helper,
|
||||
&qxl_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(qdev->ddev, &qfbdev->helper,
|
||||
qxl_num_crtc /* num_crtc - QXL supports just 1 */,
|
||||
ret = drm_fb_helper_init(&qdev->ddev, &qfbdev->helper,
|
||||
QXLFB_CONN_LIMIT);
|
||||
if (ret)
|
||||
goto free;
|
||||
|
@ -426,7 +425,7 @@ void qxl_fbdev_fini(struct qxl_device *qdev)
|
|||
if (!qdev->mode_info.qfbdev)
|
||||
return;
|
||||
|
||||
qxl_fbdev_destroy(qdev->ddev, qdev->mode_info.qfbdev);
|
||||
qxl_fbdev_destroy(&qdev->ddev, qdev->mode_info.qfbdev);
|
||||
kfree(qdev->mode_info.qfbdev);
|
||||
qdev->mode_info.qfbdev = NULL;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ static int qxl_map_ioctl(struct drm_device *dev, void *data,
|
|||
struct qxl_device *qdev = dev->dev_private;
|
||||
struct drm_qxl_map *qxl_map = data;
|
||||
|
||||
return qxl_mode_dumb_mmap(file_priv, qdev->ddev, qxl_map->handle,
|
||||
return qxl_mode_dumb_mmap(file_priv, &qdev->ddev, qxl_map->handle,
|
||||
&qxl_map->offset);
|
||||
}
|
||||
|
||||
|
@ -375,7 +375,7 @@ static int qxl_clientcap_ioctl(struct drm_device *dev, void *data,
|
|||
byte = param->index / 8;
|
||||
idx = param->index % 8;
|
||||
|
||||
if (qdev->pdev->revision < 4)
|
||||
if (dev->pdev->revision < 4)
|
||||
return -ENOSYS;
|
||||
|
||||
if (byte >= 58)
|
||||
|
|
|
@ -90,7 +90,7 @@ int qxl_irq_init(struct qxl_device *qdev)
|
|||
atomic_set(&qdev->irq_received_cursor, 0);
|
||||
atomic_set(&qdev->irq_received_io_cmd, 0);
|
||||
qdev->irq_received_error = 0;
|
||||
ret = drm_irq_install(qdev->ddev, qdev->ddev->pdev->irq);
|
||||
ret = drm_irq_install(&qdev->ddev, qdev->ddev.pdev->irq);
|
||||
qdev->ram_header->int_mask = QXL_INTERRUPT_MASK;
|
||||
if (unlikely(ret != 0)) {
|
||||
DRM_ERROR("Failed installing irq: %d\n", ret);
|
||||
|
|
|
@ -116,15 +116,20 @@ static void qxl_gc_work(struct work_struct *work)
|
|||
}
|
||||
|
||||
int qxl_device_init(struct qxl_device *qdev,
|
||||
struct drm_device *ddev,
|
||||
struct drm_driver *drv,
|
||||
struct pci_dev *pdev,
|
||||
unsigned long flags)
|
||||
{
|
||||
int r, sb;
|
||||
|
||||
qdev->dev = &pdev->dev;
|
||||
qdev->ddev = ddev;
|
||||
qdev->pdev = pdev;
|
||||
r = drm_dev_init(&qdev->ddev, drv, &pdev->dev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
qdev->ddev.pdev = pdev;
|
||||
pci_set_drvdata(pdev, &qdev->ddev);
|
||||
qdev->ddev.dev_private = qdev;
|
||||
|
||||
qdev->flags = flags;
|
||||
|
||||
mutex_init(&qdev->gem.mutex);
|
||||
|
|
|
@ -93,7 +93,7 @@ int qxl_bo_create(struct qxl_device *qdev,
|
|||
if (bo == NULL)
|
||||
return -ENOMEM;
|
||||
size = roundup(size, PAGE_SIZE);
|
||||
r = drm_gem_object_init(qdev->ddev, &bo->gem_base, size);
|
||||
r = drm_gem_object_init(&qdev->ddev, &bo->gem_base, size);
|
||||
if (unlikely(r)) {
|
||||
kfree(bo);
|
||||
return r;
|
||||
|
@ -113,7 +113,7 @@ int qxl_bo_create(struct qxl_device *qdev,
|
|||
NULL, NULL, &qxl_ttm_bo_destroy);
|
||||
if (unlikely(r != 0)) {
|
||||
if (r != -ERESTARTSYS)
|
||||
dev_err(qdev->dev,
|
||||
dev_err(qdev->ddev.dev,
|
||||
"object_init failed for (%lu, 0x%08X)\n",
|
||||
size, domain);
|
||||
return r;
|
||||
|
@ -223,7 +223,7 @@ struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo)
|
|||
|
||||
int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
|
||||
{
|
||||
struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private;
|
||||
struct drm_device *ddev = bo->gem_base.dev;
|
||||
int r;
|
||||
|
||||
if (bo->pin_count) {
|
||||
|
@ -240,17 +240,17 @@ int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
|
|||
*gpu_addr = qxl_bo_gpu_offset(bo);
|
||||
}
|
||||
if (unlikely(r != 0))
|
||||
dev_err(qdev->dev, "%p pin failed\n", bo);
|
||||
dev_err(ddev->dev, "%p pin failed\n", bo);
|
||||
return r;
|
||||
}
|
||||
|
||||
int qxl_bo_unpin(struct qxl_bo *bo)
|
||||
{
|
||||
struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private;
|
||||
struct drm_device *ddev = bo->gem_base.dev;
|
||||
int r, i;
|
||||
|
||||
if (!bo->pin_count) {
|
||||
dev_warn(qdev->dev, "%p unpin not necessary\n", bo);
|
||||
dev_warn(ddev->dev, "%p unpin not necessary\n", bo);
|
||||
return 0;
|
||||
}
|
||||
bo->pin_count--;
|
||||
|
@ -260,7 +260,7 @@ int qxl_bo_unpin(struct qxl_bo *bo)
|
|||
bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
|
||||
if (unlikely(r != 0))
|
||||
dev_err(qdev->dev, "%p validate failed for unpin\n", bo);
|
||||
dev_err(ddev->dev, "%p validate failed for unpin\n", bo);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -270,9 +270,9 @@ void qxl_bo_force_delete(struct qxl_device *qdev)
|
|||
|
||||
if (list_empty(&qdev->gem.objects))
|
||||
return;
|
||||
dev_err(qdev->dev, "Userspace still has active objects !\n");
|
||||
dev_err(qdev->ddev.dev, "Userspace still has active objects !\n");
|
||||
list_for_each_entry_safe(bo, n, &qdev->gem.objects, list) {
|
||||
dev_err(qdev->dev, "%p %p %lu %lu force free\n",
|
||||
dev_err(qdev->ddev.dev, "%p %p %lu %lu force free\n",
|
||||
&bo->gem_base, bo, (unsigned long)bo->gem_base.size,
|
||||
*((unsigned long *)&bo->gem_base.refcount));
|
||||
mutex_lock(&qdev->gem.mutex);
|
||||
|
|
|
@ -34,8 +34,8 @@ static inline int qxl_bo_reserve(struct qxl_bo *bo, bool no_wait)
|
|||
r = ttm_bo_reserve(&bo->tbo, true, no_wait, NULL);
|
||||
if (unlikely(r != 0)) {
|
||||
if (r != -ERESTARTSYS) {
|
||||
struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private;
|
||||
dev_err(qdev->dev, "%p reserve failed\n", bo);
|
||||
struct drm_device *ddev = bo->gem_base.dev;
|
||||
dev_err(ddev->dev, "%p reserve failed\n", bo);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
@ -70,8 +70,8 @@ static inline int qxl_bo_wait(struct qxl_bo *bo, u32 *mem_type,
|
|||
r = ttm_bo_reserve(&bo->tbo, true, no_wait, NULL);
|
||||
if (unlikely(r != 0)) {
|
||||
if (r != -ERESTARTSYS) {
|
||||
struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private;
|
||||
dev_err(qdev->dev, "%p reserve failed for wait\n",
|
||||
struct drm_device *ddev = bo->gem_base.dev;
|
||||
dev_err(ddev->dev, "%p reserve failed for wait\n",
|
||||
bo);
|
||||
}
|
||||
return r;
|
||||
|
|
|
@ -408,7 +408,7 @@ int qxl_ttm_init(struct qxl_device *qdev)
|
|||
r = ttm_bo_device_init(&qdev->mman.bdev,
|
||||
qdev->mman.bo_global_ref.ref.object,
|
||||
&qxl_bo_driver,
|
||||
qdev->ddev->anon_inode->i_mapping,
|
||||
qdev->ddev.anon_inode->i_mapping,
|
||||
DRM_FILE_PAGE_OFFSET, 0);
|
||||
if (r) {
|
||||
DRM_ERROR("failed initializing buffer object driver(%d).\n", r);
|
||||
|
|
|
@ -366,7 +366,6 @@ int radeon_fbdev_init(struct radeon_device *rdev)
|
|||
&radeon_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper,
|
||||
rdev->num_crtc,
|
||||
RADEONFB_CONN_LIMIT);
|
||||
if (ret)
|
||||
goto free;
|
||||
|
|
|
@ -662,7 +662,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
|
|||
drm_kms_helper_poll_init(dev);
|
||||
|
||||
if (dev->mode_config.num_connector) {
|
||||
fbdev = drm_fbdev_cma_init(dev, 32, dev->mode_config.num_crtc,
|
||||
fbdev = drm_fbdev_cma_init(dev, 32,
|
||||
dev->mode_config.num_connector);
|
||||
if (IS_ERR(fbdev))
|
||||
return PTR_ERR(fbdev);
|
||||
|
|
|
@ -129,19 +129,16 @@ int rockchip_drm_fbdev_init(struct drm_device *dev)
|
|||
{
|
||||
struct rockchip_drm_private *private = dev->dev_private;
|
||||
struct drm_fb_helper *helper;
|
||||
unsigned int num_crtc;
|
||||
int ret;
|
||||
|
||||
if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector)
|
||||
return -EINVAL;
|
||||
|
||||
num_crtc = dev->mode_config.num_crtc;
|
||||
|
||||
helper = &private->fbdev_helper;
|
||||
|
||||
drm_fb_helper_prepare(dev, helper, &rockchip_drm_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(dev, helper, num_crtc, ROCKCHIP_MAX_CONNECTOR);
|
||||
ret = drm_fb_helper_init(dev, helper, ROCKCHIP_MAX_CONNECTOR);
|
||||
if (ret < 0) {
|
||||
dev_err(dev->dev, "Failed to initialize drm fb helper - %d.\n",
|
||||
ret);
|
||||
|
|
|
@ -17,6 +17,7 @@ selftest(align32, igt_align32)
|
|||
selftest(align64, igt_align64)
|
||||
selftest(evict, igt_evict)
|
||||
selftest(evict_range, igt_evict_range)
|
||||
selftest(bottomup, igt_bottomup)
|
||||
selftest(topdown, igt_topdown)
|
||||
selftest(color, igt_color)
|
||||
selftest(color_evict, igt_color_evict)
|
||||
|
|
|
@ -22,23 +22,24 @@ static unsigned int max_iterations = 8192;
|
|||
static unsigned int max_prime = 128;
|
||||
|
||||
enum {
|
||||
DEFAULT,
|
||||
TOPDOWN,
|
||||
BEST,
|
||||
BOTTOMUP,
|
||||
TOPDOWN,
|
||||
EVICT,
|
||||
};
|
||||
|
||||
static const struct insert_mode {
|
||||
const char *name;
|
||||
unsigned int search_flags;
|
||||
unsigned int create_flags;
|
||||
enum drm_mm_insert_mode mode;
|
||||
} insert_modes[] = {
|
||||
[DEFAULT] = { "default", DRM_MM_SEARCH_DEFAULT, DRM_MM_CREATE_DEFAULT },
|
||||
[TOPDOWN] = { "top-down", DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP },
|
||||
[BEST] = { "best", DRM_MM_SEARCH_BEST, DRM_MM_CREATE_DEFAULT },
|
||||
[BEST] = { "best", DRM_MM_INSERT_BEST },
|
||||
[BOTTOMUP] = { "bottom-up", DRM_MM_INSERT_LOW },
|
||||
[TOPDOWN] = { "top-down", DRM_MM_INSERT_HIGH },
|
||||
[EVICT] = { "evict", DRM_MM_INSERT_EVICT },
|
||||
{}
|
||||
}, evict_modes[] = {
|
||||
{ "default", DRM_MM_SEARCH_DEFAULT, DRM_MM_CREATE_DEFAULT },
|
||||
{ "top-down", DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP },
|
||||
{ "bottom-up", DRM_MM_INSERT_LOW },
|
||||
{ "top-down", DRM_MM_INSERT_HIGH },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -526,8 +527,7 @@ static bool expect_insert(struct drm_mm *mm, struct drm_mm_node *node,
|
|||
|
||||
err = drm_mm_insert_node_generic(mm, node,
|
||||
size, alignment, color,
|
||||
mode->search_flags,
|
||||
mode->create_flags);
|
||||
mode->mode);
|
||||
if (err) {
|
||||
pr_err("insert (size=%llu, alignment=%llu, color=%lu, mode=%s) failed with err=%d\n",
|
||||
size, alignment, color, mode->name, err);
|
||||
|
@ -547,7 +547,7 @@ static bool expect_insert_fail(struct drm_mm *mm, u64 size)
|
|||
struct drm_mm_node tmp = {};
|
||||
int err;
|
||||
|
||||
err = drm_mm_insert_node(mm, &tmp, size, 0, DRM_MM_SEARCH_DEFAULT);
|
||||
err = drm_mm_insert_node(mm, &tmp, size);
|
||||
if (likely(err == -ENOSPC))
|
||||
return true;
|
||||
|
||||
|
@ -753,11 +753,10 @@ static bool expect_insert_in_range(struct drm_mm *mm, struct drm_mm_node *node,
|
|||
{
|
||||
int err;
|
||||
|
||||
err = drm_mm_insert_node_in_range_generic(mm, node,
|
||||
size, alignment, color,
|
||||
range_start, range_end,
|
||||
mode->search_flags,
|
||||
mode->create_flags);
|
||||
err = drm_mm_insert_node_in_range(mm, node,
|
||||
size, alignment, color,
|
||||
range_start, range_end,
|
||||
mode->mode);
|
||||
if (err) {
|
||||
pr_err("insert (size=%llu, alignment=%llu, color=%lu, mode=%s) nto range [%llx, %llx] failed with err=%d\n",
|
||||
size, alignment, color, mode->name,
|
||||
|
@ -781,11 +780,10 @@ static bool expect_insert_in_range_fail(struct drm_mm *mm,
|
|||
struct drm_mm_node tmp = {};
|
||||
int err;
|
||||
|
||||
err = drm_mm_insert_node_in_range_generic(mm, &tmp,
|
||||
size, 0, 0,
|
||||
range_start, range_end,
|
||||
DRM_MM_SEARCH_DEFAULT,
|
||||
DRM_MM_CREATE_DEFAULT);
|
||||
err = drm_mm_insert_node_in_range(mm, &tmp,
|
||||
size, 0, 0,
|
||||
range_start, range_end,
|
||||
0);
|
||||
if (likely(err == -ENOSPC))
|
||||
return true;
|
||||
|
||||
|
@ -1324,7 +1322,7 @@ static int evict_something(struct drm_mm *mm,
|
|||
drm_mm_scan_init_with_range(&scan, mm,
|
||||
size, alignment, 0,
|
||||
range_start, range_end,
|
||||
mode->create_flags);
|
||||
mode->mode);
|
||||
if (!evict_nodes(&scan,
|
||||
nodes, order, count, false,
|
||||
&evict_list))
|
||||
|
@ -1332,8 +1330,7 @@ static int evict_something(struct drm_mm *mm,
|
|||
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
err = drm_mm_insert_node_generic(mm, &tmp, size, alignment, 0,
|
||||
mode->search_flags,
|
||||
mode->create_flags);
|
||||
DRM_MM_INSERT_EVICT);
|
||||
if (err) {
|
||||
pr_err("Failed to insert into eviction hole: size=%d, align=%d\n",
|
||||
size, alignment);
|
||||
|
@ -1408,8 +1405,7 @@ static int igt_evict(void *ignored)
|
|||
ret = -EINVAL;
|
||||
drm_mm_init(&mm, 0, size);
|
||||
for (n = 0; n < size; n++) {
|
||||
err = drm_mm_insert_node(&mm, &nodes[n].node, 1, 0,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
err = drm_mm_insert_node(&mm, &nodes[n].node, 1);
|
||||
if (err) {
|
||||
pr_err("insert failed, step %d\n", n);
|
||||
ret = err;
|
||||
|
@ -1517,8 +1513,7 @@ static int igt_evict_range(void *ignored)
|
|||
ret = -EINVAL;
|
||||
drm_mm_init(&mm, 0, size);
|
||||
for (n = 0; n < size; n++) {
|
||||
err = drm_mm_insert_node(&mm, &nodes[n].node, 1, 0,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
err = drm_mm_insert_node(&mm, &nodes[n].node, 1);
|
||||
if (err) {
|
||||
pr_err("insert failed, step %d\n", n);
|
||||
ret = err;
|
||||
|
@ -1702,6 +1697,106 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int igt_bottomup(void *ignored)
|
||||
{
|
||||
const struct insert_mode *bottomup = &insert_modes[BOTTOMUP];
|
||||
DRM_RND_STATE(prng, random_seed);
|
||||
const unsigned int count = 8192;
|
||||
unsigned int size;
|
||||
unsigned long *bitmap;
|
||||
struct drm_mm mm;
|
||||
struct drm_mm_node *nodes, *node, *next;
|
||||
unsigned int *order, n, m, o = 0;
|
||||
int ret;
|
||||
|
||||
/* Like igt_topdown, but instead of searching for the last hole,
|
||||
* we search for the first.
|
||||
*/
|
||||
|
||||
ret = -ENOMEM;
|
||||
nodes = vzalloc(count * sizeof(*nodes));
|
||||
if (!nodes)
|
||||
goto err;
|
||||
|
||||
bitmap = kzalloc(count / BITS_PER_LONG * sizeof(unsigned long),
|
||||
GFP_TEMPORARY);
|
||||
if (!bitmap)
|
||||
goto err_nodes;
|
||||
|
||||
order = drm_random_order(count, &prng);
|
||||
if (!order)
|
||||
goto err_bitmap;
|
||||
|
||||
ret = -EINVAL;
|
||||
for (size = 1; size <= 64; size <<= 1) {
|
||||
drm_mm_init(&mm, 0, size*count);
|
||||
for (n = 0; n < count; n++) {
|
||||
if (!expect_insert(&mm, &nodes[n],
|
||||
size, 0, n,
|
||||
bottomup)) {
|
||||
pr_err("bottomup insert failed, size %u step %d\n", size, n);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!assert_one_hole(&mm, size*(n + 1), size*count))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!assert_continuous(&mm, size))
|
||||
goto out;
|
||||
|
||||
drm_random_reorder(order, count, &prng);
|
||||
for_each_prime_number_from(n, 1, min(count, max_prime)) {
|
||||
for (m = 0; m < n; m++) {
|
||||
node = &nodes[order[(o + m) % count]];
|
||||
drm_mm_remove_node(node);
|
||||
__set_bit(node_index(node), bitmap);
|
||||
}
|
||||
|
||||
for (m = 0; m < n; m++) {
|
||||
unsigned int first;
|
||||
|
||||
node = &nodes[order[(o + m) % count]];
|
||||
if (!expect_insert(&mm, node,
|
||||
size, 0, 0,
|
||||
bottomup)) {
|
||||
pr_err("insert failed, step %d/%d\n", m, n);
|
||||
goto out;
|
||||
}
|
||||
|
||||
first = find_first_bit(bitmap, count);
|
||||
if (node_index(node) != first) {
|
||||
pr_err("node %d/%d not inserted into bottom hole, expected %d, found %d\n",
|
||||
m, n, first, node_index(node));
|
||||
goto out;
|
||||
}
|
||||
__clear_bit(first, bitmap);
|
||||
}
|
||||
|
||||
DRM_MM_BUG_ON(find_first_bit(bitmap, count) != count);
|
||||
|
||||
o += n;
|
||||
}
|
||||
|
||||
drm_mm_for_each_node_safe(node, next, &mm)
|
||||
drm_mm_remove_node(node);
|
||||
DRM_MM_BUG_ON(!drm_mm_clean(&mm));
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
drm_mm_for_each_node_safe(node, next, &mm)
|
||||
drm_mm_remove_node(node);
|
||||
drm_mm_takedown(&mm);
|
||||
kfree(order);
|
||||
err_bitmap:
|
||||
kfree(bitmap);
|
||||
err_nodes:
|
||||
vfree(nodes);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void separate_adjacent_colors(const struct drm_mm_node *node,
|
||||
unsigned long color,
|
||||
u64 *start,
|
||||
|
@ -1904,7 +1999,7 @@ static int evict_color(struct drm_mm *mm,
|
|||
drm_mm_scan_init_with_range(&scan, mm,
|
||||
size, alignment, color,
|
||||
range_start, range_end,
|
||||
mode->create_flags);
|
||||
mode->mode);
|
||||
if (!evict_nodes(&scan,
|
||||
nodes, order, count, true,
|
||||
&evict_list))
|
||||
|
@ -1912,8 +2007,7 @@ static int evict_color(struct drm_mm *mm,
|
|||
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
err = drm_mm_insert_node_generic(mm, &tmp, size, alignment, color,
|
||||
mode->search_flags,
|
||||
mode->create_flags);
|
||||
DRM_MM_INSERT_EVICT);
|
||||
if (err) {
|
||||
pr_err("Failed to insert into eviction hole: size=%d, align=%d, color=%lu, err=%d\n",
|
||||
size, alignment, color, err);
|
||||
|
|
|
@ -109,8 +109,7 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
|
|||
if (pool == AGP_TYPE) {
|
||||
retval = drm_mm_insert_node(&dev_priv->agp_mm,
|
||||
&item->mm_node,
|
||||
mem->size, 0,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
mem->size);
|
||||
offset = item->mm_node.start;
|
||||
} else {
|
||||
#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE)
|
||||
|
@ -122,8 +121,7 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
|
|||
#else
|
||||
retval = drm_mm_insert_node(&dev_priv->vram_mm,
|
||||
&item->mm_node,
|
||||
mem->size, 0,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
mem->size);
|
||||
offset = item->mm_node.start;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -360,7 +360,7 @@ static int sti_bind(struct device *dev)
|
|||
|
||||
private = ddev->dev_private;
|
||||
if (ddev->mode_config.num_connector) {
|
||||
fbdev = drm_fbdev_cma_init(ddev, 32, ddev->mode_config.num_crtc,
|
||||
fbdev = drm_fbdev_cma_init(ddev, 32,
|
||||
ddev->mode_config.num_connector);
|
||||
if (IS_ERR(fbdev)) {
|
||||
DRM_DEBUG_DRIVER("Warning: fails to create fbdev\n");
|
||||
|
|
|
@ -40,9 +40,7 @@ struct drm_fbdev_cma *sun4i_framebuffer_init(struct drm_device *drm)
|
|||
|
||||
drm->mode_config.funcs = &sun4i_de_mode_config_funcs;
|
||||
|
||||
return drm_fbdev_cma_init(drm, 32,
|
||||
drm->mode_config.num_crtc,
|
||||
drm->mode_config.num_connector);
|
||||
return drm_fbdev_cma_init(drm, 32, drm->mode_config.num_connector);
|
||||
}
|
||||
|
||||
void sun4i_framebuffer_free(struct drm_device *drm)
|
||||
|
|
|
@ -309,7 +309,7 @@ static int tegra_fbdev_init(struct tegra_fbdev *fbdev,
|
|||
struct drm_device *drm = fbdev->base.dev;
|
||||
int err;
|
||||
|
||||
err = drm_fb_helper_init(drm, &fbdev->base, num_crtc, max_connectors);
|
||||
err = drm_fb_helper_init(drm, &fbdev->base, max_connectors);
|
||||
if (err < 0) {
|
||||
dev_err(drm->dev, "failed to initialize DRM FB helper: %d\n",
|
||||
err);
|
||||
|
|
|
@ -128,8 +128,8 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
|
|||
if (!bo->mm)
|
||||
return -ENOMEM;
|
||||
|
||||
err = drm_mm_insert_node_generic(&tegra->mm, bo->mm, bo->gem.size,
|
||||
PAGE_SIZE, 0, 0, 0);
|
||||
err = drm_mm_insert_node_generic(&tegra->mm,
|
||||
bo->mm, bo->gem.size, PAGE_SIZE, 0, 0);
|
||||
if (err < 0) {
|
||||
dev_err(tegra->drm->dev, "out of I/O virtual memory: %zd\n",
|
||||
err);
|
||||
|
|
|
@ -403,8 +403,7 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
|
|||
drm_mode_config_reset(ddev);
|
||||
|
||||
priv->fbdev = drm_fbdev_cma_init(ddev, bpp,
|
||||
ddev->mode_config.num_crtc,
|
||||
ddev->mode_config.num_connector);
|
||||
ddev->mode_config.num_connector);
|
||||
if (IS_ERR(priv->fbdev)) {
|
||||
ret = PTR_ERR(priv->fbdev);
|
||||
goto init_failed;
|
||||
|
|
|
@ -54,9 +54,8 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
|
|||
{
|
||||
struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
|
||||
struct drm_mm *mm = &rman->mm;
|
||||
struct drm_mm_node *node = NULL;
|
||||
enum drm_mm_search_flags sflags = DRM_MM_SEARCH_BEST;
|
||||
enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT;
|
||||
struct drm_mm_node *node;
|
||||
enum drm_mm_insert_mode mode;
|
||||
unsigned long lpfn;
|
||||
int ret;
|
||||
|
||||
|
@ -68,16 +67,15 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
|
|||
if (!node)
|
||||
return -ENOMEM;
|
||||
|
||||
if (place->flags & TTM_PL_FLAG_TOPDOWN) {
|
||||
sflags = DRM_MM_SEARCH_BELOW;
|
||||
aflags = DRM_MM_CREATE_TOP;
|
||||
}
|
||||
mode = DRM_MM_INSERT_BEST;
|
||||
if (place->flags & TTM_PL_FLAG_TOPDOWN)
|
||||
mode = DRM_MM_INSERT_HIGH;
|
||||
|
||||
spin_lock(&rman->lock);
|
||||
ret = drm_mm_insert_node_in_range_generic(mm, node, mem->num_pages,
|
||||
ret = drm_mm_insert_node_in_range(mm, node,
|
||||
mem->num_pages,
|
||||
mem->page_alignment, 0,
|
||||
place->fpfn, lpfn,
|
||||
sflags, aflags);
|
||||
place->fpfn, lpfn, mode);
|
||||
spin_unlock(&rman->lock);
|
||||
|
||||
if (unlikely(ret)) {
|
||||
|
|
|
@ -441,8 +441,7 @@ int udl_fbdev_init(struct drm_device *dev)
|
|||
|
||||
drm_fb_helper_prepare(dev, &ufbdev->helper, &udl_fb_helper_funcs);
|
||||
|
||||
ret = drm_fb_helper_init(dev, &ufbdev->helper,
|
||||
1, 1);
|
||||
ret = drm_fb_helper_init(dev, &ufbdev->helper, 1);
|
||||
if (ret)
|
||||
goto free;
|
||||
|
||||
|
|
|
@ -2,10 +2,12 @@ config DRM_VC4
|
|||
tristate "Broadcom VC4 Graphics"
|
||||
depends on ARCH_BCM2835 || COMPILE_TEST
|
||||
depends on DRM
|
||||
depends on COMMON_CLK
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_KMS_CMA_HELPER
|
||||
select DRM_GEM_CMA_HELPER
|
||||
select DRM_PANEL
|
||||
select DRM_MIPI_DSI
|
||||
help
|
||||
Choose this option if you have a system that has a Broadcom
|
||||
VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835.
|
||||
|
|
|
@ -8,6 +8,7 @@ vc4-y := \
|
|||
vc4_crtc.o \
|
||||
vc4_drv.o \
|
||||
vc4_dpi.o \
|
||||
vc4_dsi.o \
|
||||
vc4_kms.o \
|
||||
vc4_gem.o \
|
||||
vc4_hdmi.o \
|
||||
|
|
|
@ -348,38 +348,40 @@ static u32 vc4_get_fifo_full_level(u32 format)
|
|||
}
|
||||
|
||||
/*
|
||||
* Returns the clock select bit for the connector attached to the
|
||||
* CRTC.
|
||||
* Returns the encoder attached to the CRTC.
|
||||
*
|
||||
* VC4 can only scan out to one encoder at a time, while the DRM core
|
||||
* allows drivers to push pixels to more than one encoder from the
|
||||
* same CRTC.
|
||||
*/
|
||||
static int vc4_get_clock_select(struct drm_crtc *crtc)
|
||||
static struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
|
||||
drm_for_each_connector(connector, crtc->dev) {
|
||||
if (connector->state->crtc == crtc) {
|
||||
struct drm_encoder *encoder = connector->encoder;
|
||||
struct vc4_encoder *vc4_encoder =
|
||||
to_vc4_encoder(encoder);
|
||||
|
||||
return vc4_encoder->clock_select;
|
||||
return connector->encoder;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct vc4_dev *vc4 = to_vc4_dev(dev);
|
||||
struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
|
||||
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
|
||||
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
|
||||
struct drm_crtc_state *state = crtc->state;
|
||||
struct drm_display_mode *mode = &state->adjusted_mode;
|
||||
bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
|
||||
u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
|
||||
u32 format = PV_CONTROL_FORMAT_24;
|
||||
bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
|
||||
vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
|
||||
u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
|
||||
bool debug_dump_regs = false;
|
||||
int clock_select = vc4_get_clock_select(crtc);
|
||||
|
||||
if (debug_dump_regs) {
|
||||
DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
|
||||
|
@ -435,17 +437,19 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
|
|||
*/
|
||||
CRTC_WRITE(PV_V_CONTROL,
|
||||
PV_VCONTROL_CONTINUOUS |
|
||||
(is_dsi ? PV_VCONTROL_DSI : 0) |
|
||||
PV_VCONTROL_INTERLACE |
|
||||
VC4_SET_FIELD(mode->htotal * pixel_rep / 2,
|
||||
PV_VCONTROL_ODD_DELAY));
|
||||
CRTC_WRITE(PV_VSYNCD_EVEN, 0);
|
||||
} else {
|
||||
CRTC_WRITE(PV_V_CONTROL, PV_VCONTROL_CONTINUOUS);
|
||||
CRTC_WRITE(PV_V_CONTROL,
|
||||
PV_VCONTROL_CONTINUOUS |
|
||||
(is_dsi ? PV_VCONTROL_DSI : 0));
|
||||
}
|
||||
|
||||
CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
|
||||
|
||||
|
||||
CRTC_WRITE(PV_CONTROL,
|
||||
VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
|
||||
VC4_SET_FIELD(vc4_get_fifo_full_level(format),
|
||||
|
@ -454,7 +458,8 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
|
|||
PV_CONTROL_CLR_AT_START |
|
||||
PV_CONTROL_TRIGGER_UNDERFLOW |
|
||||
PV_CONTROL_WAIT_HSTART |
|
||||
VC4_SET_FIELD(clock_select, PV_CONTROL_CLK_SELECT) |
|
||||
VC4_SET_FIELD(vc4_encoder->clock_select,
|
||||
PV_CONTROL_CLK_SELECT) |
|
||||
PV_CONTROL_FIFO_CLR |
|
||||
PV_CONTROL_EN);
|
||||
|
||||
|
@ -588,7 +593,7 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
|
|||
|
||||
spin_lock_irqsave(&vc4->hvs->mm_lock, flags);
|
||||
ret = drm_mm_insert_node(&vc4->hvs->dlist_mm, &vc4_state->mm,
|
||||
dlist_count, 1, 0);
|
||||
dlist_count);
|
||||
spin_unlock_irqrestore(&vc4->hvs->mm_lock, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
static const struct drm_info_list vc4_debugfs_list[] = {
|
||||
{"bo_stats", vc4_bo_stats_debugfs, 0},
|
||||
{"dpi_regs", vc4_dpi_debugfs_regs, 0},
|
||||
{"dsi1_regs", vc4_dsi_debugfs_regs, 0, (void *)(uintptr_t)1},
|
||||
{"hdmi_regs", vc4_hdmi_debugfs_regs, 0},
|
||||
{"vec_regs", vc4_vec_debugfs_regs, 0},
|
||||
{"hvs_regs", vc4_hvs_debugfs_regs, 0},
|
||||
|
|
|
@ -295,6 +295,7 @@ static struct platform_driver *const component_drivers[] = {
|
|||
&vc4_hdmi_driver,
|
||||
&vc4_vec_driver,
|
||||
&vc4_dpi_driver,
|
||||
&vc4_dsi_driver,
|
||||
&vc4_hvs_driver,
|
||||
&vc4_crtc_driver,
|
||||
&vc4_v3d_driver,
|
||||
|
|
|
@ -18,6 +18,7 @@ struct vc4_dev {
|
|||
struct vc4_hvs *hvs;
|
||||
struct vc4_v3d *v3d;
|
||||
struct vc4_dpi *dpi;
|
||||
struct vc4_dsi *dsi1;
|
||||
struct vc4_vec *vec;
|
||||
|
||||
struct drm_fbdev_cma *fbdev;
|
||||
|
@ -465,6 +466,10 @@ void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index);
|
|||
extern struct platform_driver vc4_dpi_driver;
|
||||
int vc4_dpi_debugfs_regs(struct seq_file *m, void *unused);
|
||||
|
||||
/* vc4_dsi.c */
|
||||
extern struct platform_driver vc4_dsi_driver;
|
||||
int vc4_dsi_debugfs_regs(struct seq_file *m, void *unused);
|
||||
|
||||
/* vc4_gem.c */
|
||||
void vc4_gem_init(struct drm_device *dev);
|
||||
void vc4_gem_destroy(struct drm_device *dev);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -141,8 +141,7 @@ static int vc4_hvs_upload_linear_kernel(struct vc4_hvs *hvs,
|
|||
int ret, i;
|
||||
u32 __iomem *dst_kernel;
|
||||
|
||||
ret = drm_mm_insert_node(&hvs->dlist_mm, space, VC4_KERNEL_DWORDS, 1,
|
||||
0);
|
||||
ret = drm_mm_insert_node(&hvs->dlist_mm, space, VC4_KERNEL_DWORDS);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to allocate space for filter kernel: %d\n",
|
||||
ret);
|
||||
|
@ -170,6 +169,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
|
|||
struct vc4_dev *vc4 = drm->dev_private;
|
||||
struct vc4_hvs *hvs = NULL;
|
||||
int ret;
|
||||
u32 dispctrl;
|
||||
|
||||
hvs = devm_kzalloc(&pdev->dev, sizeof(*hvs), GFP_KERNEL);
|
||||
if (!hvs)
|
||||
|
@ -211,6 +211,19 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
|
|||
return ret;
|
||||
|
||||
vc4->hvs = hvs;
|
||||
|
||||
dispctrl = HVS_READ(SCALER_DISPCTRL);
|
||||
|
||||
dispctrl |= SCALER_DISPCTRL_ENABLE;
|
||||
|
||||
/* Set DSP3 (PV1) to use HVS channel 2, which would otherwise
|
||||
* be unused.
|
||||
*/
|
||||
dispctrl &= ~SCALER_DISPCTRL_DSP3_MUX_MASK;
|
||||
dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX);
|
||||
|
||||
HVS_WRITE(SCALER_DISPCTRL, dispctrl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -231,7 +231,6 @@ int vc4_kms_load(struct drm_device *dev)
|
|||
drm_mode_config_reset(dev);
|
||||
|
||||
vc4->fbdev = drm_fbdev_cma_init(dev, 32,
|
||||
dev->mode_config.num_crtc,
|
||||
dev->mode_config.num_connector);
|
||||
if (IS_ERR(vc4->fbdev))
|
||||
vc4->fbdev = NULL;
|
||||
|
|
|
@ -514,9 +514,9 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
|
|||
if (lbm_size) {
|
||||
if (!vc4_state->lbm.allocated) {
|
||||
spin_lock_irqsave(&vc4->hvs->mm_lock, irqflags);
|
||||
ret = drm_mm_insert_node(&vc4->hvs->lbm_mm,
|
||||
&vc4_state->lbm,
|
||||
lbm_size, 32, 0);
|
||||
ret = drm_mm_insert_node_generic(&vc4->hvs->lbm_mm,
|
||||
&vc4_state->lbm,
|
||||
lbm_size, 32, 0, 0);
|
||||
spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags);
|
||||
} else {
|
||||
WARN_ON_ONCE(lbm_size != vc4_state->lbm.size);
|
||||
|
|
|
@ -190,6 +190,8 @@
|
|||
# define PV_VCONTROL_ODD_DELAY_SHIFT 6
|
||||
# define PV_VCONTROL_ODD_FIRST BIT(5)
|
||||
# define PV_VCONTROL_INTERLACE BIT(4)
|
||||
# define PV_VCONTROL_DSI BIT(3)
|
||||
# define PV_VCONTROL_COMMAND BIT(2)
|
||||
# define PV_VCONTROL_CONTINUOUS BIT(1)
|
||||
# define PV_VCONTROL_VIDEN BIT(0)
|
||||
|
||||
|
@ -244,6 +246,9 @@
|
|||
# define SCALER_DISPCTRL_ENABLE BIT(31)
|
||||
# define SCALER_DISPCTRL_DSP2EISLUR BIT(15)
|
||||
# define SCALER_DISPCTRL_DSP1EISLUR BIT(14)
|
||||
# define SCALER_DISPCTRL_DSP3_MUX_MASK VC4_MASK(19, 18)
|
||||
# define SCALER_DISPCTRL_DSP3_MUX_SHIFT 18
|
||||
|
||||
/* Enables Display 0 short line and underrun contribution to
|
||||
* SCALER_DISPSTAT_IRQDISP0. Note that short frame contributions are
|
||||
* always enabled.
|
||||
|
|
|
@ -140,11 +140,11 @@ int via_mem_alloc(struct drm_device *dev, void *data,
|
|||
if (mem->type == VIA_MEM_AGP)
|
||||
retval = drm_mm_insert_node(&dev_priv->agp_mm,
|
||||
&item->mm_node,
|
||||
tmpSize, 0, DRM_MM_SEARCH_DEFAULT);
|
||||
tmpSize);
|
||||
else
|
||||
retval = drm_mm_insert_node(&dev_priv->vram_mm,
|
||||
&item->mm_node,
|
||||
tmpSize, 0, DRM_MM_SEARCH_DEFAULT);
|
||||
tmpSize);
|
||||
if (retval)
|
||||
goto fail_alloc;
|
||||
|
||||
|
|
|
@ -387,7 +387,6 @@ int virtio_gpu_fbdev_init(struct virtio_gpu_device *vgdev)
|
|||
drm_fb_helper_prepare(vgdev->ddev, &vgfbdev->helper,
|
||||
&virtio_gpu_fb_helper_funcs);
|
||||
ret = drm_fb_helper_init(vgdev->ddev, &vgfbdev->helper,
|
||||
vgdev->num_scanouts,
|
||||
VIRTIO_GPUFB_CONN_LIMIT);
|
||||
if (ret) {
|
||||
kfree(vgfbdev);
|
||||
|
|
|
@ -166,10 +166,14 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
INIT_WORK(&vgdev->config_changed_work,
|
||||
virtio_gpu_config_changed_work_func);
|
||||
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_VIRGL))
|
||||
vgdev->has_virgl_3d = true;
|
||||
DRM_INFO("virgl 3d acceleration %s\n",
|
||||
vgdev->has_virgl_3d ? "enabled" : "not available");
|
||||
vgdev->has_virgl_3d ? "enabled" : "not supported by host");
|
||||
#else
|
||||
DRM_INFO("virgl 3d acceleration not supported by guest\n");
|
||||
#endif
|
||||
|
||||
ret = vgdev->vdev->config->find_vqs(vgdev->vdev, 2, vqs,
|
||||
callbacks, names);
|
||||
|
|
|
@ -673,16 +673,10 @@ static bool vmw_cmdbuf_try_alloc(struct vmw_cmdbuf_man *man,
|
|||
|
||||
memset(info->node, 0, sizeof(*info->node));
|
||||
spin_lock_bh(&man->lock);
|
||||
ret = drm_mm_insert_node_generic(&man->mm, info->node, info->page_size,
|
||||
0, 0,
|
||||
DRM_MM_SEARCH_DEFAULT,
|
||||
DRM_MM_CREATE_DEFAULT);
|
||||
ret = drm_mm_insert_node(&man->mm, info->node, info->page_size);
|
||||
if (ret) {
|
||||
vmw_cmdbuf_man_process(man);
|
||||
ret = drm_mm_insert_node_generic(&man->mm, info->node,
|
||||
info->page_size, 0, 0,
|
||||
DRM_MM_SEARCH_DEFAULT,
|
||||
DRM_MM_CREATE_DEFAULT);
|
||||
ret = drm_mm_insert_node(&man->mm, info->node, info->page_size);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&man->lock);
|
||||
|
|
|
@ -141,7 +141,7 @@ static int zx_drm_bind(struct device *dev)
|
|||
drm_mode_config_reset(drm);
|
||||
drm_kms_helper_poll_init(drm);
|
||||
|
||||
priv->fbdev = drm_fbdev_cma_init(drm, 32, drm->mode_config.num_crtc,
|
||||
priv->fbdev = drm_fbdev_cma_init(drm, 32,
|
||||
drm->mode_config.num_connector);
|
||||
if (IS_ERR(priv->fbdev)) {
|
||||
ret = PTR_ERR(priv->fbdev);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#ifndef __MHL_H__
|
||||
#define __MHL_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* Device Capabilities Registers */
|
||||
enum {
|
||||
MHL_DCAP_DEV_STATE,
|
||||
|
@ -288,4 +290,87 @@ enum {
|
|||
/* Unsupported/unrecognized key code */
|
||||
#define MHL_UCPE_STATUS_INEFFECTIVE_KEY_CODE 0x01
|
||||
|
||||
enum mhl_burst_id {
|
||||
MHL_BURST_ID_3D_VIC = 0x10,
|
||||
MHL_BURST_ID_3D_DTD = 0x11,
|
||||
MHL_BURST_ID_HEV_VIC = 0x20,
|
||||
MHL_BURST_ID_HEV_DTDA = 0x21,
|
||||
MHL_BURST_ID_HEV_DTDB = 0x22,
|
||||
MHL_BURST_ID_VC_ASSIGN = 0x38,
|
||||
MHL_BURST_ID_VC_CONFIRM = 0x39,
|
||||
MHL_BURST_ID_AUD_DELAY = 0x40,
|
||||
MHL_BURST_ID_ADT_BURSTID = 0x41,
|
||||
MHL_BURST_ID_BIST_SETUP = 0x51,
|
||||
MHL_BURST_ID_BIST_RETURN_STAT = 0x52,
|
||||
MHL_BURST_ID_EMSC_SUPPORT = 0x61,
|
||||
MHL_BURST_ID_HID_PAYLOAD = 0x62,
|
||||
MHL_BURST_ID_BLK_RCV_BUFFER_INFO = 0x63,
|
||||
MHL_BURST_ID_BITS_PER_PIXEL_FMT = 0x64,
|
||||
};
|
||||
|
||||
struct mhl_burst_blk_rcv_buffer_info {
|
||||
__be16 id;
|
||||
__le16 size;
|
||||
} __packed;
|
||||
|
||||
struct mhl3_burst_header {
|
||||
__be16 id;
|
||||
u8 checksum;
|
||||
u8 total_entries;
|
||||
u8 sequence_index;
|
||||
} __packed;
|
||||
|
||||
struct mhl_burst_bits_per_pixel_fmt {
|
||||
struct mhl3_burst_header hdr;
|
||||
u8 num_entries;
|
||||
struct {
|
||||
u8 stream_id;
|
||||
u8 pixel_format;
|
||||
} __packed desc[0];
|
||||
} __packed;
|
||||
|
||||
struct mhl_burst_emsc_support {
|
||||
struct mhl3_burst_header hdr;
|
||||
u8 num_entries;
|
||||
__be16 burst_id[0];
|
||||
} __packed;
|
||||
|
||||
struct mhl_burst_audio_descr {
|
||||
struct mhl3_burst_header hdr;
|
||||
u8 flags;
|
||||
u8 short_desc[9];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* MHL3 infoframe related definitions
|
||||
*/
|
||||
|
||||
#define MHL3_IEEE_OUI 0x7ca61d
|
||||
#define MHL3_INFOFRAME_SIZE 15
|
||||
|
||||
enum mhl3_video_format {
|
||||
MHL3_VIDEO_FORMAT_NONE,
|
||||
MHL3_VIDEO_FORMAT_3D,
|
||||
MHL3_VIDEO_FORMAT_MULTI_VIEW,
|
||||
MHL3_VIDEO_FORMAT_DUAL_3D
|
||||
};
|
||||
|
||||
enum mhl3_3d_format_type {
|
||||
MHL3_3D_FORMAT_TYPE_FS, /* frame sequential */
|
||||
MHL3_3D_FORMAT_TYPE_TB, /* top-bottom */
|
||||
MHL3_3D_FORMAT_TYPE_LR, /* left-right */
|
||||
MHL3_3D_FORMAT_TYPE_FS_TB, /* frame sequential, top-bottom */
|
||||
MHL3_3D_FORMAT_TYPE_FS_LR, /* frame sequential, left-right */
|
||||
MHL3_3D_FORMAT_TYPE_TB_LR /* top-bottom, left-right */
|
||||
};
|
||||
|
||||
struct mhl3_infoframe {
|
||||
unsigned char version;
|
||||
enum mhl3_video_format video_format;
|
||||
enum mhl3_3d_format_type format_type;
|
||||
bool sep_audio;
|
||||
int hev_format;
|
||||
int av_delay;
|
||||
};
|
||||
|
||||
#endif /* __MHL_H__ */
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include <linux/ctype.h>
|
||||
|
||||
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
|
||||
|
||||
void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
|
||||
uint degamma_lut_size,
|
||||
bool has_ctm,
|
||||
|
@ -33,29 +35,4 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
|
|||
int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
|
||||
int gamma_size);
|
||||
|
||||
/**
|
||||
* drm_color_lut_extract - clamp and round LUT entries
|
||||
* @user_input: input value
|
||||
* @bit_precision: number of bits the hw LUT supports
|
||||
*
|
||||
* Extract a degamma/gamma LUT value provided by user (in the form of
|
||||
* &drm_color_lut entries) and round it to the precision supported by the
|
||||
* hardware.
|
||||
*/
|
||||
static inline uint32_t drm_color_lut_extract(uint32_t user_input,
|
||||
uint32_t bit_precision)
|
||||
{
|
||||
uint32_t val = user_input;
|
||||
uint32_t max = 0xffff >> (16 - bit_precision);
|
||||
|
||||
/* Round only if we're not using full precision. */
|
||||
if (bit_precision < 16) {
|
||||
val += 1UL << (16 - bit_precision - 1);
|
||||
val >>= 16 - bit_precision;
|
||||
}
|
||||
|
||||
return clamp_val(val, 0, max);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -102,6 +102,17 @@ struct drm_driver {
|
|||
*
|
||||
*/
|
||||
void (*unload) (struct drm_device *);
|
||||
|
||||
/**
|
||||
* @release:
|
||||
*
|
||||
* Optional callback for destroying device data after the final
|
||||
* reference is released, i.e. the device is being destroyed. Drivers
|
||||
* using this callback are responsible for calling drm_dev_fini()
|
||||
* to finalize the device and then freeing the struct themselves.
|
||||
*/
|
||||
void (*release) (struct drm_device *);
|
||||
|
||||
int (*set_busid)(struct drm_device *dev, struct drm_master *master);
|
||||
|
||||
/**
|
||||
|
@ -437,6 +448,8 @@ extern unsigned int drm_debug;
|
|||
int drm_dev_init(struct drm_device *dev,
|
||||
struct drm_driver *driver,
|
||||
struct device *parent);
|
||||
void drm_dev_fini(struct drm_device *dev);
|
||||
|
||||
struct drm_device *drm_dev_alloc(struct drm_driver *driver,
|
||||
struct device *parent);
|
||||
int drm_dev_register(struct drm_device *dev, unsigned long flags);
|
||||
|
|
|
@ -16,11 +16,10 @@ struct drm_plane;
|
|||
struct drm_plane_state;
|
||||
|
||||
struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *dev,
|
||||
unsigned int preferred_bpp, unsigned int num_crtc,
|
||||
unsigned int max_conn_count, const struct drm_framebuffer_funcs *funcs);
|
||||
unsigned int preferred_bpp, unsigned int max_conn_count,
|
||||
const struct drm_framebuffer_funcs *funcs);
|
||||
struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev,
|
||||
unsigned int preferred_bpp, unsigned int num_crtc,
|
||||
unsigned int max_conn_count);
|
||||
unsigned int preferred_bpp, unsigned int max_conn_count);
|
||||
void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma);
|
||||
|
||||
void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma);
|
||||
|
|
|
@ -236,8 +236,7 @@ struct drm_fb_helper {
|
|||
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
|
||||
const struct drm_fb_helper_funcs *funcs);
|
||||
int drm_fb_helper_init(struct drm_device *dev,
|
||||
struct drm_fb_helper *helper, int crtc_count,
|
||||
int max_conn);
|
||||
struct drm_fb_helper *helper, int max_conn);
|
||||
void drm_fb_helper_fini(struct drm_fb_helper *helper);
|
||||
int drm_fb_helper_blank(int blank, struct fb_info *info);
|
||||
int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
|
||||
|
@ -308,7 +307,7 @@ static inline void drm_fb_helper_prepare(struct drm_device *dev,
|
|||
}
|
||||
|
||||
static inline int drm_fb_helper_init(struct drm_device *dev,
|
||||
struct drm_fb_helper *helper, int crtc_count,
|
||||
struct drm_fb_helper *helper,
|
||||
int max_conn)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -53,19 +53,62 @@
|
|||
#define DRM_MM_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr)
|
||||
#endif
|
||||
|
||||
enum drm_mm_search_flags {
|
||||
DRM_MM_SEARCH_DEFAULT = 0,
|
||||
DRM_MM_SEARCH_BEST = 1 << 0,
|
||||
DRM_MM_SEARCH_BELOW = 1 << 1,
|
||||
};
|
||||
/**
|
||||
* enum drm_mm_insert_mode - control search and allocation behaviour
|
||||
*
|
||||
* The &struct drm_mm range manager supports finding a suitable modes using
|
||||
* a number of search trees. These trees are oranised by size, by address and
|
||||
* in most recent eviction order. This allows the user to find either the
|
||||
* smallest hole to reuse, the lowest or highest address to reuse, or simply
|
||||
* reuse the most recent eviction that fits. When allocating the &drm_mm_node
|
||||
* from within the hole, the &drm_mm_insert_mode also dictate whether to
|
||||
* allocate the lowest matching address or the highest.
|
||||
*/
|
||||
enum drm_mm_insert_mode {
|
||||
/**
|
||||
* @DRM_MM_INSERT_BEST:
|
||||
*
|
||||
* Search for the smallest hole (within the search range) that fits
|
||||
* the desired node.
|
||||
*
|
||||
* Allocates the node from the bottom of the found hole.
|
||||
*/
|
||||
DRM_MM_INSERT_BEST = 0,
|
||||
|
||||
enum drm_mm_allocator_flags {
|
||||
DRM_MM_CREATE_DEFAULT = 0,
|
||||
DRM_MM_CREATE_TOP = 1 << 0,
|
||||
};
|
||||
/**
|
||||
* @DRM_MM_INSERT_LOW:
|
||||
*
|
||||
* Search for the lowest hole (address closest to 0, within the search
|
||||
* range) that fits the desired node.
|
||||
*
|
||||
* Allocates the node from the bottom of the found hole.
|
||||
*/
|
||||
DRM_MM_INSERT_LOW,
|
||||
|
||||
#define DRM_MM_BOTTOMUP DRM_MM_SEARCH_DEFAULT, DRM_MM_CREATE_DEFAULT
|
||||
#define DRM_MM_TOPDOWN DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP
|
||||
/**
|
||||
* @DRM_MM_INSERT_HIGH:
|
||||
*
|
||||
* Search for the highest hole (address closest to U64_MAX, within the
|
||||
* search range) that fits the desired node.
|
||||
*
|
||||
* Allocates the node from the *top* of the found hole. The specified
|
||||
* alignment for the node is applied to the base of the node
|
||||
* (&drm_mm_node.start).
|
||||
*/
|
||||
DRM_MM_INSERT_HIGH,
|
||||
|
||||
/**
|
||||
* @DRM_MM_INSERT_EVICT:
|
||||
*
|
||||
* Search for the most recently evicted hole (within the search range)
|
||||
* that fits the desired node. This is appropriate for use immediately
|
||||
* after performing an eviction scan (see drm_mm_scan_init()) and
|
||||
* removing the selected nodes to form a hole.
|
||||
*
|
||||
* Allocates the node from the bottom of the found hole.
|
||||
*/
|
||||
DRM_MM_INSERT_EVICT,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_mm_node - allocated block in the DRM allocator
|
||||
|
@ -84,14 +127,16 @@ struct drm_mm_node {
|
|||
/** @size: Size of the allocated block. */
|
||||
u64 size;
|
||||
/* private: */
|
||||
struct drm_mm *mm;
|
||||
struct list_head node_list;
|
||||
struct list_head hole_stack;
|
||||
struct rb_node rb;
|
||||
unsigned hole_follows : 1;
|
||||
unsigned allocated : 1;
|
||||
bool scanned_block : 1;
|
||||
struct rb_node rb_hole_size;
|
||||
struct rb_node rb_hole_addr;
|
||||
u64 __subtree_last;
|
||||
struct drm_mm *mm;
|
||||
u64 hole_size;
|
||||
bool allocated : 1;
|
||||
bool scanned_block : 1;
|
||||
#ifdef CONFIG_DRM_DEBUG_MM
|
||||
depot_stack_handle_t stack;
|
||||
#endif
|
||||
|
@ -127,6 +172,8 @@ struct drm_mm {
|
|||
struct drm_mm_node head_node;
|
||||
/* Keep an interval_tree for fast lookup of drm_mm_nodes by address. */
|
||||
struct rb_root interval_tree;
|
||||
struct rb_root holes_size;
|
||||
struct rb_root holes_addr;
|
||||
|
||||
unsigned long scan_active;
|
||||
};
|
||||
|
@ -155,7 +202,7 @@ struct drm_mm_scan {
|
|||
u64 hit_end;
|
||||
|
||||
unsigned long color;
|
||||
unsigned int flags;
|
||||
enum drm_mm_insert_mode mode;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -208,7 +255,7 @@ static inline bool drm_mm_initialized(const struct drm_mm *mm)
|
|||
*/
|
||||
static inline bool drm_mm_hole_follows(const struct drm_mm_node *node)
|
||||
{
|
||||
return node->hole_follows;
|
||||
return node->hole_size;
|
||||
}
|
||||
|
||||
static inline u64 __drm_mm_hole_node_start(const struct drm_mm_node *hole_node)
|
||||
|
@ -291,17 +338,9 @@ static inline u64 drm_mm_hole_node_end(const struct drm_mm_node *hole_node)
|
|||
#define drm_mm_for_each_node_safe(entry, next, mm) \
|
||||
list_for_each_entry_safe(entry, next, drm_mm_nodes(mm), node_list)
|
||||
|
||||
#define __drm_mm_for_each_hole(entry, mm, hole_start, hole_end, backwards) \
|
||||
for (entry = list_entry((backwards) ? (mm)->hole_stack.prev : (mm)->hole_stack.next, struct drm_mm_node, hole_stack); \
|
||||
&entry->hole_stack != &(mm)->hole_stack ? \
|
||||
hole_start = drm_mm_hole_node_start(entry), \
|
||||
hole_end = drm_mm_hole_node_end(entry), \
|
||||
1 : 0; \
|
||||
entry = list_entry((backwards) ? entry->hole_stack.prev : entry->hole_stack.next, struct drm_mm_node, hole_stack))
|
||||
|
||||
/**
|
||||
* drm_mm_for_each_hole - iterator to walk over all holes
|
||||
* @entry: &drm_mm_node used internally to track progress
|
||||
* @pos: &drm_mm_node used internally to track progress
|
||||
* @mm: &drm_mm allocator to walk
|
||||
* @hole_start: ulong variable to assign the hole start to on each iteration
|
||||
* @hole_end: ulong variable to assign the hole end to on each iteration
|
||||
|
@ -314,57 +353,28 @@ static inline u64 drm_mm_hole_node_end(const struct drm_mm_node *hole_node)
|
|||
* Implementation Note:
|
||||
* We need to inline list_for_each_entry in order to be able to set hole_start
|
||||
* and hole_end on each iteration while keeping the macro sane.
|
||||
*
|
||||
* The __drm_mm_for_each_hole version is similar, but with added support for
|
||||
* going backwards.
|
||||
*/
|
||||
#define drm_mm_for_each_hole(entry, mm, hole_start, hole_end) \
|
||||
__drm_mm_for_each_hole(entry, mm, hole_start, hole_end, 0)
|
||||
#define drm_mm_for_each_hole(pos, mm, hole_start, hole_end) \
|
||||
for (pos = list_first_entry(&(mm)->hole_stack, \
|
||||
typeof(*pos), hole_stack); \
|
||||
&pos->hole_stack != &(mm)->hole_stack ? \
|
||||
hole_start = drm_mm_hole_node_start(pos), \
|
||||
hole_end = hole_start + pos->hole_size, \
|
||||
1 : 0; \
|
||||
pos = list_next_entry(pos, hole_stack))
|
||||
|
||||
/*
|
||||
* Basic range manager support (drm_mm.c)
|
||||
*/
|
||||
int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node);
|
||||
int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
|
||||
struct drm_mm_node *node,
|
||||
u64 size,
|
||||
u64 alignment,
|
||||
unsigned long color,
|
||||
u64 start,
|
||||
u64 end,
|
||||
enum drm_mm_search_flags sflags,
|
||||
enum drm_mm_allocator_flags aflags);
|
||||
|
||||
/**
|
||||
* drm_mm_insert_node_in_range - ranged search for space and insert @node
|
||||
* @mm: drm_mm to allocate from
|
||||
* @node: preallocate node to insert
|
||||
* @size: size of the allocation
|
||||
* @alignment: alignment of the allocation
|
||||
* @start: start of the allowed range for this node
|
||||
* @end: end of the allowed range for this node
|
||||
* @flags: flags to fine-tune the allocation
|
||||
*
|
||||
* This is a simplified version of drm_mm_insert_node_in_range_generic() with
|
||||
* @color set to 0.
|
||||
*
|
||||
* The preallocated node must be cleared to 0.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, -ENOSPC if there's no suitable hole.
|
||||
*/
|
||||
static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
|
||||
struct drm_mm_node *node,
|
||||
u64 size,
|
||||
u64 alignment,
|
||||
u64 start,
|
||||
u64 end,
|
||||
enum drm_mm_search_flags flags)
|
||||
{
|
||||
return drm_mm_insert_node_in_range_generic(mm, node, size, alignment,
|
||||
0, start, end, flags,
|
||||
DRM_MM_CREATE_DEFAULT);
|
||||
}
|
||||
int drm_mm_insert_node_in_range(struct drm_mm *mm,
|
||||
struct drm_mm_node *node,
|
||||
u64 size,
|
||||
u64 alignment,
|
||||
unsigned long color,
|
||||
u64 start,
|
||||
u64 end,
|
||||
enum drm_mm_insert_mode mode);
|
||||
|
||||
/**
|
||||
* drm_mm_insert_node_generic - search for space and insert @node
|
||||
|
@ -373,8 +383,7 @@ static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
|
|||
* @size: size of the allocation
|
||||
* @alignment: alignment of the allocation
|
||||
* @color: opaque tag value to use for this node
|
||||
* @sflags: flags to fine-tune the allocation search
|
||||
* @aflags: flags to fine-tune the allocation behavior
|
||||
* @mode: fine-tune the allocation search and placement
|
||||
*
|
||||
* This is a simplified version of drm_mm_insert_node_in_range_generic() with no
|
||||
* range restrictions applied.
|
||||
|
@ -388,13 +397,11 @@ static inline int
|
|||
drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
|
||||
u64 size, u64 alignment,
|
||||
unsigned long color,
|
||||
enum drm_mm_search_flags sflags,
|
||||
enum drm_mm_allocator_flags aflags)
|
||||
enum drm_mm_insert_mode mode)
|
||||
{
|
||||
return drm_mm_insert_node_in_range_generic(mm, node,
|
||||
size, alignment, 0,
|
||||
0, U64_MAX,
|
||||
sflags, aflags);
|
||||
return drm_mm_insert_node_in_range(mm, node,
|
||||
size, alignment, color,
|
||||
0, U64_MAX, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -402,8 +409,6 @@ drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
|
|||
* @mm: drm_mm to allocate from
|
||||
* @node: preallocate node to insert
|
||||
* @size: size of the allocation
|
||||
* @alignment: alignment of the allocation
|
||||
* @flags: flags to fine-tune the allocation
|
||||
*
|
||||
* This is a simplified version of drm_mm_insert_node_generic() with @color set
|
||||
* to 0.
|
||||
|
@ -415,13 +420,9 @@ drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
|
|||
*/
|
||||
static inline int drm_mm_insert_node(struct drm_mm *mm,
|
||||
struct drm_mm_node *node,
|
||||
u64 size,
|
||||
u64 alignment,
|
||||
enum drm_mm_search_flags flags)
|
||||
u64 size)
|
||||
{
|
||||
return drm_mm_insert_node_generic(mm, node,
|
||||
size, alignment, 0,
|
||||
flags, DRM_MM_CREATE_DEFAULT);
|
||||
return drm_mm_insert_node_generic(mm, node, size, 0, 0, 0);
|
||||
}
|
||||
|
||||
void drm_mm_remove_node(struct drm_mm_node *node);
|
||||
|
@ -468,7 +469,7 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
|
|||
struct drm_mm *mm,
|
||||
u64 size, u64 alignment, unsigned long color,
|
||||
u64 start, u64 end,
|
||||
unsigned int flags);
|
||||
enum drm_mm_insert_mode mode);
|
||||
|
||||
/**
|
||||
* drm_mm_scan_init - initialize lru scanning
|
||||
|
@ -477,7 +478,7 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
|
|||
* @size: size of the allocation
|
||||
* @alignment: alignment of the allocation
|
||||
* @color: opaque tag value to use for the allocation
|
||||
* @flags: flags to specify how the allocation will be performed afterwards
|
||||
* @mode: fine-tune the allocation search and placement
|
||||
*
|
||||
* This is a simplified version of drm_mm_scan_init_with_range() with no range
|
||||
* restrictions applied.
|
||||
|
@ -494,12 +495,11 @@ static inline void drm_mm_scan_init(struct drm_mm_scan *scan,
|
|||
u64 size,
|
||||
u64 alignment,
|
||||
unsigned long color,
|
||||
unsigned int flags)
|
||||
enum drm_mm_insert_mode mode)
|
||||
{
|
||||
drm_mm_scan_init_with_range(scan, mm,
|
||||
size, alignment, color,
|
||||
0, U64_MAX,
|
||||
flags);
|
||||
0, U64_MAX, mode);
|
||||
}
|
||||
|
||||
bool drm_mm_scan_add_block(struct drm_mm_scan *scan,
|
||||
|
|
Loading…
Reference in New Issue