* RE: [PATCH] fsl-diu-fb: remove the ioctl interface
From: Jenkins, Clive @ 2011-06-22 10:39 UTC (permalink / raw)
To: Anatolij Gustschin, Timur Tabi; +Cc: linuxppc-dev, linux-fbdev, lethal, yorksun
In-Reply-To: <20110622003853.1041385c@wker>
> > The ioctl interface in the Freescale DIU framebuffer driver is just
a
> > collection of miscellaneous functions which were only used in a
one-time
> > demo application that was never distributed. Plus, the ioctls were
spread
> > across two types (both conflicting), and the demo app didn't even
use all
> > of them.
> >
> > Removing the ioctl interface also allows us to clean up the header
file and
> > remove other unusued stuff.
>
> No! We are using ioctl interface of this driver in many video
> rendering applications on overlay planes on huge number of boards.
> So, please don't remove it.
>
> Anatolij
Can you make available your application code by posting a link to it?
Thanks,
Clive
^ permalink raw reply
* [PATCH 0/8] HDMI: Split hdmi.c to seperate HDMI IP dependant code from DSS.
From: Mythri P K @ 2011-06-22 11:55 UTC (permalink / raw)
To: linux-fbdev
HDMI IP block is common between TI OMAP4 Procerssor and Netra processor although
the Display subsytem is different. Thus to reuse the code between these two
processors , HDMI IP dependant code is seperated out from hdmi.c and moved to
new library file hdmi_ti_4xxx_ip.c which now resides in /drivers/video a more
generic location out of omap2/dss folder.
This patch series does the split and also renames hdmi_omap4_panel.c to
hdmi_panel.c as that file has nothing specific to OMAP4 and can be reused for
other OMAP family of processors as well.
This is based on Tomi's DSS pmruntime-v2 branch:
git://gitorious.org/linux-omap-dss2/linux.git
Tree with the patches for verification is available in
http://gitorious.org/~mythripk/linux-omap-dss2/mythripk-linux-lo-dss2/commits/hdmi_pmrumtime
Mythri P K (8):
OMAP4: DSS: HDMI: HDMI clean up to pass base_address dynamically
to IP dependant functions of HDMI
OMAP4 : DSS : HDMI : Move the EDID portion from HDMI IP header
OMAP4: DSS: HDMI: Use specific HDMI timings structure instead of
OMAP DSS timings
OMAP4: DSS: HDMI: Move the common header file definition to
Include/video
OMAP4: DSS2: HDMI: Split the HDMI driver to DSS and IP specific
portion.
OMAP4: DSS: HDMI: Rename the functions in HDMI IP library to IP
specific name
HDMI: Move HDMI IP Library from OMAP DSS to common Video
directory for IP present in TI OMAP4, TI81xx, TI38xx
Processor
OMAP4: DSS: Rename hdmi_omap4_panel.c to hdmi_panel.c
drivers/video/Kconfig | 7 +
drivers/video/Makefile | 1 +
drivers/video/hdmi_ti_4xxx_ip.c | 803 +++++++++++++++++
drivers/video/hdmi_ti_4xxx_ip.h | 587 +++++++++++++
drivers/video/omap2/dss/Kconfig | 1 +
drivers/video/omap2/dss/Makefile | 2 +-
drivers/video/omap2/dss/dss.h | 10 -
drivers/video/omap2/dss/hdmi.c | 919 ++++----------------
drivers/video/omap2/dss/hdmi.h | 631 --------------
.../omap2/dss/{hdmi_omap4_panel.c => hdmi_panel.c} | 2 +-
include/video/hdmi_ti_4xxx_ip.h | 94 ++
11 files changed, 1641 insertions(+), 1416 deletions(-)
create mode 100644 drivers/video/hdmi_ti_4xxx_ip.c
create mode 100644 drivers/video/hdmi_ti_4xxx_ip.h
delete mode 100644 drivers/video/omap2/dss/hdmi.h
rename drivers/video/omap2/dss/{hdmi_omap4_panel.c => hdmi_panel.c} (99%)
create mode 100644 include/video/hdmi_ti_4xxx_ip.h
--
1.7.5.4
^ permalink raw reply
* [PATCH 1/8] OMAP4: DSS: HDMI: HDMI clean up to pass base_address
From: Mythri P K @ 2011-06-22 11:55 UTC (permalink / raw)
To: linux-fbdev
As the base_address of the HDMI might differ across SoC's, offset of the HDMI
logical blocks and base address got from the platform data are passed
dynamically to the functions that modify HDMI IP registers.
Signed-off-by: Mythri P K <mythripk@ti.com>
---
drivers/video/omap2/dss/hdmi.c | 518 ++++++++++++++++++++++++----------------
drivers/video/omap2/dss/hdmi.h | 292 +++++++++++------------
2 files changed, 452 insertions(+), 358 deletions(-)
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 5e5b98b..1d16ee2 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -43,11 +43,17 @@
#include "hdmi.h"
#include "dss_features.h"
+#define HDMI_WP 0x0
+#define HDMI_CORE_SYS 0x400
+#define HDMI_CORE_AV 0x900
+#define HDMI_PLLCTRL 0x200
+#define HDMI_PHY 0x300
+
static struct {
struct mutex lock;
struct omap_display_platform_data *pdata;
struct platform_device *pdev;
- void __iomem *base_wp; /* HDMI wrapper */
+ struct hdmi_ip_data hdmi_data;
int code;
int mode;
u8 edid[HDMI_EDID_MAX_LENGTH];
@@ -146,21 +152,51 @@ static const int code_vesa[85] = {
static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
-static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val)
+static inline void hdmi_write_reg(void __iomem *base_addr,
+ const struct hdmi_reg idx, u32 val)
+{
+ __raw_writel(val, base_addr + idx.idx);
+}
+
+static inline u32 hdmi_read_reg(void __iomem *base_addr,
+ const struct hdmi_reg idx)
+{
+ return __raw_readl(base_addr + idx.idx);
+}
+
+static inline void __iomem *hdmi_wp_base(struct hdmi_ip_data *ip_data)
+{
+ return (void __iomem *) (ip_data->base_wp);
+}
+
+static inline void __iomem *hdmi_phy_base(struct hdmi_ip_data *ip_data)
{
- __raw_writel(val, hdmi.base_wp + idx.idx);
+ return (void __iomem *) (ip_data->base_wp + ip_data->hdmi_phy_offset);
}
-static inline u32 hdmi_read_reg(const struct hdmi_reg idx)
+static inline void __iomem *hdmi_pll_base(struct hdmi_ip_data *ip_data)
{
- return __raw_readl(hdmi.base_wp + idx.idx);
+ return (void __iomem *) (ip_data->base_wp + ip_data->hdmi_pll_offset);
}
-static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
+static inline void __iomem *hdmi_av_base(struct hdmi_ip_data *ip_data)
+{
+ return (void __iomem *)
+ (ip_data->base_wp + ip_data->hdmi_core_av_offset);
+}
+
+static inline void __iomem *hdmi_core_sys_base(struct hdmi_ip_data *ip_data)
+{
+ return (void __iomem *)
+ (ip_data->base_wp + ip_data->hdmi_core_sys_offset);
+}
+
+static inline int hdmi_wait_for_bit_change(void __iomem *base_addr,
+ const struct hdmi_reg idx,
int b2, int b1, u32 val)
{
u32 t = 0;
- while (val != REG_GET(idx, b2, b1)) {
+ while (val != REG_GET(base_addr, idx, b2, b1)) {
udelay(1);
if (t++ > 10000)
return !val;
@@ -225,21 +261,22 @@ int hdmi_init_display(struct omap_dss_device *dssdev)
return 0;
}
-static int hdmi_pll_init(enum hdmi_clk_refsel refsel, int dcofreq,
+static int hdmi_pll_init(struct hdmi_ip_data *ip_data,
+ enum hdmi_clk_refsel refsel, int dcofreq,
struct hdmi_pll_info *fmt, u16 sd)
{
u32 r;
/* PLL start always use manual mode */
- REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
+ REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
- r = hdmi_read_reg(PLLCTRL_CFG1);
+ r = hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG1);
r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
r = FLD_MOD(r, fmt->regn, 8, 1); /* CFG1_PLL_REGN */
- hdmi_write_reg(PLLCTRL_CFG1, r);
+ hdmi_write_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG1, r);
- r = hdmi_read_reg(PLLCTRL_CFG2);
+ r = hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG2);
r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
@@ -247,38 +284,40 @@ static int hdmi_pll_init(enum hdmi_clk_refsel refsel, int dcofreq,
if (dcofreq) {
/* divider programming for frequency beyond 1000Mhz */
- REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10);
+ REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_CFG3, sd, 17, 10);
r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
} else {
r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
}
- hdmi_write_reg(PLLCTRL_CFG2, r);
+ hdmi_write_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG2, r);
- r = hdmi_read_reg(PLLCTRL_CFG4);
+ r = hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG4);
r = FLD_MOD(r, fmt->regm2, 24, 18);
r = FLD_MOD(r, fmt->regmf, 17, 0);
- hdmi_write_reg(PLLCTRL_CFG4, r);
+ hdmi_write_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG4, r);
/* go now */
- REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0);
+ REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_PLL_GO, 0x1, 0, 0);
/* wait for bit change */
- if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) {
+ if (hdmi_wait_for_bit_change(hdmi_pll_base(ip_data), PLLCTRL_PLL_GO,
+ 0, 0, 1) != 1) {
DSSERR("PLL GO bit not set\n");
return -ETIMEDOUT;
}
/* Wait till the lock bit is set in PLL status */
- if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
+ if (hdmi_wait_for_bit_change(hdmi_pll_base(ip_data),
+ PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
DSSWARN("cannot lock PLL\n");
DSSWARN("CFG1 0x%x\n",
- hdmi_read_reg(PLLCTRL_CFG1));
+ hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG1));
DSSWARN("CFG2 0x%x\n",
- hdmi_read_reg(PLLCTRL_CFG2));
+ hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG2));
DSSWARN("CFG4 0x%x\n",
- hdmi_read_reg(PLLCTRL_CFG4));
+ hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG4));
return -ETIMEDOUT;
}
@@ -288,13 +327,14 @@ static int hdmi_pll_init(enum hdmi_clk_refsel refsel, int dcofreq,
}
/* PHY_PWR_CMD */
-static int hdmi_set_phy_pwr(enum hdmi_phy_pwr val)
+static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val)
{
/* Command for power control of HDMI PHY */
- REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6);
+ REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6);
/* Status of the power control of HDMI PHY */
- if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
+ if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data),
+ HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
DSSERR("Failed to set PHY power mode to %d\n", val);
return -ETIMEDOUT;
}
@@ -303,13 +343,14 @@ static int hdmi_set_phy_pwr(enum hdmi_phy_pwr val)
}
/* PLL_PWR_CMD */
-static int hdmi_set_pll_pwr(enum hdmi_pll_pwr val)
+int hdmi_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val)
{
/* Command for power control of HDMI PLL */
- REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2);
+ REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 3, 2);
/* wait till PHY_PWR_STATUS is set */
- if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) {
+ if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL,
+ 1, 0, val) != val) {
DSSERR("Failed to set PHY_PWR_STATUS\n");
return -ETIMEDOUT;
}
@@ -317,13 +358,14 @@ static int hdmi_set_pll_pwr(enum hdmi_pll_pwr val)
return 0;
}
-static int hdmi_pll_reset(void)
+static int hdmi_pll_reset(struct hdmi_ip_data *ip_data)
{
/* SYSRESET controlled by power FSM */
- REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
+ REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
/* READ 0x0 reset is in progress */
- if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
+ if (hdmi_wait_for_bit_change(hdmi_pll_base(ip_data),
+ PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
DSSERR("Failed to sysreset PLL\n");
return -ETIMEDOUT;
}
@@ -331,15 +373,15 @@ static int hdmi_pll_reset(void)
return 0;
}
-static int hdmi_phy_init(void)
+static int hdmi_phy_init(struct hdmi_ip_data *ip_data)
{
u16 r = 0;
- r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_LDOON);
+ r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
if (r)
return r;
- r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_TXON);
+ r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
if (r)
return r;
@@ -347,65 +389,69 @@ static int hdmi_phy_init(void)
* Read address 0 in order to get the SCP reset done completed
* Dummy access performed to make sure reset is done
*/
- hdmi_read_reg(HDMI_TXPHY_TX_CTRL);
+ hdmi_read_reg(hdmi_phy_base(ip_data), HDMI_TXPHY_TX_CTRL);
/*
* Write to phy address 0 to configure the clock
* use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
*/
- REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
+ REG_FLD_MOD(hdmi_phy_base(ip_data), HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
/* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
- hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
+ hdmi_write_reg(hdmi_phy_base(ip_data),
+ HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
/* Setup max LDO voltage */
- REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
+ REG_FLD_MOD(hdmi_phy_base(ip_data), HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
/* Write to phy address 3 to change the polarity control */
- REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
+ REG_FLD_MOD(hdmi_phy_base(ip_data),
+ HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
return 0;
}
-static int hdmi_pll_program(struct hdmi_pll_info *fmt)
+static int hdmi_pll_program(struct hdmi_ip_data *ip_data,
+ struct hdmi_pll_info *fmt)
{
u16 r = 0;
enum hdmi_clk_refsel refsel;
- r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
+ r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
if (r)
return r;
- r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
+ r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
if (r)
return r;
- r = hdmi_pll_reset();
+ r = hdmi_pll_reset(ip_data);
if (r)
return r;
refsel = HDMI_REFSEL_SYSCLK;
- r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd);
+ r = hdmi_pll_init(ip_data, refsel, fmt->dcofreq, fmt, fmt->regsd);
if (r)
return r;
return 0;
}
-static void hdmi_phy_off(void)
+static void hdmi_phy_off(struct hdmi_ip_data *ip_data)
{
- hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF);
+ hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
}
-static int hdmi_core_ddc_edid(u8 *pedid, int ext)
+static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
+ u8 *pedid, int ext)
{
u32 i, j;
char checksum = 0;
u32 offset = 0;
/* Turn on CLK for DDC */
- REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_DPD, 0x7, 2, 0);
/*
* SW HACK : Without the Delay DDC(i2c bus) reads 0 values /
@@ -416,21 +462,23 @@ static int hdmi_core_ddc_edid(u8 *pedid, int ext)
if (!ext) {
/* Clk SCL Devices */
- REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_CMD, 0xA, 3, 0);
/* HDMI_CORE_DDC_STATUS_IN_PROG */
- if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
- 4, 4, 0) != 0) {
+ if (hdmi_wait_for_bit_change(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) {
DSSERR("Failed to program DDC\n");
return -ETIMEDOUT;
}
/* Clear FIFO */
- REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data)
+ , HDMI_CORE_DDC_CMD, 0x9, 3, 0);
/* HDMI_CORE_DDC_STATUS_IN_PROG */
- if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
- 4, 4, 0) != 0) {
+ if (hdmi_wait_for_bit_change(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) {
DSSERR("Failed to program DDC\n");
return -ETIMEDOUT;
}
@@ -441,44 +489,56 @@ static int hdmi_core_ddc_edid(u8 *pedid, int ext)
}
/* Load Segment Address Register */
- REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
/* Load Slave Address Register */
- REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
/* Load Offset Address Register */
- REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_OFFSET, offset, 7, 0);
/* Load Byte Count */
- REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
- REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
/* Set DDC_CMD */
if (ext)
- REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_CMD, 0x4, 3, 0);
else
- REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_CMD, 0x2, 3, 0);
/* HDMI_CORE_DDC_STATUS_BUS_LOW */
- if (REG_GET(HDMI_CORE_DDC_STATUS, 6, 6) = 1) {
+ if (REG_GET(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_STATUS, 6, 6) = 1) {
DSSWARN("I2C Bus Low?\n");
return -EIO;
}
/* HDMI_CORE_DDC_STATUS_NO_ACK */
- if (REG_GET(HDMI_CORE_DDC_STATUS, 5, 5) = 1) {
+ if (REG_GET(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_STATUS, 5, 5) = 1) {
DSSWARN("I2C No Ack\n");
return -EIO;
}
i = ext * 128;
j = 0;
- while (((REG_GET(HDMI_CORE_DDC_STATUS, 4, 4) = 1) ||
- (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) = 0)) &&
- j < 128) {
+ while (((REG_GET(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_STATUS, 4, 4) = 1) ||
+ (REG_GET(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_STATUS, 2, 2) = 0)) && j < 128) {
- if (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) = 0) {
+ if (REG_GET(hdmi_core_sys_base(ip_data)
+ , HDMI_CORE_DDC_STATUS, 2, 2) = 0) {
/* FIFO not empty */
- pedid[i++] = REG_GET(HDMI_CORE_DDC_DATA, 7, 0);
+ pedid[i++] = REG_GET(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_DATA, 7, 0);
j++;
}
}
@@ -494,12 +554,12 @@ static int hdmi_core_ddc_edid(u8 *pedid, int ext)
return 0;
}
-static int read_edid(u8 *pedid, u16 max_length)
+static int read_edid(struct hdmi_ip_data *ip_data, u8 *pedid, u16 max_length)
{
int r = 0, n = 0, i = 0;
int max_ext_blocks = (max_length / 128) - 1;
- r = hdmi_core_ddc_edid(pedid, 0);
+ r = hdmi_core_ddc_edid(ip_data, pedid, 0);
if (r) {
return r;
} else {
@@ -515,7 +575,7 @@ static int read_edid(u8 *pedid, u16 max_length)
n = max_ext_blocks;
for (i = 1; i <= n; i++) {
- r = hdmi_core_ddc_edid(pedid, i);
+ r = hdmi_core_ddc_edid(ip_data, pedid, i);
if (r)
return r;
}
@@ -685,8 +745,8 @@ static void hdmi_read_edid(struct omap_video_timings *dp)
memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH);
if (!hdmi.edid_set)
- ret = read_edid(hdmi.edid, HDMI_EDID_MAX_LENGTH);
-
+ ret = read_edid(&hdmi.hdmi_data, hdmi.edid,
+ HDMI_EDID_MAX_LENGTH);
if (!ret) {
if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) {
/* search for timings of default resolution */
@@ -752,41 +812,43 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
repeat_cfg->generic_pkt_repeat = 0;
}
-static void hdmi_core_powerdown_disable(void)
+static void hdmi_core_powerdown_disable(struct hdmi_ip_data *ip_data)
{
DSSDBG("Enter hdmi_core_powerdown_disable\n");
- REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_CTRL1, 0x0, 0, 0);
}
-static void hdmi_core_swreset_release(void)
+static void hdmi_core_swreset_release(struct hdmi_ip_data *ip_data)
{
DSSDBG("Enter hdmi_core_swreset_release\n");
- REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_SRST, 0x0, 0, 0);
}
-static void hdmi_core_swreset_assert(void)
+static void hdmi_core_swreset_assert(struct hdmi_ip_data *ip_data)
{
DSSDBG("Enter hdmi_core_swreset_assert\n");
- REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_SRST, 0x1, 0, 0);
}
-/* DSS_HDMI_CORE_VIDEO_CONFIG */
-static void hdmi_core_video_config(struct hdmi_core_video_config *cfg)
+/* HDMI_CORE_VIDEO_CONFIG */
+static void hdmi_core_video_config(struct hdmi_ip_data *ip_data,
+ struct hdmi_core_video_config *cfg)
{
u32 r = 0;
/* sys_ctrl1 default configuration not tunable */
- r = hdmi_read_reg(HDMI_CORE_CTRL1);
+ r = hdmi_read_reg(hdmi_core_sys_base(ip_data), HDMI_CORE_CTRL1);
r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
- hdmi_write_reg(HDMI_CORE_CTRL1, r);
+ hdmi_write_reg(hdmi_core_sys_base(ip_data), HDMI_CORE_CTRL1, r);
- REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
/* Vid_Mode */
- r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE);
+ r = hdmi_read_reg(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_VID_MODE);
/* dither truncation configuration */
if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
@@ -796,106 +858,107 @@ static void hdmi_core_video_config(struct hdmi_core_video_config *cfg)
r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
r = FLD_MOD(r, 0, 5, 5);
}
- hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r);
+ hdmi_write_reg(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_VID_MODE, r);
/* HDMI_Ctrl */
- r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL);
+ r = hdmi_read_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL);
r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
- hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL, r);
/* TMDS_CTRL */
- REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL,
- cfg->tclk_sel_clkmult, 6, 5);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
}
-static void hdmi_core_aux_infoframe_avi_config(
+static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data,
struct hdmi_core_infoframe_avi info_avi)
{
u32 val;
char sum = 0, checksum = 0;
sum += 0x82 + 0x002 + 0x00D;
- hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082);
- hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002);
- hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_TYPE, 0x082);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_VERS, 0x002);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_LEN, 0x00D);
val = (info_avi.db1_format << 5) |
(info_avi.db1_active_info << 4) |
(info_avi.db1_bar_info_dv << 2) |
(info_avi.db1_scan_info);
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(0), val);
sum += val;
val = (info_avi.db2_colorimetry << 6) |
(info_avi.db2_aspect_ratio << 4) |
(info_avi.db2_active_fmt_ar);
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(1), val);
sum += val;
val = (info_avi.db3_itc << 7) |
(info_avi.db3_ec << 4) |
(info_avi.db3_q_range << 2) |
(info_avi.db3_nup_scaling);
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(2), val);
sum += val;
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(3),
+ info_avi.db4_videocode);
sum += info_avi.db4_videocode;
val = info_avi.db5_pixel_repeat;
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(4), val);
sum += val;
val = info_avi.db6_7_line_eoftop & 0x00FF;
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(5), val);
sum += val;
val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(6), val);
sum += val;
val = info_avi.db8_9_line_sofbottom & 0x00FF;
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(7), val);
sum += val;
val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(8), val);
sum += val;
val = info_avi.db10_11_pixel_eofleft & 0x00FF;
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(9), val);
sum += val;
val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(10), val);
sum += val;
val = info_avi.db12_13_pixel_sofright & 0x00FF;
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(11), val);
sum += val;
val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
- hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(12), val);
sum += val;
checksum = 0x100 - sum;
- hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_CHSUM, checksum);
}
-static void hdmi_core_av_packet_config(
+static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data,
struct hdmi_core_packet_enable_repeat repeat_cfg)
{
/* enable/repeat the infoframe */
- hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1,
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_PB_CTRL1,
(repeat_cfg.audio_pkt << 5) |
(repeat_cfg.audio_pkt_repeat << 4) |
(repeat_cfg.avi_infoframe << 1) |
(repeat_cfg.avi_infoframe_repeat));
/* enable/repeat the packet */
- hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2,
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_PB_CTRL2,
(repeat_cfg.gen_cntrl_pkt << 3) |
(repeat_cfg.gen_cntrl_pkt_repeat << 2) |
(repeat_cfg.generic_pkt << 1) |
@@ -927,9 +990,9 @@ static void hdmi_wp_init(struct omap_video_timings *timings,
}
-static void hdmi_wp_video_start(bool start)
+static void hdmi_wp_video_start(struct hdmi_ip_data *ip_data, bool start)
{
- REG_FLD_MOD(HDMI_WP_VIDEO_CFG, start, 31, 31);
+ REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, start, 31, 31);
}
static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
@@ -948,33 +1011,34 @@ static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
timings->vsw = param->timings.timings.vsw;
}
-static void hdmi_wp_video_config_format(
+static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data,
struct hdmi_video_format *video_fmt)
{
u32 l = 0;
- REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8);
+ REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG,
+ video_fmt->packing_mode, 10, 8);
l |= FLD_VAL(video_fmt->y_res, 31, 16);
l |= FLD_VAL(video_fmt->x_res, 15, 0);
- hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l);
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l);
}
-static void hdmi_wp_video_config_interface(
+static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data,
struct hdmi_video_interface *video_int)
{
u32 r;
DSSDBG("Enter hdmi_wp_video_config_interface\n");
- r = hdmi_read_reg(HDMI_WP_VIDEO_CFG);
+ r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG);
r = FLD_MOD(r, video_int->vsp, 7, 7);
r = FLD_MOD(r, video_int->hsp, 6, 6);
r = FLD_MOD(r, video_int->interlacing, 3, 3);
r = FLD_MOD(r, video_int->tm, 1, 0);
- hdmi_write_reg(HDMI_WP_VIDEO_CFG, r);
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r);
}
-static void hdmi_wp_video_config_timing(
+static void hdmi_wp_video_config_timing(struct hdmi_ip_data *ip_data,
struct omap_video_timings *timings)
{
u32 timing_h = 0;
@@ -985,15 +1049,16 @@ static void hdmi_wp_video_config_timing(
timing_h |= FLD_VAL(timings->hbp, 31, 20);
timing_h |= FLD_VAL(timings->hfp, 19, 8);
timing_h |= FLD_VAL(timings->hsw, 7, 0);
- hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h);
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_H, timing_h);
timing_v |= FLD_VAL(timings->vbp, 31, 20);
timing_v |= FLD_VAL(timings->vfp, 19, 8);
timing_v |= FLD_VAL(timings->vsw, 7, 0);
- hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v);
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_V, timing_v);
}
-static void hdmi_basic_configure(struct hdmi_config *cfg)
+static void hdmi_basic_configure(struct hdmi_ip_data *ip_data,
+ struct hdmi_config *cfg)
{
/* HDMI */
struct omap_video_timings video_timing;
@@ -1014,36 +1079,36 @@ static void hdmi_basic_configure(struct hdmi_config *cfg)
hdmi_wp_video_init_format(&video_format,
&video_timing, cfg);
- hdmi_wp_video_config_timing(&video_timing);
+ hdmi_wp_video_config_timing(ip_data, &video_timing);
/* video config */
video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
- hdmi_wp_video_config_format(&video_format);
+ hdmi_wp_video_config_format(ip_data, &video_format);
video_interface.vsp = cfg->timings.vsync_pol;
video_interface.hsp = cfg->timings.hsync_pol;
video_interface.interlacing = cfg->interlace;
video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
- hdmi_wp_video_config_interface(&video_interface);
+ hdmi_wp_video_config_interface(ip_data, &video_interface);
/*
* configure core video part
* set software reset in the core
*/
- hdmi_core_swreset_assert();
+ hdmi_core_swreset_assert(ip_data);
/* power down off */
- hdmi_core_powerdown_disable();
+ hdmi_core_powerdown_disable(ip_data);
v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
v_core_cfg.hdmi_dvi = cfg->cm.mode;
- hdmi_core_video_config(&v_core_cfg);
+ hdmi_core_video_config(ip_data, &v_core_cfg);
/* release software reset in the core */
- hdmi_core_swreset_release();
+ hdmi_core_swreset_release(ip_data);
/*
* configure packet
@@ -1068,7 +1133,7 @@ static void hdmi_basic_configure(struct hdmi_config *cfg)
avi_cfg.db10_11_pixel_eofleft = 0;
avi_cfg.db12_13_pixel_sofright = 0;
- hdmi_core_aux_infoframe_avi_config(avi_cfg);
+ hdmi_core_aux_infoframe_avi_config(ip_data, avi_cfg);
/* enable/repeat the infoframe */
repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
@@ -1076,7 +1141,7 @@ static void hdmi_basic_configure(struct hdmi_config *cfg)
/* wakeup */
repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
- hdmi_core_av_packet_config(repeat_cfg);
+ hdmi_core_av_packet_config(ip_data, repeat_cfg);
}
static void update_hdmi_timings(struct hdmi_config *cfg,
@@ -1166,16 +1231,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
hdmi_compute_pll(dssdev, phy, &pll_data);
- hdmi_wp_video_start(0);
+ hdmi_wp_video_start(&hdmi.hdmi_data, 0);
- /* config the PLL and PHY first */
- r = hdmi_pll_program(&pll_data);
+ /* config the PLL and PHY hdmi_set_pll_pwrfirst */
+ r = hdmi_pll_program(&hdmi.hdmi_data, &pll_data);
if (r) {
DSSDBG("Failed to lock PLL\n");
goto err;
}
- r = hdmi_phy_init();
+ r = hdmi_phy_init(&hdmi.hdmi_data);
if (r) {
DSSDBG("Failed to start PHY\n");
goto err;
@@ -1183,7 +1248,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
hdmi.cfg.cm.mode = hdmi.mode;
hdmi.cfg.cm.code = hdmi.code;
- hdmi_basic_configure(&hdmi.cfg);
+ hdmi_basic_configure(&hdmi.hdmi_data, &hdmi.cfg);
/* Make selection of HDMI in DSS */
dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
@@ -1205,7 +1270,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1);
- hdmi_wp_video_start(1);
+ hdmi_wp_video_start(&hdmi.hdmi_data, 1);
return 0;
err:
@@ -1217,9 +1282,9 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
{
dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
- hdmi_wp_video_start(0);
- hdmi_phy_off();
- hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
+ hdmi_wp_video_start(&hdmi.hdmi_data, 0);
+ hdmi_phy_off(&hdmi.hdmi_data);
+ hdmi_set_pll_pwr(&hdmi.hdmi_data, HDMI_PLLPWRCMD_ALLOFF);
hdmi_runtime_put();
hdmi.edid_set = 0;
@@ -1311,14 +1376,14 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
-static void hdmi_wp_audio_config_format(
- struct hdmi_audio_format *aud_fmt)
+static void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data,
+ struct hdmi_audio_format *aud_fmt)
{
u32 r;
DSSDBG("Enter hdmi_wp_audio_config_format\n");
- r = hdmi_read_reg(HDMI_WP_AUDIO_CFG);
+ r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG);
r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24);
r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16);
r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5);
@@ -1327,68 +1392,81 @@ static void hdmi_wp_audio_config_format(
r = FLD_MOD(r, aud_fmt->sample_order, 2, 2);
r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1);
r = FLD_MOD(r, aud_fmt->sample_size, 0, 0);
- hdmi_write_reg(HDMI_WP_AUDIO_CFG, r);
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG, r);
}
-static void hdmi_wp_audio_config_dma(struct hdmi_audio_dma *aud_dma)
+static void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data,
+ struct hdmi_audio_dma *aud_dma)
{
u32 r;
DSSDBG("Enter hdmi_wp_audio_config_dma\n");
- r = hdmi_read_reg(HDMI_WP_AUDIO_CFG2);
+ r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2);
r = FLD_MOD(r, aud_dma->transfer_size, 15, 8);
r = FLD_MOD(r, aud_dma->block_size, 7, 0);
- hdmi_write_reg(HDMI_WP_AUDIO_CFG2, r);
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2, r);
- r = hdmi_read_reg(HDMI_WP_AUDIO_CTRL);
+ r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL);
r = FLD_MOD(r, aud_dma->mode, 9, 9);
r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0);
- hdmi_write_reg(HDMI_WP_AUDIO_CTRL, r);
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL, r);
}
-static void hdmi_core_audio_config(struct hdmi_core_audio_config *cfg)
+static void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
+ struct hdmi_core_audio_config *cfg)
{
u32 r;
/* audio clock recovery parameters */
- r = hdmi_read_reg(HDMI_CORE_AV_ACR_CTRL);
+ r = hdmi_read_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_ACR_CTRL);
r = FLD_MOD(r, cfg->use_mclk, 2, 2);
r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
r = FLD_MOD(r, cfg->cts_mode, 0, 0);
- hdmi_write_reg(HDMI_CORE_AV_ACR_CTRL, r);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_ACR_CTRL, r);
- REG_FLD_MOD(HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
- REG_FLD_MOD(HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
- REG_FLD_MOD(HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0);
if (cfg->cts_mode = HDMI_AUDIO_CTS_MODE_SW) {
- REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0);
- REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0);
- REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
} else {
/*
* HDMI IP uses this configuration to divide the MCLK to
* update CTS value.
*/
- REG_FLD_MOD(HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
/* Configure clock for audio packets */
- REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
- cfg->aud_par_busclk, 7, 0);
- REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
- (cfg->aud_par_busclk >> 8), 7, 0);
- REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_3,
- (cfg->aud_par_busclk >> 16), 7, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
+ cfg->aud_par_busclk, 7, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
+ (cfg->aud_par_busclk >> 8), 7, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_AUD_PAR_BUSCLK_3,
+ (cfg->aud_par_busclk >> 16), 7, 0);
}
/* Override of SPDIF sample frequency with value in I2S_CHST4 */
- REG_FLD_MOD(HDMI_CORE_AV_SPDIF_CTRL, cfg->fs_override, 1, 1);
+ REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_SPDIF_CTRL,
+ cfg->fs_override, 1, 1);
/* I2S parameters */
- REG_FLD_MOD(HDMI_CORE_AV_I2S_CHST4, cfg->freq_sample, 3, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_I2S_CHST4,
+ cfg->freq_sample, 3, 0);
- r = hdmi_read_reg(HDMI_CORE_AV_I2S_IN_CTRL);
+ r = hdmi_read_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_I2S_IN_CTRL);
r = FLD_MOD(r, cfg->i2s_cfg.en_high_bitrate_aud, 7, 7);
r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6);
r = FLD_MOD(r, cfg->i2s_cfg.cbit_order, 5, 5);
@@ -1397,27 +1475,29 @@ static void hdmi_core_audio_config(struct hdmi_core_audio_config *cfg)
r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2);
r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1);
r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0);
- hdmi_write_reg(HDMI_CORE_AV_I2S_IN_CTRL, r);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_I2S_IN_CTRL, r);
- r = hdmi_read_reg(HDMI_CORE_AV_I2S_CHST5);
+ r = hdmi_read_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_I2S_CHST5);
r = FLD_MOD(r, cfg->freq_sample, 7, 4);
r = FLD_MOD(r, cfg->i2s_cfg.word_length, 3, 1);
r = FLD_MOD(r, cfg->i2s_cfg.word_max_length, 0, 0);
- hdmi_write_reg(HDMI_CORE_AV_I2S_CHST5, r);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_I2S_CHST5, r);
- REG_FLD_MOD(HDMI_CORE_AV_I2S_IN_LEN, cfg->i2s_cfg.in_length_bits, 3, 0);
+ REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_I2S_IN_LEN,
+ cfg->i2s_cfg.in_length_bits, 3, 0);
/* Audio channels and mode parameters */
- REG_FLD_MOD(HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1);
- r = hdmi_read_reg(HDMI_CORE_AV_AUD_MODE);
+ REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL,
+ cfg->layout, 2, 1);
+ r = hdmi_read_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_MODE);
r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4);
r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3);
r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2);
r = FLD_MOD(r, cfg->en_spdif, 1, 1);
- hdmi_write_reg(HDMI_CORE_AV_AUD_MODE, r);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_MODE, r);
}
-static void hdmi_core_audio_infoframe_config(
+static void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data,
struct hdmi_core_infoframe_audio *info_aud)
{
u8 val;
@@ -1428,38 +1508,39 @@ static void hdmi_core_audio_infoframe_config(
* described in HDMI 1.4a Section 8.2.2 specification.
* Checksum calculation is defined in Section 5.3.5.
*/
- hdmi_write_reg(HDMI_CORE_AV_AUDIO_TYPE, 0x84);
- hdmi_write_reg(HDMI_CORE_AV_AUDIO_VERS, 0x01);
- hdmi_write_reg(HDMI_CORE_AV_AUDIO_LEN, 0x0a);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUDIO_TYPE, 0x84);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUDIO_VERS, 0x01);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUDIO_LEN, 0x0a);
sum += 0x84 + 0x001 + 0x00a;
val = (info_aud->db1_coding_type << 4)
| (info_aud->db1_channel_count - 1);
- hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(0), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_DBYTE(0), val);
sum += val;
val = (info_aud->db2_sample_freq << 2) | info_aud->db2_sample_size;
- hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(1), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_DBYTE(1), val);
sum += val;
- hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(2), 0x00);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_DBYTE(2), 0x00);
val = info_aud->db4_channel_alloc;
- hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(3), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_DBYTE(3), val);
sum += val;
val = (info_aud->db5_downmix_inh << 7) | (info_aud->db5_lsv << 3);
- hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(4), val);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_DBYTE(4), val);
sum += val;
- hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(5), 0x00);
- hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(6), 0x00);
- hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(7), 0x00);
- hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(8), 0x00);
- hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(9), 0x00);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_DBYTE(5), 0x00);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_DBYTE(6), 0x00);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_DBYTE(7), 0x00);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_DBYTE(8), 0x00);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_DBYTE(9), 0x00);
checksum = 0x100 - sum;
- hdmi_write_reg(HDMI_CORE_AV_AUDIO_CHSUM, checksum);
+ hdmi_write_reg(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_AUDIO_CHSUM, checksum);
/*
* TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing
@@ -1467,7 +1548,8 @@ static void hdmi_core_audio_infoframe_config(
*/
}
-static int hdmi_config_audio_acr(u32 sample_freq, u32 *n, u32 *cts)
+static int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
+ u32 sample_freq, u32 *n, u32 *cts)
{
u32 r;
u32 deep_color = 0;
@@ -1479,7 +1561,7 @@ static int hdmi_config_audio_acr(u32 sample_freq, u32 *n, u32 *cts)
* Obtain current deep color configuration. This needed
* to calculate the TMDS clock based on the pixel clock.
*/
- r = REG_GET(HDMI_WP_VIDEO_CFG, 1, 0);
+ r = REG_GET(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, 1, 0);
switch (r) {
case 1: /* No deep color selected */
deep_color = 100;
@@ -1523,7 +1605,8 @@ static int hdmi_config_audio_acr(u32 sample_freq, u32 *n, u32 *cts)
return 0;
}
-static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
+static int hdmi_audio_hw_params(struct hdmi_ip_data *ip_data,
+ struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
@@ -1577,7 +1660,7 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- err = hdmi_config_audio_acr(params_rate(params), &n, &cts);
+ err = hdmi_config_audio_acr(ip_data, params_rate(params), &n, &cts);
if (err < 0)
return err;
@@ -1593,8 +1676,8 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
audio_dma.mode = HDMI_AUDIO_TRANSF_DMA;
audio_dma.fifo_threshold = 0x20; /* in number of samples */
- hdmi_wp_audio_config_dma(&audio_dma);
- hdmi_wp_audio_config_format(&audio_format);
+ hdmi_wp_audio_config_dma(ip_data, &audio_dma);
+ hdmi_wp_audio_config_format(ip_data, &audio_format);
/*
* I2S config
@@ -1638,7 +1721,7 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
/* Use parallel audio interface */
core_cfg.en_parallel_aud_input = true;
- hdmi_core_audio_config(&core_cfg);
+ hdmi_core_audio_config(ip_data, &core_cfg);
/*
* Configure packet
@@ -1652,29 +1735,36 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
aud_if_cfg.db5_downmix_inh = false;
aud_if_cfg.db5_lsv = 0;
- hdmi_core_audio_infoframe_config(&aud_if_cfg);
+ hdmi_core_audio_infoframe_config(ip_data, &aud_if_cfg);
return 0;
}
-static int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
+static int hdmi_audio_trigger(struct hdmi_ip_data *ip_data,
+ struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
{
int err = 0;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- REG_FLD_MOD(HDMI_CORE_AV_AUD_MODE, 1, 0, 0);
- REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 1, 31, 31);
- REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 1, 30, 30);
+ REG_FLD_MOD(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_AUD_MODE, 1, 0, 0);
+ REG_FLD_MOD(hdmi_wp_base(ip_data),
+ HDMI_WP_AUDIO_CTRL, 1, 31, 31);
+ REG_FLD_MOD(hdmi_wp_base(ip_data),
+ HDMI_WP_AUDIO_CTRL, 1, 30, 30);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- REG_FLD_MOD(HDMI_CORE_AV_AUD_MODE, 0, 0, 0);
- REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 0, 30, 30);
- REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 0, 31, 31);
+ REG_FLD_MOD(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_AUD_MODE, 0, 0, 0);
+ REG_FLD_MOD(hdmi_wp_base(ip_data),
+ HDMI_WP_AUDIO_CTRL, 0, 30, 30);
+ REG_FLD_MOD(hdmi_wp_base(ip_data),
+ HDMI_WP_AUDIO_CTRL, 0, 31, 31);
break;
default:
err = -EINVAL;
@@ -1765,20 +1855,26 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
}
/* Base address taken from platform */
- hdmi.base_wp = ioremap(hdmi_mem->start, resource_size(hdmi_mem));
- if (!hdmi.base_wp) {
+ hdmi.hdmi_data.base_wp = ioremap(hdmi_mem->start,
+ resource_size(hdmi_mem));
+ if (!hdmi.hdmi_data.base_wp) {
DSSERR("can't ioremap WP\n");
return -ENOMEM;
}
r = hdmi_get_clocks(pdev);
if (r) {
- iounmap(hdmi.base_wp);
+ iounmap(hdmi.hdmi_data.base_wp);
return r;
}
pm_runtime_enable(&pdev->dev);
+ hdmi.hdmi_data.hdmi_core_sys_offset = HDMI_CORE_SYS;
+ hdmi.hdmi_data.hdmi_core_av_offset = HDMI_CORE_AV;
+ hdmi.hdmi_data.hdmi_pll_offset = HDMI_PLLCTRL;
+ hdmi.hdmi_data.hdmi_phy_offset = HDMI_PHY;
+
hdmi_panel_init();
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
@@ -1808,7 +1904,7 @@ static int omapdss_hdmihw_remove(struct platform_device *pdev)
hdmi_put_clocks();
- iounmap(hdmi.base_wp);
+ iounmap(hdmi.hdmi_data.base_wp);
return 0;
}
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
index c885f9c..2281823 100644
--- a/drivers/video/omap2/dss/hdmi.h
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -24,174 +24,163 @@
#include <linux/string.h>
#include <video/omapdss.h>
-#define HDMI_WP 0x0
-#define HDMI_CORE_SYS 0x400
-#define HDMI_CORE_AV 0x900
-#define HDMI_PLLCTRL 0x200
-#define HDMI_PHY 0x300
-
struct hdmi_reg { u16 idx; };
#define HDMI_REG(idx) ((const struct hdmi_reg) { idx })
/* HDMI Wrapper */
-#define HDMI_WP_REG(idx) HDMI_REG(HDMI_WP + idx)
-
-#define HDMI_WP_REVISION HDMI_WP_REG(0x0)
-#define HDMI_WP_SYSCONFIG HDMI_WP_REG(0x10)
-#define HDMI_WP_IRQSTATUS_RAW HDMI_WP_REG(0x24)
-#define HDMI_WP_IRQSTATUS HDMI_WP_REG(0x28)
-#define HDMI_WP_PWR_CTRL HDMI_WP_REG(0x40)
-#define HDMI_WP_IRQENABLE_SET HDMI_WP_REG(0x2C)
-#define HDMI_WP_VIDEO_CFG HDMI_WP_REG(0x50)
-#define HDMI_WP_VIDEO_SIZE HDMI_WP_REG(0x60)
-#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68)
-#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C)
-#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70)
-#define HDMI_WP_AUDIO_CFG HDMI_WP_REG(0x80)
-#define HDMI_WP_AUDIO_CFG2 HDMI_WP_REG(0x84)
-#define HDMI_WP_AUDIO_CTRL HDMI_WP_REG(0x88)
-#define HDMI_WP_AUDIO_DATA HDMI_WP_REG(0x8C)
+
+#define HDMI_WP_REVISION HDMI_REG(0x0)
+#define HDMI_WP_SYSCONFIG HDMI_REG(0x10)
+#define HDMI_WP_IRQSTATUS_RAW HDMI_REG(0x24)
+#define HDMI_WP_IRQSTATUS HDMI_REG(0x28)
+#define HDMI_WP_PWR_CTRL HDMI_REG(0x40)
+#define HDMI_WP_IRQENABLE_SET HDMI_REG(0x2C)
+#define HDMI_WP_VIDEO_CFG HDMI_REG(0x50)
+#define HDMI_WP_VIDEO_SIZE HDMI_REG(0x60)
+#define HDMI_WP_VIDEO_TIMING_H HDMI_REG(0x68)
+#define HDMI_WP_VIDEO_TIMING_V HDMI_REG(0x6C)
+#define HDMI_WP_WP_CLK HDMI_REG(0x70)
+#define HDMI_WP_AUDIO_CFG HDMI_REG(0x80)
+#define HDMI_WP_AUDIO_CFG2 HDMI_REG(0x84)
+#define HDMI_WP_AUDIO_CTRL HDMI_REG(0x88)
+#define HDMI_WP_AUDIO_DATA HDMI_REG(0x8C)
/* HDMI IP Core System */
-#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx)
-
-#define HDMI_CORE_SYS_VND_IDL HDMI_CORE_SYS_REG(0x0)
-#define HDMI_CORE_SYS_DEV_IDL HDMI_CORE_SYS_REG(0x8)
-#define HDMI_CORE_SYS_DEV_IDH HDMI_CORE_SYS_REG(0xC)
-#define HDMI_CORE_SYS_DEV_REV HDMI_CORE_SYS_REG(0x10)
-#define HDMI_CORE_SYS_SRST HDMI_CORE_SYS_REG(0x14)
-#define HDMI_CORE_CTRL1 HDMI_CORE_SYS_REG(0x20)
-#define HDMI_CORE_SYS_SYS_STAT HDMI_CORE_SYS_REG(0x24)
-#define HDMI_CORE_SYS_VID_ACEN HDMI_CORE_SYS_REG(0x124)
-#define HDMI_CORE_SYS_VID_MODE HDMI_CORE_SYS_REG(0x128)
-#define HDMI_CORE_SYS_INTR_STATE HDMI_CORE_SYS_REG(0x1C0)
-#define HDMI_CORE_SYS_INTR1 HDMI_CORE_SYS_REG(0x1C4)
-#define HDMI_CORE_SYS_INTR2 HDMI_CORE_SYS_REG(0x1C8)
-#define HDMI_CORE_SYS_INTR3 HDMI_CORE_SYS_REG(0x1CC)
-#define HDMI_CORE_SYS_INTR4 HDMI_CORE_SYS_REG(0x1D0)
-#define HDMI_CORE_SYS_UMASK1 HDMI_CORE_SYS_REG(0x1D4)
-#define HDMI_CORE_SYS_TMDS_CTRL HDMI_CORE_SYS_REG(0x208)
-#define HDMI_CORE_SYS_DE_DLY HDMI_CORE_SYS_REG(0xC8)
-#define HDMI_CORE_SYS_DE_CTRL HDMI_CORE_SYS_REG(0xCC)
-#define HDMI_CORE_SYS_DE_TOP HDMI_CORE_SYS_REG(0xD0)
-#define HDMI_CORE_SYS_DE_CNTL HDMI_CORE_SYS_REG(0xD8)
-#define HDMI_CORE_SYS_DE_CNTH HDMI_CORE_SYS_REG(0xDC)
-#define HDMI_CORE_SYS_DE_LINL HDMI_CORE_SYS_REG(0xE0)
-#define HDMI_CORE_SYS_DE_LINH_1 HDMI_CORE_SYS_REG(0xE4)
+
+#define HDMI_CORE_SYS_VND_IDL HDMI_REG(0x0)
+#define HDMI_CORE_SYS_DEV_IDL HDMI_REG(0x8)
+#define HDMI_CORE_SYS_DEV_IDH HDMI_REG(0xC)
+#define HDMI_CORE_SYS_DEV_REV HDMI_REG(0x10)
+#define HDMI_CORE_SYS_SRST HDMI_REG(0x14)
+#define HDMI_CORE_CTRL1 HDMI_REG(0x20)
+#define HDMI_CORE_SYS_SYS_STAT HDMI_REG(0x24)
+#define HDMI_CORE_SYS_VID_ACEN HDMI_REG(0x124)
+#define HDMI_CORE_SYS_VID_MODE HDMI_REG(0x128)
+#define HDMI_CORE_SYS_INTR_STATE HDMI_REG(0x1C0)
+#define HDMI_CORE_SYS_INTR1 HDMI_REG(0x1C4)
+#define HDMI_CORE_SYS_INTR2 HDMI_REG(0x1C8)
+#define HDMI_CORE_SYS_INTR3 HDMI_REG(0x1CC)
+#define HDMI_CORE_SYS_INTR4 HDMI_REG(0x1D0)
+#define HDMI_CORE_SYS_UMASK1 HDMI_REG(0x1D4)
+#define HDMI_CORE_SYS_TMDS_CTRL HDMI_REG(0x208)
+#define HDMI_CORE_SYS_DE_DLY HDMI_REG(0xC8)
+#define HDMI_CORE_SYS_DE_CTRL HDMI_REG(0xCC)
+#define HDMI_CORE_SYS_DE_TOP HDMI_REG(0xD0)
+#define HDMI_CORE_SYS_DE_CNTL HDMI_REG(0xD8)
+#define HDMI_CORE_SYS_DE_CNTH HDMI_REG(0xDC)
+#define HDMI_CORE_SYS_DE_LINL HDMI_REG(0xE0)
+#define HDMI_CORE_SYS_DE_LINH_1 HDMI_REG(0xE4)
#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1
#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1
#define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1
#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1
/* HDMI DDC E-DID */
-#define HDMI_CORE_DDC_CMD HDMI_CORE_SYS_REG(0x3CC)
-#define HDMI_CORE_DDC_STATUS HDMI_CORE_SYS_REG(0x3C8)
-#define HDMI_CORE_DDC_ADDR HDMI_CORE_SYS_REG(0x3B4)
-#define HDMI_CORE_DDC_OFFSET HDMI_CORE_SYS_REG(0x3BC)
-#define HDMI_CORE_DDC_COUNT1 HDMI_CORE_SYS_REG(0x3C0)
-#define HDMI_CORE_DDC_COUNT2 HDMI_CORE_SYS_REG(0x3C4)
-#define HDMI_CORE_DDC_DATA HDMI_CORE_SYS_REG(0x3D0)
-#define HDMI_CORE_DDC_SEGM HDMI_CORE_SYS_REG(0x3B8)
+#define HDMI_CORE_DDC_CMD HDMI_REG(0x3CC)
+#define HDMI_CORE_DDC_STATUS HDMI_REG(0x3C8)
+#define HDMI_CORE_DDC_ADDR HDMI_REG(0x3B4)
+#define HDMI_CORE_DDC_OFFSET HDMI_REG(0x3BC)
+#define HDMI_CORE_DDC_COUNT1 HDMI_REG(0x3C0)
+#define HDMI_CORE_DDC_COUNT2 HDMI_REG(0x3C4)
+#define HDMI_CORE_DDC_DATA HDMI_REG(0x3D0)
+#define HDMI_CORE_DDC_SEGM HDMI_REG(0x3B8)
/* HDMI IP Core Audio Video */
-#define HDMI_CORE_AV_REG(idx) HDMI_REG(HDMI_CORE_AV + idx)
-
-#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
-#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
-#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
-#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
-#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
-#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
-#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
-#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
-#define HDMI_CORE_AV_AVI_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x110)
-#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15)
-#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190)
-#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
-#define HDMI_CORE_AV_AUD_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x210)
-#define HDMI_CORE_AV_AUD_DBYTE_NELEMS HDMI_CORE_AV_REG(10)
-#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290)
-#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
-#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300)
-#define HDMI_CORE_AV_GEN_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
-#define HDMI_CORE_AV_GEN2_DBYTE HDMI_CORE_AV_REG(0x380)
-#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
-#define HDMI_CORE_AV_ACR_CTRL HDMI_CORE_AV_REG(0x4)
-#define HDMI_CORE_AV_FREQ_SVAL HDMI_CORE_AV_REG(0x8)
-#define HDMI_CORE_AV_N_SVAL1 HDMI_CORE_AV_REG(0xC)
-#define HDMI_CORE_AV_N_SVAL2 HDMI_CORE_AV_REG(0x10)
-#define HDMI_CORE_AV_N_SVAL3 HDMI_CORE_AV_REG(0x14)
-#define HDMI_CORE_AV_CTS_SVAL1 HDMI_CORE_AV_REG(0x18)
-#define HDMI_CORE_AV_CTS_SVAL2 HDMI_CORE_AV_REG(0x1C)
-#define HDMI_CORE_AV_CTS_SVAL3 HDMI_CORE_AV_REG(0x20)
-#define HDMI_CORE_AV_CTS_HVAL1 HDMI_CORE_AV_REG(0x24)
-#define HDMI_CORE_AV_CTS_HVAL2 HDMI_CORE_AV_REG(0x28)
-#define HDMI_CORE_AV_CTS_HVAL3 HDMI_CORE_AV_REG(0x2C)
-#define HDMI_CORE_AV_AUD_MODE HDMI_CORE_AV_REG(0x50)
-#define HDMI_CORE_AV_SPDIF_CTRL HDMI_CORE_AV_REG(0x54)
-#define HDMI_CORE_AV_HW_SPDIF_FS HDMI_CORE_AV_REG(0x60)
-#define HDMI_CORE_AV_SWAP_I2S HDMI_CORE_AV_REG(0x64)
-#define HDMI_CORE_AV_SPDIF_ERTH HDMI_CORE_AV_REG(0x6C)
-#define HDMI_CORE_AV_I2S_IN_MAP HDMI_CORE_AV_REG(0x70)
-#define HDMI_CORE_AV_I2S_IN_CTRL HDMI_CORE_AV_REG(0x74)
-#define HDMI_CORE_AV_I2S_CHST0 HDMI_CORE_AV_REG(0x78)
-#define HDMI_CORE_AV_I2S_CHST1 HDMI_CORE_AV_REG(0x7C)
-#define HDMI_CORE_AV_I2S_CHST2 HDMI_CORE_AV_REG(0x80)
-#define HDMI_CORE_AV_I2S_CHST4 HDMI_CORE_AV_REG(0x84)
-#define HDMI_CORE_AV_I2S_CHST5 HDMI_CORE_AV_REG(0x88)
-#define HDMI_CORE_AV_ASRC HDMI_CORE_AV_REG(0x8C)
-#define HDMI_CORE_AV_I2S_IN_LEN HDMI_CORE_AV_REG(0x90)
-#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
-#define HDMI_CORE_AV_AUDO_TXSTAT HDMI_CORE_AV_REG(0xC0)
-#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 HDMI_CORE_AV_REG(0xCC)
-#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 HDMI_CORE_AV_REG(0xD0)
-#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 HDMI_CORE_AV_REG(0xD4)
-#define HDMI_CORE_AV_TEST_TXCTRL HDMI_CORE_AV_REG(0xF0)
-#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
-#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
-#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
-#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
-#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
-#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
-#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
-#define HDMI_CORE_AV_SPD_TYPE HDMI_CORE_AV_REG(0x180)
-#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184)
-#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188)
-#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C)
-#define HDMI_CORE_AV_AUDIO_TYPE HDMI_CORE_AV_REG(0x200)
-#define HDMI_CORE_AV_AUDIO_VERS HDMI_CORE_AV_REG(0x204)
-#define HDMI_CORE_AV_AUDIO_LEN HDMI_CORE_AV_REG(0x208)
-#define HDMI_CORE_AV_AUDIO_CHSUM HDMI_CORE_AV_REG(0x20C)
-#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280)
-#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284)
-#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288)
-#define HDMI_CORE_AV_MPEG_CHSUM HDMI_CORE_AV_REG(0x28C)
-#define HDMI_CORE_AV_CP_BYTE1 HDMI_CORE_AV_REG(0x37C)
-#define HDMI_CORE_AV_CEC_ADDR_ID HDMI_CORE_AV_REG(0x3FC)
+
+#define HDMI_CORE_AV_HDMI_CTRL HDMI_REG(0xBC)
+#define HDMI_CORE_AV_DPD HDMI_REG(0xF4)
+#define HDMI_CORE_AV_PB_CTRL1 HDMI_REG(0xF8)
+#define HDMI_CORE_AV_PB_CTRL2 HDMI_REG(0xFC)
+#define HDMI_CORE_AV_AVI_TYPE HDMI_REG(0x100)
+#define HDMI_CORE_AV_AVI_VERS HDMI_REG(0x104)
+#define HDMI_CORE_AV_AVI_LEN HDMI_REG(0x108)
+#define HDMI_CORE_AV_AVI_CHSUM HDMI_REG(0x10C)
+#define HDMI_CORE_AV_AVI_DBYTE(n) HDMI_REG(n * 4 + 0x110)
+#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_REG(15)
+#define HDMI_CORE_AV_SPD_DBYTE HDMI_REG(0x190)
+#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_REG(27)
+#define HDMI_CORE_AV_AUD_DBYTE(n) HDMI_REG(n * 4 + 0x210)
+#define HDMI_CORE_AV_AUD_DBYTE_NELEMS HDMI_REG(10)
+#define HDMI_CORE_AV_MPEG_DBYTE HDMI_REG(0x290)
+#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_REG(27)
+#define HDMI_CORE_AV_GEN_DBYTE HDMI_REG(0x300)
+#define HDMI_CORE_AV_GEN_DBYTE_NELEMS HDMI_REG(31)
+#define HDMI_CORE_AV_GEN2_DBYTE HDMI_REG(0x380)
+#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS HDMI_REG(31)
+#define HDMI_CORE_AV_ACR_CTRL HDMI_REG(0x4)
+#define HDMI_CORE_AV_FREQ_SVAL HDMI_REG(0x8)
+#define HDMI_CORE_AV_N_SVAL1 HDMI_REG(0xC)
+#define HDMI_CORE_AV_N_SVAL2 HDMI_REG(0x10)
+#define HDMI_CORE_AV_N_SVAL3 HDMI_REG(0x14)
+#define HDMI_CORE_AV_CTS_SVAL1 HDMI_REG(0x18)
+#define HDMI_CORE_AV_CTS_SVAL2 HDMI_REG(0x1C)
+#define HDMI_CORE_AV_CTS_SVAL3 HDMI_REG(0x20)
+#define HDMI_CORE_AV_CTS_HVAL1 HDMI_REG(0x24)
+#define HDMI_CORE_AV_CTS_HVAL2 HDMI_REG(0x28)
+#define HDMI_CORE_AV_CTS_HVAL3 HDMI_REG(0x2C)
+#define HDMI_CORE_AV_AUD_MODE HDMI_REG(0x50)
+#define HDMI_CORE_AV_SPDIF_CTRL HDMI_REG(0x54)
+#define HDMI_CORE_AV_HW_SPDIF_FS HDMI_REG(0x60)
+#define HDMI_CORE_AV_SWAP_I2S HDMI_REG(0x64)
+#define HDMI_CORE_AV_SPDIF_ERTH HDMI_REG(0x6C)
+#define HDMI_CORE_AV_I2S_IN_MAP HDMI_REG(0x70)
+#define HDMI_CORE_AV_I2S_IN_CTRL HDMI_REG(0x74)
+#define HDMI_CORE_AV_I2S_CHST0 HDMI_REG(0x78)
+#define HDMI_CORE_AV_I2S_CHST1 HDMI_REG(0x7C)
+#define HDMI_CORE_AV_I2S_CHST2 HDMI_REG(0x80)
+#define HDMI_CORE_AV_I2S_CHST4 HDMI_REG(0x84)
+#define HDMI_CORE_AV_I2S_CHST5 HDMI_REG(0x88)
+#define HDMI_CORE_AV_ASRC HDMI_REG(0x8C)
+#define HDMI_CORE_AV_I2S_IN_LEN HDMI_REG(0x90)
+#define HDMI_CORE_AV_HDMI_CTRL HDMI_REG(0xBC)
+#define HDMI_CORE_AV_AUDO_TXSTAT HDMI_REG(0xC0)
+#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 HDMI_REG(0xCC)
+#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 HDMI_REG(0xD0)
+#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 HDMI_REG(0xD4)
+#define HDMI_CORE_AV_TEST_TXCTRL HDMI_REG(0xF0)
+#define HDMI_CORE_AV_DPD HDMI_REG(0xF4)
+#define HDMI_CORE_AV_PB_CTRL1 HDMI_REG(0xF8)
+#define HDMI_CORE_AV_PB_CTRL2 HDMI_REG(0xFC)
+#define HDMI_CORE_AV_AVI_TYPE HDMI_REG(0x100)
+#define HDMI_CORE_AV_AVI_VERS HDMI_REG(0x104)
+#define HDMI_CORE_AV_AVI_LEN HDMI_REG(0x108)
+#define HDMI_CORE_AV_AVI_CHSUM HDMI_REG(0x10C)
+#define HDMI_CORE_AV_SPD_TYPE HDMI_REG(0x180)
+#define HDMI_CORE_AV_SPD_VERS HDMI_REG(0x184)
+#define HDMI_CORE_AV_SPD_LEN HDMI_REG(0x188)
+#define HDMI_CORE_AV_SPD_CHSUM HDMI_REG(0x18C)
+#define HDMI_CORE_AV_AUDIO_TYPE HDMI_REG(0x200)
+#define HDMI_CORE_AV_AUDIO_VERS HDMI_REG(0x204)
+#define HDMI_CORE_AV_AUDIO_LEN HDMI_REG(0x208)
+#define HDMI_CORE_AV_AUDIO_CHSUM HDMI_REG(0x20C)
+#define HDMI_CORE_AV_MPEG_TYPE HDMI_REG(0x280)
+#define HDMI_CORE_AV_MPEG_VERS HDMI_REG(0x284)
+#define HDMI_CORE_AV_MPEG_LEN HDMI_REG(0x288)
+#define HDMI_CORE_AV_MPEG_CHSUM HDMI_REG(0x28C)
+#define HDMI_CORE_AV_CP_BYTE1 HDMI_REG(0x37C)
+#define HDMI_CORE_AV_CEC_ADDR_ID HDMI_REG(0x3FC)
#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4
#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4
#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4
#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4
/* PLL */
-#define HDMI_PLL_REG(idx) HDMI_REG(HDMI_PLLCTRL + idx)
-#define PLLCTRL_PLL_CONTROL HDMI_PLL_REG(0x0)
-#define PLLCTRL_PLL_STATUS HDMI_PLL_REG(0x4)
-#define PLLCTRL_PLL_GO HDMI_PLL_REG(0x8)
-#define PLLCTRL_CFG1 HDMI_PLL_REG(0xC)
-#define PLLCTRL_CFG2 HDMI_PLL_REG(0x10)
-#define PLLCTRL_CFG3 HDMI_PLL_REG(0x14)
-#define PLLCTRL_CFG4 HDMI_PLL_REG(0x20)
+#define PLLCTRL_PLL_CONTROL HDMI_REG(0x0)
+#define PLLCTRL_PLL_STATUS HDMI_REG(0x4)
+#define PLLCTRL_PLL_GO HDMI_REG(0x8)
+#define PLLCTRL_CFG1 HDMI_REG(0xC)
+#define PLLCTRL_CFG2 HDMI_REG(0x10)
+#define PLLCTRL_CFG3 HDMI_REG(0x14)
+#define PLLCTRL_CFG4 HDMI_REG(0x20)
/* HDMI PHY */
-#define HDMI_PHY_REG(idx) HDMI_REG(HDMI_PHY + idx)
-#define HDMI_TXPHY_TX_CTRL HDMI_PHY_REG(0x0)
-#define HDMI_TXPHY_DIGITAL_CTRL HDMI_PHY_REG(0x4)
-#define HDMI_TXPHY_POWER_CTRL HDMI_PHY_REG(0x8)
-#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_PHY_REG(0xC)
+#define HDMI_TXPHY_TX_CTRL HDMI_REG(0x0)
+#define HDMI_TXPHY_DIGITAL_CTRL HDMI_REG(0x4)
+#define HDMI_TXPHY_POWER_CTRL HDMI_REG(0x8)
+#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_REG(0xC)
/* HDMI EDID Length */
#define HDMI_EDID_MAX_LENGTH 256
@@ -203,10 +192,11 @@ struct hdmi_reg { u16 idx; };
#define OMAP_HDMI_TIMINGS_NB 34
-#define REG_FLD_MOD(idx, val, start, end) \
- hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end))
-#define REG_GET(idx, start, end) \
- FLD_GET(hdmi_read_reg(idx), start, end)
+#define REG_FLD_MOD(base, idx, val, start, end) \
+ hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\
+ val, start, end))
+#define REG_GET(base, idx, start, end) \
+ FLD_GET(hdmi_read_reg(base, idx), start, end)
/* HDMI timing structure */
struct hdmi_timings {
@@ -568,6 +558,14 @@ struct hdmi_video_interface {
int tm; /* Timing mode */
};
+struct hdmi_ip_data {
+ void __iomem *base_wp; /* HDMI wrapper */
+ unsigned long hdmi_core_sys_offset;
+ unsigned long hdmi_core_av_offset;
+ unsigned long hdmi_pll_offset;
+ unsigned long hdmi_phy_offset;
+};
+
struct hdmi_cm {
int code;
int mode;
--
1.7.5.4
^ permalink raw reply related
* [PATCH 2/8] OMAP4 : DSS : HDMI : Move the EDID portion from HDMI IP
From: Mythri P K @ 2011-06-22 11:55 UTC (permalink / raw)
To: linux-fbdev
Clean up to move the EDID definition to hdmi.c from the header file which is IP
dependent.
Signed-off-by: Mythri P K <mythripk@ti.com>
---
drivers/video/omap2/dss/hdmi.c | 10 ++++++++++
drivers/video/omap2/dss/hdmi.h | 10 ----------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 1d16ee2..4ee879a 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -49,6 +49,16 @@
#define HDMI_PLLCTRL 0x200
#define HDMI_PHY 0x300
+/* HDMI EDID Length move this */
+#define HDMI_EDID_MAX_LENGTH 256
+#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
+#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
+#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
+#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
+#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
+
+#define OMAP_HDMI_TIMINGS_NB 34
+
static struct {
struct mutex lock;
struct omap_display_platform_data *pdata;
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
index 2281823..f57ef4a 100644
--- a/drivers/video/omap2/dss/hdmi.h
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -182,16 +182,6 @@ struct hdmi_reg { u16 idx; };
#define HDMI_TXPHY_POWER_CTRL HDMI_REG(0x8)
#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_REG(0xC)
-/* HDMI EDID Length */
-#define HDMI_EDID_MAX_LENGTH 256
-#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
-#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
-#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
-#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
-#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
-
-#define OMAP_HDMI_TIMINGS_NB 34
-
#define REG_FLD_MOD(base, idx, val, start, end) \
hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\
val, start, end))
--
1.7.5.4
^ permalink raw reply related
* [PATCH 3/8] OMAP4: DSS: HDMI: Use specific HDMI timings structure
From: Mythri P K @ 2011-06-22 11:55 UTC (permalink / raw)
To: linux-fbdev
Define new HDMI timings structure to replace the OMAP DSS timing strucutre in hdmi.c
to have the HDMI include defintion out of DSS.
Signed-off-by: Mythri P K <mythripk@ti.com>
---
drivers/video/omap2/dss/hdmi.c | 23 ++++++++++++++++++++---
drivers/video/omap2/dss/hdmi.h | 15 ++++++++++++++-
2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 4ee879a..c24d573 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -593,6 +593,20 @@ static int read_edid(struct hdmi_ip_data *ip_data, u8 *pedid, u16 max_length)
return 0;
}
+static void copy_hdmi_to_dss_timings(struct hdmi_video_timings hdmi_timings,
+ struct omap_video_timings *timings)
+{
+ timings->x_res = hdmi_timings.x_res;
+ timings->y_res = hdmi_timings.y_res;
+ timings->pixel_clock = hdmi_timings.pixel_clock;
+ timings->hbp = hdmi_timings.hbp;
+ timings->hfp = hdmi_timings.hfp;
+ timings->hsw = hdmi_timings.hsw;
+ timings->vbp = hdmi_timings.vbp;
+ timings->vfp = hdmi_timings.vfp;
+ timings->vsw = hdmi_timings.vsw;
+}
+
static int get_timings_index(void)
{
int code;
@@ -617,7 +631,7 @@ static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
{
int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0;
int timing_vsync = 0, timing_hsync = 0;
- struct omap_video_timings temp;
+ struct hdmi_video_timings temp;
struct hdmi_cm cm = {-1};
DSSDBG("hdmi_get_code\n");
@@ -775,7 +789,8 @@ static void hdmi_read_edid(struct omap_video_timings *dp)
code = get_timings_index();
- *dp = cea_vesa_timings[code].timings;
+ copy_hdmi_to_dss_timings(cea_vesa_timings[code].timings, dp);
+
}
static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
@@ -1234,7 +1249,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
hdmi_read_edid(p);
}
code = get_timings_index();
- dssdev->panel.timings = cea_vesa_timings[code].timings;
+ copy_hdmi_to_dss_timings(cea_vesa_timings[code].timings,
+ &dssdev->panel.timings);
+
update_hdmi_timings(&hdmi.cfg, p, code);
phy = p->pixel_clock;
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
index f57ef4a..dcc30b7 100644
--- a/drivers/video/omap2/dss/hdmi.h
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -188,9 +188,22 @@ struct hdmi_reg { u16 idx; };
#define REG_GET(base, idx, start, end) \
FLD_GET(hdmi_read_reg(base, idx), start, end)
+struct hdmi_video_timings {
+ u16 x_res;
+ u16 y_res;
+ /* Unit: KHz */
+ u32 pixel_clock;
+ u16 hsw;
+ u16 hfp;
+ u16 hbp;
+ u16 vsw;
+ u16 vfp;
+ u16 vbp;
+};
+
/* HDMI timing structure */
struct hdmi_timings {
- struct omap_video_timings timings;
+ struct hdmi_video_timings timings;
int vsync_pol;
int hsync_pol;
};
--
1.7.5.4
^ permalink raw reply related
* [PATCH 4/8] OMAP4: DSS: HDMI: Move the common header file definition
From: Mythri P K @ 2011-06-22 11:55 UTC (permalink / raw)
To: linux-fbdev
Some of the header file definitions of HDMI IP are needed by audio driver thus
moving the common defintion to more generic Include/video.
Signed-off-by: Mythri P K <mythripk@ti.com>
---
drivers/video/omap2/dss/dss.h | 10 -----
drivers/video/omap2/dss/hdmi.c | 1 +
drivers/video/omap2/dss/hdmi.h | 51 -----------------------
include/video/hdmi_ti_4xxx_ip.h | 84 +++++++++++++++++++++++++++++++++++++++
4 files changed, 85 insertions(+), 61 deletions(-)
create mode 100644 include/video/hdmi_ti_4xxx_ip.h
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index ce17a61..324e982 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -156,16 +156,6 @@ struct dsi_clock_info {
bool use_sys_clk;
};
-/* HDMI PLL structure */
-struct hdmi_pll_info {
- u16 regn;
- u16 regm;
- u32 regmf;
- u16 regm2;
- u16 regsd;
- u16 dcofreq;
-};
-
struct seq_file;
struct platform_device;
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index c24d573..1f34f63 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -33,6 +33,7 @@
#include <linux/pm_runtime.h>
#include <linux/clk.h>
#include <video/omapdss.h>
+#include <video/hdmi_ti_4xxx_ip.h>
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
#include <sound/soc.h>
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
index dcc30b7..4b0fab3 100644
--- a/drivers/video/omap2/dss/hdmi.h
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -188,39 +188,12 @@ struct hdmi_reg { u16 idx; };
#define REG_GET(base, idx, start, end) \
FLD_GET(hdmi_read_reg(base, idx), start, end)
-struct hdmi_video_timings {
- u16 x_res;
- u16 y_res;
- /* Unit: KHz */
- u32 pixel_clock;
- u16 hsw;
- u16 hfp;
- u16 hbp;
- u16 vsw;
- u16 vfp;
- u16 vbp;
-};
-
-/* HDMI timing structure */
-struct hdmi_timings {
- struct hdmi_video_timings timings;
- int vsync_pol;
- int hsync_pol;
-};
-
enum hdmi_phy_pwr {
HDMI_PHYPWRCMD_OFF = 0,
HDMI_PHYPWRCMD_LDOON = 1,
HDMI_PHYPWRCMD_TXON = 2
};
-enum hdmi_pll_pwr {
- HDMI_PLLPWRCMD_ALLOFF = 0,
- HDMI_PLLPWRCMD_PLLONLY = 1,
- HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
- HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
-};
-
enum hdmi_clk_refsel {
HDMI_REFSEL_PCLK = 0,
HDMI_REFSEL_REF1 = 1,
@@ -256,11 +229,6 @@ enum hdmi_core_packet_mode {
HDMI_PACKETMODE48BITPERPIXEL = 7
};
-enum hdmi_core_hdmi_dvi {
- HDMI_DVI = 0,
- HDMI_HDMI = 1
-};
-
enum hdmi_core_tclkselclkmult {
HDMI_FPLL05IDCK = 0,
HDMI_FPLL10IDCK = 1,
@@ -561,25 +529,6 @@ struct hdmi_video_interface {
int tm; /* Timing mode */
};
-struct hdmi_ip_data {
- void __iomem *base_wp; /* HDMI wrapper */
- unsigned long hdmi_core_sys_offset;
- unsigned long hdmi_core_av_offset;
- unsigned long hdmi_pll_offset;
- unsigned long hdmi_phy_offset;
-};
-
-struct hdmi_cm {
- int code;
- int mode;
-};
-
-struct hdmi_config {
- struct hdmi_timings timings;
- u16 interlace;
- struct hdmi_cm cm;
-};
-
struct hdmi_audio_format {
enum hdmi_stereo_channels stereo_channels;
u8 active_chnnls_msk;
diff --git a/include/video/hdmi_ti_4xxx_ip.h b/include/video/hdmi_ti_4xxx_ip.h
new file mode 100644
index 0000000..49640cd
--- /dev/null
+++ b/include/video/hdmi_ti_4xxx_ip.h
@@ -0,0 +1,84 @@
+/*
+ * hdmi_ti_4xxx_ip.h
+ *
+ * HDMI driver definition for TI OMAP4, TI81xx, TI38xx Processor.
+ *
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.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/>.
+ */
+
+#ifndef _HDMI_TI_4xxx_
+#define _HDMI_TI_4xxx_
+
+enum hdmi_pll_pwr {
+ HDMI_PLLPWRCMD_ALLOFF = 0,
+ HDMI_PLLPWRCMD_PLLONLY = 1,
+ HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
+ HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
+};
+
+enum hdmi_core_hdmi_dvi {
+ HDMI_DVI = 0,
+ HDMI_HDMI = 1
+};
+
+struct hdmi_ip_data {
+ void __iomem *base_wp; /* HDMI wrapper */
+ unsigned long hdmi_core_sys_offset;
+ unsigned long hdmi_core_av_offset;
+ unsigned long hdmi_pll_offset;
+ unsigned long hdmi_phy_offset;
+};
+
+struct hdmi_video_timings {
+ u16 x_res;
+ u16 y_res;
+ /* Unit: KHz */
+ u32 pixel_clock;
+ u16 hsw;
+ u16 hfp;
+ u16 hbp;
+ u16 vsw;
+ u16 vfp;
+ u16 vbp;
+};
+
+/* HDMI timing structure */
+struct hdmi_timings {
+ struct hdmi_video_timings timings;
+ int vsync_pol;
+ int hsync_pol;
+};
+
+struct hdmi_cm {
+ int code;
+ int mode;
+};
+
+struct hdmi_config {
+ struct hdmi_timings timings;
+ u16 interlace;
+ struct hdmi_cm cm;
+};
+
+/* HDMI PLL structure */
+struct hdmi_pll_info {
+ u16 regn;
+ u16 regm;
+ u32 regmf;
+ u16 regm2;
+ u16 regsd;
+ u16 dcofreq;
+};
+#endif
--
1.7.5.4
^ permalink raw reply related
* [PATCH 5/8] OMAP4: DSS2: HDMI: Split the HDMI driver to DSS and IP
From: Mythri P K @ 2011-06-22 11:55 UTC (permalink / raw)
To: linux-fbdev
Splitting HDMI IP dependent IP configuring code from HDMI DSS dependent code and
moving to a new IP file.
Signed-off-by: Mythri P K <mythripk@ti.com>
---
drivers/video/omap2/dss/Makefile | 1 +
drivers/video/omap2/dss/hdmi.c | 751 -------------------
drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c | 781 ++++++++++++++++++++
.../video/omap2/dss/{hdmi.h => hdmi_ti_4xxx_ip.h} | 9 +-
include/video/hdmi_ti_4xxx_ip.h | 10 +
5 files changed, 797 insertions(+), 755 deletions(-)
create mode 100644 drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c
rename drivers/video/omap2/dss/{hdmi.h => hdmi_ti_4xxx_ip.h} (99%)
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 10d9d3b..cf967e0 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -6,4 +6,5 @@ omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
+ hdmi_ti_4xxx_ip.o \
hdmi_omap4_panel.o
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 1f34f63..1bd98d9 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -41,7 +41,6 @@
#endif
#include "dss.h"
-#include "hdmi.h"
#include "dss_features.h"
#define HDMI_WP 0x0
@@ -163,58 +162,6 @@ static const int code_vesa[85] = {
static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
-static inline void hdmi_write_reg(void __iomem *base_addr,
- const struct hdmi_reg idx, u32 val)
-{
- __raw_writel(val, base_addr + idx.idx);
-}
-
-static inline u32 hdmi_read_reg(void __iomem *base_addr,
- const struct hdmi_reg idx)
-{
- return __raw_readl(base_addr + idx.idx);
-}
-
-static inline void __iomem *hdmi_wp_base(struct hdmi_ip_data *ip_data)
-{
- return (void __iomem *) (ip_data->base_wp);
-}
-
-static inline void __iomem *hdmi_phy_base(struct hdmi_ip_data *ip_data)
-{
- return (void __iomem *) (ip_data->base_wp + ip_data->hdmi_phy_offset);
-}
-
-static inline void __iomem *hdmi_pll_base(struct hdmi_ip_data *ip_data)
-{
- return (void __iomem *) (ip_data->base_wp + ip_data->hdmi_pll_offset);
-}
-
-static inline void __iomem *hdmi_av_base(struct hdmi_ip_data *ip_data)
-{
- return (void __iomem *)
- (ip_data->base_wp + ip_data->hdmi_core_av_offset);
-}
-
-static inline void __iomem *hdmi_core_sys_base(struct hdmi_ip_data *ip_data)
-{
- return (void __iomem *)
- (ip_data->base_wp + ip_data->hdmi_core_sys_offset);
-}
-
-static inline int hdmi_wait_for_bit_change(void __iomem *base_addr,
- const struct hdmi_reg idx,
- int b2, int b1, u32 val)
-{
- u32 t = 0;
- while (val != REG_GET(base_addr, idx, b2, b1)) {
- udelay(1);
- if (t++ > 10000)
- return !val;
- }
- return val;
-}
-
static int hdmi_runtime_get(void)
{
int r;
@@ -272,328 +219,6 @@ int hdmi_init_display(struct omap_dss_device *dssdev)
return 0;
}
-static int hdmi_pll_init(struct hdmi_ip_data *ip_data,
- enum hdmi_clk_refsel refsel, int dcofreq,
- struct hdmi_pll_info *fmt, u16 sd)
-{
- u32 r;
-
- /* PLL start always use manual mode */
- REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
-
- r = hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG1);
- r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
- r = FLD_MOD(r, fmt->regn, 8, 1); /* CFG1_PLL_REGN */
-
- hdmi_write_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG1, r);
-
- r = hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG2);
-
- r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
- r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
- r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
-
- if (dcofreq) {
- /* divider programming for frequency beyond 1000Mhz */
- REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_CFG3, sd, 17, 10);
- r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
- } else {
- r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
- }
-
- hdmi_write_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG2, r);
-
- r = hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG4);
- r = FLD_MOD(r, fmt->regm2, 24, 18);
- r = FLD_MOD(r, fmt->regmf, 17, 0);
-
- hdmi_write_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG4, r);
-
- /* go now */
- REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_PLL_GO, 0x1, 0, 0);
-
- /* wait for bit change */
- if (hdmi_wait_for_bit_change(hdmi_pll_base(ip_data), PLLCTRL_PLL_GO,
- 0, 0, 1) != 1) {
- DSSERR("PLL GO bit not set\n");
- return -ETIMEDOUT;
- }
-
- /* Wait till the lock bit is set in PLL status */
- if (hdmi_wait_for_bit_change(hdmi_pll_base(ip_data),
- PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
- DSSWARN("cannot lock PLL\n");
- DSSWARN("CFG1 0x%x\n",
- hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG1));
- DSSWARN("CFG2 0x%x\n",
- hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG2));
- DSSWARN("CFG4 0x%x\n",
- hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG4));
- return -ETIMEDOUT;
- }
-
- DSSDBG("PLL locked!\n");
-
- return 0;
-}
-
-/* PHY_PWR_CMD */
-static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val)
-{
- /* Command for power control of HDMI PHY */
- REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6);
-
- /* Status of the power control of HDMI PHY */
- if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data),
- HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
- DSSERR("Failed to set PHY power mode to %d\n", val);
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-/* PLL_PWR_CMD */
-int hdmi_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val)
-{
- /* Command for power control of HDMI PLL */
- REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 3, 2);
-
- /* wait till PHY_PWR_STATUS is set */
- if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL,
- 1, 0, val) != val) {
- DSSERR("Failed to set PHY_PWR_STATUS\n");
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-static int hdmi_pll_reset(struct hdmi_ip_data *ip_data)
-{
- /* SYSRESET controlled by power FSM */
- REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
-
- /* READ 0x0 reset is in progress */
- if (hdmi_wait_for_bit_change(hdmi_pll_base(ip_data),
- PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
- DSSERR("Failed to sysreset PLL\n");
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-static int hdmi_phy_init(struct hdmi_ip_data *ip_data)
-{
- u16 r = 0;
-
- r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
- if (r)
- return r;
-
- r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
- if (r)
- return r;
-
- /*
- * Read address 0 in order to get the SCP reset done completed
- * Dummy access performed to make sure reset is done
- */
- hdmi_read_reg(hdmi_phy_base(ip_data), HDMI_TXPHY_TX_CTRL);
-
- /*
- * Write to phy address 0 to configure the clock
- * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
- */
- REG_FLD_MOD(hdmi_phy_base(ip_data), HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
-
- /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
- hdmi_write_reg(hdmi_phy_base(ip_data),
- HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
-
- /* Setup max LDO voltage */
- REG_FLD_MOD(hdmi_phy_base(ip_data), HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
-
- /* Write to phy address 3 to change the polarity control */
- REG_FLD_MOD(hdmi_phy_base(ip_data),
- HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
-
- return 0;
-}
-
-static int hdmi_pll_program(struct hdmi_ip_data *ip_data,
- struct hdmi_pll_info *fmt)
-{
- u16 r = 0;
- enum hdmi_clk_refsel refsel;
-
- r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
- if (r)
- return r;
-
- r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
- if (r)
- return r;
-
- r = hdmi_pll_reset(ip_data);
- if (r)
- return r;
-
- refsel = HDMI_REFSEL_SYSCLK;
-
- r = hdmi_pll_init(ip_data, refsel, fmt->dcofreq, fmt, fmt->regsd);
- if (r)
- return r;
-
- return 0;
-}
-
-static void hdmi_phy_off(struct hdmi_ip_data *ip_data)
-{
- hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
-}
-
-static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
- u8 *pedid, int ext)
-{
- u32 i, j;
- char checksum = 0;
- u32 offset = 0;
-
- /* Turn on CLK for DDC */
- REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_DPD, 0x7, 2, 0);
-
- /*
- * SW HACK : Without the Delay DDC(i2c bus) reads 0 values /
- * right shifted values( The behavior is not consistent and seen only
- * with some TV's)
- */
- usleep_range(800, 1000);
-
- if (!ext) {
- /* Clk SCL Devices */
- REG_FLD_MOD(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_CMD, 0xA, 3, 0);
-
- /* HDMI_CORE_DDC_STATUS_IN_PROG */
- if (hdmi_wait_for_bit_change(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) {
- DSSERR("Failed to program DDC\n");
- return -ETIMEDOUT;
- }
-
- /* Clear FIFO */
- REG_FLD_MOD(hdmi_core_sys_base(ip_data)
- , HDMI_CORE_DDC_CMD, 0x9, 3, 0);
-
- /* HDMI_CORE_DDC_STATUS_IN_PROG */
- if (hdmi_wait_for_bit_change(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) {
- DSSERR("Failed to program DDC\n");
- return -ETIMEDOUT;
- }
-
- } else {
- if (ext % 2 != 0)
- offset = 0x80;
- }
-
- /* Load Segment Address Register */
- REG_FLD_MOD(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
-
- /* Load Slave Address Register */
- REG_FLD_MOD(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
-
- /* Load Offset Address Register */
- REG_FLD_MOD(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_OFFSET, offset, 7, 0);
-
- /* Load Byte Count */
- REG_FLD_MOD(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
- REG_FLD_MOD(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
-
- /* Set DDC_CMD */
- if (ext)
- REG_FLD_MOD(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_CMD, 0x4, 3, 0);
- else
- REG_FLD_MOD(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_CMD, 0x2, 3, 0);
-
- /* HDMI_CORE_DDC_STATUS_BUS_LOW */
- if (REG_GET(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_STATUS, 6, 6) = 1) {
- DSSWARN("I2C Bus Low?\n");
- return -EIO;
- }
- /* HDMI_CORE_DDC_STATUS_NO_ACK */
- if (REG_GET(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_STATUS, 5, 5) = 1) {
- DSSWARN("I2C No Ack\n");
- return -EIO;
- }
-
- i = ext * 128;
- j = 0;
- while (((REG_GET(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_STATUS, 4, 4) = 1) ||
- (REG_GET(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_STATUS, 2, 2) = 0)) && j < 128) {
-
- if (REG_GET(hdmi_core_sys_base(ip_data)
- , HDMI_CORE_DDC_STATUS, 2, 2) = 0) {
- /* FIFO not empty */
- pedid[i++] = REG_GET(hdmi_core_sys_base(ip_data),
- HDMI_CORE_DDC_DATA, 7, 0);
- j++;
- }
- }
-
- for (j = 0; j < 128; j++)
- checksum += pedid[j];
-
- if (checksum != 0) {
- DSSERR("E-EDID checksum failed!!\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static int read_edid(struct hdmi_ip_data *ip_data, u8 *pedid, u16 max_length)
-{
- int r = 0, n = 0, i = 0;
- int max_ext_blocks = (max_length / 128) - 1;
-
- r = hdmi_core_ddc_edid(ip_data, pedid, 0);
- if (r) {
- return r;
- } else {
- n = pedid[0x7e];
-
- /*
- * README: need to comply with max_length set by the caller.
- * Better implementation should be to allocate necessary
- * memory to store EDID according to nb_block field found
- * in first block
- */
- if (n > max_ext_blocks)
- n = max_ext_blocks;
-
- for (i = 1; i <= n; i++) {
- r = hdmi_core_ddc_edid(ip_data, pedid, i);
- if (r)
- return r;
- }
- }
- return 0;
-}
-
static void copy_hdmi_to_dss_timings(struct hdmi_video_timings hdmi_timings,
struct omap_video_timings *timings)
{
@@ -794,382 +419,6 @@ static void hdmi_read_edid(struct omap_video_timings *dp)
}
-static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
- struct hdmi_core_infoframe_avi *avi_cfg,
- struct hdmi_core_packet_enable_repeat *repeat_cfg)
-{
- DSSDBG("Enter hdmi_core_init\n");
-
- /* video core */
- video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
- video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
- video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
- video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
- video_cfg->hdmi_dvi = HDMI_DVI;
- video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
-
- /* info frame */
- avi_cfg->db1_format = 0;
- avi_cfg->db1_active_info = 0;
- avi_cfg->db1_bar_info_dv = 0;
- avi_cfg->db1_scan_info = 0;
- avi_cfg->db2_colorimetry = 0;
- avi_cfg->db2_aspect_ratio = 0;
- avi_cfg->db2_active_fmt_ar = 0;
- avi_cfg->db3_itc = 0;
- avi_cfg->db3_ec = 0;
- avi_cfg->db3_q_range = 0;
- avi_cfg->db3_nup_scaling = 0;
- avi_cfg->db4_videocode = 0;
- avi_cfg->db5_pixel_repeat = 0;
- avi_cfg->db6_7_line_eoftop = 0 ;
- avi_cfg->db8_9_line_sofbottom = 0;
- avi_cfg->db10_11_pixel_eofleft = 0;
- avi_cfg->db12_13_pixel_sofright = 0;
-
- /* packet enable and repeat */
- repeat_cfg->audio_pkt = 0;
- repeat_cfg->audio_pkt_repeat = 0;
- repeat_cfg->avi_infoframe = 0;
- repeat_cfg->avi_infoframe_repeat = 0;
- repeat_cfg->gen_cntrl_pkt = 0;
- repeat_cfg->gen_cntrl_pkt_repeat = 0;
- repeat_cfg->generic_pkt = 0;
- repeat_cfg->generic_pkt_repeat = 0;
-}
-
-static void hdmi_core_powerdown_disable(struct hdmi_ip_data *ip_data)
-{
- DSSDBG("Enter hdmi_core_powerdown_disable\n");
- REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_CTRL1, 0x0, 0, 0);
-}
-
-static void hdmi_core_swreset_release(struct hdmi_ip_data *ip_data)
-{
- DSSDBG("Enter hdmi_core_swreset_release\n");
- REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_SRST, 0x0, 0, 0);
-}
-
-static void hdmi_core_swreset_assert(struct hdmi_ip_data *ip_data)
-{
- DSSDBG("Enter hdmi_core_swreset_assert\n");
- REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_SRST, 0x1, 0, 0);
-}
-
-/* HDMI_CORE_VIDEO_CONFIG */
-static void hdmi_core_video_config(struct hdmi_ip_data *ip_data,
- struct hdmi_core_video_config *cfg)
-{
- u32 r = 0;
-
- /* sys_ctrl1 default configuration not tunable */
- r = hdmi_read_reg(hdmi_core_sys_base(ip_data), HDMI_CORE_CTRL1);
- r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
- r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
- r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
- r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
- hdmi_write_reg(hdmi_core_sys_base(ip_data), HDMI_CORE_CTRL1, r);
-
- REG_FLD_MOD(hdmi_core_sys_base(ip_data),
- HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
-
- /* Vid_Mode */
- r = hdmi_read_reg(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_VID_MODE);
-
- /* dither truncation configuration */
- if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
- r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
- r = FLD_MOD(r, 1, 5, 5);
- } else {
- r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
- r = FLD_MOD(r, 0, 5, 5);
- }
- hdmi_write_reg(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_VID_MODE, r);
-
- /* HDMI_Ctrl */
- r = hdmi_read_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL);
- r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
- r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
- r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL, r);
-
- /* TMDS_CTRL */
- REG_FLD_MOD(hdmi_core_sys_base(ip_data),
- HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
-}
-
-static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data,
- struct hdmi_core_infoframe_avi info_avi)
-{
- u32 val;
- char sum = 0, checksum = 0;
-
- sum += 0x82 + 0x002 + 0x00D;
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_TYPE, 0x082);
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_VERS, 0x002);
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_LEN, 0x00D);
-
- val = (info_avi.db1_format << 5) |
- (info_avi.db1_active_info << 4) |
- (info_avi.db1_bar_info_dv << 2) |
- (info_avi.db1_scan_info);
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(0), val);
- sum += val;
-
- val = (info_avi.db2_colorimetry << 6) |
- (info_avi.db2_aspect_ratio << 4) |
- (info_avi.db2_active_fmt_ar);
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(1), val);
- sum += val;
-
- val = (info_avi.db3_itc << 7) |
- (info_avi.db3_ec << 4) |
- (info_avi.db3_q_range << 2) |
- (info_avi.db3_nup_scaling);
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(2), val);
- sum += val;
-
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(3),
- info_avi.db4_videocode);
- sum += info_avi.db4_videocode;
-
- val = info_avi.db5_pixel_repeat;
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(4), val);
- sum += val;
-
- val = info_avi.db6_7_line_eoftop & 0x00FF;
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(5), val);
- sum += val;
-
- val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(6), val);
- sum += val;
-
- val = info_avi.db8_9_line_sofbottom & 0x00FF;
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(7), val);
- sum += val;
-
- val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(8), val);
- sum += val;
-
- val = info_avi.db10_11_pixel_eofleft & 0x00FF;
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(9), val);
- sum += val;
-
- val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(10), val);
- sum += val;
-
- val = info_avi.db12_13_pixel_sofright & 0x00FF;
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(11), val);
- sum += val;
-
- val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(12), val);
- sum += val;
-
- checksum = 0x100 - sum;
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_CHSUM, checksum);
-}
-
-static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data,
- struct hdmi_core_packet_enable_repeat repeat_cfg)
-{
- /* enable/repeat the infoframe */
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_PB_CTRL1,
- (repeat_cfg.audio_pkt << 5) |
- (repeat_cfg.audio_pkt_repeat << 4) |
- (repeat_cfg.avi_infoframe << 1) |
- (repeat_cfg.avi_infoframe_repeat));
-
- /* enable/repeat the packet */
- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_PB_CTRL2,
- (repeat_cfg.gen_cntrl_pkt << 3) |
- (repeat_cfg.gen_cntrl_pkt_repeat << 2) |
- (repeat_cfg.generic_pkt << 1) |
- (repeat_cfg.generic_pkt_repeat));
-}
-
-static void hdmi_wp_init(struct omap_video_timings *timings,
- struct hdmi_video_format *video_fmt,
- struct hdmi_video_interface *video_int)
-{
- DSSDBG("Enter hdmi_wp_init\n");
-
- timings->hbp = 0;
- timings->hfp = 0;
- timings->hsw = 0;
- timings->vbp = 0;
- timings->vfp = 0;
- timings->vsw = 0;
-
- video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
- video_fmt->y_res = 0;
- video_fmt->x_res = 0;
-
- video_int->vsp = 0;
- video_int->hsp = 0;
-
- video_int->interlacing = 0;
- video_int->tm = 0; /* HDMI_TIMING_SLAVE */
-
-}
-
-static void hdmi_wp_video_start(struct hdmi_ip_data *ip_data, bool start)
-{
- REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, start, 31, 31);
-}
-
-static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
- struct omap_video_timings *timings, struct hdmi_config *param)
-{
- DSSDBG("Enter hdmi_wp_video_init_format\n");
-
- video_fmt->y_res = param->timings.timings.y_res;
- video_fmt->x_res = param->timings.timings.x_res;
-
- timings->hbp = param->timings.timings.hbp;
- timings->hfp = param->timings.timings.hfp;
- timings->hsw = param->timings.timings.hsw;
- timings->vbp = param->timings.timings.vbp;
- timings->vfp = param->timings.timings.vfp;
- timings->vsw = param->timings.timings.vsw;
-}
-
-static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data,
- struct hdmi_video_format *video_fmt)
-{
- u32 l = 0;
-
- REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG,
- video_fmt->packing_mode, 10, 8);
-
- l |= FLD_VAL(video_fmt->y_res, 31, 16);
- l |= FLD_VAL(video_fmt->x_res, 15, 0);
- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l);
-}
-
-static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data,
- struct hdmi_video_interface *video_int)
-{
- u32 r;
- DSSDBG("Enter hdmi_wp_video_config_interface\n");
-
- r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG);
- r = FLD_MOD(r, video_int->vsp, 7, 7);
- r = FLD_MOD(r, video_int->hsp, 6, 6);
- r = FLD_MOD(r, video_int->interlacing, 3, 3);
- r = FLD_MOD(r, video_int->tm, 1, 0);
- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r);
-}
-
-static void hdmi_wp_video_config_timing(struct hdmi_ip_data *ip_data,
- struct omap_video_timings *timings)
-{
- u32 timing_h = 0;
- u32 timing_v = 0;
-
- DSSDBG("Enter hdmi_wp_video_config_timing\n");
-
- timing_h |= FLD_VAL(timings->hbp, 31, 20);
- timing_h |= FLD_VAL(timings->hfp, 19, 8);
- timing_h |= FLD_VAL(timings->hsw, 7, 0);
- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_H, timing_h);
-
- timing_v |= FLD_VAL(timings->vbp, 31, 20);
- timing_v |= FLD_VAL(timings->vfp, 19, 8);
- timing_v |= FLD_VAL(timings->vsw, 7, 0);
- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_V, timing_v);
-}
-
-static void hdmi_basic_configure(struct hdmi_ip_data *ip_data,
- struct hdmi_config *cfg)
-{
- /* HDMI */
- struct omap_video_timings video_timing;
- struct hdmi_video_format video_format;
- struct hdmi_video_interface video_interface;
- /* HDMI core */
- struct hdmi_core_infoframe_avi avi_cfg;
- struct hdmi_core_video_config v_core_cfg;
- struct hdmi_core_packet_enable_repeat repeat_cfg;
-
- hdmi_wp_init(&video_timing, &video_format,
- &video_interface);
-
- hdmi_core_init(&v_core_cfg,
- &avi_cfg,
- &repeat_cfg);
-
- hdmi_wp_video_init_format(&video_format,
- &video_timing, cfg);
-
- hdmi_wp_video_config_timing(ip_data, &video_timing);
-
- /* video config */
- video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
-
- hdmi_wp_video_config_format(ip_data, &video_format);
-
- video_interface.vsp = cfg->timings.vsync_pol;
- video_interface.hsp = cfg->timings.hsync_pol;
- video_interface.interlacing = cfg->interlace;
- video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
-
- hdmi_wp_video_config_interface(ip_data, &video_interface);
-
- /*
- * configure core video part
- * set software reset in the core
- */
- hdmi_core_swreset_assert(ip_data);
-
- /* power down off */
- hdmi_core_powerdown_disable(ip_data);
-
- v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
- v_core_cfg.hdmi_dvi = cfg->cm.mode;
-
- hdmi_core_video_config(ip_data, &v_core_cfg);
-
- /* release software reset in the core */
- hdmi_core_swreset_release(ip_data);
-
- /*
- * configure packet
- * info frame video see doc CEA861-D page 65
- */
- avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
- avi_cfg.db1_active_info - HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
- avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
- avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
- avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
- avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
- avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
- avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
- avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
- avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
- avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
- avi_cfg.db4_videocode = cfg->cm.code;
- avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
- avi_cfg.db6_7_line_eoftop = 0;
- avi_cfg.db8_9_line_sofbottom = 0;
- avi_cfg.db10_11_pixel_eofleft = 0;
- avi_cfg.db12_13_pixel_sofright = 0;
-
- hdmi_core_aux_infoframe_avi_config(ip_data, avi_cfg);
-
- /* enable/repeat the infoframe */
- repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
- repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
- /* wakeup */
- repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
- repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
- hdmi_core_av_packet_config(ip_data, repeat_cfg);
-}
-
static void update_hdmi_timings(struct hdmi_config *cfg,
struct omap_video_timings *timings, int code)
{
diff --git a/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c b/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c
new file mode 100644
index 0000000..b4e8875
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c
@@ -0,0 +1,781 @@
+/*
+ * hdmi_ti_4xxx_ip.c
+ *
+ * HDMI TI81xx, TI38xx, TI OMAP4 etc IP driver Library
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Authors: Yong Zhi
+ * Mythri pk <mythripk@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/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+
+#include "hdmi_ti_4xxx_ip.h"
+#include "dss.h"
+
+static inline void hdmi_write_reg(void __iomem *base_addr,
+ const struct hdmi_reg idx, u32 val)
+{
+ __raw_writel(val, base_addr + idx.idx);
+}
+
+static inline u32 hdmi_read_reg(void __iomem *base_addr,
+ const struct hdmi_reg idx)
+{
+ return __raw_readl(base_addr + idx.idx);
+}
+
+static inline void __iomem *hdmi_wp_base(struct hdmi_ip_data *ip_data)
+{
+ return (void __iomem *) (ip_data->base_wp);
+}
+
+static inline void __iomem *hdmi_phy_base(struct hdmi_ip_data *ip_data)
+{
+ return (void __iomem *) (ip_data->base_wp + ip_data->hdmi_phy_offset);
+}
+
+static inline void __iomem *hdmi_pll_base(struct hdmi_ip_data *ip_data)
+{
+ return (void __iomem *) (ip_data->base_wp + ip_data->hdmi_pll_offset);
+}
+
+static inline void __iomem *hdmi_av_base(struct hdmi_ip_data *ip_data)
+{
+ return (void __iomem *)
+ (ip_data->base_wp + ip_data->hdmi_core_av_offset);
+}
+
+static inline void __iomem *hdmi_core_sys_base(struct hdmi_ip_data *ip_data)
+{
+ return (void __iomem *)
+ (ip_data->base_wp + ip_data->hdmi_core_sys_offset);
+}
+
+static inline int hdmi_wait_for_bit_change(void __iomem *base_addr,
+ const struct hdmi_reg idx,
+ int b2, int b1, u32 val)
+{
+ u32 t = 0;
+ while (val != REG_GET(base_addr, idx, b2, b1)) {
+ udelay(1);
+ if (t++ > 10000)
+ return !val;
+ }
+ return val;
+}
+
+static int hdmi_pll_init(struct hdmi_ip_data *ip_data,
+ enum hdmi_clk_refsel refsel, int dcofreq,
+ struct hdmi_pll_info *fmt, u16 sd)
+{
+ u32 r;
+
+ /* PLL start always use manual mode */
+ REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
+
+ r = hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG1);
+ r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
+ r = FLD_MOD(r, fmt->regn, 8, 1); /* CFG1_PLL_REGN */
+
+ hdmi_write_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG1, r);
+
+ r = hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG2);
+
+ r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
+ r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
+ r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
+
+ if (dcofreq) {
+ /* divider programming for frequency beyond 1000Mhz */
+ REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_CFG3, sd, 17, 10);
+ r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
+ } else {
+ r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
+ }
+
+ hdmi_write_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG2, r);
+
+ r = hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG4);
+ r = FLD_MOD(r, fmt->regm2, 24, 18);
+ r = FLD_MOD(r, fmt->regmf, 17, 0);
+
+ hdmi_write_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG4, r);
+
+ /* go now */
+ REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_PLL_GO, 0x1, 0, 0);
+
+ /* wait for bit change */
+ if (hdmi_wait_for_bit_change(hdmi_pll_base(ip_data), PLLCTRL_PLL_GO,
+ 0, 0, 1) != 1) {
+ pr_err("PLL GO bit not set\n");
+ return -ETIMEDOUT;
+ }
+
+ /* Wait till the lock bit is set in PLL status */
+ if (hdmi_wait_for_bit_change(hdmi_pll_base(ip_data),
+ PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
+ pr_err("cannot lock PLL\n");
+ pr_err("CFG1 0x%x\n",
+ hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG1));
+ pr_err("CFG2 0x%x\n",
+ hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG2));
+ pr_err("CFG4 0x%x\n",
+ hdmi_read_reg(hdmi_pll_base(ip_data), PLLCTRL_CFG4));
+ return -ETIMEDOUT;
+ }
+
+ pr_debug("PLL locked!\n");
+
+ return 0;
+}
+
+/* PHY_PWR_CMD */
+static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val)
+{
+ /* Command for power control of HDMI PHY */
+ REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6);
+
+ /* Status of the power control of HDMI PHY */
+ if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data),
+ HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
+ pr_err("Failed to set PHY power mode to %d\n", val);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+/* PLL_PWR_CMD */
+int hdmi_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val)
+{
+ /* Command for power control of HDMI PLL */
+ REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 3, 2);
+
+ /* wait till PHY_PWR_STATUS is set */
+if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL,
+ 1, 0, val) != val) {
+ pr_err("Failed to set PLL_PWR_STATUS\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int hdmi_pll_reset(struct hdmi_ip_data *ip_data)
+{
+ /* SYSRESET controlled by power FSM */
+ REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
+
+ /* READ 0x0 reset is in progress */
+ if (hdmi_wait_for_bit_change(hdmi_pll_base(ip_data),
+ PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
+ pr_err("Failed to sysreset PLL\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+int hdmi_pll_program(struct hdmi_ip_data *ip_data,
+ struct hdmi_pll_info *fmt)
+{
+ u16 r = 0;
+ enum hdmi_clk_refsel refsel;
+
+ r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
+ if (r)
+ return r;
+
+ r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
+ if (r)
+ return r;
+
+ r = hdmi_pll_reset(ip_data);
+ if (r)
+ return r;
+
+ refsel = HDMI_REFSEL_SYSCLK;
+
+ r = hdmi_pll_init(ip_data, refsel, fmt->dcofreq, fmt, fmt->regsd);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+int hdmi_phy_init(struct hdmi_ip_data *ip_data)
+{
+ u16 r = 0;
+
+ r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
+ if (r)
+ return r;
+
+ r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
+ if (r)
+ return r;
+
+ /*
+ * Read address 0 in order to get the SCP reset done completed
+ * Dummy access performed to make sure reset is done
+ */
+ hdmi_read_reg(hdmi_phy_base(ip_data), HDMI_TXPHY_TX_CTRL);
+
+ /*
+ * Write to phy address 0 to configure the clock
+ * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
+ */
+ REG_FLD_MOD(hdmi_phy_base(ip_data), HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
+
+ /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
+ hdmi_write_reg(hdmi_phy_base(ip_data),
+ HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
+
+ /* Setup max LDO voltage */
+ REG_FLD_MOD(hdmi_phy_base(ip_data), HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
+
+ /* Write to phy address 3 to change the polarity control */
+ REG_FLD_MOD(hdmi_phy_base(ip_data),
+ HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
+
+ return 0;
+}
+
+void hdmi_phy_off(struct hdmi_ip_data *ip_data)
+{
+ hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
+}
+
+static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
+ u8 *pedid, int ext)
+{
+ u32 i, j;
+ char checksum = 0;
+ u32 offset = 0;
+
+ /* Turn on CLK for DDC */
+ REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_DPD, 0x7, 2, 0);
+
+ /*
+ * SW HACK : Without the Delay DDC(i2c bus) reads 0 values /
+ * right shifted values( The behavior is not consistent and seen only
+ * with some TV's)
+ */
+ usleep_range(800, 1000);
+
+ if (!ext) {
+ /* Clk SCL Devices */
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_CMD, 0xA, 3, 0);
+
+ /* HDMI_CORE_DDC_STATUS_IN_PROG */
+ if (hdmi_wait_for_bit_change(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) {
+ pr_err("Failed to program DDC\n");
+ return -ETIMEDOUT;
+ }
+
+ /* Clear FIFO */
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data)
+ , HDMI_CORE_DDC_CMD, 0x9, 3, 0);
+
+ /* HDMI_CORE_DDC_STATUS_IN_PROG */
+ if (hdmi_wait_for_bit_change(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) {
+ pr_err("Failed to program DDC\n");
+ return -ETIMEDOUT;
+ }
+
+ } else {
+ if (ext % 2 != 0)
+ offset = 0x80;
+ }
+
+ /* Load Segment Address Register */
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
+
+ /* Load Slave Address Register */
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
+
+ /* Load Offset Address Register */
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_OFFSET, offset, 7, 0);
+
+ /* Load Byte Count */
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
+
+ /* Set DDC_CMD */
+ if (ext)
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_CMD, 0x4, 3, 0);
+ else
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_CMD, 0x2, 3, 0);
+
+ /* HDMI_CORE_DDC_STATUS_BUS_LOW */
+ if (REG_GET(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_STATUS, 6, 6) = 1) {
+ pr_err("I2C Bus Low?\n");
+ return -EIO;
+ }
+ /* HDMI_CORE_DDC_STATUS_NO_ACK */
+ if (REG_GET(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_STATUS, 5, 5) = 1) {
+ pr_err("I2C No Ack\n");
+ return -EIO;
+ }
+
+ i = ext * 128;
+ j = 0;
+ while (((REG_GET(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_STATUS, 4, 4) = 1) ||
+ (REG_GET(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_STATUS, 2, 2) = 0)) && j < 128) {
+
+ if (REG_GET(hdmi_core_sys_base(ip_data)
+ , HDMI_CORE_DDC_STATUS, 2, 2) = 0) {
+ /* FIFO not empty */
+ pedid[i++] = REG_GET(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_DDC_DATA, 7, 0);
+ j++;
+ }
+ }
+
+ for (j = 0; j < 128; j++)
+ checksum += pedid[j];
+
+ if (checksum != 0) {
+ pr_err("E-EDID checksum failed!!\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int read_edid(struct hdmi_ip_data *ip_data, u8 *pedid, u16 max_length)
+{
+ int r = 0, n = 0, i = 0;
+ int max_ext_blocks = (max_length / 128) - 1;
+
+ r = hdmi_core_ddc_edid(ip_data, pedid, 0);
+ if (r) {
+ return r;
+ } else {
+ n = pedid[0x7e];
+
+ /*
+ * README: need to comply with max_length set by the caller.
+ * Better implementation should be to allocate necessary
+ * memory to store EDID according to nb_block field found
+ * in first block
+ */
+ if (n > max_ext_blocks)
+ n = max_ext_blocks;
+
+ for (i = 1; i <= n; i++) {
+ r = hdmi_core_ddc_edid(ip_data, pedid, i);
+ if (r)
+ return r;
+ }
+ }
+ return 0;
+}
+
+static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
+ struct hdmi_core_infoframe_avi *avi_cfg,
+ struct hdmi_core_packet_enable_repeat *repeat_cfg)
+{
+ pr_debug("Enter hdmi_core_init\n");
+
+ /* video core */
+ video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
+ video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
+ video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
+ video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
+ video_cfg->hdmi_dvi = HDMI_DVI;
+ video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
+
+ /* info frame */
+ avi_cfg->db1_format = 0;
+ avi_cfg->db1_active_info = 0;
+ avi_cfg->db1_bar_info_dv = 0;
+ avi_cfg->db1_scan_info = 0;
+ avi_cfg->db2_colorimetry = 0;
+ avi_cfg->db2_aspect_ratio = 0;
+ avi_cfg->db2_active_fmt_ar = 0;
+ avi_cfg->db3_itc = 0;
+ avi_cfg->db3_ec = 0;
+ avi_cfg->db3_q_range = 0;
+ avi_cfg->db3_nup_scaling = 0;
+ avi_cfg->db4_videocode = 0;
+ avi_cfg->db5_pixel_repeat = 0;
+ avi_cfg->db6_7_line_eoftop = 0 ;
+ avi_cfg->db8_9_line_sofbottom = 0;
+ avi_cfg->db10_11_pixel_eofleft = 0;
+ avi_cfg->db12_13_pixel_sofright = 0;
+
+ /* packet enable and repeat */
+ repeat_cfg->audio_pkt = 0;
+ repeat_cfg->audio_pkt_repeat = 0;
+ repeat_cfg->avi_infoframe = 0;
+ repeat_cfg->avi_infoframe_repeat = 0;
+ repeat_cfg->gen_cntrl_pkt = 0;
+ repeat_cfg->gen_cntrl_pkt_repeat = 0;
+ repeat_cfg->generic_pkt = 0;
+ repeat_cfg->generic_pkt_repeat = 0;
+}
+
+static void hdmi_core_powerdown_disable(struct hdmi_ip_data *ip_data)
+{
+ pr_debug("Enter hdmi_core_powerdown_disable\n");
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_CTRL1, 0x0, 0, 0);
+}
+
+static void hdmi_core_swreset_release(struct hdmi_ip_data *ip_data)
+{
+ pr_debug("Enter hdmi_core_swreset_release\n");
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_SRST, 0x0, 0, 0);
+}
+
+static void hdmi_core_swreset_assert(struct hdmi_ip_data *ip_data)
+{
+ pr_debug("Enter hdmi_core_swreset_assert\n");
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_SRST, 0x1, 0, 0);
+}
+
+/* HDMI_CORE_VIDEO_CONFIG */
+static void hdmi_core_video_config(struct hdmi_ip_data *ip_data,
+ struct hdmi_core_video_config *cfg)
+{
+ u32 r = 0;
+
+ /* sys_ctrl1 default configuration not tunable */
+ r = hdmi_read_reg(hdmi_core_sys_base(ip_data), HDMI_CORE_CTRL1);
+ r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
+ r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
+ r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
+ r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
+ hdmi_write_reg(hdmi_core_sys_base(ip_data), HDMI_CORE_CTRL1, r);
+
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
+
+ /* Vid_Mode */
+ r = hdmi_read_reg(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_VID_MODE);
+
+ /* dither truncation configuration */
+ if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
+ r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
+ r = FLD_MOD(r, 1, 5, 5);
+ } else {
+ r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
+ r = FLD_MOD(r, 0, 5, 5);
+ }
+ hdmi_write_reg(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_VID_MODE, r);
+
+ /* HDMI_Ctrl */
+ r = hdmi_read_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL);
+ r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
+ r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
+ r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL, r);
+
+ /* TMDS_CTRL */
+ REG_FLD_MOD(hdmi_core_sys_base(ip_data),
+ HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
+}
+
+static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data,
+ struct hdmi_core_infoframe_avi info_avi)
+{
+ u32 val;
+ char sum = 0, checksum = 0;
+
+ sum += 0x82 + 0x002 + 0x00D;
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_TYPE, 0x082);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_VERS, 0x002);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_LEN, 0x00D);
+
+ val = (info_avi.db1_format << 5) |
+ (info_avi.db1_active_info << 4) |
+ (info_avi.db1_bar_info_dv << 2) |
+ (info_avi.db1_scan_info);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(0), val);
+ sum += val;
+
+ val = (info_avi.db2_colorimetry << 6) |
+ (info_avi.db2_aspect_ratio << 4) |
+ (info_avi.db2_active_fmt_ar);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(1), val);
+ sum += val;
+
+ val = (info_avi.db3_itc << 7) |
+ (info_avi.db3_ec << 4) |
+ (info_avi.db3_q_range << 2) |
+ (info_avi.db3_nup_scaling);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(2), val);
+ sum += val;
+
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(3),
+ info_avi.db4_videocode);
+ sum += info_avi.db4_videocode;
+
+ val = info_avi.db5_pixel_repeat;
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(4), val);
+ sum += val;
+
+ val = info_avi.db6_7_line_eoftop & 0x00FF;
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(5), val);
+ sum += val;
+
+ val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(6), val);
+ sum += val;
+
+ val = info_avi.db8_9_line_sofbottom & 0x00FF;
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(7), val);
+ sum += val;
+
+ val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(8), val);
+ sum += val;
+
+ val = info_avi.db10_11_pixel_eofleft & 0x00FF;
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(9), val);
+ sum += val;
+
+ val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(10), val);
+ sum += val;
+
+ val = info_avi.db12_13_pixel_sofright & 0x00FF;
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(11), val);
+ sum += val;
+
+ val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_DBYTE(12), val);
+ sum += val;
+
+ checksum = 0x100 - sum;
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_AVI_CHSUM, checksum);
+}
+
+static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data,
+ struct hdmi_core_packet_enable_repeat repeat_cfg)
+{
+ /* enable/repeat the infoframe */
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_PB_CTRL1,
+ (repeat_cfg.audio_pkt << 5) |
+ (repeat_cfg.audio_pkt_repeat << 4) |
+ (repeat_cfg.avi_infoframe << 1) |
+ (repeat_cfg.avi_infoframe_repeat));
+
+ /* enable/repeat the packet */
+ hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_PB_CTRL2,
+ (repeat_cfg.gen_cntrl_pkt << 3) |
+ (repeat_cfg.gen_cntrl_pkt_repeat << 2) |
+ (repeat_cfg.generic_pkt << 1) |
+ (repeat_cfg.generic_pkt_repeat));
+}
+
+static void hdmi_wp_init(struct omap_video_timings *timings,
+ struct hdmi_video_format *video_fmt,
+ struct hdmi_video_interface *video_int)
+{
+ pr_debug("Enter hdmi_wp_init\n");
+
+ timings->hbp = 0;
+ timings->hfp = 0;
+ timings->hsw = 0;
+ timings->vbp = 0;
+ timings->vfp = 0;
+ timings->vsw = 0;
+
+ video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
+ video_fmt->y_res = 0;
+ video_fmt->x_res = 0;
+
+ video_int->vsp = 0;
+ video_int->hsp = 0;
+
+ video_int->interlacing = 0;
+ video_int->tm = 0; /* HDMI_TIMING_SLAVE */
+
+}
+
+void hdmi_wp_video_start(struct hdmi_ip_data *ip_data, bool start)
+{
+ REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, start, 31, 31);
+}
+
+static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
+ struct omap_video_timings *timings, struct hdmi_config *param)
+{
+ pr_debug("Enter hdmi_wp_video_init_format\n");
+
+ video_fmt->y_res = param->timings.timings.y_res;
+ video_fmt->x_res = param->timings.timings.x_res;
+
+ timings->hbp = param->timings.timings.hbp;
+ timings->hfp = param->timings.timings.hfp;
+ timings->hsw = param->timings.timings.hsw;
+ timings->vbp = param->timings.timings.vbp;
+ timings->vfp = param->timings.timings.vfp;
+ timings->vsw = param->timings.timings.vsw;
+}
+
+static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data,
+ struct hdmi_video_format *video_fmt)
+{
+ u32 l = 0;
+
+ REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG,
+ video_fmt->packing_mode, 10, 8);
+
+ l |= FLD_VAL(video_fmt->y_res, 31, 16);
+ l |= FLD_VAL(video_fmt->x_res, 15, 0);
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l);
+}
+
+static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data,
+ struct hdmi_video_interface *video_int)
+{
+ u32 r;
+ pr_debug("Enter hdmi_wp_video_config_interface\n");
+
+ r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG);
+ r = FLD_MOD(r, video_int->vsp, 7, 7);
+ r = FLD_MOD(r, video_int->hsp, 6, 6);
+ r = FLD_MOD(r, video_int->interlacing, 3, 3);
+ r = FLD_MOD(r, video_int->tm, 1, 0);
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r);
+}
+
+static void hdmi_wp_video_config_timing(struct hdmi_ip_data *ip_data,
+ struct omap_video_timings *timings)
+{
+ u32 timing_h = 0;
+ u32 timing_v = 0;
+
+ pr_debug("Enter hdmi_wp_video_config_timing\n");
+
+ timing_h |= FLD_VAL(timings->hbp, 31, 20);
+ timing_h |= FLD_VAL(timings->hfp, 19, 8);
+ timing_h |= FLD_VAL(timings->hsw, 7, 0);
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_H, timing_h);
+
+ timing_v |= FLD_VAL(timings->vbp, 31, 20);
+ timing_v |= FLD_VAL(timings->vfp, 19, 8);
+ timing_v |= FLD_VAL(timings->vsw, 7, 0);
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_V, timing_v);
+}
+
+void hdmi_basic_configure(struct hdmi_ip_data *ip_data,
+ struct hdmi_config *cfg)
+{
+ /* HDMI */
+ struct omap_video_timings video_timing;
+ struct hdmi_video_format video_format;
+ struct hdmi_video_interface video_interface;
+ /* HDMI core */
+ struct hdmi_core_infoframe_avi avi_cfg;
+ struct hdmi_core_video_config v_core_cfg;
+ struct hdmi_core_packet_enable_repeat repeat_cfg;
+
+ hdmi_wp_init(&video_timing, &video_format,
+ &video_interface);
+
+ hdmi_core_init(&v_core_cfg,
+ &avi_cfg,
+ &repeat_cfg);
+
+ hdmi_wp_video_init_format(&video_format, &video_timing, cfg);
+
+ hdmi_wp_video_config_timing(ip_data, &video_timing);
+
+ /* video config */
+ video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
+
+ hdmi_wp_video_config_format(ip_data, &video_format);
+
+ video_interface.vsp = cfg->timings.vsync_pol;
+ video_interface.hsp = cfg->timings.hsync_pol;
+ video_interface.interlacing = cfg->interlace;
+ video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
+
+ hdmi_wp_video_config_interface(ip_data, &video_interface);
+
+ /*
+ * configure core video part
+ * set software reset in the core
+ */
+ hdmi_core_swreset_assert(ip_data);
+
+ /* power down off */
+ hdmi_core_powerdown_disable(ip_data);
+
+ v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
+ v_core_cfg.hdmi_dvi = cfg->cm.mode;
+
+ hdmi_core_video_config(ip_data, &v_core_cfg);
+
+ /* release software reset in the core */
+ hdmi_core_swreset_release(ip_data);
+
+ /*
+ * configure packet
+ * info frame video see doc CEA861-D page 65
+ */
+ avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
+ avi_cfg.db1_active_info + HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
+ avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
+ avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
+ avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
+ avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
+ avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
+ avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
+ avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
+ avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
+ avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
+ avi_cfg.db4_videocode = cfg->cm.code;
+ avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
+ avi_cfg.db6_7_line_eoftop = 0;
+ avi_cfg.db8_9_line_sofbottom = 0;
+ avi_cfg.db10_11_pixel_eofleft = 0;
+ avi_cfg.db12_13_pixel_sofright = 0;
+
+ hdmi_core_aux_infoframe_avi_config(ip_data, avi_cfg);
+
+ /* enable/repeat the infoframe */
+ repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
+ repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
+ /* wakeup */
+ repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
+ repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
+ hdmi_core_av_packet_config(ip_data, repeat_cfg);
+}
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.h
similarity index 99%
rename from drivers/video/omap2/dss/hdmi.h
rename to drivers/video/omap2/dss/hdmi_ti_4xxx_ip.h
index 4b0fab3..97e573c 100644
--- a/drivers/video/omap2/dss/hdmi.h
+++ b/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.h
@@ -1,7 +1,7 @@
/*
- * hdmi.h
+ * hdmi_ti_4xxx_ip.h
*
- * HDMI driver definition for TI OMAP4 processors.
+ * HDMI header definition for TI81xx, TI38xx, TI OMAP4 etc processors.
*
* Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
*
@@ -18,11 +18,12 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _OMAP4_DSS_HDMI_H_
-#define _OMAP4_DSS_HDMI_H_
+#ifndef _HDMI_TI_4xxx_H_
+#define _HDMI_TI_4xxx_H_
#include <linux/string.h>
#include <video/omapdss.h>
+#include <video/hdmi_ti_4xxx_ip.h>
struct hdmi_reg { u16 idx; };
diff --git a/include/video/hdmi_ti_4xxx_ip.h b/include/video/hdmi_ti_4xxx_ip.h
index 49640cd..3355f40 100644
--- a/include/video/hdmi_ti_4xxx_ip.h
+++ b/include/video/hdmi_ti_4xxx_ip.h
@@ -81,4 +81,14 @@ struct hdmi_pll_info {
u16 regsd;
u16 dcofreq;
};
+
+int hdmi_phy_init(struct hdmi_ip_data *ip_data);
+void hdmi_phy_off(struct hdmi_ip_data *ip_data);
+int read_edid(struct hdmi_ip_data *ip_data, u8 *pedid, u16 max_length);
+void hdmi_wp_video_start(struct hdmi_ip_data *ip_data, bool start);
+int hdmi_pll_program(struct hdmi_ip_data *ip_data,
+ struct hdmi_pll_info *fmt);
+int hdmi_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val);
+void hdmi_basic_configure(struct hdmi_ip_data *ip_data,
+ struct hdmi_config *cfg);
#endif
--
1.7.5.4
^ permalink raw reply related
* [PATCH 6/8] OMAP4: DSS: HDMI: Rename the functions in HDMI IP
From: Mythri P K @ 2011-06-22 11:55 UTC (permalink / raw)
To: linux-fbdev
Functions that are included in the generic video include of HDMI TI OMAP4, TI8xx
etc IP library is renamed to have IP specific names so that it will not conflict
with similar function from other IP.
Signed-off-by: Mythri P K <mythripk@ti.com>
---
drivers/video/omap2/dss/hdmi.c | 18 +++++++++---------
drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c | 18 +++++++++---------
include/video/hdmi_ti_4xxx_ip.h | 14 +++++++-------
3 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 1bd98d9..d42bb5d 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -395,7 +395,7 @@ static void hdmi_read_edid(struct omap_video_timings *dp)
memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH);
if (!hdmi.edid_set)
- ret = read_edid(&hdmi.hdmi_data, hdmi.edid,
+ ret = read_ti_4xxx_edid(&hdmi.hdmi_data, hdmi.edid,
HDMI_EDID_MAX_LENGTH);
if (!ret) {
if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) {
@@ -508,16 +508,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
hdmi_compute_pll(dssdev, phy, &pll_data);
- hdmi_wp_video_start(&hdmi.hdmi_data, 0);
+ hdmi_ti_4xxx_wp_video_start(&hdmi.hdmi_data, 0);
/* config the PLL and PHY hdmi_set_pll_pwrfirst */
- r = hdmi_pll_program(&hdmi.hdmi_data, &pll_data);
+ r = hdmi_ti_4xxx_pll_program(&hdmi.hdmi_data, &pll_data);
if (r) {
DSSDBG("Failed to lock PLL\n");
goto err;
}
- r = hdmi_phy_init(&hdmi.hdmi_data);
+ r = hdmi_ti_4xxx_phy_init(&hdmi.hdmi_data);
if (r) {
DSSDBG("Failed to start PHY\n");
goto err;
@@ -525,7 +525,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
hdmi.cfg.cm.mode = hdmi.mode;
hdmi.cfg.cm.code = hdmi.code;
- hdmi_basic_configure(&hdmi.hdmi_data, &hdmi.cfg);
+ hdmi_ti_4xxx_basic_configure(&hdmi.hdmi_data, &hdmi.cfg);
/* Make selection of HDMI in DSS */
dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
@@ -547,7 +547,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1);
- hdmi_wp_video_start(&hdmi.hdmi_data, 1);
+ hdmi_ti_4xxx_wp_video_start(&hdmi.hdmi_data, 1);
return 0;
err:
@@ -559,9 +559,9 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
{
dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
- hdmi_wp_video_start(&hdmi.hdmi_data, 0);
- hdmi_phy_off(&hdmi.hdmi_data);
- hdmi_set_pll_pwr(&hdmi.hdmi_data, HDMI_PLLPWRCMD_ALLOFF);
+ hdmi_ti_4xxx_wp_video_start(&hdmi.hdmi_data, 0);
+ hdmi_ti_4xxx_phy_off(&hdmi.hdmi_data);
+ hdmi_ti_4xxx_set_pll_pwr(&hdmi.hdmi_data, HDMI_PLLPWRCMD_ALLOFF);
hdmi_runtime_put();
hdmi.edid_set = 0;
diff --git a/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c b/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c
index b4e8875..51dc2a8 100644
--- a/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c
+++ b/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c
@@ -165,7 +165,7 @@ static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val)
}
/* PLL_PWR_CMD */
-int hdmi_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val)
+int hdmi_ti_4xxx_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val)
{
/* Command for power control of HDMI PLL */
REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 3, 2);
@@ -195,17 +195,17 @@ static int hdmi_pll_reset(struct hdmi_ip_data *ip_data)
return 0;
}
-int hdmi_pll_program(struct hdmi_ip_data *ip_data,
+int hdmi_ti_4xxx_pll_program(struct hdmi_ip_data *ip_data,
struct hdmi_pll_info *fmt)
{
u16 r = 0;
enum hdmi_clk_refsel refsel;
- r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
+ r = hdmi_ti_4xxx_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
if (r)
return r;
- r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
+ r = hdmi_ti_4xxx_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
if (r)
return r;
@@ -222,7 +222,7 @@ int hdmi_pll_program(struct hdmi_ip_data *ip_data,
return 0;
}
-int hdmi_phy_init(struct hdmi_ip_data *ip_data)
+int hdmi_ti_4xxx_phy_init(struct hdmi_ip_data *ip_data)
{
u16 r = 0;
@@ -260,7 +260,7 @@ int hdmi_phy_init(struct hdmi_ip_data *ip_data)
return 0;
}
-void hdmi_phy_off(struct hdmi_ip_data *ip_data)
+void hdmi_ti_4xxx_phy_off(struct hdmi_ip_data *ip_data)
{
hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
}
@@ -376,7 +376,7 @@ static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
return 0;
}
-int read_edid(struct hdmi_ip_data *ip_data, u8 *pedid, u16 max_length)
+int read_ti_4xxx_edid(struct hdmi_ip_data *ip_data, u8 *pedid, u16 max_length)
{
int r = 0, n = 0, i = 0;
int max_ext_blocks = (max_length / 128) - 1;
@@ -627,7 +627,7 @@ static void hdmi_wp_init(struct omap_video_timings *timings,
}
-void hdmi_wp_video_start(struct hdmi_ip_data *ip_data, bool start)
+void hdmi_ti_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start)
{
REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, start, 31, 31);
}
@@ -694,7 +694,7 @@ static void hdmi_wp_video_config_timing(struct hdmi_ip_data *ip_data,
hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_V, timing_v);
}
-void hdmi_basic_configure(struct hdmi_ip_data *ip_data,
+void hdmi_ti_4xxx_basic_configure(struct hdmi_ip_data *ip_data,
struct hdmi_config *cfg)
{
/* HDMI */
diff --git a/include/video/hdmi_ti_4xxx_ip.h b/include/video/hdmi_ti_4xxx_ip.h
index 3355f40..d354280 100644
--- a/include/video/hdmi_ti_4xxx_ip.h
+++ b/include/video/hdmi_ti_4xxx_ip.h
@@ -82,13 +82,13 @@ struct hdmi_pll_info {
u16 dcofreq;
};
-int hdmi_phy_init(struct hdmi_ip_data *ip_data);
-void hdmi_phy_off(struct hdmi_ip_data *ip_data);
-int read_edid(struct hdmi_ip_data *ip_data, u8 *pedid, u16 max_length);
-void hdmi_wp_video_start(struct hdmi_ip_data *ip_data, bool start);
-int hdmi_pll_program(struct hdmi_ip_data *ip_data,
+int hdmi_ti_4xxx_phy_init(struct hdmi_ip_data *ip_data);
+void hdmi_ti_4xxx_phy_off(struct hdmi_ip_data *ip_data);
+int read_ti_4xxx_edid(struct hdmi_ip_data *ip_data, u8 *pedid, u16 max_length);
+void hdmi_ti_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start);
+int hdmi_ti_4xxx_pll_program(struct hdmi_ip_data *ip_data,
struct hdmi_pll_info *fmt);
-int hdmi_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val);
-void hdmi_basic_configure(struct hdmi_ip_data *ip_data,
+int hdmi_ti_4xxx_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val);
+void hdmi_ti_4xxx_basic_configure(struct hdmi_ip_data *ip_data,
struct hdmi_config *cfg);
#endif
--
1.7.5.4
^ permalink raw reply related
* [PATCH 7/8] HDMI: Move HDMI IP Library from OMAP DSS to common
From: Mythri P K @ 2011-06-22 11:55 UTC (permalink / raw)
To: linux-fbdev
Moving support of HDMI IP library from OMAP4 DSS directory to Video directory as
HDMI IP present in both TI OMAP4, TI81xx, TI38xx Processor,Thus the library in
DSS can be reused in TI81xx, TI38xx processors.
Although both these processors have different Display subsytem HDMI IP remains
the same , thus to promote the reuse of code across SoC's, IP library named
hdmi_4xxx_ip.c is moved from DSS to video directory.Also functions are renamed
as the module has to export and the function name would be global symbol table,
hence renaming to function name specific to the library module.
With this approach Independent of their(OMAP/TI81xx/TI38xx) respective DSS, generic IP
configurations will be done using this library.
Signed-off-by: Mythri P K <mythripk@ti.com>
---
drivers/video/Kconfig | 7 ++++++
drivers/video/Makefile | 1 +
drivers/video/{omap2/dss => }/hdmi_ti_4xxx_ip.c | 24 ++++++++++++++++++++++-
drivers/video/{omap2/dss => }/hdmi_ti_4xxx_ip.h | 5 ++++
drivers/video/omap2/dss/Kconfig | 1 +
drivers/video/omap2/dss/Makefile | 1 -
6 files changed, 37 insertions(+), 2 deletions(-)
rename drivers/video/{omap2/dss => }/hdmi_ti_4xxx_ip.c (97%)
rename drivers/video/{omap2/dss => }/hdmi_ti_4xxx_ip.h (98%)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index e6a8d8c..2204fef 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2341,6 +2341,13 @@ config FB_PUV3_UNIGFX
Choose this option if you want to use the Unigfx device as a
framebuffer device. Without the support of PCI & AGP.
+config HDMI_TI_4XXX_IP
+ tristate
+ default n
+ help
+ HDMI Library Interface , for TI OMAP4/Netra IP.
+ See http://www.hdmi.org/ for HDMI specification.
+
source "drivers/video/omap/Kconfig"
source "drivers/video/omap2/Kconfig"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 2ea44b6..3118055 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -133,6 +133,7 @@ obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o
obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
obj-$(CONFIG_FB_OMAP) += omap/
obj-y += omap2/
+obj-$(CONFIG_HDMI_TI_4XXX_IP) += hdmi_ti_4xxx_ip.o
obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
obj-$(CONFIG_FB_CARMINE) += carminefb.o
obj-$(CONFIG_FB_MB862XX) += mb862xx/
diff --git a/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c b/drivers/video/hdmi_ti_4xxx_ip.c
similarity index 97%
rename from drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c
rename to drivers/video/hdmi_ti_4xxx_ip.c
index 51dc2a8..c8ea145 100644
--- a/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.c
+++ b/drivers/video/hdmi_ti_4xxx_ip.c
@@ -29,7 +29,6 @@
#include <linux/string.h>
#include "hdmi_ti_4xxx_ip.h"
-#include "dss.h"
static inline void hdmi_write_reg(void __iomem *base_addr,
const struct hdmi_reg idx, u32 val)
@@ -179,6 +178,7 @@ if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL,
return 0;
}
+EXPORT_SYMBOL(hdmi_ti_4xxx_set_pll_pwr);
static int hdmi_pll_reset(struct hdmi_ip_data *ip_data)
{
@@ -264,6 +264,8 @@ void hdmi_ti_4xxx_phy_off(struct hdmi_ip_data *ip_data)
{
hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
}
+EXPORT_SYMBOL(hdmi_ti_4xxx_phy_init);
+EXPORT_SYMBOL(hdmi_ti_4xxx_phy_off);
static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
u8 *pedid, int ext)
@@ -404,6 +406,7 @@ int read_ti_4xxx_edid(struct hdmi_ip_data *ip_data, u8 *pedid, u16 max_length)
}
return 0;
}
+EXPORT_SYMBOL(read_ti_4xxx_edid);
static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
struct hdmi_core_infoframe_avi *avi_cfg,
@@ -631,6 +634,7 @@ void hdmi_ti_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start)
{
REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, start, 31, 31);
}
+EXPORT_SYMBOL(hdmi_ti_4xxx_wp_video_start);
static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
struct omap_video_timings *timings, struct hdmi_config *param)
@@ -779,3 +783,21 @@ void hdmi_ti_4xxx_basic_configure(struct hdmi_ip_data *ip_data,
repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
hdmi_core_av_packet_config(ip_data, repeat_cfg);
}
+EXPORT_SYMBOL(hdmi_ti_4xxx_basic_configure);
+
+static int __init hdmi_ti_4xxx_init(void)
+{
+ return 0;
+}
+
+static void __exit hdmi_ti_4xxx_exit(void)
+{
+
+}
+
+module_init(hdmi_ti_4xxx_init);
+module_exit(hdmi_ti_4xxx_exit);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("hdmi_ti_4xxx_ip module");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.h b/drivers/video/hdmi_ti_4xxx_ip.h
similarity index 98%
rename from drivers/video/omap2/dss/hdmi_ti_4xxx_ip.h
rename to drivers/video/hdmi_ti_4xxx_ip.h
index 97e573c..b0b8c92 100644
--- a/drivers/video/omap2/dss/hdmi_ti_4xxx_ip.h
+++ b/drivers/video/hdmi_ti_4xxx_ip.h
@@ -183,6 +183,11 @@ struct hdmi_reg { u16 idx; };
#define HDMI_TXPHY_POWER_CTRL HDMI_REG(0x8)
#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_REG(0xC)
+#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))
+#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
+#define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end))
+#define FLD_MOD(orig, val, start, end) \
+ (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
#define REG_FLD_MOD(base, idx, val, start, end) \
hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\
val, start, end))
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 0d12524..8f9420e 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -63,6 +63,7 @@ config OMAP2_DSS_VENC
config OMAP4_DSS_HDMI
bool "HDMI support"
depends on ARCH_OMAP4
+ select HDMI_TI_4XXX_IP
default y
help
HDMI Interface. This adds the High Definition Multimedia Interface.
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index cf967e0..10d9d3b 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -6,5 +6,4 @@ omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
- hdmi_ti_4xxx_ip.o \
hdmi_omap4_panel.o
--
1.7.5.4
^ permalink raw reply related
* [PATCH 8/8] OMAP4: DSS: Rename hdmi_omap4_panel.c to hdmi_panel.c
From: Mythri P K @ 2011-06-22 11:55 UTC (permalink / raw)
To: linux-fbdev
As the panel driver will remain generic across OMAP's renaming it to
hdmi_panel.c
Signed-off-by: Mythri P K <mythripk@ti.com>
---
drivers/video/omap2/dss/Makefile | 2 +-
.../omap2/dss/{hdmi_omap4_panel.c => hdmi_panel.c} | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
rename drivers/video/omap2/dss/{hdmi_omap4_panel.c => hdmi_panel.c} (99%)
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 10d9d3b..37d537c 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -6,4 +6,4 @@ omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
- hdmi_omap4_panel.o
+ hdmi_panel.o
diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
similarity index 99%
rename from drivers/video/omap2/dss/hdmi_omap4_panel.c
rename to drivers/video/omap2/dss/hdmi_panel.c
index 7d4f2bd..e30182f 100644
--- a/drivers/video/omap2/dss/hdmi_omap4_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -1,5 +1,5 @@
/*
- * hdmi_omap4_panel.c
+ * hdmi_panel.c
*
* HDMI library support functions for TI OMAP4 processors.
*
--
1.7.5.4
^ permalink raw reply related
* [PATCH V6 1/5] ARM: EXYNOS4: Change clock name for FIMD
From: Jingoo Han @ 2011-06-22 12:16 UTC (permalink / raw)
To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev,
Jonghun Han
Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
Jingoo Han
This patch changes clock name for FIMD from "fimd" to "lcd".
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
arch/arm/mach-exynos4/clock.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index 871f9d5..12e6853 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -433,12 +433,12 @@ static struct clk init_clocks_off[] = {
.enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit = (1 << 3),
}, {
- .name = "fimd",
+ .name = "lcd",
.id = 0,
.enable = exynos4_clk_ip_lcd0_ctrl,
.ctrlbit = (1 << 0),
}, {
- .name = "fimd",
+ .name = "lcd",
.id = 1,
.enable = exynos4_clk_ip_lcd1_ctrl,
.ctrlbit = (1 << 0),
--
1.7.1
^ permalink raw reply related
* [PATCH V6 2/5] ARM: EXYNOS4: Add FIMD resource definition
From: Jingoo Han @ 2011-06-22 12:16 UTC (permalink / raw)
To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev
Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
Jonghun Han, Jingoo Han
From: Jonghun Han <jonghun.han@samsung.com>
This patch adds resource definitions for EXYNOS4 FIMD.
IRQ and SFR definitions are added.
Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
arch/arm/mach-exynos4/include/mach/irqs.h | 8 ++++++++
arch/arm/mach-exynos4/include/mach/map.h | 5 +++++
2 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h
index 5d03730..2cd2090 100644
--- a/arch/arm/mach-exynos4/include/mach/irqs.h
+++ b/arch/arm/mach-exynos4/include/mach/irqs.h
@@ -73,6 +73,14 @@
#define IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6)
#define IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7)
+#define IRQ_FIMD0_FIFO COMBINER_IRQ(11, 0)
+#define IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1)
+#define IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2)
+
+#define IRQ_FIMD1_FIFO COMBINER_IRQ(12, 0)
+#define IRQ_FIMD1_VSYNC COMBINER_IRQ(12, 1)
+#define IRQ_FIMD1_SYSTEM COMBINER_IRQ(12, 2)
+
#define IRQ_PDMA0 COMBINER_IRQ(21, 0)
#define IRQ_PDMA1 COMBINER_IRQ(21, 1)
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
index 0009e77..94006f7 100644
--- a/arch/arm/mach-exynos4/include/mach/map.h
+++ b/arch/arm/mach-exynos4/include/mach/map.h
@@ -93,6 +93,9 @@
#define EXYNOS4_PA_MIPI_CSIS0 0x11880000
#define EXYNOS4_PA_MIPI_CSIS1 0x11890000
+#define EXYNOS4_PA_FIMD0 0x11C00000
+#define EXYNOS4_PA_FIMD1 0x12000000
+
#define EXYNOS4_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
#define EXYNOS4_PA_SATA 0x12560000
@@ -140,6 +143,8 @@
#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3
#define S5P_PA_MIPI_CSIS0 EXYNOS4_PA_MIPI_CSIS0
#define S5P_PA_MIPI_CSIS1 EXYNOS4_PA_MIPI_CSIS1
+#define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0
+#define S5P_PA_FIMD1 EXYNOS4_PA_FIMD1
#define S5P_PA_ONENAND EXYNOS4_PA_ONENAND
#define S5P_PA_ONENAND_DMA EXYNOS4_PA_ONENAND_DMA
#define S5P_PA_SDRAM EXYNOS4_PA_SDRAM
--
1.7.1
^ permalink raw reply related
* [PATCH V6 3/5] ARM: EXYNOS4: Add platform device and helper functions for FIMD
From: Jingoo Han @ 2011-06-22 12:17 UTC (permalink / raw)
To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev
Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
Signed-off-by: Jonghun Han, Jingoo Han
From: Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
This patch adds platform device s5p_device_fimd0 for EXYNOS4 FIMD0.
EXYNOS4 has two FIMDs(FIMD0, FIMD1). FIMD1 will be added later.
Some definitions used to enable EXYNOS4 FIMD0 are added.
Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
arch/arm/mach-exynos4/Kconfig | 9 +++
arch/arm/mach-exynos4/Makefile | 1 +
arch/arm/mach-exynos4/cpu.c | 4 +-
arch/arm/mach-exynos4/include/mach/regs-fb.h | 21 +++++++
arch/arm/mach-exynos4/setup-fimd0.c | 75 ++++++++++++++++++++++++++
arch/arm/plat-s5p/Kconfig | 5 ++
arch/arm/plat-s5p/Makefile | 1 +
arch/arm/plat-s5p/dev-fimd0.c | 67 +++++++++++++++++++++++
arch/arm/plat-samsung/include/plat/devs.h | 1 +
arch/arm/plat-samsung/include/plat/fb-core.h | 15 +++++
arch/arm/plat-samsung/include/plat/fb.h | 24 ++++++++
11 files changed, 222 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-exynos4/include/mach/regs-fb.h
create mode 100644 arch/arm/mach-exynos4/setup-fimd0.c
create mode 100644 arch/arm/plat-s5p/dev-fimd0.c
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 1435fc3..2024f50 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -25,6 +25,11 @@ config EXYNOS4_DEV_AHCI
help
Compile in platform device definitions for AHCI
+config EXYNOS4_SETUP_FIMD0
+ bool
+ help
+ Common setup code for FIMD0.
+
config EXYNOS4_DEV_PD
bool
help
@@ -103,6 +108,7 @@ menu "EXYNOS4 Machines"
config MACH_SMDKC210
bool "SMDKC210"
select CPU_EXYNOS4210
+ select S5P_DEV_FIMD0
select S3C_DEV_RTC
select S3C_DEV_WDT
select S3C_DEV_I2C1
@@ -112,6 +118,7 @@ config MACH_SMDKC210
select S3C_DEV_HSMMC3
select EXYNOS4_DEV_PD
select EXYNOS4_DEV_SYSMMU
+ select EXYNOS4_SETUP_FIMD0
select EXYNOS4_SETUP_I2C1
select EXYNOS4_SETUP_SDHCI
help
@@ -120,6 +127,7 @@ config MACH_SMDKC210
config MACH_SMDKV310
bool "SMDKV310"
select CPU_EXYNOS4210
+ select S5P_DEV_FIMD0
select S3C_DEV_RTC
select S3C_DEV_WDT
select S3C_DEV_I2C1
@@ -130,6 +138,7 @@ config MACH_SMDKV310
select SAMSUNG_DEV_KEYPAD
select EXYNOS4_DEV_PD
select EXYNOS4_DEV_SYSMMU
+ select EXYNOS4_SETUP_FIMD0
select EXYNOS4_SETUP_I2C1
select EXYNOS4_SETUP_KEYPAD
select EXYNOS4_SETUP_SDHCI
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index 60fe5ec..96472f1 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o
obj-$(CONFIG_EXYNOS4_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_EXYNOS4_SETUP_I2C2) += setup-i2c2.o
obj-$(CONFIG_EXYNOS4_SETUP_I2C3) += setup-i2c3.o
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
index 9babe44..778a5b0 100644
--- a/arch/arm/mach-exynos4/cpu.c
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -19,9 +19,10 @@
#include <plat/cpu.h>
#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/fb-core.h>
#include <plat/exynos4.h>
#include <plat/sdhci.h>
-#include <plat/devs.h>
#include <plat/fimc-core.h>
#include <mach/regs-irq.h>
@@ -132,6 +133,7 @@ void __init exynos4_map_io(void)
s3c_fimc_setname(1, "exynos4-fimc");
s3c_fimc_setname(2, "exynos4-fimc");
s3c_fimc_setname(3, "exynos4-fimc");
+ s5p_fb_setname(0, "exynos4-fb"); /* FIMD0 */
}
void __init exynos4_init_clocks(int xtal)
diff --git a/arch/arm/mach-exynos4/include/mach/regs-fb.h b/arch/arm/mach-exynos4/include/mach/regs-fb.h
new file mode 100644
index 0000000..f320105
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-fb.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Dummy framebuffer to allow build for the moment.
+ *
+ * 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.
+*/
+
+#ifndef __ASM_ARCH_MACH_REGS_FB_H
+#define __ASM_ARCH_MACH_REGS_FB_H __FILE__
+
+#include <plat/regs-fb-v4.h>
+
+static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
+{
+ return 0x2400 + (window * 256 * 4) + reg;
+}
+
+#endif /* __ASM_ARCH_MACH_REGS_FB_H */
diff --git a/arch/arm/mach-exynos4/setup-fimd0.c b/arch/arm/mach-exynos4/setup-fimd0.c
new file mode 100644
index 0000000..3295615
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-fimd0.c
@@ -0,0 +1,75 @@
+/* linux/arch/arm/mach-exynos4/setup-fimd0.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Base Exynos4 FIMD 0 configuration
+ *
+ * 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+void exynos4_fimd0_gpio_setup_24bpp(void)
+{
+ unsigned int reg = 0;
+
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2));
+
+ /*
+ * Set DISPLAY_CONTROL register for Display path selection.
+ *
+ * DISPLAY_CONTROL[1:0]
+ * ---------------------
+ * 00 | MIE
+ * 01 | MDINE
+ * 10 | FIMD : selected
+ * 11 | FIMD
+ */
+ reg = __raw_readl(S3C_VA_SYS + 0x0210);
+ reg |= (1 << 1);
+ __raw_writel(reg, S3C_VA_SYS + 0x0210);
+}
+
+int __init exynos4_fimd0_setup_clock(struct device *dev, const char *parent,
+ unsigned long clk_rate)
+{
+ struct clk *clk_parent;
+ struct clk *sclk;
+
+ sclk = clk_get(dev, "sclk_fimd");
+ if (IS_ERR(sclk))
+ return PTR_ERR(sclk);
+
+ clk_parent = clk_get(NULL, parent);
+ if (IS_ERR(clk_parent)) {
+ clk_put(sclk);
+ return PTR_ERR(clk_parent);
+ }
+
+ clk_set_parent(sclk, clk_parent);
+ if (!clk_rate)
+ clk_rate = 134000000UL;
+ clk_set_rate(sclk, clk_rate);
+
+ clk_put(sclk);
+ clk_put(clk_parent);
+
+ return 0;
+}
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index e98f5c5..46de16e 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -70,6 +70,11 @@ config S5P_DEV_FIMC3
help
Compile in platform device definitions for FIMC controller 3
+config S5P_DEV_FIMD0
+ bool
+ help
+ Compile in platform device definitions for FIMD controller 0
+
config S5P_DEV_ONENAND
bool
help
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index e234cc4..eec7e24 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
obj-$(CONFIG_S5P_DEV_FIMC3) += dev-fimc3.o
+obj-$(CONFIG_S5P_DEV_FIMD0) += dev-fimd0.o
obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o
obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o
obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o
diff --git a/arch/arm/plat-s5p/dev-fimd0.c b/arch/arm/plat-s5p/dev-fimd0.c
new file mode 100644
index 0000000..9e7176c
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimd0.c
@@ -0,0 +1,67 @@
+/* linux/arch/arm/plat-s5p/dev-fimd0.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Core file for Samsung Display Controller (FIMD) driver
+ *
+ * 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/gfp.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/fb.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s5p_fimd0_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMD0,
+ .end = S5P_PA_FIMD0 + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMD0_VSYNC,
+ .end = IRQ_FIMD0_VSYNC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_FIMD0_FIFO,
+ .end = IRQ_FIMD0_FIFO,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_FIMD0_SYSTEM,
+ .end = IRQ_FIMD0_SYSTEM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 fimd0_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_fimd0 = {
+ .name = "s5p-fb",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p_fimd0_resource),
+ .resource = s5p_fimd0_resource,
+ .dev = {
+ .dma_mask = &fimd0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
+{
+ s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+ &s5p_device_fimd0);
+}
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 4af108f..370bd2b 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -45,6 +45,7 @@ extern struct platform_device s3c64xx_device_ac97;
extern struct platform_device s3c_device_ts;
extern struct platform_device s3c_device_fb;
+extern struct platform_device s5p_device_fimd0;
extern struct platform_device s3c_device_ohci;
extern struct platform_device s3c_device_lcd;
extern struct platform_device s3c_device_wdt;
diff --git a/arch/arm/plat-samsung/include/plat/fb-core.h b/arch/arm/plat-samsung/include/plat/fb-core.h
index bca383e..6abcbf1 100644
--- a/arch/arm/plat-samsung/include/plat/fb-core.h
+++ b/arch/arm/plat-samsung/include/plat/fb-core.h
@@ -26,4 +26,19 @@ static inline void s3c_fb_setname(char *name)
#endif
}
+/* Re-define device name depending on support. */
+static inline void s5p_fb_setname(int id, char *name)
+{
+ switch (id) {
+#ifdef CONFIG_S5P_DEV_FIMD0
+ case 0:
+ s5p_device_fimd0.name = name;
+ break;
+#endif
+ default:
+ printk(KERN_ERR "%s: invalid device id(%d)\n", __func__, id);
+ break;
+ }
+}
+
#endif /* __ASM_PLAT_FB_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index cb3ca3a..a7b1c18 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -74,6 +74,14 @@ struct s3c_fb_platdata {
extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
/**
+ * s5p_fimd0_set_platdata() - Setup the FB device with platform data.
+ * @pd: The platform data to set. The data is copied from the passed structure
+ * so the machine data can mark the data __initdata so that any unused
+ * machines will end up dumping their data at runtime.
+ */
+extern void s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
* s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD
*
* Initialise the GPIO for an 24bpp LCD display on the RGB interface.
@@ -94,4 +102,20 @@ extern void s5pc100_fb_gpio_setup_24bpp(void);
*/
extern void s5pv210_fb_gpio_setup_24bpp(void);
+/**
+ * exynos4_fimd0_gpio_setup_24bpp() - Exynos4 setup function for 24bpp LCD0
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface 0.
+ */
+extern void exynos4_fimd0_gpio_setup_24bpp(void);
+
+/**
+ * exynos4_fimd0_setup_clock() = Exynos4 setup function for parent clock.
+ * @dev: device pointer
+ * @parent: parent clock used for LCD pixel clock
+ * @clk_rate: clock rate for parent clock
+ */
+int __init exynos4_fimd0_setup_clock(struct device *dev, const char *parent,
+ unsigned long clk_rate);
+
#endif /* __PLAT_S3C_FB_H */
--
1.7.1
^ permalink raw reply related
* [PATCH V6 4/5] video: s3c-fb: Add support EXYNOS4 FIMD
From: Jingoo Han @ 2011-06-22 12:18 UTC (permalink / raw)
To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev,
Jonghun Han
Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
Jingoo Han
This patch adds struct s3c_fb_driverdata s3c_fb_data_exynos4 for EXYNOS4
and adds lcd clock gating support.
FIMD driver needs two clocks for FIMD IP and LCD pixel clock. Previously,
both clocks are provided by using bus clock such as HCLK. However, EXYNOS4
can not select HCLK for LCD pixel clock because the EXYNOS4 FIMD IP does not
have the CLKSEL bit of VIDCON0. So, FIMD driver should provide the lcd clock
using SCLK_FIMD as LCD pixel clock for EXYNOS4.
The driver selects enabling lcd clock according to has_clksel which means
the CLKSEL bit of VIDCON0. If there is has_clksel, the driver will not
enable the lcd clock using SCLK_FIMD because bus clock using HCLK is used
a LCD pixel clock.
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
drivers/video/Kconfig | 2 +-
drivers/video/s3c-fb.c | 88 +++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 85 insertions(+), 5 deletions(-)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 549b960..963b8b7 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2027,7 +2027,7 @@ config FB_TMIO_ACCELL
config FB_S3C
tristate "Samsung S3C framebuffer support"
- depends on FB && S3C_DEV_FB
+ depends on FB && (S3C_DEV_FB || S5P_DEV_FIMD0)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 4aecf21..cb0d3ea 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -81,6 +81,7 @@ struct s3c_fb;
* @palette: Address of palette memory, or 0 if none.
* @has_prtcon: Set if has PRTCON register.
* @has_shadowcon: Set if has SHADOWCON register.
+ * @has_clksel: Set if VIDCON0 register has CLKSEL bit.
*/
struct s3c_fb_variant {
unsigned int is_2443:1;
@@ -98,6 +99,7 @@ struct s3c_fb_variant {
unsigned int has_prtcon:1;
unsigned int has_shadowcon:1;
+ unsigned int has_clksel:1;
};
/**
@@ -186,6 +188,7 @@ struct s3c_fb_vsync {
* @dev: The device that we bound to, for printing, etc.
* @regs_res: The resource we claimed for the IO registers.
* @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
+ * @lcd_clk: The clk (sclk) feeding pixclk.
* @regs: The mapped hardware registers.
* @variant: Variant information for this hardware.
* @enabled: A bitmask of enabled hardware windows.
@@ -200,6 +203,7 @@ struct s3c_fb {
struct device *dev;
struct resource *regs_res;
struct clk *bus_clk;
+ struct clk *lcd_clk;
void __iomem *regs;
struct s3c_fb_variant variant;
@@ -336,10 +340,15 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
*/
static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk)
{
- unsigned long clk = clk_get_rate(sfb->bus_clk);
+ unsigned long clk;
unsigned long long tmp;
unsigned int result;
+ if (sfb->variant.has_clksel)
+ clk = clk_get_rate(sfb->bus_clk);
+ else
+ clk = clk_get_rate(sfb->lcd_clk);
+
tmp = (unsigned long long)clk;
tmp *= pixclk;
@@ -1354,13 +1363,24 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
clk_enable(sfb->bus_clk);
+ if (!sfb->variant.has_clksel) {
+ sfb->lcd_clk = clk_get(dev, "sclk_fimd");
+ if (IS_ERR(sfb->lcd_clk)) {
+ dev_err(dev, "failed to get lcd clock\n");
+ ret = PTR_ERR(sfb->lcd_clk);
+ goto err_bus_clk;
+ }
+
+ clk_enable(sfb->lcd_clk);
+ }
+
pm_runtime_enable(sfb->dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "failed to find registers\n");
ret = -ENOENT;
- goto err_clk;
+ goto err_lcd_clk;
}
sfb->regs_res = request_mem_region(res->start, resource_size(res),
@@ -1368,7 +1388,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
if (!sfb->regs_res) {
dev_err(dev, "failed to claim register region\n");
ret = -ENOENT;
- goto err_clk;
+ goto err_lcd_clk;
}
sfb->regs = ioremap(res->start, resource_size(res));
@@ -1450,7 +1470,13 @@ err_ioremap:
err_req_region:
release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
-err_clk:
+err_lcd_clk:
+ if (!sfb->variant.has_clksel) {
+ clk_disable(sfb->lcd_clk);
+ clk_put(sfb->lcd_clk);
+ }
+
+err_bus_clk:
clk_disable(sfb->bus_clk);
clk_put(sfb->bus_clk);
@@ -1481,6 +1507,11 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
iounmap(sfb->regs);
+ if (!sfb->variant.has_clksel) {
+ clk_disable(sfb->lcd_clk);
+ clk_put(sfb->lcd_clk);
+ }
+
clk_disable(sfb->bus_clk);
clk_put(sfb->bus_clk);
@@ -1510,6 +1541,9 @@ static int s3c_fb_suspend(struct device *dev)
s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
}
+ if (!sfb->variant.has_clksel)
+ clk_disable(sfb->lcd_clk);
+
clk_disable(sfb->bus_clk);
return 0;
}
@@ -1524,6 +1558,9 @@ static int s3c_fb_resume(struct device *dev)
clk_enable(sfb->bus_clk);
+ if (!sfb->variant.has_clksel)
+ clk_enable(sfb->lcd_clk);
+
/* setup gpio and output polarity controls */
pd->setup_gpio();
writel(pd->vidcon1, sfb->regs + VIDCON1);
@@ -1569,6 +1606,9 @@ static int s3c_fb_runtime_suspend(struct device *dev)
s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
}
+ if (!sfb->variant.has_clksel)
+ clk_disable(sfb->lcd_clk);
+
clk_disable(sfb->bus_clk);
return 0;
}
@@ -1583,6 +1623,9 @@ static int s3c_fb_runtime_resume(struct device *dev)
clk_enable(sfb->bus_clk);
+ if (!sfb->variant.has_clksel)
+ clk_enable(sfb->lcd_clk);
+
/* setup gpio and output polarity controls */
pd->setup_gpio();
writel(pd->vidcon1, sfb->regs + VIDCON1);
@@ -1755,6 +1798,7 @@ static struct s3c_fb_driverdata s3c_fb_data_64xx = {
},
.has_prtcon = 1,
+ .has_clksel = 1,
},
.win[0] = &s3c_fb_data_64xx_wins[0],
.win[1] = &s3c_fb_data_64xx_wins[1],
@@ -1785,6 +1829,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = {
},
.has_prtcon = 1,
+ .has_clksel = 1,
},
.win[0] = &s3c_fb_data_s5p_wins[0],
.win[1] = &s3c_fb_data_s5p_wins[1],
@@ -1815,6 +1860,37 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = {
},
.has_shadowcon = 1,
+ .has_clksel = 1,
+ },
+ .win[0] = &s3c_fb_data_s5p_wins[0],
+ .win[1] = &s3c_fb_data_s5p_wins[1],
+ .win[2] = &s3c_fb_data_s5p_wins[2],
+ .win[3] = &s3c_fb_data_s5p_wins[3],
+ .win[4] = &s3c_fb_data_s5p_wins[4],
+};
+
+static struct s3c_fb_driverdata s3c_fb_data_exynos4 = {
+ .variant = {
+ .nr_windows = 5,
+ .vidtcon = VIDTCON0,
+ .wincon = WINCON(0),
+ .winmap = WINxMAP(0),
+ .keycon = WKEYCON,
+ .osd = VIDOSD_BASE,
+ .osd_stride = 16,
+ .buf_start = VIDW_BUF_START(0),
+ .buf_size = VIDW_BUF_SIZE(0),
+ .buf_end = VIDW_BUF_END(0),
+
+ .palette = {
+ [0] = 0x2400,
+ [1] = 0x2800,
+ [2] = 0x2c00,
+ [3] = 0x3000,
+ [4] = 0x3400,
+ },
+
+ .has_shadowcon = 1,
},
.win[0] = &s3c_fb_data_s5p_wins[0],
.win[1] = &s3c_fb_data_s5p_wins[1],
@@ -1843,6 +1919,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s3c2443 = {
[0] = 0x400,
[1] = 0x800,
},
+ .has_clksel = 1,
},
.win[0] = &(struct s3c_fb_win_variant) {
.palette_sz = 256,
@@ -1870,6 +1947,9 @@ static struct platform_device_id s3c_fb_driver_ids[] = {
.name = "s5pv210-fb",
.driver_data = (unsigned long)&s3c_fb_data_s5pv210,
}, {
+ .name = "exynos4-fb",
+ .driver_data = (unsigned long)&s3c_fb_data_exynos4,
+ }, {
.name = "s3c2443-fb",
.driver_data = (unsigned long)&s3c_fb_data_s3c2443,
},
--
1.7.1
^ permalink raw reply related
* [PATCH V6 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD and LTE480WV platform-lcd
From: Jingoo Han @ 2011-06-22 12:18 UTC (permalink / raw)
To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev
Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
Jonghun Han, Jingoo Han
From: Jonghun Han <jonghun.han@samsung.com>
This patch adds support EXYNOS4 FIMD0 and LTE480WV LCD pannel.
Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
arch/arm/mach-exynos4/mach-smdkc210.c | 76 +++++++++++++++++++++++++++++++++
arch/arm/mach-exynos4/mach-smdkv310.c | 76 +++++++++++++++++++++++++++++++++
2 files changed, 152 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c
index e645f7a..714f6ae 100644
--- a/arch/arm/mach-exynos4/mach-smdkc210.c
+++ b/arch/arm/mach-exynos4/mach-smdkc210.c
@@ -9,7 +9,9 @@
*/
#include <linux/serial_core.h>
+#include <linux/delay.h>
#include <linux/gpio.h>
+#include <linux/lcd.h>
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
#include <linux/smsc911x.h>
@@ -19,16 +21,20 @@
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
+#include <video/platform_lcd.h>
+
#include <plat/regs-serial.h>
#include <plat/regs-srom.h>
#include <plat/exynos4.h>
#include <plat/cpu.h>
#include <plat/devs.h>
+#include <plat/fb.h>
#include <plat/sdhci.h>
#include <plat/iic.h>
#include <plat/pd.h>
#include <mach/map.h>
+#include <mach/regs-fb.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -111,6 +117,69 @@ static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = {
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
};
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 1);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ /* fire nRESET on power up */
+ gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+ gpio_direction_output(EXYNOS4_GPX0(6), 1);
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ mdelay(10);
+
+ gpio_free(EXYNOS4_GPX0(6));
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 0);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkc210_lcd_lte480wv_data = {
+ .set_power = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkc210_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdkc210_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_platdata smdkc210_lcd0_pdata __initdata = {
+ .win[0] = &smdkc210_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
+};
+
static struct resource smdkc210_smsc911x_resources[] = {
[0] = {
.start = EXYNOS4_PA_SROM_BANK(1),
@@ -165,6 +234,8 @@ static struct platform_device *smdkc210_devices[] __initdata = {
&exynos4_device_pd[PD_GPS],
&exynos4_device_sysmmu,
&samsung_asoc_dma,
+ &s5p_device_fimd0,
+ &smdkc210_lcd_lte480wv,
&smdkc210_smsc911x,
};
@@ -210,7 +281,12 @@ static void __init smdkc210_machine_init(void)
s3c_sdhci2_set_platdata(&smdkc210_hsmmc2_pdata);
s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata);
+ s5p_fimd0_set_platdata(&smdkc210_lcd0_pdata);
+
platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
+
+ exynos4_fimd0_setup_clock(&s5p_device_fimd0.dev, "mout_mpll",
+ 134 * MHZ);
}
MACHINE_START(SMDKC210, "SMDKC210")
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
index 1526764..31a0945 100644
--- a/arch/arm/mach-exynos4/mach-smdkv310.c
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -9,7 +9,9 @@
*/
#include <linux/serial_core.h>
+#include <linux/delay.h>
#include <linux/gpio.h>
+#include <linux/lcd.h>
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
#include <linux/smsc911x.h>
@@ -20,17 +22,21 @@
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
+#include <video/platform_lcd.h>
+
#include <plat/regs-serial.h>
#include <plat/regs-srom.h>
#include <plat/exynos4.h>
#include <plat/cpu.h>
#include <plat/devs.h>
+#include <plat/fb.h>
#include <plat/keypad.h>
#include <plat/sdhci.h>
#include <plat/iic.h>
#include <plat/pd.h>
#include <mach/map.h>
+#include <mach/regs-fb.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -113,6 +119,69 @@ static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
};
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 1);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ /* fire nRESET on power up */
+ gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+ gpio_direction_output(EXYNOS4_GPX0(6), 1);
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ mdelay(10);
+
+ gpio_free(EXYNOS4_GPX0(6));
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 0);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkv310_lcd_lte480wv_data = {
+ .set_power = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkv310_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdkv310_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win0 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_platdata smdkv310_lcd0_pdata __initdata = {
+ .win[0] = &smdkv310_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
+};
+
static struct resource smdkv310_smsc911x_resources[] = {
[0] = {
.start = EXYNOS4_PA_SROM_BANK(1),
@@ -187,6 +256,8 @@ static struct platform_device *smdkv310_devices[] __initdata = {
&exynos4_device_pd[PD_GPS],
&exynos4_device_sysmmu,
&samsung_asoc_dma,
+ &s5p_device_fimd0,
+ &smdkv310_lcd_lte480wv,
&smdkv310_smsc911x,
};
@@ -232,9 +303,14 @@ static void __init smdkv310_machine_init(void)
s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
+ s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
+
samsung_keypad_set_platdata(&smdkv310_keypad_data);
platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
+
+ exynos4_fimd0_setup_clock(&s5p_device_fimd0.dev, "mout_mpll",
+ 134 * MHZ);
}
MACHINE_START(SMDKV310, "SMDKV310")
--
1.7.1
^ permalink raw reply related
* [PATCH V6 0/5] ARM: EXYNOS4: Add support EXYNOS4 FIMD
From: JinGoo Han @ 2011-06-22 12:21 UTC (permalink / raw)
To: Kukjin Kim, Paul Mundt, linux-samsung-soc@vger.kernel.org,
"linux-fbdev@vger.kernel.org" <linux-f>
Cc: ANAND KUMAR N, Sylwester Nawrocki, THOMAS P ABRAHAM,
Marek Szyprowski, Kyungmin Park, In-Ki Dae, ARM Linux, Ben Dooks,
JinGoo Han
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1254", Size: 1439 bytes --]
This patch series is based on the latest
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
This was originally submitted by Jonghun Han <jonghun.han@samsung.com>
http://www.spinics.net/lists/arm-kernel/msg101781.html
This patch adds support FIMD(Fully Interactive Mobile Display) on Exynos4.
The 4th patch is update for s3c-fb and others are for platform data.
v2: change clock name of exynos4 FIMD: "fimd" -> "lcd"
use 'has_clksel' variable in order to distinguish FIMD version
add 'lcd_clk' that can be used for only lcd pixel clock
add callback 'enable_clk()' to enable parent clock 'sclk_fimd'.
v3: remove the callback from the platform data structure
v4: move clk_enable(sfb->lcd_clk) under the if statement
v5: add clk_enable/disable(sfb->lcd_clk) to s3c_fb_runtime_suspend/resume().
v6: rename dev-fimd-24bpp.c to dev-fimd0.c
add 'exynos4_fimd0_setup_clock()' to dev-fimd0.c to setup parent clock.
o To Kukjin Kim
[PATCH V6 1/5] ARM: EXYNOS4: Change clock name for FIMD
[PATCH V6 2/5] ARM: EXYNOS4: Add FIMD resource definition
[PATCH V6 3/5] ARM: EXYNOS4: Add platform device and helper functions for FIMD
[PATCH V6 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD and LTE480WV platform-lcd
o To Paul Mundt
[PATCH V6 4/5] video: s3c-fb: Add support EXYNOS4 FIMDÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±ýöÝzÿâØ^nr¡ö¦zË\x1aëh¨èÚ&£ûàz¿äz¹Þú+Ê+zf£¢·h§~Ûiÿÿïêÿêçz_è®\x0fæj:+v¨þ)ߣøm
^ permalink raw reply
* Re: Some questions about DRM(Direct Rendering Manager)
From: Rob Clark @ 2011-06-22 13:07 UTC (permalink / raw)
To: InKi Dae
Cc: linux-fbdev, Kukjin Kim, Kyungmin Park, dri-devel, daeinki,
Paul Mundt, jesse.barnes, linux-arm-kernel
In-Reply-To: <BANLkTim6xvD5U9GJ2pHu-=OrYccRHSj7Fg@mail.gmail.com>
fwiw, drm_fb_helper_single_fb_probe() calls register_framebuffer() (if
that was the question?)
BR,
-R
2011/6/22 InKi Dae <daeinki@gmail.com>:
> It adds dri-devel@lists.freedesktop.org to this mail thread.
> Thank you.
>
> 2011년 6월 22일 오후 3:04, daeinki <inki.dae@samsung.com>님의 말:
>> below is additional comments.
>>
>> daeinki 쓴 글:
>>> Hi all,
>>>
>>> I'm writing Samsung SoC based DRM framework and this one includes FIMD
>>> and HDMI driver as hardware dependent modules. and for now, encoder,
>>> connector, crtc and fb module has been materialized almost. but I'm
>>> contending with framebuffer setting issue(created fb_info should be
>>> registered to linux framebuffer through register_framebuffer() or not)as
>>> default framebuffer at booting time.
>>>
>>> at drm_fb_helper_single_fb_probe() of drm_fb_helper.c file, fb_helper's
>>> fb_probe callback is called and this one creates new framebuffer and
>>> returns a value more then 0 if true. internally, this process creates an
>>> fb_info object and drm_framebuffer and then drm_framebuffer would be
>>> added to mode_config.fb_list of the drm_device.
>>>
>> it's my mistake. return value is 0 if true, nonzero otherwise.
>>
>>> a value returned, new_fb is used to decide that it calls
>>> register_framebuffer() or drm_fb_helper_set_par(). at this point, I am
>>> confused it's a good way to call register_framebuffer() otherwise
>>> drm_fb_helper_set_par(). if register_framebuffer() is called then I
>>> guess drm_fb_helper_set_par() or drm_crtc_helper_set_config() should be
>>> called somewhere subsequently to apply this one to real hardware because
>>> previous process is just for maintaining data logically.(not set up data
>>> to h/w)
>>>
>>> it's a right way to call register_framebuffer() and then
>>> drm_fb_helper_set_par() or drm_crtc_helper_set_config()? otherwise just
>>> only drm_fb_helper_set_par() or drm_crtc_helper_set_config() ignoring
>>> register_framebuffer()? and what is the purpose of using
>>> register_framebuffer()?
>>>
>> I understood that if fb_probe() callback is fail then fb_info object is
>> registered to linux framebuffer through register_framebuffer()
>> otherwise(if true) hardware configuration would be completed by
>> drm_fb_helper_set_par() so the reason of using register_framebuffer() is
>> that the case of failing fb_probe() callback, it is for drawing on only
>> linux framebuffer. is it right?
>>
>>> In my case, first, register_framebuffer() is called and then if desired
>>> default crtc id is matched with drm_fb_helper->crtc_info[0 ~ n].crtc_id,
>>> it gets mode_set of drm_fb_helper->crtc_info[n] and then it calls
>>> drm_crtc_helper_set_config(mode_set). at this time, all the hardware
>>> configurations would be completed.
>>>
>>> thank you in advance.
>>>
>>> Best Regards
>>> Inki Dae.
>>>
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
--
To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH V5 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD
From: Anand Kumar N @ 2011-06-22 13:37 UTC (permalink / raw)
To: Marek Szyprowski
Cc: Jingoo Han, Kukjin Kim, Paul Mundt, linux-samsung-soc,
linux-fbdev, Jonghun Han, Thomas Abraham, Sylwester Nawrocki,
Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks
In-Reply-To: <BANLkTimPjo+WefApQLe=HKbYLCwmo_gGRw@mail.gmail.com>
Hi Marek/Jingoo,
On Wed, Jun 22, 2011 at 3:17 PM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> Hello,
>
> On Wednesday, June 22, 2011 8:42 AM Jingoo Han wrote:
>
>> From: Jonghun Han <jonghun.han@samsung.com>
(snipped)
Instead of hardcoding the parent clock in platform/bootloader code ,is
it not possible to select/set the
parent clock based on the pixel clk(plat data) having the least delta
with the 9 src clks.with this change I have checked it for WA101S.
These are the changes I am proposing..
arch/arm/mach-exynos4/clock.c
+struct clk *clkset_sclk_fimd0_list[] = {
+ [0] = &clk_sclk_xxti,
+ [1] = &clk_sclk_xusbxti,
+ [2] = &clk_sclk_hdmi27m,
+ [3] = &clk_sclk_usbphy0,
+ [4] = &clk_sclk_usbphy1,
+ [5] = &clk_sclk_hdmiphy,
+ [6] = &clk_mout_mpll.clk,
+ [7] = &clk_mout_epll.clk,
+ [8] = &clk_sclk_vpll.clk,
+};
arch/arm/mach-exynos4/mach-smdkv310.c
+static int fimd_s3c_consider_clock(struct device *sfb,int src
,unsigned int wanted)
+{
+ unsigned long rate = 0;
+ int div =1;
+ struct clk *mout_mpll = NULL;
+
+ if(clkset_sclk_fimd0_list[src]){
+ mout_mpll = clk_get(sfb,clkset_sclk_fimd0_list[src]->name);
+ if (IS_ERR(mout_mpll)) {
+ dev_err(sfb, "failed to clk_get
%s\n",clkset_sclk_fimd0_list[src]->name);
+ }
+
+ rate = clk_get_rate(mout_mpll);
+
+ for (div = 1; div < 256; div *= 2) {
+ if ((rate / div) <= wanted)
+ break;
+ }
+
+
+ }
+ return (wanted - (rate / div));
+}
+
+int exynos4_fimd0_find_clock(struct platform_device *pdev,struct clk
**lcd_clk,unsigned int clock(pixel clock needed for the lcd))
+{
+ int best = 0;
+ int delta = 0;
+ int best_src = 0;
+ int src;
+ struct clk *best_clk_src = NULL;
+ struct clk *clk = NULL;
+
+ if (clock = 0)
+ return 0;
+
+ for (src = 0; src < MAX_NUM_CLKS ;src++) {
+ delta = fimd_s3c_consider_clock(&pdev->dev,src,clock);
+ if (delta < best) {
+ best = delta;
+ best_src = src;
+ }
+ }
+ clk = clk_get(&pdev->dev, "sclk_fimd");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to get sclk for fimd\n");
+ goto err_clk2;
+ }
+
+ best_clk_src clk_get(&pdev->dev,clkset_sclk_fimd0_list[best_src]->name);
+ if (IS_ERR(best_clk_src)) {
+ dev_err(&pdev->dev, "failed to get best_src\n");
+ goto err_clk1;
+ }
+ clk_set_parent(clk,best_clk_src);
+ *lcd_clk = clk;
+ clk_put(best_clk_src);
+ clk_enable(clk);
+ dev_dbg(&pdev->dev, "set fimd sclk rate to %d\n", clock);
+
+err_clk1:
+ clk_put(best_clk_src);
+err_clk2:
+ clk_put(clk);
+
+ return -EINVAL;
+}
I have based these patches on the v1 version of this patch.I can base
these changes
on your latest changes(v6) and send as a patch.
>> +static int __init smdkc210_fimd0_setup_clock(void)
>> +{
>> + struct clk *sclk = NULL;
>> + struct clk *mout_mpll = NULL;
>> +
>> + u32 rate = 0;
>> +
>> + sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
>> + if (IS_ERR(sclk)) {
>> + printk(KERN_ERR "failed to get sclk for fimd\n");
>> + goto err_clk2;
>> + }
>> +
>> + mout_mpll = clk_get(NULL, "mout_mpll");
>> + if (IS_ERR(mout_mpll)) {
>> + printk(KERN_ERR "failed to get mout_mpll\n");
>> + goto err_clk1;
>> + }
>> +
>> + clk_set_parent(sclk, mout_mpll);
>> + if (!rate)
>> + rate = 134000000;
>> +
>> + clk_set_rate(sclk, rate);
>> +
>> + clk_put(sclk);
>> + clk_put(mout_mpll);
>> +
>> + return 0;
>> +
>> +err_clk1:
>> + clk_put(mout_mpll);
>> +err_clk2:
>> + clk_put(sclk);
>> +
>> + return -EINVAL;
>> +}
>> +
>
> I'm not sure if mach-smdk*.c is the right place for the above code.
> IMHO all the code that configures very low level, board specific parameters
> (like clocks and their relations) should be performed in boot loarder.
>
I feel pushing the clock enabling into the bootloader,will create an
unneccesary dependcy for the lcd on the u-boot.
> (snipped)
>
> Best regards
> --
> Marek Szyprowski
> Samsung Poland R&D Center
>
>
>
regards
anand
^ permalink raw reply
* [PATCH] udlfb - Fix for problem with monitor resolution detection /
From: Katsak, William Alexander (Bill) @ 2011-06-22 17:15 UTC (permalink / raw)
To: linux-fbdev
[-- Attachment #1: Type: text/plain, Size: 1211 bytes --]
Hello,
This is my first contribution on this list, so please let me know if I am off with any procedures or anything.
This patch fixes a problem where a DisplayLink device autoselects a suboptimal framebuffer resolution. The problem occured with a Plugable UGA-2K-A connected to a Samsung EX2220X display. In this situation, the driver always allocates a 1600x1200 framebuffer, even after it indicates in its output that 1920x1080 is a valid mode. If my interpretation of the code is correct, the problem was in the block that selects the best mode. The existing code unset the FB_MISC_1ST_DETAIL flag if ANY of the modes is determined to be invalid (on my adapter, 1680x1680 is invalid). This in turn causes the fb_find_best_display() function to disregard the first mode (1920x1080). The comment for the line that unsets the flag implies that this should happen if we have removed the top/best mode...however, this else block is not qualified, and happens if we remove any mode. I simply put in a condition so that we only unset this flag if the first mode is invalid.
Thanks in advance for your feedback.
Bill Katsak
Bell Laboratories
Alcatel-Lucent, Inc.
william.katsak@alcatel-lucent.com
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: udlfb_resolution_fix.patch --]
[-- Type: text/x-patch; name="udlfb_resolution_fix.patch", Size: 1499 bytes --]
From c3327c41877637e80f9f06a8ce3bdcfe8b4e6fa4 Mon Sep 17 00:00:00 2001
From: William Katsak <william.katsak@alcatel-lucent.com>
Date: Wed, 22 Jun 2011 12:48:11 -0400
Subject: [PATCH] This patch fixes a problem where a DisplayLink device autoselects a
suboptimal framebuffer resolution.
The situation in which the problem occurred was with a Plugable UGA-2K-A
connected to a Samsung EX2220X display. The driver indicates that
1920x1080 is a valid mode (the first mode available, in fact), but
proceeds to set the framebuffer size to 1600x1200.
The patch corrects what seems to be a logic error, regarding unsetting
the FB_MISC_1ST_DETAIL flag, if the first (top/best) mode is invalid.
The existing code unset the flag if ANY mode was invalid.
---
drivers/video/udlfb.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index 52b0f3e..816a4fd 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -1233,8 +1233,12 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
if (dlfb_is_valid_mode(&info->monspecs.modedb[i], info))
fb_add_videomode(&info->monspecs.modedb[i],
&info->modelist);
- else /* if we've removed top/best mode */
- info->monspecs.misc &= ~FB_MISC_1ST_DETAIL;
+ else {
+ if (i == 0)
+ /* if we've removed top/best mode */
+ info->monspecs.misc
+ &= ~FB_MISC_1ST_DETAIL;
+ }
}
default_vmode = fb_find_best_display(&info->monspecs,
--
1.7.3.4
^ permalink raw reply related
* I am Mrs Helen Moore, a devoted Christian. I have chosen you for an inheritance. Please contact me f
From: Sparks, Karen @ 2011-06-22 17:42 UTC (permalink / raw)
^ permalink raw reply
* Re: [PATCH] fsl-diu-fb: remove the ioctl interface
From: Anatolij Gustschin @ 2011-06-22 20:11 UTC (permalink / raw)
To: Tabi Timur-B04825
Cc: linuxppc-dev@ozlabs.org, linux-fbdev@vger.kernel.org,
lethal@linux-sh.org, sun york-R58495
In-Reply-To: <4E012586.7050808@freescale.com>
On Tue, 21 Jun 2011 23:13:11 +0000
Tabi Timur-B04825 <B04825@freescale.com> wrote:
> Anatolij Gustschin wrote:
> > No! We are using ioctl interface of this driver in many video
> > rendering applications on overlay planes on huge number of boards.
> > So, please don't remove it.
>
> Ok, I had no idea anyone was using it.
>
> Can you email me details about how you use the ioctl interface? If I can't
> remove it, maybe I can clean it up.
Following DIU specific ioctls are used:
MFB_SET_CHROMA_KEY
MFB_SET_PIXFMT
MFB_GET_PIXFMT
MFB_SET_AOID
MFB_GET_AOID
MFB_GET_ALPHA
MFB_SET_ALPHA
Other ioctls can be removed. I'm not sure if someone
uses FBIOGET_GWINFO. If there are no objections from
other people, it can also be dropped.
^ permalink raw reply
* Re: [PATCH] udlfb - Fix for problem with monitor resolution detection
From: Florian Tobias Schandinat @ 2011-06-22 20:33 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <76676AFCFD6F05458E27320F9BB714A825120FC640@USNAVSXCHMBSD1.ndc.alcatel-lucent.com>
Hi,
On 06/22/2011 05:15 PM, Katsak, William Alexander (Bill) wrote:
> This is my first contribution on this list, so please let me know if I am off with any procedures or anything.
Please send patches inline to make review easier, preferably using "git
send-email" to avoid broken patches.
> From c3327c41877637e80f9f06a8ce3bdcfe8b4e6fa4 Mon Sep 17 00:00:00 2001
> From: William Katsak<william.katsak@alcatel-lucent.com>
> Date: Wed, 22 Jun 2011 12:48:11 -0400
> Subject: [PATCH] This patch fixes a problem where a DisplayLink device autoselects a
> suboptimal framebuffer resolution.
>
> The situation in which the problem occurred was with a Plugable UGA-2K-A
> connected to a Samsung EX2220X display. The driver indicates that
> 1920x1080 is a valid mode (the first mode available, in fact), but
> proceeds to set the framebuffer size to 1600x1200.
>
> The patch corrects what seems to be a logic error, regarding unsetting
> the FB_MISC_1ST_DETAIL flag, if the first (top/best) mode is invalid.
> The existing code unset the flag if ANY mode was invalid.
You're missing a Signed-off-line, see Documentation/SubmittingPatches in your
kernel sources.
Best regards,
Florian Tobias Schandinat
> ---
> drivers/video/udlfb.c | 8 ++++++--
> 1 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
> index 52b0f3e..816a4fd 100644
> --- a/drivers/video/udlfb.c
> +++ b/drivers/video/udlfb.c
> @@ -1233,8 +1233,12 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
> if (dlfb_is_valid_mode(&info->monspecs.modedb[i], info))
> fb_add_videomode(&info->monspecs.modedb[i],
> &info->modelist);
> - else /* if we've removed top/best mode */
> - info->monspecs.misc&= ~FB_MISC_1ST_DETAIL;
> + else {
> + if (i = 0)
> + /* if we've removed top/best mode */
> + info->monspecs.misc
> + &= ~FB_MISC_1ST_DETAIL;
> + }
> }
>
> default_vmode = fb_find_best_display(&info->monspecs,
^ permalink raw reply
* Re: [PATCH V5 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD
From: Sylwester Nawrocki @ 2011-06-22 20:33 UTC (permalink / raw)
To: Anand Kumar N
Cc: Marek Szyprowski, Jingoo Han, Kukjin Kim, Paul Mundt,
linux-samsung-soc, linux-fbdev, Jonghun Han, Thomas Abraham,
Sylwester Nawrocki, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks
In-Reply-To: <BANLkTi=iS3H8xYhouvZZwP5_daxoGSBwLA@mail.gmail.com>
On 06/22/2011 03:25 PM, Anand Kumar N wrote:
> Instead of hardcoding the parent clock in platform/bootloader code ,is
> it not possible to select/set the
> parent clock based on the pixel clk(plat data) having the least delta
> with the 9 src clks.with this change I have checked it for WA101S.
While at first sight this may look as an awesome idea I don't really
believe it is. There might be other criteria that need to be considered,
like continuous clock availability or frequency stability.
That said we could possibly have the driver setting sclk_fimd frequency
based on display planes' properties (this was my initial suggestion)
but sclk_fimd parent should be fixed either by bootloader or board
initialization code.
^ permalink raw reply
* Re: Re: [PATCH V5 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4
From: JinGoo Han @ 2011-06-23 1:09 UTC (permalink / raw)
To: ANAND KUMAR N, Marek Szyprowski
Cc: JinGoo Han, Kukjin Kim, Paul Mundt,
linux-samsung-soc@vger.kernel.org, linux-fbdev@vger.kernel.org,
Jong-Hun Han, THOMAS P ABRAHAM, Sylwester Nawrocki, Kyungmin Park,
In-Ki Dae, ARM Linux, Ben Dooks
In-Reply-To: <1308724904-31521-1-git-send-email-jg1.han@samsung.com>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1254", Size: 6229 bytes --]
Hi, Anand.
> -----Original Message-----
> From: linux-samsung-soc-owner@vger.kernel.org [mailto:linux-samsung-soc-
> owner@vger.kernel.org] On Behalf Of Anand Kumar N
> Sent: Wednesday, June 22, 2011 10:25 PM
> To: Marek Szyprowski
> Cc: Jingoo Han; Kukjin Kim; Paul Mundt; linux-samsung-soc@vger.kernel.org;
> linux-fbdev@vger.kernel.org; Jonghun Han; Thomas Abraham; Sylwester
> Nawrocki; Kyungmin Park; Inki Dae; ARM Linux; Ben Dooks
> Subject: Re: [PATCH V5 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4
> FIMD and LTE480WV platform-lcd
>
> Hi Marek/Jingoo,
>
> On Wed, Jun 22, 2011 at 3:17 PM, Marek Szyprowski
> <m.szyprowski@samsung.com> wrote:
> > Hello,
> >
> > On Wednesday, June 22, 2011 8:42 AM Jingoo Han wrote:
> >
> >> From: Jonghun Han <jonghun.han@samsung.com>
> (snipped)
> Instead of hardcoding the parent clock in platform/bootloader code ,is
> it not possible to select/set the
> parent clock based on the pixel clk(plat data) having the least delta
> with the 9 src clks.with this change I have checked it for WA101S.
> These are the changes I am proposing..
>
> arch/arm/mach-exynos4/clock.c
> +struct clk *clkset_sclk_fimd0_list[] = {
> + [0] = &clk_sclk_xxti,
> + [1] = &clk_sclk_xusbxti,
> + [2] = &clk_sclk_hdmi27m,
> + [3] = &clk_sclk_usbphy0,
> + [4] = &clk_sclk_usbphy1,
> + [5] = &clk_sclk_hdmiphy,
> + [6] = &clk_mout_mpll.clk,
> + [7] = &clk_mout_epll.clk,
> + [8] = &clk_sclk_vpll.clk,
> +};
As Sylwester Nawrocki mentioned, there would be criteria that should be considered
such as continuous clock availability or frequency stability.
For instance, when EPLL '[7] = &clk_mout_epll.clk,' is selected, there is posibility
that EPLL frequency will be changed by other devices.
However, Exynos4 FIMD can use a range of clocks as source clock, 'mout_mpll' is
most useful and can cover almost LCD pixel clock, because 'mout_mpll' is 800 MHz
and max frequency of 'sclk_fimd' can be set as 800MHz.
However, other clocks are very low. For example, HDMI PHY, VPLL are 54MHz,
USB PHY is 48MHz.
> arch/arm/mach-exynos4/mach-smdkv310.c
> +static int fimd_s3c_consider_clock(struct device *sfb,int src
> ,unsigned int wanted)
> +{
> + unsigned long rate = 0;
> + int div =1;
> + struct clk *mout_mpll = NULL;
> +
> + if(clkset_sclk_fimd0_list[src]){
> + mout_mpll = clk_get(sfb,clkset_sclk_fimd0_list[src]->name);
> + if (IS_ERR(mout_mpll)) {
> + dev_err(sfb, "failed to clk_get
> %s\n",clkset_sclk_fimd0_list[src]->name);
> + }
> +
> + rate = clk_get_rate(mout_mpll);
> +
> + for (div = 1; div < 256; div *= 2) {
> + if ((rate / div) <= wanted)
> + break;
> + }
> +
> +
> + }
> + return (wanted - (rate / div));
> +}
> +
> +int exynos4_fimd0_find_clock(struct platform_device *pdev,struct clk
> **lcd_clk,unsigned int clock(pixel clock needed for the lcd))
> +{
> + int best = 0;
> + int delta = 0;
> + int best_src = 0;
> + int src;
> + struct clk *best_clk_src = NULL;
> + struct clk *clk = NULL;
> +
> + if (clock = 0)
> + return 0;
> +
> + for (src = 0; src < MAX_NUM_CLKS ;src++) {
> + delta = fimd_s3c_consider_clock(&pdev->dev,src,clock);
> + if (delta < best) {
> + best = delta;
> + best_src = src;
> + }
> + }
> + clk = clk_get(&pdev->dev, "sclk_fimd");
> + if (IS_ERR(clk)) {
> + dev_err(&pdev->dev, "failed to get sclk for fimd\n");
> + goto err_clk2;
> + }
> +
> + best_clk_src > clk_get(&pdev->dev,clkset_sclk_fimd0_list[best_src]->name);
> + if (IS_ERR(best_clk_src)) {
> + dev_err(&pdev->dev, "failed to get best_src\n");
> + goto err_clk1;
> + }
> + clk_set_parent(clk,best_clk_src);
> + *lcd_clk = clk;
> + clk_put(best_clk_src);
> + clk_enable(clk);
> + dev_dbg(&pdev->dev, "set fimd sclk rate to %d\n", clock);
> +
> +err_clk1:
> + clk_put(best_clk_src);
> +err_clk2:
> + clk_put(clk);
> +
> + return -EINVAL;
> +}
> I have based these patches on the v1 version of this patch.I can base
> these changes
> on your latest changes(v6) and send as a patch.
>
> >> +static int __init smdkc210_fimd0_setup_clock(void)
> >> +{
> >> + struct clk *sclk = NULL;
> >> + struct clk *mout_mpll = NULL;
> >> +
> >> + u32 rate = 0;
> >> +
> >> + sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
> >> + if (IS_ERR(sclk)) {
> >> + printk(KERN_ERR "failed to get sclk for fimd\n");
> >> + goto err_clk2;
> >> + }
> >> +
> >> + mout_mpll = clk_get(NULL, "mout_mpll");
> >> + if (IS_ERR(mout_mpll)) {
> >> + printk(KERN_ERR "failed to get mout_mpll\n");
> >> + goto err_clk1;
> >> + }
> >> +
> >> + clk_set_parent(sclk, mout_mpll);
> >> + if (!rate)
> >> + rate = 134000000;
> >> +
> >> + clk_set_rate(sclk, rate);
> >> +
> >> + clk_put(sclk);
> >> + clk_put(mout_mpll);
> >> +
> >> + return 0;
> >> +
> >> +err_clk1:
> >> + clk_put(mout_mpll);
> >> +err_clk2:
> >> + clk_put(sclk);
> >> +
> >> + return -EINVAL;
> >> +}
> >> +
> >
> > I'm not sure if mach-smdk*.c is the right place for the above code.
> > IMHO all the code that configures very low level, board specific
> parameters
> > (like clocks and their relations) should be performed in boot loarder.
> >
>
> I feel pushing the clock enabling into the bootloader,will create an
> unneccesary dependcy for the lcd on the u-boot.
>
> > (snipped)
> >
> > Best regards
> > --
> > Marek Szyprowski
> > Samsung Poland R&D Center
> >
> >
> >
> regards
> anand
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-
> soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-i
ÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±ýöÝzÿâØ^nr¡ö¦zË\x1aëh¨èÚ&£ûàz¿äz¹Þú+Ê+zf£¢·h§~Ûiÿÿïêÿêçz_è®\x0fæj:+v¨þ)ߣøm
^ permalink raw reply
* Re: Some questions about DRM(Direct Rendering Manager)
From: daeinki @ 2011-06-23 1:55 UTC (permalink / raw)
To: Rob Clark
Cc: linux-fbdev, Kukjin Kim, Kyungmin Park, dri-devel, Paul Mundt,
jesse.barnes, InKi Dae, linux-arm-kernel
In-Reply-To: <BANLkTinv1uGUPBX4RE2DGw4Ca_P5x0g+DA@mail.gmail.com>
Hi Rob Clark,
I'm sorry for that my mean didn't convey to you so I condensed that into
brief again.
I know drm_fb_helper_single_fb_probe() calls register_framebuffer(),
My question is that it's right way to call only drm_fb_helper_set_par()
if fb_helper->funcs->fb_probe() returns nonzero.
In this case, if fb_helper->funcs->fb_probe() returns zero then
register_framebuffer() isn't called and this means linux framebuffer
isn't used anymore.
one more question, otherwise if it uses drm based framebuffer,
register_framebuffer() should be called necessarily at booting time?
Thank you.
Rob Clark 쓴 글:
> fwiw, drm_fb_helper_single_fb_probe() calls register_framebuffer() (if
> that was the question?)
>
> BR,
> -R
>
> 2011/6/22 InKi Dae <daeinki@gmail.com>:
>> It adds dri-devel@lists.freedesktop.org to this mail thread.
>> Thank you.
>>
>> 2011년 6월 22일 오후 3:04, daeinki <inki.dae@samsung.com>님의 말:
>>> below is additional comments.
>>>
>>> daeinki 쓴 글:
>>>> Hi all,
>>>>
>>>> I'm writing Samsung SoC based DRM framework and this one includes FIMD
>>>> and HDMI driver as hardware dependent modules. and for now, encoder,
>>>> connector, crtc and fb module has been materialized almost. but I'm
>>>> contending with framebuffer setting issue(created fb_info should be
>>>> registered to linux framebuffer through register_framebuffer() or not)as
>>>> default framebuffer at booting time.
>>>>
>>>> at drm_fb_helper_single_fb_probe() of drm_fb_helper.c file, fb_helper's
>>>> fb_probe callback is called and this one creates new framebuffer and
>>>> returns a value more then 0 if true. internally, this process creates an
>>>> fb_info object and drm_framebuffer and then drm_framebuffer would be
>>>> added to mode_config.fb_list of the drm_device.
>>>>
>>> it's my mistake. return value is 0 if true, nonzero otherwise.
>>>
>>>> a value returned, new_fb is used to decide that it calls
>>>> register_framebuffer() or drm_fb_helper_set_par(). at this point, I am
>>>> confused it's a good way to call register_framebuffer() otherwise
>>>> drm_fb_helper_set_par(). if register_framebuffer() is called then I
>>>> guess drm_fb_helper_set_par() or drm_crtc_helper_set_config() should be
>>>> called somewhere subsequently to apply this one to real hardware because
>>>> previous process is just for maintaining data logically.(not set up data
>>>> to h/w)
>>>>
>>>> it's a right way to call register_framebuffer() and then
>>>> drm_fb_helper_set_par() or drm_crtc_helper_set_config()? otherwise just
>>>> only drm_fb_helper_set_par() or drm_crtc_helper_set_config() ignoring
>>>> register_framebuffer()? and what is the purpose of using
>>>> register_framebuffer()?
>>>>
>>> I understood that if fb_probe() callback is fail then fb_info object is
>>> registered to linux framebuffer through register_framebuffer()
>>> otherwise(if true) hardware configuration would be completed by
>>> drm_fb_helper_set_par() so the reason of using register_framebuffer() is
>>> that the case of failing fb_probe() callback, it is for drawing on only
>>> linux framebuffer. is it right?
>>>
>>>> In my case, first, register_framebuffer() is called and then if desired
>>>> default crtc id is matched with drm_fb_helper->crtc_info[0 ~ n].crtc_id,
>>>> it gets mode_set of drm_fb_helper->crtc_info[n] and then it calls
>>>> drm_crtc_helper_set_config(mode_set). at this time, all the hardware
>>>> configurations would be completed.
>>>>
>>>> thank you in advance.
>>>>
>>>> Best Regards
>>>> Inki Dae.
>>>>
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel@lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox