Skip to content

Commit

Permalink
CLK: TI: add interface clock support for OMAP3
Browse files Browse the repository at this point in the history
OMAP3 has interface clocks in addition to functional clocks, which
require special handling for the autoidle and idle status register
offsets mainly.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
  • Loading branch information
Tero Kristo authored and Mike Turquette committed Jan 17, 2014
1 parent 45622e2 commit 24582b3
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 5 deletions.
54 changes: 54 additions & 0 deletions Documentation/devicetree/bindings/clock/ti/interface.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
Binding for Texas Instruments interface clock.

Binding status: Unstable - ABI compatibility may be broken in the future

This binding uses the common clock binding[1]. This clock is
quite much similar to the basic gate-clock [2], however,
it supports a number of additional features, including
companion clock finding (match corresponding functional gate
clock) and hardware autoidle enable / disable.

[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] Documentation/devicetree/bindings/clock/gate-clock.txt

Required properties:
- compatible : shall be one of:
"ti,omap3-interface-clock" - basic OMAP3 interface clock
"ti,omap3-no-wait-interface-clock" - interface clock which has no hardware
capability for waiting clock to be ready
"ti,omap3-hsotgusb-interface-clock" - interface clock with USB specific HW
handling
"ti,omap3-dss-interface-clock" - interface clock with DSS specific HW handling
"ti,omap3-ssi-interface-clock" - interface clock with SSI specific HW handling
"ti,am35xx-interface-clock" - interface clock with AM35xx specific HW handling
- #clock-cells : from common clock binding; shall be set to 0
- clocks : link to phandle of parent clock
- reg : base address for the control register

Optional properties:
- ti,bit-shift : bit shift for the bit enabling/disabling the clock (default 0)

Examples:
aes1_ick: aes1_ick@48004a14 {
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clocks = <&security_l4_ick2>;
reg = <0x48004a14 0x4>;
ti,bit-shift = <3>;
};

cam_ick: cam_ick@48004f10 {
#clock-cells = <0>;
compatible = "ti,omap3-no-wait-interface-clock";
clocks = <&l4_ick>;
reg = <0x48004f10 0x4>;
ti,bit-shift = <0>;
};

ssi_ick_3430es2: ssi_ick_3430es2@48004a10 {
#clock-cells = <0>;
compatible = "ti,omap3-ssi-interface-clock";
clocks = <&ssi_l4_ick>;
reg = <0x48004a10 0x4>;
ti,bit-shift = <0>;
};
5 changes: 0 additions & 5 deletions arch/arm/mach-omap2/clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,15 +270,10 @@ extern struct clk dummy_ck;

extern const struct clk_hw_omap_ops clkhwops_iclk_wait;
extern const struct clk_hw_omap_ops clkhwops_wait;
extern const struct clk_hw_omap_ops clkhwops_iclk;
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait;
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait;
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait;
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait;
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait;
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait;
extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait;
extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait;
extern const struct clk_hw_omap_ops clkhwops_apll54;
extern const struct clk_hw_omap_ops clkhwops_apll96;
extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll;
Expand Down
1 change: 1 addition & 0 deletions drivers/clk/ti/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ obj-y += clk.o autoidle.o clockdomain.o
clk-common = dpll.o composite.o divider.o gate.o \
fixed-factor.o mux.o apll.o
obj-$(CONFIG_SOC_AM33XX) += $(clk-common) clk-33xx.o
obj-$(CONFIG_ARCH_OMAP3) += $(clk-common) interface.o
obj-$(CONFIG_ARCH_OMAP4) += $(clk-common) clk-44xx.o
obj-$(CONFIG_SOC_OMAP5) += $(clk-common) clk-54xx.o
obj-$(CONFIG_SOC_DRA7XX) += $(clk-common) clk-7xx.o
Expand Down
125 changes: 125 additions & 0 deletions drivers/clk/ti/interface.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* OMAP interface clock support
*
* Copyright (C) 2013 Texas Instruments, Inc.
*
* Tero Kristo <t-kristo@ti.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <linux/clk-provider.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/clk/ti.h>

