android_kernel_samsung_on5x.../drivers/bts/cal_bts7570.c
2018-06-19 23:16:04 +02:00

354 lines
12 KiB
C

/* arch/arm/mach-exynos/cal_bts.c
*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* EXYNOS - BTS CAL code.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include "cal_bts7570.h"
#define LOG(x, ...) \
({ \
seq_printf(buf, x, ##__VA_ARGS__); \
})
/* for BTS V2.1 Register */
#define BTS_RCON 0x100
#define BTS_RMODE 0x104
#define BTS_WCON 0x180
#define BTS_WMODE 0x184
#define BTS_PRIORITY 0x200
#define BTS_TOKENMAX 0x204
#define BTS_BWUPBOUND 0x20C
#define BTS_BWLOBOUND 0x210
#define BTS_INITTKN 0x214
#define BTS_RSTCLK 0x218
#define BTS_RSTTKN 0x21C
#define BTS_DEMWIN 0x220
#define BTS_DEMTKN 0x224
#define BTS_DEFWIN 0x228
#define BTS_DEFTKN 0x22C
#define BTS_PRMWIN 0x230
#define BTS_PRMTKN 0x234
#define BTS_MOUPBOUND 0x240
#define BTS_MOLOBOUND 0x244
#define BTS_FLEXIBLE 0x280
#define BTS_POLARITY 0x284
#define BTS_FBMGRP0ADRS 0x290
#define BTS_FBMGRP0ADRE 0x294
#define BTS_FBMGRP1ADRS 0x298
#define BTS_FBMGRP1ADRE 0x29C
#define BTS_FBMGRP2ADRS 0x2A0
#define BTS_FBMGRP2ADRE 0x2A4
#define BTS_FBMGRP3ADRS 0x2A8
#define BTS_FBMGRP3ADRE 0x2AC
#define BTS_FBMGRP4ADRS 0x2B0
#define BTS_FBMGRP4ADRE 0x2B4
#define BTS_EMERGENTID 0x2C0
#define BTS_RISINGTH 0x2C4
#define BTS_FALLINGTH 0x2C8
#define BTS_FALLINGMO 0x2CC
#define BTS_MOCOUNTER 0x2F0
#define BTS_STATUS 0x2F4
#define BTS_BWMONLOW 0x2F8
#define BTS_BWMONUP 0x2FC
#define WOFFSET 0x100
#define TREX_CON 0x000
#define TREX_TIMEOUT 0x010
#define TREX_BLOCK_IDMASK 0x018
#define TREX_BLOCK_IDVALUE 0x01C
#define TREX_RCON 0x020
#define TREX_WCON 0x040
#define TREX_RBLOCK_UPPER 0x024
#define TREX_WBLOCK_UPPER 0x044
#define TREX_RBLOCK_UPPER_NORMAL 0x028
#define TREX_WBLOCK_UPPER_NORMAL 0x048
#define TREX_RBLOCK_UPPER_FULL 0x02C
#define TREX_WBLOCK_UPPER_FULL 0x04C
#define TREX_RBLOCK_UPPER_BUSY 0x030
#define TREX_WBLOCK_UPPER_BUSY 0x050
#define TREX_RBLOCK_UPPER_MAX 0x034
#define TREX_WBLOCK_UPPER_MAX 0x054
#define SYSREG_CP_QOS 0x0078
#define SYSREG_GNSS_QOS 0x00B8
#define SYSREG_WIFI_QOS 0x0178
#define SYSREG_APM_QOS 0x000C
#define SYSREG_DISPAUD_QOS 0x0600
#define SYSREG_DISPAUD_SEL 0x0604
#define SYSREG_FSYS_VAL0 0x0600
#define SYSREG_FSYS_VAL1 0x0604
#define SYSREG_FSYS_VAL2 0x0608
#define SYSREG_ISP_QOS 0x0500
#define SYSREG_CPU_QOS 0x0610
#define SYSREG_MFCMSCL_QOS 0x0600
void bts_setqos(addr_u32 base, unsigned int priority) /* QOS : [RRRRWWWW] */
{
__raw_writel(0x0, base + BTS_RCON);
__raw_writel(0x0, base + BTS_RCON);
__raw_writel(0x0, base + BTS_WCON);
__raw_writel(0x0, base + BTS_WCON);
__raw_writel(((priority >> 16) & 0xFFFF), base + BTS_PRIORITY);
__raw_writel(0xFFDF, base + BTS_TOKENMAX);
__raw_writel(0x18, base + BTS_BWUPBOUND);
__raw_writel(0x1, base + BTS_BWLOBOUND);
__raw_writel(0x8, base + BTS_INITTKN);
__raw_writel((priority & 0xFFFF), base + BTS_PRIORITY + WOFFSET);
__raw_writel(0xFFDF, base + BTS_TOKENMAX + WOFFSET);
__raw_writel(0x18, base + BTS_BWUPBOUND + WOFFSET);
__raw_writel(0x1, base + BTS_BWLOBOUND + WOFFSET);
__raw_writel(0x8, base + BTS_INITTKN + WOFFSET);
__raw_writel(0x1, base + BTS_RCON);
__raw_writel(0x1, base + BTS_WCON);
}
void bts_setqos_bw(addr_u32 base, unsigned int priority,
unsigned int window, unsigned int token) /* QOS : [RRRRWWWW] */
{
__raw_writel(0x0, base + BTS_RCON);
__raw_writel(0x0, base + BTS_RCON);
__raw_writel(0x0, base + BTS_WCON);
__raw_writel(0x0, base + BTS_WCON);
__raw_writel(((priority >> 16) & 0xFFFF), base + BTS_PRIORITY);
__raw_writel(0xFFDF, base + BTS_TOKENMAX);
__raw_writel(0x18, base + BTS_BWUPBOUND);
__raw_writel(0x1, base + BTS_BWLOBOUND);
__raw_writel(0x8, base + BTS_INITTKN);
__raw_writel(window, base + BTS_DEMWIN);
__raw_writel(token, base + BTS_DEMTKN);
__raw_writel(window, base + BTS_DEFWIN);
__raw_writel(token, base + BTS_DEFTKN);
__raw_writel(window, base + BTS_PRMWIN);
__raw_writel(token, base + BTS_PRMTKN);
__raw_writel(0x0, base + BTS_FLEXIBLE);
__raw_writel((priority & 0xFFFF), base + BTS_PRIORITY + WOFFSET);
__raw_writel(0xFFDF, base + BTS_TOKENMAX + WOFFSET);
__raw_writel(0x18, base + BTS_BWUPBOUND + WOFFSET);
__raw_writel(0x1, base + BTS_BWLOBOUND + WOFFSET);
__raw_writel(0x8, base + BTS_INITTKN + WOFFSET);
__raw_writel(window, base + BTS_DEMWIN + WOFFSET);
__raw_writel(token, base + BTS_DEMTKN + WOFFSET);
__raw_writel(window, base + BTS_DEFWIN + WOFFSET);
__raw_writel(token, base + BTS_DEFTKN + WOFFSET);
__raw_writel(window, base + BTS_PRMWIN + WOFFSET);
__raw_writel(token, base + BTS_PRMTKN + WOFFSET);
__raw_writel(0x0, base + BTS_FLEXIBLE + WOFFSET);
__raw_writel(0x1, base + BTS_RMODE);
__raw_writel(0x1, base + BTS_WMODE);
__raw_writel(0x3, base + BTS_RCON);
__raw_writel(0x3, base + BTS_WCON);
}
void bts_setqos_mo(addr_u32 base, unsigned int priority, unsigned int mo) /* QOS : [RRRRWWWW] */
{
__raw_writel(0x0, base + BTS_RCON);
__raw_writel(0x0, base + BTS_RCON);
__raw_writel(0x0, base + BTS_WCON);
__raw_writel(0x0, base + BTS_WCON);
__raw_writel(((priority >> 16) & 0xFFFF), base + BTS_PRIORITY);
__raw_writel(0x7F - mo, base + BTS_MOUPBOUND);
__raw_writel(mo, base + BTS_MOLOBOUND);
__raw_writel(0x0, base + BTS_FLEXIBLE);
__raw_writel((priority & 0xFFFF), base + BTS_PRIORITY + WOFFSET);
__raw_writel(0x7F - mo, base + BTS_MOUPBOUND + WOFFSET);
__raw_writel(mo, base + BTS_MOLOBOUND + WOFFSET);
__raw_writel(0x0, base + BTS_FLEXIBLE + WOFFSET);
__raw_writel(0x2, base + BTS_RMODE);
__raw_writel(0x2, base + BTS_WMODE);
__raw_writel(0x3, base + BTS_RCON);
__raw_writel(0x3, base + BTS_WCON);
}
void bts_showqos(addr_u32 base, struct seq_file *buf)
{
LOG("conreg 0x%Xr 0x%Xw qos 0x%Xr 0x%Xw\n",
__raw_readl(base + BTS_RCON),
__raw_readl(base + BTS_WCON),
__raw_readl(base + BTS_PRIORITY),
__raw_readl(base + BTS_PRIORITY + WOFFSET));
}
void bts_disable(addr_u32 base)
{
/* reset to default */
__raw_writel(0x0, base + BTS_RCON);
__raw_writel(0x0, base + BTS_RCON);
__raw_writel(0x0, base + BTS_WCON);
__raw_writel(0x0, base + BTS_WCON);
__raw_writel(0x1, base + BTS_RMODE);
__raw_writel(0x1, base + BTS_WMODE);
__raw_writel(0xA942, base + BTS_PRIORITY);
__raw_writel(0x0, base + BTS_TOKENMAX);
__raw_writel(0x3FFF, base + BTS_BWUPBOUND);
__raw_writel(0x3FFF, base + BTS_BWLOBOUND);
__raw_writel(0x7FFF, base + BTS_INITTKN);
__raw_writel(0x7FFF, base + BTS_DEMWIN);
__raw_writel(0x1FFF, base + BTS_DEMTKN);
__raw_writel(0x7FFF, base + BTS_DEFWIN);
__raw_writel(0x1FFF, base + BTS_DEFTKN);
__raw_writel(0x7FFF, base + BTS_PRMWIN);
__raw_writel(0x1FFF, base + BTS_PRMTKN);
__raw_writel(0x1F, base + BTS_MOUPBOUND);
__raw_writel(0x1F, base + BTS_MOLOBOUND);
__raw_writel(0x0, base + BTS_FLEXIBLE);
__raw_writel(0xA942, base + BTS_PRIORITY + WOFFSET);
__raw_writel(0x0, base + BTS_TOKENMAX + WOFFSET);
__raw_writel(0x3FFF, base + BTS_BWUPBOUND + WOFFSET);
__raw_writel(0x3FFF, base + BTS_BWLOBOUND + WOFFSET);
__raw_writel(0x7FFF, base + BTS_INITTKN + WOFFSET);
__raw_writel(0x7FFF, base + BTS_DEMWIN + WOFFSET);
__raw_writel(0x1FFF, base + BTS_DEMTKN + WOFFSET);
__raw_writel(0x7FFF, base + BTS_DEFWIN + WOFFSET);
__raw_writel(0x1FFF, base + BTS_DEFTKN + WOFFSET);
__raw_writel(0x7FFF, base + BTS_PRMWIN + WOFFSET);
__raw_writel(0x1FFF, base + BTS_PRMTKN + WOFFSET);
__raw_writel(0x1F, base + BTS_MOUPBOUND + WOFFSET);
__raw_writel(0x1F, base + BTS_MOLOBOUND + WOFFSET);
__raw_writel(0x0, base + BTS_FLEXIBLE + WOFFSET);
}
void trex_setqos(addr_u32 base, unsigned int priority)
{
unsigned int tmp_reg = 0;
/* override QoS value */
tmp_reg |= 1 << 8;
tmp_reg |= (priority & 0xf) << 12;
__raw_writel(tmp_reg, base + TREX_RCON);
__raw_writel(tmp_reg, base + TREX_WCON);
__raw_writel(0x1, base + TREX_CON);
}
void trex_setqos_mo(addr_u32 base, unsigned int priority, unsigned int mo)
{
unsigned int tmp_reg = 0;
if (mo > 0xffff)
mo = 0xffff;
__raw_writel(mo, base + TREX_RBLOCK_UPPER);
__raw_writel(mo, base + TREX_WBLOCK_UPPER);
/* override QoS value */
tmp_reg |= 1 << 8;
tmp_reg |= (priority & 0xf) << 12;
/* enable Blocking logic */
tmp_reg |= 1 << 0;
__raw_writel(tmp_reg, base + TREX_RCON);
__raw_writel(tmp_reg, base + TREX_WCON);
__raw_writel(0x1, base + TREX_CON);
}
void trex_showqos(addr_u32 base, struct seq_file *buf)
{
LOG("conreg 0x%X qos(%d,%d) 0x%Xr 0x%Xw mo(%d,%d) %dr %dw\n",
__raw_readl(base + TREX_CON),
(__raw_readl(base + TREX_RCON) >> 8) & 0x1,
(__raw_readl(base + TREX_WCON) >> 8) & 0x1,
(__raw_readl(base + TREX_RCON) >> 12) & 0xf,
(__raw_readl(base + TREX_WCON) >> 12) & 0xf,
__raw_readl(base + TREX_RCON) & 0x1,
__raw_readl(base + TREX_WCON) & 0x1,
__raw_readl(base + TREX_RBLOCK_UPPER),
__raw_readl(base + TREX_WBLOCK_UPPER));
}
void trex_disable(addr_u32 base)
{
__raw_writel(0x0, base + TREX_CON);
__raw_writel(0x4000, base + TREX_RCON);
__raw_writel(0x4000, base + TREX_WCON);
}
void sysreg_setqos(QOS_SYSREG_IP qos_id, addr_u32 base, unsigned int priority)
{
unsigned int tmp_reg;
switch (qos_id) {
case BTS_SYSREG_CPGNSS:
tmp_reg = __raw_readl(base + SYSREG_CP_QOS);
tmp_reg |= 1;
__raw_writel(tmp_reg, base + SYSREG_CP_QOS);
tmp_reg = __raw_readl(base + SYSREG_GNSS_QOS);
tmp_reg &= ~1;
tmp_reg &= ~((0xf << 12) | (0xf << 16));
tmp_reg |= (priority & 0xf) << 8;
tmp_reg |= (priority & 0xf) << 16;
__raw_writel(tmp_reg, base + SYSREG_GNSS_QOS);
break;
case BTS_SYSREG_APM:
tmp_reg = __raw_readl(base + SYSREG_APM_QOS);
tmp_reg &= ~(0xf | (0xf << 4));
tmp_reg |= (priority & 0xf);
tmp_reg |= (priority & 0xf) << 4;
__raw_writel(tmp_reg, base + SYSREG_APM_QOS);
break;
case BTS_SYSREG_CPU:
tmp_reg = __raw_readl(base + SYSREG_CPU_QOS);
tmp_reg &= ~(0xf | (0xf << 4));
tmp_reg |= (priority & 0xf);
tmp_reg |= (priority & 0xf) << 4;
__raw_writel(tmp_reg, base + SYSREG_CPU_QOS);
break;
default:
break;
}
}
void sysreg_disable(QOS_SYSREG_IP qos_id, addr_u32 base)
{
unsigned int tmp_reg;
switch (qos_id) {
case BTS_SYSREG_CPGNSS:
tmp_reg = __raw_readl(base + SYSREG_CP_QOS);
tmp_reg |= 1;
__raw_writel(tmp_reg, base + SYSREG_CP_QOS);
tmp_reg = __raw_readl(base + SYSREG_GNSS_QOS);
tmp_reg |= 1;
tmp_reg |= (0x4) << 8;
tmp_reg |= (0x4) << 16;
__raw_writel(tmp_reg, base + SYSREG_GNSS_QOS);
break;
case BTS_SYSREG_APM:
tmp_reg = __raw_readl(base + SYSREG_APM_QOS);
tmp_reg &= ~(0xf | (0xf << 4));
tmp_reg |= 0x4;
tmp_reg |= 0x4 << 4;
__raw_writel(tmp_reg, base + SYSREG_APM_QOS);
break;
case BTS_SYSREG_CPU:
tmp_reg = __raw_readl(base + SYSREG_CPU_QOS);
tmp_reg &= ~(0xf | (0xf << 4));
tmp_reg |= 0x4;
tmp_reg |= 0x4 << 4;
__raw_writel(tmp_reg, base + SYSREG_CPU_QOS);
break;
default:
break;
}
}
void sysreg_showqos(QOS_SYSREG_IP qos_id, addr_u32 base, struct seq_file *buf)
{
unsigned int tmp_reg;
switch (qos_id) {
case BTS_SYSREG_CPGNSS:
tmp_reg = __raw_readl(base + SYSREG_GNSS_QOS);
LOG("(cp bypass %d)bypass %u qos 0x%Xr 0x%Xw\n",
__raw_readl(base + SYSREG_CP_QOS) && 0x1,
tmp_reg & 1, (tmp_reg >> 8) & 0xf, (tmp_reg >> 16) & 0xf);
break;
case BTS_SYSREG_APM:
tmp_reg = __raw_readl(base + SYSREG_APM_QOS);
LOG("qos 0x%Xr 0x%Xw\n", tmp_reg & 0xf,
(tmp_reg >> 4) & 0xf);
break;
case BTS_SYSREG_CPU:
tmp_reg = __raw_readl(base + SYSREG_CPU_QOS);
LOG("qos 0x%Xr 0x%Xw\n", tmp_reg & 0xf,
(tmp_reg >> 4) & 0xf);
break;
default:
break;
}
}