/* * Versatile family (ARM reference designs) handling for the PL11x. * This is based on code and know-how in the previous frame buffer * driver in drivers/video/fbdev/amba-clcd.c: * Copyright (C) 2001 ARM Limited, by David A Rusling * Updated to 2.5 by Deep Blue Solutions Ltd. * Major contributions and discoveries by Russell King.
*/
switch (format) { case DRM_FORMAT_XBGR8888: case DRM_FORMAT_XRGB8888: /* 24bit formats */
val |= INTEGRATOR_CLCD_LCDMUX_VGA24; break; case DRM_FORMAT_XBGR1555: case DRM_FORMAT_XRGB1555: /* Pseudocolor, RGB555, BGR555 */
val |= INTEGRATOR_CLCD_LCDMUX_VGA555; break; default:
dev_err(drm->dev, "unhandled format on Integrator 0x%08x\n",
format); break;
}
switch (format) { case DRM_FORMAT_ABGR8888: case DRM_FORMAT_XBGR8888: case DRM_FORMAT_ARGB8888: case DRM_FORMAT_XRGB8888:
val |= SYS_CLCD_MODE_888; break; case DRM_FORMAT_BGR565:
val |= SYS_CLCD_MODE_565_R_LSB; break; case DRM_FORMAT_RGB565:
val |= SYS_CLCD_MODE_565_B_LSB; break; case DRM_FORMAT_ABGR1555: case DRM_FORMAT_XBGR1555: case DRM_FORMAT_ARGB1555: case DRM_FORMAT_XRGB1555:
val |= SYS_CLCD_MODE_5551; break; default:
dev_err(drm->dev, "unhandled format on Versatile 0x%08x\n",
format); break;
}
/* Set up the MUX */
regmap_update_bits(versatile_syscon_map,
SYS_CLCD,
SYS_CLCD_MODE_MASK,
val);
/* Then enable the display */
regmap_update_bits(versatile_syscon_map,
SYS_CLCD,
SYS_CLCD_CONNECTOR_MASK,
SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH);
}
/* * The Integrator variant is a PL110 with a bunch of broken, or not * yet implemented features
*/ staticconststruct pl111_variant_data pl110_integrator = {
.name = "PL110 Integrator",
.is_pl110 = true,
.broken_clockdivider = true,
.broken_vblank = true,
.formats = pl110_integrator_pixel_formats,
.nformats = ARRAY_SIZE(pl110_integrator_pixel_formats),
.fb_depth = 16,
};
/* * The IM-PD1 variant is a PL110 with a bunch of broken, or not * yet implemented features
*/ staticconststruct pl111_variant_data pl110_impd1 = {
.name = "PL110 IM-PD1",
.is_pl110 = true,
.broken_clockdivider = true,
.broken_vblank = true,
.formats = pl110_integrator_pixel_formats,
.nformats = ARRAY_SIZE(pl110_integrator_pixel_formats),
.fb_depth = 15,
};
/* * This is the in-between PL110 variant found in the ARM Versatile, * supporting RGB565/BGR565
*/ staticconststruct pl111_variant_data pl110_versatile = {
.name = "PL110 Versatile",
.is_pl110 = true,
.external_bgr = true,
.formats = pl110_versatile_pixel_formats,
.nformats = ARRAY_SIZE(pl110_versatile_pixel_formats),
.fb_depth = 16,
};
/* * RealView PL111 variant, the only real difference from the vanilla * PL111 is that we select 16bpp framebuffer by default to be able * to get 1024x768 without saturating the memory bus.
*/ staticconststruct pl111_variant_data pl111_realview = {
.name = "PL111 RealView",
.formats = pl111_realview_pixel_formats,
.nformats = ARRAY_SIZE(pl111_realview_pixel_formats),
.fb_depth = 16,
};
/* * Versatile Express PL111 variant, again we just push the maximum * BPP to 16 to be able to get 1024x768 without saturating the memory * bus. The clockdivider also seems broken on the Versatile Express.
*/ staticconststruct pl111_variant_data pl111_vexpress = {
.name = "PL111 Versatile Express",
.formats = pl111_realview_pixel_formats,
.nformats = ARRAY_SIZE(pl111_realview_pixel_formats),
.fb_depth = 16,
.broken_clockdivider = true,
};
if (!IS_ENABLED(CONFIG_VEXPRESS_CONFIG)) return -ENODEV;
/* * Check if we have a CLCD or HDLCD on the core tile by checking if a * CLCD or HDLCD is available in the root of the device tree.
*/
root = of_find_node_by_path("/"); if (!root) return -EINVAL;
/* * If there is a coretile HDLCD and it has a driver, * do not mux the CLCD on the motherboard to the DVI.
*/ if (has_coretile_hdlcd && IS_ENABLED(CONFIG_DRM_HDLCD))
mux_motherboard = false;
/* * On the Vexpress CA9 we let the CLCD on the coretile * take precedence, so also in this case do not mux the * motherboard to the DVI.
*/ if (has_coretile_clcd)
mux_motherboard = false;
if (mux_motherboard) {
dev_info(dev, "DVI muxed to motherboard CLCD\n");
val = VEXPRESS_FPGAMUX_MOTHERBOARD;
} elseif (ct_clcd == dev->of_node) {
dev_info(dev, "DVI muxed to daughterboard 1 (core tile) CLCD\n");
val = VEXPRESS_FPGAMUX_DAUGHTERBOARD_1;
} else {
dev_info(dev, "core tile graphics present\n");
dev_info(dev, "this device will be deactivated\n"); return -ENODEV;
}
/* Call into deep Vexpress configuration API */
pdev = of_find_device_by_node(np); if (!pdev) {
dev_err(dev, "can't find the sysreg device, deferring\n"); return -EPROBE_DEFER;
}
map = devm_regmap_init_vexpress_config(&pdev->dev); if (IS_ERR(map)) {
platform_device_put(pdev); return PTR_ERR(map);
}
ret = regmap_write(map, 0, val);
platform_device_put(pdev); if (ret) {
dev_err(dev, "error setting DVI muxmode\n"); return -ENODEV;
}
/* Versatile Express special handling */ if (versatile_clcd_type == VEXPRESS_CLCD_V2M) { int ret = pl111_vexpress_clcd_init(dev, np, priv);
of_node_put(np); if (ret)
dev_err(dev, "Versatile Express init failed - %d", ret); return ret;
}
/* * On the Integrator, check if we should use the IM-PD1 instead, * if we find it, it will take precedence. This is on the Integrator/AP * which only has this option for PL110 graphics.
*/ if (versatile_clcd_type == INTEGRATOR_CLCD_CM) {
np = of_find_matching_node_and_match(NULL, impd1_clcd_of_match,
&clcd_id); if (np)
versatile_clcd_type = (enum versatile_clcd)clcd_id->data;
}
map = syscon_node_to_regmap(np);
of_node_put(np); if (IS_ERR(map)) {
dev_err(dev, "no Versatile syscon regmap\n"); return PTR_ERR(map);
}
switch (versatile_clcd_type) { case INTEGRATOR_CLCD_CM:
versatile_syscon_map = map;
priv->variant = &pl110_integrator;
priv->variant_display_enable = pl111_integrator_enable;
dev_info(dev, "set up callbacks for Integrator PL110\n"); break; case INTEGRATOR_IMPD1:
versatile_syscon_map = map;
priv->variant = &pl110_impd1;
priv->variant_display_enable = pl111_impd1_enable;
priv->variant_display_disable = pl111_impd1_disable;
dev_info(dev, "set up callbacks for IM-PD1 PL110\n"); break; case VERSATILE_CLCD:
versatile_syscon_map = map; /* This can do RGB565 with external PLD */
priv->variant = &pl110_versatile;
priv->variant_display_enable = pl111_versatile_enable;
priv->variant_display_disable = pl111_versatile_disable; /* * The Versatile has a variant halfway between PL110 * and PL111 where these two registers have already been * swapped.
*/
priv->ienb = CLCD_PL111_IENB;
priv->ctrl = CLCD_PL111_CNTL;
dev_info(dev, "set up callbacks for Versatile PL110\n"); break; case REALVIEW_CLCD_EB: case REALVIEW_CLCD_PB1176: case REALVIEW_CLCD_PB11MP: case REALVIEW_CLCD_PBA8: case REALVIEW_CLCD_PBX:
versatile_syscon_map = map;
priv->variant = &pl111_realview;
priv->variant_display_enable = pl111_realview_clcd_enable;
priv->variant_display_disable = pl111_realview_clcd_disable;
dev_info(dev, "set up callbacks for RealView PL111\n"); break; default:
dev_info(dev, "unknown Versatile system controller\n"); break;
}
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.