Fixed MTP to work with TWRP

This commit is contained in:
awab228 2018-06-19 23:16:04 +02:00
commit f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions

2
drivers/clk/pxa/Makefile Normal file
View file

@ -0,0 +1,2 @@
obj-y += clk-pxa.o
obj-$(CONFIG_PXA27x) += clk-pxa27x.o

97
drivers/clk/pxa/clk-pxa.c Normal file
View file

@ -0,0 +1,97 @@
/*
* Marvell PXA family clocks
*
* Copyright (C) 2014 Robert Jarzmik
*
* Common clock code for PXA clocks ("CKEN" type clocks + DT)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/of.h>
#include <dt-bindings/clock/pxa-clock.h>
#include "clk-pxa.h"
DEFINE_SPINLOCK(lock);
static struct clk *pxa_clocks[CLK_MAX];
static struct clk_onecell_data onecell_data = {
.clks = pxa_clocks,
.clk_num = CLK_MAX,
};
#define to_pxa_clk(_hw) container_of(_hw, struct pxa_clk_cken, hw)
static unsigned long cken_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct pxa_clk_cken *pclk = to_pxa_clk(hw);
struct clk_fixed_factor *fix;
if (!pclk->is_in_low_power || pclk->is_in_low_power())
fix = &pclk->lp;
else
fix = &pclk->hp;
fix->hw.clk = hw->clk;
return clk_fixed_factor_ops.recalc_rate(&fix->hw, parent_rate);
}
static struct clk_ops cken_rate_ops = {
.recalc_rate = cken_recalc_rate,
};
static u8 cken_get_parent(struct clk_hw *hw)
{
struct pxa_clk_cken *pclk = to_pxa_clk(hw);
if (!pclk->is_in_low_power)
return 0;
return pclk->is_in_low_power() ? 0 : 1;
}
static struct clk_ops cken_mux_ops = {
.get_parent = cken_get_parent,
.set_parent = dummy_clk_set_parent,
};
void __init clkdev_pxa_register(int ckid, const char *con_id,
const char *dev_id, struct clk *clk)
{
if (!IS_ERR(clk) && (ckid != CLK_NONE))
pxa_clocks[ckid] = clk;
if (!IS_ERR(clk))
clk_register_clkdev(clk, con_id, dev_id);
}
int __init clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks)
{
int i;
struct pxa_clk_cken *pclk;
struct clk *clk;
for (i = 0; i < nb_clks; i++) {
pclk = clks + i;
pclk->gate.lock = &lock;
clk = clk_register_composite(NULL, pclk->name,
pclk->parent_names, 2,
&pclk->hw, &cken_mux_ops,
&pclk->hw, &cken_rate_ops,
&pclk->gate.hw, &clk_gate_ops,
pclk->flags);
clkdev_pxa_register(pclk->ckid, pclk->con_id, pclk->dev_id,
clk);
}
return 0;
}
static void __init pxa_dt_clocks_init(struct device_node *np)
{
of_clk_add_provider(np, of_clk_src_onecell_get, &onecell_data);
}
CLK_OF_DECLARE(pxa_clks, "marvell,pxa-clocks", pxa_dt_clocks_init);

107
drivers/clk/pxa/clk-pxa.h Normal file
View file

@ -0,0 +1,107 @@
/*
* Marvell PXA family clocks
*
* Copyright (C) 2014 Robert Jarzmik
*
* Common clock code for PXA clocks ("CKEN" type clocks + DT)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
*/
#ifndef _CLK_PXA_
#define _CLK_PXA_
#define PARENTS(name) \
static const char *name ## _parents[] __initconst
#define MUX_RO_RATE_RO_OPS(name, clk_name) \
static struct clk_hw name ## _mux_hw; \
static struct clk_hw name ## _rate_hw; \
static struct clk_ops name ## _mux_ops = { \
.get_parent = name ## _get_parent, \
.set_parent = dummy_clk_set_parent, \
}; \
static struct clk_ops name ## _rate_ops = { \
.recalc_rate = name ## _get_rate, \
}; \
static struct clk *clk_register_ ## name(void) \
{ \
return clk_register_composite(NULL, clk_name, \
name ## _parents, \
ARRAY_SIZE(name ## _parents), \
&name ## _mux_hw, &name ## _mux_ops, \
&name ## _rate_hw, &name ## _rate_ops, \
NULL, NULL, CLK_GET_RATE_NOCACHE); \
}
#define RATE_RO_OPS(name, clk_name) \
static struct clk_hw name ## _rate_hw; \
static struct clk_ops name ## _rate_ops = { \
.recalc_rate = name ## _get_rate, \
}; \
static struct clk *clk_register_ ## name(void) \
{ \
return clk_register_composite(NULL, clk_name, \
name ## _parents, \
ARRAY_SIZE(name ## _parents), \
NULL, NULL, \
&name ## _rate_hw, &name ## _rate_ops, \
NULL, NULL, CLK_GET_RATE_NOCACHE); \
}
/*
* CKEN clock type
* This clock takes it source from 2 possible parents :
* - a low power parent
* - a normal parent
*
* +------------+ +-----------+
* | Low Power | --- | x mult_lp |
* | Clock | | / div_lp |\
* +------------+ +-----------+ \+-----+ +-----------+
* | Mux |---| CKEN gate |
* +------------+ +-----------+ /+-----+ +-----------+
* | High Power | | x mult_hp |/
* | Clock | --- | / div_hp |
* +------------+ +-----------+
*/
struct pxa_clk_cken {
struct clk_hw hw;
int ckid;
const char *name;
const char *dev_id;
const char *con_id;
const char **parent_names;
struct clk_fixed_factor lp;
struct clk_fixed_factor hp;
struct clk_gate gate;
bool (*is_in_low_power)(void);
const unsigned long flags;
};
#define PXA_CKEN(_dev_id, _con_id, _name, parents, _mult_lp, _div_lp, \
_mult_hp, _div_hp, is_lp, _cken_reg, _cken_bit, flag) \
{ .ckid = CLK_ ## _name, .name = #_name, \
.dev_id = _dev_id, .con_id = _con_id, .parent_names = parents,\
.lp = { .mult = _mult_lp, .div = _div_lp }, \
.hp = { .mult = _mult_hp, .div = _div_hp }, \
.is_in_low_power = is_lp, \
.gate = { .reg = (void __iomem *)_cken_reg, .bit_idx = _cken_bit }, \
.flags = flag, \
}
#define PXA_CKEN_1RATE(dev_id, con_id, name, parents, cken_reg, \
cken_bit, flag) \
PXA_CKEN(dev_id, con_id, name, parents, 1, 1, 1, 1, \
NULL, cken_reg, cken_bit, flag)
static int dummy_clk_set_parent(struct clk_hw *hw, u8 index)
{
return 0;
}
extern void clkdev_pxa_register(int ckid, const char *con_id,
const char *dev_id, struct clk *clk);
extern int clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks);
#endif

