Commit 3a5b27bf authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://gitorious.org/linux-omap-dss2/linux

* 'for-linus' of git://gitorious.org/linux-omap-dss2/linux: (49 commits)
  OMAP: DSS2: Taal: Fix TE when resuming
  OMAP: DSS2: Taal: Fix ESD check
  OMAP: DSS2: OMAPFB: Constify some function parameters
  OMAP: DSS2: OMAPFB: install omapfb.h
  OMAP: DSS2: DSI: add error prints
  OMAP: DSS2: TPO-TD03MTEA1: fix function names
  OMAP: DSS2: DSI: add dsi_vc_dcs_read_2() helper
  OMAP: DSS2: OMAPFB: Remove FB_OMAP2_FORCE_AUTO_UPDATE
  OMAP: DSS2: DSI: remove external TE support
  OMAP: DSS2: move timing functions
  OMAP: DSS2: move set/get_wss()
  OMAP: DSS2: move enable/disable/suspend/resume
  OMAP: DSS2: move update() and sync()
  OMAP: DSS2: move set/get_update_mode()
  OMAP: DSS2: move enable/get_te()
  OMAP: DSS2: move get_recommended_bpp()
  OMAP: DSS2: move get_resolution()
  OMAP: DSS2: move enable/disable_channel to overlay manager
  OMAP: DSS2: move wait_vsync()
  OMAP: DSS2: move get/set_rotate()
  ...
