diff options
author | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2021-01-08 12:03:51 +0100 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2021-01-08 12:03:51 +0100 |
commit | 10205618052908770451acd33eaeaa7685e97ed2 (patch) | |
tree | 4d025943e32f343fa917db7abed8a606faa17775 /include/drm | |
parent | drm/i915/dsi: Use unconditional msleep for the panel_on_delay when there is n... (diff) | |
parent | Merge tag 'drm-misc-next-2021-01-06' of git://anongit.freedesktop.org/drm/drm... (diff) | |
download | linux-10205618052908770451acd33eaeaa7685e97ed2.tar.xz linux-10205618052908770451acd33eaeaa7685e97ed2.zip |
Merge drm/drm-next into drm-intel-next
sync-up to not fall too much behind.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Diffstat (limited to 'include/drm')
36 files changed, 739 insertions, 308 deletions
diff --git a/include/drm/amd_asic_type.h b/include/drm/amd_asic_type.h index 8712e14991ed..cde3c8c9f20c 100644 --- a/include/drm/amd_asic_type.h +++ b/include/drm/amd_asic_type.h @@ -56,6 +56,8 @@ enum amd_asic_type { CHIP_NAVI12, /* 27 */ CHIP_SIENNA_CICHLID, /* 28 */ CHIP_NAVY_FLOUNDER, /* 29 */ + CHIP_VANGOGH, /* 30 */ + CHIP_DIMGREY_CAVEFISH, /* 31 */ CHIP_LAST, }; diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index d07c851d255b..ce7023e9115d 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -248,6 +248,26 @@ struct drm_private_state_funcs { * drm_dev_register() * 2/ all calls to drm_atomic_private_obj_fini() must be done after calling * drm_dev_unregister() + * + * If that private object is used to store a state shared by multiple + * CRTCs, proper care must be taken to ensure that non-blocking commits are + * properly ordered to avoid a use-after-free issue. + * + * Indeed, assuming a sequence of two non-blocking &drm_atomic_commit on two + * different &drm_crtc using different &drm_plane and &drm_connector, so with no + * resources shared, there's no guarantee on which commit is going to happen + * first. However, the second &drm_atomic_commit will consider the first + * &drm_private_obj its old state, and will be in charge of freeing it whenever + * the second &drm_atomic_commit is done. + * + * If the first &drm_atomic_commit happens after it, it will consider its + * &drm_private_obj the new state and will be likely to access it, resulting in + * an access to a freed memory region. Drivers should store (and get a reference + * to) the &drm_crtc_commit structure in our private state in + * &drm_mode_config_helper_funcs.atomic_commit_setup, and then wait for that + * commit to complete as the first step of + * &drm_mode_config_helper_funcs.atomic_commit_tail, similar to + * drm_atomic_helper_wait_for_dependencies(). */ struct drm_private_obj { /** @@ -308,7 +328,6 @@ struct __drm_private_objs_state { * struct drm_atomic_state - the global state object for atomic updates * @ref: count of all references to this state (will not be freed until zero) * @dev: parent DRM device - * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics * @async_update: hint for asynchronous plane update * @planes: pointer to array of structures with per-plane data * @crtcs: pointer to array of CRTC pointers @@ -336,6 +355,17 @@ struct drm_atomic_state { * drm_atomic_crtc_needs_modeset(). */ bool allow_modeset : 1; + /** + * @legacy_cursor_update: + * + * Hint to enforce legacy cursor IOCTL semantics. + * + * WARNING: This is thoroughly broken and pretty much impossible to + * implement correctly. Drivers must ignore this and should instead + * implement &drm_plane_helper_funcs.atomic_async_check and + * &drm_plane_helper_funcs.atomic_async_commit hooks. New users of this + * flag are not allowed. + */ bool legacy_cursor_update : 1; bool async_update : 1; /** @@ -773,7 +803,8 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (void)(crtc) /* Only to avoid unused-but-set-variable warning */, \ (old_crtc_state) = (__state)->crtcs[__i].old_state, \ (void)(old_crtc_state) /* Only to avoid unused-but-set-variable warning */, \ - (new_crtc_state) = (__state)->crtcs[__i].new_state, 1)) + (new_crtc_state) = (__state)->crtcs[__i].new_state, \ + (void)(new_crtc_state) /* Only to avoid unused-but-set-variable warning */, 1)) /** * for_each_old_crtc_in_state - iterate over all CRTCs in an atomic update @@ -792,6 +823,7 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (__i)++) \ for_each_if ((__state)->crtcs[__i].ptr && \ ((crtc) = (__state)->crtcs[__i].ptr, \ + (void)(crtc) /* Only to avoid unused-but-set-variable warning */, \ (old_crtc_state) = (__state)->crtcs[__i].old_state, 1)) /** diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 85df04c8e62f..4045e2507e11 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -147,10 +147,6 @@ int drm_atomic_helper_page_flip_target( uint32_t flags, uint32_t target, struct drm_modeset_acquire_ctx *ctx); -int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, - u16 *red, u16 *green, u16 *blue, - uint32_t size, - struct drm_modeset_acquire_ctx *ctx); /** * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC @@ -167,7 +163,7 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, drm_for_each_plane_mask(plane, (crtc)->dev, (crtc)->state->plane_mask) /** - * drm_crtc_atomic_state_for_each_plane - iterate over attached planes in new state + * drm_atomic_crtc_state_for_each_plane - iterate over attached planes in new state * @plane: the loop cursor * @crtc_state: the incoming CRTC state * @@ -180,7 +176,7 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask) /** - * drm_crtc_atomic_state_for_each_plane_state - iterate over attached planes in new state + * drm_atomic_crtc_state_for_each_plane_state - iterate over attached planes in new state * @plane: the loop cursor * @plane_state: loop cursor for the plane's state, must be const * @crtc_state: the incoming CRTC state diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 7aaea665bfc2..f07f2fb02e75 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -3,6 +3,7 @@ #ifndef _DRM_CLIENT_H_ #define _DRM_CLIENT_H_ +#include <linux/dma-buf-map.h> #include <linux/lockdep.h> #include <linux/mutex.h> #include <linux/types.h> @@ -141,9 +142,9 @@ struct drm_client_buffer { struct drm_gem_object *gem; /** - * @vaddr: Virtual address for the buffer + * @map: Virtual address for the buffer */ - void *vaddr; + struct dma_buf_map map; /** * @fb: DRM framebuffer @@ -155,7 +156,7 @@ struct drm_client_buffer * drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format); void drm_client_framebuffer_delete(struct drm_client_buffer *buffer); int drm_client_framebuffer_flush(struct drm_client_buffer *buffer, struct drm_rect *rect); -void *drm_client_buffer_vmap(struct drm_client_buffer *buffer); +int drm_client_buffer_vmap(struct drm_client_buffer *buffer, struct dma_buf_map *map); void drm_client_buffer_vunmap(struct drm_client_buffer *buffer); int drm_client_modeset_create(struct drm_client_dev *client); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 928136556174..1922b278ffad 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -84,7 +84,7 @@ enum drm_connector_status { }; /** - * enum drm_connector_registration_status - userspace registration status for + * enum drm_connector_registration_state - userspace registration status for * a &drm_connector * * This enum is used to track the status of initializing a connector and @@ -175,6 +175,46 @@ struct drm_scdc { struct drm_scrambling scrambling; }; +/** + * struct drm_hdmi_dsc_cap - DSC capabilities of HDMI sink + * + * Describes the DSC support provided by HDMI 2.1 sink. + * The information is fetched fom additional HFVSDB blocks defined + * for HDMI 2.1. + */ +struct drm_hdmi_dsc_cap { + /** @v_1p2: flag for dsc1.2 version support by sink */ + bool v_1p2; + + /** @native_420: Does sink support DSC with 4:2:0 compression */ + bool native_420; + + /** + * @all_bpp: Does sink support all bpp with 4:4:4: or 4:2:2 + * compressed formats + */ + bool all_bpp; + + /** + * @bpc_supported: compressed bpc supported by sink : 10, 12 or 16 bpc + */ + u8 bpc_supported; + + /** @max_slices: maximum number of Horizontal slices supported by */ + u8 max_slices; + + /** @clk_per_slice : max pixel clock in MHz supported per slice */ + int clk_per_slice; + + /** @max_lanes : dsc max lanes supported for Fixed rate Link training */ + u8 max_lanes; + + /** @max_frl_rate_per_lane : maximum frl rate with DSC per lane */ + u8 max_frl_rate_per_lane; + + /** @total_chunk_kbytes: max size of chunks in KBs supported per line*/ + u8 total_chunk_kbytes; +}; /** * struct drm_hdmi_info - runtime information about the connected HDMI sink @@ -207,6 +247,15 @@ struct drm_hdmi_info { /** @y420_dc_modes: bitmap of deep color support index */ u8 y420_dc_modes; + + /** @max_frl_rate_per_lane: support fixed rate link */ + u8 max_frl_rate_per_lane; + + /** @max_lanes: supported by sink */ + u8 max_lanes; + + /** @dsc_cap: DSC capabilities of the sink */ + struct drm_hdmi_dsc_cap dsc_cap; }; /** diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index ba839e5e357d..540e2e43ec93 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1223,6 +1223,39 @@ int drm_crtc_init_with_planes(struct drm_device *dev, const char *name, ...); void drm_crtc_cleanup(struct drm_crtc *crtc); +__printf(7, 8) +void *__drmm_crtc_alloc_with_planes(struct drm_device *dev, + size_t size, size_t offset, + struct drm_plane *primary, + struct drm_plane *cursor, + const struct drm_crtc_funcs *funcs, + const char *name, ...); + +/** + * drm_crtc_alloc_with_planes - Allocate and initialize a new CRTC object with + * specified primary and cursor planes. + * @dev: DRM device + * @type: the type of the struct which contains struct &drm_crtc + * @member: the name of the &drm_crtc within @type. + * @primary: Primary plane for CRTC + * @cursor: Cursor plane for CRTC + * @funcs: callbacks for the new CRTC + * @name: printf style format string for the CRTC name, or NULL for default name + * + * Allocates and initializes a new crtc object. Cleanup is automatically + * handled through registering drmm_crtc_cleanup() with drmm_add_action(). + * + * The @drm_crtc_funcs.destroy hook must be NULL. + * + * Returns: + * Pointer to new crtc, or ERR_PTR on failure. + */ +#define drmm_crtc_alloc_with_planes(dev, type, member, primary, cursor, funcs, name, ...) \ + ((type *)__drmm_crtc_alloc_with_planes(dev, sizeof(type), \ + offsetof(type, member), \ + primary, cursor, funcs, \ + name, ##__VA_ARGS__)) + /** * drm_crtc_index - find the index of a registered CRTC * @crtc: CRTC to find index for @@ -1279,6 +1312,16 @@ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev, #define drm_for_each_crtc(crtc, dev) \ list_for_each_entry(crtc, &(dev)->mode_config.crtc_list, head) +/** + * drm_for_each_crtc_reverse - iterate over all CRTCs in reverse order + * @crtc: a &struct drm_crtc as the loop cursor + * @dev: the &struct drm_device + * + * Iterate over all CRTCs of @dev. + */ +#define drm_for_each_crtc_reverse(crtc, dev) \ + list_for_each_entry_reverse(crtc, &(dev)->mode_config.crtc_list, head) + int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc, unsigned int supported_filters); diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index f4f68e7a9149..939904ae88fc 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -27,7 +27,7 @@ struct pci_controller; /** - * enum drm_switch_power - power state of drm device + * enum switch_power_state - power state of drm device */ enum switch_power_state { @@ -51,13 +51,6 @@ enum switch_power_state { * may contain multiple heads. */ struct drm_device { - /** - * @legacy_dev_list: - * - * List of devices per driver for stealth attach cleanup - */ - struct list_head legacy_dev_list; - /** @if_version: Highest interface version set */ int if_version; @@ -83,7 +76,7 @@ struct drm_device { } managed; /** @driver: DRM driver managing the device */ - struct drm_driver *driver; + const struct drm_driver *driver; /** * @dev_private: @@ -332,6 +325,9 @@ struct drm_device { /* Everything below here is for legacy driver, never use! */ /* private: */ #if IS_ENABLED(CONFIG_DRM_LEGACY) + /* List of devices per driver for stealth attach cleanup */ + struct list_head legacy_dev_list; + /* Context handle management - linked list of context handles */ struct list_head ctxlist; diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 6b40258927bf..6236f212da61 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -411,6 +411,17 @@ struct drm_device; # define DP_DS_10BPC 1 # define DP_DS_12BPC 2 # define DP_DS_16BPC 3 +/* HDMI2.1 PCON FRL CONFIGURATION */ +# define DP_PCON_MAX_FRL_BW (7 << 2) +# define DP_PCON_MAX_0GBPS (0 << 2) +# define DP_PCON_MAX_9GBPS (1 << 2) +# define DP_PCON_MAX_18GBPS (2 << 2) +# define DP_PCON_MAX_24GBPS (3 << 2) +# define DP_PCON_MAX_32GBPS (4 << 2) +# define DP_PCON_MAX_40GBPS (5 << 2) +# define DP_PCON_MAX_48GBPS (6 << 2) +# define DP_PCON_SOURCE_CTL_MODE (1 << 5) + /* offset 3 for DVI */ # define DP_DS_DVI_DUAL_LINK (1 << 1) # define DP_DS_DVI_HIGH_COLOR_DEPTH (1 << 2) @@ -421,6 +432,17 @@ struct drm_device; # define DP_DS_HDMI_YCBCR444_TO_422_CONV (1 << 3) # define DP_DS_HDMI_YCBCR444_TO_420_CONV (1 << 4) +/* + * VESA DP-to-HDMI PCON Specification adds caps for colorspace + * conversion in DFP cap DPCD 83h. Sec6.1 Table-3. + * Based on the available support the source can enable + * color conversion by writing into PROTOCOL_COVERTER_CONTROL_2 + * DPCD 3052h. + */ +# define DP_DS_HDMI_BT601_RGB_YCBCR_CONV (1 << 5) +# define DP_DS_HDMI_BT709_RGB_YCBCR_CONV (1 << 6) +# define DP_DS_HDMI_BT2020_RGB_YCBCR_CONV (1 << 7) + #define DP_MAX_DOWNSTREAM_PORTS 0x10 /* DP Forward error Correction Registers */ @@ -430,6 +452,84 @@ struct drm_device; # define DP_FEC_CORR_BLK_ERROR_COUNT_CAP (1 << 2) # define DP_FEC_BIT_ERROR_COUNT_CAP (1 << 3) +/* DP-HDMI2.1 PCON DSC ENCODER SUPPORT */ +#define DP_PCON_DSC_ENCODER_CAP_SIZE 0xC /* 0x9E - 0x92 */ +#define DP_PCON_DSC_ENCODER 0x092 +# define DP_PCON_DSC_ENCODER_SUPPORTED (1 << 0) +# define DP_PCON_DSC_PPS_ENC_OVERRIDE (1 << 1) + +/* DP-HDMI2.1 PCON DSC Version */ +#define DP_PCON_DSC_VERSION 0x093 +# define DP_PCON_DSC_MAJOR_MASK (0xF << 0) +# define DP_PCON_DSC_MINOR_MASK (0xF << 4) +# define DP_PCON_DSC_MAJOR_SHIFT 0 +# define DP_PCON_DSC_MINOR_SHIFT 4 + +/* DP-HDMI2.1 PCON DSC RC Buffer block size */ +#define DP_PCON_DSC_RC_BUF_BLK_INFO 0x094 +# define DP_PCON_DSC_RC_BUF_BLK_SIZE (0x3 << 0) +# define DP_PCON_DSC_RC_BUF_BLK_1KB 0 +# define DP_PCON_DSC_RC_BUF_BLK_4KB 1 +# define DP_PCON_DSC_RC_BUF_BLK_16KB 2 +# define DP_PCON_DSC_RC_BUF_BLK_64KB 3 + +/* DP-HDMI2.1 PCON DSC RC Buffer size */ +#define DP_PCON_DSC_RC_BUF_SIZE 0x095 + +/* DP-HDMI2.1 PCON DSC Slice capabilities-1 */ +#define DP_PCON_DSC_SLICE_CAP_1 0x096 +# define DP_PCON_DSC_1_PER_DSC_ENC (0x1 << 0) +# define DP_PCON_DSC_2_PER_DSC_ENC (0x1 << 1) +# define DP_PCON_DSC_4_PER_DSC_ENC (0x1 << 3) +# define DP_PCON_DSC_6_PER_DSC_ENC (0x1 << 4) +# define DP_PCON_DSC_8_PER_DSC_ENC (0x1 << 5) +# define DP_PCON_DSC_10_PER_DSC_ENC (0x1 << 6) +# define DP_PCON_DSC_12_PER_DSC_ENC (0x1 << 7) + +#define DP_PCON_DSC_BUF_BIT_DEPTH 0x097 +# define DP_PCON_DSC_BIT_DEPTH_MASK (0xF << 0) +# define DP_PCON_DSC_DEPTH_9_BITS 0 +# define DP_PCON_DSC_DEPTH_10_BITS 1 +# define DP_PCON_DSC_DEPTH_11_BITS 2 +# define DP_PCON_DSC_DEPTH_12_BITS 3 +# define DP_PCON_DSC_DEPTH_13_BITS 4 +# define DP_PCON_DSC_DEPTH_14_BITS 5 +# define DP_PCON_DSC_DEPTH_15_BITS 6 +# define DP_PCON_DSC_DEPTH_16_BITS 7 +# define DP_PCON_DSC_DEPTH_8_BITS 8 + +#define DP_PCON_DSC_BLOCK_PREDICTION 0x098 +# define DP_PCON_DSC_BLOCK_PRED_SUPPORT (0x1 << 0) + +#define DP_PCON_DSC_ENC_COLOR_FMT_CAP 0x099 +# define DP_PCON_DSC_ENC_RGB (0x1 << 0) +# define DP_PCON_DSC_ENC_YUV444 (0x1 << 1) +# define DP_PCON_DSC_ENC_YUV422_S (0x1 << 2) +# define DP_PCON_DSC_ENC_YUV422_N (0x1 << 3) +# define DP_PCON_DSC_ENC_YUV420_N (0x1 << 4) + +#define DP_PCON_DSC_ENC_COLOR_DEPTH_CAP 0x09A +# define DP_PCON_DSC_ENC_8BPC (0x1 << 1) +# define DP_PCON_DSC_ENC_10BPC (0x1 << 2) +# define DP_PCON_DSC_ENC_12BPC (0x1 << 3) + +#define DP_PCON_DSC_MAX_SLICE_WIDTH 0x09B + +/* DP-HDMI2.1 PCON DSC Slice capabilities-2 */ +#define DP_PCON_DSC_SLICE_CAP_2 0x09C +# define DP_PCON_DSC_16_PER_DSC_ENC (0x1 << 0) +# define DP_PCON_DSC_20_PER_DSC_ENC (0x1 << 1) +# define DP_PCON_DSC_24_PER_DSC_ENC (0x1 << 2) + +/* DP-HDMI2.1 PCON HDMI TX Encoder Bits/pixel increment */ +#define DP_PCON_DSC_BPP_INCR 0x09E +# define DP_PCON_DSC_BPP_INCR_MASK (0x7 << 0) +# define DP_PCON_DSC_ONE_16TH_BPP 0 +# define DP_PCON_DSC_ONE_8TH_BPP 1 +# define DP_PCON_DSC_ONE_4TH_BPP 2 +# define DP_PCON_DSC_ONE_HALF_BPP 3 +# define DP_PCON_DSC_ONE_BPP 4 + /* DP Extended DSC Capabilities */ #define DP_DSC_BRANCH_OVERALL_THROUGHPUT_0 0x0a0 /* DP 1.4a SCR */ #define DP_DSC_BRANCH_OVERALL_THROUGHPUT_1 0x0a1 @@ -935,6 +1035,11 @@ struct drm_device; # define DP_CEC_IRQ (1 << 2) #define DP_LINK_SERVICE_IRQ_VECTOR_ESI0 0x2005 /* 1.2 */ +# define RX_CAP_CHANGED (1 << 0) +# define LINK_STATUS_CHANGED (1 << 1) +# define STREAM_STATUS_CHANGED (1 << 2) +# define HDMI_LINK_STATUS_CHANGED (1 << 3) +# define CONNECTED_OFF_ENTRY_REQUESTED (1 << 4) #define DP_PSR_ERROR_STATUS 0x2006 /* XXX 1.2? */ # define DP_PSR_LINK_CRC_ERROR (1 << 0) @@ -1054,6 +1159,51 @@ struct drm_device; #define DP_CEC_TX_MESSAGE_BUFFER 0x3020 #define DP_CEC_MESSAGE_BUFFER_LENGTH 0x10 +/* PCON CONFIGURE-1 FRL FOR HDMI SINK */ +#define DP_PCON_HDMI_LINK_CONFIG_1 0x305A +# define DP_PCON_ENABLE_MAX_FRL_BW (7 << 0) +# define DP_PCON_ENABLE_MAX_BW_0GBPS 0 +# define DP_PCON_ENABLE_MAX_BW_9GBPS 1 +# define DP_PCON_ENABLE_MAX_BW_18GBPS 2 +# define DP_PCON_ENABLE_MAX_BW_24GBPS 3 +# define DP_PCON_ENABLE_MAX_BW_32GBPS 4 +# define DP_PCON_ENABLE_MAX_BW_40GBPS 5 +# define DP_PCON_ENABLE_MAX_BW_48GBPS 6 +# define DP_PCON_ENABLE_SOURCE_CTL_MODE (1 << 3) +# define DP_PCON_ENABLE_CONCURRENT_LINK (1 << 4) +# define DP_PCON_ENABLE_LINK_FRL_MODE (1 << 5) +# define DP_PCON_ENABLE_HPD_READY (1 << 6) +# define DP_PCON_ENABLE_HDMI_LINK (1 << 7) + +/* PCON CONFIGURE-2 FRL FOR HDMI SINK */ +#define DP_PCON_HDMI_LINK_CONFIG_2 0x305B +# define DP_PCON_MAX_LINK_BW_MASK (0x3F << 0) +# define DP_PCON_FRL_BW_MASK_9GBPS (1 << 0) +# define DP_PCON_FRL_BW_MASK_18GBPS (1 << 1) +# define DP_PCON_FRL_BW_MASK_24GBPS (1 << 2) +# define DP_PCON_FRL_BW_MASK_32GBPS (1 << 3) +# define DP_PCON_FRL_BW_MASK_40GBPS (1 << 4) +# define DP_PCON_FRL_BW_MASK_48GBPS (1 << 5) +# define DP_PCON_FRL_LINK_TRAIN_EXTENDED (1 << 6) + +/* PCON HDMI LINK STATUS */ +#define DP_PCON_HDMI_TX_LINK_STATUS 0x303B +# define DP_PCON_HDMI_TX_LINK_ACTIVE (1 << 0) +# define DP_PCON_FRL_READY (1 << 1) + +/* PCON HDMI POST FRL STATUS */ +#define DP_PCON_HDMI_POST_FRL_STATUS 0x3036 +# define DP_PCON_HDMI_LINK_MODE (1 << 0) +# define DP_PCON_HDMI_MODE_TMDS 0 +# define DP_PCON_HDMI_MODE_FRL 1 +# define DP_PCON_HDMI_FRL_TRAINED_BW (0x3F << 1) +# define DP_PCON_FRL_TRAINED_BW_9GBPS (1 << 1) +# define DP_PCON_FRL_TRAINED_BW_18GBPS (1 << 2) +# define DP_PCON_FRL_TRAINED_BW_24GBPS (1 << 3) +# define DP_PCON_FRL_TRAINED_BW_32GBPS (1 << 4) +# define DP_PCON_FRL_TRAINED_BW_40GBPS (1 << 5) +# define DP_PCON_FRL_TRAINED_BW_48GBPS (1 << 6) + #define DP_PROTOCOL_CONVERTER_CONTROL_0 0x3050 /* DP 1.3 */ # define DP_HDMI_DVI_OUTPUT_CONFIG (1 << 0) /* DP 1.3 */ #define DP_PROTOCOL_CONVERTER_CONTROL_1 0x3051 /* DP 1.3 */ @@ -1063,6 +1213,48 @@ struct drm_device; # define DP_HDMI_FORCE_SCRAMBLING (1 << 3) /* DP 1.4 */ #define DP_PROTOCOL_CONVERTER_CONTROL_2 0x3052 /* DP 1.3 */ # define DP_CONVERSION_TO_YCBCR422_ENABLE (1 << 0) /* DP 1.3 */ +# define DP_PCON_ENABLE_DSC_ENCODER (1 << 1) +# define DP_PCON_ENCODER_PPS_OVERRIDE_MASK (0x3 << 2) +# define DP_PCON_ENC_PPS_OVERRIDE_DISABLED 0 +# define DP_PCON_ENC_PPS_OVERRIDE_EN_PARAMS 1 +# define DP_PCON_ENC_PPS_OVERRIDE_EN_BUFFER 2 +# define DP_CONVERSION_RGB_YCBCR_MASK (7 << 4) +# define DP_CONVERSION_BT601_RGB_YCBCR_ENABLE (1 << 4) +# define DP_CONVERSION_BT709_RGB_YCBCR_ENABLE (1 << 5) +# define DP_CONVERSION_BT2020_RGB_YCBCR_ENABLE (1 << 6) + +/* PCON Downstream HDMI ERROR Status per Lane */ +#define DP_PCON_HDMI_ERROR_STATUS_LN0 0x3037 +#define DP_PCON_HDMI_ERROR_STATUS_LN1 0x3038 +#define DP_PCON_HDMI_ERROR_STATUS_LN2 0x3039 +#define DP_PCON_HDMI_ERROR_STATUS_LN3 0x303A +# define DP_PCON_HDMI_ERROR_COUNT_MASK (0x7 << 0) +# define DP_PCON_HDMI_ERROR_COUNT_THREE_PLUS (1 << 0) +# define DP_PCON_HDMI_ERROR_COUNT_TEN_PLUS (1 << 1) +# define DP_PCON_HDMI_ERROR_COUNT_HUNDRED_PLUS (1 << 2) + +/* PCON HDMI CONFIG PPS Override Buffer + * Valid Offsets to be added to Base : 0-127 + */ +#define DP_PCON_HDMI_PPS_OVERRIDE_BASE 0x3100 + +/* PCON HDMI CONFIG PPS Override Parameter: Slice height + * Offset-0 8LSBs of the Slice height. + * Offset-1 8MSBs of the Slice height. + */ +#define DP_PCON_HDMI_PPS_OVRD_SLICE_HEIGHT 0x3180 + +/* PCON HDMI CONFIG PPS Override Parameter: Slice width + * Offset-0 8LSBs of the Slice width. + * Offset-1 8MSBs of the Slice width. + */ +#define DP_PCON_HDMI_PPS_OVRD_SLICE_WIDTH 0x3182 + +/* PCON HDMI CONFIG PPS Override Parameter: bits_per_pixel + * Offset-0 8LSBs of the bits_per_pixel. + * Offset-1 2MSBs of the bits_per_pixel. + */ +#define DP_PCON_HDMI_PPS_OVRD_BPP 0x3184 /* HDCP 1.3 and HDCP 2.2 */ #define DP_AUX_HDCP_BKSV 0x68000 @@ -1967,4 +2159,30 @@ int drm_dp_get_phy_test_pattern(struct drm_dp_aux *aux, struct drm_dp_phy_test_params *data); int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux, struct drm_dp_phy_test_params *data, u8 dp_rev); +int drm_dp_get_pcon_max_frl_bw(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 port_cap[4]); +int drm_dp_pcon_frl_prepare(struct drm_dp_aux *aux, bool enable_frl_ready_hpd); +bool drm_dp_pcon_is_frl_ready(struct drm_dp_aux *aux); +int drm_dp_pcon_frl_configure_1(struct drm_dp_aux *aux, int max_frl_gbps, + bool concurrent_mode); +int drm_dp_pcon_frl_configure_2(struct drm_dp_aux *aux, int max_frl_mask, + bool extended_train_mode); +int drm_dp_pcon_reset_frl_config(struct drm_dp_aux *aux); +int drm_dp_pcon_frl_enable(struct drm_dp_aux *aux); + +bool drm_dp_pcon_hdmi_link_active(struct drm_dp_aux *aux); +int drm_dp_pcon_hdmi_link_mode(struct drm_dp_aux *aux, u8 *frl_trained_mask); +void drm_dp_pcon_hdmi_frl_link_error_count(struct drm_dp_aux *aux, + struct drm_connector *connector); +bool drm_dp_pcon_enc_is_dsc_1_2(const u8 pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE]); +int drm_dp_pcon_dsc_max_slices(const u8 pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE]); +int drm_dp_pcon_dsc_max_slice_width(const u8 pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE]); +int drm_dp_pcon_dsc_bpp_incr(const u8 pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE]); +int drm_dp_pcon_pps_default(struct drm_dp_aux *aux); +int drm_dp_pcon_pps_override_buf(struct drm_dp_aux *aux, u8 pps_buf[128]); +int drm_dp_pcon_pps_override_param(struct drm_dp_aux *aux, u8 pps_param[6]); +bool drm_dp_downstream_rgb_to_ycbcr_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 port_cap[4], u8 color_spc); +int drm_dp_pcon_convert_rgb_to_ycbcr(struct drm_dp_aux *aux, u8 color_spc); + #endif /* _DRM_DP_HELPER_H_ */ diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 023076255a7f..827838e0a97e 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -495,11 +495,10 @@ struct drm_driver { */ const struct file_operations *fops; +#ifdef CONFIG_DRM_LEGACY /* Everything below here is for legacy driver, never use! */ /* private: */ - /* List of devices hanging off this driver with stealth attach. */ - struct list_head legacy_dev_list; int (*firstopen) (struct drm_device *); void (*preclose) (struct drm_device *, struct drm_file *file_priv); int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -509,9 +508,11 @@ struct drm_driver { int (*enable_vblank)(struct drm_device *dev, unsigned int pipe); void (*disable_vblank)(struct drm_device *dev, unsigned int pipe); int dev_priv_size; +#endif }; -void *__devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver, +void *__devm_drm_dev_alloc(struct device *parent, + const struct drm_driver *driver, size_t size, size_t offset); /** @@ -544,7 +545,7 @@ void *__devm_drm_dev_alloc(struct device *parent, struct drm_driver *driver, ((type *) __devm_drm_dev_alloc(parent, driver, sizeof(type), \ offsetof(type, member))) -struct drm_device *drm_dev_alloc(struct drm_driver *driver, +struct drm_device *drm_dev_alloc(const struct drm_driver *driver, struct device *parent); int drm_dev_register(struct drm_device *dev, unsigned long flags); void drm_dev_unregister(struct drm_device *dev); diff --git a/include/drm/drm_dsc.h b/include/drm/drm_dsc.h index e66560174ff1..cf43561e60fa 100644 --- a/include/drm/drm_dsc.h +++ b/include/drm/drm_dsc.h @@ -273,7 +273,8 @@ struct drm_dsc_config { }; /** - * struct picture_parameter_set - Represents 128 bytes of Picture Parameter Set + * struct drm_dsc_picture_parameter_set - Represents 128 bytes of + * Picture Parameter Set * * The VESA DSC standard defines picture parameter set (PPS) which display * stream compression encoders must communicate to decoders. diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index e97daf6ffbb1..a158f585f658 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -229,6 +229,36 @@ struct detailed_timing { DRM_EDID_YCBCR420_DC_36 | \ DRM_EDID_YCBCR420_DC_30) +/* HDMI 2.1 additional fields */ +#define DRM_EDID_MAX_FRL_RATE_MASK 0xf0 +#define DRM_EDID_FAPA_START_LOCATION (1 << 0) +#define DRM_EDID_ALLM (1 << 1) +#define DRM_EDID_FVA (1 << 2) + +/* Deep Color specific */ +#define DRM_EDID_DC_30BIT_420 (1 << 0) +#define DRM_EDID_DC_36BIT_420 (1 << 1) +#define DRM_EDID_DC_48BIT_420 (1 << 2) + +/* VRR specific */ +#define DRM_EDID_CNMVRR (1 << 3) +#define DRM_EDID_CINEMA_VRR (1 << 4) +#define DRM_EDID_MDELTA (1 << 5) +#define DRM_EDID_VRR_MAX_UPPER_MASK 0xc0 +#define DRM_EDID_VRR_MAX_LOWER_MASK 0xff +#define DRM_EDID_VRR_MIN_MASK 0x3f + +/* DSC specific */ +#define DRM_EDID_DSC_10BPC (1 << 0) +#define DRM_EDID_DSC_12BPC (1 << 1) +#define DRM_EDID_DSC_16BPC (1 << 2) +#define DRM_EDID_DSC_ALL_BPP (1 << 3) +#define DRM_EDID_DSC_NATIVE_420 (1 << 6) +#define DRM_EDID_DSC_1P2 (1 << 7) +#define DRM_EDID_DSC_MAX_FRL_RATE_MASK 0xf0 +#define DRM_EDID_DSC_MAX_SLICES 0xf +#define DRM_EDID_DSC_TOTAL_CHUNK_KBYTES 0x3f + /* ELD Header Block */ #define DRM_ELD_HEADER_BLOCK_SIZE 4 diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h index a60f5f1555ac..5bf78b5bcb2b 100644 --- a/include/drm/drm_encoder.h +++ b/include/drm/drm_encoder.h @@ -89,8 +89,7 @@ struct drm_encoder_funcs { * @head: list management * @base: base KMS object * @name: human readable name, can be overwritten by the driver - * @bridge: bridge associated to the encoder - * @funcs: control functions + * @funcs: control functions, can be NULL for simple managed encoders * @helper_private: mid-layer private data * * CRTCs drive pixels to encoders, which convert them into signals @@ -195,6 +194,36 @@ int drm_encoder_init(struct drm_device *dev, const struct drm_encoder_funcs *funcs, int encoder_type, const char *name, ...); +__printf(6, 7) +void *__drmm_encoder_alloc(struct drm_device *dev, + size_t size, size_t offset, + const struct drm_encoder_funcs *funcs, + int encoder_type, + const char *name, ...); + +/** + * drmm_encoder_alloc - Allocate and initialize an encoder + * @dev: drm device + * @type: the type of the struct which contains struct &drm_encoder + * @member: the name of the &drm_encoder within @type + * @funcs: callbacks for this encoder (optional) + * @encoder_type: user visible type of the encoder + * @name: printf style format string for the encoder name, or NULL for default name + * + * Allocates and initializes an encoder. Encoder should be subclassed as part of + * driver encoder objects. Cleanup is automatically handled through registering + * drm_encoder_cleanup() with drmm_add_action(). + * + * The @drm_encoder_funcs.destroy hook must be NULL. + * + * Returns: + * Pointer to new encoder, or ERR_PTR on failure. + */ +#define drmm_encoder_alloc(dev, type, member, funcs, encoder_type, name, ...) \ + ((type *)__drmm_encoder_alloc(dev, sizeof(type), \ + offsetof(type, member), funcs, \ + encoder_type, name, ##__VA_ARGS__)) + /** * drm_encoder_index - find the index of a registered encoder * @encoder: encoder to find index for diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 306aa3a60be9..3b273f9ca39a 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -100,10 +100,10 @@ struct drm_fb_helper_funcs { * @funcs: driver callbacks for fb helper * @fbdev: emulated fbdev device info struct * @pseudo_palette: fake palette of 16 colors - * @dirty_clip: clip rectangle used with deferred_io to accumulate damage to - * the screen buffer - * @dirty_lock: spinlock protecting @dirty_clip - * @dirty_work: worker used to flush the framebuffer + * @damage_clip: clip rectangle used with deferred_io to accumulate damage to + * the screen buffer + * @damage_lock: spinlock protecting @damage_clip + * @damage_work: worker used to flush the framebuffer * @resume_work: worker used during resume if the console lock is already taken * * This is the main structure used by the fbdev helpers. Drivers supporting @@ -131,9 +131,9 @@ struct drm_fb_helper { const struct drm_fb_helper_funcs *funcs; struct fb_info *fbdev; u32 pseudo_palette[17]; - struct drm_clip_rect dirty_clip; - spinlock_t dirty_lock; - struct work_struct dirty_work; + struct drm_clip_rect damage_clip; + spinlock_t damage_lock; + struct work_struct damage_work; struct work_struct resume_work; /** diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index c38dd35da00b..240049566592 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -39,6 +39,7 @@ #include <drm/drm_vma_manager.h> +struct dma_buf_map; struct drm_gem_object; /** @@ -138,7 +139,7 @@ struct drm_gem_object_funcs { * * This callback is optional. */ - void *(*vmap)(struct drm_gem_object *obj); + int (*vmap)(struct drm_gem_object *obj, struct dma_buf_map *map); /** * @vunmap: @@ -148,7 +149,7 @@ struct drm_gem_object_funcs { * * This callback is optional. */ - void (*vunmap)(struct drm_gem_object *obj, void *vaddr); + void (*vunmap)(struct drm_gem_object *obj, struct dma_buf_map *map); /** * @mmap: @@ -415,8 +416,5 @@ int drm_gem_fence_array_add_implicit(struct xarray *fence_array, bool write); int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, u32 handle, u64 *offset); -int drm_gem_dumb_destroy(struct drm_file *file, - struct drm_device *dev, - uint32_t handle); #endif /* __DRM_GEM_H__ */ diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h index 2bfa2502607a..0a9711caa3e8 100644 --- a/include/drm/drm_gem_cma_helper.h +++ b/include/drm/drm_gem_cma_helper.h @@ -59,7 +59,7 @@ struct drm_gem_cma_object { .poll = drm_poll,\ .read = drm_read,\ .llseek = noop_llseek,\ - .mmap = drm_gem_cma_mmap,\ + .mmap = drm_gem_mmap,\ DRM_GEM_CMA_UNMAPPED_AREA_FOPS \ } @@ -76,9 +76,6 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv, struct drm_device *drm, struct drm_mode_create_dumb *args); -/* set vm_flags and we can change the VM attribute to other one at here */ -int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma); - /* allocate physical memory */ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, size_t size); @@ -96,18 +93,13 @@ unsigned long drm_gem_cma_get_unmapped_area(struct file *filp, void drm_gem_cma_print_info(struct drm_printer *p, unsigned int indent, const struct drm_gem_object *obj); -struct sg_table *drm_gem_cma_prime_get_sg_table(struct drm_gem_object *obj); +struct sg_table *drm_gem_cma_get_sg_table(struct drm_gem_object *obj); struct drm_gem_object * drm_gem_cma_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sgt); -int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, - struct vm_area_struct *vma); -void *drm_gem_cma_prime_vmap(struct drm_gem_object *obj); -void drm_gem_cma_prime_vunmap(struct drm_gem_object *obj, void *vaddr); - -struct drm_gem_object * -drm_gem_cma_create_object_default_funcs(struct drm_device *dev, size_t size); +int drm_gem_cma_vmap(struct drm_gem_object *obj, struct dma_buf_map *map); +int drm_gem_cma_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); /** * DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE - CMA GEM driver operations @@ -123,12 +115,11 @@ drm_gem_cma_create_object_default_funcs(struct drm_device *dev, size_t size); * DRM_GEM_CMA_DRIVER_OPS_VMAP_WITH_DUMB_CREATE() instead. */ #define DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(dumb_create_func) \ - .gem_create_object = drm_gem_cma_create_object_default_funcs, \ .dumb_create = (dumb_create_func), \ .prime_handle_to_fd = drm_gem_prime_handle_to_fd, \ .prime_fd_to_handle = drm_gem_prime_fd_to_handle, \ .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, \ - .gem_prime_mmap = drm_gem_cma_prime_mmap + .gem_prime_mmap = drm_gem_prime_mmap /** * DRM_GEM_CMA_DRIVER_OPS - CMA GEM driver operations @@ -162,7 +153,6 @@ drm_gem_cma_create_object_default_funcs(struct drm_device *dev, size_t size); * DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE() instead. */ #define DRM_GEM_CMA_DRIVER_OPS_VMAP_WITH_DUMB_CREATE(dumb_create_func) \ - .gem_create_object = drm_gem_cma_create_object_default_funcs, \ .dumb_create = dumb_create_func, \ .prime_handle_to_fd = drm_gem_prime_handle_to_fd, \ .prime_fd_to_handle = drm_gem_prime_fd_to_handle, \ diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h index 5381f0c8cf6f..434328d8a0d9 100644 --- a/include/drm/drm_gem_shmem_helper.h +++ b/include/drm/drm_gem_shmem_helper.h @@ -98,9 +98,9 @@ struct drm_gem_shmem_object { unsigned int vmap_use_count; /** - * @map_cached: map object cached (instead of using writecombine). + * @map_wc: map object write-combined (instead of using shmem defaults). */ - bool map_cached; + bool map_wc; }; #define to_drm_gem_shmem_obj(obj) \ @@ -113,8 +113,8 @@ int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem); void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem); int drm_gem_shmem_pin(struct drm_gem_object *obj); void drm_gem_shmem_unpin(struct drm_gem_object *obj); -void *drm_gem_shmem_vmap(struct drm_gem_object *obj); -void drm_gem_shmem_vunmap(struct drm_gem_object *obj, void *vaddr); +int drm_gem_shmem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map); +void drm_gem_shmem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map); int drm_gem_shmem_madvise(struct drm_gem_object *obj, int madv); @@ -133,9 +133,6 @@ drm_gem_shmem_create_with_handle(struct drm_file *file_priv, struct drm_device *dev, size_t size, uint32_t *handle); -struct drm_gem_object * -drm_gem_shmem_create_object_cached(struct drm_device *dev, size_t size); - int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); diff --git a/include/drm/drm_gem_ttm_helper.h b/include/drm/drm_gem_ttm_helper.h index 118cef76f84f..7c6d874910b8 100644 --- a/include/drm/drm_gem_ttm_helper.h +++ b/include/drm/drm_gem_ttm_helper.h @@ -10,11 +10,17 @@ #include <drm/ttm/ttm_bo_api.h> #include <drm/ttm/ttm_bo_driver.h> +struct dma_buf_map; + #define drm_gem_ttm_of_gem(gem_obj) \ container_of(gem_obj, struct ttm_buffer_object, base) void drm_gem_ttm_print_info(struct drm_printer *p, unsigned int indent, const struct drm_gem_object *gem); +int drm_gem_ttm_vmap(struct drm_gem_object *gem, + struct dma_buf_map *map); +void drm_gem_ttm_vunmap(struct drm_gem_object *gem, + struct dma_buf_map *map); int drm_gem_ttm_mmap(struct drm_gem_object *gem, struct vm_area_struct *vma); diff --git a/include/drm/drm_gem_vram_helper.h b/include/drm/drm_gem_vram_helper.h index 128f88174d32..a4bac02249c2 100644 --- a/include/drm/drm_gem_vram_helper.h +++ b/include/drm/drm_gem_vram_helper.h @@ -10,6 +10,7 @@ #include <drm/ttm/ttm_bo_api.h> #include <drm/ttm/ttm_bo_driver.h> +#include <linux/dma-buf-map.h> #include <linux/kernel.h> /* for container_of() */ struct drm_mode_create_dumb; @@ -29,9 +30,8 @@ struct vm_area_struct; /** * struct drm_gem_vram_object - GEM object backed by VRAM - * @gem: GEM object * @bo: TTM buffer object - * @kmap: Mapping information for @bo + * @map: Mapping information for @bo * @placement: TTM placement information. Supported placements are \ %TTM_PL_VRAM and %TTM_PL_SYSTEM * @placements: TTM placement information. @@ -50,15 +50,15 @@ struct vm_area_struct; */ struct drm_gem_vram_object { struct ttm_buffer_object bo; - struct ttm_bo_kmap_obj kmap; + struct dma_buf_map map; /** - * @kmap_use_count: + * @vmap_use_count: * * Reference count on the virtual address. * The address are un-mapped when the count reaches zero. */ - unsigned int kmap_use_count; + unsigned int vmap_use_count; /* Supported placements are %TTM_PL_VRAM and %TTM_PL_SYSTEM */ struct ttm_placement placement; @@ -66,8 +66,8 @@ struct drm_gem_vram_object { }; /** - * Returns the container of type &struct drm_gem_vram_object - * for field bo. + * drm_gem_vram_of_bo - Returns the container of type + * &struct drm_gem_vram_object for field bo. * @bo: the VRAM buffer object * Returns: The containing GEM VRAM object */ @@ -78,8 +78,8 @@ static inline struct drm_gem_vram_object *drm_gem_vram_of_bo( } /** - * Returns the container of type &struct drm_gem_vram_object - * for field gem. + * drm_gem_vram_of_gem - Returns the container of type + * &struct drm_gem_vram_object for field gem. * @gem: the GEM object * Returns: The containing GEM VRAM object */ @@ -97,8 +97,8 @@ u64 drm_gem_vram_mmap_offset(struct drm_gem_vram_object *gbo); s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo); int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag); int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo); -void *drm_gem_vram_vmap(struct drm_gem_vram_object *gbo); -void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo, void *vaddr); +int drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, struct dma_buf_map *map); +void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo, struct dma_buf_map *map); int drm_gem_vram_fill_create_dumb(struct drm_file *file, struct drm_device *dev, diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index d77f6e65b1c6..631b22f9757d 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -28,5 +28,5 @@ struct drm_device; int drm_irq_install(struct drm_device *dev, int irq); int drm_irq_uninstall(struct drm_device *dev); - +int devm_drm_irq_install(struct drm_device *dev, int irq); #endif diff --git a/include/drm/drm_legacy.h b/include/drm/drm_legacy.h index 852d7451eeb1..8ed04e9be997 100644 --- a/include/drm/drm_legacy.h +++ b/include/drm/drm_legacy.h @@ -198,8 +198,10 @@ struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev, size_t size, size_t align); void drm_pci_free(struct drm_device *dev, struct drm_dma_handle *dmah); -int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver); -void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver); +int drm_legacy_pci_init(const struct drm_driver *driver, + struct pci_driver *pdriver); +void drm_legacy_pci_exit(const struct drm_driver *driver, + struct pci_driver *pdriver); #else @@ -214,13 +216,13 @@ static inline void drm_pci_free(struct drm_device *dev, { } -static inline int drm_legacy_pci_init(struct drm_driver *driver, +static inline int drm_legacy_pci_init(const struct drm_driver *driver, struct pci_driver *pdriver) { return -EINVAL; } -static inline void drm_legacy_pci_exit(struct drm_driver *driver, +static inline void drm_legacy_pci_exit(const struct drm_driver *driver, struct pci_driver *pdriver) { } diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h index ca4114633bf9..b45c6fbf53ac 100644 --- a/include/drm/drm_managed.h +++ b/include/drm/drm_managed.h @@ -44,8 +44,6 @@ int __must_check __drmm_add_action_or_reset(struct drm_device *dev, drmres_release_t action, void *data, const char *name); -void drmm_add_final_kfree(struct drm_device *dev, void *container); - void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc; /** diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 5ffbb4ed5b35..ab424ddd7665 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -878,18 +878,6 @@ struct drm_mode_config { bool prefer_shadow_fbdev; /** - * @fbdev_use_iomem: - * - * Set to true if framebuffer reside in iomem. - * When set to true memcpy_toio() is used when copying the framebuffer in - * drm_fb_helper.drm_fb_helper_dirty_blit_real(). - * - * FIXME: This should be replaced with a per-mapping is_iomem - * flag (like ttm does), and then used everywhere in fbdev code. - */ - bool fbdev_use_iomem; - - /** * @quirk_addfb_prefer_xbgr_30bpp: * * Special hack for legacy ADDFB to keep nouveau userspace happy. Should diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index cdf2a299ccd4..a0d79d1c51e2 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -195,6 +195,9 @@ enum drm_mode_status { * @crtc_vsync_end: hardware mode vertical sync end * @crtc_vtotal: hardware mode vertical total size * + * This is the kernel API display mode information structure. For the + * user-space version see struct drm_mode_modeinfo. + * * The horizontal and vertical timings are defined per the following diagram. * * :: diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index bde42988c4b5..eb706342861d 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -336,8 +336,7 @@ struct drm_crtc_helper_funcs { * * This function is called in the check phase of an atomic update. The * driver is not allowed to change anything outside of the free-standing - * state objects passed-in or assembled in the overall &drm_atomic_state - * update tracking structure. + * state object passed-in. * * Also beware that userspace can request its own custom modes, neither * core nor helpers filter modes to the list of probe modes reported by @@ -353,7 +352,7 @@ struct drm_crtc_helper_funcs { * deadlock. */ int (*atomic_check)(struct drm_crtc *crtc, - struct drm_crtc_state *state); + struct drm_atomic_state *state); /** * @atomic_begin: @@ -374,7 +373,7 @@ struct drm_crtc_helper_funcs { * transitional plane helpers, but it is optional. */ void (*atomic_begin)(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state); + struct drm_atomic_state *state); /** * @atomic_flush: * @@ -398,7 +397,7 @@ struct drm_crtc_helper_funcs { * transitional plane helpers, but it is optional. */ void (*atomic_flush)(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state); + struct drm_atomic_state *state); /** * @atomic_enable: @@ -867,13 +866,19 @@ struct drm_connector_helper_funcs { * The usual way to implement this is to cache the EDID retrieved in the * probe callback somewhere in the driver-private connector structure. * In this function drivers then parse the modes in the EDID and add - * them by calling drm_add_edid_modes(). But connectors that driver a + * them by calling drm_add_edid_modes(). But connectors that drive a * fixed panel can also manually add specific modes using * drm_mode_probed_add(). Drivers which manually add modes should also * make sure that the &drm_connector.display_info, * &drm_connector.width_mm and &drm_connector.height_mm fields are * filled in. * + * Note that the caller function will automatically add standard VESA + * DMT modes up to 1024x768 if the .get_modes() helper operation returns + * no mode and if the connector status is connector_status_connected or + * connector_status_unknown. There is no need to call + * drm_add_modes_noedid() manually in that case. + * * Virtual drivers that just want some standard VESA mode with a given * resolution can call drm_add_modes_noedid(), and mark the preferred * one using drm_set_preferred_mode(). @@ -1045,9 +1050,8 @@ struct drm_connector_helper_funcs { * NOTE: * * This function is called in the check phase of an atomic update. The - * driver is not allowed to change anything outside of the free-standing - * state objects passed-in or assembled in the overall &drm_atomic_state - * update tracking structure. + * driver is not allowed to change anything outside of the + * &drm_atomic_state update tracking structure passed in. * * RETURNS: * @@ -1057,7 +1061,7 @@ struct drm_connector_helper_funcs { * for this. */ struct drm_encoder *(*atomic_best_encoder)(struct drm_connector *connector, - struct drm_connector_state *connector_state); + struct drm_atomic_state *state); /** * @atomic_check: @@ -1098,15 +1102,15 @@ struct drm_connector_helper_funcs { * * This hook is to be used by drivers implementing writeback connectors * that need a point when to commit the writeback job to the hardware. - * The writeback_job to commit is available in - * &drm_connector_state.writeback_job. + * The writeback_job to commit is available in the new connector state, + * in &drm_connector_state.writeback_job. * * This hook is optional. * * This callback is used by the atomic modeset helpers. */ void (*atomic_commit)(struct drm_connector *connector, - struct drm_connector_state *state); + struct drm_atomic_state *state); /** * @prepare_writeback_job: @@ -1397,6 +1401,27 @@ struct drm_mode_config_helper_funcs { * drm_atomic_helper_commit_tail(). */ void (*atomic_commit_tail)(struct drm_atomic_state *state); + + /** + * @atomic_commit_setup: + * + * This hook is used by the default atomic_commit() hook implemented in + * drm_atomic_helper_commit() together with the nonblocking helpers (see + * drm_atomic_helper_setup_commit()) to extend the DRM commit setup. It + * is not used by the atomic helpers. + * + * This function is called at the end of + * drm_atomic_helper_setup_commit(), so once the commit has been + * properly setup across the generic DRM object states. It allows + * drivers to do some additional commit tracking that isn't related to a + * CRTC, plane or connector, tracked in a &drm_private_obj structure. + * + * Note that the documentation of &drm_private_obj has more details on + * how one should implement this. + * + * This hook is optional. + */ + int (*atomic_commit_setup)(struct drm_atomic_state *state); }; #endif diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 1d82b264e5e4..8ef06ee1c8eb 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -764,6 +764,48 @@ int drm_plane_init(struct drm_device *dev, bool is_primary); void drm_plane_cleanup(struct drm_plane *plane); +__printf(10, 11) +void *__drmm_universal_plane_alloc(struct drm_device *dev, + size_t size, size_t offset, + uint32_t possible_crtcs, + const struct drm_plane_funcs *funcs, + const uint32_t *formats, + unsigned int format_count, + const uint64_t *format_modifiers, + enum drm_plane_type plane_type, + const char *name, ...); + +/** + * drmm_universal_plane_alloc - Allocate and initialize an universal plane object + * @dev: DRM device + * @type: the type of the struct which contains struct &drm_plane + * @member: the name of the &drm_plane within @type + * @possible_crtcs: bitmask of possible CRTCs + * @funcs: callbacks for the new plane + * @formats: array of supported formats (DRM_FORMAT\_\*) + * @format_count: number of elements in @formats + * @format_modifiers: array of struct drm_format modifiers terminated by + * DRM_FORMAT_MOD_INVALID + * @plane_type: type of plane (overlay, primary, cursor) + * @name: printf style format string for the plane name, or NULL for default name + * + * Allocates and initializes a plane object of type @type. Cleanup is + * automatically handled through registering drm_plane_cleanup() with + * drmm_add_action(). + * + * The @drm_plane_funcs.destroy hook must be NULL. + * + * Returns: + * Pointer to new plane, or ERR_PTR on failure. + */ +#define drmm_universal_plane_alloc(dev, type, member, possible_crtcs, funcs, formats, \ + format_count, format_modifiers, plane_type, name, ...) \ + ((type *)__drmm_universal_plane_alloc(dev, sizeof(type), \ + offsetof(type, member), \ + possible_crtcs, funcs, formats, \ + format_count, format_modifiers, \ + plane_type, name, ##__VA_ARGS__)) + /** * drm_plane_index - find the index of a registered plane * @plane: plane to find index for diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h index 0991a47a1567..54f2c58305d2 100644 --- a/include/drm/drm_prime.h +++ b/include/drm/drm_prime.h @@ -105,8 +105,9 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg); -int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, - dma_addr_t *addrs, int max_pages); - +int drm_prime_sg_to_page_array(struct sg_table *sgt, struct page **pages, + int max_pages); +int drm_prime_sg_to_dma_addr_array(struct sg_table *sgt, dma_addr_t *addrs, + int max_pages); #endif /* __DRM_PRIME_H__ */ diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h index a026375464ff..e6dbf3161c2f 100644 --- a/include/drm/drm_simple_kms_helper.h +++ b/include/drm/drm_simple_kms_helper.h @@ -185,4 +185,28 @@ int drm_simple_encoder_init(struct drm_device *dev, struct drm_encoder *encoder, int encoder_type); +void *__drmm_simple_encoder_alloc(struct drm_device *dev, size_t size, + size_t offset, int encoder_type); + +/** + * drmm_simple_encoder_alloc - Allocate and initialize an encoder with basic + * functionality. + * @dev: drm device + * @type: the type of the struct which contains struct &drm_encoder + * @member: the name of the &drm_encoder within @type. + * @encoder_type: user visible type of the encoder + * + * Allocates and initializes an encoder that has no further functionality. + * Settings for possible CRTC and clones are left to their initial values. + * Cleanup is automatically handled through registering drm_encoder_cleanup() + * with drmm_add_action(). + * + * Returns: + * Pointer to new encoder, or ERR_PTR on failure. + */ +#define drmm_simple_encoder_alloc(dev, type, member, encoder_type) \ + ((type *)__drmm_simple_encoder_alloc(dev, sizeof(type), \ + offsetof(type, member), \ + encoder_type)) + #endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */ diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index 92436553fd6a..975e8a67947f 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -171,10 +171,10 @@ struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f); * struct drm_sched_job - A job to be run by an entity. * * @queue_node: used to append this struct to the queue of jobs in an entity. + * @list: a job participates in a "pending" and "done" lists. * @sched: the scheduler instance on which this job is scheduled. * @s_fence: contains the fences for the scheduling of job. * @finish_cb: the callback for the finished fence. - * @node: used to append this struct to the @drm_gpu_scheduler.ring_mirror_list. * @id: a unique id assigned to each job scheduled on the scheduler. * @karma: increment on every hang caused by this job. If this exceeds the hang * limit of the scheduler then the job is marked guilty and will not @@ -189,21 +189,21 @@ struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f); */ struct drm_sched_job { struct spsc_node queue_node; + struct list_head list; struct drm_gpu_scheduler *sched; struct drm_sched_fence *s_fence; struct dma_fence_cb finish_cb; - struct list_head node; uint64_t id; atomic_t karma; enum drm_sched_priority s_priority; - struct drm_sched_entity *entity; + struct drm_sched_entity *entity; struct dma_fence_cb cb; }; static inline bool drm_sched_invalidate_job(struct drm_sched_job *s_job, int threshold) { - return (s_job && atomic_inc_return(&s_job->karma) > threshold); + return s_job && atomic_inc_return(&s_job->karma) > threshold; } /** @@ -260,8 +260,8 @@ struct drm_sched_backend_ops { * @work_tdr: schedules a delayed call to @drm_sched_job_timedout after the * timeout interval is over. * @thread: the kthread on which the scheduler which run. - * @ring_mirror_list: the list of jobs which are currently in the job queue. - * @job_list_lock: lock to protect the ring_mirror_list. + * @pending_list: the list of jobs which are currently in the job queue. + * @job_list_lock: lock to protect the pending_list. * @hang_limit: once the hangs by a job crosses this limit then it is marked * guilty and it will be considered for scheduling further. * @score: score to help loadbalancer pick a idle sched @@ -282,7 +282,7 @@ struct drm_gpu_scheduler { atomic64_t job_id_count; struct delayed_work work_tdr; struct task_struct *thread; - struct list_head ring_mirror_list; + struct list_head pending_list; spinlock_t job_list_lock; int hang_limit; atomic_t score; diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 37102e45e496..e17be324d95f 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -48,6 +48,8 @@ struct ttm_bo_global; struct ttm_bo_device; +struct dma_buf_map; + struct drm_mm_node; struct ttm_placement; @@ -123,7 +125,6 @@ struct ttm_buffer_object { struct ttm_bo_device *bdev; enum ttm_bo_type type; void (*destroy) (struct ttm_buffer_object *); - unsigned long num_pages; size_t acc_size; /** @@ -195,8 +196,12 @@ struct ttm_bo_kmap_obj { * * @interruptible: Sleep interruptible if sleeping. * @no_wait_gpu: Return immediately if the GPU is busy. + * @gfp_retry_mayfail: Set the __GFP_RETRY_MAYFAIL when allocation pages. + * @allow_res_evict: Allow eviction of reserved BOs. Can be used when multiple + * BOs share the same reservation object. + * @force_alloc: Don't check the memory account during suspend or CPU page + * faults. Should only be used by TTM internally. * @resv: Reservation object to allow reserved evictions with. - * @flags: Including the following flags * * Context for TTM operations like changing buffer placement or general memory * allocation. @@ -204,16 +209,13 @@ struct ttm_bo_kmap_obj { struct ttm_operation_ctx { bool interruptible; bool no_wait_gpu; + bool gfp_retry_mayfail; + bool allow_res_evict; + bool force_alloc; struct dma_resv *resv; uint64_t bytes_moved; - uint32_t flags; }; -/* Allow eviction of reserved BOs */ -#define TTM_OPT_FLAG_ALLOW_RES_EVICT 0x1 -/* when serving page fault or suspend, allow alloc anyway */ -#define TTM_OPT_FLAG_FORCE_ALLOC 0x2 - /** * ttm_bo_get - reference a struct ttm_buffer_object * @@ -307,6 +309,7 @@ void ttm_bo_put(struct ttm_buffer_object *bo); * ttm_bo_move_to_lru_tail * * @bo: The buffer object. + * @mem: Resource object. * @bulk: optional bulk move structure to remember BO positions * * Move this BO to the tail of all lru lists used to lookup and reserve an @@ -314,6 +317,7 @@ void ttm_bo_put(struct ttm_buffer_object *bo); * held, and is used to make a BO less likely to be considered for eviction. */ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo, + struct ttm_resource *mem, struct ttm_lru_bulk_move *bulk); /** @@ -394,13 +398,11 @@ size_t ttm_bo_dma_acc_size(struct ttm_bo_device *bdev, int ttm_bo_init_reserved(struct ttm_bo_device *bdev, struct ttm_buffer_object *bo, - unsigned long size, - enum ttm_bo_type type, + size_t size, enum ttm_bo_type type, struct ttm_placement *placement, uint32_t page_alignment, struct ttm_operation_ctx *ctx, - size_t acc_size, - struct sg_table *sg, + size_t acc_size, struct sg_table *sg, struct dma_resv *resv, void (*destroy) (struct ttm_buffer_object *)); @@ -442,7 +444,7 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, * -ERESTARTSYS: Interrupted by signal while sleeping waiting for resources. */ int ttm_bo_init(struct ttm_bo_device *bdev, struct ttm_buffer_object *bo, - unsigned long size, enum ttm_bo_type type, + size_t size, enum ttm_bo_type type, struct ttm_placement *placement, uint32_t page_alignment, bool interrubtible, size_t acc_size, struct sg_table *sg, struct dma_resv *resv, @@ -495,6 +497,32 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map); /** + * ttm_bo_vmap + * + * @bo: The buffer object. + * @map: pointer to a struct dma_buf_map representing the map. + * + * Sets up a kernel virtual mapping, using ioremap or vmap to the + * data in the buffer object. The parameter @map returns the virtual + * address as struct dma_buf_map. Unmap the buffer with ttm_bo_vunmap(). + * + * Returns + * -ENOMEM: Out of memory. + * -EINVAL: Invalid range. + */ +int ttm_bo_vmap(struct ttm_buffer_object *bo, struct dma_buf_map *map); + +/** + * ttm_bo_vunmap + * + * @bo: The buffer object. + * @map: Object describing the map to unmap. + * + * Unmaps a kernel map set up by ttm_bo_vmap(). + */ +void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct dma_buf_map *map); + +/** * ttm_bo_mmap_obj - mmap memory backed by a ttm buffer object. * * @vma: vma as input from the fbdev mmap method. @@ -571,6 +599,7 @@ static inline bool ttm_bo_uses_embedded_gem_object(struct ttm_buffer_object *bo) static inline void ttm_bo_pin(struct ttm_buffer_object *bo) { dma_resv_assert_held(bo->base.resv); + WARN_ON_ONCE(!kref_read(&bo->kref)); ++bo->pin_count; } @@ -584,6 +613,7 @@ static inline void ttm_bo_unpin(struct ttm_buffer_object *bo) { dma_resv_assert_held(bo->base.resv); WARN_ON_ONCE(!bo->pin_count); + WARN_ON_ONCE(!kref_read(&bo->kref)); --bo->pin_count; } diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 29f6a1d1c853..423348414c59 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -39,9 +39,9 @@ #include "ttm_bo_api.h" #include "ttm_memory.h" -#include "ttm_module.h" #include "ttm_placement.h" #include "ttm_tt.h" +#include "ttm_pool.h" /** * struct ttm_bo_driver @@ -120,6 +120,8 @@ struct ttm_bo_driver { * Return the bo flags for a buffer which is not mapped to the hardware. * These will be placed in proposed_flags so that when the move is * finished, they'll end up in bo->mem.flags + * This should not cause multihop evictions, and the core will warn + * if one is proposed. */ void (*evict_flags)(struct ttm_buffer_object *bo, @@ -133,12 +135,15 @@ struct ttm_bo_driver { * the graphics address space * @ctx: context for this move with parameters * @new_mem: the new memory region receiving the buffer + @ @hop: placement for driver directed intermediate hop * * Move a buffer between two memory regions. + * Returns errno -EMULTIHOP if driver requests a hop */ int (*move)(struct ttm_buffer_object *bo, bool evict, struct ttm_operation_ctx *ctx, - struct ttm_resource *new_mem); + struct ttm_resource *new_mem, + struct ttm_place *hop); /** * struct ttm_bo_driver_member verify_access @@ -275,7 +280,6 @@ extern struct ttm_bo_global { * @dev_mapping: A pointer to the struct address_space representing the * device address space. * @wq: Work queue structure for the delayed delete workqueue. - * @no_retry: Don't retry allocation if it fails * */ @@ -295,6 +299,7 @@ struct ttm_bo_device { * Protected by internal locks. */ struct drm_vma_offset_manager *vma_manager; + struct ttm_pool pool; /* * Protected by the global:lru lock. @@ -312,10 +317,6 @@ struct ttm_bo_device { */ struct delayed_work wq; - - bool need_dma32; - - bool no_retry; }; static inline struct ttm_resource_manager *ttm_manager_type(struct ttm_bo_device *bdev, @@ -395,11 +396,11 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev); * @bdev: A pointer to a struct ttm_bo_device to initialize. * @glob: A pointer to an initialized struct ttm_bo_global. * @driver: A pointer to a struct ttm_bo_driver set up by the caller. + * @dev: The core kernel device pointer for DMA mappings and allocations. * @mapping: The address space to use for this bo. * @vma_manager: A pointer to a vma manager. - * @file_page_offset: Offset into the device address space that is available - * for buffer data. This ensures compatibility with other users of the - * address space. + * @use_dma_alloc: If coherent DMA allocation API should be used. + * @use_dma32: If we should use GFP_DMA32 for device memory allocations. * * Initializes a struct ttm_bo_device: * Returns: @@ -407,9 +408,10 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev); */ int ttm_bo_device_init(struct ttm_bo_device *bdev, struct ttm_bo_driver *driver, + struct device *dev, struct address_space *mapping, struct drm_vma_offset_manager *vma_manager, - bool need_dma32); + bool use_dma_alloc, bool use_dma32); /** * ttm_bo_unmap_virtual @@ -489,10 +491,11 @@ static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, return 0; } -static inline void ttm_bo_move_to_lru_tail_unlocked(struct ttm_buffer_object *bo) +static inline void +ttm_bo_move_to_lru_tail_unlocked(struct ttm_buffer_object *bo) { spin_lock(&ttm_bo_glob.lru_lock); - ttm_bo_move_to_lru_tail(bo, NULL); + ttm_bo_move_to_lru_tail(bo, &bo->mem, NULL); spin_unlock(&ttm_bo_glob.lru_lock); } diff --git a/include/drm/ttm/ttm_caching.h b/include/drm/ttm/ttm_caching.h index 161624dcf6be..a0b4a49fa432 100644 --- a/include/drm/ttm/ttm_caching.h +++ b/include/drm/ttm/ttm_caching.h @@ -25,6 +25,8 @@ #ifndef _TTM_CACHING_H_ #define _TTM_CACHING_H_ +#define TTM_NUM_CACHING_TYPES 3 + enum ttm_caching { ttm_uncached, ttm_write_combined, diff --git a/include/drm/ttm/ttm_module.h b/include/drm/ttm/ttm_module.h deleted file mode 100644 index 45fa318c1585..000000000000 --- a/include/drm/ttm/ttm_module.h +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************** - * - * Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> - */ - -#ifndef _TTM_MODULE_H_ -#define _TTM_MODULE_H_ - -#include <linux/kernel.h> -struct kobject; - -#define TTM_PFX "[TTM] " -extern struct kobject *ttm_get_kobj(void); - -#endif /* _TTM_MODULE_H_ */ diff --git a/include/drm/ttm/ttm_page_alloc.h b/include/drm/ttm/ttm_page_alloc.h deleted file mode 100644 index 8fa1e7df6213..000000000000 --- a/include/drm/ttm/ttm_page_alloc.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) Red Hat Inc. - - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie <airlied@redhat.com> - * Jerome Glisse <jglisse@redhat.com> - */ -#ifndef TTM_PAGE_ALLOC -#define TTM_PAGE_ALLOC - -#include <drm/ttm/ttm_bo_driver.h> -#include <drm/ttm/ttm_memory.h> - -struct device; - -/** - * Initialize pool allocator. - */ -int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages); -/** - * Free pool allocator. - */ -void ttm_page_alloc_fini(void); - -/** - * ttm_pool_populate: - * - * @ttm: The struct ttm_tt to contain the backing pages. - * - * Add backing pages to all of @ttm - */ -int ttm_pool_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx); - -/** - * ttm_pool_unpopulate: - * - * @ttm: The struct ttm_tt which to free backing pages. - * - * Free all pages of @ttm - */ -void ttm_pool_unpopulate(struct ttm_tt *ttm); - -/** - * Populates and DMA maps pages to fullfil a ttm_dma_populate() request - */ -int ttm_populate_and_map_pages(struct device *dev, struct ttm_tt *tt, - struct ttm_operation_ctx *ctx); - -/** - * Unpopulates and DMA unmaps pages as part of a - * ttm_dma_unpopulate() request */ -void ttm_unmap_and_unpopulate_pages(struct device *dev, struct ttm_tt *tt); - -/** - * Output the state of pools to debugfs file - */ -int ttm_page_alloc_debugfs(struct seq_file *m, void *data); - -#if defined(CONFIG_DRM_TTM_DMA_PAGE_POOL) -/** - * Initialize pool allocator. - */ -int ttm_dma_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages); - -/** - * Free pool allocator. - */ -void ttm_dma_page_alloc_fini(void); - -/** - * Output the state of pools to debugfs file - */ -int ttm_dma_page_alloc_debugfs(struct seq_file *m, void *data); - -int ttm_dma_populate(struct ttm_tt *ttm_dma, struct device *dev, - struct ttm_operation_ctx *ctx); -void ttm_dma_unpopulate(struct ttm_tt *ttm_dma, struct device *dev); - -#else -static inline int ttm_dma_page_alloc_init(struct ttm_mem_global *glob, - unsigned max_pages) -{ - return -ENODEV; -} - -static inline void ttm_dma_page_alloc_fini(void) { return; } - -static inline int ttm_dma_page_alloc_debugfs(struct seq_file *m, void *data) -{ - return 0; -} -static inline int ttm_dma_populate(struct ttm_tt *ttm_dma, - struct device *dev, - struct ttm_operation_ctx *ctx) -{ - return -ENOMEM; -} -static inline void ttm_dma_unpopulate(struct ttm_tt *ttm_dma, - struct device *dev) -{ -} -#endif - -#endif diff --git a/include/drm/ttm/ttm_pool.h b/include/drm/ttm/ttm_pool.h new file mode 100644 index 000000000000..4321728bdd11 --- /dev/null +++ b/include/drm/ttm/ttm_pool.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* + * Copyright 2020 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Christian König + */ + +#ifndef _TTM_PAGE_POOL_H_ +#define _TTM_PAGE_POOL_H_ + +#include <linux/mmzone.h> +#include <linux/llist.h> +#include <linux/spinlock.h> +#include <drm/ttm/ttm_caching.h> + +struct device; +struct ttm_tt; +struct ttm_pool; +struct ttm_operation_ctx; + +/** + * ttm_pool_type - Pool for a certain memory type + * + * @pool: the pool we belong to, might be NULL for the global ones + * @order: the allocation order our pages have + * @caching: the caching type our pages have + * @shrinker_list: our place on the global shrinker list + * @lock: protection of the page list + * @pages: the list of pages in the pool + */ +struct ttm_pool_type { + struct ttm_pool *pool; + unsigned int order; + enum ttm_caching caching; + + struct list_head shrinker_list; + + spinlock_t lock; + struct list_head pages; +}; + +/** + * ttm_pool - Pool for all caching and orders + * + * @use_dma_alloc: if coherent DMA allocations should be used + * @use_dma32: if GFP_DMA32 should be used + * @caching: pools for each caching/order + */ +struct ttm_pool { + struct device *dev; + + bool use_dma_alloc; + bool use_dma32; + + struct { + struct ttm_pool_type orders[MAX_ORDER]; + } caching[TTM_NUM_CACHING_TYPES]; +}; + +int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt, + struct ttm_operation_ctx *ctx); +void ttm_pool_free(struct ttm_pool *pool, struct ttm_tt *tt); + +void ttm_pool_init(struct ttm_pool *pool, struct device *dev, + bool use_dma_alloc, bool use_dma32); +void ttm_pool_fini(struct ttm_pool *pool); + +int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m); + +int ttm_pool_mgr_init(unsigned long num_pages); +void ttm_pool_mgr_fini(void); + +#endif diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h index f48a70d39ac5..ad6da99770e9 100644 --- a/include/drm/ttm/ttm_resource.h +++ b/include/drm/ttm/ttm_resource.h @@ -171,7 +171,6 @@ struct ttm_bus_placement { struct ttm_resource { void *mm_node; unsigned long start; - unsigned long size; unsigned long num_pages; uint32_t page_alignment; uint32_t mem_type; diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h index df9a80650feb..6c8eb9a4de81 100644 --- a/include/drm/ttm/ttm_tt.h +++ b/include/drm/ttm/ttm_tt.h @@ -37,7 +37,6 @@ struct ttm_operation_ctx; #define TTM_PAGE_FLAG_SWAPPED (1 << 4) #define TTM_PAGE_FLAG_ZERO_ALLOC (1 << 6) -#define TTM_PAGE_FLAG_DMA32 (1 << 7) #define TTM_PAGE_FLAG_SG (1 << 8) #define TTM_PAGE_FLAG_NO_RETRY (1 << 9) @@ -66,7 +65,6 @@ struct ttm_tt { struct sg_table *sg; dma_addr_t *dma_address; struct file *swap_storage; - struct list_head pages_list; enum ttm_caching caching; }; @@ -101,8 +99,6 @@ int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc); */ int ttm_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo, uint32_t page_flags, enum ttm_caching caching); -int ttm_dma_tt_init(struct ttm_tt *ttm_dma, struct ttm_buffer_object *bo, - uint32_t page_flags, enum ttm_caching caching); int ttm_sg_tt_init(struct ttm_tt *ttm_dma, struct ttm_buffer_object *bo, uint32_t page_flags, enum ttm_caching caching); |