ARM: tegra: fix regulator_get() return value check
[linux-3.10.git] / arch / arm / mach-tegra / board-ardbeg-panel.c
index 4c14345..8e20fde 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/regulator/consumer.h>
 #include <linux/pwm_backlight.h>
 #include <linux/of.h>
+#include <linux/dma-contiguous.h>
+#include <linux/clk.h>
 
 #include <mach/irqs.h>
 #include <mach/dc.h>
@@ -40,6 +42,7 @@
 #include "common.h"
 #include "iomap.h"
 #include "tegra12_host1x_devices.h"
+#include "dvfs.h"
 
 
 struct platform_device * __init ardbeg_host1x_init(void)
@@ -47,7 +50,11 @@ struct platform_device * __init ardbeg_host1x_init(void)
        struct platform_device *pdev = NULL;
 
 #ifdef CONFIG_TEGRA_GRHOST
-       pdev = tegra12_register_host1x_devices();
+       if (!of_have_populated_dt())
+               pdev = tegra12_register_host1x_devices();
+       else
+               pdev = to_platform_device(bus_find_device_by_name(
+                       &platform_bus_type, NULL, "host1x"));
 
        if (!pdev) {
                pr_err("host1x devices registration failed\n");
@@ -192,7 +199,7 @@ static int ardbeg_hdmi_enable(struct device *dev)
        int ret;
        if (!ardbeg_hdmi_reg) {
                ardbeg_hdmi_reg = regulator_get(dev, "avdd_hdmi");
-               if (IS_ERR_OR_NULL(ardbeg_hdmi_reg)) {
+               if (IS_ERR(ardbeg_hdmi_reg)) {
                        pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
                        ardbeg_hdmi_reg = NULL;
                        return PTR_ERR(ardbeg_hdmi_reg);
@@ -205,7 +212,7 @@ static int ardbeg_hdmi_enable(struct device *dev)
        }
        if (!ardbeg_hdmi_pll) {
                ardbeg_hdmi_pll = regulator_get(dev, "avdd_hdmi_pll");
-               if (IS_ERR_OR_NULL(ardbeg_hdmi_pll)) {
+               if (IS_ERR(ardbeg_hdmi_pll)) {
                        pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
                        ardbeg_hdmi_pll = NULL;
                        regulator_put(ardbeg_hdmi_reg);
@@ -256,7 +263,7 @@ static int ardbeg_hdmi_hotplug_init(struct device *dev)
                                __func__, PTR_ERR(ardbeg_hdmi_vddio));
                                ardbeg_hdmi_vddio = NULL;
                } else {
-                       regulator_enable(ardbeg_hdmi_vddio);
+                       return regulator_enable(ardbeg_hdmi_vddio);
                }
        }
 
@@ -304,6 +311,24 @@ struct tegra_hdmi_out ardbeg_hdmi_out = {
 };
 
 
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
+static struct tegra_dc_mode hdmi_panel_modes[] = {
+       {
+               .pclk =                 KHZ2PICOS(25200),
+               .h_ref_to_sync =        1,
+               .v_ref_to_sync =        1,
+               .h_sync_width =         96,     /* hsync_len */
+               .v_sync_width =         2,      /* vsync_len */
+               .h_back_porch =         48,     /* left_margin */
+               .v_back_porch =         33,     /* upper_margin */
+               .h_active =             640,    /* xres */
+               .v_active =             480,    /* yres */
+               .h_front_porch =        16,     /* right_margin */
+               .v_front_porch =        10,     /* lower_margin */
+       },
+};
+#endif /* CONFIG_FRAMEBUFFER_CONSOLE */
+
 static struct tegra_dc_out ardbeg_disp2_out = {
        .type           = TEGRA_DC_OUT_HDMI,
        .flags          = TEGRA_DC_OUT_HOTPLUG_HIGH,
@@ -315,6 +340,11 @@ static struct tegra_dc_out ardbeg_disp2_out = {
 
        /* TODO: update max pclk to POR */
        .max_pixclock   = KHZ2PICOS(297000),
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
+       .modes = hdmi_panel_modes,
+       .n_modes = ARRAY_SIZE(hdmi_panel_modes),
+       .depth = 24,
+#endif /* CONFIG_FRAMEBUFFER_CONSOLE */
 
        .align          = TEGRA_DC_ALIGN_MSB,
        .order          = TEGRA_DC_ORDER_RED_BLUE,
@@ -458,15 +488,19 @@ static struct tegra_dc_sd_settings ardbeg_sd_settings = {
        .use_vpulse2 = true,
 };
 
-static void ardbeg_panel_select(void)
+/* can be called multiple times */
+static struct tegra_panel *ardbeg_panel_configure(struct board_info *board_out,
+       u8 *dsi_instance_out)
 {
        struct tegra_panel *panel = NULL;
-       struct board_info board;
        u8 dsi_instance;
+       struct board_info boardtmp;
 
-       tegra_get_display_board_info(&board);
+       if (!board_out)
+               board_out = &boardtmp;
+       tegra_get_display_board_info(board_out);
 
-       switch (board.board_id) {
+       switch (board_out->board_id) {
        case BOARD_E1639:
        case BOARD_E1813:
                panel = &dsi_s_wqxga_10_1;
@@ -504,6 +538,18 @@ static void ardbeg_panel_select(void)
                dsi_instance = DSI_INSTANCE_0;
                break;
        }
+       if (dsi_instance_out)
+               *dsi_instance_out = dsi_instance;
+       return panel;
+}
+
+static void ardbeg_panel_select(void)
+{
+       struct tegra_panel *panel = NULL;
+       struct board_info board;
+       u8 dsi_instance;
+
+       panel = ardbeg_panel_configure(&board, &dsi_instance);
 
        if (panel) {
                if (panel->init_sd_settings)
@@ -560,6 +606,15 @@ int __init ardbeg_panel_init(void)
        ardbeg_carveouts[1].size = tegra_carveout_size;
        ardbeg_carveouts[2].base = tegra_vpr_start;
        ardbeg_carveouts[2].size = tegra_vpr_size;
+#ifdef CONFIG_NVMAP_USE_CMA_FOR_CARVEOUT
+       carveout_linear_set(&tegra_generic_cma_dev);
+       ardbeg_carveouts[1].cma_dev = &tegra_generic_cma_dev;
+       ardbeg_carveouts[1].resize = false;
+       carveout_linear_set(&tegra_vpr_cma_dev);
+       ardbeg_carveouts[2].cma_dev = &tegra_vpr_cma_dev;
+       ardbeg_carveouts[2].resize = true;
+       ardbeg_carveouts[2].cma_chunk_size = SZ_32M;
+#endif
 
        err = platform_device_register(&ardbeg_nvmap_device);
        if (err) {
@@ -609,3 +664,54 @@ int __init ardbeg_panel_init(void)
 #endif
        return err;
 }
+
+int __init ardbeg_display_init(void)
+{
+       struct clk *disp1_clk = clk_get_sys("tegradc.0", NULL);
+       struct clk *disp2_clk = clk_get_sys("tegradc.1", NULL);
+       struct tegra_panel *panel;
+       struct board_info board;
+       long disp1_rate;
+       long disp2_rate;
+
+       if (WARN_ON(IS_ERR(disp1_clk))) {
+               if (disp2_clk && !IS_ERR(disp2_clk))
+                       clk_put(disp2_clk);
+               return PTR_ERR(disp1_clk);
+       }
+
+       if (WARN_ON(IS_ERR(disp2_clk))) {
+               clk_put(disp1_clk);
+               return PTR_ERR(disp1_clk);
+       }
+
+       panel = ardbeg_panel_configure(&board, NULL);
+
+       if (panel && panel->init_dc_out) {
+               panel->init_dc_out(&ardbeg_disp1_out);
+               if (ardbeg_disp1_out.n_modes && ardbeg_disp1_out.modes)
+                       disp1_rate = ardbeg_disp1_out.modes[0].pclk;
+       } else {
+               disp1_rate = 0;
+               if (!panel || !panel->init_dc_out)
+                       printk(KERN_ERR "disp1 panel output not specified!\n");
+       }
+
+       printk(KERN_DEBUG "disp1 pclk=%ld\n", disp1_rate);
+       if (disp1_rate)
+               tegra_dvfs_resolve_override(disp1_clk, disp1_rate);
+
+
+       /* set up disp2 */
+       if (ardbeg_disp2_out.max_pixclock)
+               disp2_rate = PICOS2KHZ(ardbeg_disp2_out.max_pixclock) * 1000;
+       else
+               disp2_rate = 297000000; /* HDMI 4K */
+       printk(KERN_DEBUG "disp2 pclk=%ld\n", disp2_rate);
+       if (disp2_rate)
+               tegra_dvfs_resolve_override(disp2_clk, disp2_rate);
+
+       clk_put(disp1_clk);
+       clk_put(disp2_clk);
+       return 0;
+}