parents 5057bfaf 21df20fc
......@@ -541,10 +541,6 @@ static struct regulator_init_data sdp3430_vdac = {
/* VPLL2 for digital video outputs */
static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
{
.supply = "vdvi",
.dev = &sdp3430_lcd_device.dev,
},
{
.supply = "vdds_dsi",
.dev = &sdp3430_dss_device.dev,
......
......@@ -233,8 +233,12 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
void dsi_bus_lock(void);
void dsi_bus_unlock(void);
int dsi_vc_dcs_write(int channel, u8 *data, int len);
int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd);
int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param);
int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len);
int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen);
int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data);
int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data);
int dsi_vc_set_max_rx_packet_size(int channel, u16 len);
int dsi_vc_send_null(int channel);
int dsi_vc_send_bta_sync(int channel);
......@@ -367,6 +371,10 @@ struct omap_overlay_manager {
int (*apply)(struct omap_overlay_manager *mgr);
int (*wait_for_go)(struct omap_overlay_manager *mgr);
int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
int (*enable)(struct omap_overlay_manager *mgr);
int (*disable)(struct omap_overlay_manager *mgr);
};
struct omap_dss_device {
......@@ -426,16 +434,11 @@ struct omap_dss_device {
int acb; /* ac-bias pin frequency */
enum omap_panel_config config;
u8 recommended_bpp;
struct omap_dss_device *ctrl;
} panel;
struct {
u8 pixel_size;
struct rfbi_timings rfbi_timings;
struct omap_dss_device *panel;
} ctrl;
int reset_gpio;
......@@ -460,49 +463,6 @@ struct omap_dss_device {
enum omap_dss_display_state state;
int (*enable)(struct omap_dss_device *dssdev);
void (*disable)(struct omap_dss_device *dssdev);
int (*suspend)(struct omap_dss_device *dssdev);
int (*resume)(struct omap_dss_device *dssdev);
void (*get_resolution)(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres);
int (*get_recommended_bpp)(struct omap_dss_device *dssdev);
int (*check_timings)(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
void (*set_timings)(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
void (*get_timings)(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
int (*update)(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h);
int (*sync)(struct omap_dss_device *dssdev);
int (*wait_vsync)(struct omap_dss_device *dssdev);
int (*set_update_mode)(struct omap_dss_device *dssdev,
enum omap_dss_update_mode);
enum omap_dss_update_mode (*get_update_mode)
(struct omap_dss_device *dssdev);
int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
int (*get_te)(struct omap_dss_device *dssdev);
u8 (*get_rotate)(struct omap_dss_device *dssdev);
int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
bool (*get_mirror)(struct omap_dss_device *dssdev);
int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
int (*run_test)(struct omap_dss_device *dssdev, int test);
int (*memory_read)(struct omap_dss_device *dssdev,
void *buf, size_t size,
u16 x, u16 y, u16 w, u16 h);
int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
u32 (*get_wss)(struct omap_dss_device *dssdev);
/* platform specific */
int (*platform_enable)(struct omap_dss_device *dssdev);
void (*platform_disable)(struct omap_dss_device *dssdev);
......@@ -522,11 +482,17 @@ struct omap_dss_driver {
int (*resume)(struct omap_dss_device *display);
int (*run_test)(struct omap_dss_device *display, int test);
void (*setup_update)(struct omap_dss_device *dssdev,
int (*set_update_mode)(struct omap_dss_device *dssdev,
enum omap_dss_update_mode);
enum omap_dss_update_mode (*get_update_mode)(
struct omap_dss_device *dssdev);
int (*update)(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h);
int (*sync)(struct omap_dss_device *dssdev);
int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
int (*wait_for_te)(struct omap_dss_device *dssdev);
int (*get_te)(struct omap_dss_device *dssdev);
u8 (*get_rotate)(struct omap_dss_device *dssdev);
int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
......@@ -537,6 +503,20 @@ struct omap_dss_driver {
int (*memory_read)(struct omap_dss_device *dssdev,
void *buf, size_t size,
u16 x, u16 y, u16 w, u16 h);
void (*get_resolution)(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres);
int (*get_recommended_bpp)(struct omap_dss_device *dssdev);
int (*check_timings)(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
void (*set_timings)(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
void (*get_timings)(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
u32 (*get_wss)(struct omap_dss_device *dssdev);
};
int omap_dss_register_driver(struct omap_dss_driver *);
......@@ -561,6 +541,10 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
int omap_dss_get_num_overlays(void);
struct omap_overlay *omap_dss_get_overlay(int num);
void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres);
int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
......@@ -572,4 +556,35 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
#define to_dss_device(x) container_of((x), struct omap_dss_device, dev)
void omapdss_dsi_vc_enable_hs(int channel, bool enable);
int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable);
int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
u16 *x, u16 *y, u16 *w, u16 *h);
int omap_dsi_update(struct omap_dss_device *dssdev,
int channel,
u16 x, u16 y, u16 w, u16 h,
void (*callback)(int, void *), void *data);
int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
void omapdss_dsi_display_disable(struct omap_dss_device *dssdev);
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
void dpi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
int dpi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
int omapdss_sdi_display_enable(struct omap_dss_device *dssdev);
void omapdss_sdi_display_disable(struct omap_dss_device *dssdev);
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev);
void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev);
int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
u16 *x, u16 *y, u16 *w, u16 *h);
int omap_rfbi_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h,
void (*callback)(void *), void *data);
#endif
......@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/lcd.h>
#include <plat/board-ams-delta.h>
#include <mach/hardware.h>
......@@ -32,6 +33,71 @@
#define AMS_DELTA_DEFAULT_CONTRAST 112
#define AMS_DELTA_MAX_CONTRAST 0x00FF
#define AMS_DELTA_LCD_POWER 0x0100
/* LCD class device section */
static int ams_delta_lcd;
static int ams_delta_lcd_set_power(struct lcd_device *dev, int power)
{
if (power == FB_BLANK_UNBLANK) {
if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER)) {
omap_writeb(ams_delta_lcd & AMS_DELTA_MAX_CONTRAST,
OMAP_PWL_ENABLE);
omap_writeb(1, OMAP_PWL_CLK_ENABLE);
ams_delta_lcd |= AMS_DELTA_LCD_POWER;
}
} else {
if (ams_delta_lcd & AMS_DELTA_LCD_POWER) {
omap_writeb(0, OMAP_PWL_ENABLE);
omap_writeb(0, OMAP_PWL_CLK_ENABLE);
ams_delta_lcd &= ~AMS_DELTA_LCD_POWER;
}
}
return 0;
}
static int ams_delta_lcd_set_contrast(struct lcd_device *dev, int value)
{
if ((value >= 0) && (value <= AMS_DELTA_MAX_CONTRAST)) {
omap_writeb(value, OMAP_PWL_ENABLE);
ams_delta_lcd &= ~AMS_DELTA_MAX_CONTRAST;
ams_delta_lcd |= value;
}
return 0;
}
#ifdef CONFIG_LCD_CLASS_DEVICE
static int ams_delta_lcd_get_power(struct lcd_device *dev)
{
if (ams_delta_lcd & AMS_DELTA_LCD_POWER)
return FB_BLANK_UNBLANK;
else
return FB_BLANK_POWERDOWN;
}
static int ams_delta_lcd_get_contrast(struct lcd_device *dev)
{
if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER))
return 0;
return ams_delta_lcd & AMS_DELTA_MAX_CONTRAST;
}
static struct lcd_ops ams_delta_lcd_ops = {
.get_power = ams_delta_lcd_get_power,
.set_power = ams_delta_lcd_set_power,
.get_contrast = ams_delta_lcd_get_contrast,
.set_contrast = ams_delta_lcd_set_contrast,
};
#endif
/* omapfb panel section */
static int ams_delta_panel_init(struct lcd_panel *panel,
struct omapfb_device *fbdev)
{
......@@ -48,10 +114,6 @@ static int ams_delta_panel_enable(struct lcd_panel *panel)
AMS_DELTA_LATCH2_LCD_NDISP);
ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN,
AMS_DELTA_LATCH2_LCD_VBLEN);
omap_writeb(1, OMAP_PWL_CLK_ENABLE);
omap_writeb(AMS_DELTA_DEFAULT_CONTRAST, OMAP_PWL_ENABLE);
return 0;
}
......@@ -91,8 +153,31 @@ static struct lcd_panel ams_delta_panel = {
.get_caps = ams_delta_panel_get_caps,
};
/* platform driver section */
static int ams_delta_panel_probe(struct platform_device *pdev)
{
struct lcd_device *lcd_device = NULL;
#ifdef CONFIG_LCD_CLASS_DEVICE
int ret;
lcd_device = lcd_device_register("omapfb", &pdev->dev, NULL,
&ams_delta_lcd_ops);
if (IS_ERR(lcd_device)) {
ret = PTR_ERR(lcd_device);
dev_err(&pdev->dev, "failed to register device\n");
return ret;
}
platform_set_drvdata(pdev, lcd_device);
lcd_device->props.max_contrast = AMS_DELTA_MAX_CONTRAST;
#endif
ams_delta_lcd_set_contrast(lcd_device, AMS_DELTA_DEFAULT_CONTRAST);
ams_delta_lcd_set_power(lcd_device, FB_BLANK_UNBLANK);
omapfb_register_panel(&ams_delta_panel);
return 0;
}
......
......@@ -486,9 +486,10 @@ static int set_color_mode(struct omapfb_plane_struct *plane,
return 0;
case 12:
var->bits_per_pixel = 16;
plane->color_mode = OMAPFB_COLOR_RGB444;
return 0;
case 16:
if (plane->fbdev->panel->bpp == 12)
plane->color_mode = OMAPFB_COLOR_RGB444;
else
plane->color_mode = OMAPFB_COLOR_RGB565;
return 0;
default:
......
......@@ -13,10 +13,28 @@ config PANEL_SHARP_LS037V7DW01
help
LCD Panel used in TI's SDP3430 and EVM boards
config PANEL_SHARP_LQ043T1DG01
tristate "Sharp LQ043T1DG01 LCD Panel"
depends on OMAP2_DSS
help
LCD Panel used in TI's OMAP3517 EVM boards
config PANEL_TAAL
tristate "Taal DSI Panel"
depends on OMAP2_DSS_DSI
help
Taal DSI command mode panel from TPO.
config PANEL_TOPPOLY_TDO35S
tristate "Toppoly TDO35S LCD Panel support"
depends on OMAP2_DSS
help
LCD Panel used in CM-T35
config PANEL_TPO_TD043MTEA1
tristate "TPO TD043MTEA1 LCD Panel"
depends on OMAP2_DSS && I2C
help
LCD Panel used in OMAP3 Pandora
endmenu
obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o
obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o
obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o
obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
......@@ -35,6 +35,35 @@ static struct omap_video_timings generic_panel_timings = {
.vbp = 7,
};
static int generic_panel_power_on(struct omap_dss_device *dssdev)
{
int r;
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
if (dssdev->platform_enable) {
r = dssdev->platform_enable(dssdev);
if (r)
goto err1;
}
return 0;
err1:
omapdss_dpi_display_disable(dssdev);
err0:
return r;
}
static void generic_panel_power_off(struct omap_dss_device *dssdev)
{
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
omapdss_dpi_display_disable(dssdev);
}
static int generic_panel_probe(struct omap_dss_device *dssdev)
{
dssdev->panel.config = OMAP_DSS_LCD_TFT;
......@@ -51,27 +80,40 @@ static int generic_panel_enable(struct omap_dss_device *dssdev)
{
int r = 0;
if (dssdev->platform_enable)
r = dssdev->platform_enable(dssdev);
r = generic_panel_power_on(dssdev);
if (r)
return r;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return 0;
}
static void generic_panel_disable(struct omap_dss_device *dssdev)
{
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
generic_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
static int generic_panel_suspend(struct omap_dss_device *dssdev)
{
generic_panel_disable(dssdev);
generic_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
return 0;
}
static int generic_panel_resume(struct omap_dss_device *dssdev)
{
return generic_panel_enable(dssdev);
int r = 0;
r = generic_panel_power_on(dssdev);
if (r)
return r;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return 0;
}
static struct omap_dss_driver generic_driver = {
......
/*
* LCD panel driver for Sharp LQ043T1DG01
*
* Copyright (C) 2009 Texas Instruments Inc
* Author: Vaibhav Hiremath <hvaibhav@ti.com>
*
* 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/>.
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <plat/display.h>
static struct omap_video_timings sharp_lq_timings = {
.x_res = 480,
.y_res = 272,
.pixel_clock = 9000,
.hsw = 42,
.hfp = 3,
.hbp = 2,
.vsw = 11,
.vfp = 3,
.vbp = 2,
};
static int sharp_lq_panel_power_on(struct omap_dss_device *dssdev)
{
int r;
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
/* wait couple of vsyncs until enabling the LCD */
msleep(50);
if (dssdev->platform_enable) {
r = dssdev->platform_enable(dssdev);
if (r)
goto err1;
}
return 0;
err1:
omapdss_dpi_display_disable(dssdev);
err0:
return r;
}
static void sharp_lq_panel_power_off(struct omap_dss_device *dssdev)
{
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
/* wait at least 5 vsyncs after disabling the LCD */
msleep(100);
omapdss_dpi_display_disable(dssdev);
}
static int sharp_lq_panel_probe(struct omap_dss_device *dssdev)
{
dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO;
dssdev->panel.acb = 0x0;
dssdev->panel.timings = sharp_lq_timings;
return 0;
}
static void sharp_lq_panel_remove(struct omap_dss_device *dssdev)
{
}
static int sharp_lq_panel_enable(struct omap_dss_device *dssdev)
{
int r = 0;
r = sharp_lq_panel_power_on(dssdev);
if (r)
return r;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return 0;
}
static void sharp_lq_panel_disable(struct omap_dss_device *dssdev)
{
sharp_lq_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
static int sharp_lq_panel_suspend(struct omap_dss_device *dssdev)
{
sharp_lq_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
return 0;
}
static int sharp_lq_panel_resume(struct omap_dss_device *dssdev)
{
int r = 0;
r = sharp_lq_panel_power_on(dssdev);
if (r)
return r;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return 0;
}
static struct omap_dss_driver sharp_lq_driver = {
.probe = sharp_lq_panel_probe,
.remove = sharp_lq_panel_remove,
.enable = sharp_lq_panel_enable,
.disable = sharp_lq_panel_disable,
.suspend = sharp_lq_panel_suspend,
.resume = sharp_lq_panel_resume,
.driver = {
.name = "sharp_lq_panel",
.owner = THIS_MODULE,
},
};
static int __init sharp_lq_panel_drv_init(void)
{
return omap_dss_register_driver(&sharp_lq_driver);
}
static void __exit sharp_lq_panel_drv_exit(void)
{
omap_dss_unregister_driver(&sharp_lq_driver);
}
module_init(sharp_lq_panel_drv_init);
module_exit(sharp_lq_panel_drv_exit);
MODULE_LICENSE("GPL");
......@@ -20,19 +20,10 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/regulator/consumer.h>
#include <linux/err.h>
#include <plat/display.h>
struct sharp_data {
/* XXX This regulator should actually be in SDP board file, not here,
* as it doesn't actually power the LCD, but something else that
* affects the output to LCD (I think. Somebody clarify). It doesn't do
* harm here, as SDP is the only board using this currently */
struct regulator *vdvi_reg;
};
static struct omap_video_timings sharp_ls_timings = {
.x_res = 480,
.y_res = 640,
......@@ -50,77 +41,81 @@ static struct omap_video_timings sharp_ls_timings = {
static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
{
struct sharp_data *sd;
dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
OMAP_DSS_LCD_IHS;
dssdev->panel.acb = 0x28;
dssdev->panel.timings = sharp_ls_timings;
sd = kzalloc(sizeof(*sd), GFP_KERNEL);
if (!sd)
return -ENOMEM;
dev_set_drvdata(&dssdev->dev, sd);
sd->vdvi_reg = regulator_get(&dssdev->dev, "vdvi");
if (IS_ERR(sd->vdvi_reg)) {
kfree(sd);
pr_err("failed to get VDVI regulator\n");
return PTR_ERR(sd->vdvi_reg);
}
return 0;
}
static void sharp_ls_panel_remove(struct omap_dss_device *dssdev)
{
struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
regulator_put(sd->vdvi_reg);
kfree(sd);
}
static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
static int sharp_ls_power_on(struct omap_dss_device *dssdev)
{
struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
int r = 0;
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
/* wait couple of vsyncs until enabling the LCD */
msleep(50);
regulator_enable(sd->vdvi_reg);
if (dssdev->platform_enable)
if (dssdev->platform_enable) {
r = dssdev->platform_enable(dssdev);
if (r)
goto err1;
}
return 0;
err1:
omapdss_dpi_display_disable(dssdev);
err0:
return r;
}
static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
static void sharp_ls_power_off(struct omap_dss_device *dssdev)
{
struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
regulator_disable(sd->vdvi_reg);
/* wait at least 5 vsyncs after disabling the LCD */
msleep(100);
omapdss_dpi_display_disable(dssdev);
}
static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
{
int r;
r = sharp_ls_power_on(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return r;
}
static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
{
sharp_ls_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev)
{
sharp_ls_panel_disable(dssdev);
sharp_ls_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
return 0;
}
static int sharp_ls_panel_resume(struct omap_dss_device *dssdev)
{
return sharp_ls_panel_enable(dssdev);
int r;
r = sharp_ls_power_on(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return r;
}
static struct omap_dss_driver sharp_ls_driver = {
......
This diff is collapsed.
/*
* LCD panel driver for Toppoly TDO35S
*
* Copyright (C) 2009 CompuLab, Ltd.
* Author: Mike Rapoport <mike@compulab.co.il>
*
* Based on generic panel support
* Copyright (C) 2008 Nokia Corporation
* Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
*
* 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/>.
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <plat/display.h>
static struct omap_video_timings toppoly_tdo_panel_timings = {
/* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
.x_res = 480,
.y_res = 640,
.pixel_clock = 26000,
.hfp = 104,
.hsw = 8,
.hbp = 8,
.vfp = 4,
.vsw = 2,
.vbp = 2,
};
static int toppoly_tdo_panel_power_on(struct omap_dss_device *dssdev)
{
int r;
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
if (dssdev->platform_enable) {
r = dssdev->platform_enable(dssdev);
if (r)
goto err1;
}
return 0;
err1:
omapdss_dpi_display_disable(dssdev);
err0:
return r;
}
static void toppoly_tdo_panel_power_off(struct omap_dss_device *dssdev)
{
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
omapdss_dpi_display_disable(dssdev);
}
static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev)
{
dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
OMAP_DSS_LCD_IHS;
dssdev->panel.timings = toppoly_tdo_panel_timings;
return 0;
}
static void toppoly_tdo_panel_remove(struct omap_dss_device *dssdev)
{
}
static int toppoly_tdo_panel_enable(struct omap_dss_device *dssdev)
{
int r = 0;
r = toppoly_tdo_panel_power_on(dssdev);
if (r)
return r;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return 0;
}
static void toppoly_tdo_panel_disable(struct omap_dss_device *dssdev)
{
toppoly_tdo_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
static int toppoly_tdo_panel_suspend(struct omap_dss_device *dssdev)
{
toppoly_tdo_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
return 0;
}
static int toppoly_tdo_panel_resume(struct omap_dss_device *dssdev)
{
int r = 0;
r = toppoly_tdo_panel_power_on(dssdev);
if (r)
return r;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return 0;
}
static struct omap_dss_driver generic_driver = {
.probe = toppoly_tdo_panel_probe,
.remove = toppoly_tdo_panel_remove,
.enable = toppoly_tdo_panel_enable,
.disable = toppoly_tdo_panel_disable,
.suspend = toppoly_tdo_panel_suspend,
.resume = toppoly_tdo_panel_resume,
.driver = {
.name = "toppoly_tdo35s_panel",
.owner = THIS_MODULE,
},
};
static int __init toppoly_tdo_panel_drv_init(void)
{
return omap_dss_register_driver(&generic_driver);
}
static void __exit toppoly_tdo_panel_drv_exit(void)
{
omap_dss_unregister_driver(&generic_driver);
}
module_init(toppoly_tdo_panel_drv_init);
module_exit(toppoly_tdo_panel_drv_exit);
MODULE_LICENSE("GPL");
This diff is collapsed.
......@@ -30,19 +30,29 @@ config OMAP2_DSS_COLLECT_IRQ_STATS
depends on OMAP2_DSS_DEBUG_SUPPORT
default n
help
Collect DSS IRQ statistics, printable via debugfs
Collect DSS IRQ statistics, printable via debugfs.
The statistics can be found from
<debugfs>/omapdss/dispc_irq for DISPC interrupts, and
<debugfs>/omapdss/dsi_irq for DSI interrupts.
config OMAP2_DSS_RFBI
bool "RFBI support"
default n
help
MIPI DBI, or RFBI (Remote Framebuffer Interface), support.
MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas
Instrument's terminology).
DBI is a bus between the host processor and a peripheral,
such as a display or a framebuffer chip.
See http://www.mipi.org/ for DBI spesifications.
config OMAP2_DSS_VENC
bool "VENC support"
default y
help
OMAP Video Encoder support.
OMAP Video Encoder support for S-Video and composite TV-out.
config OMAP2_DSS_SDI
bool "SDI support"
......@@ -51,12 +61,20 @@ config OMAP2_DSS_SDI
help
SDI (Serial Display Interface) support.
SDI is a high speed one-way display serial bus between the host
processor and a display.
config OMAP2_DSS_DSI
bool "DSI support"
depends on ARCH_OMAP3
default n
help
MIPI DSI support.
MIPI DSI (Display Serial Interface) support.
DSI is a high speed half-duplex serial interface between the host
processor and a peripheral, such as a display or a framebuffer chip.
See http://www.mipi.org/ for DSI spesifications.
config OMAP2_DSS_USE_DSI_PLL
bool "Use DSI PLL for PCLK (EXPERIMENTAL)"
......
......@@ -31,6 +31,7 @@
#include <linux/debugfs.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/regulator/consumer.h>
#include <plat/display.h>
#include <plat/clock.h>
......@@ -47,6 +48,10 @@ static struct {
struct clk *dss_54m_fck;
struct clk *dss_96m_fck;
unsigned num_clks_enabled;
struct regulator *vdds_dsi_reg;
struct regulator *vdds_sdi_reg;
struct regulator *vdda_dac_reg;
} core;
static void dss_clk_enable_all_no_ctx(void);
......@@ -284,9 +289,11 @@ static void dss_clk_enable_no_ctx(enum dss_clock clks)
void dss_clk_enable(enum dss_clock clks)
{
bool check_ctx = core.num_clks_enabled == 0;
dss_clk_enable_no_ctx(clks);
if (cpu_is_omap34xx() && dss_need_ctx_restore())
if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
restore_all_ctx();
}
......@@ -352,6 +359,50 @@ static void dss_clk_disable_all(void)
dss_clk_disable(clks);
}
/* REGULATORS */
struct regulator *dss_get_vdds_dsi(void)
{
struct regulator *reg;
if (core.vdds_dsi_reg != NULL)
return core.vdds_dsi_reg;
reg = regulator_get(&core.pdev->dev, "vdds_dsi");
if (!IS_ERR(reg))
core.vdds_dsi_reg = reg;
return reg;
}
struct regulator *dss_get_vdds_sdi(void)
{
struct regulator *reg;
if (core.vdds_sdi_reg != NULL)
return core.vdds_sdi_reg;
reg = regulator_get(&core.pdev->dev, "vdds_sdi");
if (!IS_ERR(reg))
core.vdds_sdi_reg = reg;
return reg;
}
struct regulator *dss_get_vdda_dac(void)
{
struct regulator *reg;
if (core.vdda_dac_reg != NULL)
return core.vdda_dac_reg;
reg = regulator_get(&core.pdev->dev, "vdda_dac");
if (!IS_ERR(reg))
core.vdda_dac_reg = reg;
return reg;
}
/* DEBUGFS */
#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
static void dss_debug_dump_clocks(struct seq_file *s)
......@@ -397,10 +448,12 @@ static int dss_initialize_debugfs(void)
debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
&dss_debug_dump_clocks, &dss_debug_fops);
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir,
&dispc_dump_irqs, &dss_debug_fops);
#endif
#ifdef CONFIG_OMAP2_DSS_DSI
#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS)
debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir,
&dsi_dump_irqs, &dss_debug_fops);
#endif
......@@ -473,7 +526,7 @@ static int omap_dss_probe(struct platform_device *pdev)
}
#endif
r = dpi_init();
r = dpi_init(pdev);
if (r) {
DSSERR("Failed to initialize dpi\n");
goto fail0;
......@@ -718,16 +771,14 @@ static int dss_driver_probe(struct device *dev)
dss_init_device(core.pdev, dssdev);
/* skip this if the device is behind a ctrl */
if (!dssdev->panel.ctrl) {
force = pdata->default_device == dssdev;
dss_recheck_connections(dssdev, force);
}
r = dssdrv->probe(dssdev);
if (r) {
DSSERR("driver probe failed: %d\n", r);
dss_uninit_device(core.pdev, dssdev);
return r;
}
......@@ -760,6 +811,13 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
dssdriver->driver.bus = &dss_bus_type;
dssdriver->driver.probe = dss_driver_probe;
dssdriver->driver.remove = dss_driver_remove;
if (dssdriver->get_resolution == NULL)
dssdriver->get_resolution = omapdss_default_get_resolution;
if (dssdriver->get_recommended_bpp == NULL)
dssdriver->get_recommended_bpp =
omapdss_default_get_recommended_bpp;
return driver_register(&dssdriver->driver);
}
EXPORT_SYMBOL(omap_dss_register_driver);
......@@ -808,8 +866,6 @@ static void omap_dss_dev_release(struct device *dev)
int omap_dss_register_device(struct omap_dss_device *dssdev)
{
static int dev_num;
static int panel_num;
int r;
WARN_ON(!dssdev->driver_name);
......@@ -818,36 +874,12 @@ int omap_dss_register_device(struct omap_dss_device *dssdev)
dssdev->dev.parent = &dss_bus;
dssdev->dev.release = omap_dss_dev_release;
dev_set_name(&dssdev->dev, "display%d", dev_num++);
r = device_register(&dssdev->dev);
if (r)
return r;
if (dssdev->ctrl.panel) {
struct omap_dss_device *panel = dssdev->ctrl.panel;
panel->panel.ctrl = dssdev;
reset_device(&panel->dev, 1);
panel->dev.bus = &dss_bus_type;
panel->dev.parent = &dssdev->dev;
panel->dev.release = omap_dss_dev_release;
dev_set_name(&panel->dev, "panel%d", panel_num++);
r = device_register(&panel->dev);
if (r)
return r;
}
return 0;
return device_register(&dssdev->dev);
}
void omap_dss_unregister_device(struct omap_dss_device *dssdev)
{
device_unregister(&dssdev->dev);
if (dssdev->ctrl.panel) {
struct omap_dss_device *panel = dssdev->ctrl.panel;
device_unregister(&panel->dev);
}
}
/* BUS */
......@@ -901,6 +933,21 @@ static int __init omap_dss_init(void)
static void __exit omap_dss_exit(void)
{
if (core.vdds_dsi_reg != NULL) {
regulator_put(core.vdds_dsi_reg);
core.vdds_dsi_reg = NULL;
}
if (core.vdds_sdi_reg != NULL) {
regulator_put(core.vdds_sdi_reg);
core.vdds_sdi_reg = NULL;
}
if (core.vdda_dac_reg != NULL) {
regulator_put(core.vdda_dac_reg);
core.vdda_dac_reg = NULL;
}
platform_driver_unregister(&omap_dss_driver);
omap_dss_bus_unregister();
......
......@@ -1725,7 +1725,7 @@ static void _enable_lcd_out(bool enable)
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
}
void dispc_enable_lcd_out(bool enable)
static void dispc_enable_lcd_out(bool enable)
{
struct completion frame_done_completion;
bool is_on;
......@@ -1772,7 +1772,7 @@ static void _enable_digit_out(bool enable)
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
}
void dispc_enable_digit_out(bool enable)
static void dispc_enable_digit_out(bool enable)
{
struct completion frame_done_completion;
int r;
......@@ -1836,6 +1836,26 @@ void dispc_enable_digit_out(bool enable)
enable_clocks(0);
}
bool dispc_is_channel_enabled(enum omap_channel channel)
{
if (channel == OMAP_DSS_CHANNEL_LCD)
return !!REG_GET(DISPC_CONTROL, 0, 0);
else if (channel == OMAP_DSS_CHANNEL_DIGIT)
return !!REG_GET(DISPC_CONTROL, 1, 1);
else
BUG();
}
void dispc_enable_channel(enum omap_channel channel, bool enable)
{
if (channel == OMAP_DSS_CHANNEL_LCD)
dispc_enable_lcd_out(enable);
else if (channel == OMAP_DSS_CHANNEL_DIGIT)
dispc_enable_digit_out(enable);
else
BUG();
}
void dispc_lcd_enable_signal_polarity(bool act_high)
{
enable_clocks(1);
......@@ -2198,7 +2218,7 @@ unsigned long dispc_fclk_rate(void)
{
unsigned long r = 0;
if (dss_get_dispc_clk_source() == 0)
if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK)
r = dss_clk_get_rate(DSS_CLK_FCK1);
else
#ifdef CONFIG_OMAP2_DSS_DSI
......@@ -2251,7 +2271,7 @@ void dispc_dump_clocks(struct seq_file *s)
seq_printf(s, "- DISPC -\n");
seq_printf(s, "dispc fclk source = %s\n",
dss_get_dispc_clk_source() == 0 ?
dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
"dss1_alwon_fclk" : "dsi1_pll_fclk");
seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
......@@ -2301,8 +2321,6 @@ void dispc_dump_irqs(struct seq_file *s)
PIS(WAKEUP);
#undef PIS
}
#else
void dispc_dump_irqs(struct seq_file *s) { }
#endif
void dispc_dump_regs(struct seq_file *s)
......@@ -2854,12 +2872,13 @@ static void dispc_error_worker(struct work_struct *work)
manager = mgr;
enable = mgr->device->state ==
OMAP_DSS_DISPLAY_ACTIVE;
mgr->device->disable(mgr->device);
mgr->device->driver->disable(mgr->device);
break;
}
}
if (manager) {
struct omap_dss_device *dssdev = manager->device;
for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
struct omap_overlay *ovl;
ovl = omap_dss_get_overlay(i);
......@@ -2874,7 +2893,7 @@ static void dispc_error_worker(struct work_struct *work)
dispc_go(manager->id);
mdelay(50);
if (enable)
manager->device->enable(manager->device);
dssdev->driver->enable(dssdev);
}
}
......@@ -2892,12 +2911,13 @@ static void dispc_error_worker(struct work_struct *work)
manager = mgr;
enable = mgr->device->state ==
OMAP_DSS_DISPLAY_ACTIVE;
mgr->device->disable(mgr->device);
mgr->device->driver->disable(mgr->device);
break;
}
}
if (manager) {
struct omap_dss_device *dssdev = manager->device;
for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
struct omap_overlay *ovl;
ovl = omap_dss_get_overlay(i);
......@@ -2912,7 +2932,7 @@ static void dispc_error_worker(struct work_struct *work)
dispc_go(manager->id);
mdelay(50);
if (enable)
manager->device->enable(manager->device);
dssdev->driver->enable(dssdev);
}
}
......@@ -2923,7 +2943,7 @@ static void dispc_error_worker(struct work_struct *work)
mgr = omap_dss_get_overlay_manager(i);
if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC)
mgr->device->disable(mgr->device);
mgr->device->driver->disable(mgr->device);
}
}
......
......@@ -53,11 +53,11 @@ static ssize_t display_enabled_store(struct device *dev,
if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
if (enabled) {
r = dssdev->enable(dssdev);
r = dssdev->driver->enable(dssdev);
if (r)
return r;
} else {
dssdev->disable(dssdev);
dssdev->driver->disable(dssdev);
}
}
......@@ -69,8 +69,8 @@ static ssize_t display_upd_mode_show(struct device *dev,
{
struct omap_dss_device *dssdev = to_dss_device(dev);
enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO;
if (dssdev->get_update_mode)
mode = dssdev->get_update_mode(dssdev);
if (dssdev->driver->get_update_mode)
mode = dssdev->driver->get_update_mode(dssdev);
return snprintf(buf, PAGE_SIZE, "%d\n", mode);
}
......@@ -94,7 +94,7 @@ static ssize_t display_upd_mode_store(struct device *dev,
return -EINVAL;
}
r = dssdev->set_update_mode(dssdev, mode);
r = dssdev->driver->set_update_mode(dssdev, mode);
if (r)
return r;
......@@ -106,7 +106,8 @@ static ssize_t display_tear_show(struct device *dev,
{
struct omap_dss_device *dssdev = to_dss_device(dev);
return snprintf(buf, PAGE_SIZE, "%d\n",
dssdev->get_te ? dssdev->get_te(dssdev) : 0);
dssdev->driver->get_te ?
dssdev->driver->get_te(dssdev) : 0);
}
static ssize_t display_tear_store(struct device *dev,
......@@ -116,12 +117,12 @@ static ssize_t display_tear_store(struct device *dev,
unsigned long te;
int r;
if (!dssdev->enable_te || !dssdev->get_te)
if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
return -ENOENT;
te = simple_strtoul(buf, NULL, 0);
r = dssdev->enable_te(dssdev, te);
r = dssdev->driver->enable_te(dssdev, te);
if (r)
return r;
......@@ -134,10 +135,10 @@ static ssize_t display_timings_show(struct device *dev,
struct omap_dss_device *dssdev = to_dss_device(dev);
struct omap_video_timings t;
if (!dssdev->get_timings)
if (!dssdev->driver->get_timings)
return -ENOENT;
dssdev->get_timings(dssdev, &t);
dssdev->driver->get_timings(dssdev, &t);
return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
t.pixel_clock,
......@@ -152,7 +153,7 @@ static ssize_t display_timings_store(struct device *dev,
struct omap_video_timings t;
int r, found;
if (!dssdev->set_timings || !dssdev->check_timings)
if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
return -ENOENT;
found = 0;
......@@ -171,11 +172,11 @@ static ssize_t display_timings_store(struct device *dev,
&t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
return -EINVAL;
r = dssdev->check_timings(dssdev, &t);
r = dssdev->driver->check_timings(dssdev, &t);
if (r)
return r;
dssdev->set_timings(dssdev, &t);
dssdev->driver->set_timings(dssdev, &t);
return size;
}
......@@ -185,9 +186,9 @@ static ssize_t display_rotate_show(struct device *dev,
{
struct omap_dss_device *dssdev = to_dss_device(dev);
int rotate;
if (!dssdev->get_rotate)
if (!dssdev->driver->get_rotate)
return -ENOENT;
rotate = dssdev->get_rotate(dssdev);
rotate = dssdev->driver->get_rotate(dssdev);
return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
}
......@@ -198,12 +199,12 @@ static ssize_t display_rotate_store(struct device *dev,
unsigned long rot;
int r;
if (!dssdev->set_rotate || !dssdev->get_rotate)
if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
return -ENOENT;
rot = simple_strtoul(buf, NULL, 0);
r = dssdev->set_rotate(dssdev, rot);
r = dssdev->driver->set_rotate(dssdev, rot);
if (r)
return r;
......@@ -215,9 +216,9 @@ static ssize_t display_mirror_show(struct device *dev,
{
struct omap_dss_device *dssdev = to_dss_device(dev);
int mirror;
if (!dssdev->get_mirror)
if (!dssdev->driver->get_mirror)
return -ENOENT;
mirror = dssdev->get_mirror(dssdev);
mirror = dssdev->driver->get_mirror(dssdev);
return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
}
......@@ -228,12 +229,12 @@ static ssize_t display_mirror_store(struct device *dev,
unsigned long mirror;
int r;
if (!dssdev->set_mirror || !dssdev->get_mirror)
if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
return -ENOENT;
mirror = simple_strtoul(buf, NULL, 0);
r = dssdev->set_mirror(dssdev, mirror);
r = dssdev->driver->set_mirror(dssdev, mirror);
if (r)
return r;
......@@ -246,10 +247,10 @@ static ssize_t display_wss_show(struct device *dev,
struct omap_dss_device *dssdev = to_dss_device(dev);
unsigned int wss;
if (!dssdev->get_wss)
if (!dssdev->driver->get_wss)
return -ENOENT;
wss = dssdev->get_wss(dssdev);
wss = dssdev->driver->get_wss(dssdev);
return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
}
......@@ -261,7 +262,7 @@ static ssize_t display_wss_store(struct device *dev,
unsigned long wss;
int r;
if (!dssdev->get_wss || !dssdev->set_wss)
if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
return -ENOENT;
if (strict_strtoul(buf, 0, &wss))
......@@ -270,7 +271,7 @@ static ssize_t display_wss_store(struct device *dev,
if (wss > 0xfffff)
return -EINVAL;
r = dssdev->set_wss(dssdev, wss);
r = dssdev->driver->set_wss(dssdev, wss);
if (r)
return r;
......@@ -303,12 +304,13 @@ static struct device_attribute *display_sysfs_attrs[] = {
NULL
};
static void default_get_resolution(struct omap_dss_device *dssdev,
void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres)
{
*xres = dssdev->panel.timings.x_res;
*yres = dssdev->panel.timings.y_res;
}
EXPORT_SYMBOL(omapdss_default_get_resolution);
void default_get_overlay_fifo_thresholds(enum omap_plane plane,
u32 fifo_size, enum omap_burst_size *burst_size,
......@@ -323,24 +325,8 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane,
*fifo_low = fifo_size - burst_size_bytes;
}
static int default_wait_vsync(struct omap_dss_device *dssdev)
int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
{
unsigned long timeout = msecs_to_jiffies(500);
u32 irq;
if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
irq = DISPC_IRQ_EVSYNC_ODD;
else
irq = DISPC_IRQ_VSYNC;
return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
}
static int default_get_recommended_bpp(struct omap_dss_device *dssdev)
{
if (dssdev->panel.recommended_bpp)
return dssdev->panel.recommended_bpp;
switch (dssdev->type) {
case OMAP_DISPLAY_TYPE_DPI:
if (dssdev->phy.dpi.data_lines == 24)
......@@ -362,6 +348,7 @@ static int default_get_recommended_bpp(struct omap_dss_device *dssdev)
BUG();
}
}
EXPORT_SYMBOL(omapdss_default_get_recommended_bpp);
/* Checks if replication logic should be used. Only use for active matrix,
* when overlay is in RGB12U or RGB16 mode, and LCD interface is
......@@ -425,10 +412,6 @@ void dss_init_device(struct platform_device *pdev,
return;
}
dssdev->get_resolution = default_get_resolution;
dssdev->get_recommended_bpp = default_get_recommended_bpp;
dssdev->wait_vsync = default_wait_vsync;
switch (dssdev->type) {
case OMAP_DISPLAY_TYPE_DPI:
r = dpi_init_display(dssdev);
......@@ -502,13 +485,13 @@ static int dss_suspend_device(struct device *dev, void *data)
return 0;
}
if (!dssdev->suspend) {
if (!dssdev->driver->suspend) {
DSSERR("display '%s' doesn't implement suspend\n",
dssdev->name);
return -ENOSYS;
}
r = dssdev->suspend(dssdev);
r = dssdev->driver->suspend(dssdev);
if (r)
return r;
......@@ -537,8 +520,8 @@ static int dss_resume_device(struct device *dev, void *data)
int r;
struct omap_dss_device *dssdev = to_dss_device(dev);
if (dssdev->activate_after_resume && dssdev->resume) {
r = dssdev->resume(dssdev);
if (dssdev->activate_after_resume && dssdev->driver->resume) {
r = dssdev->driver->resume(dssdev);
if (r)
return r;
}
......@@ -558,7 +541,7 @@ int dss_resume_all_devices(void)
static int dss_disable_device(struct device *dev, void *data)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
dssdev->disable(dssdev);
dssdev->driver->disable(dssdev);
return 0;
}
......@@ -591,10 +574,6 @@ struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from)
int match(struct device *dev, void *data)
{
/* skip panels connected to controllers */
if (to_dss_device(dev)->panel.ctrl)
return 0;
return 1;
}
......@@ -626,45 +605,21 @@ EXPORT_SYMBOL(omap_dss_find_device);
int omap_dss_start_device(struct omap_dss_device *dssdev)
{
int r;
if (!dssdev->driver) {
DSSDBG("no driver\n");
r = -ENODEV;
goto err0;
}
if (dssdev->ctrl.panel && !dssdev->ctrl.panel->driver) {
DSSDBG("no panel driver\n");
r = -ENODEV;
goto err0;
return -ENODEV;
}
if (!try_module_get(dssdev->dev.driver->owner)) {
r = -ENODEV;
goto err0;
}
if (dssdev->ctrl.panel) {
if (!try_module_get(dssdev->ctrl.panel->dev.driver->owner)) {
r = -ENODEV;
goto err1;
}
return -ENODEV;
}
return 0;
err1:
module_put(dssdev->dev.driver->owner);
err0:
return r;
}
EXPORT_SYMBOL(omap_dss_start_device);
void omap_dss_stop_device(struct omap_dss_device *dssdev)
{
if (dssdev->ctrl.panel)
module_put(dssdev->ctrl.panel->dev.driver->owner);
module_put(dssdev->dev.driver->owner);
}
EXPORT_SYMBOL(omap_dss_stop_device);
......
......@@ -25,7 +25,10 @@
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <plat/display.h>
#include <plat/cpu.h>
......@@ -33,7 +36,7 @@
#include "dss.h"
static struct {
int update_enabled;
struct regulator *vdds_dsi_reg;
} dpi;
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
......@@ -53,7 +56,7 @@ static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req,
if (r)
return r;
dss_select_clk_source(0, 1);
dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK);
r = dispc_set_clock_div(&dispc_cinfo);
if (r)
......@@ -150,7 +153,7 @@ static int dpi_basic_init(struct omap_dss_device *dssdev)
return 0;
}
static int dpi_display_enable(struct omap_dss_device *dssdev)
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
{
int r;
......@@ -160,9 +163,9 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
goto err0;
}
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
DSSERR("display already enabled\n");
r = -EINVAL;
if (cpu_is_omap34xx()) {
r = regulator_enable(dpi.vdds_dsi_reg);
if (r)
goto err1;
}
......@@ -184,18 +187,10 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
mdelay(2);
dispc_enable_lcd_out(1);
r = dssdev->driver->enable(dssdev);
if (r)
goto err5;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
dssdev->manager->enable(dssdev->manager);
return 0;
err5:
dispc_enable_lcd_out(0);
err4:
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
dsi_pll_uninit();
......@@ -204,78 +199,35 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
#endif
err2:
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
if (cpu_is_omap34xx())
regulator_disable(dpi.vdds_dsi_reg);
err1:
omap_dss_stop_device(dssdev);
err0:
return r;
}
EXPORT_SYMBOL(omapdss_dpi_display_enable);
static int dpi_display_resume(struct omap_dss_device *dssdev);
static void dpi_display_disable(struct omap_dss_device *dssdev)
void omapdss_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);
dssdev->manager->disable(dssdev->manager);
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
dss_select_clk_source(0, 0);
dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
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;
if (cpu_is_omap34xx())
regulator_disable(dpi.vdds_dsi_reg);
omap_dss_stop_device(dssdev);
}
EXPORT_SYMBOL(omapdss_dpi_display_disable);
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,
void dpi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
DSSDBG("dpi_set_timings\n");
......@@ -285,8 +237,9 @@ static void dpi_set_timings(struct omap_dss_device *dssdev,
dispc_go(OMAP_DSS_CHANNEL_LCD);
}
}
EXPORT_SYMBOL(dpi_set_timings);
static int dpi_check_timings(struct omap_dss_device *dssdev,
int dpi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
bool is_tft;
......@@ -340,56 +293,25 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
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;
}
EXPORT_SYMBOL(dpi_check_timings);
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)
int dpi_init(struct platform_device *pdev)
{
if (cpu_is_omap34xx()) {
dpi.vdds_dsi_reg = dss_get_vdds_dsi();
if (IS_ERR(dpi.vdds_dsi_reg)) {
DSSERR("can't get VDDS_DSI regulator\n");
return PTR_ERR(dpi.vdds_dsi_reg);
}
}
return 0;
}
......
This diff is collapsed.
......@@ -68,6 +68,9 @@ static struct {
struct dss_clock_info cache_dss_cinfo;
struct dispc_clock_info cache_dispc_cinfo;
enum dss_clk_source dsi_clk_source;
enum dss_clk_source dispc_clk_source;
u32 ctx[DSS_SZ_REGS / sizeof(u32)];
} dss;
......@@ -247,23 +250,42 @@ void dss_dump_regs(struct seq_file *s)
#undef DUMPREG
}
void dss_select_clk_source(bool dsi, bool dispc)
void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
{
int b;
BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK &&
clk_src != DSS_SRC_DSS1_ALWON_FCLK);
b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */
dss.dispc_clk_source = clk_src;
}
void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
{
u32 r;
r = dss_read_reg(DSS_CONTROL);
r = FLD_MOD(r, dsi, 1, 1); /* DSI_CLK_SWITCH */
r = FLD_MOD(r, dispc, 0, 0); /* DISPC_CLK_SWITCH */
dss_write_reg(DSS_CONTROL, r);
int b;
BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK &&
clk_src != DSS_SRC_DSS1_ALWON_FCLK);
b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
dss.dsi_clk_source = clk_src;
}
int dss_get_dsi_clk_source(void)
enum dss_clk_source dss_get_dispc_clk_source(void)
{
return FLD_GET(dss_read_reg(DSS_CONTROL), 1, 1);
return dss.dispc_clk_source;
}
int dss_get_dispc_clk_source(void)
enum dss_clk_source dss_get_dsi_clk_source(void)
{
return FLD_GET(dss_read_reg(DSS_CONTROL), 0, 0);
return dss.dsi_clk_source;
}
/* calculate clock rates using dividers in cinfo */
......
......@@ -119,6 +119,12 @@ enum dss_clock {
DSS_CLK_96M = 1 << 4,
};
enum dss_clk_source {
DSS_SRC_DSI1_PLL_FCLK,
DSS_SRC_DSI2_PLL_FCLK,
DSS_SRC_DSS1_ALWON_FCLK,
};
struct dss_clock_info {
/* rates that we get with dividers below */
unsigned long fck;
......@@ -169,6 +175,9 @@ unsigned long dss_clk_get_rate(enum dss_clock clk);
int dss_need_ctx_restore(void);
void dss_dump_clocks(struct seq_file *s);
struct bus_type *dss_get_bus(void);
struct regulator *dss_get_vdds_dsi(void);
struct regulator *dss_get_vdds_sdi(void);
struct regulator *dss_get_vdda_dac(void);
/* display */
int dss_suspend_all_devices(void);
......@@ -216,9 +225,11 @@ void dss_sdi_init(u8 datapairs);
int dss_sdi_enable(void);
void dss_sdi_disable(void);
void dss_select_clk_source(bool dsi, bool dispc);
int dss_get_dsi_clk_source(void);
int dss_get_dispc_clk_source(void);
void dss_select_dispc_clk_source(enum dss_clk_source clk_src);
void dss_select_dsi_clk_source(enum dss_clk_source clk_src);
enum dss_clk_source dss_get_dispc_clk_source(void);
enum dss_clk_source dss_get_dsi_clk_source(void);
void dss_set_venc_output(enum omap_dss_venc_type type);
void dss_set_dac_pwrdn_bgz(bool enable);
......@@ -261,7 +272,7 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
u32 *fifo_low, u32 *fifo_high);
/* DPI */
int dpi_init(void);
int dpi_init(struct platform_device *pdev);
void dpi_exit(void);
int dpi_init_display(struct omap_dss_device *dssdev);
......@@ -313,8 +324,8 @@ int dispc_setup_plane(enum omap_plane plane,
bool dispc_go_busy(enum omap_channel channel);
void dispc_go(enum omap_channel channel);
void dispc_enable_lcd_out(bool enable);
void dispc_enable_digit_out(bool enable);
void dispc_enable_channel(enum omap_channel channel, bool enable);
bool dispc_is_channel_enabled(enum omap_channel channel);
int dispc_enable_plane(enum omap_plane plane, bool enable);
void dispc_enable_replication(enum omap_plane plane, bool enable);
......
......@@ -501,6 +501,19 @@ static int omap_dss_unset_device(struct omap_overlay_manager *mgr)
return 0;
}
static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
u32 irq;
if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
irq = DISPC_IRQ_EVSYNC_ODD;
else
irq = DISPC_IRQ_VSYNC;
return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
}
static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
......@@ -509,17 +522,18 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
u32 irq;
int r;
int i;
struct omap_dss_device *dssdev = mgr->device;
if (!mgr->device)
if (!dssdev)
return 0;
if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
channel = OMAP_DSS_CHANNEL_DIGIT;
} else {
if (mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
enum omap_dss_update_mode mode;
mode = mgr->device->get_update_mode(mgr->device);
mode = dssdev->driver->get_update_mode(dssdev);
if (mode != OMAP_DSS_UPDATE_AUTO)
return 0;
......@@ -592,7 +606,7 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
} else {
if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
enum omap_dss_update_mode mode;
mode = dssdev->get_update_mode(dssdev);
mode = dssdev->driver->get_update_mode(dssdev);
if (mode != OMAP_DSS_UPDATE_AUTO)
return 0;
......@@ -1064,7 +1078,7 @@ void dss_start_update(struct omap_dss_device *dssdev)
mc->shadow_dirty = false;
}
dispc_enable_lcd_out(1);
dssdev->manager->enable(dssdev->manager);
}
static void dss_apply_irq_handler(void *data, u32 mask)
......@@ -1196,7 +1210,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
oc->manual_update =
dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO;
dssdev->driver->get_update_mode(dssdev) !=
OMAP_DSS_UPDATE_AUTO;
++num_planes_enabled;
}
......@@ -1237,7 +1252,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
mc->manual_update =
dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO;
dssdev->driver->get_update_mode(dssdev) !=
OMAP_DSS_UPDATE_AUTO;
}
/* XXX TODO: Try to get fifomerge working. The problem is that it
......@@ -1351,6 +1367,18 @@ static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr,
*info = mgr->info;
}
static int dss_mgr_enable(struct omap_overlay_manager *mgr)
{
dispc_enable_channel(mgr->id, 1);
return 0;
}
static int dss_mgr_disable(struct omap_overlay_manager *mgr)
{
dispc_enable_channel(mgr->id, 0);
return 0;
}
static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager)
{
++num_managers;
......@@ -1394,6 +1422,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->set_manager_info = &omap_dss_mgr_set_info;
mgr->get_manager_info = &omap_dss_mgr_get_info;
mgr->wait_for_go = &dss_mgr_wait_for_go;
mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
mgr->enable = &dss_mgr_enable;
mgr->disable = &dss_mgr_disable;
mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC;
......
......@@ -350,7 +350,7 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
return -EINVAL;
}
dssdev->get_resolution(dssdev, &dw, &dh);
dssdev->driver->get_resolution(dssdev, &dw, &dh);
DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n",
ovl->id,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -16,16 +16,7 @@ config FB_OMAP2_DEBUG_SUPPORT
depends on FB_OMAP2
help
Support for debug output. You have to enable the actual printing
with debug module parameter.
config FB_OMAP2_FORCE_AUTO_UPDATE
bool "Force main display to automatic update mode"
depends on FB_OMAP2
help
Forces main display to automatic update mode (if possible),
and also enables tearsync (if possible). By default
displays that support manual update are started in manual
update mode.
with 'debug' module parameter.
config FB_OMAP2_NUM_FBS
int "Number of framebuffers"
......
This diff is collapsed.
This diff is collapsed.
......@@ -83,6 +83,12 @@ struct omapfb2_device {
struct omap_overlay *overlays[10];
unsigned num_managers;
struct omap_overlay_manager *managers[10];
unsigned num_bpp_overrides;
struct {
struct omap_dss_device *dssdev;
u8 bpp;
} bpp_overrides[10];
};
struct omapfb_colormode {
......@@ -105,6 +111,9 @@ void omapfb_remove_sysfs(struct omapfb2_device *fbdev);
int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg);
int omapfb_update_window(struct fb_info *fbi,
u32 x, u32 y, u32 w, u32 h);
int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
struct fb_var_screeninfo *var);
......
......@@ -126,6 +126,7 @@ header-y += nfs2.h
header-y += nfs4_mount.h
header-y += nfs_mount.h
header-y += nl80211.h
header-y += omapfb.h
header-y += param.h
header-y += pci_regs.h
header-y += perf_event.h
......
......@@ -57,6 +57,7 @@
#define OMAPFB_WAITFORGO OMAP_IO(60)
#define OMAPFB_GET_VRAM_INFO OMAP_IOR(61, struct omapfb_vram_info)
#define OMAPFB_SET_TEARSYNC OMAP_IOW(62, struct omapfb_tearsync_info)
#define OMAPFB_GET_DISPLAY_INFO OMAP_IOR(63, struct omapfb_display_info)
#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
......@@ -206,6 +207,14 @@ struct omapfb_tearsync_info {
__u16 reserved2;
};
struct omapfb_display_info {
__u16 xres;
__u16 yres;
__u32 width; /* phys width of the display in micrometers */
__u32 height; /* phys height of the display in micrometers */
__u32 reserved[5];
};
#ifdef __KERNEL__
#include <plat/board.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment