diff options
author | Sean Paul | 2018-04-16 10:47:13 -0400 |
---|---|---|
committer | Sean Paul | 2018-04-16 10:47:13 -0400 |
commit | 8089f9f5a32938ddefb1767b8ee14bb7996e5e2f (patch) | |
tree | c6c8924fda51c7f54bebffa63a41ae15954995bf /include/drm | |
parent | c0db1b677e1d584fab5d7ac76a32e1c0157542e0 (diff) | |
parent | a10beabba213924d876f2d10ca9351aeab93f58a (diff) |
Merge airlied/drm-next into drm-misc-fixes
Fast forwarding -fixes for 4.17.
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Diffstat (limited to 'include/drm')
33 files changed, 821 insertions, 477 deletions
diff --git a/include/drm/amd_asic_type.h b/include/drm/amd_asic_type.h index 599028f66585..6c731c52c071 100644 --- a/include/drm/amd_asic_type.h +++ b/include/drm/amd_asic_type.h @@ -45,6 +45,7 @@ enum amd_asic_type { CHIP_POLARIS11, CHIP_POLARIS12, CHIP_VEGA10, + CHIP_VEGA12, CHIP_RAVEN, CHIP_LAST, }; diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index c99d6eaef1ac..e9a1116d2f8e 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -13,6 +13,8 @@ #include <drm/drm_crtc.h> +struct analogix_dp_device; + enum analogix_dp_devtype { EXYNOS_DP, RK3288_DP, @@ -29,6 +31,7 @@ struct analogix_dp_plat_data { struct drm_panel *panel; struct drm_encoder *encoder; struct drm_connector *connector; + bool skip_connector; int (*power_on)(struct analogix_dp_plat_data *); int (*power_off)(struct analogix_dp_plat_data *); @@ -38,16 +41,17 @@ struct analogix_dp_plat_data { struct drm_connector *); }; -int analogix_dp_psr_supported(struct device *dev); -int analogix_dp_enable_psr(struct device *dev); -int analogix_dp_disable_psr(struct device *dev); +int analogix_dp_psr_enabled(struct analogix_dp_device *dp); +int analogix_dp_enable_psr(struct analogix_dp_device *dp); +int analogix_dp_disable_psr(struct analogix_dp_device *dp); -int analogix_dp_resume(struct device *dev); -int analogix_dp_suspend(struct device *dev); +int analogix_dp_resume(struct analogix_dp_device *dp); +int analogix_dp_suspend(struct analogix_dp_device *dp); -int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, - struct analogix_dp_plat_data *plat_data); -void analogix_dp_unbind(struct device *dev, struct device *master, void *data); +struct analogix_dp_device * +analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, + struct analogix_dp_plat_data *plat_data); +void analogix_dp_unbind(struct analogix_dp_device *dp); int analogix_dp_start_crc(struct drm_connector *connector); int analogix_dp_stop_crc(struct drm_connector *connector); diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 182f83283e24..dd2a8cf7d20b 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -143,12 +143,13 @@ struct dw_hdmi_plat_data { unsigned long mpixelclock); }; -int dw_hdmi_probe(struct platform_device *pdev, - const struct dw_hdmi_plat_data *plat_data); -void dw_hdmi_remove(struct platform_device *pdev); -void dw_hdmi_unbind(struct device *dev); -int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - const struct dw_hdmi_plat_data *plat_data); +struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, + const struct dw_hdmi_plat_data *plat_data); +void dw_hdmi_remove(struct dw_hdmi *hdmi); +void dw_hdmi_unbind(struct dw_hdmi *hdmi); +struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev, + struct drm_encoder *encoder, + const struct dw_hdmi_plat_data *plat_data); void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense); @@ -157,7 +158,18 @@ void dw_hdmi_audio_enable(struct dw_hdmi *hdmi); void dw_hdmi_audio_disable(struct dw_hdmi *hdmi); /* PHY configuration */ +void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address); void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, unsigned char addr); +void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable); +void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable); +void dw_hdmi_phy_reset(struct dw_hdmi *hdmi); + +enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, + void *data); +void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, + bool force, bool disabled, bool rxsense); +void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data); + #endif /* __IMX_HDMI_H__ */ diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h index 9b30fec302c8..d9c6d549f971 100644 --- a/include/drm/bridge/dw_mipi_dsi.h +++ b/include/drm/bridge/dw_mipi_dsi.h @@ -10,6 +10,8 @@ #ifndef __DW_MIPI_DSI__ #define __DW_MIPI_DSI__ +struct dw_mipi_dsi; + struct dw_mipi_dsi_phy_ops { int (*init)(void *priv_data); int (*get_lane_mbps)(void *priv_data, struct drm_display_mode *mode, @@ -29,11 +31,14 @@ struct dw_mipi_dsi_plat_data { void *priv_data; }; -int dw_mipi_dsi_probe(struct platform_device *pdev, - const struct dw_mipi_dsi_plat_data *plat_data); -void dw_mipi_dsi_remove(struct platform_device *pdev); -int dw_mipi_dsi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - const struct dw_mipi_dsi_plat_data *plat_data); -void dw_mipi_dsi_unbind(struct device *dev); +struct dw_mipi_dsi *dw_mipi_dsi_probe(struct platform_device *pdev, + const struct dw_mipi_dsi_plat_data + *plat_data); +void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi); +struct dw_mipi_dsi *dw_mipi_dsi_bind(struct platform_device *pdev, + struct drm_encoder *encoder, + const struct dw_mipi_dsi_plat_data + *plat_data); +void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi); #endif /* __DW_MIPI_DSI__ */ diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index cf13842a6dbd..a57a8aa90ffb 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -154,7 +154,7 @@ struct __drm_crtcs_state { struct drm_crtc *ptr; struct drm_crtc_state *state, *old_state, *new_state; s32 __user *out_fence_ptr; - unsigned last_vblank_count; + u64 last_vblank_count; }; struct __drm_connnectors_state { @@ -754,6 +754,28 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (new_plane_state) = (__state)->planes[__i].new_state, 1)) /** + * for_each_oldnew_plane_in_state_reverse - iterate over all planes in an atomic + * update in reverse order + * @__state: &struct drm_atomic_state pointer + * @plane: &struct drm_plane iteration cursor + * @old_plane_state: &struct drm_plane_state iteration cursor for the old state + * @new_plane_state: &struct drm_plane_state iteration cursor for the new state + * @__i: int iteration cursor, for macro-internal use + * + * This iterates over all planes in an atomic update in reverse order, + * tracking both old and new state. This is useful in places where the + * state delta needs to be considered, for example in atomic check functions. + */ +#define for_each_oldnew_plane_in_state_reverse(__state, plane, old_plane_state, new_plane_state, __i) \ + for ((__i) = ((__state)->dev->mode_config.num_total_plane - 1); \ + (__i) >= 0; \ + (__i)--) \ + for_each_if ((__state)->planes[__i].ptr && \ + ((plane) = (__state)->planes[__i].ptr, \ + (old_plane_state) = (__state)->planes[__i].old_state,\ + (new_plane_state) = (__state)->planes[__i].new_state, 1)) + +/** * for_each_old_plane_in_state - iterate over all planes in an atomic update * @__state: &struct drm_atomic_state pointer * @plane: &struct drm_plane iteration cursor diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 4842ee9485ce..26aaba58d6ce 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -40,7 +40,6 @@ int drm_atomic_helper_check_modeset(struct drm_device *dev, struct drm_atomic_state *state); int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, const struct drm_crtc_state *crtc_state, - const struct drm_rect *clip, int min_scale, int max_scale, bool can_position, diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 682d01ba920c..3270fec46979 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -29,6 +29,7 @@ #include <drm/drm_modes.h> struct drm_bridge; +struct drm_bridge_timings; struct drm_panel; /** @@ -90,7 +91,7 @@ struct drm_bridge_funcs { * * drm_mode_status Enum */ - enum drm_mode_status (*mode_valid)(struct drm_bridge *crtc, + enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge, const struct drm_display_mode *mode); /** @@ -223,12 +224,43 @@ struct drm_bridge_funcs { }; /** + * struct drm_bridge_timings - timing information for the bridge + */ +struct drm_bridge_timings { + /** + * @sampling_edge: + * + * Tells whether the bridge samples the digital input signal + * from the display engine on the positive or negative edge of the + * clock, this should reuse the DRM_BUS_FLAG_PIXDATA_[POS|NEG]EDGE + * bitwise flags from the DRM connector (bit 2 and 3 valid). + */ + u32 sampling_edge; + /** + * @setup_time_ps: + * + * Defines the time in picoseconds the input data lines must be + * stable before the clock edge. + */ + u32 setup_time_ps; + /** + * @hold_time_ps: + * + * Defines the time in picoseconds taken for the bridge to sample the + * input signal after the clock edge. + */ + u32 hold_time_ps; +}; + +/** * struct drm_bridge - central DRM bridge control structure * @dev: DRM device this bridge belongs to * @encoder: encoder to which this bridge is connected * @next: the next bridge in the encoder chain * @of_node: device node pointer to the bridge * @list: to keep track of all added bridges + * @timings: the timing specification for the bridge, if any (may + * be NULL) * @funcs: control functions * @driver_private: pointer to the bridge driver's internal context */ @@ -240,6 +272,7 @@ struct drm_bridge { struct device_node *of_node; #endif struct list_head list; + const struct drm_bridge_timings *timings; const struct drm_bridge_funcs *funcs; void *driver_private; diff --git a/include/drm/drm_cache.h b/include/drm/drm_cache.h index beab0f0d0cfb..bfe1639df02d 100644 --- a/include/drm/drm_cache.h +++ b/include/drm/drm_cache.h @@ -38,6 +38,8 @@ void drm_clflush_pages(struct page *pages[], unsigned long num_pages); void drm_clflush_sg(struct sg_table *st); void drm_clflush_virt_range(void *addr, unsigned long length); +u64 drm_get_max_iomem(void); + static inline bool drm_arch_can_wc_memory(void) { diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 03a59cbce621..44f04233e3db 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -26,6 +26,7 @@ #include <linux/ctype.h> struct drm_crtc; +struct drm_plane; uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision); @@ -37,4 +38,34 @@ 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_size - calculate the number of entries in the LUT + * @blob: blob containing the LUT + * + * Returns: + * The number of entries in the color LUT stored in @blob. + */ +static inline int drm_color_lut_size(const struct drm_property_blob *blob) +{ + return blob->length / sizeof(struct drm_color_lut); +} + +enum drm_color_encoding { + DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_BT709, + DRM_COLOR_YCBCR_BT2020, + DRM_COLOR_ENCODING_MAX, +}; + +enum drm_color_range { + DRM_COLOR_YCBCR_LIMITED_RANGE, + DRM_COLOR_YCBCR_FULL_RANGE, + DRM_COLOR_RANGE_MAX, +}; + +int drm_plane_create_color_properties(struct drm_plane *plane, + u32 supported_encodings, + u32 supported_ranges, + enum drm_color_encoding default_encoding, + enum drm_color_range default_range); #endif diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index ed38df4ac204..675cc3f8cf85 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -342,7 +342,11 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info, /** * struct drm_tv_connector_state - TV connector related states * @subconnector: selected subconnector - * @margins: left/right/top/bottom margins + * @margins: margins + * @margins.left: left margin + * @margins.right: right margin + * @margins.top: top margin + * @margins.bottom: bottom margin * @mode: TV mode * @brightness: brightness in percent * @contrast: contrast in percent @@ -419,6 +423,12 @@ struct drm_connector_state { * upscaling, mostly used for built-in panels. */ unsigned int scaling_mode; + + /** + * @content_protection: Connector property to request content + * protection. This is most commonly used for HDCP. + */ + unsigned int content_protection; }; /** @@ -766,6 +776,7 @@ struct drm_cmdline_mode { * @tile_h_size: horizontal size of this tile. * @tile_v_size: vertical size of this tile. * @scaling_mode_property: Optional atomic property to control the upscaling. + * @content_protection_property: Optional property to control content protection * * Each connector may be connected to one or more CRTCs, or may be clonable by * another connector if they can share a CRTC. Each connector also has a specific @@ -857,6 +868,12 @@ struct drm_connector { struct drm_property *scaling_mode_property; /** + * @content_protection_property: DRM ENUM property for content + * protection + */ + struct drm_property *content_protection_property; + + /** * @path_blob_ptr: * * DRM blob property data for the DP MST path property. @@ -1065,6 +1082,7 @@ const char *drm_get_dvi_i_subconnector_name(int val); const char *drm_get_dvi_i_select_name(int val); const char *drm_get_tv_subconnector_name(int val); const char *drm_get_tv_select_name(int val); +const char *drm_get_content_protection_name(int val); int drm_mode_create_dvi_i_properties(struct drm_device *dev); int drm_mode_create_tv_properties(struct drm_device *dev, @@ -1073,6 +1091,8 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int drm_mode_create_scaling_mode_property(struct drm_device *dev); int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, u32 scaling_mode_mask); +int drm_connector_attach_content_protection_property( + struct drm_connector *connector); int drm_mode_create_aspect_ratio_property(struct drm_device *dev); int drm_mode_create_suggested_offset_properties(struct drm_device *dev); diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index da58a428c8d7..62903bae0221 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -75,6 +75,7 @@ #define DP_MAX_DOWNSPREAD 0x003 # define DP_MAX_DOWNSPREAD_0_5 (1 << 0) # define DP_NO_AUX_HANDSHAKE_LINK_TRAINING (1 << 6) +# define DP_TPS4_SUPPORTED (1 << 7) #define DP_NORP 0x004 @@ -287,6 +288,7 @@ #define DP_PSR_SUPPORT 0x070 /* XXX 1.2? */ # define DP_PSR_IS_SUPPORTED 1 # define DP_PSR2_IS_SUPPORTED 2 /* eDP 1.4 */ +# define DP_PSR2_WITH_Y_COORD_IS_SUPPORTED 3 /* eDP 1.4a */ #define DP_PSR_CAPS 0x071 /* XXX 1.2? */ # define DP_PSR_NO_TRAIN_ON_EXIT 1 @@ -328,12 +330,20 @@ # define DP_DS_12BPC 2 # define DP_DS_16BPC 3 +/* DP Forward error Correction Registers */ +#define DP_FEC_CAPABILITY 0x090 /* 1.4 */ +# define DP_FEC_CAPABLE (1 << 0) +# define DP_FEC_UNCORR_BLK_ERROR_COUNT_CAP (1 << 1) +# define DP_FEC_CORR_BLK_ERROR_COUNT_CAP (1 << 2) +# define DP_FEC_BIT_ERROR_COUNT_CAP (1 << 3) + /* link configuration */ #define DP_LINK_BW_SET 0x100 # define DP_LINK_RATE_TABLE 0x00 /* eDP 1.4 */ # define DP_LINK_BW_1_62 0x06 # define DP_LINK_BW_2_7 0x0a # define DP_LINK_BW_5_4 0x14 /* 1.2 */ +# define DP_LINK_BW_8_1 0x1e /* 1.4 */ #define DP_LANE_COUNT_SET 0x101 # define DP_LANE_COUNT_MASK 0x0f @@ -344,7 +354,9 @@ # define DP_TRAINING_PATTERN_1 1 # define DP_TRAINING_PATTERN_2 2 # define DP_TRAINING_PATTERN_3 3 /* 1.2 */ +# define DP_TRAINING_PATTERN_4 7 /* 1.4 */ # define DP_TRAINING_PATTERN_MASK 0x3 +# define DP_TRAINING_PATTERN_MASK_1_4 0xf /* DPCD 1.1 only. For DPCD >= 1.2 see per-lane DP_LINK_QUAL_LANEn_SET */ # define DP_LINK_QUAL_PATTERN_11_DISABLE (0 << 2) @@ -441,6 +453,19 @@ #define DP_UPSTREAM_DEVICE_DP_PWR_NEED 0x118 /* 1.2 */ # define DP_PWR_NOT_NEEDED (1 << 0) +#define DP_FEC_CONFIGURATION 0x120 /* 1.4 */ +# define DP_FEC_READY (1 << 0) +# define DP_FEC_ERR_COUNT_SEL_MASK (7 << 1) +# define DP_FEC_ERR_COUNT_DIS (0 << 1) +# define DP_FEC_UNCORR_BLK_ERROR_COUNT (1 << 1) +# define DP_FEC_CORR_BLK_ERROR_COUNT (2 << 1) +# define DP_FEC_BIT_ERROR_COUNT (3 << 1) +# define DP_FEC_LANE_SELECT_MASK (3 << 4) +# define DP_FEC_LANE_0_SELECT (0 << 4) +# define DP_FEC_LANE_1_SELECT (1 << 4) +# define DP_FEC_LANE_2_SELECT (2 << 4) +# define DP_FEC_LANE_3_SELECT (3 << 4) + #define DP_AUX_FRAME_SYNC_VALUE 0x15c /* eDP 1.4 */ # define DP_AUX_FRAME_SYNC_VALID (1 << 0) @@ -616,6 +641,16 @@ #define DP_TEST_SINK 0x270 # define DP_TEST_SINK_START (1 << 0) +#define DP_FEC_STATUS 0x280 /* 1.4 */ +# define DP_FEC_DECODE_EN_DETECTED (1 << 0) +# define DP_FEC_DECODE_DIS_DETECTED (1 << 1) + +#define DP_FEC_ERROR_COUNT_LSB 0x0281 /* 1.4 */ + +#define DP_FEC_ERROR_COUNT_MSB 0x0282 /* 1.4 */ +# define DP_FEC_ERROR_COUNT_MASK 0x7F +# define DP_FEC_ERR_COUNT_VALID (1 << 7) + #define DP_PAYLOAD_TABLE_UPDATE_STATUS 0x2c0 /* 1.2 MST */ # define DP_PAYLOAD_TABLE_UPDATED (1 << 0) # define DP_PAYLOAD_ACT_HANDLED (1 << 1) @@ -836,6 +871,23 @@ #define DP_CEC_TX_MESSAGE_BUFFER 0x3020 #define DP_CEC_MESSAGE_BUFFER_LENGTH 0x10 +#define DP_AUX_HDCP_BKSV 0x68000 +#define DP_AUX_HDCP_RI_PRIME 0x68005 +#define DP_AUX_HDCP_AKSV 0x68007 +#define DP_AUX_HDCP_AN 0x6800C +#define DP_AUX_HDCP_V_PRIME(h) (0x68014 + h * 4) +#define DP_AUX_HDCP_BCAPS 0x68028 +# define DP_BCAPS_REPEATER_PRESENT BIT(1) +# define DP_BCAPS_HDCP_CAPABLE BIT(0) +#define DP_AUX_HDCP_BSTATUS 0x68029 +# define DP_BSTATUS_REAUTH_REQ BIT(3) +# define DP_BSTATUS_LINK_FAILURE BIT(2) +# define DP_BSTATUS_R0_PRIME_READY BIT(1) +# define DP_BSTATUS_READY BIT(0) +#define DP_AUX_HDCP_BINFO 0x6802A +#define DP_AUX_HDCP_KSV_FIFO 0x6802C +#define DP_AUX_HDCP_AINFO 0x6803B + /* DP 1.2 Sideband message defines */ /* peer device type - DP 1.2a Table 2-92 */ #define DP_PEER_DEVICE_NONE 0x0 @@ -971,6 +1023,20 @@ drm_dp_tps3_supported(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) } static inline bool +drm_dp_tps4_supported(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) +{ + return dpcd[DP_DPCD_REV] >= 0x14 && + dpcd[DP_MAX_DOWNSPREAD] & DP_TPS4_SUPPORTED; +} + +static inline u8 +drm_dp_training_pattern_mask(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) +{ + return (dpcd[DP_DPCD_REV] >= 0x14) ? DP_TRAINING_PATTERN_MASK_1_4 : + DP_TRAINING_PATTERN_MASK; +} + +static inline bool drm_dp_is_branch(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) { return dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT; diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h index 6942e84b6edd..3e86408dac9f 100644 --- a/include/drm/drm_fourcc.h +++ b/include/drm/drm_fourcc.h @@ -38,6 +38,7 @@ struct drm_mode_fb_cmd2; * @cpp: Number of bytes per pixel (per plane) * @hsub: Horizontal chroma subsampling factor * @vsub: Vertical chroma subsampling factor + * @has_alpha: Does the format embeds an alpha component? */ struct drm_format_info { u32 format; @@ -46,6 +47,7 @@ struct drm_format_info { u8 cpp[3]; u8 hsub; u8 vsub; + bool has_alpha; }; /** diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index 9c55c2acaa2b..3583b98a1718 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -116,21 +116,6 @@ struct drm_gem_object { int name; /** - * @read_domains: - * - * Read memory domains. These monitor which caches contain read/write data - * related to the object. When transitioning from one set of domains - * to another, the driver is called to ensure that caches are suitably - * flushed and invalidated. - */ - uint32_t read_domains; - - /** - * @write_domain: Corresponding unique write memory domain. - */ - uint32_t write_domain; - - /** * @dma_buf: * * dma-buf associated with this GEM object. diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h new file mode 100644 index 000000000000..562fa7df2637 --- /dev/null +++ b/include/drm/drm_hdcp.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright (C) 2017 Google, Inc. + * + * Authors: + * Sean Paul <seanpaul@chromium.org> + */ + +#ifndef _DRM_HDCP_H_INCLUDED_ +#define _DRM_HDCP_H_INCLUDED_ + +/* Period of hdcp checks (to ensure we're still authenticated) */ +#define DRM_HDCP_CHECK_PERIOD_MS (128 * 16) + +/* Shared lengths/masks between HDMI/DVI/DisplayPort */ +#define DRM_HDCP_AN_LEN 8 +#define DRM_HDCP_BSTATUS_LEN 2 +#define DRM_HDCP_KSV_LEN 5 +#define DRM_HDCP_RI_LEN 2 +#define DRM_HDCP_V_PRIME_PART_LEN 4 +#define DRM_HDCP_V_PRIME_NUM_PARTS 5 +#define DRM_HDCP_NUM_DOWNSTREAM(x) (x & 0x3f) +#define DRM_HDCP_MAX_CASCADE_EXCEEDED(x) (x & BIT(3)) +#define DRM_HDCP_MAX_DEVICE_EXCEEDED(x) (x & BIT(7)) + +/* Slave address for the HDCP registers in the receiver */ +#define DRM_HDCP_DDC_ADDR 0x3A + +/* HDCP register offsets for HDMI/DVI devices */ +#define DRM_HDCP_DDC_BKSV 0x00 +#define DRM_HDCP_DDC_RI_PRIME 0x08 +#define DRM_HDCP_DDC_AKSV 0x10 +#define DRM_HDCP_DDC_AN 0x18 +#define DRM_HDCP_DDC_V_PRIME(h) (0x20 + h * 4) +#define DRM_HDCP_DDC_BCAPS 0x40 +#define DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT BIT(6) +#define DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY BIT(5) +#define DRM_HDCP_DDC_BSTATUS 0x41 +#define DRM_HDCP_DDC_KSV_FIFO 0x43 + +#endif diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 2cb6f02df64a..7569f22ffef6 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -36,6 +36,7 @@ struct drm_device; struct drm_atomic_state; struct drm_mode_fb_cmd2; struct drm_format_info; +struct drm_display_mode; /** * struct drm_mode_config_funcs - basic driver provided mode setting functions @@ -102,6 +103,17 @@ struct drm_mode_config_funcs { void (*output_poll_changed)(struct drm_device *dev); /** + * @mode_valid: + * + * Device specific validation of display modes. Can be used to reject + * modes that can never be supported. Only device wide constraints can + * be checked here. crtc/encoder/bridge/connector specific constraints + * should be checked in the .mode_valid() hook for each specific object. + */ + enum drm_mode_status (*mode_valid)(struct drm_device *dev, + const struct drm_display_mode *mode); + + /** * @atomic_check: * * This is the only hook to validate an atomic modeset update. This diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h index 7ba3913f30b5..c34a3e8030e1 100644 --- a/include/drm/drm_mode_object.h +++ b/include/drm/drm_mode_object.h @@ -120,30 +120,6 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, void drm_mode_object_get(struct drm_mode_object *obj); void drm_mode_object_put(struct drm_mode_object *obj); -/** - * drm_mode_object_reference - acquire a mode object reference - * @obj: DRM mode object - * - * This is a compatibility alias for drm_mode_object_get() and should not be - * used by new code. - */ -static inline void drm_mode_object_reference(struct drm_mode_object *obj) -{ - drm_mode_object_get(obj); -} - -/** - * drm_mode_object_unreference - release a mode object reference - * @obj: DRM mode object - * - * This is a compatibility alias for drm_mode_object_put() and should not be - * used by new code. - */ -static inline void drm_mode_object_unreference(struct drm_mode_object *obj) -{ - drm_mode_object_put(obj); -} - int drm_object_property_set_value(struct drm_mode_object *obj, struct drm_property *property, uint64_t val); diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index 9f3421c8efcd..0d310beae6af 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -131,9 +131,6 @@ enum drm_mode_status { MODE_ERROR = -1 }; -#define DRM_MODE_TYPE_CLOCK_CRTC_C (DRM_MODE_TYPE_CLOCK_C | \ - DRM_MODE_TYPE_CRTC_C) - #define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \ .name = nm, .status = 0, .type = (t), .clock = (c), \ .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \ @@ -245,26 +242,25 @@ struct drm_display_mode { * A bitmask of flags, mostly about the source of a mode. Possible flags * are: * - * - DRM_MODE_TYPE_BUILTIN: Meant for hard-coded modes, effectively - * unused. * - DRM_MODE_TYPE_PREFERRED: Preferred mode, usually the native * resolution of an LCD panel. There should only be one preferred * mode per connector at any given time. * - DRM_MODE_TYPE_DRIVER: Mode created by the driver, which is all of * them really. Drivers must set this bit for all modes they create * and expose to userspace. + * - DRM_MODE_TYPE_USERDEF: Mode defined via kernel command line * * Plus a big list of flags which shouldn't be used at all, but are - * still around since these flags are also used in the userspace ABI: + * still around since these flags are also used in the userspace ABI. + * We no longer accept modes with these types though: * + * - DRM_MODE_TYPE_BUILTIN: Meant for hard-coded modes, unused. + * Use DRM_MODE_TYPE_DRIVER instead. * - DRM_MODE_TYPE_DEFAULT: Again a leftover, use * DRM_MODE_TYPE_PREFERRED instead. * - DRM_MODE_TYPE_CLOCK_C and DRM_MODE_TYPE_CRTC_C: Define leftovers * which are stuck around for hysterical raisins only. No one has an * idea what they were meant for. Don't use. - * - DRM_MODE_TYPE_USERDEF: Mode defined by userspace, again a vestige - * from older kms designs where userspace had to first add a custom - * mode to the kernel's mode list before it could use it. Don't use. */ unsigned int type; @@ -299,8 +295,8 @@ struct drm_display_mode { * - DRM_MODE_FLAG_PCSYNC: composite sync is active high. * - DRM_MODE_FLAG_NCSYNC: composite sync is active low. * - DRM_MODE_FLAG_HSKEW: hskew provided (not used?). - * - DRM_MODE_FLAG_BCAST: not used? - * - DRM_MODE_FLAG_PIXMUX: not used? + * - DRM_MODE_FLAG_BCAST: <deprecated> + * - DRM_MODE_FLAG_PIXMUX: <deprecated> * - DRM_MODE_FLAG_DBLCLK: double-clocked mode. * - DRM_MODE_FLAG_CLKDIV2: half-clocked mode. * @@ -448,7 +444,8 @@ struct drm_display_mode *drm_mode_create(struct drm_device *dev); void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out, const struct drm_display_mode *in); -int drm_mode_convert_umode(struct drm_display_mode *out, +int drm_mode_convert_umode(struct drm_device *dev, + struct drm_display_mode *out, const struct drm_mode_modeinfo *in); void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); void drm_mode_debug_printmodeline(const struct drm_display_mode *mode); @@ -501,7 +498,8 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2); /* for use by the crtc helper probe functions */ -enum drm_mode_status drm_mode_validate_basic(const struct drm_display_mode *mode); +enum drm_mode_status drm_mode_validate_driver(struct drm_device *dev, + const struct drm_display_mode *mode); enum drm_mode_status drm_mode_validate_size(const struct drm_display_mode *mode, int maxX, int maxY); enum drm_mode_status diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8185e3468a23..f7bf4a48b1c3 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -26,6 +26,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <drm/drm_mode_object.h> +#include <drm/drm_color_mgmt.h> struct drm_crtc; struct drm_printer; @@ -112,6 +113,20 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos; + /** + * @color_encoding: + * + * Color encoding for non RGB formats + */ + enum drm_color_encoding color_encoding; + + /** + * @color_range: + * + * Color range for non RGB formats + */ + enum drm_color_range color_range; + /* Clipped coordinates */ struct drm_rect src, dst; @@ -558,6 +573,23 @@ struct drm_plane { struct drm_property *zpos_property; struct drm_property *rotation_property; + + /** + * @color_encoding_property: + * + * Optional "COLOR_ENCODING" enum property for specifying + * color encoding for non RGB formats. + * See drm_plane_create_color_properties(). + */ + struct drm_property *color_encoding_property; + /** + * @color_range_property: + * + * Optional "COLOR_RANGE" enum property for specifying + * color range for non RGB formats. + * See drm_plane_create_color_properties(). + */ + struct drm_property *color_range_property; }; #define obj_to_plane(x) container_of(x, struct drm_plane, base) diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h index 8aa49c0ecd4d..28d7ce620729 100644 --- a/include/drm/drm_plane_helper.h +++ b/include/drm/drm_plane_helper.h @@ -43,7 +43,6 @@ int drm_plane_helper_check_update(struct drm_plane *plane, struct drm_framebuffer *fb, struct drm_rect *src, struct drm_rect *dest, - const struct drm_rect *clip, unsigned int rotation, int min_scale, int max_scale, diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h index 9cd9e36f77b5..4d5f5d6cf6a6 100644 --- a/include/drm/drm_prime.h +++ b/include/drm/drm_prime.h @@ -54,6 +54,9 @@ struct device; struct dma_buf_export_info; struct dma_buf; +struct dma_buf_attachment; + +enum dma_data_direction; struct drm_device; struct drm_gem_object; @@ -79,6 +82,25 @@ int drm_gem_prime_fd_to_handle(struct drm_device *dev, struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev, struct dma_buf_export_info *exp_info); void drm_gem_dmabuf_release(struct dma_buf *dma_buf); +int drm_gem_map_attach(struct dma_buf *dma_buf, struct device *target_dev, + struct dma_buf_attachment *attach); +void drm_gem_map_detach(struct dma_buf *dma_buf, + struct dma_buf_attachment *attach); +struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, + enum dma_data_direction dir); +void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, + struct sg_table *sgt, + enum dma_data_direction dir); +void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf); +void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr); +void *drm_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, + unsigned long page_num); +void drm_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, + unsigned long page_num, void *addr); +void *drm_gem_dmabuf_kmap(struct dma_buf *dma_buf, unsigned long page_num); +void drm_gem_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_num, + void *addr); +int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma); int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, dma_addr_t *addrs, int max_pages); diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 2a4a42e59a47..e1a46e9991cc 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -196,21 +196,22 @@ static inline struct drm_printer drm_debug_printer(const char *prefix) #define DRM_UT_STATE 0x40 #define DRM_UT_LEASE 0x80 -__printf(6, 7) +__printf(3, 4) void drm_dev_printk(const struct device *dev, const char *level, - unsigned int category, const char *function_name, - const char *prefix, const char *format, ...); + const char *format, ...); __printf(3, 4) -void drm_printk(const char *level, unsigned int category, - const char *format, ...); +void drm_dev_dbg(const struct device *dev, unsigned int category, + const char *format, ...); + +__printf(2, 3) +void drm_dbg(unsigned int category, const char *format, ...); +__printf(1, 2) +void drm_err(const char *format, ...); /* Macros to make printk easier */ #define _DRM_PRINTK(once, level, fmt, ...) \ - do { \ - printk##once(KERN_##level "[" DRM_NAME "] " fmt, \ - ##__VA_ARGS__); \ - } while (0) + printk##once(KERN_##level "[" DRM_NAME "] " fmt, ##__VA_ARGS__) #define DRM_INFO(fmt, ...) \ _DRM_PRINTK(, INFO, fmt, ##__VA_ARGS__) @@ -233,10 +234,9 @@ void drm_printk(const char *level, unsigned int category, * @fmt: printf() like format string. */ #define DRM_DEV_ERROR(dev, fmt, ...) \ - drm_dev_printk(dev, KERN_ERR, DRM_UT_NONE, __func__, " *ERROR*",\ - fmt, ##__VA_ARGS__) + drm_dev_printk(dev, KERN_ERR, "*ERROR* " fmt, ##__VA_ARGS__) #define DRM_ERROR(fmt, ...) \ - drm_printk(KERN_ERR, DRM_UT_NONE, fmt, ##__VA_ARGS__) + drm_err(fmt, ##__VA_ARGS__) /** * Rate limited error output. Like DRM_ERROR() but won't flood the log. @@ -257,8 +257,7 @@ void drm_printk(const char *level, unsigned int category, DRM_DEV_ERROR_RATELIMITED(NULL, fmt, ##__VA_ARGS__) #define DRM_DEV_INFO(dev, fmt, ...) \ - drm_dev_printk(dev, KERN_INFO, DRM_UT_NONE, __func__, "", fmt, \ - ##__VA_ARGS__) + drm_dev_printk(dev, KERN_INFO, fmt, ##__VA_ARGS__) #define DRM_DEV_INFO_ONCE(dev, fmt, ...) \ ({ \ @@ -275,53 +274,46 @@ void drm_printk(const char *level, unsigned int category, * @dev: device pointer * @fmt: printf() like format string. */ -#define DRM_DEV_DEBUG(dev, fmt, args...) \ - drm_dev_printk(dev, KERN_DEBUG, DRM_UT_CORE, __func__, "", fmt, \ - ##args) +#define DRM_DEV_DEBUG(dev, fmt, ...) \ + drm_dev_dbg(dev, DRM_UT_CORE, fmt, ##__VA_ARGS__) #define DRM_DEBUG(fmt, ...) \ - drm_printk(KERN_DEBUG, DRM_UT_CORE, fmt, ##__VA_ARGS__) + drm_dbg(DRM_UT_CORE, fmt, ##__VA_ARGS__) -#define DRM_DEV_DEBUG_DRIVER(dev, fmt, args...) \ - drm_dev_printk(dev, KERN_DEBUG, DRM_UT_DRIVER, __func__, "", \ - fmt, ##args) +#define DRM_DEV_DEBUG_DRIVER(dev, fmt, ...) \ + drm_dev_dbg(dev, DRM_UT_DRIVER, fmt, ##__VA_ARGS__) #define DRM_DEBUG_DRIVER(fmt, ...) \ - drm_printk(KERN_DEBUG, DRM_UT_DRIVER, fmt, ##__VA_ARGS__) + drm_dbg(DRM_UT_DRIVER, fmt, ##__VA_ARGS__) -#define DRM_DEV_DEBUG_KMS(dev, fmt, args...) \ - drm_dev_printk(dev, KERN_DEBUG, DRM_UT_KMS, __func__, "", fmt, \ - ##args) -#define DRM_DEBUG_KMS(fmt, ...) \ - drm_printk(KERN_DEBUG, DRM_UT_KMS, fmt, ##__VA_ARGS__) +#define DRM_DEV_DEBUG_KMS(dev, fmt, ...) \ + drm_dev_dbg(dev, DRM_UT_KMS, fmt, ##__VA_ARGS__) +#define DRM_DEBUG_KMS(fmt, ...) \ + drm_dbg(DRM_UT_KMS, fmt, ##__VA_ARGS__) -#define DRM_DEV_DEBUG_PRIME(dev, fmt, args...) \ - drm_dev_printk(dev, KERN_DEBUG, DRM_UT_PRIME, __func__, "", \ - fmt, ##args) +#define DRM_DEV_DEBUG_PRIME(dev, fmt, ...) \ + drm_dev_dbg(dev, DRM_UT_PRIME, fmt, ##__VA_ARGS__) #define DRM_DEBUG_PRIME(fmt, ...) \ - drm_printk(KERN_DEBUG, DRM_UT_PRIME, fmt, ##__VA_ARGS__) + drm_dbg(DRM_UT_PRIME, fmt, ##__VA_ARGS__) -#define DRM_DEV_DEBUG_ATOMIC(dev, fmt, args...) \ - drm_dev_printk(dev, KERN_DEBUG, DRM_UT_ATOMIC, __func__, "", \ - fmt, ##args) +#define DRM_DEV_DEBUG_ATOMIC(dev, fmt, ...) \ + drm_dev_dbg(dev, DRM_UT_ATOMIC, fmt, ##__VA_ARGS__) #define DRM_DEBUG_ATOMIC(fmt, ...) \ - drm_printk(KERN_DEBUG, DRM_UT_ATOMIC, fmt, ##__VA_ARGS__) + drm_dbg(DRM_UT_ATOMIC, fmt, ##__VA_ARGS__) -#define DRM_DEV_DEBUG_VBL(dev, fmt, args...) \ - drm_dev_printk(dev, KERN_DEBUG, DRM_UT_VBL, __func__, "", fmt, \ - ##args) -#define DRM_DEBUG_VBL(fmt, ...) \ - drm_printk(KERN_DEBUG, DRM_UT_VBL, fmt, ##__VA_ARGS__) +#define DRM_DEV_DEBUG_VBL(dev, fmt, ...) \ + drm_dev_dbg(dev, DRM_UT_VBL, fmt, ##__VA_ARGS__) +#define DRM_DEBUG_VBL(fmt, ...) \ + drm_dbg(DRM_UT_VBL, fmt, ##__VA_ARGS__) #define DRM_DEBUG_LEASE(fmt, ...) \ - drm_printk(KERN_DEBUG, DRM_UT_LEASE, fmt, ##__VA_ARGS__) + drm_dbg(DRM_UT_LEASE, fmt, ##__VA_ARGS__) -#define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, level, fmt, args...) \ +#define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, category, fmt, ...) \ ({ \ static DEFINE_RATELIMIT_STATE(_rs, \ DEFAULT_RATELIMIT_INTERVAL, \ DEFAULT_RATELIMIT_BURST); \ if (__ratelimit(&_rs)) \ - drm_dev_printk(dev, KERN_DEBUG, DRM_UT_ ## level, \ - __func__, "", fmt, ##args); \ + drm_dev_dbg(dev, category, fmt, ##__VA_ARGS__); \ }) /** @@ -330,21 +322,28 @@ void drm_printk(const char *level, unsigned int category, * @dev: device pointer * @fmt: printf() like format string. */ -#define DRM_DEV_DEBUG_RATELIMITED(dev, fmt, args...) \ - DEV__DRM_DEFINE_DEBUG_RATELIMITED(dev, CORE, fmt, ##args) -#define DRM_DEBUG_RATELIMITED(fmt, args...) \ - DRM_DEV_DEBUG_RATELIMITED(NULL, fmt, ##args) -#define DRM_DEV_DEBUG_DRIVER_RATELIMITED(dev, fmt, args...) \ - _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRIVER, fmt, ##args) -#define DRM_DEBUG_DRIVER_RATELIMITED(fmt, args...) \ - DRM_DEV_DEBUG_DRIVER_RATELIMITED(NULL, fmt, ##args) -#define DRM_DEV_DEBUG_KMS_RATELIMITED(dev, fmt, args...) \ - _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, KMS, fmt, ##args) -#define DRM_DEBUG_KMS_RATELIMITED(fmt, args...) \ - DRM_DEV_DEBUG_KMS_RATELIMITED(NULL, fmt, ##args) -#define DRM_DEV_DEBUG_PRIME_RATELIMITED(dev, fmt, args...) \ - _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, PRIME, fmt, ##args) -#define DRM_DEBUG_PRIME_RATELIMITED(fmt, args...) \ - DRM_DEV_DEBUG_PRIME_RATELIMITED(NULL, fmt, ##args) +#define DRM_DEV_DEBUG_RATELIMITED(dev, fmt, ...) \ + _DEV_DRM_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_CORE, \ + fmt, ##__VA_ARGS__) +#define DRM_DEBUG_RATELIMITED(fmt, ...) \ + DRM_DEV_DEBUG_RATELIMITED(NULL, fmt, ##__VA_ARGS__) + +#define DRM_DEV_DEBUG_DRIVER_RATELIMITED(dev, fmt, ...) \ + _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_DRIVER, \ + fmt, ##__VA_ARGS__) +#define DRM_DEBUG_DRIVER_RATELIMITED(fmt, ...) \ + DRM_DEV_DEBUG_DRIVER_RATELIMITED(NULL, fmt, ##__VA_ARGS__) + +#define DRM_DEV_DEBUG_KMS_RATELIMITED(dev, fmt, ...) \ + _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_KMS, \ + fmt, ##__VA_ARGS__) +#define DRM_DEBUG_KMS_RATELIMITED(fmt, ...) \ + DRM_DEV_DEBUG_KMS_RATELIMITED(NULL, fmt, ##__VA_ARGS__) + +#define DRM_DEV_DEBUG_PRIME_RATELIMITED(dev, fmt, ...) \ + _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_PRIME, \ + fmt, ##__VA_ARGS__) +#define DRM_DEBUG_PRIME_RATELIMITED(fmt, ...) \ + DRM_DEV_DEBUG_PRIME_RATELIMITED(NULL, fmt, ##__VA_ARGS__) #endif /* DRM_PRINT_H_ */ diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h index 8a522b4bed40..d1423c7f3c73 100644 --- a/include/drm/drm_property.h +++ b/include/drm/drm_property.h @@ -209,7 +209,7 @@ struct drm_property_blob { struct list_head head_global; struct list_head head_file; size_t length; - unsigned char data[]; + void *data; }; struct drm_prop_enum_list { @@ -237,27 +237,29 @@ static inline bool drm_property_type_is(struct drm_property *property, return property->flags & type; } -struct drm_property *drm_property_create(struct drm_device *dev, int flags, - const char *name, int num_values); -struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, - const char *name, +struct drm_property *drm_property_create(struct drm_device *dev, + u32 flags, const char *name, + int num_values); +struct drm_property *drm_property_create_enum(struct drm_device *dev, + u32 flags, const char *name, const struct drm_prop_enum_list *props, int num_values); struct drm_property *drm_property_create_bitmask(struct drm_device *dev, - int flags, const char *name, + u32 flags, const char *name, const struct drm_prop_enum_list *props, int num_props, uint64_t supported_bits); -struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, - const char *name, +struct drm_property *drm_property_create_range(struct drm_device *dev, + u32 flags, const char *name, uint64_t min, uint64_t max); struct drm_property *drm_property_create_signed_range(struct drm_device *dev, - int flags, const char *name, + u32 flags, const char *name, int64_t min, int64_t max); struct drm_property *drm_property_create_object(struct drm_device *dev, - int flags, const char *name, uint32_t type); -struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags, - const char *name); + u32 flags, const char *name, + uint32_t type); +struct drm_property *drm_property_create_bool(struct drm_device *dev, + u32 flags, const char *name); int drm_property_add_enum(struct drm_property *property, int index, uint64_t value, const char *name); void drm_property_destroy(struct drm_device *dev, struct drm_property *property); diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h index 6d9adbb46293..1b4e352143fd 100644 --- a/include/drm/drm_simple_kms_helper.h +++ b/include/drm/drm_simple_kms_helper.h @@ -22,6 +22,41 @@ struct drm_simple_display_pipe; */ struct drm_simple_display_pipe_funcs { /** + * @mode_valid: + * + * This callback is used to check if a specific mode is valid in the + * crtc used in this simple display pipe. This should be implemented + * if the display pipe has some sort of restriction in the modes + * it can display. For example, a given display pipe may be responsible + * to set a clock value. If the clock can not produce all the values + * for the available modes then this callback can be used to restrict + * the number of modes to only the ones that can be displayed. Another + * reason can be bandwidth mitigation: the memory port on the display + * controller can have bandwidth limitations not allowing pixel data + * to be fetched at any rate. + * + * This hook is used by the probe helpers to filter the mode list in + * drm_helper_probe_single_connector_modes(), and it is used by the + * atomic helpers to validate modes supplied by userspace in + * drm_atomic_helper_check_modeset(). + * + * This function is optional. + * + * NOTE: + * + * Since this function is both called from the check phase of an atomic + * commit, and the mode validation in the probe paths it is not allowed + * to look at anything else but the passed-in mode, and validate it + * against configuration-invariant hardware constraints. + * + * RETURNS: + * + * drm_mode_status Enum + */ + enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc, + const struct drm_display_mode *mode); + + /** * @enable: * * This function should be used to enable the pipeline. @@ -93,6 +128,24 @@ struct drm_simple_display_pipe_funcs { */ void (*cleanup_fb)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *plane_state); + + /** + * @enable_vblank: + * + * Optional, called by &drm_crtc_funcs.enable_vblank. Please read + * the documentation for the &drm_crtc_funcs.enable_vblank hook for + * more details. + */ + int (*enable_vblank)(struct drm_simple_display_pipe *pipe); + + /** + * @disable_vblank: + * + * Optional, called by &drm_crtc_funcs.disable_vblank. Please read + * the documentation for the &drm_crtc_funcs.disable_vblank hook for + * more details. + */ + void (*disable_vblank)(struct drm_simple_display_pipe *pipe); }; /** diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h index 848b463a0af5..d25a9603ab57 100644 --- a/include/drm/drm_vblank.h +++ b/include/drm/drm_vblank.h @@ -55,8 +55,24 @@ struct drm_pending_vblank_event { * @event: Actual event which will be sent to userspace. */ union { + /** + * @event.base: DRM event base class. + */ struct drm_event base; + + /** + * @event.vbl: + * + * Event payload for vblank events, requested through + * either the MODE_PAGE_FLIP or MODE_ATOMIC IOCTL. Also + * generated by the legacy WAIT_VBLANK IOCTL, but new userspace + * should use MODE_QUEUE_SEQUENCE and &event.seq instead. + */ struct drm_event_vblank vbl; + + /** + * @event.seq: Event payload for the MODE_QUEUEU_SEQUENCE IOCTL. + */ struct drm_event_crtc_sequence seq; } event; }; @@ -179,7 +195,9 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc); void drm_crtc_vblank_off(struct drm_crtc *crtc); void drm_crtc_vblank_reset(struct drm_crtc *crtc); void drm_crtc_vblank_on(struct drm_crtc *crtc); -u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc); +u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc); +void drm_vblank_restore(struct drm_device *dev, unsigned int pipe); +void drm_crtc_vblank_restore(struct drm_crtc *crtc); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h index 545c6e0fea7d..346b1f5cb180 100644 --- a/include/drm/i915_component.h +++ b/include/drm/i915_component.h @@ -26,9 +26,8 @@ /* MAX_PORT is the number of port * It must be sync with I915_MAX_PORTS defined i915_drv.h - * 5 should be enough as only HSW, BDW, SKL need such fix. */ -#define MAX_PORTS 5 +#define MAX_PORTS 6 /** * struct i915_audio_component_ops - Ops implemented by i915 driver, called by hda driver diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 5db0458dd832..70f0c2535b87 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -414,24 +414,33 @@ INTEL_CFL_U_GT2_IDS(info), \ INTEL_CFL_U_GT3_IDS(info) -/* CNL U 2+2 */ -#define INTEL_CNL_U_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x5A52, info), \ - INTEL_VGA_DEVICE(0x5A5A, info), \ - INTEL_VGA_DEVICE(0x5A42, info), \ - INTEL_VGA_DEVICE(0x5A4A, info) - -/* CNL Y 2+2 */ -#define INTEL_CNL_Y_GT2_IDS(info) \ +/* CNL */ +#define INTEL_CNL_IDS(info) \ INTEL_VGA_DEVICE(0x5A51, info), \ INTEL_VGA_DEVICE(0x5A59, info), \ INTEL_VGA_DEVICE(0x5A41, info), \ INTEL_VGA_DEVICE(0x5A49, info), \ - INTEL_VGA_DEVICE(0x5A71, info), \ - INTEL_VGA_DEVICE(0x5A79, info) - -#define INTEL_CNL_IDS(info) \ - INTEL_CNL_U_GT2_IDS(info), \ - INTEL_CNL_Y_GT2_IDS(info) + INTEL_VGA_DEVICE(0x5A52, info), \ + INTEL_VGA_DEVICE(0x5A5A, info), \ + INTEL_VGA_DEVICE(0x5A42, info), \ + INTEL_VGA_DEVICE(0x5A4A, info), \ + INTEL_VGA_DEVICE(0x5A50, info), \ + INTEL_VGA_DEVICE(0x5A40, info), \ + INTEL_VGA_DEVICE(0x5A54, info), \ + INTEL_VGA_DEVICE(0x5A5C, info), \ + INTEL_VGA_DEVICE(0x5A44, info), \ + INTEL_VGA_DEVICE(0x5A4C, info) + +/* ICL */ +#define INTEL_ICL_11_IDS(info) \ + INTEL_VGA_DEVICE(0x8A50, info), \ + INTEL_VGA_DEVICE(0x8A51, info), \ + INTEL_VGA_DEVICE(0x8A5C, info), \ + INTEL_VGA_DEVICE(0x8A5D, info), \ + INTEL_VGA_DEVICE(0x8A52, info), \ + INTEL_VGA_DEVICE(0x8A5A, info), \ + INTEL_VGA_DEVICE(0x8A5B, info), \ + INTEL_VGA_DEVICE(0x8A71, info), \ + INTEL_VGA_DEVICE(0x8A70, info) #endif /* _I915_PCIIDS_H */ diff --git a/include/drm/tinydrm/ili9341.h b/include/drm/tinydrm/ili9341.h deleted file mode 100644 index 807a09f43cad..000000000000 --- a/include/drm/tinydrm/ili9341.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ILI9341 LCD controller - * - * Copyright 2016 Noralf Trønnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __LINUX_ILI9341_H -#define __LINUX_ILI9341_H - -#define ILI9341_FRMCTR1 0xb1 -#define ILI9341_FRMCTR2 0xb2 -#define ILI9341_FRMCTR3 0xb3 -#define ILI9341_INVTR 0xb4 -#define ILI9341_PRCTR 0xb5 -#define ILI9341_DISCTRL 0xb6 -#define ILI9341_ETMOD 0xb7 - -#define ILI9341_PWCTRL1 0xc0 -#define ILI9341_PWCTRL2 0xc1 -#define ILI9341_VMCTRL1 0xc5 -#define ILI9341_VMCTRL2 0xc7 -#define ILI9341_PWCTRLA 0xcb -#define ILI9341_PWCTRLB 0xcf - -#define ILI9341_RDID1 0xda -#define ILI9341_RDID2 0xdb -#define ILI9341_RDID3 0xdc -#define ILI9341_RDID4 0xd3 - -#define ILI9341_PGAMCTRL 0xe0 -#define ILI9341_NGAMCTRL 0xe1 -#define ILI9341_DGAMCTRL1 0xe2 -#define ILI9341_DGAMCTRL2 0xe3 -#define ILI9341_DTCTRLA 0xe8 -#define ILI9341_DTCTRLB 0xea -#define ILI9341_PWRSEQ 0xed - -#define ILI9341_EN3GAM 0xf2 -#define ILI9341_IFCTRL 0xf6 -#define ILI9341_PUMPCTRL 0xf7 - -#define ILI9341_MADCTL_MH BIT(2) -#define ILI9341_MADCTL_BGR BIT(3) -#define ILI9341_MADCTL_ML BIT(4) -#define ILI9341_MADCTL_MV BIT(5) -#define ILI9341_MADCTL_MX BIT(6) -#define ILI9341_MADCTL_MY BIT(7) - -#endif /* __LINUX_ILI9341_H */ diff --git a/include/drm/tinydrm/mipi-dbi.h b/include/drm/tinydrm/mipi-dbi.h index 5d0e82b36eaf..44e824af2ef6 100644 --- a/include/drm/tinydrm/mipi-dbi.h +++ b/include/drm/tinydrm/mipi-dbi.h @@ -67,11 +67,12 @@ int mipi_dbi_init(struct device *dev, struct mipi_dbi *mipi, const struct drm_simple_display_pipe_funcs *pipe_funcs, struct drm_driver *driver, const struct drm_display_mode *mode, unsigned int rotation); -void mipi_dbi_pipe_enable(struct drm_simple_display_pipe *pipe, - struct drm_crtc_state *crtc_state); +void mipi_dbi_enable_flush(struct mipi_dbi *mipi); void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe); void mipi_dbi_hw_reset(struct mipi_dbi *mipi); bool mipi_dbi_display_is_on(struct mipi_dbi *mipi); +int mipi_dbi_poweron_reset(struct mipi_dbi *mipi); +int mipi_dbi_poweron_conditional_reset(struct mipi_dbi *mipi); u32 mipi_dbi_spi_cmd_max_speed(struct spi_device *spi, size_t len); int mipi_dbi_command_read(struct mipi_dbi *mipi, u8 cmd, u8 *val); diff --git a/include/drm/tinydrm/tinydrm-helpers.h b/include/drm/tinydrm/tinydrm-helpers.h index d554ded60ee9..0a4ddbc04c60 100644 --- a/include/drm/tinydrm/tinydrm-helpers.h +++ b/include/drm/tinydrm/tinydrm-helpers.h @@ -46,10 +46,6 @@ void tinydrm_xrgb8888_to_rgb565(u16 *dst, void *vaddr, void tinydrm_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb, struct drm_clip_rect *clip); -struct backlight_device *tinydrm_of_find_backlight(struct device *dev); -int tinydrm_enable_backlight(struct backlight_device *backlight); -int tinydrm_disable_backlight(struct backlight_device *backlight); - size_t tinydrm_spi_max_transfer_size(struct spi_device *spi, size_t max_len); bool tinydrm_spi_bpw_supported(struct spi_device *spi, u8 bpw); int tinydrm_spi_transfer(struct spi_device *spi, u32 speed_hz, diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 2cd025c2abe7..c67977aa1a0e 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -41,6 +41,8 @@ #include <linux/bitmap.h> #include <linux/reservation.h> +struct ttm_bo_global; + struct ttm_bo_device; struct drm_mm_node; @@ -169,7 +171,6 @@ struct ttm_buffer_object { * Members constant at init. */ - struct ttm_bo_global *glob; struct ttm_bo_device *bdev; enum ttm_bo_type type; void (*destroy) (struct ttm_buffer_object *); @@ -263,8 +264,8 @@ struct ttm_bo_kmap_obj { * * @interruptible: Sleep interruptible if sleeping. * @no_wait_gpu: Return immediately if the GPU is busy. - * @allow_reserved_eviction: Allow eviction of reserved BOs. * @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. @@ -272,11 +273,16 @@ struct ttm_bo_kmap_obj { struct ttm_operation_ctx { bool interruptible; bool no_wait_gpu; - bool allow_reserved_eviction; struct reservation_object *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_reference - reference a struct ttm_buffer_object * @@ -461,11 +467,6 @@ size_t ttm_bo_dma_acc_size(struct ttm_bo_device *bdev, * @flags: Initial placement flags. * @page_alignment: Data alignment in pages. * @ctx: TTM operation context for memory allocation. - * @persistent_swap_storage: Usually the swap storage is deleted for buffers - * pinned in physical memory. If this behaviour is not desired, this member - * holds a pointer to a persistent shmem object. Typically, this would - * point to the shmem object backing a GEM object if TTM is used to back a - * GEM user interface. * @acc_size: Accounted size for this object. * @resv: Pointer to a reservation_object, or NULL to let ttm allocate one. * @destroy: Destroy function. Use NULL for kfree(). @@ -498,7 +499,6 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, struct ttm_placement *placement, uint32_t page_alignment, struct ttm_operation_ctx *ctx, - struct file *persistent_swap_storage, size_t acc_size, struct sg_table *sg, struct reservation_object *resv, @@ -515,7 +515,6 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, * @page_alignment: Data alignment in pages. * @interruptible: If needing to sleep to wait for GPU resources, * sleep interruptible. - * @persistent_swap_storage: Usually the swap storage is deleted for buffers * pinned in physical memory. If this behaviour is not desired, this member * holds a pointer to a persistent shmem object. Typically, this would * point to the shmem object backing a GEM object if TTM is used to back a @@ -545,8 +544,7 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, int ttm_bo_init(struct ttm_bo_device *bdev, struct ttm_buffer_object *bo, unsigned long size, enum ttm_bo_type type, struct ttm_placement *placement, - uint32_t page_alignment, bool interrubtible, - struct file *persistent_swap_storage, size_t acc_size, + uint32_t page_alignment, bool interrubtible, size_t acc_size, struct sg_table *sg, struct reservation_object *resv, void (*destroy) (struct ttm_buffer_object *)); @@ -560,11 +558,6 @@ int ttm_bo_init(struct ttm_bo_device *bdev, struct ttm_buffer_object *bo, * @page_alignment: Data alignment in pages. * @interruptible: If needing to sleep while waiting for GPU resources, * sleep interruptible. - * @persistent_swap_storage: Usually the swap storage is deleted for buffers - * pinned in physical memory. If this behaviour is not desired, this member - * holds a pointer to a persistent shmem object. Typically, this would - * point to the shmem object backing a GEM object if TTM is used to back a - * GEM user interface. * @p_bo: On successful completion *p_bo points to the created object. * * This function allocates a ttm_buffer_object, and then calls ttm_bo_init @@ -577,7 +570,6 @@ int ttm_bo_init(struct ttm_bo_device *bdev, struct ttm_buffer_object *bo, int ttm_bo_create(struct ttm_bo_device *bdev, unsigned long size, enum ttm_bo_type type, struct ttm_placement *placement, uint32_t page_alignment, bool interruptible, - struct file *persistent_swap_storage, struct ttm_buffer_object **p_bo); /** @@ -717,6 +709,10 @@ int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo); int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma, struct ttm_bo_device *bdev); +void *ttm_kmap_atomic_prot(struct page *page, pgprot_t prot); + +void ttm_kunmap_atomic_prot(void *addr, pgprot_t prot); + /** * ttm_bo_io * diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 94064b126e8e..3234cc322e70 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -42,113 +42,10 @@ #include "ttm_memory.h" #include "ttm_module.h" #include "ttm_placement.h" +#include "ttm_tt.h" #define TTM_MAX_BO_PRIORITY 4U -struct ttm_backend_func { - /** - * struct ttm_backend_func member bind - * - * @ttm: Pointer to a struct ttm_tt. - * @bo_mem: Pointer to a struct ttm_mem_reg describing the - * memory type and location for binding. - * - * Bind the backend pages into the aperture in the location - * indicated by @bo_mem. This function should be able to handle - * differences between aperture and system page sizes. - */ - int (*bind) (struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem); - - /** - * struct ttm_backend_func member unbind - * - * @ttm: Pointer to a struct ttm_tt. - * - * Unbind previously bound backend pages. This function should be - * able to handle differences between aperture and system page sizes. - */ - int (*unbind) (struct ttm_tt *ttm); - - /** - * struct ttm_backend_func member destroy - * - * @ttm: Pointer to a struct ttm_tt. - * - * Destroy the backend. This will be call back from ttm_tt_destroy so - * don't call ttm_tt_destroy from the callback or infinite loop. - */ - void (*destroy) (struct ttm_tt *ttm); -}; - -#define TTM_PAGE_FLAG_WRITE (1 << 3) -#define TTM_PAGE_FLAG_SWAPPED (1 << 4) -#define TTM_PAGE_FLAG_PERSISTENT_SWAP (1 << 5) -#define TTM_PAGE_FLAG_ZERO_ALLOC (1 << 6) -#define TTM_PAGE_FLAG_DMA32 (1 << 7) -#define TTM_PAGE_FLAG_SG (1 << 8) - -enum ttm_caching_state { - tt_uncached, - tt_wc, - tt_cached -}; - -/** - * struct ttm_tt - * - * @bdev: Pointer to a struct ttm_bo_device. - * @func: Pointer to a struct ttm_backend_func that describes - * the backend methods. - * @dummy_read_page: Page to map where the ttm_tt page array contains a NULL - * pointer. - * @pages: Array of pages backing the data. - * @num_pages: Number of pages in the page array. - * @bdev: Pointer to the current struct ttm_bo_device. - * @be: Pointer to the ttm backend. - * @swap_storage: Pointer to shmem struct file for swap storage. - * @caching_state: The current caching state of the pages. - * @state: The current binding state of the pages. - * - * This is a structure holding the pages, caching- and aperture binding - * status for a buffer object that isn't backed by fixed (VRAM / AGP) - * memory. - */ - -struct ttm_tt { - struct ttm_bo_device *bdev; - struct ttm_backend_func *func; - struct page *dummy_read_page; - struct page **pages; - uint32_t page_flags; - unsigned long num_pages; - struct sg_table *sg; /* for SG objects via dma-buf */ - struct ttm_bo_global *glob; - struct file *swap_storage; - enum ttm_caching_state caching_state; - enum { - tt_bound, - tt_unbound, - tt_unpopulated, - } state; -}; - -/** - * struct ttm_dma_tt - * - * @ttm: Base ttm_tt struct. - * @dma_address: The DMA (bus) addresses of the pages - * @pages_list: used by some page allocation backend - * - * This is a structure holding the pages, caching- and aperture binding - * status for a buffer object that isn't backed by fixed (VRAM / AGP) - * memory. - */ -struct ttm_dma_tt { - struct ttm_tt ttm; - dma_addr_t *dma_address; - struct list_head pages_list; -}; - #define TTM_MEMTYPE_FLAG_FIXED (1 << 0) /* Fixed (on-card) PCI memory */ #define TTM_MEMTYPE_FLAG_MAPPABLE (1 << 1) /* Memory mappable */ #define TTM_MEMTYPE_FLAG_CMA (1 << 3) /* Can't map aperture */ @@ -328,20 +225,16 @@ struct ttm_bo_driver { /** * ttm_tt_create * - * @bdev: pointer to a struct ttm_bo_device: - * @size: Size of the data needed backing. + * @bo: The buffer object to create the ttm for. * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags. - * @dummy_read_page: See struct ttm_bo_device. * * Create a struct ttm_tt to back data with system memory pages. * No pages are actually allocated. * Returns: * NULL: Out of memory. */ - struct ttm_tt *(*ttm_tt_create)(struct ttm_bo_device *bdev, - unsigned long size, - uint32_t page_flags, - struct page *dummy_read_page); + struct ttm_tt *(*ttm_tt_create)(struct ttm_buffer_object *bo, + uint32_t page_flags); /** * ttm_tt_populate @@ -556,6 +449,7 @@ 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 * */ @@ -592,6 +486,8 @@ struct ttm_bo_device { struct delayed_work wq; bool need_dma32; + + bool no_retry; }; /** @@ -611,100 +507,6 @@ ttm_flag_masked(uint32_t *old, uint32_t new, uint32_t mask) return *old; } -/** - * ttm_tt_init - * - * @ttm: The struct ttm_tt. - * @bdev: pointer to a struct ttm_bo_device: - * @size: Size of the data needed backing. - * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags. - * @dummy_read_page: See struct ttm_bo_device. - * - * Create a struct ttm_tt to back data with system memory pages. - * No pages are actually allocated. - * Returns: - * NULL: Out of memory. - */ -int ttm_tt_init(struct ttm_tt *ttm, struct ttm_bo_device *bdev, - unsigned long size, uint32_t page_flags, - struct page *dummy_read_page); -int ttm_dma_tt_init(struct ttm_dma_tt *ttm_dma, struct ttm_bo_device *bdev, - unsigned long size, uint32_t page_flags, - struct page *dummy_read_page); - -/** - * ttm_tt_fini - * - * @ttm: the ttm_tt structure. - * - * Free memory of ttm_tt structure - */ -void ttm_tt_fini(struct ttm_tt *ttm); -void ttm_dma_tt_fini(struct ttm_dma_tt *ttm_dma); - -/** - * ttm_ttm_bind: - * - * @ttm: The struct ttm_tt containing backing pages. - * @bo_mem: The struct ttm_mem_reg identifying the binding location. - * - * Bind the pages of @ttm to an aperture location identified by @bo_mem - */ -int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem, - struct ttm_operation_ctx *ctx); - -/** - * ttm_ttm_destroy: - * - * @ttm: The struct ttm_tt. - * - * Unbind, unpopulate and destroy common struct ttm_tt. - */ -void ttm_tt_destroy(struct ttm_tt *ttm); - -/** - * ttm_ttm_unbind: - * - * @ttm: The struct ttm_tt. - * - * Unbind a struct ttm_tt. - */ -void ttm_tt_unbind(struct ttm_tt *ttm); - -/** - * ttm_tt_swapin: - * - * @ttm: The struct ttm_tt. - * - * Swap in a previously swap out ttm_tt. - */ -int ttm_tt_swapin(struct ttm_tt *ttm); - -/** - * ttm_tt_set_placement_caching: - * - * @ttm A struct ttm_tt the backing pages of which will change caching policy. - * @placement: Flag indicating the desired caching policy. - * - * This function will change caching policy of any default kernel mappings of - * the pages backing @ttm. If changing from cached to uncached or - * write-combined, - * all CPU caches will first be flushed to make sure the data of the pages - * hit RAM. This function may be very costly as it involves global TLB - * and cache flushes and potential page splitting / combining. - */ -int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement); -int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage); - -/** - * ttm_tt_unpopulate - free pages from a ttm - * - * @ttm: Pointer to the ttm_tt structure - * - * Calls the driver method to free all pages from a ttm - */ -void ttm_tt_unpopulate(struct ttm_tt *ttm); - /* * ttm_bo.c */ @@ -943,9 +745,9 @@ static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, static inline void ttm_bo_unreserve(struct ttm_buffer_object *bo) { if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) { - spin_lock(&bo->glob->lru_lock); + spin_lock(&bo->bdev->glob->lru_lock); ttm_bo_add_to_lru(bo); - spin_unlock(&bo->glob->lru_lock); + spin_unlock(&bo->bdev->glob->lru_lock); } reservation_object_unlock(bo->resv); } @@ -1046,6 +848,15 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem); /** + * ttm_bo_pipeline_gutting. + * + * @bo: A pointer to a struct ttm_buffer_object. + * + * Pipelined gutting a BO of it's backing store. + */ +int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo); + +/** * ttm_io_prot * * @c_state: Caching state. @@ -1058,29 +869,4 @@ pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp); extern const struct ttm_mem_type_manager_func ttm_bo_manager_func; -#if IS_ENABLED(CONFIG_AGP) -#include <linux/agp_backend.h> - -/** - * ttm_agp_tt_create - * - * @bdev: Pointer to a struct ttm_bo_device. - * @bridge: The agp bridge this device is sitting on. - * @size: Size of the data needed backing. - * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags. - * @dummy_read_page: See struct ttm_bo_device. - * - * - * Create a TTM backend that uses the indicated AGP bridge as an aperture - * for TT memory. This function uses the linux agpgart interface to - * bind and unbind memory backing a ttm_tt. - */ -struct ttm_tt *ttm_agp_tt_create(struct ttm_bo_device *bdev, - struct agp_bridge_data *bridge, - unsigned long size, uint32_t page_flags, - struct page *dummy_read_page); -int ttm_agp_tt_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx); -void ttm_agp_tt_unpopulate(struct ttm_tt *ttm); -#endif - #endif diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h index 8936285b6543..737b5fed8003 100644 --- a/include/drm/ttm/ttm_memory.h +++ b/include/drm/ttm/ttm_memory.h @@ -49,6 +49,8 @@ * @work: The workqueue callback for the shrink queue. * @lock: Lock to protect the @shrink - and the memory accounting members, * that is, essentially the whole structure with some exceptions. + * @lower_mem_limit: include lower limit of swap space and lower limit of + * system memory. * @zones: Array of pointers to accounting zones. * @num_zones: Number of populated entries in the @zones array. * @zone_kernel: Pointer to the kernel zone. @@ -67,6 +69,7 @@ struct ttm_mem_global { struct workqueue_struct *swap_queue; struct work_struct work; spinlock_t lock; + uint64_t lower_mem_limit; struct ttm_mem_zone *zones[TTM_MEM_MAX_ZONES]; unsigned int num_zones; struct ttm_mem_zone *zone_kernel; @@ -90,4 +93,6 @@ extern void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page, uint64_t size); extern size_t ttm_round_pot(size_t size); extern uint64_t ttm_get_kernel_zone_memory_size(struct ttm_mem_global *glob); +extern bool ttm_check_under_lowerlimit(struct ttm_mem_global *glob, + uint64_t num_pages, struct ttm_operation_ctx *ctx); #endif diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h new file mode 100644 index 000000000000..c0e928abf592 --- /dev/null +++ b/include/drm/ttm/ttm_tt.h @@ -0,0 +1,272 @@ +/************************************************************************** + * + * Copyright (c) 2006-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. + * + **************************************************************************/ +#ifndef _TTM_TT_H_ +#define _TTM_TT_H_ + +#include <linux/types.h> + +struct ttm_tt; +struct ttm_mem_reg; +struct ttm_buffer_object; +struct ttm_operation_ctx; + +#define TTM_PAGE_FLAG_WRITE (1 << 3) +#define TTM_PAGE_FLAG_SWAPPED (1 << 4) +#define TTM_PAGE_FLAG_PERSISTENT_SWAP (1 << 5) +#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) + +enum ttm_caching_state { + tt_uncached, + tt_wc, + tt_cached +}; + +struct ttm_backend_func { + /** + * struct ttm_backend_func member bind + * + * @ttm: Pointer to a struct ttm_tt. + * @bo_mem: Pointer to a struct ttm_mem_reg describing the + * memory type and location for binding. + * + * Bind the backend pages into the aperture in the location + * indicated by @bo_mem. This function should be able to handle + * differences between aperture and system page sizes. + */ + int (*bind) (struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem); + + /** + * struct ttm_backend_func member unbind + * + * @ttm: Pointer to a struct ttm_tt. + * + * Unbind previously bound backend pages. This function should be + * able to handle differences between aperture and system page sizes. + */ + int (*unbind) (struct ttm_tt *ttm); + + /** + * struct ttm_backend_func member destroy + * + * @ttm: Pointer to a struct ttm_tt. + * + * Destroy the backend. This will be call back from ttm_tt_destroy so + * don't call ttm_tt_destroy from the callback or infinite loop. + */ + void (*destroy) (struct ttm_tt *ttm); +}; + +/** + * struct ttm_tt + * + * @bdev: Pointer to a struct ttm_bo_device. + * @func: Pointer to a struct ttm_backend_func that describes + * the backend methods. + * pointer. + * @pages: Array of pages backing the data. + * @num_pages: Number of pages in the page array. + * @bdev: Pointer to the current struct ttm_bo_device. + * @be: Pointer to the ttm backend. + * @swap_storage: Pointer to shmem struct file for swap storage. + * @caching_state: The current caching state of the pages. + * @state: The current binding state of the pages. + * + * This is a structure holding the pages, caching- and aperture binding + * status for a buffer object that isn't backed by fixed (VRAM / AGP) + * memory. + */ +struct ttm_tt { + struct ttm_bo_device *bdev; + struct ttm_backend_func *func; + struct page **pages; + uint32_t page_flags; + unsigned long num_pages; + struct sg_table *sg; /* for SG objects via dma-buf */ + struct file *swap_storage; + enum ttm_caching_state caching_state; + enum { + tt_bound, + tt_unbound, + tt_unpopulated, + } state; +}; + +/** + * struct ttm_dma_tt + * + * @ttm: Base ttm_tt struct. + * @dma_address: The DMA (bus) addresses of the pages + * @pages_list: used by some page allocation backend + * + * This is a structure holding the pages, caching- and aperture binding + * status for a buffer object that isn't backed by fixed (VRAM / AGP) + * memory. + */ +struct ttm_dma_tt { + struct ttm_tt ttm; + dma_addr_t *dma_address; + struct list_head pages_list; +}; + +/** + * ttm_tt_create + * + * @bo: pointer to a struct ttm_buffer_object + * @zero_alloc: true if allocated pages needs to be zeroed + * + * Make sure we have a TTM structure allocated for the given BO. + * No pages are actually allocated. + */ +int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc); + +/** + * ttm_tt_init + * + * @ttm: The struct ttm_tt. + * @bo: The buffer object we create the ttm for. + * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags. + * + * Create a struct ttm_tt to back data with system memory pages. + * No pages are actually allocated. + * Returns: + * NULL: Out of memory. + */ +int ttm_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo, + uint32_t page_flags); +int ttm_dma_tt_init(struct ttm_dma_tt *ttm_dma, struct ttm_buffer_object *bo, + uint32_t page_flags); +int ttm_sg_tt_init(struct ttm_dma_tt *ttm_dma, struct ttm_buffer_object *bo, + uint32_t page_flags); + +/** + * ttm_tt_fini + * + * @ttm: the ttm_tt structure. + * + * Free memory of ttm_tt structure + */ +void ttm_tt_fini(struct ttm_tt *ttm); +void ttm_dma_tt_fini(struct ttm_dma_tt *ttm_dma); + +/** + * ttm_ttm_bind: + * + * @ttm: The struct ttm_tt containing backing pages. + * @bo_mem: The struct ttm_mem_reg identifying the binding location. + * + * Bind the pages of @ttm to an aperture location identified by @bo_mem + */ +int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem, + struct ttm_operation_ctx *ctx); + +/** + * ttm_ttm_destroy: + * + * @ttm: The struct ttm_tt. + * + * Unbind, unpopulate and destroy common struct ttm_tt. + */ +void ttm_tt_destroy(struct ttm_tt *ttm); + +/** + * ttm_ttm_unbind: + * + * @ttm: The struct ttm_tt. + * + * Unbind a struct ttm_tt. + */ +void ttm_tt_unbind(struct ttm_tt *ttm); + +/** + * ttm_tt_swapin: + * + * @ttm: The struct ttm_tt. + * + * Swap in a previously swap out ttm_tt. + */ +int ttm_tt_swapin(struct ttm_tt *ttm); + +/** + * ttm_tt_set_placement_caching: + * + * @ttm A struct ttm_tt the backing pages of which will change caching policy. + * @placement: Flag indicating the desired caching policy. + * + * This function will change caching policy of any default kernel mappings of + * the pages backing @ttm. If changing from cached to uncached or + * write-combined, + * all CPU caches will first be flushed to make sure the data of the pages + * hit RAM. This function may be very costly as it involves global TLB + * and cache flushes and potential page splitting / combining. + */ +int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement); +int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage); + +/** + * ttm_tt_populate - allocate pages for a ttm + * + * @ttm: Pointer to the ttm_tt structure + * + * Calls the driver method to allocate pages for a ttm + */ +int ttm_tt_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx); + +/** + * ttm_tt_unpopulate - free pages from a ttm + * + * @ttm: Pointer to the ttm_tt structure + * + * Calls the driver method to free all pages from a ttm + */ +void ttm_tt_unpopulate(struct ttm_tt *ttm); + +#if IS_ENABLED(CONFIG_AGP) +#include <linux/agp_backend.h> + +/** + * ttm_agp_tt_create + * + * @bo: Buffer object we allocate the ttm for. + * @bridge: The agp bridge this device is sitting on. + * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags. + * + * + * Create a TTM backend that uses the indicated AGP bridge as an aperture + * for TT memory. This function uses the linux agpgart interface to + * bind and unbind memory backing a ttm_tt. + */ +struct ttm_tt *ttm_agp_tt_create(struct ttm_buffer_object *bo, + struct agp_bridge_data *bridge, + uint32_t page_flags); +int ttm_agp_tt_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx); +void ttm_agp_tt_unpopulate(struct ttm_tt *ttm); +#endif + +#endif |