blob: 882be02f9fa0f5d3d02963c43569dafbd59c596b [file] [log] [blame]
Vadim Bendebury476f7312014-04-08 18:45:46 -07001/*
2 * Copyright (c) 2012 - 2013 The Linux Foundation. All rights reserved.
3 */
4
5#include <common.h>
6#include <asm/arch-ipq806x/clock.h>
7#include <asm/arch-ipq806x/nss/clock.h>
8#include <asm/arch-ipq806x/iomap.h>
9#include <asm/io.h>
10
11/**
12 * uart_pll_vote_clk_enable - enables PLL8
13 */
14void uart_pll_vote_clk_enable(unsigned int clk_dummy)
15{
16 setbits_le32(BB_PLL_ENA_SC0_REG, BIT(8));
17
18 if (!clk_dummy)
19 while((readl(PLL_LOCK_DET_STATUS_REG) & BIT(8)) == 0);
20}
21
22/**
23 * uart_set_rate_mnd - configures divider M and D values
24 *
25 * Sets the M, D parameters of the divider to generate the GSBI UART
26 * apps clock.
27 */
28static void uart_set_rate_mnd(unsigned int gsbi_port, unsigned int m,
29 unsigned int n)
30{
31 /* Assert MND reset. */
32 setbits_le32(GSBIn_UART_APPS_NS_REG(gsbi_port), BIT(7));
33 /* Program M and D values. */
34 writel(MD16(m, n), GSBIn_UART_APPS_MD_REG(gsbi_port));
35 /* Deassert MND reset. */
36 clrbits_le32(GSBIn_UART_APPS_NS_REG(gsbi_port), BIT(7));
37}
38
39/**
40 * uart_branch_clk_enable_reg - enables branch clock
41 *
42 * Enables branch clock for GSBI UART port.
43 */
44static void uart_branch_clk_enable_reg(unsigned int gsbi_port)
45{
46 setbits_le32(GSBIn_UART_APPS_NS_REG(gsbi_port), BIT(9));
47}
48
49/**
50 * uart_local_clock_enable - configures N value and enables root clocks
51 *
52 * Sets the N parameter of the divider and enables root clock and
53 * branch clocks for GSBI UART port.
54 */
55static void uart_local_clock_enable(unsigned int gsbi_port, unsigned int n,
56 unsigned int m)
57{
58 unsigned int reg_val, uart_ns_val;
59 void *const reg = (void *)GSBIn_UART_APPS_NS_REG(gsbi_port);
60
61 /*
62 * Program the NS register, if applicable. NS registers are not
63 * set in the set_rate path because power can be saved by deferring
64 * the selection of a clocked source until the clock is enabled.
65 */
66 reg_val = readl(reg); // REG(0x29D4+(0x20*((n)-1)))
67 reg_val &= ~(Uart_clk_ns_mask);
68 uart_ns_val = NS(BIT_POS_31,BIT_POS_16,n,m, 5, 4, 3, 1, 2, 0,3);
69 reg_val |= (uart_ns_val & Uart_clk_ns_mask);
70 writel(reg_val,reg);
71
72 /* enable MNCNTR_EN */
73 reg_val = readl(reg);
74 reg_val |= BIT(8);
75 writel(reg_val, reg);
76
77 /* set source to PLL8 running @384MHz */
78 reg_val = readl(reg);
79 reg_val |= 0x3;
80 writel(reg_val, reg);
81
82 /* Enable root. */
83 reg_val |= Uart_en_mask;
84 writel(reg_val, reg);
85 uart_branch_clk_enable_reg(gsbi_port);
86}
87
88/**
89 * uart_set_gsbi_clk - enables HCLK for UART GSBI port
90 */
91static void uart_set_gsbi_clk(unsigned int gsbi_port)
92{
93 setbits_le32(GSBIn_HCLK_CTL_REG(gsbi_port), BIT(4));
94}
95
96/**
97 * uart_clock_config - configures UART clocks
98 *
99 * Configures GSBI UART dividers, enable root and branch clocks.
100 */
101void uart_clock_config(unsigned int gsbi_port, unsigned int m,
102 unsigned int n, unsigned int d, unsigned int clk_dummy)
103{
104 uart_set_rate_mnd(gsbi_port, m, d);
105 uart_pll_vote_clk_enable(clk_dummy);
106 uart_local_clock_enable(gsbi_port, n, m);
107 uart_set_gsbi_clk(gsbi_port);
108}
109
110/**
111 * nand_clock_config - configure NAND controller clocks
112 *
113 * Enable clocks to EBI2. Must be invoked before touching EBI2
114 * registers.
115 */
116void nand_clock_config(void)
117{
118 writel(CLK_BRANCH_ENA(1) | ALWAYS_ON_CLK_BRANCH_ENA(1),
119 EBI2_CLK_CTL_REG);
120
121 /* Wait for clock to stabilize. */
122 udelay(10);
123}