Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2559da9 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: Implement work queue for crtc events" into msm-4.9

parents f1630338 b6b401f8
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ static void sde_cp_update_list(struct sde_cp_node *prop_node,
static int sde_cp_ad_validate_prop(struct sde_cp_node *prop_node,
		struct sde_crtc *crtc);

static void sde_cp_notify_ad_event(struct drm_crtc *crtc_drm, void *arg);

#define setup_dspp_prop_install_funcs(func) \
do { \
	func[SDE_DSPP_PCC] = dspp_pcc_install_property; \
@@ -1323,15 +1325,25 @@ static int sde_cp_ad_validate_prop(struct sde_cp_node *prop_node,
static void sde_cp_ad_interrupt_cb(void *arg, int irq_idx)
{
	struct sde_crtc *crtc = arg;
	struct drm_event event;

	sde_crtc_event_queue(&crtc->base, sde_cp_notify_ad_event, NULL);
}

static void sde_cp_notify_ad_event(struct drm_crtc *crtc_drm, void *arg)
{
	uint32_t bl = 0;
	u32 num_mixers = crtc->num_mixers;
	struct sde_hw_mixer *hw_lm = NULL;
	struct sde_hw_dspp *hw_dspp = NULL;
	u32 num_mixers;
	struct sde_crtc *crtc;
	struct drm_event event;
	int i;

	event.type = DRM_EVENT_AD_BACKLIGHT;
	event.length = sizeof(bl);
	crtc = to_sde_crtc(crtc_drm);
	num_mixers = crtc->num_mixers;
	if (!num_mixers)
		return;

	for (i = 0; i < num_mixers; i++) {
		hw_lm = crtc->mixers[i].hw_lm;
		hw_dspp = crtc->mixers[i].hw_dspp;
@@ -1343,6 +1355,8 @@ static void sde_cp_ad_interrupt_cb(void *arg, int irq_idx)
		return;

	hw_dspp->ops.ad_read_intr_resp(hw_dspp, AD4_BACKLIGHT, &bl);
	event.length = sizeof(u32);
	event.type = DRM_EVENT_AD_BACKLIGHT;
	msm_send_crtc_notification(&crtc->base, &event, (u8 *)&bl);
}

+32 −15
Original line number Diff line number Diff line
@@ -45,6 +45,16 @@ struct sde_crtc_irq_info {
	struct list_head list;
};

struct sde_crtc_custom_events {
	u32 event;
	int (*func)(struct drm_crtc *crtc, bool en,
			struct sde_irq_callback *irq);
};

static struct sde_crtc_custom_events custom_events[] = {
	{DRM_EVENT_AD_BACKLIGHT, sde_cp_ad_interrupt}
};

/* default input fence timeout, in ms */
#define SDE_CRTC_INPUT_FENCE_TIMEOUT    2000

@@ -2322,21 +2332,22 @@ static void _sde_crtc_event_cb(struct kthread_work *work)
	}

	event = container_of(work, struct sde_crtc_event, kt_work);
	if (event->cb_func)
		event->cb_func(event->usr);

	/* set sde_crtc to NULL for static work structures */
	sde_crtc = event->sde_crtc;
	if (!sde_crtc)
		return;

	if (event->cb_func)
		event->cb_func(&sde_crtc->base, event->usr);

	spin_lock_irqsave(&sde_crtc->event_lock, irq_flags);
	list_add_tail(&event->list, &sde_crtc->event_free_list);
	spin_unlock_irqrestore(&sde_crtc->event_lock, irq_flags);
}

int sde_crtc_event_queue(struct drm_crtc *crtc,
		void (*func)(void *usr), void *usr)
		void (*func)(struct drm_crtc *crtc, void *usr), void *usr)
{
	unsigned long irq_flags;
	struct sde_crtc *sde_crtc;
@@ -2346,6 +2357,8 @@ int sde_crtc_event_queue(struct drm_crtc *crtc,
		return -EINVAL;
	sde_crtc = to_sde_crtc(crtc);

	if (!sde_crtc->event_thread)
		return -EINVAL;
	/*
	 * Obtain an event struct from the private cache. This event
	 * queue may be called from ISR contexts, so use a private
@@ -2482,7 +2495,7 @@ static int _sde_crtc_event_enable(struct sde_kms *kms,
	struct msm_drm_private *priv;
	unsigned long flags;
	bool found = false;
	int ret;
	int ret, i = 0;

	crtc = to_sde_crtc(crtc_drm);
	spin_lock_irqsave(&crtc->spin_lock, flags);
@@ -2498,19 +2511,23 @@ static int _sde_crtc_event_enable(struct sde_kms *kms,
	if (found)
		return 0;

	node = NULL;
	for (i = 0; i < ARRAY_SIZE(custom_events); i++) {
		if (custom_events[i].event == event &&
			custom_events[i].func) {
			node = kzalloc(sizeof(*node), GFP_KERNEL);
			if (!node)
				return -ENOMEM;
			node->event = event;
			INIT_LIST_HEAD(&node->list);

	switch (event) {
	case DRM_EVENT_AD_BACKLIGHT:
		node->func = sde_cp_ad_interrupt;
			node->func = custom_events[i].func;
			node->event = event;
			break;
	default:
		}
	}

	if (!node) {
		SDE_ERROR("unsupported event %x\n", event);
		kfree(node);
		return -EINVAL;
	}

+2 −2
Original line number Diff line number Diff line
@@ -92,7 +92,7 @@ struct sde_crtc_event {
	struct kthread_work kt_work;
	void *sde_crtc;

	void (*cb_func)(void *usr);
	void (*cb_func)(struct drm_crtc *crtc, void *usr);
	void *usr;
};

@@ -368,6 +368,6 @@ static inline bool sde_crtc_is_enabled(struct drm_crtc *crtc)
 * Returns: Zero on success
 */
int sde_crtc_event_queue(struct drm_crtc *crtc,
		void (*func)(void *usr), void *usr);
		void (*func)(struct drm_crtc *crtc, void *usr), void *usr);

#endif /* _SDE_CRTC_H_ */