* [PATCH] phy: Add exynos-phy driver
@ 2013-11-27 13:26 Tomasz Stanislawski
2013-11-27 13:26 ` Tomasz Stanislawski
2013-12-11 9:54 ` Kishon Vijay Abraham I
0 siblings, 2 replies; 5+ messages in thread
From: Tomasz Stanislawski @ 2013-11-27 13:26 UTC (permalink / raw)
To: linux-arm-kernel
Hello everyone,
The Samsung SoCs from Exynos family are enhanced with a bunch of switches
dedicated for IP blocks. Those switches are called PHYs in Exynos
specification. They are usually controlled by a single bit in a single
one-word-long register.
A IP driver has to control such a switch in an abstract manner. Therefore,
such 'enablers' were implemented as clocks in older versions of Linux kernel.
With the dawn of PHY subsystems, PHYs become a natural way of exporting the
'enabler' functionality to drivers. However, there is an unexpected
consequence. Some of those 1-bit PHYs were implemented as separate drivers.
This means that one has to create a struct device, struct phy, its phy provider
and 100-150 lines of driver code to basically set one bit.
The DP phy driver is a good example:
https://lkml.org/lkml/2013/7/18/53
And simple-phy RFC (shares only driver code but not other resources):
https://lkml.org/lkml/2013/10/21/313
To avoid waste of resources I propose to create all such 1-bit phys from Exynos
SoC using a single device, driver and phy provider.
This patchset contains a proposed solution.
All comment are welcome.
Hopefully in future the functionality introduced by this patch may be merged
into a larger Power Management Unit (PMU) gluer driver. On Samsusng SoC , the
PMU part contains a number of register barely linked to power management (like
clock gating, clock dividers, CPU resetting, etc.). It may be tempting to
create a hybrid driver that export clocks/phys/etc that are controlled by PMU
unit.
Regards,
Tomasz Stanislawski
Tomasz Stanislawski (1):
phy: Add exynos-phy driver
drivers/phy/Kconfig | 5 ++
drivers/phy/Makefile | 1 +
drivers/phy/exynos-phy.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 158 insertions(+)
create mode 100644 drivers/phy/exynos-phy.c
--
1.7.9.5
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] phy: Add exynos-phy driver
2013-11-27 13:26 [PATCH] phy: Add exynos-phy driver Tomasz Stanislawski
@ 2013-11-27 13:26 ` Tomasz Stanislawski
2013-12-11 9:54 ` Kishon Vijay Abraham I
1 sibling, 0 replies; 5+ messages in thread
From: Tomasz Stanislawski @ 2013-11-27 13:26 UTC (permalink / raw)
To: linux-arm-kernel
Add exynos-phy driver to support a single register
PHY interfaces present on Exynos4 SoC.
Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
drivers/phy/Kconfig | 5 ++
drivers/phy/Makefile | 1 +
drivers/phy/exynos-phy.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 158 insertions(+)
create mode 100644 drivers/phy/exynos-phy.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index a344f3d..4414c73 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -51,4 +51,9 @@ config PHY_EXYNOS_DP_VIDEO
help
Support for Display Port PHY found on Samsung EXYNOS SoCs.
+config EXYNOS_PHY
+ tristate "Exynos PHY driver"
+ help
+ Support for PHY controllers on SoCs from Exynos family.
+
endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index d0caae9..b2a833d 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -5,5 +5,6 @@
obj-$(CONFIG_GENERIC_PHY) += phy-core.o
obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o
obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
+obj-$(CONFIG_EXYNOS_PHY) += exynos-phy.o
obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o
diff --git a/drivers/phy/exynos-phy.c b/drivers/phy/exynos-phy.c
new file mode 100644
index 0000000..5a1ae6d
--- /dev/null
+++ b/drivers/phy/exynos-phy.c
@@ -0,0 +1,152 @@
+/*
+ * Exynos PHY driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Tomasz Stanislawski <t.stanislaws@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/of_device.h>
+#include <linux/phy/phy.h>
+
+#define EXYNOS_PHY_ENABLE (1 << 0)
+
+static int exynos_phy_power_on(struct phy *phy)
+{
+ void __iomem *reg = phy_get_drvdata(phy);
+ u32 val;
+
+ val = readl(reg);
+ val |= EXYNOS_PHY_ENABLE;
+ writel(val, reg);
+
+ return 0;
+}
+
+static int exynos_phy_power_off(struct phy *phy)
+{
+ void __iomem *reg = phy_get_drvdata(phy);
+ u32 val;
+
+ val = readl(reg);
+ val &= ~EXYNOS_PHY_ENABLE;
+ writel(val, reg);
+
+ return 0;
+}
+
+static struct phy_ops exynos_phy_ops = {
+ .power_on = exynos_phy_power_on,
+ .power_off = exynos_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static const u32 exynos4210_offsets[] = {
+ 0x0700, /* HDMI_PHY */
+ 0x070C, /* DAC_PHY */
+ 0x0718, /* ADC_PHY */
+ 0x071C, /* PCIE_PHY */
+ 0x0720, /* SATA_PHY */
+ ~0, /* end mark */
+};
+
+static const u32 exynos4412_offsets[] = {
+ 0x0700, /* HDMI_PHY */
+ 0x0718, /* ADC_PHY */
+ ~0, /* end mark */
+};
+
+static const struct of_device_id exynos_phy_of_match[] = {
+ { .compatible = "exynos4210-phy", .data = exynos4210_offsets},
+ { .compatible = "exynos4412-phy", .data = exynos4412_offsets},
+ { },
+};
+MODULE_DEVICE_TABLE(of, exynos_phy_of_match);
+
+static struct phy *exynos_phy_xlate(struct device *dev,
+ struct of_phandle_args *args)
+{
+ struct phy **phys = dev_get_drvdata(dev);
+ int index = args->args[0];
+ int i;
+
+ /* verify if index is valid */
+ for (i = 0; i <= index; ++i)
+ if (!phys[i])
+ return ERR_PTR(-ENODEV);
+
+ return phys[index];
+}
+
+static int exynos_phy_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *of_id = of_match_device(
+ of_match_ptr(exynos_phy_of_match), &pdev->dev);
+ const u32 *offsets = of_id->data;
+ int count;
+ struct device *dev = &pdev->dev;
+ struct phy **phys;
+ struct resource *res;
+ void __iomem *regs;
+ int i;
+ struct phy_provider *phy_provider;
+
+ /* count number of phys to create */
+ for (count = 0; offsets[count] != ~0; ++count)
+ ;
+
+ phys = devm_kzalloc(dev, (count + 1) * sizeof(phys[0]), GFP_KERNEL);
+ if (!phys)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, phys);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ regs = devm_ioremap(dev, res->start, res->end);
+ if (IS_ERR(regs)) {
+ dev_err(dev, "failed to ioremap registers\n");
+ return PTR_ERR(regs);
+ }
+
+ /* NOTE: last entry in phys[] is NULL */
+ for (i = 0; i < count; ++i) {
+ phys[i] = devm_phy_create(dev, &exynos_phy_ops, NULL);
+ if (IS_ERR(phys[i])) {
+ dev_err(dev, "failed to create PHY %d\n", i);
+ return PTR_ERR(phys[i]);
+ }
+ phy_set_drvdata(phys[i], regs + offsets[i]);
+ }
+
+ phy_provider = devm_of_phy_provider_register(dev, exynos_phy_xlate);
+ if (IS_ERR(phy_provider)) {
+ dev_err(dev, "failed to register PHY provider\n");
+ return PTR_ERR(phy_provider);
+ }
+
+ dev_info(dev, "added %d phys\n", count);
+
+ return 0;
+}
+
+static struct platform_driver exynos_phy_driver = {
+ .probe = exynos_phy_probe,
+ .driver = {
+ .of_match_table = exynos_phy_of_match,
+ .name = "exynos-phy",
+ .owner = THIS_MODULE,
+ }
+};
+module_platform_driver(exynos_phy_driver);
+
+MODULE_DESCRIPTION("Exynos PHY driver");
+MODULE_AUTHOR("Tomasz Stanislawski <t.stanislaws@samsung.com>");
+MODULE_LICENSE("GPL v2");
--
1.7.9.5
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH] phy: Add exynos-phy driver
2013-11-27 13:26 [PATCH] phy: Add exynos-phy driver Tomasz Stanislawski
2013-11-27 13:26 ` Tomasz Stanislawski
@ 2013-12-11 9:54 ` Kishon Vijay Abraham I
2013-12-11 10:16 ` Sylwester Nawrocki
1 sibling, 1 reply; 5+ messages in thread
From: Kishon Vijay Abraham I @ 2013-12-11 9:54 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
On Wednesday 27 November 2013 06:56 PM, Tomasz Stanislawski wrote:
> Hello everyone,
> The Samsung SoCs from Exynos family are enhanced with a bunch of switches
> dedicated for IP blocks. Those switches are called PHYs in Exynos
> specification. They are usually controlled by a single bit in a single
> one-word-long register.
So only enabling this switch is enough for the controller or some other actual
PHY IP is needed along with this switch?
However I'm not sure if the switch should be modelled as PHY as it is not a PHY
in the real sense.
Thanks
Kishon
>
> A IP driver has to control such a switch in an abstract manner. Therefore,
> such 'enablers' were implemented as clocks in older versions of Linux kernel.
> With the dawn of PHY subsystems, PHYs become a natural way of exporting the
> 'enabler' functionality to drivers. However, there is an unexpected
> consequence. Some of those 1-bit PHYs were implemented as separate drivers.
> This means that one has to create a struct device, struct phy, its phy provider
> and 100-150 lines of driver code to basically set one bit.
>
> The DP phy driver is a good example:
> https://lkml.org/lkml/2013/7/18/53
>
> And simple-phy RFC (shares only driver code but not other resources):
> https://lkml.org/lkml/2013/10/21/313
>
> To avoid waste of resources I propose to create all such 1-bit phys from Exynos
> SoC using a single device, driver and phy provider.
>
> This patchset contains a proposed solution.
>
> All comment are welcome.
>
> Hopefully in future the functionality introduced by this patch may be merged
> into a larger Power Management Unit (PMU) gluer driver. On Samsusng SoC , the
> PMU part contains a number of register barely linked to power management (like
> clock gating, clock dividers, CPU resetting, etc.). It may be tempting to
> create a hybrid driver that export clocks/phys/etc that are controlled by PMU
> unit.
>
> Regards,
> Tomasz Stanislawski
>
> Tomasz Stanislawski (1):
> phy: Add exynos-phy driver
>
> drivers/phy/Kconfig | 5 ++
> drivers/phy/Makefile | 1 +
> drivers/phy/exynos-phy.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 158 insertions(+)
> create mode 100644 drivers/phy/exynos-phy.c
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] phy: Add exynos-phy driver
2013-12-11 9:54 ` Kishon Vijay Abraham I
@ 2013-12-11 10:16 ` Sylwester Nawrocki
2013-12-13 11:22 ` Kishon Vijay Abraham I
0 siblings, 1 reply; 5+ messages in thread
From: Sylwester Nawrocki @ 2013-12-11 10:16 UTC (permalink / raw)
To: linux-arm-kernel
On 11/12/13 10:54, Kishon Vijay Abraham I wrote:
> On Wednesday 27 November 2013 06:56 PM, Tomasz Stanislawski wrote:
>> > Hello everyone,
>> > The Samsung SoCs from Exynos family are enhanced with a bunch of switches
>> > dedicated for IP blocks. Those switches are called PHYs in Exynos
>> > specification. They are usually controlled by a single bit in a single
>> > one-word-long register.
>
> So only enabling this switch is enough for the controller or some other actual
> PHY IP is needed along with this switch?
>
> However I'm not sure if the switch should be modelled as PHY as it is not a PHY
> in the real sense.
These are ordinary PHY devices embedded in an SoC. I wouldn't really call
them "switches", as they indeed provide the physical layer functionality
for various interfaces, like USB, HDMI, MIPI CSI/DSI, etc. Their control
interface is often very simple - usually only an enable and a reset
control bit. But that can't change the fact they are real PHY devices,
so let's not call them switches, that's just untrue.
Regards,
Sylwester
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] phy: Add exynos-phy driver
2013-12-11 10:16 ` Sylwester Nawrocki
@ 2013-12-13 11:22 ` Kishon Vijay Abraham I
0 siblings, 0 replies; 5+ messages in thread
From: Kishon Vijay Abraham I @ 2013-12-13 11:22 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
On Wednesday 11 December 2013 03:46 PM, Sylwester Nawrocki wrote:
> On 11/12/13 10:54, Kishon Vijay Abraham I wrote:
>> On Wednesday 27 November 2013 06:56 PM, Tomasz Stanislawski wrote:
>>>> Hello everyone,
>>>> The Samsung SoCs from Exynos family are enhanced with a bunch of switches
>>>> dedicated for IP blocks. Those switches are called PHYs in Exynos
>>>> specification. They are usually controlled by a single bit in a single
>>>> one-word-long register.
>>
>> So only enabling this switch is enough for the controller or some other actual
>> PHY IP is needed along with this switch?
>>
>> However I'm not sure if the switch should be modelled as PHY as it is not a PHY
>> in the real sense.
>
> These are ordinary PHY devices embedded in an SoC. I wouldn't really call
> them "switches", as they indeed provide the physical layer functionality
> for various interfaces, like USB, HDMI, MIPI CSI/DSI, etc. Their control
Are they used along with the phy IPs for which Kamil and others have sent
patches or this is used in different SoCs from what Kamil uses?
Thanks
Kishon
> interface is often very simple - usually only an enable and a reset
> control bit. But that can't change the fact they are real PHY devices,
> so let's not call them switches, that's just untrue.
>
> Regards,
> Sylwester
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-12-13 11:22 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-27 13:26 [PATCH] phy: Add exynos-phy driver Tomasz Stanislawski
2013-11-27 13:26 ` Tomasz Stanislawski
2013-12-11 9:54 ` Kishon Vijay Abraham I
2013-12-11 10:16 ` Sylwester Nawrocki
2013-12-13 11:22 ` Kishon Vijay Abraham I
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).