blob: 0f689f182dd63dbddcdfc6fd3c720bd13c609664 [file] [log] [blame]
/*
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __MACH_CLOCK_GENERIC_H
#define __MACH_CLOCK_GENERIC_H
#include <mach/clk-provider.h>
/* ==================== Mux clock ==================== */
struct clk_src {
struct clk *src;
int sel;
};
struct mux_clk;
struct clk_mux_ops {
int (*set_mux_sel)(struct mux_clk *clk, int sel);
int (*get_mux_sel)(struct mux_clk *clk);
/* Optional */
bool (*is_enabled)(struct mux_clk *clk);
int (*enable)(struct mux_clk *clk);
void (*disable)(struct mux_clk *clk);
};
#define MUX_SRC_LIST(...) \
.parents = (struct clk_src[]){__VA_ARGS__}, \
.num_parents = ARRAY_SIZE(((struct clk_src[]){__VA_ARGS__}))
struct mux_clk {
/* Parents in decreasing order of preference for obtaining rates. */
struct clk_src *parents;
int num_parents;
struct clk *safe_parent;
int safe_sel;
struct clk_mux_ops *ops;
/* Fields not used by helper function. */
void *const __iomem *base;
u32 offset;
u32 mask;
u32 shift;
u32 en_mask;
void *priv;
struct clk c;
};
static inline struct mux_clk *to_mux_clk(struct clk *c)
{
return container_of(c, struct mux_clk, c);
}
extern struct clk_ops clk_ops_gen_mux;
/* ==================== Divider clock ==================== */
struct div_clk;
struct clk_div_ops {
int (*set_div)(struct div_clk *clk, int div);
int (*get_div)(struct div_clk *clk);
/* Optional */
bool (*is_enabled)(struct div_clk *clk);
int (*enable)(struct div_clk *clk);
void (*disable)(struct div_clk *clk);
};
struct div_clk {
unsigned int div;
unsigned int min_div;
unsigned int max_div;
unsigned long rate_margin;
struct clk_div_ops *ops;
/* Fields not used by helper function. */
void *const __iomem *base;
u32 offset;
u32 mask;
u32 shift;
u32 en_mask;
void *priv;
struct clk c;
};
static inline struct div_clk *to_div_clk(struct clk *c)
{
return container_of(c, struct div_clk, c);
}
extern struct clk_ops clk_ops_div;
extern struct clk_ops clk_ops_slave_div;
#define DEFINE_FIXED_DIV_CLK(clk_name, _div, _parent) \
static struct div_clk clk_name = { \
.div = _div, \
.c = { \
.parent = _parent, \
.dbg_name = #clk_name, \
.ops = &clk_ops_div, \
CLK_INIT(clk_name.c), \
} \
}
#define DEFINE_FIXED_SLAVE_DIV_CLK(clk_name, _div, _parent) \
static struct div_clk clk_name = { \
.div = _div, \
.c = { \
.parent = _parent, \
.dbg_name = #clk_name, \
.ops = &clk_ops_slave_div, \
CLK_INIT(clk_name.c), \
} \
}
#endif