Merge "ipq6018: add UART clock settings"

This commit is contained in:
Linux Build Service Account 2020-04-15 10:47:46 -07:00 committed by Gerrit - the friendly Code Review server
commit 429d109cfd
7 changed files with 124 additions and 112 deletions

View file

@ -22,6 +22,9 @@
reg = <0x78B1000 0x200>;
id = <4>;
bit_rate = <0xff>;
m_value = <36>;
n_value = <15625>;
d_value = <15625>;
serial_gpio {
gpio1 {
gpio = <44>;

View file

@ -14,6 +14,8 @@
#ifndef IPQ6018_CLK_H
#define IPQ6018_CLK_H
#include <asm/arch-qca-common/uart.h>
/* I2C clocks configuration */
#ifdef CONFIG_IPQ6018_I2C
@ -31,4 +33,42 @@
void i2c_clock_config(void);
#endif
#define GCC_BLSP1_UART1_BCR 0x1802038
#define GCC_BLSP1_UART2_BCR 0x1803028
#define GCC_BLSP1_UART3_BCR 0x1804028
#define GCC_BLSP1_UART4_BCR 0x1805028
#define GCC_BLSP1_UART5_BCR 0x1806028
#define GCC_BLSP1_UART6_BCR 0x1807028
#define GCC_BLSP1_UART_BCR(id) ((id < 1) ? \
(GCC_BLSP1_UART1_BCR):\
(GCC_BLSP1_UART1_BCR + (0x1000 * id) - 0x10))
#define GCC_BLSP1_UART_APPS_CBCR(id) (GCC_BLSP1_UART_BCR(id) + 0x04)
#define GCC_BLSP1_UART_APPS_CMD_RCGR(id) (GCC_BLSP1_UART_BCR(id) + 0x0C)
#define GCC_BLSP1_UART_APPS_CFG_RCGR(id) (GCC_BLSP1_UART_BCR(id) + 0x10)
#define GCC_BLSP1_UART_APPS_M(id) (GCC_BLSP1_UART_BCR(id) + 0x14)
#define GCC_BLSP1_UART_APPS_N(id) (GCC_BLSP1_UART_BCR(id) + 0x18)
#define GCC_BLSP1_UART_APPS_D(id) (GCC_BLSP1_UART_BCR(id) + 0x1C)
#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 UART_RCGR_SRC_SEL 0x1
#define UART_RCGR_SRC_DIV 0x0
#define UART_RCGR_MODE 0x2
#define UART_CMD_RCGR_UPDATE 0x1
#define UART_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
int uart_clock_config(struct ipq_serial_platdata *plat);
#endif /*IPQ6018_CLK_H*/

View file

@ -88,6 +88,7 @@ struct ipq_serial_platdata {
int m_value;
int n_value;
int d_value;
int gpio_node;
};

View file

@ -14,6 +14,7 @@
#include <common.h>
#include <asm/io.h>
#include <asm/arch-ipq6018/clk.h>
#include <asm/errno.h>
#ifdef CONFIG_IPQ6018_I2C
void i2c_clock_config(void)
@ -34,3 +35,67 @@ void i2c_clock_config(void)
}
#endif
static void uart_configure_mux(u8 id)
{
unsigned long cfg_rcgr;
cfg_rcgr = readl(GCC_BLSP1_UART_APPS_CFG_RCGR(id));
/* 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 |= ((UART_RCGR_SRC_SEL << GCC_UART_CFG_RCGR_SRCSEL_SHIFT)
& GCC_UART_CFG_RCGR_SRCSEL_MASK);
cfg_rcgr |= ((UART_RCGR_SRC_DIV << GCC_UART_CFG_RCGR_SRCDIV_SHIFT)
& GCC_UART_CFG_RCGR_SRCDIV_MASK);
cfg_rcgr |= ((UART_RCGR_MODE << GCC_UART_CFG_RCGR_MODE_SHIFT)
& GCC_UART_CFG_RCGR_MODE_MASK);
writel(cfg_rcgr, GCC_BLSP1_UART_APPS_CFG_RCGR(id));
}
static int uart_trigger_update(u8 id)
{
unsigned long cmd_rcgr;
int timeout = 0;
cmd_rcgr = readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id));
cmd_rcgr |= UART_CMD_RCGR_UPDATE;
writel(cmd_rcgr, GCC_BLSP1_UART_APPS_CMD_RCGR(id));
while (readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id)) & UART_CMD_RCGR_UPDATE) {
if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) {
printf("Timeout waiting for UART clock update\n");
return -ETIMEDOUT;
}
udelay(1);
}
cmd_rcgr = readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id));
return 0;
}
int uart_clock_config(struct ipq_serial_platdata *plat)
{
unsigned long cbcr_val;
int ret;
uart_configure_mux(plat->port_id);
writel(plat->m_value, GCC_BLSP1_UART_APPS_M(plat->port_id));
writel(NOT_N_MINUS_M(plat->n_value, plat->m_value),
GCC_BLSP1_UART_APPS_N(plat->port_id));
writel(NOT_2D(plat->d_value), GCC_BLSP1_UART_APPS_D(plat->port_id));
ret = uart_trigger_update(plat->port_id);
if (ret)
return ret;
cbcr_val = readl(GCC_BLSP1_UART_APPS_CBCR(plat->port_id));
cbcr_val |= UART_CBCR_CLK_ENABLE;
writel(cbcr_val, GCC_BLSP1_UART_APPS_CBCR(plat->port_id));
return 0;
}

View file

@ -109,99 +109,25 @@ struct dumpinfo_t dumpinfo_s[] = {
int dump_entries_s = ARRAY_SIZE(dumpinfo_s);
u32 *tz_wonce = (u32 *)CONFIG_IPQ6018_TZ_WONCE_4_ADDR;
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();
}
#define BLSP1_UART0_BASE 0x078AF000
#define UART_PORT_ID(reg) ((reg - BLSP1_UART0_BASE) / 0x1000)
void qca_serial_init(struct ipq_serial_platdata *plat)
{
int node, uart2_node;
int ret;
writel(1, GCC_BLSP1_UART1_APPS_CBCR);
node = fdt_path_offset(gd->fdt_blob, "/serial@78B1000/serial_gpio");
if (node < 0) {
printf("Could not find serial_gpio node\n");
if (plat->gpio_node < 0) {
printf("serial_init: unable to find gpio node \n");
return;
}
if (plat->port_id == 1) {
uart2_node = fdt_path_offset(gd->fdt_blob, "uart2");
if (uart2_node < 0) {
printf("Could not find uart2 node\n");
return;
}
node = fdt_subnode_offset(gd->fdt_blob,
uart2_node, "serial_gpio");
uart2_clock_config(plat->m_value, plat->n_value, plat->d_value);
writel(1, GCC_BLSP1_UART2_APPS_CBCR);
}
qca_gpio_init(node);
qca_gpio_init(plat->gpio_node);
plat->port_id = UART_PORT_ID(plat->reg_base);
ret = uart_clock_config(plat);
if (ret)
printf("UART clock config failed %d \n", ret);
return;
}
int do_pmic_reset()

View file

@ -59,35 +59,9 @@
#define SDCC1_N_VAL 0xFC
#define SDCC1_D_VAL 0xFD
#define GCC_BLSP1_UART1_APPS_CBCR 0x0180203c
#define GCC_SDCC1_BCR 0x01842000
#define GCC_SDCC1_AHB_CBCR 0x0184201C
#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 0x1
#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
#define CLOCK_UPDATE_TIMEOUT_US 1000
#define KERNEL_AUTH_CMD 0x1E
#define SCM_CMD_SEC_AUTH 0x1F

View file

@ -453,6 +453,8 @@ static int ipq_serial_ofdata_to_platdata(struct udevice *dev)
plat->n_value = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "n_value", -1);
plat->d_value = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "d_value", -1);
plat->gpio_node = fdt_subnode_offset(gd->fdt_blob, dev->of_offset, "serial_gpio");
return 0;
}
@ -559,6 +561,7 @@ static void do_uart_start(void)
uart2.n_value = fdtdec_get_int(gd->fdt_blob, node, "n_value", -1);
uart2.d_value = fdtdec_get_int(gd->fdt_blob, node, "d_value", -1);
uart2.gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "serial_gpio");
ipq_serial_init(&uart2, uart2.reg_base);
}