if (modifier == DRM_FORMAT_MOD_LINEAR) returntrue;
/* check for the sector layout bit */ if (fourcc_mod_is_vendor(modifier, NVIDIA)) { if (modifier & DRM_FORMAT_MOD_NVIDIA_SECTOR_LAYOUT) { if (!tegra_plane_supports_sector_layout(plane)) returnfalse;
}
}
if (!dc->client.group) { /* * The display controller needs contiguous memory, so * fail if the buffer is discontiguous and we fail to * map its SG table to a single contiguous chunk of * I/O virtual memory.
*/ if (map->chunks > 1) {
err = -EINVAL; goto unpin;
}
/* * Note that real memory bandwidth vary depending on format and * memory layout, we are not taking that into account because small * estimation error isn't important since bandwidth is rounded up * anyway.
*/ for (i = 0, bpp = 0; i < fmt->num_planes; i++) { unsignedint bpp_plane = fmt->cpp[i] * 8;
/* * Sub-sampling is relevant for chroma planes only and vertical * readouts are not cached, hence only horizontal sub-sampling * matters.
*/ if (i > 0)
bpp_plane /= fmt->hsub;
/* mode.clock in kHz, peak bandwidth in kbytes/sec */
peak_bandwidth = DIV_ROUND_UP(crtc_state->adjusted_mode.clock * bpp, 8);
/* * Tegra30/114 Memory Controller can't interleave DC memory requests * for the tiled windows because DC uses 16-bytes atom, while DDR3 * uses 32-bytes atom. Hence there is x2 memory overfetch for tiled * framebuffer and DDR3 on these SoCs.
*/ if (soc->plane_tiled_memory_bandwidth_x2 &&
tegra_state->tiling.mode == TEGRA_BO_TILING_MODE_TILED)
mul = 2; else
mul = 1;
case DRM_FORMAT_YUV420:
*format = WIN_COLOR_DEPTH_YCbCr420P; break;
case DRM_FORMAT_YUV422:
*format = WIN_COLOR_DEPTH_YCbCr422P; break;
case DRM_FORMAT_YUV444:
*format = WIN_COLOR_DEPTH_YCbCr444P; break;
case DRM_FORMAT_NV12:
*format = WIN_COLOR_DEPTH_YCbCr420SP; break;
case DRM_FORMAT_NV21:
*format = WIN_COLOR_DEPTH_YCrCb420SP; break;
case DRM_FORMAT_NV16:
*format = WIN_COLOR_DEPTH_YCbCr422SP; break;
case DRM_FORMAT_NV61:
*format = WIN_COLOR_DEPTH_YCrCb422SP; break;
case DRM_FORMAT_NV24:
*format = WIN_COLOR_DEPTH_YCbCr444SP; break;
case DRM_FORMAT_NV42:
*format = WIN_COLOR_DEPTH_YCrCb444SP; break;
default: return -EINVAL;
}
return 0;
}
bool tegra_plane_format_is_indexed(unsignedint format)
{ switch (format) { case WIN_COLOR_DEPTH_P1: case WIN_COLOR_DEPTH_P2: case WIN_COLOR_DEPTH_P4: case WIN_COLOR_DEPTH_P8: returntrue;
}
returnfalse;
}
bool tegra_plane_format_is_yuv(unsignedint format, unsignedint *planes, unsignedint *bpc)
{ switch (format) { case WIN_COLOR_DEPTH_YCbCr422: case WIN_COLOR_DEPTH_YUV422: if (planes)
*planes = 1;
if (bpc)
*bpc = 8;
returntrue;
case WIN_COLOR_DEPTH_YCbCr420P: case WIN_COLOR_DEPTH_YUV420P: case WIN_COLOR_DEPTH_YCbCr422P: case WIN_COLOR_DEPTH_YUV422P: case WIN_COLOR_DEPTH_YCbCr422R: case WIN_COLOR_DEPTH_YUV422R: case WIN_COLOR_DEPTH_YCbCr422RA: case WIN_COLOR_DEPTH_YUV422RA: case WIN_COLOR_DEPTH_YCbCr444P: if (planes)
*planes = 3;
if (bpc)
*bpc = 8;
returntrue;
case WIN_COLOR_DEPTH_YCrCb420SP: case WIN_COLOR_DEPTH_YCbCr420SP: case WIN_COLOR_DEPTH_YCrCb422SP: case WIN_COLOR_DEPTH_YCbCr422SP: case WIN_COLOR_DEPTH_YCrCb444SP: case WIN_COLOR_DEPTH_YCbCr444SP: if (planes)
*planes = 2;
if (bpc)
*bpc = 8;
returntrue;
}
if (planes)
*planes = 1;
returnfalse;
}
staticbool __drm_format_has_alpha(u32 format)
{ switch (format) { case DRM_FORMAT_ARGB1555: case DRM_FORMAT_RGBA5551: case DRM_FORMAT_ABGR8888: case DRM_FORMAT_ARGB8888: returntrue;
}
switch (opaque) { case WIN_COLOR_DEPTH_B5G5R5X1:
*alpha = WIN_COLOR_DEPTH_B5G5R5A1; return 0;
case WIN_COLOR_DEPTH_X1B5G5R5:
*alpha = WIN_COLOR_DEPTH_A1B5G5R5; return 0;
case WIN_COLOR_DEPTH_R8G8B8X8:
*alpha = WIN_COLOR_DEPTH_R8G8B8A8; return 0;
case WIN_COLOR_DEPTH_B8G8R8X8:
*alpha = WIN_COLOR_DEPTH_B8G8R8A8; return 0;
case WIN_COLOR_DEPTH_B5G6R5:
*alpha = opaque; return 0;
}
return -EINVAL;
}
/* * This is applicable to Tegra20 and Tegra30 only where the opaque formats can * be emulated using the alpha formats and alpha blending disabled.
*/ staticint tegra_plane_setup_opacity(struct tegra_plane *tegra, struct tegra_plane_state *state)
{ unsignedint format; int err;
switch (state->format) { case WIN_COLOR_DEPTH_B5G5R5A1: case WIN_COLOR_DEPTH_A1B5G5R5: case WIN_COLOR_DEPTH_R8G8B8A8: case WIN_COLOR_DEPTH_B8G8R8A8:
state->opaque = false; break;
/* * Missing framebuffer means that plane is disabled, in this * case mark B / C window as top to be able to differentiate * windows indices order in regards to zPos for the middle * window X / Y registers programming.
*/ if (!new->fb)
state->blending[index].top = (index == 1);
}
}
/* * If planes zpos / transparency changed, sibling planes blending * state may require adjustment and in this case they will be included * into this atom commit, otherwise blending state is unchanged.
*/
err = tegra_plane_check_transparency(tegra, state); if (err <= 0) return err;
/* * All planes are now in the atomic state, walk them up and update * transparency state for each plane.
*/
drm_for_each_plane(plane, tegra->base.dev) { struct tegra_plane *p = to_tegra_plane(plane);
/* skip planes on different CRTCs */ if (p->dc != tegra->dc) continue;
new = drm_atomic_get_new_plane_state(state->base.state, plane);
tegra_state = to_tegra_plane_state(new);
/* * There is no need to update blending state for the disabled * plane.
*/ if (new->fb)
tegra_plane_update_transparency(p, tegra_state);
}
return 0;
}
int tegra_plane_setup_legacy_state(struct tegra_plane *tegra, struct tegra_plane_state *state)
{ int err;
err = tegra_plane_setup_opacity(tegra, state); if (err < 0) return err;
err = tegra_plane_setup_transparency(tegra, state); if (err < 0) return err;
if (WARN_ON(plane->index >= TEGRA_DC_LEGACY_PLANES_NUM) ||
WARN_ON(!tegra_plane_icc_names[plane->index])) return -EINVAL;
plane->icc_mem = devm_of_icc_get(dev, icc_name);
err = PTR_ERR_OR_ZERO(plane->icc_mem); if (err) return dev_err_probe(dev, err, "failed to get %s interconnect\n",
icc_name);
/* plane B on T20/30 has a dedicated memory client for a 6-tap vertical filter */ if (plane->index == 1 && dc->soc->has_win_b_vfilter_mem_client) {
plane->icc_mem_vfilter = devm_of_icc_get(dev, "winb-vfilter");
err = PTR_ERR_OR_ZERO(plane->icc_mem_vfilter); if (err) return dev_err_probe(dev, err, "failed to get %s interconnect\n", "winb-vfilter");
}
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.