#undef pr_fmt
#define pr_fmt(fmt) "%s: " fmt, __func__

static const struct clk_ops ti_interface_clk_ops = {
.init = &omap2_init_clk_clkdm,
.enable = &omap2_dflt_clk_enable,
.disable = &omap2_dflt_clk_disable,
.is_enabled = &omap2_dflt_clk_is_enabled,
};

static void __init _of_ti_interface_clk_setup(struct device_node *node,
const struct clk_hw_omap_ops *ops)
{
struct clk *clk;
struct clk_init_data init = { NULL };
struct clk_hw_omap *clk_hw;
const char *parent_name;
u32 val;

clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
if (!clk_hw)
return;

clk_hw->hw.init = &init;
clk_hw->ops = ops;
clk_hw->flags = MEMMAP_ADDRESSING;

clk_hw->enable_reg = ti_clk_get_reg_addr(node, 0);
if (!clk_hw->enable_reg)
goto cleanup;

if (!of_property_read_u32(node, "ti,bit-shift", &val))
clk_hw->enable_bit = val;

init.name = node->name;
init.ops = &ti_interface_clk_ops;
init.flags = 0;

parent_name = of_clk_get_parent_name(node, 0);
if (!parent_name) {
pr_err("%s must have a parent\n", node->name);
goto cleanup;
}

init.num_parents = 1;
init.parent_names = &parent_name;

clk = clk_register(NULL, &clk_hw->hw);

if (!IS_ERR(clk)) {
of_clk_add_provider(node, of_clk_src_simple_get, clk);
omap2_init_clk_hw_omap_clocks(clk);
return;
}

cleanup:
kfree(clk_hw);
}

static void __init of_ti_interface_clk_setup(struct device_node *node)
{
_of_ti_interface_clk_setup(node, &clkhwops_iclk_wait);
}
CLK_OF_DECLARE(ti_interface_clk, "ti,omap3-interface-clock",
of_ti_interface_clk_setup);

static void __init of_ti_no_wait_interface_clk_setup(struct device_node *node)
{
_of_ti_interface_clk_setup(node, &clkhwops_iclk);
}
CLK_OF_DECLARE(ti_no_wait_interface_clk, "ti,omap3-no-wait-interface-clock",
of_ti_no_wait_interface_clk_setup);

static void __init of_ti_hsotgusb_interface_clk_setup(struct device_node *node)
{
_of_ti_interface_clk_setup(node,
&clkhwops_omap3430es2_iclk_hsotgusb_wait);
}
CLK_OF_DECLARE(ti_hsotgusb_interface_clk, "ti,omap3-hsotgusb-interface-clock",
of_ti_hsotgusb_interface_clk_setup);

static void __init of_ti_dss_interface_clk_setup(struct device_node *node)
{
_of_ti_interface_clk_setup(node,
&clkhwops_omap3430es2_iclk_dss_usbhost_wait);
}
CLK_OF_DECLARE(ti_dss_interface_clk, "ti,omap3-dss-interface-clock",
of_ti_dss_interface_clk_setup);

static void __init of_ti_ssi_interface_clk_setup(struct device_node *node)
{
_of_ti_interface_clk_setup(node, &clkhwops_omap3430es2_iclk_ssi_wait);
}
CLK_OF_DECLARE(ti_ssi_interface_clk, "ti,omap3-ssi-interface-clock",
of_ti_ssi_interface_clk_setup);

static void __init of_ti_am35xx_interface_clk_setup(struct device_node *node)
{
_of_ti_interface_clk_setup(node, &clkhwops_am35xx_ipss_wait);
}
CLK_OF_DECLARE(ti_am35xx_interface_clk, "ti,am35xx-interface-clock",
of_ti_am35xx_interface_clk_setup);
5 changes: 5 additions & 0 deletions include/linux/clk/ti.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@ extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
extern const struct clk_hw_omap_ops clkhwops_wait;
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait;
extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait;
extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait;
extern const struct clk_hw_omap_ops clkhwops_iclk;
extern const struct clk_hw_omap_ops clkhwops_iclk_wait;
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait;
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait;
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait;

#endif

0 comments on commit 24582b3

Please sign in to comment.