* [PATCH v4 0/4] PWM changes for rk3288-evb
@ 2014-08-20 18:53 Doug Anderson
[not found] ` <1408560842-3746-1-git-send-email-dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2014-08-20 18:54 ` [PATCH v4 2/4] ARM: rockchip: rk3288: Switch to use the proper PWM IP Doug Anderson
0 siblings, 2 replies; 3+ messages in thread
From: Doug Anderson @ 2014-08-20 18:53 UTC (permalink / raw)
To: Heiko Stuebner, Thierry Reding, Caesar Wang
Cc: Sonny Rao, olof, Eddie Cai, Dmitry Torokhov, Doug Anderson,
mark.rutland, linux-pwm, linux, pawel.moll, ijc+devicetree,
linux-kernel, robh+dt, devicetree, galak, linux-arm-kernel
These patches enable the PWM backlight for the rk3288-evb board.
There were tested by watching the backlight grow from off to max with
the following instructions:
cd /sys/class/backlight/backlight*/
for i in $(seq 255); do echo $i > brightness; sleep .01; done
The first patch switches PWM cells from 2 to 3 on rk3288. I think it
could land in Thierry's tree. This patch will break backward
compatibility for rk3288 until changes land handling PWM cells more
dynamically, but since there are no rk3288 boards shipping yet it
seems OK.
The second patch enables the proper IP. This will also break backward
compatibility, but again should be OK since there are no users. If
needed we could make the "grf" optional and assume any shipping boards
enabled the bit in their bootloader. I think this could land in
Thierry's tree with Heiko's ACK.
The 3rd and 4th patches are DTS ones. They could land in Heiko's tree
after the first two patches. They are based atop his current WIP 3.18
dts tree. Note that instantiating the PWM backlight will cause the
system to hang unless Heiko's (clk: rockchip: protect critical clocks
from getting disabled) <patchwork.kernel.org/patch/4725391> is landed.
There are no compile time or runtime dependencies between these
patches except that patch #3 needs to come before patch #4. ...and of
course the PWM won't work without all 4 patches.
Changes in v4:
- Updated comment not to add caveats about pwm_cells 3.
- rockchip_pwm_set_polarity() is now static.
- Separate pwm_ops for v1 and v2; no set_polarity() in v1.
- Added a blank line.
- Totally rewrote to go in the PWM driver.
- Reordered IP switch to be atop invert patch.
- Add rockchip,grf to pwm nodes.
Changes in v3:
- Don't store a private copy of polarity.
- Use true instead of 1.
- Cleanup init order with "has_invert".
- Fix space to tab in 2 places in DTS.
- Make sure PWM is upper case in prose.
Changes in v2:
- Check for failed ioremap()
Doug Anderson (4):
pwm: rockchip: Allow polarity invert on rk3288
ARM: rockchip: rk3288: Switch to use the proper PWM IP
ARM: dts: Add main PWM info to rk3288
ARM: dts: Enable PWM backlight on rk3288-evb
.../devicetree/bindings/pwm/pwm-rockchip.txt | 8 +-
arch/arm/boot/dts/rk3288-evb.dtsi | 53 +++++++++++++
arch/arm/boot/dts/rk3288.dtsi | 72 ++++++++++++++++++
drivers/pwm/pwm-rockchip.c | 86 +++++++++++++++++++---
4 files changed, 208 insertions(+), 11 deletions(-)
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v4 1/4] pwm: rockchip: Allow polarity invert on rk3288
[not found] ` <1408560842-3746-1-git-send-email-dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
@ 2014-08-20 18:53 ` Doug Anderson
0 siblings, 0 replies; 3+ messages in thread
From: Doug Anderson @ 2014-08-20 18:53 UTC (permalink / raw)
To: Heiko Stuebner, Thierry Reding, Caesar Wang
Cc: Sonny Rao, olof-nZhT3qVonbNeoWH0uzbU5w, Eddie Cai,
Dmitry Torokhov, Doug Anderson, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, linux-pwm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
The rk3288 has the ability to invert the polarity of the PWM. Let's
enable that ability. Note that this increases pwm_cells to 3 for
rk3288.
Signed-off-by: Doug Anderson <dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
---
Changes in v4:
- Updated comment not to add caveats about pwm_cells 3.
- rockchip_pwm_set_polarity() is now static.
- Separate pwm_ops for v1 and v2; no set_polarity() in v1.
- Added a blank line.
Changes in v3:
- Don't store a private copy of polarity.
- Use true instead of 1.
- Cleanup init order with "has_invert".
Changes in v2: None
.../devicetree/bindings/pwm/pwm-rockchip.txt | 4 +-
drivers/pwm/pwm-rockchip.c | 57 ++++++++++++++++++----
2 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt b/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
index d47d15a..b8be3d0 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
@@ -7,8 +7,8 @@ Required properties:
"rockchip,vop-pwm": found integrated in VOP on RK3288 SoC
- reg: physical base address and length of the controller's registers
- clocks: phandle and clock specifier of the PWM reference clock
- - #pwm-cells: should be 2. See pwm.txt in this directory for a
- description of the cell format.
+ - #pwm-cells: must be 2 (rk2928) or 3 (rk3288). See pwm.txt in this directory
+ for a description of the cell format.
Example:
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index bdd8644..9442df2 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -24,7 +24,9 @@
#define PWM_ENABLE (1 << 0)
#define PWM_CONTINUOUS (1 << 1)
#define PWM_DUTY_POSITIVE (1 << 3)
+#define PWM_DUTY_NEGATIVE (0 << 3)
#define PWM_INACTIVE_NEGATIVE (0 << 4)
+#define PWM_INACTIVE_POSITIVE (1 << 4)
#define PWM_OUTPUT_LEFT (0 << 5)
#define PWM_LP_DISABLE (0 << 8)
@@ -45,8 +47,10 @@ struct rockchip_pwm_regs {
struct rockchip_pwm_data {
struct rockchip_pwm_regs regs;
unsigned int prescaler;
+ const struct pwm_ops *ops;
- void (*set_enable)(struct pwm_chip *chip, bool enable);
+ void (*set_enable)(struct pwm_chip *chip,
+ struct pwm_device *pwm, bool enable);
};
static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *c)
@@ -54,7 +58,8 @@ static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *c)
return container_of(c, struct rockchip_pwm_chip, chip);
}
-static void rockchip_pwm_set_enable_v1(struct pwm_chip *chip, bool enable)
+static void rockchip_pwm_set_enable_v1(struct pwm_chip *chip,
+ struct pwm_device *pwm, bool enable)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
u32 enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
@@ -70,14 +75,19 @@ static void rockchip_pwm_set_enable_v1(struct pwm_chip *chip, bool enable)
writel_relaxed(val, pc->base + pc->data->regs.ctrl);
}
-static void rockchip_pwm_set_enable_v2(struct pwm_chip *chip, bool enable)
+static void rockchip_pwm_set_enable_v2(struct pwm_chip *chip,
+ struct pwm_device *pwm, bool enable)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
u32 enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
- PWM_CONTINUOUS | PWM_DUTY_POSITIVE |
- PWM_INACTIVE_NEGATIVE;
+ PWM_CONTINUOUS;
u32 val;
+ if (pwm->polarity == PWM_POLARITY_INVERSED)
+ enable_conf |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSITIVE;
+ else
+ enable_conf |= PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE;
+
val = readl_relaxed(pc->base + pc->data->regs.ctrl);
if (enable)
@@ -124,6 +134,19 @@ static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
return 0;
}
+static int rockchip_pwm_set_polarity(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ enum pwm_polarity polarity)
+{
+ /*
+ * No action needed here because pwm->polarity will be set by the core
+ * and the core will only change polarity when the PWM is not enabled.
+ * We'll handle things in set_enable().
+ */
+
+ return 0;
+}
+
static int rockchip_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
@@ -133,7 +156,7 @@ static int rockchip_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
if (ret)
return ret;
- pc->data->set_enable(chip, true);
+ pc->data->set_enable(chip, pwm, true);
return 0;
}
@@ -142,18 +165,26 @@ static void rockchip_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
- pc->data->set_enable(chip, false);
+ pc->data->set_enable(chip, pwm, false);
clk_disable(pc->clk);
}
-static const struct pwm_ops rockchip_pwm_ops = {
+static const struct pwm_ops rockchip_pwm_ops_v1 = {
.config = rockchip_pwm_config,
.enable = rockchip_pwm_enable,
.disable = rockchip_pwm_disable,
.owner = THIS_MODULE,
};
+static const struct pwm_ops rockchip_pwm_ops_v2 = {
+ .config = rockchip_pwm_config,
+ .set_polarity = rockchip_pwm_set_polarity,
+ .enable = rockchip_pwm_enable,
+ .disable = rockchip_pwm_disable,
+ .owner = THIS_MODULE,
+};
+
static const struct rockchip_pwm_data pwm_data_v1 = {
.regs = {
.duty = 0x04,
@@ -162,6 +193,7 @@ static const struct rockchip_pwm_data pwm_data_v1 = {
.ctrl = 0x0c,
},
.prescaler = 2,
+ .ops = &rockchip_pwm_ops_v1,
.set_enable = rockchip_pwm_set_enable_v1,
};
@@ -173,6 +205,7 @@ static const struct rockchip_pwm_data pwm_data_v2 = {
.ctrl = 0x0c,
},
.prescaler = 1,
+ .ops = &rockchip_pwm_ops_v2,
.set_enable = rockchip_pwm_set_enable_v2,
};
@@ -184,6 +217,7 @@ static const struct rockchip_pwm_data pwm_data_vop = {
.ctrl = 0x00,
},
.prescaler = 1,
+ .ops = &rockchip_pwm_ops_v2,
.set_enable = rockchip_pwm_set_enable_v2,
};
@@ -227,10 +261,15 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
pc->data = id->data;
pc->chip.dev = &pdev->dev;
- pc->chip.ops = &rockchip_pwm_ops;
+ pc->chip.ops = pc->data->ops;
pc->chip.base = -1;
pc->chip.npwm = 1;
+ if (pc->data->ops->set_polarity) {
+ pc->chip.of_xlate = of_pwm_xlate_with_flags;
+ pc->chip.of_pwm_n_cells = 3;
+ }
+
ret = pwmchip_add(&pc->chip);
if (ret < 0) {
clk_unprepare(pc->clk);
--
2.1.0.rc2.206.gedb03e5
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v4 2/4] ARM: rockchip: rk3288: Switch to use the proper PWM IP
2014-08-20 18:53 [PATCH v4 0/4] PWM changes for rk3288-evb Doug Anderson
[not found] ` <1408560842-3746-1-git-send-email-dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
@ 2014-08-20 18:54 ` Doug Anderson
1 sibling, 0 replies; 3+ messages in thread
From: Doug Anderson @ 2014-08-20 18:54 UTC (permalink / raw)
To: Heiko Stuebner, Thierry Reding, Caesar Wang
Cc: Sonny Rao, olof, Eddie Cai, Dmitry Torokhov, Doug Anderson,
robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
linux-pwm, devicetree, linux-kernel, linux-arm-kernel
The rk3288 SoC has an option to switch all of the PWMs in the system
between the old IP block and the new IP block. The rk3288 PWM driver
is written for the new block, so make sure that we enable the new
block in the GRF (general register file) when the PWM driver probes.
We emulate the solution to this problem used in i2c-rk3x.c. One
difference for the PWM is that there's a single "enable new IP" that's
used for all 4 PWMs. That means we set this bit 4 times if we've got
all 4 PWMs enabled. That shouldn't hurt.
Signed-off-by: Doug Anderson <dianders@chromium.org>
---
Changes in v4:
- Totally rewrote to go in the PWM driver.
- Reordered IP switch to be atop invert patch.
Changes in v3: None
Changes in v2:
- Check for failed ioremap()
.../devicetree/bindings/pwm/pwm-rockchip.txt | 4 +++
drivers/pwm/pwm-rockchip.c | 29 ++++++++++++++++++++++
2 files changed, 33 insertions(+)
diff --git a/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt b/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
index b8be3d0..39190ec 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
@@ -10,6 +10,10 @@ Required properties:
- #pwm-cells: must be 2 (rk2928) or 3 (rk3288). See pwm.txt in this directory
for a description of the cell format.
+Required for "rockchip,rk3288-pwm":
+ - rockchip,grf : the phandle of the syscon node for the general register
+ file (GRF)
+
Example:
pwm0: pwm@20030000 {
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 9442df2..08cbde6 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -16,7 +16,12 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
+#include <linux/regmap.h>
#include <linux/time.h>
+#include <linux/mfd/syscon.h>
+
+#define RK3288_GRF_PWM_ENABLE_OFFSET 0x024c
+#define RK3288_GRF_PWM_ENABLE_BIT 0
#define PWM_CTRL_TIMER_EN (1 << 0)
#define PWM_CTRL_OUTPUT_EN (1 << 3)
@@ -231,6 +236,7 @@ MODULE_DEVICE_TABLE(of, rockchip_pwm_dt_ids);
static int rockchip_pwm_probe(struct platform_device *pdev)
{
+ struct device_node *np = pdev->dev.of_node;
const struct of_device_id *id;
struct rockchip_pwm_chip *pc;
struct resource *r;
@@ -240,6 +246,29 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
if (!id)
return -EINVAL;
+ /*
+ * Switch to new interface on rk3288.
+ * The control bit is located in the GRF register space.
+ */
+ if (of_device_is_compatible(np, "rockchip,rk3288-pwm")) {
+ struct regmap *grf;
+
+ grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+ if (IS_ERR(grf)) {
+ dev_err(&pdev->dev, "Missing rockchip,grf property\n");
+ return PTR_ERR(grf);
+ }
+
+ /* Set bit 16 for write mask, 0 for switch to new IP */
+ ret = regmap_write(grf, RK3288_GRF_PWM_ENABLE_OFFSET,
+ BIT(RK3288_GRF_PWM_ENABLE_BIT + 16) |
+ BIT(RK3288_GRF_PWM_ENABLE_BIT));
+ if (ret != 0) {
+ dev_err(&pdev->dev, "Could not access GRF: %d\n", ret);
+ return ret;
+ }
+ }
+
pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
if (!pc)
return -ENOMEM;
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-08-20 18:54 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-20 18:53 [PATCH v4 0/4] PWM changes for rk3288-evb Doug Anderson
[not found] ` <1408560842-3746-1-git-send-email-dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2014-08-20 18:53 ` [PATCH v4 1/4] pwm: rockchip: Allow polarity invert on rk3288 Doug Anderson
2014-08-20 18:54 ` [PATCH v4 2/4] ARM: rockchip: rk3288: Switch to use the proper PWM IP Doug Anderson
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).