Bläddra i källkod

Merge "disp: msm: sde: report AVR_STATUS in vsync_event sysfs node"

qctecmdr 4 år sedan
förälder
incheckning
a8bdcf2e77

+ 17 - 2
msm/sde/sde_crtc.c

@@ -388,6 +388,8 @@ static ssize_t vsync_event_show(struct device *device,
 {
 	struct drm_crtc *crtc;
 	struct sde_crtc *sde_crtc;
+	struct drm_encoder *encoder;
+	int avr_status = -EPIPE;
 
 	if (!device || !buf) {
 		SDE_ERROR("invalid input param(s)\n");
@@ -396,8 +398,21 @@ static ssize_t vsync_event_show(struct device *device,
 
 	crtc = dev_get_drvdata(device);
 	sde_crtc = to_sde_crtc(crtc);
-	return scnprintf(buf, PAGE_SIZE, "VSYNC=%llu\n",
-			ktime_to_ns(sde_crtc->vblank_last_cb_time));
+
+	mutex_lock(&sde_crtc->crtc_lock);
+	if (sde_crtc->enabled) {
+		drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) {
+			if (sde_encoder_in_clone_mode(encoder))
+				continue;
+
+			avr_status = sde_encoder_get_avr_status(encoder);
+			break;
+		}
+	}
+	mutex_unlock(&sde_crtc->crtc_lock);
+
+	return scnprintf(buf, PAGE_SIZE, "VSYNC=%llu\nAVR_STATUS=%d\n",
+			ktime_to_ns(sde_crtc->vblank_last_cb_time), avr_status);
 }
 
 static ssize_t retire_frame_event_show(struct device *device,

+ 21 - 0
msm/sde/sde_encoder.c

@@ -4378,6 +4378,27 @@ void sde_encoder_get_transfer_time(struct drm_encoder *drm_enc,
 	*transfer_time_us = info->mdp_transfer_time_us;
 }
 
+int sde_encoder_get_avr_status(struct drm_encoder *drm_enc)
+{
+	struct sde_encoder_virt *sde_enc;
+	struct sde_encoder_phys *master;
+	bool is_vid_mode;
+
+	if (!drm_enc)
+		return -EINVAL;
+
+	sde_enc = to_sde_encoder_virt(drm_enc);
+	master = sde_enc->cur_master;
+	is_vid_mode = sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CAP_VID_MODE);
+	if (!master || !is_vid_mode || !sde_connector_get_qsync_mode(master->connector))
+		return -ENODATA;
+
+	if (!master->hw_intf->ops.get_avr_status)
+		return -EOPNOTSUPP;
+
+	return master->hw_intf->ops.get_avr_status(master->hw_intf);
+}
+
 int sde_encoder_helper_reset_mixers(struct sde_encoder_phys *phys_enc,
 		struct drm_framebuffer *fb)
 {

+ 6 - 0
msm/sde/sde_encoder.h

@@ -392,6 +392,12 @@ enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder);
  */
 u32 sde_encoder_get_frame_count(struct drm_encoder *encoder);
 
+/**
+ * sde_encoder_get_avr_status - get combined avr_status from all intfs for given virt encoder
+ * @drm_enc: Pointer to drm encoder structure
+ */
+int sde_encoder_get_avr_status(struct drm_encoder *drm_enc);
+
 /*
  * sde_encoder_get_vblank_timestamp - get the last vsync timestamp
  * @encoder: Pointer to drm encoder object

+ 1 - 0
msm/sde/sde_hw_catalog.c

@@ -2431,6 +2431,7 @@ static int sde_intf_parse_dt(struct device_node *np,
 			set_bit(SDE_INTF_WD_TIMER, &intf->features);
 			set_bit(SDE_INTF_RESET_COUNTER, &intf->features);
 			set_bit(SDE_INTF_VSYNC_TIMESTAMP, &intf->features);
+			set_bit(SDE_INTF_AVR_STATUS, &intf->features);
 		}
 	}
 

+ 2 - 0
msm/sde/sde_hw_catalog.h

@@ -508,6 +508,7 @@ enum {
  * @SDE_INTF_STATUS             INTF block has INTF_STATUS register
  * @SDE_INTF_RESET_COUNTER      INTF block has frame/line counter reset support
  * @SDE_INTF_VSYNC_TIMESTAMP    INTF block has vsync timestamp logged
+ * @SDE_INTF_AVR_STATUS         INTF block has AVR_STATUS field in AVR_CONTROL register
  * @SDE_INTF_MAX
  */
 enum {
@@ -518,6 +519,7 @@ enum {
 	SDE_INTF_STATUS,
 	SDE_INTF_RESET_COUNTER,
 	SDE_INTF_VSYNC_TIMESTAMP,
+	SDE_INTF_AVR_STATUS,
 	SDE_INTF_MAX
 };
 

+ 17 - 0
msm/sde/sde_hw_intf.c

@@ -184,6 +184,20 @@ static void sde_hw_intf_avr_ctrl(struct sde_hw_intf *ctx,
 	SDE_REG_WRITE(c, INTF_AVR_MODE, avr_mode);
 }
 
+static u32 sde_hw_intf_get_avr_status(struct sde_hw_intf *ctx)
+{
+	struct sde_hw_blk_reg_map *c;
+	u32 avr_ctrl;
+
+	if (!ctx)
+		return false;
+
+	c = &ctx->hw;
+	avr_ctrl = SDE_REG_READ(c, INTF_AVR_CONTROL);
+
+	return avr_ctrl >> 31;
+}
+
 static inline void _check_and_set_comp_bit(struct sde_hw_intf *ctx,
 		bool dsc_4hs_merge, bool compression_en, u32 *intf_cfg2)
 {
@@ -868,6 +882,9 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
 	if (cap & BIT(SDE_INTF_WD_TIMER))
 		ops->setup_vsync_source = sde_hw_intf_setup_vsync_source;
 
+	if (cap & BIT(SDE_INTF_AVR_STATUS))
+		ops->get_avr_status = sde_hw_intf_get_avr_status;
+
 	if (cap & BIT(SDE_INTF_TE)) {
 		ops->setup_tearcheck = sde_hw_intf_setup_te_config;
 		ops->enable_tearcheck = sde_hw_intf_enable_te;

+ 7 - 0
msm/sde/sde_hw_intf.h

@@ -194,6 +194,13 @@ struct sde_hw_intf_ops {
 	void (*avr_ctrl)(struct sde_hw_intf *intf,
 			const struct intf_avr_params *avr_params);
 
+	/**
+	 * Indicates the AVR armed status
+	 *
+	 * @return: false if a trigger is pending, else true while AVR is enabled
+	 */
+	u32 (*get_avr_status)(struct sde_hw_intf *intf);
+
 	/**
 	 * Enable/disable 64 bit compressed data input to interface block
 	 */