summaryrefslogtreecommitdiff
path: root/patches.tizen/0756-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHYs.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches.tizen/0756-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHYs.patch')
-rw-r--r--patches.tizen/0756-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHYs.patch263
1 files changed, 263 insertions, 0 deletions
diff --git a/patches.tizen/0756-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHYs.patch b/patches.tizen/0756-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHYs.patch
new file mode 100644
index 00000000000..68c0de2b334
--- /dev/null
+++ b/patches.tizen/0756-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHYs.patch
@@ -0,0 +1,263 @@
+From 384e16b37787c8a97bfd1012c08b51a7a8596c37 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 4 Sep 2013 15:07:24 +0200
+Subject: [PATCH 0756/1302] phy: Add driver for Exynos MIPI CSIS/DSIM DPHYs
+
+Add a PHY provider driver for the Samsung S5P/Exynos SoC MIPI CSI-2
+receiver and MIPI DSI transmitter DPHYs.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Felipe Balbi <balbi@ti.com>
+---
+Changes since v4:
+ - updated to new version of devm_phy_create().
+
+Changes since v3:
+ - replaced spin_(un)lock_irq_{save,restore} with spin_{lock,unlock}.
+ - DT binding file renamed to samsung-phy.txt, so it can be used for
+ other PHYs as well,
+ - removed <linux/delay.h> inclusion,
+ - added missing spin_lock_init().
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/phy/samsung-phy.txt | 14 ++
+ drivers/phy/Kconfig | 6 +
+ drivers/phy/Makefile | 3 +-
+ drivers/phy/phy-exynos-mipi-video.c | 176 +++++++++++++++++++++
+ 4 files changed, 198 insertions(+), 1 deletion(-)
+ create mode 100644 Documentation/devicetree/bindings/phy/samsung-phy.txt
+ create mode 100644 drivers/phy/phy-exynos-mipi-video.c
+
+diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
+new file mode 100644
+index 0000000..5ff208c
+--- /dev/null
++++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
+@@ -0,0 +1,14 @@
++Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY
++-------------------------------------------------
++
++Required properties:
++- compatible : should be "samsung,s5pv210-mipi-video-phy";
++- reg : offset and length of the MIPI DPHY register set;
++- #phy-cells : from the generic phy bindings, must be 1;
++
++For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in
++the PHY specifier identifies the PHY and its meaning is as follows:
++ 0 - MIPI CSIS 0,
++ 1 - MIPI DSIM 0,
++ 2 - MIPI CSIS 1,
++ 3 - MIPI DSIM 1.
+diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
+index 349bef2..108c5f6 100644
+--- a/drivers/phy/Kconfig
++++ b/drivers/phy/Kconfig
+@@ -15,4 +15,10 @@ config GENERIC_PHY
+ phy users can obtain reference to the PHY. All the users of this
+ framework should select this config.
+
++config PHY_EXYNOS_MIPI_VIDEO
++ tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
++ help
++ Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung
++ S5P and EXYNOS SoCs.
++
+ endmenu
+diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
+index 9e9560f..71d8841 100644
+--- a/drivers/phy/Makefile
++++ b/drivers/phy/Makefile
+@@ -2,4 +2,5 @@
+ # Makefile for the phy drivers.
+ #
+
+-obj-$(CONFIG_GENERIC_PHY) += phy-core.o
++obj-$(CONFIG_GENERIC_PHY) += phy-core.o
++obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
+diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c
+new file mode 100644
+index 0000000..b73b86a
+--- /dev/null
++++ b/drivers/phy/phy-exynos-mipi-video.c
+@@ -0,0 +1,176 @@
++/*
++ * Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++
++/* MIPI_PHYn_CONTROL register offset: n = 0..1 */
++#define EXYNOS_MIPI_PHY_CONTROL(n) ((n) * 4)
++#define EXYNOS_MIPI_PHY_ENABLE (1 << 0)
++#define EXYNOS_MIPI_PHY_SRESETN (1 << 1)
++#define EXYNOS_MIPI_PHY_MRESETN (1 << 2)
++#define EXYNOS_MIPI_PHY_RESET_MASK (3 << 1)
++
++enum exynos_mipi_phy_id {
++ EXYNOS_MIPI_PHY_ID_CSIS0,
++ EXYNOS_MIPI_PHY_ID_DSIM0,
++ EXYNOS_MIPI_PHY_ID_CSIS1,
++ EXYNOS_MIPI_PHY_ID_DSIM1,
++ EXYNOS_MIPI_PHYS_NUM
++};
++
++#define is_mipi_dsim_phy_id(id) \
++ ((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM1)
++
++struct exynos_mipi_video_phy {
++ spinlock_t slock;
++ struct video_phy_desc {
++ struct phy *phy;
++ unsigned int index;
++ } phys[EXYNOS_MIPI_PHYS_NUM];
++ void __iomem *regs;
++};
++
++static int __set_phy_state(struct exynos_mipi_video_phy *state,
++ enum exynos_mipi_phy_id id, unsigned int on)
++{
++ void __iomem *addr;
++ u32 reg, reset;
++
++ addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2);
++
++ if (is_mipi_dsim_phy_id(id))
++ reset = EXYNOS_MIPI_PHY_MRESETN;
++ else
++ reset = EXYNOS_MIPI_PHY_SRESETN;
++
++ spin_lock(&state->slock);
++ reg = readl(addr);
++ if (on)
++ reg |= reset;
++ else
++ reg &= ~reset;
++ writel(reg, addr);
++
++ /* Clear ENABLE bit only if MRESETN, SRESETN bits are not set. */
++ if (on)
++ reg |= EXYNOS_MIPI_PHY_ENABLE;
++ else if (!(reg & EXYNOS_MIPI_PHY_RESET_MASK))
++ reg &= ~EXYNOS_MIPI_PHY_ENABLE;
++
++ writel(reg, addr);
++ spin_unlock(&state->slock);
++ return 0;
++}
++
++#define to_mipi_video_phy(desc) \
++ container_of((desc), struct exynos_mipi_video_phy, phys[(desc)->index]);
++
++static int exynos_mipi_video_phy_power_on(struct phy *phy)
++{
++ struct video_phy_desc *phy_desc = phy_get_drvdata(phy);
++ struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc);
++
++ return __set_phy_state(state, phy_desc->index, 1);
++}
++
++static int exynos_mipi_video_phy_power_off(struct phy *phy)
++{
++ struct video_phy_desc *phy_desc = phy_get_drvdata(phy);
++ struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc);
++
++ return __set_phy_state(state, phy_desc->index, 1);
++}
++
++static struct phy *exynos_mipi_video_phy_xlate(struct device *dev,
++ struct of_phandle_args *args)
++{
++ struct exynos_mipi_video_phy *state = dev_get_drvdata(dev);
++
++ if (WARN_ON(args->args[0] > EXYNOS_MIPI_PHYS_NUM))
++ return ERR_PTR(-ENODEV);
++
++ return state->phys[args->args[0]].phy;
++}
++
++static struct phy_ops exynos_mipi_video_phy_ops = {
++ .power_on = exynos_mipi_video_phy_power_on,
++ .power_off = exynos_mipi_video_phy_power_off,
++ .owner = THIS_MODULE,
++};
++
++static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
++{
++ struct exynos_mipi_video_phy *state;
++ struct device *dev = &pdev->dev;
++ struct resource *res;
++ struct phy_provider *phy_provider;
++ unsigned int i;
++
++ state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
++ if (!state)
++ return -ENOMEM;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++ state->regs = devm_ioremap_resource(dev, res);
++ if (IS_ERR(state->regs))
++ return PTR_ERR(state->regs);
++
++ dev_set_drvdata(dev, state);
++ spin_lock_init(&state->slock);
++
++ phy_provider = devm_of_phy_provider_register(dev,
++ exynos_mipi_video_phy_xlate);
++ if (IS_ERR(phy_provider))
++ return PTR_ERR(phy_provider);
++
++ for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
++ struct phy *phy = devm_phy_create(dev,
++ &exynos_mipi_video_phy_ops, NULL);
++ if (IS_ERR(phy)) {
++ dev_err(dev, "failed to create PHY %d\n", i);
++ return PTR_ERR(phy);
++ }
++
++ state->phys[i].phy = phy;
++ state->phys[i].index = i;
++ phy_set_drvdata(phy, &state->phys[i]);
++ }
++
++ return 0;
++}
++
++static const struct of_device_id exynos_mipi_video_phy_of_match[] = {
++ { .compatible = "samsung,s5pv210-mipi-video-phy" },
++ { },
++};
++MODULE_DEVICE_TABLE(of, exynos_mipi_video_phy_of_match);
++
++static struct platform_driver exynos_mipi_video_phy_driver = {
++ .probe = exynos_mipi_video_phy_probe,
++ .driver = {
++ .of_match_table = exynos_mipi_video_phy_of_match,
++ .name = "exynos-mipi-video-phy",
++ .owner = THIS_MODULE,
++ }
++};
++module_platform_driver(exynos_mipi_video_phy_driver);
++
++MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI CSI-2/DSI PHY driver");
++MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
++MODULE_LICENSE("GPL v2");
+--
+1.8.3.2
+