M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions

View File

@@ -0,0 +1,289 @@
/*
* Copyright (c) 2012-2013, 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 <debug.h>
#include <reg.h>
#include <platform/iomap.h>
#include <platform/clock.h>
#include <uart_dm.h>
#include <gsbi.h>
#include <mmc.h>
#include <clock.h>
#include <board.h>
#include <smem.h>
/* Set rate and enable the clock */
static void clock_config(uint32_t ns, uint32_t md, uint32_t ns_addr, uint32_t md_addr)
{
unsigned int val = 0;
/* Activate the reset for the M/N Counter */
val = 1 << 7;
writel(val, ns_addr);
/* Write the MD value into the MD register */
if (md_addr != 0x0)
writel(md, md_addr);
/* Write the ns value, and active reset for M/N Counter, again */
val = 1 << 7;
val |= ns;
writel(val, ns_addr);
/* De-activate the reset for M/N Counter */
val = 1 << 7;
val = ~val;
val = val & readl(ns_addr);
writel(val, ns_addr);
/* Enable the Clock Root */
val = 1 << 11;
val = val | readl(ns_addr);
writel(val, ns_addr);
/* Enable the Clock Branch */
val = 1 << 9;
val = val | readl(ns_addr);
writel(val, ns_addr);
/* Enable the M/N Counter */
val = 1 << 8;
val = val | readl(ns_addr);
writel(val, ns_addr);
}
/* Write the M,N,D values and enable the MMSS Clocks */
void config_mmss_clk(uint32_t ns,
uint32_t md,
uint32_t cc,
uint32_t ns_addr, uint32_t md_addr, uint32_t cc_addr)
{
unsigned int val = 0;
clock_config(ns, md, ns_addr, md_addr);
/* Enable MND counter */
val = cc | (1 << 5);
val = val | readl(cc_addr);
writel(val, cc_addr);
/* Enable the root of the clock tree */
val = 1 << 2;
val = val | readl(cc_addr);
writel(val, cc_addr);
/* Enable the Pixel Clock */
val = 1 << 0;
val = val | readl(cc_addr);
writel(val, cc_addr);
/* Force On */
val = 1 << 31;
val = val | readl(cc_addr);
writel(val, cc_addr);
}
void hsusb_clock_init(void)
{
clk_get_set_enable("usb_hs_clk", 60000000, 1);
}
/* Configure UART clock - based on the gsbi id */
void clock_config_uart_dm(uint8_t id)
{
char gsbi_uart_clk_id[64];
char gsbi_p_clk_id[64];
snprintf(gsbi_uart_clk_id, 64,"gsbi%u_uart_clk", id);
clk_get_set_enable(gsbi_uart_clk_id, 1843200, 1);
snprintf(gsbi_p_clk_id, 64,"gsbi%u_pclk", id);
clk_get_set_enable(gsbi_p_clk_id, 0, 1);
}
/* Configure i2c clock */
void clock_config_i2c(uint8_t id, uint32_t freq)
{
char gsbi_qup_clk_id[64];
char gsbi_p_clk_id[64];
snprintf(gsbi_qup_clk_id, 64,"gsbi%u_qup_clk", id);
clk_get_set_enable(gsbi_qup_clk_id, 24000000, 1);
snprintf(gsbi_p_clk_id, 64,"gsbi%u_pclk", id);
clk_get_set_enable(gsbi_p_clk_id, 0, 1);
}
/* Turn on MDP related clocks and pll's for MDP */
void mdp_clock_init(void)
{
/* Set MDP clock to 200MHz */
clk_get_set_enable("mdp_clk", 200000000, 1);
/* Seems to lose pixels without this from status 0x051E0048 */
clk_get_set_enable("lut_mdp", 0, 1);
}
/* Initialize all clocks needed by Display */
void mmss_clock_init(void)
{
/* Configure Pixel clock */
config_mmss_clk(PIXEL_NS_VAL, PIXEL_MD_VAL, PIXEL_CC_VAL,
DSI_PIXEL_NS_REG, DSI_PIXEL_MD_REG, DSI_PIXEL_CC_REG);
/* Configure DSI clock */
config_mmss_clk(DSI_NS_VAL, DSI_MD_VAL, DSI_CC_VAL, DSI_NS_REG,
DSI_MD_REG, DSI_CC_REG);
/* Configure Byte clock */
config_mmss_clk(BYTE_NS_VAL, 0x0, BYTE_CC_VAL, DSI1_BYTE_NS_REG, 0x0,
DSI1_BYTE_CC_REG);
/* Configure ESC clock */
config_mmss_clk(ESC_NS_VAL, 0x0, ESC_CC_VAL, DSI1_ESC_NS_REG, 0x0,
DSI1_ESC_CC_REG);
}
void liquid_mmss_clock_init(void)
{
/* Configure Pixel clock = 78.75 MHZ */
config_mmss_clk(0x2003, 0x01FB, 0x0005,
DSI_PIXEL_NS_REG, DSI_PIXEL_MD_REG, DSI_PIXEL_CC_REG);
/* Configure DSI clock = 236.25 MHZ */
config_mmss_clk(0x03, 0x03FB, 0x05,
DSI_NS_REG, DSI_MD_REG, DSI_CC_REG);
/* Configure Byte clock = 59.06 MHZ */
config_mmss_clk(0x0B01, 0x0, 0x80ff0025,
DSI1_BYTE_NS_REG, 0x0, DSI1_BYTE_CC_REG);
/* Configure ESC clock = 13.5 MHZ */
config_mmss_clk(0x1B00, 0x0, 0x005,
DSI1_ESC_NS_REG, 0x0, DSI1_ESC_CC_REG);
}
void mmss_clock_disable(void)
{
writel(0x80000000, DSI1_BYTE_CC_REG);
writel(0x0, DSI_PIXEL_CC_REG);
writel(0x0, DSI1_BYTE_NS_REG);
writel(0x0, DSI1_ESC_CC_REG);
writel(0x0, DSI1_ESC_NS_REG);
/* Disable root clock */
writel(0x0, DSI_CC_REG);
}
/* Intialize MMC clock */
void clock_init_mmc(uint32_t interface)
{
/* Nothing to be done. */
}
/* Configure MMC clock */
void clock_config_mmc(uint32_t interface, uint32_t freq)
{
char sdc_clk[64];
unsigned rate;
uint32_t reg = 0;
snprintf(sdc_clk, 64, "sdc%u_clk", interface);
/* Disalbe MCI_CLK before changing the sdcc clock */
mmc_boot_mci_clk_disable();
switch(freq)
{
case MMC_CLK_400KHZ:
rate = 144000;
break;
case MMC_CLK_48MHZ:
case MMC_CLK_50MHZ: /* Max supported is 48MHZ */
rate = 48000000;
break;
case MMC_CLK_96MHZ:
rate = 96000000;
break;
default:
ASSERT(0);
};
clk_get_set_enable(sdc_clk, rate, 1);
/* Enable MCI clk */
mmc_boot_mci_clk_enable();
}
/* Configure crypto engine clock */
void ce_clock_init(void)
{
uint32_t platform_id;
platform_id = board_platform_id();
if ((platform_id == APQ8064) || (platform_id == APQ8064AA)
|| (platform_id == APQ8064AB))
{
/* Enable HCLK for CE3 */
clk_get_set_enable("ce3_pclk", 0, 1);
/* Enable core clk for CE3 */
clk_get_set_enable("ce3_clk", 0, 1);
}
else
{
/* Enable HCLK for CE1 */
clk_get_set_enable("ce1_pclk", 0, 1);
/* Enable core clk for CE3 */
clk_get_set_enable("ce1_clk", 0, 1);
}
}
/* Async Reset CE1 */
void ce_async_reset()
{
/* Enable Async reset bit for HCLK CE1 */
writel((1<<7) | (1 << 4), CE1_HCLK_CTL_REG);
/* Enable Async reset bit for core clk for CE1 */
writel((1<<7) | (1 << 4), CE1_CORE_CLK_CTL_REG);
/* Add a small delay between switching the
* async intput from high to low
*/
udelay(2);
/* Disable Async reset bit for HCLK for CE1 */
writel((1 << 4), CE1_HCLK_CTL_REG);
/* Disable Async reset bit for core clk for CE1 */
writel((1 << 4), CE1_CORE_CLK_CTL_REG);
return;
}

View File

