aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLajos Molnar <lajos@ti.com>2012-05-13 13:14:35 -0700
committerZiyann <jaraidaniel@gmail.com>2014-11-19 21:05:26 +0100
commit6ac4c786827bf038fffa600b99a62c6d76897464 (patch)
tree2f07cd7d5791e352f760e141a860e95b79353fbe
parente67c9a6c21efdf1de2d4534e1d2b873910f1bb9d (diff)
downloadkernel_samsung_tuna-6ac4c786827bf038fffa600b99a62c6d76897464.zip
kernel_samsung_tuna-6ac4c786827bf038fffa600b99a62c6d76897464.tar.gz
kernel_samsung_tuna-6ac4c786827bf038fffa600b99a62c6d76897464.tar.bz2
OMAP2: generic Android display configuration setup
Added android_display methods to allow runtime configuration of Android display resources, such as: - FB0's vram is dynamically calculated from the number of buffers SGX requires in VRAM (swap chain and/or composition buffers), and the FB0 display size. - OMAP VRAM is calculated from FB0's vram need + any other specified FB's vram. (If command line is used to specify FB vrams, omap vram must also be specified.) - TILER1D area reserved for use as DSS MMU by DSSCOMP is calculated from default display size. It can be overriden by board file. - TILER2D carveout size is reduced by TILER1D area (if coallocated with TILER2D) and by the TILER2D SGX buffers (swapchain and/or composition buffers) - nonsecure TILER2D carveout size is set to the backpages needed by TILER2D SGX buffers. All of this is coordinated by omap_android_display_setup. It takes pointers to the DSS board info, FB platform data, and optionally to the ION, SGX and DSSCOMP platform data. It should be called in board_reserve before omap_ion_init. If SGX data is provided, it is set as the SGX platform data for FB0. Similarly, if DSSCOMP platform data is provided it is also set. This can be used to set a preferred tiler1d slot size. If ION platform data is provided, it is updated with the required tiler2d carveout sizes. NOTE: To maximize TILER2D space, the TILER1D area reserved for android display is not aligned to 1MB, but is aligned to 32 pages as the smallest 2D allocation needs a 32-page band. We further reduce TILER2D space by the container space lost by the SGX buffers, which may be larger than the actual backpages bneeded for the SGX buffers. Therefore the sum of secure + nonsecure + 1D tiler space may be smaller than the available container space. Ported to latest SGX DDK by Dima Svetlov. Change-Id: I5d8858c38efd842452994e3a3476463083d200d7 Signed-off-by: Lajos Molnar <lajos@ti.com> Signed-off-by: Dima Svetlov <svetlov@ti.com>
-rw-r--r--arch/arm/plat-omap/Makefile2
-rw-r--r--arch/arm/plat-omap/android-display.c255
-rw-r--r--arch/arm/plat-omap/include/plat/android-display.h29
3 files changed, 286 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 6fd1670..0cdc68f 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -34,5 +34,7 @@ obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-interface.o
obj-$(CONFIG_OMAP_PM) += omap-pm-interface.o omap-pm-helper.o
+
obj-$(CONFIG_DSSCOMP) += omap_dsscomp.o
+obj-$(CONFIG_ION_OMAP) += android-display.o
obj-$(CONFIG_ION_OMAP) += sgx_omaplfb.o
diff --git a/arch/arm/plat-omap/android-display.c b/arch/arm/plat-omap/android-display.c
new file mode 100644
index 0000000..0bf65c0
--- /dev/null
+++ b/arch/arm/plat-omap/android-display.c
@@ -0,0 +1,255 @@
+/*
+ * Android display memory setup for OMAP4+ displays
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author: Lajos Molnar
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+
+#include <video/omapdss.h>
+
+#include <mach/tiler.h>
+
+#include <plat/android-display.h>
+#include <plat/dsscomp.h>
+#include <plat/vram.h>
+
+struct omap_android_display_data {
+ /* members with default values */
+ u32 width;
+ u32 height;
+ u32 bpp; /* must be 2 or 4 */
+
+ /* members with no default value */
+ u32 tiler1d_mem;
+};
+
+/*
+ * We need to peek at omapdss settings so that we have enough memory for swap
+ * chain and vram. While this could be done by omapdss, omapdss could be
+ * compiled as a module, which is too late to get this information.
+ */
+static char default_display[16];
+static __init int get_default_display(char *str)
+{
+ strncpy(default_display, str, sizeof(default_display));
+ if (strlen(str) >= sizeof(default_display))
+ pr_warn("android_display: cannot set default display larger "
+ "than %d characters", sizeof(default_display) - 1);
+ default_display[sizeof(default_display) - 1] = '\0';
+ return 1;
+}
+early_param("omapdss.def_disp", get_default_display);
+
+static unsigned int hdmi_width, hdmi_height;
+static __init int get_hdmi_options(char *str)
+{
+ unsigned int width, height;
+ char dummy;
+ if (sscanf(str, "%ux%u%c", &width, &height, &dummy) == 2) {
+ hdmi_width = width;
+ hdmi_height = height;
+ }
+ return 1;
+}
+early_param("omapdss.hdmi_options", get_hdmi_options);
+
+static void get_display_size(struct omap_dss_board_info *info,
+ struct omap_android_display_data *mem)
+{
+ struct omap_dss_device *device = NULL;
+ int i;
+
+ if (!info)
+ goto done;
+
+ device = info->default_device;
+ for (i = 0; i < info->num_devices; i++) {
+ if (!strcmp(default_display, info->devices[i]->name)) {
+ device = info->devices[i];
+ break;
+ }
+ }
+
+ if (!device)
+ goto done;
+
+ if (device->type == OMAP_DISPLAY_TYPE_HDMI &&
+ hdmi_width && hdmi_height) {
+ mem->width = hdmi_width;
+ mem->height = hdmi_height;
+ } else if (device->panel.timings.x_res && device->panel.timings.y_res) {
+ mem->width = device->panel.timings.x_res;
+ mem->height = device->panel.timings.y_res;
+ }
+ if (device->ctrl.pixel_size)
+ mem->bpp = ALIGN(device->ctrl.pixel_size, 16) >> 3;
+
+ pr_info("android_display: setting default resolution %u*%u, bpp=%u\n",
+ mem->width, mem->height, mem->bpp);
+done:
+ return;
+}
+
+static void set_tiler1d_slot_size(struct dsscomp_platform_data *dsscomp,
+ struct omap_android_display_data *mem)
+{
+ struct dsscomp_platform_data data = {
+ .tiler1d_slotsz = 0,
+ };
+
+ if (dsscomp)
+ data = *dsscomp;
+
+ /* do not change board specified value if given */
+ if (data.tiler1d_slotsz)
+ goto done;
+
+ /*
+ * 4 bytes per pixel, and ICS factor of 4. The ICS factor
+ * is chosen somewhat arbitrarily to support the home screen layers
+ * to be displayed by DSS. The size of the home screen layers is
+ * roughly (1 + 2.5 + 0.1 + 0.1) * size_of_the_screen
+ * for the icons, wallpaper, status bar and navigation bar. Boards
+ * that wish to use a different factor should supply their tiler1D
+ * slot size directly.
+ */
+ data.tiler1d_slotsz =
+ PAGE_ALIGN(mem->width * mem->height * 4 * 4);
+
+done:
+ if (dsscomp)
+ *dsscomp = data;
+ dsscomp_set_platform_data(&data);
+
+ /* remember setting for ion carveouts */
+ mem->tiler1d_mem =
+ NUM_ANDROID_TILER1D_SLOTS * data.tiler1d_slotsz;
+ pr_info("android_display: tiler1d %u\n", mem->tiler1d_mem);
+}
+
+static u32 vram_size(struct omap_android_display_data *mem)
+{
+ /* calculate required VRAM */
+ return PAGE_ALIGN(ALIGN(mem->width, 64) * mem->height * mem->bpp);
+}
+
+static void set_vram_sizes(struct sgx_omaplfb_config *sgx_config,
+ struct omapfb_platform_data *fb,
+ struct omap_android_display_data *mem)
+{
+ u32 num_vram_buffers = 1;
+ u32 vram = 0;
+ int i;
+
+ if (sgx_config) {
+ vram += sgx_config->vram_reserve;
+ num_vram_buffers = sgx_config->vram_buffers;
+ }
+ vram += num_vram_buffers * vram_size(mem);
+
+ if (fb) {
+ /* set fb0 vram needs */
+ if (fb->mem_desc.region_cnt >= 1) {
+ fb->mem_desc.region[0].size = vram;
+ pr_info("android_display: setting fb0.vram to %u\n",
+ vram);
+ }
+
+ /* set global vram needs incl. additional regions specified */
+ for (i = 1; i < fb->mem_desc.region_cnt; i++)
+ if (!fb->mem_desc.region[i].paddr)
+ vram += fb->mem_desc.region[i].size;
+ }
+
+ pr_info("android_display: setting vram to %u\n", vram);
+ omap_vram_set_sdram_vram(vram, 0);
+}
+
+static void set_ion_carveouts(struct sgx_omaplfb_config *sgx_config,
+ struct omap_ion_platform_data *ion,
+ struct omap_android_display_data *mem)
+{
+ u32 alloc_pages, width;
+ enum tiler_fmt fmt;
+ u32 num_buffers = 2;
+
+ BUG_ON(!mem || (mem->bpp == 0));
+
+ if (sgx_config)
+ num_buffers = sgx_config->tiler2d_buffers;
+
+
+ /* width must be aligned to 128 bytes */
+ width = ALIGN(mem->width, 128 / mem->bpp);
+ fmt = mem->bpp <= 2 ? TILFMT_16BIT : TILFMT_32BIT;
+
+ /* max pages used from TILER2D container */
+ alloc_pages = tiler_backpages(fmt,
+ ALIGN(width, PAGE_SIZE / mem->bpp),
+ mem->height);
+
+ /* actual pages used is the same */
+ ion->nonsecure_tiler2d_size = alloc_pages * PAGE_SIZE * num_buffers;
+
+ ion->tiler2d_size = SZ_128M;
+
+ /* min pages used from TILER2D container */
+ alloc_pages = tiler_backpages(fmt,
+ ALIGN(width, PAGE_SIZE / mem->bpp),
+ mem->height * num_buffers);
+ ion->tiler2d_size -= alloc_pages * PAGE_SIZE;
+
+ /*
+ * On OMAP4 tiler1d and tiler2d are in the same container. However,
+ * leftover space must be in 32-page bands
+ */
+ if (1 /* !cpu_is_omap54xx() */)
+ ion->tiler2d_size -= ALIGN(mem->tiler1d_mem, PAGE_SIZE * 32);
+
+ pr_info("android_display: ion carveouts: %u tiler2d, %u nonsecure\n",
+ ion->tiler2d_size, ion->nonsecure_tiler2d_size);
+}
+
+/* coordinate between sgx, omapdss, dsscomp and ion needs */
+void omap_android_display_setup(struct omap_dss_board_info *dss,
+ struct dsscomp_platform_data *dsscomp,
+ struct sgx_omaplfb_platform_data *sgx,
+ struct omapfb_platform_data *fb,
+ struct omap_ion_platform_data *ion)
+{
+ struct sgx_omaplfb_config *p_sgx_config = NULL;
+
+ struct omap_android_display_data mem = {
+ .bpp = 4,
+ .width = 1920,
+ .height = 1080,
+ };
+
+ if (!sgx || !sgx->configs)
+ p_sgx_config = sgx_omaplfb_get(0);
+ else
+ p_sgx_config = &(sgx->configs[0]);
+
+ get_display_size(dss, &mem);
+ set_tiler1d_slot_size(dsscomp, &mem);
+ set_vram_sizes(p_sgx_config, fb, &mem);
+ if (ion)
+ set_ion_carveouts(p_sgx_config, ion, &mem);
+
+ sgx_omaplfb_set(0, p_sgx_config);
+}
diff --git a/arch/arm/plat-omap/include/plat/android-display.h b/arch/arm/plat-omap/include/plat/android-display.h
new file mode 100644
index 0000000..2be3887
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/android-display.h
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-omap2/android_display.h
+ *
+ * OMAP2 platform device setup/initialization
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP_ANDROID_DISPLAY_H
+#define __ARCH_ARM_MACH_OMAP_ANDROID_DISPLAY_H
+
+#include <linux/omapfb.h>
+#include <video/omapdss.h>
+#include <mach/omap4_ion.h>
+#include <plat/sgx_omaplfb.h>
+#include <plat/dsscomp.h>
+
+#define NUM_ANDROID_TILER1D_SLOTS 2
+
+void omap_android_display_setup(struct omap_dss_board_info *dss,
+ struct dsscomp_platform_data *dsscomp,
+ struct sgx_omaplfb_platform_data *sgx,
+ struct omapfb_platform_data *fb,
+ struct omap_ion_platform_data *ion);
+
+#endif