示例#1
0
int rcar_du_group_set_routing(struct rcar_du_group *rgrp)
{
	struct rcar_du_crtc *crtc0 = &rgrp->dev->crtcs[rgrp->index * 2];
	u32 dorcr = rcar_du_group_read(rgrp, DORCR);

	dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK);

	/* Set the DPAD1 pins sources. Select CRTC 0 if explicitly requested and
	 * CRTC 1 in all other cases to avoid cloning CRTC 0 to DPAD0 and DPAD1
	 * by default.
	 */
	if (crtc0->outputs & BIT(RCAR_DU_OUTPUT_DPAD1))
		dorcr |= DORCR_PG2D_DS1;
	else
		dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2;

	rcar_du_group_write(rgrp, DORCR, dorcr);

	return rcar_du_set_dpad0_routing(rgrp->dev);
}
示例#2
0
void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
{
	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
	struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
	unsigned int num_planes = 0;
	unsigned int prio = 0;
	unsigned int i;
	u32 dptsr = 0;
	u32 dspr = 0;

	for (i = 0; i < ARRAY_SIZE(rcrtc->group->planes.planes); ++i) {
		struct rcar_du_plane *plane = &rcrtc->group->planes.planes[i];
		unsigned int j;

		if (plane->crtc != &rcrtc->crtc || !plane->enabled)
			continue;

		/* Insert the plane in the sorted planes array. */
		for (j = num_planes++; j > 0; --j) {
			if (planes[j-1]->zpos <= plane->zpos)
				break;
			planes[j] = planes[j-1];
		}

		planes[j] = plane;
		prio += plane->format->planes * 4;
	}

	for (i = 0; i < num_planes; ++i) {
		struct rcar_du_plane *plane = planes[i];
		unsigned int index = plane->hwindex;

#ifdef CONFIG_DRM_RCAR_DESKTOP_TURN_OFF
		if (!plane->fb_plane) {
			prio -= 4;
			dspr |= (index + 1) << prio;
			dptsr |= DPTSR_PnDK(index) | DPTSR_PnTS(index);
		}
#else
		prio -= 4;
		dspr |= (index + 1) << prio;
		dptsr |= DPTSR_PnDK(index) | DPTSR_PnTS(index);
#endif

		if (plane->format->planes == 2) {
			index = (index + 1) % 8;

#ifdef CONFIG_DRM_RCAR_DESKTOP_TURN_OFF
			if (!plane->fb_plane) {
				prio -= 4;
				dspr |= (index + 1) << prio;
				dptsr |= DPTSR_PnDK(index) | DPTSR_PnTS(index);
			}
#else
			prio -= 4;
			dspr |= (index + 1) << prio;
			dptsr |= DPTSR_PnDK(index) | DPTSR_PnTS(index);
#endif
		}
	}

	/* Select display timing and dot clock generator 1 for planes associated
	 * with superposition controller 1.
	 */
	if (rcrtc->index % 2) {
		u32 value = rcar_du_group_read(rcrtc->group, DPTSR);

		/* The DPTSR register is updated when the display controller is
		 * stopped. We thus need to restart the DU. Once again, sorry
		 * for the flicker. One way to mitigate the issue would be to
		 * pre-associate planes with CRTCs (either with a fixed 4/4
		 * split, or through a module parameter). Flicker would then
		 * occur only if we need to break the pre-association.
		 */
		if (value != dptsr) {
			rcar_du_group_write(rcrtc->group, DPTSR, dptsr);
			rcar_du_group_restart(rcrtc->group);
		}
	}

	rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR,
			    dspr);
}
示例#3
0
static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
{
	rcar_du_group_write(rgrp, DSYSR,
		(rcar_du_group_read(rgrp, DSYSR) & ~(DSYSR_DRES | DSYSR_DEN)) |
		(start ? DSYSR_DEN : DSYSR_DRES));
}