mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2026-03-14 21:10:27 +01:00
ipq807x: Added clock support
These files are copied from: https://source.codeaurora.org/quic/qsdk/oss/boot/uboot-1.0/tree/arch/arm/cpu/armv7/qca/clock.c https://source.codeaurora.org/quic/qsdk/oss/boot/uboot-1.0/tree/arch/arm/include/asm/arch-qcom-common/clk.h Change-Id: Ie9782f97ece0d76696818c1c1f942c45a6221ae0 Signed-off-by: Ajay Kishore <akisho@codeaurora.org>
This commit is contained in:
parent
d8cf279460
commit
7ec20f4d28
2 changed files with 307 additions and 0 deletions
100
board/qca/ipq807x/clk.h
Normal file
100
board/qca/ipq807x/clk.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef QCA_CLK_H
|
||||
#define QCA_CLK_H
|
||||
|
||||
#define MMC_IDENTIFY_MODE 0
|
||||
#define MMC_DATA_TRANSFER_MODE 1
|
||||
|
||||
#define GCC_BLSP1_UART2_APPS_CFG_RCGR 0x01803038
|
||||
#define GCC_BLSP1_UART2_APPS_M 0x0180303C
|
||||
#define GCC_BLSP1_UART2_APPS_N 0x01803040
|
||||
#define GCC_BLSP1_UART2_APPS_D 0x01803044
|
||||
#define GCC_BLSP1_UART2_APPS_CMD_RCGR 0x01803034
|
||||
#define GCC_BLSP1_UART2_APPS_CBCR 0x0180302C
|
||||
|
||||
#define GCC_UART_CFG_RCGR_MODE_MASK 0x3000
|
||||
#define GCC_UART_CFG_RCGR_SRCSEL_MASK 0x0700
|
||||
#define GCC_UART_CFG_RCGR_SRCDIV_MASK 0x001F
|
||||
|
||||
#define GCC_UART_CFG_RCGR_MODE_SHIFT 12
|
||||
#define GCC_UART_CFG_RCGR_SRCSEL_SHIFT 8
|
||||
#define GCC_UART_CFG_RCGR_SRCDIV_SHIFT 0
|
||||
|
||||
#define UART2_RCGR_SRC_SEL 0x0
|
||||
#define UART2_RCGR_SRC_DIV 0x0
|
||||
#define UART2_RCGR_MODE 0x2
|
||||
#define UART2_CMD_RCGR_UPDATE 0x1
|
||||
#define UART2_CBCR_CLK_ENABLE 0x1
|
||||
|
||||
#define NOT_2D(two_d) (~two_d)
|
||||
#define NOT_N_MINUS_M(n,m) (~(n - m))
|
||||
#define CLOCK_UPDATE_TIMEOUT_US 1000
|
||||
|
||||
#ifdef CONFIG_IPQ40XX_I2C
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR 0x01802010
|
||||
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_M 0x0180303C
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_N 0x01803040
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_D 0x01803044
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR 0x0180200C
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_CBCR 0x01802008
|
||||
|
||||
#define GCC_I2C_CFG_RCGR_SRCSEL_MASK 0x0700
|
||||
#define GCC_I2C_CFG_RCGR_SRCDIV_MASK 0x001F
|
||||
|
||||
#define GCC_I2C_CFG_RCGR_SRCSEL_SHIFT 8
|
||||
#define GCC_I2C_CFG_RCGR_SRCDIV_SHIFT 0
|
||||
|
||||
#define I2C0_RCGR_SRC_SEL 1
|
||||
#define I2C0_RCGR_SRC_DIV 20
|
||||
#define I2C0_CMD_RCGR_UPDATE 0x1
|
||||
#define I2C0_CBCR_CLK_ENABLE 0x1
|
||||
#define NOT_2D(two_d) (~two_d)
|
||||
#define NOT_N_MINUS_M(n,m) (~(n - m))
|
||||
#define CLOCK_UPDATE_TIMEOUT_US 1000
|
||||
#endif
|
||||
|
||||
#define GCC_PCIE_SLEEP_CBCR 0x0181D014
|
||||
#define GCC_PCIE_AXI_M_CBCR 0x0181D004
|
||||
#define GCC_PCIE_AXI_S_CBCR 0x0181D008
|
||||
#define GCC_PCIE_AHB_CBCR 0x0181D00C
|
||||
#define PCIE_TIMEOUT_CNT 100
|
||||
#define ENABLE 0x1
|
||||
#define DISABLE 0x0
|
||||
#define BIT(s) (1<<s)
|
||||
|
||||
void emmc_clock_config(int mode);
|
||||
void emmc_clock_disable(void);
|
||||
|
||||
/* UART clocks configuration */
|
||||
void uart2_clock_config(unsigned int m,
|
||||
unsigned int n, unsigned int two_d);
|
||||
void uart2_toggle_clock(void);
|
||||
int uart2_trigger_update(void);
|
||||
void uart2_set_rate_mnd(unsigned int m,
|
||||
unsigned int n, unsigned int two_d);
|
||||
void uart2_configure_mux(void);
|
||||
|
||||
/* I2C clocks configuration */
|
||||
#ifdef CONFIG_IPQ40XX_I2C
|
||||
void i2c_clock_config(void);
|
||||
void i2c0_toggle_clock(void);
|
||||
int i2c0_trigger_update(void);
|
||||
void i2c0_configure_mux(void);
|
||||
#endif
|
||||
|
||||
int pcie_clock_enable(int clk_addr);
|
||||
void pcie_clock_disable(int clk_addr);
|
||||
#endif /*QCA_CLK_H*/
|
||||
207
board/qca/ipq807x/clock.c
Normal file
207
board/qca/ipq807x/clock.c
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch-qcom-common/clk.h>
|
||||
#include <asm/arch-ipq40xx/iomap.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
#define GCC_SDCC1_MISC 0x1818014
|
||||
#define GCC_SDCC1_APPS_CBCR 0x181800C
|
||||
#define GCC_SDCC1_APPS_RCGR 0x1818008
|
||||
#define GCC_SDCC1_APPS_CMD_RCGR 0x1818004
|
||||
|
||||
void emmc_clock_config(int mode)
|
||||
{
|
||||
/* Select SDCC clock source as DDR_PLL_SDCC1_CLK 192MHz */
|
||||
writel(0x100, GCC_SDCC1_APPS_RCGR);
|
||||
/* Update APPS_CMD_RCGR to reflect source selection */
|
||||
writel(0x1, GCC_SDCC1_APPS_CMD_RCGR);
|
||||
udelay(10);
|
||||
|
||||
if (mode == MMC_IDENTIFY_MODE) {
|
||||
/* Set root clock generator to bypass mode */
|
||||
writel(0x0, GCC_SDCC1_APPS_CBCR);
|
||||
udelay(10);
|
||||
/* Choose divider for 400KHz */
|
||||
writel(0x1e4 , GCC_SDCC1_MISC);
|
||||
/* Enable root clock generator */
|
||||
writel(0x1, GCC_SDCC1_APPS_CBCR);
|
||||
udelay(10);
|
||||
}
|
||||
if (mode == MMC_DATA_TRANSFER_MODE) {
|
||||
/* Set root clock generator to bypass mode */
|
||||
writel(0x0, GCC_SDCC1_APPS_CBCR);
|
||||
udelay(10);
|
||||
/* Choose divider for 48MHz */
|
||||
writel(0x3, GCC_SDCC1_MISC);
|
||||
/* Enable root clock generator */
|
||||
writel(0x1, GCC_SDCC1_APPS_CBCR);
|
||||
udelay(10);
|
||||
}
|
||||
}
|
||||
void emmc_clock_disable(void)
|
||||
{
|
||||
/* Clear divider */
|
||||
writel(0x0, GCC_SDCC1_MISC);
|
||||
|
||||
}
|
||||
|
||||
void uart2_configure_mux(void)
|
||||
{
|
||||
unsigned long cfg_rcgr;
|
||||
|
||||
cfg_rcgr = readl(GCC_BLSP1_UART2_APPS_CFG_RCGR);
|
||||
/* Clear mode, src sel, src div */
|
||||
cfg_rcgr &= ~(GCC_UART_CFG_RCGR_MODE_MASK |
|
||||
GCC_UART_CFG_RCGR_SRCSEL_MASK |
|
||||
GCC_UART_CFG_RCGR_SRCDIV_MASK);
|
||||
|
||||
cfg_rcgr |= ((UART2_RCGR_SRC_SEL << GCC_UART_CFG_RCGR_SRCSEL_SHIFT)
|
||||
& GCC_UART_CFG_RCGR_SRCSEL_MASK);
|
||||
|
||||
cfg_rcgr |= ((UART2_RCGR_SRC_DIV << GCC_UART_CFG_RCGR_SRCDIV_SHIFT)
|
||||
& GCC_UART_CFG_RCGR_SRCDIV_MASK);
|
||||
|
||||
cfg_rcgr |= ((UART2_RCGR_MODE << GCC_UART_CFG_RCGR_MODE_SHIFT)
|
||||
& GCC_UART_CFG_RCGR_MODE_MASK);
|
||||
|
||||
writel(cfg_rcgr, GCC_BLSP1_UART2_APPS_CFG_RCGR);
|
||||
}
|
||||
|
||||
void uart2_set_rate_mnd(unsigned int m,
|
||||
unsigned int n, unsigned int two_d)
|
||||
{
|
||||
writel(m, GCC_BLSP1_UART2_APPS_M);
|
||||
writel(NOT_N_MINUS_M(n, m), GCC_BLSP1_UART2_APPS_N);
|
||||
writel(NOT_2D(two_d), GCC_BLSP1_UART2_APPS_D);
|
||||
}
|
||||
|
||||
int uart2_trigger_update(void)
|
||||
{
|
||||
unsigned long cmd_rcgr;
|
||||
int timeout = 0;
|
||||
|
||||
cmd_rcgr = readl(GCC_BLSP1_UART2_APPS_CMD_RCGR);
|
||||
cmd_rcgr |= UART2_CMD_RCGR_UPDATE;
|
||||
writel(cmd_rcgr, GCC_BLSP1_UART2_APPS_CMD_RCGR);
|
||||
|
||||
while (readl(GCC_BLSP1_UART2_APPS_CMD_RCGR) & UART2_CMD_RCGR_UPDATE) {
|
||||
if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) {
|
||||
printf("Timeout waiting for UART2 clock update\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
udelay(1);
|
||||
}
|
||||
cmd_rcgr = readl(GCC_BLSP1_UART2_APPS_CMD_RCGR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uart2_toggle_clock(void)
|
||||
{
|
||||
unsigned long cbcr_val;
|
||||
|
||||
cbcr_val = readl(GCC_BLSP1_UART2_APPS_CBCR);
|
||||
cbcr_val |= UART2_CBCR_CLK_ENABLE;
|
||||
writel(cbcr_val, GCC_BLSP1_UART2_APPS_CBCR);
|
||||
}
|
||||
|
||||
void uart2_clock_config(unsigned int m,
|
||||
unsigned int n, unsigned int two_d)
|
||||
{
|
||||
uart2_configure_mux();
|
||||
uart2_set_rate_mnd(m, n, two_d);
|
||||
uart2_trigger_update();
|
||||
uart2_toggle_clock();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPQ40XX_I2C
|
||||
void i2c0_configure_mux(void)
|
||||
{
|
||||
unsigned long cfg_rcgr;
|
||||
|
||||
cfg_rcgr = readl(GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR);
|
||||
/* Clear mode, src sel, src div */
|
||||
cfg_rcgr &= ~(GCC_I2C_CFG_RCGR_SRCSEL_MASK |
|
||||
GCC_I2C_CFG_RCGR_SRCDIV_MASK);
|
||||
|
||||
cfg_rcgr |= ((I2C0_RCGR_SRC_SEL << GCC_I2C_CFG_RCGR_SRCSEL_SHIFT)
|
||||
& GCC_UART_CFG_RCGR_SRCSEL_MASK);
|
||||
|
||||
cfg_rcgr |= ((I2C0_RCGR_SRC_DIV << GCC_I2C_CFG_RCGR_SRCDIV_SHIFT)
|
||||
& GCC_UART_CFG_RCGR_SRCDIV_MASK);
|
||||
|
||||
writel(cfg_rcgr, GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR);
|
||||
}
|
||||
|
||||
int i2c0_trigger_update(void)
|
||||
{
|
||||
unsigned long cmd_rcgr;
|
||||
int timeout = 0;
|
||||
|
||||
cmd_rcgr = readl(GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR);
|
||||
cmd_rcgr |= I2C0_CMD_RCGR_UPDATE;
|
||||
writel(cmd_rcgr, GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR);
|
||||
|
||||
while (readl(GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR) & I2C0_CMD_RCGR_UPDATE) {
|
||||
if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) {
|
||||
printf("Timeout waiting for I2C0 clock update\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
udelay(1);
|
||||
}
|
||||
cmd_rcgr = readl(GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i2c0_toggle_clock(void)
|
||||
{
|
||||
unsigned long cbcr_val;
|
||||
|
||||
cbcr_val = readl(GCC_BLSP1_QUP1_I2C_APPS_CBCR);
|
||||
cbcr_val |= I2C0_CBCR_CLK_ENABLE;
|
||||
writel(cbcr_val, GCC_BLSP1_QUP1_I2C_APPS_CBCR);
|
||||
}
|
||||
|
||||
void i2c_clock_config(void)
|
||||
{
|
||||
i2c0_configure_mux();
|
||||
i2c0_trigger_update();
|
||||
i2c0_toggle_clock();
|
||||
}
|
||||
#endif
|
||||
|
||||
int pcie_clock_enable(int clk_addr)
|
||||
{
|
||||
unsigned int count = PCIE_TIMEOUT_CNT;
|
||||
int state, val;
|
||||
|
||||
writel(ENABLE, clk_addr);
|
||||
do {
|
||||
val = readl(clk_addr);
|
||||
count--;
|
||||
if (count == 0) {
|
||||
printf("Timeout waiting for %d enable \n", clk_addr);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
state = (val & BIT(31));
|
||||
udelay(10);
|
||||
} while (state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pcie_clock_disable(int clk_addr)
|
||||
{
|
||||
writel(0, clk_addr);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue