diff options
author | Koen Kooi <koen@openembedded.org> | 2009-09-04 11:41:31 +0200 |
---|---|---|
committer | Koen Kooi <koen@openembedded.org> | 2009-09-04 11:41:31 +0200 |
commit | 00705178d3fae14a7cf2e2bb817745ad9b41b8b7 (patch) | |
tree | bdf5573ef9b9bfc1da5d08f7048b161360b77844 /recipes/linux/linux-omap-2.6.31/dss2/0010-OMAP-DSS2-DPI-driver.patch | |
parent | c26fc5db90702b035bd545cff3ee7575a0f9b70f (diff) |
linux-omap git: add dss2 and cache patches
Diffstat (limited to 'recipes/linux/linux-omap-2.6.31/dss2/0010-OMAP-DSS2-DPI-driver.patch')
-rw-r--r-- | recipes/linux/linux-omap-2.6.31/dss2/0010-OMAP-DSS2-DPI-driver.patch | 410 |
1 files changed, 410 insertions, 0 deletions
diff --git a/recipes/linux/linux-omap-2.6.31/dss2/0010-OMAP-DSS2-DPI-driver.patch b/recipes/linux/linux-omap-2.6.31/dss2/0010-OMAP-DSS2-DPI-driver.patch new file mode 100644 index 0000000000..db6d780552 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/dss2/0010-OMAP-DSS2-DPI-driver.patch @@ -0,0 +1,410 @@ +From 544b715d21a38a64bcafe850e31ae0dfd5227e9f Mon Sep 17 00:00:00 2001 +From: Tomi Valkeinen <tomi.valkeinen@nokia.com> +Date: Fri, 7 Aug 2009 13:15:50 +0300 +Subject: [PATCH 10/18] OMAP: DSS2: DPI driver + +This implements MIPI DPI interface. + +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com> +--- + drivers/video/omap2/dss/dpi.c | 388 +++++++++++++++++++++++++++++++++++++++++ + 1 files changed, 388 insertions(+), 0 deletions(-) + create mode 100644 drivers/video/omap2/dss/dpi.c + +diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c +new file mode 100644 +index 0000000..b6543c8 +--- /dev/null ++++ b/drivers/video/omap2/dss/dpi.c +@@ -0,0 +1,388 @@ ++/* ++ * linux/drivers/video/omap2/dss/dpi.c ++ * ++ * Copyright (C) 2009 Nokia Corporation ++ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> ++ * ++ * Some code and ideas taken from drivers/video/omap/ driver ++ * by Imre Deak. ++ * ++ * 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 in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#define DSS_SUBSYS_NAME "DPI" ++ ++#include <linux/kernel.h> ++#include <linux/clk.h> ++#include <linux/delay.h> ++#include <linux/errno.h> ++ ++#include <mach/board.h> ++#include <mach/display.h> ++#include <mach/cpu.h> ++ ++#include "dss.h" ++ ++static struct { ++ int update_enabled; ++} dpi; ++ ++#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL ++static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req, ++ unsigned long *fck, int *lck_div, int *pck_div) ++{ ++ struct dsi_clock_info cinfo; ++ int r; ++ ++ r = dsi_pll_calc_pck(is_tft, pck_req, &cinfo); ++ if (r) ++ return r; ++ ++ r = dsi_pll_program(&cinfo); ++ if (r) ++ return r; ++ ++ dss_select_clk_source(0, 1); ++ ++ dispc_set_lcd_divisor(cinfo.lck_div, cinfo.pck_div); ++ ++ *fck = cinfo.dsi1_pll_fclk; ++ *lck_div = cinfo.lck_div; ++ *pck_div = cinfo.pck_div; ++ ++ return 0; ++} ++#else ++static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req, ++ unsigned long *fck, int *lck_div, int *pck_div) ++{ ++ struct dispc_clock_info cinfo; ++ int r; ++ ++ r = dispc_calc_clock_div(is_tft, pck_req, &cinfo); ++ if (r) ++ return r; ++ ++ r = dispc_set_clock_div(&cinfo); ++ if (r) ++ return r; ++ ++ *fck = cinfo.fck; ++ *lck_div = cinfo.lck_div; ++ *pck_div = cinfo.pck_div; ++ ++ return 0; ++} ++#endif ++ ++static int dpi_set_mode(struct omap_dss_device *dssdev) ++{ ++ struct omap_video_timings *t = &dssdev->panel.timings; ++ int lck_div, pck_div; ++ unsigned long fck; ++ unsigned long pck; ++ bool is_tft; ++ int r = 0; ++ ++ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); ++ ++ dispc_set_pol_freq(dssdev->panel.config, dssdev->panel.acbi, ++ dssdev->panel.acb); ++ ++ is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; ++ ++#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL ++ r = dpi_set_dsi_clk(is_tft, t->pixel_clock * 1000, ++ &fck, &lck_div, &pck_div); ++#else ++ r = dpi_set_dispc_clk(is_tft, t->pixel_clock * 1000, ++ &fck, &lck_div, &pck_div); ++#endif ++ if (r) ++ goto err0; ++ ++ pck = fck / lck_div / pck_div / 1000; ++ ++ if (pck != t->pixel_clock) { ++ DSSWARN("Could not find exact pixel clock. " ++ "Requested %d kHz, got %lu kHz\n", ++ t->pixel_clock, pck); ++ ++ t->pixel_clock = pck; ++ } ++ ++ dispc_set_lcd_timings(t); ++ ++err0: ++ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); ++ return r; ++} ++ ++static int dpi_basic_init(struct omap_dss_device *dssdev) ++{ ++ bool is_tft; ++ ++ is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; ++ ++ dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS); ++ dispc_set_lcd_display_type(is_tft ? OMAP_DSS_LCD_DISPLAY_TFT : ++ OMAP_DSS_LCD_DISPLAY_STN); ++ dispc_set_tft_data_lines(dssdev->phy.dpi.data_lines); ++ ++ return 0; ++} ++ ++static int dpi_display_enable(struct omap_dss_device *dssdev) ++{ ++ int r; ++ ++ r = omap_dss_start_device(dssdev); ++ if (r) { ++ DSSERR("failed to start device\n"); ++ goto err0; ++ } ++ ++ if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { ++ DSSERR("display already enabled\n"); ++ r = -EINVAL; ++ goto err1; ++ } ++ ++ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); ++ ++ r = dpi_basic_init(dssdev); ++ if (r) ++ goto err2; ++ ++#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL ++ dss_clk_enable(DSS_CLK_FCK2); ++ r = dsi_pll_init(0, 1); ++ if (r) ++ goto err3; ++#endif ++ r = dpi_set_mode(dssdev); ++ if (r) ++ goto err4; ++ ++ mdelay(2); ++ ++ dispc_enable_lcd_out(1); ++ ++ r = dssdev->driver->enable(dssdev); ++ if (r) ++ goto err5; ++ ++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; ++ ++ return 0; ++ ++err5: ++ dispc_enable_lcd_out(0); ++err4: ++#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL ++ dsi_pll_uninit(); ++err3: ++ dss_clk_disable(DSS_CLK_FCK2); ++#endif ++err2: ++ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); ++err1: ++ omap_dss_stop_device(dssdev); ++err0: ++ return r; ++} ++ ++static int dpi_display_resume(struct omap_dss_device *dssdev); ++ ++static void dpi_display_disable(struct omap_dss_device *dssdev) ++{ ++ if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) ++ return; ++ ++ if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) ++ dpi_display_resume(dssdev); ++ ++ dssdev->driver->disable(dssdev); ++ ++ dispc_enable_lcd_out(0); ++ ++#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL ++ dss_select_clk_source(0, 0); ++ dsi_pll_uninit(); ++ dss_clk_disable(DSS_CLK_FCK2); ++#endif ++ ++ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); ++ ++ dssdev->state = OMAP_DSS_DISPLAY_DISABLED; ++ ++ omap_dss_stop_device(dssdev); ++} ++ ++static int dpi_display_suspend(struct omap_dss_device *dssdev) ++{ ++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) ++ return -EINVAL; ++ ++ DSSDBG("dpi_display_suspend\n"); ++ ++ if (dssdev->driver->suspend) ++ dssdev->driver->suspend(dssdev); ++ ++ dispc_enable_lcd_out(0); ++ ++ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); ++ ++ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; ++ ++ return 0; ++} ++ ++static int dpi_display_resume(struct omap_dss_device *dssdev) ++{ ++ if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) ++ return -EINVAL; ++ ++ DSSDBG("dpi_display_resume\n"); ++ ++ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); ++ ++ dispc_enable_lcd_out(1); ++ ++ if (dssdev->driver->resume) ++ dssdev->driver->resume(dssdev); ++ ++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; ++ ++ return 0; ++} ++ ++static void dpi_set_timings(struct omap_dss_device *dssdev, ++ struct omap_video_timings *timings) ++{ ++ DSSDBG("dpi_set_timings\n"); ++ dssdev->panel.timings = *timings; ++ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { ++ dpi_set_mode(dssdev); ++ dispc_go(OMAP_DSS_CHANNEL_LCD); ++ } ++} ++ ++static int dpi_check_timings(struct omap_dss_device *dssdev, ++ struct omap_video_timings *timings) ++{ ++ bool is_tft; ++ int r; ++ int lck_div, pck_div; ++ unsigned long fck; ++ unsigned long pck; ++ ++ if (!dispc_lcd_timings_ok(timings)) ++ return -EINVAL; ++ ++ if (timings->pixel_clock == 0) ++ return -EINVAL; ++ ++ is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; ++ ++#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL ++ { ++ struct dsi_clock_info cinfo; ++ r = dsi_pll_calc_pck(is_tft, timings->pixel_clock * 1000, ++ &cinfo); ++ ++ if (r) ++ return r; ++ ++ fck = cinfo.dsi1_pll_fclk; ++ lck_div = cinfo.lck_div; ++ pck_div = cinfo.pck_div; ++ } ++#else ++ { ++ struct dispc_clock_info cinfo; ++ r = dispc_calc_clock_div(is_tft, timings->pixel_clock * 1000, ++ &cinfo); ++ ++ if (r) ++ return r; ++ ++ fck = cinfo.fck; ++ lck_div = cinfo.lck_div; ++ pck_div = cinfo.pck_div; ++ } ++#endif ++ ++ pck = fck / lck_div / pck_div / 1000; ++ ++ timings->pixel_clock = pck; ++ ++ return 0; ++} ++ ++static void dpi_get_timings(struct omap_dss_device *dssdev, ++ struct omap_video_timings *timings) ++{ ++ *timings = dssdev->panel.timings; ++} ++ ++static int dpi_display_set_update_mode(struct omap_dss_device *dssdev, ++ enum omap_dss_update_mode mode) ++{ ++ if (mode == OMAP_DSS_UPDATE_MANUAL) ++ return -EINVAL; ++ ++ if (mode == OMAP_DSS_UPDATE_DISABLED) { ++ dispc_enable_lcd_out(0); ++ dpi.update_enabled = 0; ++ } else { ++ dispc_enable_lcd_out(1); ++ dpi.update_enabled = 1; ++ } ++ ++ return 0; ++} ++ ++static enum omap_dss_update_mode dpi_display_get_update_mode( ++ struct omap_dss_device *dssdev) ++{ ++ return dpi.update_enabled ? OMAP_DSS_UPDATE_AUTO : ++ OMAP_DSS_UPDATE_DISABLED; ++} ++ ++int dpi_init_display(struct omap_dss_device *dssdev) ++{ ++ DSSDBG("init_display\n"); ++ ++ dssdev->enable = dpi_display_enable; ++ dssdev->disable = dpi_display_disable; ++ dssdev->suspend = dpi_display_suspend; ++ dssdev->resume = dpi_display_resume; ++ dssdev->set_timings = dpi_set_timings; ++ dssdev->check_timings = dpi_check_timings; ++ dssdev->get_timings = dpi_get_timings; ++ dssdev->set_update_mode = dpi_display_set_update_mode; ++ dssdev->get_update_mode = dpi_display_get_update_mode; ++ ++ return 0; ++} ++ ++int dpi_init(void) ++{ ++ return 0; ++} ++ ++void dpi_exit(void) ++{ ++} ++ +-- +1.6.2.4 + |