* [PATCH v2 0/2] da8xx-fb: LCDC driver cleanup
From: Manjunathappa, Prakash @ 2012-10-16 5:05 UTC (permalink / raw)
To: linux-fbdev
This patch series clean up driver as it is necessary for DT migration.
Manjunathappa, Prakash (2):
da8xx-fb: adopt fb_videomode data for panel information
da8xx-fb: cleanup LCDC configurations
arch/arm/mach-davinci/devices-da8xx.c | 22 +----
drivers/video/da8xx-fb.c | 167 +++++++++++++++------------------
include/video/da8xx-fb.h | 25 +----
3 files changed, 79 insertions(+), 135 deletions(-)
^ permalink raw reply
* [PATCH V8 2/2] video: exynos_dp: device tree documentation
From: Jingoo Han @ 2012-10-16 2:17 UTC (permalink / raw)
To: 'Florian Tobias Schandinat'
Cc: linux-fbdev, linux-samsung-soc, devicetree-discuss,
'Ajay Kumar', 'Sylwester Nawrocki',
'Tomasz Figa', 'Thomas Abraham',
'Jingoo Han'
From: Ajay Kumar <ajaykumar.rs@samsung.com>
Add documentation for the DT bindings in exynos display port driver.
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
No changes since v7:
.../devicetree/bindings/video/exynos_dp.txt | 80 ++++++++++++++++++++
1 files changed, 80 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/video/exynos_dp.txt
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
new file mode 100644
index 0000000..7cc7d9f
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -0,0 +1,80 @@
+The Exynos display port interface should be configured based on
+the type of panel connected to it.
+
+We use two nodes:
+ -display-port-controller node
+ -dptx-phy node(defined inside display-port-controller node)
+
+For the DP-PHY initialization, we use the dptx-phy node.
+Required properties for dptx-phy:
+ -reg:
+ Base address of DP PHY register.
+ -samsung,enable-mask:
+ The bit-mask used to enable/disable DP PHY.
+
+For the Panel initialization, we read data from display-port-controller node.
+Required properties for display-port-controller:
+ -compatible:
+ should be "samsung,exynos5-dp".
+ -reg:
+ physical base address of the controller and length
+ of memory mapped region.
+ -interrupts:
+ interrupt combiner values.
+ -interrupt-parent:
+ phandle to Interrupt combiner node.
+ -samsung,color-space:
+ input video data format.
+ COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
+ -samsung,dynamic-range:
+ dynamic range for input video data.
+ VESA = 0, CEA = 1
+ -samsung,ycbcr-coeff:
+ YCbCr co-efficients for input video.
+ COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
+ -samsung,color-depth:
+ number of bits per colour component.
+ COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
+ -samsung,link-rate:
+ link rate supported by the panel.
+ LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
+ -samsung,lane-count:
+ number of lanes supported by the panel.
+ LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
+
+Optional properties for display-port-controller:
+ -interlaced:
+ interlace scan mode.
+ Progressive if defined, Interlaced if not defined
+ -vsync-active-high:
+ VSYNC polarity configuration.
+ High if defined, Low if not defined
+ -hsync-active-high:
+ HSYNC polarity configuration.
+ High if defined, Low if not defined
+
+Example:
+
+SOC specific portion:
+ display-port-controller {
+ compatible = "samsung,exynos5-dp";
+ reg = <0x145b0000 0x10000>;
+ interrupts = <10 3>;
+ interrupt-parent = <&combiner>;
+
+ dptx-phy {
+ reg = <0x10040720>;
+ samsung,enable-mask = <1>;
+ };
+
+ };
+
+Board Specific portion:
+ display-port-controller {
+ samsung,color-space = <0>;
+ samsung,dynamic-range = <0>;
+ samsung,ycbcr-coeff = <0>;
+ samsung,color-depth = <1>;
+ samsung,link-rate = <0x0a>;
+ samsung,lane-count = <4>;
+ };
--
1.7.1
^ permalink raw reply related
* [PATCH V8 1/2] video: exynos_dp: Add device tree support to DP driver
From: Jingoo Han @ 2012-10-16 2:16 UTC (permalink / raw)
To: 'Florian Tobias Schandinat'
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, 'Jingoo Han',
'Ajay Kumar', 'Sylwester Nawrocki',
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
From: Ajay Kumar <ajaykumar.rs@samsung.com>
This patch enables device tree based discovery support for DP driver.
The driver is modified to handle platform data in both the cases:
with DT and non-DT.
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
This patch is tested with Exynos5250.
Changes since v7:
- Replace platform_get_drvdata() with dev_get_drvdata() in suspend/resume
drivers/video/exynos/exynos_dp_core.c | 216 ++++++++++++++++++++++++++++++---
drivers/video/exynos/exynos_dp_core.h | 2 +
2 files changed, 198 insertions(+), 20 deletions(-)
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e..9a9ecc1 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/of.h>
#include <video/exynos_dp.h>
@@ -856,6 +857,145 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
return IRQ_HANDLED;
}
+#ifdef CONFIG_OF
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+ struct device_node *dp_node = dev->of_node;
+ struct exynos_dp_platdata *pd;
+ struct video_info *dp_video_config;
+
+ pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ dev_err(dev, "memory allocation for pdata failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ dp_video_config = devm_kzalloc(dev,
+ sizeof(*dp_video_config), GFP_KERNEL);
+
+ if (!dp_video_config) {
+ dev_err(dev, "memory allocation for video config failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ pd->video_info = dp_video_config;
+
+ dp_video_config->h_sync_polarity + of_property_read_bool(dp_node, "hsync-active-high");
+
+ dp_video_config->v_sync_polarity + of_property_read_bool(dp_node, "vsync-active-high");
+
+ dp_video_config->interlaced + of_property_read_bool(dp_node, "interlaced");
+
+ if (of_property_read_u32(dp_node, "samsung,color-space",
+ &dp_video_config->color_space)) {
+ dev_err(dev, "failed to get color-space\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,dynamic-range",
+ &dp_video_config->dynamic_range)) {
+ dev_err(dev, "failed to get dynamic-range\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
+ &dp_video_config->ycbcr_coeff)) {
+ dev_err(dev, "failed to get ycbcr-coeff\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,color-depth",
+ &dp_video_config->color_depth)) {
+ dev_err(dev, "failed to get color-depth\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,link-rate",
+ &dp_video_config->link_rate)) {
+ dev_err(dev, "failed to get link-rate\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,lane-count",
+ &dp_video_config->lane_count)) {
+ dev_err(dev, "failed to get lane-count\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ return pd;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+ struct device_node *dp_phy_node;
+ u32 phy_base;
+
+ dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
+ if (!dp_phy_node) {
+ dev_err(dp->dev, "could not find dptx-phy node\n");
+ return -ENODEV;
+ }
+
+ if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
+ dev_err(dp->dev, "faild to get reg for dptx-phy\n");
+ return -EINVAL;
+ }
+
+ if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
+ &dp->enable_mask)) {
+ dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n");
+ return -EINVAL;
+ }
+
+ dp->phy_addr = ioremap(phy_base, SZ_4);
+ if (!dp->phy_addr) {
+ dev_err(dp->dev, "failed to ioremap dp-phy\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->phy_addr);
+ reg |= dp->enable_mask;
+ __raw_writel(reg, dp->phy_addr);
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->phy_addr);
+ reg &= ~(dp->enable_mask);
+ __raw_writel(reg, dp->phy_addr);
+}
+#else
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+ return NULL;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+ return -EINVAL;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+ return;
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+ return;
+}
+#endif /* CONFIG_OF */
+
static int __devinit exynos_dp_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -864,12 +1004,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
int ret = 0;
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
GFP_KERNEL);
if (!dp) {
@@ -879,6 +1013,22 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
dp->dev = &pdev->dev;
+ if (pdev->dev.of_node) {
+ pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+
+ ret = exynos_dp_dt_parse_phydata(dp);
+ if (ret)
+ return ret;
+ } else {
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data\n");
+ return -EINVAL;
+ }
+ }
+
dp->clock = devm_clk_get(&pdev->dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(&pdev->dev, "failed to get clock\n");
@@ -909,8 +1059,14 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
}
dp->video_info = pdata->video_info;
- if (pdata->phy_init)
- pdata->phy_init();
+
+ if (pdev->dev.of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_init(dp);
+ } else {
+ if (pdata->phy_init)
+ pdata->phy_init();
+ }
exynos_dp_init_dp(dp);
@@ -953,8 +1109,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_exit)
- pdata->phy_exit();
+ if (pdev->dev.of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_exit(dp);
+ } else {
+ if (pdata->phy_exit)
+ pdata->phy_exit();
+ }
clk_disable_unprepare(dp->clock);
@@ -964,12 +1125,16 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int exynos_dp_suspend(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
- struct exynos_dp_device *dp = platform_get_drvdata(pdev);
+ struct exynos_dp_platdata *pdata = dev->platform_data;
+ struct exynos_dp_device *dp = dev_get_drvdata(dev);
- if (pdata && pdata->phy_exit)
- pdata->phy_exit();
+ if (dev->of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_exit(dp);
+ } else {
+ if (pdata->phy_exit)
+ pdata->phy_exit();
+ }
clk_disable_unprepare(dp->clock);
@@ -978,12 +1143,16 @@ static int exynos_dp_suspend(struct device *dev)
static int exynos_dp_resume(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
- struct exynos_dp_device *dp = platform_get_drvdata(pdev);
+ struct exynos_dp_platdata *pdata = dev->platform_data;
+ struct exynos_dp_device *dp = dev_get_drvdata(dev);
- if (pdata && pdata->phy_init)
- pdata->phy_init();
+ if (dev->of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_init(dp);
+ } else {
+ if (pdata->phy_init)
+ pdata->phy_init();
+ }
clk_prepare_enable(dp->clock);
@@ -1013,6 +1182,12 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
};
+static const struct of_device_id exynos_dp_match[] = {
+ { .compatible = "samsung,exynos5-dp" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
+
static struct platform_driver exynos_dp_driver = {
.probe = exynos_dp_probe,
.remove = __devexit_p(exynos_dp_remove),
@@ -1020,6 +1195,7 @@ static struct platform_driver exynos_dp_driver = {
.name = "exynos-dp",
.owner = THIS_MODULE,
.pm = &exynos_dp_pm_ops,
+ .of_match_table = of_match_ptr(exynos_dp_match),
},
};
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 57b8a65..6dbeeb2 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -29,6 +29,8 @@ struct exynos_dp_device {
struct clk *clock;
unsigned int irq;
void __iomem *reg_base;
+ void __iomem *phy_addr;
+ unsigned int enable_mask;
struct video_info *video_info;
struct link_train link_train;
--
1.7.1
^ permalink raw reply related
* Re: [PATCH V5 1/2] video: exynos_dp: Add device tree support to DP driver
From: Jingoo Han @ 2012-10-16 2:02 UTC (permalink / raw)
To: 'Sylwester Nawrocki'
Cc: 'Florian Tobias Schandinat', 'Ajay Kumar',
linux-samsung-soc, linux-fbdev, devicetree-discuss,
'Tomasz Figa', 'Thomas Abraham',
'Jingoo Han'
In-Reply-To: <507C7C9E.1030503@gmail.com>
On Tuesday, October 16, 2012 6:14 AM Sylwester Nawrocki wrote
>
> On 10/15/2012 10:14 AM, Jingoo Han wrote:
> > On Saturday, October 13, 2012 6:44 AM Sylwester Nawrocki wrote
> >>
> >> On 10/12/2012 10:47 PM, Ajay Kumar wrote:
> >>> This patch enables device tree based discovery support for DP driver.
> >>> The driver is modified to handle platform data in both the cases:
> >>> with DT and non-DT.
> >>>
> >>> Signed-off-by: Ajay Kumar<ajaykumar.rs@samsung.com>
> >>> Acked-by: Jingoo Han<jg1.han@samsung.com>
> >>> ---
> >>> drivers/video/exynos/exynos_dp_core.c | 161 ++++++++++++++++++++++++++++++---
> >>> drivers/video/exynos/exynos_dp_core.h | 2 +
> >>> 2 files changed, 149 insertions(+), 14 deletions(-)
> ...
> >>> @@ -953,8 +1062,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
> >>> struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> >>> struct exynos_dp_device *dp = platform_get_drvdata(pdev);
> >>
> >> This doesn't belong to your patch, but the above 2 lines could be written as:
> >>
> >> struct exynos_dp_device *dp = dev_get_drvdata(&pdev->dev);
> >>
> >> Same in functions exynos_dp_suspend() and exynos_dp_resume().
> >
> > No, above 2 lines cannot be reduced to 1 line, as you mentioned.
> > This is because it makes build error.
>
> Sorry, my bad. It looks fine in case of exynos_dp_remove().
>
> But at exynos_dp_suspend/resume() there is something like:
>
>
> static int exynos_dp_suspend(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>
>
> You need only pdata and dp there. I think that simpler form would
> do as well:
>
> struct exynos_dp_device *dp = dev_get_drvdata(dev);
> struct exynos_dp_platdata *pdata = dev->platform_data;
OK, I see.
I will accept your suggestion, because it is helpful to reduce
lines. Then, I will send v8 patch, soon.
>
>
> Sorry, this is just a nitpicking.
>
> BTW, shouldn't CONFIG_EXYNOS_VIDEO depend on ARCH_EXYNOS ?
>
>
> --
> Regards,
> Sylwester
> --
> 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 1/2] video: exynos_dp: Add device tree support to DP driver
From: Sylwester Nawrocki @ 2012-10-15 21:14 UTC (permalink / raw)
To: Jingoo Han
Cc: 'Ajay Kumar', linux-samsung-soc, linux-fbdev,
devicetree-discuss, FlorianSchandinat, tomasz.figa, thomas.ab
In-Reply-To: <009d01cdaaad$0fa33230$2ee99690$%han@samsung.com>
On 10/15/2012 10:14 AM, Jingoo Han wrote:
> On Saturday, October 13, 2012 6:44 AM Sylwester Nawrocki wrote
>>
>> On 10/12/2012 10:47 PM, Ajay Kumar wrote:
>>> This patch enables device tree based discovery support for DP driver.
>>> The driver is modified to handle platform data in both the cases:
>>> with DT and non-DT.
>>>
>>> Signed-off-by: Ajay Kumar<ajaykumar.rs@samsung.com>
>>> Acked-by: Jingoo Han<jg1.han@samsung.com>
>>> ---
>>> drivers/video/exynos/exynos_dp_core.c | 161 ++++++++++++++++++++++++++++++---
>>> drivers/video/exynos/exynos_dp_core.h | 2 +
>>> 2 files changed, 149 insertions(+), 14 deletions(-)
...
>>> @@ -953,8 +1062,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
>>> struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
>>> struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>>
>> This doesn't belong to your patch, but the above 2 lines could be written as:
>>
>> struct exynos_dp_device *dp = dev_get_drvdata(&pdev->dev);
>>
>> Same in functions exynos_dp_suspend() and exynos_dp_resume().
>
> No, above 2 lines cannot be reduced to 1 line, as you mentioned.
> This is because it makes build error.
Sorry, my bad. It looks fine in case of exynos_dp_remove().
But at exynos_dp_suspend/resume() there is something like:
static int exynos_dp_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
You need only pdata and dp there. I think that simpler form would
do as well:
struct exynos_dp_device *dp = dev_get_drvdata(dev);
struct exynos_dp_platdata *pdata = dev->platform_data;
Sorry, this is just a nitpicking.
BTW, shouldn't CONFIG_EXYNOS_VIDEO depend on ARCH_EXYNOS ?
--
Regards,
Sylwester
^ permalink raw reply
* Re: [PATCH 0/2 v6] of: add display helper
From: Steffen Trumtrar @ 2012-10-15 14:17 UTC (permalink / raw)
To: Leela Krishna Amudala
Cc: linux-fbdev, devicetree-discuss, dri-devel, Tomi Valkeinen,
Laurent Pinchart, linux-media
In-Reply-To: <CAL1wa8fP8LBCUBVJS1=dy3cyFe+bY-Gu2+wtJyuCrgbP93m3Wg@mail.gmail.com>
Hi Leela,
On Mon, Oct 15, 2012 at 04:24:43PM +0530, Leela Krishna Amudala wrote:
> Hello Steffen,
>
> To which version of the kernel we can expect this patch set to be merged into?
> Because I'm waiting for this from long time to add DT support for my
> display controller :)
>
I have no idea, sorry. It seems like we have almost settled with the binding
(clock-name needs to be changed), but I'm not responsible for any merging/inclusions
in the kernel.
Regards,
Steffen
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH 0/2 v6] of: add display helper
From: Leela Krishna Amudala @ 2012-10-15 10:55 UTC (permalink / raw)
To: Steffen Trumtrar
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Tomi Valkeinen,
Laurent Pinchart, linux-media-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1349373560-11128-1-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Hello Steffen,
To which version of the kernel we can expect this patch set to be merged into?
Because I'm waiting for this from long time to add DT support for my
display controller :)
Best Wishes,
Leela Krishna Amudala.
On Thu, Oct 4, 2012 at 11:29 PM, Steffen Trumtrar
<s.trumtrar@pengutronix.de> wrote:
>
> Hi!
>
> In accordance with Stepehn Warren, I downsized the binding.
> Now, just the display-timing is described, as I think, it is way easier to
> agree
> on those and have a complete binding.
>
> Regards,
> Steffen
>
> Steffen Trumtrar (2):
> of: add helper to parse display timings
> of: add generic videomode description
>
> .../devicetree/bindings/video/display-timings.txt | 222
> ++++++++++++++++++++
> drivers/of/Kconfig | 10 +
> drivers/of/Makefile | 2 +
> drivers/of/of_display_timings.c | 183
> ++++++++++++++++
> drivers/of/of_videomode.c | 212
> +++++++++++++++++++
> include/linux/of_display_timings.h | 85 ++++++++
> include/linux/of_videomode.h | 41 ++++
> 7 files changed, 755 insertions(+)
> create mode 100644
> Documentation/devicetree/bindings/video/display-timings.txt
> create mode 100644 drivers/of/of_display_timings.c
> create mode 100644 drivers/of/of_videomode.c
> create mode 100644 include/linux/of_display_timings.h
> create mode 100644 include/linux/of_videomode.h
>
> --
> 1.7.10.4
>
> --
> 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
* [PATCH V7 2/2] video: exynos_dp: device tree documentation
From: Jingoo Han @ 2012-10-15 9:57 UTC (permalink / raw)
To: 'Florian Tobias Schandinat'
Cc: linux-fbdev, linux-samsung-soc, devicetree-discuss,
'Ajay Kumar', 'Sylwester Nawrocki',
'Tomasz Figa', 'Thomas Abraham',
'Jingoo Han'
In-Reply-To: <00a201cdaabb$5f6eb6f0$1e4c24d0$%han@samsung.com>
From: Ajay Kumar <ajaykumar.rs@samsung.com>
Add documentation for the DT bindings in exynos display port driver.
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
No changes since v6:
.../devicetree/bindings/video/exynos_dp.txt | 80 ++++++++++++++++++++
1 files changed, 80 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/video/exynos_dp.txt
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
new file mode 100644
index 0000000..7cc7d9f
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -0,0 +1,80 @@
+The Exynos display port interface should be configured based on
+the type of panel connected to it.
+
+We use two nodes:
+ -display-port-controller node
+ -dptx-phy node(defined inside display-port-controller node)
+
+For the DP-PHY initialization, we use the dptx-phy node.
+Required properties for dptx-phy:
+ -reg:
+ Base address of DP PHY register.
+ -samsung,enable-mask:
+ The bit-mask used to enable/disable DP PHY.
+
+For the Panel initialization, we read data from display-port-controller node.
+Required properties for display-port-controller:
+ -compatible:
+ should be "samsung,exynos5-dp".
+ -reg:
+ physical base address of the controller and length
+ of memory mapped region.
+ -interrupts:
+ interrupt combiner values.
+ -interrupt-parent:
+ phandle to Interrupt combiner node.
+ -samsung,color-space:
+ input video data format.
+ COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
+ -samsung,dynamic-range:
+ dynamic range for input video data.
+ VESA = 0, CEA = 1
+ -samsung,ycbcr-coeff:
+ YCbCr co-efficients for input video.
+ COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
+ -samsung,color-depth:
+ number of bits per colour component.
+ COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
+ -samsung,link-rate:
+ link rate supported by the panel.
+ LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
+ -samsung,lane-count:
+ number of lanes supported by the panel.
+ LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
+
+Optional properties for display-port-controller:
+ -interlaced:
+ interlace scan mode.
+ Progressive if defined, Interlaced if not defined
+ -vsync-active-high:
+ VSYNC polarity configuration.
+ High if defined, Low if not defined
+ -hsync-active-high:
+ HSYNC polarity configuration.
+ High if defined, Low if not defined
+
+Example:
+
+SOC specific portion:
+ display-port-controller {
+ compatible = "samsung,exynos5-dp";
+ reg = <0x145b0000 0x10000>;
+ interrupts = <10 3>;
+ interrupt-parent = <&combiner>;
+
+ dptx-phy {
+ reg = <0x10040720>;
+ samsung,enable-mask = <1>;
+ };
+
+ };
+
+Board Specific portion:
+ display-port-controller {
+ samsung,color-space = <0>;
+ samsung,dynamic-range = <0>;
+ samsung,ycbcr-coeff = <0>;
+ samsung,color-depth = <1>;
+ samsung,link-rate = <0x0a>;
+ samsung,lane-count = <4>;
+ };
--
1.7.1
^ permalink raw reply related
* [PATCH V7 1/2] video: exynos_dp: Add device tree support to DP driver
From: Jingoo Han @ 2012-10-15 9:56 UTC (permalink / raw)
To: 'Florian Tobias Schandinat'
Cc: linux-fbdev, linux-samsung-soc, devicetree-discuss,
'Ajay Kumar', 'Sylwester Nawrocki',
'Tomasz Figa', 'Thomas Abraham',
'Jingoo Han'
From: Ajay Kumar <ajaykumar.rs@samsung.com>
This patch enables device tree based discovery support for DP driver.
The driver is modified to handle platform data in both the cases:
with DT and non-DT.
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
This patch is tested with Exynos5250.
Changes since v6:
- Fix return check for exynos_dp_dt_parse_phydata() in exynos_dp_probe()
drivers/video/exynos/exynos_dp_core.c | 206 ++++++++++++++++++++++++++++++---
drivers/video/exynos/exynos_dp_core.h | 2 +
2 files changed, 194 insertions(+), 14 deletions(-)
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e..0d9c0ee 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/of.h>
#include <video/exynos_dp.h>
@@ -856,6 +857,145 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
return IRQ_HANDLED;
}
+#ifdef CONFIG_OF
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+ struct device_node *dp_node = dev->of_node;
+ struct exynos_dp_platdata *pd;
+ struct video_info *dp_video_config;
+
+ pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ dev_err(dev, "memory allocation for pdata failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ dp_video_config = devm_kzalloc(dev,
+ sizeof(*dp_video_config), GFP_KERNEL);
+
+ if (!dp_video_config) {
+ dev_err(dev, "memory allocation for video config failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ pd->video_info = dp_video_config;
+
+ dp_video_config->h_sync_polarity + of_property_read_bool(dp_node, "hsync-active-high");
+
+ dp_video_config->v_sync_polarity + of_property_read_bool(dp_node, "vsync-active-high");
+
+ dp_video_config->interlaced + of_property_read_bool(dp_node, "interlaced");
+
+ if (of_property_read_u32(dp_node, "samsung,color-space",
+ &dp_video_config->color_space)) {
+ dev_err(dev, "failed to get color-space\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,dynamic-range",
+ &dp_video_config->dynamic_range)) {
+ dev_err(dev, "failed to get dynamic-range\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
+ &dp_video_config->ycbcr_coeff)) {
+ dev_err(dev, "failed to get ycbcr-coeff\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,color-depth",
+ &dp_video_config->color_depth)) {
+ dev_err(dev, "failed to get color-depth\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,link-rate",
+ &dp_video_config->link_rate)) {
+ dev_err(dev, "failed to get link-rate\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,lane-count",
+ &dp_video_config->lane_count)) {
+ dev_err(dev, "failed to get lane-count\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ return pd;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+ struct device_node *dp_phy_node;
+ u32 phy_base;
+
+ dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
+ if (!dp_phy_node) {
+ dev_err(dp->dev, "could not find dptx-phy node\n");
+ return -ENODEV;
+ }
+
+ if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
+ dev_err(dp->dev, "faild to get reg for dptx-phy\n");
+ return -EINVAL;
+ }
+
+ if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
+ &dp->enable_mask)) {
+ dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n");
+ return -EINVAL;
+ }
+
+ dp->phy_addr = ioremap(phy_base, SZ_4);
+ if (!dp->phy_addr) {
+ dev_err(dp->dev, "failed to ioremap dp-phy\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->phy_addr);
+ reg |= dp->enable_mask;
+ __raw_writel(reg, dp->phy_addr);
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->phy_addr);
+ reg &= ~(dp->enable_mask);
+ __raw_writel(reg, dp->phy_addr);
+}
+#else
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+ return NULL;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+ return -EINVAL;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+ return;
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+ return;
+}
+#endif /* CONFIG_OF */
+
static int __devinit exynos_dp_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -864,12 +1004,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
int ret = 0;
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
GFP_KERNEL);
if (!dp) {
@@ -879,6 +1013,22 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
dp->dev = &pdev->dev;
+ if (pdev->dev.of_node) {
+ pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+
+ ret = exynos_dp_dt_parse_phydata(dp);
+ if (ret)
+ return ret;
+ } else {
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data\n");
+ return -EINVAL;
+ }
+ }
+
dp->clock = devm_clk_get(&pdev->dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(&pdev->dev, "failed to get clock\n");
@@ -909,8 +1059,14 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
}
dp->video_info = pdata->video_info;
- if (pdata->phy_init)
- pdata->phy_init();
+
+ if (pdev->dev.of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_init(dp);
+ } else {
+ if (pdata->phy_init)
+ pdata->phy_init();
+ }
exynos_dp_init_dp(dp);
@@ -953,8 +1109,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_exit)
- pdata->phy_exit();
+ if (pdev->dev.of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_exit(dp);
+ } else {
+ if (pdata->phy_exit)
+ pdata->phy_exit();
+ }
clk_disable_unprepare(dp->clock);
@@ -968,8 +1129,13 @@ static int exynos_dp_suspend(struct device *dev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_exit)
- pdata->phy_exit();
+ if (dev->of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_exit(dp);
+ } else {
+ if (pdata->phy_exit)
+ pdata->phy_exit();
+ }
clk_disable_unprepare(dp->clock);
@@ -982,8 +1148,13 @@ static int exynos_dp_resume(struct device *dev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_init)
- pdata->phy_init();
+ if (dev->of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_init(dp);
+ } else {
+ if (pdata->phy_init)
+ pdata->phy_init();
+ }
clk_prepare_enable(dp->clock);
@@ -1013,6 +1184,12 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
};
+static const struct of_device_id exynos_dp_match[] = {
+ { .compatible = "samsung,exynos5-dp" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
+
static struct platform_driver exynos_dp_driver = {
.probe = exynos_dp_probe,
.remove = __devexit_p(exynos_dp_remove),
@@ -1020,6 +1197,7 @@ static struct platform_driver exynos_dp_driver = {
.name = "exynos-dp",
.owner = THIS_MODULE,
.pm = &exynos_dp_pm_ops,
+ .of_match_table = of_match_ptr(exynos_dp_match),
},
};
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 57b8a65..6dbeeb2 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -29,6 +29,8 @@ struct exynos_dp_device {
struct clk *clock;
unsigned int irq;
void __iomem *reg_base;
+ void __iomem *phy_addr;
+ unsigned int enable_mask;
struct video_info *video_info;
struct link_train link_train;
--
1.7.1
^ permalink raw reply related
* RE: [PATCH V6 1/2] video: exynos_dp: Add device tree support to DP driver
From: Jingoo Han @ 2012-10-15 9:44 UTC (permalink / raw)
To: 'Florian Tobias Schandinat'
Cc: linux-fbdev, linux-samsung-soc, devicetree-discuss,
'Ajay Kumar', 'Sylwester Nawrocki',
'Tomasz Figa', 'Thomas Abraham',
'Jingoo Han'
In-Reply-To: <009e01cdaab5$25cff2c0$716fd840$%han@samsung.com>
On Monday, October 15, 2012 6:12 PM Jingoo Han wrote
>
> From: Ajay Kumar <ajaykumar.rs@samsung.com>
>
> This patch enables device tree based discovery support for DP driver.
> The driver is modified to handle platform data in both the cases:
> with DT and non-DT.
>
> Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> ---
> This patch is tested with Exynos5250.
>
> Changes since v6:
> - Check return values of required properties
> - Replace dp_phy_addr with phy_addr
> - Remove unnecessary NULL deference checking for 'pdata'
> - Remove unncessary 'virt_phy_base' variable
> - Make functions static
> - Fix build errors when CONFIG_OF option is diabled
> - Add return values to exynos_dp_dt_parse_phydata()
>
> drivers/video/exynos/exynos_dp_core.c | 206 ++++++++++++++++++++++++++++++---
> drivers/video/exynos/exynos_dp_core.h | 2 +
> 2 files changed, 194 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
> index d55470e..0d9c0ee 100644
> --- a/drivers/video/exynos/exynos_dp_core.c
> +++ b/drivers/video/exynos/exynos_dp_core.c
> @@ -18,6 +18,7 @@
> #include <linux/io.h>
> #include <linux/interrupt.h>
> #include <linux/delay.h>
> +#include <linux/of.h>
>
> #include <video/exynos_dp.h>
>
> @@ -856,6 +857,145 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
> return IRQ_HANDLED;
> }
>
> +#ifdef CONFIG_OF
> +static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
> +{
> + struct device_node *dp_node = dev->of_node;
> + struct exynos_dp_platdata *pd;
> + struct video_info *dp_video_config;
> +
> + pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
> + if (!pd) {
> + dev_err(dev, "memory allocation for pdata failed\n");
> + return ERR_PTR(-ENOMEM);
> + }
> + dp_video_config = devm_kzalloc(dev,
> + sizeof(*dp_video_config), GFP_KERNEL);
> +
> + if (!dp_video_config) {
> + dev_err(dev, "memory allocation for video config failed\n");
> + return ERR_PTR(-ENOMEM);
> + }
> + pd->video_info = dp_video_config;
> +
> + dp_video_config->h_sync_polarity > + of_property_read_bool(dp_node, "hsync-active-high");
> +
> + dp_video_config->v_sync_polarity > + of_property_read_bool(dp_node, "vsync-active-high");
> +
> + dp_video_config->interlaced > + of_property_read_bool(dp_node, "interlaced");
> +
> + if (of_property_read_u32(dp_node, "samsung,color-space",
> + &dp_video_config->color_space)) {
> + dev_err(dev, "failed to get color-space\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (of_property_read_u32(dp_node, "samsung,dynamic-range",
> + &dp_video_config->dynamic_range)) {
> + dev_err(dev, "failed to get dynamic-range\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
> + &dp_video_config->ycbcr_coeff)) {
> + dev_err(dev, "failed to get ycbcr-coeff\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (of_property_read_u32(dp_node, "samsung,color-depth",
> + &dp_video_config->color_depth)) {
> + dev_err(dev, "failed to get color-depth\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (of_property_read_u32(dp_node, "samsung,link-rate",
> + &dp_video_config->link_rate)) {
> + dev_err(dev, "failed to get link-rate\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (of_property_read_u32(dp_node, "samsung,lane-count",
> + &dp_video_config->lane_count)) {
> + dev_err(dev, "failed to get lane-count\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + return pd;
> +}
> +
> +static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
> +{
> + struct device_node *dp_phy_node;
> + u32 phy_base;
> +
> + dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
> + if (!dp_phy_node) {
> + dev_err(dp->dev, "could not find dptx-phy node\n");
> + return -ENODEV;
> + }
> +
> + if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
> + dev_err(dp->dev, "faild to get reg for dptx-phy\n");
> + return -EINVAL;
> + }
> +
> + if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
> + &dp->enable_mask)) {
> + dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n");
> + return -EINVAL;
> + }
> +
> + dp->phy_addr = ioremap(phy_base, SZ_4);
> + if (!dp->phy_addr) {
> + dev_err(dp->dev, "failed to ioremap dp-phy\n");
> + return -ENOMEM;
> + }
> +
> + return 0;
> +}
> +
> +static void exynos_dp_phy_init(struct exynos_dp_device *dp)
> +{
> + u32 reg;
> +
> + reg = __raw_readl(dp->phy_addr);
> + reg |= dp->enable_mask;
> + __raw_writel(reg, dp->phy_addr);
> +}
> +
> +static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
> +{
> + u32 reg;
> +
> + reg = __raw_readl(dp->phy_addr);
> + reg &= ~(dp->enable_mask);
> + __raw_writel(reg, dp->phy_addr);
> +}
> +#else
> +static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
> +{
> + return NULL;
> +}
> +
> +static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
> +{
> + return -EINVAL;
> +}
> +
> +static void exynos_dp_phy_init(struct exynos_dp_device *dp)
> +{
> + return;
> +}
> +
> +static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
> +{
> + return;
> +}
> +#endif /* CONFIG_OF */
> +
> static int __devinit exynos_dp_probe(struct platform_device *pdev)
> {
> struct resource *res;
> @@ -864,12 +1004,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
>
> int ret = 0;
>
> - pdata = pdev->dev.platform_data;
> - if (!pdata) {
> - dev_err(&pdev->dev, "no platform data\n");
> - return -EINVAL;
> - }
> -
> dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
> GFP_KERNEL);
> if (!dp) {
> @@ -879,6 +1013,22 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
>
> dp->dev = &pdev->dev;
>
> + if (pdev->dev.of_node) {
> + pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
> + if (IS_ERR(pdata))
> + return PTR_ERR(pdata);
> +
> + ret = exynos_dp_dt_parse_phydata(dp);
> + if (!ret)
It should be 'if (ret)' instead of 'if (!ret)'.
It is my fault. I will send v7 patch, soon.
Sorry.
> + return ret;
> + } else {
> + pdata = pdev->dev.platform_data;
> + if (!pdata) {
> + dev_err(&pdev->dev, "no platform data\n");
> + return -EINVAL;
> + }
> + }
> +
> dp->clock = devm_clk_get(&pdev->dev, "dp");
> if (IS_ERR(dp->clock)) {
> dev_err(&pdev->dev, "failed to get clock\n");
> @@ -909,8 +1059,14 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
> }
>
> dp->video_info = pdata->video_info;
> - if (pdata->phy_init)
> - pdata->phy_init();
> +
> + if (pdev->dev.of_node) {
> + if (dp->phy_addr)
> + exynos_dp_phy_init(dp);
> + } else {
> + if (pdata->phy_init)
> + pdata->phy_init();
> + }
>
> exynos_dp_init_dp(dp);
>
> @@ -953,8 +1109,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
> struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>
> - if (pdata && pdata->phy_exit)
> - pdata->phy_exit();
> + if (pdev->dev.of_node) {
> + if (dp->phy_addr)
> + exynos_dp_phy_exit(dp);
> + } else {
> + if (pdata->phy_exit)
> + pdata->phy_exit();
> + }
>
> clk_disable_unprepare(dp->clock);
>
> @@ -968,8 +1129,13 @@ static int exynos_dp_suspend(struct device *dev)
> struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>
> - if (pdata && pdata->phy_exit)
> - pdata->phy_exit();
> + if (dev->of_node) {
> + if (dp->phy_addr)
> + exynos_dp_phy_exit(dp);
> + } else {
> + if (pdata->phy_exit)
> + pdata->phy_exit();
> + }
>
> clk_disable_unprepare(dp->clock);
>
> @@ -982,8 +1148,13 @@ static int exynos_dp_resume(struct device *dev)
> struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>
> - if (pdata && pdata->phy_init)
> - pdata->phy_init();
> + if (dev->of_node) {
> + if (dp->phy_addr)
> + exynos_dp_phy_init(dp);
> + } else {
> + if (pdata->phy_init)
> + pdata->phy_init();
> + }
>
> clk_prepare_enable(dp->clock);
>
> @@ -1013,6 +1184,12 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
> SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
> };
>
> +static const struct of_device_id exynos_dp_match[] = {
> + { .compatible = "samsung,exynos5-dp" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, exynos_dp_match);
> +
> static struct platform_driver exynos_dp_driver = {
> .probe = exynos_dp_probe,
> .remove = __devexit_p(exynos_dp_remove),
> @@ -1020,6 +1197,7 @@ static struct platform_driver exynos_dp_driver = {
> .name = "exynos-dp",
> .owner = THIS_MODULE,
> .pm = &exynos_dp_pm_ops,
> + .of_match_table = of_match_ptr(exynos_dp_match),
> },
> };
>
> diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
> index 57b8a65..6dbeeb2 100644
> --- a/drivers/video/exynos/exynos_dp_core.h
> +++ b/drivers/video/exynos/exynos_dp_core.h
> @@ -29,6 +29,8 @@ struct exynos_dp_device {
> struct clk *clock;
> unsigned int irq;
> void __iomem *reg_base;
> + void __iomem *phy_addr;
> + unsigned int enable_mask;
>
> struct video_info *video_info;
> struct link_train link_train;
> --
> 1.7.1
^ permalink raw reply
* [PATCH V6 2/2] video: exynos_dp: device tree documentation
From: Jingoo Han @ 2012-10-15 9:13 UTC (permalink / raw)
To: 'Florian Tobias Schandinat'
Cc: linux-fbdev, linux-samsung-soc, devicetree-discuss,
'Ajay Kumar', 'Sylwester Nawrocki',
'Tomasz Figa', 'Thomas Abraham',
'Jingoo Han'
In-Reply-To: <009e01cdaab5$25cff2c0$716fd840$%han@samsung.com>
From: Ajay Kumar <ajaykumar.rs@samsung.com>
Add documentation for the DT bindings in exynos display port driver.
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
Changes since v6:
- Remove duplicated 'based on'
.../devicetree/bindings/video/exynos_dp.txt | 80 ++++++++++++++++++++
1 files changed, 80 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/video/exynos_dp.txt
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
new file mode 100644
index 0000000..7cc7d9f
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -0,0 +1,80 @@
+The Exynos display port interface should be configured based on
+the type of panel connected to it.
+
+We use two nodes:
+ -display-port-controller node
+ -dptx-phy node(defined inside display-port-controller node)
+
+For the DP-PHY initialization, we use the dptx-phy node.
+Required properties for dptx-phy:
+ -reg:
+ Base address of DP PHY register.
+ -samsung,enable-mask:
+ The bit-mask used to enable/disable DP PHY.
+
+For the Panel initialization, we read data from display-port-controller node.
+Required properties for display-port-controller:
+ -compatible:
+ should be "samsung,exynos5-dp".
+ -reg:
+ physical base address of the controller and length
+ of memory mapped region.
+ -interrupts:
+ interrupt combiner values.
+ -interrupt-parent:
+ phandle to Interrupt combiner node.
+ -samsung,color-space:
+ input video data format.
+ COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
+ -samsung,dynamic-range:
+ dynamic range for input video data.
+ VESA = 0, CEA = 1
+ -samsung,ycbcr-coeff:
+ YCbCr co-efficients for input video.
+ COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
+ -samsung,color-depth:
+ number of bits per colour component.
+ COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
+ -samsung,link-rate:
+ link rate supported by the panel.
+ LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
+ -samsung,lane-count:
+ number of lanes supported by the panel.
+ LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
+
+Optional properties for display-port-controller:
+ -interlaced:
+ interlace scan mode.
+ Progressive if defined, Interlaced if not defined
+ -vsync-active-high:
+ VSYNC polarity configuration.
+ High if defined, Low if not defined
+ -hsync-active-high:
+ HSYNC polarity configuration.
+ High if defined, Low if not defined
+
+Example:
+
+SOC specific portion:
+ display-port-controller {
+ compatible = "samsung,exynos5-dp";
+ reg = <0x145b0000 0x10000>;
+ interrupts = <10 3>;
+ interrupt-parent = <&combiner>;
+
+ dptx-phy {
+ reg = <0x10040720>;
+ samsung,enable-mask = <1>;
+ };
+
+ };
+
+Board Specific portion:
+ display-port-controller {
+ samsung,color-space = <0>;
+ samsung,dynamic-range = <0>;
+ samsung,ycbcr-coeff = <0>;
+ samsung,color-depth = <1>;
+ samsung,link-rate = <0x0a>;
+ samsung,lane-count = <4>;
+ };
--
1.7.1
^ permalink raw reply related
* [PATCH V6 1/2] video: exynos_dp: Add device tree support to DP driver
From: Jingoo Han @ 2012-10-15 9:12 UTC (permalink / raw)
To: 'Florian Tobias Schandinat'
Cc: linux-fbdev, linux-samsung-soc, devicetree-discuss,
'Ajay Kumar', 'Sylwester Nawrocki',
'Tomasz Figa', 'Thomas Abraham',
'Jingoo Han'
From: Ajay Kumar <ajaykumar.rs@samsung.com>
This patch enables device tree based discovery support for DP driver.
The driver is modified to handle platform data in both the cases:
with DT and non-DT.
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
This patch is tested with Exynos5250.
Changes since v6:
- Check return values of required properties
- Replace dp_phy_addr with phy_addr
- Remove unnecessary NULL deference checking for 'pdata'
- Remove unncessary 'virt_phy_base' variable
- Make functions static
- Fix build errors when CONFIG_OF option is diabled
- Add return values to exynos_dp_dt_parse_phydata()
drivers/video/exynos/exynos_dp_core.c | 206 ++++++++++++++++++++++++++++++---
drivers/video/exynos/exynos_dp_core.h | 2 +
2 files changed, 194 insertions(+), 14 deletions(-)
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e..0d9c0ee 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/of.h>
#include <video/exynos_dp.h>
@@ -856,6 +857,145 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
return IRQ_HANDLED;
}
+#ifdef CONFIG_OF
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+ struct device_node *dp_node = dev->of_node;
+ struct exynos_dp_platdata *pd;
+ struct video_info *dp_video_config;
+
+ pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ dev_err(dev, "memory allocation for pdata failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ dp_video_config = devm_kzalloc(dev,
+ sizeof(*dp_video_config), GFP_KERNEL);
+
+ if (!dp_video_config) {
+ dev_err(dev, "memory allocation for video config failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ pd->video_info = dp_video_config;
+
+ dp_video_config->h_sync_polarity + of_property_read_bool(dp_node, "hsync-active-high");
+
+ dp_video_config->v_sync_polarity + of_property_read_bool(dp_node, "vsync-active-high");
+
+ dp_video_config->interlaced + of_property_read_bool(dp_node, "interlaced");
+
+ if (of_property_read_u32(dp_node, "samsung,color-space",
+ &dp_video_config->color_space)) {
+ dev_err(dev, "failed to get color-space\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,dynamic-range",
+ &dp_video_config->dynamic_range)) {
+ dev_err(dev, "failed to get dynamic-range\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
+ &dp_video_config->ycbcr_coeff)) {
+ dev_err(dev, "failed to get ycbcr-coeff\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,color-depth",
+ &dp_video_config->color_depth)) {
+ dev_err(dev, "failed to get color-depth\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,link-rate",
+ &dp_video_config->link_rate)) {
+ dev_err(dev, "failed to get link-rate\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_property_read_u32(dp_node, "samsung,lane-count",
+ &dp_video_config->lane_count)) {
+ dev_err(dev, "failed to get lane-count\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ return pd;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+ struct device_node *dp_phy_node;
+ u32 phy_base;
+
+ dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
+ if (!dp_phy_node) {
+ dev_err(dp->dev, "could not find dptx-phy node\n");
+ return -ENODEV;
+ }
+
+ if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
+ dev_err(dp->dev, "faild to get reg for dptx-phy\n");
+ return -EINVAL;
+ }
+
+ if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
+ &dp->enable_mask)) {
+ dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n");
+ return -EINVAL;
+ }
+
+ dp->phy_addr = ioremap(phy_base, SZ_4);
+ if (!dp->phy_addr) {
+ dev_err(dp->dev, "failed to ioremap dp-phy\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->phy_addr);
+ reg |= dp->enable_mask;
+ __raw_writel(reg, dp->phy_addr);
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->phy_addr);
+ reg &= ~(dp->enable_mask);
+ __raw_writel(reg, dp->phy_addr);
+}
+#else
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+ return NULL;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+ return -EINVAL;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+ return;
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+ return;
+}
+#endif /* CONFIG_OF */
+
static int __devinit exynos_dp_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -864,12 +1004,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
int ret = 0;
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
GFP_KERNEL);
if (!dp) {
@@ -879,6 +1013,22 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
dp->dev = &pdev->dev;
+ if (pdev->dev.of_node) {
+ pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+
+ ret = exynos_dp_dt_parse_phydata(dp);
+ if (!ret)
+ return ret;
+ } else {
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data\n");
+ return -EINVAL;
+ }
+ }
+
dp->clock = devm_clk_get(&pdev->dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(&pdev->dev, "failed to get clock\n");
@@ -909,8 +1059,14 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
}
dp->video_info = pdata->video_info;
- if (pdata->phy_init)
- pdata->phy_init();
+
+ if (pdev->dev.of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_init(dp);
+ } else {
+ if (pdata->phy_init)
+ pdata->phy_init();
+ }
exynos_dp_init_dp(dp);
@@ -953,8 +1109,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_exit)
- pdata->phy_exit();
+ if (pdev->dev.of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_exit(dp);
+ } else {
+ if (pdata->phy_exit)
+ pdata->phy_exit();
+ }
clk_disable_unprepare(dp->clock);
@@ -968,8 +1129,13 @@ static int exynos_dp_suspend(struct device *dev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_exit)
- pdata->phy_exit();
+ if (dev->of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_exit(dp);
+ } else {
+ if (pdata->phy_exit)
+ pdata->phy_exit();
+ }
clk_disable_unprepare(dp->clock);
@@ -982,8 +1148,13 @@ static int exynos_dp_resume(struct device *dev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_init)
- pdata->phy_init();
+ if (dev->of_node) {
+ if (dp->phy_addr)
+ exynos_dp_phy_init(dp);
+ } else {
+ if (pdata->phy_init)
+ pdata->phy_init();
+ }
clk_prepare_enable(dp->clock);
@@ -1013,6 +1184,12 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
};
+static const struct of_device_id exynos_dp_match[] = {
+ { .compatible = "samsung,exynos5-dp" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
+
static struct platform_driver exynos_dp_driver = {
.probe = exynos_dp_probe,
.remove = __devexit_p(exynos_dp_remove),
@@ -1020,6 +1197,7 @@ static struct platform_driver exynos_dp_driver = {
.name = "exynos-dp",
.owner = THIS_MODULE,
.pm = &exynos_dp_pm_ops,
+ .of_match_table = of_match_ptr(exynos_dp_match),
},
};
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 57b8a65..6dbeeb2 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -29,6 +29,8 @@ struct exynos_dp_device {
struct clk *clock;
unsigned int irq;
void __iomem *reg_base;
+ void __iomem *phy_addr;
+ unsigned int enable_mask;
struct video_info *video_info;
struct link_train link_train;
--
1.7.1
^ permalink raw reply related
* Re: [PATCH V5 1/2] video: exynos_dp: Add device tree support to DP driver
From: Jingoo Han @ 2012-10-15 8:14 UTC (permalink / raw)
To: 'Sylwester Nawrocki', 'Ajay Kumar'
Cc: linux-samsung-soc, linux-fbdev, devicetree-discuss,
FlorianSchandinat, tomasz.figa, thomas.ab, 'Jingoo Han'
In-Reply-To: <50788F25.2040003@gmail.com>
On Saturday, October 13, 2012 6:44 AM Sylwester Nawrocki wrote
>
> On 10/12/2012 10:47 PM, Ajay Kumar wrote:
> > This patch enables device tree based discovery support for DP driver.
> > The driver is modified to handle platform data in both the cases:
> > with DT and non-DT.
> >
> > Signed-off-by: Ajay Kumar<ajaykumar.rs@samsung.com>
> > Acked-by: Jingoo Han<jg1.han@samsung.com>
> > ---
> > drivers/video/exynos/exynos_dp_core.c | 161 ++++++++++++++++++++++++++++++---
> > drivers/video/exynos/exynos_dp_core.h | 2 +
> > 2 files changed, 149 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
> > index d55470e..62932ba 100644
> > --- a/drivers/video/exynos/exynos_dp_core.c
> > +++ b/drivers/video/exynos/exynos_dp_core.c
> > @@ -18,6 +18,7 @@
> > #include<linux/io.h>
> > #include<linux/interrupt.h>
> > #include<linux/delay.h>
> > +#include<linux/of.h>
> >
> > #include<video/exynos_dp.h>
> >
> > @@ -856,6 +857,99 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
> > return IRQ_HANDLED;
> > }
> >
> > +#ifdef CONFIG_OF
> > +struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
> > +{
> > + struct device_node *dp_node = dev->of_node;
> > + struct exynos_dp_platdata *pd;
> > + struct video_info *dp_video_config;
> > +
> > + pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
> > + if (!pd) {
> > + dev_err(dev, "memory allocation for pdata failed\n");
> > + return ERR_PTR(-ENOMEM);
> > + }
> > + dp_video_config = devm_kzalloc(dev,
> > + sizeof(*dp_video_config), GFP_KERNEL);
> > +
> > + if (!dp_video_config) {
> > + dev_err(dev, "memory allocation for video config failed\n");
> > + return ERR_PTR(-ENOMEM);
> > + }
> > + pd->video_info = dp_video_config;
> > +
> > + if (of_get_property(dp_node, "hsync-active-high", NULL))
> > + dp_video_config->h_sync_polarity = 1;
> > +
> > + if (of_get_property(dp_node, "vsync-active-high", NULL))
> > + dp_video_config->v_sync_polarity = 1;
> > +
> > + if (of_get_property(dp_node, "interlaced", NULL))
> > + dp_video_config->interlaced = 1;
>
> of_property_read_bool() could also be used here.
OK, right.
of_property_read_bool() would be better.
>
> > +
> > + of_property_read_u32(dp_node, "samsung,color-space",
> > + &dp_video_config->color_space);
> > +
> > + of_property_read_u32(dp_node, "samsung,dynamic-range",
> > + &dp_video_config->dynamic_range);
> > +
> > + of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
> > + &dp_video_config->ycbcr_coeff);
> > +
> > + of_property_read_u32(dp_node, "samsung,color-depth",
> > + &dp_video_config->color_depth);
> > +
> > + of_property_read_u32(dp_node, "samsung,link-rate",
> > + &dp_video_config->link_rate);
> > +
> > + of_property_read_u32(dp_node, "samsung,lane-count",
> > + &dp_video_config->lane_count);
>
> Shouldn't it be checked whether all these required properties are present ?
> If someone forgets to specify any one the driver will silently ignore it,
> not giving a clue what's wrong.
OK, right.
>
> > + return pd;
> > +}
> > +
> > +void exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
> > +{
> > + struct device_node *dp_phy_node;
> > + u32 phy_base;
> > + void *virt_phy_base;
> > +
> > + dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
> > + if (!dp_phy_node) {
> > + dp->dp_phy_addr = NULL;
>
> Is this required ? You've allocated dp with kzalloc().
OK, right.
>
> > + return;
> > + }
> > +
> > + of_property_read_u32(dp_phy_node, "reg",&phy_base);
> > + of_property_read_u32(dp_phy_node, "samsung,enable-mask",
> > + &dp->enable_mask);
>
> I think you should check the return values, these are required properties.
> Some error logs might be useful here.
OK, right.
>
> > + virt_phy_base = ioremap(phy_base, SZ_4);
>
> How about assigning to dp->dp_phy_addr directly and gettting rid of
> virt_phy_base ?
OK, right.
There is no reason, virt_phy_base should be removed.
>
> > + if (!virt_phy_base) {
> > + dev_err(dp->dev, "failed to ioremap dp-phy\n");
> > + dp->dp_phy_addr = NULL;
> > + return;
> > + }
> > + dp->dp_phy_addr = virt_phy_base;
> > +}
> > +
> > +void exynos_dp_phy_init(struct exynos_dp_device *dp)
> > +{
> > + u32 reg;
> > +
> > + reg = __raw_readl(dp->dp_phy_addr);
> > + reg |= dp->enable_mask;
> > + __raw_writel(reg, dp->dp_phy_addr);
> > +}
> > +
> > +void exynos_dp_phy_exit(struct exynos_dp_device *dp)
> > +{
> > + u32 reg;
> > +
> > + reg = __raw_readl(dp->dp_phy_addr);
> > + reg&= ~(dp->enable_mask);
> > + __raw_writel(reg, dp->dp_phy_addr);
> > +}
> > +#endif /* CONFIG_OF */
> > +
> > static int __devinit exynos_dp_probe(struct platform_device *pdev)
> > {
> > struct resource *res;
> > @@ -864,12 +958,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
> >
> > int ret = 0;
> >
> > - pdata = pdev->dev.platform_data;
> > - if (!pdata) {
> > - dev_err(&pdev->dev, "no platform data\n");
> > - return -EINVAL;
> > - }
> > -
> > dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
> > GFP_KERNEL);
> > if (!dp) {
> > @@ -879,6 +967,21 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
> >
> > dp->dev =&pdev->dev;
> >
> > + if (pdev->dev.of_node) {
> > + pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
> > + if (IS_ERR(pdata))
> > + return PTR_ERR(pdata);
> > +
> > + exynos_dp_dt_parse_phydata(dp);
> > + } else {
> > + pdata = pdev->dev.platform_data;
> > + }
> > +
> > + if (!pdata) {
> > + dev_err(&pdev->dev, "no platform data\n");
> > + return -EINVAL;
> > + }
> > +
>
> This check is only reqired for non-dt case, might be worth to move
> it under else statement above.
OK, right.
>
> > dp->clock = devm_clk_get(&pdev->dev, "dp");
> > if (IS_ERR(dp->clock)) {
> > dev_err(&pdev->dev, "failed to get clock\n");
> > @@ -909,8 +1012,14 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
> > }
> >
> > dp->video_info = pdata->video_info;
> > - if (pdata->phy_init)
> > - pdata->phy_init();
> > +
> > + if (pdev->dev.of_node) {
> > + if (dp->dp_phy_addr)
> > + exynos_dp_phy_init(dp);
> > + } else {
> > + if (pdata->phy_init)
> > + pdata->phy_init();
> > + }
> >
> > exynos_dp_init_dp(dp);
> >
> > @@ -953,8 +1062,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
> > struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> > struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>
> This doesn't belong to your patch, but the above 2 lines could be written as:
>
> struct exynos_dp_device *dp = dev_get_drvdata(&pdev->dev);
>
> Same in functions exynos_dp_suspend() and exynos_dp_resume().
No, above 2 lines cannot be reduced to 1 line, as you mentioned.
This is because it makes build error.
>
> >
> > - if (pdata&& pdata->phy_exit)
> > - pdata->phy_exit();
> > + if (pdev->dev.of_node) {
> > + if (dp->dp_phy_addr)
> > + exynos_dp_phy_exit(dp);
> > + } else {
> > + if (pdata&& pdata->phy_exit)
> > + pdata->phy_exit();
> > + }
>
> It is not possible to have valid dp->dp_phy_addr pointer without
> valid pdev->dev.of_node, is it ?
Right, however, I prefer coding style as bellow:
if (pdev->dev.of_node)
DT
else
non-DT
>
> Can't this (and all similar occurrences) be simplified to:
>
> if (dp->dp_phy_addr)
> exynos_dp_phy_exit(dp);
> else if (pdata->phy_exit)
> pdata->phy_exit();
> ?
>
> It just requires dp->dp_phy_addr being NULL for non-dt case.
> pdata is never NULL, otherwise probe() would have already failed.
OK, right.
pdata can be removed.
>
> > clk_disable_unprepare(dp->clock);
> >
> > @@ -968,8 +1082,13 @@ static int exynos_dp_suspend(struct device *dev)
> > struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> > struct exynos_dp_device *dp = platform_get_drvdata(pdev);
> >
> > - if (pdata&& pdata->phy_exit)
> > - pdata->phy_exit();
> > + if (dev->of_node) {
> > + if (dp->dp_phy_addr)
> > + exynos_dp_phy_exit(dp);
> > + } else {
> > + if (pdata&& pdata->phy_exit)
> > + pdata->phy_exit();
> > + }
> >
> > clk_disable_unprepare(dp->clock);
> >
> > @@ -982,8 +1101,13 @@ static int exynos_dp_resume(struct device *dev)
> > struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> > struct exynos_dp_device *dp = platform_get_drvdata(pdev);
> >
> > - if (pdata&& pdata->phy_init)
> > - pdata->phy_init();
> > + if (dev->of_node) {
> > + if (dp->dp_phy_addr)
> > + exynos_dp_phy_init(dp);
> > + } else {
> > + if (pdata&& pdata->phy_init)
> > + pdata->phy_init();
> > + }
> >
> > clk_prepare_enable(dp->clock);
> >
> > @@ -1013,6 +1137,14 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
> > SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
> > };
> >
> > +#ifdef CONFIG_OF
> > +static const struct of_device_id exynos_dp_match[] = {
> > + { .compatible = "samsung,exynos5-dp" },
> > + {},
> > +};
> > +MODULE_DEVICE_TABLE(of, exynos_dp_match);
> > +#endif
> > +
>
> How about just dropping this #ifdef, since you're using of_match_ptr() ?
OK, right.
>
> > static struct platform_driver exynos_dp_driver = {
> > .probe = exynos_dp_probe,
> > .remove = __devexit_p(exynos_dp_remove),
> > @@ -1020,6 +1152,7 @@ static struct platform_driver exynos_dp_driver = {
> > .name = "exynos-dp",
> > .owner = THIS_MODULE,
> > .pm =&exynos_dp_pm_ops,
> > + .of_match_table = of_match_ptr(exynos_dp_match),
> > },
> > };
> >
> > diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
> > index 57b8a65..569858b 100644
> > --- a/drivers/video/exynos/exynos_dp_core.h
> > +++ b/drivers/video/exynos/exynos_dp_core.h
> > @@ -29,6 +29,8 @@ struct exynos_dp_device {
> > struct clk *clock;
> > unsigned int irq;
> > void __iomem *reg_base;
> > + void __iomem *dp_phy_addr;
>
> Nit: "dp" is already within the structure name. How about just
> naming it phy_addr ? dp->phy_addr might look better than
> dp->dp_phy_addr ;)
OK, right.
>
> > + unsigned int enable_mask;
> >
> > struct video_info *video_info;
> > struct link_train link_train;
Ajay,
When CONFIG_OF is not enabled, it makes build errors.
In addition, exynos_dp_dt_parse_phydata needs return value,
instead of returning void.
Best regards,
Jingoo Han
> --
> 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 2/2] video: exynos_dp: device tree documentation
From: Jingoo Han @ 2012-10-15 6:13 UTC (permalink / raw)
To: 'Ajay Kumar'
Cc: linux-samsung-soc, linux-fbdev, devicetree-discuss,
FlorianSchandinat, sylvester.nawrocki, tomasz.figa, thomas.ab,
'Jingoo Han'
In-Reply-To: <1350074859-23226-2-git-send-email-ajaykumar.rs@samsung.com>
On Saturday, October 13, 2012 5:48 AM Ajay kumar wrote
>
> Add documentation for the DT bindings in exynos display port driver.
>
> Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
> ---
> .../devicetree/bindings/video/exynos_dp.txt | 80 ++++++++++++++++++++
> 1 files changed, 80 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/video/exynos_dp.txt
>
> diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt
> b/Documentation/devicetree/bindings/video/exynos_dp.txt
> new file mode 100644
> index 0000000..e19594b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
> @@ -0,0 +1,80 @@
> +The Exynos display port interface should be configured based on the
> +based on the type of panel connected to it.
'based on' is duplicated. So, please fix it as bellows:
+The Exynos display port interface should be configured based on
+the type of panel connected to it.
> +
> +We use two nodes:
> + -display-port-controller node
> + -dptx-phy node(defined inside display-port-controller node)
> +
> +For the DP-PHY initialization, we use the dptx-phy node.
> +Required properties for dptx-phy:
> + -reg:
> + Base address of DP PHY register.
> + -samsung,enable-mask:
> + The bit-mask used to enable/disable DP PHY.
> +
> +For the Panel initialization, we read data from display-port-controller node.
> +Required properties for display-port-controller:
> + -compatible:
> + should be "samsung,exynos5-dp".
> + -reg:
> + physical base address of the controller and length
> + of memory mapped region.
> + -interrupts:
> + interrupt combiner values.
> + -interrupt-parent:
> + phandle to Interrupt combiner node.
> + -samsung,color-space:
> + input video data format.
> + COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
> + -samsung,dynamic-range:
> + dynamic range for input video data.
> + VESA = 0, CEA = 1
> + -samsung,ycbcr-coeff:
> + YCbCr co-efficients for input video.
> + COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
> + -samsung,color-depth:
> + number of bits per colour component.
> + COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
> + -samsung,link-rate:
> + link rate supported by the panel.
> + LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
> + -samsung,lane-count:
> + number of lanes supported by the panel.
> + LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
> +
> +Optional properties for display-port-controller:
> + -interlaced:
> + interlace scan mode.
> + Progressive if defined, Interlaced if not defined
> + -vsync-active-high:
> + VSYNC polarity configuration.
> + High if defined, Low if not defined
> + -hsync-active-high:
> + HSYNC polarity configuration.
> + High if defined, Low if not defined
> +
> +Example:
> +
> +SOC specific portion:
> + display-port-controller {
> + compatible = "samsung,exynos5-dp";
> + reg = <0x145b0000 0x10000>;
> + interrupts = <10 3>;
> + interrupt-parent = <&combiner>;
> +
> + dptx-phy {
> + reg = <0x10040720>;
> + samsung,enable-mask = <1>;
> + };
> +
> + };
> +
> +Board Specific portion:
> + display-port-controller {
> + samsung,color-space = <0>;
> + samsung,dynamic-range = <0>;
> + samsung,ycbcr-coeff = <0>;
> + samsung,color-depth = <1>;
> + samsung,link-rate = <0x0a>;
> + samsung,lane-count = <2>;
> + };
> --
> 1.7.0.4
^ permalink raw reply
* (no subject)
From: Alexey Dobriyan @ 2012-10-14 10:03 UTC (permalink / raw)
To: linux-fbdev
http://www.art-e-choke.com/blog/wp-content/plugins/zcoawuuqveq/bbc.html
^ permalink raw reply
* Re: [PATCH RESEND] video/udlfb: fix line counting in fb_write
From: Alexander Holler @ 2012-10-13 11:44 UTC (permalink / raw)
To: Florian Tobias Schandinat; +Cc: linux-kernel, Bernie Thompson, linux-fbdev
In-Reply-To: <50756A21.1020700@gmx.de>
Am 10.10.2012 14:29, schrieb Florian Tobias Schandinat:
> On 08/14/2012 07:11 AM, Alexander Holler wrote:
>> Line 0 and 1 were both written to line 0 (on the display) and all
>> subsequent
>> lines had an offset of -1. The result was that the last line on the display
>> was never overwritten by writes to /dev/fbN.
>>
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Alexander Holler <holler@ahsoftware.de>
>
> As Bernie agreed but didn't send me a pull request, I applied this one.
Thanks a lot.
> Though the formatting was screwed up and I had to fix it...
Sorry, must have happened because I've used "Edit as new" in Thunderbird
to resend the patch while just adding the RESEND to the subject.
Good to know.
Thanks,
Alexander
^ permalink raw reply
* enquiry
From: Royaldoc International Globe @ 2012-10-12 23:37 UTC (permalink / raw)
To: linux-fbdev
Royaldoc International Globe,
103, Park son road,
Carlifonia,USA.
63-1-3522 2501
royaldoc@inbox.org.tw
We are interested in purchasing your products and I would like to
make an inquiry. can you inform me of your minimum order quantity? and
also your maximum order quantity, if there is any available sample do
let me know.
Sincerely,
Purchase Manager
Alan Smith
^ permalink raw reply
* Re: [PATCH V5 1/2] video: exynos_dp: Add device tree support to DP driver
From: Tomasz Figa @ 2012-10-12 22:22 UTC (permalink / raw)
To: Sylwester Nawrocki
Cc: Ajay Kumar, linux-samsung-soc, linux-fbdev, jg1.han,
devicetree-discuss, FlorianSchandinat, thomas.ab
In-Reply-To: <5078964F.4000902@gmail.com>
On Saturday 13 of October 2012 00:14:39 Sylwester Nawrocki wrote:
> On 10/12/2012 11:54 PM, Tomasz Figa wrote:
> >>> + if (of_get_property(dp_node, "interlaced", NULL))
> >>> + dp_video_config->interlaced = 1;
> >>
> >> of_property_read_bool() could also be used here.
> >
> > Wouldn't it make the property mandatory?
>
> No, it wouldn't. of_property_read_bool() uses of_find_property()
> internally. It just returns true if property is found or false
> otherwise.
Right, sorry. I thought that all of_property_read_* return error in case
of missing property.
> Anyway, it appears of_get_property(..., NULL) pattern
> is commonly used for boolean properties.
I guess all three of them should be fine in this case, but since there is
a dedicated function for bool, it might be the best solution here indeed.
Best regards,
Tomasz Figa
^ permalink raw reply
* Re: [PATCH V5 1/2] video: exynos_dp: Add device tree support to DP driver
From: Sylwester Nawrocki @ 2012-10-12 22:14 UTC (permalink / raw)
To: Tomasz Figa
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
FlorianSchandinat-Mmb7MZpHnFY,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
jg1.han-Sze3O3UU22JBDgjK7y7TUQ, thomas.ab-Sze3O3UU22JBDgjK7y7TUQ,
Sylwester Nawrocki, Ajay Kumar
In-Reply-To: <1909932.BXc5ALaqMM@flatron>
On 10/12/2012 11:54 PM, Tomasz Figa wrote:
>>> + if (of_get_property(dp_node, "interlaced", NULL))
>>> + dp_video_config->interlaced = 1;
>>
>> of_property_read_bool() could also be used here.
>
> Wouldn't it make the property mandatory?
No, it wouldn't. of_property_read_bool() uses of_find_property()
internally. It just returns true if property is found or false
otherwise. Anyway, it appears of_get_property(..., NULL) pattern
is commonly used for boolean properties.
> I would just use of_find_property here, instead of of_get_property.
>
> Best regards,
> Tomasz Figa
^ permalink raw reply
* Re: [PATCH V5 1/2] video: exynos_dp: Add device tree support to DP driver
From: Tomasz Figa @ 2012-10-12 21:54 UTC (permalink / raw)
To: Sylwester Nawrocki
Cc: Ajay Kumar, linux-samsung-soc, linux-fbdev, jg1.han,
devicetree-discuss, FlorianSchandinat, thomas.ab
In-Reply-To: <50788F25.2040003@gmail.com>
Dnia piątek, 12 października 2012 23:44:05 Sylwester Nawrocki pisze:
> On 10/12/2012 10:47 PM, Ajay Kumar wrote:
> > This patch enables device tree based discovery support for DP driver.
> > The driver is modified to handle platform data in both the cases:
> > with DT and non-DT.
> >
> > Signed-off-by: Ajay Kumar<ajaykumar.rs@samsung.com>
> > Acked-by: Jingoo Han<jg1.han@samsung.com>
> > ---
> >
> > drivers/video/exynos/exynos_dp_core.c | 161
> > ++++++++++++++++++++++++++++++---
> > drivers/video/exynos/exynos_dp_core.h | 2 +
> > 2 files changed, 149 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/video/exynos/exynos_dp_core.c
> > b/drivers/video/exynos/exynos_dp_core.c index d55470e..62932ba 100644
> > --- a/drivers/video/exynos/exynos_dp_core.c
> > +++ b/drivers/video/exynos/exynos_dp_core.c
> > @@ -18,6 +18,7 @@
> >
> > #include<linux/io.h>
> > #include<linux/interrupt.h>
> > #include<linux/delay.h>
> >
> > +#include<linux/of.h>
> >
> > #include<video/exynos_dp.h>
> >
> > @@ -856,6 +857,99 @@ static irqreturn_t exynos_dp_irq_handler(int irq,
> > void *arg)>
> > return IRQ_HANDLED;
> >
> > }
> >
> > +#ifdef CONFIG_OF
> > +struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device
> > *dev)
> > +{
> > + struct device_node *dp_node = dev->of_node;
> > + struct exynos_dp_platdata *pd;
> > + struct video_info *dp_video_config;
> > +
> > + pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
> > + if (!pd) {
> > + dev_err(dev, "memory allocation for pdata failed\n");
> > + return ERR_PTR(-ENOMEM);
> > + }
> > + dp_video_config = devm_kzalloc(dev,
> > + sizeof(*dp_video_config), GFP_KERNEL);
> > +
> > + if (!dp_video_config) {
> > + dev_err(dev, "memory allocation for video config failed\n");
> > + return ERR_PTR(-ENOMEM);
> > + }
> > + pd->video_info = dp_video_config;
> > +
> > + if (of_get_property(dp_node, "hsync-active-high", NULL))
> > + dp_video_config->h_sync_polarity = 1;
> > +
> > + if (of_get_property(dp_node, "vsync-active-high", NULL))
> > + dp_video_config->v_sync_polarity = 1;
> > +
> > + if (of_get_property(dp_node, "interlaced", NULL))
> > + dp_video_config->interlaced = 1;
>
> of_property_read_bool() could also be used here.
Wouldn't it make the property mandatory?
I would just use of_find_property here, instead of of_get_property.
Best regards,
Tomasz Figa
^ permalink raw reply
* Re: [PATCH V5 1/2] video: exynos_dp: Add device tree support to DP driver
From: Sylwester Nawrocki @ 2012-10-12 21:44 UTC (permalink / raw)
To: Ajay Kumar
Cc: linux-samsung-soc, linux-fbdev, jg1.han, devicetree-discuss,
FlorianSchandinat, sylvester.nawrocki, tomasz.figa, thomas.ab
In-Reply-To: <1350074859-23226-1-git-send-email-ajaykumar.rs@samsung.com>
On 10/12/2012 10:47 PM, Ajay Kumar wrote:
> This patch enables device tree based discovery support for DP driver.
> The driver is modified to handle platform data in both the cases:
> with DT and non-DT.
>
> Signed-off-by: Ajay Kumar<ajaykumar.rs@samsung.com>
> Acked-by: Jingoo Han<jg1.han@samsung.com>
> ---
> drivers/video/exynos/exynos_dp_core.c | 161 ++++++++++++++++++++++++++++++---
> drivers/video/exynos/exynos_dp_core.h | 2 +
> 2 files changed, 149 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
> index d55470e..62932ba 100644
> --- a/drivers/video/exynos/exynos_dp_core.c
> +++ b/drivers/video/exynos/exynos_dp_core.c
> @@ -18,6 +18,7 @@
> #include<linux/io.h>
> #include<linux/interrupt.h>
> #include<linux/delay.h>
> +#include<linux/of.h>
>
> #include<video/exynos_dp.h>
>
> @@ -856,6 +857,99 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
> return IRQ_HANDLED;
> }
>
> +#ifdef CONFIG_OF
> +struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
> +{
> + struct device_node *dp_node = dev->of_node;
> + struct exynos_dp_platdata *pd;
> + struct video_info *dp_video_config;
> +
> + pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
> + if (!pd) {
> + dev_err(dev, "memory allocation for pdata failed\n");
> + return ERR_PTR(-ENOMEM);
> + }
> + dp_video_config = devm_kzalloc(dev,
> + sizeof(*dp_video_config), GFP_KERNEL);
> +
> + if (!dp_video_config) {
> + dev_err(dev, "memory allocation for video config failed\n");
> + return ERR_PTR(-ENOMEM);
> + }
> + pd->video_info = dp_video_config;
> +
> + if (of_get_property(dp_node, "hsync-active-high", NULL))
> + dp_video_config->h_sync_polarity = 1;
> +
> + if (of_get_property(dp_node, "vsync-active-high", NULL))
> + dp_video_config->v_sync_polarity = 1;
> +
> + if (of_get_property(dp_node, "interlaced", NULL))
> + dp_video_config->interlaced = 1;
of_property_read_bool() could also be used here.
> +
> + of_property_read_u32(dp_node, "samsung,color-space",
> + &dp_video_config->color_space);
> +
> + of_property_read_u32(dp_node, "samsung,dynamic-range",
> + &dp_video_config->dynamic_range);
> +
> + of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
> + &dp_video_config->ycbcr_coeff);
> +
> + of_property_read_u32(dp_node, "samsung,color-depth",
> + &dp_video_config->color_depth);
> +
> + of_property_read_u32(dp_node, "samsung,link-rate",
> + &dp_video_config->link_rate);
> +
> + of_property_read_u32(dp_node, "samsung,lane-count",
> + &dp_video_config->lane_count);
Shouldn't it be checked whether all these required properties are present ?
If someone forgets to specify any one the driver will silently ignore it,
not giving a clue what's wrong.
> + return pd;
> +}
> +
> +void exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
> +{
> + struct device_node *dp_phy_node;
> + u32 phy_base;
> + void *virt_phy_base;
> +
> + dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
> + if (!dp_phy_node) {
> + dp->dp_phy_addr = NULL;
Is this required ? You've allocated dp with kzalloc().
> + return;
> + }
> +
> + of_property_read_u32(dp_phy_node, "reg",&phy_base);
> + of_property_read_u32(dp_phy_node, "samsung,enable-mask",
> + &dp->enable_mask);
I think you should check the return values, these are required properties.
Some error logs might be useful here.
> + virt_phy_base = ioremap(phy_base, SZ_4);
How about assigning to dp->dp_phy_addr directly and gettting rid of
virt_phy_base ?
> + if (!virt_phy_base) {
> + dev_err(dp->dev, "failed to ioremap dp-phy\n");
> + dp->dp_phy_addr = NULL;
> + return;
> + }
> + dp->dp_phy_addr = virt_phy_base;
> +}
> +
> +void exynos_dp_phy_init(struct exynos_dp_device *dp)
> +{
> + u32 reg;
> +
> + reg = __raw_readl(dp->dp_phy_addr);
> + reg |= dp->enable_mask;
> + __raw_writel(reg, dp->dp_phy_addr);
> +}
> +
> +void exynos_dp_phy_exit(struct exynos_dp_device *dp)
> +{
> + u32 reg;
> +
> + reg = __raw_readl(dp->dp_phy_addr);
> + reg&= ~(dp->enable_mask);
> + __raw_writel(reg, dp->dp_phy_addr);
> +}
> +#endif /* CONFIG_OF */
> +
> static int __devinit exynos_dp_probe(struct platform_device *pdev)
> {
> struct resource *res;
> @@ -864,12 +958,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
>
> int ret = 0;
>
> - pdata = pdev->dev.platform_data;
> - if (!pdata) {
> - dev_err(&pdev->dev, "no platform data\n");
> - return -EINVAL;
> - }
> -
> dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
> GFP_KERNEL);
> if (!dp) {
> @@ -879,6 +967,21 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
>
> dp->dev =&pdev->dev;
>
> + if (pdev->dev.of_node) {
> + pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
> + if (IS_ERR(pdata))
> + return PTR_ERR(pdata);
> +
> + exynos_dp_dt_parse_phydata(dp);
> + } else {
> + pdata = pdev->dev.platform_data;
> + }
> +
> + if (!pdata) {
> + dev_err(&pdev->dev, "no platform data\n");
> + return -EINVAL;
> + }
> +
This check is only reqired for non-dt case, might be worth to move
it under else statement above.
> dp->clock = devm_clk_get(&pdev->dev, "dp");
> if (IS_ERR(dp->clock)) {
> dev_err(&pdev->dev, "failed to get clock\n");
> @@ -909,8 +1012,14 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
> }
>
> dp->video_info = pdata->video_info;
> - if (pdata->phy_init)
> - pdata->phy_init();
> +
> + if (pdev->dev.of_node) {
> + if (dp->dp_phy_addr)
> + exynos_dp_phy_init(dp);
> + } else {
> + if (pdata->phy_init)
> + pdata->phy_init();
> + }
>
> exynos_dp_init_dp(dp);
>
> @@ -953,8 +1062,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
> struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> struct exynos_dp_device *dp = platform_get_drvdata(pdev);
This doesn't belong to your patch, but the above 2 lines could be written as:
struct exynos_dp_device *dp = dev_get_drvdata(&pdev->dev);
Same in functions exynos_dp_suspend() and exynos_dp_resume().
>
> - if (pdata&& pdata->phy_exit)
> - pdata->phy_exit();
> + if (pdev->dev.of_node) {
> + if (dp->dp_phy_addr)
> + exynos_dp_phy_exit(dp);
> + } else {
> + if (pdata&& pdata->phy_exit)
> + pdata->phy_exit();
> + }
It is not possible to have valid dp->dp_phy_addr pointer without
valid pdev->dev.of_node, is it ?
Can't this (and all similar occurrences) be simplified to:
if (dp->dp_phy_addr)
exynos_dp_phy_exit(dp);
else if (pdata->phy_exit)
pdata->phy_exit();
?
It just requires dp->dp_phy_addr being NULL for non-dt case.
pdata is never NULL, otherwise probe() would have already failed.
> clk_disable_unprepare(dp->clock);
>
> @@ -968,8 +1082,13 @@ static int exynos_dp_suspend(struct device *dev)
> struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>
> - if (pdata&& pdata->phy_exit)
> - pdata->phy_exit();
> + if (dev->of_node) {
> + if (dp->dp_phy_addr)
> + exynos_dp_phy_exit(dp);
> + } else {
> + if (pdata&& pdata->phy_exit)
> + pdata->phy_exit();
> + }
>
> clk_disable_unprepare(dp->clock);
>
> @@ -982,8 +1101,13 @@ static int exynos_dp_resume(struct device *dev)
> struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>
> - if (pdata&& pdata->phy_init)
> - pdata->phy_init();
> + if (dev->of_node) {
> + if (dp->dp_phy_addr)
> + exynos_dp_phy_init(dp);
> + } else {
> + if (pdata&& pdata->phy_init)
> + pdata->phy_init();
> + }
>
> clk_prepare_enable(dp->clock);
>
> @@ -1013,6 +1137,14 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
> SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
> };
>
> +#ifdef CONFIG_OF
> +static const struct of_device_id exynos_dp_match[] = {
> + { .compatible = "samsung,exynos5-dp" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, exynos_dp_match);
> +#endif
> +
How about just dropping this #ifdef, since you're using of_match_ptr() ?
> static struct platform_driver exynos_dp_driver = {
> .probe = exynos_dp_probe,
> .remove = __devexit_p(exynos_dp_remove),
> @@ -1020,6 +1152,7 @@ static struct platform_driver exynos_dp_driver = {
> .name = "exynos-dp",
> .owner = THIS_MODULE,
> .pm =&exynos_dp_pm_ops,
> + .of_match_table = of_match_ptr(exynos_dp_match),
> },
> };
>
> diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
> index 57b8a65..569858b 100644
> --- a/drivers/video/exynos/exynos_dp_core.h
> +++ b/drivers/video/exynos/exynos_dp_core.h
> @@ -29,6 +29,8 @@ struct exynos_dp_device {
> struct clk *clock;
> unsigned int irq;
> void __iomem *reg_base;
> + void __iomem *dp_phy_addr;
Nit: "dp" is already within the structure name. How about just
naming it phy_addr ? dp->phy_addr might look better than
dp->dp_phy_addr ;)
> + unsigned int enable_mask;
>
> struct video_info *video_info;
> struct link_train link_train;
^ permalink raw reply
* RE: [PATCH 1/2] da8xx-fb: move panel information from driver to platform file
From: Manjunathappa, Prakash @ 2012-10-12 12:53 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1349445084-9857-2-git-send-email-prakash.pm@ti.com>
SGkgU2VraGFyLA0KDQpPbiBUdWUsIE9jdCAwOSwgMjAxMiBhdCAxMjowMjo1MiwgTm9yaSwgU2Vr
aGFyIHdyb3RlOg0KPiBPbiAxMC84LzIwMTIgMTA6MDMgUE0sIE1hbmp1bmF0aGFwcGEsIFByYWth
c2ggd3JvdGU6DQo+ID4gSGkgU2VraGFyLA0KPiA+IA0KPiA+IE9uIE1vbiwgT2N0IDA4LCAyMDEy
IGF0IDE4OjEwOjEyLCBOb3JpLCBTZWtoYXIgd3JvdGU6DQo+ID4+IEhpIFByYWthc2gsDQo+ID4+
DQo+ID4+IE9uIDEwLzUvMjAxMiA3OjIxIFBNLCBNYW5qdW5hdGhhcHBhLCBQcmFrYXNoIHdyb3Rl
Og0KPiA+Pj4gTW92aW5nIHBhbmVsIGluZm9ybWF0aW9uIGZyb20gZHJpdmVyIHRvIHBsYXRmb3Jt
IGZpbGUsIHBhdGNoIGFsc28gbWFkZQ0KPiA+Pj4gY29tcGxpYW50IHRvIGZiX3ZpZGVvbW9kZSBk
YXRhLg0KPiA+Pj4NCj4gPj4+IFNpZ25lZC1vZmYtYnk6IE1hbmp1bmF0aGFwcGEsIFByYWthc2gg
PHByYWthc2gucG1AdGkuY29tPg0KPiA+Pg0KPiA+PiBXaHkgZG8geW91IGhhdmUgdG8gZG8gdGhp
cz8gSnVzdCBtb3ZpbmcgcGFuZWwgZGF0YSBmcm9tIGRyaXZlciB0bw0KPiA+PiBwbGF0Zm9ybSBj
b2RlIGRvZXNuJ3Qgc2VlbSB0byBidXkgYW55dGhpbmcuDQo+ID4+DQo+ID4+IElmIHlvdSBhcmUg
cGFzc2VkIERUIGRhdGEsIHRoZW4gdXNlIGl0IGVsc2UgY29udGludWUgdGhlIGV4aXN0aW5nDQo+
ID4+IHBsYXRmb3JtIGRhdGEgbWV0aG9kPyBPbmNlIGFsbCB0aGUgYm9hcmRzIHVzaW5nIHRoaXMg
ZHJpdmVyIGFyZQ0KPiA+PiBjb252ZXJ0ZWQgdG8gRFQsIHRoZW4gYWxsIHRoZSBwYW5lbCBpbmZv
cm1hdGlvbiBjYW4gYmUgcmVtb3ZlZCBmcm9tDQo+ID4+IGRyaXZlci4gVGhhdCB3aWxsIHNhdmUg
Y29kZS4NCj4gPj4NCj4gPiANCj4gPiBCZWNhdXNlIG9mIGZvbGxvd2luZyByZWFzb25zIEkgbW92
ZWQgaXQgb3V0IG9mIGRyaXZlcg0KPiA+IDEpVGhpcyBwYXRjaCBhbHNvIGNvbnZlcnRzIHBhbmVs
IGluZm9ybWF0aW9uIGNvbXBsaWFudCB0byBmYl92aWRlb21vZGUuDQo+ID4gUGF0Y2ggIm9mOiBh
ZGQgZGlzcGxheSBoZWxwZXIiWzFdIHVuZGVyIHJldmlldyBleHBlY3RzIHBhbmVsIGRhdGEgaW4g
ZmJfdmlkZW9tb2RlIGZvcm1hdC4NCj4gDQo+IFNvdW5kcyBsaWtlIHRoaXMgc2hvdWxkIGJlIGEg
c2VwYXJhdGUgcGF0Y2ggYXMgdGhpcyBoYXMgZ290IG5vdGhpbmcgdG8NCj4gZG8gd2l0aCBtb3Zp
bmcgcGFuZWwgaW5mb3JtYXRpb24gdG8gcGxhdGZvcm0gY29kZS4NCj4gDQoNCk9rIEkgd2lsbCBz
cGxpdCBpdCBhcyBzZXBhcmF0ZSBwYXRjaC4NCg0KPiA+IDIpSSBmZWx0IGRpZmZpY3VsdCBhbmQg
dW5jbGVhbiB0byBoYXZlIGRyaXZlciBzdXBwb3J0aW5nIGJvdGggcGFuZWwgZGF0YSBmcm9tIGRy
aXZlciBhbmQgcGFuZWwgZGF0YSBmcm9tIERULg0KPiANCj4gRG8geW91IGhhdmUgYW55IGNvZGUg
d2hlcmUgeW91IHRyaWVkIHRoaXM/IElmIGl0IGlzIGNsZWFuIGVub3VnaCwgY2FuDQo+IHlvdSBw
b3N0IGl0IHNvIHdlIGNhbiBhbGwgc2VlIHdoYXQgdGhlIGFsdGVybmF0ZSBsb29rcyBsaWtlPw0K
PiANCg0KT2sgSSB3aWxsIHBvc3QgaXQgd2l0aCBEVCBzdXBwb3J0Lg0KDQo+ID4gMylUaGlzIGVm
Zm9ydCB3aWxsIGFsc28gZWFzZSBhZGRpbmcgRFQgc3VwcG9ydCBvZiB0aGlzIGRyaXZlci4NCj4g
DQo+IEl0IGlzIHN0aWxsIG5vdCBjbGVhciB0byBtZSB3aHkgZXhhY3RseSBpdCB3aWxsIGVhc2Ug
YWRkaW5nIERUIHN1cHBvcnQuDQo+IA0KDQpJIHNlZSB2NiBvZiAib2Y6IGFkZCBkaXNwbGF5IGhl
bHBlciIgcGF0Y2ggc3VibWl0dGVkLiBIYXMgY2hhbmdlZCBjb21wYXJlZCB0byBpbml0aWFsIHZl
cnNpb24uDQoNClsxXTogaHR0cDovL21hcmMuaW5mby8/bD1saW51eC1mYmRldiZtPTEzNDkzNzM1
ODIwODY3NiZ3PTINCg0KVGhhbmtzLA0KUHJha2FzaA0KDQo
^ permalink raw reply
* [PATCH V5 2/2] video: exynos_dp: device tree documentation
From: Ajay Kumar @ 2012-10-12 11:19 UTC (permalink / raw)
To: linux-samsung-soc, linux-fbdev, jg1.han, devicetree-discuss
Cc: FlorianSchandinat, sylvester.nawrocki, tomasz.figa, thomas.ab
In-Reply-To: <1350074859-23226-1-git-send-email-ajaykumar.rs@samsung.com>
Add documentation for the DT bindings in exynos display port driver.
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
---
.../devicetree/bindings/video/exynos_dp.txt | 80 ++++++++++++++++++++
1 files changed, 80 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/video/exynos_dp.txt
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
new file mode 100644
index 0000000..e19594b
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -0,0 +1,80 @@
+The Exynos display port interface should be configured based on the
+based on the type of panel connected to it.
+
+We use two nodes:
+ -display-port-controller node
+ -dptx-phy node(defined inside display-port-controller node)
+
+For the DP-PHY initialization, we use the dptx-phy node.
+Required properties for dptx-phy:
+ -reg:
+ Base address of DP PHY register.
+ -samsung,enable-mask:
+ The bit-mask used to enable/disable DP PHY.
+
+For the Panel initialization, we read data from display-port-controller node.
+Required properties for display-port-controller:
+ -compatible:
+ should be "samsung,exynos5-dp".
+ -reg:
+ physical base address of the controller and length
+ of memory mapped region.
+ -interrupts:
+ interrupt combiner values.
+ -interrupt-parent:
+ phandle to Interrupt combiner node.
+ -samsung,color-space:
+ input video data format.
+ COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
+ -samsung,dynamic-range:
+ dynamic range for input video data.
+ VESA = 0, CEA = 1
+ -samsung,ycbcr-coeff:
+ YCbCr co-efficients for input video.
+ COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
+ -samsung,color-depth:
+ number of bits per colour component.
+ COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
+ -samsung,link-rate:
+ link rate supported by the panel.
+ LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
+ -samsung,lane-count:
+ number of lanes supported by the panel.
+ LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
+
+Optional properties for display-port-controller:
+ -interlaced:
+ interlace scan mode.
+ Progressive if defined, Interlaced if not defined
+ -vsync-active-high:
+ VSYNC polarity configuration.
+ High if defined, Low if not defined
+ -hsync-active-high:
+ HSYNC polarity configuration.
+ High if defined, Low if not defined
+
+Example:
+
+SOC specific portion:
+ display-port-controller {
+ compatible = "samsung,exynos5-dp";
+ reg = <0x145b0000 0x10000>;
+ interrupts = <10 3>;
+ interrupt-parent = <&combiner>;
+
+ dptx-phy {
+ reg = <0x10040720>;
+ samsung,enable-mask = <1>;
+ };
+
+ };
+
+Board Specific portion:
+ display-port-controller {
+ samsung,color-space = <0>;
+ samsung,dynamic-range = <0>;
+ samsung,ycbcr-coeff = <0>;
+ samsung,color-depth = <1>;
+ samsung,link-rate = <0x0a>;
+ samsung,lane-count = <2>;
+ };
--
1.7.0.4
^ permalink raw reply related
* [PATCH V5 1/2] video: exynos_dp: Add device tree support to DP driver
From: Ajay Kumar @ 2012-10-12 11:18 UTC (permalink / raw)
To: linux-samsung-soc, linux-fbdev, jg1.han, devicetree-discuss
Cc: FlorianSchandinat, sylvester.nawrocki, tomasz.figa, thomas.ab
This patch enables device tree based discovery support for DP driver.
The driver is modified to handle platform data in both the cases:
with DT and non-DT.
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
---
drivers/video/exynos/exynos_dp_core.c | 161 ++++++++++++++++++++++++++++++---
drivers/video/exynos/exynos_dp_core.h | 2 +
2 files changed, 149 insertions(+), 14 deletions(-)
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e..62932ba 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/of.h>
#include <video/exynos_dp.h>
@@ -856,6 +857,99 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
return IRQ_HANDLED;
}
+#ifdef CONFIG_OF
+struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+ struct device_node *dp_node = dev->of_node;
+ struct exynos_dp_platdata *pd;
+ struct video_info *dp_video_config;
+
+ pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ dev_err(dev, "memory allocation for pdata failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ dp_video_config = devm_kzalloc(dev,
+ sizeof(*dp_video_config), GFP_KERNEL);
+
+ if (!dp_video_config) {
+ dev_err(dev, "memory allocation for video config failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ pd->video_info = dp_video_config;
+
+ if (of_get_property(dp_node, "hsync-active-high", NULL))
+ dp_video_config->h_sync_polarity = 1;
+
+ if (of_get_property(dp_node, "vsync-active-high", NULL))
+ dp_video_config->v_sync_polarity = 1;
+
+ if (of_get_property(dp_node, "interlaced", NULL))
+ dp_video_config->interlaced = 1;
+
+ of_property_read_u32(dp_node, "samsung,color-space",
+ &dp_video_config->color_space);
+
+ of_property_read_u32(dp_node, "samsung,dynamic-range",
+ &dp_video_config->dynamic_range);
+
+ of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
+ &dp_video_config->ycbcr_coeff);
+
+ of_property_read_u32(dp_node, "samsung,color-depth",
+ &dp_video_config->color_depth);
+
+ of_property_read_u32(dp_node, "samsung,link-rate",
+ &dp_video_config->link_rate);
+
+ of_property_read_u32(dp_node, "samsung,lane-count",
+ &dp_video_config->lane_count);
+ return pd;
+}
+
+void exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+ struct device_node *dp_phy_node;
+ u32 phy_base;
+ void *virt_phy_base;
+
+ dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
+ if (!dp_phy_node) {
+ dp->dp_phy_addr = NULL;
+ return;
+ }
+
+ of_property_read_u32(dp_phy_node, "reg", &phy_base);
+ of_property_read_u32(dp_phy_node, "samsung,enable-mask",
+ &dp->enable_mask);
+ virt_phy_base = ioremap(phy_base, SZ_4);
+ if (!virt_phy_base) {
+ dev_err(dp->dev, "failed to ioremap dp-phy\n");
+ dp->dp_phy_addr = NULL;
+ return;
+ }
+ dp->dp_phy_addr = virt_phy_base;
+}
+
+void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->dp_phy_addr);
+ reg |= dp->enable_mask;
+ __raw_writel(reg, dp->dp_phy_addr);
+}
+
+void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->dp_phy_addr);
+ reg &= ~(dp->enable_mask);
+ __raw_writel(reg, dp->dp_phy_addr);
+}
+#endif /* CONFIG_OF */
+
static int __devinit exynos_dp_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -864,12 +958,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
int ret = 0;
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
GFP_KERNEL);
if (!dp) {
@@ -879,6 +967,21 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
dp->dev = &pdev->dev;
+ if (pdev->dev.of_node) {
+ pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+
+ exynos_dp_dt_parse_phydata(dp);
+ } else {
+ pdata = pdev->dev.platform_data;
+ }
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data\n");
+ return -EINVAL;
+ }
+
dp->clock = devm_clk_get(&pdev->dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(&pdev->dev, "failed to get clock\n");
@@ -909,8 +1012,14 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
}
dp->video_info = pdata->video_info;
- if (pdata->phy_init)
- pdata->phy_init();
+
+ if (pdev->dev.of_node) {
+ if (dp->dp_phy_addr)
+ exynos_dp_phy_init(dp);
+ } else {
+ if (pdata->phy_init)
+ pdata->phy_init();
+ }
exynos_dp_init_dp(dp);
@@ -953,8 +1062,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_exit)
- pdata->phy_exit();
+ if (pdev->dev.of_node) {
+ if (dp->dp_phy_addr)
+ exynos_dp_phy_exit(dp);
+ } else {
+ if (pdata && pdata->phy_exit)
+ pdata->phy_exit();
+ }
clk_disable_unprepare(dp->clock);
@@ -968,8 +1082,13 @@ static int exynos_dp_suspend(struct device *dev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_exit)
- pdata->phy_exit();
+ if (dev->of_node) {
+ if (dp->dp_phy_addr)
+ exynos_dp_phy_exit(dp);
+ } else {
+ if (pdata && pdata->phy_exit)
+ pdata->phy_exit();
+ }
clk_disable_unprepare(dp->clock);
@@ -982,8 +1101,13 @@ static int exynos_dp_resume(struct device *dev)
struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
struct exynos_dp_device *dp = platform_get_drvdata(pdev);
- if (pdata && pdata->phy_init)
- pdata->phy_init();
+ if (dev->of_node) {
+ if (dp->dp_phy_addr)
+ exynos_dp_phy_init(dp);
+ } else {
+ if (pdata && pdata->phy_init)
+ pdata->phy_init();
+ }
clk_prepare_enable(dp->clock);
@@ -1013,6 +1137,14 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
};
+#ifdef CONFIG_OF
+static const struct of_device_id exynos_dp_match[] = {
+ { .compatible = "samsung,exynos5-dp" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
+#endif
+
static struct platform_driver exynos_dp_driver = {
.probe = exynos_dp_probe,
.remove = __devexit_p(exynos_dp_remove),
@@ -1020,6 +1152,7 @@ static struct platform_driver exynos_dp_driver = {
.name = "exynos-dp",
.owner = THIS_MODULE,
.pm = &exynos_dp_pm_ops,
+ .of_match_table = of_match_ptr(exynos_dp_match),
},
};
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 57b8a65..569858b 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -29,6 +29,8 @@ struct exynos_dp_device {
struct clk *clock;
unsigned int irq;
void __iomem *reg_base;
+ void __iomem *dp_phy_addr;
+ unsigned int enable_mask;
struct video_info *video_info;
struct link_train link_train;
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 1/2 v6] of: add helper to parse display timings
From: Steffen Trumtrar @ 2012-10-12 7:21 UTC (permalink / raw)
To: Thierry Reding
Cc: Tomi Valkeinen, devicetree-discuss, Rob Herring, linux-fbdev,
dri-devel, Laurent Pinchart, linux-media
In-Reply-To: <20121011193118.GA27599@avionic-0098.mockup.avionic-design.de>
On Thu, Oct 11, 2012 at 09:31:18PM +0200, Thierry Reding wrote:
> On Mon, Oct 08, 2012 at 09:49:21AM +0200, Steffen Trumtrar wrote:
> > On Mon, Oct 08, 2012 at 10:07:45AM +0300, Tomi Valkeinen wrote:
> > > On Thu, 2012-10-04 at 19:59 +0200, Steffen Trumtrar wrote:
> [...]
> > > > +
> > > > + disp->num_timings = 0;
> > > > +
> > > > + for_each_child_of_node(timings_np, entry) {
> > > > + disp->num_timings++;
> > > > + }
> > >
> > > No need for { }
> > >
> >
> > Okay.
>
> Or you could just use of_get_child_count().
>
> Thierry
Ah, very nice. That's definitely better. Didn't know about that function.
Thanks,
Steffen
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ 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