diff --git a/platform/msm/common/clock.c b/platform/msm/common/clock.c new file mode 100644 index 000000000..87bec1d45 --- /dev/null +++ b/platform/msm/common/clock.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2012, 2014-2015, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of The Linux Foundation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +static struct clk_list msm_clk_list; + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + if (!clk->ops->set_parent) + return 0; + + return clk->ops->set_parent(clk, parent); +} + +struct clk *clk_get_parent(struct clk *clk) +{ + if (!clk->ops->get_parent) + return NULL; + + return clk->ops->get_parent(clk); +} + +int clk_reset(struct clk *clk, enum clk_reset_action action) +{ + if (!clk) + return 0; + + if (!clk->ops->reset) + return 0; + + return clk->ops->reset(clk, action); +} + +/* + * Standard clock functions defined in include/clk.h + */ +int clk_enable(struct clk *clk) +{ + int ret = 0; + struct clk *parent; + + if (!clk) + return 0; + + if (clk->count == 0) { + parent = clk_get_parent(clk); + ret = clk_enable(parent); + if (ret) + goto out; + + if (clk->ops->enable) + ret = clk->ops->enable(clk); + if (ret) { + clk_disable(parent); + goto out; + } + } + clk->count++; +out: + return ret; +} + +void clk_disable(struct clk *clk) +{ + struct clk *parent; + + if (!clk) + return; + + if (clk->count == 0) + goto out; + if (clk->count == 1) { + if (clk->ops->disable) + clk->ops->disable(clk); + parent = clk_get_parent(clk); + clk_disable(parent); + } + clk->count--; +out: + return; +} + +unsigned long clk_get_rate(struct clk *clk) +{ + if (!clk->ops->get_rate) + return 0; + + return clk->ops->get_rate(clk); +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + if (!clk->ops->set_rate) + return ERR_NOT_VALID; + + return clk->ops->set_rate(clk, rate); +} + +void clk_init(struct clk_lookup *clist, unsigned num) +{ + if(clist && num) + { + msm_clk_list.clist = (struct clk_lookup *)clist; + msm_clk_list.num = num; + } +} + +struct clk *clk_get (const char * cid) +{ + unsigned i; + struct clk_lookup *cl= msm_clk_list.clist; + unsigned num = msm_clk_list.num; + + if(!cl || !num) + { + dprintf (CRITICAL, "Alert!! clock list not defined!\n"); + return NULL; + } + for(i=0; i < num; i++, cl++) + { + if(!strcmp(cl->con_id, cid)) + { + return cl->clk; + } + } + + dprintf(CRITICAL, "Alert!! Requested clock \"%s\" is not supported!\n", cid); + return NULL; +} + +int clk_get_set_enable(char *id, unsigned long rate, bool enable) +{ + int ret = NO_ERROR; + struct clk *cp; + + /* Get clk */ + cp = clk_get(id); + if(!cp) + { + dprintf(CRITICAL, "Can't find clock with id: %s\n", id); + ret = ERR_NOT_VALID; + goto get_set_enable_error; + } + + /* Set rate */ + if(rate) + { + ret = clk_set_rate(cp, rate); + if(ret) + { + dprintf(CRITICAL, "Clock set rate failed.\n"); + goto get_set_enable_error; + } + } + + /* Enable clock */ + if(enable) + { + ret = clk_enable(cp); + if(ret) + { + dprintf(CRITICAL, "Clock enable failed.\n"); + } + } + +get_set_enable_error: + return ret; +} + +#ifdef DEBUG_CLOCK +struct clk_list *clk_get_list(void) +{ + return &msm_clk_list; +} +#endif diff --git a/platform/msm/common/clock_lib2.c b/platform/msm/common/clock_lib2.c new file mode 100644 index 000000000..bba15febb --- /dev/null +++ b/platform/msm/common/clock_lib2.c @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of The Linux Foundation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +/*=============== CXO clock ops =============*/ +int cxo_clk_enable(struct clk *clk) +{ + /* Nothing to do. */ + return 0; +} + +void cxo_clk_disable(struct clk *clk) +{ + /* Nothing to do. */ + return; +} + + +/*=============== Branch clock ops =============*/ + +/* Branch clock enable */ +int clock_lib2_branch_clk_enable(struct clk *clk) +{ + int rc = 0; + uint32_t cbcr_val; + int retry = 100; + struct branch_clk *bclk = to_branch_clk(clk); + + cbcr_val = readl(bclk->cbcr_reg); + cbcr_val |= CBCR_BRANCH_ENABLE_BIT; + writel(cbcr_val, bclk->cbcr_reg); + + /* Some clocks do not need to check the enable status, return + * if the halt_check is not set + */ + if (!bclk->halt_check) + return rc; + + /* wait until status shows it is enabled */ + while(readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT) + { + /* Add 100 ms of time out, bail out if the clock is not enable + * within 100 ms */ + if (!retry) + { + rc = 1; + break; + } + retry--; + mdelay(1); + } + + return rc; +} + +/* Branch clock disable */ +void clock_lib2_branch_clk_disable(struct clk *clk) +{ + uint32_t cbcr_val; + struct branch_clk *bclk = to_branch_clk(clk); + + cbcr_val = readl(bclk->cbcr_reg); + cbcr_val &= ~CBCR_BRANCH_ENABLE_BIT; + writel(cbcr_val, bclk->cbcr_reg); + + if (!bclk->no_halt_check_on_disable) + /* wait until status shows it is disabled */ + while(!(readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT)); +} + +/* Branch clock set rate */ +int clock_lib2_branch_set_rate(struct clk *c, unsigned rate) +{ + struct branch_clk *branch = to_branch_clk(c); + + if (!branch->has_sibling) + return clk_set_rate(branch->parent, rate); + + return -1; +} + + +/*=============== Root clock ops =============*/ + +/* Root enable */ +int clock_lib2_rcg_enable(struct clk *c) +{ + /* Hardware feedback from branch enable results in root being enabled. + * Nothing to do here. + */ + + return 0; +} + +/* Root set rate: + * Find the entry in the frequecy table corresponding to the requested rate. + * Enable the source clock required for the new frequency. + * Call the set_rate function defined for this particular root clock. + */ +int clock_lib2_rcg_set_rate(struct clk *c, unsigned rate) +{ + struct rcg_clk *rclk = to_rcg_clk(c); + struct clk_freq_tbl *nf; /* new freq */ + int rc = 0; + + /* ck if new freq is in table */ + for (nf = rclk->freq_tbl; nf->freq_hz != FREQ_END + && nf->freq_hz != rate; nf++) + ; + + /* Frequency not found in the table */ + if (nf->freq_hz == FREQ_END) + return ERR_INVALID_ARGS; + + /* Check if frequency is actually changed. */ + if (nf == rclk->current_freq) + return rc; + + /* First enable the source clock for this freq. */ + clk_enable(nf->src_clk); + + /* Perform clock-specific frequency switch operations. */ + ASSERT(rclk->set_rate); + rclk->set_rate(rclk, nf); + + /* update current freq */ + rclk->current_freq = nf; + + return rc; +} + +/* root update config: informs h/w to start using the new config values */ +static void clock_lib2_rcg_update_config(struct rcg_clk *rclk) +{ + uint32_t cmd; + + cmd = readl(rclk->cmd_reg); + cmd |= CMD_UPDATE_BIT; + writel(cmd, rclk->cmd_reg); + + /* Wait for frequency to be updated. */ + while(readl(rclk->cmd_reg) & CMD_UPDATE_MASK); +} + +/* root set rate for clocks with half integer and MND divider */ +void clock_lib2_rcg_set_rate_mnd(struct rcg_clk *rclk, struct clk_freq_tbl *freq) +{ + uint32_t cfg; + + /* Program MND values */ + writel(freq->m_val, rclk->m_reg); + writel(freq->n_val, rclk->n_reg); + writel(freq->d_val, rclk->d_reg); + + /* setup src select and divider */ + cfg = readl(rclk->cfg_reg); + cfg &= ~(CFG_SRC_SEL_MASK | CFG_SRC_DIV_MASK | CFG_MODE_MASK); + cfg |= freq->div_src_val; + if(freq->n_val !=0) + { + cfg |= (CFG_MODE_DUAL_EDGE << CFG_MODE_OFFSET); + } + writel(cfg, rclk->cfg_reg); + + /* Inform h/w to start using the new config. */ + clock_lib2_rcg_update_config(rclk); +} + +/* root set rate for clocks with half integer divider */ +void clock_lib2_rcg_set_rate_hid(struct rcg_clk *rclk, struct clk_freq_tbl *freq) +{ + uint32_t cfg; + + /* setup src select and divider */ + cfg = readl(rclk->cfg_reg); + cfg &= ~(CFG_SRC_SEL_MASK | CFG_SRC_DIV_MASK); + cfg |= freq->div_src_val; + writel(cfg, rclk->cfg_reg); + + clock_lib2_rcg_update_config(rclk); +} + +/*=============== Vote clock ops =============*/ + +/* Vote clock enable */ +int clock_lib2_vote_clk_enable(struct clk *c) +{ + uint32_t vote_regval; + uint32_t val; + struct vote_clk *vclk = to_local_vote_clk(c); + + vote_regval = readl(vclk->vote_reg); + vote_regval |= vclk->en_mask; + writel_relaxed(vote_regval, vclk->vote_reg); + do { + val = readl(vclk->cbcr_reg); + val &= BRANCH_CHECK_MASK; + } + /* wait until status shows it is enabled */ + while((val != BRANCH_ON_VAL) && (val != BRANCH_NOC_FSM_ON_VAL)); + + return 0; +} + +/* Vote clock disable */ +void clock_lib2_vote_clk_disable(struct clk *c) +{ + uint32_t vote_regval; + struct vote_clk *vclk = to_local_vote_clk(c); + + vote_regval = readl(vclk->vote_reg); + vote_regval &= ~vclk->en_mask; + writel_relaxed(vote_regval, vclk->vote_reg); +} + +/* Reset clock */ +static int __clock_lib2_branch_clk_reset(uint32_t bcr_reg, enum clk_reset_action action) +{ + uint32_t reg; + int ret = 0; + + reg = readl(bcr_reg); + + switch (action) { + case CLK_RESET_ASSERT: + reg |= (1<<0); + break; + case CLK_RESET_DEASSERT: + reg &= ~(1<<0); + break; + default: + ret = 1; + } + + writel(reg, bcr_reg); + + /* Wait for writes to go through */ + DMB; + + return ret; +} + +int clock_lib2_reset_clk_reset(struct clk *c, enum clk_reset_action action) +{ + struct reset_clk *rst = to_reset_clk(c); + + if (!rst) + return 0; + + return __clock_lib2_branch_clk_reset(rst->bcr_reg, action); +} + +int clock_lib2_branch_clk_reset(struct clk *c, enum clk_reset_action action) +{ + struct branch_clk *bclk = to_branch_clk(c); + + if (!bclk) + return 0; + + return __clock_lib2_branch_clk_reset((uint32_t)bclk->bcr_reg, action); +} diff --git a/platform/msm/common/clock_pll.c b/platform/msm/common/clock_pll.c new file mode 100644 index 000000000..e7f3fe371 --- /dev/null +++ b/platform/msm/common/clock_pll.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of The Linux Foundation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +/* + * pll_vote_clk functions + */ +int pll_vote_clk_enable(struct clk *clk) +{ + uint32_t ena; + struct pll_vote_clk *pll = to_pll_vote_clk(clk); + + ena = readl_relaxed(pll->en_reg); + ena |= pll->en_mask; + writel_relaxed(ena, pll->en_reg); + + /* Wait until PLL is enabled */ + while ((readl_relaxed(pll->status_reg) & pll->status_mask) == 0); + + return 0; +} + +void pll_vote_clk_disable(struct clk *clk) +{ + uint32_t ena; + struct pll_vote_clk *pll = to_pll_vote_clk(clk); + + ena = readl_relaxed(pll->en_reg); + ena &= ~(pll->en_mask); + writel_relaxed(ena, pll->en_reg); +} + +unsigned pll_vote_clk_get_rate(struct clk *clk) +{ + struct pll_vote_clk *pll = to_pll_vote_clk(clk); + return pll->rate; +} + +struct clk *pll_vote_clk_get_parent(struct clk *clk) +{ + struct pll_vote_clk *pll = to_pll_vote_clk(clk); + return pll->parent; +} + +int pll_vote_clk_is_enabled(struct clk *clk) +{ + struct pll_vote_clk *pll = to_pll_vote_clk(clk); + return !!(readl_relaxed(pll->status_reg) & pll->status_mask); +} + +/* + * PLLs functions + */ +int pll_clk_enable(struct clk *clk) +{ + uint32_t mode; + struct pll_clk *pll = to_pll_clk(clk); + + mode = readl_relaxed(pll->mode_reg); + /* Disable PLL bypass mode. */ + mode |= (1<<1); + writel_relaxed(mode, pll->mode_reg); + + /* + * H/W requires a 5us delay between disabling the bypass and + * de-asserting the reset. Delay 10us just to be safe. + */ + udelay(10); + + /* De-assert active-low PLL reset. */ + mode |= (1<<2); + writel_relaxed(mode, pll->mode_reg); + + /* Wait until PLL is locked. */ + udelay(50); + + /* Enable PLL output. */ + mode |= (1<<0); + writel_relaxed(mode, pll->mode_reg); + + return 0; +} + +void pll_clk_disable(struct clk *clk) +{ + uint32_t mode; + struct pll_clk *pll = to_pll_clk(clk); + + /* + * Disable the PLL output, disable test mode, enable + * the bypass mode, and assert the reset. + */ + mode = readl_relaxed(pll->mode_reg); + mode &= ~BM(3, 0); + writel_relaxed(mode, pll->mode_reg); +} + +unsigned pll_clk_get_rate(struct clk *clk) +{ + struct pll_clk *pll = to_pll_clk(clk); + return pll->rate; +} + +struct clk *pll_clk_get_parent(struct clk *clk) +{ + struct pll_clk *pll = to_pll_clk(clk); + return pll->parent; +} + diff --git a/platform/msm/common/debug.c b/platform/msm/common/debug.c new file mode 100644 index 000000000..0bd33f2c3 --- /dev/null +++ b/platform/msm/common/debug.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2016, 2018-2019, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google, Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +int platform_dgetc(char *c, bool wait) +{ + int n; + n = uart_getc(0, 0); + if (n < 0) { + return -1; + } else { + *c = n; + return 0; + } +} + +void platform_dputc(char c) +{ + uart_putc(0, c); +} diff --git a/platform/msm/common/include/blsp_qup.h b/platform/msm/common/include/blsp_qup.h new file mode 100644 index 000000000..990df67c8 --- /dev/null +++ b/platform/msm/common/include/blsp_qup.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2012-2013,2015, The Linux Foundation. All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __BLSP_QUP_H_ +#define __BLSP_QUP_H_ + +typedef enum { + QUP_ID_0 = 0, + QUP_ID_1, + QUP_ID_2, + QUP_ID_3, + QUP_ID_4, + QUP_ID_5, +} qup_instance; + +typedef enum { + BLSP_ID_1 = 1, + BLSP_ID_2, +} blsp_instance; + +#endif /* __BLSP_QUP_H_ */ diff --git a/platform/msm/common/include/clock.h b/platform/msm/common/include/clock.h new file mode 100644 index 000000000..868999705 --- /dev/null +++ b/platform/msm/common/include/clock.h @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2012, 2014, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of The Linux Foundation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CLOCK_H +#define CLOCK_H + +#include + +#undef readl_relaxed +#undef writel_relaxed + +#ifdef MSM_SECURE_IO +#define readl_relaxed secure_readl +#define writel_relaxed secure_writel +#else +#define readl_relaxed readl +#define writel_relaxed writel +#endif + +enum clk_reset_action { + CLK_RESET_DEASSERT = 0, + CLK_RESET_ASSERT = 1 +}; + +struct clk; +struct clk_ops { + int (*enable)(struct clk *clk); + void (*disable)(struct clk *clk); + void (*auto_off)(struct clk *clk); + int (*reset)(struct clk *clk, enum clk_reset_action action); + int (*set_rate)(struct clk *clk, unsigned rate); + int (*set_min_rate)(struct clk *clk, unsigned rate); + int (*set_max_rate)(struct clk *clk, unsigned rate); + int (*set_flags)(struct clk *clk, unsigned flags); + unsigned (*get_rate)(struct clk *clk); + int (*list_rate)(struct clk *clk, unsigned n); + int (*is_enabled)(struct clk *clk); + long (*round_rate)(struct clk *clk, unsigned rate); + int (*set_parent)(struct clk *clk, struct clk *parent); + struct clk *(*get_parent)(struct clk *clk); + bool (*is_local)(struct clk *clk); +}; + +/** + * struct clk + * @count: enable refcount + * @lock: protects clk_enable()/clk_disable() path and @count + */ +struct clk { + uint32_t flags; + uint32_t rate; + struct clk_ops *ops; + const char *dbg_name; + unsigned count; +}; + +/** + * clk_get - lookup and obtain a reference to a clock producer. + * @dev: device for clock "consumer" + * @id: clock comsumer ID + * + * Returns a struct clk corresponding to the clock producer, or + * valid IS_ERR() condition containing errno. The implementation + * uses @dev and @id to determine the clock consumer, and thereby + * the clock producer. (IOW, @id may be identical strings, but + * clk_get may return different clock producers depending on @dev.) + * + * Drivers must assume that the clock source is not enabled. + * + * clk_get should not be called from within interrupt context. + */ +struct clk *clk_get(const char *id); + + +/** + * clk_enable - inform the system when the clock source should be running. + * @clk: clock source + * + * If the clock can not be enabled/disabled, this should return success. + * + * Returns success (0) or negative errno. + */ +int clk_enable(struct clk *clk); + +/** + * clk_disable - inform the system when the clock source is no longer required. + * @clk: clock source + * + * Inform the system that a clock source is no longer required by + * a driver and may be shut down. + * + * Implementation detail: if the clock source is shared between + * multiple drivers, clk_enable() calls must be balanced by the + * same number of clk_disable() calls for the clock source to be + * disabled. + */ +void clk_disable(struct clk *clk); + +/** + * clk_get_rate - obtain the current clock rate (in Hz) for a clock source. + * This is only valid once the clock source has been enabled. + * @clk: clock source + */ +unsigned long clk_get_rate(struct clk *clk); + +/** + * clk_set_rate - set the clock rate for a clock source + * @clk: clock source + * @rate: desired clock rate in Hz + * + * Returns success (0) or negative errno. + */ +int clk_set_rate(struct clk *clk, unsigned long rate); + +/** + * clk_set_parent - set the parent clock source for this clock + * @clk: clock source + * @parent: parent clock source + * + * Returns success (0) or negative errno. + */ +int clk_set_parent(struct clk *clk, struct clk *parent); + +/** + * clk_get_parent - get the parent clock source for this clock + * @clk: clock source + * + * Returns struct clk corresponding to parent clock source, or + * valid IS_ERR() condition containing errno. + */ +struct clk *clk_get_parent(struct clk *clk); + +/** + * clk_get_set_enable - + * -- get the clock. + * -- set the rate to @rate if @rate is non-zero + * -- enable the clock if @enable = ture; + * @id: clock identifier (char *) + * @rate: desired clock rate in Hz + * + * Returns success (0) or negative errno. + */ +int clk_get_set_enable(char *id, unsigned long rate, bool enable); + +struct clk_lookup { + const char *con_id; + struct clk *clk; +}; + +struct clk_list { + struct clk_lookup *clist; + unsigned num; +}; + +#define CLK_LOOKUP(con, c) { .con_id = con, .clk = &c } + +#ifdef DEBUG_CLOCK +struct clk_list *clk_get_list(void); +#endif + +/** + * clk_init - register all the clocks in the system. + * @clist: pointer to clock list + * @num: number of clocks in the list + */ +void clk_init(struct clk_lookup *clist, unsigned num); +/** + * clk_reset - Reset block using BCR + * @clk: pointer to clock + * @action: clock assert or deassert + */ +int clk_reset(struct clk *clk, enum clk_reset_action); +#endif diff --git a/platform/msm/common/include/clock_lib2.h b/platform/msm/common/include/clock_lib2.h new file mode 100644 index 000000000..61ee48319 --- /dev/null +++ b/platform/msm/common/include/clock_lib2.h @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2012-2014, Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Linux Foundation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __CLOCK_LIB2_H +#define __CLOCK_LIB2_H + +#include + +/* + * Bit manipulation macros + */ +#define BM(msb, lsb) (((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb) +#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb)) + +#define container_of(ptr, type, member) \ + ((type *)((addr_t)(ptr) - offsetof(type, member))) + +/* Frequency Macros */ +#define FREQ_END (UINT_MAX-1) +#define F_END \ + { \ + .freq_hz = FREQ_END, \ + } + +/* F(frequency, source, div, m, n) */ +#define F(f, s, div, m, n) \ + { \ + .freq_hz = (f), \ + .src_clk = &s##_clk_src.c, \ + .m_val = (m), \ + .n_val = ~((n)-(m)) * !!(n), \ + .d_val = ~(n),\ + .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \ + | BVAL(10, 8, s##_source_val), \ + } + +/* F(frequency, source, div, m, n) */ +#define F_EXT_SRC(f, s, div, m, n) \ + { \ + .freq_hz = (f), \ + .m_val = (m), \ + .n_val = ~((n)-(m)) * !!(n), \ + .d_val = ~(n),\ + .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \ + | BVAL(10, 8, s##_source_val), \ + } + +/* F_MM(frequency, source, div, m, n) */ +#define F_MM(f, s, div, m, n) \ + { \ + .freq_hz = (f), \ + .src_clk = &s##_clk_src.c, \ + .m_val = (m), \ + .n_val = ~((n)-(m)) * !!(n), \ + .d_val = ~(n),\ + .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \ + | BVAL(10, 8, s##_mm_source_val), \ + } + +#define F_MDSS(f, s, div, m, n) \ + { \ + .freq_hz = (f), \ + .m_val = (m), \ + .n_val = ~((n)-(m)) * !!(n), \ + .d_val = ~(n),\ + .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \ + | BVAL(10, 8, s##_mm_source_val), \ + } + +/* Branch Clock Bits */ +#define CBCR_BRANCH_ENABLE_BIT (1<<0) +#define CBCR_BRANCH_OFF_BIT (1<<31) +#define BRANCH_CHECK_MASK BM(31, 28) +#define BRANCH_ON_VAL BVAL(31, 28, 0x0) +#define BRANCH_NOC_FSM_ON_VAL BVAL(31, 28, 0x2) + +/* Root Clock Bits */ +#define CMD_UPDATE_BIT (1<<0) +#define CMD_UPDATE_MASK 1 + +#define CFG_SRC_DIV_OFFSET 0 +#define CFG_SRC_DIV_MASK (0x1F << CFG_SRC_DIV_OFFSET) + +#define CFG_SRC_SEL_OFFSET 8 +#define CFG_SRC_SEL_MASK (0x3 << CFG_SRC_SEL_OFFSET) + +#define CFG_MODE_DUAL_EDGE 0x2 + +#define CFG_MODE_OFFSET 12 +#define CFG_MODE_MASK (0x3 << CFG_MODE_OFFSET) + + +/* + * Generic frequency-definition structs and macros + */ +struct clk_freq_tbl { + + const uint32_t freq_hz; + struct clk *src_clk; + const uint32_t div_src_val; + + /* TODO: find out if sys_vdd is needed. */ + + const uint32_t m_val; + const uint32_t n_val; /* not_n_minus_m_val */ + const uint32_t d_val; /* not_2d_val */ +}; + +/* Fixed clock */ +struct fixed_clk { + struct clk c; +}; + +/* Branch clock */ +struct branch_clk { + + uint32_t *const bcr_reg; + uint32_t *const cbcr_reg; + + void (*set_rate)(struct branch_clk *, struct clk_freq_tbl *); + + struct clk *parent; + struct clk c; + + int has_sibling; + uint32_t cur_div; + uint32_t max_div; + uint32_t halt_check; + bool no_halt_check_on_disable; +}; + +/* Root Clock */ +struct rcg_clk { + + /* RCG registers for this clock */ + + uint32_t *const cmd_reg; /* Command reg */ + uint32_t *const cfg_reg; /* Config reg */ + uint32_t *const m_reg; /* m */ + uint32_t *const n_reg; /* not (n-m) */ + uint32_t *const d_reg; /* not (2d) */ + + /* set rate function for this clock */ + void (*set_rate)(struct rcg_clk *, struct clk_freq_tbl *); + + /* freq table */ + struct clk_freq_tbl *freq_tbl; + struct clk_freq_tbl *current_freq; + + struct clk c; +}; + +/* Vote Clock */ +struct vote_clk { + + uint32_t *const cbcr_reg; + uint32_t *const vote_reg; + uint32_t en_mask; + + struct clk c; +}; + +struct reset_clk { + uint32_t bcr_reg; + struct clk c; +}; + +static inline struct reset_clk *to_reset_clk(struct clk *clk) +{ + return container_of(clk, struct reset_clk, c); +} + +static inline struct rcg_clk *to_rcg_clk(struct clk *clk) +{ + return container_of(clk, struct rcg_clk, c); +} + +static inline struct branch_clk *to_branch_clk(struct clk *clk) +{ + return container_of(clk, struct branch_clk, c); +} + +static inline struct vote_clk *to_local_vote_clk(struct clk *clk) +{ + return container_of(clk, struct vote_clk, c); +} + +/* RCG clock functions */ +int clock_lib2_rcg_enable(struct clk *c); +int clock_lib2_rcg_set_rate(struct clk *c, unsigned rate); +void clock_lib2_rcg_set_rate_mnd(struct rcg_clk *rclk, struct clk_freq_tbl *freq); +void clock_lib2_rcg_set_rate_hid(struct rcg_clk *rclk, struct clk_freq_tbl *freq); + +/* CXO clock functions */ +int cxo_clk_enable(struct clk *clk); +void cxo_clk_disable(struct clk *clk); + +/* Branch clock functions */ +int clock_lib2_branch_clk_enable(struct clk *clk); +void clock_lib2_branch_clk_disable(struct clk *clk); +int clock_lib2_branch_set_rate(struct clk *c, unsigned rate); + +/* Vote clock functions*/ +int clock_lib2_vote_clk_enable(struct clk *c); +void clock_lib2_vote_clk_disable(struct clk *c); +/* clock reset function */ +int clock_lib2_reset_clk_reset(struct clk *c, enum clk_reset_action action); +int clock_lib2_branch_clk_reset(struct clk *c, enum clk_reset_action action); +#endif diff --git a/platform/msm/common/include/clock_pll.h b/platform/msm/common/include/clock_pll.h new file mode 100644 index 000000000..a606aa006 --- /dev/null +++ b/platform/msm/common/include/clock_pll.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2012,2015, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of The Linux Foundation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef CLOCK_PLL_H +#define CLOCK_PLL_H + +#include + +/* + * Bit manipulation macros + */ +#define BM(msb, lsb) (((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb) +#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb)) + +struct clk; +struct clk_ops; + +#define container_of(ptr, type, member) \ + ((type *)((addr_t)(ptr) - offsetof(type, member))) + + +/** + * struct pll_vote_clk - phase locked loop (HW voteable) + * @rate: output rate + * @en_reg: enable register + * @en_mask: ORed with @en_reg to enable the clock + * @status_reg: status register + * @parent: clock source + * @c: clk + */ +struct pll_vote_clk { + unsigned long rate; + + void *const en_reg; + const uint32_t en_mask; + + void *status_reg; + uint32_t status_mask; + + struct clk *parent; + struct clk c; +}; + +static inline struct pll_vote_clk *to_pll_vote_clk(struct clk *clk) +{ + return container_of(clk, struct pll_vote_clk, c); +} + +/** + * struct pll_clk - phase locked loop + * @rate: output rate + * @mode_reg: enable register + * @parent: clock source + * @c: clk + */ +struct pll_clk { + unsigned long rate; + + void *const mode_reg; + + struct clk *parent; + struct clk c; +}; + +static inline struct pll_clk *to_pll_clk(struct clk *clk) +{ + return container_of(clk, struct pll_clk, c); +} + +int pll_vote_clk_enable(struct clk *clk); +void pll_vote_clk_disable(struct clk *clk); +unsigned pll_vote_clk_get_rate(struct clk *clk); +struct clk *pll_vote_clk_get_parent(struct clk *clk); +int pll_vote_clk_is_enabled(struct clk *clk); + + +int pll_clk_enable(struct clk *clk); +void pll_clk_disable(struct clk *clk); +unsigned pll_clk_get_rate(struct clk *clk); +struct clk *pll_clk_get_parent(struct clk *clk); +#endif diff --git a/platform/msm/common/include/gpio.h b/platform/msm/common/include/gpio.h new file mode 100644 index 000000000..d95508c7f --- /dev/null +++ b/platform/msm/common/include/gpio.h @@ -0,0 +1,97 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _GPIO_H_ +#define _GPIO_H_ + +#include + +#define TLMM_PULL_MASK 0x3 +#define TLMM_HDRV_MASK 0x7 + +/* Current values for tlmm pins */ +typedef enum { + TLMM_CUR_VAL_2MA = 0x0, + TLMM_CUR_VAL_4MA, + TLMM_CUR_VAL_6MA, + TLMM_CUR_VAL_8MA, + TLMM_CUR_VAL_10MA, + TLMM_CUR_VAL_12MA, + TLMM_CUR_VAL_14MA, + TLMM_CUR_VAL_16MA, +} tlmm_drive_config; + +typedef enum { + TLMM_PULL_UP = 0x3, + TLMM_PULL_DOWN = 0x1, + TLMM_NO_PULL = 0x0, +} tlmm_pull_values; + +/* SDC Bit offsets in the TLMM register */ +typedef enum { + SDC1_DATA_HDRV_CTL_OFF = 0, + SDC1_CMD_HDRV_CTL_OFF = 3, + SDC1_CLK_HDRV_CTL_OFF = 6, + SDC1_DATA_PULL_CTL_OFF = 9, + SDC1_CMD_PULL_CTL_OFF = 11, + SDC1_CLK_PULL_CTL_OFF = 13, + SDC1_RCLK_PULL_CTL_OFF = 15, +} tlmm_sdc_drv_ctrl; + +/* EBI2 Bit offsets in the TLMM register */ +typedef enum { + EBI2_BUSY_HDRV_CTL_OFF = 29, + EBI2_WE_HDRV_CTL_OFF = 24, + EBI2_OE_HDRV_CTL_OFF = 9, + EBI2_CLE_HDRV_CTL_OFF = 19, + EBI2_ALE_HDRV_CTL_OFF = 14, + EBI2_CS_HDRV_CTL_OFF = 4, + EBI2_DATA_HDRV_CTL_OFF = 17, + EBI2_BUSY_PULL_CTL_OFF = 27, + EBI2_WE_PULL_CTL_OFF = 22, + EBI2_OE_PULL_CTL_OFF = 7 , + EBI2_CLE_PULL_CTL_OFF = 17, + EBI2_ALE_PULL_CTL_OFF = 12, + EBI2_CS_PULL_CTL_OFF = 2, + EBI2_DATA_PULL_CTL_OFF = 15, +} tlmm_ebi2_drv_ctrl; + +/* Input for the tlmm config function */ +struct tlmm_cfgs { + uint32_t off; /* Bit offeset in the register */ + uint8_t val; /* Current value */ + uint8_t mask; /* Mask for the clk/dat/cmd control */ + uint32_t reg; /* TLMM ping register */ +}; + +/* APIs: exposed for other drivers */ +/* API: Hdrive control for tlmm pins */ +void tlmm_set_hdrive_ctrl(struct tlmm_cfgs *, uint8_t); +/* API: Pull control for tlmm pins */ +void tlmm_set_pull_ctrl(struct tlmm_cfgs *, uint8_t); +#endif diff --git a/platform/msm/common/include/gsbi.h b/platform/msm/common/include/gsbi.h new file mode 100644 index 000000000..ce473dd3b --- /dev/null +++ b/platform/msm/common/include/gsbi.h @@ -0,0 +1,60 @@ +/* Copyright (c) 2011, The Linux Foundation. All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __GSBI_H_ +#define __GSBI_H_ + +#include + +/* GSBI Registers */ +#define GSBI_CTRL_REG(base) ((base) + 0x0) + +#define GSBI_CTRL_REG_PROTOCOL_CODE_S 4 +#define GSBI_PROTOCOL_CODE_I2C 0x2 +#define GSBI_PROTOCOL_CODE_SPI 0x3 +#define GSBI_PROTOCOL_CODE_UART_FLOW 0x4 +#define GSBI_PROTOCOL_CODE_I2C_UART 0x6 + +#define GSBI_HCLK_CTL_S 4 +#define GSBI_HCLK_CTL_CLK_ENA 0x1 + +enum { + GSBI_ID_1 = 1, + GSBI_ID_2, + GSBI_ID_3, + GSBI_ID_4, + GSBI_ID_5, + GSBI_ID_6, + GSBI_ID_7, + GSBI_ID_8, + GSBI_ID_9, + GSBI_ID_10, + GSBI_ID_11, + GSBI_ID_12, +}; + +#endif diff --git a/platform/msm/common/include/qgic.h b/platform/msm/common/include/qgic.h new file mode 100644 index 000000000..9bc66ff3e --- /dev/null +++ b/platform/msm/common/include/qgic.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011, 2014, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PLATFORM_MSM_SHARED_QGIC_H +#define __PLATFORM_MSM_SHARED_QGIC_H + +#include "qgic_common.h" +#include +#include +#include + +#define GIC_CPU_REG(off) (MSM_GIC_CPU_BASE + (off)) + +#define GIC_CPU_CTRL GIC_CPU_REG(0x00) +#define GIC_CPU_PRIMASK GIC_CPU_REG(0x04) +#define GIC_CPU_BINPOINT GIC_CPU_REG(0x08) +#define GIC_CPU_INTACK GIC_CPU_REG(0x0c) +#define GIC_CPU_EOI GIC_CPU_REG(0x10) +#define GIC_CPU_RUNNINGPRI GIC_CPU_REG(0x14) +#define GIC_CPU_HIGHPRI GIC_CPU_REG(0x18) + +#define INTERRUPT_LVL_N_TO_N 0x0 +#define INTERRUPT_LVL_1_TO_N 0x1 +#define INTERRUPT_EDGE_N_TO_N 0x2 +#define INTERRUPT_EDGE_1_TO_N 0x3 + +uint32_t qgic_read_iar(void); +void qgic_write_eoi(uint32_t); + +enum handler_return gic_platform_irq(struct arm_iframe *frame); +void gic_platform_fiq(struct arm_iframe *frame); +status_t gic_mask_interrupt(unsigned int vector); +status_t gic_unmask_interrupt(unsigned int vector); +void gic_register_int_handler(unsigned int vector, int_handler func, void *arg); +#endif diff --git a/platform/msm/common/include/qgic_common.h b/platform/msm/common/include/qgic_common.h new file mode 100644 index 000000000..431803d3d --- /dev/null +++ b/platform/msm/common/include/qgic_common.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011,2014 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PLATFORM_MSM_SHARED_QGIC_COMMON_H +#define __PLATFORM_MSM_SHARED_QGIC_COMMON_H + +#include +#include +#include + +#define GIC_DIST_REG(off) (MSM_GIC_DIST_BASE + (off)) + +#define GIC_DIST_CTRL GIC_DIST_REG(0x000) +#define GIC_DIST_CTR GIC_DIST_REG(0x004) +#define GIC_DIST_ENABLE_SET GIC_DIST_REG(0x100) +#define GIC_DIST_ENABLE_CLEAR GIC_DIST_REG(0x180) +#define GIC_DIST_PENDING_SET GIC_DIST_REG(0x200) +#define GIC_DIST_PENDING_CLEAR GIC_DIST_REG(0x280) +#define GIC_DIST_ACTIVE_BIT GIC_DIST_REG(0x300) +#define GIC_DIST_PRI GIC_DIST_REG(0x400) +#define GIC_DIST_TARGET GIC_DIST_REG(0x800) +#define GIC_DIST_CONFIG GIC_DIST_REG(0xc00) +#define GIC_DIST_SOFTINT GIC_DIST_REG(0xf00) + +struct ihandler { + int_handler func; + void *arg; +}; + +void qgic_init(void); +void qgic_dist_config(uint32_t); +void qgic_dist_init(void); +void qgic_cpu_init(void); +void qgic_change_interrupt_cfg(uint32_t spi_number, uint8_t type); +#endif diff --git a/platform/msm/common/include/qtimer.h b/platform/msm/common/include/qtimer.h new file mode 100644 index 000000000..0f457fe81 --- /dev/null +++ b/platform/msm/common/include/qtimer.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2012, The Linux Foundation. All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + + +#define QTMR_TIMER_CTRL_ENABLE (1 << 0) +#define QTMR_TIMER_CTRL_INT_MASK (1 << 1) + +#define QTMR_PHY_CNT_MAX_VALUE 0xFFFFFFFFFFFFFF + +void qtimer_set_physical_timer(lk_time_t msecs_interval, + platform_timer_callback tmr_callback, void *tmr_arg); +void qtimer_disable(void); +uint64_t qtimer_get_phy_timer_cnt(void); +uint32_t qtimer_current_time(void); +uint32_t qtimer_get_frequency(void); +void qtimer_uninit(void); +void qtimer_init(void); +uint32_t qtimer_tick_rate(void); +void udelay(unsigned usecs); +void mdelay(unsigned msecs); diff --git a/platform/msm/common/include/qtimer_mmap_hw.h b/platform/msm/common/include/qtimer_mmap_hw.h new file mode 100644 index 000000000..11dbcdc61 --- /dev/null +++ b/platform/msm/common/include/qtimer_mmap_hw.h @@ -0,0 +1,43 @@ + +/* Copyright (c) 2012, The Linux Foundation. All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PLATFORM_MSM_SHARED_QTMR_MMAP_H +#define __PLATFORM_MSM_SHARED_QRMR_MMAP_H + +#include + +#define QTMR_V1_CNTPCT_LO (0x00000000 + QTMR_BASE) +#define QTMR_V1_CNTPCT_HI (0x00000004 + QTMR_BASE) +#define QTMR_V1_CNTFRQ (0x00000010 + QTMR_BASE) +#define QTMR_V1_CNTP_CVAL_LO (0x00000020 + QTMR_BASE) +#define QTMR_V1_CNTP_CVAL_HI (0x00000024 + QTMR_BASE) +#define QTMR_V1_CNTP_TVAL (0x00000028 + QTMR_BASE) +#define QTMR_V1_CNTP_CTL (0x0000002C + QTMR_BASE) + +#endif diff --git a/platform/msm/common/include/uart_dm.h b/platform/msm/common/include/uart_dm.h new file mode 100644 index 000000000..1dd0aad45 --- /dev/null +++ b/platform/msm/common/include/uart_dm.h @@ -0,0 +1,269 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __UART_DM_H__ +#define __UART_DM_H__ + +#include + +#define MSM_BOOT_UART_DM_EXTR_BITS(value, start_pos, end_pos) \ + ((value << (32 - end_pos))\ + >> (32 - (end_pos - start_pos))) + +/* UART Parity Mode */ +enum MSM_BOOT_UART_DM_PARITY_MODE { + MSM_BOOT_UART_DM_NO_PARITY, + MSM_BOOT_UART_DM_ODD_PARITY, + MSM_BOOT_UART_DM_EVEN_PARITY, + MSM_BOOT_UART_DM_SPACE_PARITY +}; + +/* UART Stop Bit Length */ +enum MSM_BOOT_UART_DM_STOP_BIT_LEN { + MSM_BOOT_UART_DM_SBL_9_16, + MSM_BOOT_UART_DM_SBL_1, + MSM_BOOT_UART_DM_SBL_1_9_16, + MSM_BOOT_UART_DM_SBL_2 +}; + +/* UART Bits per Char */ +enum MSM_BOOT_UART_DM_BITS_PER_CHAR { + MSM_BOOT_UART_DM_5_BPS, + MSM_BOOT_UART_DM_6_BPS, + MSM_BOOT_UART_DM_7_BPS, + MSM_BOOT_UART_DM_8_BPS +}; + +/* 8-N-1 Configuration */ +#define MSM_BOOT_UART_DM_8_N_1_MODE (MSM_BOOT_UART_DM_NO_PARITY | \ + (MSM_BOOT_UART_DM_SBL_1 << 2) | \ + (MSM_BOOT_UART_DM_8_BPS << 4)) + +/* UART_DM Registers */ + +/* UART Operational Mode Register */ +#define MSM_BOOT_UART_DM_MR1(base) ((base) + 0x00) +#define MSM_BOOT_UART_DM_MR2(base) ((base) + 0x04) +#define MSM_BOOT_UART_DM_RXBRK_ZERO_CHAR_OFF (1 << 8) +#define MSM_BOOT_UART_DM_LOOPBACK (1 << 7) + +/* UART Clock Selection Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_CSR(base) ((base) + 0xA0) +#else +#define MSM_BOOT_UART_DM_CSR(base) ((base) + 0x08) +#endif + +/* UART DM TX FIFO Registers - 4 */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_TF(base, x) ((base) + 0x100+(4*(x))) +#else +#define MSM_BOOT_UART_DM_TF(base, x) ((base) + 0x70+(4*(x))) +#endif + +/* UART Command Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_CR(base) ((base) + 0xA8) +#else +#define MSM_BOOT_UART_DM_CR(base) ((base) + 0x10) +#endif +#define MSM_BOOT_UART_DM_CR_RX_ENABLE (1 << 0) +#define MSM_BOOT_UART_DM_CR_RX_DISABLE (1 << 1) +#define MSM_BOOT_UART_DM_CR_TX_ENABLE (1 << 2) +#define MSM_BOOT_UART_DM_CR_TX_DISABLE (1 << 3) + +/* UART Channel Command */ +#define MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x) ((x & 0x0f) << 4) +#define MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x) ((x >> 4 ) << 11 ) +#define MSM_BOOT_UART_DM_CR_CH_CMD(x) (MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x)\ + | MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x)) +#define MSM_BOOT_UART_DM_CMD_NULL MSM_BOOT_UART_DM_CR_CH_CMD(0) +#define MSM_BOOT_UART_DM_CMD_RESET_RX MSM_BOOT_UART_DM_CR_CH_CMD(1) +#define MSM_BOOT_UART_DM_CMD_RESET_TX MSM_BOOT_UART_DM_CR_CH_CMD(2) +#define MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT MSM_BOOT_UART_DM_CR_CH_CMD(3) +#define MSM_BOOT_UART_DM_CMD_RES_BRK_CHG_INT MSM_BOOT_UART_DM_CR_CH_CMD(4) +#define MSM_BOOT_UART_DM_CMD_START_BRK MSM_BOOT_UART_DM_CR_CH_CMD(5) +#define MSM_BOOT_UART_DM_CMD_STOP_BRK MSM_BOOT_UART_DM_CR_CH_CMD(6) +#define MSM_BOOT_UART_DM_CMD_RES_CTS_N MSM_BOOT_UART_DM_CR_CH_CMD(7) +#define MSM_BOOT_UART_DM_CMD_RES_STALE_INT MSM_BOOT_UART_DM_CR_CH_CMD(8) +#define MSM_BOOT_UART_DM_CMD_PACKET_MODE MSM_BOOT_UART_DM_CR_CH_CMD(9) +#define MSM_BOOT_UART_DM_CMD_MODE_RESET MSM_BOOT_UART_DM_CR_CH_CMD(C) +#define MSM_BOOT_UART_DM_CMD_SET_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(D) +#define MSM_BOOT_UART_DM_CMD_RES_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(E) +#define MSM_BOOT_UART_DM_CMD_RES_TX_ERR MSM_BOOT_UART_DM_CR_CH_CMD(10) +#define MSM_BOOT_UART_DM_CMD_CLR_TX_DONE MSM_BOOT_UART_DM_CR_CH_CMD(11) +#define MSM_BOOT_UART_DM_CMD_RES_BRKSTRT_INT MSM_BOOT_UART_DM_CR_CH_CMD(12) +#define MSM_BOOT_UART_DM_CMD_RES_BRKEND_INT MSM_BOOT_UART_DM_CR_CH_CMD(13) +#define MSM_BOOT_UART_DM_CMD_RES_PER_FRM_INT MSM_BOOT_UART_DM_CR_CH_CMD(14) + +/*UART General Command */ +#define MSM_BOOT_UART_DM_CR_GENERAL_CMD(x) ((x) << 8) + +#define MSM_BOOT_UART_DM_GCMD_NULL MSM_BOOT_UART_DM_CR_GENERAL_CMD(0) +#define MSM_BOOT_UART_DM_GCMD_CR_PROT_EN MSM_BOOT_UART_DM_CR_GENERAL_CMD(1) +#define MSM_BOOT_UART_DM_GCMD_CR_PROT_DIS MSM_BOOT_UART_DM_CR_GENERAL_CMD(2) +#define MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT MSM_BOOT_UART_DM_CR_GENERAL_CMD(3) +#define MSM_BOOT_UART_DM_GCMD_SW_FORCE_STALE MSM_BOOT_UART_DM_CR_GENERAL_CMD(4) +#define MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT MSM_BOOT_UART_DM_CR_GENERAL_CMD(5) +#define MSM_BOOT_UART_DM_GCMD_DIS_STALE_EVT MSM_BOOT_UART_DM_CR_GENERAL_CMD(6) + +/* UART Interrupt Mask Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_IMR(base) ((base) + 0xB0) +#else +#define MSM_BOOT_UART_DM_IMR(base) ((base) + 0x14) +#endif + +#define MSM_BOOT_UART_DM_TXLEV (1 << 0) +#define MSM_BOOT_UART_DM_RXHUNT (1 << 1) +#define MSM_BOOT_UART_DM_RXBRK_CHNG (1 << 2) +#define MSM_BOOT_UART_DM_RXSTALE (1 << 3) +#define MSM_BOOT_UART_DM_RXLEV (1 << 4) +#define MSM_BOOT_UART_DM_DELTA_CTS (1 << 5) +#define MSM_BOOT_UART_DM_CURRENT_CTS (1 << 6) +#define MSM_BOOT_UART_DM_TX_READY (1 << 7) +#define MSM_BOOT_UART_DM_TX_ERROR (1 << 8) +#define MSM_BOOT_UART_DM_TX_DONE (1 << 9) +#define MSM_BOOT_UART_DM_RXBREAK_START (1 << 10) +#define MSM_BOOT_UART_DM_RXBREAK_END (1 << 11) +#define MSM_BOOT_UART_DM_PAR_FRAME_ERR_IRQ (1 << 12) + +#define MSM_BOOT_UART_DM_IMR_ENABLED (MSM_BOOT_UART_DM_TX_READY | \ + MSM_BOOT_UART_DM_TXLEV | \ + MSM_BOOT_UART_DM_RXLEV | \ + MSM_BOOT_UART_DM_RXSTALE) + +/* UART Interrupt Programming Register */ +#define MSM_BOOT_UART_DM_IPR(base) ((base) + 0x18) +#define MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB 0x0f +#define MSM_BOOT_UART_DM_STALE_TIMEOUT_MSB 0 /* Not used currently */ + +/* UART Transmit/Receive FIFO Watermark Register */ +#define MSM_BOOT_UART_DM_TFWR(base) ((base) + 0x1C) +/* Interrupt is generated when FIFO level is less than or equal to this value */ +#define MSM_BOOT_UART_DM_TFW_VALUE 0 + +#define MSM_BOOT_UART_DM_RFWR(base) ((base) + 0x20) +/*Interrupt generated when no of words in RX FIFO is greater than this value */ +#define MSM_BOOT_UART_DM_RFW_VALUE 0 + +/* UART Hunt Character Register */ +#define MSM_BOOT_UART_DM_HCR(base) ((base) + 0x24) + +/* Used for RX transfer initialization */ +#define MSM_BOOT_UART_DM_DMRX(base) ((base) + 0x34) + +/* Default DMRX value - any value bigger than FIFO size would be fine */ +#define MSM_BOOT_UART_DM_DMRX_DEF_VALUE 0x220 + +/* Register to enable IRDA function */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_IRDA(base) ((base) + 0xB8) +#else +#define MSM_BOOT_UART_DM_IRDA(base) ((base) + 0x38) +#endif + +/* UART Data Mover Enable Register */ +#define MSM_BOOT_UART_DM_DMEN(base) ((base) + 0x3C) + +/* Number of characters for Transmission */ +#define MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base) ((base) + 0x040) + +/* UART RX FIFO Base Address */ +#define MSM_BOOT_UART_DM_BADR(base) ((base) + 0x44) + +/* UART Status Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_SR(base) ((base) + 0x0A4) +#else +#define MSM_BOOT_UART_DM_SR(base) ((base) + 0x008) +#endif +#define MSM_BOOT_UART_DM_SR_RXRDY (1 << 0) +#define MSM_BOOT_UART_DM_SR_RXFULL (1 << 1) +#define MSM_BOOT_UART_DM_SR_TXRDY (1 << 2) +#define MSM_BOOT_UART_DM_SR_TXEMT (1 << 3) +#define MSM_BOOT_UART_DM_SR_UART_OVERRUN (1 << 4) +#define MSM_BOOT_UART_DM_SR_PAR_FRAME_ERR (1 << 5) +#define MSM_BOOT_UART_DM_RX_BREAK (1 << 6) +#define MSM_BOOT_UART_DM_HUNT_CHAR (1 << 7) +#define MSM_BOOT_UART_DM_RX_BRK_START_LAST (1 << 8) + +/* UART Receive FIFO Registers - 4 in numbers */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_RF(base, x) ((base) + 0x140 + (4*(x))) +#else +#define MSM_BOOT_UART_DM_RF(base, x) ((base) + 0x70 + (4*(x))) +#endif + +/* UART Masked Interrupt Status Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_MISR(base) ((base) + 0xAC) +#else +#define MSM_BOOT_UART_DM_MISR(base) ((base) + 0x10) +#endif + +/* UART Interrupt Status Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_ISR(base) ((base) + 0xB4) +#else +#define MSM_BOOT_UART_DM_ISR(base) ((base) + 0x14) +#endif + +/* Number of characters received since the end of last RX transfer */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base) ((base) + 0xBC) +#else +#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base) ((base) + 0x38) +#endif + +/* UART TX FIFO Status Register */ +#define MSM_BOOT_UART_DM_TXFS(base) ((base) + 0x4C) +#define MSM_BOOT_UART_DM_TXFS_STATE_LSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x,0,6) +#define MSM_BOOT_UART_DM_TXFS_STATE_MSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x,14,31) +#define MSM_BOOT_UART_DM_TXFS_BUF_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x,7,9) +#define MSM_BOOT_UART_DM_TXFS_ASYNC_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x,10,13) + +/* UART RX FIFO Status Register */ +#define MSM_BOOT_UART_DM_RXFS(base) ((base) + 0x50) +#define MSM_BOOT_UART_DM_RXFS_STATE_LSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x,0,6) +#define MSM_BOOT_UART_DM_RXFS_STATE_MSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x,14,31) +#define MSM_BOOT_UART_DM_RXFS_BUF_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x,7,9) +#define MSM_BOOT_UART_DM_RXFS_ASYNC_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x,10,13) + +/* Macros for Common Errors */ +#define MSM_BOOT_UART_DM_E_SUCCESS 0 +#define MSM_BOOT_UART_DM_E_FAILURE 1 +#define MSM_BOOT_UART_DM_E_TIMEOUT 2 +#define MSM_BOOT_UART_DM_E_INVAL 3 +#define MSM_BOOT_UART_DM_E_MALLOC_FAIL 4 +#define MSM_BOOT_UART_DM_E_RX_NOT_READY 5 + +void uart_dm_init(uint8_t id, + uint32_t gsbi_base, + uint32_t uart_dm_base); +#endif /* __UART_DM_H__ */ diff --git a/platform/msm/common/interrupts.c b/platform/msm/common/interrupts.c new file mode 100644 index 000000000..4aec37e35 --- /dev/null +++ b/platform/msm/common/interrupts.c @@ -0,0 +1,60 @@ +/* Copyright (c) 2012, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + +extern int target_supports_qgic(void); + +enum handler_return platform_irq(struct arm_iframe *frame) +{ + return gic_platform_irq(frame); +} + +void platform_fiq(struct arm_iframe *frame) +{ + gic_platform_fiq(frame); +} + +status_t mask_interrupt(unsigned int vector) +{ + return gic_mask_interrupt(vector); +} + +status_t unmask_interrupt(unsigned int vector) +{ + return gic_unmask_interrupt(vector); +} + +void register_int_handler(unsigned int vector, int_handler func, void *arg) +{ + gic_register_int_handler(vector, func, arg); +} diff --git a/platform/msm/common/qgic.c b/platform/msm/common/qgic.c new file mode 100644 index 000000000..62fbdfa72 --- /dev/null +++ b/platform/msm/common/qgic.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2011,2014, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google, Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +static uint8_t qgic_get_cpumask(void) +{ + uint32_t mask=0, i; + + /* Fetch the CPU MASK from the SGI/PPI reg */ + for (i=0; i < 32; i += 4) { + mask = readl(GIC_DIST_TARGET + i); + mask |= mask >> 16; + mask |= mask >> 8; + if (mask) + break; + } + return mask; +} + +/* Intialize distributor */ +void qgic_dist_init(void) +{ + uint32_t i; + uint32_t num_irq = 0; + uint32_t cpumask; + + cpumask = qgic_get_cpumask(); + + cpumask |= cpumask << 8; + cpumask |= cpumask << 16; + + /* Disabling GIC */ + writel(0, GIC_DIST_CTRL); + + /* + * Find out how many interrupts are supported. + */ + num_irq = readl(GIC_DIST_CTR) & 0x1f; + num_irq = (num_irq + 1) * 32; + + /* Set up interrupts for this CPU */ + for (i = 32; i < num_irq; i += 4) + writel(cpumask, GIC_DIST_TARGET + i * 4 / 4); + + qgic_dist_config(num_irq); + + /*Enabling GIC */ + writel(1, GIC_DIST_CTRL); +} + +/* Intialize cpu specific controller */ +void qgic_cpu_init(void) +{ + writel(0xf0, GIC_CPU_PRIMASK); + writel(1, GIC_CPU_CTRL); +} + +uint32_t qgic_read_iar(void) +{ + return readl(GIC_CPU_INTACK); +} + +void qgic_write_eoi(uint32_t num) +{ + writel(num, GIC_CPU_EOI); +} diff --git a/platform/msm/common/qgic_common.c b/platform/msm/common/qgic_common.c new file mode 100644 index 000000000..49d05addb --- /dev/null +++ b/platform/msm/common/qgic_common.c @@ -0,0 +1,153 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Fundation, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include + +static struct ihandler handler[NR_IRQS]; + +/* Intialize distributor */ +void qgic_dist_config(uint32_t num_irq) +{ + uint32_t i; + + /* Set each interrupt line to use N-N software model + * and edge sensitive, active high + */ + for (i = 32; i < num_irq; i += 16) + writel(0xffffffff, GIC_DIST_CONFIG + i * 4 / 16); + + writel(0xffffffff, GIC_DIST_CONFIG + 4); + + /* Set priority of all interrupts */ + + /* + * In bootloader we dont care about priority so + * setting up equal priorities for all + */ + for (i = 0; i < num_irq; i += 4) + writel(0xa0a0a0a0, GIC_DIST_PRI + i * 4 / 4); + + /* Disabling interrupts */ + for (i = 0; i < num_irq; i += 32) + writel(0xffffffff, GIC_DIST_ENABLE_CLEAR + i * 4 / 32); + + writel(0x0000ffff, GIC_DIST_ENABLE_SET); +} + +/* Initialize QGIC. Called from platform specific init code */ +void qgic_init(void) +{ + qgic_dist_init(); + qgic_cpu_init(); +} + +/* IRQ handler */ +enum handler_return gic_platform_irq(struct arm_iframe *frame) +{ + uint32_t num; + enum handler_return ret; + + /* Read the interrupt number to be served*/ + num = qgic_read_iar(); + + if (num >= NR_IRQS) + return 0; + + ret = handler[num].func(handler[num].arg); + + /* End of interrupt */ + qgic_write_eoi(num); + + return ret; +} + +/* FIQ handler */ +void gic_platform_fiq(struct arm_iframe *frame) +{ + PANIC_UNIMPLEMENTED; +} + +/* Mask interrupt */ +status_t gic_mask_interrupt(unsigned int vector) +{ + uint32_t reg = GIC_DIST_ENABLE_CLEAR + (vector / 32) * 4; + uint32_t bit = 1 << (vector & 31); + + writel(bit, reg); + + return 0; +} + +/* Un-mask interrupt */ +status_t gic_unmask_interrupt(unsigned int vector) +{ + uint32_t reg = GIC_DIST_ENABLE_SET + (vector / 32) * 4; + uint32_t bit = 1 << (vector & 31); + + writel(bit, reg); + + return 0; +} + +/* Register interrupt handler */ +void gic_register_int_handler(unsigned int vector, int_handler func, void *arg) +{ + ASSERT(vector < NR_IRQS); + + THREAD_LOCK(state); + handler[vector].func = func; + handler[vector].arg = arg; + THREAD_UNLOCK(state); +} + +void qgic_change_interrupt_cfg(uint32_t spi_number, uint8_t type) +{ + uint32_t register_number, register_address, bit_number, value; + register_number = spi_number >> 4; // r = n DIV 16 + bit_number = (spi_number % 16) << 1; // b = (n MOD 16) * 2 + value = readl(GIC_DIST_CONFIG + (register_number << 2)); + // there are two bits per register to indicate the level + if (type == INTERRUPT_LVL_N_TO_N) + value &= ~((1< +#include +#include + +static uint32_t ticks_per_sec; + +status_t platform_set_periodic_timer(platform_timer_callback callback, + void *arg, lk_time_t interval) +{ + + THREAD_LOCK(state); + + qtimer_set_physical_timer(interval, callback, arg); + + THREAD_UNLOCK(state); + return 0; +} + +lk_time_t current_time(void) +{ + return qtimer_current_time(); +} + +void qtimer_uninit(void) +{ + qtimer_disable(); +} + +/* Blocking function to wait until the specified ticks of the timer. + * Note: ticks to wait for cannot be more than 56 bit. + * Should be sufficient for all practical purposes. + */ +static void delay(uint64_t ticks) +{ + volatile uint64_t cnt; + uint64_t init_cnt; + uint64_t timeout = 0; + + cnt = qtimer_get_phy_timer_cnt(); + init_cnt = cnt; + + /* Calculate timeout = cnt + ticks (mod 2^56) + * to account for timer counter wrapping + */ + timeout = (cnt + ticks) & (uint64_t)(QTMR_PHY_CNT_MAX_VALUE); + + /* Wait out till the counter wrapping occurs + * in cases where there is a wrapping. + */ + while(timeout < cnt && init_cnt <= cnt) + /* read global counter */ + cnt = qtimer_get_phy_timer_cnt(); + + /* Wait till the number of ticks is reached*/ + while(timeout > cnt) + /* read global counter */ + cnt = qtimer_get_phy_timer_cnt(); + +} + + +void mdelay(unsigned msecs) +{ + uint64_t ticks; + + ticks = ((uint64_t) msecs * ticks_per_sec) / 1000; + + delay(ticks); +} + +void udelay(unsigned usecs) +{ + uint64_t ticks; + + ticks = ((uint64_t) usecs * ticks_per_sec) / 1000000; + + delay(ticks); +} + +/* Return current time in micro seconds */ +lk_bigtime_t current_time_hires(void) +{ + return qtimer_current_time() * 1000000ULL; +} + +void qtimer_init(void) +{ + ticks_per_sec = qtimer_get_frequency(); +} + +uint32_t qtimer_tick_rate(void) +{ + return ticks_per_sec; +} diff --git a/platform/msm/common/qtimer_mmap.c b/platform/msm/common/qtimer_mmap.c new file mode 100644 index 000000000..3de6eb713 --- /dev/null +++ b/platform/msm/common/qtimer_mmap.c @@ -0,0 +1,147 @@ +/* Copyright (c) 2012, The Linux Foundation. All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static platform_timer_callback timer_callback; +static void *timer_arg; +static lk_time_t timer_interval; +/* time in ms from start of LK. */ +static volatile uint32_t current_time; +static uint32_t tick_count; + +static void qtimer_enable(void); + +static enum handler_return qtimer_irq(void *arg) +{ + current_time += timer_interval; + + /* Program the down counter again to get + * an interrupt after timer_interval msecs + */ + writel(tick_count, QTMR_V1_CNTP_TVAL); + DSB; + + return timer_callback(timer_arg, current_time); +} + + +/* Programs the Physical Secure Down counter timer. + * interval : Counter ticks till expiry interrupt is fired. + */ +void qtimer_set_physical_timer(lk_time_t msecs_interval, + platform_timer_callback tmr_callback, + void *tmr_arg) +{ + qtimer_disable(); + + /* Save the timer interval and call back data*/ + tick_count = msecs_interval * qtimer_tick_rate() / 1000;; + timer_interval = msecs_interval; + timer_arg = tmr_arg; + timer_callback = tmr_callback; + + /* Set Physical Down Counter */ + writel(tick_count, QTMR_V1_CNTP_TVAL); + DSB; + + register_int_handler(INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP, qtimer_irq, 0); + + unmask_interrupt(INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP); + + qtimer_enable(); +} + + +/* Function to return the frequency of the timer */ +uint32_t qtimer_get_frequency(void) +{ + uint32_t freq; + + /* Read the Global counter frequency */ + /* freq = readl(QTMR_V1_CNTFRQ); */ + /* TODO: remove this when bootchaint sets up the frequency. */ + freq = 19200000; + + return freq; +} + +static void qtimer_enable(void) +{ + uint32_t ctrl; + + ctrl = readl(QTMR_V1_CNTP_CTL); + + /* Program CTRL Register */ + ctrl |= QTMR_TIMER_CTRL_ENABLE; + ctrl &= ~QTMR_TIMER_CTRL_INT_MASK; + + writel(ctrl, QTMR_V1_CNTP_CTL); + DSB; +} + +void qtimer_disable(void) +{ + uint32_t ctrl; + + ctrl = readl(QTMR_V1_CNTP_CTL); + + /* program cntrl register */ + ctrl &= ~QTMR_TIMER_CTRL_ENABLE; + ctrl |= QTMR_TIMER_CTRL_INT_MASK; + + writel(ctrl, QTMR_V1_CNTP_CTL); + DSB; +} + +inline __ALWAYS_INLINE uint64_t qtimer_get_phy_timer_cnt(void) +{ + uint32_t phy_cnt_lo; + uint32_t phy_cnt_hi_1; + uint32_t phy_cnt_hi_2; + + do { + phy_cnt_hi_1 = readl(QTMR_V1_CNTPCT_HI); + phy_cnt_lo = readl(QTMR_V1_CNTPCT_LO); + phy_cnt_hi_2 = readl(QTMR_V1_CNTPCT_HI); + } while (phy_cnt_hi_1 != phy_cnt_hi_2); + + return ((uint64_t)phy_cnt_hi_1 << 32) | phy_cnt_lo; +} + +uint32_t qtimer_current_time(void) +{ + return current_time; +} diff --git a/platform/msm/common/rules.mk b/platform/msm/common/rules.mk new file mode 100644 index 000000000..44a8cc9db --- /dev/null +++ b/platform/msm/common/rules.mk @@ -0,0 +1,16 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR)/include + +MODULE_SRCS += \ + $(LOCAL_DIR)/clock.c \ + $(LOCAL_DIR)/clock_lib2.c \ + $(LOCAL_DIR)/clock_pll.c \ + $(LOCAL_DIR)/debug.c \ + $(LOCAL_DIR)/interrupts.c \ + $(LOCAL_DIR)/qgic.c \ + $(LOCAL_DIR)/qgic_common.c \ + $(LOCAL_DIR)/qtimer.c \ + $(LOCAL_DIR)/qtimer_mmap.c \ + $(LOCAL_DIR)/uart_dm.c \ diff --git a/platform/msm/common/uart_dm.c b/platform/msm/common/uart_dm.c new file mode 100644 index 000000000..6c33ceb3c --- /dev/null +++ b/platform/msm/common/uart_dm.c @@ -0,0 +1,469 @@ +/* Copyright (c) 2010-2012, 2014, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef NULL +#define NULL 0 +#endif + + +static int uart_init_flag = 0; + +/* Note: + * This is a basic implementation of UART_DM protocol. More focus has been + * given on simplicity than efficiency. Few of the things to be noted are: + * - RX path may not be suitable for multi-threaded scenaraio because of the + * use of static variables. TX path shouldn't have any problem though. If + * multi-threaded support is required, a simple data-structure can + * be maintained for each thread. + * - Right now we are using polling method than interrupt based. + * - We are using legacy UART protocol without Data Mover. + * - Not all interrupts and error events are handled. + * - While waiting Watchdog hasn't been taken into consideration. + */ + +#define NON_PRINTABLE_ASCII_CHAR 128 + +static uint8_t pack_chars_into_words(uint8_t *buffer, uint8_t cnt, uint32_t *word) +{ + uint8_t num_chars_writtten = 0; + + *word = 0; + + for(int j=0; j < cnt; j++) + { + if (buffer[num_chars_writtten] == '\n') + { + /* replace '\n' by the NON_PRINTABLE_ASCII_CHAR and print '\r'. + * While printing the NON_PRINTABLE_ASCII_CHAR, we will print '\n'. + * Thus successfully replacing '\n' by '\r' '\n'. + */ + *word |= ('\r' & 0xff) << (j * 8); + buffer[num_chars_writtten] = NON_PRINTABLE_ASCII_CHAR; + } + else + { + if (buffer[num_chars_writtten] == NON_PRINTABLE_ASCII_CHAR) + { + buffer[num_chars_writtten] = '\n'; + } + + *word |= (buffer[num_chars_writtten] & 0xff) << (j * 8); + + num_chars_writtten++; + } + } + + return num_chars_writtten; +} + +/* Static Function Prototype Declarations */ +static unsigned int msm_boot_uart_calculate_num_chars_to_write(char *data_in, + uint32_t *num_of_chars); +static unsigned int msm_boot_uart_dm_init(uint32_t base); +static unsigned int msm_boot_uart_dm_read(uint32_t base, + unsigned int *data, int wait); +static unsigned int msm_boot_uart_dm_write(uint32_t base, char *data, + unsigned int num_of_chars); +static unsigned int msm_boot_uart_dm_init_rx_transfer(uint32_t base); +static unsigned int msm_boot_uart_dm_reset(uint32_t base); + +/* Keep track of uart block vs port mapping. + */ +static uint32_t port_lookup[4]; + +/* Extern functions */ +void udelay(unsigned usecs); + +/* + * Helper function to keep track of Line Feed char "\n" with + * Carriage Return "\r\n". + */ +static unsigned int +msm_boot_uart_calculate_num_chars_to_write(char *data_in, + uint32_t *num_of_chars) +{ + uint32_t i = 0, j = 0; + + if ((data_in == NULL)) { + return MSM_BOOT_UART_DM_E_INVAL; + } + + for (i = 0, j = 0; i < *num_of_chars; i++, j++) { + if (data_in[i] == '\n') { + j++; + } + + } + + *num_of_chars = j; + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + +/* + * Reset the UART + */ +static unsigned int msm_boot_uart_dm_reset(uint32_t base) +{ + writel(MSM_BOOT_UART_DM_CMD_RESET_RX, MSM_BOOT_UART_DM_CR(base)); + writel(MSM_BOOT_UART_DM_CMD_RESET_TX, MSM_BOOT_UART_DM_CR(base)); + writel(MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT, MSM_BOOT_UART_DM_CR(base)); + writel(MSM_BOOT_UART_DM_CMD_RES_TX_ERR, MSM_BOOT_UART_DM_CR(base)); + writel(MSM_BOOT_UART_DM_CMD_RES_STALE_INT, MSM_BOOT_UART_DM_CR(base)); + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + +/* + * Initialize UART_DM - configure clock and required registers. + */ +static unsigned int msm_boot_uart_dm_init(uint32_t uart_dm_base) +{ + /* Configure UART mode registers MR1 and MR2 */ + /* Hardware flow control isn't supported */ + writel(0x0, MSM_BOOT_UART_DM_MR1(uart_dm_base)); + + /* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */ + writel(MSM_BOOT_UART_DM_8_N_1_MODE, MSM_BOOT_UART_DM_MR2(uart_dm_base)); + + /* Configure Interrupt Mask register IMR */ + writel(MSM_BOOT_UART_DM_IMR_ENABLED, MSM_BOOT_UART_DM_IMR(uart_dm_base)); + + /* Configure Tx and Rx watermarks configuration registers */ + /* TX watermark value is set to 0 - interrupt is generated when + * FIFO level is less than or equal to 0 */ + writel(MSM_BOOT_UART_DM_TFW_VALUE, MSM_BOOT_UART_DM_TFWR(uart_dm_base)); + + /* RX watermark value */ + writel(MSM_BOOT_UART_DM_RFW_VALUE, MSM_BOOT_UART_DM_RFWR(uart_dm_base)); + + /* Configure Interrupt Programming Register */ + /* Set initial Stale timeout value */ + writel(MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB, MSM_BOOT_UART_DM_IPR(uart_dm_base)); + + /* Configure IRDA if required */ + /* Disabling IRDA mode */ + writel(0x0, MSM_BOOT_UART_DM_IRDA(uart_dm_base)); + + /* Configure and enable sim interface if required */ + + /* Configure hunt character value in HCR register */ + /* Keep it in reset state */ + writel(0x0, MSM_BOOT_UART_DM_HCR(uart_dm_base)); + + /* Configure Rx FIFO base address */ + /* Both TX/RX shares same SRAM and default is half-n-half. + * Sticking with default value now. + * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries). + * We have found RAM_ADDR_WIDTH = 0x7f */ + + /* Issue soft reset command */ + msm_boot_uart_dm_reset(uart_dm_base); + + /* Enable/Disable Rx/Tx DM interfaces */ + /* Data Mover not currently utilized. */ + writel(0x0, MSM_BOOT_UART_DM_DMEN(uart_dm_base)); + + /* Enable transmitter and receiver */ + writel(MSM_BOOT_UART_DM_CR_RX_ENABLE, MSM_BOOT_UART_DM_CR(uart_dm_base)); + writel(MSM_BOOT_UART_DM_CR_TX_ENABLE, MSM_BOOT_UART_DM_CR(uart_dm_base)); + + /* Initialize Receive Path */ + msm_boot_uart_dm_init_rx_transfer(uart_dm_base); + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + +/* + * Initialize Receive Path + */ +static unsigned int msm_boot_uart_dm_init_rx_transfer(uint32_t uart_dm_base) +{ + writel(MSM_BOOT_UART_DM_GCMD_DIS_STALE_EVT, MSM_BOOT_UART_DM_CR(uart_dm_base)); + writel(MSM_BOOT_UART_DM_CMD_RES_STALE_INT, MSM_BOOT_UART_DM_CR(uart_dm_base)); + writel(MSM_BOOT_UART_DM_DMRX_DEF_VALUE, MSM_BOOT_UART_DM_DMRX(uart_dm_base)); + writel(MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT, MSM_BOOT_UART_DM_CR(uart_dm_base)); + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + +/* + * UART Receive operation + * Reads a word from the RX FIFO. + */ +static unsigned int +msm_boot_uart_dm_read(uint32_t base, unsigned int *data, int wait) +{ + static int rx_last_snap_count = 0; + static int rx_chars_read_since_last_xfer = 0; + + if (data == NULL) { + return MSM_BOOT_UART_DM_E_INVAL; + } + + /* We will be polling RXRDY status bit */ + while (!(readl(MSM_BOOT_UART_DM_SR(base)) & MSM_BOOT_UART_DM_SR_RXRDY)) { + /* if this is not a blocking call, we'll just return */ + if (!wait) { + return MSM_BOOT_UART_DM_E_RX_NOT_READY; + } + } + + /* Check for Overrun error. We'll just reset Error Status */ + if (readl(MSM_BOOT_UART_DM_SR(base)) & MSM_BOOT_UART_DM_SR_UART_OVERRUN) { + writel(MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT, MSM_BOOT_UART_DM_CR(base)); + } + + /* RX FIFO is ready; read a word. */ + *data = readl(MSM_BOOT_UART_DM_RF(base, 0)); + + /* increment the total count of chars we've read so far */ + rx_chars_read_since_last_xfer += 4; + + /* Rx transfer ends when one of the conditions is met: + * - The number of characters received since the end of the previous + * xfer equals the value written to DMRX at Transfer Initialization + * - A stale event occurred + */ + + /* If RX transfer has not ended yet */ + if (rx_last_snap_count == 0) { + /* Check if we've received stale event */ + if (readl(MSM_BOOT_UART_DM_MISR(base)) & MSM_BOOT_UART_DM_RXSTALE) { + /* Send command to reset stale interrupt */ + writel(MSM_BOOT_UART_DM_CMD_RES_STALE_INT, MSM_BOOT_UART_DM_CR(base)); + } + + /* Check if we haven't read more than DMRX value */ + else if ((unsigned int)rx_chars_read_since_last_xfer < + readl(MSM_BOOT_UART_DM_DMRX(base))) { + /* We can still continue reading before initializing RX transfer */ + return MSM_BOOT_UART_DM_E_SUCCESS; + } + + /* If we've reached here it means RX + * xfer end conditions been met + */ + + /* Read UART_DM_RX_TOTAL_SNAP register + * to know how many valid chars + * we've read so far since last transfer + */ + rx_last_snap_count = readl(MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base)); + + } + + /* If there are still data left in FIFO we'll read them before + * initializing RX Transfer again */ + if ((rx_last_snap_count - rx_chars_read_since_last_xfer) >= 0) { + return MSM_BOOT_UART_DM_E_SUCCESS; + } + + msm_boot_uart_dm_init_rx_transfer(base); + rx_last_snap_count = 0; + rx_chars_read_since_last_xfer = 0; + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + +/* + * UART transmit operation + */ +static unsigned int +msm_boot_uart_dm_write(uint32_t base, char *data, unsigned int num_of_chars) +{ + unsigned int tx_word_count = 0; + unsigned int tx_char_left = 0, tx_char = 0; + unsigned int tx_word = 0; + int i = 0; + char *tx_data = NULL; + uint8_t num_chars_written; + + if ((data == NULL) || (num_of_chars <= 0)) { + return MSM_BOOT_UART_DM_E_INVAL; + } + + msm_boot_uart_calculate_num_chars_to_write(data, &num_of_chars); + + tx_data = data; + + /* Write to NO_CHARS_FOR_TX register number of characters + * to be transmitted. However, before writing TX_FIFO must + * be empty as indicated by TX_READY interrupt in IMR register + */ + + /* Check if transmit FIFO is empty. + * If not we'll wait for TX_READY interrupt. */ + if (!(readl(MSM_BOOT_UART_DM_SR(base)) & MSM_BOOT_UART_DM_SR_TXEMT)) { + while (!(readl(MSM_BOOT_UART_DM_ISR(base)) & MSM_BOOT_UART_DM_TX_READY)) { + udelay(1); + /* Kick watchdog? */ + } + } + + //We need to make sure the DM_NO_CHARS_FOR_TX&DM_TF are are programmed atmoically. + THREAD_LOCK(state); + /* We are here. FIFO is ready to be written. */ + /* Write number of characters to be written */ + writel(num_of_chars, MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base)); + + /* Clear TX_READY interrupt */ + writel(MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT, MSM_BOOT_UART_DM_CR(base)); + + /* We use four-character word FIFO. So we need to divide data into + * four characters and write in UART_DM_TF register */ + tx_word_count = (num_of_chars % 4) ? ((num_of_chars / 4) + 1) : + (num_of_chars / 4); + tx_char_left = num_of_chars; + + for (i = 0; i < (int)tx_word_count; i++) { + tx_char = (tx_char_left < 4) ? tx_char_left : 4; + num_chars_written = pack_chars_into_words((uint8_t *)tx_data, tx_char, &tx_word); + + /* Wait till TX FIFO has space */ + while (!(readl(MSM_BOOT_UART_DM_SR(base)) & MSM_BOOT_UART_DM_SR_TXRDY)) { + udelay(1); + } + + /* TX FIFO has space. Write the chars */ + writel(tx_word, MSM_BOOT_UART_DM_TF(base, 0)); + tx_char_left = num_of_chars - (i + 1) * 4; + tx_data = tx_data + num_chars_written; + } + THREAD_UNLOCK(state); + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + +/* Defining functions that's exposed to outside world and in coformance to + * existing uart implemention. These functions are being called to initialize + * UART and print debug messages in bootloader. + */ +void uart_dm_init(uint8_t id, uint32_t gsbi_base, uint32_t uart_dm_base) +{ + static uint8_t port = 0; + char *data = "Android Bootloader - UART_DM Initialized!!!\n"; + + /* Configure the uart clock */ + clock_config_uart_dm(id); + DSB; + + /* Configure GPIO to provide connectivity between UART block + product ports and chip pads */ + gpio_config_uart_dm(id); + DSB; + + /* Configure GSBI for UART_DM protocol. + * I2C on 2 ports, UART (without HS flow control) on the other 2. + * This is only on chips that have GSBI block + */ + if(gsbi_base) + writel(GSBI_PROTOCOL_CODE_I2C_UART << + GSBI_CTRL_REG_PROTOCOL_CODE_S, + GSBI_CTRL_REG(gsbi_base)); + DSB; + + /* Configure clock selection register for tx and rx rates. + * Selecting 115.2k for both RX and TX. + */ + writel(UART_DM_CLK_RX_TX_BIT_RATE, MSM_BOOT_UART_DM_CSR(uart_dm_base)); + DSB; + + /* Intialize UART_DM */ + msm_boot_uart_dm_init(uart_dm_base); + + msm_boot_uart_dm_write(uart_dm_base, data, 44); + + ASSERT(port < ARRAY_SIZE(port_lookup)); + port_lookup[port++] = uart_dm_base; + + /* Set UART init flag */ + uart_init_flag = 1; +} + +/* UART_DM uses four character word FIFO where as UART core + * uses a character FIFO. so it's really inefficient to try + * to write single character. But that's how dprintf has been + * implemented. + */ +int uart_putc(int port, char c) +{ + uint32_t uart_base = port_lookup[port]; + + /* Don't do anything if UART is not initialized */ + if (!uart_init_flag) + return -1; + + msm_boot_uart_dm_write(uart_base, &c, 1); + + return 0; +} + +/* UART_DM uses four character word FIFO whereas uart_getc + * is supposed to read only one character. So we need to + * read a word and keep track of each character in the word. + */ +int uart_getc(int port, bool wait) +{ + int byte; + static unsigned int word = 0; + uint32_t uart_base = port_lookup[port]; + + /* Don't do anything if UART is not initialized */ + if (!uart_init_flag) + return -1; + + if (!word) { + /* Read from FIFO only if it's a first read or all the four + * characters out of a word have been read */ + if (msm_boot_uart_dm_read(uart_base, &word, wait) != MSM_BOOT_UART_DM_E_SUCCESS) { + return -1; + } + + } + + byte = (int)word & 0xff; + word = word >> 8; + + return byte; +} diff --git a/platform/msm/msm8916/acpuclock.c b/platform/msm/msm8916/acpuclock.c new file mode 100644 index 000000000..8388a3397 --- /dev/null +++ b/platform/msm/msm8916/acpuclock.c @@ -0,0 +1,441 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include + +#define MAX_LOOPS 500 + +void hsusb_clock_init(void) +{ + int ret; + struct clk *iclk, *cclk; + + ret = clk_get_set_enable("usb_iface_clk", 0, 1); + if(ret) + { + dprintf(CRITICAL, "failed to set usb_iface_clk ret = %d\n", ret); + ASSERT(0); + } + + ret = clk_get_set_enable("usb_core_clk", 80000000, 1); + if(ret) + { + dprintf(CRITICAL, "failed to set usb_core_clk ret = %d\n", ret); + ASSERT(0); + } + + mdelay(20); + + iclk = clk_get("usb_iface_clk"); + cclk = clk_get("usb_core_clk"); + + clk_disable(iclk); + clk_disable(cclk); + + mdelay(20); + + /* Start the block reset for usb */ + writel(1, USB_HS_BCR); + + mdelay(20); + + /* Take usb block out of reset */ + writel(0, USB_HS_BCR); + + mdelay(20); + + ret = clk_enable(iclk); + + if(ret) + { + dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret); + ASSERT(0); + } + + ret = clk_enable(cclk); + + if(ret) + { + dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret); + ASSERT(0); + } +} + +#if 0 +void clock_init_mmc(uint32_t interface) +{ + char clk_name[64]; + int ret; + + snprintf(clk_name, sizeof(clk_name), "sdc%u_iface_clk", interface); + + /* enable interface clock */ + ret = clk_get_set_enable(clk_name, 0, 1); + if(ret) + { + dprintf(CRITICAL, "failed to set sdc1_iface_clk ret = %d\n", ret); + ASSERT(0); + } +} + + +/* Configure MMC clock */ +void clock_config_mmc(uint32_t interface, uint32_t freq) +{ + int ret = 1; + char clk_name[64]; + + snprintf(clk_name, sizeof(clk_name), "sdc%u_core_clk", interface); + + if(freq == MMC_CLK_400KHZ) + { + ret = clk_get_set_enable(clk_name, 400000, 1); + } + else if(freq == MMC_CLK_50MHZ) + { + ret = clk_get_set_enable(clk_name, 50000000, 1); + } + else if(freq == MMC_CLK_200MHZ) + { + ret = clk_get_set_enable(clk_name, 200000000, 1); + } + else if(freq == MMC_CLK_177MHZ) + { + ret = clk_get_set_enable(clk_name, 177770000, 1); + } + else + { + dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq); + ASSERT(0); + } + + if(ret) + { + dprintf(CRITICAL, "failed to set %s ret = %d\n", clk_name, ret); + ASSERT(0); + } +} +#endif + +/* Configure UART clock based on the UART block id*/ +void clock_config_uart_dm(uint8_t id) +{ + int ret; + char iclk[64]; + char cclk[64]; + + snprintf(iclk, sizeof(iclk), "uart%u_iface_clk", id); + snprintf(cclk, sizeof(cclk), "uart%u_core_clk", id); + + ret = clk_get_set_enable(iclk, 0, 1); + if(ret) + { + dprintf(CRITICAL, "failed to set %s ret = %d\n", iclk, ret); + ASSERT(0); + } + + ret = clk_get_set_enable(cclk, 7372800, 1); + if(ret) + { + dprintf(CRITICAL, "failed to set %s ret = %d\n", cclk, ret); + ASSERT(0); + } +} + +/* Control the MDSS GDSC */ +void mdp_gdsc_ctrl(uint8_t enable) +{ + uint32_t reg = 0; + reg = readl(MDP_GDSCR); + if (enable) { + if (!(reg & GDSC_POWER_ON_BIT)) { + reg &= ~((1<<0) | GDSC_EN_FEW_WAIT_MASK); + reg |= GDSC_EN_FEW_WAIT_256_MASK; + writel(reg, MDP_GDSCR); + while(!(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT))); + } else { + dprintf(SPEW, "MDP GDSC already enabled\n"); + } + } else { + reg |= (1<<0); + writel(reg, MDP_GDSCR); + while(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT)); + } +} + +/* Enable all the MDP branch clocks */ +void mdp_clock_enable(void) +{ + int ret; + + ret = clk_get_set_enable("mdp_ahb_clk", 0, 1); + if(ret) + { + dprintf(CRITICAL, "failed to set mdp_ahb_clk ret = %d\n", ret); + ASSERT(0); + } + + /* Set MDP clock to 320MHz */ + ret = clk_get_set_enable("mdss_mdp_clk_src", 320000000, 1); + + if(ret) + { + dprintf(CRITICAL, "failed to set mdp_clk_src ret = %d\n", ret); + ASSERT(0); + } + + ret = clk_get_set_enable("mdss_vsync_clk", 0, 1); + if(ret) + { + dprintf(CRITICAL, "failed to set mdss vsync clk ret = %d\n", ret); + ASSERT(0); + } + + ret = clk_get_set_enable("mdss_mdp_clk", 0, 1); + if(ret) + { + dprintf(CRITICAL, "failed to set mdp_clk ret = %d\n", ret); + ASSERT(0); + } +} + +/* Disable all the MDP branch clocks */ +void mdp_clock_disable(void) +{ + clk_disable(clk_get("mdss_vsync_clk")); + clk_disable(clk_get("mdss_mdp_clk")); + clk_disable(clk_get("mdss_mdp_clk_src")); + clk_disable(clk_get("mdp_ahb_clk")); +} + +/* Disable all the bus clocks needed by MDSS */ +void mdss_bus_clocks_disable(void) +{ + /* Disable MDSS AXI clock */ + clk_disable(clk_get("mdss_axi_clk")); +} + +/* Enable all the bus clocks needed by MDSS */ +void mdss_bus_clocks_enable(void) +{ + int ret; + + /* Configure AXI clock */ + ret = clk_get_set_enable("mdss_axi_clk", 0, 1); + if(ret) + { + dprintf(CRITICAL, "failed to set mdss_axi_clk ret = %d\n", ret); + ASSERT(0); + } +} + +static void rcg_update_config(uint32_t reg) +{ + int i; + + for (i = 0; i < MAX_LOOPS; i++) { + if (!(readl(reg) & (1<<0))) + return; + udelay(1); + } + + dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg); + ASSERT(0); +} + +static void branch_clk_halt_check(uint32_t reg) +{ + int i; + + for (i = 0; i < MAX_LOOPS; i++) { + if (!(readl(reg) & (1<<31))) + return; + udelay(1); + } + + dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg); + ASSERT(0); +} + +/* Disable all the branch clocks needed by the DSI controller */ +void gcc_dsi_clocks_disable(uint8_t dual_dsi) +{ + clk_disable(clk_get("mdss_esc0_clk")); + writel(0x0, DSI_PIXEL0_CBCR); + writel(0x0, DSI_BYTE0_CBCR); + if (dual_dsi) { + clk_disable(clk_get("mdss_esc1_clk")); + writel(0x0, DSI_PIXEL1_CBCR); + writel(0x0, DSI_BYTE1_CBCR); + } +} + +/* Configure all the branch clocks needed by the DSI controller */ +void gcc_dsi_clocks_enable(uint8_t dual_dsi, uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d) +{ + int ret; + + /* + * Configure Byte clock -autopll- This will not change becasue + * byte clock does not need any divider + */ + /* Set the source for DSI0 byte RCG */ + writel(0x100, DSI_BYTE0_CFG_RCGR); + /* Set the update RCG bit */ + writel(0x1, DSI_BYTE0_CMD_RCGR); + rcg_update_config(DSI_BYTE0_CMD_RCGR); + /* Enable the branch clock */ + writel(0x1, DSI_BYTE0_CBCR); + branch_clk_halt_check(DSI_BYTE0_CBCR); + + /* Configure Pixel clock */ + /* Set the source for DSI0 pixel RCG */ + writel(0x100, DSI_PIXEL0_CFG_RCGR); + /* Set the MND for DSI0 pixel clock */ + writel(pclk0_m, DSI_PIXEL0_M); + writel(pclk0_n, DSI_PIXEL0_N); + writel(pclk0_d, DSI_PIXEL0_D); + /* Set the update RCG bit */ + writel(0x1, DSI_PIXEL0_CMD_RCGR); + rcg_update_config(DSI_PIXEL0_CMD_RCGR); + /* Enable the branch clock */ + writel(0x1, DSI_PIXEL0_CBCR); + branch_clk_halt_check(DSI_PIXEL0_CBCR); + + /* Configure ESC clock */ + ret = clk_get_set_enable("mdss_esc0_clk", 0, 1); + if (ret) { + dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret); + ASSERT(0); + } + + if (dual_dsi) { + /* Set the source for DSI1 byte RCG */ + writel(0x100, DSI_BYTE1_CFG_RCGR); + /* Set the update RCG bit */ + writel(0x1, DSI_BYTE1_CMD_RCGR); + rcg_update_config(DSI_BYTE1_CMD_RCGR); + /* Enable the branch clock */ + writel(0x1, DSI_BYTE1_CBCR); + branch_clk_halt_check(DSI_BYTE1_CBCR); + + /* Set the source for DSI1 pixel RCG */ + writel(0x100, DSI_PIXEL1_CFG_RCGR); + /* Set the MND for DSI1 pixel clock */ + writel(pclk0_m, DSI_PIXEL1_M); + writel(pclk0_n, DSI_PIXEL1_N); + writel(pclk0_d, DSI_PIXEL1_D); + /* Set the update RCG bit */ + writel(0x1, DSI_PIXEL1_CMD_RCGR); + rcg_update_config(DSI_PIXEL1_CMD_RCGR); + /* Enable the branch clock */ + writel(0x1, DSI_PIXEL1_CBCR); + branch_clk_halt_check(DSI_PIXEL1_CBCR); + + /* Configure ESC clock */ + ret = clk_get_set_enable("mdss_esc1_clk", 0, 1); + if (ret) { + dprintf(CRITICAL, "failed to set esc1_clk ret = %d\n", ret); + ASSERT(0); + } + } +} + +/* Function to asynchronously reset CE. + * Function assumes that all the CE clocks are off. + */ +static void ce_async_reset(uint8_t instance) +{ + /* Start the block reset for CE */ + writel(1, GCC_CRYPTO_BCR); + + udelay(2); + + /* Take CE block out of reset */ + writel(0, GCC_CRYPTO_BCR); + + udelay(2); +} + +void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id) +{ + uint8_t ret = 0; + char clk_name[64]; + + struct clk *qup_clk; + + if((blsp_id != BLSP_ID_1) || ((qup_id != QUP_ID_1) && (qup_id != QUP_ID_3))) { + dprintf(CRITICAL, "Incorrect BLSP-%d or QUP-%d configuration\n", blsp_id, qup_id); + ASSERT(0); + } + + if (qup_id == QUP_ID_1) { + snprintf(clk_name, sizeof(clk_name), "blsp1_qup2_ahb_iface_clk"); + } + else if (qup_id == QUP_ID_3) { + snprintf(clk_name, sizeof(clk_name), "blsp1_qup4_ahb_iface_clk"); + } + + ret = clk_get_set_enable(clk_name, 0 , 1); + + if (ret) { + dprintf(CRITICAL, "Failed to enable %s clock\n", clk_name); + return; + } + + if (qup_id == QUP_ID_1) { + snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup2_i2c_apps_clk"); + } + else if (qup_id == QUP_ID_3) { + snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup4_i2c_apps_clk"); + } + + qup_clk = clk_get(clk_name); + + if (!qup_clk) { + dprintf(CRITICAL, "Failed to get %s\n", clk_name); + return; + } + + ret = clk_enable(qup_clk); + + if (ret) { + dprintf(CRITICAL, "Failed to enable %s\n", clk_name); + return; + } +} diff --git a/platform/msm/msm8916/clock.c b/platform/msm/msm8916/clock.c new file mode 100644 index 000000000..e8c89dcc0 --- /dev/null +++ b/platform/msm/msm8916/clock.c @@ -0,0 +1,772 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + + +/* Mux source select values */ +#define cxo_source_val 0 +#define gpll0_source_val 1 +#define cxo_mm_source_val 0 +#define gpll0_mm_source_val 5 +#define gpll1_mm_source_val 1 +struct clk_freq_tbl rcg_dummy_freq = F_END; + + +/* Clock Operations */ +static struct clk_ops clk_ops_branch = +{ + .enable = clock_lib2_branch_clk_enable, + .disable = clock_lib2_branch_clk_disable, + .set_rate = clock_lib2_branch_set_rate, +}; + +static struct clk_ops clk_ops_rcg_mnd = +{ + .enable = clock_lib2_rcg_enable, + .set_rate = clock_lib2_rcg_set_rate, +}; + +static struct clk_ops clk_ops_rcg = +{ + .enable = clock_lib2_rcg_enable, + .set_rate = clock_lib2_rcg_set_rate, +}; + +static struct clk_ops clk_ops_cxo = +{ + .enable = cxo_clk_enable, + .disable = cxo_clk_disable, +}; + +static struct clk_ops clk_ops_pll_vote = +{ + .enable = pll_vote_clk_enable, + .disable = pll_vote_clk_disable, + .auto_off = pll_vote_clk_disable, + .is_enabled = pll_vote_clk_is_enabled, +}; + +static struct clk_ops clk_ops_vote = +{ + .enable = clock_lib2_vote_clk_enable, + .disable = clock_lib2_vote_clk_disable, +}; + +/* Clock Sources */ +static struct fixed_clk cxo_clk_src = +{ + .c = { + .rate = 19200000, + .dbg_name = "cxo_clk_src", + .ops = &clk_ops_cxo, + }, +}; + +static struct pll_vote_clk gpll0_clk_src = +{ + .en_reg = (void *) APCS_GPLL_ENA_VOTE, + .en_mask = (1<<0), + .status_reg = (void *) GPLL0_STATUS, + .status_mask = (1<<17), + .parent = &cxo_clk_src.c, + + .c = { + .rate = 800000000, + .dbg_name = "gpll0_clk_src", + .ops = &clk_ops_pll_vote, + }, +}; + +static struct pll_vote_clk gpll1_clk_src = +{ + .en_reg = (void *) APCS_GPLL_ENA_VOTE, + .en_mask = (1<<1), + .status_reg = (void *) GPLL1_STATUS, + .status_mask = (1<<17), + .parent = &cxo_clk_src.c, + + .c = { + .rate = 614400000, + .dbg_name = "gpll1_clk_src", + .ops = &clk_ops_pll_vote, + }, +}; + +/* SDCC Clocks */ +static struct clk_freq_tbl ftbl_gcc_sdcc1_2_apps_clk[] = +{ + F( 144000, cxo, 16, 3, 25), + F( 400000, cxo, 12, 1, 4), + F( 20000000, gpll0, 10, 1, 4), + F( 25000000, gpll0, 16, 1, 2), + F( 50000000, gpll0, 16, 0, 0), + F(100000000, gpll0, 8, 0, 0), + F(177770000, gpll0, 4.5, 0, 0), + F(200000000, gpll0, 4, 0, 0), + F_END +}; + +static struct rcg_clk sdcc1_apps_clk_src = +{ + .cmd_reg = (uint32_t *) SDCC1_CMD_RCGR, + .cfg_reg = (uint32_t *) SDCC1_CFG_RCGR, + .m_reg = (uint32_t *) SDCC1_M, + .n_reg = (uint32_t *) SDCC1_N, + .d_reg = (uint32_t *) SDCC1_D, + + .set_rate = clock_lib2_rcg_set_rate_mnd, + .freq_tbl = ftbl_gcc_sdcc1_2_apps_clk, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "sdc1_clk", + .ops = &clk_ops_rcg_mnd, + }, +}; + +/* BLSP1_QUP2 Clocks */ +static struct clk_freq_tbl ftbl_gcc_blsp1_qup2_i2c_apps_clk_src[] = +{ + F( 96000, cxo, 10, 1, 2), + F( 4800000, cxo, 4, 0, 0), + F( 9600000, cxo, 2, 0, 0), + F( 16000000, gpll0, 10, 1, 5), + F( 19200000, gpll0, 1, 0, 0), + F( 25000000, gpll0, 16, 1, 2), + F( 50000000, gpll0, 16, 0, 0), + F_END +}; + +static struct branch_clk gcc_sdcc1_apps_clk = +{ + .cbcr_reg = (uint32_t *) SDCC1_APPS_CBCR, + .parent = &sdcc1_apps_clk_src.c, + + .c = { + .dbg_name = "gcc_sdcc1_apps_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct branch_clk gcc_sdcc1_ahb_clk = +{ + .cbcr_reg = (uint32_t *) SDCC1_AHB_CBCR, + .has_sibling = 1, + + .c = { + .dbg_name = "gcc_sdcc1_ahb_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct rcg_clk sdcc2_apps_clk_src = +{ + .cmd_reg = (uint32_t *) SDCC2_CMD_RCGR, + .cfg_reg = (uint32_t *) SDCC2_CFG_RCGR, + .m_reg = (uint32_t *) SDCC2_M, + .n_reg = (uint32_t *) SDCC2_N, + .d_reg = (uint32_t *) SDCC2_D, + + .set_rate = clock_lib2_rcg_set_rate_mnd, + .freq_tbl = ftbl_gcc_sdcc1_2_apps_clk, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "sdc2_clk", + .ops = &clk_ops_rcg_mnd, + }, +}; + +static struct branch_clk gcc_sdcc2_apps_clk = +{ + .cbcr_reg = (uint32_t *) SDCC2_APPS_CBCR, + .parent = &sdcc2_apps_clk_src.c, + + .c = { + .dbg_name = "gcc_sdcc2_apps_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct branch_clk gcc_sdcc2_ahb_clk = +{ + .cbcr_reg = (uint32_t *) SDCC2_AHB_CBCR, + .has_sibling = 1, + + .c = { + .dbg_name = "gcc_sdcc2_ahb_clk", + .ops = &clk_ops_branch, + }, +}; + +/* UART Clocks */ +static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_6_apps_clk[] = +{ + F( 3686400, gpll0, 1, 72, 15625), + F( 7372800, gpll0, 1, 144, 15625), + F(14745600, gpll0, 1, 288, 15625), + F(16000000, gpll0, 10, 1, 5), + F(19200000, cxo, 1, 0, 0), + F(24000000, gpll0, 1, 3, 100), + F(25000000, gpll0, 16, 1, 2), + F(32000000, gpll0, 1, 1, 25), + F(40000000, gpll0, 1, 1, 20), + F(46400000, gpll0, 1, 29, 500), + F(48000000, gpll0, 1, 3, 50), + F(51200000, gpll0, 1, 8, 125), + F(56000000, gpll0, 1, 7, 100), + F(58982400, gpll0, 1,1152, 15625), + F(60000000, gpll0, 1, 3, 40), + F_END +}; + +static struct rcg_clk blsp1_uart1_apps_clk_src = +{ + .cmd_reg = (uint32_t *) BLSP1_UART1_APPS_CMD_RCGR, + .cfg_reg = (uint32_t *) BLSP1_UART1_APPS_CFG_RCGR, + .m_reg = (uint32_t *) BLSP1_UART1_APPS_M, + .n_reg = (uint32_t *) BLSP1_UART1_APPS_N, + .d_reg = (uint32_t *) BLSP1_UART1_APPS_D, + + .set_rate = clock_lib2_rcg_set_rate_mnd, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "blsp1_uart1_apps_clk", + .ops = &clk_ops_rcg_mnd, + }, +}; + +static struct branch_clk gcc_blsp1_uart1_apps_clk = +{ + .cbcr_reg = (uint32_t *) BLSP1_UART1_APPS_CBCR, + .parent = &blsp1_uart1_apps_clk_src.c, + + .c = { + .dbg_name = "gcc_blsp1_uart1_apps_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct rcg_clk blsp1_uart2_apps_clk_src = +{ + .cmd_reg = (uint32_t *) BLSP1_UART2_APPS_CMD_RCGR, + .cfg_reg = (uint32_t *) BLSP1_UART2_APPS_CFG_RCGR, + .m_reg = (uint32_t *) BLSP1_UART2_APPS_M, + .n_reg = (uint32_t *) BLSP1_UART2_APPS_N, + .d_reg = (uint32_t *) BLSP1_UART2_APPS_D, + + .set_rate = clock_lib2_rcg_set_rate_mnd, + .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "blsp1_uart2_apps_clk", + .ops = &clk_ops_rcg_mnd, + }, +}; + +static struct branch_clk gcc_blsp1_uart2_apps_clk = +{ + .cbcr_reg = (uint32_t *) BLSP1_UART2_APPS_CBCR, + .parent = &blsp1_uart2_apps_clk_src.c, + + .c = { + .dbg_name = "gcc_blsp1_uart2_apps_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct vote_clk gcc_blsp1_ahb_clk = { + .cbcr_reg = (uint32_t *) BLSP1_AHB_CBCR, + .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE, + .en_mask = (1<<10), + + .c = { + .dbg_name = "gcc_blsp1_ahb_clk", + .ops = &clk_ops_vote, + }, +}; + +/* USB Clocks */ +static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] = +{ + F(80000000, gpll0, 10, 0, 0), + F_END +}; + +static struct rcg_clk usb_hs_system_clk_src = +{ + .cmd_reg = (uint32_t *) USB_HS_SYSTEM_CMD_RCGR, + .cfg_reg = (uint32_t *) USB_HS_SYSTEM_CFG_RCGR, + + .set_rate = clock_lib2_rcg_set_rate_hid, + .freq_tbl = ftbl_gcc_usb_hs_system_clk, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "usb_hs_system_clk", + .ops = &clk_ops_rcg, + }, +}; + +static struct branch_clk gcc_usb_hs_system_clk = +{ + .cbcr_reg = (uint32_t *) USB_HS_SYSTEM_CBCR, + .parent = &usb_hs_system_clk_src.c, + + .c = { + .dbg_name = "gcc_usb_hs_system_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct branch_clk gcc_usb_hs_ahb_clk = +{ + .cbcr_reg = (uint32_t *) USB_HS_AHB_CBCR, + .has_sibling = 1, + + .c = { + .dbg_name = "gcc_usb_hs_ahb_clk", + .ops = &clk_ops_branch, + }, +}; + +/* Display clocks */ +static struct clk_freq_tbl ftbl_mdss_esc0_1_clk[] = { + F_MM(19200000, cxo, 1, 0, 0), + F_END +}; + +static struct clk_freq_tbl ftbl_mdss_esc1_1_clk[] = { + F_MM(19200000, cxo, 1, 0, 0), + F_END +}; + +static struct clk_freq_tbl ftbl_mdp_clk[] = { + F( 80000000, gpll0, 10, 0, 0), + F( 100000000, gpll0, 8, 0, 0), + F( 200000000, gpll0, 4, 0, 0), + F( 320000000, gpll0, 2.5, 0, 0), + F_END +}; + +static struct clk_freq_tbl ftbl_mdss_mdp_clk_src[] = { + F_MM( 50000000, gpll0, 16, 0, 0), + F_MM( 80000000, gpll0, 10, 0, 0), + F_MM( 100000000, gpll0, 8, 0, 0), + F_MM( 153600000, gpll1, 4, 0, 0), + F_MM( 160000000, gpll0, 5, 0, 0), + F_MM( 177780000, gpll0, 4.5, 0, 0), + F_MM( 200000000, gpll0, 4, 0, 0), + F_MM( 266670000, gpll0, 3, 0, 0), + F_MM( 307200000, gpll1, 2, 0, 0), + F_END +}; + +static struct rcg_clk dsi_esc0_clk_src = { + .cmd_reg = (uint32_t *) DSI_ESC0_CMD_RCGR, + .cfg_reg = (uint32_t *) DSI_ESC0_CFG_RCGR, + .set_rate = clock_lib2_rcg_set_rate_hid, + .freq_tbl = ftbl_mdss_esc0_1_clk, + + .c = { + .dbg_name = "dsi_esc0_clk_src", + .ops = &clk_ops_rcg, + }, +}; + +static struct rcg_clk dsi_esc1_clk_src = { + .cmd_reg = (uint32_t *) DSI_ESC1_CMD_RCGR, + .cfg_reg = (uint32_t *) DSI_ESC1_CFG_RCGR, + .set_rate = clock_lib2_rcg_set_rate_hid, + .freq_tbl = ftbl_mdss_esc1_1_clk, + + .c = { + .dbg_name = "dsi_esc1_clk_src", + .ops = &clk_ops_rcg, + }, +}; + +static struct clk_freq_tbl ftbl_mdss_vsync_clk[] = { + F_MM(19200000, cxo, 1, 0, 0), + F_END +}; + +static struct rcg_clk vsync_clk_src = { + .cmd_reg = (uint32_t *) VSYNC_CMD_RCGR, + .cfg_reg = (uint32_t *) VSYNC_CFG_RCGR, + .set_rate = clock_lib2_rcg_set_rate_hid, + .freq_tbl = ftbl_mdss_vsync_clk, + + .c = { + .dbg_name = "vsync_clk_src", + .ops = &clk_ops_rcg, + }, +}; + +static struct branch_clk mdss_esc0_clk = { + .cbcr_reg = (uint32_t *) DSI_ESC0_CBCR, + .parent = &dsi_esc0_clk_src.c, + .has_sibling = 0, + + .c = { + .dbg_name = "mdss_esc0_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct branch_clk mdss_esc1_clk = { + .cbcr_reg = (uint32_t *) DSI_ESC1_CBCR, + .parent = &dsi_esc1_clk_src.c, + .has_sibling = 0, + + .c = { + .dbg_name = "mdss_esc1_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct branch_clk mdss_axi_clk = { + .cbcr_reg = (uint32_t *) MDP_AXI_CBCR, + .has_sibling = 1, + + .c = { + .dbg_name = "mdss_axi_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct branch_clk mdp_ahb_clk = { + .cbcr_reg = (uint32_t *) MDP_AHB_CBCR, + .has_sibling = 1, + + .c = { + .dbg_name = "mdp_ahb_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct rcg_clk mdss_mdp_clk_src = { + .cmd_reg = (uint32_t *) MDP_CMD_RCGR, + .cfg_reg = (uint32_t *) MDP_CFG_RCGR, + .set_rate = clock_lib2_rcg_set_rate_hid, + .freq_tbl = ftbl_mdp_clk, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "mdss_mdp_clk_src", + .ops = &clk_ops_rcg, + }, +}; + +static struct branch_clk mdss_mdp_clk = { + .cbcr_reg = (uint32_t *) MDP_CBCR, + .parent = &mdss_mdp_clk_src.c, + .has_sibling = 0, + + .c = { + .dbg_name = "mdss_mdp_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct branch_clk mdss_vsync_clk = { + .cbcr_reg = MDSS_VSYNC_CBCR, + .parent = &vsync_clk_src.c, + .has_sibling = 0, + + .c = { + .dbg_name = "mdss_vsync_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = { + F(160000000, gpll0, 5, 0, 0), + F_END +}; + +static struct rcg_clk ce1_clk_src = { + .cmd_reg = (uint32_t *) GCC_CRYPTO_CMD_RCGR, + .cfg_reg = (uint32_t *) GCC_CRYPTO_CFG_RCGR, + .set_rate = clock_lib2_rcg_set_rate_hid, + .freq_tbl = ftbl_gcc_ce1_clk, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "ce1_clk_src", + .ops = &clk_ops_rcg, + }, +}; + +static struct vote_clk gcc_ce1_clk = { + .cbcr_reg = (uint32_t *) GCC_CRYPTO_CBCR, + .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE, + .en_mask = (1<<2), + + .c = { + .dbg_name = "gcc_ce1_clk", + .ops = &clk_ops_vote, + }, +}; + +static struct vote_clk gcc_ce1_ahb_clk = { + .cbcr_reg = (uint32_t *) GCC_CRYPTO_AHB_CBCR, + .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE, + .en_mask = (1<<0), + + .c = { + .dbg_name = "gcc_ce1_ahb_clk", + .ops = &clk_ops_vote, + }, +}; + +static struct vote_clk gcc_ce1_axi_clk = { + .cbcr_reg = (uint32_t *) GCC_CRYPTO_AXI_CBCR, + .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE, + .en_mask = (1<<1), + + .c = { + .dbg_name = "gcc_ce1_axi_clk", + .ops = &clk_ops_vote, + }, +}; + +static struct rcg_clk gcc_blsp1_qup1_i2c_apps_clk_src = +{ + .cmd_reg = (uint32_t *) GCC_BLSP1_QUP1_CMD_RCGR, + .cfg_reg = (uint32_t *) GCC_BLSP1_QUP1_CFG_RCGR, + .set_rate = clock_lib2_rcg_set_rate_hid, + .freq_tbl = ftbl_gcc_blsp1_qup2_i2c_apps_clk_src, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "gcc_blsp1_qup1_i2c_apps_clk_src", + .ops = &clk_ops_rcg, + }, +}; + +static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = { + .cbcr_reg = (uint32_t *) GCC_BLSP1_QUP1_APPS_CBCR, + .parent = &gcc_blsp1_qup1_i2c_apps_clk_src.c, + + .c = { + .dbg_name = "gcc_blsp1_qup1_i2c_apps_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct rcg_clk gcc_blsp1_qup2_i2c_apps_clk_src = +{ + .cmd_reg = (uint32_t *) GCC_BLSP1_QUP2_CMD_RCGR, + .cfg_reg = (uint32_t *) GCC_BLSP1_QUP2_CFG_RCGR, + .set_rate = clock_lib2_rcg_set_rate_hid, + .freq_tbl = ftbl_gcc_blsp1_qup2_i2c_apps_clk_src, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "gcc_blsp1_qup2_i2c_apps_clk_src", + .ops = &clk_ops_rcg, + }, +}; + +static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = { + .cbcr_reg = GCC_BLSP1_QUP2_APPS_CBCR, + .parent = &gcc_blsp1_qup2_i2c_apps_clk_src.c, + + .c = { + .dbg_name = "gcc_blsp1_qup2_i2c_apps_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct rcg_clk gcc_blsp1_qup3_i2c_apps_clk_src = +{ + .cmd_reg = (uint32_t *) GCC_BLSP1_QUP3_CMD_RCGR, + .cfg_reg = (uint32_t *) GCC_BLSP1_QUP3_CFG_RCGR, + .set_rate = clock_lib2_rcg_set_rate_hid, + .freq_tbl = ftbl_gcc_blsp1_qup2_i2c_apps_clk_src, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "gcc_blsp1_qup3_i2c_apps_clk_src", + .ops = &clk_ops_rcg, + }, +}; + +static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = { + .cbcr_reg = (uint32_t *) GCC_BLSP1_QUP3_APPS_CBCR, + .parent = &gcc_blsp1_qup3_i2c_apps_clk_src.c, + + .c = { + .dbg_name = "gcc_blsp1_qup3_i2c_apps_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct rcg_clk gcc_blsp1_qup4_i2c_apps_clk_src = +{ + .cmd_reg = (uint32_t *) GCC_BLSP1_QUP4_CMD_RCGR, + .cfg_reg = (uint32_t *) GCC_BLSP1_QUP4_CFG_RCGR, + .set_rate = clock_lib2_rcg_set_rate_hid, + .freq_tbl = ftbl_gcc_blsp1_qup2_i2c_apps_clk_src, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "gcc_blsp1_qup4_i2c_apps_clk_src", + .ops = &clk_ops_rcg, + }, +}; + +static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = { + .cbcr_reg = (uint32_t *) GCC_BLSP1_QUP4_APPS_CBCR, + .parent = &gcc_blsp1_qup4_i2c_apps_clk_src.c, + + .c = { + .dbg_name = "gcc_blsp1_qup4_i2c_apps_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct rcg_clk gcc_blsp1_qup5_i2c_apps_clk_src = +{ + .cmd_reg = (uint32_t *) GCC_BLSP1_QUP5_CMD_RCGR, + .cfg_reg = (uint32_t *) GCC_BLSP1_QUP5_CFG_RCGR, + .set_rate = clock_lib2_rcg_set_rate_hid, + .freq_tbl = ftbl_gcc_blsp1_qup2_i2c_apps_clk_src, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "gcc_blsp1_qup5_i2c_apps_clk_src", + .ops = &clk_ops_rcg, + }, +}; + +static struct branch_clk gcc_blsp1_qup5_i2c_apps_clk = { + .cbcr_reg = (uint32_t *) GCC_BLSP1_QUP5_APPS_CBCR, + .parent = &gcc_blsp1_qup5_i2c_apps_clk_src.c, + + .c = { + .dbg_name = "gcc_blsp1_qup5_i2c_apps_clk", + .ops = &clk_ops_branch, + }, +}; + +static struct rcg_clk gcc_blsp1_qup6_i2c_apps_clk_src = +{ + .cmd_reg = (uint32_t *) GCC_BLSP1_QUP6_CMD_RCGR, + .cfg_reg = (uint32_t *) GCC_BLSP1_QUP6_CFG_RCGR, + .set_rate = clock_lib2_rcg_set_rate_hid, + .freq_tbl = ftbl_gcc_blsp1_qup2_i2c_apps_clk_src, + .current_freq = &rcg_dummy_freq, + + .c = { + .dbg_name = "gcc_blsp1_qup6_i2c_apps_clk_src", + .ops = &clk_ops_rcg, + }, +}; + +static struct branch_clk gcc_blsp1_qup6_i2c_apps_clk = { + .cbcr_reg = (uint32_t *) GCC_BLSP1_QUP6_APPS_CBCR, + .parent = &gcc_blsp1_qup6_i2c_apps_clk_src.c, + + .c = { + .dbg_name = "gcc_blsp1_qup6_i2c_apps_clk", + .ops = &clk_ops_branch, + }, +}; + +/* Clock lookup table */ +static struct clk_lookup msm_clocks_8916[] = +{ + CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c), + CLK_LOOKUP("sdc1_core_clk", gcc_sdcc1_apps_clk.c), + + CLK_LOOKUP("sdc2_iface_clk", gcc_sdcc2_ahb_clk.c), + CLK_LOOKUP("sdc2_core_clk", gcc_sdcc2_apps_clk.c), + + CLK_LOOKUP("uart1_iface_clk", gcc_blsp1_ahb_clk.c), + CLK_LOOKUP("uart1_core_clk", gcc_blsp1_uart1_apps_clk.c), + + CLK_LOOKUP("uart2_iface_clk", gcc_blsp1_ahb_clk.c), + CLK_LOOKUP("uart2_core_clk", gcc_blsp1_uart2_apps_clk.c), + + CLK_LOOKUP("usb_iface_clk", gcc_usb_hs_ahb_clk.c), + CLK_LOOKUP("usb_core_clk", gcc_usb_hs_system_clk.c), + + CLK_LOOKUP("mdp_ahb_clk", mdp_ahb_clk.c), + CLK_LOOKUP("mdss_esc0_clk", mdss_esc0_clk.c), + CLK_LOOKUP("mdss_esc1_clk", mdss_esc1_clk.c), + CLK_LOOKUP("mdss_axi_clk", mdss_axi_clk.c), + CLK_LOOKUP("mdss_vsync_clk", mdss_vsync_clk.c), + CLK_LOOKUP("mdss_mdp_clk_src", mdss_mdp_clk_src.c), + CLK_LOOKUP("mdss_mdp_clk", mdss_mdp_clk.c), + + CLK_LOOKUP("ce1_ahb_clk", gcc_ce1_ahb_clk.c), + CLK_LOOKUP("ce1_axi_clk", gcc_ce1_axi_clk.c), + CLK_LOOKUP("ce1_core_clk", gcc_ce1_clk.c), + CLK_LOOKUP("ce1_src_clk", ce1_clk_src.c), + + CLK_LOOKUP("blsp1_qup1_ahb_iface_clk", gcc_blsp1_ahb_clk.c), + CLK_LOOKUP("gcc_blsp1_qup1_i2c_apps_clk_src", gcc_blsp1_qup1_i2c_apps_clk_src.c), + CLK_LOOKUP("gcc_blsp1_qup1_i2c_apps_clk", gcc_blsp1_qup1_i2c_apps_clk.c), + + CLK_LOOKUP("blsp1_qup2_ahb_iface_clk", gcc_blsp1_ahb_clk.c), + CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk_src", gcc_blsp1_qup2_i2c_apps_clk_src.c), + CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk", gcc_blsp1_qup2_i2c_apps_clk.c), + + CLK_LOOKUP("blsp1_qup3_ahb_iface_clk", gcc_blsp1_ahb_clk.c), + CLK_LOOKUP("gcc_blsp1_qup3_i2c_apps_clk_src", gcc_blsp1_qup3_i2c_apps_clk_src.c), + CLK_LOOKUP("gcc_blsp1_qup3_i2c_apps_clk", gcc_blsp1_qup3_i2c_apps_clk.c), + + CLK_LOOKUP("blsp1_qup4_ahb_iface_clk", gcc_blsp1_ahb_clk.c), + CLK_LOOKUP("gcc_blsp1_qup4_i2c_apps_clk_src", gcc_blsp1_qup4_i2c_apps_clk_src.c), + CLK_LOOKUP("gcc_blsp1_qup4_i2c_apps_clk", gcc_blsp1_qup4_i2c_apps_clk.c), + + CLK_LOOKUP("blsp1_qup5_ahb_iface_clk", gcc_blsp1_ahb_clk.c), + CLK_LOOKUP("gcc_blsp1_qup5_i2c_apps_clk_src", gcc_blsp1_qup5_i2c_apps_clk_src.c), + CLK_LOOKUP("gcc_blsp1_qup5_i2c_apps_clk", gcc_blsp1_qup5_i2c_apps_clk.c), + + CLK_LOOKUP("blsp1_qup6_ahb_iface_clk", gcc_blsp1_ahb_clk.c), + CLK_LOOKUP("gcc_blsp1_qup6_i2c_apps_clk_src", gcc_blsp1_qup6_i2c_apps_clk_src.c), + CLK_LOOKUP("gcc_blsp1_qup6_i2c_apps_clk", gcc_blsp1_qup6_i2c_apps_clk.c), +}; + + +void msm8916_clock_init(void) +{ + clk_init(msm_clocks_8916, ARRAY_SIZE(msm_clocks_8916)); +} diff --git a/platform/msm/msm8916/gpio.c b/platform/msm/msm8916/gpio.c new file mode 100644 index 000000000..63a8a66dc --- /dev/null +++ b/platform/msm/msm8916/gpio.c @@ -0,0 +1,102 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +void gpio_tlmm_config(uint32_t gpio, uint8_t func, + uint8_t dir, uint8_t pull, + uint8_t drvstr, uint32_t enable) +{ + uint32_t val = 0; + val |= pull; + val |= func << 2; + val |= drvstr << 6; + val |= enable << 9; + writel(val, (uint32_t *)GPIO_CONFIG_ADDR(gpio)); + return; +} + +void gpio_set_dir(uint32_t gpio, uint32_t dir) +{ + writel(dir, (uint32_t *)GPIO_IN_OUT_ADDR(gpio)); + return; +} + +uint32_t gpio_status(uint32_t gpio) +{ + return readl(GPIO_IN_OUT_ADDR(gpio)) & GPIO_IN; +} + +/* Configure gpio for blsp uart 2 */ +void gpio_config_uart_dm(uint8_t id) +{ + /* configure rx gpio */ + gpio_tlmm_config(5, 2, GPIO_INPUT, GPIO_NO_PULL, + GPIO_8MA, GPIO_DISABLE); + + /* configure tx gpio */ + gpio_tlmm_config(4, 2, GPIO_OUTPUT, GPIO_NO_PULL, + GPIO_8MA, GPIO_DISABLE); +} + +void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id) +{ + if(blsp_id == BLSP_ID_1) { + switch (qup_id) { + case QUP_ID_1: + /* configure I2C SDA gpio */ + gpio_tlmm_config(6, 3, GPIO_OUTPUT, GPIO_NO_PULL, + GPIO_8MA, GPIO_DISABLE); + + /* configure I2C SCL gpio */ + gpio_tlmm_config(7, 3, GPIO_OUTPUT, GPIO_NO_PULL, + GPIO_8MA, GPIO_DISABLE); + break; + case QUP_ID_3: + /* configure I2C SDA gpio */ + gpio_tlmm_config(14, 2, GPIO_OUTPUT, GPIO_NO_PULL, + GPIO_8MA, GPIO_DISABLE); + + /* configure I2C SCL gpio */ + gpio_tlmm_config(15, 2, GPIO_OUTPUT, GPIO_NO_PULL, + GPIO_8MA, GPIO_DISABLE); + break; + default: + dprintf(CRITICAL, "Incorrect QUP id %d\n",qup_id); + DEBUG_ASSERT(0); + }; + } else { + dprintf(CRITICAL, "Incorrect BLSP id %d\n",blsp_id); + DEBUG_ASSERT(0); + } +} diff --git a/platform/msm/msm8916/include/platform/clock.h b/platform/msm/msm8916/include/platform/clock.h new file mode 100644 index 000000000..133bc2585 --- /dev/null +++ b/platform/msm/msm8916/include/platform/clock.h @@ -0,0 +1,94 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __MSM8916_CLOCK_H +#define __MSM8916_CLOCK_H + +#include +#include +#include + +#define UART_DM_CLK_RX_TX_BIT_RATE 0xCC + +#define REG_MM(off) (CLK_CTL_BASE + (off)) + +#define MDP_GDSCR REG_MM(0x4D078) +#define GDSC_POWER_ON_BIT (1<<31) +#define GDSC_EN_FEW_WAIT_MASK (0x0F << 16) +#define GDSC_EN_FEW_WAIT_256_MASK (1<<19) + +#define VSYNC_CMD_RCGR REG_MM(0x4D02C) +#define VSYNC_CFG_RCGR REG_MM(0x4D030) +#define MDSS_VSYNC_CBCR REG_MM(0x4D090) + +#define MDP_CMD_RCGR REG_MM(0x4D014) +#define MDP_CFG_RCGR REG_MM(0x4D018) +#define MDP_CBCR REG_MM(0x4D088) +#define MDP_AHB_CBCR REG_MM(0x4D07C) +#define MDP_AXI_CBCR REG_MM(0x4D080) + +#define DSI_BYTE0_CMD_RCGR REG_MM(0x4D044) +#define DSI_BYTE0_CFG_RCGR REG_MM(0x4D048) +#define DSI_BYTE0_CBCR REG_MM(0x4D094) +#define DSI_ESC0_CMD_RCGR REG_MM(0x4D05C) +#define DSI_ESC0_CFG_RCGR REG_MM(0x4D060) +#define DSI_ESC0_CBCR REG_MM(0x4D098) +#define DSI_PIXEL0_CMD_RCGR REG_MM(0x4D000) +#define DSI_PIXEL0_CFG_RCGR REG_MM(0x4D004) +#define DSI_PIXEL0_CBCR REG_MM(0x4D084) +#define DSI_PIXEL0_M REG_MM(0x4D008) +#define DSI_PIXEL0_N REG_MM(0x4D00C) +#define DSI_PIXEL0_D REG_MM(0x4D010) + +#define DSI_BYTE1_CMD_RCGR REG_MM(0x4D0B0) +#define DSI_BYTE1_CFG_RCGR REG_MM(0x4D0B4) +#define DSI_BYTE1_CBCR REG_MM(0x4D0A0) +#define DSI_ESC1_CMD_RCGR REG_MM(0x4D0A8) +#define DSI_ESC1_CFG_RCGR REG_MM(0x4D0AC) +#define DSI_ESC1_CBCR REG_MM(0x4D09C) +#define DSI_PIXEL1_CMD_RCGR REG_MM(0x4D0B8) +#define DSI_PIXEL1_CFG_RCGR REG_MM(0x4D0BC) +#define DSI_PIXEL1_CBCR REG_MM(0x4D0A4) +#define DSI_PIXEL1_M REG_MM(0x4D0C0) +#define DSI_PIXEL1_N REG_MM(0x4D0C4) +#define DSI_PIXEL1_D REG_MM(0x4D0C8) + +void msm8916_clock_init(void); +void mdp_clock_enable(void); +void mdp_clock_disable(void); +void clock_init_mmc(uint32_t interface); +void clock_config_mmc(uint32_t interface, uint32_t freq); +void clock_config_uart_dm(uint8_t id); +void hsusb_clock_init(void); +void mdp_gdsc_ctrl(uint8_t enable); +void mdss_bus_clocks_enable(void); +void mdss_bus_clocks_disable(void); +void gcc_dsi_clocks_enable(uint8_t dual_dsi,uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d); +void gcc_dsi_clocks_disable(uint8_t dual_dsi); +void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id); +#endif diff --git a/platform/msm/msm8916/include/platform/gpio.h b/platform/msm/msm8916/include/platform/gpio.h new file mode 100644 index 000000000..31bc0a5b6 --- /dev/null +++ b/platform/msm/msm8916/include/platform/gpio.h @@ -0,0 +1,72 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PLATFORM_MSM8916_GPIO_H +#define __PLATFORM_MSM8916_GPIO_H + +#include + +/* GPIO TLMM: Direction */ +#define GPIO_INPUT 0 +#define GPIO_OUTPUT 1 + +/* GPIO TLMM: Pullup/Pulldown */ +#define GPIO_NO_PULL 0 +#define GPIO_PULL_DOWN 1 +#define GPIO_KEEPER 2 +#define GPIO_PULL_UP 3 + +/* GPIO TLMM: Drive Strength */ +#define GPIO_2MA 0 +#define GPIO_4MA 1 +#define GPIO_6MA 2 +#define GPIO_8MA 3 +#define GPIO_10MA 4 +#define GPIO_12MA 5 +#define GPIO_14MA 6 +#define GPIO_16MA 7 + +/* GPIO TLMM: Status */ +#define GPIO_ENABLE 0 +#define GPIO_DISABLE 1 + +/* GPIO_IN_OUT register shifts. */ +#define GPIO_IN 0 +#define GPIO_OUT (1<<1) + +void gpio_config_uart_dm(uint8_t id); +uint32_t gpio_status(uint32_t gpio); +void gpio_set_dir(uint32_t gpio, uint32_t dir); +void gpio_tlmm_config(uint32_t gpio, + uint8_t func, + uint8_t dir, + uint8_t pull, + uint8_t drvstr, + uint32_t enable); +void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id); +#endif diff --git a/platform/msm/msm8916/include/platform/iomap.h b/platform/msm/msm8916/include/platform/iomap.h new file mode 100644 index 000000000..5e23a2528 --- /dev/null +++ b/platform/msm/msm8916/include/platform/iomap.h @@ -0,0 +1,310 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _PLATFORM_MSM8916_IOMAP_H_ +#define _PLATFORM_MSM8916_IOMAP_H_ + +#define MSM_IOMAP_BASE 0x00000000 +#define MSM_IOMAP_END 0x08000000 +#define A53_SS_BASE 0x0B000000 +#define A53_SS_END 0x0B200000 + +#define SYSTEM_IMEM_BASE 0x08600000 +#define MSM_SHARED_IMEM_BASE 0x08600000 + +#define RESTART_REASON_ADDR (MSM_SHARED_IMEM_BASE + 0x65C) +#define BS_INFO_OFFSET (0x6B0) +#define BS_INFO_ADDR (MSM_SHARED_IMEM_BASE + BS_INFO_OFFSET) +#define SDRAM_START_ADDR 0x80000000 + +#define MSM_SHARED_BASE 0x86300000 +#define APPS_SS_BASE 0x0B000000 + +#define DDR_START get_ddr_start() +#define ABOOT_FORCE_KERNEL_ADDR DDR_START + 0x8000 +#define ABOOT_FORCE_KERNEL64_ADDR DDR_START + 0x80000 +#define ABOOT_FORCE_RAMDISK_ADDR DDR_START + 0x2000000 +#define ABOOT_FORCE_TAGS_ADDR DDR_START + 0x1E00000 + +#define MSM_GIC_DIST_BASE APPS_SS_BASE +#define MSM_GIC_CPU_BASE (APPS_SS_BASE + 0x2000) +#define APCS_ALIAS0_IPC_INTERRUPT (APPS_SS_BASE + 0x00011008) +#define MSM_WATCHDOG_BASE (APPS_SS_BASE + 0x00017000) +#define MSM_WATCHDOG_RST (MSM_WATCHDOG_BASE + 0x04) +#define MSM_WATCHDOG_EN (MSM_WATCHDOG_BASE + 0x08) +#define APPS_APCS_QTMR_AC_BASE (APPS_SS_BASE + 0x00020000) +#define APPS_APCS_F0_QTMR_V1_BASE (APPS_SS_BASE + 0x00021000) +#define QTMR_BASE APPS_APCS_F0_QTMR_V1_BASE + +#define APCS_BANKED_SAW2_BASE (APPS_SS_BASE + 0x9000) +#define APCS_L2_SAW2_BASE (APPS_SS_BASE + 0x12000) + +#define PERIPH_SS_BASE 0x07800000 + +#define MSM_SDC1_BASE (PERIPH_SS_BASE + 0x00024000) +#define MSM_SDC1_SDHCI_BASE (PERIPH_SS_BASE + 0x00024900) +#define MSM_SDC2_BASE (PERIPH_SS_BASE + 0x00064000) +#define MSM_SDC2_SDHCI_BASE (PERIPH_SS_BASE + 0x00064900) + +/* SDHCI */ +#define SDCC_MCI_HC_MODE (0x00000078) +#define SDCC_HC_PWRCTL_STATUS_REG (0x000000DC) +#define SDCC_HC_PWRCTL_MASK_REG (0x000000E0) +#define SDCC_HC_PWRCTL_CLEAR_REG (0x000000E4) +#define SDCC_HC_PWRCTL_CTL_REG (0x000000E8) +#define BLSP1_UART0_BASE (PERIPH_SS_BASE + 0x000AF000) +#define BLSP1_UART1_BASE (PERIPH_SS_BASE + 0x000B0000) +#define MSM_USB_BASE (PERIPH_SS_BASE + 0x000D9000) + +#define CLK_CTL_BASE 0x1800000 + +#define SPMI_BASE 0x02000000 +#define SPMI_GENI_BASE (SPMI_BASE + 0xA000) +#define SPMI_PIC_BASE (SPMI_BASE + 0x01800000) +#define PMIC_ARB_CORE 0x200F000 + +#define TLMM_BASE_ADDR 0x1000000 +#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + (x)*0x1000) +#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE_ADDR + 0x00000004 + (x)*0x1000) + +#define MPM2_MPM_CTRL_BASE 0x004A0000 +#define MPM2_MPM_PS_HOLD 0x004AB000 +#define MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL 0x004A3000 + +/* CRYPTO ENGINE */ +#define MSM_CE1_BASE 0x073A000 +#define MSM_CE1_BAM_BASE 0x0704000 +#define GCC_CRYPTO_BCR (CLK_CTL_BASE + 0x16000) +#define GCC_CRYPTO_CMD_RCGR (CLK_CTL_BASE + 0x16004) +#define GCC_CRYPTO_CFG_RCGR (CLK_CTL_BASE + 0x16008) +#define GCC_CRYPTO_CBCR (CLK_CTL_BASE + 0x1601C) +#define GCC_CRYPTO_AXI_CBCR (CLK_CTL_BASE + 0x16020) +#define GCC_CRYPTO_AHB_CBCR (CLK_CTL_BASE + 0x16024) + +/* I2C */ +#define BLSP_QUP_BASE(blsp_id, qup_id) (PERIPH_SS_BASE + 0xB5000 + 0x1000 * qup_id) + +#define GCC_BLSP1_QUP1_APPS_CBCR (CLK_CTL_BASE + 0x2008) +#define GCC_BLSP1_QUP1_CFG_RCGR (CLK_CTL_BASE + 0x2010) +#define GCC_BLSP1_QUP1_CMD_RCGR (CLK_CTL_BASE + 0x200C) + +#define GCC_BLSP1_QUP2_APPS_CBCR (CLK_CTL_BASE + 0x3010) +#define GCC_BLSP1_QUP2_CFG_RCGR (CLK_CTL_BASE + 0x3004) +#define GCC_BLSP1_QUP2_CMD_RCGR (CLK_CTL_BASE + 0x3000) + +#define GCC_BLSP1_QUP3_APPS_CBCR (CLK_CTL_BASE + 0x4020) +#define GCC_BLSP1_QUP3_CFG_RCGR (CLK_CTL_BASE + 0x4004) +#define GCC_BLSP1_QUP3_CMD_RCGR (CLK_CTL_BASE + 0x4000) + +#define GCC_BLSP1_QUP4_APPS_CBCR (CLK_CTL_BASE + 0x5020) +#define GCC_BLSP1_QUP4_CFG_RCGR (CLK_CTL_BASE + 0x5004) +#define GCC_BLSP1_QUP4_CMD_RCGR (CLK_CTL_BASE + 0x5000) + +#define GCC_BLSP1_QUP5_APPS_CBCR (CLK_CTL_BASE + 0x6020) +#define GCC_BLSP1_QUP5_CFG_RCGR (CLK_CTL_BASE + 0x6004) +#define GCC_BLSP1_QUP5_CMD_RCGR (CLK_CTL_BASE + 0x6000) + +#define GCC_BLSP1_QUP6_APPS_CBCR (CLK_CTL_BASE + 0x7020) +#define GCC_BLSP1_QUP6_CFG_RCGR (CLK_CTL_BASE + 0x7004) +#define GCC_BLSP1_QUP6_CMD_RCGR (CLK_CTL_BASE + 0x7000) + +/* GPLL */ +#define GPLL0_STATUS (CLK_CTL_BASE + 0x2101C) +#define GPLL1_STATUS (CLK_CTL_BASE + 0x2001C) +#define APCS_GPLL_ENA_VOTE (CLK_CTL_BASE + 0x45000) +#define APCS_CLOCK_BRANCH_ENA_VOTE (CLK_CTL_BASE + 0x45004) + +/* SDCC */ +#define SDC1_HDRV_PULL_CTL (TLMM_BASE_ADDR + 0x10A000) +#define SDCC1_BCR (CLK_CTL_BASE + 0x42000) /* block reset*/ +#define SDCC1_APPS_CBCR (CLK_CTL_BASE + 0x42018) /* branch ontrol */ +#define SDCC1_AHB_CBCR (CLK_CTL_BASE + 0x4201C) +#define SDCC1_CMD_RCGR (CLK_CTL_BASE + 0x42004) /* cmd */ +#define SDCC1_CFG_RCGR (CLK_CTL_BASE + 0x42008) /* cfg */ +#define SDCC1_M (CLK_CTL_BASE + 0x4200C) /* m */ +#define SDCC1_N (CLK_CTL_BASE + 0x42010) /* n */ +#define SDCC1_D (CLK_CTL_BASE + 0x42014) /* d */ + +#define SDC2_HDRV_PULL_CTL (TLMM_BASE_ADDR + 0x109000) +#define SDCC2_BCR (CLK_CTL_BASE + 0x43000) /* block reset */ +#define SDCC2_APPS_CBCR (CLK_CTL_BASE + 0x43018) /* branch control */ +#define SDCC2_AHB_CBCR (CLK_CTL_BASE + 0x4301C) +#define SDCC2_CMD_RCGR (CLK_CTL_BASE + 0x43004) /* cmd */ +#define SDCC2_CFG_RCGR (CLK_CTL_BASE + 0x43008) /* cfg */ +#define SDCC2_M (CLK_CTL_BASE + 0x4300C) /* m */ +#define SDCC2_N (CLK_CTL_BASE + 0x43010) /* n */ +#define SDCC2_D (CLK_CTL_BASE + 0x43014) /* d */ + +/* UART */ +#define BLSP1_AHB_CBCR (CLK_CTL_BASE + 0x1008) +#define BLSP1_UART1_APPS_CBCR (CLK_CTL_BASE + 0x203C) +#define BLSP1_UART1_APPS_CMD_RCGR (CLK_CTL_BASE + 0x2044) +#define BLSP1_UART1_APPS_CFG_RCGR (CLK_CTL_BASE + 0x2048) +#define BLSP1_UART1_APPS_M (CLK_CTL_BASE + 0x204C) +#define BLSP1_UART1_APPS_N (CLK_CTL_BASE + 0x2050) +#define BLSP1_UART1_APPS_D (CLK_CTL_BASE + 0x2054) +#define BLSP1_UART2_APPS_CBCR (CLK_CTL_BASE + 0x302C) +#define BLSP1_UART2_APPS_CMD_RCGR (CLK_CTL_BASE + 0x3034) +#define BLSP1_UART2_APPS_CFG_RCGR (CLK_CTL_BASE + 0x3038) +#define BLSP1_UART2_APPS_M (CLK_CTL_BASE + 0x303C) +#define BLSP1_UART2_APPS_N (CLK_CTL_BASE + 0x3040) +#define BLSP1_UART2_APPS_D (CLK_CTL_BASE + 0x3044) + + +/* USB */ +#define USB_HS_BCR (CLK_CTL_BASE + 0x41000) +#define USB_HS_SYSTEM_CBCR (CLK_CTL_BASE + 0x41004) +#define USB_HS_AHB_CBCR (CLK_CTL_BASE + 0x41008) +#define USB_HS_SYSTEM_CMD_RCGR (CLK_CTL_BASE + 0x41010) +#define USB_HS_SYSTEM_CFG_RCGR (CLK_CTL_BASE + 0x41014) + + +/* RPMB send receive buffer needs to be mapped + * as device memory, define the start address + * and size in MB + */ +#define RPMB_SND_RCV_BUF 0x90000000 +#define RPMB_SND_RCV_BUF_SZ 0x1 + +/* QSEECOM: Secure app region notification */ +#define APP_REGION_ADDR 0x86000000 +#define APP_REGION_SIZE 0x300000 + +/* MDSS */ +#define MIPI_DSI_BASE (0x1A98000) +#define MIPI_DSI0_BASE MIPI_DSI_BASE +#define MIPI_DSI1_BASE (0x1AA0000) +#define DSI0_PHY_BASE (0x1A98500) +#define DSI1_PHY_BASE (0x1AA0500) +#define DSI0_PLL_BASE (0x1A98300) +#define DSI1_PLL_BASE DSI0_PLL_BASE +#define REG_DSI(off) (MIPI_DSI_BASE + 0x04 + (off)) +#define MDP_BASE (0x1A00000) +#define REG_MDP(off) (MDP_BASE + (off)) +#define MDP_HW_REV REG_MDP(0x1000) +#define MDP_VP_0_VIG_0_BASE REG_MDP(0x5000) +#define MDP_VP_0_VIG_1_BASE REG_MDP(0x7000) +#define MDP_VP_0_RGB_0_BASE REG_MDP(0x15000) +#define MDP_VP_0_RGB_1_BASE REG_MDP(0x17000) +#define MDP_VP_0_DMA_0_BASE REG_MDP(0x25000) +#define MDP_VP_0_DMA_1_BASE REG_MDP(0x27000) +#define MDP_VP_0_MIXER_0_BASE REG_MDP(0x45000) +#define MDP_VP_0_MIXER_1_BASE REG_MDP(0x46000) +#define MDP_DISP_INTF_SEL REG_MDP(0x1004) +#define MDP_VIDEO_INTF_UNDERFLOW_CTL REG_MDP(0x12E0) +#define MDP_UPPER_NEW_ROI_PRIOR_RO_START REG_MDP(0x11EC) +#define MDP_LOWER_NEW_ROI_PRIOR_TO_START REG_MDP(0x13F8) +#define MDP_CTL_0_BASE REG_MDP(0x2000) +#define MDP_CTL_1_BASE REG_MDP(0x2200) +#define MDP_CLK_CTRL0 REG_MDP(0x012AC) +#define MDP_CLK_CTRL1 REG_MDP(0x012B4) +#define MDP_CLK_CTRL2 REG_MDP(0x012BC) +#define MDP_CLK_CTRL3 REG_MDP(0x013A8) +#define MDP_CLK_CTRL4 REG_MDP(0x013B0) +#define MDP_CLK_CTRL5 REG_MDP(0x013B8) + +#define MDP_INTF_0_BASE REG_MDP(0x11F00) +#define MDP_INTF_1_BASE REG_MDP(0x12700) +#define MDP_INTF_2_BASE REG_MDP(0x12F00) + +#define MDP_REG_SPLIT_DISPLAY_EN REG_MDP(0x12f4) +#define MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL REG_MDP(0x12F8) +#define MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL REG_MDP(0x13F0) + +#define MDP_REG_PPB0_CNTL REG_MDP(0x1420) +#define MDP_REG_PPB0_CONFIG REG_MDP(0x1424) + +#define MMSS_MDP_SMP_ALLOC_W_BASE REG_MDP(0x1080) +#define MMSS_MDP_SMP_ALLOC_R_BASE REG_MDP(0x1130) + +#define MDP_QOS_REMAPPER_CLASS_0 REG_MDP(0x11E0) + +#define VBIF_VBIF_DDR_FORCE_CLK_ON REG_MDP(0xc8004) +#define VBIF_VBIF_DDR_OUT_MAX_BURST REG_MDP(0xc80D8) +#define VBIF_VBIF_DDR_ARB_CTRL REG_MDP(0xc80F0) +#define VBIF_VBIF_DDR_RND_RBN_QOS_ARB REG_MDP(0xc8124) +#define VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF0 REG_MDP(0xc8160) +#define VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF1 REG_MDP(0xc8164) +#define VBIF_VBIF_DDR_OUT_AOOO_AXI_EN REG_MDP(0xc8178) +#define VBIF_VBIF_DDR_OUT_AX_AOOO REG_MDP(0xc817C) +#define VBIF_VBIF_IN_RD_LIM_CONF0 REG_MDP(0xc80B0) +#define VBIF_VBIF_IN_RD_LIM_CONF1 REG_MDP(0xc80B4) +#define VBIF_VBIF_IN_RD_LIM_CONF2 REG_MDP(0xc80B8) +#define VBIF_VBIF_IN_RD_LIM_CONF3 REG_MDP(0xc80BC) +#define VBIF_VBIF_IN_WR_LIM_CONF0 REG_MDP(0xc80C0) +#define VBIF_VBIF_IN_WR_LIM_CONF1 REG_MDP(0xc80C4) +#define VBIF_VBIF_IN_WR_LIM_CONF2 REG_MDP(0xc80C8) +#define VBIF_VBIF_IN_WR_LIM_CONF3 REG_MDP(0xc80CC) +#define VBIF_VBIF_ABIT_SHORT REG_MDP(0xc8070) +#define VBIF_VBIF_ABIT_SHORT_CONF REG_MDP(0xc8074) +#define VBIF_VBIF_GATE_OFF_WRREQ_EN REG_MDP(0xc80A8) + +#define SOFT_RESET 0x118 +#define CLK_CTRL 0x11C +#define TRIG_CTRL 0x084 +#define CTRL 0x004 +#define COMMAND_MODE_DMA_CTRL 0x03C +#define COMMAND_MODE_MDP_CTRL 0x040 +#define COMMAND_MODE_MDP_DCS_CMD_CTRL 0x044 +#define COMMAND_MODE_MDP_STREAM0_CTRL 0x058 +#define COMMAND_MODE_MDP_STREAM0_TOTAL 0x05C +#define COMMAND_MODE_MDP_STREAM1_CTRL 0x060 +#define COMMAND_MODE_MDP_STREAM1_TOTAL 0x064 +#define ERR_INT_MASK0 0x10C + +#define LANE_CTL 0x0AC +#define LANE_SWAP_CTL 0x0B0 +#define TIMING_CTL 0x0C4 + +#define VIDEO_MODE_ACTIVE_H 0x024 +#define VIDEO_MODE_ACTIVE_V 0x028 +#define VIDEO_MODE_TOTAL 0x02C +#define VIDEO_MODE_HSYNC 0x030 +#define VIDEO_MODE_VSYNC 0x034 +#define VIDEO_MODE_VSYNC_VPOS 0x038 + +#define DMA_CMD_OFFSET 0x048 +#define DMA_CMD_LENGTH 0x04C + +#define INT_CTRL 0x110 +#define CMD_MODE_DMA_SW_TRIGGER 0x090 + +#define EOT_PACKET_CTRL 0x0CC +#define MISR_CMD_CTRL 0x0A0 +#define MISR_VIDEO_CTRL 0x0A4 +#define VIDEO_MODE_CTRL 0x010 +#define HS_TIMER_CTRL 0x0BC + +#define TCSR_TZ_WONCE 0x193D000 +#define TCSR_BOOT_MISC_DETECT 0x193D100 + +#define BOOT_ROM_BASE 0x00100000 +#define BOOT_ROM_END 0x00124000 /* Crashes when reading more */ + +#define RPM_DATA_RAM 0x00290000 +#endif diff --git a/platform/msm/msm8916/include/platform/irqs.h b/platform/msm/msm8916/include/platform/irqs.h new file mode 100644 index 000000000..6859c0c46 --- /dev/null +++ b/platform/msm/msm8916/include/platform/irqs.h @@ -0,0 +1,68 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __IRQS_MSM8916_H +#define __IRQS_MSM8916_H + +/* MSM ACPU Interrupt Numbers */ + +/* 0-15: STI/SGI (software triggered/generated interrupts) + * 16-31: PPI (private peripheral interrupts) + * 32+: SPI (shared peripheral interrupts) + */ +int qtmr_irq(void); + +#define GIC_PPI_START 16 +#define GIC_SPI_START 32 + +#define INT_QTMR_NON_SECURE_PHY_TIMER_EXP (GIC_PPI_START + 3) +#define INT_QTMR_VIRTUAL_TIMER_EXP (GIC_PPI_START + 4) + +#define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP qtmr_irq() +#define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP_8x16 (GIC_SPI_START + 8) +#define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP_8x39 (GIC_SPI_START + 257) +#define SDCC1_PWRCTL_IRQ (GIC_SPI_START + 138) +#define SDCC2_PWRCTL_IRQ (GIC_SPI_START + 221) + +#define USB1_HS_BAM_IRQ (GIC_SPI_START + 135) +#define USB1_HS_IRQ (GIC_SPI_START + 134) + +/* Retrofit universal macro names */ +#define INT_USB_HS USB1_HS_IRQ + +#define EE0_KRAIT_HLOS_SPMI_PERIPH_IRQ (GIC_SPI_START + 190) + +#define NR_MSM_IRQS 256 +#define NR_GPIO_IRQS 173 +#define NR_BOARD_IRQS 0 + +#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + \ + NR_BOARD_IRQS) + +#define BLSP_QUP_IRQ(blsp_id, qup_id) (GIC_SPI_START + 95 + qup_id) +#endif /* __IRQS_MSM8916_H */ diff --git a/platform/msm/msm8916/platform.c b/platform/msm/msm8916/platform.c new file mode 100644 index 000000000..c61ae08f0 --- /dev/null +++ b/platform/msm/msm8916/platform.c @@ -0,0 +1,64 @@ +/* + * Use of this source code is governed by a MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT + */ +#include +#include +#include +#include +#include +#include +#include + +struct mmu_initial_mapping mmu_initial_mappings[] = { + { + .phys = MEMBASE, + .virt = MEMBASE, + .size = MEMSIZE, + .flags = 0, + .name = "lk" + }, + { + .phys = MSM_IOMAP_BASE, + .virt = MSM_IOMAP_BASE, + .size = MSM_IOMAP_END - MSM_IOMAP_BASE, + .flags = MMU_INITIAL_MAPPING_FLAG_DEVICE, + }, + { + .phys = A53_SS_BASE, + .virt = A53_SS_BASE, + .size = A53_SS_END - A53_SS_BASE, + .flags = MMU_INITIAL_MAPPING_FLAG_DEVICE, + }, + { + .phys = SYSTEM_IMEM_BASE, + .virt = SYSTEM_IMEM_BASE, + .size = MB, + .flags = 0, + }, + { + .phys = MSM_SHARED_BASE, + .virt = MSM_SHARED_BASE, + .size = MB, + .flags = 0, + }, + { + .phys = SCRATCH_ADDR, + .virt = SCRATCH_ADDR, + .size = 256*MB, + .flags = 0, + }, + /* null entry to terminate the list */ + { 0 } +}; + +void platform_early_init(void) { + msm8916_clock_init(); + uart_dm_init(2, 0, BLSP1_UART1_BASE); +} + +int qtmr_irq(void) +{ + return INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP_8x16; +} diff --git a/platform/msm/msm8916/rules.mk b/platform/msm/msm8916/rules.mk new file mode 100644 index 000000000..83461800c --- /dev/null +++ b/platform/msm/msm8916/rules.mk @@ -0,0 +1,20 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +MODULE := $(LOCAL_DIR) + +ARCH := arm +ARM_CPU := cortex-a8 +CPU := generic + +MODULE_SRCS += \ + $(LOCAL_DIR)/acpuclock.c \ + $(LOCAL_DIR)/clock.c \ + $(LOCAL_DIR)/gpio.c \ + $(LOCAL_DIR)/platform.c + +MEMBASE := 0x8F600000 +MEMSIZE := 0x00100000 +KERNEL_BASE = $(MEMBASE) + +include platform/msm/common/rules.mk +include make/module.mk diff --git a/platform/msm/rules.mk b/platform/msm/rules.mk new file mode 100644 index 000000000..12db36219 --- /dev/null +++ b/platform/msm/rules.mk @@ -0,0 +1,8 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld + +GLOBAL_INCLUDES += \ + $(LOCAL_DIR)/common/include + +include $(LOCAL_DIR)/$(SUB_PLATFORM)/rules.mk diff --git a/project/msm8916.mk b/project/msm8916.mk new file mode 100644 index 000000000..51a9dc388 --- /dev/null +++ b/project/msm8916.mk @@ -0,0 +1,6 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +TARGET := msm8916 + +MODULES += \ + app/shell diff --git a/target/msm8916/init.c b/target/msm8916/init.c new file mode 100644 index 000000000..519e009ed --- /dev/null +++ b/target/msm8916/init.c @@ -0,0 +1,12 @@ +/* + * Use of this source code is governed by a MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT + */ +#include + +void target_early_init(void) { +} + +void target_init(void) { +} diff --git a/target/msm8916/rules.mk b/target/msm8916/rules.mk new file mode 100644 index 000000000..d163a0154 --- /dev/null +++ b/target/msm8916/rules.mk @@ -0,0 +1,16 @@ +LOCAL_DIR := $(GET_LOCAL_DIR) + +MODULE := $(LOCAL_DIR) + +PLATFORM := msm +SUB_PLATFORM := msm8916 + +SCRATCH_ADDR := 0x90000000 + +GLOBAL_DEFINES += \ + SCRATCH_ADDR=$(SCRATCH_ADDR) + +MODULE_SRCS += \ + $(LOCAL_DIR)/init.c + +include make/module.mk