View file

@ -0,0 +1,370 @@
/*
* Marvell PXA27x family clocks
*
* Copyright (C) 2014 Robert Jarzmik
*
* Heavily inspired from former arch/arm/mach-pxa/clock.c.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
*/
#include <linux/clk-provider.h>
#include <mach/pxa2xx-regs.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/of.h>
#include <dt-bindings/clock/pxa-clock.h>
#include "clk-pxa.h"
#define KHz 1000
#define MHz (1000 * 1000)
enum {
PXA_CORE_13Mhz = 0,
PXA_CORE_RUN,
PXA_CORE_TURBO,
};
enum {
PXA_BUS_13Mhz = 0,
PXA_BUS_RUN,
};
enum {
PXA_LCD_13Mhz = 0,
PXA_LCD_RUN,
};
enum {
PXA_MEM_13Mhz = 0,
PXA_MEM_SYSTEM_BUS,
PXA_MEM_RUN,
};
static const char * const get_freq_khz[] = {
"core", "run", "cpll", "memory",
"system_bus"
};
/*
* Get the clock frequency as reflected by CCSR and the turbo flag.
* We assume these values have been applied via a fcs.
* If info is not 0 we also display the current settings.
*/
unsigned int pxa27x_get_clk_frequency_khz(int info)
{
struct clk *clk;
unsigned long clks[5];
int i;
for (i = 0; i < 5; i++) {
clk = clk_get(NULL, get_freq_khz[i]);
if (IS_ERR(clk)) {
clks[i] = 0;
} else {
clks[i] = clk_get_rate(clk);
clk_put(clk);
}
}
if (info) {
pr_info("Run Mode clock: %ld.%02ldMHz\n",
clks[1] / 1000000, (clks[1] % 1000000) / 10000);
pr_info("Turbo Mode clock: %ld.%02ldMHz\n",
clks[2] / 1000000, (clks[2] % 1000000) / 10000);
pr_info("Memory clock: %ld.%02ldMHz\n",
clks[3] / 1000000, (clks[3] % 1000000) / 10000);
pr_info("System bus clock: %ld.%02ldMHz\n",
clks[4] / 1000000, (clks[4] % 1000000) / 10000);
}
return (unsigned int)clks[0];
}
bool pxa27x_is_ppll_disabled(void)
{
unsigned long ccsr = CCSR;
return ccsr & (1 << CCCR_PPDIS_BIT);
}
#define PXA27X_CKEN(dev_id, con_id, parents, mult_hp, div_hp, \
bit, is_lp, flags) \
PXA_CKEN(dev_id, con_id, bit, parents, 1, 1, mult_hp, div_hp, \
is_lp, &CKEN, CKEN_ ## bit, flags)
#define PXA27X_PBUS_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \
PXA27X_CKEN(dev_id, con_id, pxa27x_pbus_parents, mult_hp, \
div_hp, bit, pxa27x_is_ppll_disabled, 0)
PARENTS(pxa27x_pbus) = { "osc_13mhz", "ppll_312mhz" };
PARENTS(pxa27x_sbus) = { "system_bus", "system_bus" };
PARENTS(pxa27x_32Mhz_bus) = { "osc_32_768khz", "osc_32_768khz" };
PARENTS(pxa27x_lcd_bus) = { "lcd_base", "lcd_base" };
PARENTS(pxa27x_membus) = { "lcd_base", "lcd_base" };
#define PXA27X_CKEN_1RATE(dev_id, con_id, bit, parents, delay) \
PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \
&CKEN, CKEN_ ## bit, 0)
#define PXA27X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay) \
PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \
&CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED)
static struct pxa_clk_cken pxa27x_clocks[] = {
PXA27X_PBUS_CKEN("pxa2xx-uart.0", NULL, FFUART, 2, 42, 1),
PXA27X_PBUS_CKEN("pxa2xx-uart.1", NULL, BTUART, 2, 42, 1),
PXA27X_PBUS_CKEN("pxa2xx-uart.2", NULL, STUART, 2, 42, 1),
PXA27X_PBUS_CKEN("pxa2xx-i2s", NULL, I2S, 2, 51, 0),
PXA27X_PBUS_CKEN("pxa2xx-i2c.0", NULL, I2C, 2, 19, 0),
PXA27X_PBUS_CKEN("pxa27x-udc", NULL, USB, 2, 13, 5),
PXA27X_PBUS_CKEN("pxa2xx-mci.0", NULL, MMC, 2, 32, 0),
PXA27X_PBUS_CKEN("pxa2xx-ir", "FICPCLK", FICP, 2, 13, 0),
PXA27X_PBUS_CKEN("pxa27x-ohci", NULL, USBHOST, 2, 13, 0),
PXA27X_PBUS_CKEN("pxa2xx-i2c.1", NULL, PWRI2C, 1, 24, 0),
PXA27X_PBUS_CKEN("pxa27x-ssp.0", NULL, SSP1, 1, 24, 0),
PXA27X_PBUS_CKEN("pxa27x-ssp.1", NULL, SSP2, 1, 24, 0),
PXA27X_PBUS_CKEN("pxa27x-ssp.2", NULL, SSP3, 1, 24, 0),
PXA27X_PBUS_CKEN("pxa27x-pwm.0", NULL, PWM0, 1, 24, 0),
PXA27X_PBUS_CKEN("pxa27x-pwm.1", NULL, PWM1, 1, 24, 0),
PXA27X_PBUS_CKEN(NULL, "MSLCLK", MSL, 2, 13, 0),
PXA27X_PBUS_CKEN(NULL, "USIMCLK", USIM, 2, 13, 0),
PXA27X_PBUS_CKEN(NULL, "MSTKCLK", MEMSTK, 2, 32, 0),
PXA27X_PBUS_CKEN(NULL, "AC97CLK", AC97, 1, 1, 0),
PXA27X_PBUS_CKEN(NULL, "AC97CONFCLK", AC97CONF, 1, 1, 0),
PXA27X_PBUS_CKEN(NULL, "OSTIMER0", OSTIMER, 1, 96, 0),
PXA27X_CKEN_1RATE("pxa27x-keypad", NULL, KEYPAD,
pxa27x_32Mhz_bus_parents, 0),
PXA27X_CKEN_1RATE(NULL, "IMCLK", IM, pxa27x_sbus_parents, 0),
PXA27X_CKEN_1RATE("pxa2xx-fb", NULL, LCD, pxa27x_lcd_bus_parents, 0),
PXA27X_CKEN_1RATE("pxa27x-camera.0", NULL, CAMERA,
pxa27x_lcd_bus_parents, 0),
PXA27X_CKEN_1RATE_AO("pxa2xx-pcmcia", NULL, MEMC,
pxa27x_membus_parents, 0),
};
static unsigned long clk_pxa27x_cpll_get_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
unsigned long clkcfg;
unsigned int t, ht;
unsigned int l, L, n2, N;
unsigned long ccsr = CCSR;
asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
t = clkcfg & (1 << 0);
ht = clkcfg & (1 << 2);
l = ccsr & CCSR_L_MASK;
n2 = (ccsr & CCSR_N2_MASK) >> CCSR_N2_SHIFT;
L = l * parent_rate;
N = (L * n2) / 2;
return t ? N : L;
}
PARENTS(clk_pxa27x_cpll) = { "osc_13mhz" };
RATE_RO_OPS(clk_pxa27x_cpll, "cpll");
static unsigned long clk_pxa27x_lcd_base_get_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
unsigned int l, osc_forced;
unsigned long ccsr = CCSR;
unsigned long cccr = CCCR;
l = ccsr & CCSR_L_MASK;
osc_forced = ccsr & (1 << CCCR_CPDIS_BIT);
if (osc_forced) {
if (cccr & (1 << CCCR_LCD_26_BIT))
return parent_rate * 2;
else
return parent_rate;
}
if (l <= 7)
return parent_rate;
if (l <= 16)
return parent_rate / 2;
return parent_rate / 4;
}
static u8 clk_pxa27x_lcd_base_get_parent(struct clk_hw *hw)
{
unsigned int osc_forced;
unsigned long ccsr = CCSR;
osc_forced = ccsr & (1 << CCCR_CPDIS_BIT);
if (osc_forced)
return PXA_LCD_13Mhz;
else
return PXA_LCD_RUN;
}
PARENTS(clk_pxa27x_lcd_base) = { "osc_13mhz", "run" };
MUX_RO_RATE_RO_OPS(clk_pxa27x_lcd_base, "lcd_base");
static void __init pxa27x_register_plls(void)
{
clk_register_fixed_rate(NULL, "osc_13mhz", NULL,
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
13 * MHz);
clk_register_fixed_rate(NULL, "osc_32_768khz", NULL,
CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
32768 * KHz);
clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0);
clk_register_fixed_factor(NULL, "ppll_312mhz", "osc_13mhz", 0, 24, 1);
}
static unsigned long clk_pxa27x_core_get_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
unsigned long clkcfg;
unsigned int t, ht, b, osc_forced;
unsigned long ccsr = CCSR;
osc_forced = ccsr & (1 << CCCR_CPDIS_BIT);
asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
t = clkcfg & (1 << 0);
ht = clkcfg & (1 << 2);
b = clkcfg & (1 << 3);
if (osc_forced)
return parent_rate;
if (ht)
return parent_rate / 2;
else
return parent_rate;
}
static u8 clk_pxa27x_core_get_parent(struct clk_hw *hw)
{
unsigned long clkcfg;
unsigned int t, ht, b, osc_forced;
unsigned long ccsr = CCSR;
osc_forced = ccsr & (1 << CCCR_CPDIS_BIT);
if (osc_forced)
return PXA_CORE_13Mhz;
asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
t = clkcfg & (1 << 0);
ht = clkcfg & (1 << 2);
b = clkcfg & (1 << 3);
if (ht || t)
return PXA_CORE_TURBO;
return PXA_CORE_RUN;
}
PARENTS(clk_pxa27x_core) = { "osc_13mhz", "run", "cpll" };
MUX_RO_RATE_RO_OPS(clk_pxa27x_core, "core");
static unsigned long clk_pxa27x_run_get_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
unsigned long ccsr = CCSR;
unsigned int n2 = (ccsr & CCSR_N2_MASK) >> CCSR_N2_SHIFT;
return (parent_rate / n2) * 2;
}
PARENTS(clk_pxa27x_run) = { "cpll" };
RATE_RO_OPS(clk_pxa27x_run, "run");
static void __init pxa27x_register_core(void)
{
clk_register_clk_pxa27x_cpll();
clk_register_clk_pxa27x_run();
clkdev_pxa_register(CLK_CORE, "core", NULL,
clk_register_clk_pxa27x_core());
}
static unsigned long clk_pxa27x_system_bus_get_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
unsigned long clkcfg;
unsigned int b, osc_forced;
unsigned long ccsr = CCSR;
osc_forced = ccsr & (1 << CCCR_CPDIS_BIT);
asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
b = clkcfg & (1 << 3);
if (osc_forced)
return parent_rate;
if (b)
return parent_rate / 2;
else
return parent_rate;
}
static u8 clk_pxa27x_system_bus_get_parent(struct clk_hw *hw)
{
unsigned int osc_forced;
unsigned long ccsr = CCSR;
osc_forced = ccsr & (1 << CCCR_CPDIS_BIT);
if (osc_forced)
return PXA_BUS_13Mhz;
else
return PXA_BUS_RUN;
}
PARENTS(clk_pxa27x_system_bus) = { "osc_13mhz", "run" };
MUX_RO_RATE_RO_OPS(clk_pxa27x_system_bus, "system_bus");
static unsigned long clk_pxa27x_memory_get_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
unsigned int a, l, osc_forced;
unsigned long cccr = CCCR;
unsigned long ccsr = CCSR;
osc_forced = ccsr & (1 << CCCR_CPDIS_BIT);
a = cccr & (1 << CCCR_A_BIT);
l = ccsr & CCSR_L_MASK;
if (osc_forced || a)
return parent_rate;
if (l <= 10)
return parent_rate;
if (l <= 20)
return parent_rate / 2;
return parent_rate / 4;
}
static u8 clk_pxa27x_memory_get_parent(struct clk_hw *hw)
{
unsigned int osc_forced, a;
unsigned long cccr = CCCR;
unsigned long ccsr = CCSR;
osc_forced = ccsr & (1 << CCCR_CPDIS_BIT);
a = cccr & (1 << CCCR_A_BIT);
if (osc_forced)
return PXA_MEM_13Mhz;
if (a)
return PXA_MEM_SYSTEM_BUS;
else
return PXA_MEM_RUN;
}
PARENTS(clk_pxa27x_memory) = { "osc_13mhz", "system_bus", "run" };
MUX_RO_RATE_RO_OPS(clk_pxa27x_memory, "memory");
static void __init pxa27x_base_clocks_init(void)
{
pxa27x_register_plls();
pxa27x_register_core();
clk_register_clk_pxa27x_system_bus();
clk_register_clk_pxa27x_memory();
clk_register_clk_pxa27x_lcd_base();
}
static int __init pxa27x_clocks_init(void)
{
pxa27x_base_clocks_init();
return clk_pxa_cken_init(pxa27x_clocks, ARRAY_SIZE(pxa27x_clocks));
}
postcore_initcall(pxa27x_clocks_init);