Merge "radio: iris: Add support for FM Subsystem Restart" into msm-3.0
diff --git a/Documentation/devicetree/bindings/mmc/msm_sdcc.txt b/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
index 4fb653e..084050e 100644
--- a/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
+++ b/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
@@ -24,13 +24,13 @@
Example:
- qcom,sdcc@F9600000 {
+ qcom,sdcc@f9600000 {
/* SDC1 used as eMMC slot */
cell-index = <1>;
compatible = "qcom,msm-sdcc";
- reg = <0xF9600000 0x800 // SDCC register interface
- 0xF9600800 0x1800 // DML register interface
- 0xF9602000 0x2000> // BAM register interface
+ reg = <0xf9600000 0x800 // SDCC register interface
+ 0xf9600800 0x1800 // DML register interface
+ 0xf9602000 0x2000> // BAM register interface
interrupts = <123>;
qcom,sdcc-clk-rates = <400000 24000000 48000000>;
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index c1399ae..95ddf34 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -35,16 +35,16 @@
- qcom,hsusb-otg-pmic-id-irq: ID, routed to PMIC IRQ number
Example HSUSB OTG controller device node :
- usb@F9690000 {
+ usb@f9690000 {
compatible = "qcom,hsusb-otg";
- reg = <0xF9690000 0x400>;
+ reg = <0xf9690000 0x400>;
interrupts = <134>;
qcom,hsusb-otg-phy-type = <2>;
qcom,hsusb-otg-mode = <1>;
qcom,hsusb-otg-otg-control = <1>;
qcom,hsusb-otg-default-mode = <2>;
- qcom,hsusb-otg-phy-init-seq = <0x01 0x90 0xFFFFFFFF>;
+ qcom,hsusb-otg-phy-init-seq = <0x01 0x90 0xffffffff>;
qcom,hsusb-otg-power-budget = <500>;
qcom,hsusb-otg-pclk-src-name = "dfab_usb_clk";
qcom,hsusb-otg-pmic-id-irq = <47>
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dts
index 57ad77a..08c16fa 100644
--- a/arch/arm/boot/dts/msmcopper.dts
+++ b/arch/arm/boot/dts/msmcopper.dts
@@ -27,15 +27,15 @@
interrupts = <1 2 0>;
};
- serial@F991F000 {
+ serial@f991f000 {
compatible = "qcom,msm-lsuart-v14";
- reg = <0xF991F000 0x1000>;
+ reg = <0xf991f000 0x1000>;
interrupts = <0 109 0>;
};
- usb@F9A55000 {
+ usb@f9a55000 {
compatible = "qcom,hsusb-otg";
- reg = <0xF9A55000 0x400>;
+ reg = <0xf9a55000 0x400>;
interrupts = <0 134 0>;
qcom,hsusb-otg-phy-type = <2>;
@@ -43,10 +43,10 @@
qcom,hsusb-otg-otg-control = <1>;
};
- qcom,sdcc@F980B000 {
+ qcom,sdcc@f980b000 {
cell-index = <1>;
compatible = "qcom,msm-sdcc";
- reg = <0xF980B000 0x1000>;
+ reg = <0xf980b000 0x1000>;
interrupts = <0 123 0>;
qcom,sdcc-clk-rates = <400000 24000000 48000000>;
@@ -56,10 +56,10 @@
qcom,sdcc-disable_cmd23;
};
- qcom,sdcc@F984B000 {
+ qcom,sdcc@f984b000 {
cell-index = <3>;
compatible = "qcom,msm-sdcc";
- reg = <0xF984B000 0x1000>;
+ reg = <0xf984b000 0x1000>;
interrupts = <0 127 0>;
qcom,sdcc-clk-rates = <400000 24000000 48000000>;
@@ -68,10 +68,10 @@
qcom,sdcc-disable_cmd23;
};
- qcom,sps@F9980000 {
+ qcom,sps@f9980000 {
compatible = "qcom,msm_sps";
- reg = <0xF9984000 0x15000>,
- <0xF9999000 0xB000>;
+ reg = <0xf9984000 0x15000>,
+ <0xf9999000 0xb000>;
interrupts = <0 94 0>;
qcom,bam-dma-res-pipes = <6>;
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 22cf652..95dd09c 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -329,7 +329,7 @@
CONFIG_FB_MSM_OVERLAY=y
CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
CONFIG_FB_MSM_OVERLAY1_WRITEBACK=y
-CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index c38c161..3a70b22 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -331,7 +331,7 @@
CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
CONFIG_FB_MSM_OVERLAY1_WRITEBACK=y
CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
-CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/kernel/perf_event_msm.c b/arch/arm/kernel/perf_event_msm.c
index 4a8e276..0ca5164 100644
--- a/arch/arm/kernel/perf_event_msm.c
+++ b/arch/arm/kernel/perf_event_msm.c
@@ -21,6 +21,8 @@
#define SCORPION_EVT_PREFIX 1
#define SCORPION_MAX_L1_REG 4
+#define SCORPION_EVTYPE_EVENT 0xfffff
+
static u32 scorpion_evt_type_base[] = {0x4c, 0x50, 0x54, 0x58, 0x5c};
enum scorpion_perf_common {
@@ -380,12 +382,14 @@
evtinfo->group_setval = 0x80000000 | (code << (group * 8));
evtinfo->groupcode = reg;
evtinfo->armv7_evt_type = scorpion_evt_type_base[reg] | group;
+
return evtinfo->armv7_evt_type;
}
if (scorpion_evt_type < SCORPION_EVT_START_IDX || scorpion_evt_type >=
(ARRAY_SIZE(scorpion_event) + SCORPION_EVT_START_IDX))
return -EINVAL;
+
idx = scorpion_evt_type - SCORPION_EVT_START_IDX;
if (scorpion_event[idx].scorpion_evt_type == scorpion_evt_type) {
evtinfo->group_setval = scorpion_event[idx].group_setval;
@@ -594,7 +598,7 @@
*/
if (idx != ARMV7_CYCLE_COUNTER) {
val = hwc->config_base;
- val &= ARMV7_EVTYPE_EVENT;
+ val &= SCORPION_EVTYPE_EVENT;
if (val > 0x40) {
event = get_scorpion_evtinfo(val, &evtinfo);
@@ -636,7 +640,7 @@
*/
if (idx != ARMV7_CYCLE_COUNTER) {
val = hwc->config_base;
- val &= ARMV7_EVTYPE_EVENT;
+ val &= SCORPION_EVTYPE_EVENT;
if (val < 0x40) {
armv7_pmnc_write_evtsel(idx, hwc->config_base);
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index f087fbc..0b0f733 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -451,7 +451,15 @@
default y
bool "MSM7627A QRD1"
help
- Support for the Qualcomm MSM7627A Refrence Design.
+ Support for the Qualcomm MSM7627A Reference Design.
+
+config MACH_MSM7627A_QRD3
+ depends on ARCH_MSM7X27A
+ depends on !MSM_STACKED_MEMORY
+ default y
+ bool "MSM7627A QRD3"
+ help
+ Support for the Qualcomm MSM7627A Reference Design.
config MACH_MSM7627A_EVB
depends on ARCH_MSM7X27A
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 2394c47..6bca244 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -38,7 +38,12 @@
obj-$(CONFIG_MSM_SOC_REV_NONE) += acpuclock-8x50.o
endif
-obj-$(CONFIG_SMP) += headsmp.o platsmp.o
+obj-$(CONFIG_SMP) += headsmp.o
+ifdef CONFIG_ARCH_MSM8625
+ obj-$(CONFIG_SMP) += platsmp-8625.o
+else
+ obj-$(CONFIG_SMP) += platsmp.o
+endif
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_MSM_CPU_AVS) += avs.o
@@ -218,6 +223,7 @@
obj-$(CONFIG_MACH_MSM7X27A_SURF) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
obj-$(CONFIG_MACH_MSM7X27A_FFA) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
obj-$(CONFIG_MACH_MSM7627A_QRD1) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7627A_QRD3) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
obj-$(CONFIG_MACH_MSM7627A_EVB) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
obj-$(CONFIG_ARCH_MSM8625) += devices-msm7x27a.o clock-pcom-lookup.o
obj-$(CONFIG_MACH_MSM8625_RUMI3) += board-msm7x27a.o
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index 6140559..7ad3f65 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -757,7 +757,7 @@
res = clk_set_rate(drv_state.ebi1_clk, speed->axiclk_khz * 1000);
if (res < 0)
pr_warning("Setting AXI min rate failed (%d)\n", res);
- res = clk_enable(drv_state.ebi1_clk);
+ res = clk_prepare_enable(drv_state.ebi1_clk);
if (res < 0)
pr_warning("Enabling AXI clock failed (%d)\n", res);
diff --git a/arch/arm/mach-msm/acpuclock-9615.c b/arch/arm/mach-msm/acpuclock-9615.c
index 35eb52b..8882f41 100644
--- a/arch/arm/mach-msm/acpuclock-9615.c
+++ b/arch/arm/mach-msm/acpuclock-9615.c
@@ -323,6 +323,11 @@
if (clocks[i].name) {
clocks[i].clk = clk_get_sys("acpu", clocks[i].name);
BUG_ON(IS_ERR(clocks[i].clk));
+ /*
+ * Prepare the PLLs because we enable/disable them
+ * in atomic context during power collapse/restore.
+ */
+ BUG_ON(clk_prepare(clocks[i].clk));
}
}
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 5ead88c..604769d 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -15,13 +15,14 @@
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/bootmem.h>
+#include <linux/ion.h>
#include <asm/mach-types.h>
#include <mach/msm_memtypes.h>
#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/gpiomux.h>
-#include <linux/ion.h>
#include <mach/ion.h>
+#include <mach/msm_bus_board.h>
#include "devices.h"
#include "board-8064.h"
@@ -134,6 +135,90 @@
#define MDP_VSYNC_GPIO 0
+#ifdef CONFIG_MSM_BUS_SCALING
+static struct msm_bus_vectors mdp_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_MDP_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+};
+
+static struct msm_bus_vectors mdp_ui_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_MDP_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 216000000 * 2,
+ .ib = 270000000 * 2,
+ },
+};
+
+static struct msm_bus_vectors mdp_vga_vectors[] = {
+ /* VGA and less video */
+ {
+ .src = MSM_BUS_MASTER_MDP_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 216000000 * 2,
+ .ib = 270000000 * 2,
+ },
+};
+
+static struct msm_bus_vectors mdp_720p_vectors[] = {
+ /* 720p and less video */
+ {
+ .src = MSM_BUS_MASTER_MDP_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 230400000 * 2,
+ .ib = 288000000 * 2,
+ },
+};
+
+static struct msm_bus_vectors mdp_1080p_vectors[] = {
+ /* 1080p and less video */
+ {
+ .src = MSM_BUS_MASTER_MDP_PORT0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 334080000 * 2,
+ .ib = 417600000 * 2,
+ },
+};
+
+static struct msm_bus_paths mdp_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(mdp_init_vectors),
+ mdp_init_vectors,
+ },
+ {
+ ARRAY_SIZE(mdp_ui_vectors),
+ mdp_ui_vectors,
+ },
+ {
+ ARRAY_SIZE(mdp_ui_vectors),
+ mdp_ui_vectors,
+ },
+ {
+ ARRAY_SIZE(mdp_vga_vectors),
+ mdp_vga_vectors,
+ },
+ {
+ ARRAY_SIZE(mdp_720p_vectors),
+ mdp_720p_vectors,
+ },
+ {
+ ARRAY_SIZE(mdp_1080p_vectors),
+ mdp_1080p_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata mdp_bus_scale_pdata = {
+ mdp_bus_scale_usecases,
+ ARRAY_SIZE(mdp_bus_scale_usecases),
+ .name = "mdp",
+};
+
+#endif
+
static int mdp_core_clk_rate_table[] = {
200000000,
200000000,
@@ -146,6 +231,9 @@
.mdp_core_clk_rate = 200000000,
.mdp_core_clk_table = mdp_core_clk_rate_table,
.num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
+#ifdef CONFIG_MSM_BUS_SCALING
+ .mdp_bus_scale_table = &mdp_bus_scale_pdata,
+#endif
.mdp_rev = MDP_REV_44,
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
.mem_hid = ION_CP_MM_HEAP_ID,
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index 62b7f17..c3cc9eb 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -85,6 +85,20 @@
},
};
+
+static struct gpiomux_setting wcnss_5wire_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting wcnss_5wire_active_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_6MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+
static struct gpiomux_setting slimbus = {
.func = GPIOMUX_FUNC_1,
.drv = GPIOMUX_DRV_8MA,
@@ -479,6 +493,44 @@
},
};
+static struct msm_gpiomux_config wcnss_5wire_interface[] = {
+ {
+ .gpio = 64,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 65,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 66,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 67,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 68,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &wcnss_5wire_active_cfg,
+ [GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+ },
+ },
+};
+
void __init apq8064_init_gpiomux(void)
{
int rc;
@@ -494,6 +546,9 @@
ARRAY_SIZE(apq8064_ethernet_configs));
#endif
+ msm_gpiomux_install(wcnss_5wire_interface,
+ ARRAY_SIZE(wcnss_5wire_interface));
+
msm_gpiomux_install(apq8064_gsbi_configs,
ARRAY_SIZE(apq8064_gsbi_configs));
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index 8a3b958..0b336dd 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -220,7 +220,7 @@
#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
static unsigned int sdc3_sup_clk_rates[] = {
- 400000, 24000000, 48000000, 96000000
+ 400000, 24000000, 48000000, 96000000, 192000000
};
static struct mmc_platform_data sdc3_data = {
@@ -230,6 +230,14 @@
.sup_clk_cnt = ARRAY_SIZE(sdc3_sup_clk_rates),
.pin_data = &mmc_slot_pin_data[SDCC3],
.vreg_data = &mmc_slot_vreg_data[SDCC3],
+ .status_gpio = 26,
+ .status_irq = MSM_GPIO_TO_INT(26),
+ .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ .is_status_gpio_active_low = 1,
+ .xpc_cap = 1,
+ .uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+ MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
+ MMC_CAP_UHS_SDR104 | MMC_CAP_MAX_CURRENT_800),
};
static struct mmc_platform_data *apq8064_sdc3_pdata = &sdc3_data;
#else
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index af2e18c..468c87a 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -30,6 +30,7 @@
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
#include <asm/mach/mmc.h>
+#include <linux/platform_data/qcom_wcnss_device.h>
#include <mach/board.h>
#include <mach/msm_iomap.h>
@@ -728,6 +729,48 @@
},
};
+#define MSM_WCNSS_PHYS 0x03000000
+#define MSM_WCNSS_SIZE 0x280000
+
+static struct resource resources_wcnss_wlan[] = {
+ {
+ .start = RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ,
+ .end = RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ,
+ .name = "wcnss_wlanrx_irq",
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ,
+ .end = RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ,
+ .name = "wcnss_wlantx_irq",
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_WCNSS_PHYS,
+ .end = MSM_WCNSS_PHYS + MSM_WCNSS_SIZE - 1,
+ .name = "wcnss_mmio",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 64,
+ .end = 68,
+ .name = "wcnss_gpios_5wire",
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static struct qcom_wcnss_opts qcom_wcnss_pdata = {
+ .has_48mhz_xo = 1,
+};
+
+static struct platform_device msm_device_wcnss_wlan = {
+ .name = "wcnss_wlan",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resources_wcnss_wlan),
+ .resource = resources_wcnss_wlan,
+ .dev = {.platform_data = &qcom_wcnss_pdata},
+};
+
#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
@@ -1182,7 +1225,6 @@
static struct msm_spm_platform_data msm_spm_l2_data[] __initdata = {
[0] = {
.reg_base_addr = MSM_SAW_L2_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x00A000AE,
@@ -1195,9 +1237,7 @@
static struct msm_spm_platform_data msm_spm_data[] __initdata = {
[0] = {
.reg_base_addr = MSM_SAW0_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1212,9 +1252,7 @@
},
[1] = {
.reg_base_addr = MSM_SAW1_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1229,9 +1267,7 @@
},
[2] = {
.reg_base_addr = MSM_SAW2_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1246,9 +1282,7 @@
},
[3] = {
.reg_base_addr = MSM_SAW3_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1340,6 +1374,7 @@
&apq8064_device_hsusb_host,
&apq8064_device_hsic_host,
&android_usb_device,
+ &msm_device_wcnss_wlan,
#ifdef CONFIG_ANDROID_PMEM
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
&android_pmem_device,
@@ -1398,7 +1433,7 @@
&msm_bus_8064_mm_fabric,
&msm_bus_8064_sys_fpb,
&msm_bus_8064_cpss_fpb,
- &msm_device_vidc,
+ &apq8064_msm_device_vidc,
&msm_8960_riva,
&msm_8960_q6_lpass,
&msm_gss,
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index 2f59d9d..3f9f976 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -225,6 +225,45 @@
.thermal_levels = ARRAY_SIZE(pm8921_therm_mitigation),
};
+#define PM8038_WLED_MAX_CURRENT 25
+
+static struct led_info pm8038_led_info[] = {
+ [0] = {
+ .name = "wled",
+ },
+};
+
+static struct led_platform_data pm8038_led_core_pdata = {
+ .num_leds = ARRAY_SIZE(pm8038_led_info),
+ .leds = pm8038_led_info,
+};
+
+static struct wled_config_data wled_cfg = {
+ .dig_mod_gen_en = true,
+ .cs_out_en = true,
+ .ctrl_delay_us = 0,
+ .op_fdbck = true,
+ .ovp_val = WLED_OVP_32V,
+ .boost_curr_lim = WLED_CURR_LIMIT_525mA,
+ .num_strings = 1,
+};
+
+static struct pm8xxx_led_config pm8038_led_configs[] = {
+ [0] = {
+ .id = PM8XXX_ID_WLED,
+ .mode = PM8XXX_LED_MODE_MANUAL,
+ .max_current = PM8038_WLED_MAX_CURRENT,
+ .default_state = 1,
+ .wled_cfg = &wled_cfg,
+ },
+};
+
+static struct pm8xxx_led_platform_data pm8xxx_leds_pdata = {
+ .led_core = &pm8038_led_core_pdata,
+ .configs = pm8038_led_configs,
+ .num_configs = ARRAY_SIZE(pm8038_led_configs),
+};
+
static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
.r_sense = 10,
};
@@ -252,6 +291,7 @@
.charger_pdata = &pm8921_chg_pdata,
.bms_pdata = &pm8921_bms_pdata,
.adc_pdata = &pm8xxx_adc_pdata,
+ .leds_pdata = &pm8xxx_leds_pdata,
.ccadc_pdata = &pm8xxx_ccadc_pdata,
};
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 90cc3c5..033d92e 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1047,9 +1047,7 @@
static struct msm_spm_platform_data msm_spm_data[] __initdata = {
[0] = {
.reg_base_addr = MSM_SAW0_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1064,9 +1062,7 @@
},
[1] = {
.reg_base_addr = MSM_SAW1_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1120,7 +1116,6 @@
static struct msm_spm_platform_data msm_spm_l2_data[] __initdata = {
[0] = {
.reg_base_addr = MSM_SAW_L2_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x00A000AE,
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index aa8477e..1f6d04f 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -68,6 +68,7 @@
#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME "mipi_cmd_novatek_qhd"
#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME "mipi_video_novatek_qhd"
#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
+#define MIPI_VIDEO_ASUS_WUXGA_PANEL_NAME "mipi_video_asus_wuxga"
#define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME "mipi_video_chimei_wxga"
#define MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME "mipi_video_chimei_wuxga"
#define MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME "mipi_video_simulator_vga"
@@ -81,7 +82,7 @@
}
};
-static void set_mdp_clocks_for_liquid_wuxga(void);
+static void set_mdp_clocks_for_wuxga(void);
static int msm_fb_detect_panel(const char *name)
{
@@ -91,7 +92,7 @@
if (!strncmp(name, MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
strnlen(MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
PANEL_NAME_MAX_LEN))) {
- set_mdp_clocks_for_liquid_wuxga();
+ set_mdp_clocks_for_wuxga();
return 0;
}
} else {
@@ -126,6 +127,13 @@
strnlen(MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
PANEL_NAME_MAX_LEN)))
return 0;
+
+ if (!strncmp(name, MIPI_VIDEO_ASUS_WUXGA_PANEL_NAME,
+ strnlen(MIPI_VIDEO_ASUS_WUXGA_PANEL_NAME,
+ PANEL_NAME_MAX_LEN))) {
+ set_mdp_clocks_for_wuxga();
+ return 0;
+ }
#endif
}
@@ -649,9 +657,9 @@
/**
* Set MDP clocks to high frequency to avoid DSI underflow
- * when using high resolution 1200x1920 WUXGA panel.
+ * when using high resolution 1200x1920 WUXGA panels
*/
-static void set_mdp_clocks_for_liquid_wuxga(void)
+static void set_mdp_clocks_for_wuxga(void)
{
int i;
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 76a27ff..931d7da 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1186,9 +1186,7 @@
static struct msm_spm_platform_data msm_spm_data[] __initdata = {
[0] = {
.reg_base_addr = MSM_SAW0_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0xB0,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1203,9 +1201,7 @@
},
[1] = {
.reg_base_addr = MSM_SAW1_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0xB0,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1259,7 +1255,6 @@
static struct msm_spm_platform_data msm_spm_l2_data[] __initdata = {
[0] = {
.reg_base_addr = MSM_SAW_L2_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x00A000AE,
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index 5acfcd5..c70b30e 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.c
@@ -935,6 +935,9 @@
int i, rc = 0;
struct device *dev;
+ if (machine_is_msm7627a_qrd3())
+ return;
+
gpio_bt_config();
i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index e3f668f..c0b1d16 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -796,6 +796,8 @@
ARRAY_SIZE(camera_devices_qrd));
} else if (machine_is_msm7627a_evb())
return;
+ else if (machine_is_msm7627a_qrd3())
+ return;
else
platform_add_devices(camera_devices_msm,
ARRAY_SIZE(camera_devices_msm));
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index 15f681d..011a4d4 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -843,6 +843,8 @@
else if (machine_is_msm7627a_evb())
platform_add_devices(evb_fb_devices,
ARRAY_SIZE(evb_fb_devices));
+ else if (machine_is_msm7627a_qrd3())
+ return;
else
platform_add_devices(msm_fb_devices,
ARRAY_SIZE(msm_fb_devices));
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index 8eb92a4..d5d8edc 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -1588,15 +1588,17 @@
static struct msm_pm_platform_data msm7x25_pm_data[MSM_PM_SLEEP_MODE_NR] = {
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE].latency = 16000,
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)].latency = 16000,
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN].latency = 12000,
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN)]
+ .latency = 12000,
- [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency = 2000,
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT)]
+ .latency = 2000,
};
static struct msm_pm_platform_data msm7x27_pm_data[MSM_PM_SLEEP_MODE_NR] = {
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 1,
@@ -1605,7 +1607,7 @@
.residency = 20000,
},
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN)] = {
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 1,
@@ -1614,7 +1616,7 @@
.residency = 20000,
},
- [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT)] = {
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 1,
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 0680c44..51da14b 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -326,7 +326,7 @@
};
#endif
static struct msm_pm_platform_data msm7x27a_pm_data[MSM_PM_SLEEP_MODE_NR] = {
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 1,
@@ -334,7 +334,7 @@
.latency = 16000,
.residency = 20000,
},
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN)] = {
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 1,
@@ -342,7 +342,7 @@
.latency = 12000,
.residency = 20000,
},
- [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT)] = {
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 0,
@@ -350,7 +350,7 @@
.latency = 2000,
.residency = 0,
},
- [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 1,
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index e0b3c49..47a4605 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -2907,7 +2907,7 @@
};
static struct msm_pm_platform_data msm_pm_data[MSM_PM_SLEEP_MODE_NR] = {
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 1,
@@ -2915,7 +2915,7 @@
.latency = 8594,
.residency = 23740,
},
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN)] = {
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 1,
@@ -2923,7 +2923,7 @@
.latency = 4594,
.residency = 23740,
},
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
#ifdef CONFIG_MSM_STANDALONE_POWER_COLLAPSE
.idle_supported = 1,
.suspend_supported = 1,
@@ -2938,7 +2938,7 @@
.latency = 500,
.residency = 6000,
},
- [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT)] = {
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 0,
@@ -2946,7 +2946,7 @@
.latency = 443,
.residency = 1098,
},
- [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT] = {
+ [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 1,
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 1222b67..0427632 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -684,6 +684,10 @@
&asoc_msm_dai1,
};
+static struct platform_device *qrd3_devices[] __initdata = {
+ &msm_device_nand,
+};
+
static unsigned pmem_kernel_ebi1_size = PMEM_KERNEL_EBI1_SIZE;
static int __init pmem_kernel_ebi1_size_setup(char *p)
{
@@ -1016,6 +1020,16 @@
return platform_device_register(&msm_wlan_ar6000_pm_device);
}
+static void add_platform_devices(void)
+{
+ platform_add_devices(qrd_common_devices,
+ ARRAY_SIZE(qrd_common_devices));
+
+ if (machine_is_msm7627a_qrd3())
+ platform_add_devices(qrd3_devices,
+ ARRAY_SIZE(qrd3_devices));
+}
+
#define UART1DM_RX_GPIO 45
static void __init msm_qrd_init(void)
{
@@ -1035,8 +1049,7 @@
msm_device_gadget_peripheral.dev.platform_data =
&msm_gadget_pdata;
- platform_add_devices(qrd_common_devices,
- ARRAY_SIZE(qrd_common_devices));
+ add_platform_devices();
/* Ensure ar6000pm device is registered before MMC/SDC */
msm_qrd_init_ar6000pm();
@@ -1075,6 +1088,16 @@
.init_early = qrd7627a_init_early,
.handle_irq = vic_handle_irq,
MACHINE_END
+MACHINE_START(MSM7627A_QRD3, "QRD MSM7627a QRD3")
+ .boot_params = PHYS_OFFSET + 0x100,
+ .map_io = msm_common_io_init,
+ .reserve = msm7627a_reserve,
+ .init_irq = msm_init_irq,
+ .init_machine = msm_qrd_init,
+ .timer = &msm_timer,
+ .init_early = qrd7627a_init_early,
+ .handle_irq = vic_handle_irq,
+MACHINE_END
MACHINE_START(MSM7627A_EVB, "QRD MSM7627a EVB")
.boot_params = PHYS_OFFSET + 0x100,
.map_io = msm_common_io_init,
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 2bd0dcd..b0e616c 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5045,7 +5045,7 @@
CLK_LOOKUP("i2s_spkr_osr_clk", spare_i2s_spkr_osr_clk.c, ""),
CLK_LOOKUP("pcm_clk", pcm_clk.c, ""),
CLK_LOOKUP("sps_slimbus_clk", sps_slimbus_clk.c, ""),
- CLK_LOOKUP("audio_slimbus_clk", audio_slimbus_clk.c, NULL),
+ CLK_LOOKUP("core_clk", audio_slimbus_clk.c, "msm_slim_ctrl.1"),
CLK_LOOKUP("core_clk", jpegd_axi_clk.c, ""),
CLK_LOOKUP("core_clk", vpe_axi_clk.c, ""),
CLK_LOOKUP("core_clk", mdp_axi_clk.c, ""),
@@ -5327,7 +5327,7 @@
CLK_LOOKUP("i2s_spkr_osr_clk", spare_i2s_spkr_osr_clk.c, NULL),
CLK_LOOKUP("pcm_clk", pcm_clk.c, NULL),
CLK_LOOKUP("sps_slimbus_clk", sps_slimbus_clk.c, NULL),
- CLK_LOOKUP("audio_slimbus_clk", audio_slimbus_clk.c, NULL),
+ CLK_LOOKUP("core_clk", audio_slimbus_clk.c, "msm_slim_ctrl.1"),
CLK_LOOKUP("core_clk", jpegd_axi_clk.c, "msm_iommu.0"),
CLK_LOOKUP("core_clk", vpe_axi_clk.c, "msm_iommu.1"),
CLK_LOOKUP("core_clk", mdp_axi_clk.c, "msm_iommu.2"),
@@ -5599,6 +5599,10 @@
/* Local clock driver initialization. */
static void __init msm8960_clock_init(void)
{
+ /* Copy gfx2d's frequency table because it's modified by both clocks */
+ gfx2d1_clk.freq_tbl = kmemdup(clk_tbl_gfx2d,
+ sizeof(struct clk_freq_tbl) * ARRAY_SIZE(clk_tbl_gfx2d),
+ GFP_KERNEL);
if (cpu_is_msm8960()) {
rpm_vreg_id_vdd_dig = RPM_VREG_ID_PM8921_S3;
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 043cdbc..e53d441 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3900,6 +3900,11 @@
}
vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+ /* Copy gfx2d's frequency table because it's modified by both clocks */
+ gfx2d1_clk.freq_tbl = kmemdup(clk_tbl_gfx2d,
+ sizeof(struct clk_freq_tbl) * ARRAY_SIZE(clk_tbl_gfx2d),
+ GFP_KERNEL);
+
/* Initialize clock registers. */
reg_init();
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index ac68d7a..7233a16 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1703,7 +1703,7 @@
CLK_LOOKUP("pcm_clk", pcm_clk.c, NULL),
CLK_LOOKUP("sps_slimbus_clk", sps_slimbus_clk.c, NULL),
- CLK_LOOKUP("audio_slimbus_clk", audio_slimbus_clk.c, NULL),
+ CLK_LOOKUP("core_clk", audio_slimbus_clk.c, "msm_slim_ctrl.1"),
CLK_LOOKUP("core_clk", dfab_usb_hs_clk.c, "msm_otg"),
CLK_LOOKUP("bus_clk", dfab_sdc1_clk.c, "msm_sdcc.1"),
CLK_LOOKUP("bus_clk", dfab_sdc2_clk.c, "msm_sdcc.2"),
@@ -1834,6 +1834,14 @@
regval = readl_relaxed(PMEM_ACLK_CTL_REG);
regval &= ~BIT(6);
writel_relaxed(regval, PMEM_ACLK_CTL_REG);
+
+ /*
+ * Disable hardware clock gating for dma_bam_p_clk, which does
+ * not have working support for the feature.
+ */
+ regval = readl_relaxed(DMA_BAM_HCLK_CTL);
+ regval &= ~BIT(6);
+ writel_relaxed(regval, DMA_BAM_HCLK_CTL);
}
/* Local clock driver initialization. */
diff --git a/arch/arm/mach-msm/cp14.h b/arch/arm/mach-msm/cp14.h
index 9f7241e..d640412 100644
--- a/arch/arm/mach-msm/cp14.h
+++ b/arch/arm/mach-msm/cp14.h
@@ -325,21 +325,21 @@
#define RCP14_ETMACTR14() MRC14(1, c0, c14, 2)
#define RCP14_ETMACTR15() MRC14(1, c0, c15, 2)
#define RCP14_ETMDCVR0() MRC14(1, c0, c0, 3)
-#define RCP14_ETMDCVR1() MRC14(1, c0, c1, 3)
#define RCP14_ETMDCVR2() MRC14(1, c0, c2, 3)
-#define RCP14_ETMDCVR3() MRC14(1, c0, c3, 3)
#define RCP14_ETMDCVR4() MRC14(1, c0, c4, 3)
-#define RCP14_ETMDCVR5() MRC14(1, c0, c5, 3)
#define RCP14_ETMDCVR6() MRC14(1, c0, c6, 3)
-#define RCP14_ETMDCVR7() MRC14(1, c0, c7, 3)
+#define RCP14_ETMDCVR8() MRC14(1, c0, c8, 3)
+#define RCP14_ETMDCVR10() MRC14(1, c0, c10, 3)
+#define RCP14_ETMDCVR12() MRC14(1, c0, c12, 3)
+#define RCP14_ETMDCVR14() MRC14(1, c0, c14, 3)
#define RCP14_ETMDCMR0() MRC14(1, c0, c0, 4)
-#define RCP14_ETMDCMR1() MRC14(1, c0, c1, 4)
#define RCP14_ETMDCMR2() MRC14(1, c0, c2, 4)
-#define RCP14_ETMDCMR3() MRC14(1, c0, c3, 4)
#define RCP14_ETMDCMR4() MRC14(1, c0, c4, 4)
-#define RCP14_ETMDCMR5() MRC14(1, c0, c5, 4)
#define RCP14_ETMDCMR6() MRC14(1, c0, c6, 4)
-#define RCP14_ETMDCMR7() MRC14(1, c0, c7, 4)
+#define RCP14_ETMDCMR8() MRC14(1, c0, c8, 4)
+#define RCP14_ETMDCMR10() MRC14(1, c0, c10, 4)
+#define RCP14_ETMDCMR12() MRC14(1, c0, c12, 4)
+#define RCP14_ETMDCMR14() MRC14(1, c0, c14, 4)
#define RCP14_ETMCNTRLDVR0() MRC14(1, c0, c0, 5)
#define RCP14_ETMCNTRLDVR1() MRC14(1, c0, c1, 5)
#define RCP14_ETMCNTRLDVR2() MRC14(1, c0, c2, 5)
@@ -389,7 +389,7 @@
#define RCP14_ETMAUXCR() MRC14(1, c0, c15, 7)
#define RCP14_ETMTRACEIDR() MRC14(1, c1, c0, 0)
#define RCP14_ETMIDR2() MRC14(1, c1, c2, 0)
-#define RCP14_ETMVMIDCVR() MRC14(1, c1, c1, 0)
+#define RCP14_ETMVMIDCVR() MRC14(1, c1, c0, 1)
#define RCP14_ETMOSLSR() MRC14(1, c1, c1, 4)
/* not available in PFTv1.1 */
#define RCP14_ETMOSSRR() MRC14(1, c1, c2, 4)
@@ -462,21 +462,21 @@
#define WCP14_ETMACTR14(val) MCR14(val, 1, c0, c14, 2)
#define WCP14_ETMACTR15(val) MCR14(val, 1, c0, c15, 2)
#define WCP14_ETMDCVR0(val) MCR14(val, 1, c0, c0, 3)
-#define WCP14_ETMDCVR1(val) MCR14(val, 1, c0, c1, 3)
#define WCP14_ETMDCVR2(val) MCR14(val, 1, c0, c2, 3)
-#define WCP14_ETMDCVR3(val) MCR14(val, 1, c0, c3, 3)
#define WCP14_ETMDCVR4(val) MCR14(val, 1, c0, c4, 3)
-#define WCP14_ETMDCVR5(val) MCR14(val, 1, c0, c5, 3)
#define WCP14_ETMDCVR6(val) MCR14(val, 1, c0, c6, 3)
-#define WCP14_ETMDCVR7(val) MCR14(val, 1, c0, c7, 3)
+#define WCP14_ETMDCVR8(val) MCR14(val, 1, c0, c8, 3)
+#define WCP14_ETMDCVR10(val) MCR14(val, 1, c0, c10, 3)
+#define WCP14_ETMDCVR12(val) MCR14(val, 1, c0, c12, 3)
+#define WCP14_ETMDCVR14(val) MCR14(val, 1, c0, c14, 3)
#define WCP14_ETMDCMR0(val) MCR14(val, 1, c0, c0, 4)
-#define WCP14_ETMDCMR1(val) MCR14(val, 1, c0, c1, 4)
#define WCP14_ETMDCMR2(val) MCR14(val, 1, c0, c2, 4)
-#define WCP14_ETMDCMR3(val) MCR14(val, 1, c0, c3, 4)
#define WCP14_ETMDCMR4(val) MCR14(val, 1, c0, c4, 4)
-#define WCP14_ETMDCMR5(val) MCR14(val, 1, c0, c5, 4)
#define WCP14_ETMDCMR6(val) MCR14(val, 1, c0, c6, 4)
-#define WCP14_ETMDCMR7(val) MCR14(val, 1, c0, c7, 4)
+#define WCP14_ETMDCMR8(val) MCR14(val, 1, c0, c8, 4)
+#define WCP14_ETMDCMR10(val) MCR14(val, 1, c0, c10, 4)
+#define WCP14_ETMDCMR12(val) MCR14(val, 1, c0, c12, 4)
+#define WCP14_ETMDCMR14(val) MCR14(val, 1, c0, c14, 4)
#define WCP14_ETMCNTRLDVR0(val) MCR14(val, 1, c0, c0, 5)
#define WCP14_ETMCNTRLDVR1(val) MCR14(val, 1, c0, c1, 5)
#define WCP14_ETMCNTRLDVR2(val) MCR14(val, 1, c0, c2, 5)
@@ -525,7 +525,7 @@
#define WCP14_ETMAUXCR(val) MCR14(val, 1, c0, c15, 7)
#define WCP14_ETMTRACEIDR(val) MCR14(val, 1, c1, c0, 0)
#define WCP14_ETMIDR2(val) MCR14(val, 1, c1, c2, 0)
-#define WCP14_ETMVMIDCVR(val) MCR14(val, 1, c1, c1, 0)
+#define WCP14_ETMVMIDCVR(val) MCR14(val, 1, c1, c0, 1)
#define WCP14_ETMOSLAR(val) MCR14(val, 1, c1, c0, 4)
/* not available in PFTv1.1 */
#define WCP14_ETMOSSRR(val) MCR14(val, 1, c1, c2, 4)
diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index 81d01c2..56778e2 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -173,6 +173,14 @@
struct cpufreq_work_struct *cpu_work = NULL;
#endif
+ /*
+ * In 8625 both cpu core's frequency can not
+ * be changed independently. Each cpu is bound to
+ * same frequency. Hence set the cpumask to all cpu.
+ */
+ if (cpu_is_msm8625())
+ cpumask_setall(policy->cpus);
+
table = cpufreq_frequency_get_table(policy->cpu);
if (table == NULL)
return -ENODEV;
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 912d1b0..7915b5f 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -28,6 +28,7 @@
#include <mach/msm_bus_board.h>
#include <mach/rpm.h>
#include <mach/mdm2.h>
+#include <linux/ion.h>
#include "clock.h"
#include "devices.h"
#include "msm_watchdog.h"
@@ -305,7 +306,7 @@
};
struct platform_device apq_cpudai_hdmi_rx = {
- .name = "msm-dai-q6",
+ .name = "msm-dai-q6-hdmi",
.id = 8,
};
@@ -590,6 +591,270 @@
},
};
+/* MSM Video core device */
+#ifdef CONFIG_MSM_BUS_SCALING
+static struct msm_bus_vectors vidc_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VIDEO_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_VIDEO_DEC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+};
+static struct msm_bus_vectors vidc_venc_vga_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VIDEO_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 54525952,
+ .ib = 436207616,
+ },
+ {
+ .src = MSM_BUS_MASTER_VIDEO_DEC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 72351744,
+ .ib = 289406976,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 500000,
+ .ib = 1000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 500000,
+ .ib = 1000000,
+ },
+};
+static struct msm_bus_vectors vidc_vdec_vga_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VIDEO_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 40894464,
+ .ib = 327155712,
+ },
+ {
+ .src = MSM_BUS_MASTER_VIDEO_DEC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 48234496,
+ .ib = 192937984,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 500000,
+ .ib = 2000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 500000,
+ .ib = 2000000,
+ },
+};
+static struct msm_bus_vectors vidc_venc_720p_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VIDEO_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 163577856,
+ .ib = 1308622848,
+ },
+ {
+ .src = MSM_BUS_MASTER_VIDEO_DEC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 219152384,
+ .ib = 876609536,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 1750000,
+ .ib = 3500000,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 1750000,
+ .ib = 3500000,
+ },
+};
+static struct msm_bus_vectors vidc_vdec_720p_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VIDEO_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 121634816,
+ .ib = 973078528,
+ },
+ {
+ .src = MSM_BUS_MASTER_VIDEO_DEC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 155189248,
+ .ib = 620756992,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 1750000,
+ .ib = 7000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 1750000,
+ .ib = 7000000,
+ },
+};
+static struct msm_bus_vectors vidc_venc_1080p_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VIDEO_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 372244480,
+ .ib = 2560000000U,
+ },
+ {
+ .src = MSM_BUS_MASTER_VIDEO_DEC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 501219328,
+ .ib = 2560000000U,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 2500000,
+ .ib = 5000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 2500000,
+ .ib = 5000000,
+ },
+};
+static struct msm_bus_vectors vidc_vdec_1080p_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VIDEO_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 222298112,
+ .ib = 2560000000U,
+ },
+ {
+ .src = MSM_BUS_MASTER_VIDEO_DEC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 330301440,
+ .ib = 2560000000U,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 2500000,
+ .ib = 700000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_AMPSS_M0,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 2500000,
+ .ib = 10000000,
+ },
+};
+
+static struct msm_bus_paths vidc_bus_client_config[] = {
+ {
+ ARRAY_SIZE(vidc_init_vectors),
+ vidc_init_vectors,
+ },
+ {
+ ARRAY_SIZE(vidc_venc_vga_vectors),
+ vidc_venc_vga_vectors,
+ },
+ {
+ ARRAY_SIZE(vidc_vdec_vga_vectors),
+ vidc_vdec_vga_vectors,
+ },
+ {
+ ARRAY_SIZE(vidc_venc_720p_vectors),
+ vidc_venc_720p_vectors,
+ },
+ {
+ ARRAY_SIZE(vidc_vdec_720p_vectors),
+ vidc_vdec_720p_vectors,
+ },
+ {
+ ARRAY_SIZE(vidc_venc_1080p_vectors),
+ vidc_venc_1080p_vectors,
+ },
+ {
+ ARRAY_SIZE(vidc_vdec_1080p_vectors),
+ vidc_vdec_1080p_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata vidc_bus_client_data = {
+ vidc_bus_client_config,
+ ARRAY_SIZE(vidc_bus_client_config),
+ .name = "vidc",
+};
+#endif
+
+
+#define APQ8064_VIDC_BASE_PHYS 0x04400000
+#define APQ8064_VIDC_BASE_SIZE 0x00100000
+
+static struct resource apq8064_device_vidc_resources[] = {
+ {
+ .start = APQ8064_VIDC_BASE_PHYS,
+ .end = APQ8064_VIDC_BASE_PHYS + APQ8064_VIDC_BASE_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = VCODEC_IRQ,
+ .end = VCODEC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct msm_vidc_platform_data apq8064_vidc_platform_data = {
+#ifdef CONFIG_MSM_BUS_SCALING
+ .vidc_bus_client_pdata = &vidc_bus_client_data,
+#endif
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ .memtype = ION_CP_MM_HEAP_ID,
+ .enable_ion = 1,
+#else
+ .memtype = MEMTYPE_EBI1,
+ .enable_ion = 0,
+#endif
+ .disable_dmx = 0,
+ .disable_fullhd = 0,
+};
+
+struct platform_device apq8064_msm_device_vidc = {
+ .name = "msm_vidc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(apq8064_device_vidc_resources),
+ .resource = apq8064_device_vidc_resources,
+ .dev = {
+ .platform_data = &apq8064_vidc_platform_data,
+ },
+};
#define MSM_SDC1_BASE 0x12400000
#define MSM_SDC1_DML_BASE (MSM_SDC1_BASE + 0x800)
#define MSM_SDC1_BAM_BASE (MSM_SDC1_BASE + 0x2000)
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index fc732da..e9b94f6 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -1181,6 +1181,7 @@
.set_grp_async = set_grp3d_async,
.idle_timeout = HZ/20,
.nap_allowed = true,
+ .idle_needed = true,
.clk_map = KGSL_CLK_SRC | KGSL_CLK_CORE |
KGSL_CLK_IFACE | KGSL_CLK_MEM,
};
@@ -1223,6 +1224,7 @@
.set_grp_async = NULL,
.idle_timeout = HZ/10,
.nap_allowed = true,
+ .idle_needed = true,
.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE,
};
diff --git a/arch/arm/mach-msm/devices-msm8x60.h b/arch/arm/mach-msm/devices-msm8x60.h
index a2f6a1f..9bfaeee 100644
--- a/arch/arm/mach-msm/devices-msm8x60.h
+++ b/arch/arm/mach-msm/devices-msm8x60.h
@@ -56,6 +56,7 @@
extern struct platform_device msm_device_smd;
extern struct platform_device msm_device_gpio;
extern struct platform_device msm_device_vidc;
+extern struct platform_device apq8064_msm_device_vidc;
extern struct platform_device msm_charm_modem;
extern struct platform_device msm_device_tz_log;
diff --git a/arch/arm/mach-msm/etm.c b/arch/arm/mach-msm/etm.c
index bee0975..9d04a58 100644
--- a/arch/arm/mach-msm/etm.c
+++ b/arch/arm/mach-msm/etm.c
@@ -377,9 +377,9 @@
etm_write(etm_config.etm_addr_access_type[6], ETMACTR6);
etm_write(etm_config.etm_addr_access_type[7], ETMACTR7);
etm_write(etm_config.etm_data_comp_value[0], ETMDCVR0);
- etm_write(etm_config.etm_data_comp_value[1], ETMDCVR1);
+ etm_write(etm_config.etm_data_comp_value[1], ETMDCVR2);
etm_write(etm_config.etm_data_comp_mask[0], ETMDCMR0);
- etm_write(etm_config.etm_data_comp_mask[1], ETMDCMR1);
+ etm_write(etm_config.etm_data_comp_mask[1], ETMDCMR2);
etm_write(etm_config.etm_counter_reload_value[0], ETMCNTRLDVR0);
etm_write(etm_config.etm_counter_reload_value[1], ETMCNTRLDVR1);
etm_write(etm_config.etm_counter_enable[0], ETMCNTENR0);
@@ -564,9 +564,9 @@
emit_log_word(etm_read(ETMACTR6));
emit_log_word(etm_read(ETMACTR7));
emit_log_word(etm_read(ETMDCVR0));
- emit_log_word(etm_read(ETMDCVR1));
+ emit_log_word(etm_read(ETMDCVR2));
emit_log_word(etm_read(ETMDCMR0));
- emit_log_word(etm_read(ETMDCMR1));
+ emit_log_word(etm_read(ETMDCMR2));
emit_log_word(etm_read(ETMCNTRLDVR0));
emit_log_word(etm_read(ETMCNTRLDVR1));
emit_log_word(etm_read(ETMCNTENR0));
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index 26adec6..616763c 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -49,6 +49,9 @@
/*
* OK, proper wakeup, we're done
*/
+ pen_release = -1;
+ dmac_flush_range((void *)&pen_release,
+ (void *)(&pen_release + sizeof(pen_release)));
break;
}
@@ -60,6 +63,8 @@
* possible, since we are currently running incoherently, and
* therefore cannot safely call printk() or anything else
*/
+ dmac_inv_range((void *)&pen_release,
+ (void *)(&pen_release + sizeof(pen_release)));
pr_debug("CPU%u: spurious wakeup call\n", cpu);
}
}
diff --git a/arch/arm/mach-msm/idle-v7.S b/arch/arm/mach-msm/idle-v7.S
index 631d520..c274899 100644
--- a/arch/arm/mach-msm/idle-v7.S
+++ b/arch/arm/mach-msm/idle-v7.S
@@ -106,12 +106,6 @@
sub r1, r1, r0
bl v7_flush_kern_dcache_area
- mrc p15, 0, r4, c1, c0, 0 /* read current CR */
- bic r0, r4, #(1 << 2) /* clear dcache bit */
- bic r0, r0, #(1 << 12) /* clear icache bit */
- mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */
-
- dsb
#ifdef CONFIG_ARCH_MSM_KRAIT
ldr r0, =SCM_SVC_BOOT
ldr r1, =SCM_CMD_TERMINATE_PC
@@ -119,10 +113,18 @@
ldr r2, [r2]
bl scm_call_atomic1
#else
+ mrc p15, 0, r4, c1, c0, 0 /* read current CR */
+ bic r0, r4, #(1 << 2) /* clear dcache bit */
+ bic r0, r0, #(1 << 12) /* clear icache bit */
+ mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */
+ dsb
+
wfi
-#endif
+
mcr p15, 0, r4, c1, c0, 0 /* restore d/i cache */
isb
+#endif
+
#if defined(CONFIG_MSM_FIQ_SUPPORT)
cpsie f
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 530d2c1..700e28c 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -52,6 +52,7 @@
VFE_MODE_OF_OPERATION_VIDEO,
VFE_MODE_OF_OPERATION_RAW_SNAPSHOT,
VFE_MODE_OF_OPERATION_ZSL,
+ VFE_MODE_OF_OPERATION_JPEG_SNAPSHOT,
VFE_LAST_MODE_OF_OPERATION_ENUM
};
@@ -87,6 +88,7 @@
VFE_MSG_V32_START,
VFE_MSG_V32_START_RECORDING, /* 20 */
VFE_MSG_V32_CAPTURE,
+ VFE_MSG_V32_JPEG_CAPTURE,
VFE_MSG_OUTPUT_IRQ,
VFE_MSG_V2X_PREVIEW,
VFE_MSG_V2X_CAPTURE,
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h b/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
index 88bc3c6..4c26d08 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
@@ -44,9 +44,6 @@
#define MSM7XXX_TMR_PHYS MSM7XXX_CSR_PHYS
#define MSM7XXX_TMR_SIZE SZ_4K
-#define MSM7XXX_TMR0_PHYS 0xC0800000
-#define MSM7XXX_TMR0_SIZE SZ_4K
-
#define MSM7XXX_GPIO1_PHYS 0xA9200000
#define MSM7XXX_GPIO1_SIZE SZ_4K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8625.h b/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
index 8088a4c..3435c2a 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
@@ -48,11 +48,11 @@
#define MSM8625_SCU_PHYS 0xC0600000
#define MSM8625_SCU_SIZE SZ_256
-#define MSM8625_SPM0_PHYS 0xC0200000
-#define MSM8625_SPM0_SIZE SZ_4K
+#define MSM8625_SAW0_PHYS 0xC0200000
+#define MSM8625_SAW0_SIZE SZ_4K
-#define MSM8625_SPM1_PHYS 0xC0700000
-#define MSM8625_SPM1_SIZE SZ_4K
+#define MSM8625_SAW1_PHYS 0xC0700000
+#define MSM8625_SAW1_SIZE SZ_4K
#define MSM8625_CFG_CTL_PHYS 0xA9800000
#define MSM8625_CFG_CTL_SIZE SZ_4K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index bb2b019..7715811 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -48,7 +48,7 @@
#if defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_APQ8064) || \
defined(CONFIG_ARCH_MSM8930) || defined(CONFIG_ARCH_MSM9615) || \
defined(CONFIG_ARCH_MSMCOPPER) || defined(CONFIG_ARCH_MSM7X27) || \
- defined(CONFIG_ARCH_MSM7X01A) || defined(CONFIG_ARCH_MSM7X25) || \
+ defined(CONFIG_ARCH_MSM7X25) || defined(CONFIG_ARCH_MSM7X01A) || \
defined(CONFIG_ARCH_MSM8625)
/* Unified iomap */
@@ -82,34 +82,33 @@
#define MSM_APCS_GLB_BASE IOMEM(0xFA702000) /* 4K */
#define MSM_SAW2_BASE IOMEM(0xFA703000) /* 4k */
#define MSM_SAW3_BASE IOMEM(0xFA704000) /* 4k */
-#define MSM_VIC_BASE IOMEM(0xFA705000) /* 4K */
-#define MSM_CSR_BASE MSM_TMR_BASE /* 4K */
-#define MSM_GPIO1_BASE IOMEM(0xFA706000) /* 4K */
-#define MSM_GPIO2_BASE IOMEM(0xFA707000) /* 4K */
-#define MSM_SCU_BASE IOMEM(0xFA708000) /* 4K */
-#define MSM_SPM0_BASE IOMEM(0xFA709000) /* 4K */
-#define MSM_SPM1_BASE IOMEM(0xFA70A000) /* 4K */
-#define MSM_CFG_CTL_BASE IOMEM(0xFA70B000) /* 4K */
-#define MSM_MDC_BASE IOMEM(0xFA70C000) /* 4K */
-#define MSM_AD5_BASE IOMEM(0xFA70D000) /* 4K */
-
+#define MSM_VIC_BASE IOMEM(0xFA100000) /* 4K */
+#define MSM_CSR_BASE IOMEM(0xFA101000) /* 4K */
+#define MSM_GPIO1_BASE IOMEM(0xFA102000) /* 4K */
+#define MSM_GPIO2_BASE IOMEM(0xFA103000) /* 4K */
+#define MSM_SCU_BASE IOMEM(0xFA102000) /* 4K */
+#define MSM_CFG_CTL_BASE IOMEM(0xFA00C000) /* 4K */
+#define MSM_MDC_BASE IOMEM(0xFA400000) /* 1M */
+#define MSM_AD5_BASE IOMEM(0xFA900000) /* 13M (D00000)
+ 0xFB600000 */
#define MSM_STRONGLY_ORDERED_PAGE 0xFA0F0000
#define MSM8625_SECONDARY_PHYS 0x0FE00000
+
#if defined(CONFIG_ARCH_MSM9615) || defined(CONFIG_ARCH_MSM7X27)
#define MSM_SHARED_RAM_SIZE SZ_1M
#else
#define MSM_SHARED_RAM_SIZE SZ_2M
#endif
+#include "msm_iomap-7xxx.h"
+#include "msm_iomap-8625.h"
#include "msm_iomap-8960.h"
#include "msm_iomap-8930.h"
#include "msm_iomap-8064.h"
#include "msm_iomap-9615.h"
#include "msm_iomap-copper.h"
-#include "msm_iomap-7xxx.h"
-#include "msm_iomap-8625.h"
#else
/* Legacy single-target iomap */
@@ -123,7 +122,7 @@
#elif defined(CONFIG_ARCH_FSM9XXX)
#include "msm_iomap-fsm9xxx.h"
#else
-#error "Target compiling without iomap"
+#error "Target compiled without IO map\n"
#endif
#if defined(CONFIG_DEBUG_MSM_UART1)
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 830db1f..507b74b 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -410,8 +410,8 @@
MSM_CHIP_DEVICE(SCU, MSM8625),
MSM_CHIP_DEVICE(CFG_CTL, MSM8625),
MSM_CHIP_DEVICE(CLK_CTL, MSM8625),
- MSM_CHIP_DEVICE(SPM0, MSM8625),
- MSM_CHIP_DEVICE(SPM1, MSM8625),
+ MSM_CHIP_DEVICE(SAW0, MSM8625),
+ MSM_CHIP_DEVICE(SAW1, MSM8625),
#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
defined(CONFIG_DEBUG_MSM_UART3)
MSM_CHIP_DEVICE(DEBUG_UART, MSM7XXX),
diff --git a/arch/arm/mach-msm/jtag.c b/arch/arm/mach-msm/jtag.c
index f720fa9..b75fb38 100644
--- a/arch/arm/mach-msm/jtag.c
+++ b/arch/arm/mach-msm/jtag.c
@@ -22,8 +22,10 @@
#include "qdss.h"
#include "cp14.h"
+ /* no of dbg regs + 1 (for storing the reg count) */
#define MAX_DBG_REGS (90)
#define MAX_DBG_STATE_SIZE (MAX_DBG_REGS * num_possible_cpus())
+ /* no of etm regs + 1 (for storing the reg count) */
#define MAX_ETM_REGS (78)
#define MAX_ETM_STATE_SIZE (MAX_ETM_REGS * num_possible_cpus())
@@ -70,7 +72,7 @@
break;
case 3:
state[i++] = dbg_read(DBGBVR3);
- state[i++] = dbg_read(DBGBVR3);
+ state[i++] = dbg_read(DBGBCR3);
break;
case 4:
state[i++] = dbg_read(DBGBVR4);
@@ -78,7 +80,7 @@
break;
case 5:
state[i++] = dbg_read(DBGBVR5);
- state[i++] = dbg_read(DBGBVR5);
+ state[i++] = dbg_read(DBGBCR5);
break;
case 6:
state[i++] = dbg_read(DBGBVR6);
@@ -143,7 +145,7 @@
break;
case 3:
dbg_write(state[i++], DBGBVR3);
- dbg_write(state[i++], DBGBVR3);
+ dbg_write(state[i++], DBGBCR3);
break;
case 4:
dbg_write(state[i++], DBGBVR4);
@@ -151,7 +153,7 @@
break;
case 5:
dbg_write(state[i++], DBGBVR5);
- dbg_write(state[i++], DBGBVR5);
+ dbg_write(state[i++], DBGBCR5);
break;
case 6:
dbg_write(state[i++], DBGBVR6);
@@ -937,9 +939,9 @@
etm_write(etm.state[i++], ETMSQ12EVR);
etm_write(etm.state[i++], ETMSQ21EVR);
etm_write(etm.state[i++], ETMSQ23EVR);
+ etm_write(etm.state[i++], ETMSQ31EVR);
etm_write(etm.state[i++], ETMSQ32EVR);
etm_write(etm.state[i++], ETMSQ13EVR);
- etm_write(etm.state[i++], ETMSQ31EVR);
etm_write(etm.state[i++], ETMSQR);
for (j = 0; j < etm.nr_ext_out; j++)
i = etm_write_extoutevr(etm.state, i, j);
@@ -1046,9 +1048,9 @@
pr_info("dbg arch %u not supported\n", dbg.arch);
goto dbg_out;
}
- dbg.nr_ctx_cmp = BMVAL(dbgdidr, 20, 23);
- dbg.nr_bp = BMVAL(dbgdidr, 24, 27);
- dbg.nr_wp = BMVAL(dbgdidr, 28, 31);
+ dbg.nr_ctx_cmp = BMVAL(dbgdidr, 20, 23) + 1;
+ dbg.nr_bp = BMVAL(dbgdidr, 24, 27) + 1;
+ dbg.nr_wp = BMVAL(dbgdidr, 28, 31) + 1;
/* Allocate dbg state save space */
dbg.state = kzalloc(MAX_DBG_STATE_SIZE * sizeof(uint32_t), GFP_KERNEL);
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 3b064ff..d26d76b 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -1,7 +1,7 @@
/* arch/arm/mach-msm/memory.c
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -226,6 +226,25 @@
return unstable_limit - mb->start;
}
+/* stable size of all memory banks contiguous to and below this one */
+static unsigned long total_stable_size(unsigned long bank)
+{
+ int i;
+ struct membank *mb = &meminfo.bank[bank];
+ int memtype = reserve_info->paddr_to_memtype(mb->start);
+ unsigned long size;
+
+ size = stable_size(mb, reserve_info->low_unstable_address);
+ for (i = bank - 1, mb = &meminfo.bank[bank - 1]; i >= 0; i--, mb--) {
+ if (mb->start + mb->size != (mb + 1)->start)
+ break;
+ if (reserve_info->paddr_to_memtype(mb->start) != memtype)
+ break;
+ size += stable_size(mb, reserve_info->low_unstable_address);
+ }
+ return size;
+}
+
static void __init calculate_reserve_limits(void)
{
int i;
@@ -242,7 +261,7 @@
continue;
}
mt = &reserve_info->memtype_reserve_table[memtype];
- size = stable_size(mb, reserve_info->low_unstable_address);
+ size = total_stable_size(i);
mt->limit = max(mt->limit, size);
}
}
@@ -277,10 +296,11 @@
if (mt->flags & MEMTYPE_FLAGS_FIXED || !mt->size)
continue;
- /* We know we will find a memory bank of the proper size
+ /* We know we will find memory bank(s) of the proper size
* as we have limited the size of the memory pool for
- * each memory type to the size of the largest memory
- * bank. Choose the memory bank with the highest physical
+ * each memory type to the largest total size of the memory
+ * banks which are contiguous and of the correct memory type.
+ * Choose the memory bank with the highest physical
* address which is large enough, so that we will not
* take memory from the lowest memory bank which the kernel
* is in (and cause boot problems) and so that we might
@@ -293,9 +313,14 @@
reserve_info->paddr_to_memtype(mb->start);
if (memtype != membank_type)
continue;
- size = stable_size(mb,
- reserve_info->low_unstable_address);
+ size = total_stable_size(i);
if (size >= mt->size) {
+ size = stable_size(mb,
+ reserve_info->low_unstable_address);
+ /* mt->size may be larger than size, all this
+ * means is that we are carving the memory pool
+ * out of multiple contiguous memory banks.
+ */
mt->start = mb->start + (size - mt->size);
ret = memblock_remove(mt->start, mt->size);
BUG_ON(ret);
diff --git a/arch/arm/mach-msm/platsmp-8625.c b/arch/arm/mach-msm/platsmp-8625.c
new file mode 100644
index 0000000..534fc0e
--- /dev/null
+++ b/arch/arm/mach-msm/platsmp-8625.c
@@ -0,0 +1,202 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/smp_scu.h>
+#include <asm/unified.h>
+#include <mach/msm_iomap.h>
+#include <mach/smp.h>
+#include "pm.h"
+
+#define MSM_CORE1_RESET 0xA8600590
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+int pen_release = -1;
+
+static bool cold_boot_done;
+
+static uint32_t *msm8625_boot_vector;
+
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably.
+ */
+static void __cpuinit write_pen_release(int val)
+{
+ pen_release = val;
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+ outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static void __iomem *scu_base_addr(void)
+{
+ return MSM_SCU_BASE;
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ /*
+ * if any interrupts are already enabled for the primary
+ * core (e.g. timer irq), then they will not have been enabled
+ * for us: do so
+ */
+ gic_secondary_init(0);
+
+ /*
+ * let the primary processor know we're out of the
+ * pen, then head off into the C entry point
+ */
+ write_pen_release(-1);
+
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long timeout;
+ void __iomem *base_ptr;
+
+ if (cold_boot_done == false) {
+ base_ptr = ioremap_nocache(MSM_CORE1_RESET, SZ_4);
+ if (!base_ptr)
+ return -ENODEV;
+ /* Reset core 1 out of reset */
+ __raw_writel(0x0, base_ptr);
+ mb();
+ cold_boot_done = true;
+ iounmap(base_ptr);
+ }
+
+ /*
+ * Set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * This is really belt and braces; we hold unintended secondary
+ * CPUs in the holding pen until we're ready for them. However,
+ * since we haven't sent them a soft interrupt, they shouldn't
+ * be there.
+ */
+ write_pen_release(cpu);
+
+ /*
+ * Send the secondary CPU a soft interrupt, thereby causing
+ * the boot monitor to read the system wide flags register,
+ * and branch to the address found there.
+ */
+ gic_raise_softirq(cpumask_of(cpu), 1);
+
+ timeout = jiffies + (1 * HZ);
+ while (time_before(jiffies, timeout)) {
+ smp_rmb();
+ if (pen_release == -1)
+ break;
+
+ udelay(10);
+ }
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+ void __iomem *scu_base = scu_base_addr();
+
+ unsigned int i, ncores;
+
+ ncores = scu_base ? scu_get_core_count(scu_base) : 1;
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+static void __init msm8625_boot_vector_init(uint32_t *boot_vector,
+ unsigned long entry)
+{
+ if (!boot_vector)
+ return;
+ msm8625_boot_vector = boot_vector;
+
+ msm8625_boot_vector[0] = 0xE51FF004; /* ldr pc, 4 */
+ msm8625_boot_vector[1] = entry;
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i, value;
+ void __iomem *second_ptr;
+
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time.
+ */
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ scu_enable(scu_base_addr());
+
+ /*
+ * Write the address of secondary startup into the
+ * boot remapper register. The secondary CPU branches to this address.
+ */
+ __raw_writel(MSM8625_SECONDARY_PHYS, (MSM_CFG_CTL_BASE + 0x34));
+ mb();
+
+ second_ptr = ioremap_nocache(MSM8625_SECONDARY_PHYS, SZ_8);
+ if (!second_ptr) {
+ pr_err("failed to ioremap for secondary core\n");
+ return;
+ }
+
+ msm8625_boot_vector_init(second_ptr,
+ virt_to_phys(msm_secondary_startup));
+ iounmap(second_ptr);
+
+ /* Enable boot remapper address: bit 26 for core1 */
+ value = __raw_readl(MSM_CFG_CTL_BASE + 0x30);
+ __raw_writel(value | (0x4 << 24), MSM_CFG_CTL_BASE + 0x30) ;
+ mb();
+}
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 4cdd7ae..e1934bb 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -3,7 +3,7 @@
* MSM Power Management Routines
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012 Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -118,18 +118,6 @@
* Sleep Modes and Parameters
*****************************************************************************/
-static int msm_pm_sleep_mode = CONFIG_MSM7X00A_SLEEP_MODE;
-module_param_named(
- sleep_mode, msm_pm_sleep_mode,
- int, S_IRUGO | S_IWUSR | S_IWGRP
-);
-
-static int msm_pm_idle_sleep_mode = CONFIG_MSM7X00A_IDLE_SLEEP_MODE;
-module_param_named(
- idle_sleep_mode, msm_pm_idle_sleep_mode,
- int, S_IRUGO | S_IWUSR | S_IWGRP
-);
-
static int msm_pm_idle_sleep_min_time = CONFIG_MSM7X00A_IDLE_SLEEP_MIN_TIME;
module_param_named(
idle_sleep_min_time, msm_pm_idle_sleep_min_time,
@@ -166,10 +154,20 @@
static struct msm_pm_platform_data *msm_pm_modes;
-static struct kobject *msm_pm_mode_kobjs[MSM_PM_SLEEP_MODE_NR];
-static struct attribute_group *msm_pm_mode_attr_group[MSM_PM_SLEEP_MODE_NR];
-static struct attribute **msm_pm_mode_attrs[MSM_PM_SLEEP_MODE_NR];
-static struct kobj_attribute *msm_pm_mode_kobj_attrs[MSM_PM_SLEEP_MODE_NR];
+struct msm_pm_kobj_attribute {
+ unsigned int cpu;
+ struct kobj_attribute ka;
+};
+
+#define GET_CPU_OF_ATTR(attr) \
+ (container_of(attr, struct msm_pm_kobj_attribute, ka)->cpu)
+
+struct msm_pm_sysfs_sleep_mode {
+ struct kobject *kobj;
+ struct attribute_group attr_group;
+ struct attribute *attrs[MSM_PM_MODE_ATTR_NR + 1];
+ struct msm_pm_kobj_attribute kas[MSM_PM_MODE_ATTR_NR];
+};
/*
* Write out the attribute.
@@ -182,6 +180,8 @@
for (i = 0; i < MSM_PM_SLEEP_MODE_NR; i++) {
struct kernel_param kp;
+ unsigned int cpu;
+ struct msm_pm_platform_data *mode;
if (msm_pm_sleep_mode_labels[i] == NULL)
continue;
@@ -189,23 +189,28 @@
if (strcmp(kobj->name, msm_pm_sleep_mode_labels[i]))
continue;
+ cpu = GET_CPU_OF_ATTR(attr);
+ mode = &msm_pm_modes[MSM_PM_MODE(cpu, i)];
+
if (!strcmp(attr->attr.name,
msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_SUSPEND])) {
- u32 arg = msm_pm_modes[i].suspend_enabled;
+ u32 arg = mode->suspend_enabled;
kp.arg = &arg;
ret = param_get_ulong(buf, &kp);
} else if (!strcmp(attr->attr.name,
msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_IDLE])) {
- u32 arg = msm_pm_modes[i].idle_enabled;
+ u32 arg = mode->idle_enabled;
kp.arg = &arg;
ret = param_get_ulong(buf, &kp);
} else if (!strcmp(attr->attr.name,
msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_LATENCY])) {
- kp.arg = &msm_pm_modes[i].latency;
+ u32 arg = mode->latency;
+ kp.arg = &arg;
ret = param_get_ulong(buf, &kp);
} else if (!strcmp(attr->attr.name,
msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_RESIDENCY])) {
- kp.arg = &msm_pm_modes[i].residency;
+ u32 arg = mode->residency;
+ kp.arg = &arg;
ret = param_get_ulong(buf, &kp);
}
@@ -213,7 +218,7 @@
}
if (ret > 0) {
- strcat(buf, "\n");
+ strlcat(buf, "\n", PAGE_SIZE);
ret++;
}
@@ -231,6 +236,8 @@
for (i = 0; i < MSM_PM_SLEEP_MODE_NR; i++) {
struct kernel_param kp;
+ unsigned int cpu;
+ struct msm_pm_platform_data *mode;
if (msm_pm_sleep_mode_labels[i] == NULL)
continue;
@@ -238,21 +245,24 @@
if (strcmp(kobj->name, msm_pm_sleep_mode_labels[i]))
continue;
+ cpu = GET_CPU_OF_ATTR(attr);
+ mode = &msm_pm_modes[MSM_PM_MODE(cpu, i)];
+
if (!strcmp(attr->attr.name,
msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_SUSPEND])) {
- kp.arg = &msm_pm_modes[i].suspend_enabled;
+ kp.arg = &mode->suspend_enabled;
ret = param_set_byte(buf, &kp);
} else if (!strcmp(attr->attr.name,
msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_IDLE])) {
- kp.arg = &msm_pm_modes[i].idle_enabled;
+ kp.arg = &mode->idle_enabled;
ret = param_set_byte(buf, &kp);
} else if (!strcmp(attr->attr.name,
msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_LATENCY])) {
- kp.arg = &msm_pm_modes[i].latency;
+ kp.arg = &mode->latency;
ret = param_set_ulong(buf, &kp);
} else if (!strcmp(attr->attr.name,
msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_RESIDENCY])) {
- kp.arg = &msm_pm_modes[i].residency;
+ kp.arg = &mode->residency;
ret = param_set_ulong(buf, &kp);
}
@@ -262,6 +272,86 @@
return ret ? ret : count;
}
+ /* Add sysfs entries for one cpu. */
+static int __init msm_pm_mode_sysfs_add_cpu(
+ unsigned int cpu, struct kobject *modes_kobj)
+{
+ char cpu_name[8];
+ struct kobject *cpu_kobj;
+ struct msm_pm_sysfs_sleep_mode *mode = NULL;
+ int i, j, k;
+ int ret;
+
+ snprintf(cpu_name, sizeof(cpu_name), "cpu%u", cpu);
+ cpu_kobj = kobject_create_and_add(cpu_name, modes_kobj);
+ if (!cpu_kobj) {
+ pr_err("%s: cannot create %s kobject\n", __func__, cpu_name);
+ ret = -ENOMEM;
+ goto mode_sysfs_add_cpu_exit;
+ }
+
+ for (i = 0; i < MSM_PM_SLEEP_MODE_NR; i++) {
+ int idx = MSM_PM_MODE(cpu, i);
+
+ if ((!msm_pm_modes[idx].suspend_supported) &&
+ (!msm_pm_modes[idx].idle_supported))
+ continue;
+
+ mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+ if (!mode) {
+ pr_err("%s: cannot allocate memory for attributes\n",
+ __func__);
+ ret = -ENOMEM;
+ goto mode_sysfs_add_cpu_exit;
+ }
+
+ mode->kobj = kobject_create_and_add(
+ msm_pm_sleep_mode_labels[i], cpu_kobj);
+ if (!mode->kobj) {
+ pr_err("%s: cannot create kobject\n", __func__);
+ ret = -ENOMEM;
+ goto mode_sysfs_add_cpu_exit;
+ }
+
+ for (k = 0, j = 0; k < MSM_PM_MODE_ATTR_NR; k++) {
+ if ((k == MSM_PM_MODE_ATTR_IDLE) &&
+ !msm_pm_modes[idx].idle_supported)
+ continue;
+ if ((k == MSM_PM_MODE_ATTR_SUSPEND) &&
+ !msm_pm_modes[idx].suspend_supported)
+ continue;
+ mode->kas[j].cpu = cpu;
+ mode->kas[j].ka.attr.mode = 0644;
+ mode->kas[j].ka.show = msm_pm_mode_attr_show;
+ mode->kas[j].ka.store = msm_pm_mode_attr_store;
+ mode->kas[j].ka.attr.name = msm_pm_mode_attr_labels[k];
+ mode->attrs[j] = &mode->kas[j].ka.attr;
+ j++;
+ }
+ mode->attrs[j] = NULL;
+
+ mode->attr_group.attrs = mode->attrs;
+ ret = sysfs_create_group(mode->kobj, &mode->attr_group);
+ if (ret) {
+ printk(KERN_ERR
+ "%s: cannot create kobject attribute group\n",
+ __func__);
+ goto mode_sysfs_add_cpu_exit;
+ }
+ }
+
+ ret = 0;
+
+mode_sysfs_add_cpu_exit:
+ if (ret) {
+ if (mode && mode->kobj)
+ kobject_del(mode->kobj);
+ kfree(mode);
+ }
+
+ return ret;
+}
+
/*
* Add sysfs entries for the sleep modes.
*/
@@ -269,13 +359,7 @@
{
struct kobject *module_kobj = NULL;
struct kobject *modes_kobj = NULL;
-
- struct kobject *kobj;
- struct attribute_group *attr_group;
- struct attribute **attrs;
- struct kobj_attribute *kobj_attrs;
-
- int i, j, k;
+ unsigned int cpu;
int ret;
module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
@@ -283,98 +367,32 @@
printk(KERN_ERR "%s: cannot find kobject for module %s\n",
__func__, KBUILD_MODNAME);
ret = -ENOENT;
- goto mode_sysfs_add_cleanup;
+ goto mode_sysfs_add_exit;
}
modes_kobj = kobject_create_and_add("modes", module_kobj);
if (!modes_kobj) {
printk(KERN_ERR "%s: cannot create modes kobject\n", __func__);
ret = -ENOMEM;
- goto mode_sysfs_add_cleanup;
+ goto mode_sysfs_add_exit;
}
- for (i = 0; i < ARRAY_SIZE(msm_pm_mode_kobjs); i++) {
- if (!msm_pm_modes[i].suspend_supported &&
- !msm_pm_modes[i].idle_supported)
- continue;
-
- kobj = kobject_create_and_add(
- msm_pm_sleep_mode_labels[i], modes_kobj);
- attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL);
- attrs = kzalloc(sizeof(*attrs) * (MSM_PM_MODE_ATTR_NR + 1),
- GFP_KERNEL);
- kobj_attrs = kzalloc(sizeof(*kobj_attrs) * MSM_PM_MODE_ATTR_NR,
- GFP_KERNEL);
-
- if (!kobj || !attr_group || !attrs || !kobj_attrs) {
- printk(KERN_ERR
- "%s: cannot create kobject or attributes\n",
- __func__);
- ret = -ENOMEM;
- goto mode_sysfs_add_abort;
- }
-
- for (k = 0, j = 0; k < MSM_PM_MODE_ATTR_NR; k++) {
- if ((k == MSM_PM_MODE_ATTR_SUSPEND) &&
- (!msm_pm_modes[i].suspend_supported))
- continue;
- if ((k == MSM_PM_MODE_ATTR_IDLE) &&
- (!msm_pm_modes[i].idle_supported))
- continue;
-
- kobj_attrs[j].attr.mode = 0644;
- kobj_attrs[j].show = msm_pm_mode_attr_show;
- kobj_attrs[j].store = msm_pm_mode_attr_store;
- kobj_attrs[j].attr.name = msm_pm_mode_attr_labels[k];
- attrs[j] = &kobj_attrs[j].attr;
- j++;
- }
- attrs[j] = NULL;
-
- attr_group->attrs = attrs;
- ret = sysfs_create_group(kobj, attr_group);
- if (ret) {
- printk(KERN_ERR
- "%s: cannot create kobject attribute group\n",
- __func__);
- goto mode_sysfs_add_abort;
- }
-
- msm_pm_mode_kobjs[i] = kobj;
- msm_pm_mode_attr_group[i] = attr_group;
- msm_pm_mode_attrs[i] = attrs;
- msm_pm_mode_kobj_attrs[i] = kobj_attrs;
+ for_each_possible_cpu(cpu) {
+ ret = msm_pm_mode_sysfs_add_cpu(cpu, modes_kobj);
+ if (ret)
+ goto mode_sysfs_add_exit;
}
- return 0;
+ ret = 0;
-mode_sysfs_add_abort:
- kfree(kobj_attrs);
- kfree(attrs);
- kfree(attr_group);
- kobject_put(kobj);
-
-mode_sysfs_add_cleanup:
- for (i = ARRAY_SIZE(msm_pm_mode_kobjs) - 1; i >= 0; i--) {
- if (!msm_pm_mode_kobjs[i])
- continue;
-
- sysfs_remove_group(
- msm_pm_mode_kobjs[i], msm_pm_mode_attr_group[i]);
-
- kfree(msm_pm_mode_kobj_attrs[i]);
- kfree(msm_pm_mode_attrs[i]);
- kfree(msm_pm_mode_attr_group[i]);
- kobject_put(msm_pm_mode_kobjs[i]);
- }
-
+mode_sysfs_add_exit:
return ret;
}
void __init msm_pm_set_platform_data(
struct msm_pm_platform_data *data, int count)
{
- BUG_ON(MSM_PM_SLEEP_MODE_NR != count);
+ BUG_ON(MSM_PM_SLEEP_MODE_NR * num_possible_cpus() > count);
msm_pm_modes = data;
}
@@ -674,7 +692,7 @@
MSM_PM_STAT_COUNT
};
-static struct msm_pm_time_stats {
+struct msm_pm_time_stats {
const char *name;
int64_t first_bucket_time;
int bucket[CONFIG_MSM_IDLE_STATS_BUCKET_COUNT];
@@ -682,74 +700,37 @@
int64_t max_time[CONFIG_MSM_IDLE_STATS_BUCKET_COUNT];
int count;
int64_t total_time;
-} msm_pm_stats[MSM_PM_STAT_COUNT] = {
- [MSM_PM_STAT_REQUESTED_IDLE].name = "idle-request",
- [MSM_PM_STAT_REQUESTED_IDLE].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
- [MSM_PM_STAT_IDLE_SPIN].name = "idle-spin",
- [MSM_PM_STAT_IDLE_SPIN].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
- [MSM_PM_STAT_IDLE_WFI].name = "idle-wfi",
- [MSM_PM_STAT_IDLE_WFI].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
- [MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE].name =
- "idle-standalone-power-collapse",
- [MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
- [MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE].name =
- "idle-failed-standalone-power-collapse",
- [MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
- [MSM_PM_STAT_IDLE_SLEEP].name = "idle-sleep",
- [MSM_PM_STAT_IDLE_SLEEP].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
- [MSM_PM_STAT_IDLE_FAILED_SLEEP].name = "idle-failed-sleep",
- [MSM_PM_STAT_IDLE_FAILED_SLEEP].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
- [MSM_PM_STAT_IDLE_POWER_COLLAPSE].name = "idle-power-collapse",
- [MSM_PM_STAT_IDLE_POWER_COLLAPSE].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
- [MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE].name =
- "idle-failed-power-collapse",
- [MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
- [MSM_PM_STAT_SUSPEND].name = "suspend",
- [MSM_PM_STAT_SUSPEND].first_bucket_time =
- CONFIG_MSM_SUSPEND_STATS_FIRST_BUCKET,
-
- [MSM_PM_STAT_FAILED_SUSPEND].name = "failed-suspend",
- [MSM_PM_STAT_FAILED_SUSPEND].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
- [MSM_PM_STAT_NOT_IDLE].name = "not-idle",
- [MSM_PM_STAT_NOT_IDLE].first_bucket_time =
- CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
};
+struct msm_pm_cpu_time_stats {
+ struct msm_pm_time_stats stats[MSM_PM_STAT_COUNT];
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(
+ struct msm_pm_cpu_time_stats, msm_pm_stats);
+
static uint32_t msm_pm_sleep_limit = SLEEP_LIMIT_NONE;
+static DEFINE_SPINLOCK(msm_pm_stats_lock);
+
/*
* Add the given time data to the statistics collection.
*/
static void msm_pm_add_stat(enum msm_pm_time_stats_id id, int64_t t)
{
+ unsigned long flags;
+ struct msm_pm_time_stats *stats;
int i;
int64_t bt;
- msm_pm_stats[id].total_time += t;
- msm_pm_stats[id].count++;
+ spin_lock_irqsave(&msm_pm_stats_lock, flags);
+ stats = __get_cpu_var(msm_pm_stats).stats;
+
+ stats[id].total_time += t;
+ stats[id].count++;
bt = t;
- do_div(bt, msm_pm_stats[id].first_bucket_time);
+ do_div(bt, stats[id].first_bucket_time);
if (bt < 1ULL << (CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT *
(CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1)))
@@ -758,12 +739,17 @@
else
i = CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1;
- msm_pm_stats[id].bucket[i]++;
+ if (i >= CONFIG_MSM_IDLE_STATS_BUCKET_COUNT)
+ i = CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1;
- if (t < msm_pm_stats[id].min_time[i] || !msm_pm_stats[id].max_time[i])
- msm_pm_stats[id].min_time[i] = t;
- if (t > msm_pm_stats[id].max_time[i])
- msm_pm_stats[id].max_time[i] = t;
+ stats[id].bucket[i]++;
+
+ if (t < stats[id].min_time[i] || !stats[id].max_time[i])
+ stats[id].min_time[i] = t;
+ if (t > stats[id].max_time[i])
+ stats[id].max_time[i] = t;
+
+ spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
}
/*
@@ -793,7 +779,8 @@
static int msm_pm_read_proc
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
- int i;
+ unsigned int cpu = off / MSM_PM_STAT_COUNT;
+ int id = off % MSM_PM_STAT_COUNT;
char *p = page;
if (count < 1024) {
@@ -809,44 +796,51 @@
SNPRINTF(p, count, "for TCXO shutdown\n\n");
else
SNPRINTF(p, count, "against TCXO shutdown\n\n");
+ }
- *start = (char *) 1;
- *eof = 0;
- } else if (--off < ARRAY_SIZE(msm_pm_stats)) {
+ if (cpu < num_possible_cpus()) {
+ unsigned long flags;
+ struct msm_pm_time_stats *stats;
+ int i;
int64_t bucket_time;
int64_t s;
uint32_t ns;
- s = msm_pm_stats[off].total_time;
+ spin_lock_irqsave(&msm_pm_stats_lock, flags);
+ stats = per_cpu(msm_pm_stats, cpu).stats;
+
+ s = stats[id].total_time;
ns = do_div(s, NSEC_PER_SEC);
SNPRINTF(p, count,
- "%s:\n"
+ "[cpu %u] %s:\n"
" count: %7d\n"
" total_time: %lld.%09u\n",
- msm_pm_stats[off].name,
- msm_pm_stats[off].count,
+ cpu, stats[id].name,
+ stats[id].count,
s, ns);
- bucket_time = msm_pm_stats[off].first_bucket_time;
+ bucket_time = stats[id].first_bucket_time;
for (i = 0; i < CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1; i++) {
s = bucket_time;
ns = do_div(s, NSEC_PER_SEC);
SNPRINTF(p, count,
" <%6lld.%09u: %7d (%lld-%lld)\n",
- s, ns, msm_pm_stats[off].bucket[i],
- msm_pm_stats[off].min_time[i],
- msm_pm_stats[off].max_time[i]);
+ s, ns, stats[id].bucket[i],
+ stats[id].min_time[i],
+ stats[id].max_time[i]);
bucket_time <<= CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT;
}
SNPRINTF(p, count, " >=%6lld.%09u: %7d (%lld-%lld)\n",
- s, ns, msm_pm_stats[off].bucket[i],
- msm_pm_stats[off].min_time[i],
- msm_pm_stats[off].max_time[i]);
+ s, ns, stats[id].bucket[i],
+ stats[id].min_time[i],
+ stats[id].max_time[i]);
*start = (char *) 1;
- *eof = (off + 1 >= ARRAY_SIZE(msm_pm_stats));
+ *eof = (off + 1 >= MSM_PM_STAT_COUNT * num_possible_cpus());
+
+ spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
}
return p - page;
@@ -864,7 +858,7 @@
char buf[sizeof(MSM_PM_STATS_RESET)];
int ret;
unsigned long flags;
- int i;
+ unsigned int cpu;
if (count < strlen(MSM_PM_STATS_RESET)) {
ret = -EINVAL;
@@ -881,26 +875,32 @@
goto write_proc_failed;
}
- local_irq_save(flags);
- for (i = 0; i < ARRAY_SIZE(msm_pm_stats); i++) {
- memset(msm_pm_stats[i].bucket,
- 0, sizeof(msm_pm_stats[i].bucket));
- memset(msm_pm_stats[i].min_time,
- 0, sizeof(msm_pm_stats[i].min_time));
- memset(msm_pm_stats[i].max_time,
- 0, sizeof(msm_pm_stats[i].max_time));
- msm_pm_stats[i].count = 0;
- msm_pm_stats[i].total_time = 0;
- }
+ spin_lock_irqsave(&msm_pm_stats_lock, flags);
+ for_each_possible_cpu(cpu) {
+ struct msm_pm_time_stats *stats;
+ int i;
+ stats = per_cpu(msm_pm_stats, cpu).stats;
+ for (i = 0; i < MSM_PM_STAT_COUNT; i++) {
+ memset(stats[i].bucket,
+ 0, sizeof(stats[i].bucket));
+ memset(stats[i].min_time,
+ 0, sizeof(stats[i].min_time));
+ memset(stats[i].max_time,
+ 0, sizeof(stats[i].max_time));
+ stats[i].count = 0;
+ stats[i].total_time = 0;
+ }
+ }
msm_pm_sleep_limit = SLEEP_LIMIT_NONE;
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
return count;
write_proc_failed:
return ret;
}
+
#undef MSM_PM_STATS_RESET
#endif /* CONFIG_MSM_IDLE_STATS */
@@ -1389,16 +1389,19 @@
int low_power;
int ret;
int i;
+ unsigned int cpu;
#ifdef CONFIG_MSM_IDLE_STATS
int64_t t1;
static int64_t t2;
int exit_stat;
-#endif /* CONFIG_MSM_IDLE_STATS */
+ #endif /* CONFIG_MSM_IDLE_STATS */
if (!atomic_read(&msm_pm_init_done))
return;
+ cpu = smp_processor_id();
+
latency_qos = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
timer_expiration = msm_timer_enter_idle();
@@ -1406,39 +1409,14 @@
t1 = ktime_to_ns(ktime_get());
msm_pm_add_stat(MSM_PM_STAT_NOT_IDLE, t1 - t2);
msm_pm_add_stat(MSM_PM_STAT_REQUESTED_IDLE, timer_expiration);
+
+ exit_stat = MSM_PM_STAT_IDLE_SPIN;
+ low_power = 0;
#endif /* CONFIG_MSM_IDLE_STATS */
for (i = 0; i < ARRAY_SIZE(allow); i++)
allow[i] = true;
- switch (msm_pm_idle_sleep_mode) {
- case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
- allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] =
- false;
- /* fall through */
- case MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT:
- allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE] = false;
- /* fall through */
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
- allow[MSM_PM_SLEEP_MODE_APPS_SLEEP] = false;
- /* fall through */
- case MSM_PM_SLEEP_MODE_APPS_SLEEP:
- allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = false;
- allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = false;
- /* fall through */
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND:
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
- break;
- default:
- printk(KERN_ERR "idle sleep mode is invalid: %d\n",
- msm_pm_idle_sleep_mode);
-#ifdef CONFIG_MSM_IDLE_STATS
- exit_stat = MSM_PM_STAT_IDLE_SPIN;
-#endif /* CONFIG_MSM_IDLE_STATS */
- low_power = 0;
- goto arch_idle_exit;
- }
-
if ((timer_expiration < msm_pm_idle_sleep_min_time) ||
#ifdef CONFIG_HAS_WAKELOCK
has_wake_lock(WAKE_LOCK_IDLE) ||
@@ -1450,7 +1428,8 @@
}
for (i = 0; i < ARRAY_SIZE(allow); i++) {
- struct msm_pm_platform_data *mode = &msm_pm_modes[i];
+ struct msm_pm_platform_data *mode =
+ &msm_pm_modes[MSM_PM_MODE(cpu, i)];
if (!mode->idle_supported || !mode->idle_enabled ||
mode->latency >= latency_qos ||
mode->residency * 1000ULL >= timer_expiration)
@@ -1564,7 +1543,6 @@
#endif /* CONFIG_MSM_IDLE_STATS */
}
-arch_idle_exit:
msm_timer_exit_idle(low_power);
#ifdef CONFIG_MSM_IDLE_STATS
@@ -1604,32 +1582,9 @@
for (i = 0; i < ARRAY_SIZE(allow); i++)
allow[i] = true;
- switch (msm_pm_sleep_mode) {
- case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
- allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] =
- false;
- /* fall through */
- case MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT:
- allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE] = false;
- /* fall through */
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
- allow[MSM_PM_SLEEP_MODE_APPS_SLEEP] = false;
- /* fall through */
- case MSM_PM_SLEEP_MODE_APPS_SLEEP:
- allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = false;
- allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = false;
- /* fall through */
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND:
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
- break;
- default:
- printk(KERN_ERR "suspend sleep mode is invalid: %d\n",
- msm_pm_sleep_mode);
- return -EINVAL;
- }
-
for (i = 0; i < ARRAY_SIZE(allow); i++) {
- struct msm_pm_platform_data *mode = &msm_pm_modes[i];
+ struct msm_pm_platform_data *mode;
+ mode = &msm_pm_modes[MSM_PM_MODE(0, i)];
if (!mode->suspend_supported || !mode->suspend_enabled)
allow[i] = false;
}
@@ -1778,6 +1733,7 @@
{
#ifdef CONFIG_MSM_IDLE_STATS
struct proc_dir_entry *d_entry;
+ unsigned int cpu;
#endif
int ret;
#ifdef CONFIG_CPU_V7
@@ -1846,6 +1802,66 @@
msm_pm_mode_sysfs_add();
#ifdef CONFIG_MSM_IDLE_STATS
+ for_each_possible_cpu(cpu) {
+ struct msm_pm_time_stats *stats =
+ per_cpu(msm_pm_stats, cpu).stats;
+
+ stats[MSM_PM_STAT_REQUESTED_IDLE].name = "idle-request";
+ stats[MSM_PM_STAT_REQUESTED_IDLE].first_bucket_time =
+ CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+ stats[MSM_PM_STAT_IDLE_SPIN].name = "idle-spin";
+ stats[MSM_PM_STAT_IDLE_SPIN].first_bucket_time =
+ CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+ stats[MSM_PM_STAT_IDLE_WFI].name = "idle-wfi";
+ stats[MSM_PM_STAT_IDLE_WFI].first_bucket_time =
+ CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+ stats[MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE].name =
+ "idle-standalone-power-collapse";
+ stats[MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE].
+ first_bucket_time =
+ CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+ stats[MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE].name =
+ "idle-failed-standalone-power-collapse";
+ stats[MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE].
+ first_bucket_time =
+ CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+ stats[MSM_PM_STAT_IDLE_SLEEP].name = "idle-sleep";
+ stats[MSM_PM_STAT_IDLE_SLEEP].first_bucket_time =
+ CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+ stats[MSM_PM_STAT_IDLE_FAILED_SLEEP].name =
+ "idle-failed-sleep";
+ stats[MSM_PM_STAT_IDLE_FAILED_SLEEP].first_bucket_time =
+ CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+ stats[MSM_PM_STAT_IDLE_POWER_COLLAPSE].name =
+ "idle-power-collapse";
+ stats[MSM_PM_STAT_IDLE_POWER_COLLAPSE].first_bucket_time =
+ CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+ stats[MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE].name =
+ "idle-failed-power-collapse";
+ stats[MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE].
+ first_bucket_time =
+ CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+ stats[MSM_PM_STAT_SUSPEND].name = "suspend";
+ stats[MSM_PM_STAT_SUSPEND].first_bucket_time =
+ CONFIG_MSM_SUSPEND_STATS_FIRST_BUCKET;
+
+ stats[MSM_PM_STAT_FAILED_SUSPEND].name = "failed-suspend";
+ stats[MSM_PM_STAT_FAILED_SUSPEND].first_bucket_time =
+ CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+ stats[MSM_PM_STAT_NOT_IDLE].name = "not-idle";
+ stats[MSM_PM_STAT_NOT_IDLE].first_bucket_time =
+ CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+ }
d_entry = create_proc_entry("msm_pm_stats",
S_IRUGO | S_IWUSR | S_IWGRP, NULL);
if (d_entry) {
diff --git a/arch/arm/mach-msm/qdss-ptm.c b/arch/arm/mach-msm/qdss-ptm.c
index 96a727a..c0dc58e 100644
--- a/arch/arm/mach-msm/qdss-ptm.c
+++ b/arch/arm/mach-msm/qdss-ptm.c
@@ -67,9 +67,9 @@
#define ETMSQ12EVR (0x180)
#define ETMSQ21EVR (0x184)
#define ETMSQ23EVR (0x188)
-#define ETMSQ32EVR (0x18C)
-#define ETMSQ13EVR (0x190)
-#define ETMSQ31EVR (0x194)
+#define ETMSQ31EVR (0x18C)
+#define ETMSQ32EVR (0x190)
+#define ETMSQ13EVR (0x194)
#define ETMSQR (0x19C)
#define ETMEXTOUTEVRn(n) (0x1A0 + (n * 4))
#define ETMCIDCVRn(n) (0x1B0 + (n * 4))
@@ -91,7 +91,7 @@
#define ETMTSEVR (0x1F8)
#define ETMAUXCR (0x1FC)
#define ETMTRACEIDR (0x200)
-#define ETMVMIDCVR (0x204)
+#define ETMVMIDCVR (0x240)
/* Management registers (0x300-0x314) */
#define ETMOSLAR (0x300)
#define ETMOSLSR (0x304)
diff --git a/arch/arm/mach-msm/spm.h b/arch/arm/mach-msm/spm.h
index 78fd922..b155781 100644
--- a/arch/arm/mach-msm/spm.h
+++ b/arch/arm/mach-msm/spm.h
@@ -65,12 +65,7 @@
#elif defined(CONFIG_MSM_SPM_V2)
enum {
- MSM_SPM_REG_SAW2_SECURE,
- MSM_SPM_REG_SAW2_ID,
MSM_SPM_REG_SAW2_CFG,
- MSM_SPM_REG_SAW2_STS0,
- MSM_SPM_REG_SAW2_STS1,
- MSM_SPM_REG_SAW2_VCTL,
MSM_SPM_REG_SAW2_AVS_CTL,
MSM_SPM_REG_SAW2_AVS_HYSTERESIS,
MSM_SPM_REG_SAW2_SPM_CTL,
@@ -79,8 +74,13 @@
MSM_SPM_REG_SAW2_PMIC_DATA_1,
MSM_SPM_REG_SAW2_RST,
- MSM_SPM_REG_NR_INITIALIZE,
- MSM_SPM_REG_SAW2_SEQ_ENTRY = MSM_SPM_REG_NR_INITIALIZE,
+ MSM_SPM_REG_NR_INITIALIZE = MSM_SPM_REG_SAW2_RST,
+ MSM_SPM_REG_SAW2_ID,
+ MSM_SPM_REG_SAW2_SECURE,
+ MSM_SPM_REG_SAW2_STS0,
+ MSM_SPM_REG_SAW2_STS1,
+ MSM_SPM_REG_SAW2_VCTL,
+ MSM_SPM_REG_SAW2_SEQ_ENTRY ,
MSM_SPM_REG_NR
};
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 5cd1b05..3bce534 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -54,9 +54,15 @@
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt skip @ skip if no cache, or just i-cache
+#ifdef CONFIG_PREEMPT
+ save_and_disable_irqs r9 @ make cssr&csidr read atomic
+#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
+#ifdef CONFIG_PREEMPT
+ restore_irqs_notrace r9
+#endif
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index a9faff0..7d28604 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -128,6 +128,7 @@
struct diag_client_map *client_map;
int *data_ready;
int num_clients;
+ int polling_reg_flag;
struct diag_write_device *buf_tbl;
/* Memory pool parameters */
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index a703148..e24d896 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -60,8 +60,8 @@
static unsigned int max_clients = 15;
static unsigned int threshold_client_limit = 30;
/* This is the maximum number of pkt registrations supported at initialization*/
-unsigned int diag_max_registration = 500;
-unsigned int diag_threshold_registration = 650;
+unsigned int diag_max_registration = 600;
+unsigned int diag_threshold_registration = 750;
/* Timer variables */
static struct timer_list drain_timer;
@@ -256,15 +256,49 @@
return -ENOMEM;
}
+int diag_find_polling_reg(int i)
+{
+ uint16_t subsys_id, cmd_code_lo, cmd_code_hi;
+
+ subsys_id = driver->table[i].subsys_id;
+ cmd_code_lo = driver->table[i].cmd_code_lo;
+ cmd_code_hi = driver->table[i].cmd_code_hi;
+ if (driver->table[i].cmd_code == 0x0C)
+ return 1;
+ else if (driver->table[i].cmd_code == 0xFF) {
+ if (subsys_id == 0x04 && cmd_code_hi == 0x0E &&
+ cmd_code_lo == 0x0E)
+ return 1;
+ else if (subsys_id == 0x08 && cmd_code_hi == 0x02 &&
+ cmd_code_lo == 0x02)
+ return 1;
+ else if (subsys_id == 0x32 && cmd_code_hi == 0x03 &&
+ cmd_code_lo == 0x03)
+ return 1;
+ }
+ return 0;
+}
+
void diag_clear_reg(int proc_num)
{
int i;
+ mutex_lock(&driver->diagchar_mutex);
+ /* reset polling flag */
+ driver->polling_reg_flag = 0;
for (i = 0; i < diag_max_registration; i++) {
if (driver->table[i].client_id == proc_num) {
driver->table[i].process_id = 0;
}
}
+ /* re-scan the registration table */
+ for (i = 0; i < diag_max_registration; i++) {
+ if (diag_find_polling_reg(i) == 1) {
+ driver->polling_reg_flag = 1;
+ break;
+ }
+ }
+ mutex_unlock(&driver->diagchar_mutex);
}
void diag_add_reg(int j, struct bindpkt_params *params,
@@ -275,6 +309,11 @@
driver->table[j].subsys_id = params->subsys_id;
driver->table[j].cmd_code_lo = params->cmd_code_lo;
driver->table[j].cmd_code_hi = params->cmd_code_hi;
+
+ /* check if incoming reg is polling & polling is yet not registered */
+ if (driver->polling_reg_flag == 0)
+ if (diag_find_polling_reg(j) == 1)
+ driver->polling_reg_flag = 1;
if (params->proc_id == APPS_PROC) {
driver->table[j].process_id = current->tgid;
driver->table[j].client_id = APPS_PROC;
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 07322cd..5838bba 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -891,8 +891,8 @@
/* Check for polling for Apps only DIAG */
else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
(*(buf+2) == 0x03)) {
- /* If there is NO MODEM present */
- if (!(driver->ch)) {
+ /* If no one has registered for polling */
+ if (!(driver->polling_reg_flag)) {
/* Respond to polling for Apps only DIAG */
for (i = 0; i < 3; i++)
driver->apps_rsp_buf[i] = *(buf+i);
@@ -901,13 +901,10 @@
ENCODE_RSP_AND_SEND(15);
return 0;
- } else {
- /* Since Modem is present, send error response */
- return 1;
}
}
/* Check for ID for NO MODEM present */
- else if (!(driver->ch)) {
+ else if (!(driver->polling_reg_flag)) {
/* respond to 0x0 command */
if (*buf == 0x00) {
for (i = 0; i < 55; i++)
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index df2cd65..22a2ccb 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -192,6 +192,7 @@
void diagfwd_cntl_init(void)
{
+ driver->polling_reg_flag = 0;
if (driver->buf_in_cntl == NULL) {
driver->buf_in_cntl = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
if (driver->buf_in_cntl == NULL)
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 9cbebbe..06f4a14 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -834,7 +834,11 @@
unsigned int rbbm_status;
unsigned long wait_timeout =
msecs_to_jiffies(adreno_dev->wait_timeout);
- unsigned long wait_time = jiffies + wait_timeout;
+ unsigned long wait_time;
+ unsigned long wait_time_part;
+ unsigned int msecs;
+ unsigned int msecs_first;
+ unsigned int msecs_part;
kgsl_cffdump_regpoll(device->id,
adreno_dev->gpudev->reg_rbbm_status << 2,
@@ -844,8 +848,18 @@
*/
retry:
if (rb->flags & KGSL_FLAGS_STARTED) {
+ msecs = adreno_dev->wait_timeout;
+ msecs_first = (msecs <= 100) ? ((msecs + 4) / 5) : 100;
+ msecs_part = (msecs - msecs_first + 3) / 4;
+ wait_time = jiffies + wait_timeout;
+ wait_time_part = jiffies + msecs_to_jiffies(msecs_first);
adreno_poke(device);
do {
+ if (time_after(jiffies, wait_time_part)) {
+ adreno_poke(device);
+ wait_time_part = jiffies +
+ msecs_to_jiffies(msecs_part);
+ }
GSL_RB_GET_READPTR(rb, &rb->rptr);
if (time_after(jiffies, wait_time)) {
KGSL_DRV_ERR(device, "rptr: %x, wptr: %x\n",
@@ -1146,57 +1160,56 @@
msecs_first = (msecs <= 100) ? ((msecs + 4) / 5) : 100;
msecs_part = (msecs - msecs_first + 3) / 4;
for (retries = 0; retries < 5; retries++) {
- if (!kgsl_check_timestamp(device, timestamp)) {
- adreno_poke(device);
- io_cnt = (io_cnt + 1) % 100;
- if (io_cnt <
- pwr->pwrlevels[pwr->active_pwrlevel].
- io_fraction)
- io = 0;
- mutex_unlock(&device->mutex);
- /* We need to make sure that the process is
- * placed in wait-q before its condition is called
+ if (kgsl_check_timestamp(device, timestamp)) {
+ /* if the timestamp happens while we're not
+ * waiting, there's a chance that an interrupt
+ * will not be generated and thus the timestamp
+ * work needs to be queued.
*/
- status = kgsl_wait_event_interruptible_timeout(
- device->wait_queue,
- kgsl_check_interrupt_timestamp(device,
- timestamp),
- msecs_to_jiffies(retries ?
- msecs_part : msecs_first), io);
- mutex_lock(&device->mutex);
-
- if (status > 0) {
- /*completed before the wait finished */
- status = 0;
- goto done;
- } else if (status < 0) {
- /*an error occurred*/
- goto done;
- }
- /*this wait timed out*/
+ queue_work(device->work_queue, &device->ts_expired_ws);
+ status = 0;
+ goto done;
}
- }
- if (!kgsl_check_timestamp(device, timestamp)) {
- status = -ETIMEDOUT;
- KGSL_DRV_ERR(device,
- "Device hang detected while waiting "
- "for timestamp: %x, last "
- "submitted(rb->timestamp): %x, wptr: "
- "%x\n", timestamp,
- adreno_dev->ringbuffer.timestamp,
- adreno_dev->ringbuffer.wptr);
- if (!adreno_dump_and_recover(device)) {
- /* wait for idle after recovery as the
- * timestamp that this process wanted
- * to wait on may be invalid */
- if (!adreno_idle(device,
- KGSL_TIMEOUT_DEFAULT))
- status = 0;
- }
- } else {
- status = 0;
- }
+ adreno_poke(device);
+ io_cnt = (io_cnt + 1) % 100;
+ if (io_cnt <
+ pwr->pwrlevels[pwr->active_pwrlevel].io_fraction)
+ io = 0;
+ mutex_unlock(&device->mutex);
+ /* We need to make sure that the process is
+ * placed in wait-q before its condition is called
+ */
+ status = kgsl_wait_event_interruptible_timeout(
+ device->wait_queue,
+ kgsl_check_interrupt_timestamp(device,
+ timestamp),
+ msecs_to_jiffies(retries ?
+ msecs_part : msecs_first), io);
+ mutex_lock(&device->mutex);
+ if (status > 0) {
+ /*completed before the wait finished */
+ status = 0;
+ goto done;
+ } else if (status < 0) {
+ /*an error occurred*/
+ goto done;
+ }
+ /*this wait timed out*/
+ }
+ status = -ETIMEDOUT;
+ KGSL_DRV_ERR(device,
+ "Device hang detected while waiting for timestamp: %x,"
+ "last submitted(rb->timestamp): %x, wptr: %x\n",
+ timestamp, adreno_dev->ringbuffer.timestamp,
+ adreno_dev->ringbuffer.wptr);
+ if (!adreno_dump_and_recover(device)) {
+ /* wait for idle after recovery as the
+ * timestamp that this process wanted
+ * to wait on may be invalid */
+ if (!adreno_idle(device, KGSL_TIMEOUT_DEFAULT))
+ status = 0;
+ }
done:
return (int)status;
}
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 512a262..1a0a17d 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -102,6 +102,7 @@
if (n == &device->events)
list_add_tail(&event->list, &device->events);
+ queue_work(device->work_queue, &device->ts_expired_ws);
return 0;
}
#endif
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 1ef71a4..ae50183 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -66,8 +66,17 @@
struct kgsl_pwrlevel *pwrlevel = &pwr->pwrlevels[new_level];
pwr->active_pwrlevel = new_level;
if ((test_bit(KGSL_PWRFLAGS_CLK_ON, &pwr->power_flags)) ||
- (device->state == KGSL_STATE_NAP))
+ (device->state == KGSL_STATE_NAP)) {
+ /*
+ * On some platforms, instability is caused on
+ * changing clock freq when the core is busy.
+ * Idle the gpu core before changing the clock freq.
+ */
+ if (pwr->idle_needed == true)
+ device->ftbl->idle(device,
+ KGSL_TIMEOUT_DEFAULT);
clk_set_rate(pwr->grp_clks[0], pwrlevel->gpu_freq);
+ }
if (test_bit(KGSL_PWRFLAGS_AXI_ON, &pwr->power_flags)) {
if (pwr->pcl)
msm_bus_scale_client_update_request(pwr->pcl,
@@ -499,6 +508,7 @@
pwr->power_flags = 0;
pwr->nap_allowed = pdata->nap_allowed;
+ pwr->idle_needed = pdata->idle_needed;
pwr->interval_timeout = pdata->idle_timeout;
pwr->ebi1_clk = clk_get(&pdev->dev, "bus_clk");
if (IS_ERR(pwr->ebi1_clk))
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 23e2bd1..99dbae9 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -50,6 +50,7 @@
struct regulator *gpu_reg;
uint32_t pcl;
unsigned int nap_allowed;
+ unsigned int idle_needed;
const char *regulator_name;
const char *irq_name;
s64 time;
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index c8b4707..4988313 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -324,13 +324,13 @@
{
dev->clk_state = state;
if (state != 0) {
- clk_prepare_enable(dev->clk);
- clk_prepare_enable(dev->pclk);
+ clk_enable(dev->clk);
+ clk_enable(dev->pclk);
} else {
qup_update_state(dev, QUP_RESET_STATE);
- clk_disable_unprepare(dev->clk);
+ clk_disable(dev->clk);
qup_config_core_on_en(dev);
- clk_disable_unprepare(dev->pclk);
+ clk_disable(dev->pclk);
}
}
@@ -1285,6 +1285,8 @@
dev->suspended = 0;
mutex_init(&dev->mlock);
dev->clk_state = 0;
+ clk_prepare(dev->clk);
+ clk_prepare(dev->pclk);
setup_timer(&dev->pwr_timer, qup_i2c_pwr_timer, (unsigned long) dev);
pm_runtime_set_active(&pdev->dev);
@@ -1344,6 +1346,8 @@
}
free_irq(dev->err_irq, dev);
i2c_del_adapter(&dev->adapter);
+ clk_unprepare(dev->clk);
+ clk_unprepare(dev->pclk);
clk_put(dev->clk);
clk_put(dev->pclk);
qup_i2c_free_gpios(dev);
@@ -1378,6 +1382,8 @@
del_timer_sync(&dev->pwr_timer);
if (dev->clk_state != 0)
qup_i2c_pwr_mgmt(dev, 0);
+ clk_unprepare(dev->clk);
+ clk_unprepare(dev->pclk);
qup_i2c_free_gpios(dev);
return 0;
}
@@ -1387,6 +1393,8 @@
struct platform_device *pdev = to_platform_device(device);
struct qup_i2c_dev *dev = platform_get_drvdata(pdev);
BUG_ON(qup_i2c_request_gpios(dev) != 0);
+ clk_prepare(dev->clk);
+ clk_prepare(dev->pclk);
dev->suspended = 0;
return 0;
}
diff --git a/drivers/input/touchscreen/cyttsp-i2c.c b/drivers/input/touchscreen/cyttsp-i2c.c
index a60dbf5..267e481 100644
--- a/drivers/input/touchscreen/cyttsp-i2c.c
+++ b/drivers/input/touchscreen/cyttsp-i2c.c
@@ -710,25 +710,26 @@
else if (!(g_bl_data.bl_status & BL_CHECKSUM_MASK) &&
(appid_lo == ts->platform_data->correct_fw_ver))
fw_upgrade = 1;
- else
- if ((appid_hi == g_bl_data.appid_hi) &&
- (appid_lo == g_bl_data.appid_lo)) {
- if (appver_hi > g_bl_data.appver_hi) {
+ else if ((appid_hi == g_bl_data.appid_hi) &&
+ (appid_lo == g_bl_data.appid_lo))
+ if (appver_hi > g_bl_data.appver_hi)
fw_upgrade = 1;
- } else if ((appver_hi == g_bl_data.appver_hi) &&
- (appver_lo > g_bl_data.appver_lo)) {
- fw_upgrade = 1;
- } else {
- fw_upgrade = 0;
- pr_info("%s: Firmware version "
- "lesser/equal to existing firmware, "
- "upgrade not needed\n", __func__);
- }
- } else {
- fw_upgrade = 0;
- pr_info("%s: Firware versions do not match, "
- "cannot upgrade\n", __func__);
- }
+ else if ((appver_hi == g_bl_data.appver_hi) &&
+ (appver_lo > g_bl_data.appver_lo))
+ fw_upgrade = 1;
+ else {
+ fw_upgrade = 0;
+ pr_info("%s: Firmware version "
+ "lesser/equal to existing firmware, "
+ "upgrade not needed\n", __func__);
+ }
+ else if (appid_lo == ts->platform_data->correct_fw_ver)
+ fw_upgrade = 1;
+ else {
+ fw_upgrade = 0;
+ pr_info("%s: Firmware versions do not match, "
+ "cannot upgrade\n", __func__);
+ }
if (fw_upgrade) {
pr_info("%s: Starting firmware upgrade\n", __func__);
diff --git a/drivers/leds/leds-pm8xxx.c b/drivers/leds/leds-pm8xxx.c
index 025b756..46199d8 100644
--- a/drivers/leds/leds-pm8xxx.c
+++ b/drivers/leds/leds-pm8xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -39,6 +39,46 @@
#define PM8XXX_DRV_LED_CTRL_MASK 0xf8
#define PM8XXX_DRV_LED_CTRL_SHIFT 0x03
+#define SSBI_REG_ADDR_WLED_CTRL_BASE 0x25A
+#define SSBI_REG_ADDR_WLED_CTRL(n) (SSBI_REG_ADDR_WLED_CTRL_BASE + (n) - 1)
+
+/* wled control registers */
+#define WLED_MOD_CTRL_REG SSBI_REG_ADDR_WLED_CTRL(1)
+#define WLED_MAX_CURR_CFG_REG(n) SSBI_REG_ADDR_WLED_CTRL(n + 2)
+#define WLED_BRIGHTNESS_CNTL_REG1(n) SSBI_REG_ADDR_WLED_CTRL(n + 5)
+#define WLED_BRIGHTNESS_CNTL_REG2(n) SSBI_REG_ADDR_WLED_CTRL(n + 6)
+#define WLED_SYNC_REG SSBI_REG_ADDR_WLED_CTRL(11)
+#define WLED_OVP_CFG_REG SSBI_REG_ADDR_WLED_CTRL(13)
+#define WLED_BOOST_CFG_REG SSBI_REG_ADDR_WLED_CTRL(14)
+#define WLED_HIGH_POLE_CAP_REG SSBI_REG_ADDR_WLED_CTRL(16)
+
+#define WLED_STRINGS 0x03
+#define WLED_OVP_VAL_MASK 0x30
+#define WLED_OVP_VAL_BIT_SHFT 0x04
+#define WLED_BOOST_LIMIT_MASK 0xE0
+#define WLED_BOOST_LIMIT_BIT_SHFT 0x05
+#define WLED_EN_MASK 0x01
+#define WLED_CP_SELECT_MAX 0x03
+#define WLED_CP_SELECT_MASK 0x03
+#define WLED_DIG_MOD_GEN_MASK 0x70
+#define WLED_CS_OUT_MASK 0x0E
+#define WLED_CTL_DLY_STEP 200
+#define WLED_CTL_DLY_MAX 1400
+#define WLED_CTL_DLY_MASK 0xE0
+#define WLED_CTL_DLY_BIT_SHFT 0x05
+#define WLED_MAX_CURR 25
+#define WLED_MAX_CURR_MASK 0x1F
+#define WLED_OP_FDBCK_MASK 0x1C
+#define WLED_OP_FDBCK_BIT_SHFT 0x02
+
+#define WLED_MAX_LEVEL 100
+#define WLED_8_BIT_MASK 0xFF
+#define WLED_8_BIT_SHFT 0x08
+#define WLED_MAX_DUTY_CYCLE 0xFFF
+
+#define WLED_SYNC_VAL 0x07
+#define WLED_SYNC_RESET_VAL 0x00
+
#define MAX_FLASH_LED_CURRENT 300
#define MAX_LC_LED_CURRENT 40
#define MAX_KP_BL_LED_CURRENT 300
@@ -81,6 +121,8 @@
int pwm_channel;
u32 pwm_period_us;
struct pm8xxx_pwm_duty_cycles *pwm_duty_cycles;
+ struct wled_config_data *wled_cfg;
+ int max_current;
};
static void led_kp_set(struct pm8xxx_led_data *led, enum led_brightness value)
@@ -145,6 +187,79 @@
led->id, rc);
}
+static int
+led_wled_set(struct pm8xxx_led_data *led, enum led_brightness value)
+{
+ int rc, duty;
+ u8 val, i, num_wled_strings;
+
+ if (value > WLED_MAX_LEVEL)
+ value = WLED_MAX_LEVEL;
+
+ duty = (WLED_MAX_DUTY_CYCLE * value) / WLED_MAX_LEVEL;
+
+ num_wled_strings = led->wled_cfg->num_strings;
+
+ /* program brightness control registers */
+ for (i = 0; i < num_wled_strings; i++) {
+ rc = pm8xxx_readb(led->dev->parent,
+ WLED_BRIGHTNESS_CNTL_REG1(i), &val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't read wled brightnes ctrl"
+ " register1 rc=%d\n", rc);
+ return rc;
+ }
+
+ val = (val & ~WLED_MAX_CURR_MASK) | (duty >> WLED_8_BIT_SHFT);
+ rc = pm8xxx_writeb(led->dev->parent,
+ WLED_BRIGHTNESS_CNTL_REG1(i), val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't write wled brightness ctrl"
+ " register1 rc=%d\n", rc);
+ return rc;
+ }
+
+ val = duty & WLED_8_BIT_MASK;
+ rc = pm8xxx_writeb(led->dev->parent,
+ WLED_BRIGHTNESS_CNTL_REG2(i), val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't write wled brightness ctrl"
+ " register2 rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ /* sync */
+ val = WLED_SYNC_VAL;
+ rc = pm8xxx_writeb(led->dev->parent, WLED_SYNC_REG, val);
+ if (rc) {
+ dev_err(led->dev->parent,
+ "can't read wled sync register rc=%d\n", rc);
+ return rc;
+ }
+
+ val = WLED_SYNC_RESET_VAL;
+ rc = pm8xxx_writeb(led->dev->parent, WLED_SYNC_REG, val);
+ if (rc) {
+ dev_err(led->dev->parent,
+ "can't read wled sync register rc=%d\n", rc);
+ return rc;
+ }
+ return 0;
+}
+
+static void wled_dump_regs(struct pm8xxx_led_data *led)
+{
+ int i;
+ u8 val;
+
+ for (i = 1; i < 17; i++) {
+ pm8xxx_readb(led->dev->parent,
+ SSBI_REG_ADDR_WLED_CTRL(i), &val);
+ pr_debug("WLED_CTRL_%d = 0x%x\n", i, val);
+ }
+}
+
static int pm8xxx_led_pwm_work(struct pm8xxx_led_data *led)
{
int duty_us;
@@ -168,21 +283,31 @@
static void __pm8xxx_led_work(struct pm8xxx_led_data *led,
enum led_brightness level)
{
+ int rc;
+
mutex_lock(&led->lock);
switch (led->id) {
case PM8XXX_ID_LED_KB_LIGHT:
led_kp_set(led, level);
- break;
+ break;
case PM8XXX_ID_LED_0:
case PM8XXX_ID_LED_1:
case PM8XXX_ID_LED_2:
led_lc_set(led, level);
- break;
+ break;
case PM8XXX_ID_FLASH_LED_0:
case PM8XXX_ID_FLASH_LED_1:
led_flash_set(led, level);
- break;
+ break;
+ case PM8XXX_ID_WLED:
+ rc = led_wled_set(led, level);
+ if (rc < 0)
+ pr_err("wled brightness set failed %d\n", rc);
+ break;
+ default:
+ dev_err(led->cdev.dev, "unknown led id %d", led->id);
+ break;
}
mutex_unlock(&led->lock);
@@ -261,6 +386,9 @@
break;
}
break;
+ case PM8XXX_ID_WLED:
+ led->cdev.max_brightness = WLED_MAX_LEVEL;
+ break;
default:
rc = -EINVAL;
pr_err("LED Id is invalid");
@@ -279,6 +407,149 @@
return led->cdev.brightness;
}
+static int __devinit init_wled(struct pm8xxx_led_data *led)
+{
+ int rc, i;
+ u8 val, num_wled_strings;
+
+ num_wled_strings = led->wled_cfg->num_strings;
+
+ /* program over voltage protection threshold */
+ if (led->wled_cfg->ovp_val > WLED_OVP_37V) {
+ dev_err(led->dev->parent, "Invalid ovp value");
+ return -EINVAL;
+ }
+
+ rc = pm8xxx_readb(led->dev->parent, WLED_OVP_CFG_REG, &val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't read wled ovp config"
+ " register rc=%d\n", rc);
+ return rc;
+ }
+
+ val = (val & ~WLED_OVP_VAL_MASK) |
+ (led->wled_cfg->ovp_val << WLED_OVP_VAL_BIT_SHFT);
+
+ rc = pm8xxx_writeb(led->dev->parent, WLED_OVP_CFG_REG, val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't write wled ovp config"
+ " register rc=%d\n", rc);
+ return rc;
+ }
+
+ /* program current boost limit and output feedback*/
+ if (led->wled_cfg->boost_curr_lim > WLED_CURR_LIMIT_1680mA) {
+ dev_err(led->dev->parent, "Invalid boost current limit");
+ return -EINVAL;
+ }
+
+ rc = pm8xxx_readb(led->dev->parent, WLED_BOOST_CFG_REG, &val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't read wled boost config"
+ " register rc=%d\n", rc);
+ return rc;
+ }
+
+ val = (val & ~WLED_BOOST_LIMIT_MASK) |
+ (led->wled_cfg->boost_curr_lim << WLED_BOOST_LIMIT_BIT_SHFT);
+
+ val = (val & ~WLED_OP_FDBCK_MASK) |
+ (led->wled_cfg->op_fdbck << WLED_OP_FDBCK_BIT_SHFT);
+
+ rc = pm8xxx_writeb(led->dev->parent, WLED_BOOST_CFG_REG, val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't write wled boost config"
+ " register rc=%d\n", rc);
+ return rc;
+ }
+
+ /* program high pole capacitance */
+ if (led->wled_cfg->cp_select > WLED_CP_SELECT_MAX) {
+ dev_err(led->dev->parent, "Invalid pole capacitance");
+ return -EINVAL;
+ }
+
+ rc = pm8xxx_readb(led->dev->parent, WLED_HIGH_POLE_CAP_REG, &val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't read wled high pole"
+ " capacitance register rc=%d\n", rc);
+ return rc;
+ }
+
+ val = (val & ~WLED_CP_SELECT_MASK) | led->wled_cfg->cp_select;
+
+ rc = pm8xxx_writeb(led->dev->parent, WLED_HIGH_POLE_CAP_REG, val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't write wled high pole"
+ " capacitance register rc=%d\n", rc);
+ return rc;
+ }
+
+ /* program activation delay and maximum current */
+ for (i = 0; i < num_wled_strings; i++) {
+ rc = pm8xxx_readb(led->dev->parent,
+ WLED_MAX_CURR_CFG_REG(i + 2), &val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't read wled max current"
+ " config register rc=%d\n", rc);
+ return rc;
+ }
+
+ if ((led->wled_cfg->ctrl_delay_us % WLED_CTL_DLY_STEP) ||
+ (led->wled_cfg->ctrl_delay_us > WLED_CTL_DLY_MAX)) {
+ dev_err(led->dev->parent, "Invalid control delay\n");
+ return rc;
+ }
+
+ val = val / WLED_CTL_DLY_STEP;
+ val = (val & ~WLED_CTL_DLY_MASK) |
+ (led->wled_cfg->ctrl_delay_us << WLED_CTL_DLY_BIT_SHFT);
+
+ if ((led->max_current > WLED_MAX_CURR)) {
+ dev_err(led->dev->parent, "Invalid max current\n");
+ return -EINVAL;
+ }
+
+ val = (val & ~WLED_MAX_CURR_MASK) | led->max_current;
+
+ rc = pm8xxx_writeb(led->dev->parent,
+ WLED_MAX_CURR_CFG_REG(i + 2), val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't write wled max current"
+ " config register rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ /* program digital module generator, cs out and enable the module */
+ rc = pm8xxx_readb(led->dev->parent, WLED_MOD_CTRL_REG, &val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't read wled module ctrl"
+ " register rc=%d\n", rc);
+ return rc;
+ }
+
+ if (led->wled_cfg->dig_mod_gen_en)
+ val |= WLED_DIG_MOD_GEN_MASK;
+
+ if (led->wled_cfg->cs_out_en)
+ val |= WLED_CS_OUT_MASK;
+
+ val |= WLED_EN_MASK;
+
+ rc = pm8xxx_writeb(led->dev->parent, WLED_MOD_CTRL_REG, val);
+ if (rc) {
+ dev_err(led->dev->parent, "can't write wled module ctrl"
+ " register rc=%d\n", rc);
+ return rc;
+ }
+
+ /* dump wled registers */
+ wled_dump_regs(led);
+
+ return 0;
+}
+
static int __devinit get_init_value(struct pm8xxx_led_data *led, u8 *val)
{
int rc, offset;
@@ -300,6 +571,15 @@
case PM8XXX_ID_FLASH_LED_1:
addr = SSBI_REG_ADDR_FLASH_DRV1;
break;
+ case PM8XXX_ID_WLED:
+ rc = init_wled(led);
+ if (rc)
+ dev_err(led->cdev.dev, "can't initialize wled rc=%d\n",
+ rc);
+ return rc;
+ default:
+ dev_err(led->cdev.dev, "unknown led id %d", led->id);
+ return -EINVAL;
}
rc = pm8xxx_readb(led->dev->parent, addr, val);
@@ -351,6 +631,7 @@
return rc;
}
+
static int __devinit pm8xxx_led_probe(struct platform_device *pdev)
{
const struct pm8xxx_led_platform_data *pdata = pdev->dev.platform_data;
@@ -388,9 +669,11 @@
led_dat->pwm_channel = led_cfg->pwm_channel;
led_dat->pwm_period_us = led_cfg->pwm_period_us;
led_dat->pwm_duty_cycles = led_cfg->pwm_duty_cycles;
+ led_dat->wled_cfg = led_cfg->wled_cfg;
+ led_dat->max_current = led_cfg->max_current;
if (!((led_dat->id >= PM8XXX_ID_LED_KB_LIGHT) &&
- (led_dat->id <= PM8XXX_ID_FLASH_LED_1))) {
+ (led_dat->id < PM8XXX_ID_MAX))) {
dev_err(&pdev->dev, "invalid LED ID (%d) specified\n",
led_dat->id);
rc = -EINVAL;
@@ -424,6 +707,12 @@
goto fail_id_check;
}
+ /* configure default state */
+ if (led_cfg->default_state)
+ led->cdev.brightness = led_dat->cdev.max_brightness;
+ else
+ led->cdev.brightness = LED_OFF;
+
if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL) {
__pm8xxx_led_work(led_dat,
led_dat->cdev.max_brightness);
@@ -436,9 +725,10 @@
"configure LED, error: %d\n", rc);
goto fail_id_check;
}
+ schedule_work(&led->work);
}
} else {
- __pm8xxx_led_work(led_dat, LED_OFF);
+ __pm8xxx_led_work(led_dat, led->cdev.brightness);
}
}
diff --git a/drivers/media/video/msm/gemini/Makefile b/drivers/media/video/msm/gemini/Makefile
index 3e2fc97..8a7cd93 100644
--- a/drivers/media/video/msm/gemini/Makefile
+++ b/drivers/media/video/msm/gemini/Makefile
@@ -1,2 +1,3 @@
GCC_VERSION := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+EXTRA_CFLAGS += -Idrivers/media/video/msm
obj-$(CONFIG_MSM_GEMINI) += msm_gemini_dev.o msm_gemini_sync.o msm_gemini_core.o msm_gemini_hw.o msm_gemini_platform.o
diff --git a/drivers/media/video/msm/gemini/msm_gemini_dev.c b/drivers/media/video/msm/gemini/msm_gemini_dev.c
index 1156bb0..01d45ed 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_dev.c
+++ b/drivers/media/video/msm/gemini/msm_gemini_dev.c
@@ -20,8 +20,11 @@
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/uaccess.h>
-
#include <media/msm_gemini.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+
+#include "msm.h"
#include "msm_gemini_sync.h"
#include "msm_gemini_common.h"
@@ -66,8 +69,8 @@
int rc;
struct msm_gemini_device *pgmn_dev = filp->private_data;
- GMN_DBG(KERN_INFO "%s:%d] cmd = %d\n", __func__, __LINE__,
- _IOC_NR(cmd));
+ GMN_DBG("%s:%d] cmd=%d pgmn_dev=0x%x arg=0x%x\n", __func__,
+ __LINE__, _IOC_NR(cmd), (uint32_t)pgmn_dev, (uint32_t)arg);
rc = __msm_gemini_ioctl(pgmn_dev, cmd, arg);
@@ -84,21 +87,78 @@
static struct class *msm_gemini_class;
static dev_t msm_gemini_devno;
-static struct msm_gemini_device *msm_gemini_device_p;
+struct msm_gemini_device *msm_gemini_device_p;
+
+int msm_gemini_subdev_init(struct v4l2_subdev *gemini_sd)
+{
+ int rc;
+ struct msm_gemini_device *pgmn_dev =
+ (struct msm_gemini_device *)gemini_sd->host_priv;
+
+ GMN_DBG("%s:%d: gemini_sd=0x%x pgmn_dev=0x%x\n",
+ __func__, __LINE__, (uint32_t)gemini_sd, (uint32_t)pgmn_dev);
+ rc = __msm_gemini_open(pgmn_dev);
+ GMN_DBG("%s:%d: rc=%d\n",
+ __func__, __LINE__, rc);
+ return rc;
+}
+
+static long msm_gemini_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ long rc;
+ struct msm_gemini_device *pgmn_dev =
+ (struct msm_gemini_device *)sd->host_priv;
+
+ GMN_DBG("%s: cmd=%d\n", __func__, cmd);
+
+ GMN_DBG("%s: pgmn_dev 0x%x", __func__, (uint32_t)pgmn_dev);
+
+ GMN_DBG("%s: Calling __msm_gemini_ioctl\n", __func__);
+
+ rc = __msm_gemini_ioctl(pgmn_dev, cmd, (unsigned long)arg);
+ pr_debug("%s: X\n", __func__);
+ return rc;
+}
+
+void msm_gemini_subdev_release(struct v4l2_subdev *gemini_sd)
+{
+ int rc;
+ struct msm_gemini_device *pgmn_dev =
+ (struct msm_gemini_device *)gemini_sd->host_priv;
+ GMN_DBG("%s:pgmn_dev=0x%x", __func__, (uint32_t)pgmn_dev);
+ rc = __msm_gemini_release(pgmn_dev);
+ GMN_DBG("%s:rc=%d", __func__, rc);
+}
+
+static const struct v4l2_subdev_core_ops msm_gemini_subdev_core_ops = {
+ .ioctl = msm_gemini_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_gemini_subdev_ops = {
+ .core = &msm_gemini_subdev_core_ops,
+};
static int msm_gemini_init(struct platform_device *pdev)
{
int rc = -1;
struct device *dev;
- GMN_DBG("%s:%d]\n", __func__, __LINE__);
-
+ GMN_DBG("%s:\n", __func__);
msm_gemini_device_p = __msm_gemini_init(pdev);
if (msm_gemini_device_p == NULL) {
GMN_PR_ERR("%s: initialization failed\n", __func__);
goto fail;
}
+ v4l2_subdev_init(&msm_gemini_device_p->subdev, &msm_gemini_subdev_ops);
+ v4l2_set_subdev_hostdata(&msm_gemini_device_p->subdev,
+ msm_gemini_device_p);
+ pr_debug("%s: msm_gemini_device_p 0x%x", __func__,
+ (uint32_t)msm_gemini_device_p);
+ GMN_DBG("%s:gemini: platform_set_drvdata\n", __func__);
+ platform_set_drvdata(pdev, &msm_gemini_device_p->subdev);
+
rc = alloc_chrdev_region(&msm_gemini_devno, 0, 1, MSM_GEMINI_NAME);
if (rc < 0) {
GMN_PR_ERR("%s: failed to allocate chrdev\n", __func__);
@@ -168,9 +228,7 @@
static int __msm_gemini_probe(struct platform_device *pdev)
{
- int rc;
- rc = msm_gemini_init(pdev);
- return rc;
+ return msm_gemini_init(pdev);
}
static int __msm_gemini_remove(struct platform_device *pdev)
@@ -183,7 +241,7 @@
.probe = __msm_gemini_probe,
.remove = __msm_gemini_remove,
.driver = {
- .name = "msm_gemini",
+ .name = MSM_GEMINI_DRV_NAME,
.owner = THIS_MODULE,
},
};
diff --git a/drivers/media/video/msm/gemini/msm_gemini_sync.h b/drivers/media/video/msm/gemini/msm_gemini_sync.h
index 6c69a92..a47e766 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_sync.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_sync.h
@@ -17,6 +17,8 @@
#include <linux/list.h>
#include <linux/cdev.h>
#include <linux/platform_device.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
#include "msm_gemini_core.h"
struct msm_gemini_q {
@@ -63,6 +65,8 @@
/* input buf queue
*/
struct msm_gemini_q input_buf_q;
+
+ struct v4l2_subdev subdev;
};
int __msm_gemini_open(struct msm_gemini_device *pgmn_dev);
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 7680559..40bc160 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -36,7 +36,7 @@
#define MSM_V4L2_DIMENSION_SIZE 96
#define MAX_DEV_NAME_LEN 50
-#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \
+#define ERR_USER_COPY(to) pr_debug("%s(%d): copy %s user\n", \
__func__, __LINE__, ((to) ? "to" : "from"))
#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
#define ERR_COPY_TO_USER() ERR_USER_COPY(1)
@@ -47,6 +47,7 @@
#define MSM_ISPIF_DRV_NAME "msm_ispif"
#define MSM_VFE_DRV_NAME "msm_vfe"
#define MSM_VPE_DRV_NAME "msm_vpe"
+#define MSM_GEMINI_DRV_NAME "msm_gemini"
/* msm queue management APIs*/
@@ -232,6 +233,7 @@
struct v4l2_subdev *csic_sdev; /*csid sub device*/
struct v4l2_subdev *ispif_sdev; /* ispif sub device */
struct v4l2_subdev *act_sdev; /* actuator sub device */
+ struct v4l2_subdev *gemini_sdev; /* gemini sub device */
struct pm_qos_request_list pm_qos_req_list;
struct msm_mctl_pp_info pp_info;
@@ -248,12 +250,13 @@
/*int (*isp_init)(struct msm_cam_v4l2_device *pcam);*/
int (*isp_open)(struct v4l2_subdev *sd, struct v4l2_subdev *sd_vpe,
- struct msm_sync *sync);
+ struct v4l2_subdev *gemini_sdev, struct msm_sync *sync);
int (*isp_config)(struct msm_cam_media_controller *pmctl,
unsigned int cmd, unsigned long arg);
int (*isp_notify)(struct v4l2_subdev *sd,
unsigned int notification, void *arg);
- void (*isp_release)(struct msm_sync *psync);
+ void (*isp_release)(struct msm_sync *psync,
+ struct v4l2_subdev *gemini_sdev);
int (*isp_pp_cmd)(struct msm_cam_media_controller *pmctl,
struct msm_mctl_pp_cmd, void *data);
@@ -462,7 +465,9 @@
struct msm_vfe_cfg_cmd *cfgcmd, void *data);
int msm_vpe_subdev_init(struct v4l2_subdev *sd, void *data,
struct platform_device *pdev);
+int msm_gemini_subdev_init(struct v4l2_subdev *sd);
void msm_vpe_subdev_release(struct platform_device *pdev);
+void msm_gemini_subdev_release(struct v4l2_subdev *gemini_sd);
int msm_isp_subdev_ioctl_vpe(struct v4l2_subdev *isp_subdev,
struct msm_mctl_pp_cmd *cmd, void *data);
int msm_mctl_is_pp_msg_type(struct msm_cam_media_controller *p_mctl,
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index bb50d77..16964b2 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -26,6 +26,7 @@
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
#include <media/msm_isp.h>
+#include <media/msm_gemini.h>
#include "msm.h"
@@ -34,10 +35,6 @@
#else
#define D(fmt, args...) do {} while (0)
#endif
-#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \
- __func__, __LINE__, ((to) ? "to" : "from"))
-#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
-#define ERR_COPY_TO_USER() ERR_USER_COPY(1)
#define MSM_FRAME_AXI_MAX_BUF 32
@@ -151,7 +148,7 @@
int vfe_id = vdata->evt_msg.msg_id;
if (!pcam) {
- pr_err("%s pcam is null. return\n", __func__);
+ pr_debug("%s pcam is null. return\n", __func__);
msm_isp_sync_free(vdata);
return rc;
}
@@ -181,7 +178,7 @@
break;
case VFE_MSG_V32_CAPTURE:
case VFE_MSG_V2X_CAPTURE:
- pr_err("%s Got V32_CAPTURE: getting buffer for id = %d",
+ pr_debug("%s Got V32_CAPTURE: getting buffer for id = %d",
__func__, vfe_id);
msm_mctl_reserve_free_buf(&pcam->mctl, NULL,
image_mode, &free_buf);
@@ -202,6 +199,19 @@
vfe_params.data = (void *)&free_buf;
rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
break;
+ case VFE_MSG_V32_JPEG_CAPTURE:
+ free_buf.num_planes = 1;
+ free_buf.ch_paddr[0] = IMEM_Y_OFFSET;
+ free_buf.ch_paddr[1] = IMEM_CBCR_OFFSET;
+ cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
+ cfgcmd.value = &vfe_id;
+ vfe_params.vfe_cfg = &cfgcmd;
+ vfe_params.data = (void *)&free_buf;
+ rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+ /* Write the same buffer into PONG */
+ cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
+ rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+ break;
case VFE_MSG_OUTPUT_IRQ:
D("%s Got OUTPUT_IRQ: Getting free buf id = %d",
__func__, vfe_id);
@@ -413,7 +423,7 @@
/* This function is called by open() function, so we need to init HW*/
static int msm_isp_open(struct v4l2_subdev *sd,
- struct v4l2_subdev *sd_vpe,
+ struct v4l2_subdev *sd_vpe, struct v4l2_subdev *gemini_sdev,
struct msm_sync *sync)
{
/* init vfe and senor, register sync callbacks for init*/
@@ -439,7 +449,8 @@
return rc;
}
-static void msm_isp_release(struct msm_sync *psync)
+static void msm_isp_release(struct msm_sync *psync,
+ struct v4l2_subdev *gemini_sdev)
{
D("%s\n", __func__);
msm_vfe_subdev_release(psync->pdev);
@@ -447,7 +458,7 @@
}
static int msm_config_vfe(struct v4l2_subdev *sd,
- struct msm_sync *sync, void __user *arg)
+ struct msm_sync *sync, void __user *arg)
{
struct msm_vfe_cfg_cmd cfgcmd;
struct msm_pmem_region region[8];
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 13d1daf..54458d1 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -304,7 +304,7 @@
pr_err("%s: param is NULL", __func__);
return -EINVAL;
}
- D("%s cmd = %d\n", __func__, _IOC_NR(cmd));
+ D("%s:%d: cmd %d\n", __func__, __LINE__, cmd);
/* ... call sensor, ISPIF or VEF subdev*/
switch (cmd) {
@@ -436,6 +436,8 @@
/* ISFIF config*/
default:
/* ISP config*/
+ D("%s:%d: go to default. Calling msm_isp_config\n",
+ __func__, __LINE__);
rc = p_mctl->isp_sdev->isp_config(p_mctl, cmd, arg);
break;
}
@@ -556,6 +558,34 @@
}
rc = 0;
+
+
+ /* register gemini subdev */
+ driver = driver_find(MSM_GEMINI_DRV_NAME, &platform_bus_type);
+ if (!driver) {
+ pr_err("%s:%d:Gemini: Failure: goto out\n",
+ __func__, __LINE__);
+ goto out;
+ }
+ pr_debug("%s:%d:Gemini: driver_find_device Gemini driver 0x%x\n",
+ __func__, __LINE__, (uint32_t)driver);
+ dev = driver_find_device(driver, NULL, NULL,
+ msm_mctl_subdev_match_core);
+ if (!dev) {
+ pr_err("%s:%d:Gemini: Failure goto out_put_driver\n",
+ __func__, __LINE__);
+ goto out_put_driver;
+ }
+ p_mctl->gemini_sdev = dev_get_drvdata(dev);
+ pr_debug("%s:%d:Gemini: After dev_get_drvdata gemini_sdev=0x%x\n",
+ __func__, __LINE__, (uint32_t)p_mctl->gemini_sdev);
+
+ if (p_mctl->gemini_sdev == NULL) {
+ pr_err("%s:%d:Gemini: Failure gemini_sdev is null\n",
+ __func__, __LINE__);
+ goto out_put_driver;
+ }
+ rc = 0;
return rc;
out_put_driver:
put_driver(driver);
@@ -629,7 +659,9 @@
if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_open)
rc = p_mctl->isp_sdev->isp_open(
p_mctl->isp_sdev->sd,
- p_mctl->isp_sdev->sd_vpe, sync);
+ p_mctl->isp_sdev->sd_vpe,
+ p_mctl->gemini_sdev,
+ sync);
if (rc < 0) {
pr_err("%s: isp init failed: %d\n", __func__, rc);
goto msm_open_done;
@@ -691,7 +723,8 @@
}
if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_release)
- p_mctl->isp_sdev->isp_release(&p_mctl->sync);
+ p_mctl->isp_sdev->isp_release(&p_mctl->sync,
+ p_mctl->gemini_sdev);
if (camdev->is_csid) {
v4l2_subdev_call(p_mctl->csid_sdev, core, ioctl,
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index 0ba1c0f..54b4efb 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.c
@@ -36,13 +36,6 @@
#define D(fmt, args...) do {} while (0)
#endif
-
-#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \
- __func__, __LINE__, ((to) ? "to" : "from"))
-#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
-#define ERR_COPY_TO_USER() ERR_USER_COPY(1)
-
-
#define PAD_TO_WORD(a) (((a) + 3) & ~3)
#define __CONTAINS(r, v, l, field) ({ \
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 99d9911..89bdf0f 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -702,8 +702,6 @@
msm_io_w(VFE_IMASK_WHILE_STOPPING_1,
vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
- msm_io_dump(vfe32_ctrl->vfebase, vfe32_ctrl->register_total * 4);
-
/* Ensure the write order while writing
to the command register using the barrier */
msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
@@ -851,7 +849,9 @@
/* capture command is valid for both idle and active state. */
vfe32_ctrl->outpath.out1.capture_cnt = num_frames_capture;
if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
- vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
vfe32_ctrl->outpath.out0.capture_cnt =
num_frames_capture;
}
@@ -887,6 +887,9 @@
vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
}
}
+
+ vfe32_ctrl->vfe_capture_count = num_frames_capture;
+
msm_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
msm_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
msm_camio_bus_scale_cfg(
@@ -1286,16 +1289,31 @@
rc = vfe32_capture_raw(snapshot_cnt);
break;
case VFE_CMD_CAPTURE:
- pr_info("vfe32_proc_general: cmdID = %s\n",
- vfe32_general_cmd[cmd->id]);
+ CDBG("vfe32_proc_general: cmdID = %s op mode = %d\n",
+ vfe32_general_cmd[cmd->id], vfe32_ctrl->operation_mode);
if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
sizeof(uint32_t))) {
rc = -EFAULT;
goto proc_general_done;
}
- /* Configure primary channel */
- rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE,
- VFE_MSG_OUTPUT_PRIMARY);
+
+ if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
+ if (snapshot_cnt != 1) {
+ pr_err("only support 1 inline snapshot\n");
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ /* Configure primary channel for JPEG */
+ rc = vfe32_configure_pingpong_buffers(
+ VFE_MSG_V32_JPEG_CAPTURE,
+ VFE_MSG_OUTPUT_PRIMARY);
+ } else {
+ /* Configure primary channel */
+ rc = vfe32_configure_pingpong_buffers(
+ VFE_MSG_V32_CAPTURE,
+ VFE_MSG_OUTPUT_PRIMARY);
+ }
if (rc < 0) {
pr_err("%s error configuring pingpong buffers"
" for primary output", __func__);
@@ -2610,7 +2628,9 @@
}
if ((vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) ||
- (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB)) {
+ (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB) ||
+ (vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) ||
+ (vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB)) {
/* in snapshot mode */
/* later we need to add check for live snapshot mode. */
if (vfe32_ctrl->frame_skip_pattern & (0x1 <<
@@ -2858,6 +2878,8 @@
*/
out_bool = ((vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG ||
+ vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
vfe32_ctrl->operation_mode == VFE_OUTPUTS_RAW ||
vfe32_ctrl->liveshot_state == VFE_STATE_STARTED ||
vfe32_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED ||
@@ -2899,6 +2921,10 @@
vfe32_ctrl->operation_mode ==
VFE_OUTPUTS_MAIN_AND_THUMB ||
vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_THUMB_AND_JPEG ||
+ vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_JPEG_AND_THUMB ||
+ vfe32_ctrl->operation_mode ==
VFE_OUTPUTS_RAW ||
vfe32_ctrl->liveshot_state == VFE_STATE_STOPPED)
vfe32_ctrl->outpath.out0.capture_cnt--;
@@ -3392,6 +3418,10 @@
vfe32_ctrl->operation_mode ==
VFE_OUTPUTS_MAIN_AND_THUMB ||
vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_THUMB_AND_JPEG ||
+ vfe32_ctrl->operation_mode ==
+ VFE_OUTPUTS_JPEG_AND_THUMB ||
+ vfe32_ctrl->operation_mode ==
VFE_OUTPUTS_RAW) {
if ((vfe32_ctrl->outpath.out0.capture_cnt == 0)
&& (vfe32_ctrl->outpath.out1.
diff --git a/drivers/media/video/msm/sensors/Makefile b/drivers/media/video/msm/sensors/Makefile
index 33db124..047226e 100644
--- a/drivers/media/video/msm/sensors/Makefile
+++ b/drivers/media/video/msm/sensors/Makefile
@@ -5,8 +5,8 @@
obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor.o
obj-$(CONFIG_IMX074) += imx074_v4l2.o
obj-$(CONFIG_MT9M114) += mt9m114_v4l2.o
+obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
obj-$(CONFIG_OV2720) += ov2720.o
obj-$(CONFIG_S5K4E1) += s5k4e1_v4l2.o
obj-$(CONFIG_MT9E013) += mt9e013_v4l2.o
obj-$(CONFIG_WEBCAM_OV9726) += ov9726_v4l2.o
-obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 30192d9..c8fcf5f 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -69,7 +69,7 @@
obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
-obj-$(CONFIG_WCD9310_CODEC) += wcd9310-core.o wcd9310-irq.o
+obj-$(CONFIG_WCD9310_CODEC) += wcd9310-core.o wcd9310-irq.o wcd9310-slimslave.o
ifeq ($(CONFIG_SA1100_ASSABET),y)
obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
diff --git a/drivers/mfd/wcd9310-core.c b/drivers/mfd/wcd9310-core.c
index 588f950..87abcda 100644
--- a/drivers/mfd/wcd9310-core.c
+++ b/drivers/mfd/wcd9310-core.c
@@ -14,8 +14,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mfd/core.h>
+#include <linux/mfd/wcd9310/wcd9310-slimslave.h>
#include <linux/mfd/pm8xxx/pm8921.h>
-#include <linux/mfd/wcd9310/core.h>
#include <linux/mfd/wcd9310/pdata.h>
#include <linux/mfd/wcd9310/registers.h>
#include <linux/delay.h>
@@ -921,7 +921,7 @@
pr_err("%s: error, initializing device failed\n", __func__);
goto err_slim_add;
}
-
+ tabla_init_slimslave(tabla, tabla_pgd_la);
#ifdef CONFIG_DEBUG_FS
debugTabla = tabla;
@@ -963,6 +963,7 @@
#endif
tabla = slim_get_devicedata(pdev);
+ tabla_deinit_slimslave(tabla);
tabla_device_exit(tabla);
tabla_disable_supplies(tabla);
slim_remove_device(tabla->slim_slave);
diff --git a/drivers/mfd/wcd9310-slimslave.c b/drivers/mfd/wcd9310-slimslave.c
new file mode 100644
index 0000000..dd586fa
--- /dev/null
+++ b/drivers/mfd/wcd9310-slimslave.c
@@ -0,0 +1,522 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/mfd/wcd9310/wcd9310-slimslave.h>
+
+struct tabla_slim_sch_rx {
+ u32 sph;
+ u32 ch_num;
+ u16 ch_h;
+ u16 grph;
+};
+
+struct tabla_slim_sch_tx {
+ u32 sph;
+ u32 ch_num;
+ u16 ch_h;
+ u16 grph;
+};
+
+struct tabla_slim_sch {
+ struct tabla_slim_sch_rx rx[SLIM_MAX_RX_PORTS];
+ struct tabla_slim_sch_tx tx[SLIM_MAX_TX_PORTS];
+};
+
+static struct tabla_slim_sch sh_ch;
+
+static int tabla_alloc_slim_sh_ch_rx(struct tabla *tabla, u8 tabla_pgd_la);
+static int tabla_alloc_slim_sh_ch_tx(struct tabla *tabla, u8 tabla_pgd_la);
+static int tabla_dealloc_slim_sh_ch_rx(struct tabla *tab);
+static int tabla_dealloc_slim_sh_ch_tx(struct tabla *tab);
+
+int tabla_init_slimslave(struct tabla *tabla, u8 tabla_pgd_la)
+{
+ int ret = 0;
+
+ ret = tabla_alloc_slim_sh_ch_rx(tabla, tabla_pgd_la);
+ if (ret) {
+ pr_err("%s: Failed to alloc rx slimbus shared channels\n",
+ __func__);
+ goto rx_err;
+ }
+ ret = tabla_alloc_slim_sh_ch_tx(tabla, tabla_pgd_la);
+ if (ret) {
+ pr_err("%s: Failed to alloc tx slimbus shared channels\n",
+ __func__);
+ goto tx_err;
+ }
+ return 0;
+tx_err:
+ tabla_dealloc_slim_sh_ch_rx(tabla);
+rx_err:
+ return ret;
+}
+
+
+int tabla_deinit_slimslave(struct tabla *tabla)
+{
+ int ret = 0;
+ ret = tabla_dealloc_slim_sh_ch_rx(tabla);
+ if (ret < 0) {
+ pr_err("%s: fail to dealloc rx slim ports\n", __func__);
+ goto err;
+ }
+ ret = tabla_dealloc_slim_sh_ch_tx(tabla);
+ if (ret < 0) {
+ pr_err("%s: fail to dealloc tx slim ports\n", __func__);
+ goto err;
+ }
+err:
+ return ret;
+}
+
+int tabla_get_channel(struct tabla *tabla,
+ unsigned int *rx_ch,
+ unsigned int *tx_ch)
+{
+ int ch_idx = 0;
+ struct tabla_slim_sch_rx *rx = sh_ch.rx;
+ struct tabla_slim_sch_tx *tx = sh_ch.tx;
+
+ for (ch_idx = 0; ch_idx < SLIM_MAX_RX_PORTS; ch_idx++)
+ rx_ch[ch_idx] = rx[ch_idx].ch_num;
+ for (ch_idx = 0; ch_idx < SLIM_MAX_TX_PORTS; ch_idx++)
+ tx_ch[ch_idx] = tx[ch_idx].ch_num;
+ return 0;
+}
+
+static int tabla_alloc_slim_sh_ch_rx(struct tabla *tabla, u8 tabla_pgd_la)
+{
+ int ret = 0;
+ u8 ch_idx ;
+ u16 slave_port_id = 0;
+ struct tabla_slim_sch_rx *rx = sh_ch.rx;
+
+ /* DSP requires channel number to be between 128 and 255. For RX port
+ * use channel numbers from 138 to 144, for TX port
+ * use channel numbers from 128 to 137
+ */
+ pr_debug("%s: pgd_la[%d]\n", __func__, tabla_pgd_la);
+ for (ch_idx = 0; ch_idx < SLIM_MAX_RX_PORTS; ch_idx++) {
+ slave_port_id = (ch_idx + 1 +
+ SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS);
+ rx[ch_idx].ch_num = slave_port_id + BASE_CH_NUM;
+ ret = slim_get_slaveport(tabla_pgd_la, slave_port_id,
+ &rx[ch_idx].sph, SLIM_SINK);
+ if (ret < 0) {
+ pr_err("%s: slave port failure id[%d] ret[%d]\n",
+ __func__, slave_port_id, ret);
+ goto err;
+ }
+
+ ret = slim_query_ch(tabla->slim, rx[ch_idx].ch_num,
+ &rx[ch_idx].ch_h);
+ if (ret < 0) {
+ pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n",
+ __func__, rx[ch_idx].ch_num, ret);
+ goto err;
+ }
+ }
+err:
+ return ret;
+}
+
+static int tabla_alloc_slim_sh_ch_tx(struct tabla *tabla, u8 tabla_pgd_la)
+{
+ int ret = 0;
+ u8 ch_idx ;
+ struct tabla_slim_sch_tx *tx = sh_ch.tx;
+ u16 slave_port_id = 0;
+
+ pr_debug("%s: pgd_la[%d]\n", __func__, tabla_pgd_la);
+ /* DSP requires channel number to be between 128 and 255. For RX port
+ * use channel numbers from 138 to 144, for TX port
+ * use channel numbers from 128 to 137
+ */
+ for (ch_idx = 0; ch_idx < SLIM_MAX_TX_PORTS; ch_idx++) {
+ slave_port_id = ch_idx;
+ tx[ch_idx].ch_num = slave_port_id + BASE_CH_NUM;
+ ret = slim_get_slaveport(tabla_pgd_la, slave_port_id,
+ &tx[ch_idx].sph, SLIM_SRC);
+ if (ret < 0) {
+ pr_err("%s: slave port failure id[%d] ret[%d]\n",
+ __func__, slave_port_id, ret);
+ goto err;
+ }
+ ret = slim_query_ch(tabla->slim, tx[ch_idx].ch_num,
+ &tx[ch_idx].ch_h);
+ if (ret < 0) {
+ pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n",
+ __func__, tx[ch_idx].ch_num, ret);
+ goto err;
+ }
+ }
+err:
+ return ret;
+}
+
+static int tabla_dealloc_slim_sh_ch_rx(struct tabla *tab)
+{
+ int idx = 0;
+ int ret = 0;
+ struct tabla_slim_sch_rx *rx = sh_ch.rx;
+ /* slim_dealloc_ch */
+ for (idx = 0; idx < SLIM_MAX_RX_PORTS; idx++) {
+ ret = slim_dealloc_ch(tab->slim, rx[idx].ch_h);
+ if (ret < 0) {
+ pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n",
+ __func__, ret, rx[idx].ch_h);
+ }
+ }
+ memset(sh_ch.rx, 0, sizeof(sh_ch.rx));
+ return ret;
+}
+
+static int tabla_dealloc_slim_sh_ch_tx(struct tabla *tab)
+{
+ int idx = 0;
+ int ret = 0;
+ struct tabla_slim_sch_tx *tx = sh_ch.tx;
+ /* slim_dealloc_ch */
+ for (idx = 0; idx < SLIM_MAX_TX_PORTS; idx++) {
+ ret = slim_dealloc_ch(tab->slim, tx[idx].ch_h);
+ if (ret < 0) {
+ pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n",
+ __func__, ret, tx[idx].ch_h);
+ }
+ }
+ memset(sh_ch.tx, 0, sizeof(sh_ch.tx));
+ return ret;
+}
+
+/* Enable slimbus slave device for RX path */
+int tabla_cfg_slim_sch_rx(struct tabla *tab, unsigned int *ch_num,
+ unsigned int ch_cnt, unsigned int rate)
+{
+ u8 i = 0;
+ u16 grph;
+ u32 sph[SLIM_MAX_RX_PORTS] = {0};
+ u16 ch_h[SLIM_MAX_RX_PORTS] = {0};
+ u16 slave_port_id;
+ u8 payload_rx = 0, wm_payload = 0;
+ int ret, idx = 0;
+ unsigned short multi_chan_cfg_reg_addr;
+ struct tabla_slim_sch_rx *rx = sh_ch.rx;
+ struct slim_ch prop;
+
+ /* Configure slave interface device */
+ pr_debug("%s: ch_cnt[%d] rate=%d\n", __func__, ch_cnt, rate);
+
+ for (i = 0; i < ch_cnt; i++) {
+ idx = (ch_num[i] - BASE_CH_NUM -
+ SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+ ch_h[i] = rx[idx].ch_h;
+ sph[i] = rx[idx].sph;
+ slave_port_id = idx + 1;
+ if ((slave_port_id > SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS) ||
+ (slave_port_id == 0)) {
+ pr_err("Slimbus: invalid slave port id: %d",
+ slave_port_id);
+ ret = -EINVAL;
+ goto err;
+ }
+ slave_port_id += SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS;
+ /* look for the valid port range and chose the
+ * payload accordingly
+ */
+ if ((slave_port_id >
+ SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID) &&
+ (slave_port_id <
+ SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID)) {
+ payload_rx = payload_rx |
+ (1 <<
+ (slave_port_id -
+ SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID));
+ } else {
+ ret = -EINVAL;
+ goto err;
+ }
+ multi_chan_cfg_reg_addr =
+ SB_PGD_RX_PORT_MULTI_CHANNEL_0(slave_port_id);
+ /* write to interface device */
+ ret = tabla_interface_reg_write(tab, multi_chan_cfg_reg_addr,
+ payload_rx);
+ if (ret < 0) {
+ pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
+ __func__,
+ multi_chan_cfg_reg_addr,
+ payload_rx, ret);
+ goto err;
+ }
+ /* configure the slave port for water mark and enable*/
+ wm_payload = (SLAVE_PORT_WATER_MARK_VALUE <<
+ SLAVE_PORT_WATER_MARK_SHIFT) +
+ SLAVE_PORT_ENABLE;
+ ret = tabla_interface_reg_write(tab,
+ SB_PGD_PORT_CFG_BYTE_ADDR(slave_port_id),
+ wm_payload);
+ if (ret < 0) {
+ pr_err("%s:watermark set failure for port[%d] ret[%d]",
+ __func__, slave_port_id, ret);
+ }
+ }
+
+ /* slim_define_ch api */
+ prop.prot = SLIM_AUTO_ISO;
+ prop.baser = SLIM_RATE_4000HZ;
+ prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
+ prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
+ prop.ratem = (rate/4000);
+ prop.sampleszbits = 16;
+
+ ret = slim_define_ch(tab->slim, &prop, ch_h, ch_cnt,
+ true, &grph);
+ if (ret < 0) {
+ pr_err("%s: slim_define_ch failed ret[%d]\n",
+ __func__, ret);
+ goto err;
+ }
+ for (i = 0; i < ch_cnt; i++) {
+ ret = slim_connect_sink(tab->slim, &sph[i],
+ 1, ch_h[i]);
+ if (ret < 0) {
+ pr_err("%s: slim_connect_sink failed ret[%d]\n",
+ __func__, ret);
+ goto err_close_slim_sch;
+ }
+ }
+ /* slim_control_ch */
+ ret = slim_control_ch(tab->slim, grph, SLIM_CH_ACTIVATE,
+ true);
+ if (ret < 0) {
+ pr_err("%s: slim_control_ch failed ret[%d]\n",
+ __func__, ret);
+ goto err_close_slim_sch;
+ }
+ for (i = 0; i < ch_cnt; i++) {
+ idx = (ch_num[i] - BASE_CH_NUM -
+ SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+ rx[idx].grph = grph;
+ }
+ return 0;
+
+err_close_slim_sch:
+ /* release all acquired handles */
+ tabla_close_slim_sch_rx(tab, ch_num, ch_cnt);
+err:
+ return ret;
+}
+EXPORT_SYMBOL_GPL(tabla_cfg_slim_sch_rx);
+
+/* Enable slimbus slave device for RX path */
+int tabla_cfg_slim_sch_tx(struct tabla *tab, unsigned int *ch_num,
+ unsigned int ch_cnt, unsigned int rate)
+{
+ u8 i = 0;
+ u8 payload_tx_0 = 0, payload_tx_1 = 0, wm_payload = 0;
+ u16 grph;
+ u32 sph[SLIM_MAX_TX_PORTS] = {0};
+ u16 ch_h[SLIM_MAX_TX_PORTS] = {0};
+ u16 idx = 0, slave_port_id;
+ int ret = 0;
+ unsigned short multi_chan_cfg_reg_addr;
+
+ struct tabla_slim_sch_tx *tx = sh_ch.tx;
+ struct slim_ch prop;
+
+ pr_debug("%s: ch_cnt[%d] rate[%d]\n", __func__, ch_cnt, rate);
+ for (i = 0; i < ch_cnt; i++) {
+ idx = (ch_num[i] - BASE_CH_NUM);
+ ch_h[i] = tx[idx].ch_h;
+ sph[i] = tx[idx].sph;
+ slave_port_id = idx ;
+ if ((slave_port_id > SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS) ||
+ (slave_port_id == 0)) {
+ pr_err("SLIMbus: invalid slave port id: %d",
+ slave_port_id);
+ ret = -EINVAL;
+ goto err;
+ }
+ /* look for the valid port range and chose the
+ * payload accordingly
+ */
+ if (slave_port_id <=
+ SB_PGD_TX_PORT_MULTI_CHANNEL_0_END_PORT_ID) {
+ payload_tx_0 = payload_tx_0 | (1 << slave_port_id);
+ } else if (slave_port_id <
+ SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID) {
+ payload_tx_1 = payload_tx_1 |
+ (1 <<
+ (slave_port_id -
+ SB_PGD_TX_PORT_MULTI_CHANNEL_1_START_PORT_ID));
+ } else {
+ ret = -EINVAL;
+ goto err;
+ }
+ multi_chan_cfg_reg_addr =
+ SB_PGD_TX_PORT_MULTI_CHANNEL_0(slave_port_id);
+ /* write to interface device */
+ ret = tabla_interface_reg_write(tab, multi_chan_cfg_reg_addr,
+ payload_tx_0);
+ if (ret < 0) {
+ pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
+ __func__,
+ multi_chan_cfg_reg_addr,
+ payload_tx_0, ret);
+ goto err;
+ }
+ multi_chan_cfg_reg_addr =
+ SB_PGD_TX_PORT_MULTI_CHANNEL_1(slave_port_id);
+ /* ports 8,9 */
+ ret = tabla_interface_reg_write(tab, multi_chan_cfg_reg_addr,
+ payload_tx_1);
+ if (ret < 0) {
+ pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
+ __func__,
+ multi_chan_cfg_reg_addr,
+ payload_tx_1, ret);
+ goto err;
+ }
+ /* configure the slave port for water mark and enable*/
+ wm_payload = (SLAVE_PORT_WATER_MARK_VALUE <<
+ SLAVE_PORT_WATER_MARK_SHIFT) +
+ SLAVE_PORT_ENABLE;
+ ret = tabla_interface_reg_write(tab,
+ SB_PGD_PORT_CFG_BYTE_ADDR(slave_port_id),
+ wm_payload);
+ if (ret < 0) {
+ pr_err("%s:watermark set failure for port[%d] ret[%d]",
+ __func__,
+ slave_port_id, ret);
+ }
+ }
+
+ /* slim_define_ch api */
+ prop.prot = SLIM_AUTO_ISO;
+ prop.baser = SLIM_RATE_4000HZ;
+ prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
+ prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
+ prop.ratem = (rate/4000);
+ prop.sampleszbits = 16;
+ ret = slim_define_ch(tab->slim, &prop, ch_h, ch_cnt,
+ true, &grph);
+ if (ret < 0) {
+ pr_err("%s: slim_define_ch failed ret[%d]\n",
+ __func__, ret);
+ goto err;
+ }
+ for (i = 0; i < ch_cnt; i++) {
+ ret = slim_connect_src(tab->slim, sph[i],
+ ch_h[i]);
+ if (ret < 0) {
+ pr_err("%s: slim_connect_src failed ret[%d]\n",
+ __func__, ret);
+ goto err;
+ }
+ }
+ /* slim_control_ch */
+ ret = slim_control_ch(tab->slim, grph, SLIM_CH_ACTIVATE,
+ true);
+ if (ret < 0) {
+ pr_err("%s: slim_control_ch failed ret[%d]\n",
+ __func__, ret);
+ goto err;
+ }
+ for (i = 0; i < ch_cnt; i++) {
+ idx = (ch_num[i] - BASE_CH_NUM);
+ tx[idx].grph = grph;
+ }
+ return 0;
+err:
+ /* release all acquired handles */
+ tabla_close_slim_sch_tx(tab, ch_num, ch_cnt);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(tabla_cfg_slim_sch_tx);
+
+int tabla_close_slim_sch_rx(struct tabla *tab, unsigned int *ch_num,
+ unsigned int ch_cnt)
+{
+ u16 grph = 0;
+ u32 sph[SLIM_MAX_RX_PORTS] = {0};
+ int i = 0 , idx = 0;
+ int ret = 0;
+ struct tabla_slim_sch_rx *rx = sh_ch.rx;
+
+ pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt);
+ for (i = 0; i < ch_cnt; i++) {
+ idx = (ch_num[i] - BASE_CH_NUM -
+ SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+ sph[i] = rx[idx].sph;
+ grph = rx[idx].grph;
+ }
+
+ /* slim_disconnect_port */
+ ret = slim_disconnect_ports(tab->slim, sph, ch_cnt);
+ if (ret < 0) {
+ pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
+ __func__, ret);
+ }
+ /* slim_control_ch (REMOVE) */
+ ret = slim_control_ch(tab->slim, grph, SLIM_CH_REMOVE, true);
+ if (ret < 0) {
+ pr_err("%s: slim_control_ch failed ret[%d]\n",
+ __func__, ret);
+ goto err;
+ }
+ for (i = 0; i < ch_cnt; i++) {
+ idx = (ch_num[i] - BASE_CH_NUM -
+ SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+ rx[idx].grph = 0;
+ }
+err:
+ return ret;
+}
+EXPORT_SYMBOL_GPL(tabla_close_slim_sch_rx);
+
+int tabla_close_slim_sch_tx(struct tabla *tab, unsigned int *ch_num,
+ unsigned int ch_cnt)
+{
+ u16 grph = 0;
+ u32 sph[SLIM_MAX_TX_PORTS] = {0};
+ int ret = 0;
+ int i = 0 , idx = 0;
+ struct tabla_slim_sch_tx *tx = sh_ch.tx;
+
+ pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt);
+ for (i = 0; i < ch_cnt; i++) {
+ idx = (ch_num[i] - BASE_CH_NUM);
+ sph[i] = tx[idx].sph;
+ grph = tx[idx].grph;
+ }
+ /* slim_disconnect_port */
+ ret = slim_disconnect_ports(tab->slim, sph, ch_cnt);
+ if (ret < 0) {
+ pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
+ __func__, ret);
+ }
+ /* slim_control_ch (REMOVE) */
+ ret = slim_control_ch(tab->slim, grph, SLIM_CH_REMOVE, true);
+ if (ret < 0) {
+ pr_err("%s: slim_control_ch failed ret[%d]\n",
+ __func__, ret);
+ goto err;
+ }
+ for (i = 0; i < ch_cnt; i++) {
+ idx = (ch_num[i] - BASE_CH_NUM);
+ tx[idx].grph = 0;
+ }
+err:
+ return ret;
+}
+EXPORT_SYMBOL_GPL(tabla_close_slim_sch_tx);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 8f42e5b..1ecf2f3 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1002,6 +1002,12 @@
}
}
+ /* Clear CDR_EN bit for write operations */
+ if (host->tuning_needed && cmd->mrq->data &&
+ (cmd->mrq->data->flags & MMC_DATA_WRITE))
+ writel_relaxed((readl_relaxed(host->base + MCI_DLL_CONFIG) &
+ ~MCI_CDR_EN), host->base + MCI_DLL_CONFIG);
+
if ((cmd->flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
*c |= MCI_CPSM_PROGENA;
host->prog_enable = 1;
@@ -1036,8 +1042,6 @@
host->curr.got_dataend = 0;
host->curr.got_auto_prog_done = 0;
- memset(&host->pio, 0, sizeof(host->pio));
-
datactrl = MCI_DPSM_ENABLE | (data->blksz << 4);
if (host->curr.wait_for_auto_prog_done)
@@ -1072,17 +1076,21 @@
/* Is data transfer in PIO mode required? */
if (!(datactrl & MCI_DPSM_DMAENABLE)) {
- host->pio.sg = data->sg;
- host->pio.sg_len = data->sg_len;
- host->pio.sg_off = 0;
+ unsigned int sg_miter_flags = SG_MITER_ATOMIC;
if (data->flags & MMC_DATA_READ) {
+ sg_miter_flags |= SG_MITER_TO_SG;
pio_irqmask = MCI_RXFIFOHALFFULLMASK;
if (host->curr.xfer_remain < MCI_FIFOSIZE)
pio_irqmask |= MCI_RXDATAAVLBLMASK;
- } else
+ } else {
+ sg_miter_flags |= SG_MITER_FROM_SG;
pio_irqmask = MCI_TXFIFOHALFEMPTYMASK |
MCI_TXFIFOEMPTYMASK;
+ }
+
+ sg_miter_start(&host->sg_miter, data->sg, data->sg_len,
+ sg_miter_flags);
}
if (data->flags & MMC_DATA_READ)
@@ -1248,6 +1256,7 @@
struct msmsdcc_host *host = dev_id;
void __iomem *base = host->base;
uint32_t status;
+ unsigned long flags;
spin_lock(&host->lock);
@@ -1262,9 +1271,10 @@
#if IRQ_DEBUG
msmsdcc_print_status(host, "irq1-r", status);
#endif
+ local_irq_save(flags);
- do {
- unsigned long flags;
+ while (sg_miter_next(&host->sg_miter)) {
+
unsigned int remain, len;
char *buffer;
@@ -1272,12 +1282,8 @@
| MCI_RXDATAAVLBL)))
break;
- /* Map the current scatter buffer */
- local_irq_save(flags);
- buffer = kmap_atomic(sg_page(host->pio.sg),
- KM_BIO_SRC_IRQ) + host->pio.sg->offset;
- buffer += host->pio.sg_off;
- remain = host->pio.sg->length - host->pio.sg_off;
+ buffer = host->sg_miter.addr;
+ remain = host->sg_miter.length;
len = 0;
if (status & MCI_RXACTIVE)
@@ -1288,11 +1294,7 @@
if (len > remain)
len = remain;
- /* Unmap the buffer */
- kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
- local_irq_restore(flags);
-
- host->pio.sg_off += len;
+ host->sg_miter.consumed = len;
host->curr.xfer_remain -= len;
host->curr.data_xfered += len;
remain -= len;
@@ -1300,20 +1302,11 @@
if (remain) /* Done with this page? */
break; /* Nope */
- if (status & MCI_RXACTIVE && host->curr.user_pages)
- flush_dcache_page(sg_page(host->pio.sg));
-
- if (!--host->pio.sg_len) {
- memset(&host->pio, 0, sizeof(host->pio));
- break;
- }
-
- /* Advance to next sg */
- host->pio.sg++;
- host->pio.sg_off = 0;
-
status = readl_relaxed(base + MMCISTATUS);
- } while (1);
+ }
+
+ sg_miter_stop(&host->sg_miter);
+ local_irq_restore(flags);
if (status & MCI_RXACTIVE && host->curr.xfer_remain < MCI_FIFOSIZE) {
writel_relaxed((readl_relaxed(host->base + MMCIMASK0) &
@@ -2876,22 +2869,21 @@
* Select the 3/4 of the range and configure the DLL with the
* selected DLL clock output phase.
*/
-
static u8 find_most_appropriate_phase(struct msmsdcc_host *host,
u8 *phase_table, u8 total_phases)
{
- u8 ret, temp;
- u8 ranges[16][16] = { {0}, {0} };
+ u8 ret, ranges[16][16] = { {0}, {0} };
u8 phases_per_row[16] = {0};
int row_index = 0, col_index = 0, selected_row_index = 0, curr_max = 0;
- int cnt;
+ int i, cnt, phase_0_raw_index = 0, phase_15_raw_index = 0;
+ bool phase_0_found = false, phase_15_found = false;
- for (cnt = 0; cnt <= total_phases; cnt++) {
+ for (cnt = 0; cnt < total_phases; cnt++) {
ranges[row_index][col_index] = phase_table[cnt];
phases_per_row[row_index] += 1;
col_index++;
- if ((cnt + 1) > total_phases) {
+ if ((cnt + 1) == total_phases) {
continue;
/* check if next phase in phase_table is consecutive or not */
} else if ((phase_table[cnt] + 1) != phase_table[cnt + 1]) {
@@ -2900,15 +2892,50 @@
}
}
- for (cnt = 0; cnt <= total_phases; cnt++) {
+ /* Check if phase-0 is present in first valid window? */
+ if (!ranges[0][0]) {
+ phase_0_found = true;
+ phase_0_raw_index = 0;
+ /* Check if cycle exist between 2 valid windows */
+ for (cnt = 1; cnt <= row_index; cnt++) {
+ if (phases_per_row[cnt]) {
+ for (i = 0; i <= phases_per_row[cnt]; i++) {
+ if (ranges[cnt][i] == 15) {
+ phase_15_found = true;
+ phase_15_raw_index = cnt;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* If 2 valid windows form cycle then merge them as single window */
+ if (phase_0_found && phase_15_found) {
+ /* number of phases in raw where phase 0 is present */
+ u8 phases_0 = phases_per_row[phase_0_raw_index];
+ /* number of phases in raw where phase 15 is present */
+ u8 phases_15 = phases_per_row[phase_15_raw_index];
+
+ cnt = 0;
+ for (i = phases_15; i < (phases_15 + phases_0); i++) {
+ ranges[phase_15_raw_index][i] =
+ ranges[phase_0_raw_index][cnt];
+ cnt++;
+ }
+ phases_per_row[phase_0_raw_index] = 0;
+ phases_per_row[phase_15_raw_index] = phases_15 + phases_0;
+ }
+
+ for (cnt = 0; cnt <= row_index; cnt++) {
if (phases_per_row[cnt] > curr_max) {
curr_max = phases_per_row[cnt];
selected_row_index = cnt;
}
}
- temp = ((curr_max * 3) / 4);
- ret = ranges[selected_row_index][temp];
+ i = ((curr_max * 3) / 4) - 1;
+ ret = ranges[selected_row_index][i];
return ret;
}
@@ -2981,11 +3008,12 @@
!memcmp(data_buf, cmd19_tuning_block, 64)) {
/* tuning is successful with this tuning point */
tuned_phases[tuned_phase_cnt++] = phase;
+ pr_debug("%s: %s: found good phase = %d\n",
+ mmc_hostname(mmc), __func__, phase);
}
} while (++phase < 16);
if (tuned_phase_cnt) {
- tuned_phase_cnt--;
phase = find_most_appropriate_phase(host, tuned_phases,
tuned_phase_cnt);
/*
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index ee7a3e5..319d721 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -361,7 +361,7 @@
struct msmsdcc_sps_data sps;
bool is_dma_mode;
bool is_sps_mode;
- struct msmsdcc_pio_data pio;
+ struct sg_mapping_iter sg_miter;
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 02d1c39..d053cd6 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -1886,7 +1886,7 @@
}
- dev->rclk = clk_get(dev->dev, "audio_slimbus_clk");
+ dev->rclk = clk_get(dev->dev, "core_clk");
if (!dev->rclk) {
dev_err(dev->dev, "slimbus clock not found");
goto err_clk_get_failed;
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index ed80b1b..ef28844 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -51,10 +51,7 @@
cpu_policy->user_policy.max = max_freq;
ret = cpufreq_update_policy(cpu);
- if (ret)
- pr_err("msm_thermal: cpufreq update to core%d %d err:%d\n",
- cpu, max_freq, ret);
- else
+ if (!ret)
pr_info("msm_thermal: Limiting core%d max frequency to %d\n",
cpu, max_freq);
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 84cb3f5..3aa4553 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -3,7 +3,7 @@
* MSM 7k High speed uart driver
*
* Copyright (c) 2008 Google Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
* Modified: Nick Pelly <npelly@google.com>
*
* All source code in this file is licensed under the following license
@@ -656,7 +656,6 @@
struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
spin_lock_irqsave(&uport->lock, flags);
- clk_enable(msm_uport->clk);
/*
* Disable Rx channel of UARTDM
@@ -764,9 +763,7 @@
}
msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
- /* calling other hardware component here clk_disable API. */
mb();
- clk_disable(msm_uport->clk);
spin_unlock_irqrestore(&uport->lock, flags);
}
@@ -778,16 +775,11 @@
{
unsigned int data;
unsigned int ret = 0;
- struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
-
- clk_enable(msm_uport->clk);
data = msm_hs_read(uport, UARTDM_SR_ADDR);
if (data & UARTDM_SR_TXEMT_BMSK)
ret = TIOCSER_TEMT;
- clk_disable(msm_uport->clk);
-
return ret;
}
EXPORT_SYMBOL(msm_hs_tx_empty);
@@ -817,8 +809,6 @@
struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
unsigned int data;
- clk_enable(msm_uport->clk);
-
/* disable dlink */
data = msm_hs_read(uport, UARTDM_DMEN_ADDR);
data &= ~UARTDM_RX_DM_EN_BMSK;
@@ -835,8 +825,6 @@
}
if (msm_uport->rx.flush != FLUSH_SHUTDOWN)
msm_uport->rx.flush = FLUSH_STOP;
-
- clk_disable(msm_uport->clk);
}
/* Transmit the next chunk of data */
@@ -1011,7 +999,6 @@
spin_lock_irqsave(&uport->lock, flags);
- clk_enable(msm_uport->clk);
msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE);
/* overflow is not connect to data in a FIFO */
@@ -1085,7 +1072,6 @@
schedule_delayed_work(&msm_uport->rx.flip_insert_work
, msecs_to_jiffies(RETRY_TIMEOUT));
}
- clk_disable(msm_uport->clk);
/* release wakelock in 500ms, not immediately, because higher layers
* don't always take wakelocks when they should */
wake_lock_timeout(&msm_uport->rx.wake_lock, HZ / 2);
@@ -1100,15 +1086,11 @@
{
struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
- clk_enable(msm_uport->clk);
-
if (msm_uport->tx.tx_ready_int_en == 0) {
msm_uport->tx.tx_ready_int_en = 1;
if (msm_uport->tx.dma_in_flight == 0)
msm_hs_submit_tx_locked(uport);
}
-
- clk_disable(msm_uport->clk);
}
/*
@@ -1138,14 +1120,12 @@
tlet_ptr, struct msm_hs_port, tx.tlet);
spin_lock_irqsave(&(msm_uport->uport.lock), flags);
- clk_enable(msm_uport->clk);
msm_uport->imr_reg |= UARTDM_ISR_TX_READY_BMSK;
msm_hs_write(&(msm_uport->uport), UARTDM_IMR_ADDR, msm_uport->imr_reg);
/* Calling clk API. Hence mb() requires. */
mb();
- clk_disable(msm_uport->clk);
spin_unlock_irqrestore(&(msm_uport->uport.lock), flags);
}
@@ -1198,9 +1178,6 @@
{
unsigned int set_rts;
unsigned int data;
- struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
-
- clk_enable(msm_uport->clk);
/* RTS is active low */
set_rts = TIOCM_RTS & mctrl ? 0 : 1;
@@ -1217,9 +1194,7 @@
data |= UARTDM_MR1_RX_RDY_CTL_BMSK;
msm_hs_write(uport, UARTDM_MR1_ADDR, data);
}
- /* Calling CLOCK API. Hence mb() requires. */
mb();
- clk_disable(msm_uport->clk);
}
void msm_hs_set_mctrl(struct uart_port *uport,
@@ -1238,16 +1213,11 @@
{
struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
- clk_enable(msm_uport->clk);
-
/* Enable DELTA_CTS Interrupt */
msm_uport->imr_reg |= UARTDM_ISR_DELTA_CTS_BMSK;
msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
- /* Calling CLOCK API. Hence mb() requires here. */
mb();
- clk_disable(msm_uport->clk);
-
}
/*
@@ -1259,14 +1229,10 @@
static void msm_hs_break_ctl(struct uart_port *uport, int ctl)
{
unsigned long flags;
- struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
spin_lock_irqsave(&uport->lock, flags);
- clk_enable(msm_uport->clk);
msm_hs_write(uport, UARTDM_CR_ADDR, ctl ? START_BREAK : STOP_BREAK);
- /* Calling CLOCK API. Hence mb() requires here. */
mb();
- clk_disable(msm_uport->clk);
spin_unlock_irqrestore(&uport->lock, flags);
}
@@ -1295,18 +1261,12 @@
/* Handle CTS changes (Called from interrupt handler) */
static void msm_hs_handle_delta_cts_locked(struct uart_port *uport)
{
- struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
-
- clk_enable(msm_uport->clk);
-
/* clear interrupt */
msm_hs_write(uport, UARTDM_CR_ADDR, RESET_CTS);
/* Calling CLOCK API. Hence mb() requires here. */
mb();
uport->icount.cts++;
- clk_disable(msm_uport->clk);
-
/* clear the IOCTL TIOCMIWAIT if called */
wake_up_interruptible(&uport->state->port.delta_msr_wait);
}
@@ -1999,8 +1959,6 @@
tasklet_kill(&msm_uport->rx.tlet);
cancel_delayed_work_sync(&msm_uport->rx.flip_insert_work);
- clk_enable(msm_uport->clk);
-
pm_runtime_disable(uport->dev);
pm_runtime_set_suspended(uport->dev);
@@ -2018,7 +1976,6 @@
*/
mb();
- clk_disable(msm_uport->clk); /* to balance local clk_enable() */
if (msm_uport->clk_state != MSM_HS_CLK_OFF) {
clk_disable(msm_uport->clk); /* to balance clk_state */
if (msm_uport->pclk)
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index 6e3982e..f49769d 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -142,20 +142,21 @@
if (enable) {
- ret = clk_enable(msm_hsl_port->clk);
+ ret = clk_prepare_enable(msm_hsl_port->clk);
if (ret)
goto err;
if (msm_hsl_port->pclk) {
- ret = clk_enable(msm_hsl_port->pclk);
+ ret = clk_prepare_enable(msm_hsl_port->pclk);
if (ret) {
- clk_disable(msm_hsl_port->clk);
+ clk_disable_unprepare(msm_hsl_port->clk);
goto err;
}
}
} else {
- clk_disable(msm_hsl_port->clk);
+
+ clk_disable_unprepare(msm_hsl_port->clk);
if (msm_hsl_port->pclk)
- clk_disable(msm_hsl_port->pclk);
+ clk_disable_unprepare(msm_hsl_port->pclk);
}
err:
return ret;
@@ -245,53 +246,37 @@
{
struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
- clk_en(port, 1);
-
msm_hsl_port->imr &= ~UARTDM_ISR_TXLEV_BMSK;
msm_hsl_write(port, msm_hsl_port->imr,
regmap[msm_hsl_port->ver_id][UARTDM_IMR]);
-
- clk_en(port, 0);
}
static void msm_hsl_start_tx(struct uart_port *port)
{
struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
- clk_en(port, 1);
-
msm_hsl_port->imr |= UARTDM_ISR_TXLEV_BMSK;
msm_hsl_write(port, msm_hsl_port->imr,
regmap[msm_hsl_port->ver_id][UARTDM_IMR]);
-
- clk_en(port, 0);
}
static void msm_hsl_stop_rx(struct uart_port *port)
{
struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
- clk_en(port, 1);
-
msm_hsl_port->imr &= ~(UARTDM_ISR_RXLEV_BMSK |
UARTDM_ISR_RXSTALE_BMSK);
msm_hsl_write(port, msm_hsl_port->imr,
regmap[msm_hsl_port->ver_id][UARTDM_IMR]);
-
- clk_en(port, 0);
}
static void msm_hsl_enable_ms(struct uart_port *port)
{
struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
- clk_en(port, 1);
-
msm_hsl_port->imr |= UARTDM_ISR_DELTA_CTS_BMSK;
msm_hsl_write(port, msm_hsl_port->imr,
regmap[msm_hsl_port->ver_id][UARTDM_IMR]);
-
- clk_en(port, 0);
}
static void handle_rx(struct uart_port *port, unsigned int misr)
@@ -460,7 +445,6 @@
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
- clk_en(port, 1);
vid = msm_hsl_port->ver_id;
misr = msm_hsl_read(port, regmap[vid][UARTDM_MISR]);
/* disable interrupt */
@@ -482,7 +466,6 @@
/* restore interrupt */
msm_hsl_write(port, msm_hsl_port->imr, regmap[vid][UARTDM_IMR]);
- clk_en(port, 0);
spin_unlock_irqrestore(&port->lock, flags);
return IRQ_HANDLED;
@@ -490,14 +473,11 @@
static unsigned int msm_hsl_tx_empty(struct uart_port *port)
{
- unsigned int vid = UART_TO_MSM(port)->ver_id;
unsigned int ret;
+ unsigned int vid = UART_TO_MSM(port)->ver_id;
- clk_en(port, 1);
ret = (msm_hsl_read(port, regmap[vid][UARTDM_SR]) &
UARTDM_SR_TXEMT_BMSK) ? TIOCSER_TEMT : 0;
- clk_en(port, 0);
-
return ret;
}
@@ -525,8 +505,6 @@
unsigned int mr;
unsigned int loop_mode;
- clk_en(port, 1);
-
mr = msm_hsl_read(port, regmap[vid][UARTDM_MR1]);
if (!(mctrl & TIOCM_RTS)) {
@@ -551,22 +529,16 @@
msm_hsl_write(port, UARTDM_CR_RX_EN_BMSK
| UARTDM_CR_TX_EN_BMSK, regmap[vid][UARTDM_CR]);
}
-
- clk_en(port, 0);
}
static void msm_hsl_break_ctl(struct uart_port *port, int break_ctl)
{
unsigned int vid = UART_TO_MSM(port)->ver_id;
- clk_en(port, 1);
-
if (break_ctl)
msm_hsl_write(port, START_BREAK, regmap[vid][UARTDM_CR]);
else
msm_hsl_write(port, STOP_BREAK, regmap[vid][UARTDM_CR]);
-
- clk_en(port, 0);
}
static void msm_hsl_set_baud_rate(struct uart_port *port, unsigned int baud)
@@ -774,14 +746,10 @@
const struct msm_serial_hslite_platform_data *pdata =
pdev->dev.platform_data;
- clk_en(port, 1);
-
msm_hsl_port->imr = 0;
/* disable interrupts */
msm_hsl_write(port, 0, regmap[msm_hsl_port->ver_id][UARTDM_IMR]);
- clk_en(port, 0);
-
free_irq(port->irq, port);
#ifndef CONFIG_PM_RUNTIME
@@ -806,7 +774,6 @@
unsigned int vid;
spin_lock_irqsave(&port->lock, flags);
- clk_en(port, 1);
/* calculate and set baud rate */
baud = uart_get_baud_rate(port, termios, old, 300, 460800);
@@ -872,7 +839,6 @@
uart_update_timeout(port, termios->c_cflag, baud);
- clk_en(port, 0);
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -971,13 +937,13 @@
}
if (msm_serial_hsl_has_gsbi(port)) {
if (msm_hsl_port->pclk)
- clk_enable(msm_hsl_port->pclk);
+ clk_prepare_enable(msm_hsl_port->pclk);
if ((ioread32(msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR) &
GSBI_PROTOCOL_I2C_UART) != GSBI_PROTOCOL_I2C_UART)
iowrite32(GSBI_PROTOCOL_I2C_UART,
msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR);
if (msm_hsl_port->pclk)
- clk_disable(msm_hsl_port->pclk);
+ clk_disable_unprepare(msm_hsl_port->pclk);
}
}
@@ -1384,10 +1350,10 @@
* condition with the earlyprintk handover mechanism.
*/
if (msm_hsl_port->pclk)
- clk_enable(msm_hsl_port->pclk);
+ clk_prepare_enable(msm_hsl_port->pclk);
ret = uart_add_one_port(&msm_hsl_uart_driver, port);
if (msm_hsl_port->pclk)
- clk_disable(msm_hsl_port->pclk);
+ clk_disable_unprepare(msm_hsl_port->pclk);
return ret;
}
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 35327cc..ff4bbad 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -858,6 +858,32 @@
*idx = (*idx + 1) & (DBG_DATA_MAX-1);
}
+
+static unsigned int ep_addr_txdbg_mask;
+module_param(ep_addr_txdbg_mask, uint, S_IRUGO | S_IWUSR);
+static unsigned int ep_addr_rxdbg_mask;
+module_param(ep_addr_rxdbg_mask, uint, S_IRUGO | S_IWUSR);
+
+static int allow_dbg_print(u8 addr)
+{
+ int dir, num;
+
+ /* allow bus wide events */
+ if (addr == 0xff)
+ return 1;
+
+ dir = addr & USB_ENDPOINT_DIR_MASK ? TX : RX;
+ num = addr & ~USB_ENDPOINT_DIR_MASK;
+ num = 1 << num;
+
+ if ((dir == TX) && (num & ep_addr_txdbg_mask))
+ return 1;
+ if ((dir == RX) && (num & ep_addr_rxdbg_mask))
+ return 1;
+
+ return 0;
+}
+
/**
* dbg_print: prints the common part of the event
* @addr: endpoint address
@@ -871,6 +897,9 @@
unsigned int stamp;
unsigned long flags;
+ if (!allow_dbg_print(addr))
+ return;
+
write_lock_irqsave(&dbg_data.lck, flags);
do_gettimeofday(&tval);
@@ -1407,7 +1436,7 @@
n = hw_ep_bit(mEp->num, mEp->dir);
pr_info("%s: prime:%08x stat:%08x ep#%d dir:%s"
- "dTD_update_fail_count: %lu"
+ "dTD_update_fail_count: %lu "
"mEp->dTD_update_fail_count: %lu\n", __func__,
hw_cread(CAP_ENDPTPRIME, ~0),
hw_cread(CAP_ENDPTSTAT, ~0),
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 30cbdd8..4e1895f 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -37,6 +37,7 @@
#include <linux/usb/msm_hsusb_hw.h>
#include <linux/regulator/consumer.h>
#include <linux/mfd/pm8xxx/pm8921-charger.h>
+#include <linux/mfd/pm8xxx/misc.h>
#include <linux/pm_qos_params.h>
#include <linux/power_supply.h>
@@ -571,6 +572,9 @@
writel_relaxed(val, USB_OTGSC);
ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_RISE);
ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_FALL);
+ } else if (pdata->otg_control == OTG_PMIC_CONTROL) {
+ /* Enable PMIC pull-up */
+ pm8xxx_usb_id_pullup(1);
}
return 0;
@@ -1307,6 +1311,8 @@
ulpi_write(otg, 0x01, 0x0C);
ulpi_write(otg, 0x10, 0x0F);
ulpi_write(otg, 0x10, 0x12);
+ /* Disable PMIC ID pull-up */
+ pm8xxx_usb_id_pullup(0);
/* Enable ACA ID detection */
ulpi_write(otg, 0x20, 0x85);
aca_id_turned_on = true;
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index b590c41..d3f8b2b 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -495,6 +495,14 @@
---help---
Support for LCDC + MIPI panel auto detect
+config FB_MSM_LVDS_MIPI_PANEL_DETECT
+ bool "LVDS + MIPI Panel Auto Detect"
+ select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
+ select FB_MSM_LVDS_CHIMEI_WXGA
+ select FB_MSM_MIPI_CHIMEI_WXGA
+ ---help---
+ Support for LVDS + MIPI panel auto detect
+
config FB_MSM_MDDI_PRISM_WVGA
bool "MDDI Prism WVGA Panel"
select FB_MSM_MDDI
diff --git a/drivers/video/msm/lvds.c b/drivers/video/msm/lvds.c
index 7ef437c..a69c64f 100644
--- a/drivers/video/msm/lvds.c
+++ b/drivers/video/msm/lvds.c
@@ -19,9 +19,10 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
-#include <mach/hardware.h>
#include <linux/io.h>
-
+#include <mach/hardware.h>
+#include <mach/msm_iomap.h>
+#include <mach/clk.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
@@ -29,10 +30,9 @@
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
-#include <mach/clk.h>
#include "msm_fb.h"
-
+#include "mdp4.h"
static int lvds_probe(struct platform_device *pdev);
static int lvds_remove(struct platform_device *pdev);
@@ -57,6 +57,126 @@
static struct lcdc_platform_data *lvds_pdata;
+static void lvds_init(struct msm_fb_data_type *mfd)
+{
+ unsigned int lvds_intf, lvds_phy_cfg0;
+
+ MDP_OUTP(MDP_BASE + 0xc2034, 0x33);
+ usleep(1000);
+
+ /* LVDS PHY PLL configuration */
+ MDP_OUTP(MDP_BASE + 0xc3000, 0x08);
+ MDP_OUTP(MDP_BASE + 0xc3004, 0x87);
+ MDP_OUTP(MDP_BASE + 0xc3008, 0x30);
+ MDP_OUTP(MDP_BASE + 0xc300c, 0x06);
+ MDP_OUTP(MDP_BASE + 0xc3014, 0x20);
+ MDP_OUTP(MDP_BASE + 0xc3018, 0x0F);
+ MDP_OUTP(MDP_BASE + 0xc301c, 0x01);
+ MDP_OUTP(MDP_BASE + 0xc3020, 0x41);
+ MDP_OUTP(MDP_BASE + 0xc3024, 0x0d);
+ MDP_OUTP(MDP_BASE + 0xc3028, 0x07);
+ MDP_OUTP(MDP_BASE + 0xc302c, 0x00);
+ MDP_OUTP(MDP_BASE + 0xc3030, 0x1c);
+ MDP_OUTP(MDP_BASE + 0xc3034, 0x01);
+ MDP_OUTP(MDP_BASE + 0xc3038, 0x00);
+ MDP_OUTP(MDP_BASE + 0xc3040, 0xC0);
+ MDP_OUTP(MDP_BASE + 0xc3044, 0x00);
+ MDP_OUTP(MDP_BASE + 0xc3048, 0x30);
+ MDP_OUTP(MDP_BASE + 0xc304c, 0x00);
+
+ MDP_OUTP(MDP_BASE + 0xc3000, 0x11);
+ MDP_OUTP(MDP_BASE + 0xc3064, 0x05);
+ MDP_OUTP(MDP_BASE + 0xc3050, 0x20);
+
+ MDP_OUTP(MDP_BASE + 0xc3000, 0x01);
+ /* Wait until LVDS PLL is locked and ready */
+ while (!readl_relaxed(MDP_BASE + 0xc3080))
+ cpu_relax();
+
+ writel_relaxed(0x00, mmss_cc_base + 0x0264);
+ writel_relaxed(0x00, mmss_cc_base + 0x0094);
+
+ writel_relaxed(0x02, mmss_cc_base + 0x00E4);
+
+ writel_relaxed((0x80 | readl_relaxed(mmss_cc_base + 0x00E4)),
+ mmss_cc_base + 0x00E4);
+ usleep(1000);
+ writel_relaxed((~0x80 & readl_relaxed(mmss_cc_base + 0x00E4)),
+ mmss_cc_base + 0x00E4);
+
+ writel_relaxed(0x05, mmss_cc_base + 0x0094);
+ writel_relaxed(0x02, mmss_cc_base + 0x0264);
+ /* Wait until LVDS pixel clock output is enabled */
+ mb();
+
+ if (mfd->panel_info.bpp == 24) {
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc2014, 0x03040508);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2018, 0x00000102);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc201c, 0x0c0d1011);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2020, 0x00090a0b);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc2024, 0x151a191a);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2028, 0x00121314);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc202c, 0x1706071b);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2030, 0x000e0f16);
+
+ if (mfd->panel_info.lvds.channel_mode ==
+ LVDS_DUAL_CHANNEL_MODE) {
+ lvds_intf = 0x0001ff80;
+ lvds_phy_cfg0 = BIT(6) | BIT(7);
+ if (mfd->panel_info.lvds.channel_swap)
+ lvds_intf |= BIT(4);
+ } else {
+ lvds_intf = 0x00010f84;
+ lvds_phy_cfg0 = BIT(6);
+ }
+ } else if (mfd->panel_info.bpp == 18) {
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc2014, 0x03040508);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2018, 0x00000102);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc201c, 0x0c0d1011);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2020, 0x00090a0b);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc2024, 0x1518191a);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2028, 0x00121314);
+
+ if (mfd->panel_info.lvds.channel_mode ==
+ LVDS_DUAL_CHANNEL_MODE) {
+ lvds_intf = 0x00017788;
+ lvds_phy_cfg0 = BIT(6) | BIT(7);
+ if (mfd->panel_info.lvds.channel_swap)
+ lvds_intf |= BIT(4);
+ } else {
+ lvds_intf = 0x0001078c;
+ lvds_phy_cfg0 = BIT(6);
+ }
+ }
+
+ /* MDP_LVDSPHY_CFG0 */
+ MDP_OUTP(MDP_BASE + 0xc3100, lvds_phy_cfg0);
+ /* MDP_LCDC_LVDS_INTF_CTL */
+ MDP_OUTP(MDP_BASE + 0xc2000, lvds_intf);
+ MDP_OUTP(MDP_BASE + 0xc3108, 0x30);
+ lvds_phy_cfg0 |= BIT(4);
+
+ /* Wait until LVDS PHY registers are configured */
+ mb();
+ usleep(1);
+ /* MDP_LVDSPHY_CFG0, enable serialization */
+ MDP_OUTP(MDP_BASE + 0xc3100, lvds_phy_cfg0);
+}
+
static int lvds_off(struct platform_device *pdev)
{
int ret = 0;
@@ -65,7 +185,8 @@
mfd = platform_get_drvdata(pdev);
ret = panel_next_off(pdev);
- clk_disable(lvds_clk);
+ if (lvds_clk)
+ clk_disable(lvds_clk);
if (lvds_pdata && lvds_pdata->lcdc_power_save)
lvds_pdata->lcdc_power_save(0);
@@ -97,22 +218,24 @@
#endif
mfd = platform_get_drvdata(pdev);
- mfd->fbi->var.pixclock = clk_round_rate(lvds_clk,
- mfd->fbi->var.pixclock);
- ret = clk_set_rate(lvds_clk, mfd->fbi->var.pixclock);
- if (ret) {
- pr_err("%s: Can't set lvds clock to rate %u\n",
- __func__, mfd->fbi->var.pixclock);
- goto out;
+ if (lvds_clk) {
+ mfd->fbi->var.pixclock = clk_round_rate(lvds_clk,
+ mfd->fbi->var.pixclock);
+ ret = clk_set_rate(lvds_clk, mfd->fbi->var.pixclock);
+ if (ret) {
+ pr_err("%s: Can't set lvds clock to rate %u\n",
+ __func__, mfd->fbi->var.pixclock);
+ goto out;
+ }
+ clk_enable(lvds_clk);
}
- clk_enable(lvds_clk);
-
if (lvds_pdata && lvds_pdata->lcdc_power_save)
lvds_pdata->lcdc_power_save(1);
if (lvds_pdata && lvds_pdata->lcdc_gpio_config)
ret = lvds_pdata->lcdc_gpio_config(1);
+ lvds_init(mfd);
ret = panel_next_on(pdev);
out:
@@ -182,8 +305,11 @@
mfd->fb_imgType = MDP_RGB_565;
fbi = mfd->fbi;
- fbi->var.pixclock = clk_round_rate(lvds_clk,
- mfd->panel_info.clk_rate);
+ if (lvds_clk) {
+ fbi->var.pixclock = clk_round_rate(lvds_clk,
+ mfd->panel_info.clk_rate);
+ }
+
fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch;
fbi->var.right_margin = mfd->panel_info.lcdc.h_front_porch;
fbi->var.upper_margin = mfd->panel_info.lcdc.v_back_porch;
@@ -224,9 +350,9 @@
static int __init lvds_driver_init(void)
{
lvds_clk = clk_get(NULL, "lvds_clk");
- if (IS_ERR(lvds_clk)) {
+ if (IS_ERR_OR_NULL(lvds_clk)) {
pr_err("Couldnt find lvds_clk\n");
- return -EINVAL;
+ lvds_clk = NULL;
}
return lvds_register_driver();
diff --git a/drivers/video/msm/lvds_chimei_wxga.c b/drivers/video/msm/lvds_chimei_wxga.c
index 2c6b6d4..9a385b9 100644
--- a/drivers/video/msm/lvds_chimei_wxga.c
+++ b/drivers/video/msm/lvds_chimei_wxga.c
@@ -11,9 +11,19 @@
*/
#include "msm_fb.h"
+#include <linux/pwm.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
-static struct msm_panel_common_pdata *cm_pdata;
+#define LVDS_CHIMEI_PWM_FREQ_HZ 300
+#define LVDS_CHIMEI_PWM_PERIOD_USEC (USEC_PER_SEC / LVDS_CHIMEI_PWM_FREQ_HZ)
+#define LVDS_CHIMEI_PWM_LEVEL 255
+#define LVDS_CHIMEI_PWM_DUTY_LEVEL \
+ (LVDS_CHIMEI_PWM_PERIOD_USEC / LVDS_CHIMEI_PWM_LEVEL)
+
+
+static struct lvds_panel_platform_data *cm_pdata;
static struct platform_device *cm_fbpdev;
+static struct pwm_device *bl_lpm;
static int lvds_chimei_panel_on(struct platform_device *pdev)
{
@@ -27,6 +37,26 @@
static void lvds_chimei_set_backlight(struct msm_fb_data_type *mfd)
{
+ int ret;
+
+ pr_debug("%s: back light level %d\n", __func__, mfd->bl_level);
+
+ if (bl_lpm) {
+ ret = pwm_config(bl_lpm, LVDS_CHIMEI_PWM_DUTY_LEVEL *
+ mfd->bl_level, LVDS_CHIMEI_PWM_PERIOD_USEC);
+ if (ret) {
+ pr_err("pwm_config on lpm failed %d\n", ret);
+ return;
+ }
+ if (mfd->bl_level) {
+ ret = pwm_enable(bl_lpm);
+ if (ret)
+ pr_err("pwm enable/disable on lpm failed"
+ "for bl %d\n", mfd->bl_level);
+ } else {
+ pwm_disable(bl_lpm);
+ }
+ }
}
static int __devinit lvds_chimei_probe(struct platform_device *pdev)
@@ -40,6 +70,17 @@
return 0;
}
+ if (cm_pdata != NULL)
+ bl_lpm = pwm_request(cm_pdata->gpio[0],
+ "backlight");
+
+ if (bl_lpm == NULL || IS_ERR(bl_lpm)) {
+ pr_err("%s pwm_request() failed\n", __func__);
+ bl_lpm = NULL;
+ }
+ pr_debug("bl_lpm = %p lpm = %d\n", bl_lpm,
+ cm_pdata->gpio[0]);
+
cm_fbpdev = msm_fb_add_device(pdev);
if (!cm_fbpdev) {
dev_err(&pdev->dev, "failed to add msm_fb device\n");
@@ -85,8 +126,8 @@
return ret;
pinfo = &lvds_chimei_panel_data.panel_info;
- pinfo->xres = 320;
- pinfo->yres = 240;
+ pinfo->xres = 1366;
+ pinfo->yres = 768;
MSM_FB_SINGLE_MODE_PANEL(pinfo);
pinfo->type = LVDS_PANEL;
pinfo->pdest = DISPLAY_1;
@@ -94,7 +135,7 @@
pinfo->bpp = 24;
pinfo->fb_num = 2;
pinfo->clk_rate = 75000000;
- pinfo->bl_max = 15;
+ pinfo->bl_max = 255;
pinfo->bl_min = 1;
/*
@@ -107,12 +148,14 @@
pinfo->lcdc.v_back_porch = 0;
pinfo->lcdc.v_front_porch = 38;
pinfo->lcdc.v_pulse_width = 20;
- pinfo->lcdc.border_clr = 0xffff00;
pinfo->lcdc.underflow_clr = 0xff;
pinfo->lcdc.hsync_skew = 0;
pinfo->lvds.channel_mode = LVDS_SINGLE_CHANNEL_MODE;
- pinfo->lcdc.xres_pad = 1046;
- pinfo->lcdc.yres_pad = 528;
+
+ /* Set border color, padding only for reducing active display region */
+ pinfo->lcdc.border_clr = 0x0;
+ pinfo->lcdc.xres_pad = 0;
+ pinfo->lcdc.yres_pad = 0;
ret = platform_device_register(&this_device);
if (ret)
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 4c443ea..43520e0 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -1221,7 +1221,7 @@
return -EINVAL;
}
if (mdp_bus_scale_handle < 1) {
- printk(KERN_ERR "%s invalid bus handle\n", __func__);
+ pr_debug("%s invalid bus handle\n", __func__);
return -EINVAL;
}
return msm_bus_scale_client_update_request(mdp_bus_scale_handle,
@@ -1318,7 +1318,7 @@
if (IS_ERR(mdp_pclk))
mdp_pclk = NULL;
- if (mdp_rev == MDP_REV_42) {
+ if (mdp_rev >= MDP_REV_42) {
mdp_lut_clk = clk_get(NULL, "lut_mdp");
if (IS_ERR(mdp_lut_clk)) {
ret = PTR_ERR(mdp_lut_clk);
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 7b2b2c2..155bc54 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -26,6 +26,7 @@
extern spinlock_t mdp_spin_lock;
extern struct mdp4_statistic mdp4_stat;
extern uint32 mdp4_extn_disp;
+extern char *mmss_cc_base; /* mutimedia sub system clock control */
#define MDP4_OVERLAYPROC0_BASE 0x10000
#define MDP4_OVERLAYPROC1_BASE 0x18000
@@ -417,6 +418,7 @@
struct mdp4_overlay_pipe *pipe);
int mdp4_overlay_dtv_unset(struct msm_fb_data_type *mfd,
struct mdp4_overlay_pipe *pipe);
+void mdp4_dma_e_done_dtv(void);
#else
static inline void mdp4_overlay_dtv_ov_done_push(struct msm_fb_data_type *mfd,
struct mdp4_overlay_pipe *pipe)
@@ -438,6 +440,10 @@
{
return 0;
}
+static inline void mdp4_dma_e_done_dtv(void)
+{
+ return;
+}
#endif
#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
@@ -691,7 +697,6 @@
struct mdp4_overlay_pipe *pipe);
void mdp4_writeback_dma_busy_wait(struct msm_fb_data_type *mfd);
void mdp4_overlay1_done_writeback(struct mdp_dma_data *dma);
-void mdp4_dma_e_done_dtv(void);
int mdp4_writeback_start(struct fb_info *info);
int mdp4_writeback_stop(struct fb_info *info);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index bf53c73..8299202 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -370,17 +370,18 @@
static uint32 mdp4_scale_phase_step(int f_num, uint32 src, uint32 dst)
{
- uint32 val;
+ uint32 val, s;
int n;
n = mdp4_leading_0(src);
if (n > f_num)
n = f_num;
- val = src << n; /* maximum to reduce lose of resolution */
- val /= dst;
+ s = src << n; /* maximum to reduce lose of resolution */
+ val = s / dst;
if (n < f_num) {
n = f_num - n;
val <<= n;
+ val |= ((s % dst) << n) / dst;
}
return val;
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 3a1a9aa..f417110 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -527,7 +527,7 @@
*/
temp_src_format = inpdw(rgb_base + 0x0050);
MDP_OUTP(rgb_base + 0x0050, temp_src_format | BIT(22));
- mdp4_mixer_stage_up(pipe);
+ mdp4_mixer_stage_up(dtv_pipe);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
#endif
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index fdb1ec5..3dece1f 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -45,73 +45,6 @@
static struct mdp4_overlay_pipe *lcdc_pipe;
static struct completion lcdc_comp;
-static void lvds_init(struct msm_fb_data_type *mfd)
-{
- unsigned int lvds_intf, lvds_phy_cfg0;
-
- if (mfd->panel_info.bpp == 24) {
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
- MDP_OUTP(MDP_BASE + 0xc2014, 0x03040508);
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
- MDP_OUTP(MDP_BASE + 0xc2018, 0x00000102);
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
- MDP_OUTP(MDP_BASE + 0xc201c, 0x0c0d1011);
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
- MDP_OUTP(MDP_BASE + 0xc2020, 0x00090a0b);
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
- MDP_OUTP(MDP_BASE + 0xc2024, 0x1518191a);
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
- MDP_OUTP(MDP_BASE + 0xc2028, 0x00121314);
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
- MDP_OUTP(MDP_BASE + 0xc202c, 0x0f16171b);
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
- MDP_OUTP(MDP_BASE + 0xc2030, 0x0006070e);
-
- if (mfd->panel_info.lvds.channel_mode ==
- LVDS_DUAL_CHANNEL_MODE) {
- lvds_intf = 0x0001ff80;
- lvds_phy_cfg0 = BIT(6) | BIT(7);
- if (mfd->panel_info.lvds.channel_swap)
- lvds_intf |= BIT(4);
- } else {
- lvds_intf = 0x00010f84;
- lvds_phy_cfg0 = BIT(6);
- }
- } else if (mfd->panel_info.bpp == 18) {
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
- MDP_OUTP(MDP_BASE + 0xc2014, 0x03040508);
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
- MDP_OUTP(MDP_BASE + 0xc2018, 0x00000102);
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
- MDP_OUTP(MDP_BASE + 0xc201c, 0x0c0d1011);
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
- MDP_OUTP(MDP_BASE + 0xc2020, 0x00090a0b);
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
- MDP_OUTP(MDP_BASE + 0xc2024, 0x1518191a);
- /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
- MDP_OUTP(MDP_BASE + 0xc2028, 0x00121314);
-
- if (mfd->panel_info.lvds.channel_mode ==
- LVDS_DUAL_CHANNEL_MODE) {
- lvds_intf = 0x00017788;
- lvds_phy_cfg0 = BIT(6) | BIT(7);
- if (mfd->panel_info.lvds.channel_swap)
- lvds_intf |= BIT(4);
- } else {
- lvds_intf = 0x0001078c;
- lvds_phy_cfg0 = BIT(6);
- }
- }
-
- /* MDP_LVDSPHY_CFG0 */
- MDP_OUTP(MDP_BASE + 0xc3100, lvds_phy_cfg0);
- /* MDP_LCDC_LVDS_INTF_CTL */
- MDP_OUTP(MDP_BASE + 0xc2000, lvds_intf);
- lvds_phy_cfg0 |= BIT(4);
- /* MDP_LVDSPHY_CFG0, enable serialization */
- MDP_OUTP(MDP_BASE + 0xc3100, lvds_phy_cfg0);
-}
-
int mdp_lcdc_on(struct platform_device *pdev)
{
int lcdc_width;
@@ -305,9 +238,6 @@
#endif
mdp_histogram_ctrl(TRUE);
- if (mfd->panel.type == LVDS_PANEL)
- lvds_init(mfd);
-
ret = panel_next_on(pdev);
if (ret == 0) {
/* enable LCDC block */
diff --git a/drivers/video/msm/mipi_NT35510.c b/drivers/video/msm/mipi_NT35510.c
index ff513d0..930b4e9 100644
--- a/drivers/video/msm/mipi_NT35510.c
+++ b/drivers/video/msm/mipi_NT35510.c
@@ -172,7 +172,7 @@
0xB6, 0x02,
};
static char cmd19[3] = {
- 0xB1, 0xEC, 0x06,
+ 0xB1, 0xEC, 0x00,
};
static char cmd20[4] = {
0xBC, 0x05, 0x05, 0x05,
@@ -206,7 +206,7 @@
static char cmd27[2] = {
0x35, 0x00,
};
-static char config_MADCTL[2] = {0x36, 0xC0};
+static char config_MADCTL[2] = {0x36, 0x00};
static struct dsi_cmd_desc nt35510_cmd_display_on_cmds[] = {
{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd0), cmd0},
{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd1), cmd1},
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index cd3f954..bf1c112 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -540,9 +540,10 @@
client_ctx->user_ion_client,
buff_ion_handle,
ionflag);
- if (!(*kernel_vaddr)) {
+ if (IS_ERR_OR_NULL((void *)*kernel_vaddr)) {
ERR("%s():ION virtual addr fail\n",
__func__);
+ *kernel_vaddr = (unsigned long)NULL;
goto ion_error;
}
if (ion_phys(client_ctx->user_ion_client,
@@ -587,7 +588,7 @@
mutex_unlock(&client_ctx->enrty_queue_lock);
return true;
ion_error:
- if (*kernel_vaddr)
+ if (*kernel_vaddr && buff_ion_handle)
ion_unmap_kernel(client_ctx->user_ion_client, buff_ion_handle);
if (!IS_ERR_OR_NULL(buff_ion_handle))
ion_free(client_ctx->user_ion_client, buff_ion_handle);
diff --git a/include/linux/leds-pm8xxx.h b/include/linux/leds-pm8xxx.h
index 3f31498..18e6398 100644
--- a/include/linux/leds-pm8xxx.h
+++ b/include/linux/leds-pm8xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -34,6 +34,8 @@
PM8XXX_ID_LED_2,
PM8XXX_ID_FLASH_LED_0,
PM8XXX_ID_FLASH_LED_1,
+ PM8XXX_ID_WLED,
+ PM8XXX_ID_MAX,
};
/**
@@ -50,6 +52,48 @@
PM8XXX_LED_MODE_DTEST4
};
+/* current boost limit */
+enum wled_current_bost_limit {
+ WLED_CURR_LIMIT_105mA,
+ WLED_CURR_LIMIT_385mA,
+ WLED_CURR_LIMIT_525mA,
+ WLED_CURR_LIMIT_805mA,
+ WLED_CURR_LIMIT_980mA,
+ WLED_CURR_LIMIT_1260mA,
+ WLED_CURR_LIMIT_1400mA,
+ WLED_CURR_LIMIT_1680mA,
+};
+
+/* over voltage protection threshold */
+enum wled_ovp_threshold {
+ WLED_OVP_35V,
+ WLED_OVP_32V,
+ WLED_OVP_29V,
+ WLED_OVP_37V,
+};
+
+/**
+ * wled_config_data - wled configuration data
+ * @num_strings - number of wled strings supported
+ * @ovp_val - over voltage protection threshold
+ * @boost_curr_lim - boot current limit
+ * @cp_select - high pole capacitance
+ * @ctrl_delay_us - delay in activation of led
+ * @dig_mod_gen_en - digital module generator
+ * @cs_out_en - current sink output enable
+ * @op_fdbck - selection of output as feedback for the boost
+ */
+struct wled_config_data {
+ u8 num_strings;
+ u8 ovp_val;
+ u8 boost_curr_lim;
+ u8 cp_select;
+ u8 ctrl_delay_us;
+ bool dig_mod_gen_en;
+ bool cs_out_en;
+ bool op_fdbck;
+};
+
/**
* pm8xxx_led_config - led configuration parameters
* @id - LED id
@@ -57,6 +101,7 @@
* @max_current - maximum current that LED can sustain
* @pwm_channel - PWM channel ID the LED is driven to
* @pwm_period_us - PWM period value in micro seconds
+ * @default_state - default state of the led
* @pwm_duty_cycles - PWM duty cycle information
*/
struct pm8xxx_led_config {
@@ -65,7 +110,9 @@
u16 max_current;
int pwm_channel;
u32 pwm_period_us;
+ bool default_state;
struct pm8xxx_pwm_duty_cycles *pwm_duty_cycles;
+ struct wled_config_data *wled_cfg;
};
/**
diff --git a/include/linux/mfd/wcd9310/wcd9310-slimslave.h b/include/linux/mfd/wcd9310/wcd9310-slimslave.h
new file mode 100644
index 0000000..0bbf96f
--- /dev/null
+++ b/include/linux/mfd/wcd9310/wcd9310-slimslave.h
@@ -0,0 +1,102 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __WCD9310_SLIMSLAVE_H_
+#define __WCD9310_SLIMSLAVE_H_
+
+#include <linux/slimbus/slimbus.h>
+#include <linux/mfd/wcd9310/core.h>
+
+/* Local to the core only */
+#define SLIM_MAX_RX_PORTS 7
+#define SLIM_MAX_TX_PORTS 10
+
+/* Channel numbers to be used for each port */
+enum {
+ SLIM_TX_1 = 128,
+ SLIM_TX_2 = 129,
+ SLIM_TX_3 = 130,
+ SLIM_TX_4 = 131,
+ SLIM_TX_5 = 132,
+ SLIM_TX_6 = 133,
+ SLIM_TX_7 = 134,
+ SLIM_TX_8 = 135,
+ SLIM_TX_9 = 136,
+ SLIM_TX_10 = 137,
+ SLIM_RX_1 = 138,
+ SLIM_RX_2 = 139,
+ SLIM_RX_3 = 140,
+ SLIM_RX_4 = 141,
+ SLIM_RX_5 = 142,
+ SLIM_RX_6 = 143,
+ SLIM_RX_7 = 144,
+ SLIM_MAX = 145
+};
+
+/*
+ * client is expected to give port ids in the range of 1-10 for Tx ports and
+ * 1-7 for Rx ports, we need to add offset for getting the absolute slave
+ * port id before configuring the HW
+ */
+#define SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS 10
+#define SB_PGD_OFFSET_OF_TX_SLAVE_DEV_PORTS -1
+#define SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS 7
+#define SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS 9
+
+/* below details are taken from SLIMBUS slave SWI */
+#define SB_PGD_PORT_BASE 0x000
+
+#define SB_PGD_PORT_CFG_BYTE_ADDR(port_num) \
+ (SB_PGD_PORT_BASE + 0x040 + 1*port_num)
+
+#define SB_PGD_TX_PORT_MULTI_CHANNEL_0(port_num) \
+ (SB_PGD_PORT_BASE + 0x100 + 4*port_num)
+#define SB_PGD_TX_PORT_MULTI_CHANNEL_0_START_PORT_ID 0
+#define SB_PGD_TX_PORT_MULTI_CHANNEL_0_END_PORT_ID 7
+
+#define SB_PGD_TX_PORT_MULTI_CHANNEL_1(port_num) \
+ (SB_PGD_PORT_BASE + 0x101 + 4*port_num)
+#define SB_PGD_TX_PORT_MULTI_CHANNEL_1_START_PORT_ID 8
+#define SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID 9
+
+#define SB_PGD_RX_PORT_MULTI_CHANNEL_0(port_num) \
+ (SB_PGD_PORT_BASE + 0x180 + 4*port_num)
+#define SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID 10
+#define SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID 16
+
+/* slave port water mark level
+ * (0: 6bytes, 1: 9bytes, 2: 12 bytes, 3: 15 bytes)
+ */
+#define SLAVE_PORT_WATER_MARK_VALUE 2
+#define SLAVE_PORT_WATER_MARK_SHIFT 1
+#define SLAVE_PORT_ENABLE 1
+#define SLAVE_PORT_DISABLE 0
+
+#define BASE_CH_NUM 128
+
+
+int tabla_init_slimslave(struct tabla *tabla, u8 tabla_pgd_la);
+
+int tabla_deinit_slimslave(struct tabla *tabla);
+
+int tabla_cfg_slim_sch_rx(struct tabla *tabla, unsigned int *ch_num,
+ unsigned int tot_ch, unsigned int rate);
+int tabla_cfg_slim_sch_tx(struct tabla *tabla, unsigned int *ch_num,
+ unsigned int tot_ch, unsigned int rate);
+int tabla_close_slim_sch_rx(struct tabla *tabla, unsigned int *ch_num,
+ unsigned int tot_ch);
+int tabla_close_slim_sch_tx(struct tabla *tabla, unsigned int *ch_num,
+ unsigned int tot_ch);
+int tabla_get_channel(struct tabla *tabla,
+ unsigned int *rx_ch,
+ unsigned int *tx_ch);
+#endif /* __WCD9310_SLIMSLAVE_H_ */
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 9eb6dda..37b9d35 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -148,6 +148,7 @@
unsigned int idle_timeout;
unsigned int nap_allowed;
unsigned int clk_map;
+ unsigned int idle_needed;
struct msm_bus_scale_pdata *bus_scale_table;
const char *iommu_user_ctx_name;
const char *iommu_priv_ctx_name;
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 87fbbd2..1a6f68f 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -693,6 +693,9 @@
#define MSM_V4L2_CAM_OP_ZSL (MSM_V4L2_CAM_OP_DEFAULT+4)
/* camera operation mode for raw snapshot - one frame output queue */
#define MSM_V4L2_CAM_OP_RAW (MSM_V4L2_CAM_OP_DEFAULT+5)
+/* camera operation mode for jpeg snapshot - one frame output queue */
+#define MSM_V4L2_CAM_OP_JPEG_CAPTURE (MSM_V4L2_CAM_OP_DEFAULT+6)
+
#define MSM_V4L2_VID_CAP_TYPE 0
#define MSM_V4L2_STREAM_ON 1
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 5dd1445..07784e2 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -241,6 +241,9 @@
#define VPE_SCALER_CONFIG_LEN 260
#define VPE_DIS_OFFSET_CFG_LEN 12
+#define IMEM_Y_OFFSET 0x2E000000
+#define IMEM_CBCR_OFFSET 0x2E00FA00
+
struct msm_vpe_op_mode_cfg {
uint8_t op_mode_cfg[VPE_OPERATION_MODE_CFG_LEN];
};
@@ -311,6 +314,8 @@
#define VFE_OUTPUTS_PREVIEW BIT(6)
#define VFE_OUTPUTS_VIDEO BIT(7)
#define VFE_OUTPUTS_RAW BIT(8)
+#define VFE_OUTPUTS_JPEG_AND_THUMB BIT(9)
+#define VFE_OUTPUTS_THUMB_AND_JPEG BIT(10)
#endif /*__MSM_ISP_H__*/
diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h
index 87bafed..097ba39 100644
--- a/include/sound/apr_audio.h
+++ b/include/sound/apr_audio.h
@@ -272,6 +272,16 @@
u16 reserved;
} __packed;
+struct afe_port_slimbus_sch_cfg {
+ u16 slimbus_dev_id; /* SLIMBUS Device id.*/
+ u16 bit_width; /** bit width of the samples, 16, 24.*/
+ u16 data_format; /** data format.*/
+ u16 num_channels; /** Number of channels.*/
+ u16 reserved;
+ /** Slave channel mapping for respective channels.*/
+ u8 slave_ch_mapping[8];
+} __packed;
+
struct afe_port_rtproxy_cfg {
u16 bitwidth; /* 16,24,32 */
u16 interleaved; /* interleaved = 1 */
@@ -284,16 +294,18 @@
int num_ch; /* 1 to 8 */
} __packed;
-#define AFE_PORT_AUDIO_IF_CONFIG 0x000100d3
+#define AFE_PORT_AUDIO_IF_CONFIG 0x000100d3
+#define AFE_PORT_AUDIO_SLIM_SCH_CONFIG 0x000100e4
#define AFE_PORT_MULTI_CHAN_HDMI_AUDIO_IF_CONFIG 0x000100D9
union afe_port_config {
- struct afe_port_pcm_cfg pcm;
- struct afe_port_mi2s_cfg mi2s;
- struct afe_port_hdmi_cfg hdmi;
- struct afe_port_hdmi_multi_ch_cfg hdmi_multi_ch;
- struct afe_port_slimbus_cfg slimbus;
- struct afe_port_rtproxy_cfg rtproxy;
+ struct afe_port_pcm_cfg pcm;
+ struct afe_port_mi2s_cfg mi2s;
+ struct afe_port_hdmi_cfg hdmi;
+ struct afe_port_hdmi_multi_ch_cfg hdmi_multi_ch;
+ struct afe_port_slimbus_cfg slimbus;
+ struct afe_port_slimbus_sch_cfg slim_sch;
+ struct afe_port_rtproxy_cfg rtproxy;
} __attribute__((packed));
struct afe_audioif_config_command {
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index bda171e..f1ce01f 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -2,6 +2,7 @@
* linux/sound/soc-dai.h -- ALSA SoC Layer
*
* Copyright: 2005-2008 Wolfson Microelectronics. PLC.
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -121,6 +122,10 @@
unsigned int tx_num, unsigned int *tx_slot,
unsigned int rx_num, unsigned int *rx_slot);
+int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
+ unsigned int *tx_num, unsigned int *tx_slot,
+ unsigned int *rx_num, unsigned int *rx_slot);
+
int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
/* Digital Audio Interface mute */
@@ -150,6 +155,9 @@
unsigned int rx_num, unsigned int *rx_slot);
int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
+ int (*get_channel_map)(struct snd_soc_dai *dai,
+ unsigned int *tx_num, unsigned int *tx_slot,
+ unsigned int *rx_num, unsigned int *rx_slot);
/*
* DAI digital mute - optional.
* Called by soc-core to minimise any pops.
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 94cacde..468f86c 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -611,8 +611,16 @@
case L2CAP_MODE_BASIC:
l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
break;
- case L2CAP_MODE_ERTM:
case L2CAP_MODE_STREAMING:
+ if (!disable_ertm) {
+ /* No fallback to ERTM or Basic mode */
+ l2cap_pi(sk)->conf_state |=
+ L2CAP_CONF_STATE2_DEVICE;
+ break;
+ }
+ err = -EINVAL;
+ break;
+ case L2CAP_MODE_ERTM:
if (!disable_ertm)
break;
/* fall through */
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 7c2073d..ac7f050 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -36,8 +36,6 @@
#define NUM_DECIMATORS 10
#define NUM_INTERPOLATORS 7
#define BITS_PER_REG 8
-#define TABLA_RX_DAI_ID 1
-#define TABLA_TX_DAI_ID 2
#define TABLA_CFILT_FAST_MODE 0x00
#define TABLA_CFILT_SLOW_MODE 0x40
#define MBHC_FW_READ_ATTEMPTS 15
@@ -49,6 +47,17 @@
#define TABLA_OCP_ATTEMPT 1
+#define AIF1_PB 1
+#define AIF1_CAP 2
+#define NUM_CODEC_DAIS 2
+
+struct tabla_codec_dai_data {
+ u32 rate;
+ u32 *ch_num;
+ u32 ch_act;
+ u32 ch_tot;
+};
+
#define TABLA_MCLK_RATE_12288KHZ 12288000
#define TABLA_MCLK_RATE_9600KHZ 9600000
@@ -58,6 +67,7 @@
static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
+static struct snd_soc_dai_driver tabla_dai[];
enum tabla_bandgap_type {
TABLA_BANDGAP_OFF = 0,
@@ -194,6 +204,9 @@
/* Work to perform MBHC Firmware Read */
struct delayed_work mbhc_firmware_dwork;
const struct firmware *mbhc_fw;
+
+ /* num of slim ports required */
+ struct tabla_codec_dai_data dai[NUM_CODEC_DAIS];
};
#ifdef CONFIG_DEBUG_FS
@@ -340,9 +353,9 @@
int coeff_idx)
{
/* Address does not automatically update if reading */
- snd_soc_update_bits(codec,
+ snd_soc_write(codec,
(TABLA_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
- 0x1F, band_idx * BAND_MAX + coeff_idx);
+ (band_idx * BAND_MAX + coeff_idx) & 0x1F);
/* Mask bits top 2 bits since they are reserved */
return ((snd_soc_read(codec,
@@ -401,27 +414,27 @@
{
/* Mask top 3 bits, 6-8 are reserved */
/* Update address manually each time */
- snd_soc_update_bits(codec,
+ snd_soc_write(codec,
(TABLA_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
- 0x1F, band_idx * BAND_MAX + coeff_idx);
+ (band_idx * BAND_MAX + coeff_idx) & 0x1F);
/* Mask top 2 bits, 7-8 are reserved */
- snd_soc_update_bits(codec,
+ snd_soc_write(codec,
(TABLA_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
- 0x3F, (value >> 24) & 0x3F);
+ (value >> 24) & 0x3F);
/* Isolate 8bits at a time */
- snd_soc_update_bits(codec,
+ snd_soc_write(codec,
(TABLA_A_CDC_IIR1_COEF_B3_CTL + 16 * iir_idx),
- 0xFF, (value >> 16) & 0xFF);
+ (value >> 16) & 0xFF);
- snd_soc_update_bits(codec,
+ snd_soc_write(codec,
(TABLA_A_CDC_IIR1_COEF_B4_CTL + 16 * iir_idx),
- 0xFF, (value >> 8) & 0xFF);
+ (value >> 8) & 0xFF);
- snd_soc_update_bits(codec,
+ snd_soc_write(codec,
(TABLA_A_CDC_IIR1_COEF_B5_CTL + 16 * iir_idx),
- 0xFF, value & 0xFF);
+ value & 0xFF);
}
static int tabla_put_iir_band_audio_mixer(
@@ -1907,306 +1920,6 @@
return 0;
}
-static const struct snd_soc_dapm_widget tabla_dapm_widgets[] = {
- /*RX stuff */
- SND_SOC_DAPM_OUTPUT("EAR"),
-
- SND_SOC_DAPM_PGA("EAR PA", TABLA_A_RX_EAR_EN, 4, 0, NULL, 0),
-
- SND_SOC_DAPM_MIXER("DAC1", TABLA_A_RX_EAR_EN, 6, 0, dac1_switch,
- ARRAY_SIZE(dac1_switch)),
-
- SND_SOC_DAPM_AIF_IN("SLIM RX1", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_IN("SLIM RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_IN("SLIM RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_IN("SLIM RX4", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
-
- /* Headphone */
- SND_SOC_DAPM_OUTPUT("HEADPHONE"),
- SND_SOC_DAPM_PGA_E("HPHL", TABLA_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
- tabla_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MIXER("HPHL DAC", TABLA_A_RX_HPH_L_DAC_CTL, 7, 0,
- hphl_switch, ARRAY_SIZE(hphl_switch)),
-
- SND_SOC_DAPM_PGA_E("HPHR", TABLA_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
- tabla_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, TABLA_A_RX_HPH_R_DAC_CTL, 7, 0,
- tabla_hphr_dac_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
- /* Speaker */
- SND_SOC_DAPM_OUTPUT("LINEOUT1"),
- SND_SOC_DAPM_OUTPUT("LINEOUT2"),
- SND_SOC_DAPM_OUTPUT("LINEOUT3"),
- SND_SOC_DAPM_OUTPUT("LINEOUT4"),
- SND_SOC_DAPM_OUTPUT("LINEOUT5"),
-
- SND_SOC_DAPM_PGA_E("LINEOUT1 PA", TABLA_A_RX_LINE_CNP_EN, 0, 0, NULL,
- 0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_PGA_E("LINEOUT2 PA", TABLA_A_RX_LINE_CNP_EN, 1, 0, NULL,
- 0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_PGA_E("LINEOUT3 PA", TABLA_A_RX_LINE_CNP_EN, 2, 0, NULL,
- 0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_PGA_E("LINEOUT4 PA", TABLA_A_RX_LINE_CNP_EN, 3, 0, NULL,
- 0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_PGA_E("LINEOUT5 PA", TABLA_A_RX_LINE_CNP_EN, 4, 0, NULL, 0,
- tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TABLA_A_RX_LINE_1_DAC_CTL, 7, 0
- , tabla_lineout_dac_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_DAC_E("LINEOUT2 DAC", NULL, TABLA_A_RX_LINE_2_DAC_CTL, 7, 0
- , tabla_lineout_dac_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_DAC_E("LINEOUT3 DAC", NULL, TABLA_A_RX_LINE_3_DAC_CTL, 7, 0
- , tabla_lineout_dac_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SWITCH("LINEOUT3 DAC GROUND", SND_SOC_NOPM, 0, 0,
- &lineout3_ground_switch),
- SND_SOC_DAPM_DAC_E("LINEOUT4 DAC", NULL, TABLA_A_RX_LINE_4_DAC_CTL, 7, 0
- , tabla_lineout_dac_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SWITCH("LINEOUT4 DAC GROUND", SND_SOC_NOPM, 0, 0,
- &lineout4_ground_switch),
- SND_SOC_DAPM_DAC_E("LINEOUT5 DAC", NULL, TABLA_A_RX_LINE_5_DAC_CTL, 7, 0
- , tabla_lineout_dac_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_MIXER_E("RX1 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
- 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
- SND_SOC_DAPM_MIXER_E("RX2 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
- 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
- SND_SOC_DAPM_MIXER_E("RX3 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
- 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
- SND_SOC_DAPM_MIXER_E("RX4 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 3, 0, NULL,
- 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
- SND_SOC_DAPM_MIXER_E("RX5 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 4, 0, NULL,
- 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
- SND_SOC_DAPM_MIXER_E("RX6 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 5, 0, NULL,
- 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
- SND_SOC_DAPM_MIXER_E("RX7 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 6, 0, NULL,
- 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
-
-
- SND_SOC_DAPM_MUX_E("RX4 DSM MUX", TABLA_A_CDC_CLK_RX_B1_CTL, 3, 0,
- &rx4_dsm_mux, tabla_codec_reset_interpolator,
- SND_SOC_DAPM_PRE_PMU),
-
- SND_SOC_DAPM_MUX_E("RX6 DSM MUX", TABLA_A_CDC_CLK_RX_B1_CTL, 5, 0,
- &rx6_dsm_mux, tabla_codec_reset_interpolator,
- SND_SOC_DAPM_PRE_PMU),
-
- SND_SOC_DAPM_MIXER("RX1 CHAIN", TABLA_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("RX2 CHAIN", TABLA_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
-
- SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
- &rx_mix1_inp1_mux),
- SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
- &rx_mix1_inp2_mux),
- SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
- &rx2_mix1_inp1_mux),
- SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
- &rx2_mix1_inp2_mux),
- SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
- &rx3_mix1_inp1_mux),
- SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
- &rx3_mix1_inp2_mux),
- SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
- &rx4_mix1_inp1_mux),
- SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0,
- &rx4_mix1_inp2_mux),
- SND_SOC_DAPM_MUX("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0,
- &rx5_mix1_inp1_mux),
- SND_SOC_DAPM_MUX("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0,
- &rx5_mix1_inp2_mux),
- SND_SOC_DAPM_MUX("RX6 MIX1 INP1", SND_SOC_NOPM, 0, 0,
- &rx6_mix1_inp1_mux),
- SND_SOC_DAPM_MUX("RX6 MIX1 INP2", SND_SOC_NOPM, 0, 0,
- &rx6_mix1_inp2_mux),
- SND_SOC_DAPM_MUX("RX7 MIX1 INP1", SND_SOC_NOPM, 0, 0,
- &rx7_mix1_inp1_mux),
- SND_SOC_DAPM_MUX("RX7 MIX1 INP2", SND_SOC_NOPM, 0, 0,
- &rx7_mix1_inp2_mux),
-
- SND_SOC_DAPM_SUPPLY("CP", TABLA_A_CP_EN, 0, 0,
- tabla_codec_enable_charge_pump, SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD),
-
- SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
- tabla_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-
- /* TX */
-
- SND_SOC_DAPM_SUPPLY("CDC_CONN", TABLA_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
- 0),
-
- SND_SOC_DAPM_SUPPLY("LDO_H", TABLA_A_LDO_H_MODE_1, 7, 0,
- tabla_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
-
- SND_SOC_DAPM_INPUT("AMIC1"),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TABLA_A_MICB_1_CTL, 7, 0,
- tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", TABLA_A_MICB_1_CTL, 7, 0,
- tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", TABLA_A_MICB_1_CTL, 7, 0,
- tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_ADC_E("ADC1", NULL, TABLA_A_TX_1_2_EN, 7, 0,
- tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_INPUT("AMIC3"),
- SND_SOC_DAPM_ADC_E("ADC3", NULL, TABLA_A_TX_3_4_EN, 7, 0,
- tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_INPUT("AMIC4"),
- SND_SOC_DAPM_ADC_E("ADC4", NULL, TABLA_A_TX_3_4_EN, 3, 0,
- tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_INPUT("AMIC5"),
- SND_SOC_DAPM_ADC_E("ADC5", NULL, TABLA_A_TX_5_6_EN, 7, 0,
- tabla_codec_enable_adc, SND_SOC_DAPM_POST_PMU),
-
- SND_SOC_DAPM_INPUT("AMIC6"),
- SND_SOC_DAPM_ADC_E("ADC6", NULL, TABLA_A_TX_5_6_EN, 3, 0,
- tabla_codec_enable_adc, SND_SOC_DAPM_POST_PMU),
-
- SND_SOC_DAPM_MUX_E("DEC1 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
- &dec1_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
- SND_SOC_DAPM_MUX_E("DEC2 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
- &dec2_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
- SND_SOC_DAPM_MUX_E("DEC3 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 2, 0,
- &dec3_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
- SND_SOC_DAPM_MUX_E("DEC4 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 3, 0,
- &dec4_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
- SND_SOC_DAPM_MUX_E("DEC5 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 4, 0,
- &dec5_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
- SND_SOC_DAPM_MUX_E("DEC6 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 5, 0,
- &dec6_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
- SND_SOC_DAPM_MUX_E("DEC7 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 6, 0,
- &dec7_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
- SND_SOC_DAPM_MUX_E("DEC8 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 7, 0,
- &dec8_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
- SND_SOC_DAPM_MUX_E("DEC9 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0, 0,
- &dec9_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
- SND_SOC_DAPM_MUX_E("DEC10 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B2_CTL, 1, 0,
- &dec10_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
- SND_SOC_DAPM_MUX("ANC1 MUX", SND_SOC_NOPM, 0, 0, &anc1_mux),
- SND_SOC_DAPM_MUX("ANC2 MUX", SND_SOC_NOPM, 0, 0, &anc2_mux),
-
- SND_SOC_DAPM_MIXER_E("ANC", SND_SOC_NOPM, 0, 0, NULL, 0,
- tabla_codec_enable_anc, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
-
- SND_SOC_DAPM_INPUT("AMIC2"),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", TABLA_A_MICB_2_CTL, 7, 0,
- tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", TABLA_A_MICB_2_CTL, 7, 0,
- tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", TABLA_A_MICB_2_CTL, 7, 0,
- tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", TABLA_A_MICB_2_CTL, 7, 0,
- tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", TABLA_A_MICB_3_CTL, 7, 0,
- tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", TABLA_A_MICB_3_CTL, 7, 0,
- tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", TABLA_A_MICB_3_CTL, 7, 0,
- tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_ADC_E("ADC2", NULL, TABLA_A_TX_1_2_EN, 3, 0,
- tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, 0, 0, &sb_tx1_mux),
- SND_SOC_DAPM_AIF_OUT("SLIM TX1", "AIF1 Capture", NULL, SND_SOC_NOPM,
- 0, 0),
-
- SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, 0, 0, &sb_tx5_mux),
- SND_SOC_DAPM_AIF_OUT("SLIM TX5", "AIF1 Capture", NULL, SND_SOC_NOPM,
- 4, 0),
-
- SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, 0, 0, &sb_tx6_mux),
- SND_SOC_DAPM_AIF_OUT("SLIM TX6", "AIF1 Capture", NULL, SND_SOC_NOPM,
- 5, 0),
-
- SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, 0, 0, &sb_tx7_mux),
- SND_SOC_DAPM_AIF_OUT("SLIM TX7", "AIF1 Capture", NULL, SND_SOC_NOPM,
- 0, 0),
-
- SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, 0, 0, &sb_tx8_mux),
- SND_SOC_DAPM_AIF_OUT("SLIM TX8", "AIF1 Capture", NULL, SND_SOC_NOPM,
- 0, 0),
-
- SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, 0, 0, &sb_tx9_mux),
- SND_SOC_DAPM_AIF_OUT("SLIM TX9", "AIF1 Capture", NULL, SND_SOC_NOPM,
- 0, 0),
-
- SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, 0, 0, &sb_tx10_mux),
- SND_SOC_DAPM_AIF_OUT("SLIM TX10", "AIF1 Capture", NULL, SND_SOC_NOPM,
- 0, 0),
-
- /* Digital Mic Inputs */
- SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
- tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
- tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
- tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
- tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
- tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 0,
- tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMD),
-
- /* Sidetone */
- SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
- SND_SOC_DAPM_PGA("IIR1", TABLA_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
-};
-
static const struct snd_soc_dapm_widget tabla_1_x_dapm_widgets[] = {
SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", TABLA_1_A_MICB_4_CTL, 7,
0, tabla_codec_enable_micbias,
@@ -2675,7 +2388,6 @@
{
struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
- pr_debug("%s: enable = %d\n", __func__, enable);
if (enable) {
snd_soc_update_bits(codec, TABLA_A_CONFIG_MODE_FREQ, 0x10, 0);
snd_soc_write(codec, TABLA_A_BIAS_CONFIG_MODE_BG_CTL, 0x17);
@@ -2880,11 +2592,11 @@
case SND_SOC_DAIFMT_CBS_CFS:
/* CPU is master */
if (tabla->intf_type == TABLA_INTERFACE_TYPE_I2C) {
- if (dai->id == TABLA_TX_DAI_ID)
+ if (dai->id == AIF1_CAP)
snd_soc_update_bits(dai->codec,
TABLA_A_CDC_CLK_TX_I2S_CTL,
TABLA_I2S_MASTER_MODE_MASK, 0);
- else if (dai->id == TABLA_RX_DAI_ID)
+ else if (dai->id == AIF1_PB)
snd_soc_update_bits(dai->codec,
TABLA_A_CDC_CLK_RX_I2S_CTL,
TABLA_I2S_MASTER_MODE_MASK, 0);
@@ -2894,10 +2606,10 @@
/* CPU is slave */
if (tabla->intf_type == TABLA_INTERFACE_TYPE_I2C) {
val = TABLA_I2S_MASTER_MODE_MASK;
- if (dai->id == TABLA_TX_DAI_ID)
+ if (dai->id == AIF1_CAP)
snd_soc_update_bits(dai->codec,
TABLA_A_CDC_CLK_TX_I2S_CTL, val, val);
- else if (dai->id == TABLA_RX_DAI_ID)
+ else if (dai->id == AIF1_PB)
snd_soc_update_bits(dai->codec,
TABLA_A_CDC_CLK_RX_I2S_CTL, val, val);
}
@@ -2908,6 +2620,71 @@
return 0;
}
+static int tabla_set_channel_map(struct snd_soc_dai *dai,
+ unsigned int tx_num, unsigned int *tx_slot,
+ unsigned int rx_num, unsigned int *rx_slot)
+
+{
+ struct tabla_priv *tabla = snd_soc_codec_get_drvdata(dai->codec);
+ u32 i = 0;
+ if (!tx_slot && !rx_slot) {
+ pr_err("%s: Invalid\n", __func__);
+ return -EINVAL;
+ }
+ pr_debug("%s: DAI-ID %x %d %d\n", __func__, dai->id, tx_num, rx_num);
+
+ if (dai->id == AIF1_PB) {
+ for (i = 0; i < rx_num; i++) {
+ tabla->dai[dai->id - 1].ch_num[i] = rx_slot[i];
+ tabla->dai[dai->id - 1].ch_act = 0;
+ tabla->dai[dai->id - 1].ch_tot = rx_num;
+ }
+ } else if (dai->id == AIF1_CAP) {
+ for (i = 0; i < tx_num; i++) {
+ tabla->dai[dai->id - 1].ch_num[i] = tx_slot[i];
+ tabla->dai[dai->id - 1].ch_act = 0;
+ tabla->dai[dai->id - 1].ch_tot = tx_num;
+ }
+ }
+ return 0;
+}
+
+static int tabla_get_channel_map(struct snd_soc_dai *dai,
+ unsigned int *tx_num, unsigned int *tx_slot,
+ unsigned int *rx_num, unsigned int *rx_slot)
+
+{
+ struct tabla *tabla = dev_get_drvdata(dai->codec->control_data);
+
+ u32 cnt = 0;
+ u32 tx_ch[SLIM_MAX_TX_PORTS];
+ u32 rx_ch[SLIM_MAX_RX_PORTS];
+
+ if (!rx_slot && !tx_slot) {
+ pr_err("%s: Invalid\n", __func__);
+ return -EINVAL;
+ }
+ pr_debug("%s: DAI-ID %x\n", __func__, dai->id);
+ /* for virtual port, codec driver needs to do
+ * housekeeping, for now should be ok
+ */
+ tabla_get_channel(tabla, rx_ch, tx_ch);
+ if (dai->id == AIF1_PB) {
+ *rx_num = tabla_dai[dai->id - 1].playback.channels_max;
+ while (cnt < *rx_num) {
+ rx_slot[cnt] = rx_ch[cnt];
+ cnt++;
+ }
+ } else if (dai->id == AIF1_CAP) {
+ *tx_num = tabla_dai[dai->id - 1].capture.channels_max;
+ while (cnt < *tx_num) {
+ tx_slot[cnt] = tx_ch[6 + cnt];
+ cnt++;
+ }
+ }
+ return 0;
+}
+
static int tabla_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -2918,7 +2695,8 @@
u16 tx_fs_reg, rx_fs_reg;
u8 tx_fs_rate, rx_fs_rate, rx_state, tx_state;
- pr_debug("%s: DAI-ID %x\n", __func__, dai->id);
+ pr_debug("%s: DAI-ID %x rate %d\n", __func__, dai->id,
+ params_rate(params));
switch (params_rate(params)) {
case 8000:
@@ -2948,7 +2726,7 @@
* If current dai is a tx dai, set sample rate to
* all the txfe paths that are currently not active
*/
- if (dai->id == TABLA_TX_DAI_ID) {
+ if (dai->id == AIF1_CAP) {
tx_state = snd_soc_read(codec,
TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL);
@@ -2987,9 +2765,10 @@
}
snd_soc_update_bits(codec, TABLA_A_CDC_CLK_TX_I2S_CTL,
0x03, tx_fs_rate);
+ } else {
+ tabla->dai[dai->id - 1].rate = params_rate(params);
}
}
-
/**
* TODO: Need to handle case where same RX chain takes 2 or more inputs
* with varying sample rates
@@ -2999,7 +2778,7 @@
* If current dai is a rx dai, set sample rate to
* all the rx paths that are currently not active
*/
- if (dai->id == TABLA_RX_DAI_ID) {
+ if (dai->id == AIF1_PB) {
rx_state = snd_soc_read(codec,
TABLA_A_CDC_CLK_RX_B1_CTL);
@@ -3032,6 +2811,8 @@
}
snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_I2S_CTL,
0x03, (rx_fs_rate >> 0x05));
+ } else {
+ tabla->dai[dai->id - 1].rate = params_rate(params);
}
}
@@ -3044,12 +2825,14 @@
.hw_params = tabla_hw_params,
.set_sysclk = tabla_set_dai_sysclk,
.set_fmt = tabla_set_dai_fmt,
+ .set_channel_map = tabla_set_channel_map,
+ .get_channel_map = tabla_get_channel_map,
};
static struct snd_soc_dai_driver tabla_dai[] = {
{
.name = "tabla_rx1",
- .id = 1,
+ .id = AIF1_PB,
.playback = {
.stream_name = "AIF1 Playback",
.rates = WCD9310_RATES,
@@ -3057,13 +2840,13 @@
.rate_max = 48000,
.rate_min = 8000,
.channels_min = 1,
- .channels_max = 4,
+ .channels_max = 2,
},
.ops = &tabla_dai_ops,
},
{
.name = "tabla_tx1",
- .id = 2,
+ .id = AIF1_CAP,
.capture = {
.stream_name = "AIF1 Capture",
.rates = WCD9310_RATES,
@@ -3071,7 +2854,7 @@
.rate_max = 48000,
.rate_min = 8000,
.channels_min = 1,
- .channels_max = 2,
+ .channels_max = 4,
},
.ops = &tabla_dai_ops,
},
@@ -3107,6 +2890,426 @@
.ops = &tabla_dai_ops,
},
};
+
+static int tabla_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct tabla *tabla;
+ struct snd_soc_codec *codec = w->codec;
+ struct tabla_priv *tabla_p = snd_soc_codec_get_drvdata(codec);
+ u32 j = 0;
+ u32 ret = 0;
+ codec->control_data = dev_get_drvdata(codec->dev->parent);
+ tabla = codec->control_data;
+ /* Execute the callback only if interface type is slimbus */
+ if (tabla_p->intf_type != TABLA_INTERFACE_TYPE_SLIMBUS)
+ return 0;
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
+ if (tabla_dai[j].id == AIF1_CAP)
+ continue;
+ if (!strncmp(w->sname,
+ tabla_dai[j].playback.stream_name, 13)) {
+ ++tabla_p->dai[j].ch_act;
+ break;
+ }
+ }
+ if (tabla_p->dai[j].ch_act == tabla_p->dai[j].ch_tot)
+ ret = tabla_cfg_slim_sch_rx(tabla,
+ tabla_p->dai[j].ch_num,
+ tabla_p->dai[j].ch_tot,
+ tabla_p->dai[j].rate);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
+ if (tabla_dai[j].id == AIF1_CAP)
+ continue;
+ if (!strncmp(w->sname,
+ tabla_dai[j].playback.stream_name, 13)) {
+ --tabla_p->dai[j].ch_act;
+ break;
+ }
+ }
+ if (!tabla_p->dai[j].ch_act) {
+ ret = tabla_close_slim_sch_rx(tabla,
+ tabla_p->dai[j].ch_num,
+ tabla_p->dai[j].ch_tot);
+ tabla_p->dai[j].rate = 0;
+ memset(tabla_p->dai[j].ch_num, 0, (sizeof(u32)*
+ tabla_p->dai[j].ch_tot));
+ tabla_p->dai[j].ch_tot = 0;
+ }
+ }
+ return ret;
+}
+
+static int tabla_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct tabla *tabla;
+ struct snd_soc_codec *codec = w->codec;
+ struct tabla_priv *tabla_p = snd_soc_codec_get_drvdata(codec);
+ /* index to the DAI ID, for now hardcoding */
+ u32 j = 0;
+ u32 ret = 0;
+
+ codec->control_data = dev_get_drvdata(codec->dev->parent);
+ tabla = codec->control_data;
+
+ /* Execute the callback only if interface type is slimbus */
+ if (tabla_p->intf_type != TABLA_INTERFACE_TYPE_SLIMBUS)
+ return 0;
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
+ if (tabla_dai[j].id == AIF1_PB)
+ continue;
+ if (!strncmp(w->sname,
+ tabla_dai[j].capture.stream_name, 13)) {
+ ++tabla_p->dai[j].ch_act;
+ break;
+ }
+ }
+ if (tabla_p->dai[j].ch_act == tabla_p->dai[j].ch_tot)
+ ret = tabla_cfg_slim_sch_tx(tabla,
+ tabla_p->dai[j].ch_num,
+ tabla_p->dai[j].ch_tot,
+ tabla_p->dai[j].rate);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
+ if (tabla_dai[j].id == AIF1_PB)
+ continue;
+ if (!strncmp(w->sname,
+ tabla_dai[j].capture.stream_name, 13)) {
+ --tabla_p->dai[j].ch_act;
+ break;
+ }
+ }
+ if (!tabla_p->dai[j].ch_act) {
+ ret = tabla_close_slim_sch_tx(tabla,
+ tabla_p->dai[j].ch_num,
+ tabla_p->dai[j].ch_tot);
+ tabla_p->dai[j].rate = 0;
+ memset(tabla_p->dai[j].ch_num, 0, (sizeof(u32)*
+ tabla_p->dai[j].ch_tot));
+ tabla_p->dai[j].ch_tot = 0;
+ }
+ }
+ return ret;
+}
+
+/* Todo: Have seperate dapm widgets for I2S and Slimbus.
+ * Might Need to have callbacks registered only for slimbus
+ */
+static const struct snd_soc_dapm_widget tabla_dapm_widgets[] = {
+ /*RX stuff */
+ SND_SOC_DAPM_OUTPUT("EAR"),
+
+ SND_SOC_DAPM_PGA("EAR PA", TABLA_A_RX_EAR_EN, 4, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("DAC1", TABLA_A_RX_EAR_EN, 6, 0, dac1_switch,
+ ARRAY_SIZE(dac1_switch)),
+
+ SND_SOC_DAPM_AIF_IN_E("SLIM RX1", "AIF1 Playback", 0, SND_SOC_NOPM, 0,
+ 0, tabla_codec_enable_slimrx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_AIF_IN_E("SLIM RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0,
+ 0, tabla_codec_enable_slimrx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_AIF_IN("SLIM RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("SLIM RX4", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
+
+ /* Headphone */
+ SND_SOC_DAPM_OUTPUT("HEADPHONE"),
+ SND_SOC_DAPM_PGA_E("HPHL", TABLA_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
+ tabla_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER("HPHL DAC", TABLA_A_RX_HPH_L_DAC_CTL, 7, 0,
+ hphl_switch, ARRAY_SIZE(hphl_switch)),
+
+ SND_SOC_DAPM_PGA_E("HPHR", TABLA_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
+ tabla_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, TABLA_A_RX_HPH_R_DAC_CTL, 7, 0,
+ tabla_hphr_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ /* Speaker */
+ SND_SOC_DAPM_OUTPUT("LINEOUT1"),
+ SND_SOC_DAPM_OUTPUT("LINEOUT2"),
+ SND_SOC_DAPM_OUTPUT("LINEOUT3"),
+ SND_SOC_DAPM_OUTPUT("LINEOUT4"),
+ SND_SOC_DAPM_OUTPUT("LINEOUT5"),
+
+ SND_SOC_DAPM_PGA_E("LINEOUT1 PA", TABLA_A_RX_LINE_CNP_EN, 0, 0, NULL,
+ 0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("LINEOUT2 PA", TABLA_A_RX_LINE_CNP_EN, 1, 0, NULL,
+ 0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("LINEOUT3 PA", TABLA_A_RX_LINE_CNP_EN, 2, 0, NULL,
+ 0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("LINEOUT4 PA", TABLA_A_RX_LINE_CNP_EN, 3, 0, NULL,
+ 0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("LINEOUT5 PA", TABLA_A_RX_LINE_CNP_EN, 4, 0, NULL, 0,
+ tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TABLA_A_RX_LINE_1_DAC_CTL, 7, 0
+ , tabla_lineout_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_DAC_E("LINEOUT2 DAC", NULL, TABLA_A_RX_LINE_2_DAC_CTL, 7, 0
+ , tabla_lineout_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_DAC_E("LINEOUT3 DAC", NULL, TABLA_A_RX_LINE_3_DAC_CTL, 7, 0
+ , tabla_lineout_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SWITCH("LINEOUT3 DAC GROUND", SND_SOC_NOPM, 0, 0,
+ &lineout3_ground_switch),
+ SND_SOC_DAPM_DAC_E("LINEOUT4 DAC", NULL, TABLA_A_RX_LINE_4_DAC_CTL, 7, 0
+ , tabla_lineout_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SWITCH("LINEOUT4 DAC GROUND", SND_SOC_NOPM, 0, 0,
+ &lineout4_ground_switch),
+ SND_SOC_DAPM_DAC_E("LINEOUT5 DAC", NULL, TABLA_A_RX_LINE_5_DAC_CTL, 7, 0
+ , tabla_lineout_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER_E("RX1 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
+ 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_MIXER_E("RX2 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
+ 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_MIXER_E("RX3 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
+ 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_MIXER_E("RX4 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 3, 0, NULL,
+ 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_MIXER_E("RX5 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 4, 0, NULL,
+ 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_MIXER_E("RX6 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 5, 0, NULL,
+ 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_MIXER_E("RX7 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 6, 0, NULL,
+ 0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX_E("RX4 DSM MUX", TABLA_A_CDC_CLK_RX_B1_CTL, 3, 0,
+ &rx4_dsm_mux, tabla_codec_reset_interpolator,
+ SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX_E("RX6 DSM MUX", TABLA_A_CDC_CLK_RX_B1_CTL, 5, 0,
+ &rx6_dsm_mux, tabla_codec_reset_interpolator,
+ SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MIXER("RX1 CHAIN", TABLA_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("RX2 CHAIN", TABLA_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+ &rx_mix1_inp1_mux),
+ SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+ &rx_mix1_inp2_mux),
+ SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+ &rx2_mix1_inp1_mux),
+ SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+ &rx2_mix1_inp2_mux),
+ SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+ &rx3_mix1_inp1_mux),
+ SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+ &rx3_mix1_inp2_mux),
+ SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+ &rx4_mix1_inp1_mux),
+ SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+ &rx4_mix1_inp2_mux),
+ SND_SOC_DAPM_MUX("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+ &rx5_mix1_inp1_mux),
+ SND_SOC_DAPM_MUX("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+ &rx5_mix1_inp2_mux),
+ SND_SOC_DAPM_MUX("RX6 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+ &rx6_mix1_inp1_mux),
+ SND_SOC_DAPM_MUX("RX6 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+ &rx6_mix1_inp2_mux),
+ SND_SOC_DAPM_MUX("RX7 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+ &rx7_mix1_inp1_mux),
+ SND_SOC_DAPM_MUX("RX7 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+ &rx7_mix1_inp2_mux),
+
+ SND_SOC_DAPM_SUPPLY("CP", TABLA_A_CP_EN, 0, 0,
+ tabla_codec_enable_charge_pump, SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD),
+
+ SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
+ tabla_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ /* TX */
+
+ SND_SOC_DAPM_SUPPLY("CDC_CONN", TABLA_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
+ 0),
+
+ SND_SOC_DAPM_SUPPLY("LDO_H", TABLA_A_LDO_H_MODE_1, 7, 0,
+ tabla_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
+
+ SND_SOC_DAPM_INPUT("AMIC1"),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TABLA_A_MICB_1_CTL, 7, 0,
+ tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", TABLA_A_MICB_1_CTL, 7, 0,
+ tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", TABLA_A_MICB_1_CTL, 7, 0,
+ tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("ADC1", NULL, TABLA_A_TX_1_2_EN, 7, 0,
+ tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_INPUT("AMIC3"),
+ SND_SOC_DAPM_ADC_E("ADC3", NULL, TABLA_A_TX_3_4_EN, 7, 0,
+ tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_INPUT("AMIC4"),
+ SND_SOC_DAPM_ADC_E("ADC4", NULL, TABLA_A_TX_3_4_EN, 3, 0,
+ tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_INPUT("AMIC5"),
+ SND_SOC_DAPM_ADC_E("ADC5", NULL, TABLA_A_TX_5_6_EN, 7, 0,
+ tabla_codec_enable_adc, SND_SOC_DAPM_POST_PMU),
+
+ SND_SOC_DAPM_INPUT("AMIC6"),
+ SND_SOC_DAPM_ADC_E("ADC6", NULL, TABLA_A_TX_5_6_EN, 3, 0,
+ tabla_codec_enable_adc, SND_SOC_DAPM_POST_PMU),
+
+ SND_SOC_DAPM_MUX_E("DEC1 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
+ &dec1_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX_E("DEC2 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
+ &dec2_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX_E("DEC3 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 2, 0,
+ &dec3_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX_E("DEC4 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 3, 0,
+ &dec4_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX_E("DEC5 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 4, 0,
+ &dec5_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX_E("DEC6 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 5, 0,
+ &dec6_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX_E("DEC7 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 6, 0,
+ &dec7_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX_E("DEC8 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 7, 0,
+ &dec8_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX_E("DEC9 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0, 0,
+ &dec9_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX_E("DEC10 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B2_CTL, 1, 0,
+ &dec10_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX("ANC1 MUX", SND_SOC_NOPM, 0, 0, &anc1_mux),
+ SND_SOC_DAPM_MUX("ANC2 MUX", SND_SOC_NOPM, 0, 0, &anc2_mux),
+
+ SND_SOC_DAPM_MIXER_E("ANC", SND_SOC_NOPM, 0, 0, NULL, 0,
+ tabla_codec_enable_anc, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
+
+ SND_SOC_DAPM_INPUT("AMIC2"),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", TABLA_A_MICB_2_CTL, 7, 0,
+ tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", TABLA_A_MICB_2_CTL, 7, 0,
+ tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", TABLA_A_MICB_2_CTL, 7, 0,
+ tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", TABLA_A_MICB_2_CTL, 7, 0,
+ tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", TABLA_A_MICB_3_CTL, 7, 0,
+ tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", TABLA_A_MICB_3_CTL, 7, 0,
+ tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", TABLA_A_MICB_3_CTL, 7, 0,
+ tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("ADC2", NULL, TABLA_A_TX_1_2_EN, 3, 0,
+ tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, 0, 0, &sb_tx1_mux),
+ SND_SOC_DAPM_AIF_OUT("SLIM TX1", "AIF1 Capture", NULL, SND_SOC_NOPM,
+ 0, 0),
+
+ SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, 0, 0, &sb_tx5_mux),
+ SND_SOC_DAPM_AIF_OUT("SLIM TX5", "AIF1 Capture", NULL, SND_SOC_NOPM,
+ 4, 0),
+
+ SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, 0, 0, &sb_tx6_mux),
+ SND_SOC_DAPM_AIF_OUT("SLIM TX6", "AIF1 Capture", NULL, SND_SOC_NOPM,
+ 5, 0),
+
+ SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, 0, 0, &sb_tx7_mux),
+ SND_SOC_DAPM_AIF_OUT_E("SLIM TX7", "AIF1 Capture", 0, SND_SOC_NOPM, 0,
+ 0, tabla_codec_enable_slimtx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, 0, 0, &sb_tx8_mux),
+ SND_SOC_DAPM_AIF_OUT_E("SLIM TX8", "AIF1 Capture", 0, SND_SOC_NOPM, 0,
+ 0, tabla_codec_enable_slimtx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, 0, 0, &sb_tx9_mux),
+ SND_SOC_DAPM_AIF_OUT_E("SLIM TX9", "AIF1 Capture", NULL, SND_SOC_NOPM,
+ 0, 0, tabla_codec_enable_slimtx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, 0, 0, &sb_tx10_mux),
+ SND_SOC_DAPM_AIF_OUT_E("SLIM TX10", "AIF1 Capture", NULL, SND_SOC_NOPM,
+ 0, 0, tabla_codec_enable_slimtx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ /* Digital Mic Inputs */
+ SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
+ tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
+ tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
+ tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
+ tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
+ tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 0,
+ tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ /* Sidetone */
+ SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
+ SND_SOC_DAPM_PGA("IIR1", TABLA_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
+};
+
static short tabla_codec_read_sta_result(struct snd_soc_codec *codec)
{
u8 bias_msb, bias_lsb;
@@ -4680,6 +4883,7 @@
struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;
int i;
+ int ch_cnt;
codec->control_data = dev_get_drvdata(codec->dev->parent);
control = codec->control_data;
@@ -4831,6 +5035,20 @@
goto err_hphr_ocp_irq;
}
tabla_disable_irq(codec->control_data, TABLA_IRQ_HPH_PA_OCPR_FAULT);
+ for (i = 0; i < ARRAY_SIZE(tabla_dai); i++) {
+ switch (tabla_dai[i].id) {
+ case AIF1_PB:
+ ch_cnt = tabla_dai[i].playback.channels_max;
+ break;
+ case AIF1_CAP:
+ ch_cnt = tabla_dai[i].capture.channels_max;
+ break;
+ default:
+ continue;
+ }
+ tabla->dai[i].ch_num = kzalloc((sizeof(unsigned int)*
+ ch_cnt), GFP_KERNEL);
+ }
#ifdef CONFIG_DEBUG_FS
debug_tabla_priv = tabla;
@@ -4857,6 +5075,7 @@
}
static int tabla_codec_remove(struct snd_soc_codec *codec)
{
+ int i;
struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
tabla_free_irq(codec->control_data, TABLA_IRQ_SLIMBUS, tabla);
tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE, tabla);
@@ -4867,6 +5086,8 @@
tabla_codec_enable_bandgap(codec, TABLA_BANDGAP_OFF);
if (tabla->mbhc_fw)
release_firmware(tabla->mbhc_fw);
+ for (i = 0; i < ARRAY_SIZE(tabla_dai); i++)
+ kfree(tabla->dai[i].ch_num);
kfree(tabla);
return 0;
}
diff --git a/sound/soc/codecs/wcd9310.h b/sound/soc/codecs/wcd9310.h
index 6ddc471..9c430b9 100644
--- a/sound/soc/codecs/wcd9310.h
+++ b/sound/soc/codecs/wcd9310.h
@@ -11,6 +11,7 @@
*/
#include <sound/soc.h>
#include <sound/jack.h>
+#include <linux/mfd/wcd9310/wcd9310-slimslave.h>
#define TABLA_NUM_REGISTERS 0x400
#define TABLA_MAX_REGISTER (TABLA_NUM_REGISTERS-1)
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index bd41e0b..e69d134 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -671,6 +671,66 @@
return tabla_cal;
}
+static int msm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
+ unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
+
+ pr_debug("%s: ch=%d\n", __func__,
+ msm_slim_0_rx_ch);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map\n", __func__);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+ msm_slim_0_rx_ch, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map\n", __func__);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(codec_dai, 0, 0,
+ msm_slim_0_rx_ch, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set codec channel map\n",
+ __func__);
+ goto end;
+ }
+ } else {
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map\n", __func__);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ msm_slim_0_tx_ch, tx_ch, 0 , 0);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map\n", __func__);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(codec_dai,
+ msm_slim_0_tx_ch, tx_ch, 0, 0);
+ if (ret < 0) {
+ pr_err("%s: failed to set codec channel map\n",
+ __func__);
+ goto end;
+ }
+
+
+ }
+end:
+ return ret;
+}
+
static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
int err;
@@ -805,6 +865,23 @@
return 0;
}
+static int msm_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
+ channels->min, channels->max);
+
+ rate->min = rate->max = 48000;
+
+ return 0;
+}
+
static int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -924,6 +1001,7 @@
static struct snd_soc_ops msm_be_ops = {
.startup = msm_startup,
+ .hw_params = msm_hw_params,
.shutdown = msm_shutdown,
};
@@ -1099,14 +1177,14 @@
{
.name = LPASS_BE_HDMI,
.stream_name = "HDMI Playback",
- .cpu_dai_name = "msm-dai-q6.8",
+ .cpu_dai_name = "msm-dai-q6-hdmi.8",
.platform_name = "msm-pcm-routing",
.codec_name = "msm-stub-codec.1",
.codec_dai_name = "msm-stub-rx",
.no_pcm = 1,
.no_codec = 1,
.be_id = MSM_BACKEND_DAI_HDMI_RX,
- .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .be_hw_params_fixup = msm_hdmi_be_hw_params_fixup,
},
/* Backend AFE DAI Links */
{
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 0951795..aff87ae 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -211,81 +211,28 @@
struct snd_soc_dai *dai, int stream)
{
struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
- u8 pgd_la, inf_la;
- u16 *slave_port_mapping;
-
- memset(dai_data->port_config.slimbus.slave_port_mapping, 0,
- sizeof(dai_data->port_config.slimbus.slave_port_mapping));
dai_data->channels = params_channels(params);
-
- slave_port_mapping = dai_data->port_config.slimbus.slave_port_mapping;
-
- switch (dai_data->channels) {
- case 4:
- if (dai->id == SLIMBUS_0_TX) {
- slave_port_mapping[0] = 7;
- slave_port_mapping[1] = 8;
- slave_port_mapping[2] = 9;
- slave_port_mapping[3] = 10;
- } else {
- return -EINVAL;
- }
- break;
- case 3:
- if (dai->id == SLIMBUS_0_TX) {
- slave_port_mapping[0] = 7;
- slave_port_mapping[1] = 8;
- slave_port_mapping[2] = 9;
- } else {
- return -EINVAL;
- }
- break;
- case 2:
- if (dai->id == SLIMBUS_0_RX) {
- slave_port_mapping[0] = 1;
- slave_port_mapping[1] = 2;
- } else {
- slave_port_mapping[0] = 7;
- slave_port_mapping[1] = 8;
- }
- break;
- case 1:
- if (dai->id == SLIMBUS_0_RX)
- slave_port_mapping[0] = 1;
- else
- slave_port_mapping[0] = 7;
- break;
- default:
- return -EINVAL;
- break;
- }
dai_data->rate = params_rate(params);
- tabla_get_logical_addresses(&pgd_la, &inf_la);
dai_data->port_config.slimbus.slimbus_dev_id = AFE_SLIMBUS_DEVICE_1;
- dai_data->port_config.slimbus.slave_dev_pgd_la = pgd_la;
- dai_data->port_config.slimbus.slave_dev_intfdev_la = inf_la;
/* Q6 only supports 16 as now */
- dai_data->port_config.slimbus.bit_width = 16;
- dai_data->port_config.slimbus.data_format = 0;
- dai_data->port_config.slimbus.num_channels = dai_data->channels;
- dai_data->port_config.slimbus.reserved = 0;
+ dai_data->port_config.slim_sch.bit_width = 16;
+ dai_data->port_config.slim_sch.data_format = 0;
+ dai_data->port_config.slim_sch.num_channels = dai_data->channels;
+ dai_data->port_config.slim_sch.reserved = 0;
- dev_dbg(dai->dev, "slimbus_dev_id %hu slave_dev_pgd_la 0x%hx\n"
- "slave_dev_intfdev_la 0x%hx bit_width %hu data_format %hu\n"
- "num_channel %hu slave_port_mapping[0] %hu\n"
+ dev_dbg(dai->dev, "%s:slimbus_dev_id[%hu] bit_wd[%hu] format[%hu]\n"
+ "num_channel %hu slave_ch_mapping[0] %hu\n"
"slave_port_mapping[1] %hu slave_port_mapping[2] %hu\n"
- "sample_rate %d\n",
- dai_data->port_config.slimbus.slimbus_dev_id,
- dai_data->port_config.slimbus.slave_dev_pgd_la,
- dai_data->port_config.slimbus.slave_dev_intfdev_la,
- dai_data->port_config.slimbus.bit_width,
- dai_data->port_config.slimbus.data_format,
- dai_data->port_config.slimbus.num_channels,
- dai_data->port_config.slimbus.slave_port_mapping[0],
- dai_data->port_config.slimbus.slave_port_mapping[1],
- dai_data->port_config.slimbus.slave_port_mapping[2],
+ "sample_rate %d\n", __func__,
+ dai_data->port_config.slim_sch.slimbus_dev_id,
+ dai_data->port_config.slim_sch.bit_width,
+ dai_data->port_config.slim_sch.data_format,
+ dai_data->port_config.slim_sch.num_channels,
+ dai_data->port_config.slim_sch.slave_ch_mapping[0],
+ dai_data->port_config.slim_sch.slave_ch_mapping[1],
+ dai_data->port_config.slim_sch.slave_ch_mapping[2],
dai_data->rate);
return 0;
@@ -784,7 +731,8 @@
{
int rc = 0;
- dev_dbg(dai->dev, "enter %s, id = %d\n", __func__, dai->id);
+ dev_dbg(dai->dev, "enter %s, id = %d fmt[%d]\n", __func__,
+ dai->id, fmt);
switch (dai->id) {
case PRIMARY_I2S_TX:
case PRIMARY_I2S_RX:
@@ -801,12 +749,69 @@
return rc;
}
+static int msm_dai_q6_set_channel_map(struct snd_soc_dai *dai,
+ unsigned int tx_num, unsigned int *tx_slot,
+ unsigned int rx_num, unsigned int *rx_slot)
+
+{
+ int rc = 0;
+ struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
+ unsigned int i = 0;
+
+ dev_dbg(dai->dev, "enter %s, id = %d\n", __func__,
+ dai->id);
+ if (!tx_slot && !rx_slot)
+ return -EINVAL;
+ switch (dai->id) {
+ case SLIMBUS_0_RX:
+ /* channel number to be between 128 and 255. For RX port
+ * use channel numbers from 138 to 144, for TX port
+ * use channel numbers from 128 to 137
+ */
+ for (i = 0; i < rx_num; i++) {
+ dai_data->port_config.slim_sch.slave_ch_mapping[i] =
+ rx_slot[i];
+ pr_debug("%s: find number of channels[%d] ch[%d]\n",
+ __func__, i,
+ rx_slot[i]);
+ }
+ dai_data->port_config.slim_sch.num_channels = rx_num;
+ pr_debug("%s:SLIMBUS_0_RX cnt[%d] ch[%d %d]\n", __func__,
+ rx_num, dai_data->port_config.slim_sch.slave_ch_mapping[0],
+ dai_data->port_config.slim_sch.slave_ch_mapping[1]);
+
+ break;
+ case SLIMBUS_0_TX:
+ /* channel number to be between 128 and 255. For RX port
+ * use channel numbers from 138 to 144, for TX port
+ * use channel numbers from 128 to 137
+ */
+ for (i = 0; i < tx_num; i++) {
+ dai_data->port_config.slim_sch.slave_ch_mapping[i] =
+ tx_slot[i];
+ pr_debug("%s: find number of channels[%d] ch[%d]\n",
+ __func__, i, tx_slot[i]);
+ }
+ dai_data->port_config.slim_sch.num_channels = tx_num;
+ pr_debug("%s:SLIMBUS_0_TX cnt[%d] ch[%d %d]\n", __func__,
+ tx_num, dai_data->port_config.slim_sch.slave_ch_mapping[0],
+ dai_data->port_config.slim_sch.slave_ch_mapping[1]);
+ break;
+ default:
+ dev_err(dai->dev, "invalid cpu_dai set_fmt\n");
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
+
static struct snd_soc_dai_ops msm_dai_q6_ops = {
.prepare = msm_dai_q6_prepare,
.trigger = msm_dai_q6_trigger,
.hw_params = msm_dai_q6_hw_params,
.shutdown = msm_dai_q6_shutdown,
.set_fmt = msm_dai_q6_set_fmt,
+ .set_channel_map = msm_dai_q6_set_channel_map,
};
static struct snd_soc_dai_ops msm_dai_q6_auxpcm_ops = {
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 1ed73e2..bedfd68 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -643,6 +643,66 @@
return tabla_cal;
}
+static int msm8960_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
+ unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
+
+ pr_debug("%s: ch=%d\n", __func__,
+ msm8960_slim_0_rx_ch);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map\n", __func__);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+ msm8960_slim_0_rx_ch, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map\n", __func__);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(codec_dai, 0, 0,
+ msm8960_slim_0_rx_ch, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set codec channel map\n",
+ __func__);
+ goto end;
+ }
+ } else {
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map\n", __func__);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ msm8960_slim_0_tx_ch, tx_ch, 0 , 0);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map\n", __func__);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(codec_dai,
+ msm8960_slim_0_tx_ch, tx_ch, 0, 0);
+ if (ret < 0) {
+ pr_err("%s: failed to set codec channel map\n",
+ __func__);
+ goto end;
+ }
+
+
+ }
+end:
+ return ret;
+}
+
static int msm8960_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
int err;
@@ -914,6 +974,7 @@
static struct snd_soc_ops msm8960_be_ops = {
.startup = msm8960_startup,
+ .hw_params = msm8960_hw_params,
.shutdown = msm8960_shutdown,
};
diff --git a/sound/soc/msm/qdsp6/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index ef01fb3..59506f1 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -78,6 +78,7 @@
switch (payload[0]) {
case AFE_PORT_AUDIO_IF_CONFIG:
case AFE_PORT_MULTI_CHAN_HDMI_AUDIO_IF_CONFIG:
+ case AFE_PORT_AUDIO_SLIM_SCH_CONFIG:
case AFE_PORT_CMD_STOP:
case AFE_PORT_CMD_START:
case AFE_PORT_CMD_LOOPBACK:
@@ -285,7 +286,7 @@
break;
case SLIMBUS_0_RX:
case SLIMBUS_0_TX:
- ret_size = SIZEOF_CFG_CMD(afe_port_slimbus_cfg);
+ ret_size = SIZEOF_CFG_CMD(afe_port_slimbus_sch_cfg);
break;
case RT_PROXY_PORT_001_RX:
case RT_PROXY_PORT_001_TX:
@@ -418,7 +419,23 @@
config.hdr.src_port = 0;
config.hdr.dest_port = 0;
config.hdr.token = 0;
- config.hdr.opcode = AFE_PORT_AUDIO_IF_CONFIG;
+ switch (port_id) {
+ case SLIMBUS_0_RX:
+ case SLIMBUS_0_TX:
+ case SLIMBUS_1_RX:
+ case SLIMBUS_1_TX:
+ case SLIMBUS_2_RX:
+ case SLIMBUS_2_TX:
+ case SLIMBUS_3_RX:
+ case SLIMBUS_3_TX:
+ case SLIMBUS_4_RX:
+ case SLIMBUS_4_TX:
+ config.hdr.opcode = AFE_PORT_AUDIO_SLIM_SCH_CONFIG;
+ break;
+ default:
+ config.hdr.opcode = AFE_PORT_AUDIO_IF_CONFIG;
+ break;
+ }
}
if (afe_validate_port(port_id) < 0) {
@@ -485,7 +502,7 @@
return ret;
}
- pr_info("%s: %d %d\n", __func__, port_id, rate);
+ pr_debug("%s: %d %d\n", __func__, port_id, rate);
if ((port_id == RT_PROXY_DAI_001_RX) ||
(port_id == RT_PROXY_DAI_002_TX))
@@ -793,7 +810,7 @@
int ret = 0;
struct afe_pseudoport_start_command start;
- pr_info("%s: port_id=%d\n", __func__, port_id);
+ pr_debug("%s: port_id=%d\n", __func__, port_id);
ret = afe_q6_interface_prepare();
if (ret != 0)
@@ -866,7 +883,7 @@
int ret = 0;
struct afe_pseudoport_stop_command stop;
- pr_info("%s: port_id=%d\n", __func__, port_id);
+ pr_debug("%s: port_id=%d\n", __func__, port_id);
if (this_afe.apr == NULL) {
pr_err("%s: AFE is already closed\n", __func__);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 219ae10..d528f4b 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3673,6 +3673,29 @@
EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
/**
+ * snd_soc_dai_get_channel_map - configure DAI audio channel map
+ * @dai: DAI
+ * @tx_num: how many TX channels
+ * @tx_slot: pointer to an array which imply the TX slot number channel
+ * 0~num-1 uses
+ * @rx_num: how many RX channels
+ * @rx_slot: pointer to an array which imply the RX slot number channel
+ * 0~num-1 uses
+ *
+ * configure the relationship between channel number and TDM slot number.
+ */
+int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
+ unsigned int *tx_num, unsigned int *tx_slot,
+ unsigned int *rx_num, unsigned int *rx_slot)
+{
+ if (dai->driver && dai->driver->ops->get_channel_map)
+ return dai->driver->ops->get_channel_map(dai, tx_num, tx_slot,
+ rx_num, rx_slot);
+ else
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_get_channel_map);
+/**
* snd_soc_dai_set_tristate - configure DAI system or master clock.
* @dai: DAI
* @tristate: tristate enable
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b462639..c03f7ca7 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -2,6 +2,7 @@
* soc-dapm.c -- ALSA SoC Dynamic Audio Power Management
*
* Copyright 2005 Wolfson Microelectronics PLC.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* Author: Liam Girdwood <lrg@slimlogic.co.uk>
*
@@ -59,8 +60,6 @@
[snd_soc_dapm_pre] = 0,
[snd_soc_dapm_supply] = 1,
[snd_soc_dapm_micbias] = 2,
- [snd_soc_dapm_aif_in] = 3,
- [snd_soc_dapm_aif_out] = 3,
[snd_soc_dapm_mic] = 4,
[snd_soc_dapm_mux] = 5,
[snd_soc_dapm_virt_mux] = 5,
@@ -69,6 +68,8 @@
[snd_soc_dapm_mixer] = 7,
[snd_soc_dapm_mixer_named_ctl] = 7,
[snd_soc_dapm_pga] = 8,
+ [snd_soc_dapm_aif_in] = 8,
+ [snd_soc_dapm_aif_out] = 8,
[snd_soc_dapm_adc] = 9,
[snd_soc_dapm_out_drv] = 10,
[snd_soc_dapm_hp] = 10,
@@ -78,6 +79,8 @@
static int dapm_down_seq[] = {
[snd_soc_dapm_pre] = 0,
+ [snd_soc_dapm_aif_in] = 1,
+ [snd_soc_dapm_aif_out] = 1,
[snd_soc_dapm_adc] = 1,
[snd_soc_dapm_hp] = 2,
[snd_soc_dapm_spk] = 2,
@@ -91,8 +94,6 @@
[snd_soc_dapm_mux] = 9,
[snd_soc_dapm_virt_mux] = 9,
[snd_soc_dapm_value_mux] = 9,
- [snd_soc_dapm_aif_in] = 10,
- [snd_soc_dapm_aif_out] = 10,
[snd_soc_dapm_supply] = 11,
[snd_soc_dapm_post] = 12,
};