/* * Copyright (C) 2013-2015 ARM Limited * Author: Liviu Dudau <Liviu.Dudau@arm.com> * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. * * Implementation of a CRTC class for the HDLCD driver.
*/
/* * The HDLCD controller is a dumb RGB streamer that gets connected to * a single HDMI transmitter or in the case of the ARM Models it gets * emulated by the software that does the actual rendering. *
*/
/* * Setup the HDLCD registers for decoding the pixels out of the framebuffer
*/ staticint hdlcd_set_pxl_fmt(struct drm_crtc *crtc)
{ unsignedint btpp; struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); conststruct drm_framebuffer *fb = crtc->primary->state->fb; conststruct pixel_format *format = NULL; int i;
for (i = 0; i < ARRAY_SIZE(supported_formats); i++) { if (supported_formats[i].fourcc == fb->format->format)
format = &supported_formats[i].pixel;
}
if (WARN_ON(!format)) return 0;
/* HDLCD uses 'bytes per pixel', zero means 1 byte */
btpp = (format->bits_per_pixel + 7) / 8;
hdlcd_write(hdlcd, HDLCD_REG_PIXEL_FORMAT, (btpp - 1) << 3);
/* * The format of the HDLCD_REG_<color>_SELECT register is: * - bits[23:16] - default value for that color component * - bits[11:8] - number of bits to extract for each color component * - bits[4:0] - index of the lowest bit to extract * * The default color value is used when bits[11:8] are zero, when the * pixel is outside the visible frame area or when there is a * buffer underrun.
*/
hdlcd_write(hdlcd, HDLCD_REG_RED_SELECT, format->red.offset | #ifdef CONFIG_DRM_HDLCD_SHOW_UNDERRUN
0x00ff0000 | /* show underruns in red */ #endif
((format->red.length & 0xf) << 8));
hdlcd_write(hdlcd, HDLCD_REG_GREEN_SELECT, format->green.offset |
((format->green.length & 0xf) << 8));
hdlcd_write(hdlcd, HDLCD_REG_BLUE_SELECT, format->blue.offset |
((format->blue.length & 0xf) << 8));
if (m->flags & DRM_MODE_FLAG_PHSYNC)
polarities |= HDLCD_POLARITY_HSYNC; if (m->flags & DRM_MODE_FLAG_PVSYNC)
polarities |= HDLCD_POLARITY_VSYNC;
/* Allow max number of outstanding requests and largest burst size */
hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS,
HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);
rate = clk_round_rate(hdlcd->clk, clk_rate); /* 0.1% seems a close enough tolerance for the TDA19988 on Juno */ if (abs(rate - clk_rate) * 1000 > clk_rate) { /* clock required by mode not supported by hardware */ return MODE_NOCLOCK;
}
/* only the HDLCD_REG_FB_LINE_COUNT register has a limit */ if (src_h >= HDLCD_MAX_YRES) {
DRM_DEBUG_KMS("Invalid source width: %d\n", src_h); return -EINVAL;
}
for_each_new_crtc_in_state(state, crtc, crtc_state,
i) { /* we cannot disable the plane while the CRTC is active */ if (!new_plane_state->fb && crtc_state->active) return -EINVAL; return drm_atomic_helper_check_plane_state(new_plane_state,
crtc_state,
DRM_PLANE_NO_SCALING,
DRM_PLANE_NO_SCALING, false, true);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.