M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions
@@ -0,0 +1,358 @@
/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdint.h>
#include <kernel/thread.h>
#include <platform/iomap.h>
#include <reg.h>
#include <debug.h>
#include <mmc.h>
#define ACPU_806MHZ 42
#define ACPU_1024MHZ 53
#define ACPU_1200MHZ 125
#define ACPU_1400MHZ 73
/* Macros to select PLL2 with divide by 1 */
#define ACPU_SRC_SEL 3
#define ACPU_SRC_DIV 0
#define BIT(n) (1 << (n))
#define VREG_CONFIG (BIT(7) | BIT(6)) /* Enable VREG, pull-down if disabled. */
#define VREG_DATA (VREG_CONFIG | (VREF_SEL << 5))
#define VREF_SEL 1 /* 0: 0.625V (50mV step), 1: 0.3125V (25mV step). */
#define V_STEP (25 * (2 - VREF_SEL)) /* Minimum voltage step size. */
#define MV(mv) ((mv) / (!((mv) % V_STEP)))
/* mv = (750mV + (raw * 25mV)) * (2 - VREF_SEL) */
#define VDD_RAW(mv) (((MV(mv) / V_STEP) - 30) | VREG_DATA)
/* enum for SDC CLK IDs */
enum {
SDC1_CLK = 19,
SDC1_PCLK = 20,
SDC2_CLK = 21,
SDC2_PCLK = 22,
SDC3_CLK = 23,
SDC3_PCLK = 24,
SDC4_CLK = 25,
SDC4_PCLK = 26
};
/* Zero'th entry is dummy */
static uint8_t sdc_clk[] = { 0, SDC1_CLK, SDC2_CLK, SDC3_CLK, SDC4_CLK };
static uint8_t sdc_pclk[] = { 0, SDC1_PCLK, SDC2_PCLK, SDC3_PCLK, SDC4_PCLK };
void spm_init(void)
{
writel(0x05, MSM_SAW_BASE + 0x10); /* MSM_SPM_REG_SAW_CFG */
writel(0x18, MSM_SAW_BASE + 0x14); /* MSM_SPM_REG_SAW_SPM_CTL */
writel(0x00006666, MSM_SAW_BASE + 0x18); /* MSM_SPM_REG_SAW_SPM_SLP_TMR_DLY */
writel(0xFF000666, MSM_SAW_BASE + 0x1C); /* MSM_SPM_REG_SAW_SPM_WAKE_TMR_DLY */
writel(0x01, MSM_SAW_BASE + 0x24); /* MSM_SPM_REG_SAW_SLP_CLK_EN */
writel(0x03, MSM_SAW_BASE + 0x28); /* MSM_SPM_REG_SAW_SLP_HSFS_PRECLMP_EN */
writel(0x00, MSM_SAW_BASE + 0x2C); /* MSM_SPM_REG_SAW_SLP_HSFS_POSTCLMP_EN */
writel(0x01, MSM_SAW_BASE + 0x30); /* MSM_SPM_REG_SAW_SLP_CLMP_EN */
writel(0x00, MSM_SAW_BASE + 0x34); /* MSM_SPM_REG_SAW_SLP_RST_EN */
writel(0x00, MSM_SAW_BASE + 0x38); /* MSM_SPM_REG_SAW_SPM_MPM_CFG */
}
/* Configures msmc2 voltage. vlevel is in mV */
void msmc2_config(unsigned vlevel)
{
unsigned val;
val = readl(MSM_SAW_BASE + 0x08); /* MSM_SPM_REG_SAW_VCTL */
val &= ~0xFF;
val |= VDD_RAW(vlevel);
writel(val, MSM_SAW_BASE + 0x08); /* MSM_SPM_REG_SAW_VCTL */
/* Wait for PMIC state to return to idle and for VDD to stabilize */
while (((readl(MSM_SAW_BASE + 0x0C) >> 0x20) & 0x3) != 0) ;
udelay(160);
}
void enable_pll(unsigned num)
{
unsigned reg_val;
reg_val = readl(PLL_ENA_REG);
reg_val |= (1 << num);
writel(reg_val, PLL_ENA_REG);
/* Wait until PLL is enabled */
while ((readl(PLL2_STATUS_BASE_REG) & (1 << 16)) == 0) ;
}
void acpu_clock_init(void)
{
unsigned clk, reg_clksel, reg_clkctl, src_sel;
/* Fixing msmc2 voltage */
spm_init();
clk = readl(PLL2_L_VAL_ADDR) & 0xFF;
if (clk == ACPU_806MHZ)
msmc2_config(1100);
else if (clk == ACPU_1024MHZ || clk == ACPU_1200MHZ)
msmc2_config(1200);
else if (clk == ACPU_1400MHZ)
msmc2_config(1250);
/* Enable pll 2 */
enable_pll(2);
reg_clksel = readl(SCSS_CLK_SEL);
/* CLK_SEL_SRC1NO */
src_sel = reg_clksel & 1;
/* Program clock source and divider. */
reg_clkctl = readl(SCSS_CLK_CTL);
reg_clkctl &= ~(0xFF << (8 * src_sel));
reg_clkctl |= ACPU_SRC_SEL << (4 + 8 * src_sel);
reg_clkctl |= ACPU_SRC_DIV << (0 + 8 * src_sel);
writel(reg_clkctl, SCSS_CLK_CTL);
/* Toggle clock source. */
reg_clksel ^= 1;
/* Program clock source selection. */
writel(reg_clksel, SCSS_CLK_SEL);
}
void hsusb_clock_init(void)
{
int val = 0;
unsigned sh2_own_row2;
unsigned sh2_own_row2_hsusb_mask = (1 << 11);
sh2_own_row2 = readl(SH2_OWN_ROW2_BASE_REG);
if (sh2_own_row2 & sh2_own_row2_hsusb_mask) {
/* USB local clock control enabled */
/* Set value in MD register */
val = 0x5DF;
writel(val, SH2_USBH_MD_REG);
/* Set value in NS register */
val = 1 << 8;
val = val | readl(SH2_USBH_NS_REG);
writel(val, SH2_USBH_NS_REG);
val = 1 << 11;
val = val | readl(SH2_USBH_NS_REG);
writel(val, SH2_USBH_NS_REG);
val = 1 << 9;
val = val | readl(SH2_USBH_NS_REG);
writel(val, SH2_USBH_NS_REG);
val = 1 << 13;
val = val | readl(SH2_USBH_NS_REG);
writel(val, SH2_USBH_NS_REG);
/* Enable USBH_P_CLK */
val = 1 << 25;
val = val | readl(SH2_GLBL_CLK_ENA_SC);
writel(val, SH2_GLBL_CLK_ENA_SC);
} else {
/* USB local clock control not enabled; use proc comm */
usb_clock_init();
}
}
void adm_enable_clock(void)
{
unsigned int val = 0;
/* Enable ADM_CLK */
val = 1 << 5;
val = val | readl(SH2_GLBL_CLK_ENA_SC);
writel(val, SH2_GLBL_CLK_ENA_SC);
}
void mdp_lcdc_clock_init(void)
{
unsigned int val = 0;
unsigned sh2_own_apps2;
unsigned sh2_own_apps2_lcdc_mask = (1 << 3);
sh2_own_apps2 = readl(SH2_OWN_APPS2_BASE_REG);
if (sh2_own_apps2 & sh2_own_apps2_lcdc_mask) {
/* MDP local clock control enabled */
/* Select clock source and divider */
val = 0x29;
val = val | readl(SH2_MDP_NS_REG);
writel(val, SH2_MDP_NS_REG);
/* Enable MDP source clock(root) */
val = 1 << 11;
val = val | readl(SH2_MDP_NS_REG);
writel(val, SH2_MDP_NS_REG);
/* Enable graphics clock(branch) */
val = 1 << 9;
val = val | readl(SH2_MDP_NS_REG);
writel(val, SH2_MDP_NS_REG);
/* Enable MDP_P_CLK */
val = 1 << 6;
val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
writel(val, SH2_GLBL_CLK_ENA_2_SC);
/* Enable AXI_MDP_CLK */
val = 1 << 29;
val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
writel(val, SH2_GLBL_CLK_ENA_2_SC);
/* LCDC local clock control enabled */
/* Set value in MD register */
val = 0x1FFF9;
writel(val, SH2_MDP_LCDC_MD_REG);
/* Set MDP_LCDC_N_VAL in NS register */
val = 0xFFFA << 16;
val = val | readl(SH2_MDP_LCDC_NS_REG);
writel(val, SH2_MDP_LCDC_NS_REG);
/* Set clock source */
val = 1;
val = val | readl(SH2_MDP_LCDC_NS_REG);
writel(val, SH2_MDP_LCDC_NS_REG);
/* Set divider */
val = 3 << 3;
val = val | readl(SH2_MDP_LCDC_NS_REG);
writel(val, SH2_MDP_LCDC_NS_REG);
/* Set MN counter mode */
val = 2 << 5;
val = val | readl(SH2_MDP_LCDC_NS_REG);
writel(val, SH2_MDP_LCDC_NS_REG);
/* Enable MN counter */
val = 1 << 8;
val = val | readl(SH2_MDP_LCDC_NS_REG);
writel(val, SH2_MDP_LCDC_NS_REG);
/* Enable mdp_lcdc_src(root) clock */
val = 1 << 11;
val = val | readl(SH2_MDP_LCDC_NS_REG);
writel(val, SH2_MDP_LCDC_NS_REG);
/* Enable mdp_lcdc_pclk(branch) clock */
val = 1 << 9;
val = val | readl(SH2_MDP_LCDC_NS_REG);
writel(val, SH2_MDP_LCDC_NS_REG);
/* Enable mdp_lcdc_pad_pclk(branch) clock */
val = 1 << 12;
val = val | readl(SH2_MDP_LCDC_NS_REG);
writel(val, SH2_MDP_LCDC_NS_REG);
} else {
/* MDP local clock control not enabled; use proc comm */
mdp_clock_init(122880000);
/* LCDC local clock control not enabled; use proc comm */
lcdc_clock_init(27648000);
}
}
void mddi_pmdh_clock_init(void)
{
unsigned int val = 0;
unsigned sh2_own_row1;
unsigned sh2_own_row1_pmdh_mask = (1 << 19);
sh2_own_row1 = readl(SH2_OWN_ROW1_BASE_REG);
if (sh2_own_row1 & sh2_own_row1_pmdh_mask) {
/* Select clock source and divider */
val = 1;
val |= (1 << 3);
val = val | readl(SH2_PMDH_NS_REG);
writel(val, SH2_PMDH_NS_REG);
/* Enable PMDH_SRC (root) signal */
val = 1 << 11;
val = val | readl(SH2_PMDH_NS_REG);
writel(val, SH2_PMDH_NS_REG);
/* Enable PMDH_P_CLK */
val = 1 << 4;
val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
writel(val, SH2_GLBL_CLK_ENA_2_SC);
} else {
/* MDDI local clock control not enabled; use proc comm */
mddi_clock_init(0, 480000000);
}
}
void ce_clock_init(void)
{
unsigned int val = 0;
/* Enable CE_CLK */
val = 1 << 6;
val = val | readl(SH2_GLBL_CLK_ENA_SC);
writel(val, SH2_GLBL_CLK_ENA_SC);
}
/* Configure MMC clock */
void clock_config_mmc(uint32_t interface, uint32_t freq)
{
uint32_t reg = 0;
if (mmc_clock_set_rate(sdc_clk[interface], freq) < 0) {
dprintf(CRITICAL, "Failure setting clock rate for MCLK - "
"clk_rate: %d\n!", freq);
ASSERT(0);
}
/* enable clock */
if (mmc_clock_enable_disable(sdc_clk[interface], MMC_CLK_ENABLE) < 0) {
dprintf(CRITICAL, "Failure enabling MMC Clock!\n");
ASSERT(0);
}
reg |= MMC_BOOT_MCI_CLK_ENABLE;
reg |= MMC_BOOT_MCI_CLK_ENA_FLOW;
reg |= MMC_BOOT_MCI_CLK_IN_FEEDBACK;
writel(reg, MMC_BOOT_MCI_CLK);
/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
mmc_mclk_reg_wr_delay();
/* Wait 1 ms to provide the free running SD CLK to the card. */
mdelay(1);
}
/* Intialize MMC clock */
void clock_init_mmc(uint32_t interface)
{
if (mmc_clock_enable_disable(sdc_pclk[interface], MMC_CLK_ENABLE) < 0) {
dprintf(CRITICAL, "Failure enabling PCLK!\n");
ASSERT(0);
}
}
@@ -0,0 +1,699 @@
/*
* Copyright (c) 2008, Google Inc.
* All rights reserved.
* Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* TODO:
* - style cleanup
* - do we need to do *all* of this at boot?
*/
.text
.code 32
#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5
#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5
/*
; LVT Ring Osc counter
; used to determine sense amp settings
; Clobbers registers r0, r4, r5, r6, r7, r9, r10, r11
*/
.equ CLK_CTL_BASE, 0xA8600000
.equ A_GLBL_CLK_ENA, 0x0000
.equ A_PRPH_WEB_NS_REG,0x0080
.equ A_MSM_CLK_RINGOSC,0x00D0
.equ A_TCXO_CNT, 0x00D4
.equ A_TCXO_CNT_DONE, 0x00D8
.equ A_RINGOSC_CNT, 0x00DC
.equ A_MISC_CLK_CTL, 0x0108
.equ CLK_TEST, 0xA8600114
.equ SPSS_CSR_BASE, 0xAC100000
.equ A_SCRINGOSC, 0x0510
//;; Number of TCXO cycles to count ring oscillations
.equ TCXO_CNT_VAL, 0x100
//; Halcyon addresses
.equ TCSR_CONF_FUSE_1, 0xAB600060 //; TCSR_CONF_FUSE_1 register
.equ TCSR_CONF_FUSE_4, 0xAB60006C //; TCSR_CONF_FUSE_4 register
//; SCORPION_L1_ACC (1:0) Fuses bit location
.equ L1_ACC_BIT_0, 12 //;12th bit of TCSR_CONF_FUSE_4
.equ L1_ACC_BIT_1, 13 //;13th bit of TCSR_CONF_FUSE_4
//; SCORPION_L2_ACC (2:0) Fuses bit location
.equ L2_ACC_BIT_0, 25 //;25th bit of TCSR_CONF_FUSE_1
.equ L2_ACC_BIT_1, 10 //;10th bit of TCSR_CONF_FUSE_4
.equ L2_ACC_BIT_2, 11 //;11th bit of TCSR_CONF_FUSE_4
//; CP15: PVR2F0 values according to SCORPION_L1_ACC (1:0)
.equ PVR2F0_00, 0x00000000
.equ PVR2F0_01, 0x04000000
.equ PVR2F0_10, 0x08000000
.equ PVR2F0_11, 0x0C000000
//; CP15: PVR2F1 values according to SCORPION_L1_ACC (1:0)
.equ PVR2F1_00, 0x00000008
.equ PVR2F1_01, 0x00000008
.equ PVR2F1_10, 0x00000208
.equ PVR2F1_11, 0x00000208
//; CP15: PVR0F2 values according to SCORPION_L1_ACC (1:0)
.equ PVR0F2_00, 0x00000000
.equ PVR0F2_01, 0x00000000
.equ PVR0F2_10, 0x00000200
.equ PVR0F2_11, 0x00000200
//; CP15: PVR0F0 values according to SCORPION_L1_ACC (1:0)
.equ PVR0F0_00, 0x7F000000
.equ PVR0F0_01, 0x7F000400
.equ PVR0F0_10, 0x7F000000
.equ PVR0F0_11, 0x7F000400
//; CP15: L2VR3F1 values according to SCORPION_L2_ACC (2:0)
.equ L2VR3F1_000, 0x00FFFF60
.equ L2VR3F1_001, 0x00FFFF40
.equ L2VR3F1_010, 0x00FFFC60
.equ L2VR3F1_011, 0x00FFFC40
.equ L2VR3F1_100, 0x00FCFF60
.equ L2VR3F1_101, 0x00FCFF40
.equ L2VR3F1_110, 0x00FCFC60
.equ L2VR3F1_111, 0x00FCFC40
.globl SET_SA
SET_SA:
//;--------------------------------------------------------------------
//; Fuse bits used to determine sense amp settings
//;--------------------------------------------------------------------
//; Reading L1_ACC
LDR r4, = 0x0
//; Read L1_ACC_BIT_0
LDR r1, =TCSR_CONF_FUSE_4
LDR r2, =L1_ACC_BIT_0
LDR r3, [r1]
MOV r3, r3, LSR r2
AND r3, r3, #1
ORR r4, r3, r4
//; Read L1_ACC_BIT_1
LDR r1, =TCSR_CONF_FUSE_4
LDR r2, =L1_ACC_BIT_1
LDR r3, [r1]
MOV r3, r3, LSR r2
AND r3, r3, #1
MOV r3, r3, LSL #1
ORR r4, r3, r4
l1_ck_0:
//; if L1_[1:0] == 00
LDR r5, = 0x0
CMP r4, r5
BNE l1_ck_1
LDR r0, =PVR0F0_00
LDR r1, =PVR0F2_00
LDR r2, =PVR2F0_00
LDR r3, =PVR2F1_00
B WRITE_L1_SA_SETTINGS
l1_ck_1:
//; if L1_[1:0] == 01
LDR r1, = 0x01
CMP r4, r1
BNE l1_ck_2
LDR r0, =PVR0F0_01
LDR r1, =PVR0F2_01
LDR r2, =PVR2F0_01
LDR r3, =PVR2F1_01
B WRITE_L1_SA_SETTINGS
l1_ck_2:
//; if L1_[2:0] == 10
LDR r1, = 0x02
CMP r4, r1
BNE l1_ck_3
LDR r0, =PVR0F0_10
LDR r1, =PVR0F2_10
LDR r2, =PVR2F0_10
LDR r3, =PVR2F1_10
B WRITE_L1_SA_SETTINGS
l1_ck_3:
//; if L1_[2:0] == 11
LDR r1, = 0x03
CMP r4, r1
LDR r0, =PVR0F0_11
LDR r1, =PVR0F2_11
LDR r2, =PVR2F0_11
LDR r3, =PVR2F1_11
B WRITE_L1_SA_SETTINGS
WRITE_L1_SA_SETTINGS:
//;WCP15_PVR0F0 r0
MCR p15, 0x0, r0, c15, c15, 0x0 //; write R0 to PVR0F0
//;WCP15_PVR0F2 r1
MCR p15, 0x0, r1, c15, c15, 0x2 //; write R1 to PVR0F2
//;WCP15_PVR2F0 r2
MCR p15, 0x2, r2, c15, c15, 0x0 //; write R2 to PVR2F0
// Disable predecode repair cache on certain Scorpion revisions
// (Raptor V2 and earlier, or Halcyon V1)
MRC p15, 0, r1, c0, c0, 0 //; MIDR
BIC r2, r1, #0xf0 //; check for Halcyon V1
LDR r4, =0x511f0000
CMP r2, r4
BNE PVR2F1
DPRC:
MRC p15, 0, r1, c15, c15, 2 //; PVR0F2
ORR r1, r1, #0x10 //; enable bit 4
MCR p15, 0, r1, c15, c15, 2 //; disable predecode repair cache
PVR2F1:
//;WCP15_PVR2F1 r3
MCR p15, 0x2, r3, c15, c15, 0x1 //; write R3 to PVR2F1
//; Reading L2_ACC
LDR r4, = 0x0
//; Read L2_ACC_BIT_0
LDR r1, =TCSR_CONF_FUSE_1
LDR r2, =L2_ACC_BIT_0
LDR r3, [r1]
MOV r3, r3, LSR r2
AND r3, r3, #1
ORR r4, r3, r4
//; Read L2_ACC_BIT_1
LDR r1, =TCSR_CONF_FUSE_4
LDR r2, =L2_ACC_BIT_1
LDR r3, [r1]
MOV r3, r3, LSR r2
AND r3, r3, #1
MOV r3, r3, LSL #1
ORR r4, r3, r4
//; Read L2_ACC_BIT_2
LDR r1, =TCSR_CONF_FUSE_4
LDR r2, =L2_ACC_BIT_2
LDR r3, [r1]
MOV r3, r3, LSR r2
AND r3, r3, #1
MOV r3, r3, LSL #2
ORR r4, r3, r4
l2_ck_0:
//; if L2_[2:0] == 000
LDR r5, = 0x0
CMP r4, r5
BNE l2_ck_1
LDR r0, =L2VR3F1_000
B WRITE_L2_SA_SETTINGS
l2_ck_1:
//; if L2_[2:0] == 001
LDR r5, = 0x1
CMP r4, r5
BNE l2_ck_2
LDR r0, =L2VR3F1_001
B WRITE_L2_SA_SETTINGS
l2_ck_2:
//; if L2_[2:0] == 010
LDR r5, = 0x2
CMP r4, r5
BNE l2_ck_3
LDR r0, =L2VR3F1_010
B WRITE_L2_SA_SETTINGS
l2_ck_3:
//; if L2_[2:0] == 011
LDR r5, = 0x3
CMP r4, r5
BNE l2_ck_4
LDR r0, =L2VR3F1_011
B WRITE_L2_SA_SETTINGS
l2_ck_4:
//; if L2_[2:0] == 100
LDR r5, = 0x4
CMP r4, r5
BNE l2_ck_5
LDR r0, =L2VR3F1_100
B WRITE_L2_SA_SETTINGS
l2_ck_5:
//; if L2_[2:0] == 101
LDR r5, = 0x5
CMP r4, r5
BNE l2_ck_6
LDR r0, =L2VR3F1_101
B WRITE_L2_SA_SETTINGS
l2_ck_6:
//; if L2_[2:0] == 110
LDR r5, = 0x6
CMP r4, r5
BNE l2_ck_7
LDR r0, =L2VR3F1_110
B WRITE_L2_SA_SETTINGS
l2_ck_7:
//; if L2_[2:0] == 111
LDR r5, = 0x7
CMP r4, r5
LDR r0, =L2VR3F1_111
B WRITE_L2_SA_SETTINGS
WRITE_L2_SA_SETTINGS:
//;WCP15_L2VR3F1 r0
MCR p15, 0x3, r0, c15, c15, 0x1 //;write r0 to L2VR3F1
DSB
ISB
LDR r0, =0 //;make sure the registers we touched
LDR r1, =0 //;are cleared when we return
LDR r2, =0
LDR r3, =0
LDR r4, =0
LDR r5, =0
//; routine complete
B _cpu_early_init_complete
.ltorg
.globl __cpu_early_init
__cpu_early_init:
//; Zero out r0 for use throughout this code. All other GPRs
//; (r1-r3) are set throughout this code to help establish
//; a consistent startup state for any code that follows.
//; Users should add code at the end of this routine to establish
//; their own stack address (r13), add translation page tables, enable
//; the caches, etc.
MOV r0, #0x0
//; Remove hardcoded cache settings. appsbl_handler.s calls Set_SA
//; API to dynamically configure cache for slow/nominal/fast parts
//; DCIALL to invalidate L2 cache bank (needs to be run 4 times, once per bank)
//; This must be done early in code (prior to enabling the caches)
MOV r1, #0x2
MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank D ([15:14] == 2'b00)
ORR r1, r1, #0x00004000
MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank C ([15:14] == 2'b01)
ADD r1, r1, #0x00004000
MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank B ([15:14] == 2'b10)
ADD r1, r1, #0x00004000
MCR p15, 0, r1, c9, c0, 6 //; DCIALL bank A ([15:14] == 2'b11)
//; Initialize the BPCR - setup Global History Mask (GHRM) to all 1's
//; and have all address bits (AM) participate.
//; Different settings can be used to improve performance
// MOVW r1, #0x01FF
.word 0xe30011ff // hardcoded MOVW instruction due to lack of compiler support
// MOVT r1, #0x01FF
.word 0xe34011ff // hardcoded MOVT instruction due to lack of compiler support
MCR p15, 7, r1, c15, c0, 2 //; WCP15_BPCR
//; Initialize all I$ Victim Registers to 0 for startup
MCR p15, 0, r0, c9, c1, 0 //; WCP15_ICVIC0 r0
MCR p15, 0, r0, c9, c1, 1 //; WCP15_ICVIC1 r0
MCR p15, 0, r0, c9, c1, 2 //; WCP15_ICVIC2 r0
MCR p15, 0, r0, c9, c1, 3 //; WCP15_ICVIC3 r0
MCR p15, 0, r0, c9, c1, 4 //; WCP15_ICVIC4 r0
MCR p15, 0, r0, c9, c1, 5 //; WCP15_ICVIC5 r0
MCR p15, 0, r0, c9, c1, 6 //; WCP15_ICVIC5 r0
MCR p15, 0, r0, c9, c1, 7 //; WCP15_ICVIC7 r0
//; Initialize all I$ Locked Victim Registers (Unlocked Floors) to 0
MCR p15, 1, r0, c9, c1, 0 //; WCP15_ICFLOOR0 r0
MCR p15, 1, r0, c9, c1, 1 //; WCP15_ICFLOOR1 r0
MCR p15, 1, r0, c9, c1, 2 //; WCP15_ICFLOOR2 r0
MCR p15, 1, r0, c9, c1, 3 //; WCP15_ICFLOOR3 r0
MCR p15, 1, r0, c9, c1, 4 //; WCP15_ICFLOOR4 r0
MCR p15, 1, r0, c9, c1, 5 //; WCP15_ICFLOOR5 r0
MCR p15, 1, r0, c9, c1, 6 //; WCP15_ICFLOOR6 r0
MCR p15, 1, r0, c9, c1, 7 //; WCP15_ICFLOOR7 r0
//; Initialize all D$ Victim Registers to 0
MCR p15, 2, r0, c9, c1, 0 //; WP15_DCVIC0 r0
MCR p15, 2, r0, c9, c1, 1 //; WP15_DCVIC1 r0
MCR p15, 2, r0, c9, c1, 2 //; WP15_DCVIC2 r0
MCR p15, 2, r0, c9, c1, 3 //; WP15_DCVIC3 r0
MCR p15, 2, r0, c9, c1, 4 //; WP15_DCVIC4 r0
MCR p15, 2, r0, c9, c1, 5 //; WP15_DCVIC5 r0
MCR p15, 2, r0, c9, c1, 6 //; WP15_DCVIC6 r0
MCR p15, 2, r0, c9, c1, 7 //; WP15_DCVIC7 r0
//; Initialize all D$ Locked VDCtim Registers (Unlocked Floors) to 0
MCR p15, 3, r0, c9, c1, 0 //; WCP15_DCFLOOR0 r0
MCR p15, 3, r0, c9, c1, 1 //; WCP15_DCFLOOR1 r0
MCR p15, 3, r0, c9, c1, 2 //; WCP15_DCFLOOR2 r0
MCR p15, 3, r0, c9, c1, 3 //; WCP15_DCFLOOR3 r0
MCR p15, 3, r0, c9, c1, 4 //; WCP15_DCFLOOR4 r0
MCR p15, 3, r0, c9, c1, 5 //; WCP15_DCFLOOR5 r0
MCR p15, 3, r0, c9, c1, 6 //; WCP15_DCFLOOR6 r0
MCR p15, 3, r0, c9, c1, 7 //; WCP15_DCFLOOR7 r0
//; Initialize ASID to zero
MCR p15, 0, r0, c13, c0, 1 //; WCP15_CONTEXTIDR r0
//; ICIALL to invalidate entire I-Cache
MCR p15, 0, r0, c7, c5, 0 //; ICIALLU
//; DCIALL to invalidate entire D-Cache
MCR p15, 0, r0, c9, c0, 6 //; DCIALL r0
//; Initialize ADFSR to zero
MCR p15, 0, r0, c5, c1, 0 //; ADFSR r0
//; Initialize EFSR to zero
MCR p15, 7, r0, c15, c0, 1 //; EFSR r0
//; The VBAR (Vector Base Address Register) should be initialized
//; early in your code. We are setting it to zero
MCR p15, 0, r0, c12, c0, 0 //; WCP15_VBAR r0
//; Ensure the MCR's above have completed their operation before continuing
DSB
ISB
//; Setup CCPR - Cache Coherency Policy Register
//; setup CCPR[L1ISHP, L2ISHP] both to 0b00 (no forcing)
//; setup CCPR[L1OSHP, L2OSHP] both to 0b10 (force non-cacheable)
MOVW r2, #0x88
MCR p15, 0, r2, c10, c4, 2
//;-------------------------------------------------------------------
//; There are a number of registers that must be set prior to enabling
//; the MMU. The DCAR is one of these registers. We are setting
//; it to zero (no access) to easily detect improper setup in subsequent
//; code sequences
//;-------------------------------------------------------------------
//; Setup DACR (Domain Access Control Register) to zero
MCR p15, 0, r0, c3, c0, 0 //; WCP15_DACR r0
//; Setup DCLKCR to allow normal D-Cache line fills
MCR p15, 1, r0, c9, c0, 7 //; WCP15_DCLKCR r0
//; Setup the TLBLKCR
//; Victim = 6'b000000; Floor = 6'b000000;
//; IASIDCFG = 2'b00 (State-Machine); IALLCFG = 2'b01 (Flash); BNA = 1'b0;
MOV r1, #0x02
MCR p15, 0, r1, c10, c1, 3 //; WCP15_TLBLKCR r1
//;Make sure TLBLKCR is complete before continuing
ISB
//; Invalidate the UTLB
MCR p15, 0, r0, c8, c7, 0 //; UTLBIALL
//; Make sure UTLB request has been presented to macro before continuing
ISB
SYSI2:
//; setup L2CR1 to some default Instruction and data prefetching values
//; Users may want specific settings for various performance enhancements
//; In Halcyon we do not have broadcasting barriers. So we need to turn
// ; on bit 8 of L2CR1; which DBB:( Disable barrier broadcast )
LDR r2, =0x133
MCR p15, 3, r2, c15, c0, 3 //; WCP15_L2CR1 r0
//; Enable Z bit to enable branch prediction (default is off)
MRC p15, 0, r2, c1, c0, 0 //; RCP15_SCTLR r2
ORR r2, r2, #0x00000800
MCR p15, 0, r2, c1, c0, 0 //; WCP15_SCTLR r2
//; Make sure Link stack is initialized with branch and links to sequential addresses
//; This aids in creating a predictable startup environment
BL SEQ1
SEQ1: BL SEQ2
SEQ2: BL SEQ3
SEQ3: BL SEQ4
SEQ4: BL SEQ5
SEQ5: BL SEQ6
SEQ6: BL SEQ7
SEQ7: BL SEQ8
SEQ8:
//; REMOVE FOLLOWING THREE INSTRUCTIONS WHEN POWER COLLAPSE IS ENA
//;Make sure the DBGOSLSR[LOCK] bit is cleared to allow access to the debug registers
//; Writing anything but the "secret code" to the DBGOSLAR clears the DBGOSLSR[LOCK] bit
MCR p14, 0, r0, c1, c0, 4 //; WCP14_DBGOSLAR r0
//; Read the DBGPRSR to clear the DBGPRSR[STICKYPD]
//; Any read to DBGPRSR clear the STICKYPD bit
//; ISB guarantees the read completes before attempting to
//; execute a CP14 instruction.
MRC p14, 0, r3, c1, c5, 4 //; RCP14_DBGPRSR r3
ISB
//; Initialize the Watchpoint Control Registers to zero (optional)
//;;; MCR p14, 0, r0, c0, c0, 7 ; WCP14_DBGWCR0 r0
//;;; MCR p14, 0, r0, c0, c1, 7 ; WCP14_DBGWCR1 r0
//;----------------------------------------------------------------------
//; The saved Program Status Registers (SPSRs) should be setup
//; prior to any automatic mode switches. The following
//; code sets these registers up to a known state. Users will need to
//; customize these settings to meet their needs.
//;----------------------------------------------------------------------
MOV r2, #0x1f
MOV r1, #0xd7 //;ABT mode
msr cpsr_c, r1 //;ABT mode
msr spsr_cxfs, r2 //;clear the spsr
MOV r1, #0xdb //;UND mode
msr cpsr_c, r1 //;UND mode
msr spsr_cxfs, r2 //;clear the spsr
MOV r1, #0xd1 //;FIQ mode
msr cpsr_c, r1 //;FIQ mode
msr spsr_cxfs, r2 //;clear the spsr
MOV r1, #0xd2 //;IRQ mode
msr cpsr_c, r1 //;IRQ mode
msr spsr_cxfs, r2 //;clear the spsr
MOV r1, #0xd6 //;Monitor mode
msr cpsr_c, r1 //;Monitor mode
msr spsr_cxfs, r2 //;clear the spsr
MOV r1, #0xd3 //;SVC mode
msr cpsr_c, r1 //;SVC mode
msr spsr_cxfs, r2 //;clear the spsr
//;----------------------------------------------------------------------
//; Enabling Error reporting is something users may want to do at
//; some other point in time. We have chosen some default settings
//; that should be reviewed. Most of these registers come up in an
//; unpredictable state after reset.
//;----------------------------------------------------------------------
//;Start of error and control setting
//; setup L2CR0 with various L2/TCM control settings
//; enable out of order bus attributes and error reporting
//; this register comes up unpredictable after reset
// MOVW r1, #0x0F0F
.word 0xe3001f0f // hardcoded MOVW instruction due to lack of compiler support
// MOVT r1, #0xC005
.word 0xe34c1005 // hardcoded MOVW instruction due to lack of compiler support
MCR p15, 3, r1, c15, c0, 1 //; WCP15_L2CR0 r1
//; setup L2CPUCR
//; MOV r2, #0xFF
//; Enable I and D cache parity
//;L2CPUCR[7:5] = 3~Rh7 ~V enable parity error reporting for modified,
//;tag, and data parity errors
MOV r2, #0xe0
MCR p15, 3, r2, c15, c0, 2 //; WCP15_L2CPUCR r2
//; setup SPCR
//; enable all error reporting (reset value is unpredicatble for most bits)
MOV r3, #0x0F
MCR p15, 0, r3, c9, c7, 0 //; WCP15_SPCR r3
//; setup DMACHCRs (reset value unpredictable)
//; control setting and enable all error reporting
MOV r1, #0x0F
//; DMACHCR0 = 0000000F
MOV r2, #0x00 //; channel 0
MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
//; DMACHCR1 = 0000000F
MOV r2, #0x01 //; channel 1
MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
//; DMACHCR2 = 0000000F
MOV r2, #0x02 //; channel 2
MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
//; DMACHCR3 = 0000000F
MOV r2, #0x03 //; channel 3
MCR p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
MCR p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
//; Set ACTLR (reset unpredictable)
//; Set AVIVT control, error reporting, etc.
//; MOV r3, #0x07
//; Enable I and D cache parity
//;ACTLR[2:0] = 3'h7 - enable parity error reporting from L2/I$/D$)
//;ACTLR[5:4] = 2'h3 - enable parity
//;ACTLR[19:18] =2'h3 - always generate and check parity(when MMU disabled).
//;Value to be written #0xC0037
// MOVW r3, #0x0037
.word 0xe3003037 // hardcoded MOVW instruction due to lack of compiler support
// MOVT r3, #0x000C
.word 0xe340300c // hardcoded MOVW instruction due to lack of compiler support
MCR p15, 0, r3, c1, c0, 1 //; WCP15_ACTLR r3
//;End of error and control setting
//;----------------------------------------------------------------------
//; Unlock ETM and read StickyPD to halt the ETM clocks from running.
//; This is required for power saving whether the ETM is used or not.
//;----------------------------------------------------------------------
//;Clear ETMOSLSR[LOCK] bit
MOV r1, #0x00000000
MCR p14, 1, r1, c1, c0, 4 //; WCP14_ETMOSLAR r1
//;Clear ETMPDSR[STICKYPD] bit
MRC p14, 1, r2, c1, c5, 4 //; RCP14_ETMPDSR r2
/*
#ifdef APPSBL_ETM_ENABLE
;----------------------------------------------------------------------
; Optionally Enable the ETM (Embedded Trace Macro) which is used for debug
;----------------------------------------------------------------------
; enable ETM clock if disabled
MRC p15, 7, r1, c15, c0, 5 ; RCP15_CPMR r1
ORR r1, r1, #0x00000008
MCR p15, 7, r1, c15, c0, 5 ; WCP15_CPMR r1
ISB
; set trigger event to counter1 being zero
MOV r3, #0x00000040
MCR p14, 1, r3, c0, c2, 0 ; WCP14_ETMTRIGGER r3
; clear ETMSR
MOV r2, #0x00000000
MCR p14, 1, r2, c0, c4, 0 ; WCP14_ETMSR r2
; clear trace enable single address comparator usage
MCR p14, 1, r2, c0, c7, 0 ; WCP14_ETMTECR2 r2
; set trace enable to always
MOV r2, #0x0000006F
MCR p14, 1, r2, c0, c8, 0 ; WCP14_ETMTEEVR r2
; clear trace enable address range comparator usage and exclude nothing
MOV r2, #0x01000000
MCR p14, 1, r2, c0, c9, 0 ; WCP14_ETMTECR1 r2
; set view data to always
MOV r2, #0x0000006F
MCR p14, 1, r2, c0, c12, 0 ; WCP14_ETMVDEVR r2
; clear view data single address comparator usage
MOV r2, #0x00000000
MCR p14, 1, r2, c0, c13, 0 ; WCP14_ETMVDCR1 r2
; clear view data address range comparator usage and exclude nothing
MOV r2, #0x00010000
MCR p14, 1, r2, c0, c15, 0 ; WCP14_ETMVDCR3 r2
; set counter1 to 194
MOV r2, #0x000000C2
MCR p14, 1, r2, c0, c0, 5 ; WCP14_ETMCNTRLDVR1 r2
; set counter1 to never reload
MOV r2, #0x0000406F
MCR p14, 1, r2, c0, c8, 5 ; WCP14_ETMCNTRLDEVR1 r2
; set counter1 to decrement every cycle
MOV r2, #0x0000006F
MCR p14, 1, r2, c0, c4, 5 ; WCP14_ETMCNTENR1 r2
; Set trace synchronization frequency 1024 bytes
MOV r2, #0x00000400
MCR p14, 1, r2, c0, c8, 7 ; WCP14_ETMSYNCFR r2
; Program etm control register
; - Set the CPU to ETM clock ratio to 1:1
; - Set the ETM to perform data address tracing
MOV r2, #0x00002008
MCR p14, 1, r2, c0, c0, 0 ; WCP14_ETMCR r2
ISB
#endif *//* APPSBL_ETM_ENABLE */
/*
#ifdef APPSBL_VFP_ENABLE
;----------------------------------------------------------------------
; Perform the following operations if you intend to make use of
; the VFP/Neon unit. Note that the FMXR instruction requires a CPU ID
; indicating the VFP unit is present (i.e.Cortex-A8). .
; Some tools will require full double precision floating point support
; which will become available in Scorpion pass 2
;----------------------------------------------------------------------
; allow full access to CP 10 and 11 space for VFP/NEON use
MRC p15, 0, r1, c1, c0, 2 ; Read CP Access Control Register
ORR r1, r1, #0x00F00000 ; enable full access for p10,11
MCR p15, 0, r1, c1, c0, 2 ; Write CPACR
;make sure the CPACR is complete before continuing
ISB
; Enable VFP itself (certain OSes may want to dynamically set/clear
; the enable bit based on the application being executed
MOV r1, #0x40000000
FMXR FPEXC, r1
#endif *//* APPSBL_VFP_ENABLE */
/* we have no stack, so just tail-call into the SET_SA routine... */
b SET_SA
.ltorg
@@ -0,0 +1,241 @@
/*
* Copyright (c) 2008, Google Inc.
* All rights reserved.
*
* Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <debug.h>
#include <reg.h>
#include <platform/iomap.h>
#include <dev/gpio.h>
#include "gpio_hw.h"
typedef struct gpioregs gpioregs;
struct gpioregs {
unsigned out;
unsigned in;
unsigned int_status;
unsigned int_clear;
unsigned int_en;
unsigned int_edge;
unsigned int_pos;
unsigned oe;
};
static gpioregs GPIO_REGS[] = {
{
.out = GPIO_OUT_0,
.in = GPIO_IN_0,
.int_status = GPIO_INT_STATUS_0,
.int_clear = GPIO_INT_CLEAR_0,
.int_en = GPIO_INT_EN_0,
.int_edge = GPIO_INT_EDGE_0,
.int_pos = GPIO_INT_POS_0,
.oe = GPIO_OE_0,
},
{
.out = GPIO_OUT_1,
.in = GPIO_IN_1,
.int_status = GPIO_INT_STATUS_1,
.int_clear = GPIO_INT_CLEAR_1,
.int_en = GPIO_INT_EN_1,
.int_edge = GPIO_INT_EDGE_1,
.int_pos = GPIO_INT_POS_1,
.oe = GPIO_OE_1,
},
{
.out = GPIO_OUT_2,
.in = GPIO_IN_2,
.int_status = GPIO_INT_STATUS_2,
.int_clear = GPIO_INT_CLEAR_2,
.int_en = GPIO_INT_EN_2,
.int_edge = GPIO_INT_EDGE_2,
.int_pos = GPIO_INT_POS_2,
.oe = GPIO_OE_2,
},
{
.out = GPIO_OUT_3,
.in = GPIO_IN_3,
.int_status = GPIO_INT_STATUS_3,
.int_clear = GPIO_INT_CLEAR_3,
.int_en = GPIO_INT_EN_3,
.int_edge = GPIO_INT_EDGE_3,
.int_pos = GPIO_INT_POS_3,
.oe = GPIO_OE_3,
},
{
.out = GPIO_OUT_4,
.in = GPIO_IN_4,
.int_status = GPIO_INT_STATUS_4,
.int_clear = GPIO_INT_CLEAR_4,
.int_en = GPIO_INT_EN_4,
.int_edge = GPIO_INT_EDGE_4,
.int_pos = GPIO_INT_POS_4,
.oe = GPIO_OE_4,
},
{
.out = GPIO_OUT_5,
.in = GPIO_IN_5,
.int_status = GPIO_INT_STATUS_5,
.int_clear = GPIO_INT_CLEAR_5,
.int_en = GPIO_INT_EN_5,
.int_edge = GPIO_INT_EDGE_5,
.int_pos = GPIO_INT_POS_5,
.oe = GPIO_OE_5,
},
{
.out = GPIO_OUT_6,
.in = GPIO_IN_6,
.int_status = GPIO_INT_STATUS_6,
.int_clear = GPIO_INT_CLEAR_6,
.int_en = GPIO_INT_EN_6,
.int_edge = GPIO_INT_EDGE_6,
.int_pos = GPIO_INT_POS_6,
.oe = GPIO_OE_6,
},
{
.out = GPIO_OUT_7,
.in = GPIO_IN_7,
.int_status = GPIO_INT_STATUS_7,
.int_clear = GPIO_INT_CLEAR_7,
.int_en = GPIO_INT_EN_7,
.int_edge = GPIO_INT_EDGE_7,
.int_pos = GPIO_INT_POS_7,
.oe = GPIO_OE_7,
},
};
static gpioregs *find_gpio(unsigned n, unsigned *bit)
{
if (n > 150) {
*bit = 1 << (n - 151);
return GPIO_REGS + 7;
}
if (n > 133) {
*bit = 1 << (n - 134);
return GPIO_REGS + 6;
}
if (n > 106) {
*bit = 1 << (n - 107);
return GPIO_REGS + 5;
}
if (n > 94) {
*bit = 1 << (n - 95);
return GPIO_REGS + 4;
}
if (n > 67) {
*bit = 1 << (n - 68);
return GPIO_REGS + 3;
}
if (n > 43) {
*bit = 1 << (n - 44);
return GPIO_REGS + 2;
}
if (n > 15) {
*bit = 1 << (n - 16);
return GPIO_REGS + 1;
}
*bit = 1 << n;
return GPIO_REGS + 0;
}
int gpio_config(unsigned n, unsigned flags)
{
gpioregs *r;
unsigned b;
unsigned v;
if ((r = find_gpio(n, &b)) == 0)
return -1;
v = readl(r->oe);
if (flags & GPIO_OUTPUT) {
writel(v | b, r->oe);
} else {
writel(v & (~b), r->oe);
}
return 0;
}
void gpio_set(unsigned n, unsigned on)
{
gpioregs *r;
unsigned b;
unsigned v;
if ((r = find_gpio(n, &b)) == 0)
return;
v = readl(r->out);
if (on) {
writel(v | b, r->out);
} else {
writel(v & (~b), r->out);
}
}
int gpio_get(unsigned n)
{
gpioregs *r;
unsigned b;
if ((r = find_gpio(n, &b)) == 0)
return 0;
return (readl(r->in) & b) ? 1 : 0;
}
void platform_config_interleaved_mode_gpios(void)
{
/* configure EB2_CS1 through GPIO86 */
writel(GPIO_ALT_FUNC_PAGE_REG, 0x56);
writel(GPIO_ALT_FUNC_CFG_REG, 0x04);
/* configure the EBI2_BUSY1_N through GPIO115 */
writel(GPIO_ALT_FUNC_PAGE_REG, 0x73);
writel(GPIO_ALT_FUNC_CFG_REG, 0x08);
}
/* Enables all gpios passed in table*/
int platform_gpios_enable(const struct msm_gpio *table, int size)
{
int rc;
int i;
const struct msm_gpio *g;
for (i = 0; i < size; i++) {
g = table + i;
/* Enable gpio */
rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE);
if (rc) {
goto err;
}
}
return 0;
err:
return rc;
}
@@ -0,0 +1,180 @@
/*
* Copyright (c) 2008, Google Inc.
* All rights reserved.
*
* Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef __PLATFORM_MSM7X30_GPIO_HW_H
#define __PLATFORM_MSM7X30_GPIO_HW_H
#define MSM_GPIO1_BASE 0xAC001000
#define MSM_GPIO2_BASE 0xAC101000
#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
/* output value */
#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */
#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 43-16 */
#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-44 */
#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */
#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 106-95 */
#define GPIO_OUT_5 GPIO1_REG(0x50) /* gpio 133-107 */
#define GPIO_OUT_6 GPIO1_REG(0xC4) /* gpio 150-134 */
#define GPIO_OUT_7 GPIO1_REG(0x214) /* gpio 181-151 */
/* same pin map as above, output enable */
#define GPIO_OE_0 GPIO1_REG(0x10)
#define GPIO_OE_1 GPIO2_REG(0x08)
#define GPIO_OE_2 GPIO1_REG(0x14)
#define GPIO_OE_3 GPIO1_REG(0x18)
#define GPIO_OE_4 GPIO1_REG(0x1C)
#define GPIO_OE_5 GPIO1_REG(0x54)
#define GPIO_OE_6 GPIO1_REG(0xC8)
#define GPIO_OE_7 GPIO1_REG(0x218)
/* same pin map as above, input read */
#define GPIO_IN_0 GPIO1_REG(0x34)
#define GPIO_IN_1 GPIO2_REG(0x20)
#define GPIO_IN_2 GPIO1_REG(0x38)
#define GPIO_IN_3 GPIO1_REG(0x3C)
#define GPIO_IN_4 GPIO1_REG(0x40)
#define GPIO_IN_5 GPIO1_REG(0x44)
#define GPIO_IN_6 GPIO1_REG(0xCC)
#define GPIO_IN_7 GPIO1_REG(0x21C)
/* same pin map as above, 1=edge 0=level interrup */
#define GPIO_INT_EDGE_0 GPIO1_REG(0x60)
#define GPIO_INT_EDGE_1 GPIO2_REG(0x50)
#define GPIO_INT_EDGE_2 GPIO1_REG(0x64)
#define GPIO_INT_EDGE_3 GPIO1_REG(0x68)
#define GPIO_INT_EDGE_4 GPIO1_REG(0x6C)
#define GPIO_INT_EDGE_5 GPIO1_REG(0xC0)
#define GPIO_INT_EDGE_6 GPIO1_REG(0xD0)
#define GPIO_INT_EDGE_7 GPIO1_REG(0x240)
/* same pin map as above, 1=positive 0=negative */
#define GPIO_INT_POS_0 GPIO1_REG(0x70)
#define GPIO_INT_POS_1 GPIO2_REG(0x58)
#define GPIO_INT_POS_2 GPIO1_REG(0x74)
#define GPIO_INT_POS_3 GPIO1_REG(0x78)
#define GPIO_INT_POS_4 GPIO1_REG(0x7C)
#define GPIO_INT_POS_5 GPIO1_REG(0xBC)
#define GPIO_INT_POS_6 GPIO1_REG(0xD4)
#define GPIO_INT_POS_7 GPIO1_REG(0x228)
/* same pin map as above, interrupt enable */
#define GPIO_INT_EN_0 GPIO1_REG(0x80)
#define GPIO_INT_EN_1 GPIO2_REG(0x60)
#define GPIO_INT_EN_2 GPIO1_REG(0x84)
#define GPIO_INT_EN_3 GPIO1_REG(0x88)
#define GPIO_INT_EN_4 GPIO1_REG(0x8C)
#define GPIO_INT_EN_5 GPIO1_REG(0xB8)
#define GPIO_INT_EN_6 GPIO1_REG(0xD8)
#define GPIO_INT_EN_7 GPIO1_REG(0x22C)
/* same pin map as above, write 1 to clear interrupt */
#define GPIO_INT_CLEAR_0 GPIO1_REG(0x90)
#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68)
#define GPIO_INT_CLEAR_2 GPIO1_REG(0x94)
#define GPIO_INT_CLEAR_3 GPIO1_REG(0x98)
#define GPIO_INT_CLEAR_4 GPIO1_REG(0x9C)
#define GPIO_INT_CLEAR_5 GPIO1_REG(0xB4)
#define GPIO_INT_CLEAR_6 GPIO1_REG(0xDC)
#define GPIO_INT_CLEAR_7 GPIO1_REG(0x230)
/* same pin map as above, 1=interrupt pending */
#define GPIO_INT_STATUS_0 GPIO1_REG(0xA0)
#define GPIO_INT_STATUS_1 GPIO2_REG(0x70)
#define GPIO_INT_STATUS_2 GPIO1_REG(0xA4)
#define GPIO_INT_STATUS_3 GPIO1_REG(0xA8)
#define GPIO_INT_STATUS_4 GPIO1_REG(0xAC)
#define GPIO_INT_STATUS_5 GPIO1_REG(0xB0)
#define GPIO_INT_STATUS_6 GPIO1_REG(0xE0)
#define GPIO_INT_STATUS_7 GPIO1_REG(0x234)
#define GPIO_OUT_VAL_REG_BASE 0xABC00000
#define GPIO_ALT_FUNC_PAGE_REG (GPIO_OUT_VAL_REG_BASE + 0x20)
#define GPIO_ALT_FUNC_CFG_REG (GPIO_OUT_VAL_REG_BASE + 0x24)
/* GPIO TLMM: Direction */
#define GPIO_INPUT 0
#define GPIO_OUTPUT 1
/* GPIO TLMM: Pullup/Pulldown */
#define GPIO_NO_PULL 0
#define GPIO_PULL_DOWN 1
#define GPIO_KEEPER 2
#define GPIO_PULL_UP 3
/* GPIO TLMM: Drive Strength */
#define GPIO_2MA 0
#define GPIO_4MA 1
#define GPIO_6MA 2
#define GPIO_8MA 3
#define GPIO_10MA 4
#define GPIO_12MA 5
#define GPIO_14MA 6
#define GPIO_16MA 7
#define GPIO38_GPIO_CNTRL 0x175
/* GPIO TLMM: Status */
#define GPIO_ENABLE 0
#define GPIO_DISABLE 1
#define GPIO_CFG(gpio, func, dir, pull, drvstr) \
((((gpio) & 0x3FF) << 4) | \
((func) & 0xf) | \
(((dir) & 0x1) << 14) | \
(((pull) & 0x3) << 15) | \
(((drvstr) & 0xF) << 17))
/**
* struct msm_gpio - GPIO pin description
* @gpio_cfg - configuration bitmap, as per gpio_tlmm_config()
* @label - textual label
*
* Usually, GPIO's are operated by sets.
* This struct accumulate all GPIO information in single source
* and facilitete group operations provided by msm_gpios_xxx()
*/
struct msm_gpio {
unsigned gpio_cfg;
const char *label;
};
/**
* extract GPIO pin from bit-field used for gpio_tlmm_config
*/
#define GPIO_PIN(gpio_cfg) (((gpio_cfg) >> 4) & 0x3ff)
#define GPIO_FUNC(gpio_cfg) (((gpio_cfg) >> 0) & 0xf)
#define GPIO_DIR(gpio_cfg) (((gpio_cfg) >> 14) & 0x1)
#define GPIO_PULL(gpio_cfg) (((gpio_cfg) >> 15) & 0x3)
#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf)
#endif
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __PLATFORM_ADM_H
#define __PLATFORM_ADM_H
/* Channel #s and security domain */
#define ADM_CHN 8
#define ADM_SD 2
#endif
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2008, Google Inc.
* All rights reserved.
* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _PLATFORM_MSM7X30_IOMAP_H_
#define _PLATFORM_MSM7X30_IOMAP_H_
#define MSM_UART1_BASE 0xACA00000
#define MSM_UART2_BASE 0xACB00000
#define MSM_UART3_BASE 0xACC00000
#define MSM_VIC_BASE 0xC0080000
#define MSM_TMR_BASE 0xC0100000
#define MSM_GPT_BASE (MSM_TMR_BASE + 0x04)
#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24)
#define SPSS_TIMER_STATUS (MSM_TMR_BASE + 0x88)
#define GPT_REG(off) (MSM_GPT_BASE + (off))
#define DGT_REG(off) (MSM_DGT_BASE + (off))
#define GPT_MATCH_VAL GPT_REG(0x0000)
#define GPT_COUNT_VAL GPT_REG(0x0004)
#define GPT_ENABLE GPT_REG(0x0008)
#define GPT_CLEAR GPT_REG(0x000C)
#define DGT_MATCH_VAL DGT_REG(0x0000)
#define DGT_COUNT_VAL DGT_REG(0x0004)
#define DGT_ENABLE DGT_REG(0x0008)
#define DGT_CLEAR DGT_REG(0x000C)
#define DGT_CLK_CTL DGT_REG(0x0010)
#define HW_REVISION_NUMBER 0xABC00270
#define MSM_CSR_BASE 0xC0100000
#define MSM_GCC_BASE 0xC0182000
#define MSM_SDC1_BASE 0xA0400000
#define MSM_SDC2_BASE 0xA0500000
#define MSM_SDC3_BASE 0xA3000000
#define MSM_SDC4_BASE 0xA3100000
#define MSM_SHARED_BASE 0x00100000
#define MSM_CLK_CTL_BASE 0xAB800000
#define MSM_CLK_CTL_SH2_BASE 0xABA01000
#define REG_BASE(off) (MSM_CLK_CTL_BASE + (off))
#define REG_SH2_BASE(off) (MSM_CLK_CTL_SH2_BASE + (off))
#define SCSS_CLK_CTL 0xC0101004
#define SCSS_CLK_SEL 0xC0101008
#define MSM_USB_BASE 0xA3600000
#define MSM_CRYPTO_BASE 0xA8400000
#define SH2_USBH_MD_REG REG_SH2_BASE(0x2BC)
#define SH2_USBH_NS_REG REG_SH2_BASE(0x2C0)
#define SH2_MDP_NS_REG REG_SH2_BASE(0x14C)
#define SH2_MDP_LCDC_MD_REG REG_SH2_BASE(0x38C)
#define SH2_MDP_LCDC_NS_REG REG_SH2_BASE(0x390)
#define SH2_MDP_VSYNC_REG REG_SH2_BASE(0x460)
#define SH2_PMDH_NS_REG REG_SH2_BASE(0x8C)
#define SH2_GLBL_CLK_ENA_SC REG_SH2_BASE(0x3BC)
#define SH2_GLBL_CLK_ENA_2_SC REG_SH2_BASE(0x3C0)
#define SH2_OWN_ROW1_BASE_REG REG_BASE(0x041C)
#define SH2_OWN_ROW2_BASE_REG REG_BASE(0x0424)
#define SH2_OWN_APPS2_BASE_REG REG_BASE(0x0414)
#define MSM_ADM_BASE 0xAC200000
#define MSM_ADM_SD_OFFSET 0x00100400
#define MSM_SAW_BASE 0xC0102000
#define PLL_ENA_REG REG_SH2_BASE(0x0264)
#define PLL2_STATUS_BASE_REG REG_BASE(0x0350)
#define PLL2_L_VAL_ADDR REG_BASE(0x033C)
#endif
@@ -0,0 +1,170 @@
/* Copyright (c) 2009, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __ASM_ARCH_MSM_IRQS_7X30_H
#define __ASM_ARCH_MSM_IRQS_7X30_H
/* MSM ACPU Interrupt Numbers */
#define INT_DEBUG_TIMER_EXP 0
#define INT_GPT0_TIMER_EXP 1
#define INT_GPT1_TIMER_EXP 2
#define INT_WDT0_ACCSCSSBARK 3
#define INT_WDT1_ACCSCSSBARK 4
#define INT_AVS_SVIC 5
#define INT_AVS_SVIC_SW_DONE 6
#define INT_SC_DBG_RX_FULL 7
#define INT_SC_DBG_TX_EMPTY 8
#define INT_SC_PERF_MON 9
#define INT_AVS_REQ_DOWN 10
#define INT_AVS_REQ_UP 11
#define INT_SC_ACG 12
/* SCSS_VICFIQSTS1[13:15] are RESERVED */
#define INT_L2_SVICCPUIRPTREQ 16
#define INT_L2_SVICDMANSIRPTREQ 17
#define INT_L2_SVICDMASIRPTREQ 18
#define INT_L2_SVICSLVIRPTREQ 19
#define INT_AD5A_MPROC_APPS_0 20
#define INT_AD5A_MPROC_APPS_1 21
#define INT_A9_M2A_0 22
#define INT_A9_M2A_1 23
#define INT_A9_M2A_2 24
#define INT_A9_M2A_3 25
#define INT_A9_M2A_4 26
#define INT_A9_M2A_5 27
#define INT_A9_M2A_6 28
#define INT_A9_M2A_7 29
#define INT_A9_M2A_8 30
#define INT_A9_M2A_9 31
#define INT_AXI_EBI1_SC (32 + 0)
#define INT_IMEM_ERR (32 + 1)
#define INT_AXI_EBI0_SC (32 + 2)
#define INT_PBUS_SC_IRQC (32 + 3)
#define INT_PERPH_BUS_BPM (32 + 4)
#define INT_CC_TEMP_SENSE (32 + 5)
#define INT_UXMC_EBI0 (32 + 6)
#define INT_UXMC_EBI1 (32 + 7)
#define INT_EBI2_OP_DONE (32 + 8)
#define INT_EBI2_WR_ER_DONE (32 + 9)
#define INT_TCSR_SPSS_CE (32 + 10)
#define INT_EMDH (32 + 11)
#define INT_PMDH (32 + 12)
#define INT_MDC (32 + 13)
#define INT_MIDI_TO_SUPSS (32 + 14)
#define INT_LPA_2 (32 + 15)
#define INT_GPIO_GROUP1_SECURE (32 + 16)
#define INT_GPIO_GROUP2_SECURE (32 + 17)
#define INT_GPIO_GROUP1 (32 + 18)
#define INT_GPIO_GROUP2 (32 + 19)
#define INT_MPRPH_SOFTRESET (32 + 20)
#define INT_PWB_I2C (32 + 21)
#define INT_PWB_I2C_2 (32 + 22)
#define INT_TSSC_SAMPLE (32 + 23)
#define INT_TSSC_PENUP (32 + 24)
#define INT_TCHSCRN_SSBI (32 + 25)
#define INT_FM_RDS (32 + 26)
#define INT_KEYSENSE (32 + 27)
#define INT_USB_OTG_HS (32 + 28)
#define INT_USB_OTG_HS2 (32 + 29)
#define INT_USB_OTG_HS3 (32 + 30)
#define INT_RESERVED_BIT31 (32 + 31)
#define INT_SPI_OUTPUT (64 + 0)
#define INT_SPI_INPUT (64 + 1)
#define INT_SPI_ERROR (64 + 2)
#define INT_UART1 (64 + 3)
#define INT_UART1_RX (64 + 4)
#define INT_UART2 (64 + 5)
#define INT_UART2_RX (64 + 6)
#define INT_UART3 (64 + 7)
#define INT_UART3_RX (64 + 8)
#define INT_UART1DM_IRQ (64 + 9)
#define INT_UART1DM_RX (64 + 10)
#define INT_UART2DM_IRQ (64 + 11)
#define INT_UART2DM_RX (64 + 12)
#define INT_TSIF (64 + 13)
#define INT_ADM_SC1 (64 + 14)
#define INT_ADM_SC2 (64 + 15)
#define INT_MDP (64 + 16)
#define INT_VPE (64 + 17)
#define INT_GRP_2D (64 + 18)
#define INT_GRP_3D (64 + 19)
#define INT_ROTATOR (64 + 20)
#define INT_MFC720 (64 + 21)
#define INT_JPEG (64 + 22)
#define INT_VFE (64 + 23)
#define INT_TV_ENC (64 + 24)
#define INT_PMIC_SSBI (64 + 25)
#define INT_MPM_1 (64 + 26)
#define INT_TCSR_SPSS_SAMPLE (64 + 27)
#define INT_TCSR_SPSS_PENUP (64 + 28)
#define INT_MPM_2 (64 + 29)
#define INT_SDC1_0 (64 + 30)
#define INT_SDC1_1 (64 + 31)
#define INT_SDC3_0 (96 + 0)
#define INT_SDC3_1 (96 + 1)
#define INT_SDC2_0 (96 + 2)
#define INT_SDC2_1 (96 + 3)
#define INT_SDC4_0 (96 + 4)
#define INT_SDC4_1 (96 + 5)
#define INT_PWB_QUP_IN (96 + 6)
#define INT_PWB_QUP_OUT (96 + 7)
#define INT_PWB_QUP_ERR (96 + 8)
/* SCSS_VICFIQSTS3[6:31] are RESERVED */
/* Retrofit universal macro names */
#define INT_ADM_AARM INT_ADM_SC2
#define INT_USB_HS INT_USB_OTG_HS
#define INT_USB_OTG INT_USB_OTG_HS
#define INT_TCHSCRN1 INT_TSSC_SAMPLE
#define INT_TCHSCRN2 INT_TSSC_PENUP
#define INT_GP_TIMER_EXP INT_GPT0_TIMER_EXP
#define INT_ADSP_A11 INT_AD5A_MPROC_APPS_0
#define INT_ADSP_A9_A11 INT_AD5A_MPROC_APPS_1
#define INT_MDDI_EXT INT_EMDH
#define INT_MDDI_PRI INT_PMDH
#define INT_MDDI_CLIENT INT_MDC
#define INT_NAND_WR_ER_DONE INT_EBI2_WR_ER_DONE
#define INT_NAND_OP_DONE INT_EBI2_OP_DONE
#define NR_MSM_IRQS 128
#define NR_GPIO_IRQS 182
#define PMIC8058_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
#define NR_PMIC8058_GPIO_IRQS 40
#define NR_PMIC8058_MPP_IRQS 12
#define NR_PMIC8058_MISC_IRQS 8
#define NR_PMIC8058_IRQS (NR_PMIC8058_GPIO_IRQS +\
NR_PMIC8058_MPP_IRQS +\
NR_PMIC8058_MISC_IRQS)
#define NR_BOARD_IRQS NR_PMIC8058_IRQS
#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS)
#endif /* __ASM_ARCH_MSM_IRQS_7X30_H */
@@ -0,0 +1,41 @@
/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _PLATFORM_MSM7X30_MACHTYPE_H_
#define _PLATFORM_MSM7X30_MACHTYPE_H_
#define LINUX_MACHTYPE_7x30_SURF 2679
#define LINUX_MACHTYPE_7x30_FFA 2707
#define LINUX_MACHTYPE_7x30_FLUID 2741
#define LINUX_MACHTYPE_8x55_SURF 2768
#define LINUX_MACHTYPE_8x55_FFA 2769
#define LINUX_MACHTYPE_8x55_SVLTE_FFA 2863
#define LINUX_MACHTYPE_8x55_SVLTE_SURF 2864
#endif
@@ -0,0 +1,60 @@
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <sys/types.h>
#define RLOCK_CHUNK_NAME_LENGTH 10
#define RLOCK_CHUNK_NAME "PMIC_SSBI"
#define DEK_LOCK_REQUEST 1
#define DEK_LOCK_YIELD (!DEK_LOCK_REQUEST)
#define DEK_YIELD_TURN_SELF 0
struct rlock_chunk_header {
uint32_t size;
char name[RLOCK_CHUNK_NAME_LENGTH];
uint32_t lock;
uint32_t reserved;
uint32_t type;
uint32_t version;
};
struct dek_spinlock {
volatile uint8_t self_lock;
volatile uint8_t other_lock;
volatile uint8_t next_yield;
uint8_t pad;
};
typedef union {
volatile uint32_t lock;
struct dek_spinlock dek;
} raw_remote_spinlock_t;
typedef raw_remote_spinlock_t *remote_spinlock_t;
remote_spinlock_t rlock;
@@ -0,0 +1,158 @@
/*
* Copyright (c) 2008, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <debug.h>
#include <arch/arm.h>
#include <reg.h>
#include <kernel/thread.h>
#include <platform/interrupts.h>
#include <platform/irqs.h>
#include <platform/iomap.h>
#define VIC_REG(off) (MSM_VIC_BASE + (off))
#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */
#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */
#define VIC_INT_EN0 VIC_REG(0x0010)
#define VIC_INT_EN1 VIC_REG(0x0014)
#define VIC_INT_ENCLEAR0 VIC_REG(0x0020)
#define VIC_INT_ENCLEAR1 VIC_REG(0x0024)
#define VIC_INT_ENSET0 VIC_REG(0x0030)
#define VIC_INT_ENSET1 VIC_REG(0x0034)
#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */
#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */
#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */
#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */
#define VIC_NO_PEND_VAL VIC_REG(0x0060)
#define VIC_INT_MASTEREN VIC_REG(0x0068) /* 1: IRQ, 2: FIQ */
#define VIC_CONFIG VIC_REG(0x006C) /* 1: USE ARM1136 VIC */
#define VIC_SECURITY0 VIC_REG(0x0070)
#define VIC_SECURITY1 VIC_REG(0x0074)
#define VIC_IRQ_STATUS0 VIC_REG(0x0080)
#define VIC_IRQ_STATUS1 VIC_REG(0x0084)
#define VIC_FIQ_STATUS0 VIC_REG(0x0090)
#define VIC_FIQ_STATUS1 VIC_REG(0x0094)
#define VIC_RAW_STATUS0 VIC_REG(0x00A0)
#define VIC_RAW_STATUS1 VIC_REG(0x00A4)
#define VIC_INT_CLEAR0 VIC_REG(0x00B0)
#define VIC_INT_CLEAR1 VIC_REG(0x00B4)
#define VIC_SOFTINT0 VIC_REG(0x00C0)
#define VIC_SOFTINT1 VIC_REG(0x00C4)
#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */
#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */
#define VIC_IRQ_VEC_WR VIC_REG(0x00D8)
#define VIC_FIQ_VEC_RD VIC_REG(0x00DC) /* pending int # */
#define VIC_FIQ_VEC_PEND_RD VIC_REG(0x00E0) /* pending vector addr */
#define VIC_FIQ_VEC_WR VIC_REG(0x00E4)
#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E8)
#define VIC_IRQ_IN_STACK VIC_REG(0x00EC)
#define VIC_FIQ_IN_SERVICE VIC_REG(0x00F0)
#define VIC_FIQ_IN_STACK VIC_REG(0x00F4)
#define VIC_TEST_BUS_SEL VIC_REG(0x00F8)
#define SIRC_REG(off) (MSM_SIRC_BASE + (off))
#define SIRC_INT_SELECT SIRC_REG(0x0000) /* 0: IRQ0 1: IRQ1 */
#define SIRC_INT_ENABLE SIRC_REG(0x0004)
#define SIRC_INT_ENCLEAR SIRC_REG(0x0008)
#define SIRC_INT_ENSET SIRC_REG(0x000C)
#define SIRC_INT_TYPE SIRC_REG(0x0010) /* 1: EDGE, 0: LEVEL */
#define SIRC_INT_POLARITY SIRC_REG(0x0014) /* 1: NEG, 0: POS */
#define SIRC_SECURITY SIRC_REG(0x0018) /* 0: SEC, 1: NSEC */
#define SIRC_IRQ0_STATUS SIRC_REG(0x001C)
#define SIRC_IRQ1_STATUS SIRC_REG(0x0020)
#define SIRC_RAW_STATUS SIRC_REG(0x0024)
struct ihandler {
int_handler func;
void *arg;
};
static struct ihandler handler[NR_IRQS];
void platform_init_interrupts(void)
{
writel(0xffffffff, VIC_INT_CLEAR0);
writel(0xffffffff, VIC_INT_CLEAR1);
writel(0, VIC_INT_SELECT0);
writel(0, VIC_INT_SELECT1);
writel(0xffffffff, VIC_INT_TYPE0);
writel(0xffffffff, VIC_INT_TYPE1);
writel(0, VIC_CONFIG);
writel(1, VIC_INT_MASTEREN);
}
enum handler_return platform_irq(struct arm_iframe *frame)
{
unsigned num;
enum handler_return ret;
num = readl(VIC_IRQ_VEC_RD);
num = readl(VIC_IRQ_VEC_PEND_RD);
if (num > NR_IRQS)
return 0;
writel(1 << (num & 31), (num > 31) ? VIC_INT_CLEAR1 : VIC_INT_CLEAR0);
ret = handler[num].func(handler[num].arg);
writel(0, VIC_IRQ_VEC_WR);
return ret;
}
void platform_fiq(struct arm_iframe *frame)
{
PANIC_UNIMPLEMENTED;
}
status_t mask_interrupt(unsigned int vector)
{
unsigned reg = (vector > 31) ? VIC_INT_ENCLEAR1 : VIC_INT_ENCLEAR0;
unsigned bit = 1 << (vector & 31);
writel(bit, reg);
return 0;
}
status_t unmask_interrupt(unsigned int vector)
{
unsigned reg = (vector > 31) ? VIC_INT_ENSET1 : VIC_INT_ENSET0;
unsigned bit = 1 << (vector & 31);
writel(bit, reg);
return 0;
}
void register_int_handler(unsigned int vector, int_handler func, void *arg)
{
if (vector >= NR_IRQS)
return;
enter_critical_section();
handler[vector].func = func;
handler[vector].arg = arg;
exit_critical_section();
}
@@ -0,0 +1,667 @@
/*
* Copyright (c) 2007, Google Inc.
* All rights reserved.
*
* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <debug.h>
#include <dev/gpio.h>
#include <kernel/thread.h>
#include "gpio_hw.h"
#include "panel.h"
#include <platform/machtype.h>
#include <dev/lcdc.h>
static int display_common_power(int);
#if DISPLAY_TYPE_MDDI
#include <mddi.h>
#define MDDI_CLIENT_CORE_BASE 0x108000
#define LCD_CONTROL_BLOCK_BASE 0x110000
#define SPI_BLOCK_BASE 0x120000
#define I2C_BLOCK_BASE 0x130000
#define PWM_BLOCK_BASE 0x140000
#define GPIO_BLOCK_BASE 0x150000
#define SYSTEM_BLOCK1_BASE 0x160000
#define SYSTEM_BLOCK2_BASE 0x170000
#define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00)
#define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04)
#define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08)
#define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C)
#define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10)
#define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14)
#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18)
#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C)
#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20)
#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)
#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28)
#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C)
#define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30)
#define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34)
#define INTMONI (MDDI_CLIENT_CORE_BASE|0x38)
#define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C)
#define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40)
#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44)
#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48)
#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C)
#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50)
#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54)
#define SRST (LCD_CONTROL_BLOCK_BASE|0x00)
#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04)
#define START (LCD_CONTROL_BLOCK_BASE|0x08)
#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C)
#define CMN (LCD_CONTROL_BLOCK_BASE|0x10)
#define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14)
#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18)
#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C)
#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20)
#define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24)
#define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28)
#define PXL (LCD_CONTROL_BLOCK_BASE|0x30)
#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34)
#define HSW (LCD_CONTROL_BLOCK_BASE|0x38)
#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C)
#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40)
#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44)
#define VSW (LCD_CONTROL_BLOCK_BASE|0x48)
#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C)
#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50)
#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54)
#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58)
#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C)
#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60)
#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64)
#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68)
#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C)
#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70)
#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74)
#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78)
#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C)
#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80)
#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84)
#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88)
#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C)
#define MONI (LCD_CONTROL_BLOCK_BASE|0xB0)
#define Current (LCD_CONTROL_BLOCK_BASE|0xC0)
#define LCD (LCD_CONTROL_BLOCK_BASE|0xC4)
#define COMMAND (LCD_CONTROL_BLOCK_BASE|0xC8)
#define SSICTL (SPI_BLOCK_BASE|0x00)
#define SSITIME (SPI_BLOCK_BASE|0x04)
#define SSITX (SPI_BLOCK_BASE|0x08)
#define SSIRX (SPI_BLOCK_BASE|0x0C)
#define SSIINTC (SPI_BLOCK_BASE|0x10)
#define SSIINTS (SPI_BLOCK_BASE|0x14)
#define SSIDBG1 (SPI_BLOCK_BASE|0x18)
#define SSIDBG2 (SPI_BLOCK_BASE|0x1C)
#define SSIID (SPI_BLOCK_BASE|0x20)
#define I2CSETUP (I2C_BLOCK_BASE|0x00)
#define I2CCTRL (I2C_BLOCK_BASE|0x04)
#define TIMER0LOAD (PWM_BLOCK_BASE|0x00)
#define TIMER0VALUE (PWM_BLOCK_BASE|0x04)
#define TIMER0CONTROL (PWM_BLOCK_BASE|0x08)
#define TIMER0INTCLR (PWM_BLOCK_BASE|0x0C)
#define TIMER0RIS (PWM_BLOCK_BASE|0x10)
#define TIMER0MIS (PWM_BLOCK_BASE|0x14)
#define TIMER0BGLOAD (PWM_BLOCK_BASE|0x18)
#define PWM0OFF (PWM_BLOCK_BASE|0x1C)
#define TIMER1LOAD (PWM_BLOCK_BASE|0x20)
#define TIMER1VALUE (PWM_BLOCK_BASE|0x24)
#define TIMER1CONTROL (PWM_BLOCK_BASE|0x28)
#define TIMER1INTCLR (PWM_BLOCK_BASE|0x2C)
#define TIMER1RIS (PWM_BLOCK_BASE|0x30)
#define TIMER1MIS (PWM_BLOCK_BASE|0x34)
#define TIMER1BGLOAD (PWM_BLOCK_BASE|0x38)
#define PWM1OFF (PWM_BLOCK_BASE|0x3C)
#define TIMERITCR (PWM_BLOCK_BASE|0x60)
#define TIMERITOP (PWM_BLOCK_BASE|0x64)
#define PWMCR (PWM_BLOCK_BASE|0x68)
#define PWMID (PWM_BLOCK_BASE|0x6C)
#define PWMMON (PWM_BLOCK_BASE|0x70)
#define GPIODATA (GPIO_BLOCK_BASE|0x00)
#define GPIODIR (GPIO_BLOCK_BASE|0x04)
#define GPIOIS (GPIO_BLOCK_BASE|0x08)
#define GPIOIBE (GPIO_BLOCK_BASE|0x0C)
#define GPIOIEV (GPIO_BLOCK_BASE|0x10)
#define GPIOIE (GPIO_BLOCK_BASE|0x14)
#define GPIORIS (GPIO_BLOCK_BASE|0x18)
#define GPIOMIS (GPIO_BLOCK_BASE|0x1C)
#define GPIOIC (GPIO_BLOCK_BASE|0x20)
#define GPIOOMS (GPIO_BLOCK_BASE|0x24)
#define GPIOPC (GPIO_BLOCK_BASE|0x28)
#define GPIOID (GPIO_BLOCK_BASE|0x30)
#define WKREQ (SYSTEM_BLOCK1_BASE|0x00)
#define CLKENB (SYSTEM_BLOCK1_BASE|0x04)
#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08)
#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C)
#define CNT_DIS (SYSTEM_BLOCK1_BASE|0x10)
#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00)
struct init_table {
unsigned int reg;
unsigned int val;
};
static struct init_table toshiba_480x800_init_table[] = {
{DPSET0, 0x4BEC0066}, // # MDC.DPSET0 # Setup DPLL parameters
{DPSET1, 0x00000113}, // # MDC.DPSET1
{DPSUS, 0x00000000}, // # MDC.DPSUS # Set DPLL oscillation enable
{DPRUN, 0x00000001}, // # MDC.DPRUN # Release reset signal for DPLL
{0, 15}, // wait_ms(15);
{SYSCKENA, 0x00000001}, // # MDC.SYSCKENA # Enable system clock output
{CLKENB, 0x000000E9}, // # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK)
{GPIO_BLOCK_BASE, 0x03FF0000}, // # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0
{GPIODIR, 0x0000024D}, // # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output)
{SYSTEM_BLOCK2_BASE, 0x00000173}, // # SYS.GPIOSEL # GPIO port multiplexing control
{GPIOPC, 0x03C300C0}, // # GPI .GPIOPC # GPIO2,3 PD cut
{SYSTEM_BLOCK1_BASE, 0x00000000}, // # SYS.WKREQ # Wake-up request event is VSYNC alignment
{GPIOIS, 0x00000000}, // # GPI .GPIOIS # Set interrupt sense of GPIO
{GPIOIEV, 0x00000001}, // # GPI .GPIOIEV # Set interrupt event of GPIO
{GPIOIC, 0x000003FF}, // # GPI .GPIOIC # GPIO interrupt clear
{GPIO_BLOCK_BASE, 0x00040004}, // # GPI .GPIODATA # Release LCDD reset
{GPIO_BLOCK_BASE, 0x00080008}, // # GPI .GPIODATA # eDRAM VD supply
{DRAMPWR, 0x00000001}, // # SYS.DRAMPWR # eDRAM power up
{CLKENB, 0x000000EB}, // # enable eDRAM clock
{PWMCR, 0x00000000}, // # PWM.PWMCR # PWM output enable
{0, 1}, // wait_ms(1);
{SPI_BLOCK_BASE, 0x00060399}, // # SPI .SSICTL # SPI operation mode setting
{SSITIME, 0x00000100}, // # SPI .SSITIME # SPI serial interface timing setting
{CNT_DIS, 0x00000002}, // # SPI .SSITIME # SPI serial interface timing setting
{SPI_BLOCK_BASE, 0x0006039B}, // # SPI .SSICTL # Set SPI active mode
{SSITX, 0x00000000}, // # SPI.SSITX # Release from Deep Stanby mode
{0, 7}, // wait_ms(2);
{SSITX, 0x00000000}, // # SPI.SSITX
{0, 7}, // wait_ms(2);
{SSITX, 0x00000000}, // # SPI.SSITX
{0, 7}, // wait_ms(2);
{SSITX, 0x000800BA}, // # SPI.SSITX *NOTE 1 # Command setting of SPI block
{SSITX, 0x00000111}, // # Display mode setup(1) : Normaly Black
{SSITX, 0x00080036}, // # Command setting of SPI block
{SSITX, 0x00000100}, // # Memory access control
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x0008003A}, // # Command setting of SPI block
{SSITX, 0x00000160}, // # Display mode setup(2)
{SSITX, 0x000800B1}, // # Command setting of SPI block
{SSITX, 0x0000015D}, // # RGB Interface data format
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800B2}, // # Command setting of SPI block
{SSITX, 0x00000133}, // # Drivnig method
{SSITX, 0x000800B3}, // # Command setting of SPI block
{SSITX, 0x00000122}, // # Booster operation setup
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800B4}, // # Command setting of SPI block
{SSITX, 0x00000102}, // # OP-amp capability/System clock freq. division setup
{SSITX, 0x000800B5}, // # Command setting of SPI block
{SSITX, 0x0000011E}, // # VCS Voltage adjustment (1C->1F for Rev 2)
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800B6}, // # Command setting of SPI block
{SSITX, 0x00000127}, // # VCOM Voltage adjustment
{SSITX, 0x000800B7}, // # Command setting of SPI block
{SSITX, 0x00000103}, // # Configure an external display signal
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800B9}, // # Command setting of SPI block
{SSITX, 0x00000124}, // # DCCK/DCEV timing setup
{SSITX, 0x000800BD}, // # Command setting of SPI block
{SSITX, 0x000001A1}, // # ASW signal control
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800BB}, // # Command setting of SPI block
{SSITX, 0x00000100}, // # Dummy display (white/black) count setup for QUAD Data operation
{SSITX, 0x000800BF}, // # Command setting of SPI block
{SSITX, 0x00000101}, // # Dummy display (white/black) count setup for QUAD Data operation
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800BE}, // # Command setting of SPI block
{SSITX, 0x00000100}, // # wait_ms(-out FR count setup (A)
{SSITX, 0x000800C0}, // # Command setting of SPI block
{SSITX, 0x00000111}, // # wait_ms(-out FR count setup (A)
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800C1}, // # Command setting of SPI block
{SSITX, 0x00000111}, // # wait_ms(-out FR count setup (B)
{SSITX, 0x000800C2}, // # Command setting of SPI block
{SSITX, 0x00000111}, // # wait_ms(-out FR count setup (C)
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800C3}, // # Command setting of SPI block
{SSITX, 0x00080132}, // # wait_ms(-in line clock count setup (D)
{SSITX, 0x00000132}, //
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800C4}, // # Command setting of SPI block
{SSITX, 0x00080132}, // # Seep-in line clock count setup (E)
{SSITX, 0x00000132}, //
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800C5}, // # Command setting of SPI block
{SSITX, 0x00080132}, // # wait_ms(-in line clock count setup (F)
{SSITX, 0x00000132}, //
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800C6}, // # Command setting of SPI block
{SSITX, 0x00080132}, // # wait_ms(-in line clock setup (G)
{SSITX, 0x00000132}, //
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800C7}, // # Command setting of SPI block
{SSITX, 0x00080164}, // # Gamma 1 fine tuning (1)
{SSITX, 0x00000145}, //
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800C8}, // # Command setting of SPI block
{SSITX, 0x00000144}, // # Gamma 1 fine tuning (2)
{SSITX, 0x000800C9}, // # Command setting of SPI block
{SSITX, 0x00000152}, // # Gamma 1 inclination adjustment
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800CA}, // # Command setting of SPI block
{SSITX, 0x00000100}, // # Gamma 1 blue offset adjustment
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800EC}, // # Command setting of SPI block
{SSITX, 0x00080102}, // # Total number of horizontal clock cycles (1) [PCLK Sync. VGA setting]
{SSITX, 0x00000118}, //
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800CF}, // # Command setting of SPI block
{SSITX, 0x00000101}, // # Blanking period control (1) [PCLK Sync. Table1 for VGA]
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800D0}, // # Command setting of SPI block
{SSITX, 0x00080110}, // # Blanking period control (2) [PCLK Sync. Table1 for VGA]
{SSITX, 0x00000104}, //
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800D1}, // # Command setting of SPI block
{SSITX, 0x00000101}, // # CKV timing control on/off [PCLK Sync. Table1 for VGA]
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800D2}, // # Command setting of SPI block
{SSITX, 0x00080100}, // # CKV1,2 timing control [PCLK Sync. Table1 for VGA]
{SSITX, 0x00000128}, //
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800D3}, // # Command setting of SPI block
{SSITX, 0x00080100}, // # OEV timing control [PCLK Sync. Table1 for VGA]
{SSITX, 0x00000128}, //
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800D4}, // # Command setting of SPI block
{SSITX, 0x00080126}, // # ASW timing control (1) [PCLK Sync. Table1 for VGA]
{SSITX, 0x000001A4}, //
{0, 1}, // wait_ms(1); // # Wait SPI fifo empty
{SSITX, 0x000800D5}, // # Command setting of SPI block
{SSITX, 0x00000120}, // # ASW timing control (2) [PCLK Sync. Table1 for VGA]
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{SSITX, 0x000800EF}, // # Command setting of SPI block
{SSITX, 0x00080132}, // # Total number of horizontal clock cycles (2) [PCLK Sync. Table1 for QVGA ]
{SSITX, 0x00000100}, //
{0, 2}, // wait_ms(2); // # Wait SPI fifo empty
{BITMAP0, 0x032001E0}, // MDC.BITMAP0 ); // Setup of PITCH size to Frame buffer1
{BITMAP1, 0x032001E0}, // MDC.BITMAP1 ); // Setup of PITCH size to Frame buffer1
{BITMAP2, 0x014000F0}, // MDC.BITMAP3 ); // Setup of PITCH size to Frame buffer2
{BITMAP3, 0x014000F0}, // MDC.BITMAP4 ); // Setup of PITCH size to Frame buffer3
{BITMAP4, 0x014000F0}, // MDC.BITMAP5 ); // Setup of PITCH size to Frame buffer4
{CLKENB, 0x000001EB}, // SYS.CLKENB ); // DCLK supply
{PORT_ENB, 0x00000001}, // LCD.PORT_ENB ); // Synchronous port enable
{PORT, 0x00000004}, // LCD.PORT ); // Polarity of DE is set to high active
{PXL, 0x00000002}, // LCD.PXL ); // ACTMODE 2 set (1st frame black data output)
{MPLFBUF, 0x00000000}, // LCD.MPLFBUF ); // Select the reading buffer
{HCYCLE, 0x0000010B}, // LCD.HCYCLE ); // Setup to VGA size
{HSW, 0x00000003}, // LCD.HSW
{HDE_START, 0x00000007}, // LCD.HDE_START
{HDE_SIZE, 0x000000EF}, // LCD.HDE_SIZE
{VCYCLE, 0x00000325}, // LCD.VCYCLE
{VSW, 0x00000001}, // LCD.VSW
{VDE_START, 0x00000003}, // LCD.VDE_START
{VDE_SIZE, 0x0000031F}, // LCD.VDE_SIZE
{START, 0x00000001}, // LCD.START ); // LCDC - Pixel data transfer start
{0, 10}, // wait_ms( 10 );
{SSITX, 0x000800BC}, // SPI.SSITX ); // Command setting of SPI block
{SSITX, 0x00000180}, // Display data setup
{SSITX, 0x0008003B}, // Command setting of SPI block
{SSITX, 0x00000100}, // Quad Data configuration - VGA
{0, 1}, // wait_ms( 1 ); // Wait SPI fifo empty
{SSITX, 0x000800B0}, // Command setting of SPI block
{SSITX, 0x00000116}, // Power supply ON/OFF control
{0, 1}, // wait_ms( 1 ); // Wait SPI fifo empty
{SSITX, 0x000800B8}, // Command setting of SPI block
{SSITX, 0x000801FF}, // Output control
{SSITX, 0x000001F5},
{0, 1}, // wait_ms( 1); // Wait SPI fifo empty
{SSITX, 0x00000011}, // wait_ms(-out (Command only)
{0, 5}, // wait_ms( 1); // Wait SPI fifo empty
{SSITX, 0x00000029}, // Display on (Command only)
//{ SYSTEM_BLOCK1_BASE, 0x00000002 }, // # wakeREQ -> GPIO
{0, 0}
};
void mddi_panel_poweron(void)
{
display_common_power(1);
}
static void _panel_init(struct init_table *init_table)
{
unsigned n;
dprintf(INFO, "panel_init()\n");
n = 0;
while (init_table[n].reg != 0 || init_table[n].val != 0) {
if (init_table[n].reg != 0)
mddi_remote_write(init_table[n].val, init_table[n].reg);
else
mdelay(init_table[n].val);
n++;
}
dprintf(INFO, "panel_init() done\n");
}
void panel_init(struct mddi_client_caps *client_caps)
{
switch (client_caps->manufacturer_name) {
case 0xd263: // Toshiba
dprintf(INFO, "Found Toshiba panel\n");
_panel_init(toshiba_480x800_init_table);
break;
case 0x4474: //??
if (client_caps->product_code == 0xc065)
dprintf(INFO, "Found WVGA panel\n");
break;
}
}
#endif //mddi
void panel_poweron(void)
{
#if DISPLAY_TYPE_LCDC
if (board_machtype() == LINUX_MACHTYPE_7x30_FLUID) {
sharp_lcdc_on();
} else {
panel_backlight(1);
lcdc_on();
}
#endif
}
void panel_backlight(int on)
{
unsigned char reg_data = 0xA0;
if (on)
pmic_write(0x132, reg_data);
else
pmic_write(0x132, 0);
}
static unsigned wega_reset_gpio =
GPIO_CFG(180, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA);
static int display_common_power(int on)
{
int rc = 0, flag_on = !!on;
static int display_common_power_save_on;
unsigned int vreg_ldo12, vreg_ldo15, vreg_ldo20, vreg_ldo16, vreg_ldo8;
if (display_common_power_save_on == flag_on)
return 0;
display_common_power_save_on = flag_on;
if (on) {
/* reset Toshiba WeGA chip -- toggle reset pin -- gpio_180 */
rc = gpio_tlmm_config(wega_reset_gpio, GPIO_ENABLE);
if (rc) {
return rc;
}
gpio_set(180, 0); /* bring reset line low to hold reset */
}
// Set power for WEGA chip.
// Set LD020 to 1.5V
pmic_write(LDO20_CNTRL, 0x00 | LDO_LOCAL_EN_BMSK);
mdelay(5);
// Set LD012 to 1.8V
pmic_write(LDO12_CNTRL, 0x06 | LDO_LOCAL_EN_BMSK);
mdelay(5);
// Set LD016 to 2.6V
pmic_write(LDO16_CNTRL, 0x16 | LDO_LOCAL_EN_BMSK);
mdelay(5);
// Set LD015 to 3.0V
pmic_write(LDO15_CNTRL, 0x1E | LDO_LOCAL_EN_BMSK);
mdelay(5);
gpio_set(180, 1); /* bring reset line high */
mdelay(10); /* 10 msec before IO can be accessed */
if (rc) {
return rc;
}
return rc;
}
#if DISPLAY_TYPE_LCDC
static struct msm_gpio lcd_panel_gpios[] = {
{GPIO_CFG(45, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "spi_clk"},
{GPIO_CFG(46, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "spi_cs0"},
{GPIO_CFG(47, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "spi_mosi"},
{GPIO_CFG(48, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA), "spi_miso"}
};
int lcdc_toshiba_panel_power(int on)
{
int rc, i;
struct msm_gpio *gp;
rc = display_common_power(on);
if (rc < 0) {
return rc;
}
if (on) {
rc = platform_gpios_enable(lcd_panel_gpios,
ARRAY_SIZE(lcd_panel_gpios));
if (rc) {
return rc;
}
} else { /* off */
gp = lcd_panel_gpios;
for (i = 0; i < ARRAY_SIZE(lcd_panel_gpios); i++) {
/* ouput low */
gpio_set(GPIO_PIN(gp->gpio_cfg), 0);
gp++;
}
}
return rc;
}
static void toshiba_spi_write_byte(char dc, unsigned char data)
{
unsigned bit;
int bnum;
gpio_set(SPI_SCLK, 0); /* clk low */
/* dc: 0 for command, 1 for parameter */
gpio_set(SPI_MOSI, dc);
mdelay(1); /* at least 20 ns */
gpio_set(SPI_SCLK, 1); /* clk high */
mdelay(1); /* at least 20 ns */
bnum = 8; /* 8 data bits */
bit = 0x80;
while (bnum) {
gpio_set(SPI_SCLK, 0); /* clk low */
if (data & bit)
gpio_set(SPI_MOSI, 1);
else
gpio_set(SPI_MOSI, 0);
mdelay(1);
gpio_set(SPI_SCLK, 1); /* clk high */
mdelay(1);
bit >>= 1;
bnum--;
}
}
static int toshiba_spi_write(char cmd, unsigned data, int num)
{
char *bp;
gpio_set(SPI_CS, 1); /* cs high */
/* command byte first */
toshiba_spi_write_byte(0, cmd);
/* followed by parameter bytes */
if (num) {
bp = (char *)&data;;
bp += (num - 1);
while (num) {
toshiba_spi_write_byte(1, *bp);
num--;
bp--;
}
}
gpio_set(SPI_CS, 0); /* cs low */
mdelay(1);
return 0;
}
void lcdc_disp_on(void)
{
gpio_set(SPI_CS, 0); /* low */
gpio_set(SPI_SCLK, 1); /* high */
gpio_set(SPI_MOSI, 0);
gpio_set(SPI_MISO, 0);
if (1) {
toshiba_spi_write(0, 0, 0);
mdelay(7);
toshiba_spi_write(0, 0, 0);
mdelay(7);
toshiba_spi_write(0, 0, 0);
mdelay(7);
toshiba_spi_write(0xba, 0x11, 1);
toshiba_spi_write(0x36, 0x00, 1);
mdelay(1);
toshiba_spi_write(0x3a, 0x60, 1);
toshiba_spi_write(0xb1, 0x5d, 1);
mdelay(1);
toshiba_spi_write(0xb2, 0x33, 1);
toshiba_spi_write(0xb3, 0x22, 1);
mdelay(1);
toshiba_spi_write(0xb4, 0x02, 1);
toshiba_spi_write(0xb5, 0x1e, 1); /* vcs -- adjust brightness */
mdelay(1);
toshiba_spi_write(0xb6, 0x27, 1);
toshiba_spi_write(0xb7, 0x03, 1);
mdelay(1);
toshiba_spi_write(0xb9, 0x24, 1);
toshiba_spi_write(0xbd, 0xa1, 1);
mdelay(1);
toshiba_spi_write(0xbb, 0x00, 1);
toshiba_spi_write(0xbf, 0x01, 1);
mdelay(1);
toshiba_spi_write(0xbe, 0x00, 1);
toshiba_spi_write(0xc0, 0x11, 1);
mdelay(1);
toshiba_spi_write(0xc1, 0x11, 1);
toshiba_spi_write(0xc2, 0x11, 1);
mdelay(1);
toshiba_spi_write(0xc3, 0x3232, 2);
mdelay(1);
toshiba_spi_write(0xc4, 0x3232, 2);
mdelay(1);
toshiba_spi_write(0xc5, 0x3232, 2);
mdelay(1);
toshiba_spi_write(0xc6, 0x3232, 2);
mdelay(1);
toshiba_spi_write(0xc7, 0x6445, 2);
mdelay(1);
toshiba_spi_write(0xc8, 0x44, 1);
toshiba_spi_write(0xc9, 0x52, 1);
mdelay(1);
toshiba_spi_write(0xca, 0x00, 1);
mdelay(1);
toshiba_spi_write(0xec, 0x02a4, 2); /* 0x02a4 */
mdelay(1);
toshiba_spi_write(0xcf, 0x01, 1);
mdelay(1);
toshiba_spi_write(0xd0, 0xc003, 2); /* c003 */
mdelay(1);
toshiba_spi_write(0xd1, 0x01, 1);
mdelay(1);
toshiba_spi_write(0xd2, 0x0028, 2);
mdelay(1);
toshiba_spi_write(0xd3, 0x0028, 2);
mdelay(1);
toshiba_spi_write(0xd4, 0x26a4, 2);
mdelay(1);
toshiba_spi_write(0xd5, 0x20, 1);
mdelay(1);
toshiba_spi_write(0xef, 0x3200, 2);
mdelay(32);
toshiba_spi_write(0xbc, 0x80, 1); /* wvga pass through */
toshiba_spi_write(0x3b, 0x00, 1);
mdelay(1);
toshiba_spi_write(0xb0, 0x16, 1);
mdelay(1);
toshiba_spi_write(0xb8, 0xfff5, 2);
mdelay(1);
toshiba_spi_write(0x11, 0, 0);
mdelay(5);
toshiba_spi_write(0x29, 0, 0);
mdelay(5);
}
}
void lcdc_on(void)
{
lcdc_toshiba_panel_power(1);
lcdc_disp_on();
}
struct lcdc_timing_parameters *get_lcd_timing(void)
{
if (board_machtype() == LINUX_MACHTYPE_7x30_FLUID) {
return sharp_timing_param();
} else {
return DEFAULT_LCD_TIMING;
}
}
#endif
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef __PLATFORM_MSM7X30_PANEL_H
#define __PLATFORM_MSM7X30_PANEL_H
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define LDO08_CNTRL 0x011
#define LDO12_CNTRL 0x015
#define LDO15_CNTRL 0x089
#define LDO16_CNTRL 0x08A
#define LDO20_CNTRL 0x11F /* PM8058 only */
#define LDO_LOCAL_EN_BMSK 0x80
#define SPI_SCLK 45
#define SPI_CS 46
#define SPI_MOSI 47
#define SPI_MISO 48
#endif
@@ -0,0 +1,317 @@
/*
* Copyright (c) 2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <debug.h>
#include <dev/gpio.h>
#include <kernel/thread.h>
#include "gpio_hw.h"
#include "panel.h"
#include <dev/lcdc.h>
#define VEE_RESET 20
#define LCD_RESET 180
#define GPIO26_GPIO_CNTRL 0x169 /* backlight */
struct sharp_spi_data {
unsigned addr;
unsigned data;
};
static struct sharp_spi_data init_sequence[] = {
{15, 0x01},
{5, 0x01},
{7, 0x10},
{9, 0x1E},
{10, 0x04},
{17, 0xFF},
{21, 0x8A},
{22, 0x00},
{23, 0x82},
{24, 0x24},
{25, 0x22},
{26, 0x6D},
{27, 0xEB},
{28, 0xB9},
{29, 0x3A},
{49, 0x1A},
{50, 0x16},
{51, 0x05},
{55, 0x7F},
{56, 0x15},
{57, 0x7B},
{60, 0x05},
{61, 0x0C},
{62, 0x80},
{63, 0x00},
{92, 0x90},
{97, 0x01},
{98, 0xFF},
{113, 0x11},
{114, 0x02},
{115, 0x08},
{123, 0xAB},
{124, 0x04},
{6, 0x02},
{133, 0x00},
{134, 0xFE},
{135, 0x22},
{136, 0x0B},
{137, 0xFF},
{138, 0x0F},
{139, 0x00},
{140, 0xFE},
{141, 0x22},
{142, 0x0B},
{143, 0xFF},
{144, 0x0F},
{145, 0x00},
{146, 0xFE},
{147, 0x22},
{148, 0x0B},
{149, 0xFF},
{150, 0x0F},
{202, 0x30},
{30, 0x01},
{4, 0x01},
{31, 0x41}
};
static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
(1 << 6),
(1 << 5),
(1 << 4),
(1 << 3),
(1 << 2),
(1 << 1),
(1 << 0) /* LSB */
};
static unsigned vee_reset_gpio =
GPIO_CFG(VEE_RESET, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA);
static unsigned lcd_reset_gpio =
GPIO_CFG(LCD_RESET, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA);
static int sharp_display_common_power(int on)
{
int rc = 0, flag_on = !!on;
static int display_common_power_save_on;
unsigned int vreg_ldo12, vreg_ldo15, vreg_ldo20, vreg_ldo16, vreg_ldo8;
if (display_common_power_save_on == flag_on)
return 0;
display_common_power_save_on = flag_on;
if (on) {
/* set LCD reset */
rc = gpio_tlmm_config(lcd_reset_gpio, GPIO_ENABLE);
if (rc) {
return rc;
}
gpio_set(LCD_RESET, 0); /* bring reset line low to hold reset */
/* set VEE reset */
rc = gpio_tlmm_config(vee_reset_gpio, GPIO_ENABLE);
if (rc) {
return rc;
}
gpio_set(VEE_RESET, 1);
gpio_set(VEE_RESET, 0); /* bring reset line low to hold reset */
mdelay(10);
}
/* Set LD008 to 1.8V - VEE (VCC, VDDIO, pullups) */
pmic_write(LDO08_CNTRL, 0x06 | LDO_LOCAL_EN_BMSK);
/* Set LD012 to 1.8V - display (VDDIO) */
pmic_write(LDO12_CNTRL, 0x06 | LDO_LOCAL_EN_BMSK);
/* Set LD015 to 3.0V - display (VCC), VEE (VLP) */
pmic_write(LDO15_CNTRL, 0x1E | LDO_LOCAL_EN_BMSK);
/* wait for power to stabilize */
mdelay(10);
gpio_config(VEE_RESET, 0); /*disable VEE_RESET, rely on pullups to bring it high */
mdelay(5);
gpio_set(LCD_RESET, 1); /* bring reset line high */
mdelay(10); /* 10 msec before IO can be accessed */
return rc;
}
static struct msm_gpio sharp_lcd_panel_gpios[] = {
{GPIO_CFG(45, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "spi_clk"},
{GPIO_CFG(46, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "spi_cs0"},
{GPIO_CFG(47, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "spi_mosi"},
{GPIO_CFG(48, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA), "spi_miso"},
{GPIO_CFG(22, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_blu2"},
{GPIO_CFG(25, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_red2"},
{GPIO_CFG(90, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_pclk"},
{GPIO_CFG(91, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en"},
{GPIO_CFG(92, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_vsync"},
{GPIO_CFG(93, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_hsync"},
{GPIO_CFG(94, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_grn2"},
{GPIO_CFG(95, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_grn3"},
{GPIO_CFG(96, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_grn4"},
{GPIO_CFG(97, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_grn5"},
{GPIO_CFG(98, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_grn6"},
{GPIO_CFG(99, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_grn7"},
{GPIO_CFG(100, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_blu3"},
{GPIO_CFG(101, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_blu4"},
{GPIO_CFG(102, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_blu5"},
{GPIO_CFG(103, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_blu6"},
{GPIO_CFG(104, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_blu7"},
{GPIO_CFG(105, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_red3"},
{GPIO_CFG(106, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_red4"},
{GPIO_CFG(107, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_red5"},
{GPIO_CFG(108, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_red6"},
};
int sharp_lcdc_panel_power(int on)
{
int rc, i;
struct msm_gpio *gp;
rc = sharp_display_common_power(on);
if (rc < 0) {
return rc;
}
if (on) {
rc = platform_gpios_enable(sharp_lcd_panel_gpios,
ARRAY_SIZE(sharp_lcd_panel_gpios));
if (rc) {
return rc;
}
} else { /* off */
gp = sharp_lcd_panel_gpios;
for (i = 0; i < ARRAY_SIZE(sharp_lcd_panel_gpios); i++) {
/* ouput low */
gpio_set(GPIO_PIN(gp->gpio_cfg), 0);
gp++;
}
}
return rc;
}
static void sharp_spi_write_byte(unsigned val)
{
int i;
/* Clock should be Low before entering */
for (i = 0; i < 8; i++) {
/* #1: Drive the Data (High or Low) */
if (val & bit_shift[i])
gpio_set(SPI_MOSI, 1);
else
gpio_set(SPI_MOSI, 0);
/* #2: Drive the Clk High and then Low */
gpio_set(SPI_SCLK, 1);
gpio_set(SPI_SCLK, 0);
}
}
static int serigo(unsigned reg, unsigned data)
{
/* Enable the Chip Select - low */
gpio_set(SPI_CS, 0);
udelay(1);
/* Transmit register address first, then data */
sharp_spi_write_byte(reg);
/* Idle state of MOSI is Low */
gpio_set(SPI_MOSI, 0);
udelay(1);
sharp_spi_write_byte(data);
gpio_set(SPI_MOSI, 0);
gpio_set(SPI_CS, 1);
return 0;
}
void sharp_lcdc_disp_on(void)
{
unsigned i;
gpio_set(SPI_CS, 1);
gpio_set(SPI_SCLK, 1);
gpio_set(SPI_MOSI, 0);
gpio_set(SPI_MISO, 0);
for (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
serigo(init_sequence[i].addr, init_sequence[i].data);
}
mdelay(10);
serigo(31, 0xC1);
mdelay(10);
serigo(31, 0xD9);
serigo(31, 0xDF);
}
void sharp_lcdc_on(void)
{
lcdc_clock_init(27648000);
sharp_lcdc_panel_power(1);
/*enable backlight, open up gpio, use default for LPG */
pmic_write(GPIO26_GPIO_CNTRL, 0x81); /* Write, Bank0, VIN0=VPH, Mode selection enabled */
pmic_write(GPIO26_GPIO_CNTRL, 0x99); /* Write, Bank1, OutOn/InOff, CMOS, Invert Output (GPIO High) */
pmic_write(GPIO26_GPIO_CNTRL, 0xAA); /* Write, Bank2, GPIO no pull */
pmic_write(GPIO26_GPIO_CNTRL, 0xB4); /* Write, Bank3, high drv strength */
pmic_write(GPIO26_GPIO_CNTRL, 0xC6); /* Write, Bank4, Src: Special Function 2 */
sharp_lcdc_disp_on();
}
static struct lcdc_timing_parameters param = {
.lcdc_fb_width = 480,
.lcdc_fb_height = 800,
.lcdc_hsync_pulse_width_dclk = 10,
.lcdc_hsync_back_porch_dclk = 20,
.lcdc_hsync_front_porch_dclk = 10,
.lcdc_hsync_skew_dclk = 0,
.lcdc_vsync_pulse_width_lines = 2,
.lcdc_vsync_back_porch_lines = 2,
.lcdc_vsync_front_porch_lines = 2,
};
struct lcdc_timing_parameters *sharp_timing_param()
{
return &param;
}
+189
View File
@@ -0,0 +1,189 @@
/*
* Copyright (c) 2008, Google Inc.
* All rights reserved.
* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <debug.h>
#include <reg.h>
#include <dev/fbcon.h>
#include <kernel/thread.h>
#include <platform/debug.h>
#include <platform/iomap.h>
#include <mddi_hw.h>
#include "gpio_hw.h"
#include <dev/lcdc.h>
void platform_init_interrupts(void);
void platform_init_timer();
void uart2_clock_init(void);
void uart_init(void);
struct fbcon_config *lcdc_init(void);
static uint32_t ticks_per_sec = 0;
#define ARRAY_SIZE(a) (sizeof(a)/(sizeof((a)[0])))
static unsigned uart2_gpio_table[] = {
GPIO_CFG(49, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA),
GPIO_CFG(50, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA),
GPIO_CFG(51, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA),
GPIO_CFG(52, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA),
};
/* CRCI - mmc slot mapping.
* mmc slot numbering start from 1.
* entry at index 0 is just dummy.
*/
uint8_t sdc_crci_map[5] = { 0, 6, 7, 12, 13 };
void uart2_mux_init(void)
{
platform_gpios_enable(uart2_gpio_table, ARRAY_SIZE(uart2_gpio_table));
}
void platform_early_init(void)
{
#if WITH_DEBUG_UART
uart2_mux_init();
uart2_clock_init();
uart_init();
#endif
platform_init_interrupts();
platform_init_timer();
}
void platform_init(void)
{
struct fbcon_config *fb_cfg;
dprintf(INFO, "platform_init()\n");
acpu_clock_init();
adm_enable_clock();
}
void mdp4_display_intf_sel(int output, int intf)
{
unsigned bits, mask;
unsigned dma2_cfg_reg;
bits = readl(MSM_MDP_BASE1 + 0x0038);
mask = 0x03; /* 2 bits */
intf &= 0x03; /* 2 bits */
switch (output) {
case EXTERNAL_INTF_SEL:
intf <<= 4;
mask <<= 4;
break;
case SECONDARY_INTF_SEL:
intf &= 0x02; /* only MDDI and EBI2 support */
intf <<= 2;
mask <<= 2;
break;
default:
break;
}
bits &= ~mask;
bits |= intf;
writel(bits, MSM_MDP_BASE1 + 0x0038); /* MDP_DISP_INTF_SEL */
}
void display_init(void)
{
struct fbcon_config *fb_cfg;
#if DISPLAY_TYPE_MDDI
mddi_pmdh_clock_init();
mddi_panel_poweron();
/* We need to config GPIO 38 for Sleep clock with Spl Fun 2 */
toshiba_pmic_gpio_init(GPIO38_GPIO_CNTRL);
fb_cfg = mddi_init();
fbcon_setup(fb_cfg);
#endif
#if DISPLAY_TYPE_LCDC
if(!machine_is_ffa()) {
struct lcdc_timing_parameters *lcd_timing;
mdp_lcdc_clock_init();
lcd_timing = get_lcd_timing();
fb_cfg = lcdc_init_set(lcd_timing);
panel_poweron();
fbcon_setup(fb_cfg);
}
#endif
}
void display_shutdown(void)
{
#if DISPLAY_TYPE_LCDC
/* Turning off LCDC */
if(!machine_is_ffa()) {
lcdc_shutdown();
}
#endif
}
void platform_uninit(void)
{
#if DISPLAY_SPLASH_SCREEN
display_shutdown();
#endif
platform_uninit_timer();
}
/* Initialize DGT timer */
void platform_init_timer(void)
{
uint32_t val = 0;
/* Disable timer */
writel(0, DGT_ENABLE);
/* Check for the hardware revision */
val = readl(HW_REVISION_NUMBER);
val = (val >> 28) & 0x0F;
if (val >= 1)
writel(1, DGT_CLK_CTL);
#if _EMMC_BOOT
ticks_per_sec = 19200000; /* Uses TCXO (19.2 MHz) */
#else
ticks_per_sec = 6144000; /* Uses LPXO/4 (24.576 MHz / 4) */
#endif
}
/* Returns platform specific ticks per sec */
uint32_t platform_tick_rate(void)
{
return ticks_per_sec;
}
@@ -0,0 +1,108 @@
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <platform/iomap.h>
#include <platform/remote_spinlock.h>
#include <debug.h>
#include <smem.h>
#include <reg.h>
static struct smem *smem = (void *)(MSM_SHARED_BASE);
void *smem_rlock_get_entry(unsigned id, unsigned *size)
{
struct smem_alloc_info *ainfo;
void *ret = 0;
unsigned long flags = 0;
ainfo = &smem->alloc_info[id];
if (readl(&ainfo->allocated) == 0) {
dprintf(SPEW,"Shared memory is not allocated\n");
return ret;
}
/* Read the DAL area */
*size = readl(&ainfo->size);
ret = (void *) (MSM_SHARED_BASE + readl(&ainfo->offset));
return ret;
}
int remote_spinlock_init(remote_spinlock_t *lock)
{
struct rlock_chunk_header *cur_header;
void *rlock_smem_start, *rlock_smem_end;
uint32_t rlock_smem_size = 0;
int smem_status = 0;
rlock_smem_start = smem_rlock_get_entry(SMEM_RLOCK_AREA, &rlock_smem_size);
if (!rlock_smem_start) {
dprintf(CRITICAL,"Failed to get smem entry for remote spin lock\n");
return 1;
}
rlock_smem_end = rlock_smem_start + rlock_smem_size;
cur_header = (struct rlock_chunk_header *)
(((uint32_t)rlock_smem_start + (4095)) & ~4095);
*lock = NULL;
/* Find the lock from the list */
while (cur_header->size != 0
&& ((uint32_t)(cur_header + 1) < (uint32_t)rlock_smem_end)) {
/* If we found the lock, get the address */
if (!strncmp(cur_header->name, RLOCK_CHUNK_NAME,
RLOCK_CHUNK_NAME_LENGTH)) {
*lock = (remote_spinlock_t)&cur_header->lock;
return 0;
}
cur_header = (void *)cur_header + cur_header->size;
}
dprintf(CRITICAL,"%s: remote lock not found: %s\n",RLOCK_CHUNK_NAME,__FILE__);
return 1;
}
void remote_spin_lock(raw_remote_spinlock_t *lock)
{
lock->dek.self_lock = DEK_LOCK_REQUEST;
/* check if the lock is available*/
while(lock->dek.other_lock) {
if(lock->dek.next_yield == DEK_YIELD_TURN_SELF)
while (lock->dek.other_lock);
lock->dek.self_lock = DEK_LOCK_REQUEST;
}
/* We acquired the lock */
lock->dek.next_yield = DEK_YIELD_TURN_SELF;
dmb();
}
void remote_spin_unlock(raw_remote_spinlock_t *lock)
{
dmb();
lock->dek.self_lock = DEK_LOCK_YIELD;
}
@@ -0,0 +1,40 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
ARCH := arm
ARM_CPU := cortex-a8
CPU := generic
DEFINES += ARM_CPU_CORE_SCORPION
MMC_SLOT := 2
DEFINES += WITH_CPU_EARLY_INIT=1 WITH_CPU_WARM_BOOT=1 \
MMC_SLOT=$(MMC_SLOT) MDP4=1
INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/target/$(TARGET)/include
DEVS += fbcon
MODULES += dev/fbcon
OBJS += \
$(LOCAL_DIR)/arch_init.o \
$(LOCAL_DIR)/platform.o \
$(LOCAL_DIR)/interrupts.o \
$(LOCAL_DIR)/gpio.o \
$(LOCAL_DIR)/panel.o \
$(LOCAL_DIR)/panel_sharp_wvga.o \
$(LOCAL_DIR)/acpuclock.o \
$(LOCAL_DIR)/remote_spinlock.o
ifeq ($(ENABLE_TRUSTZONE),1)
ifeq ($(ENABLE_ROMLITE_LOCAL_TEST), 1)
LINKER_SCRIPT += $(BUILDDIR)/trustzone-test-system-onesegment.ld
else
LINKER_SCRIPT += $(BUILDDIR)/trustzone-system-onesegment.ld
endif
else
LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld
endif
include platform/msm_shared/rules.mk