@@ -0,0 +1,997 @@
/*
* 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 <stdint.h>
#include <debug.h>
#include <reg.h>
#include <err.h>
#include <limits.h>
#include <clock.h>
#include <clock_pll.h>
#include <clock-local.h>
#include <bits.h>
#include <platform/iomap.h>
#include <platform/clock.h>
#include <platform/timer.h>
#include <sys/types.h>
extern void dmb(void);
static int xo_clk_enable(struct clk *clk)
{
/* Assuming pxo already running */
return 0;
}
static void xo_clk_disable(struct clk *clk)
{
/* Do nothing */
}
static struct clk_ops clk_ops_xo = {
.enable = xo_clk_enable,
.disable = xo_clk_disable,
.get_rate = fixed_clk_get_rate,
};
static struct fixed_clk pxo_clk = {
.rate = 27000000,
.c = {
.dbg_name = "pxo_clk",
.ops = &clk_ops_xo,
},
};
static struct fixed_clk cxo_clk = {
.rate = 19200000,
.c = {
.dbg_name = "cxo_clk",
.ops = &clk_ops_xo,
},
};
/*
* PLL Clocks
*/
struct clk_ops clk_ops_pll_vote = {
.enable = pll_vote_clk_enable,
.disable = pll_vote_clk_disable,
.is_enabled = pll_vote_clk_is_enabled,
.get_rate = pll_vote_clk_get_rate,
.get_parent = pll_vote_clk_get_parent,
};
struct clk_ops clk_ops_pll = {
.enable = pll_clk_enable,
.disable = pll_clk_disable,
.get_rate = pll_clk_get_rate,
.get_parent = pll_clk_get_parent,
};
static struct pll_clk pll2_clk = {
.rate = 800000000,
.mode_reg = (void *)MM_PLL1_MODE_REG,
.parent = &pxo_clk.c,
.c = {
.dbg_name = "pll2_clk",
.ops = &clk_ops_pll,
},
};
static struct pll_clk pll3_clk = {
.rate = 1200000000,
.mode_reg = (void *)BB_PLL3_MODE_REG,
.parent = &pxo_clk.c,
.c = {
.dbg_name = "pll3_clk",
.ops = &clk_ops_pll,
},
};
static struct pll_vote_clk pll8_clk = {
.rate = 384000000,
.en_reg = (void *)BB_PLL_ENA_SC0_REG,
.en_mask = BIT(8),
.status_reg = (void *)BB_PLL8_STATUS_REG,
.status_mask = BIT(16),
.parent = &pxo_clk.c,
.c = {
.dbg_name = "pll8_clk",
.ops = &clk_ops_pll_vote,
},
};
static struct clk_ops soc_clk_ops_8960 = {
.enable = local_clk_enable,
.disable = local_clk_disable,
.set_rate = local_clk_set_rate,
.get_rate = local_clk_get_rate,
.is_enabled = local_clk_is_enabled,
.round_rate = local_clk_round_rate,
.get_parent = local_clk_get_parent,
};
static struct clk_ops clk_ops_branch = {
.enable = branch_clk_enable,
.disable = branch_clk_disable,
.is_enabled = branch_clk_is_enabled,
.get_parent = branch_clk_get_parent,
.set_parent = branch_clk_set_parent,
};
/*
* Peripheral Clocks
*/
#define CLK_GSBI_UART(i, n, h_r, h_b) \
struct rcg_clk i##_clk = { \
.b = { \
.ctl_reg = (void *)GSBIn_UART_APPS_NS_REG(n), \
.en_mask = BIT(9), \
.reset_reg = (void *)GSBIn_RESET_REG(n), \
.reset_mask = BIT(0), \
.halt_reg = (void *)h_r, \
.halt_bit = h_b, \
}, \
.ns_reg = (void *)GSBIn_UART_APPS_NS_REG(n), \
.md_reg = (void *)GSBIn_UART_APPS_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(31, 16) | BM(6, 0)), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_gsbi_uart, \
.current_freq = &local_dummy_freq, \
.c = { \
.dbg_name = #i "_clk", \
.ops = &soc_clk_ops_8960, \
}, \
}
#define F_GSBI_UART(f, s, d, m, n) \
{ \
.freq_hz = f, \
.src_clk = &s##_clk.c, \
.md_val = MD16(m, n), \
.ns_val = NS(31, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
.mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gsbi_uart[] = {
F_GSBI_UART( 1843200, pll8, 1, 3, 625),
F_GSBI_UART( 3686400, pll8, 1, 6, 625),
F_GSBI_UART( 7372800, pll8, 1, 12, 625),
F_GSBI_UART(14745600, pll8, 1, 24, 625),
F_GSBI_UART(16000000, pll8, 4, 1, 6),
F_GSBI_UART(24000000, pll8, 4, 1, 4),
F_GSBI_UART(32000000, pll8, 4, 1, 3),
F_GSBI_UART(40000000, pll8, 1, 5, 48),
F_GSBI_UART(46400000, pll8, 1, 29, 240),
F_GSBI_UART(48000000, pll8, 4, 1, 2),
F_GSBI_UART(51200000, pll8, 1, 2, 15),
F_GSBI_UART(56000000, pll8, 1, 7, 48),
F_GSBI_UART(58982400, pll8, 1, 96, 625),
F_GSBI_UART(64000000, pll8, 2, 1, 3),
F_END
};
static CLK_GSBI_UART(gsbi1_uart, 1, CLK_HALT_CFPB_STATEA_REG, 10);
static CLK_GSBI_UART(gsbi2_uart, 2, CLK_HALT_CFPB_STATEA_REG, 6);
static CLK_GSBI_UART(gsbi3_uart, 3, CLK_HALT_CFPB_STATEA_REG, 2);
static CLK_GSBI_UART(gsbi4_uart, 4, CLK_HALT_CFPB_STATEB_REG, 26);
static CLK_GSBI_UART(gsbi5_uart, 5, CLK_HALT_CFPB_STATEB_REG, 22);
static CLK_GSBI_UART(gsbi6_uart, 6, CLK_HALT_CFPB_STATEB_REG, 18);
static CLK_GSBI_UART(gsbi7_uart, 7, CLK_HALT_CFPB_STATEB_REG, 14);
static CLK_GSBI_UART(gsbi8_uart, 8, CLK_HALT_CFPB_STATEB_REG, 10);
static CLK_GSBI_UART(gsbi9_uart, 9, CLK_HALT_CFPB_STATEB_REG, 6);
static CLK_GSBI_UART(gsbi10_uart, 10, CLK_HALT_CFPB_STATEB_REG, 2);
static CLK_GSBI_UART(gsbi11_uart, 11, CLK_HALT_CFPB_STATEC_REG, 17);
static CLK_GSBI_UART(gsbi12_uart, 12, CLK_HALT_CFPB_STATEC_REG, 13);
#define CLK_GSBI_QUP(i, n, h_r, h_b) \
struct rcg_clk i##_clk = { \
.b = { \
.ctl_reg = (void *)GSBIn_QUP_APPS_NS_REG(n), \
.en_mask = BIT(9), \
.reset_reg = (void *)GSBIn_RESET_REG(n), \
.reset_mask = BIT(0), \
.halt_reg = (void *)h_r, \
.halt_bit = h_b, \
}, \
.ns_reg = (void *)GSBIn_QUP_APPS_NS_REG(n), \
.md_reg = (void *)GSBIn_QUP_APPS_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_gsbi_qup, \
.current_freq = &local_dummy_freq, \
.c = { \
.dbg_name = #i "_clk", \
.ops = &soc_clk_ops_8960, \
}, \
}
#define F_GSBI_QUP(f, s, d, m, n) \
{ \
.freq_hz = f, \
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
.mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gsbi_qup[] = {
F_GSBI_QUP( 1100000, pxo, 1, 2, 49),
F_GSBI_QUP( 5400000, pxo, 1, 1, 5),
F_GSBI_QUP(10800000, pxo, 1, 2, 5),
F_GSBI_QUP(15060000, pll8, 1, 2, 51),
F_GSBI_QUP(24000000, pll8, 4, 1, 4),
F_GSBI_QUP(25600000, pll8, 1, 1, 15),
F_GSBI_QUP(27000000, pxo, 1, 0, 0),
F_GSBI_QUP(48000000, pll8, 4, 1, 2),
F_GSBI_QUP(51200000, pll8, 1, 2, 15),
F_END
};
static CLK_GSBI_QUP(gsbi1_qup, 1, CLK_HALT_CFPB_STATEA_REG, 9);
static CLK_GSBI_QUP(gsbi2_qup, 2, CLK_HALT_CFPB_STATEA_REG, 4);
static CLK_GSBI_QUP(gsbi3_qup, 3, CLK_HALT_CFPB_STATEA_REG, 0);
static CLK_GSBI_QUP(gsbi4_qup, 4, CLK_HALT_CFPB_STATEB_REG, 24);
static CLK_GSBI_QUP(gsbi5_qup, 5, CLK_HALT_CFPB_STATEB_REG, 20);
static CLK_GSBI_QUP(gsbi6_qup, 6, CLK_HALT_CFPB_STATEB_REG, 16);
static CLK_GSBI_QUP(gsbi7_qup, 7, CLK_HALT_CFPB_STATEB_REG, 12);
static CLK_GSBI_QUP(gsbi8_qup, 8, CLK_HALT_CFPB_STATEB_REG, 8);
static CLK_GSBI_QUP(gsbi9_qup, 9, CLK_HALT_CFPB_STATEB_REG, 4);
static CLK_GSBI_QUP(gsbi10_qup, 10, CLK_HALT_CFPB_STATEB_REG, 0);
static CLK_GSBI_QUP(gsbi11_qup, 11, CLK_HALT_CFPB_STATEC_REG, 15);
static CLK_GSBI_QUP(gsbi12_qup, 12, CLK_HALT_CFPB_STATEC_REG, 11);
#define F_USB(f, s, d, m, n) \
{ \
.freq_hz = f, \
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
.mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_usb[] = {
F_USB(60000000, pll8, 1, 5, 32),
F_END
};
static struct rcg_clk usb_hs1_xcvr_clk = {
.b = {
.ctl_reg = (void *)USB_HS1_XCVR_FS_CLK_NS_REG,
.en_mask = BIT(9),
.reset_reg = (void *)USB_HS1_RESET_REG,
.reset_mask = BIT(0),
.halt_reg = (void *)CLK_HALT_DFAB_STATE_REG,
.halt_bit = 0,
},
.ns_reg = (void *)USB_HS1_XCVR_FS_CLK_NS_REG,
.md_reg = (void *)USB_HS1_XCVR_FS_CLK_MD_REG,
.root_en_mask = BIT(11),
.ns_mask = (BM(23, 16) | BM(6, 0)),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_usb,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "usb_hs1_xcvr_clk",
.ops = &soc_clk_ops_8960,
},
};
#define CLK_SDC(i, n, h_r, h_c, h_b) \
struct rcg_clk i##_clk = { \
.b = { \
.ctl_reg = (void *)SDCn_APPS_CLK_NS_REG(n), \
.en_mask = BIT(9), \
.reset_reg = (void *)SDCn_RESET_REG(n), \
.reset_mask = BIT(0), \
.halt_reg = (void *)h_r, \
.halt_check = h_c, \
.halt_bit = h_b, \
}, \
.ns_reg = (void *)SDCn_APPS_CLK_NS_REG(n), \
.md_reg = (void *)SDCn_APPS_CLK_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_sdc, \
.current_freq = &local_dummy_freq, \
.c = { \
.dbg_name = #i "_clk", \
.ops = &soc_clk_ops_8960, \
}, \
}
#define F_SDC(f, s, d, m, n) \
{ \
.freq_hz = f, \
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
.mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_sdc[] = {
F_SDC( 144000, pxo, 3, 2, 125),
F_SDC( 400000, pll8, 4, 1, 240),
F_SDC( 16000000, pll8, 4, 1, 6),
F_SDC( 17070000, pll8, 1, 2, 45),
F_SDC( 20210000, pll8, 1, 1, 19),
F_SDC( 24000000, pll8, 4, 1, 4),
F_SDC( 48000000, pll8, 4, 1, 2),
F_SDC( 64000000, pll8, 3, 1, 2),
F_SDC( 96000000, pll8, 4, 0, 0),
F_SDC(192000000, pll8, 2, 0, 0),
F_END
};
static CLK_SDC(sdc1, 1, CLK_HALT_DFAB_STATE_REG, HALT, 6);
static CLK_SDC(sdc2, 2, CLK_HALT_DFAB_STATE_REG, HALT, 5);
static CLK_SDC(sdc3, 3, CLK_HALT_DFAB_STATE_REG, HALT, 4);
static CLK_SDC(sdc4, 4, CLK_HALT_DFAB_STATE_REG, HALT, 3);
static CLK_SDC(sdc5, 5, CLK_HALT_DFAB_STATE_REG, HALT, 2);
static struct branch_clk ce1_core_clk = {
.b = {
.ctl_reg = (void *)CE1_CORE_CLK_CTL_REG,
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEC_REG,
.halt_bit = 27,
},
.c = {
.dbg_name = "ce1_core_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk ce1_p_clk = {
.b = {
.ctl_reg = (void *)CE1_HCLK_CTL_REG,
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEC_REG,
.halt_bit = 1,
},
.c = {
.dbg_name = "ce1_p_clk",
.ops = &clk_ops_branch,
},
};
#define F_CE(f, s, d) \
{ \
.freq_hz = f, \
.src_clk = &s##_clk.c, \
.ns_val = NS_DIVSRC(6, 3, d, 2, 0, s##_to_bb_mux), \
}
static struct clk_freq_tbl clk_tbl_ce3[] = {
F_CE( 48000000, pll8, 8),
F_CE(100000000, pll3, 12),
F_END
};
static struct rcg_clk ce3_src_clk = {
.b = {
.ctl_reg = (void *)CE3_CLK_SRC_NS_REG,
.en_mask = 0,
.halt_check = NOCHECK,
},
.ns_reg = (void *)CE3_CLK_SRC_NS_REG,
.root_en_mask = BIT(7),
.ns_mask = BM(6, 0),
.set_rate = set_rate_nop,
.freq_tbl = clk_tbl_ce3,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "ce3_src_clk",
.ops = &soc_clk_ops_8960,
},
};
static struct branch_clk ce3_core_clk = {
.b = {
.ctl_reg = (void *)CE3_CORE_CLK_CTL_REG,
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_GSS_KPSS_MISC_STATE_REG,
.halt_bit = 5,
},
.parent = &ce3_src_clk.c,
.c = {
.dbg_name = "ce3_core_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk ce3_p_clk = {
.b = {
.ctl_reg = (void *)CE3_HCLK_CTL_REG,
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_AFAB_SFAB_STATEB_REG,
.halt_bit = 16,
},
.parent = &ce3_src_clk.c,
.c = {
.dbg_name = "ce3_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gsbi1_p_clk = {
.b = {
.ctl_reg = (void *)GSBIn_HCLK_CTL_REG(1),
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 11,
},
.c = {
.dbg_name = "gsbi1_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gsbi2_p_clk = {
.b = {
.ctl_reg = (void *)GSBIn_HCLK_CTL_REG(2),
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 7,
},
.c = {
.dbg_name = "gsbi2_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gsbi3_p_clk = {
.b = {
.ctl_reg = (void *)GSBIn_HCLK_CTL_REG(3),
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEA_REG,
.halt_bit = 3,
},
.c = {
.dbg_name = "gsbi3_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gsbi4_p_clk = {
.b = {
.ctl_reg = (void *)GSBIn_HCLK_CTL_REG(4),
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEB_REG,
.halt_bit = 27,
},
.c = {
.dbg_name = "gsbi4_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gsbi5_p_clk = {
.b = {
.ctl_reg = (void *)GSBIn_HCLK_CTL_REG(5),
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEB_REG,
.halt_bit = 23,
},
.c = {
.dbg_name = "gsbi5_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gsbi6_p_clk = {
.b = {
.ctl_reg = (void *)GSBIn_HCLK_CTL_REG(6),
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEB_REG,
.halt_bit = 19,
},
.c = {
.dbg_name = "gsbi6_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gsbi7_p_clk = {
.b = {
.ctl_reg = (void *)GSBIn_HCLK_CTL_REG(7),
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEB_REG,
.halt_bit = 15,
},
.c = {
.dbg_name = "gsbi7_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gsbi8_p_clk = {
.b = {
.ctl_reg = (void *)GSBIn_HCLK_CTL_REG(8),
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEB_REG,
.halt_bit = 11,
},
.c = {
.dbg_name = "gsbi8_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gsbi9_p_clk = {
.b = {
.ctl_reg = (void *)GSBIn_HCLK_CTL_REG(9),
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEB_REG,
.halt_bit = 7,
},
.c = {
.dbg_name = "gsbi9_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gsbi10_p_clk = {
.b = {
.ctl_reg = (void *)GSBIn_HCLK_CTL_REG(10),
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEB_REG,
.halt_bit = 3,
},
.c = {
.dbg_name = "gsbi10_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gsbi11_p_clk = {
.b = {
.ctl_reg = (void *)GSBIn_HCLK_CTL_REG(11),
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEC_REG,
.halt_bit = 18,
},
.c = {
.dbg_name = "gsbi11_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gsbi12_p_clk = {
.b = {
.ctl_reg = (void *)GSBIn_HCLK_CTL_REG(12),
.en_mask = BIT(4),
.halt_reg = (void *)CLK_HALT_CFPB_STATEC_REG,
.halt_bit = 14,
},
.c = {
.dbg_name = "gsbi12_p_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk mdp_axi_clk = {
.b = {
.ctl_reg = (void *)MAXI_EN_REG,
.en_mask = BIT(23),
.reset_reg = (void *)SW_RESET_AXI_REG,
.reset_mask = BIT(13),
.halt_reg = (void *)DBG_BUS_VEC_E_REG,
.halt_bit = 8,
},
.c = {
.dbg_name = "mdp_axi_clk",
.ops = &clk_ops_branch,
},
};
#define F_MDP(f, s, m, n) \
{ \
.freq_hz = f, \
.src_clk = &s##_clk.c, \
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MND_BANKED8(22, 14, n, m, 3, 0, s##_to_mm_mux), \
.ctl_val = CC_BANKED(9, 6, n), \
.mnd_en_mask = (BIT(8) | BIT(5)) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_mdp[] = {
F_MDP( 9600000, pll8, 1, 40),
F_MDP( 13710000, pll8, 1, 28),
F_MDP( 27000000, pxo, 0, 0),
F_MDP( 29540000, pll8, 1, 13),
F_MDP( 34910000, pll8, 1, 11),
F_MDP( 38400000, pll8, 1, 10),
F_MDP( 59080000, pll8, 2, 13),
F_MDP( 76800000, pll8, 1, 5),
F_MDP( 85330000, pll8, 2, 9),
F_MDP( 96000000, pll8, 1, 4),
F_MDP(128000000, pll8, 1, 3),
F_MDP(160000000, pll2, 1, 5),
F_MDP(177780000, pll2, 2, 9),
F_MDP(200000000, pll2, 1, 4),
F_END
};
static struct bank_masks bmnd_info_mdp = {
.bank_sel_mask = BIT(11),
.bank0_mask = {
.md_reg = (void *)MDP_MD0_REG,
.ns_mask = BM(29, 22) | BM(5, 3),
.rst_mask = BIT(31),
.mnd_en_mask = BIT(8),
.mode_mask = BM(10, 9),
},
.bank1_mask = {
.md_reg = (void *)MDP_MD1_REG,
.ns_mask = BM(21, 14) | BM(2, 0),
.rst_mask = BIT(30),
.mnd_en_mask = BIT(5),
.mode_mask = BM(7, 6),
},
};
static struct rcg_clk mdp_clk = {
.b = {
.ctl_reg = (void *)MDP_CC_REG,
.en_mask = BIT(0),
.reset_reg = (void *)SW_RESET_CORE_REG,
.reset_mask = BIT(21),
.halt_reg = (void *)DBG_BUS_VEC_C_REG,
.halt_bit = 10,
},
.ns_reg = (void *)MDP_NS_REG,
.root_en_mask = BIT(2),
.set_rate = set_rate_mnd_banked,
.freq_tbl = clk_tbl_mdp,
.bank_masks = &bmnd_info_mdp,
.depends = &mdp_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "mdp_clk",
.ops = &soc_clk_ops_8960,
},
};
static struct branch_clk lut_mdp_clk = {
.b = {
.ctl_reg = (void *)MDP_LUT_CC_REG,
.en_mask = BIT(0),
.halt_reg = (void *)DBG_BUS_VEC_I_REG,
.halt_bit = 13,
},
.parent = &mdp_clk.c,
.c = {
.dbg_name = "lut_mdp_clk",
.ops = &clk_ops_branch,
},
};
#ifdef DEBUG_CLOCK
struct measure_sel {
uint32_t test_vector;
struct clk *clk;
};
static struct measure_sel measure_mux[] = {
{ TEST_PER_LS(0x13), &sdc1_clk.c },
{ TEST_PER_LS(0x15), &sdc2_clk.c },
{ TEST_PER_LS(0x17), &sdc3_clk.c },
{ TEST_PER_LS(0x19), &sdc4_clk.c },
{ TEST_PER_LS(0x1B), &sdc5_clk.c },
{ TEST_PER_LS(0x3D), &gsbi1_p_clk.c },
{ TEST_PER_LS(0x3E), &gsbi1_uart_clk.c },
{ TEST_PER_LS(0x3F), &gsbi1_qup_clk.c },
{ TEST_PER_LS(0x41), &gsbi2_p_clk.c },
{ TEST_PER_LS(0x42), &gsbi2_uart_clk.c },
{ TEST_PER_LS(0x44), &gsbi2_qup_clk.c },
{ TEST_PER_LS(0x45), &gsbi3_p_clk.c },
{ TEST_PER_LS(0x46), &gsbi3_uart_clk.c },
{ TEST_PER_LS(0x48), &gsbi3_qup_clk.c },
{ TEST_PER_LS(0x49), &gsbi4_p_clk.c },
{ TEST_PER_LS(0x4A), &gsbi4_uart_clk.c },
{ TEST_PER_LS(0x4C), &gsbi4_qup_clk.c },
{ TEST_PER_LS(0x4D), &gsbi5_p_clk.c },
{ TEST_PER_LS(0x4E), &gsbi5_uart_clk.c },
{ TEST_PER_LS(0x50), &gsbi5_qup_clk.c },
{ TEST_PER_LS(0x51), &gsbi6_p_clk.c },
{ TEST_PER_LS(0x52), &gsbi6_uart_clk.c },
{ TEST_PER_LS(0x54), &gsbi6_qup_clk.c },
{ TEST_PER_LS(0x55), &gsbi7_p_clk.c },
{ TEST_PER_LS(0x56), &gsbi7_uart_clk.c },
{ TEST_PER_LS(0x58), &gsbi7_qup_clk.c },
{ TEST_PER_LS(0x59), &gsbi8_p_clk.c },
{ TEST_PER_LS(0x5A), &gsbi8_uart_clk.c },
{ TEST_PER_LS(0x5C), &gsbi8_qup_clk.c },
{ TEST_PER_LS(0x5D), &gsbi9_p_clk.c },
{ TEST_PER_LS(0x5E), &gsbi9_uart_clk.c },
{ TEST_PER_LS(0x60), &gsbi9_qup_clk.c },
{ TEST_PER_LS(0x61), &gsbi10_p_clk.c },
{ TEST_PER_LS(0x62), &gsbi10_uart_clk.c },
{ TEST_PER_LS(0x64), &gsbi10_qup_clk.c },
{ TEST_PER_LS(0x65), &gsbi11_p_clk.c },
{ TEST_PER_LS(0x66), &gsbi11_uart_clk.c },
{ TEST_PER_LS(0x68), &gsbi11_qup_clk.c },
{ TEST_PER_LS(0x69), &gsbi12_p_clk.c },
{ TEST_PER_LS(0x6A), &gsbi12_uart_clk.c },
{ TEST_PER_LS(0x6C), &gsbi12_qup_clk.c },
{ TEST_PER_LS(0x85), &usb_hs1_xcvr_clk.c },
{ TEST_PER_LS(0x92), &ce1_p_clk.c },
{ TEST_PER_LS(0xA4), &ce1_core_clk.c },
{ TEST_PER_LS(0x5F), &ce3_p_clk.c },
{ TEST_PER_LS(0x60), &ce3_core_clk.c },
{ TEST_MM_HS(0x15), &mdp_axi_clk.c },
{ TEST_MM_HS(0x1A), &mdp_clk.c },
{ TEST_MM_HS(0x28), &lut_mdp_clk.c },
};
static struct measure_sel *find_measure_sel(struct clk *clk)
{
int i;
for (i = 0; i < ARRAY_SIZE(measure_mux); i++)
if (measure_mux[i].clk == clk)
return &measure_mux[i];
return NULL;
}
static int measure_clk_set_parent(struct clk *c, struct clk *parent)
{
int ret = 0;
uint32_t clk_sel;
struct measure_sel *p;
struct measure_clk *clk = to_measure_clk(c);
if (!parent)
return ERR_INVALID_ARGS;
p = find_measure_sel(parent);
if (!p)
return ERR_INVALID_ARGS;
/*
* Program the test vector, measurement period (sample_ticks)
* and scaling multiplier.
*/
clk->sample_ticks = 0x10000;
clk_sel = p->test_vector & TEST_CLK_SEL_MASK;
clk->multiplier = 1;
switch (p->test_vector >> TEST_TYPE_SHIFT) {
case TEST_TYPE_PER_LS:
writel_relaxed(0x4030D00|BVAL(7, 0, clk_sel), CLK_TEST_REG);
break;
case TEST_TYPE_PER_HS:
writel_relaxed(0x4020000|BVAL(16, 10, clk_sel), CLK_TEST_REG);
break;
case TEST_TYPE_MM_LS:
writel_relaxed(0x4030D97, CLK_TEST_REG);
writel_relaxed(BVAL(6, 1, clk_sel)|BIT(0), DBG_CFG_REG_LS_REG);
break;
case TEST_TYPE_MM_HS:
writel_relaxed(0x402B800, CLK_TEST_REG);
writel_relaxed(BVAL(6, 1, clk_sel)|BIT(0), DBG_CFG_REG_HS_REG);
break;
default:
ret = ERR_NOT_SUPPORTED;
}
/* Make sure test vector is set before starting measurements. */
dmb();
return ret;
}
/* Sample clock for 'ticks' reference clock ticks. */
static uint32_t run_measurement(unsigned ticks)
{
/* Stop counters and set the XO4 counter start value. */
writel_relaxed(ticks, RINGOSC_TCXO_CTL_REG);
/* Wait for timer to become ready. */
while ((readl_relaxed(RINGOSC_STATUS_REG) & BIT(25)) != 0)
dmb();
/* Run measurement and wait for completion. */
writel_relaxed(BIT(20)|ticks, RINGOSC_TCXO_CTL_REG);
while ((readl_relaxed(RINGOSC_STATUS_REG) & BIT(25)) == 0)
dmb();
/* Stop counters. */
writel_relaxed(0x0, RINGOSC_TCXO_CTL_REG);
/* Return measured ticks. */
return readl_relaxed(RINGOSC_STATUS_REG) & BM(24, 0);
}
/* Perform a hardware rate measurement for a given clock.
FOR DEBUG USE ONLY: Measurements take ~15 ms! */
static unsigned long measure_clk_get_rate(struct clk *c)
{
uint32_t pdm_reg_backup, ringosc_reg_backup;
uint64_t raw_count_short, raw_count_full;
struct measure_clk *clk = to_measure_clk(c);
unsigned ret;
ret = clk_enable(&cxo_clk.c);
if (ret) {
dprintf(CRITICAL, "CXO clock failed to enable. Can't measure\n");
return 0;
}
/* Enable CXO/4 and RINGOSC branch and root. */
pdm_reg_backup = readl_relaxed(PDM_CLK_NS_REG);
ringosc_reg_backup = readl_relaxed(RINGOSC_NS_REG);
writel_relaxed(0x2898, PDM_CLK_NS_REG);
writel_relaxed(0xA00, RINGOSC_NS_REG);
/*
* The ring oscillator counter will not reset if the measured clock
* is not running. To detect this, run a short measurement before
* the full measurement. If the raw results of the two are the same
* then the clock must be off.
*/
/* Run a short measurement. (~1 ms) */
raw_count_short = run_measurement(0x1000);
/* Run a full measurement. (~14 ms) */
raw_count_full = run_measurement(clk->sample_ticks);
writel_relaxed(ringosc_reg_backup, RINGOSC_NS_REG);
writel_relaxed(pdm_reg_backup, PDM_CLK_NS_REG);
/* Return 0 if the clock is off. */
if (raw_count_full == raw_count_short)
ret = 0;
else {
/* Compute rate in Hz. */
raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
raw_count_full /= ((clk->sample_ticks * 10) + 35);
ret = (raw_count_full * clk->multiplier);
}
/* Route dbg_hs_clk to PLLTEST. 300mV single-ended amplitude. */
writel_relaxed(0x38F8, PLLTEST_PAD_CFG_REG);
clk_disable(&cxo_clk.c);
return ret;
}
#else
static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
{
return ERR_INVALID_ARGS;
}
static unsigned long measure_clk_get_rate(struct clk *clk)
{
return 0;
}
#endif
static struct clk_ops measure_clk_ops = {
.set_parent = measure_clk_set_parent,
.get_rate = measure_clk_get_rate,
};
static struct measure_clk measure_clk = {
.c = {
.dbg_name = "measure_clk",
.ops = &measure_clk_ops,
},
.multiplier = 1,
};
static struct clk_lookup msm_clocks_8960[] = {
CLK_LOOKUP("gsbi1_uart_clk", gsbi1_uart_clk.c),
CLK_LOOKUP("gsbi2_uart_clk", gsbi2_uart_clk.c),
CLK_LOOKUP("gsbi3_uart_clk", gsbi3_uart_clk.c),
CLK_LOOKUP("gsbi4_uart_clk", gsbi4_uart_clk.c),
CLK_LOOKUP("gsbi5_uart_clk", gsbi5_uart_clk.c),
CLK_LOOKUP("gsbi6_uart_clk", gsbi6_uart_clk.c),
CLK_LOOKUP("gsbi7_uart_clk", gsbi7_uart_clk.c),
CLK_LOOKUP("gsbi8_uart_clk", gsbi8_uart_clk.c),
CLK_LOOKUP("gsbi9_uart_clk", gsbi9_uart_clk.c),
CLK_LOOKUP("gsbi10_uart_clk", gsbi10_uart_clk.c),
CLK_LOOKUP("gsbi11_uart_clk", gsbi11_uart_clk.c),
CLK_LOOKUP("gsbi12_uart_clk", gsbi12_uart_clk.c),
CLK_LOOKUP("gsbi1_qup_clk", gsbi1_qup_clk.c),
CLK_LOOKUP("gsbi2_qup_clk", gsbi2_qup_clk.c),
CLK_LOOKUP("gsbi3_qup_clk", gsbi3_qup_clk.c),
CLK_LOOKUP("gsbi4_qup_clk", gsbi4_qup_clk.c),
CLK_LOOKUP("gsbi5_qup_clk", gsbi5_qup_clk.c),
CLK_LOOKUP("gsbi6_qup_clk", gsbi6_qup_clk.c),
CLK_LOOKUP("gsbi7_qup_clk", gsbi7_qup_clk.c),
CLK_LOOKUP("gsbi8_qup_clk", gsbi8_qup_clk.c),
CLK_LOOKUP("gsbi9_qup_clk", gsbi9_qup_clk.c),
CLK_LOOKUP("gsbi10_qup_clk", gsbi10_qup_clk.c),
CLK_LOOKUP("gsbi11_qup_clk", gsbi11_qup_clk.c),
CLK_LOOKUP("gsbi12_qup_clk", gsbi12_qup_clk.c),
CLK_LOOKUP("gsbi1_pclk", gsbi1_p_clk.c),
CLK_LOOKUP("gsbi2_pclk", gsbi2_p_clk.c),
CLK_LOOKUP("gsbi3_pclk", gsbi3_p_clk.c),
CLK_LOOKUP("gsbi4_pclk", gsbi4_p_clk.c),
CLK_LOOKUP("gsbi5_pclk", gsbi5_p_clk.c),
CLK_LOOKUP("gsbi6_pclk", gsbi6_p_clk.c),
CLK_LOOKUP("gsbi7_pclk", gsbi7_p_clk.c),
CLK_LOOKUP("gsbi8_pclk", gsbi8_p_clk.c),
CLK_LOOKUP("gsbi9_pclk", gsbi9_p_clk.c),
CLK_LOOKUP("gsbi10_pclk", gsbi10_p_clk.c),
CLK_LOOKUP("gsbi11_pclk", gsbi11_p_clk.c),
CLK_LOOKUP("gsbi12_pclk", gsbi12_p_clk.c),
CLK_LOOKUP("usb_hs_clk", usb_hs1_xcvr_clk.c),
CLK_LOOKUP("sdc1_clk", sdc1_clk.c),
CLK_LOOKUP("sdc2_clk", sdc2_clk.c),
CLK_LOOKUP("sdc3_clk", sdc3_clk.c),
CLK_LOOKUP("sdc4_clk", sdc4_clk.c),
CLK_LOOKUP("sdc5_clk", sdc5_clk.c),
CLK_LOOKUP("mdp_axi_clk", mdp_axi_clk.c),
CLK_LOOKUP("mdp_clk", mdp_clk.c),
CLK_LOOKUP("lut_mdp", lut_mdp_clk.c),
CLK_LOOKUP("ce1_pclk", ce1_p_clk.c),
CLK_LOOKUP("ce1_clk", ce1_core_clk.c),
CLK_LOOKUP("ce3_src_clk", ce3_src_clk.c),
CLK_LOOKUP("ce3_pclk", ce3_p_clk.c),
CLK_LOOKUP("ce3_clk", ce3_core_clk.c),
CLK_LOOKUP("measure", measure_clk.c),
};
static int sr_pll_clk_enable(struct clk *clk)
{
uint32_t mode;
struct pll_clk *pll = to_pll_clk(clk);
mode = readl_relaxed(pll->mode_reg);
/* De-assert active-low PLL reset. */
mode |= BIT(2);
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.
*/
dmb();
udelay(10);
/* Disable PLL bypass mode. */
mode |= BIT(1);
writel_relaxed(mode, pll->mode_reg);
/* Wait until PLL is locked. */
dmb();
udelay(60);
/* Enable PLL output. */
mode |= BIT(0);
writel_relaxed(mode, pll->mode_reg);
return 0;
}
static unsigned msm_num_clocks_8960 = ARRAY_SIZE(msm_clocks_8960);
void msm_clocks_init()
{
clk_ops_pll.enable = sr_pll_clk_enable;
clk_init(msm_clocks_8960, msm_num_clocks_8960);
}

View File

@@ -0,0 +1,335 @@
/* Copyright (c) 2012-2013, 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 <debug.h>
#include <reg.h>
#include <platform/iomap.h>
#include <platform/gpio.h>
#include <gsbi.h>
#include <dev/pm8921.h>
#include <sys/types.h>
#include <smem.h>
void gpio_tlmm_config(uint32_t gpio, uint8_t func,
uint8_t dir, uint8_t pull,
uint8_t drvstr, uint32_t enable)
{
unsigned int val = 0;
val |= pull;
val |= func << 2;
val |= drvstr << 6;
val |= enable << 9;
unsigned int *addr = (unsigned int *)GPIO_CONFIG_ADDR(gpio);
writel(val, addr);
return;
}
void gpio_set(uint32_t gpio, uint32_t dir)
{
unsigned int *addr = (unsigned int *)GPIO_IN_OUT_ADDR(gpio);
writel(dir, addr);
return;
}
/* TODO: this and other code below in this file should ideally by in target dir.
* keeping it here for this brigup.
*/
/* Configure gpio for uart - based on gsbi id */
void gpio_config_uart_dm(uint8_t id)
{
if(board_platform_id() == MPQ8064)
{
switch (id) {
case GSBI_ID_5:
/* configure rx gpio */
gpio_tlmm_config(52, 2, GPIO_INPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
/* configure tx gpio */
gpio_tlmm_config(51, 2, GPIO_OUTPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
break;
default:
ASSERT(0);
}
}
else if((board_platform_id() == APQ8064) ||
(board_platform_id() == APQ8064AA) ||
(board_platform_id() == APQ8064AB))
{
switch (id) {
case GSBI_ID_1:
/* configure rx gpio */
gpio_tlmm_config(19, 1, GPIO_INPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
/* configure tx gpio */
gpio_tlmm_config(18, 1, GPIO_OUTPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
break;
case GSBI_ID_2:
/* configure rx gpio */
gpio_tlmm_config(22, 1, GPIO_INPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
/* configure tx gpio */
gpio_tlmm_config(23, 1, GPIO_OUTPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
break;
case GSBI_ID_7:
/* configure rx gpio */
gpio_tlmm_config(83, 1, GPIO_INPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
/* configure tx gpio */
gpio_tlmm_config(82, 2, GPIO_OUTPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
break;
default:
ASSERT(0);
}
}
else
{
switch (id) {
case GSBI_ID_3:
/* configure rx gpio */
gpio_tlmm_config(15, 1, GPIO_INPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
/* configure tx gpio */
gpio_tlmm_config(14, 1, GPIO_OUTPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
break;
case GSBI_ID_5:
/* configure rx gpio */
gpio_tlmm_config(23, 1, GPIO_INPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
/* configure tx gpio */
gpio_tlmm_config(22, 1, GPIO_OUTPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
break;
case GSBI_ID_8:
/* configure rx gpio */
gpio_tlmm_config(35, 1, GPIO_INPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
/* configure tx gpio */
gpio_tlmm_config(34, 1, GPIO_OUTPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
break;
default:
ASSERT(0);
}
}
}
struct pm8xxx_gpio_init {
uint32_t gpio;
struct pm8921_gpio config;
};
#define PM8XXX_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
_func, _inv, _disable) \
{ \
.gpio = _gpio, \
.config = { \
.direction = _dir, \
.output_buffer = _buf, \
.output_value = _val, \
.pull = _pull, \
.vin_sel = _vin, \
.out_strength = _out_strength, \
.function = _func, \
.inv_int_pol = _inv, \
.disable_pin = _disable, \
} \
}
#define PM8XXX_GPIO_OUTPUT(_gpio, _val) \
PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, 0, _val, \
PM_GPIO_PULL_NO, 2, \
PM_GPIO_STRENGTH_HIGH, \
PM_GPIO_FUNC_NORMAL, 1, 0)
#define PM8XXX_GPIO_INPUT(_gpio, _pull) \
PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, \
_pull, 2, \
PM_GPIO_STRENGTH_NO, \
PM_GPIO_FUNC_NORMAL, 1, 0)
/* Initial pm8038 GPIO configurations */
static struct pm8xxx_gpio_init pm8038_keypad_gpios[] = {
/* keys GPIOs */
PM8XXX_GPIO_INPUT(PM_GPIO(3), PM_GPIO_PULL_UP_30),
PM8XXX_GPIO_INPUT(PM_GPIO(8), PM_GPIO_PULL_UP_30),
PM8XXX_GPIO_INPUT(PM_GPIO(10), PM_GPIO_PULL_UP_30),
PM8XXX_GPIO_INPUT(PM_GPIO(11), PM_GPIO_PULL_UP_30),
};
static struct pm8xxx_gpio_init pm8921_keypad_gpios[] = {
/* keys GPIOs */
PM8XXX_GPIO_INPUT(PM_GPIO(1), PM_GPIO_PULL_UP_31_5),
PM8XXX_GPIO_INPUT(PM_GPIO(2), PM_GPIO_PULL_UP_31_5),
PM8XXX_GPIO_INPUT(PM_GPIO(3), PM_GPIO_PULL_UP_31_5),
PM8XXX_GPIO_INPUT(PM_GPIO(4), PM_GPIO_PULL_UP_31_5),
PM8XXX_GPIO_INPUT(PM_GPIO(5), PM_GPIO_PULL_UP_31_5),
PM8XXX_GPIO_OUTPUT(PM_GPIO(9), 0),
};
/* pm8921 GPIO configuration for APQ8064 keypad */
static struct pm8xxx_gpio_init pm8921_keypad_gpios_apq[] = {
/* keys GPIOs */
PM8XXX_GPIO_INPUT(PM_GPIO(35), PM_GPIO_PULL_UP_31_5),
PM8XXX_GPIO_INPUT(PM_GPIO(38), PM_GPIO_PULL_UP_31_5),
PM8XXX_GPIO_OUTPUT(PM_GPIO(9), 0),
};
/* pm8917 GPIO configuration for APQ8064 keypad */
static struct pm8xxx_gpio_init pm8917_keypad_gpios_apq[] = {
/* keys GPIOs */
PM8XXX_GPIO_INPUT(PM_GPIO(35), PM_GPIO_PULL_UP_31_5),
PM8XXX_GPIO_INPUT(PM_GPIO(30), PM_GPIO_PULL_UP_31_5),
PM8XXX_GPIO_OUTPUT(PM_GPIO(9), 0),
};
/* pm8917 GPIO configuration for MSM8930 keypad */
static struct pm8xxx_gpio_init pm8917_keypad_gpios[] = {
/* keys GPIOs */
PM8XXX_GPIO_INPUT(PM_GPIO(27), PM_GPIO_PULL_UP_30),
PM8XXX_GPIO_INPUT(PM_GPIO(28), PM_GPIO_PULL_UP_30),
PM8XXX_GPIO_INPUT(PM_GPIO(36), PM_GPIO_PULL_UP_30),
PM8XXX_GPIO_INPUT(PM_GPIO(37), PM_GPIO_PULL_UP_30),
};
void msm8960_keypad_gpio_init()
{
int i = 0;
int num = 0;
num = ARRAY_SIZE(pm8921_keypad_gpios);
for(i=0; i < num; i++)
{
pm8921_gpio_config(pm8921_keypad_gpios[i].gpio,
&(pm8921_keypad_gpios[i].config));
}
}
void msm8930_keypad_gpio_init()
{
int i = 0;
int num = 0;
struct pm8xxx_gpio_init *gpio_array;
if (platform_pmic_type(PMIC_IS_PM8917))
{
num = ARRAY_SIZE(pm8917_keypad_gpios);
gpio_array = pm8917_keypad_gpios;
}
else
{
num = ARRAY_SIZE(pm8038_keypad_gpios);
gpio_array = pm8038_keypad_gpios;
}
for(i=0; i < num; i++)
{
pm8921_gpio_config(gpio_array[i].gpio,
&(gpio_array[i].config));
}
}
void apq8064_keypad_gpio_init()
{
int i = 0;
int num = 0;
struct pm8xxx_gpio_init *gpio_array;
if (platform_pmic_type(PMIC_IS_PM8917))
{
num = ARRAY_SIZE(pm8917_keypad_gpios_apq);
gpio_array = pm8917_keypad_gpios_apq;
}
else
{
num = ARRAY_SIZE(pm8921_keypad_gpios_apq);
gpio_array = pm8921_keypad_gpios_apq;
}
for(i = 0; i < num; i++)
{
pm8921_gpio_config(gpio_array[i].gpio,
&(gpio_array[i].config));
}
}
#define PM8921_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, 0, _val, \
PM_GPIO_PULL_NO, 2, \
PM_GPIO_STRENGTH_HIGH, \
_func, 0, 0)
#define PM8921_GPIO_OUTPUT_BUFCONF(_gpio, _val, _strength, _bufconf) \
PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT,\
PM_GPIO_OUT_BUF_##_bufconf, _val, \
PM_GPIO_PULL_NO, 2, \
PM_GPIO_STRENGTH_##_strength, \
PM_GPIO_FUNC_NORMAL, 0, 0)
static struct pm8xxx_gpio_init pm8921_display_gpios_apq[] = {
/* Display GPIOs */
/* Bl: ON, PWM mode */
PM8921_GPIO_OUTPUT_FUNC(PM_GPIO(26), 1, PM_GPIO_FUNC_2),
/* LCD1_PWR_EN_N */
PM8921_GPIO_OUTPUT_BUFCONF(PM_GPIO(36), 0, LOW, OPEN_DRAIN),
/* DISP_RESET_N */
PM8921_GPIO_OUTPUT_BUFCONF(PM_GPIO(25), 1, LOW, CMOS),
};
void apq8064_display_gpio_init()
{
int i = 0;
int num = 0;
num = ARRAY_SIZE(pm8921_display_gpios_apq);
for (i = 0; i < num; i++) {
pm8921_gpio_config(pm8921_display_gpios_apq[i].gpio,
&(pm8921_display_gpios_apq[i].config));
}
}

View File

@@ -0,0 +1,404 @@
/* Copyright (c) 2009-2013, 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 <hdmi.h>
#include <dev/pm8921.h>
#include <platform/timer.h>
#include <platform/gpio.h>
#include <platform/clock.h>
#include <platform/iomap.h>
extern void hdmi_app_clk_init(int);
extern int hdmi_msm_turn_on();
/* HDMI PLL macros */
#define HDMI_PHY_PLL_REFCLK_CFG (MSM_HDMI_BASE + 0x00000500)
#define HDMI_PHY_PLL_CHRG_PUMP_CFG (MSM_HDMI_BASE + 0x00000504)
#define HDMI_PHY_PLL_LOOP_FLT_CFG0 (MSM_HDMI_BASE + 0x00000508)
#define HDMI_PHY_PLL_LOOP_FLT_CFG1 (MSM_HDMI_BASE + 0x0000050c)
#define HDMI_PHY_PLL_IDAC_ADJ_CFG (MSM_HDMI_BASE + 0x00000510)
#define HDMI_PHY_PLL_I_VI_KVCO_CFG (MSM_HDMI_BASE + 0x00000514)
#define HDMI_PHY_PLL_PWRDN_B (MSM_HDMI_BASE + 0x00000518)
#define HDMI_PHY_PLL_SDM_CFG0 (MSM_HDMI_BASE + 0x0000051c)
#define HDMI_PHY_PLL_SDM_CFG1 (MSM_HDMI_BASE + 0x00000520)
#define HDMI_PHY_PLL_SDM_CFG2 (MSM_HDMI_BASE + 0x00000524)
#define HDMI_PHY_PLL_SDM_CFG3 (MSM_HDMI_BASE + 0x00000528)
#define HDMI_PHY_PLL_SDM_CFG4 (MSM_HDMI_BASE + 0x0000052c)
#define HDMI_PHY_PLL_SSC_CFG0 (MSM_HDMI_BASE + 0x00000530)
#define HDMI_PHY_PLL_SSC_CFG1 (MSM_HDMI_BASE + 0x00000534)
#define HDMI_PHY_PLL_SSC_CFG2 (MSM_HDMI_BASE + 0x00000538)
#define HDMI_PHY_PLL_SSC_CFG3 (MSM_HDMI_BASE + 0x0000053c)
#define HDMI_PHY_PLL_LOCKDET_CFG0 (MSM_HDMI_BASE + 0x00000540)
#define HDMI_PHY_PLL_LOCKDET_CFG1 (MSM_HDMI_BASE + 0x00000544)
#define HDMI_PHY_PLL_LOCKDET_CFG2 (MSM_HDMI_BASE + 0x00000548)
#define HDMI_PHY_PLL_VCOCAL_CFG0 (MSM_HDMI_BASE + 0x0000054c)
#define HDMI_PHY_PLL_VCOCAL_CFG1 (MSM_HDMI_BASE + 0x00000550)
#define HDMI_PHY_PLL_VCOCAL_CFG2 (MSM_HDMI_BASE + 0x00000554)
#define HDMI_PHY_PLL_VCOCAL_CFG3 (MSM_HDMI_BASE + 0x00000558)
#define HDMI_PHY_PLL_VCOCAL_CFG4 (MSM_HDMI_BASE + 0x0000055c)
#define HDMI_PHY_PLL_VCOCAL_CFG5 (MSM_HDMI_BASE + 0x00000560)
#define HDMI_PHY_PLL_VCOCAL_CFG6 (MSM_HDMI_BASE + 0x00000564)
#define HDMI_PHY_PLL_VCOCAL_CFG7 (MSM_HDMI_BASE + 0x00000568)
#define HDMI_PHY_PLL_DEBUG_SEL (MSM_HDMI_BASE + 0x0000056c)
#define HDMI_PHY_PLL_PWRDN_B (MSM_HDMI_BASE + 0x00000518)
#define HDMI_PHY_PLL_STATUS0 (MSM_HDMI_BASE + 0x00000598)
/* HDMI PHY/PLL bit field macros */
#define SW_RESET BIT(2)
#define SW_RESET_PLL BIT(0)
#define PWRDN_B BIT(7)
#define PLL_PWRDN_B BIT(3)
#define PD_PLL BIT(1)
static unsigned hdmi_pll_on;
void hdmi_msm_init_phy()
{
dprintf(INFO, "phy init\n");
uint32_t offset;
writel(0x1B, HDMI_PHY_REG_0);
writel(0xf2, HDMI_PHY_REG_1);
offset = HDMI_PHY_REG_4;
while (offset <= HDMI_PHY_REG_11) {
writel(0x0, offset);
offset += 0x4;
}
writel(0x20, HDMI_PHY_REG_3);
}
static void hdmi_gpio_config()
{
writel(0x07, GPIO_CONFIG_ADDR(70));
writel(0x07, GPIO_CONFIG_ADDR(71));
writel(0x05, GPIO_CONFIG_ADDR(72));
}
void hdmi_msm_reset_core()
{
uint32_t reg_val = 0;
// Disable clocks
hdmi_app_clk_init(0);
udelay(5);
// Enable clocks
hdmi_app_clk_init(1);
reg_val = readl(SW_RESET_CORE_REG);
reg_val |= BIT(11);
writel(reg_val, SW_RESET_CORE_REG);
udelay(5);
reg_val = readl(SW_RESET_CORE_REG);
reg_val &= ~(BIT(11));
writel(reg_val, SW_RESET_CORE_REG);
udelay(5);
}
void hdmi_phy_reset(void)
{
uint32_t phy_reset_polarity = 0x0;
uint32_t pll_reset_polarity = 0x0;
uint32_t val = readl(HDMI_PHY_CTRL);
phy_reset_polarity = val >> 3 & 0x1;
pll_reset_polarity = val >> 1 & 0x1;
if (phy_reset_polarity == 0)
writel(val | SW_RESET, HDMI_PHY_CTRL);
else
writel(val & (~SW_RESET), HDMI_PHY_CTRL);
if (pll_reset_polarity == 0)
writel(val | SW_RESET_PLL, HDMI_PHY_CTRL);
else
writel(val & (~SW_RESET_PLL), HDMI_PHY_CTRL);
udelay(10);
if (phy_reset_polarity == 0)
writel(val & (~SW_RESET), HDMI_PHY_CTRL);
else
writel(val | SW_RESET, HDMI_PHY_CTRL);
if (pll_reset_polarity == 0)
writel(val & (~SW_RESET_PLL), HDMI_PHY_CTRL);
else
writel(val | SW_RESET_PLL, HDMI_PHY_CTRL);
}
/*
* This is the start function which initializes clocks , gpios for hdmi
* & powers on the HDMI core
*/
void hdmi_power_init()
{
pm8921_low_voltage_switch_enable(lvs_7);
apq8064_ext_3p3V_enable();
pm8921_HDMI_Switch();
hdmi_gpio_config();
hdmi_phy_reset();
hdmi_msm_set_mode(1);
}
void hdmi_pll_disable(void)
{
uint32_t val;
uint32_t ahb_en_reg, ahb_enabled;
ahb_en_reg = readl(AHB_EN_REG);
ahb_enabled = ahb_en_reg & BIT(4);
if (!ahb_enabled) {
writel(ahb_en_reg | BIT(4), AHB_EN_REG);
udelay(10);
}
val = readl(HDMI_PHY_REG_12);
val &= (~PWRDN_B);
writel(val, HDMI_PHY_REG_12);
val = readl(HDMI_PHY_PLL_PWRDN_B);
val |= PD_PLL;
val &= (~PLL_PWRDN_B);
writel(val, HDMI_PHY_PLL_PWRDN_B);
/* Make sure HDMI PHY/PLL are powered down */
udelay(10);
if (!ahb_enabled)
writel(ahb_en_reg & ~BIT(4), AHB_EN_REG);
hdmi_pll_on = 0;
}
void hdmi_pll_enable(void)
{
uint32_t val;
uint32_t ahb_en_reg, ahb_enabled;
uint32_t timeout_count;
int pll_lock_retry = 10;
ahb_en_reg = readl(AHB_EN_REG);
ahb_enabled = ahb_en_reg & BIT(4);
if (!ahb_enabled) {
dprintf(INFO, "ahb not enabled\n");
writel(ahb_en_reg | BIT(4), AHB_EN_REG);
/* Make sure iface clock is enabled before register access */
udelay(10);
}
/* Assert PLL S/W reset */
writel(0x8D, HDMI_PHY_PLL_LOCKDET_CFG2);
writel(0x10, HDMI_PHY_PLL_LOCKDET_CFG0);
writel(0x1A, HDMI_PHY_PLL_LOCKDET_CFG1);
/* Wait for a short time before de-asserting
* to allow the hardware to complete its job.
* This much of delay should be fine for hardware
* to assert and de-assert.
*/
udelay(10);
/* De-assert PLL S/W reset */
writel(0x0D, HDMI_PHY_PLL_LOCKDET_CFG2);
val = readl(HDMI_PHY_REG_12);
val |= BIT(5);
/* Assert PHY S/W reset */
writel(val, HDMI_PHY_REG_12);
val &= ~BIT(5);
/* Wait for a short time before de-asserting
to allow the hardware to complete its job.
This much of delay should be fine for hardware
to assert and de-assert. */
udelay(10);
/* De-assert PHY S/W reset */
writel(val, HDMI_PHY_REG_12);
writel(0x3f, HDMI_PHY_REG_2);
val = readl(HDMI_PHY_REG_12);
val |= PWRDN_B;
writel(val, HDMI_PHY_REG_12);
/* Wait 10 us for enabling global power for PHY */
udelay(10);
val = readl(HDMI_PHY_PLL_PWRDN_B);
val |= PLL_PWRDN_B;
val &= ~PD_PLL;
writel(val, HDMI_PHY_PLL_PWRDN_B);
writel(0x80, HDMI_PHY_REG_2);
timeout_count = 1000;
while (!(readl(HDMI_PHY_PLL_STATUS0) & BIT(0)) &&
timeout_count && pll_lock_retry) {
if (--timeout_count == 0) {
dprintf(INFO, "PLL not locked, retry\n");
/*
* PLL has still not locked.
* Do a software reset and try again
* Assert PLL S/W reset first
*/
writel(0x8D, HDMI_PHY_PLL_LOCKDET_CFG2);
/* Wait for a short time before de-asserting
* to allow the hardware to complete its job.
* This much of delay should be fine for hardware
* to assert and de-assert.
*/
udelay(10);
writel(0x0D, HDMI_PHY_PLL_LOCKDET_CFG2);
/*
* Wait for a short duration for the PLL calibration
* before checking if the PLL gets locked
*/
udelay(350);
timeout_count = 1000;
pll_lock_retry--;
}
}
if (!ahb_enabled) {
writel(ahb_en_reg & ~BIT(4), AHB_EN_REG);
udelay(10);
}
if (!pll_lock_retry) {
dprintf(INFO, "%s: HDMI PLL not locked\n", __func__);
hdmi_pll_disable();
}
hdmi_pll_on = 1;
}
int hdmi_dtv_on()
{
uint32_t ahb_en_reg = readl(AHB_EN_REG);
uint32_t ahb_enabled = ahb_en_reg & BIT(4);
uint32_t val, pll_mode, ns_val, pll_config;
if (!ahb_enabled) {
dprintf(INFO, "ahb not enabled, turning on\n");
writel(ahb_en_reg | BIT(4), AHB_EN_REG);
/* Make sure iface clock is enabled before register access */
udelay(10);
}
if (hdmi_pll_on)
hdmi_pll_disable();
/* 1080p60/1080p50 case */
writel(0x2, HDMI_PHY_PLL_REFCLK_CFG);
writel(0x2, HDMI_PHY_PLL_CHRG_PUMP_CFG);
writel(0x01, HDMI_PHY_PLL_LOOP_FLT_CFG0);
writel(0x33, HDMI_PHY_PLL_LOOP_FLT_CFG1);
writel(0x2C, HDMI_PHY_PLL_IDAC_ADJ_CFG);
writel(0x6, HDMI_PHY_PLL_I_VI_KVCO_CFG);
writel(0xA, HDMI_PHY_PLL_PWRDN_B);
writel(0x76, HDMI_PHY_PLL_SDM_CFG0);
writel(0x01, HDMI_PHY_PLL_SDM_CFG1);
writel(0x4C, HDMI_PHY_PLL_SDM_CFG2);
writel(0xC0, HDMI_PHY_PLL_SDM_CFG3);
writel(0x00, HDMI_PHY_PLL_SDM_CFG4);
writel(0x9A, HDMI_PHY_PLL_SSC_CFG0);
writel(0x00, HDMI_PHY_PLL_SSC_CFG1);
writel(0x00, HDMI_PHY_PLL_SSC_CFG2);
writel(0x00, HDMI_PHY_PLL_SSC_CFG3);
writel(0x10, HDMI_PHY_PLL_LOCKDET_CFG0);
writel(0x1A, HDMI_PHY_PLL_LOCKDET_CFG1);
writel(0x0D, HDMI_PHY_PLL_LOCKDET_CFG2);
writel(0xe6, HDMI_PHY_PLL_VCOCAL_CFG0);
writel(0x02, HDMI_PHY_PLL_VCOCAL_CFG1);
writel(0x3B, HDMI_PHY_PLL_VCOCAL_CFG2);
writel(0x00, HDMI_PHY_PLL_VCOCAL_CFG3);
writel(0x86, HDMI_PHY_PLL_VCOCAL_CFG4);
writel(0x00, HDMI_PHY_PLL_VCOCAL_CFG5);
writel(0x33, HDMI_PHY_PLL_VCOCAL_CFG6);
writel(0x00, HDMI_PHY_PLL_VCOCAL_CFG7);
udelay(10);
hdmi_pll_enable();
if (!ahb_enabled)
writel(ahb_en_reg & ~BIT(4), AHB_EN_REG);
// set M N D
ns_val = readl(TV_NS_REG);
ns_val |= BIT(7);
writel(ns_val, TV_NS_REG);
writel(0x00, TV_MD_REG);
val = readl(TV_CC_REG);
val &= ~(BM(7, 6));
val |= CC(6, 0);
writel(val, TV_CC_REG);
ns_val &= ~BIT(7);
writel(ns_val, TV_NS_REG);
// confiure hdmi_ref clk to run @ 148.5 MHz
val = readl(MISC_CC2_REG);
val |= BIT(11);
writel(val, MISC_CC2_REG);
// Enable TV src clk
writel(0x03, TV_NS_REG);
// Enable hdmi clk
val = readl(TV_CC_REG);
val |= BIT(12);
writel(val, TV_CC_REG);
// De-Assert hdmi clk
val = readl(SW_RESET_CORE_REG);
val |= BIT(1);
writel(val, SW_RESET_CORE_REG);
udelay(10);
val = readl(SW_RESET_CORE_REG);
val &= ~(BIT(1));
writel(val, SW_RESET_CORE_REG);
udelay(10);
// Root en of tv src clk
val = readl(TV_CC_REG);
val |= BIT(2);
writel(val, TV_CC_REG);
// enable mdp dtv clk
val = readl(TV_CC_REG);
val |= BIT(0);
writel(val, TV_CC_REG);
udelay(10);
return 0;
}

View File

@@ -0,0 +1,346 @@
/*
* * Copyright (c) 2011-2013, 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_MSM8960_CLOCK_H
#define __PLATFORM_MSM8960_CLOCK_H
#define MSM_MMSS_CLK_CTL_SIZE 4096
#define UART_DM_CLK_RX_TX_BIT_RATE 0xFF
#define REG(off) (MSM_CLK_CTL_BASE + (off))
#define REG_MM(off) (MSM_MMSS_CLK_CTL_BASE + (off))
#define REG_LPA(off) (MSM_LPASS_CLK_CTL_BASE + (off))
/* Peripheral clock registers. */
#define CE1_HCLK_CTL_REG REG(0x2720)
#define CE1_CORE_CLK_CTL_REG REG(0x2724)
#define CE3_CLK_SRC_NS_REG REG(0x36C0)
#define CE3_HCLK_CTL_REG REG(0x36C4)
#define CE3_CORE_CLK_CTL_REG REG(0x36CC)
#define DMA_BAM_HCLK_CTL REG(0x25C0)
#define CLK_HALT_AFAB_SFAB_STATEB_REG REG(0x2FC4)
#define CLK_HALT_CFPB_STATEA_REG REG(0x2FCC)
#define CLK_HALT_CFPB_STATEB_REG REG(0x2FD0)
#define CLK_HALT_CFPB_STATEC_REG REG(0x2FD4)
#define CLK_HALT_GSS_KPSS_MISC_STATE_REG REG(0x2FDC)
#define CLK_HALT_DFAB_STATE_REG REG(0x2FC8)
#define CLK_HALT_MSS_SMPSS_MISC_STATE_REG REG(0x2FDC)
#define CLK_HALT_SFPB_MISC_STATE_REG REG(0x2FD8)
#define CLK_TEST_REG REG(0x2FA0)
#define GSBIn_HCLK_CTL_REG(n) REG(0x29C0+(0x20*((n)-1)))
#define GSBIn_QUP_APPS_MD_REG(n) REG(0x29C8+(0x20*((n)-1)))
#define GSBIn_QUP_APPS_NS_REG(n) REG(0x29CC+(0x20*((n)-1)))
#define GSBIn_RESET_REG(n) REG(0x29DC+(0x20*((n)-1)))
#define GSBIn_UART_APPS_MD_REG(n) REG(0x29D0+(0x20*((n)-1)))
#define GSBIn_UART_APPS_NS_REG(n) REG(0x29D4+(0x20*((n)-1)))
#define LPASS_XO_SRC_CLK_CTL_REG REG(0x2EC0)
#define PDM_CLK_NS_REG REG(0x2CC0)
#define BB_PLL_ENA_Q6_SW_REG REG(0x3500)
#define BB_PLL_ENA_SC0_REG REG(0x34C0)
#define BB_PLL0_STATUS_REG REG(0x30D8)
#define BB_PLL5_STATUS_REG REG(0x30F8)
#define BB_PLL6_STATUS_REG REG(0x3118)
#define BB_PLL7_STATUS_REG REG(0x3138)
#define BB_PLL8_L_VAL_REG REG(0x3144)
#define BB_PLL8_M_VAL_REG REG(0x3148)
#define BB_PLL8_MODE_REG REG(0x3140)
#define BB_PLL8_N_VAL_REG REG(0x314C)
#define BB_PLL8_STATUS_REG REG(0x3158)
#define BB_PLL8_CONFIG_REG REG(0x3154)
#define BB_PLL8_TEST_CTL_REG REG(0x3150)
#define BB_PLL3_MODE_REG REG(0x3160)
#define PLLTEST_PAD_CFG_REG REG(0x2FA4)
#define PMEM_ACLK_CTL_REG REG(0x25A0)
#define RINGOSC_NS_REG REG(0x2DC0)
#define RINGOSC_STATUS_REG REG(0x2DCC)
#define RINGOSC_TCXO_CTL_REG REG(0x2DC4)
#define SC0_U_CLK_BRANCH_ENA_VOTE_REG REG(0x3080)
#define SDCn_APPS_CLK_MD_REG(n) REG(0x2828+(0x20*((n)-1)))
#define SDCn_APPS_CLK_NS_REG(n) REG(0x282C+(0x20*((n)-1)))
#define SDCn_HCLK_CTL_REG(n) REG(0x2820+(0x20*((n)-1)))
#define SDCn_RESET_REG(n) REG(0x2830+(0x20*((n)-1)))
#define SLIMBUS_XO_SRC_CLK_CTL_REG REG(0x2628)
#define TSIF_HCLK_CTL_REG REG(0x2700)
#define TSIF_REF_CLK_MD_REG REG(0x270C)
#define TSIF_REF_CLK_NS_REG REG(0x2710)
#define TSSC_CLK_CTL_REG REG(0x2CA0)
#define USB_FSn_HCLK_CTL_REG(n) REG(0x2960+(0x20*((n)-1)))
#define USB_FSn_RESET_REG(n) REG(0x2974+(0x20*((n)-1)))
#define USB_FSn_SYSTEM_CLK_CTL_REG(n) REG(0x296C+(0x20*((n)-1)))
#define USB_FSn_XCVR_FS_CLK_MD_REG(n) REG(0x2964+(0x20*((n)-1)))
#define USB_FSn_XCVR_FS_CLK_NS_REG(n) REG(0x2968+(0x20*((n)-1)))
#define USB_HS1_HCLK_CTL_REG REG(0x2900)
#define USB_HS1_RESET_REG REG(0x2910)
#define USB_HS1_XCVR_FS_CLK_MD_REG REG(0x2908)
#define USB_HS1_XCVR_FS_CLK_NS_REG REG(0x290C)
#define USB_PHY0_RESET_REG REG(0x2E20)
/* Multimedia clock registers. */
#define AHB_EN_REG REG_MM(0x0008)
#define AHB_EN2_REG REG_MM(0x0038)
#define AHB_NS_REG REG_MM(0x0004)
#define AXI_NS_REG REG_MM(0x0014)
#define CAMCLKn_NS_REG(n) REG_MM(0x0148+(0x14*(n)))
#define CAMCLKn_CC_REG(n) REG_MM(0x0140+(0x14*(n)))
#define CAMCLKn_MD_REG(n) REG_MM(0x0144+(0x14*(n)))
#define CSI0_NS_REG REG_MM(0x0048)
#define CSI0_CC_REG REG_MM(0x0040)
#define CSI0_MD_REG REG_MM(0x0044)
#define CSI1_NS_REG REG_MM(0x0010)
#define CSI1_CC_REG REG_MM(0x0024)
#define CSI1_MD_REG REG_MM(0x0028)
#define CSIPHYTIMER_CC_REG REG_MM(0x0160)
#define CSIPHYTIMER_MD_REG REG_MM(0x0164)
#define CSIPHYTIMER_NS_REG REG_MM(0x0168)
#define DSI1_BYTE_NS_REG REG_MM(0x00B0)
#define DSI1_BYTE_CC_REG REG_MM(0x0090)
#define DSI2_BYTE_NS_REG REG_MM(0x00BC)
#define DSI2_BYTE_CC_REG REG_MM(0x00B4)
#define DSI1_ESC_NS_REG REG_MM(0x011C)
#define DSI1_ESC_CC_REG REG_MM(0x00CC)
#define MM_PLL1_MODE_REG REG_MM(0x031C)
#define MM_PLL1_L_VAL_REG REG_MM(0x0320)
#define MM_PLL1_M_VAL_REG REG_MM(0x0324)
#define MM_PLL1_N_VAL_REG REG_MM(0x0328)
#define MM_PLL1_TEST_CTL_REG REG_MM(0x0330)
#define MM_PLL1_CONFIG_REG REG_MM(0x032C)
#define MM_PLL2_MODE_REG REG_MM(0x3160)
#define MM_PLL2_L_VAL_REG REG_MM(0x3164)
#define MM_PLL2_M_VAL_REG REG_MM(0x3168)
#define MM_PLL2_N_VAL_REG REG_MM(0x316C)
#define MM_PLL2_TEST_CTL_REG REG_MM(0x3170)
#define MM_PLL2_CONFIG_REG REG_MM(0x3174)
#define MMSS_AHB_EN_REG REG_MM(0x08)
#define DSI2_ESC_NS_REG REG_MM(0x0150)
#define DSI2_ESC_CC_REG REG_MM(0x013C)
#define DSI_PIXEL_CC_REG REG_MM(0x0130)
#define DSI_PIXEL_MD_REG REG_MM(0x0134)
#define DSI_PIXEL_NS_REG REG_MM(0x0138)
#define DSI2_PIXEL_CC_REG REG_MM(0x0094)
#define DSI_NS_REG REG_MM(0x54)
#define DSI_MD_REG REG_MM(0x50)
#define DSI_CC_REG REG_MM(0x4C)
#define DBG_BUS_VEC_A_REG REG_MM(0x01C8)
#define DBG_BUS_VEC_B_REG REG_MM(0x01CC)
#define DBG_BUS_VEC_C_REG REG_MM(0x01D0)
#define DBG_BUS_VEC_D_REG REG_MM(0x01D4)
#define DBG_BUS_VEC_E_REG REG_MM(0x01D8)
#define DBG_BUS_VEC_F_REG REG_MM(0x01DC)
#define DBG_BUS_VEC_G_REG REG_MM(0x01E0)
#define DBG_BUS_VEC_H_REG REG_MM(0x01E4)
#define DBG_BUS_VEC_I_REG REG_MM(0x01E8)
#define DBG_CFG_REG_HS_REG REG_MM(0x01B4)
#define DBG_CFG_REG_LS_REG REG_MM(0x01B8)
#define GFX2D0_CC_REG REG_MM(0x0060)
#define GFX2D0_MD0_REG REG_MM(0x0064)
#define GFX2D0_MD1_REG REG_MM(0x0068)
#define GFX2D0_NS_REG REG_MM(0x0070)
#define GFX2D1_CC_REG REG_MM(0x0074)
#define GFX2D1_MD0_REG REG_MM(0x0078)
#define GFX2D1_MD1_REG REG_MM(0x006C)
#define GFX2D1_NS_REG REG_MM(0x007C)
#define GFX3D_CC_REG REG_MM(0x0080)
#define GFX3D_MD0_REG REG_MM(0x0084)
#define GFX3D_MD1_REG REG_MM(0x0088)
#define GFX3D_NS_REG REG_MM(0x008C)
#define IJPEG_CC_REG REG_MM(0x0098)
#define IJPEG_MD_REG REG_MM(0x009C)
#define IJPEG_NS_REG REG_MM(0x00A0)
#define JPEGD_CC_REG REG_MM(0x00A4)
#define JPEGD_NS_REG REG_MM(0x00AC)
#define MAXI_EN_REG REG_MM(0x0018)
#define MAXI_EN2_REG REG_MM(0x0020)
#define MAXI_EN3_REG REG_MM(0x002C)
#define MAXI_EN4_REG REG_MM(0x0114)
#define MDP_CC_REG REG_MM(0x00C0)
#define MDP_LUT_CC_REG REG_MM(0x016C)
#define MDP_MD0_REG REG_MM(0x00C4)
#define MDP_MD1_REG REG_MM(0x00C8)
#define MDP_NS_REG REG_MM(0x00D0)
#define MISC_CC_REG REG_MM(0x0058)
#define MISC_CC2_REG REG_MM(0x005C)
#define MM_PLL1_MODE_REG REG_MM(0x031C)
#define ROT_CC_REG REG_MM(0x00E0)
#define ROT_NS_REG REG_MM(0x00E8)
#define SAXI_EN_REG REG_MM(0x0030)
#define SW_RESET_AHB_REG REG_MM(0x020C)
#define SW_RESET_AHB2_REG REG_MM(0x0200)
#define SW_RESET_ALL_REG REG_MM(0x0204)
#define SW_RESET_AXI_REG REG_MM(0x0208)
#define SW_RESET_CORE_REG REG_MM(0x0210)
#define TV_CC_REG REG_MM(0x00EC)
#define TV_CC2_REG REG_MM(0x0124)
#define TV_MD_REG REG_MM(0x00F0)
#define TV_NS_REG REG_MM(0x00F4)
#define VCODEC_CC_REG REG_MM(0x00F8)
#define VCODEC_MD0_REG REG_MM(0x00FC)
#define VCODEC_MD1_REG REG_MM(0x0128)
#define VCODEC_NS_REG REG_MM(0x0100)
#define VFE_CC_REG REG_MM(0x0104)
#define VFE_MD_REG REG_MM(0x0108)
#define VFE_NS_REG REG_MM(0x010C)
#define VPE_CC_REG REG_MM(0x0110)
#define VPE_NS_REG REG_MM(0x0118)
/* MUX source input identifiers. */
#define pxo_to_bb_mux 0
#define cxo_to_bb_mux pxo_to_bb_mux
#define pll0_to_bb_mux 2
#define pll8_to_bb_mux 3
#define pll6_to_bb_mux 4
#define gnd_to_bb_mux 5
#define pll3_to_bb_mux 6
#define pxo_to_mm_mux 0
#define pll1_to_mm_mux 1
#define pll2_to_mm_mux 1
#define pll8_to_mm_mux 2
#define pll0_to_mm_mux 3
#define gnd_to_mm_mux 4
#define hdmi_pll_to_mm_mux 3
#define cxo_to_xo_mux 0
#define pxo_to_xo_mux 1
#define gnd_to_xo_mux 3
#define pxo_to_lpa_mux 0
#define cxo_to_lpa_mux 1
#define pll4_to_lpa_mux 2
#define gnd_to_lpa_mux 6
/* Test Vector Macros */
#define TEST_TYPE_PER_LS 1
#define TEST_TYPE_PER_HS 2
#define TEST_TYPE_MM_LS 3
#define TEST_TYPE_MM_HS 4
#define TEST_TYPE_LPA 5
#define TEST_TYPE_CPUL2 6
#define TEST_TYPE_LPA_HS 7
#define TEST_TYPE_SHIFT 24
#define TEST_CLK_SEL_MASK BM(23, 0)
#define TEST_VECTOR(s, t) (((t) << TEST_TYPE_SHIFT) | BVAL(23, 0, (s)))
#define TEST_PER_LS(s) TEST_VECTOR((s), TEST_TYPE_PER_LS)
#define TEST_PER_HS(s) TEST_VECTOR((s), TEST_TYPE_PER_HS)
#define TEST_MM_LS(s) TEST_VECTOR((s), TEST_TYPE_MM_LS)
#define TEST_MM_HS(s) TEST_VECTOR((s), TEST_TYPE_MM_HS)
#define TEST_LPA(s) TEST_VECTOR((s), TEST_TYPE_LPA)
#define TEST_LPA_HS(s) TEST_VECTOR((s), TEST_TYPE_LPA_HS)
#define TEST_CPUL2(s) TEST_VECTOR((s), TEST_TYPE_CPUL2)
#define MN_MODE_DUAL_EDGE 0x2
/* MD Registers */
#define MD4(m_lsb, m, n_lsb, n) \
(BVAL((m_lsb+3), m_lsb, m) | BVAL((n_lsb+3), n_lsb, ~(n)))
#define MD8(m_lsb, m, n_lsb, n) \
(BVAL((m_lsb+7), m_lsb, m) | BVAL((n_lsb+7), n_lsb, ~(n)))
#define MD16(m, n) (BVAL(31, 16, m) | BVAL(15, 0, ~(n)))
/* NS Registers */
#define NS(n_msb, n_lsb, n, m, mde_lsb, d_msb, d_lsb, d, s_msb, s_lsb, s) \
(BVAL(n_msb, n_lsb, ~(n-m)) \
| (BVAL((mde_lsb+1), mde_lsb, MN_MODE_DUAL_EDGE) * !!(n)) \
| BVAL(d_msb, d_lsb, (d-1)) | BVAL(s_msb, s_lsb, s))
#define NS_MM(n_msb, n_lsb, n, m, d_msb, d_lsb, d, s_msb, s_lsb, s) \
(BVAL(n_msb, n_lsb, ~(n-m)) | BVAL(d_msb, d_lsb, (d-1)) \
| BVAL(s_msb, s_lsb, s))
#define NS_DIVSRC(d_msb , d_lsb, d, s_msb, s_lsb, s) \
(BVAL(d_msb, d_lsb, (d-1)) | BVAL(s_msb, s_lsb, s))
#define NS_DIV(d_msb , d_lsb, d) \
BVAL(d_msb, d_lsb, (d-1))
#define NS_SRC_SEL(s_msb, s_lsb, s) \
BVAL(s_msb, s_lsb, s)
#define NS_MND_BANKED4(n0_lsb, n1_lsb, n, m, s0_lsb, s1_lsb, s) \
(BVAL((n0_lsb+3), n0_lsb, ~(n-m)) \
| BVAL((n1_lsb+3), n1_lsb, ~(n-m)) \
| BVAL((s0_lsb+2), s0_lsb, s) \
| BVAL((s1_lsb+2), s1_lsb, s))
#define NS_MND_BANKED8(n0_lsb, n1_lsb, n, m, s0_lsb, s1_lsb, s) \
(BVAL((n0_lsb+7), n0_lsb, ~(n-m)) \
| BVAL((n1_lsb+7), n1_lsb, ~(n-m)) \
| BVAL((s0_lsb+2), s0_lsb, s) \
| BVAL((s1_lsb+2), s1_lsb, s))
#define NS_DIVSRC_BANKED(d0_msb, d0_lsb, d1_msb, d1_lsb, d, \
s0_msb, s0_lsb, s1_msb, s1_lsb, s) \
(BVAL(d0_msb, d0_lsb, (d-1)) | BVAL(d1_msb, d1_lsb, (d-1)) \
| BVAL(s0_msb, s0_lsb, s) \
| BVAL(s1_msb, s1_lsb, s))
/* CC Registers */
#define CC(mde_lsb, n) (BVAL((mde_lsb+1), mde_lsb, MN_MODE_DUAL_EDGE) * !!(n))
#define CC_BANKED(mde0_lsb, mde1_lsb, n) \
((BVAL((mde0_lsb+1), mde0_lsb, MN_MODE_DUAL_EDGE) \
| BVAL((mde1_lsb+1), mde1_lsb, MN_MODE_DUAL_EDGE)) \
* !!(n))
struct pll_rate {
const uint32_t l_val;
const uint32_t m_val;
const uint32_t n_val;
const uint32_t vco;
const uint32_t post_div;
const uint32_t i_bits;
};
#define PLL_RATE(l, m, n, v, d, i) { l, m, n, v, (d>>1), i }
/* DSI specific data */
/* Configured at 13.5 MHz */
#define ESC_NS_VAL 0x00001000
#define ESC_CC_VAL 0x00000004
#define BYTE_NS_VAL 0x00000001
#define BYTE_CC_VAL 0x00000004
#define PIXEL_NS_VAL 0x00F80003
#define PIXEL_MD_VAL 0x000001FB
#define PIXEL_CC_VAL 0x00000080
#define DSI_NS_VAL 0xFA000003
#define DSI_MD_VAL 0x000003FB
#define DSI_CC_VAL 0x00000080
void config_mmss_clk(uint32_t ns,
uint32_t md,
uint32_t cc,
uint32_t ns_addr, uint32_t md_addr, uint32_t cc_addr);
void config_mdp_lut_clk(void);
void mdp_clock_init(void);
#endif

View File

@@ -0,0 +1,61 @@
/* Copyright (c) 2011-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_MSM8960_GPIO_H
#define __PLATFORM_MSM8960_GPIO_H
/* 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 1
#define GPIO_DISABLE 0
void gpio_config_i2c(uint8_t gsbi_id);
void gpio_config_uart_dm(uint8_t id);
void msm8960_keypad_gpio_init();
void msm8930_keypad_gpio_init();
#endif

View File

@@ -0,0 +1,146 @@
/* Copyright (c) 2008, Google Inc.
* All rights reserved.
*
* Copyright (c) 2009-2013, 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.
*/
#ifndef _PLATFORM_MSM8960_IOMAP_H_
#define _PLATFORM_MSM8960_IOMAP_H_
#define MSM_IOMAP_BASE 0x00100000
#define MSM_IOMAP_END 0x28000000
#define MSM_IMEM_BASE 0x2A000000
#define MSM_SHARED_IMEM_BASE 0x2A03F000
#define RESTART_REASON_ADDR (MSM_SHARED_IMEM_BASE + 0x65C)
#define MSM_SHARED_BASE 0x80000000
#define MSM_TCSR_BASE 0x1A400000
#define MSM_GIC_DIST_BASE 0x02000000
#define MSM_TMR_BASE 0x0200A000
#define MSM_GPT_BASE (MSM_TMR_BASE + 0x04)
#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24)
#define SPSS_TIMER_STATUS (MSM_TMR_BASE + 0x88)
#define GPT_REG(off) (MSM_GPT_BASE + (off))
#define DGT_REG(off) (MSM_DGT_BASE + (off))
#define GPT_MATCH_VAL GPT_REG(0x0000)
#define GPT_COUNT_VAL GPT_REG(0x0004)
#define GPT_ENABLE GPT_REG(0x0008)
#define GPT_CLEAR GPT_REG(0x000C)
#define DGT_MATCH_VAL DGT_REG(0x0000)
#define DGT_COUNT_VAL DGT_REG(0x0004)
#define DGT_ENABLE DGT_REG(0x0008)
#define DGT_CLEAR DGT_REG(0x000C)
#define DGT_CLK_CTL DGT_REG(0x0010)
#define MSM_GIC_CPU_BASE 0x02002000
#define MSM_VIC_BASE 0x02080000
#define MSM_TCSR_SIZE 4096
#define MSM_USB_BASE 0x12500000
#define TLMM_BASE_ADDR 0x00800000
#define TCSR_WDOG_CFG 0x30
#define MSM_WDT0_RST (MSM_TMR_BASE + 0x38)
#define MSM_WDT0_EN (MSM_TMR_BASE + 0x40)
#define MSM_WDT0_BT (MSM_TMR_BASE + 0x4C)
#define MSM_PSHOLD_CTL_SU (TLMM_BASE_ADDR + 0x820)
#define MSM_SDC1_BASE 0x12400000
#define MSM_SDC2_BASE 0x12140000
#define MSM_SDC3_BASE 0x12180000
#define MSM_SDC4_BASE 0x121C0000
#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + 0x1000 + (x)*0x10)
#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE_ADDR + 0x1004 + (x)*0x10)
#define EBI2_CHIP_SELECT_CFG0 0x1A100000
#define EBI2_XMEM_CS3_CFG1 0x1A110034
#define MSM_CLK_CTL_BASE 0x00900000
#define MSM_MMSS_CLK_CTL_BASE 0x04000000
#define MIPI_DSI_BASE (0x04700000)
#define REG_DSI(off) (MIPI_DSI_BASE + (off))
#define DSIPHY_REGULATOR_BASE (0x500)
#define DSIPHY_TIMING_BASE (0x440)
#define DSIPHY_CTRL_BASE (0x470)
#define DSIPHY_PLL_BASE (0x200)
#define DSIPHY_STRENGTH_BASE (0x480)
/* Range 0 - 4 */
#define DSIPHY_REGULATOR_CTRL(x) REG_DSI(DSIPHY_REGULATOR_BASE + (x) * 4)
/* Range 0 - 11 */
#define DSIPHY_TIMING_CTRL(x) REG_DSI(DSIPHY_TIMING_BASE + (x) * 4)
/* Range 0 - 3 */
#define DSIPHY_CTRL(x) REG_DSI(DSIPHY_CTRL_BASE + (x) * 4)
/* Range 0 - 2 */
#define DSIPHY_STRENGTH_CTRL(x) REG_DSI(DSIPHY_STRENGTH_BASE + (x) * 4)
/* Range 0 - 19 */
#define DSIPHY_PLL_CTRL(x) REG_DSI(DSIPHY_PLL_BASE + (x) * 4)
#define MDP_BASE (0x05100000)
#define REG_MDP(off) (MDP_BASE + (off))
//TODO: Where does this go?
#define MMSS_SFPB_GPREG (0x05700058)
/* HDMI base addresses */
#define MSM_HDMI_BASE 0x04A00000
#define DTV_BASE 0xD0000
#define HDMI_USEC_REFTIMER (MSM_HDMI_BASE + 0x0208)
#define HDMI_CTRL (MSM_HDMI_BASE + 0x0000)
#define HDMI_HPD_INT_STATUS (MSM_HDMI_BASE + 0x0250)
#define HDMI_HPD_INT_CTRL (MSM_HDMI_BASE + 0x0254)
#define HDMI_HPD_CTRL (MSM_HDMI_BASE + 0x0258)
#define HDMI_PHY_CTRL (MSM_HDMI_BASE + 0x000002D4)
#define HDMI_PHY_REG_0 (MSM_HDMI_BASE + 0x00000400)
#define HDMI_PHY_REG_1 (MSM_HDMI_BASE + 0x00000404)
#define HDMI_PHY_REG_2 (MSM_HDMI_BASE + 0x00000408)
#define HDMI_PHY_REG_3 (MSM_HDMI_BASE + 0x0000040c)
#define HDMI_PHY_REG_4 (MSM_HDMI_BASE + 0x00000410)
#define HDMI_PHY_REG_9 (MSM_HDMI_BASE + 0x00000424)
#define HDMI_PHY_REG_11 (MSM_HDMI_BASE + 0x0000042c)
#define HDMI_PHY_REG_12 (MSM_HDMI_BASE + 0x00000430)
#define HDMI_TOTAL (MSM_HDMI_BASE + 0x000002C0)
#define HDMI_ACTIVE_HSYNC (MSM_HDMI_BASE + 0x000002B4)
#define HDMI_ACTIVE_VSYNC (MSM_HDMI_BASE + 0x000002B8)
#define HDMI_VSYNC_TOTAL_F2 (MSM_HDMI_BASE + 0x000002C4)
#define HDMI_VSYNC_ACTIVE_F2 (MSM_HDMI_BASE + 0x000002BC)
#define HDMI_FRAME_CTRL (MSM_HDMI_BASE + 0x000002C8)
#define CE1_CRYPTO4_BASE (0x18500000)
#define CE3_CRYPTO4_BASE (0x11000000)
#define LCDC_BASE (0x000C0000)
#endif

View File

@@ -0,0 +1,61 @@
/* Copyright (c) 2009-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 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 __IRQS_8960_H
#define __IRQS_8960_H
/* MSM ACPU Interrupt Numbers */
/* 0-15: STI/SGI (software triggered/generated interrupts)
* 16-31: PPI (private peripheral interrupts)
* 32+: SPI (shared peripheral interrupts)
*/
#define GIC_PPI_START 16
#define GIC_SPI_START 32
#define INT_DEBUG_TIMER_EXP (GIC_PPI_START + 1)
#define USB1_HS_BAM_IRQ (GIC_SPI_START + 94)
#define USB1_HS_IRQ (GIC_SPI_START + 100)
#define USB2_IRQ (GIC_SPI_START + 141)
#define USB1_IRQ (GIC_SPI_START + 142)
#define GSBI_QUP_IRQ(id) ((id) <= 8 ? (GIC_SPI_START + 145 + 2*((id))) : \
(GIC_SPI_START + 187 + 2*((id)-8)))
/* Retrofit universal macro names */
#define INT_USB_HS USB1_HS_IRQ
#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)
#endif /* __IRQS_8960_H */

View File

@@ -0,0 +1,168 @@
/*
* Copyright (c) 2011-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 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 <debug.h>
#include <reg.h>
#include <platform/iomap.h>
#include <qgic.h>
#include <uart_dm.h>
#include <dev/fbcon.h>
#include <mmu.h>
#include <arch/arm/mmu.h>
#include <board.h>
extern void platform_init_timer(void);
extern void platform_panel_backlight_on(void);
extern void platform_uninit_timer(void);
extern void mipi_panel_reset(void);
extern void mipi_dsi_panel_power_on(void);
extern void mdp_clock_init(void);
extern void mmss_clock_init(void);
extern struct fbcon_config *mipi_init(void);
extern void mipi_dsi_shutdown(void);
extern void msm_clocks_init(void);
static uint32_t ticks_per_sec = 0;
static uint8_t display_enabled = 0;
#define MB (1024*1024)
#define MSM_IOMAP_SIZE ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
/* LK memory - cacheable, write through */
#define LK_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
MMU_MEMORY_AP_READ_WRITE)
/* Kernel region - cacheable, write through */
#define KERNEL_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
/* Scratch region - cacheable, write through */
#define SCRATCH_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
/* Peripherals - non-shared device */
#define IOMAP_MEMORY (MMU_MEMORY_TYPE_DEVICE_NON_SHARED | \
MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
/* IMEM: Must set execute never bit to avoid instruction prefetch from TZ */
#define IMEM_MEMORY (MMU_MEMORY_TYPE_STRONGLY_ORDERED | \
MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
mmu_section_t mmu_section_table[] = {
/* Physical addr, Virtual addr, Size (in MB), Flags */
{MEMBASE, MEMBASE, (MEMSIZE / MB), LK_MEMORY},
{BASE_ADDR, BASE_ADDR, 44, KERNEL_MEMORY},
{SCRATCH_ADDR, SCRATCH_ADDR, 768, SCRATCH_MEMORY},
{MSM_IOMAP_BASE, MSM_IOMAP_BASE, MSM_IOMAP_SIZE, IOMAP_MEMORY},
{MSM_IMEM_BASE, MSM_IMEM_BASE, 1, IMEM_MEMORY},
};
void platform_early_init(void)
{
msm_clocks_init();
qgic_init();
platform_init_timer();
board_init();
}
void platform_init(void)
{
dprintf(INFO, "platform_init()\n");
}
void platform_uninit(void)
{
#if DISPLAY_SPLASH_SCREEN
display_shutdown();
#endif
platform_uninit_timer();
}
/* Setup memory for this platform */
void platform_init_mmu_mappings(void)
{
uint32_t i;
uint32_t sections;
uint32_t table_size = ARRAY_SIZE(mmu_section_table);
for (i = 0; i < table_size; i++) {
sections = mmu_section_table[i].num_of_sections;
while (sections--) {
arm_mmu_map_section(mmu_section_table[i].paddress +
sections * MB,
mmu_section_table[i].vaddress +
sections * MB,
mmu_section_table[i].flags);
}
}
}
/* Initialize DGT timer */
void platform_init_timer(void)
{
/* disable timer */
writel(0, DGT_ENABLE);
/* DGT uses LPXO source which is 27MHz.
* Set clock divider to 4.
*/
writel(3, DGT_CLK_CTL);
ticks_per_sec = 6750000; /* (27 MHz / 4) */
}
/* Returns timer ticks per sec */
uint32_t platform_tick_rate(void)
{
return ticks_per_sec;
}
/* Return true if the pmic type matches */
uint8_t platform_pmic_type(uint32_t pmic_type)
{
uint8_t ret = 0;
uint8_t i = 0;
uint8_t num_ent = 0;
struct board_pmic_data pmic_info[SMEM_V7_SMEM_MAX_PMIC_DEVICES];
num_ent = board_pmic_info(&pmic_info, SMEM_V7_SMEM_MAX_PMIC_DEVICES);
for(i = 0; i < num_ent; i++) {
if (pmic_info[i].pmic_type == pmic_type) {
ret = 1;
break;
}
}
return ret;
}

View File

@@ -0,0 +1,29 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
ARCH := arm
ARM_CPU := cortex-a8
CPU := generic
DEFINES += ARM_CPU_CORE_KRAIT
MMC_SLOT := 1
DEFINES += WITH_CPU_EARLY_INIT=0 WITH_CPU_WARM_BOOT=0 \
MMC_SLOT=$(MMC_SLOT) MDP4=1 SSD_ENABLE
INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared/include
DEVS += fbcon
MODULES += dev/fbcon
OBJS += \
$(LOCAL_DIR)/platform.o \
$(LOCAL_DIR)/acpuclock.o \
$(LOCAL_DIR)/gpio.o \
$(LOCAL_DIR)/clock.o \
$(LOCAL_DIR)/hdmi_core.o
LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld
include platform/msm_shared/rules.mk