Merge "ASoC: msm: Apply cached volume and mute at call start." into msm-3.4
diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
index 11af7a9..dbbe46d 100644
--- a/Documentation/devicetree/bindings/media/video/msm-vidc.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
@@ -5,11 +5,20 @@
- "qcom,msm-vidc"
- reg : offset and length of the register set for the device.
- interrupts : should contain the vidc interrupt.
+- vidc-cp-map : start and size of device virtual address range for secure buffers.
+ Video hardware uses this address range to identify if the buffers are secure
+ or non-secure.
+- vidc-ns-map : start and size of device virtual address range for non-secure buffers.
+ Video hardware uses this address range to identify if the buffers are secure
+ or non-secure.
Example:
+
qcom,vidc@fdc00000 {
compatible = "qcom,msm-vidc";
reg = <0xfdc00000 0xff000>;
interrupts = <0 44 0>;
+ vidc-cp-map = <0x1000000 0x40000000>;
+ vidc-ns-map = <0x40000000 0x40000000>;
};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 8426b52..2eb8216 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -46,6 +46,8 @@
compatible = "qcom,msm-vidc";
reg = <0xfdc00000 0xff000>;
interrupts = <0 44 0>;
+ vidc-cp-map = <0x1000000 0x40000000>;
+ vidc-ns-map = <0x40000000 0x40000000>;
};
serial@f991f000 {
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 7ccdd0f..5cd93dc 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -295,6 +295,7 @@
obj-$(CONFIG_ARCH_MSM8974) += clock-local2.o clock-pll.o clock-8974.o clock-rpm.o clock-voter.o
obj-$(CONFIG_ARCH_MSM8974) += gdsc.o
obj-$(CONFIG_ARCH_MSM9625) += board-9625.o board-9625-gpiomux.o
+obj-$(CONFIG_ARCH_MSM8930) += acpuclock-krait.o acpuclock-8930.o acpuclock-8627.o
obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire.o board-sapphire-gpio.o
obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire-keypad.o board-sapphire-panel.o
diff --git a/arch/arm/mach-msm/acpuclock-8627.c b/arch/arm/mach-msm/acpuclock-8627.c
new file mode 100644
index 0000000..45f2096
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-8627.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2011-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/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <mach/rpm-regulator.h>
+#include <mach/msm_bus_board.h>
+#include <mach/msm_bus.h>
+
+#include "acpuclock.h"
+#include "acpuclock-krait.h"
+
+/* Corner type vreg VDD values */
+#define LVL_NONE RPM_VREG_CORNER_NONE
+#define LVL_LOW RPM_VREG_CORNER_LOW
+#define LVL_NOM RPM_VREG_CORNER_NOMINAL
+#define LVL_HIGH RPM_VREG_CORNER_HIGH
+
+static struct hfpll_data hfpll_data = {
+ .mode_offset = 0x00,
+ .l_offset = 0x08,
+ .m_offset = 0x0C,
+ .n_offset = 0x10,
+ .config_offset = 0x04,
+ .config_val = 0x7845C665,
+ .has_droop_ctl = true,
+ .droop_offset = 0x14,
+ .droop_val = 0x0108C000,
+ .low_vdd_l_max = 40,
+ .vdd[HFPLL_VDD_NONE] = LVL_NONE,
+ .vdd[HFPLL_VDD_LOW] = LVL_LOW,
+ .vdd[HFPLL_VDD_NOM] = LVL_NOM,
+};
+
+static struct scalable scalable[] = {
+ [CPU0] = {
+ .hfpll_phys_base = 0x00903200,
+ .hfpll_data = &hfpll_data,
+ .aux_clk_sel_phys = 0x02088014,
+ .aux_clk_sel = 3,
+ .l2cpmr_iaddr = 0x4501,
+ .vreg[VREG_CORE] = { "krait0", 1300000, 1740000 },
+ .vreg[VREG_MEM] = { "krait0_mem", 1150000 },
+ .vreg[VREG_DIG] = { "krait0_dig", 1150000 },
+ .vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
+ },
+ [CPU1] = {
+ .hfpll_phys_base = 0x00903300,
+ .hfpll_data = &hfpll_data,
+ .aux_clk_sel_phys = 0x02098014,
+ .aux_clk_sel = 3,
+ .l2cpmr_iaddr = 0x5501,
+ .vreg[VREG_CORE] = { "krait1", 1300000, 1740000 },
+ .vreg[VREG_MEM] = { "krait1_mem", 1150000 },
+ .vreg[VREG_DIG] = { "krait1_dig", 1150000 },
+ .vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
+ },
+ [L2] = {
+ .hfpll_phys_base = 0x00903400,
+ .hfpll_data = &hfpll_data,
+ .aux_clk_sel_phys = 0x02011028,
+ .aux_clk_sel = 3,
+ .l2cpmr_iaddr = 0x0500,
+ .vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
+ },
+};
+
+static struct msm_bus_paths bw_level_tbl[] = {
+ [0] = BW_MBPS(640), /* At least 80 MHz on bus. */
+ [1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
+ [2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
+ [3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
+ [4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
+};
+
+static struct msm_bus_scale_pdata bus_scale_data = {
+ .usecase = bw_level_tbl,
+ .num_usecases = ARRAY_SIZE(bw_level_tbl),
+ .active_only = 1,
+ .name = "acpuclk-8627",
+};
+
+/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
+#define L2(x) (&l2_freq_tbl[(x)])
+static struct l2_level l2_freq_tbl[] = {
+ [0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, LVL_NOM, 1050000, 0 },
+ [1] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
+ [2] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 1 },
+ [3] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 1 },
+ [4] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
+ [5] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
+ [6] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 2 },
+ [7] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 3 },
+ [8] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 3 },
+ [9] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 3 },
+ [10] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
+ [11] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 4 },
+ [12] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 4 },
+};
+
+/* TODO: Update core voltages when data is available. */
+static struct acpu_level acpu_freq_tbl[] = {
+ { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 925000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 925000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 937500 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 962500 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(9), 987500 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(9), 1000000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(9), 1025000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(9), 1062500 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(12), 1062500 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(12), 1087500 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(12), 1100000 },
+ { 0, { 0 } }
+};
+
+static struct acpuclk_krait_params acpuclk_8627_params = {
+ .scalable = scalable,
+ .pvs_acpu_freq_tbl[PVS_SLOW] = acpu_freq_tbl,
+ .pvs_acpu_freq_tbl[PVS_NOMINAL] = acpu_freq_tbl,
+ .pvs_acpu_freq_tbl[PVS_FAST] = acpu_freq_tbl,
+ .l2_freq_tbl = l2_freq_tbl,
+ .l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl),
+ .bus_scale_data = &bus_scale_data,
+ .qfprom_phys_base = 0x00700000,
+};
+
+static int __init acpuclk_8627_probe(struct platform_device *pdev)
+{
+ return acpuclk_krait_init(&pdev->dev, &acpuclk_8627_params);
+}
+
+static struct platform_driver acpuclk_8627_driver = {
+ .driver = {
+ .name = "acpuclk-8627",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init acpuclk_8627_init(void)
+{
+ return platform_driver_probe(&acpuclk_8627_driver,
+ acpuclk_8627_probe);
+}
+device_initcall(acpuclk_8627_init);
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
new file mode 100644
index 0000000..d60b4eb
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-8930.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2011-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/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <mach/rpm-regulator.h>
+#include <mach/msm_bus_board.h>
+#include <mach/msm_bus.h>
+
+#include "acpuclock.h"
+#include "acpuclock-krait.h"
+
+/* Corner type vreg VDD values */
+#define LVL_NONE RPM_VREG_CORNER_NONE
+#define LVL_LOW RPM_VREG_CORNER_LOW
+#define LVL_NOM RPM_VREG_CORNER_NOMINAL
+#define LVL_HIGH RPM_VREG_CORNER_HIGH
+
+static struct hfpll_data hfpll_data = {
+ .mode_offset = 0x00,
+ .l_offset = 0x08,
+ .m_offset = 0x0C,
+ .n_offset = 0x10,
+ .config_offset = 0x04,
+ .config_val = 0x7845C665,
+ .has_droop_ctl = true,
+ .droop_offset = 0x14,
+ .droop_val = 0x0108C000,
+ .low_vdd_l_max = 40,
+ .vdd[HFPLL_VDD_NONE] = LVL_NONE,
+ .vdd[HFPLL_VDD_LOW] = LVL_LOW,
+ .vdd[HFPLL_VDD_NOM] = LVL_NOM,
+};
+
+static struct scalable scalable[] = {
+ [CPU0] = {
+ .hfpll_phys_base = 0x00903200,
+ .hfpll_data = &hfpll_data,
+ .aux_clk_sel_phys = 0x02088014,
+ .aux_clk_sel = 3,
+ .l2cpmr_iaddr = 0x4501,
+ .vreg[VREG_CORE] = { "krait0", 1300000, 1740000 },
+ .vreg[VREG_MEM] = { "krait0_mem", 1150000 },
+ .vreg[VREG_DIG] = { "krait0_dig", 1150000 },
+ .vreg[VREG_HFPLL_A] = { "krait0_hfpll", 1800000 },
+ },
+ [CPU1] = {
+ .hfpll_phys_base = 0x00903300,
+ .hfpll_data = &hfpll_data,
+ .aux_clk_sel_phys = 0x02098014,
+ .aux_clk_sel = 3,
+ .l2cpmr_iaddr = 0x5501,
+ .vreg[VREG_CORE] = { "krait1", 1300000, 1740000 },
+ .vreg[VREG_MEM] = { "krait1_mem", 1150000 },
+ .vreg[VREG_DIG] = { "krait1_dig", 1150000 },
+ .vreg[VREG_HFPLL_A] = { "krait1_hfpll", 1800000 },
+ },
+ [L2] = {
+ .hfpll_phys_base = 0x00903400,
+ .hfpll_data = &hfpll_data,
+ .aux_clk_sel_phys = 0x02011028,
+ .aux_clk_sel = 3,
+ .l2cpmr_iaddr = 0x0500,
+ .vreg[VREG_HFPLL_A] = { "l2_hfpll", 1800000 },
+ },
+};
+
+static struct msm_bus_paths bw_level_tbl[] = {
+ [0] = BW_MBPS(640), /* At least 80 MHz on bus. */
+ [1] = BW_MBPS(1064), /* At least 133 MHz on bus. */
+ [2] = BW_MBPS(1600), /* At least 200 MHz on bus. */
+ [3] = BW_MBPS(2128), /* At least 266 MHz on bus. */
+ [4] = BW_MBPS(3200), /* At least 400 MHz on bus. */
+ [5] = BW_MBPS(3600), /* At least 450 MHz on bus. */
+ [6] = BW_MBPS(3936), /* At least 492 MHz on bus. */
+ [7] = BW_MBPS(4264), /* At least 533 MHz on bus. */
+};
+
+static struct msm_bus_scale_pdata bus_scale_data = {
+ .usecase = bw_level_tbl,
+ .num_usecases = ARRAY_SIZE(bw_level_tbl),
+ .active_only = 1,
+ .name = "acpuclk-8930",
+};
+
+/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
+#define L2(x) (&l2_freq_tbl[(x)])
+static struct l2_level l2_freq_tbl[] = {
+ [0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, LVL_NOM, 1050000, 0 },
+ [1] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
+ [2] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 2 },
+ [3] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 2 },
+ [4] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
+ [5] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
+ [6] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 4 },
+ [7] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 4 },
+ [8] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 4 },
+ [9] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 4 },
+ [10] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
+ [11] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 7 },
+ [12] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 7 },
+ [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, LVL_HIGH, 1150000, 7 },
+ [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, LVL_HIGH, 1150000, 7 },
+ [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, LVL_HIGH, 1150000, 7 },
+ [16] = { { 1188000, HFPLL, 1, 0, 0x2C }, LVL_HIGH, 1150000, 7 },
+};
+
+static struct acpu_level acpu_freq_tbl_slow[] = {
+ { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 975000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 975000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 1000000 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1075000 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1100000 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1125000 },
+ { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1175000 },
+ { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_nom[] = {
+ { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 925000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 925000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 950000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 950000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 975000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 975000 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1000000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1000000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1050000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1050000 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1075000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1075000 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1100000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1100000 },
+ { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1150000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1150000 },
+ { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1175000 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_fast[] = {
+ { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 900000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 900000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 925000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 925000 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 950000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 950000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1000000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1000000 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1025000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1025000 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1050000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1050000 },
+ { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1100000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1100000 },
+ { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1125000 },
+ { 0, { 0 } }
+};
+
+static struct acpuclk_krait_params acpuclk_8930_params = {
+ .scalable = scalable,
+ .pvs_acpu_freq_tbl[PVS_SLOW] = acpu_freq_tbl_slow,
+ .pvs_acpu_freq_tbl[PVS_NOMINAL] = acpu_freq_tbl_nom,
+ .pvs_acpu_freq_tbl[PVS_FAST] = acpu_freq_tbl_fast,
+ .l2_freq_tbl = l2_freq_tbl,
+ .l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl),
+ .bus_scale_data = &bus_scale_data,
+ .qfprom_phys_base = 0x00700000,
+};
+
+static int __init acpuclk_8930_probe(struct platform_device *pdev)
+{
+ return acpuclk_krait_init(&pdev->dev, &acpuclk_8930_params);
+}
+
+static struct platform_driver acpuclk_8930_driver = {
+ .driver = {
+ .name = "acpuclk-8930",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init acpuclk_8930_init(void)
+{
+ return platform_driver_probe(&acpuclk_8930_driver,
+ acpuclk_8930_probe);
+}
+device_initcall(acpuclk_8930_init);
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 7f198d2..8947c9f 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -170,12 +170,6 @@
[HFPLL_VDD_NOM] = 1050000
};
-static unsigned int hfpll_vdd_dig_tbl_8930[] = {
- [HFPLL_VDD_NONE] = LVL_NONE,
- [HFPLL_VDD_LOW] = LVL_LOW,
- [HFPLL_VDD_NOM] = LVL_NOM
-};
-
static struct scalable scalable_8960[] = {
[CPU0] = {
.hfpll_base = MSM_HFPLL_BASE + 0x200,
@@ -302,95 +296,6 @@
},
};
-static struct scalable scalable_8930[] = {
- [CPU0] = {
- .hfpll_base = MSM_HFPLL_BASE + 0x200,
- .aux_clk_sel = MSM_ACC0_BASE + 0x014,
- .l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait0", 1300000 },
- .vreg[VREG_MEM] = { "krait0_mem", 1150000,
- RPM_VREG_VOTER1,
- RPM_VREG_ID_PM8038_L24 },
- .vreg[VREG_DIG] = { "krait0_dig", LVL_HIGH,
- RPM_VREG_VOTER1,
- RPM_VREG_ID_PM8038_VDD_DIG_CORNER
- },
- .vreg[VREG_HFPLL_B] = { "hfpll0", 1800000,
- RPM_VREG_VOTER1,
- RPM_VREG_ID_PM8038_L23 },
- },
- [CPU1] = {
- .hfpll_base = MSM_HFPLL_BASE + 0x300,
- .aux_clk_sel = MSM_ACC1_BASE + 0x014,
- .l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait1", 1300000 },
- .vreg[VREG_MEM] = { "krait1_mem", 1150000,
- RPM_VREG_VOTER2,
- RPM_VREG_ID_PM8038_L24 },
- .vreg[VREG_DIG] = { "krait1_dig", LVL_HIGH,
- RPM_VREG_VOTER2,
- RPM_VREG_ID_PM8038_VDD_DIG_CORNER
- },
- .vreg[VREG_HFPLL_B] = { "hfpll1", 1800000,
- RPM_VREG_VOTER2,
- RPM_VREG_ID_PM8038_L23 },
- },
- [L2] = {
- .hfpll_base = MSM_HFPLL_BASE + 0x400,
- .hfpll_vdd_tbl = hfpll_vdd_dig_tbl_8930,
- .aux_clk_sel = MSM_APCS_GCC_BASE + 0x028,
- .l2cpmr_iaddr = L2CPMR_IADDR,
- .vreg[VREG_HFPLL_B] = { "hfpll_l2", 1800000,
- RPM_VREG_VOTER6,
- RPM_VREG_ID_PM8038_L23 },
- },
-};
-
-/*TODO: Update the rpm vreg id when the rpm driver is ready */
-static struct scalable scalable_8627[] = {
- [CPU0] = {
- .hfpll_base = MSM_HFPLL_BASE + 0x200,
- .aux_clk_sel = MSM_ACC0_BASE + 0x014,
- .l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait0", 1300000 },
- .vreg[VREG_MEM] = { "krait0_mem", 1150000,
- RPM_VREG_VOTER1,
- RPM_VREG_ID_PM8038_L24 },
- .vreg[VREG_DIG] = { "krait0_dig", LVL_HIGH,
- RPM_VREG_VOTER1,
- RPM_VREG_ID_PM8038_VDD_DIG_CORNER
- },
- .vreg[VREG_HFPLL_B] = { "hfpll0", 1800000,
- RPM_VREG_VOTER1,
- RPM_VREG_ID_PM8038_L23 },
- },
- [CPU1] = {
- .hfpll_base = MSM_HFPLL_BASE + 0x300,
- .aux_clk_sel = MSM_ACC1_BASE + 0x014,
- .l2cpmr_iaddr = L2CPUCPMR_IADDR,
- .vreg[VREG_CORE] = { "krait1", 1300000 },
- .vreg[VREG_MEM] = { "krait1_mem", 1150000,
- RPM_VREG_VOTER2,
- RPM_VREG_ID_PM8038_L24 },
- .vreg[VREG_DIG] = { "krait1_dig", LVL_HIGH,
- RPM_VREG_VOTER2,
- RPM_VREG_ID_PM8038_VDD_DIG_CORNER
- },
- .vreg[VREG_HFPLL_B] = { "hfpll1", 1800000,
- RPM_VREG_VOTER2,
- RPM_VREG_ID_PM8038_L23 },
- },
- [L2] = {
- .hfpll_base = MSM_HFPLL_BASE + 0x400,
- .hfpll_vdd_tbl = hfpll_vdd_dig_tbl_8930,
- .aux_clk_sel = MSM_APCS_GCC_BASE + 0x028,
- .l2cpmr_iaddr = L2CPMR_IADDR,
- .vreg[VREG_HFPLL_B] = { "hfpll_l2", 1800000,
- RPM_VREG_VOTER6,
- RPM_VREG_ID_PM8038_L23 },
- },
-};
-
static struct l2_level *l2_freq_tbl;
static struct acpu_level *acpu_freq_tbl;
static int l2_freq_tbl_size;
@@ -695,129 +600,6 @@
{ 0, { 0 } }
};
-/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
-#undef L2
-#define L2(x) (&l2_freq_tbl_8930[(x)])
-static struct l2_level l2_freq_tbl_8930[] = {
- [0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, LVL_NOM, 1050000, 0 },
- [1] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
- [2] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 2 },
- [3] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 2 },
- [4] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
- [5] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
- [6] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 4 },
- [7] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 4 },
- [8] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 4 },
- [9] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 4 },
- [10] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
- [11] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 7 },
- [12] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 7 },
- [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, LVL_HIGH, 1150000, 7 },
- [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, LVL_HIGH, 1150000, 7 },
- [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, LVL_HIGH, 1150000, 7 },
- [16] = { { 1188000, HFPLL, 1, 0, 0x2C }, LVL_HIGH, 1150000, 7 },
-};
-
-/* TODO: Update core voltages when data is available. */
-static struct acpu_level acpu_freq_tbl_8930_slow[] = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 975000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 975000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 1000000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 1000000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1025000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1075000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1075000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1100000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1100000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1125000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1125000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1175000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1175000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
- { 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_8930_nom[] = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 925000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 925000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 950000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 950000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 975000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 975000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1000000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1000000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1050000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1050000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1075000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1075000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1100000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1100000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1150000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1150000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1175000 },
- { 0, { 0 } }
-};
-
-static struct acpu_level acpu_freq_tbl_8930_fast[] = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 900000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 900000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 925000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 925000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 950000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 950000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1000000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1000000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1025000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1025000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1050000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1050000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1100000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1100000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1125000 },
- { 0, { 0 } }
-};
-/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
-#undef L2
-#define L2(x) (&l2_freq_tbl_8627[(x)])
-static struct l2_level l2_freq_tbl_8627[] = {
- [0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, LVL_NOM, 1050000, 0 },
- [1] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
- [2] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 1 },
- [3] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 1 },
- [4] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
- [5] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
- [6] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 2 },
- [7] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 3 },
- [8] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 3 },
- [9] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 3 },
- [10] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
- [11] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 4 },
- [12] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 4 },
-};
-
-/* TODO: Update core voltages when data is available. */
-static struct acpu_level acpu_freq_tbl_8627[] = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 925000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 925000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 937500 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 962500 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(9), 987500 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(9), 1000000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(9), 1025000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(9), 1062500 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(12), 1062500 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(12), 1087500 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(12), 1100000 },
- { 0, { 0 } }
-};
-
static struct acpu_level *acpu_freq_tbl_8960_v1[NUM_PVS] __initdata = {
[PVS_SLOW] = acpu_freq_tbl_8960_kraitv1_slow,
[PVS_NOM] = acpu_freq_tbl_8960_kraitv1_nom_fast,
@@ -838,12 +620,6 @@
[PVS_FASTER] = acpu_freq_tbl_8064_fast,
};
-static struct acpu_level *acpu_freq_tbl_8930_pvs[NUM_PVS] __initdata = {
- [PVS_SLOW] = acpu_freq_tbl_8930_slow,
- [PVS_NOM] = acpu_freq_tbl_8930_nom,
- [PVS_FAST] = acpu_freq_tbl_8930_fast,
-};
-
static struct acpu_level *max_acpu_level;
static unsigned long acpuclk_8960_get_rate(int cpu)
@@ -1608,18 +1384,6 @@
acpu_freq_tbl = acpu_freq_tbl_8064[pvs_id];
l2_freq_tbl = l2_freq_tbl_8064;
l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8064);
- } else if (cpu_is_msm8627()) {
- scalable = scalable_8627;
- acpu_freq_tbl = acpu_freq_tbl_8627;
- l2_freq_tbl = l2_freq_tbl_8627;
- l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8627);
- } else if (cpu_is_msm8930() || cpu_is_msm8930aa()) {
- enum pvs pvs_id = get_pvs();
-
- scalable = scalable_8930;
- acpu_freq_tbl = acpu_freq_tbl_8930_pvs[pvs_id];
- l2_freq_tbl = l2_freq_tbl_8930;
- l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8930);
} else {
BUG();
}
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index c37491d..40995bb 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -243,7 +243,7 @@
{
.src = MSM_BUS_MASTER_VFE,
.dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 140451840,
+ .ab = 274406400,
.ib = 561807360,
},
{
@@ -302,6 +302,27 @@
},
};
+static struct msm_bus_vectors cam_video_ls_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 348192000,
+ .ib = 617103360,
+ },
+ {
+ .src = MSM_BUS_MASTER_VPE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 206807040,
+ .ib = 488816640,
+ },
+ {
+ .src = MSM_BUS_MASTER_JPEG_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 540000000,
+ .ib = 1350000000,
+ },
+};
+
static struct msm_bus_paths cam_bus_client_config[] = {
{
ARRAY_SIZE(cam_init_vectors),
@@ -323,6 +344,10 @@
ARRAY_SIZE(cam_zsl_vectors),
cam_zsl_vectors,
},
+ {
+ ARRAY_SIZE(cam_video_ls_vectors),
+ cam_video_ls_vectors,
+ },
};
static struct msm_bus_scale_pdata cam_bus_client_pdata = {
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 177e1fd..330d7a8 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -1045,7 +1045,8 @@
}
}
-void __init apq8064_set_display_params(char *prim_panel, char *ext_panel)
+void __init apq8064_set_display_params(char *prim_panel, char *ext_panel,
+ unsigned char resolution)
{
/*
* For certain MPQ boards, HDMI should be set as primary display
@@ -1080,4 +1081,6 @@
pr_debug("msm_fb_pdata.ext_panel_name %s\n",
msm_fb_pdata.ext_panel_name);
}
+
+ msm_fb_pdata.ext_resolution = resolution;
}
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 08c3408..1f59909 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -657,6 +657,9 @@
static char prim_panel_name[PANEL_NAME_MAX_LEN];
static char ext_panel_name[PANEL_NAME_MAX_LEN];
+
+static int ext_resolution;
+
static int __init prim_display_setup(char *param)
{
if (strnlen(param, PANEL_NAME_MAX_LEN))
@@ -673,9 +676,18 @@
}
early_param("ext_display", ext_display_setup);
+static int __init hdmi_resulution_setup(char *param)
+{
+ int ret;
+ ret = kstrtoint(param, 10, &ext_resolution);
+ return ret;
+}
+early_param("ext_resolution", hdmi_resulution_setup);
+
static void __init apq8064_reserve(void)
{
- apq8064_set_display_params(prim_panel_name, ext_panel_name);
+ apq8064_set_display_params(prim_panel_name, ext_panel_name,
+ ext_resolution);
msm_reserve();
if (apq8064_fmem_pdata.size) {
#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index a241ab3..2258b8d 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -87,7 +87,8 @@
void apq8064_init_fb(void);
void apq8064_allocate_fb_region(void);
void apq8064_mdp_writeback(struct memtype_reserve *reserve_table);
-void __init apq8064_set_display_params(char *prim_panel, char *ext_panel);
+void __init apq8064_set_display_params(char *prim_panel, char *ext_panel,
+ unsigned char resolution);
void apq8064_init_gpu(void);
void apq8064_pm8xxx_gpio_mpp_init(void);
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index 6ee315c..d3e37cd 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -251,7 +251,7 @@
{
.src = MSM_BUS_MASTER_VFE,
.dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 140451840,
+ .ab = 274406400,
.ib = 561807360,
},
{
@@ -310,6 +310,27 @@
},
};
+static struct msm_bus_vectors cam_video_ls_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 348192000,
+ .ib = 617103360,
+ },
+ {
+ .src = MSM_BUS_MASTER_VPE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 206807040,
+ .ib = 488816640,
+ },
+ {
+ .src = MSM_BUS_MASTER_JPEG_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 540000000,
+ .ib = 1350000000,
+ },
+};
+
static struct msm_bus_paths cam_bus_client_config[] = {
{
ARRAY_SIZE(cam_init_vectors),
@@ -331,6 +352,10 @@
ARRAY_SIZE(cam_zsl_vectors),
cam_zsl_vectors,
},
+ {
+ ARRAY_SIZE(cam_video_ls_vectors),
+ cam_video_ls_vectors,
+ },
};
static struct msm_bus_scale_pdata cam_bus_client_pdata = {
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index f06a1b7..af91089 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -172,11 +172,13 @@
};
VREG_CONSUMERS(S5) = {
REGULATOR_SUPPLY("8038_s5", NULL),
- REGULATOR_SUPPLY("krait0", NULL),
+ REGULATOR_SUPPLY("krait0", "acpuclk-8627"),
+ REGULATOR_SUPPLY("krait0", "acpuclk-8930"),
};
VREG_CONSUMERS(S6) = {
REGULATOR_SUPPLY("8038_s6", NULL),
- REGULATOR_SUPPLY("krait1", NULL),
+ REGULATOR_SUPPLY("krait1", "acpuclk-8627"),
+ REGULATOR_SUPPLY("krait1", "acpuclk-8930"),
};
VREG_CONSUMERS(LVS1) = {
REGULATOR_SUPPLY("8038_lvs1", NULL),
@@ -511,10 +513,39 @@
int msm8930_pm8038_regulator_pdata_len __devinitdata =
ARRAY_SIZE(msm8930_pm8038_regulator_pdata);
+#define RPM_REG_MAP(_id, _sleep_also, _voter, _supply, _dev_name) \
+ { \
+ .vreg_id = RPM_VREG_ID_PM8038_##_id, \
+ .sleep_also = _sleep_also, \
+ .voter = _voter, \
+ .supply = _supply, \
+ .dev_name = _dev_name, \
+ }
+static struct rpm_regulator_consumer_mapping
+ msm_rpm_regulator_consumer_mapping[] __devinitdata = {
+ RPM_REG_MAP(L23, 0, 1, "krait0_hfpll", "acpuclk-8930"),
+ RPM_REG_MAP(L23, 0, 2, "krait1_hfpll", "acpuclk-8930"),
+ RPM_REG_MAP(L23, 0, 6, "l2_hfpll", "acpuclk-8930"),
+ RPM_REG_MAP(L24, 0, 1, "krait0_mem", "acpuclk-8930"),
+ RPM_REG_MAP(L24, 0, 2, "krait1_mem", "acpuclk-8930"),
+ RPM_REG_MAP(VDD_DIG_CORNER, 0, 1, "krait0_dig", "acpuclk-8930"),
+ RPM_REG_MAP(VDD_DIG_CORNER, 0, 2, "krait1_dig", "acpuclk-8930"),
+
+ RPM_REG_MAP(L23, 0, 1, "krait0_hfpll", "acpuclk-8627"),
+ RPM_REG_MAP(L23, 0, 2, "krait1_hfpll", "acpuclk-8627"),
+ RPM_REG_MAP(L23, 0, 6, "l2_hfpll", "acpuclk-8627"),
+ RPM_REG_MAP(L24, 0, 1, "krait0_mem", "acpuclk-8627"),
+ RPM_REG_MAP(L24, 0, 2, "krait1_mem", "acpuclk-8627"),
+ RPM_REG_MAP(VDD_DIG_CORNER, 0, 1, "krait0_dig", "acpuclk-8627"),
+ RPM_REG_MAP(VDD_DIG_CORNER, 0, 2, "krait1_dig", "acpuclk-8627"),
+};
+
struct rpm_regulator_platform_data msm8930_rpm_regulator_pdata __devinitdata = {
.init_data = msm8930_rpm_regulator_init_data,
.num_regulators = ARRAY_SIZE(msm8930_rpm_regulator_init_data),
.version = RPM_VREG_VERSION_8930,
.vreg_id_vdd_mem = RPM_VREG_ID_PM8038_L24,
.vreg_id_vdd_dig = RPM_VREG_ID_PM8038_VDD_DIG_CORNER,
+ .consumer_map = msm_rpm_regulator_consumer_mapping,
+ .consumer_map_len = ARRAY_SIZE(msm_rpm_regulator_consumer_mapping),
};
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 5a803e6..88c0924 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -2162,7 +2162,6 @@
};
static struct platform_device *common_devices[] __initdata = {
- &msm8960_device_acpuclk,
&msm8960_device_dmov,
&msm_device_smd,
&msm8960_device_uart_gsbi5,
@@ -2576,6 +2575,10 @@
msm_spm_l2_init(msm_spm_l2_data);
msm8930_init_buses();
platform_add_devices(msm8930_footswitch, msm8930_num_footswitch);
+ if (cpu_is_msm8627())
+ platform_device_register(&msm8627_device_acpuclk);
+ else if (cpu_is_msm8930() || cpu_is_msm8930aa())
+ platform_device_register(&msm8930_device_acpuclk);
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
msm8930_add_vidc_device();
/*
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index b6c03a4..a21c4c3 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -272,7 +272,7 @@
{
.src = MSM_BUS_MASTER_VFE,
.dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 154275840,
+ .ab = 274406400,
.ib = 617103360,
},
{
@@ -367,6 +367,40 @@
},
};
+static struct msm_bus_vectors cam_video_ls_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 348192000,
+ .ib = 617103360,
+ },
+ {
+ .src = MSM_BUS_MASTER_VPE,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 206807040,
+ .ib = 488816640,
+ },
+ {
+ .src = MSM_BUS_MASTER_JPEG_ENC,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 540000000,
+ .ib = 1350000000,
+ },
+ {
+ .src = MSM_BUS_MASTER_JPEG_ENC,
+ .dst = MSM_BUS_SLAVE_MM_IMEM,
+ .ab = 0,
+ .ib = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_VFE,
+ .dst = MSM_BUS_SLAVE_MM_IMEM,
+ .ab = 0,
+ .ib = 0,
+ },
+};
+
+
static struct msm_bus_paths cam_bus_client_config[] = {
{
ARRAY_SIZE(cam_init_vectors),
@@ -388,6 +422,10 @@
ARRAY_SIZE(cam_zsl_vectors),
cam_zsl_vectors,
},
+ {
+ ARRAY_SIZE(cam_video_ls_vectors),
+ cam_video_ls_vectors,
+ },
};
static struct msm_bus_scale_pdata cam_bus_client_pdata = {
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 7db4bda..ba4e098 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -48,7 +48,6 @@
#include <mach/msm_battery.h>
#include <linux/smsc911x.h>
#include <linux/atmel_maxtouch.h>
-#include <linux/fmem.h>
#include <linux/msm_adc.h>
#include <linux/ion.h>
#include "devices.h"
@@ -448,9 +447,6 @@
.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
.cached = 1,
.memory_type = MEMTYPE_EBI1,
- .request_region = request_fmem_c_region,
- .release_region = release_fmem_c_region,
- .reusable = 1,
};
static struct platform_device android_pmem_adsp_device = {
@@ -778,14 +774,6 @@
static void msm7x27a_cfg_uart2dm_serial(void) { }
#endif
-static struct fmem_platform_data fmem_pdata;
-
-static struct platform_device fmem_device = {
- .name = "fmem",
- .id = 1,
- .dev = { .platform_data = &fmem_pdata },
-};
-
static struct platform_device *rumi_sim_devices[] __initdata = {
&msm_device_dmov,
&msm_device_smd,
@@ -823,7 +811,6 @@
&android_pmem_device,
&android_pmem_adsp_device,
&android_pmem_audio_device,
- &fmem_device,
&msm_device_nand,
&msm_device_snd,
&msm_device_adspdec,
@@ -966,32 +953,10 @@
{
#ifdef CONFIG_ANDROID_PMEM
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
- unsigned int i;
- unsigned int reusable_count = 0;
-
android_pmem_adsp_pdata.size = pmem_adsp_size;
android_pmem_pdata.size = pmem_mdp_size;
android_pmem_audio_pdata.size = pmem_audio_size;
- fmem_pdata.size = 0;
- fmem_pdata.align = PAGE_SIZE;
-
- /* Find pmem devices that should use FMEM (reusable) memory.
- */
- for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i) {
- struct android_pmem_platform_data *pdata = pmem_pdata_array[i];
-
- if (!reusable_count && pdata->reusable)
- fmem_pdata.size += pdata->size;
-
- reusable_count += (pdata->reusable) ? 1 : 0;
-
- if (pdata->reusable && reusable_count > 1) {
- pr_err("%s: Too many PMEM devices specified as reusable. PMEM device %s was not configured as reusable.\n",
- __func__, pdata->name);
- pdata->reusable = 0;
- }
- }
#endif
#endif
}
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index bd73b70..a694557 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -31,7 +31,6 @@
#include <linux/memblock.h>
#include <linux/input/ft5x06_ts.h>
#include <linux/msm_adc.h>
-#include <linux/fmem.h>
#include <linux/regulator/msm-gpio-regulator.h>
#include <linux/ion.h>
#include <asm/mach/mmc.h>
@@ -394,9 +393,6 @@
.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
.cached = 1,
.memory_type = MEMTYPE_EBI1,
- .request_region = request_fmem_c_region,
- .release_region = release_fmem_c_region,
- .reusable = 1,
};
static struct platform_device android_pmem_adsp_device = {
@@ -639,14 +635,6 @@
},
};
-static struct fmem_platform_data fmem_pdata;
-
-static struct platform_device fmem_device = {
- .name = "fmem",
- .id = 1,
- .dev = { .platform_data = &fmem_pdata },
-};
-
#define GPIO_VREG_INIT(_id, _reg_name, _gpio_label, _gpio, _active_low) \
[GPIO_VREG_ID_##_id] = { \
.init_data = { \
@@ -717,7 +705,6 @@
&asoc_msm_dai0,
&asoc_msm_dai1,
&msm_adc_device,
- &fmem_device,
#ifdef CONFIG_ION_MSM
&ion_dev,
#endif
@@ -858,32 +845,9 @@
{
#ifdef CONFIG_ANDROID_PMEM
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
- unsigned int i;
- unsigned int reusable_count = 0;
-
android_pmem_adsp_pdata.size = pmem_adsp_size;
android_pmem_pdata.size = pmem_mdp_size;
android_pmem_audio_pdata.size = pmem_audio_size;
-
- fmem_pdata.size = 0;
- fmem_pdata.align = PAGE_SIZE;
-
- /* Find pmem devices that should use FMEM (reusable) memory.
- */
- for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i) {
- struct android_pmem_platform_data *pdata = pmem_pdata_array[i];
-
- if (!reusable_count && pdata->reusable)
- fmem_pdata.size += pdata->size;
-
- reusable_count += (pdata->reusable) ? 1 : 0;
-
- if (pdata->reusable && reusable_count > 1) {
- pr_err("%s: Too many PMEM devices specified as reusable. PMEM device %s was not configured as reusable.\n",
- __func__, pdata->name);
- pdata->reusable = 0;
- }
- }
#endif
#endif
}
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index d31e629..e87dd14 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -194,6 +194,7 @@
#define DSI2_ESC_CC_REG REG_MM(0x013C)
#define DSI_PIXEL_CC_REG REG_MM(0x0130)
#define DSI2_PIXEL_CC_REG REG_MM(0x0094)
+#define DSI2_PIXEL_CC2_REG REG_MM(0x0264)
#define DBG_BUS_VEC_A_REG REG_MM(0x01C8)
#define DBG_BUS_VEC_B_REG REG_MM(0x01CC)
#define DBG_BUS_VEC_C_REG REG_MM(0x01D0)
@@ -785,7 +786,7 @@
};
/* gfx3d_axi_clk is set as a dependency of gmem_axi_clk at runtime */
-static struct branch_clk gfx3d_axi_clk_8064 = {
+static struct branch_clk gfx3d_axi_clk = {
.b = {
.ctl_reg = MAXI_EN5_REG,
.en_mask = BIT(25),
@@ -799,7 +800,7 @@
.c = {
.dbg_name = "gfx3d_axi_clk",
.ops = &clk_ops_branch,
- CLK_INIT(gfx3d_axi_clk_8064.c),
+ CLK_INIT(gfx3d_axi_clk.c),
},
};
@@ -2688,6 +2689,7 @@
.ops = &clk_ops_rcg,
VDD_DIG_FMAX_MAP2(LOW, 86000000, NOMINAL, 178000000),
CLK_INIT(csi0_src_clk.c),
+ .warned = true,
},
};
@@ -2705,6 +2707,7 @@
.dbg_name = "csi0_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi0_clk.c),
+ .warned = true,
},
};
@@ -2744,6 +2747,7 @@
.ops = &clk_ops_rcg,
VDD_DIG_FMAX_MAP2(LOW, 86000000, NOMINAL, 178000000),
CLK_INIT(csi1_src_clk.c),
+ .warned = true,
},
};
@@ -2761,6 +2765,7 @@
.dbg_name = "csi1_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi1_clk.c),
+ .warned = true,
},
};
@@ -2800,6 +2805,7 @@
.ops = &clk_ops_rcg,
VDD_DIG_FMAX_MAP2(LOW, 86000000, NOMINAL, 178000000),
CLK_INIT(csi2_src_clk.c),
+ .warned = true,
},
};
@@ -2817,6 +2823,7 @@
.dbg_name = "csi2_clk",
.ops = &clk_ops_branch,
CLK_INIT(csi2_clk.c),
+ .warned = true,
},
};
@@ -3406,6 +3413,27 @@
.ctl_val = CC_BANKED(9, 6, n), \
}
+static struct clk_freq_tbl clk_tbl_gfx3d_8960ab[] = {
+ F_GFX3D( 0, gnd, 0, 0),
+ F_GFX3D( 27000000, pxo, 0, 0),
+ F_GFX3D( 48000000, pll8, 1, 8),
+ F_GFX3D( 54857000, pll8, 1, 7),
+ F_GFX3D( 64000000, pll8, 1, 6),
+ F_GFX3D( 76800000, pll8, 1, 5),
+ F_GFX3D( 96000000, pll8, 1, 4),
+ F_GFX3D(128000000, pll8, 1, 3),
+ F_GFX3D(145455000, pll2, 2, 11),
+ F_GFX3D(160000000, pll2, 1, 5),
+ F_GFX3D(177778000, pll2, 2, 9),
+ F_GFX3D(200000000, pll2, 1, 4),
+ F_GFX3D(228571000, pll2, 2, 7),
+ F_GFX3D(266667000, pll2, 1, 3),
+ F_GFX3D(320000000, pll2, 2, 5),
+ F_GFX3D(325000000, pll3, 1, 2),
+ F_GFX3D(400000000, pll2, 1, 2),
+ F_END
+};
+
static struct clk_freq_tbl clk_tbl_gfx3d_8960[] = {
F_GFX3D( 0, gnd, 0, 0),
F_GFX3D( 27000000, pxo, 0, 0),
@@ -3713,6 +3741,27 @@
.ns_val = NS_MND_BANKED8(22, 14, n, m, 3, 0, s##_to_mm_mux), \
.ctl_val = CC_BANKED(9, 6, n), \
}
+static struct clk_freq_tbl clk_tbl_mdp_8960ab[] = {
+ F_MDP( 0, gnd, 0, 0),
+ F_MDP( 9600000, pll8, 1, 40),
+ F_MDP( 13710000, pll8, 1, 28),
+ F_MDP( 27000000, pxo, 0, 0),
+ F_MDP( 29540000, pll8, 1, 13),
+ F_MDP( 34910000, pll8, 1, 11),
+ F_MDP( 38400000, pll8, 1, 10),
+ F_MDP( 59080000, pll8, 2, 13),
+ F_MDP( 76800000, pll8, 1, 5),
+ F_MDP( 85330000, pll8, 2, 9),
+ F_MDP( 96000000, pll8, 1, 4),
+ F_MDP(128000000, pll8, 1, 3),
+ F_MDP(160000000, pll2, 1, 5),
+ F_MDP(177780000, pll2, 2, 9),
+ F_MDP(200000000, pll2, 1, 4),
+ F_MDP(228571000, pll2, 2, 7),
+ F_MDP(266667000, pll2, 1, 3),
+ F_END
+};
+
static struct clk_freq_tbl clk_tbl_mdp[] = {
F_MDP( 0, gnd, 0, 0),
F_MDP( 9600000, pll8, 1, 40),
@@ -4336,7 +4385,23 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS(31, 24, n, m, 5, 4, 3, d, 2, 0, s##_to_lpa_mux), \
}
-static struct clk_freq_tbl clk_tbl_aif_osr[] = {
+static struct clk_freq_tbl clk_tbl_aif_osr_492[] = {
+ F_AIF_OSR( 0, gnd, 1, 0, 0),
+ F_AIF_OSR( 512000, pll4, 4, 1, 240),
+ F_AIF_OSR( 768000, pll4, 4, 1, 160),
+ F_AIF_OSR( 1024000, pll4, 4, 1, 120),
+ F_AIF_OSR( 1536000, pll4, 4, 1, 80),
+ F_AIF_OSR( 2048000, pll4, 4, 1, 60),
+ F_AIF_OSR( 3072000, pll4, 4, 1, 40),
+ F_AIF_OSR( 4096000, pll4, 4, 1, 30),
+ F_AIF_OSR( 6144000, pll4, 4, 1, 20),
+ F_AIF_OSR( 8192000, pll4, 4, 1, 15),
+ F_AIF_OSR(12288000, pll4, 4, 1, 10),
+ F_AIF_OSR(24576000, pll4, 4, 1, 5),
+ F_END
+};
+
+static struct clk_freq_tbl clk_tbl_aif_osr_393[] = {
F_AIF_OSR( 0, gnd, 1, 0, 0),
F_AIF_OSR( 512000, pll4, 4, 1, 192),
F_AIF_OSR( 768000, pll4, 4, 1, 128),
@@ -4369,7 +4434,7 @@
.ns_mask = (BM(31, 24) | BM(6, 0)), \
.mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
- .freq_tbl = clk_tbl_aif_osr, \
+ .freq_tbl = clk_tbl_aif_osr_393, \
.current_freq = &rcg_dummy_freq, \
.c = { \
.dbg_name = #i "_clk", \
@@ -4395,7 +4460,7 @@
.ns_mask = (BM(31, 24) | BM(6, 0)), \
.mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
- .freq_tbl = clk_tbl_aif_osr, \
+ .freq_tbl = clk_tbl_aif_osr_393, \
.current_freq = &rcg_dummy_freq, \
.c = { \
.dbg_name = #i "_clk", \
@@ -4476,7 +4541,23 @@
.md_val = MD16(m, n), \
.ns_val = NS(31, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_lpa_mux), \
}
-static struct clk_freq_tbl clk_tbl_pcm[] = {
+static struct clk_freq_tbl clk_tbl_pcm_492[] = {
+ { .ns_val = BIT(10) /* external input */ },
+ F_PCM( 512000, pll4, 4, 1, 240),
+ F_PCM( 768000, pll4, 4, 1, 160),
+ F_PCM( 1024000, pll4, 4, 1, 120),
+ F_PCM( 1536000, pll4, 4, 1, 80),
+ F_PCM( 2048000, pll4, 4, 1, 60),
+ F_PCM( 3072000, pll4, 4, 1, 40),
+ F_PCM( 4096000, pll4, 4, 1, 30),
+ F_PCM( 6144000, pll4, 4, 1, 20),
+ F_PCM( 8192000, pll4, 4, 1, 15),
+ F_PCM(12288000, pll4, 4, 1, 10),
+ F_PCM(24576000, pll4, 4, 1, 5),
+ F_END
+};
+
+static struct clk_freq_tbl clk_tbl_pcm_393[] = {
{ .ns_val = BIT(10) /* external input */ },
F_PCM( 512000, pll4, 4, 1, 192),
F_PCM( 768000, pll4, 4, 1, 128),
@@ -4508,7 +4589,7 @@
.ns_mask = BM(31, 16) | BIT(10) | BM(6, 0),
.mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
- .freq_tbl = clk_tbl_pcm,
+ .freq_tbl = clk_tbl_pcm_393,
.current_freq = &rcg_dummy_freq,
.c = {
.dbg_name = "pcm_clk",
@@ -4535,7 +4616,7 @@
.ns_mask = (BM(31, 24) | BM(6, 0)),
.mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
- .freq_tbl = clk_tbl_aif_osr,
+ .freq_tbl = clk_tbl_aif_osr_393,
.current_freq = &rcg_dummy_freq,
.c = {
.dbg_name = "audio_slimbus_clk",
@@ -4821,7 +4902,7 @@
{ TEST_MM_HS(0x35), &vcap_axi_clk.c },
{ TEST_MM_HS(0x36), &rgb_tv_clk.c },
{ TEST_MM_HS(0x37), &npl_tv_clk.c },
- { TEST_MM_HS(0x38), &gfx3d_axi_clk_8064.c },
+ { TEST_MM_HS(0x38), &gfx3d_axi_clk.c },
{ TEST_LPA(0x0F), &mi2s_bit_clk.c },
{ TEST_LPA(0x10), &codec_i2s_mic_bit_clk.c },
@@ -5199,7 +5280,7 @@
CLK_LOOKUP("core_clk", gfx3d_clk.c, "kgsl-3d0.0"),
CLK_LOOKUP("core_clk", gfx3d_clk.c, "footswitch-8x60.2"),
CLK_LOOKUP("bus_clk",
- gfx3d_axi_clk_8064.c, "footswitch-8x60.2"),
+ gfx3d_axi_clk.c, "footswitch-8x60.2"),
CLK_LOOKUP("iface_clk", vcap_p_clk.c, ""),
CLK_LOOKUP("iface_clk", vcap_p_clk.c, "msm_vcap.0"),
CLK_LOOKUP("iface_clk", vcap_p_clk.c, "footswitch-8x60.10"),
@@ -5305,7 +5386,7 @@
CLK_LOOKUP("core_clk", vfe_axi_clk.c, ""),
CLK_LOOKUP("core_clk", vcodec_axi_a_clk.c, ""),
CLK_LOOKUP("core_clk", vcodec_axi_b_clk.c, ""),
- CLK_LOOKUP("core_clk", gfx3d_axi_clk_8064.c, ""),
+ CLK_LOOKUP("core_clk", gfx3d_axi_clk.c, ""),
CLK_LOOKUP("dfab_dsps_clk", dfab_dsps_clk.c, NULL),
CLK_LOOKUP("core_clk", dfab_usb_hs_clk.c, "msm_otg"),
@@ -5335,8 +5416,9 @@
CLK_LOOKUP("core_clk", vfe_axi_clk.c, "msm_iommu.6"),
CLK_LOOKUP("core_clk", vcodec_axi_a_clk.c, "msm_iommu.7"),
CLK_LOOKUP("core_clk", vcodec_axi_b_clk.c, "msm_iommu.8"),
- CLK_LOOKUP("core_clk", gfx3d_axi_clk_8064.c, "msm_iommu.9"),
- CLK_LOOKUP("core_clk", gfx3d_axi_clk_8064.c, "msm_iommu.10"),
+ CLK_LOOKUP("core_clk", gfx3d_axi_clk.c, "msm_iommu.9"),
+ CLK_LOOKUP("core_clk", gfx3d_axi_clk.c, "msm_iommu.10"),
+
CLK_LOOKUP("core_clk", vcap_axi_clk.c, "msm_iommu.11"),
CLK_LOOKUP("mdp_iommu_clk", mdp_axi_clk.c, "msm_vidc.0"),
@@ -5358,7 +5440,7 @@
CLK_LOOKUP("krait3_mclk", krait3_m_clk, ""),
};
-static struct clk_lookup msm_clocks_8960[] = {
+static struct clk_lookup msm_clocks_8960_common[] __initdata = {
CLK_LOOKUP("xo", cxo_a_clk.c, ""),
CLK_LOOKUP("xo", pxo_a_clk.c, ""),
CLK_LOOKUP("cxo", cxo_clk.c, "wcnss_wlan.0"),
@@ -5537,10 +5619,6 @@
CLK_LOOKUP("byte_clk", dsi2_byte_clk.c, "mipi_dsi.2"),
CLK_LOOKUP("esc_clk", dsi1_esc_clk.c, "mipi_dsi.1"),
CLK_LOOKUP("esc_clk", dsi2_esc_clk.c, "mipi_dsi.2"),
- CLK_LOOKUP("core_clk", gfx2d0_clk.c, "kgsl-2d0.0"),
- CLK_LOOKUP("core_clk", gfx2d0_clk.c, "footswitch-8x60.0"),
- CLK_LOOKUP("core_clk", gfx2d1_clk.c, "kgsl-2d1.1"),
- CLK_LOOKUP("core_clk", gfx2d1_clk.c, "footswitch-8x60.1"),
CLK_LOOKUP("core_clk", gfx3d_clk.c, "kgsl-3d0.0"),
CLK_LOOKUP("core_clk", gfx3d_clk.c, "footswitch-8x60.2"),
CLK_LOOKUP("bus_clk", ijpeg_axi_clk.c, "footswitch-8x60.3"),
@@ -5560,8 +5638,6 @@
CLK_LOOKUP("src_clk", tv_src_clk.c, "dtv.0"),
CLK_LOOKUP("src_clk", tv_src_clk.c, "tvenc.0"),
CLK_LOOKUP("tv_src_clk", tv_src_clk.c, "footswitch-8x60.4"),
- CLK_LOOKUP("enc_clk", tv_enc_clk.c, "tvenc.0"),
- CLK_LOOKUP("dac_clk", tv_dac_clk.c, "tvenc.0"),
CLK_LOOKUP("core_clk", vcodec_clk.c, "msm_vidc.0"),
CLK_LOOKUP("core_clk", vcodec_clk.c, "footswitch-8x60.7"),
CLK_LOOKUP("mdp_clk", mdp_tv_clk.c, "dtv.0"),
@@ -5590,10 +5666,6 @@
CLK_LOOKUP("slave_iface_clk", dsi1_s_p_clk.c, "mipi_dsi.1"),
CLK_LOOKUP("master_iface_clk", dsi2_m_p_clk.c, "mipi_dsi.2"),
CLK_LOOKUP("slave_iface_clk", dsi2_s_p_clk.c, "mipi_dsi.2"),
- CLK_LOOKUP("iface_clk", gfx2d0_p_clk.c, "kgsl-2d0.0"),
- CLK_LOOKUP("iface_clk", gfx2d0_p_clk.c, "footswitch-8x60.0"),
- CLK_LOOKUP("iface_clk", gfx2d1_p_clk.c, "kgsl-2d1.1"),
- CLK_LOOKUP("iface_clk", gfx2d1_p_clk.c, "footswitch-8x60.1"),
CLK_LOOKUP("iface_clk", gfx3d_p_clk.c, "kgsl-3d0.0"),
CLK_LOOKUP("iface_clk", gfx3d_p_clk.c, "footswitch-8x60.2"),
CLK_LOOKUP("master_iface_clk", hdmi_m_p_clk.c, "hdmi_msm.1"),
@@ -5607,7 +5679,6 @@
CLK_LOOKUP("iface_clk", smmu_p_clk.c, "msm_iommu"),
CLK_LOOKUP("iface_clk", rot_p_clk.c, "msm_rotator.0"),
CLK_LOOKUP("iface_clk", rot_p_clk.c, "footswitch-8x60.6"),
- CLK_LOOKUP("iface_clk", tv_enc_p_clk.c, "tvenc.0"),
CLK_LOOKUP("iface_clk", vcodec_p_clk.c, "msm_vidc.0"),
CLK_LOOKUP("iface_clk", vcodec_p_clk.c, "footswitch-8x60.7"),
CLK_LOOKUP("vfe_pclk", vfe_p_clk.c, "msm_vfe.0"),
@@ -5648,8 +5719,6 @@
CLK_LOOKUP("core_clk", vcodec_axi_a_clk.c, "msm_iommu.7"),
CLK_LOOKUP("core_clk", vcodec_axi_b_clk.c, "msm_iommu.8"),
CLK_LOOKUP("core_clk", gfx3d_clk.c, "msm_iommu.9"),
- CLK_LOOKUP("core_clk", gfx2d0_clk.c, "msm_iommu.10"),
- CLK_LOOKUP("core_clk", gfx2d1_clk.c, "msm_iommu.11"),
CLK_LOOKUP("mdp_iommu_clk", mdp_axi_clk.c, "msm_vidc.0"),
CLK_LOOKUP("rot_iommu_clk", rot_axi_clk.c, "msm_vidc.0"),
@@ -5683,6 +5752,32 @@
CLK_LOOKUP("q6_func_clk", q6_func_clk, ""),
};
+static struct clk_lookup msm_clocks_8960_only[] __initdata = {
+ CLK_LOOKUP("enc_clk", tv_enc_clk.c, "tvenc.0"),
+ CLK_LOOKUP("dac_clk", tv_dac_clk.c, "tvenc.0"),
+ CLK_LOOKUP("iface_clk", tv_enc_p_clk.c, "tvenc.0"),
+
+ CLK_LOOKUP("core_clk", gfx2d0_clk.c, "kgsl-2d0.0"),
+ CLK_LOOKUP("core_clk", gfx2d0_clk.c, "footswitch-8x60.0"),
+ CLK_LOOKUP("core_clk", gfx2d1_clk.c, "kgsl-2d1.1"),
+ CLK_LOOKUP("core_clk", gfx2d1_clk.c, "footswitch-8x60.1"),
+ CLK_LOOKUP("iface_clk", gfx2d0_p_clk.c, "kgsl-2d0.0"),
+ CLK_LOOKUP("iface_clk", gfx2d0_p_clk.c, "footswitch-8x60.0"),
+ CLK_LOOKUP("iface_clk", gfx2d1_p_clk.c, "kgsl-2d1.1"),
+ CLK_LOOKUP("iface_clk", gfx2d1_p_clk.c, "footswitch-8x60.1"),
+ CLK_LOOKUP("core_clk", gfx2d0_clk.c, "msm_iommu.10"),
+ CLK_LOOKUP("core_clk", gfx2d1_clk.c, "msm_iommu.11"),
+};
+
+static struct clk_lookup msm_clocks_8960ab_only[] __initdata = {
+ CLK_LOOKUP("bus_clk", gfx3d_axi_clk.c, "footswitch-8x60.2"),
+ CLK_LOOKUP("div_clk", tv_src_div_clk.c, ""),
+};
+
+static struct clk_lookup msm_clocks_8960[ARRAY_SIZE(msm_clocks_8960_common)
+ + ARRAY_SIZE(msm_clocks_8960_only)
+ + ARRAY_SIZE(msm_clocks_8960ab_only)];
+
static struct clk_lookup msm_clocks_8930[] = {
CLK_LOOKUP("xo", cxo_clk.c, "msm_xo"),
CLK_LOOKUP("cxo", cxo_clk.c, "wcnss_wlan.0"),
@@ -6002,7 +6097,7 @@
.mode_reg = LCC_PLL0_MODE_REG,
};
-static struct pll_config pll4_config __initdata = {
+static struct pll_config pll4_config_393 __initdata = {
.l = 0xE,
.m = 0x27A,
.n = 0x465,
@@ -6080,12 +6175,12 @@
*/
/*
* Initialize MM AHB registers: Enable the FPB clock and disable HW
- * gating on 8627 for all clocks. Also set VFE_AHB's
+ * gating on 8627 and 8960 for all clocks. Also set VFE_AHB's
* FORCE_CORE_ON bit to prevent its memory from being collapsed when
* the clock is halted. The sleep and wake-up delays are set to safe
* values.
*/
- if (cpu_is_msm8627()) {
+ if (cpu_is_msm8627() || cpu_is_msm8960ab()) {
rmwreg(0x00000003, AHB_EN_REG, 0x6C000103);
writel_relaxed(0x000007F9, AHB_EN2_REG);
} else {
@@ -6103,7 +6198,7 @@
/* Initialize MM AXI registers: Enable HW gating for all clocks that
* support it. Also set FORCE_CORE_ON bits, and any sleep and wake-up
* delays to safe values. */
- if ((cpu_is_msm8960() &&
+ if (cpu_is_msm8960ab() || (cpu_is_msm8960() &&
SOCINFO_VERSION_MAJOR(socinfo_get_version()) < 3) ||
cpu_is_msm8627()) {
rmwreg(0x000007F9, MAXI_EN_REG, 0x0803FFFF);
@@ -6120,8 +6215,13 @@
rmwreg(0x019FECFF, MAXI_EN5_REG, 0x01FFEFFF);
if (cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627())
rmwreg(0x000004FF, MAXI_EN5_REG, 0x00000FFF);
+ if (cpu_is_msm8960ab())
+ rmwreg(0x009FE000, MAXI_EN5_REG, 0x01FFE000);
+
if (cpu_is_msm8627())
rmwreg(0x000003C7, SAXI_EN_REG, 0x00003FFF);
+ else if (cpu_is_msm8960ab())
+ rmwreg(0x000001C6, SAXI_EN_REG, 0x00001DF6);
else
rmwreg(0x00003C38, SAXI_EN_REG, 0x00003FFF);
@@ -6149,14 +6249,19 @@
rmwreg(0x80FF0000, VFE_CC_REG, 0xE0FF4010);
rmwreg(0x800000FF, VFE_CC2_REG, 0xE00000FF);
rmwreg(0x80FF0000, VPE_CC_REG, 0xE0FF0010);
- if (cpu_is_msm8960() || cpu_is_apq8064()) {
+ if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_apq8064()) {
rmwreg(0x80FF0000, DSI2_BYTE_CC_REG, 0xE0FF0010);
rmwreg(0x80FF0000, DSI2_PIXEL_CC_REG, 0xE0FF0010);
rmwreg(0x80FF0000, JPEGD_CC_REG, 0xE0FF0010);
}
+ if (cpu_is_msm8960ab())
+ rmwreg(0x00000001, DSI2_PIXEL_CC2_REG, 0x00000001);
+
if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8930aa() ||
cpu_is_msm8627())
- rmwreg(0x80FF0000, TV_CC_REG, 0xE1FFC010);
+ rmwreg(0x80FF0000, TV_CC_REG, 0xE1FFC010);
+ if (cpu_is_msm8960ab())
+ rmwreg(0x00000000, TV_CC_REG, 0x00004010);
if (cpu_is_msm8960()) {
rmwreg(0x80FF0000, GFX2D0_CC_REG, 0xE0FF0010);
@@ -6190,12 +6295,12 @@
writel_relaxed(BIT(15), PDM_CLK_NS_REG);
/* Source SLIMBus xo src from slimbus reference clock */
- if (cpu_is_msm8960())
+ if (cpu_is_msm8960ab() || cpu_is_msm8960())
writel_relaxed(0x3, SLIMBUS_XO_SRC_CLK_CTL_REG);
/* Source the dsi_byte_clks from the DSI PHY PLLs */
rmwreg(0x1, DSI1_BYTE_NS_REG, 0x7);
- if (cpu_is_msm8960() || cpu_is_apq8064())
+ if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_apq8064())
rmwreg(0x2, DSI2_BYTE_NS_REG, 0x7);
/* Source the dsi1_esc_clk from the DSI1 PHY PLLs */
@@ -6233,7 +6338,7 @@
is_pll_enabled = readl_relaxed(LCC_PLL0_STATUS_REG) & BIT(16);
if (!is_pll_enabled)
/* Ref clk = 27MHz and program pll4 to 393.2160MHz */
- configure_pll(&pll4_config, &pll4_regs, 1);
+ configure_pll(&pll4_config_393, &pll4_regs, 1);
/* Enable PLL4 source on the LPASS Primary PLL Mux */
writel_relaxed(0x1, LCC_PRI_PLL_CLK_CTL_REG);
@@ -6257,8 +6362,12 @@
}
}
+struct clock_init_data msm8960_clock_init_data __initdata;
static void __init msm8960_clock_pre_init(void)
{
+ /* Initialize clock registers. */
+ reg_init();
+
if (cpu_is_apq8064()) {
vdd_sr2_hdmi_pll.set_vdd = set_vdd_sr2_hdmi_pll_8064;
} else if (cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627()) {
@@ -6266,6 +6375,41 @@
vdd_sr2_hdmi_pll.set_vdd = set_vdd_sr2_hdmi_pll_8930;
}
+ /* Detect PLL4 programmed for alternate 491.52MHz clock plan. */
+ if (readl_relaxed(LCC_PLL0_L_VAL_REG) == 0x12) {
+ pll4_clk.c.rate = 491520000;
+ audio_slimbus_clk.freq_tbl = clk_tbl_aif_osr_492;
+ mi2s_osr_clk.freq_tbl = clk_tbl_aif_osr_492;
+ codec_i2s_mic_osr_clk.freq_tbl = clk_tbl_aif_osr_492;
+ spare_i2s_mic_osr_clk.freq_tbl = clk_tbl_aif_osr_492;
+ codec_i2s_spkr_osr_clk.freq_tbl = clk_tbl_aif_osr_492;
+ spare_i2s_spkr_osr_clk.freq_tbl = clk_tbl_aif_osr_492;
+ pcm_clk.freq_tbl = clk_tbl_pcm_492;
+ }
+
+ if (cpu_is_msm8960() || cpu_is_msm8960ab())
+ memcpy(msm_clocks_8960, msm_clocks_8960_common,
+ sizeof(msm_clocks_8960_common));
+ if (cpu_is_msm8960ab()) {
+ pll3_clk.c.rate = 650000000;
+ gfx3d_clk.freq_tbl = clk_tbl_gfx3d_8960ab;
+ gfx3d_clk.c.fmax[VDD_DIG_LOW] = 192000000;
+ gfx3d_clk.c.fmax[VDD_DIG_NOMINAL] = 325000000;
+ gfx3d_clk.c.fmax[VDD_DIG_HIGH] = 400000000;
+ mdp_clk.freq_tbl = clk_tbl_mdp_8960ab;
+ mdp_clk.c.fmax[VDD_DIG_LOW] = 128000000;
+ mdp_clk.c.fmax[VDD_DIG_NOMINAL] = 266667000;
+
+ memcpy(msm_clocks_8960 + ARRAY_SIZE(msm_clocks_8960_common),
+ msm_clocks_8960ab_only, sizeof(msm_clocks_8960ab_only));
+ msm8960_clock_init_data.size -=
+ ARRAY_SIZE(msm_clocks_8960_only);
+ } else if (cpu_is_msm8960()) {
+ memcpy(msm_clocks_8960 + ARRAY_SIZE(msm_clocks_8960_common),
+ msm_clocks_8960_only, sizeof(msm_clocks_8960_only));
+ msm8960_clock_init_data.size -=
+ ARRAY_SIZE(msm_clocks_8960ab_only);
+ }
/*
* Change the freq tables for and voltage requirements for
* clocks which differ between 8960 and 8064.
@@ -6284,7 +6428,7 @@
memcpy(vfe_clk.c.fmax, fmax_vfe_8064,
sizeof(vfe_clk.c.fmax));
- gmem_axi_clk.c.depends = &gfx3d_axi_clk_8064.c;
+ gmem_axi_clk.c.depends = &gfx3d_axi_clk.c;
}
/*
@@ -6306,9 +6450,6 @@
vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
clk_ops_local_pll.enable = sr_pll_clk_enable;
-
- /* Initialize clock registers. */
- reg_init();
}
static void __init msm8960_clock_post_init(void)
@@ -6336,8 +6477,8 @@
clk_set_rate(&usb_hs4_xcvr_clk.c, 60000000);
}
clk_set_rate(&usb_fs1_src_clk.c, 60000000);
- if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8930aa() ||
- cpu_is_msm8627())
+ if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_msm8930() ||
+ cpu_is_msm8930aa() || cpu_is_msm8627())
clk_set_rate(&usb_fs2_src_clk.c, 60000000);
clk_set_rate(&usb_hsic_xcvr_fs_clk.c, 60000000);
clk_set_rate(&usb_hsic_hsic_src_clk.c, 480000000);
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index a36e7d7..1f954c8 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -355,6 +355,16 @@
.id = MSM_BUS_FAB_CPSS_FPB,
};
+struct platform_device msm8627_device_acpuclk = {
+ .name = "acpuclk-8627",
+ .id = -1,
+};
+
+struct platform_device msm8930_device_acpuclk = {
+ .name = "acpuclk-8930",
+ .id = -1,
+};
+
static struct fs_driver_data gfx3d_fs_data = {
.clks = (struct fs_clk_data[]){
{ .name = "core_clk", .reset_rate = 27000000 },
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 045dfb9..2207e3c 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -420,7 +420,9 @@
extern struct platform_device msm7x27aa_device_acpuclk;
extern struct platform_device msm7x30_device_acpuclk;
extern struct platform_device msm8625_device_acpuclk;
+extern struct platform_device msm8627_device_acpuclk;
extern struct platform_device msm8x50_device_acpuclk;
extern struct platform_device msm8x60_device_acpuclk;
+extern struct platform_device msm8930_device_acpuclk;
extern struct platform_device msm8960_device_acpuclk;
extern struct platform_device msm9615_device_acpuclk;
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 86720d8..f21d296 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -475,6 +475,7 @@
struct msm_fb_platform_data {
int (*detect_client)(const char *name);
int mddi_prescan;
+ unsigned char ext_resolution;
int (*allow_set_offset)(void);
char prim_panel_name[PANEL_NAME_MAX_LEN];
char ext_panel_name[PANEL_NAME_MAX_LEN];
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 08e2d44..43d707e 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -567,6 +567,7 @@
S_STEREO_VIDEO,
S_STEREO_CAPTURE,
S_DEFAULT,
+ S_LIVESHOT,
S_EXIT
};
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 23d11c3..c0a35f9 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -103,6 +103,7 @@
struct hci_fm_ch_det_threshold ch_det_threshold;
struct hci_fm_data_rd_rsp default_data;
struct hci_fm_spur_data spur_data;
+ unsigned char is_station_valid;
};
static struct video_device *priv_videodev;
@@ -2645,6 +2646,9 @@
ctrl->value = radio->ch_det_threshold.sinr_samples;
break;
+ case V4L2_CID_PRIVATE_VALID_CHANNEL:
+ ctrl->value = radio->is_station_valid;
+ break;
default:
retval = -EINVAL;
}
@@ -2811,6 +2815,8 @@
struct hci_fm_tx_rt tx_rt = {0};
struct hci_fm_def_data_rd_req rd_txgain;
struct hci_fm_def_data_wr_req wr_txgain;
+ char sinr_th, sinr;
+ __u8 intf_det_low_th, intf_det_high_th, intf_det_out;
switch (ctrl->id) {
case V4L2_CID_PRIVATE_IRIS_TX_TONE:
@@ -3281,6 +3287,40 @@
case V4L2_CID_PRIVATE_UPDATE_SPUR_TABLE:
update_spur_table(radio);
break;
+ case V4L2_CID_PRIVATE_VALID_CHANNEL:
+ retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("%s: Failed to determine channel's validity\n",
+ __func__);
+ return retval;
+ } else {
+ sinr_th = radio->ch_det_threshold.sinr;
+ intf_det_low_th = radio->ch_det_threshold.low_th;
+ intf_det_high_th = radio->ch_det_threshold.high_th;
+ }
+
+ retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("%s: Failed to determine channel's validity\n",
+ __func__);
+ return retval;
+ } else
+ sinr = radio->fm_st_rsp.station_rsp.sinr;
+
+ retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("%s: Failed to determine channel's validity\n",
+ __func__);
+ return retval;
+ } else
+ intf_det_out = radio->st_dbg_param.in_det_out;
+
+ if ((sinr >= sinr_th) && (intf_det_out >= intf_det_low_th) &&
+ (intf_det_out <= intf_det_high_th))
+ radio->is_station_valid = VALID_CHANNEL;
+ else
+ radio->is_station_valid = INVALID_CHANNEL;
+ break;
default:
retval = -EINVAL;
}
diff --git a/drivers/media/video/msm/csi/msm_csi2_register.c b/drivers/media/video/msm/csi/msm_csi2_register.c
index 7b85ded..aa539ff 100644
--- a/drivers/media/video/msm/csi/msm_csi2_register.c
+++ b/drivers/media/video/msm/csi/msm_csi2_register.c
@@ -16,48 +16,28 @@
#include "msm_csi_register.h"
int msm_csi_register_subdevs(struct msm_cam_media_controller *p_mctl,
- int core_index,
- int (*msm_mctl_subdev_match_core)(struct device *, void *))
+ int core_index, struct msm_cam_server_dev *server_dev)
{
int rc = -ENODEV;
- struct device_driver *driver;
- struct device *dev;
/* register csiphy subdev */
- driver = driver_find(MSM_CSIPHY_DRV_NAME, &platform_bus_type);
- if (!driver)
+ p_mctl->csiphy_sdev = server_dev->csiphy_device[core_index];
+ if (!p_mctl->csiphy_sdev)
goto out;
-
- dev = driver_find_device(driver, NULL, (void *)core_index,
- msm_mctl_subdev_match_core);
- if (!dev)
- goto out;
-
- p_mctl->csiphy_sdev = dev_get_drvdata(dev);
+ v4l2_set_subdev_hostdata(p_mctl->csiphy_sdev, p_mctl);
/* register csid subdev */
- driver = driver_find(MSM_CSID_DRV_NAME, &platform_bus_type);
- if (!driver)
+ p_mctl->csid_sdev = server_dev->csid_device[core_index];
+ if (!p_mctl->csid_sdev)
goto out;
-
- dev = driver_find_device(driver, NULL, (void *)core_index,
- msm_mctl_subdev_match_core);
- if (!dev)
- goto out;
-
- p_mctl->csid_sdev = dev_get_drvdata(dev);
+ v4l2_set_subdev_hostdata(p_mctl->csid_sdev, p_mctl);
/* register ispif subdev */
- driver = driver_find(MSM_ISPIF_DRV_NAME, &platform_bus_type);
- if (!driver)
+ p_mctl->ispif_sdev = server_dev->ispif_device[0];
+ if (!p_mctl->ispif_sdev)
goto out;
+ v4l2_set_subdev_hostdata(p_mctl->ispif_sdev, p_mctl);
- dev = driver_find_device(driver, NULL, 0,
- msm_mctl_subdev_match_core);
- if (!dev)
- goto out;
-
- p_mctl->ispif_sdev = dev_get_drvdata(dev);
rc = 0;
return rc;
out:
diff --git a/drivers/media/video/msm/csi/msm_csi_register.h b/drivers/media/video/msm/csi/msm_csi_register.h
index 578b609..ebb001c 100644
--- a/drivers/media/video/msm/csi/msm_csi_register.h
+++ b/drivers/media/video/msm/csi/msm_csi_register.h
@@ -13,4 +13,4 @@
int msm_csi_register_subdevs(struct msm_cam_media_controller *p_mctl,
int core_index,
- int (*msm_mctl_subdev_match_core)(struct device *, void *));
+ struct msm_cam_server_dev *server_dev);
diff --git a/drivers/media/video/msm/csi/msm_csic.c b/drivers/media/video/msm/csi/msm_csic.c
index dbb4f32..bcb7bb3 100644
--- a/drivers/media/video/msm/csi/msm_csic.c
+++ b/drivers/media/video/msm/csi/msm_csic.c
@@ -463,6 +463,12 @@
msm_cam_register_subdev_node(
&new_csic_dev->subdev, &sd_info);
+ media_entity_init(&new_csic_dev->subdev.entity, 0, NULL, 0);
+ new_csic_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ new_csic_dev->subdev.entity.group_id = CSIC_DEV;
+ new_csic_dev->subdev.entity.name = pdev->name;
+ new_csic_dev->subdev.entity.revision =
+ new_csic_dev->subdev.devnode->num;
return 0;
csic_no_resource:
diff --git a/drivers/media/video/msm/csi/msm_csic_register.c b/drivers/media/video/msm/csi/msm_csic_register.c
index 7ccaff2..dc3641a 100644
--- a/drivers/media/video/msm/csi/msm_csic_register.c
+++ b/drivers/media/video/msm/csi/msm_csic_register.c
@@ -16,23 +16,14 @@
#include "msm_csi_register.h"
int msm_csi_register_subdevs(struct msm_cam_media_controller *p_mctl,
- int core_index,
- int (*msm_mctl_subdev_match_core)(struct device *, void *))
+ int core_index, struct msm_cam_server_dev *server_dev)
{
int rc = -ENODEV;
- struct device_driver *driver;
- struct device *dev;
- driver = driver_find(MSM_CSIC_DRV_NAME, &platform_bus_type);
- if (!driver)
+ p_mctl->csic_sdev = server_dev->csic_device[core_index];
+ if (!p_mctl->csic_sdev)
goto out;
-
- dev = driver_find_device(driver, NULL, (void *)core_index,
- msm_mctl_subdev_match_core);
- if (!dev)
- goto out;
-
- p_mctl->csic_sdev = dev_get_drvdata(dev);
+ v4l2_set_subdev_hostdata(p_mctl->csic_sdev, p_mctl);
rc = 0;
p_mctl->ispif_sdev = NULL;
diff --git a/drivers/media/video/msm/csi/msm_csid.c b/drivers/media/video/msm/csi/msm_csid.c
index 962c60e..6ee87b7 100644
--- a/drivers/media/video/msm/csi/msm_csid.c
+++ b/drivers/media/video/msm/csi/msm_csid.c
@@ -320,6 +320,13 @@
sd_info.sd_index = pdev->id;
sd_info.irq_num = new_csid_dev->irq->start;
msm_cam_register_subdev_node(&new_csid_dev->subdev, &sd_info);
+
+ media_entity_init(&new_csid_dev->subdev.entity, 0, NULL, 0);
+ new_csid_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ new_csid_dev->subdev.entity.group_id = CSID_DEV;
+ new_csid_dev->subdev.entity.name = pdev->name;
+ new_csid_dev->subdev.entity.revision =
+ new_csid_dev->subdev.devnode->num;
return 0;
csid_no_resource:
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
index c524884..bec7ae3 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.c
+++ b/drivers/media/video/msm/csi/msm_csiphy.c
@@ -341,6 +341,13 @@
sd_info.irq_num = new_csiphy_dev->irq->start;
msm_cam_register_subdev_node(
&new_csiphy_dev->subdev, &sd_info);
+
+ media_entity_init(&new_csiphy_dev->subdev.entity, 0, NULL, 0);
+ new_csiphy_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ new_csiphy_dev->subdev.entity.group_id = CSIPHY_DEV;
+ new_csiphy_dev->subdev.entity.name = pdev->name;
+ new_csiphy_dev->subdev.entity.revision =
+ new_csiphy_dev->subdev.devnode->num;
return 0;
csiphy_no_resource:
diff --git a/drivers/media/video/msm/csi/msm_ispif.c b/drivers/media/video/msm/csi/msm_ispif.c
index 0f16bbf..1494644 100644
--- a/drivers/media/video/msm/csi/msm_ispif.c
+++ b/drivers/media/video/msm/csi/msm_ispif.c
@@ -517,7 +517,6 @@
if (rc < 0)
return rc;
}
-
rc = msm_ispif_reset();
return rc;
}
@@ -693,6 +692,12 @@
sd_info.sd_index = pdev->id;
sd_info.irq_num = ispif->irq->start;
msm_cam_register_subdev_node(&ispif->subdev, &sd_info);
+
+ media_entity_init(&ispif->subdev.entity, 0, NULL, 0);
+ ispif->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ ispif->subdev.entity.group_id = ISPIF_DEV;
+ ispif->subdev.entity.name = pdev->name;
+ ispif->subdev.entity.revision = ispif->subdev.devnode->num;
return 0;
ispif_no_mem:
diff --git a/drivers/media/video/msm/io/msm_io_8960.c b/drivers/media/video/msm/io/msm_io_8960.c
index f9c454a..699425a 100644
--- a/drivers/media/video/msm/io/msm_io_8960.c
+++ b/drivers/media/video/msm/io/msm_io_8960.c
@@ -87,6 +87,14 @@
} else
CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
break;
+ case S_LIVESHOT:
+ if (bus_perf_client) {
+ rc = msm_bus_scale_client_update_request(
+ bus_perf_client, 5);
+ CDBG("%s: S_LIVESHOT rc = %d\n", __func__, rc);
+ } else
+ CDBG("%s: Bus Client NOT Registered!!!\n", __func__);
+ break;
case S_DEFAULT:
break;
default:
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index b67af4f..3222f905 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -92,6 +92,33 @@
return rc;
}
+static int msm_camera_v4l2_private_g_ctrl(struct file *f, void *pctx,
+ struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
+{
+ int rc = -EINVAL;
+ struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+
+ WARN_ON(pctx != f->private_data);
+
+ mutex_lock(&pcam->vid_lock);
+ switch (ioctl_ptr->id) {
+ case MSM_V4L2_PID_INST_HANDLE:
+ COPY_TO_USER(rc, (void __user *)ioctl_ptr->ioctl_ptr,
+ (void *)&pcam_inst->inst_handle, sizeof(uint32_t));
+ if (rc)
+ ERR_COPY_TO_USER();
+ break;
+ default:
+ pr_err("%s Unsupported ioctl %d ", __func__, ioctl_ptr->id);
+ break;
+ }
+ mutex_unlock(&pcam->vid_lock);
+ return rc;
+}
+
static int msm_camera_v4l2_g_ctrl(struct file *f, void *pctx,
struct v4l2_control *c)
{
@@ -686,7 +713,9 @@
struct msm_cam_v4l2_dev_inst *pcam_inst;
pcam_inst = container_of(f->private_data,
struct msm_cam_v4l2_dev_inst, eventHandle);
- pcam_inst->image_mode = a->parm.capture.extendedmode;
+ pcam_inst->image_mode = (a->parm.capture.extendedmode & 0x7F);
+ SET_IMG_MODE(pcam_inst->inst_handle, pcam_inst->image_mode);
+ SET_VIDEO_INST_IDX(pcam_inst->inst_handle, pcam_inst->my_index);
pcam_inst->pcam->dev_inst_map[pcam_inst->image_mode] = pcam_inst;
pcam_inst->path = msm_vidbuf_get_path(pcam_inst->image_mode);
D("%spath=%d,rc=%d\n", __func__,
@@ -745,6 +774,12 @@
case MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL:
rc = msm_camera_v4l2_private_s_ctrl(file, fh, ioctl_ptr);
break;
+ case MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL:
+ rc = msm_camera_v4l2_private_g_ctrl(file, fh, ioctl_ptr);
+ break;
+ default:
+ pr_err("%s Unsupported ioctl cmd %d ", __func__, cmd);
+ break;
}
return rc;
}
@@ -876,13 +911,8 @@
}
pmctl->pcam_ptr = pcam;
- rc = msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
+ msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
pcam->pvdev);
- if (rc < 0) {
- pr_err("%s: msm_setup_v4l2_event_queue failed %d",
- __func__, rc);
- goto mctl_event_q_setup_failed;
- }
}
pcam_inst->vbqueue_initialized = 0;
rc = 0;
@@ -905,9 +935,8 @@
return rc;
msm_send_open_server_failed:
- v4l2_fh_del(&pcam_inst->eventHandle);
- v4l2_fh_exit(&pcam_inst->eventHandle);
-mctl_event_q_setup_failed:
+ msm_destroy_v4l2_event_queue(&pcam_inst->eventHandle);
+
if (pmctl->mctl_release)
if (pmctl->mctl_release(pmctl) < 0)
pr_err("%s: mctl_release failed\n", __func__);
@@ -1051,10 +1080,11 @@
D("%s index %d nodeid %d count %d\n", __func__, pcam_inst->my_index,
pcam->vnode_id, pcam->use_count);
pcam->dev_inst[pcam_inst->my_index] = NULL;
- if (pcam_inst->my_index == 0) {
- v4l2_fh_del(&pcam_inst->eventHandle);
- v4l2_fh_exit(&pcam_inst->eventHandle);
- }
+ if (pcam_inst->my_index == 0)
+ msm_destroy_v4l2_event_queue(&pcam_inst->eventHandle);
+
+ CLR_VIDEO_INST_IDX(pcam_inst->inst_handle);
+ CLR_IMG_MODE(pcam_inst->inst_handle);
mutex_unlock(&pcam_inst->inst_lock);
mutex_destroy(&pcam_inst->inst_lock);
kfree(pcam_inst);
@@ -1137,18 +1167,6 @@
return 0;
}
-int msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
- struct video_device *pvdev)
-{
- int rc = 0;
- /* v4l2_fh support */
- spin_lock_init(&pvdev->fh_lock);
- INIT_LIST_HEAD(&pvdev->fh_list);
-
- v4l2_fh_init(eventHandle, pvdev);
- v4l2_fh_add(eventHandle);
- return rc;
-}
static struct v4l2_file_operations g_msm_fops = {
.owner = THIS_MODULE,
@@ -1201,7 +1219,7 @@
pvdev->fops = &g_msm_fops;
pvdev->ioctl_ops = &g_msm_ioctl_ops;
pvdev->minor = -1;
- pvdev->vfl_type = 1;
+ pvdev->vfl_type = VFL_TYPE_GRABBER;
media_entity_init(&pvdev->entity, 0, NULL, 0);
pvdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 08278ff..d77defd 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -61,6 +61,7 @@
#define MSM_IRQ_ROUTER_DRV_NAME "msm_cam_irq_router"
#define MSM_CPP_DRV_NAME "msm_cpp"
+#define MAX_NUM_SENSOR_DEV 3
#define MAX_NUM_CSIPHY_DEV 3
#define MAX_NUM_CSID_DEV 4
#define MAX_NUM_CSIC_DEV 3
@@ -71,22 +72,6 @@
#define MAX_NUM_JPEG_DEV 3
#define MAX_NUM_CPP_DEV 1
-enum msm_cam_subdev_type {
- CSIPHY_DEV,
- CSID_DEV,
- CSIC_DEV,
- ISPIF_DEV,
- VFE_DEV,
- AXI_DEV,
- VPE_DEV,
- SENSOR_DEV,
- ACTUATOR_DEV,
- EEPROM_DEV,
- GESTURE_DEV,
- IRQ_ROUTER_DEV,
- CPP_DEV,
-};
-
/* msm queue management APIs*/
#define msm_dequeue(queue, member) ({ \
@@ -137,7 +122,7 @@
struct msm_free_buf {
uint8_t num_planes;
- int32_t image_mode;
+ uint32_t inst_handle;
uint32_t ch_paddr[VIDEO_MAX_PLANES];
uint32_t vb;
};
@@ -315,7 +300,6 @@
/* vfe subdevice */
struct v4l2_subdev *sd;
- struct v4l2_subdev *sd_vpe;
};
struct msm_isp_buf_info {
@@ -339,7 +323,7 @@
enum v4l2_mbus_pixelcode sensor_pxlcode;
struct msm_cam_v4l2_device *pcam;
int my_index;
- int image_mode;
+ uint32_t image_mode;
int path;
int buf_count;
/* buffer offsets, if any */
@@ -351,6 +335,7 @@
struct img_plane_info plane_info;
int vbqueue_initialized;
struct mutex inst_lock;
+ uint32_t inst_handle;
};
struct msm_cam_mctl_node {
@@ -540,10 +525,11 @@
struct mutex server_lock;
struct mutex server_queue_lock;
/*v4l2 subdevs*/
+ struct v4l2_subdev *sensor_device[MAX_NUM_SENSOR_DEV];
struct v4l2_subdev *csiphy_device[MAX_NUM_CSIPHY_DEV];
struct v4l2_subdev *csid_device[MAX_NUM_CSID_DEV];
struct v4l2_subdev *csic_device[MAX_NUM_CSIC_DEV];
- struct v4l2_subdev *ispif_device;
+ struct v4l2_subdev *ispif_device[MAX_NUM_ISPIF_DEV];
struct v4l2_subdev *vfe_device[MAX_NUM_VFE_DEV];
struct v4l2_subdev *axi_device[MAX_NUM_AXI_DEV];
struct v4l2_subdev *vpe_device[MAX_NUM_VPE_DEV];
@@ -562,6 +548,18 @@
struct msm_cam_server_irqmap_entry hw_irqmap[CAMERA_SS_IRQ_MAX];
};
+enum msm_cam_buf_lookup_type {
+ BUF_LOOKUP_INVALID,
+ BUF_LOOKUP_BY_IMG_MODE,
+ BUF_LOOKUP_BY_INST_HANDLE,
+};
+
+struct msm_cam_buf_handle {
+ uint16_t buf_lookup_type;
+ uint32_t image_mode;
+ uint32_t inst_handle;
+};
+
/* ISP related functions */
void msm_isp_vfe_dev_init(struct v4l2_subdev *vd);
/*
@@ -577,78 +575,69 @@
int msm_mctl_buf_init(struct msm_cam_v4l2_device *pcam);
int msm_mctl_init_user_formats(struct msm_cam_v4l2_device *pcam);
int msm_mctl_buf_done(struct msm_cam_media_controller *pmctl,
- int msg_type, struct msm_free_buf *buf,
- uint32_t frame_id);
+ struct msm_cam_buf_handle *buf_handle,
+ struct msm_free_buf *buf,
+ uint32_t frame_id);
int msm_mctl_buf_done_pp(struct msm_cam_media_controller *pmctl,
- int msg_type, struct msm_free_buf *frame, int dirty, int node_type);
+ struct msm_cam_buf_handle *buf_handle,
+ struct msm_free_buf *frame, int dirty, int node_type);
int msm_mctl_reserve_free_buf(struct msm_cam_media_controller *pmctl,
- struct msm_cam_v4l2_dev_inst *pcam_inst,
- int path, struct msm_free_buf *free_buf);
+ struct msm_cam_v4l2_dev_inst *pcam_inst,
+ struct msm_cam_buf_handle *buf_handle,
+ struct msm_free_buf *free_buf);
int msm_mctl_release_free_buf(struct msm_cam_media_controller *pmctl,
- struct msm_cam_v4l2_dev_inst *pcam_inst,
- int path, struct msm_free_buf *free_buf);
+ struct msm_cam_v4l2_dev_inst *pcam_inst,
+ struct msm_free_buf *free_buf);
/*Memory(PMEM) functions*/
int msm_register_pmem(struct hlist_head *ptype, void __user *arg,
- struct ion_client *client);
+ struct ion_client *client);
int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg,
- struct ion_client *client);
+ struct ion_client *client);
int msm_pmem_region_get_phy_addr(struct hlist_head *ptype,
struct msm_mem_map_info *mem_map, int32_t *phyaddr);
uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
int pmem_type, struct msm_pmem_region *reg, uint8_t maxcount);
uint8_t msm_pmem_region_lookup_2(struct hlist_head *ptype,
- int pmem_type,
- struct msm_pmem_region *reg,
- uint8_t maxcount);
+ int pmem_type, struct msm_pmem_region *reg,
+ uint8_t maxcount);
unsigned long msm_pmem_stats_vtop_lookup(
- struct msm_cam_media_controller *mctl,
- unsigned long buffer,
- int fd);
+ struct msm_cam_media_controller *mctl,
+ unsigned long buffer, int fd);
unsigned long msm_pmem_stats_ptov_lookup(
struct msm_cam_media_controller *mctl,
unsigned long addr, int *fd);
-int msm_vfe_subdev_init(struct v4l2_subdev *sd,
- struct msm_cam_media_controller *mctl);
+int msm_vfe_subdev_init(struct v4l2_subdev *sd);
void msm_vfe_subdev_release(struct v4l2_subdev *sd);
int msm_isp_subdev_ioctl(struct v4l2_subdev *sd,
struct msm_vfe_cfg_cmd *cfgcmd, void *data);
-int msm_vpe_subdev_init(struct v4l2_subdev *sd,
- struct msm_cam_media_controller *mctl);
+int msm_vpe_subdev_init(struct v4l2_subdev *sd);
int msm_gemini_subdev_init(struct v4l2_subdev *gemini_sd);
void msm_vpe_subdev_release(void);
void msm_gemini_subdev_release(struct v4l2_subdev *gemini_sd);
int msm_mctl_is_pp_msg_type(struct msm_cam_media_controller *p_mctl,
int msg_type);
int msm_mctl_do_pp(struct msm_cam_media_controller *p_mctl,
- int msg_type, uint32_t y_phy, uint32_t frame_id);
+ int msg_type, uint32_t y_phy, uint32_t frame_id);
int msm_mctl_pp_ioctl(struct msm_cam_media_controller *p_mctl,
- unsigned int cmd, unsigned long arg);
+ unsigned int cmd, unsigned long arg);
int msm_mctl_pp_notify(struct msm_cam_media_controller *pmctl,
- struct msm_mctl_pp_frame_info *pp_frame_info);
+ struct msm_mctl_pp_frame_info *pp_frame_info);
int msm_mctl_img_mode_to_inst_index(struct msm_cam_media_controller *pmctl,
- int out_type, int node_type);
+ int out_type, int node_type);
struct msm_frame_buffer *msm_mctl_buf_find(
struct msm_cam_media_controller *pmctl,
struct msm_cam_v4l2_dev_inst *pcam_inst, int del_buf,
- int msg_type, struct msm_free_buf *fbuf);
+ struct msm_free_buf *fbuf);
void msm_mctl_gettimeofday(struct timeval *tv);
-struct msm_frame_buffer *msm_mctl_get_free_buf(
- struct msm_cam_media_controller *pmctl,
- int msg_type);
-int msm_mctl_put_free_buf(
- struct msm_cam_media_controller *pmctl,
- int msg_type, struct msm_frame_buffer *buf);
int msm_mctl_check_pp(struct msm_cam_media_controller *p_mctl,
- int msg_type, int *pp_divert_type, int *pp_type);
+ int msg_type, int *pp_divert_type, int *pp_type);
int msm_mctl_do_pp_divert(
struct msm_cam_media_controller *p_mctl,
- int msg_type, struct msm_free_buf *fbuf,
+ struct msm_cam_buf_handle *buf_handle,
+ struct msm_free_buf *fbuf,
uint32_t frame_id, int pp_type);
-int msm_mctl_buf_del(struct msm_cam_media_controller *pmctl,
- int msg_type,
- struct msm_frame_buffer *my_buf);
int msm_mctl_pp_release_free_frame(
struct msm_cam_media_controller *p_mctl,
void __user *arg);
@@ -656,26 +645,29 @@
struct msm_cam_media_controller *p_mctl,
void __user *arg);
int msm_mctl_set_pp_key(struct msm_cam_media_controller *p_mctl,
- void __user *arg);
+ void __user *arg);
int msm_mctl_pp_done(
struct msm_cam_media_controller *p_mctl,
void __user *arg);
int msm_mctl_pp_divert_done(
struct msm_cam_media_controller *p_mctl,
void __user *arg);
-int msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
- struct video_device *pvdev);
+void msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
+ struct video_device *pvdev);
+void msm_destroy_v4l2_event_queue(struct v4l2_fh *eventHandle);
int msm_setup_mctl_node(struct msm_cam_v4l2_device *pcam);
struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst(
- struct msm_cam_media_controller *pmctl,
- int image_mode);
+ struct msm_cam_media_controller *pmctl,
+ struct msm_cam_buf_handle *buf_handle);
int msm_mctl_buf_return_buf(struct msm_cam_media_controller *pmctl,
- int image_mode, struct msm_frame_buffer *buf);
+ int image_mode, struct msm_frame_buffer *buf);
int msm_mctl_pp_mctl_divert_done(struct msm_cam_media_controller *p_mctl,
- void __user *arg);
+ void __user *arg);
void msm_release_ion_client(struct kref *ref);
int msm_cam_register_subdev_node(struct v4l2_subdev *sd,
struct msm_cam_subdev_info *sd_info);
+int msm_mctl_find_sensor_subdevs(struct msm_cam_media_controller *p_mctl,
+ int core_index);
int msm_server_open_client(int *p_qidx);
int msm_server_send_ctrl(struct msm_ctrl_cmd *out, int ctrl_id);
int msm_server_close_client(int idx);
@@ -683,7 +675,7 @@
int *p_active);
int msm_cam_server_close_mctl_session(struct msm_cam_v4l2_device *pcam);
long msm_v4l2_evt_notify(struct msm_cam_media_controller *mctl,
- unsigned int cmd, unsigned long evt);
+ unsigned int cmd, unsigned long evt);
int msm_mctl_pp_get_vpe_buf_info(struct msm_mctl_pp_frame_info *zoom);
void msm_queue_init(struct msm_device_queue *queue, const char *name);
void msm_enqueue(struct msm_device_queue *queue, struct list_head *entry);
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 5fcb62b..67e7c02 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -168,7 +168,9 @@
struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
struct msm_frame_info *frame_info =
(struct msm_frame_info *)vdata->evt_msg.data;
- uint32_t vfe_id, image_mode;
+ uint32_t vfe_id;
+ struct msm_cam_buf_handle buf_handle;
+
if (!pcam) {
pr_debug("%s pcam is null. return\n", __func__);
msm_isp_sync_free(vdata);
@@ -176,10 +178,13 @@
}
if (frame_info) {
vfe_id = frame_info->path;
- image_mode = frame_info->image_mode;
+ buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+ buf_handle.inst_handle = frame_info->inst_handle;
} else {
vfe_id = vdata->evt_msg.msg_id;
- image_mode = msm_isp_vfe_msg_to_img_mode(pmctl, vfe_id);
+ buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+ buf_handle.image_mode =
+ msm_isp_vfe_msg_to_img_mode(pmctl, vfe_id);
}
switch (vdata->type) {
@@ -189,14 +194,14 @@
D("%s Got V32_START_*: Getting ping addr id = %d",
__func__, vfe_id);
msm_mctl_reserve_free_buf(pmctl, NULL,
- image_mode, &free_buf);
+ &buf_handle, &free_buf);
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);
msm_mctl_reserve_free_buf(pmctl, NULL,
- image_mode, &free_buf);
+ &buf_handle, &free_buf);
cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
cfgcmd.value = &vfe_id;
vfe_params.vfe_cfg = &cfgcmd;
@@ -208,7 +213,7 @@
pr_debug("%s Got V32_CAPTURE: getting buffer for id = %d",
__func__, vfe_id);
msm_mctl_reserve_free_buf(pmctl, NULL,
- image_mode, &free_buf);
+ &buf_handle, &free_buf);
cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
cfgcmd.value = &vfe_id;
vfe_params.vfe_cfg = &cfgcmd;
@@ -216,7 +221,7 @@
rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
temp_free_buf = free_buf;
if (msm_mctl_reserve_free_buf(pmctl, NULL,
- image_mode, &free_buf)) {
+ &buf_handle, &free_buf)) {
/* Write the same buffer into PONG */
free_buf = temp_free_buf;
}
@@ -254,7 +259,7 @@
D("%s Got OUTPUT_IRQ: Getting free buf id = %d",
__func__, vfe_id);
msm_mctl_reserve_free_buf(pmctl, NULL,
- image_mode, &free_buf);
+ &buf_handle, &free_buf);
cfgcmd.cmd_type = CMD_CONFIG_FREE_BUF_ADDR;
cfgcmd.value = &vfe_id;
vfe_params.vfe_cfg = &cfgcmd;
@@ -320,10 +325,10 @@
}
case NOTIFY_VFE_MSG_OUT: {
uint8_t msgid;
- int32_t image_mode = -1;
+ struct msm_cam_buf_handle buf_handle;
struct isp_msg_output *isp_output =
(struct isp_msg_output *)arg;
- if (isp_output->buf.image_mode < 0) {
+ if (!isp_output->buf.inst_handle) {
switch (isp_output->output_id) {
case MSG_ID_OUTPUT_P:
msgid = VFE_MSG_OUTPUT_P;
@@ -356,19 +361,22 @@
rc = -EINVAL;
break;
}
- if (!rc)
- image_mode =
+ if (!rc) {
+ buf_handle.buf_lookup_type =
+ BUF_LOOKUP_BY_IMG_MODE;
+ buf_handle.image_mode =
msm_isp_vfe_msg_to_img_mode(pmctl, msgid);
+ }
} else {
- image_mode = isp_output->buf.image_mode;
+ buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+ buf_handle.inst_handle = isp_output->buf.inst_handle;
}
isp_event->isp_data.isp_msg.msg_id =
isp_output->output_id;
isp_event->isp_data.isp_msg.frame_id =
isp_output->frameCounter;
buf = isp_output->buf;
- BUG_ON(image_mode < 0);
- msm_mctl_buf_done(pmctl, image_mode,
+ msm_mctl_buf_done(pmctl, &buf_handle,
&buf, isp_output->frameCounter);
}
break;
@@ -498,32 +506,8 @@
return -EINVAL;
}
- rc = msm_iommu_map_contig_buffer(
- (unsigned long)IMEM_Y_PING_OFFSET, CAMERA_DOMAIN, GEN_POOL,
- ((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
- SZ_4K, IOMMU_WRITE | IOMMU_READ,
- (unsigned long *)&mctl->ping_imem_y);
- mctl->ping_imem_cbcr = mctl->ping_imem_y + IMEM_Y_SIZE;
- if (rc < 0) {
- pr_err("%s: ping iommu mapping returned error %d\n",
- __func__, rc);
- mctl->ping_imem_y = 0;
- mctl->ping_imem_cbcr = 0;
- }
- msm_iommu_map_contig_buffer(
- (unsigned long)IMEM_Y_PONG_OFFSET, CAMERA_DOMAIN, GEN_POOL,
- ((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
- SZ_4K, IOMMU_WRITE | IOMMU_READ,
- (unsigned long *)&mctl->pong_imem_y);
- mctl->pong_imem_cbcr = mctl->pong_imem_y + IMEM_Y_SIZE;
- if (rc < 0) {
- pr_err("%s: pong iommu mapping returned error %d\n",
- __func__, rc);
- mctl->pong_imem_y = 0;
- mctl->pong_imem_cbcr = 0;
- }
-
- rc = msm_vfe_subdev_init(sd, mctl);
+ rc = v4l2_subdev_call(sd, core, ioctl,
+ VIDIOC_MSM_VFE_INIT, NULL);
if (rc < 0) {
pr_err("%s: vfe_init failed at %d\n",
__func__, rc);
@@ -535,17 +519,8 @@
struct v4l2_subdev *sd)
{
D("%s\n", __func__);
- msm_vfe_subdev_release(sd);
- msm_iommu_unmap_contig_buffer(mctl->ping_imem_y,
- CAMERA_DOMAIN, GEN_POOL,
- ((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
- msm_iommu_unmap_contig_buffer(mctl->pong_imem_y,
- CAMERA_DOMAIN, GEN_POOL,
- ((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
- mctl->ping_imem_y = 0;
- mctl->ping_imem_cbcr = 0;
- mctl->pong_imem_y = 0;
- mctl->pong_imem_cbcr = 0;
+ v4l2_subdev_call(sd, core, ioctl,
+ VIDIOC_MSM_VFE_RELEASE, NULL);
}
static int msm_config_vfe(struct v4l2_subdev *sd,
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index be4cb41..4bbc47c 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -418,94 +418,6 @@
return rc;
}
-static int msm_mctl_subdev_match_core(struct device *dev, void *data)
-{
- int core_index = (int)data;
- struct platform_device *pdev = to_platform_device(dev);
-
- if (pdev->id == core_index)
- return 1;
- else
- return 0;
-}
-
-static int msm_mctl_register_subdevs(struct msm_cam_media_controller *p_mctl,
- int core_index)
-{
- struct device_driver *driver;
- struct device *dev;
- int rc = -ENODEV;
-
- struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(p_mctl->sensor_sdev);
- struct msm_camera_sensor_info *sinfo =
- (struct msm_camera_sensor_info *) s_ctrl->sensordata;
- struct msm_camera_device_platform_data *pdata = sinfo->pdata;
-
- rc = msm_csi_register_subdevs(p_mctl, core_index,
- msm_mctl_subdev_match_core);
-
- if (rc < 0)
- goto out;
-
- /* register vfe subdev */
- driver = driver_find(MSM_VFE_DRV_NAME, &platform_bus_type);
- if (!driver)
- goto out;
-
- dev = driver_find_device(driver, NULL, 0,
- msm_mctl_subdev_match_core);
- if (!dev)
- goto out;
-
- p_mctl->isp_sdev->sd = dev_get_drvdata(dev);
-
- if (pdata->is_vpe) {
- /* register vfe subdev */
- driver = driver_find(MSM_VPE_DRV_NAME, &platform_bus_type);
- if (!driver)
- goto out;
-
- dev = driver_find_device(driver, NULL, 0,
- msm_mctl_subdev_match_core);
- if (!dev)
- goto out;
-
- p_mctl->vpe_sdev = dev_get_drvdata(dev);
- }
-
- 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\n",
- __func__, __LINE__);
- goto out;
- }
- 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;
- }
- rc = 0;
-out:
- return rc;
-}
-
static int msm_mctl_open(struct msm_cam_media_controller *p_mctl,
const char *const apps_id)
{
@@ -529,9 +441,9 @@
wake_lock(&p_mctl->wake_lock);
csid_core = camdev->csid_core;
- rc = msm_mctl_register_subdevs(p_mctl, csid_core);
+ rc = msm_mctl_find_sensor_subdevs(p_mctl, csid_core);
if (rc < 0) {
- pr_err("%s: msm_mctl_register_subdevs failed:%d\n",
+ pr_err("%s: msm_mctl_find_sensor_subdevs failed:%d\n",
__func__, rc);
goto register_sdev_failed;
}
@@ -592,38 +504,6 @@
goto msm_csi_version;
}
- /* ISP first*/
- 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);
- if (rc < 0) {
- pr_err("%s: isp init failed: %d\n",
- __func__, rc);
- goto isp_open_failed;
- }
- }
-
- if (p_mctl->axi_sdev) {
- rc = v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
- VIDIOC_MSM_AXI_INIT, p_mctl);
- if (rc < 0) {
- pr_err("%s: axi initialization failed %d\n",
- __func__, rc);
- goto axi_init_failed;
- }
- }
-
- if (camdev->is_vpe) {
- rc = v4l2_subdev_call(p_mctl->vpe_sdev, core, ioctl,
- VIDIOC_MSM_VPE_INIT, p_mctl);
- if (rc < 0) {
- pr_err("%s: vpe initialization failed %d\n",
- __func__, rc);
- goto vpe_init_failed;
- }
- }
-
-
pm_qos_add_request(&p_mctl->pm_qos_req_list,
PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
pm_qos_update_request(&p_mctl->pm_qos_req_list,
@@ -635,19 +515,9 @@
D("%s: camera is already open", __func__);
}
mutex_unlock(&p_mctl->lock);
-
return rc;
-vpe_init_failed:
- if (p_mctl->axi_sdev)
- if (v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
- VIDIOC_MSM_AXI_RELEASE, NULL) < 0)
- pr_err("%s: axi release failed %d\n", __func__, rc);
-axi_init_failed:
- if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_release)
- p_mctl->isp_sdev->isp_release(p_mctl, p_mctl->isp_sdev->sd);
msm_csi_version:
-isp_open_failed:
if (p_mctl->csic_sdev)
if (v4l2_subdev_call(p_mctl->csic_sdev, core, ioctl,
VIDIOC_MSM_CSIC_RELEASE, NULL) < 0)
@@ -684,7 +554,6 @@
struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(p_mctl->sensor_sdev);
struct msm_camera_sensor_info *sinfo =
(struct msm_camera_sensor_info *) s_ctrl->sensordata;
- struct msm_camera_device_platform_data *camdev = sinfo->pdata;
v4l2_subdev_call(p_mctl->sensor_sdev, core, ioctl,
VIDIOC_MSM_SENSOR_RELEASE, NULL);
@@ -694,7 +563,7 @@
VIDIOC_MSM_CSIC_RELEASE, NULL);
}
- if (camdev->is_vpe) {
+ if (p_mctl->vpe_sdev) {
v4l2_subdev_call(p_mctl->vpe_sdev, core, ioctl,
VIDIOC_MSM_VPE_RELEASE, NULL);
}
@@ -704,7 +573,8 @@
VIDIOC_MSM_AXI_RELEASE, NULL);
}
- if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_release)
+ if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_release
+ && p_mctl->isp_sdev->sd)
p_mctl->isp_sdev->isp_release(p_mctl,
p_mctl->isp_sdev->sd);
@@ -832,6 +702,7 @@
pmctl->eeprom_sdev = pcam->eeprom_sdev;
pmctl->sensor_sdev = pcam->sensor_sdev;
pmctl->sdata = pcam->sdata;
+ v4l2_set_subdev_hostdata(pcam->sensor_sdev, pmctl);
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
pmctl->client = msm_ion_client_create(-1, "camera");
@@ -855,6 +726,8 @@
mutex_destroy(&pmctl->lock);
wake_lock_destroy(&pmctl->wake_lock);
+ /*clear out mctl fields*/
+ memset(pmctl, 0, sizeof(struct msm_cam_media_controller));
msm_cam_server_free_mctl(pcam->mctl_handle);
return rc;
}
@@ -919,12 +792,9 @@
}
D("%s active %d\n", __func__, pcam->mctl_node.active);
- rc = msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
- pcam->mctl_node.pvdev);
- if (rc < 0) {
- mutex_unlock(&pcam->mctl_node.dev_lock);
- return rc;
- }
+ msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
+ pcam->mctl_node.pvdev);
+
pcam_inst->vbqueue_initialized = 0;
kref_get(&pmctl->refcount);
f->private_data = &pcam_inst->eventHandle;
@@ -1007,8 +877,10 @@
vb2_queue_release(&pcam_inst->vid_bufq);
D("%s Closing down instance %p ", __func__, pcam_inst);
pcam->mctl_node.dev_inst[pcam_inst->my_index] = NULL;
- v4l2_fh_del(&pcam_inst->eventHandle);
- v4l2_fh_exit(&pcam_inst->eventHandle);
+ msm_destroy_v4l2_event_queue(&pcam_inst->eventHandle);
+ CLR_MCTLPP_INST_IDX(pcam_inst->inst_handle);
+ CLR_IMG_MODE(pcam_inst->inst_handle);
+
mutex_destroy(&pcam_inst->inst_lock);
kfree(pcam_inst);
@@ -1581,7 +1453,9 @@
struct msm_cam_v4l2_dev_inst *pcam_inst;
pcam_inst = container_of(f->private_data,
struct msm_cam_v4l2_dev_inst, eventHandle);
- pcam_inst->image_mode = a->parm.capture.extendedmode;
+ pcam_inst->image_mode = (a->parm.capture.extendedmode & 0x7F);
+ SET_IMG_MODE(pcam_inst->inst_handle, pcam_inst->image_mode);
+ SET_MCTLPP_INST_IDX(pcam_inst->inst_handle, pcam_inst->my_index);
pcam_inst->pcam->mctl_node.dev_inst_map[pcam_inst->image_mode] =
pcam_inst;
pcam_inst->path = msm_mctl_vidbuf_get_path(pcam_inst->image_mode);
@@ -1626,6 +1500,51 @@
return rc;
}
+static int msm_mctl_v4l2_private_g_ctrl(struct file *f, void *pctx,
+ struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
+{
+ int rc = -EINVAL;
+ struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
+
+ WARN_ON(pctx != f->private_data);
+
+ mutex_lock(&pcam->mctl_node.dev_lock);
+ switch (ioctl_ptr->id) {
+ case MSM_V4L2_PID_INST_HANDLE:
+ COPY_TO_USER(rc, (void __user *)ioctl_ptr->ioctl_ptr,
+ (void *)&pcam_inst->inst_handle, sizeof(uint32_t));
+ if (rc)
+ ERR_COPY_TO_USER();
+ break;
+ default:
+ pr_err("%s Unsupported ioctl %d ", __func__, ioctl_ptr->id);
+ break;
+ }
+ mutex_unlock(&pcam->mctl_node.dev_lock);
+ return rc;
+}
+
+static long msm_mctl_v4l2_private_ioctl(struct file *file, void *fh,
+ bool valid_prio, int cmd, void *arg)
+{
+ int rc = -EINVAL;
+ struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+ D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
+
+ switch (cmd) {
+ case MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL:
+ rc = msm_mctl_v4l2_private_g_ctrl(file, fh, ioctl_ptr);
+ break;
+ default:
+ pr_err("%s Unsupported ioctl cmd %d ", __func__, cmd);
+ break;
+ }
+ return rc;
+}
+
/* mctl node v4l2_ioctl_ops */
static const struct v4l2_ioctl_ops g_msm_mctl_ioctl_ops = {
.vidioc_querycap = msm_mctl_v4l2_querycap,
@@ -1665,6 +1584,7 @@
/* event subscribe/unsubscribe */
.vidioc_subscribe_event = msm_mctl_v4l2_subscribe_event,
.vidioc_unsubscribe_event = msm_mctl_v4l2_unsubscribe_event,
+ .vidioc_default = msm_mctl_v4l2_private_ioctl,
};
int msm_setup_mctl_node(struct msm_cam_v4l2_device *pcam)
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index cd86a80..befd213 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -368,7 +368,7 @@
struct msm_frame_buffer *msm_mctl_buf_find(
struct msm_cam_media_controller *pmctl,
struct msm_cam_v4l2_dev_inst *pcam_inst, int del_buf,
- int image_mode, struct msm_free_buf *fbuf)
+ struct msm_free_buf *fbuf)
{
struct msm_frame_buffer *buf = NULL, *tmp;
uint32_t buf_phyaddr = 0;
@@ -409,14 +409,13 @@
int msm_mctl_buf_done_proc(
struct msm_cam_media_controller *pmctl,
struct msm_cam_v4l2_dev_inst *pcam_inst,
- int image_mode, struct msm_free_buf *fbuf,
+ struct msm_free_buf *fbuf,
uint32_t *frame_id, int gen_timestamp)
{
struct msm_frame_buffer *buf = NULL;
int del_buf = 1;
- buf = msm_mctl_buf_find(pmctl, pcam_inst, del_buf,
- image_mode, fbuf);
+ buf = msm_mctl_buf_find(pmctl, pcam_inst, del_buf, fbuf);
if (!buf) {
pr_err("%s: buf=0x%x not found\n",
__func__, fbuf->ch_paddr[0]);
@@ -434,48 +433,81 @@
int msm_mctl_buf_done(struct msm_cam_media_controller *p_mctl,
- int image_mode, struct msm_free_buf *fbuf,
- uint32_t frame_id)
+ struct msm_cam_buf_handle *buf_handle,
+ struct msm_free_buf *fbuf,
+ uint32_t frame_id)
{
struct msm_cam_v4l2_dev_inst *pcam_inst;
int idx, rc;
int pp_divert_type = 0, pp_type = 0;
+ uint32_t image_mode;
+
+ if (!p_mctl || !buf_handle || !fbuf) {
+ pr_err("%s Invalid argument. ", __func__);
+ return -EINVAL;
+ }
+ if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE)
+ image_mode = buf_handle->image_mode;
+ else
+ image_mode = GET_IMG_MODE(buf_handle->inst_handle);
+
+ if (image_mode > MSM_V4L2_EXT_CAPTURE_MODE_MAX) {
+ pr_err("%s Invalid image mode %d ", __func__, image_mode);
+ return -EINVAL;
+ }
msm_mctl_check_pp(p_mctl, image_mode, &pp_divert_type, &pp_type);
D("%s: pp_type=%d, pp_divert_type = %d, frame_id = 0x%x image_mode %d",
__func__, pp_type, pp_divert_type, frame_id, image_mode);
- if (pp_type || pp_divert_type)
- rc = msm_mctl_do_pp_divert(p_mctl,
- image_mode, fbuf, frame_id, pp_type);
- else {
- idx = msm_mctl_img_mode_to_inst_index(
- p_mctl, image_mode, 0);
- if (idx < 0) {
- /* check mctl node */
- if ((image_mode >= 0) &&
- p_mctl->pcam_ptr->mctl_node.
- dev_inst_map[image_mode]) {
- int index = p_mctl->pcam_ptr->mctl_node.
- dev_inst_map[image_mode]->my_index;
- pcam_inst = p_mctl->pcam_ptr->mctl_node.
- dev_inst[index];
- D("%s: Mctl node index %d inst %p",
- __func__, index, pcam_inst);
- rc = msm_mctl_buf_done_proc(p_mctl, pcam_inst,
- image_mode, fbuf,
- &frame_id, 1);
- D("%s mctl node buf done %d\n", __func__, 0);
- return rc;
+ if (pp_type || pp_divert_type) {
+ rc = msm_mctl_do_pp_divert(p_mctl, buf_handle,
+ fbuf, frame_id, pp_type);
+ } else {
+ /* Find the instance on which vb2_buffer_done() needs to be
+ * called, so that the user can get the buffer.
+ * If the lookup type is
+ * - By instance handle:
+ * Either mctl_pp inst idx or video inst idx should be set.
+ * Try to get the MCTL_PP inst idx first, if its not set,
+ * fall back to video inst idx. Once we get the inst idx,
+ * get the pcam_inst from the corresponding dev_inst[] map.
+ * If neither are set, its a serious error, trigger a BUG_ON.
+ * - By image mode:
+ * Legacy usecase. Use the image mode and get the pcam_inst
+ * from the video node.
+ */
+ if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+ idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
+ if (idx > MSM_DEV_INST_MAX) {
+ idx = GET_VIDEO_INST_IDX(
+ buf_handle->inst_handle);
+ BUG_ON(idx > MSM_DEV_INST_MAX);
+ pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
} else {
- pr_err("%s Invalid instance, dropping buffer\n",
- __func__);
- return idx;
+ pcam_inst = p_mctl->pcam_ptr->mctl_node.
+ dev_inst[idx];
}
+ } else if (buf_handle->buf_lookup_type ==
+ BUF_LOOKUP_BY_IMG_MODE) {
+ idx = msm_mctl_img_mode_to_inst_index(p_mctl,
+ buf_handle->image_mode, 0);
+ if (idx < 0) {
+ pr_err("%s Invalid idx %d ", __func__, idx);
+ return -EINVAL;
+ }
+ pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
+ } else {
+ pr_err("%s Invalid buffer lookup type %d", __func__,
+ buf_handle->buf_lookup_type);
+ return -EINVAL;
}
- pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
+ if (!pcam_inst) {
+ pr_err("%s Invalid instance, Dropping buffer. ",
+ __func__);
+ return -EINVAL;
+ }
rc = msm_mctl_buf_done_proc(p_mctl, pcam_inst,
- image_mode, fbuf,
- &frame_id, 1);
+ fbuf, &frame_id, 1);
}
return rc;
}
@@ -508,58 +540,99 @@
return ret;
}
-struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst(
- struct msm_cam_media_controller *pmctl,
- int image_mode)
+struct msm_cam_v4l2_dev_inst *msm_mctl_get_inst_by_img_mode(
+ struct msm_cam_media_controller *pmctl, uint32_t img_mode)
{
struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
int idx;
- if (image_mode >= 0) {
- /* Valid image mode. Search the mctl node first.
- * If mctl node doesnt have the instance, then
- * search in the user's video node */
- if (pmctl->vfe_output_mode == VFE_OUTPUTS_MAIN_AND_THUMB
+ /* Valid image mode. Search the mctl node first.
+ * If mctl node doesnt have the instance, then
+ * search in the user's video node */
+ if (pmctl->vfe_output_mode == VFE_OUTPUTS_MAIN_AND_THUMB
|| pmctl->vfe_output_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
- if (pcam->mctl_node.dev_inst_map[image_mode]
- && is_buffer_queued(pcam, image_mode)) {
- idx =
- pcam->mctl_node.dev_inst_map[image_mode]
- ->my_index;
- pcam_inst = pcam->mctl_node.dev_inst[idx];
- D("%s Found instance %p in mctl node device\n",
- __func__, pcam_inst);
- } else if (pcam->dev_inst_map[image_mode]) {
- idx = pcam->dev_inst_map[image_mode]->my_index;
- pcam_inst = pcam->dev_inst[idx];
- D("%s Found instance %p in video device\n",
+ if (pcam->mctl_node.dev_inst_map[img_mode]
+ && is_buffer_queued(pcam, img_mode)) {
+ idx = pcam->mctl_node.dev_inst_map[img_mode]->my_index;
+ pcam_inst = pcam->mctl_node.dev_inst[idx];
+ D("%s Found instance %p in mctl node device\n",
__func__, pcam_inst);
- }
- } else {
- if (pcam->mctl_node.dev_inst_map[image_mode]) {
- idx = pcam->mctl_node.dev_inst_map[image_mode]
- ->my_index;
- pcam_inst = pcam->mctl_node.dev_inst[idx];
- D("%s Found instance %p in mctl node device\n",
+ } else if (pcam->dev_inst_map[img_mode]) {
+ idx = pcam->dev_inst_map[img_mode]->my_index;
+ pcam_inst = pcam->dev_inst[idx];
+ D("%s Found instance %p in video device\n",
__func__, pcam_inst);
- } else if (pcam->dev_inst_map[image_mode]) {
- idx = pcam->dev_inst_map[image_mode]->my_index;
- pcam_inst = pcam->dev_inst[idx];
- D("%s Found instance %p in video device\n",
- __func__, pcam_inst);
- }
}
- } else
- pr_err("%s Invalid image mode %d. Return NULL\n",
- __func__, image_mode);
+ } else {
+ if (pcam->mctl_node.dev_inst_map[img_mode]) {
+ idx = pcam->mctl_node.dev_inst_map[img_mode]->my_index;
+ pcam_inst = pcam->mctl_node.dev_inst[idx];
+ D("%s Found instance %p in mctl node device\n",
+ __func__, pcam_inst);
+ } else if (pcam->dev_inst_map[img_mode]) {
+ idx = pcam->dev_inst_map[img_mode]->my_index;
+ pcam_inst = pcam->dev_inst[idx];
+ D("%s Found instance %p in video device\n",
+ __func__, pcam_inst);
+ }
+ }
+ return pcam_inst;
+}
+
+struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst(
+ struct msm_cam_media_controller *pmctl,
+ struct msm_cam_buf_handle *buf_handle)
+{
+ struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
+ struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
+ int idx;
+
+ /* Get the pcam instance on based on the following rules:
+ * If the lookup type is
+ * - By instance handle:
+ * Either mctl_pp inst idx or video inst idx should be set.
+ * Try to get the MCTL_PP inst idx first, if its not set,
+ * fall back to video inst idx. Once we get the inst idx,
+ * get the pcam_inst from the corresponding dev_inst[] map.
+ * If neither are set, its a serious error, trigger a BUG_ON.
+ * - By image mode:(Legacy usecase)
+ * If vfe is in configured in snapshot mode, first check if
+ * mctl pp node has a instance created for this image mode
+ * and if there is a buffer queued for that instance.
+ * If so, return that instance, otherwise get the pcam instance
+ * for this image_mode from the video instance.
+ * If the vfe is configured in any other mode, then first check
+ * if mctl pp node has a instance created for this image mode,
+ * otherwise get the pcam instance for this image mode from the
+ * video instance.
+ */
+ if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+ idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
+ if (idx > MSM_DEV_INST_MAX) {
+ idx = GET_VIDEO_INST_IDX(buf_handle->inst_handle);
+ BUG_ON(idx > MSM_DEV_INST_MAX);
+ pcam_inst = pcam->dev_inst[idx];
+ } else {
+ pcam_inst = pcam->mctl_node.dev_inst[idx];
+ }
+ } else if ((buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE)
+ && (buf_handle->image_mode >= 0 &&
+ buf_handle->image_mode < MSM_V4L2_EXT_CAPTURE_MODE_MAX)) {
+ pcam_inst = msm_mctl_get_inst_by_img_mode(pmctl,
+ buf_handle->image_mode);
+ } else {
+ pr_err("%s Invalid buffer lookup type %d", __func__,
+ buf_handle->buf_lookup_type);
+ }
return pcam_inst;
}
int msm_mctl_reserve_free_buf(
- struct msm_cam_media_controller *pmctl,
- struct msm_cam_v4l2_dev_inst *pref_pcam_inst,
- int image_mode, struct msm_free_buf *free_buf)
+ struct msm_cam_media_controller *pmctl,
+ struct msm_cam_v4l2_dev_inst *pref_pcam_inst,
+ struct msm_cam_buf_handle *buf_handle,
+ struct msm_free_buf *free_buf)
{
struct msm_cam_v4l2_dev_inst *pcam_inst = pref_pcam_inst;
unsigned long flags = 0;
@@ -568,8 +641,8 @@
int rc = -EINVAL, i;
uint32_t buf_idx, plane_offset = 0;
- if (!free_buf || !pmctl) {
- pr_err("%s: free_buf/pmctl is null\n", __func__);
+ if (!free_buf || !pmctl || !buf_handle) {
+ pr_err("%s: Invalid argument passed\n", __func__);
return rc;
}
memset(free_buf, 0, sizeof(struct msm_free_buf));
@@ -579,7 +652,7 @@
* If the preferred camera instance is NULL, get the
* camera instance using the image mode passed */
if (!pcam_inst)
- pcam_inst = msm_mctl_get_pcam_inst(pmctl, image_mode);
+ pcam_inst = msm_mctl_get_pcam_inst(pmctl, buf_handle);
if (!pcam_inst || !pcam_inst->streamon) {
pr_err("%s: stream is turned off\n", __func__);
@@ -641,7 +714,7 @@
int msm_mctl_release_free_buf(struct msm_cam_media_controller *pmctl,
struct msm_cam_v4l2_dev_inst *pcam_inst,
- int image_mode, struct msm_free_buf *free_buf)
+ struct msm_free_buf *free_buf)
{
unsigned long flags = 0;
struct msm_frame_buffer *buf = NULL;
@@ -677,20 +750,39 @@
}
int msm_mctl_buf_done_pp(struct msm_cam_media_controller *pmctl,
- int image_mode, struct msm_free_buf *frame, int dirty, int node_type)
+ struct msm_cam_buf_handle *buf_handle,
+ struct msm_free_buf *frame, int dirty, int node_type)
{
- struct msm_cam_v4l2_dev_inst *pcam_inst;
+ struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
int rc = 0, idx;
- idx = msm_mctl_img_mode_to_inst_index(pmctl, image_mode, node_type);
- if (idx < 0) {
- pr_err("%s Invalid instance, buffer not released\n", __func__);
- return idx;
+ if (!pmctl || !buf_handle) {
+ pr_err("%s Invalid argument ", __func__);
+ return -EINVAL;
}
- if (node_type)
- pcam_inst = pmctl->pcam_ptr->mctl_node.dev_inst[idx];
- else
- pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
+
+ if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+ idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
+ if (idx > MSM_DEV_INST_MAX) {
+ idx = GET_VIDEO_INST_IDX(buf_handle->inst_handle);
+ BUG_ON(idx > MSM_DEV_INST_MAX);
+ pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
+ } else {
+ pcam_inst = pmctl->pcam_ptr->mctl_node.dev_inst[idx];
+ }
+ } else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
+ idx = msm_mctl_img_mode_to_inst_index(pmctl,
+ buf_handle->image_mode, node_type);
+ if (idx < 0) {
+ pr_err("%s Invalid instance, buffer not released\n",
+ __func__);
+ return idx;
+ }
+ if (node_type)
+ pcam_inst = pmctl->pcam_ptr->mctl_node.dev_inst[idx];
+ else
+ pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
+ }
if (!pcam_inst) {
pr_err("%s Invalid instance, cannot send buf to user",
__func__);
@@ -701,121 +793,12 @@
__func__, pcam_inst, frame->ch_paddr[0], dirty);
if (dirty)
/* the frame is dirty, not going to disptach to app */
- rc = msm_mctl_release_free_buf(pmctl, pcam_inst,
- image_mode, frame);
+ rc = msm_mctl_release_free_buf(pmctl, pcam_inst, frame);
else
- rc = msm_mctl_buf_done_proc(pmctl, pcam_inst,
- image_mode, frame, NULL, 0);
+ rc = msm_mctl_buf_done_proc(pmctl, pcam_inst, frame, NULL, 0);
return rc;
}
-struct msm_frame_buffer *msm_mctl_get_free_buf(
- struct msm_cam_media_controller *pmctl,
- int image_mode)
-{
- struct msm_cam_v4l2_dev_inst *pcam_inst;
- unsigned long flags = 0;
- struct msm_frame_buffer *buf = NULL;
- int rc = -EINVAL, idx;
-
- idx = msm_mctl_img_mode_to_inst_index(pmctl,
- image_mode, 0);
- if (idx < 0) {
- pr_err("%s Invalid instance, cant get buffer\n", __func__);
- return NULL;
- }
- pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
- if (!pcam_inst->streamon) {
- D("%s: stream 0x%p is off\n", __func__, pcam_inst);
- return NULL;
- }
- spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
- if (!list_empty(&pcam_inst->free_vq)) {
- list_for_each_entry(buf, &pcam_inst->free_vq, list) {
- if (buf->state == MSM_BUFFER_STATE_QUEUED) {
- buf->state = MSM_BUFFER_STATE_RESERVED;
- rc = 0;
- break;
- }
- }
- }
- if (rc != 0) {
- D("%s:No free buffer available: inst = 0x%p ",
- __func__, pcam_inst);
- buf = NULL;
- }
- spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
- return buf;
-}
-
-int msm_mctl_put_free_buf(
- struct msm_cam_media_controller *pmctl,
- int image_mode, struct msm_frame_buffer *my_buf)
-{
- struct msm_cam_v4l2_dev_inst *pcam_inst;
- unsigned long flags = 0;
- int rc = 0, idx;
- struct msm_frame_buffer *buf = NULL;
-
- idx = msm_mctl_img_mode_to_inst_index(pmctl,
- image_mode, 0);
- if (idx < 0) {
- pr_err("%s Invalid instance, cant put buffer\n", __func__);
- return idx;
- }
- pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
- if (!pcam_inst->streamon) {
- D("%s: stream 0x%p is off\n", __func__, pcam_inst);
- return rc;
- }
- spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
- if (!list_empty(&pcam_inst->free_vq)) {
- list_for_each_entry(buf, &pcam_inst->free_vq, list) {
- if (my_buf == buf) {
- buf->state = MSM_BUFFER_STATE_QUEUED;
- spin_unlock_irqrestore(&pcam_inst->vq_irqlock,
- flags);
- return 0;
- }
- }
- }
- spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
- return rc;
-}
-
-int msm_mctl_buf_del(struct msm_cam_media_controller *pmctl,
- int image_mode,
- struct msm_frame_buffer *my_buf)
-{
- struct msm_cam_v4l2_dev_inst *pcam_inst;
- struct msm_frame_buffer *buf = NULL;
- unsigned long flags = 0;
- int idx;
-
- idx = msm_mctl_img_mode_to_inst_index(pmctl,
- image_mode, 0);
- if (idx < 0) {
- pr_err("%s Invalid instance, cant delete buffer\n", __func__);
- return idx;
- }
- pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
- D("%s: idx = %d, pinst=0x%p", __func__, idx, pcam_inst);
- spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
- if (!list_empty(&pcam_inst->free_vq)) {
- list_for_each_entry(buf, &pcam_inst->free_vq, list) {
- if (my_buf == buf) {
- list_del_init(&buf->list);
- spin_unlock_irqrestore(&pcam_inst->vq_irqlock,
- flags);
- return 0;
- }
- }
- }
- spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
- pr_err("%s: buf 0x%p not found", __func__, my_buf);
- return -EINVAL;
-}
-
int msm_mctl_buf_return_buf(struct msm_cam_media_controller *pmctl,
int image_mode, struct msm_frame_buffer *rbuf)
{
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index abcee4b..dcb7c51 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -153,61 +153,96 @@
spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
return 0;
}
+
static struct msm_cam_v4l2_dev_inst *msm_mctl_get_pcam_inst_for_divert(
- struct msm_cam_media_controller *pmctl,
- int image_mode, struct msm_free_buf *fbuf, int *node_type)
+ struct msm_cam_media_controller *pmctl,
+ struct msm_cam_buf_handle *buf_handle,
+ struct msm_free_buf *fbuf, int *node_type)
{
struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
int idx;
+ uint32_t img_mode;
- if (image_mode >= 0) {
- /* Valid image mode. Search the mctl node first.
- * If mctl node doesnt have the instance, then
- * search in the user's video node */
- if (pcam->mctl_node.dev_inst_map[image_mode]
- && is_buf_in_queue(pcam, fbuf, image_mode)) {
- idx =
- pcam->mctl_node.dev_inst_map[image_mode]->my_index;
- pcam_inst = pcam->mctl_node.dev_inst[idx];
- *node_type = MCTL_NODE;
- D("%s Found instance %p in mctl node device\n",
- __func__, pcam_inst);
- } else if (pcam->dev_inst_map[image_mode]) {
- idx = pcam->dev_inst_map[image_mode]->my_index;
+ if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+ idx = GET_MCTLPP_INST_IDX(buf_handle->inst_handle);
+ if (idx > MSM_DEV_INST_MAX) {
+ idx = GET_VIDEO_INST_IDX(buf_handle->inst_handle);
+ BUG_ON(idx > MSM_DEV_INST_MAX);
pcam_inst = pcam->dev_inst[idx];
*node_type = VIDEO_NODE;
- D("%s Found instance %p in video device",
- __func__, pcam_inst);
- } else
+ } else {
+ pcam_inst = pcam->mctl_node.dev_inst[idx];
+ *node_type = MCTL_NODE;
+ }
+ } else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
+ img_mode = buf_handle->image_mode;
+ if (img_mode >= 0 && img_mode < MSM_V4L2_EXT_CAPTURE_MODE_MAX) {
+ /* Valid image mode. Search the mctl node first.
+ * If mctl node doesnt have the instance, then
+ * search in the user's video node */
+ if (pcam->mctl_node.dev_inst_map[img_mode]
+ && is_buf_in_queue(pcam, fbuf, img_mode)) {
+ idx = pcam->mctl_node.
+ dev_inst_map[img_mode]->my_index;
+ pcam_inst = pcam->mctl_node.dev_inst[idx];
+ *node_type = MCTL_NODE;
+ D("%s Found instance %p in mctl node device\n",
+ __func__, pcam_inst);
+ } else if (pcam->dev_inst_map[img_mode]) {
+ idx = pcam->dev_inst_map[img_mode]->my_index;
+ pcam_inst = pcam->dev_inst[idx];
+ *node_type = VIDEO_NODE;
+ D("%s Found instance %p in video device",
+ __func__, pcam_inst);
+ } else {
+ pr_err("%s Cannot find instance for %d.\n",
+ __func__, img_mode);
+ }
+ } else {
pr_err("%s Invalid image mode %d. Return NULL\n",
- __func__, image_mode);
+ __func__, buf_handle->image_mode);
+ }
+ } else {
+ pr_err("%s Invalid buffer lookup type ", __func__);
}
- return pcam_inst;
+ return pcam_inst;
}
int msm_mctl_do_pp_divert(
struct msm_cam_media_controller *p_mctl,
- int image_mode, struct msm_free_buf *fbuf,
+ struct msm_cam_buf_handle *buf_handle,
+ struct msm_free_buf *fbuf,
uint32_t frame_id, int pp_type)
{
struct msm_cam_v4l2_dev_inst *pcam_inst;
- int rc = 0, i, buf_idx;
+ int rc = 0, i, buf_idx, node;
int del_buf = 0; /* delete from free queue */
struct msm_cam_evt_divert_frame div;
struct msm_frame_buffer *vb = NULL;
struct videobuf2_contig_pmem *mem;
- int node;
+ uint32_t image_mode;
- pcam_inst = msm_mctl_get_pcam_inst_for_divert
- (p_mctl, image_mode, fbuf, &node);
+ if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
+ image_mode = buf_handle->image_mode;
+ div.frame.inst_handle = 0;
+ } else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_INST_HANDLE) {
+ image_mode = GET_IMG_MODE(buf_handle->inst_handle);
+ div.frame.inst_handle = buf_handle->inst_handle;
+ } else {
+ pr_err("%s Invalid buffer lookup type %d ", __func__,
+ buf_handle->buf_lookup_type);
+ return -EINVAL;
+ }
+
+ pcam_inst = msm_mctl_get_pcam_inst_for_divert(p_mctl,
+ buf_handle, fbuf, &node);
if (!pcam_inst) {
pr_err("%s Invalid instance. Cannot divert frame.\n",
__func__);
return -EINVAL;
}
- vb = msm_mctl_buf_find(p_mctl, pcam_inst,
- del_buf, image_mode, fbuf);
+ vb = msm_mctl_buf_find(p_mctl, pcam_inst, del_buf, fbuf);
if (!vb)
return -EINVAL;
@@ -392,50 +427,16 @@
struct msm_mctl_pp_cmd *pp_cmd)
{
int rc = 0;
- struct msm_mctl_pp_frame_buffer pp_buffer;
- struct msm_frame_buffer *buf = NULL;
- void __user *argp = (void __user *)pp_cmd->value;
- int img_mode;
unsigned long flags;
switch (pp_cmd->id) {
- case MCTL_CMD_GET_FRAME_BUFFER: {
- if (copy_from_user(&pp_buffer, pp_cmd->value,
- sizeof(pp_buffer)))
- return -EFAULT;
- img_mode = msm_mctl_pp_path_to_img_mode(pp_buffer.path);
- if (img_mode < 0) {
- pr_err("%s Invalid image mode\n", __func__);
- return img_mode;
- }
- buf = msm_mctl_get_free_buf(p_mctl, img_mode);
- pp_buffer.buf_handle = (uint32_t)buf;
- if (copy_to_user((void *)argp,
- &pp_buffer,
- sizeof(struct msm_mctl_pp_frame_buffer))) {
- ERR_COPY_TO_USER();
- rc = -EFAULT;
- }
- break;
- }
- case MCTL_CMD_PUT_FRAME_BUFFER: {
- if (copy_from_user(&pp_buffer, pp_cmd->value,
- sizeof(pp_buffer)))
- return -EFAULT;
- img_mode = msm_mctl_pp_path_to_img_mode(pp_buffer.path);
- if (img_mode < 0) {
- pr_err("%s Invalid image mode\n", __func__);
- return img_mode;
- }
- buf = (struct msm_frame_buffer *)pp_buffer.buf_handle;
- msm_mctl_put_free_buf(p_mctl, img_mode, buf);
- break;
- }
case MCTL_CMD_DIVERT_FRAME_PP_PATH: {
struct msm_mctl_pp_divert_pp divert_pp;
if (copy_from_user(&divert_pp, pp_cmd->value,
- sizeof(divert_pp)))
+ sizeof(divert_pp))) {
+ ERR_COPY_FROM_USER();
return -EFAULT;
+ }
D("%s: PP_PATH, path=%d",
__func__, divert_pp.path);
spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
@@ -490,17 +491,20 @@
struct msm_cam_media_controller *p_mctl,
void __user *arg)
{
- struct msm_cam_evt_divert_frame frame;
+ struct msm_cam_evt_divert_frame div_frame;
int image_mode, rc = 0;
struct msm_free_buf free_buf;
struct msm_cam_v4l2_dev_inst *pcam_inst;
+ struct msm_cam_buf_handle buf_handle;
memset(&free_buf, 0, sizeof(struct msm_free_buf));
- if (copy_from_user(&frame, arg,
- sizeof(struct msm_cam_evt_divert_frame)))
+ if (copy_from_user(&div_frame, arg,
+ sizeof(struct msm_cam_evt_divert_frame))) {
+ ERR_COPY_FROM_USER();
return -EFAULT;
+ }
- image_mode = frame.image_mode;
+ image_mode = div_frame.image_mode;
if (image_mode <= 0) {
pr_err("%s Invalid image mode %d", __func__, image_mode);
return -EINVAL;
@@ -511,17 +515,25 @@
pr_err("%s Instance already closed ", __func__);
return -EINVAL;
}
+ if (div_frame.frame.inst_handle) {
+ buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+ buf_handle.inst_handle = div_frame.frame.inst_handle;
+ } else {
+ buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+ buf_handle.image_mode = image_mode;
+ }
rc = msm_mctl_reserve_free_buf(p_mctl, pcam_inst,
- image_mode, &free_buf);
+ &buf_handle, &free_buf);
if (rc == 0) {
- msm_mctl_pp_get_phy_addr(pcam_inst, free_buf.vb, &frame.frame);
- if (copy_to_user((void *)arg, &frame, sizeof(frame))) {
+ msm_mctl_pp_get_phy_addr(pcam_inst,
+ free_buf.vb, &div_frame.frame);
+ if (copy_to_user((void *)arg, &div_frame, sizeof(div_frame))) {
ERR_COPY_TO_USER();
rc = -EFAULT;
}
}
D("%s: reserve free buf got buffer %d from %p rc = %d, phy = 0x%x",
- __func__, frame.frame.buf_idx,
+ __func__, div_frame.frame.buf_idx,
pcam_inst, rc, free_buf.ch_paddr[0]);
return rc;
}
@@ -535,10 +547,13 @@
struct msm_pp_frame *frame;
int image_mode, rc = 0;
struct msm_free_buf free_buf;
+ struct msm_cam_buf_handle buf_handle;
if (copy_from_user(&div_frame, arg,
- sizeof(struct msm_cam_evt_divert_frame)))
+ sizeof(struct msm_cam_evt_divert_frame))) {
+ ERR_COPY_FROM_USER();
return -EFAULT;
+ }
image_mode = div_frame.image_mode;
if (image_mode < 0) {
@@ -551,15 +566,21 @@
else
free_buf.ch_paddr[0] = frame->sp.phy_addr;
- pcam_inst = msm_mctl_get_pcam_inst(p_mctl, image_mode);
+ if (div_frame.frame.inst_handle) {
+ buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+ buf_handle.inst_handle = div_frame.frame.inst_handle;
+ } else {
+ buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+ buf_handle.image_mode = image_mode;
+ }
+ pcam_inst = msm_mctl_get_pcam_inst(p_mctl, &buf_handle);
if (!pcam_inst) {
pr_err("%s Invalid instance. Cannot release frame.\n",
__func__);
return -EINVAL;
}
- rc = msm_mctl_release_free_buf(p_mctl, pcam_inst,
- image_mode, &free_buf);
+ rc = msm_mctl_release_free_buf(p_mctl, pcam_inst, &free_buf);
D("%s: release free buf, rc = %d, phy = 0x%x",
__func__, rc, free_buf.ch_paddr[0]);
@@ -573,11 +594,13 @@
unsigned long flags;
spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
if (copy_from_user(&p_mctl->pp_info.pp_key,
- arg, sizeof(p_mctl->pp_info.pp_key)))
+ arg, sizeof(p_mctl->pp_info.pp_key))) {
+ ERR_COPY_FROM_USER();
rc = -EFAULT;
- else
+ } else {
D("%s: mctl=0x%p, pp_key_setting=0x%x",
__func__, p_mctl, p_mctl->pp_info.pp_key);
+ }
spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
return rc;
}
@@ -591,12 +614,24 @@
int dirty = 0;
struct msm_free_buf buf;
unsigned long flags;
+ struct msm_cam_buf_handle buf_handle;
- if (copy_from_user(&frame, arg, sizeof(frame)))
+ if (copy_from_user(&frame, arg, sizeof(frame))) {
+ ERR_COPY_FROM_USER();
return -EFAULT;
+ }
spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
- image_mode = msm_mctl_pp_path_to_img_mode(frame.path);
+ if (frame.inst_handle) {
+ buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+ buf_handle.inst_handle = frame.inst_handle;
+ image_mode = GET_IMG_MODE(frame.inst_handle);
+ } else {
+ buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+ buf_handle.image_mode =
+ msm_mctl_pp_path_to_img_mode(frame.path);
+ image_mode = buf_handle.image_mode;
+ }
if (image_mode < 0) {
pr_err("%s Invalid image mode\n", __func__);
return image_mode;
@@ -622,8 +657,7 @@
buf.ch_paddr[0] = frame.sp.phy_addr + frame.sp.y_off;
}
spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
- /* here buf.addr is phy_addr */
- rc = msm_mctl_buf_done_pp(p_mctl, image_mode, &buf, dirty, 0);
+ rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle, &buf, dirty, 0);
return rc;
}
@@ -636,10 +670,14 @@
int dirty = 0;
struct msm_free_buf buf;
unsigned long flags;
+ struct msm_cam_buf_handle buf_handle;
+
D("%s enter\n", __func__);
- if (copy_from_user(&frame, arg, sizeof(frame)))
+ if (copy_from_user(&frame, arg, sizeof(frame))) {
+ ERR_COPY_FROM_USER();
return -EFAULT;
+ }
spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
D("%s Frame path: %d\n", __func__, frame.path);
@@ -665,6 +703,14 @@
goto err;
}
+ if (frame.inst_handle) {
+ buf_handle.buf_lookup_type = BUF_LOOKUP_BY_INST_HANDLE;
+ buf_handle.inst_handle = frame.inst_handle;
+ } else {
+ buf_handle.buf_lookup_type = BUF_LOOKUP_BY_IMG_MODE;
+ buf_handle.image_mode = image_mode;
+ }
+
if (frame.num_planes > 1)
buf.ch_paddr[0] = frame.mp[0].phy_addr +
frame.mp[0].data_offset;
@@ -673,7 +719,7 @@
spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
D("%s Frame done id: %d\n", __func__, frame.frame_id);
- rc = msm_mctl_buf_done_pp(p_mctl, image_mode,
+ rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle,
&buf, dirty, frame.node_type);
return rc;
err:
diff --git a/drivers/media/video/msm/msm_vfe31_v4l2.c b/drivers/media/video/msm/msm_vfe31_v4l2.c
index b520a92..18168ee 100644
--- a/drivers/media/video/msm/msm_vfe31_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe31_v4l2.c
@@ -643,7 +643,7 @@
vfe31_ctrl->vfebase + VFE_GLOBAL_RESET);
}
-static void vfe31_subdev_notify(int id, int path, int image_mode)
+static void vfe31_subdev_notify(int id, int path, uint32_t inst_handle)
{
struct msm_vfe_resp rp;
struct msm_frame_info frame_info;
@@ -652,7 +652,7 @@
memset(&rp, 0, sizeof(struct msm_vfe_resp));
CDBG("vfe31_subdev_notify : msgId = %d\n", id);
rp.evt_msg.type = MSM_CAMERA_MSG;
- frame_info.image_mode = image_mode;
+ frame_info.inst_handle = inst_handle;
frame_info.path = path;
rp.evt_msg.data = &frame_info;
rp.type = id;
@@ -663,20 +663,21 @@
static int vfe31_config_axi(int mode, uint32_t *ao)
{
uint32_t *ch_info;
- uint32_t *axi_cfg = ao+V31_AXI_RESERVED;
+ uint32_t *axi_cfg = ao + V31_AXI_RESERVED;
/* Update the corresponding write masters for each output*/
ch_info = axi_cfg + V31_AXI_CFG_LEN;
vfe31_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
vfe31_ctrl->outpath.out0.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
- vfe31_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info;
- vfe31_ctrl->outpath.out0.image_mode = 0x0000FFFF & (*ch_info++ >> 16);
+ vfe31_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
+ vfe31_ctrl->outpath.out0.inst_handle = *ch_info++;
vfe31_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
vfe31_ctrl->outpath.out1.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
- vfe31_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info;
- vfe31_ctrl->outpath.out1.image_mode = 0x0000FFFF & (*ch_info++ >> 16);
+ vfe31_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
+ vfe31_ctrl->outpath.out1.inst_handle = *ch_info++;
vfe31_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
vfe31_ctrl->outpath.out2.ch1 = 0x0000FFFF & (*ch_info++ >> 16);
vfe31_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+ vfe31_ctrl->outpath.out2.inst_handle = *ch_info++;
switch (mode) {
case OUTPUT_PRIM:
@@ -713,7 +714,7 @@
msm_camera_io_memcpy(vfe31_ctrl->vfebase +
vfe31_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length - V31_AXI_CH_INF_LEN -
- V31_AXI_RESERVED);
+ V31_AXI_RESERVED_LEN);
return 0;
}
@@ -1301,14 +1302,14 @@
{
struct vfe31_output_ch *outch = NULL;
struct msm_free_buf *b = NULL;
- uint32_t image_mode = 0;
+ uint32_t inst_handle = 0;
if (path == VFE_MSG_OUTPUT_PRIMARY)
- image_mode = vfe31_ctrl->outpath.out0.image_mode;
+ inst_handle = vfe31_ctrl->outpath.out0.inst_handle;
else
- image_mode = vfe31_ctrl->outpath.out1.image_mode;
+ inst_handle = vfe31_ctrl->outpath.out1.inst_handle;
- vfe31_subdev_notify(id, path, image_mode);
+ vfe31_subdev_notify(id, path, inst_handle);
outch = vfe31_get_ch(path);
if (outch->free_buf.ch_paddr[0])
b = &outch->free_buf;
@@ -1318,14 +1319,14 @@
{
struct vfe31_output_ch *outch = NULL;
int rc = 0;
- uint32_t image_mode = 0;
+ uint32_t inst_handle = 0;
if (path == VFE_MSG_OUTPUT_PRIMARY)
- image_mode = vfe31_ctrl->outpath.out0.image_mode;
+ inst_handle = vfe31_ctrl->outpath.out0.inst_handle;
else
- image_mode = vfe31_ctrl->outpath.out1.image_mode;
+ inst_handle = vfe31_ctrl->outpath.out1.inst_handle;
- vfe31_subdev_notify(id, path, image_mode);
+ vfe31_subdev_notify(id, path, inst_handle);
outch = vfe31_get_ch(path);
if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
/* Configure Preview Ping Pong */
@@ -1477,16 +1478,26 @@
case VFE_CMD_START_RECORDING:
pr_info("vfe31_proc_general: cmdID = %s\n",
vfe31_general_cmd[cmd->id]);
+ if (copy_from_user(&temp1, (void __user *)(cmd->value),
+ sizeof(uint32_t))) {
+ pr_err("%s Error copying inst_handle for recording\n",
+ __func__);
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
if (vfe31_ctrl->operation_mode ==
- VFE_OUTPUTS_PREVIEW_AND_VIDEO)
+ VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+ vfe31_ctrl->outpath.out1.inst_handle = temp1;
rc = vfe31_configure_pingpong_buffers(
VFE_MSG_V31_START_RECORDING,
VFE_MSG_OUTPUT_SECONDARY);
- else if (vfe31_ctrl->operation_mode ==
- VFE_OUTPUTS_VIDEO_AND_PREVIEW)
+ } else if (vfe31_ctrl->operation_mode ==
+ VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+ vfe31_ctrl->outpath.out0.inst_handle = temp1;
rc = vfe31_configure_pingpong_buffers(
VFE_MSG_V31_START_RECORDING,
VFE_MSG_OUTPUT_PRIMARY);
+ }
if (rc < 0) {
pr_err("%s error configuring pingpong buffers"
" for video", __func__);
@@ -1916,6 +1927,14 @@
break;
case VFE_CMD_LIVESHOT:
+ if (copy_from_user(&temp1, (void __user *)(cmd->value),
+ sizeof(uint32_t))) {
+ pr_err("%s Error copying inst_handle for liveshot ",
+ __func__);
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
+ vfe31_ctrl->outpath.out0.inst_handle = temp1;
/* Configure primary channel */
rc = vfe31_configure_pingpong_buffers(VFE_MSG_V31_CAPTURE,
VFE_MSG_OUTPUT_PRIMARY);
@@ -2715,12 +2734,12 @@
}
static void vfe_send_outmsg(struct v4l2_subdev *sd, uint8_t msgid,
uint32_t ch0_paddr, uint32_t ch1_paddr,
- uint32_t ch2_paddr, uint32_t image_mode)
+ uint32_t ch2_paddr, uint32_t inst_handle)
{
struct isp_msg_output msg;
msg.output_id = msgid;
- msg.buf.image_mode = image_mode;
+ msg.buf.inst_handle = inst_handle;
msg.buf.ch_paddr[0] = ch0_paddr;
msg.buf.ch_paddr[1] = ch1_paddr;
msg.buf.ch_paddr[2] = ch2_paddr;
@@ -2803,7 +2822,7 @@
vfe_send_outmsg(&vfe31_ctrl->subdev,
MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
ch1_paddr, ch2_paddr,
- vfe31_ctrl->outpath.out0.image_mode);
+ vfe31_ctrl->outpath.out0.inst_handle);
if (vfe31_ctrl->liveshot_state == VFE_STATE_STOPPED)
vfe31_ctrl->liveshot_state = VFE_STATE_IDLE;
@@ -2876,7 +2895,7 @@
vfe_send_outmsg(&vfe31_ctrl->subdev,
MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
ch1_paddr, ch2_paddr,
- vfe31_ctrl->outpath.out1.image_mode);
+ vfe31_ctrl->outpath.out1.inst_handle);
} else {
vfe31_ctrl->outpath.out1.frame_drop_cnt++;
CDBG("path_irq_1 - no free buffer!\n");
@@ -3541,15 +3560,25 @@
struct msm_cam_media_controller *pmctl =
(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
struct msm_isp_cmd vfecmd;
- struct msm_camvfe_params *vfe_params =
- (struct msm_camvfe_params *)arg;
- struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
- void *data = vfe_params->data;
+ struct msm_camvfe_params *vfe_params;
+ struct msm_vfe_cfg_cmd *cmd;
+ void *data;
long rc = 0;
struct vfe_cmd_stats_buf *scfg = NULL;
struct vfe_cmd_stats_ack *sack = NULL;
+ if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
+ CDBG("%s init\n", __func__);
+ return msm_vfe_subdev_init(sd);
+ } else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
+ msm_vfe_subdev_release(sd);
+ return 0;
+ }
+ vfe_params = (struct msm_camvfe_params *)arg;
+ cmd = vfe_params->vfe_cfg;
+ data = vfe_params->data;
+
switch (cmd->cmd_type) {
case VFE_CMD_STATS_REQBUF:
case VFE_CMD_STATS_ENQUEUEBUF:
@@ -3575,186 +3604,190 @@
return -EFAULT;
}
} else {
- /* here eith stats release or frame release. */
- if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
- cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
- cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR) {
- /* then must be stats release. */
- if (!data) {
- pr_err("%s: data = NULL, cmd->cmd_type = %d",
- __func__, cmd->cmd_type);
- return -EFAULT;
- }
- sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
+ /* here eith stats release or frame release. */
+ if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
+ cmd->cmd_type != CMD_CONFIG_PONG_ADDR &&
+ cmd->cmd_type != CMD_CONFIG_FREE_BUF_ADDR) {
+ /* then must be stats release. */
+ if (!data) {
+ pr_err("%s: data = NULL," \
+ "cmd->cmd_type = %d\n",
+ __func__, cmd->cmd_type);
+ return -EFAULT;
+ }
+ sack = kmalloc(sizeof(struct vfe_cmd_stats_ack),
GFP_ATOMIC);
- if (!sack) {
- pr_err("%s: no mem for cmd->cmd_type = %d",
- __func__, cmd->cmd_type);
- return -ENOMEM;
+ if (!sack) {
+ pr_err("%s: no mem for" \
+ "cmd->cmd_type = %d\n",
+ __func__, cmd->cmd_type);
+ return -ENOMEM;
+ }
+
+ sack->nextStatsBuf = *(uint32_t *)data;
+ }
+ }
+
+ CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
+
+ if ((cmd->cmd_type == CMD_STATS_AF_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_AWB_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_RS_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_CS_ENABLE) ||
+ (cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
+ scfg = NULL;
+ goto vfe31_config_done;
+ }
+ switch (cmd->cmd_type) {
+ case CMD_GENERAL: {
+ rc = vfe31_proc_general(pmctl, &vfecmd);
+ }
+ break;
+ case CMD_CONFIG_PING_ADDR: {
+ int path = *((int *)cmd->value);
+ struct vfe31_output_ch *outch = vfe31_get_ch(path);
+ outch->ping = *((struct msm_free_buf *)data);
+ }
+ break;
+
+ case CMD_CONFIG_PONG_ADDR: {
+ int path = *((int *)cmd->value);
+ struct vfe31_output_ch *outch = vfe31_get_ch(path);
+ outch->pong = *((struct msm_free_buf *)data);
+ }
+ break;
+
+ case CMD_CONFIG_FREE_BUF_ADDR: {
+ int path = *((int *)cmd->value);
+ struct vfe31_output_ch *outch = vfe31_get_ch(path);
+ outch->free_buf = *((struct msm_free_buf *)data);
+ }
+ break;
+
+ case CMD_SNAP_BUF_RELEASE:
+ break;
+
+ case CMD_AXI_CFG_PRIM: {
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio) {
+ rc = -ENOMEM;
+ break;
}
- sack->nextStatsBuf = *(uint32_t *)data;
- }
- }
-
- CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);
-
- if ((cmd->cmd_type == CMD_STATS_AF_ENABLE) ||
- (cmd->cmd_type == CMD_STATS_AWB_ENABLE) ||
- (cmd->cmd_type == CMD_STATS_IHIST_ENABLE) ||
- (cmd->cmd_type == CMD_STATS_RS_ENABLE) ||
- (cmd->cmd_type == CMD_STATS_CS_ENABLE) ||
- (cmd->cmd_type == CMD_STATS_AEC_ENABLE)) {
- scfg = NULL;
- goto vfe31_config_done;
- }
- switch (cmd->cmd_type) {
- case CMD_GENERAL: {
- rc = vfe31_proc_general(pmctl, &vfecmd);
- }
- break;
- case CMD_CONFIG_PING_ADDR: {
- int path = *((int *)cmd->value);
- struct vfe31_output_ch *outch = vfe31_get_ch(path);
- outch->ping = *((struct msm_free_buf *)data);
- }
- break;
-
- case CMD_CONFIG_PONG_ADDR: {
- int path = *((int *)cmd->value);
- struct vfe31_output_ch *outch = vfe31_get_ch(path);
- outch->pong = *((struct msm_free_buf *)data);
- }
- break;
-
- case CMD_CONFIG_FREE_BUF_ADDR: {
- int path = *((int *)cmd->value);
- struct vfe31_output_ch *outch = vfe31_get_ch(path);
- outch->free_buf = *((struct msm_free_buf *)data);
- }
- break;
-
- case CMD_SNAP_BUF_RELEASE:
- break;
-
- case CMD_AXI_CFG_PRIM: {
- uint32_t *axio = NULL;
- axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
- GFP_ATOMIC);
- if (!axio) {
- rc = -ENOMEM;
- break;
- }
-
- if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ rc = -EFAULT;
+ break;
+ }
+ vfe31_config_axi(OUTPUT_PRIM, axio);
kfree(axio);
- rc = -EFAULT;
+ }
break;
- }
- vfe31_config_axi(OUTPUT_PRIM, axio);
- kfree(axio);
- }
- break;
- case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
- uint32_t *axio = NULL;
- axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
- GFP_ATOMIC);
- if (!axio) {
- rc = -ENOMEM;
- break;
- }
+ case CMD_AXI_CFG_PRIM_ALL_CHNLS: {
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio) {
+ rc = -ENOMEM;
+ break;
+ }
- if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ rc = -EFAULT;
+ break;
+ }
+ vfe31_config_axi(OUTPUT_PRIM_ALL_CHNLS, axio);
kfree(axio);
- rc = -EFAULT;
+ }
break;
- }
- vfe31_config_axi(OUTPUT_PRIM_ALL_CHNLS, axio);
- kfree(axio);
- }
- break;
- case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
- uint32_t *axio = NULL;
- axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
- GFP_ATOMIC);
- if (!axio) {
- rc = -ENOMEM;
- break;
- }
+ case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC: {
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio) {
+ rc = -ENOMEM;
+ break;
+ }
- if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ rc = -EFAULT;
+ break;
+ }
+ vfe31_config_axi(OUTPUT_PRIM|OUTPUT_SEC, axio);
kfree(axio);
- rc = -EFAULT;
+ }
break;
- }
- vfe31_config_axi(OUTPUT_PRIM|OUTPUT_SEC, axio);
- kfree(axio);
- }
- break;
- case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
- uint32_t *axio = NULL;
- axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
- GFP_ATOMIC);
- if (!axio) {
- rc = -ENOMEM;
- break;
- }
+ case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS: {
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ GFP_ATOMIC);
+ if (!axio) {
+ rc = -ENOMEM;
+ break;
+ }
- if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ rc = -EFAULT;
+ break;
+ }
+ vfe31_config_axi
+ (OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
kfree(axio);
- rc = -EFAULT;
+ }
break;
- }
- vfe31_config_axi(OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS, axio);
- kfree(axio);
- }
- break;
- case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
- uint32_t *axio = NULL;
- axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
+ case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC: {
+ uint32_t *axio = NULL;
+ axio = kmalloc(vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length,
GFP_ATOMIC);
- if (!axio) {
- rc = -ENOMEM;
- break;
- }
+ if (!axio) {
+ rc = -ENOMEM;
+ break;
+ }
- if (copy_from_user(axio, (void __user *)(vfecmd.value),
+ if (copy_from_user(axio, (void __user *)(vfecmd.value),
vfe31_cmd[VFE_CMD_AXI_OUT_CFG].length)) {
+ kfree(axio);
+ rc = -EFAULT;
+ break;
+ }
+ vfe31_config_axi
+ (OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
kfree(axio);
- rc = -EFAULT;
+ }
break;
- }
- vfe31_config_axi(OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC, axio);
- kfree(axio);
- }
- break;
- case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS: {
- pr_err("%s Invalid/Unsupported AXI configuration %x",
- __func__, cmd->cmd_type);
- }
- break;
+ case CMD_AXI_CFG_PRIM_ALL_CHNLS|CMD_AXI_CFG_SEC_ALL_CHNLS: {
+ pr_err("%s Invalid/Unsupported AXI configuration %x",
+ __func__, cmd->cmd_type);
+ }
+ break;
- case CMD_AXI_START:
- /* No need to decouple AXI/VFE for VFE3.1*/
- break;
+ case CMD_AXI_START:
+ /* No need to decouple AXI/VFE for VFE3.1*/
+ break;
- case CMD_AXI_STOP:
- /* No need to decouple AXI/VFE for VFE3.1*/
- break;
+ case CMD_AXI_STOP:
+ /* No need to decouple AXI/VFE for VFE3.1*/
+ break;
- default:
- pr_err("%s Unsupported AXI configuration %x ", __func__,
- cmd->cmd_type);
- break;
+ default:
+ pr_err("%s Unsupported AXI configuration %x ", __func__,
+ cmd->cmd_type);
+ break;
}
}
vfe31_config_done:
@@ -3855,11 +3888,15 @@
usleep_range(10000, 15000);
}
-int msm_vfe_subdev_init(struct v4l2_subdev *sd,
- struct msm_cam_media_controller *mctl)
+int msm_vfe_subdev_init(struct v4l2_subdev *sd)
{
int rc = 0;
- v4l2_set_subdev_hostdata(sd, mctl);
+ struct msm_cam_media_controller *mctl;
+ mctl = v4l2_get_subdev_hostdata(sd);
+ if (mctl == NULL) {
+ rc = -EINVAL;
+ goto mctl_failed;
+ }
spin_lock_init(&vfe31_ctrl->stop_flag_lock);
spin_lock_init(&vfe31_ctrl->state_lock);
@@ -3939,6 +3976,7 @@
iounmap(vfe31_ctrl->vfebase);
vfe_remap_failed:
disable_irq(vfe31_ctrl->vfeirq->start);
+mctl_failed:
return rc;
}
@@ -4064,6 +4102,12 @@
sd_info.sd_index = 0;
sd_info.irq_num = vfe31_ctrl->vfeirq->start;
msm_cam_register_subdev_node(&vfe31_ctrl->subdev, &sd_info);
+
+ media_entity_init(&vfe31_ctrl->subdev.entity, 0, NULL, 0);
+ vfe31_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ vfe31_ctrl->subdev.entity.group_id = VFE_DEV;
+ vfe31_ctrl->subdev.entity.name = pdev->name;
+ vfe31_ctrl->subdev.entity.revision = vfe31_ctrl->subdev.devnode->num;
return 0;
vfe31_no_resource:
diff --git a/drivers/media/video/msm/msm_vfe31_v4l2.h b/drivers/media/video/msm/msm_vfe31_v4l2.h
index 2cba995..6396966 100644
--- a/drivers/media/video/msm/msm_vfe31_v4l2.h
+++ b/drivers/media/video/msm/msm_vfe31_v4l2.h
@@ -217,10 +217,11 @@
#define V31_OPERATION_CFG_LEN 32
#define V31_AXI_OUT_OFF 0x00000038
-#define V31_AXI_OUT_LEN 212
-#define V31_AXI_CH_INF_LEN 24
+#define V31_AXI_OUT_LEN 240
+#define V31_AXI_CH_INF_LEN 48
#define V31_AXI_CFG_LEN 47
#define V31_AXI_RESERVED 1
+#define V31_AXI_RESERVED_LEN 4
#define V31_FRAME_SKIP_OFF 0x00000504
#define V31_FRAME_SKIP_LEN 32
@@ -696,7 +697,7 @@
struct vfe31_output_ch {
struct list_head free_buf_queue;
spinlock_t free_buf_lock;
- uint16_t image_mode;
+ uint32_t inst_handle;
int8_t ch0;
int8_t ch1;
int8_t ch2;
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 396729e..38179e6 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -393,7 +393,7 @@
vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
}
-static void vfe32_subdev_notify(int id, int path, int image_mode,
+static void vfe32_subdev_notify(int id, int path, uint32_t inst_handle,
struct v4l2_subdev *sd, struct vfe_share_ctrl_t *share_ctrl)
{
struct msm_vfe_resp rp;
@@ -403,7 +403,7 @@
CDBG("vfe32_subdev_notify : msgId = %d\n", id);
memset(&rp, 0, sizeof(struct msm_vfe_resp));
rp.evt_msg.type = MSM_CAMERA_MSG;
- frame_info.image_mode = image_mode;
+ frame_info.inst_handle = inst_handle;
frame_info.path = path;
rp.evt_msg.data = &frame_info;
rp.type = id;
@@ -423,27 +423,27 @@
axi_ctrl->share_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info;
axi_ctrl->share_ctrl->outpath.out0.ch1 =
0x0000FFFF & (*ch_info++ >> 16);
- axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info;
- axi_ctrl->share_ctrl->outpath.out0.image_mode =
- 0x0000FFFF & (*ch_info++ >> 16);
+ axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info++;
+ axi_ctrl->share_ctrl->outpath.out0.inst_handle = *ch_info++;
+
axi_ctrl->share_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info;
axi_ctrl->share_ctrl->outpath.out1.ch1 =
0x0000FFFF & (*ch_info++ >> 16);
- axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info;
- axi_ctrl->share_ctrl->outpath.out1.image_mode =
- 0x0000FFFF & (*ch_info++ >> 16);
+ axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info++;
+ axi_ctrl->share_ctrl->outpath.out1.inst_handle = *ch_info++;
+
axi_ctrl->share_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info;
axi_ctrl->share_ctrl->outpath.out2.ch1 =
0x0000FFFF & (*ch_info++ >> 16);
- axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info;
- axi_ctrl->share_ctrl->outpath.out2.image_mode =
- 0x0000FFFF & (*ch_info++ >> 16);
+ axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++;
+ axi_ctrl->share_ctrl->outpath.out2.inst_handle = *ch_info++;
+
axi_ctrl->share_ctrl->outpath.out3.ch0 = 0x0000FFFF & *ch_info;
axi_ctrl->share_ctrl->outpath.out3.ch1 =
0x0000FFFF & (*ch_info++ >> 16);
- axi_ctrl->share_ctrl->outpath.out3.ch2 = 0x0000FFFF & *ch_info;
- axi_ctrl->share_ctrl->outpath.out3.image_mode =
- 0x0000FFFF & (*ch_info++ >> 16);
+ axi_ctrl->share_ctrl->outpath.out3.ch2 = 0x0000FFFF & *ch_info++;
+ axi_ctrl->share_ctrl->outpath.out3.inst_handle = *ch_info++;
+
axi_ctrl->share_ctrl->outpath.output_mode = 0;
if (mode & OUTPUT_TERT1)
@@ -956,6 +956,8 @@
vfe32_ctrl->share_ctrl->vfe_capture_count =
vfe32_ctrl->share_ctrl->outpath.out0.capture_cnt;
+ msm_camio_bus_scale_cfg(
+ pmctl->sdata->pdata->cam_bus_scale_table, S_LIVESHOT);
vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_START_REQUESTED;
msm_camera_io_w_mb(1, vfe32_ctrl->
share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
@@ -968,6 +970,8 @@
vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_STOP_REQUESTED;
msm_camera_io_w_mb(1,
vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ msm_camio_bus_scale_cfg(
+ pmctl->sdata->pdata->cam_bus_scale_table, S_VIDEO);
}
static int vfe32_zsl(
@@ -1464,18 +1468,18 @@
{
struct vfe32_output_ch *outch = NULL;
struct msm_free_buf *b = NULL;
- uint32_t image_mode = 0;
+ uint32_t inst_handle = 0;
if (path == VFE_MSG_OUTPUT_PRIMARY)
- image_mode = axi_ctrl->share_ctrl->outpath.out0.image_mode;
+ inst_handle = axi_ctrl->share_ctrl->outpath.out0.inst_handle;
else if (path == VFE_MSG_OUTPUT_SECONDARY)
- image_mode = axi_ctrl->share_ctrl->outpath.out1.image_mode;
+ inst_handle = axi_ctrl->share_ctrl->outpath.out1.inst_handle;
else if (path == VFE_MSG_OUTPUT_TERTIARY1)
- image_mode = axi_ctrl->share_ctrl->outpath.out2.image_mode;
+ inst_handle = axi_ctrl->share_ctrl->outpath.out2.inst_handle;
else if (path == VFE_MSG_OUTPUT_TERTIARY2)
- image_mode = axi_ctrl->share_ctrl->outpath.out3.image_mode;
+ inst_handle = axi_ctrl->share_ctrl->outpath.out3.inst_handle;
- vfe32_subdev_notify(id, path, image_mode,
+ vfe32_subdev_notify(id, path, inst_handle,
&axi_ctrl->subdev, axi_ctrl->share_ctrl);
outch = vfe32_get_ch(path, axi_ctrl->share_ctrl);
if (outch->free_buf.ch_paddr[0])
@@ -1487,17 +1491,17 @@
{
struct vfe32_output_ch *outch = NULL;
int rc = 0;
- uint32_t image_mode = 0;
+ uint32_t inst_handle = 0;
if (path == VFE_MSG_OUTPUT_PRIMARY)
- image_mode = vfe32_ctrl->share_ctrl->outpath.out0.image_mode;
+ inst_handle = vfe32_ctrl->share_ctrl->outpath.out0.inst_handle;
else if (path == VFE_MSG_OUTPUT_SECONDARY)
- image_mode = vfe32_ctrl->share_ctrl->outpath.out1.image_mode;
+ inst_handle = vfe32_ctrl->share_ctrl->outpath.out1.inst_handle;
else if (path == VFE_MSG_OUTPUT_TERTIARY1)
- image_mode = vfe32_ctrl->share_ctrl->outpath.out2.image_mode;
+ inst_handle = vfe32_ctrl->share_ctrl->outpath.out2.inst_handle;
else if (path == VFE_MSG_OUTPUT_TERTIARY2)
- image_mode = vfe32_ctrl->share_ctrl->outpath.out3.image_mode;
+ inst_handle = vfe32_ctrl->share_ctrl->outpath.out3.inst_handle;
- vfe32_subdev_notify(id, path, image_mode,
+ vfe32_subdev_notify(id, path, inst_handle,
&vfe32_ctrl->subdev, vfe32_ctrl->share_ctrl);
outch = vfe32_get_ch(path, vfe32_ctrl->share_ctrl);
if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
@@ -1704,18 +1708,30 @@
case VFE_CMD_START_RECORDING:
pr_info("vfe32_proc_general: cmdID = %s\n",
vfe32_general_cmd[cmd->id]);
+ if (copy_from_user(&temp1, (void __user *)(cmd->value),
+ sizeof(uint32_t))) {
+ pr_err("%s Error copying inst_handle for recording\n",
+ __func__);
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
if (vfe32_ctrl->share_ctrl->operation_mode &
- VFE_OUTPUTS_PREVIEW_AND_VIDEO)
+ VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+ vfe32_ctrl->share_ctrl->outpath.out1.inst_handle =
+ temp1;
rc = vfe32_configure_pingpong_buffers(
VFE_MSG_V32_START_RECORDING,
VFE_MSG_OUTPUT_SECONDARY,
vfe32_ctrl);
- else if (vfe32_ctrl->share_ctrl->operation_mode &
- VFE_OUTPUTS_VIDEO_AND_PREVIEW)
+ } else if (vfe32_ctrl->share_ctrl->operation_mode &
+ VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+ vfe32_ctrl->share_ctrl->outpath.out0.inst_handle =
+ temp1;
rc = vfe32_configure_pingpong_buffers(
VFE_MSG_V32_START_RECORDING,
VFE_MSG_OUTPUT_PRIMARY,
vfe32_ctrl);
+ }
if (rc < 0) {
pr_err("%s error configuring pingpong buffers"
" for video", __func__);
@@ -2187,6 +2203,14 @@
break;
case VFE_CMD_LIVESHOT:
+ if (copy_from_user(&temp1, (void __user *)(cmd->value),
+ sizeof(uint32_t))) {
+ pr_err("%s Error copying inst_handle for liveshot ",
+ __func__);
+ rc = -EFAULT;
+ goto proc_general_done;
+ }
+ vfe32_ctrl->share_ctrl->outpath.out0.inst_handle = temp1;
/* Configure primary channel */
rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE,
VFE_MSG_OUTPUT_PRIMARY, vfe32_ctrl);
@@ -3452,12 +3476,12 @@
static void vfe_send_outmsg(
struct axi_ctrl_t *axi_ctrl, uint8_t msgid,
uint32_t ch0_paddr, uint32_t ch1_paddr,
- uint32_t ch2_paddr, uint32_t image_mode)
+ uint32_t ch2_paddr, uint32_t inst_handle)
{
struct isp_msg_output msg;
msg.output_id = msgid;
- msg.buf.image_mode = image_mode;
+ msg.buf.inst_handle = inst_handle;
msg.buf.ch_paddr[0] = ch0_paddr;
msg.buf.ch_paddr[1] = ch1_paddr;
msg.buf.ch_paddr[2] = ch2_paddr;
@@ -3559,7 +3583,7 @@
vfe_send_outmsg(axi_ctrl,
MSG_ID_OUTPUT_PRIMARY, ch0_paddr,
ch1_paddr, ch2_paddr,
- axi_ctrl->share_ctrl->outpath.out0.image_mode);
+ axi_ctrl->share_ctrl->outpath.out0.inst_handle);
} else {
axi_ctrl->share_ctrl->outpath.out0.frame_drop_cnt++;
@@ -3637,7 +3661,7 @@
vfe_send_outmsg(axi_ctrl,
MSG_ID_OUTPUT_SECONDARY, ch0_paddr,
ch1_paddr, ch2_paddr,
- axi_ctrl->share_ctrl->outpath.out1.image_mode);
+ axi_ctrl->share_ctrl->outpath.out1.inst_handle);
} else {
axi_ctrl->share_ctrl->outpath.out1.frame_drop_cnt++;
@@ -3678,7 +3702,7 @@
vfe_send_outmsg(axi_ctrl,
MSG_ID_OUTPUT_TERTIARY1, ch0_paddr,
0, 0,
- axi_ctrl->share_ctrl->outpath.out2.image_mode);
+ axi_ctrl->share_ctrl->outpath.out2.inst_handle);
} else {
axi_ctrl->share_ctrl->outpath.out2.frame_drop_cnt++;
@@ -3719,7 +3743,7 @@
vfe_send_outmsg(axi_ctrl,
MSG_ID_OUTPUT_TERTIARY2, ch0_paddr,
0, 0,
- axi_ctrl->share_ctrl->outpath.out3.image_mode);
+ axi_ctrl->share_ctrl->outpath.out3.inst_handle);
} else {
axi_ctrl->share_ctrl->outpath.out3.frame_drop_cnt++;
pr_err("path_irq irq - no free buffer for rdi1!\n");
@@ -4515,10 +4539,9 @@
struct vfe32_ctrl_type *vfe32_ctrl =
(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
struct msm_isp_cmd vfecmd;
- struct msm_camvfe_params *vfe_params =
- (struct msm_camvfe_params *)arg;
- struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
- void *data = vfe_params->data;
+ struct msm_camvfe_params *vfe_params;
+ struct msm_vfe_cfg_cmd *cmd;
+ void *data;
long rc = 0;
struct vfe_cmd_stats_buf *scfg = NULL;
@@ -4529,6 +4552,17 @@
return -EFAULT;
}
+ CDBG("%s\n", __func__);
+ if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
+ CDBG("%s init\n", __func__);
+ return msm_vfe_subdev_init(sd);
+ } else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
+ msm_vfe_subdev_release(sd);
+ return 0;
+ }
+ vfe_params = (struct msm_camvfe_params *)arg;
+ cmd = vfe_params->vfe_cfg;
+ data = vfe_params->data;
switch (cmd->cmd_type) {
case CMD_VFE_PROCESS_IRQ:
vfe32_process_irq(vfe32_ctrl, (uint32_t) data);
@@ -4668,12 +4702,17 @@
.core = &msm_vfe_subdev_core_ops,
};
-int msm_axi_subdev_init(struct v4l2_subdev *sd,
- struct msm_cam_media_controller *mctl)
+int msm_axi_subdev_init(struct v4l2_subdev *sd)
{
int rc = 0;
struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
- v4l2_set_subdev_hostdata(sd, mctl);
+ struct msm_cam_media_controller *mctl;
+ mctl = v4l2_get_subdev_hostdata(sd);
+ if (mctl == NULL) {
+ pr_err("%s: mctl is NULL\n", __func__);
+ rc = -EINVAL;
+ goto mctl_failed;
+ }
spin_lock_init(&axi_ctrl->tasklet_lock);
INIT_LIST_HEAD(&axi_ctrl->tasklet_q);
spin_lock_init(&axi_ctrl->share_ctrl->sd_notify_lock);
@@ -4721,16 +4760,15 @@
axi_ctrl->share_ctrl->vfebase = NULL;
remap_failed:
disable_irq(axi_ctrl->vfeirq->start);
+mctl_failed:
return rc;
}
-int msm_vfe_subdev_init(struct v4l2_subdev *sd,
- struct msm_cam_media_controller *mctl)
+int msm_vfe_subdev_init(struct v4l2_subdev *sd)
{
int rc = 0;
struct vfe32_ctrl_type *vfe32_ctrl =
(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
- v4l2_set_subdev_hostdata(sd, mctl);
spin_lock_init(&vfe32_ctrl->share_ctrl->stop_flag_lock);
spin_lock_init(&vfe32_ctrl->state_lock);
@@ -5198,8 +5236,7 @@
int rc = -ENOIOCTLCMD;
switch (cmd) {
case VIDIOC_MSM_AXI_INIT:
- rc = msm_axi_subdev_init(sd,
- (struct msm_cam_media_controller *)arg);
+ rc = msm_axi_subdev_init(sd);
break;
case VIDIOC_MSM_AXI_CFG:
rc = msm_axi_config(sd, arg);
@@ -5288,6 +5325,12 @@
sd_info.irq_num = 0;
msm_cam_register_subdev_node(&axi_ctrl->subdev, &sd_info);
+ media_entity_init(&axi_ctrl->subdev.entity, 0, NULL, 0);
+ axi_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ axi_ctrl->subdev.entity.group_id = AXI_DEV;
+ axi_ctrl->subdev.entity.name = pdev->name;
+ axi_ctrl->subdev.entity.revision = axi_ctrl->subdev.devnode->num;
+
v4l2_subdev_init(&vfe32_ctrl->subdev, &msm_vfe_subdev_ops);
vfe32_ctrl->subdev.internal_ops = &msm_vfe_internal_ops;
vfe32_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@@ -5333,6 +5376,12 @@
sd_info.irq_num = axi_ctrl->vfeirq->start;
msm_cam_register_subdev_node(&vfe32_ctrl->subdev, &sd_info);
+ media_entity_init(&vfe32_ctrl->subdev.entity, 0, NULL, 0);
+ vfe32_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ vfe32_ctrl->subdev.entity.group_id = VFE_DEV;
+ vfe32_ctrl->subdev.entity.name = pdev->name;
+ vfe32_ctrl->subdev.entity.revision = vfe32_ctrl->subdev.devnode->num;
+
/* Request for this device irq from the camera server. If the
* IRQ Router is present on this target, the interrupt will be
* handled by the camera server and the interrupt service
diff --git a/drivers/media/video/msm/msm_vfe32.h b/drivers/media/video/msm/msm_vfe32.h
index 2c528da..9336cfb 100644
--- a/drivers/media/video/msm/msm_vfe32.h
+++ b/drivers/media/video/msm/msm_vfe32.h
@@ -241,8 +241,8 @@
#define V32_OPERATION_CFG_LEN 44
#define V32_AXI_OUT_OFF 0x00000038
-#define V32_AXI_OUT_LEN 224
-#define V32_AXI_CH_INF_LEN 32
+#define V32_AXI_OUT_LEN 240
+#define V32_AXI_CH_INF_LEN 48
#define V32_AXI_CFG_LEN 47
#define V32_AXI_BUS_FMT_OFF 1
#define V32_AXI_BUS_FMT_LEN 4
@@ -756,7 +756,7 @@
struct vfe32_output_ch {
struct list_head free_buf_queue;
spinlock_t free_buf_lock;
- uint16_t image_mode;
+ uint32_t inst_handle;
int8_t ch0;
int8_t ch1;
int8_t ch2;
@@ -1028,19 +1028,4 @@
uint32_t statsBuf[VFE_STATS_BUFFER_COUNT];
};
-#define VIDIOC_MSM_AXI_INIT \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 18, struct msm_cam_media_controller *)
-
-#define VIDIOC_MSM_AXI_RELEASE \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 19, struct msm_cam_media_controller *)
-
-#define VIDIOC_MSM_AXI_CFG \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 20, void *)
-
-#define VIDIOC_MSM_AXI_IRQ \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 21, void *)
-
-#define VIDIOC_MSM_AXI_BUF_CFG \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 22, void *)
-
#endif /* __MSM_VFE32_H__ */
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
index 96047d5..64e0385 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
@@ -585,7 +585,7 @@
struct isp_msg_output msg;
msg.output_id = msgid;
- msg.buf.image_mode = -1;
+ msg.buf.inst_handle = 0;
msg.buf.ch_paddr[0] = ch0_paddr;
msg.buf.ch_paddr[1] = ch1_paddr;
msg.frameCounter = vfe2x_ctrl->vfeFrameId;
@@ -1182,12 +1182,11 @@
unsigned int subdev_cmd, void *arg)
{
struct msm_isp_cmd vfecmd;
- struct msm_camvfe_params *vfe_params =
- (struct msm_camvfe_params *)arg;
- struct msm_vfe_cfg_cmd *cmd = vfe_params->vfe_cfg;
+ struct msm_camvfe_params *vfe_params;
+ struct msm_vfe_cfg_cmd *cmd;
struct table_cmd *table_pending;
long rc = 0;
- void *data = vfe_params->data;
+ void *data;
struct msm_pmem_region *regptr;
unsigned char buf[256];
@@ -1208,6 +1207,18 @@
struct vfe_outputack fack;
CDBG("msm_vfe_subdev_ioctl is called\n");
+ if (subdev_cmd == VIDIOC_MSM_VFE_INIT) {
+ CDBG("%s init\n", __func__);
+ return msm_vfe_subdev_init(sd);
+ } else if (subdev_cmd == VIDIOC_MSM_VFE_RELEASE) {
+ msm_vfe_subdev_release(sd);
+ return 0;
+ }
+
+ vfe_params = (struct msm_camvfe_params *)arg;
+ cmd = vfe_params->vfe_cfg;
+ data = vfe_params->data;
+
if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE &&
@@ -1954,11 +1965,16 @@
{"vfe_clk", 192000000},
};
-int msm_vfe_subdev_init(struct v4l2_subdev *sd,
- struct msm_cam_media_controller *mctl)
+int msm_vfe_subdev_init(struct v4l2_subdev *sd)
{
int rc = 0;
- v4l2_set_subdev_hostdata(sd, mctl);
+ struct msm_cam_media_controller *mctl;
+ mctl = v4l2_get_subdev_hostdata(sd);
+ if (mctl == NULL) {
+ pr_err("%s: mctl is NULL\n", __func__);
+ rc = -EINVAL;
+ goto mctl_failed;
+ }
spin_lock_init(&vfe2x_ctrl->sd_notify_lock);
spin_lock_init(&vfe2x_ctrl->table_lock);
@@ -2011,11 +2027,11 @@
kfree(extdata);
init_fail:
extlen = 0;
+mctl_failed:
return rc;
}
-int msm_vpe_subdev_init(struct v4l2_subdev *sd,
- struct msm_cam_media_controller *mctl)
+int msm_vpe_subdev_init(struct v4l2_subdev *sd)
{
return 0;
}
@@ -2101,6 +2117,12 @@
sd_info.sd_index = 0;
sd_info.irq_num = 0;
msm_cam_register_subdev_node(&vfe2x_ctrl->subdev, &sd_info);
+
+ media_entity_init(&vfe2x_ctrl->subdev.entity, 0, NULL, 0);
+ vfe2x_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ vfe2x_ctrl->subdev.entity.group_id = VFE_DEV;
+ vfe2x_ctrl->subdev.entity.name = pdev->name;
+ vfe2x_ctrl->subdev.entity.revision = vfe2x_ctrl->subdev.devnode->num;
return 0;
}
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index 2b58f44..58fc153 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -603,10 +603,11 @@
static int msm_vpe_resource_init(void);
-int msm_vpe_subdev_init(struct v4l2_subdev *sd,
- struct msm_cam_media_controller *mctl)
+int msm_vpe_subdev_init(struct v4l2_subdev *sd)
{
int rc = 0;
+ struct msm_cam_media_controller *mctl;
+ mctl = v4l2_get_subdev_hostdata(sd);
D("%s:begin", __func__);
if (atomic_read(&vpe_init_done)) {
pr_err("%s: VPE has been initialized", __func__);
@@ -619,7 +620,6 @@
atomic_set(&vpe_init_done, 0);
return rc;
}
- v4l2_set_subdev_hostdata(sd, mctl);
spin_lock_init(&vpe_ctrl->lock);
D("%s:end", __func__);
return rc;
@@ -843,9 +843,7 @@
switch (cmd) {
case VIDIOC_MSM_VPE_INIT: {
- struct msm_cam_media_controller *mctl =
- (struct msm_cam_media_controller *)arg;
- msm_vpe_subdev_init(sd, mctl);
+ msm_vpe_subdev_init(sd);
break;
}
@@ -980,7 +978,7 @@
platform_set_drvdata(pdev, &vpe_ctrl->subdev);
media_entity_init(&vpe_ctrl->subdev.entity, 0, NULL, 0);
- vpe_ctrl->subdev.entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+ vpe_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
vpe_ctrl->subdev.entity.group_id = VPE_DEV;
vpe_ctrl->subdev.entity.name = vpe_ctrl->subdev.name;
diff --git a/drivers/media/video/msm/msm_vpe.h b/drivers/media/video/msm/msm_vpe.h
index 5cf0309..6516ea1 100644
--- a/drivers/media/video/msm/msm_vpe.h
+++ b/drivers/media/video/msm/msm_vpe.h
@@ -180,14 +180,5 @@
int32_t phase_step_y;
};
-#define VIDIOC_MSM_VPE_INIT \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 15, struct msm_cam_media_controller *)
-
-#define VIDIOC_MSM_VPE_RELEASE \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 16, struct msm_cam_media_controller *)
-
-#define VIDIOC_MSM_VPE_CFG \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 17, struct msm_mctl_pp_params *)
-
#endif /*_MSM_VPE_H_*/
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index be1efe0..72f3f3d 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -284,7 +284,6 @@
int update_type, int res)
{
int32_t rc = 0;
-
s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
msleep(30);
if (update_type == MSM_SENSOR_REG_INIT) {
@@ -792,8 +791,15 @@
sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
s_ctrl->sensor_v4l2_subdev_ops);
-
+ s_ctrl->sensor_v4l2_subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ media_entity_init(&s_ctrl->sensor_v4l2_subdev.entity, 0, NULL, 0);
+ s_ctrl->sensor_v4l2_subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ s_ctrl->sensor_v4l2_subdev.entity.group_id = SENSOR_DEV;
+ s_ctrl->sensor_v4l2_subdev.entity.name =
+ s_ctrl->sensor_v4l2_subdev.name;
msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
+ s_ctrl->sensor_v4l2_subdev.entity.revision =
+ s_ctrl->sensor_v4l2_subdev.devnode->num;
goto power_down;
probe_fail:
pr_err("%s %s_i2c_probe failed\n", __func__, client->name);
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index 2d3022f..715b4e7 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -19,6 +19,7 @@
#include "msm_sensor.h"
#include "msm_actuator.h"
#include "msm_vfe32.h"
+#include "msm_csi_register.h"
#ifdef CONFIG_MSM_CAMERA_DEBUG
#define D(fmt, args...) pr_debug("msm: " fmt, ##args)
@@ -95,6 +96,19 @@
return -EINVAL;
}
+void msm_setup_v4l2_event_queue(struct v4l2_fh *eventHandle,
+ struct video_device *pvdev)
+{
+ v4l2_fh_init(eventHandle, pvdev);
+ v4l2_fh_add(eventHandle);
+}
+
+void msm_destroy_v4l2_event_queue(struct v4l2_fh *eventHandle)
+{
+ v4l2_fh_del(eventHandle);
+ v4l2_fh_exit(eventHandle);
+}
+
uint32_t msm_cam_server_get_mctl_handle(void)
{
uint32_t i;
@@ -422,6 +436,7 @@
plane_info.buffer_type = pfmt->type;
plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
plane_info.num_planes = 1;
+ plane_info.inst_handle = pcam->dev_inst[idx]->inst_handle;
D("%s: %d, %d, 0x%x\n", __func__,
pfmt->fmt.pix.width, pfmt->fmt.pix.height,
pfmt->fmt.pix.pixelformat);
@@ -478,6 +493,8 @@
plane_info.buffer_type = pfmt->type;
plane_info.ext_mode = pcam->dev_inst[idx]->image_mode;
plane_info.num_planes = pix_mp->num_planes;
+ plane_info.inst_handle = pcam->dev_inst[idx]->inst_handle;
+
if (plane_info.num_planes <= 0 ||
plane_info.num_planes > VIDEO_MAX_PLANES) {
pr_err("%s Invalid number of planes set %d", __func__,
@@ -880,7 +897,6 @@
struct msm_cam_v4l2_device *pcam)
{
int rc = 0;
- struct msm_cam_media_controller *pmctl;
D("%s\n", __func__);
@@ -906,17 +922,6 @@
/* initialization the media controller module*/
msm_mctl_init(pcam);
- /*for single VFE msms (8660, 8960v1), just populate the session
- with our VFE devices that registered*/
- pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
- if (pmctl == NULL) {
- pr_err("%s: cannot find mctl\n", __func__);
- msm_mctl_free(pcam);
- atomic_dec(&ps->number_pcam_active);
- return -ENODEV;
- }
- pmctl->axi_sdev = ps->axi_device[0];
- pmctl->isp_sdev = ps->isp_subdev[0];
return rc;
}
@@ -940,6 +945,50 @@
return rc;
}
+static int map_imem_addresses(struct msm_cam_media_controller *mctl)
+{
+ int rc = 0;
+ rc = msm_iommu_map_contig_buffer(
+ (unsigned long)IMEM_Y_PING_OFFSET, CAMERA_DOMAIN, GEN_POOL,
+ ((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
+ SZ_4K, IOMMU_WRITE | IOMMU_READ,
+ (unsigned long *)&mctl->ping_imem_y);
+ mctl->ping_imem_cbcr = mctl->ping_imem_y + IMEM_Y_SIZE;
+ if (rc < 0) {
+ pr_err("%s: ping iommu mapping returned error %d\n",
+ __func__, rc);
+ mctl->ping_imem_y = 0;
+ mctl->ping_imem_cbcr = 0;
+ }
+ msm_iommu_map_contig_buffer(
+ (unsigned long)IMEM_Y_PONG_OFFSET, CAMERA_DOMAIN, GEN_POOL,
+ ((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
+ SZ_4K, IOMMU_WRITE | IOMMU_READ,
+ (unsigned long *)&mctl->pong_imem_y);
+ mctl->pong_imem_cbcr = mctl->pong_imem_y + IMEM_Y_SIZE;
+ if (rc < 0) {
+ pr_err("%s: pong iommu mapping returned error %d\n",
+ __func__, rc);
+ mctl->pong_imem_y = 0;
+ mctl->pong_imem_cbcr = 0;
+ }
+ return rc;
+}
+
+static void unmap_imem_addresses(struct msm_cam_media_controller *mctl)
+{
+ msm_iommu_unmap_contig_buffer(mctl->ping_imem_y,
+ CAMERA_DOMAIN, GEN_POOL,
+ ((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
+ msm_iommu_unmap_contig_buffer(mctl->pong_imem_y,
+ CAMERA_DOMAIN, GEN_POOL,
+ ((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
+ mctl->ping_imem_y = 0;
+ mctl->ping_imem_cbcr = 0;
+ mctl->pong_imem_y = 0;
+ mctl->pong_imem_cbcr = 0;
+}
+
static long msm_ioctl_server(struct file *file, void *fh,
bool valid_prio, int cmd, void *arg)
{
@@ -1283,6 +1332,7 @@
{
int rc = -EINVAL, ges_evt;
struct msm_cam_server_queue *queue;
+ struct msm_cam_media_controller *pmctl;
if (!pcam) {
pr_err("%s pcam passed is null ", __func__);
@@ -1301,7 +1351,6 @@
msm_queue_init(&queue->ctrl_q, "control");
msm_queue_init(&queue->eventData_q, "eventdata");
queue->queue_active = 1;
-
rc = msm_cam_server_open_session(&g_server_dev, pcam);
if (rc < 0) {
pr_err("%s: cam_server_open_session failed %d\n",
@@ -1309,6 +1358,17 @@
goto error;
}
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+ if (!pmctl) {
+ pr_err("%s: invalid mctl controller", __func__);
+ goto error;
+ }
+ rc = map_imem_addresses(pmctl);
+ if (rc < 0) {
+ pr_err("%sFailed to map imem addresses %d\n", __func__, rc);
+ goto error;
+ }
+
return rc;
error:
ges_evt = MSM_V4L2_GES_CAM_CLOSE;
@@ -1328,6 +1388,7 @@
{
int rc = -EINVAL, ges_evt;
struct msm_cam_server_queue *queue;
+ struct msm_cam_media_controller *pmctl;
mutex_lock(&g_server_dev.server_queue_lock);
queue = &g_server_dev.server_queue[pcam->server_queue_idx];
@@ -1338,6 +1399,13 @@
msm_drain_eventq(&queue->eventData_q);
mutex_unlock(&g_server_dev.server_queue_lock);
+ pmctl = msm_cam_server_get_mctl(pcam->mctl_handle);
+ if (!pmctl) {
+ pr_err("%s: invalid mctl controller", __func__);
+ return -EINVAL;
+ }
+ unmap_imem_addresses(pmctl);
+
rc = msm_cam_server_close_session(&g_server_dev, pcam);
if (rc < 0)
pr_err("msm_cam_server_close_session fails %d\n", rc);
@@ -1374,6 +1442,7 @@
struct msm_camera_sensor_info *sinfo;
struct msm_camera_device_platform_data *camdev;
uint8_t csid_core = 0;
+ struct msm_cam_media_controller *p_mctl;
if (notification == NOTIFY_PCLK_CHANGE ||
notification == NOTIFY_CSIPHY_CFG ||
@@ -1384,7 +1453,14 @@
camdev = sinfo->pdata;
csid_core = camdev->csid_core;
}
-
+ if (notification != NOTIFY_GESTURE_CAM_EVT) {
+ p_mctl = v4l2_get_subdev_hostdata(sd);
+ if (p_mctl == NULL) {
+ pr_err("%s: cannot find mctl, %d\n",
+ __func__, notification);
+ return;
+ }
+ }
switch (notification) {
case NOTIFY_ISP_MSG_EVT:
case NOTIFY_VFE_MSG_OUT:
@@ -1393,10 +1469,10 @@
case NOTIFY_VFE_BUF_EVT:
case NOTIFY_VFE_BUF_FREE_EVT:
if (g_server_dev.isp_subdev[0] &&
- g_server_dev.isp_subdev[0]->isp_notify) {
+ g_server_dev.isp_subdev[0]->isp_notify
+ && p_mctl->isp_sdev->sd)
rc = g_server_dev.isp_subdev[0]->isp_notify(
- g_server_dev.vfe_device[0], notification, arg);
- }
+ p_mctl->isp_sdev->sd, notification, arg);
break;
case NOTIFY_VFE_IRQ:{
struct msm_vfe_cfg_cmd cfg_cmd;
@@ -1404,32 +1480,32 @@
cfg_cmd.cmd_type = CMD_VFE_PROCESS_IRQ;
vfe_params.vfe_cfg = &cfg_cmd;
vfe_params.data = arg;
- rc = v4l2_subdev_call(g_server_dev.vfe_device[0],
+ rc = v4l2_subdev_call(p_mctl->isp_sdev->sd,
core, ioctl, 0, &vfe_params);
}
break;
case NOTIFY_AXI_IRQ:
- rc = v4l2_subdev_call(g_server_dev.axi_device[0],
+ rc = v4l2_subdev_call(p_mctl->axi_sdev,
core, ioctl, VIDIOC_MSM_AXI_IRQ, arg);
break;
case NOTIFY_PCLK_CHANGE:
- if (g_server_dev.axi_device[0])
- rc = v4l2_subdev_call(g_server_dev.axi_device[0], video,
+ if (p_mctl->axi_sdev)
+ rc = v4l2_subdev_call(p_mctl->axi_sdev, video,
s_crystal_freq, *(uint32_t *)arg, 0);
else
- rc = v4l2_subdev_call(g_server_dev.vfe_device[0], video,
+ rc = v4l2_subdev_call(p_mctl->isp_sdev->sd, video,
s_crystal_freq, *(uint32_t *)arg, 0);
break;
case NOTIFY_CSIPHY_CFG:
- rc = v4l2_subdev_call(g_server_dev.csiphy_device[csid_core],
+ rc = v4l2_subdev_call(p_mctl->csiphy_sdev,
core, ioctl, VIDIOC_MSM_CSIPHY_CFG, arg);
break;
case NOTIFY_CSID_CFG:
- rc = v4l2_subdev_call(g_server_dev.csid_device[csid_core],
+ rc = v4l2_subdev_call(p_mctl->csid_sdev,
core, ioctl, VIDIOC_MSM_CSID_CFG, arg);
break;
case NOTIFY_CSIC_CFG:
- rc = v4l2_subdev_call(g_server_dev.csic_device[csid_core],
+ rc = v4l2_subdev_call(p_mctl->csic_sdev,
core, ioctl, VIDIOC_MSM_CSIC_CFG, arg);
break;
case NOTIFY_GESTURE_EVT:
@@ -1471,6 +1547,33 @@
return -EINVAL;
}
+static struct v4l2_subdev *msm_cam_find_subdev_node(
+ struct v4l2_subdev **sd_list, u32 revision_num)
+{
+ int i = 0;
+ for (i = 0; sd_list[i] != NULL; i++) {
+ if (sd_list[i]->entity.revision == revision_num) {
+ return sd_list[i];
+ break;
+ }
+ }
+ return NULL;
+}
+
+int msm_mctl_find_sensor_subdevs(struct msm_cam_media_controller *p_mctl,
+ int core_index)
+{
+ int rc = -ENODEV;
+
+ v4l2_set_subdev_hostdata(p_mctl->sensor_sdev, p_mctl);
+
+ rc = msm_csi_register_subdevs(p_mctl, core_index, &g_server_dev);
+ if (rc < 0)
+ pr_err("%s: Could not find sensor subdevs\n", __func__);
+
+ return rc;
+}
+
static irqreturn_t msm_camera_server_parse_irq(int irq_num, void *data)
{
unsigned long flags;
@@ -1825,6 +1928,15 @@
index = sd_info->sd_index;
switch (sdev_type) {
+ case SENSOR_DEV:
+ if (index >= MAX_NUM_SENSOR_DEV) {
+ pr_err("%s Invalid sensor idx %d", __func__, index);
+ err = -EINVAL;
+ break;
+ }
+ g_server_dev.sensor_device[index] = sd;
+ break;
+
case CSIPHY_DEV:
if (index >= MAX_NUM_CSIPHY_DEV) {
pr_err("%s Invalid CSIPHY idx %d", __func__, index);
@@ -1865,7 +1977,7 @@
break;
}
cam_hw_idx = MSM_CAM_HW_ISPIF + index;
- g_server_dev.ispif_device = sd;
+ g_server_dev.ispif_device[index] = sd;
if (g_server_dev.irqr_device) {
g_server_dev.subdev_table[cam_hw_idx] = sd;
err = msm_cam_server_fill_sdev_irqnum(cam_hw_idx,
@@ -1881,6 +1993,7 @@
}
cam_hw_idx = MSM_CAM_HW_VFE0 + index;
g_server_dev.vfe_device[index] = sd;
+ g_server_dev.isp_subdev[index]->sd = sd;
if (g_server_dev.irqr_device) {
g_server_dev.subdev_table[cam_hw_idx] = sd;
err = msm_cam_server_fill_sdev_irqnum(cam_hw_idx,
@@ -1960,19 +2073,25 @@
g_server_dev.video_dev->ioctl_ops = &msm_ioctl_ops_server;
g_server_dev.video_dev->release = video_device_release;
g_server_dev.video_dev->minor = 100;
- g_server_dev.video_dev->vfl_type = 1;
+ g_server_dev.video_dev->vfl_type = VFL_TYPE_GRABBER;
video_set_drvdata(g_server_dev.video_dev, &g_server_dev);
- strlcpy(g_server_dev.media_dev.model, "qcamera",
+ strlcpy(g_server_dev.media_dev.model, QCAMERA_SERVER_NAME,
sizeof(g_server_dev.media_dev.model));
g_server_dev.media_dev.dev = &pdev->dev;
rc = media_device_register(&g_server_dev.media_dev);
g_server_dev.v4l2_dev.mdev = &g_server_dev.media_dev;
+ media_entity_init(&g_server_dev.video_dev->entity, 0, NULL, 0);
+ g_server_dev.video_dev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+ g_server_dev.video_dev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
rc = video_register_device(g_server_dev.video_dev,
VFL_TYPE_GRABBER, 100);
+ g_server_dev.video_dev->entity.name =
+ video_device_node_name(g_server_dev.video_dev);
+
mutex_init(&g_server_dev.server_lock);
mutex_init(&g_server_dev.server_queue_lock);
spin_lock_init(&g_server_dev.intr_table_lock);
@@ -1986,16 +2105,10 @@
/*initialize fake video device and event queue*/
g_server_dev.server_command_queue.pvdev = g_server_dev.video_dev;
- rc = msm_setup_v4l2_event_queue(
+ msm_setup_v4l2_event_queue(
&g_server_dev.server_command_queue.eventHandle,
g_server_dev.server_command_queue.pvdev);
- if (rc < 0) {
- pr_err("%s failed to initialize event queue\n", __func__);
- video_device_release(g_server_dev.server_command_queue.pvdev);
- return rc;
- }
-
for (i = 0; i < MAX_NUM_ACTIVE_CAMERA; i++) {
struct msm_cam_server_queue *queue;
queue = &g_server_dev.server_queue[i];
@@ -2342,6 +2455,104 @@
return rc;
}
+static struct msm_isp_ops *find_isp_op(struct v4l2_subdev *sdev)
+{
+ int i;
+ for (i = 0; i < g_server_dev.config_info.num_config_nodes; i++) {
+ if (g_server_dev.isp_subdev[i]->sd == sdev)
+ return g_server_dev.isp_subdev[i];
+ }
+ return NULL;
+}
+
+static int msm_set_mctl_subdev(struct msm_cam_media_controller *pmctl,
+ struct msm_mctl_set_sdev_data *set_data)
+{
+ int rc = 0;
+ struct v4l2_subdev *vfe_sdev = NULL;
+ struct v4l2_subdev *temp_sdev = NULL;
+ switch (set_data->sdev_type) {
+ case CSIPHY_DEV:
+ pmctl->csiphy_sdev = msm_cam_find_subdev_node
+ (&g_server_dev.csiphy_device[0], set_data->revision);
+ temp_sdev = pmctl->csiphy_sdev;
+ break;
+ case CSID_DEV:
+ pmctl->csid_sdev = msm_cam_find_subdev_node
+ (&g_server_dev.csid_device[0], set_data->revision);
+ temp_sdev = pmctl->csid_sdev;
+ break;
+ case CSIC_DEV:
+ pmctl->csic_sdev = msm_cam_find_subdev_node
+ (&g_server_dev.csic_device[0], set_data->revision);
+ temp_sdev = pmctl->csic_sdev;
+ break;
+ case ISPIF_DEV:
+ pmctl->ispif_sdev = msm_cam_find_subdev_node
+ (&g_server_dev.ispif_device[0], set_data->revision);
+ temp_sdev = pmctl->ispif_sdev;
+ break;
+ case VFE_DEV:
+ vfe_sdev = msm_cam_find_subdev_node
+ (&g_server_dev.vfe_device[0], set_data->revision);
+ temp_sdev = vfe_sdev;
+ pmctl->isp_sdev = find_isp_op(vfe_sdev);
+ pmctl->isp_sdev->sd = vfe_sdev;
+ break;
+ case AXI_DEV:
+ pmctl->axi_sdev = msm_cam_find_subdev_node
+ (&g_server_dev.axi_device[0], set_data->revision);
+ temp_sdev = pmctl->axi_sdev;
+ break;
+ case VPE_DEV:
+ pmctl->vpe_sdev = msm_cam_find_subdev_node
+ (&g_server_dev.vpe_device[0], set_data->revision);
+ temp_sdev = pmctl->vpe_sdev;
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
+ if (temp_sdev != NULL)
+ v4l2_set_subdev_hostdata(temp_sdev, pmctl);
+ else
+ pr_err("%s: Could not find subdev\n", __func__);
+ return rc;
+}
+
+static int msm_unset_mctl_subdev(struct msm_cam_media_controller *pmctl,
+ struct msm_mctl_set_sdev_data *set_data)
+{
+ int rc = 0;
+ switch (set_data->sdev_type) {
+ case CSIPHY_DEV:
+ pmctl->csiphy_sdev = NULL;
+ break;
+ case CSID_DEV:
+ pmctl->csid_sdev = NULL;
+ break;
+ case CSIC_DEV:
+ pmctl->csic_sdev = NULL;
+ break;
+ case ISPIF_DEV:
+ pmctl->ispif_sdev = NULL;
+ break;
+ case VFE_DEV:
+ pmctl->isp_sdev = NULL;
+ break;
+ case AXI_DEV:
+ pmctl->axi_sdev = NULL;
+ break;
+ case VPE_DEV:
+ pmctl->vpe_sdev = NULL;
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
+
static long msm_ioctl_config(struct file *fp, unsigned int cmd,
unsigned long arg)
{
@@ -2497,6 +2708,30 @@
rc = -EINVAL;
break;
+ case MSM_CAM_IOCTL_SET_MCTL_SDEV:{
+ struct msm_mctl_set_sdev_data set_data;
+ if (copy_from_user(&set_data, (void __user *)arg,
+ sizeof(struct msm_mctl_set_sdev_data))) {
+ ERR_COPY_FROM_USER();
+ rc = -EINVAL;
+ break;
+ }
+ rc = msm_set_mctl_subdev(config_cam->p_mctl, &set_data);
+ break;
+ }
+
+ case MSM_CAM_IOCTL_UNSET_MCTL_SDEV:{
+ struct msm_mctl_set_sdev_data set_data;
+ if (copy_from_user(&set_data, (void __user *)arg,
+ sizeof(struct msm_mctl_set_sdev_data))) {
+ ERR_COPY_FROM_USER();
+ rc = -EINVAL;
+ break;
+ }
+ rc = msm_unset_mctl_subdev(config_cam->p_mctl, &set_data);
+ break;
+ }
+
default:{
/* For the rest of config command, forward to media controller*/
struct msm_cam_media_controller *p_mctl = config_cam->p_mctl;
@@ -2603,14 +2838,12 @@
goto config_setup_fail;
}
- rc = msm_setup_v4l2_event_queue(
+ /* v4l2_fh support */
+ spin_lock_init(&config_cam->config_stat_event_queue.pvdev->fh_lock);
+ INIT_LIST_HEAD(&config_cam->config_stat_event_queue.pvdev->fh_list);
+ msm_setup_v4l2_event_queue(
&config_cam->config_stat_event_queue.eventHandle,
config_cam->config_stat_event_queue.pvdev);
- if (rc < 0) {
- pr_err("%s failed to initialize event queue\n", __func__);
- video_device_release(config_cam->config_stat_event_queue.pvdev);
- goto config_setup_fail;
- }
return rc;
@@ -2622,6 +2855,7 @@
static int __devinit msm_camera_probe(struct platform_device *pdev)
{
int rc = 0, i;
+ memset(&g_server_dev, 0, sizeof(struct msm_cam_server_dev));
/*for now just create a config 0 node
put logic here later to know how many configs to create*/
g_server_dev.config_info.num_config_nodes = 1;
diff --git a/drivers/media/video/msm_vidc/msm_smem.c b/drivers/media/video/msm_vidc/msm_smem.c
index 2913d74..76e3592 100644
--- a/drivers/media/video/msm_vidc/msm_smem.c
+++ b/drivers/media/video/msm_vidc/msm_smem.c
@@ -12,6 +12,7 @@
*/
#include <linux/slab.h>
+#include <mach/iommu_domains.h>
#include "msm_smem.h"
struct smem_client {
@@ -19,12 +20,44 @@
void *clnt;
};
+static int get_device_address(struct ion_client *clnt,
+ struct ion_handle *hndl, int domain_num, int partition_num,
+ unsigned long align, unsigned long *iova,
+ unsigned long *buffer_size, unsigned long flags)
+{
+ int rc;
+
+ if (!iova || !buffer_size || !hndl || !clnt) {
+ pr_err("Invalid params: %p, %p, %p, %p\n",
+ clnt, hndl, iova, buffer_size);
+ return -EINVAL;
+ }
+ if (align < 4096)
+ align = 4096;
+ flags |= UNCACHED;
+ rc = ion_map_iommu(clnt, hndl, domain_num, partition_num, align,
+ 0, iova, buffer_size, flags, 0);
+ if (rc)
+ pr_err("ion_map_iommu failed(%d).domain: %d,partition: %d\n",
+ rc, domain_num, partition_num);
+
+ return rc;
+}
+
+static void put_device_address(struct ion_client *clnt,
+ struct ion_handle *hndl, int domain_num)
+{
+ ion_unmap_iommu(clnt, hndl, domain_num, 0);
+}
+
static int ion_user_to_kernel(struct smem_client *client,
- int fd, u32 offset, struct msm_smem *mem)
+ int fd, u32 offset, int domain, int partition,
+ struct msm_smem *mem)
{
struct ion_handle *hndl;
unsigned long ionflag;
- size_t len;
+ unsigned long iova = 0;
+ unsigned long buffer_size = 0;
int rc = 0;
hndl = ion_import_dma_buf(client->clnt, fd);
if (IS_ERR_OR_NULL(hndl)) {
@@ -38,25 +71,29 @@
pr_err("Failed to get ion flags: %d", rc);
goto fail_map;
}
- rc = ion_phys(client->clnt, hndl, &mem->paddr, &len);
- if (rc) {
- pr_err("Failed to get physical address\n");
- goto fail_map;
- }
mem->kvaddr = ion_map_kernel(client->clnt, hndl, ionflag);
if (!mem->kvaddr) {
pr_err("Failed to map shared mem in kernel\n");
rc = -EIO;
goto fail_map;
}
+ mem->domain = domain;
+ mem->partition_num = partition;
+ rc = get_device_address(client->clnt, hndl, mem->domain,
+ mem->partition_num, 4096, &iova, &buffer_size, UNCACHED);
+ if (rc) {
+ pr_err("Failed to get device address: %d\n", rc);
+ goto fail_device_address;
+ }
mem->kvaddr += offset;
- mem->paddr += offset;
mem->mem_type = client->mem_type;
mem->smem_priv = hndl;
- mem->device_addr = mem->paddr;
- mem->size = len;
+ mem->device_addr = iova + offset;
+ mem->size = buffer_size;
return rc;
+fail_device_address:
+ ion_unmap_kernel(client->clnt, hndl);
fail_map:
ion_free(client->clnt, hndl);
fail_import_fd:
@@ -64,14 +101,19 @@
}
static int alloc_ion_mem(struct smem_client *client, size_t size,
- u32 align, u32 flags, struct msm_smem *mem)
+ u32 align, u32 flags, int domain, int partition,
+ struct msm_smem *mem)
{
struct ion_handle *hndl;
- size_t len;
+ unsigned long iova = 0;
+ unsigned long buffer_size = 0;
int rc = 0;
if (size == 0)
goto skip_mem_alloc;
flags = flags | ION_HEAP(ION_CP_MM_HEAP_ID);
+ if (align < 4096)
+ align = 4096;
+ size = (size + 4095) & (~4095);
hndl = ion_alloc(client->clnt, size, align, flags);
if (IS_ERR_OR_NULL(hndl)) {
pr_err("Failed to allocate shared memory = %p, %d, %d, 0x%x\n",
@@ -81,20 +123,27 @@
}
mem->mem_type = client->mem_type;
mem->smem_priv = hndl;
- if (ion_phys(client->clnt, hndl, &mem->paddr, &len)) {
- pr_err("Failed to get physical address\n");
- rc = -EIO;
- goto fail_map;
- }
- mem->device_addr = mem->paddr;
- mem->size = size;
+ mem->domain = domain;
+ mem->partition_num = partition;
mem->kvaddr = ion_map_kernel(client->clnt, hndl, 0);
if (!mem->kvaddr) {
pr_err("Failed to map shared mem in kernel\n");
rc = -EIO;
goto fail_map;
}
+ rc = get_device_address(client->clnt, hndl, mem->domain,
+ mem->partition_num, align, &iova, &buffer_size, UNCACHED);
+ if (rc) {
+ pr_err("Failed to get device address: %d\n", rc);
+ goto fail_device_address;
+ }
+ mem->device_addr = iova;
+ pr_err("device_address = 0x%lx, kvaddr = 0x%p\n",
+ mem->device_addr, mem->kvaddr);
+ mem->size = size;
return rc;
+fail_device_address:
+ ion_unmap_kernel(client->clnt, hndl);
fail_map:
ion_free(client->clnt, hndl);
fail_shared_mem_alloc:
@@ -104,6 +153,8 @@
static void free_ion_mem(struct smem_client *client, struct msm_smem *mem)
{
+ put_device_address(client->clnt,
+ mem->smem_priv, mem->domain);
ion_unmap_kernel(client->clnt, mem->smem_priv);
ion_free(client->clnt, mem->smem_priv);
}
@@ -122,7 +173,8 @@
ion_client_destroy(client->clnt);
}
-struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset)
+struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset,
+ int domain, int partition)
{
struct smem_client *client = clt;
int rc = 0;
@@ -138,7 +190,8 @@
}
switch (client->mem_type) {
case SMEM_ION:
- rc = ion_user_to_kernel(clt, fd, offset, mem);
+ rc = ion_user_to_kernel(clt, fd, offset,
+ domain, partition, mem);
break;
default:
pr_err("Mem type not supported\n");
@@ -177,7 +230,8 @@
return client;
};
-struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags)
+struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags,
+ int domain, int partition)
{
struct smem_client *client;
int rc = 0;
@@ -195,7 +249,8 @@
}
switch (client->mem_type) {
case SMEM_ION:
- rc = alloc_ion_mem(client, size, align, flags, mem);
+ rc = alloc_ion_mem(client, size, align, flags,
+ domain, partition, mem);
break;
default:
pr_err("Mem type not supported\n");
diff --git a/drivers/media/video/msm_vidc/msm_smem.h b/drivers/media/video/msm_vidc/msm_smem.h
index 84d12cc..b742c79 100644
--- a/drivers/media/video/msm_vidc/msm_smem.h
+++ b/drivers/media/video/msm_vidc/msm_smem.h
@@ -24,15 +24,17 @@
int mem_type;
size_t size;
void *kvaddr;
- unsigned long paddr;
unsigned long device_addr;
- /*Device address and others to follow*/
+ int domain;
+ int partition_num;
void *smem_priv;
};
void *msm_smem_new_client(enum smem_type mtype);
-struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags);
+struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags,
+ int domain, int partition);
void msm_smem_free(void *clt, struct msm_smem *mem);
void msm_smem_delete_client(void *clt);
-struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset);
+struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset, int
+ domain, int partition);
#endif
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
index 6cd9e6b..e1a71ce 100644
--- a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
@@ -21,7 +21,9 @@
#include <linux/debugfs.h>
#include <linux/version.h>
#include <linux/slab.h>
-
+#include <linux/of.h>
+#include <mach/iommu.h>
+#include <mach/iommu_domains.h>
#include <media/msm_vidc.h>
#include "msm_vidc_internal.h"
#include "vidc_hal_api.h"
@@ -277,8 +279,10 @@
goto exit;
}
handle = msm_smem_user_to_kernel(v4l2_inst->mem_client,
- b->m.planes[i].reserved[0],
- b->m.planes[i].reserved[1]);
+ b->m.planes[i].reserved[0],
+ b->m.planes[i].reserved[1],
+ vidc_inst->core->resources.io_map[NS_MAP].domain,
+ 0);
if (!handle) {
pr_err("Failed to get device buffer address\n");
kfree(binfo);
@@ -420,11 +424,92 @@
{
}
+static size_t read_u32_array(struct platform_device *pdev,
+ char *name, u32 *arr, size_t size)
+{
+ int len;
+ size_t sz = 0;
+ struct device_node *np = pdev->dev.of_node;
+ if (!of_get_property(np, name, &len)) {
+ pr_err("Failed to read %s from device tree\n",
+ name);
+ goto fail_read;
+ }
+ sz = len / sizeof(u32);
+ if (sz <= 0) {
+ pr_err("%s not specified in device tree\n", name);
+ goto fail_read;
+ }
+ if (sz > size) {
+ pr_err("Not enough memory to store %s values\n", name);
+ goto fail_read;
+ }
+ if (of_property_read_u32_array(np, name, arr, sz)) {
+ pr_err("error while reading %s from device tree\n",
+ name);
+ goto fail_read;
+ }
+ return sz;
+fail_read:
+ sz = 0;
+ return sz;
+}
+
+static int register_iommu_domains(struct platform_device *pdev,
+ struct msm_vidc_core *core)
+{
+ size_t len;
+ struct msm_iova_partition partition;
+ struct msm_iova_layout layout;
+ int rc = 0;
+ int i;
+ struct iommu_info *io_map = core->resources.io_map;
+ strlcpy(io_map[CP_MAP].name, "vidc-cp-map",
+ sizeof(io_map[CP_MAP].name));
+ strlcpy(io_map[CP_MAP].ctx, "venus_cp",
+ sizeof(io_map[CP_MAP].ctx));
+ strlcpy(io_map[NS_MAP].name, "vidc-ns-map",
+ sizeof(io_map[NS_MAP].name));
+ strlcpy(io_map[NS_MAP].ctx, "venus_ns",
+ sizeof(io_map[NS_MAP].ctx));
+
+ for (i = 0; i < MAX_MAP; i++) {
+ len = read_u32_array(pdev, io_map[i].name,
+ io_map[i].addr_range,
+ (sizeof(io_map[i].addr_range)/sizeof(u32)));
+ if (!len) {
+ pr_err("Error in reading cp address range\n");
+ rc = -EINVAL;
+ break;
+ }
+ partition.start = io_map[i].addr_range[0];
+ partition.size = io_map[i].addr_range[1];
+ layout.partitions = &partition;
+ layout.npartitions = 1;
+ layout.client_name = io_map[i].name;
+ layout.domain_flags = 0;
+ pr_debug("Registering domain with: %lx, %lx, %s\n",
+ partition.start, partition.size, layout.client_name);
+ io_map[i].domain = msm_register_domain(&layout);
+ if (io_map[i].domain < 0) {
+ pr_err("Failed to register cp domain\n");
+ rc = -EINVAL;
+ break;
+ }
+ }
+ /* There is no api provided as msm_unregister_domain, so
+ * we are not able to unregister the previously
+ * registered domains if any domain registration fails.*/
+ BUG_ON(i < MAX_MAP);
+ return rc;
+}
+
static int msm_vidc_initialize_core(struct platform_device *pdev,
struct msm_vidc_core *core)
{
struct resource *res;
int i = 0;
+ int rc = 0;
if (!core)
return -EINVAL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -443,13 +528,19 @@
INIT_LIST_HEAD(&core->instances);
mutex_init(&core->sync_lock);
spin_lock_init(&core->lock);
- core->base_addr = 0x14f00000;
+ core->base_addr = 0x0;
core->state = VIDC_CORE_UNINIT;
for (i = SYS_MSG_INDEX(SYS_MSG_START);
i <= SYS_MSG_INDEX(SYS_MSG_END); i++) {
init_completion(&core->completions[i]);
}
- return 0;
+ rc = register_iommu_domains(pdev, core);
+ if (rc) {
+ pr_err("Failed to register iommu domains: %d\n", rc);
+ goto fail_domain_register;
+ }
+fail_domain_register:
+ return rc;
}
static int __devinit msm_vidc_probe(struct platform_device *pdev)
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index 6fe196e..a8c6428 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -22,6 +22,8 @@
#define MAX_PLANES 1
#define DEFAULT_HEIGHT 720
#define DEFAULT_WIDTH 1280
+#define MAX_SUPPORTED_WIDTH 4096
+#define MAX_SUPPORTED_HEIGHT 2160
#define MIN_NUM_OUTPUT_BUFFERS 2
#define MAX_NUM_OUTPUT_BUFFERS 6
@@ -169,7 +171,7 @@
static u32 get_frame_size_compressed(int plane,
u32 height, u32 width)
{
- return height * width * 3/2;
+ return (MAX_SUPPORTED_WIDTH * MAX_SUPPORTED_HEIGHT * 3/2)/2;
}
static const struct msm_vidc_format vdec_formats[] = {
@@ -307,8 +309,21 @@
buffer_info.num_buffers = 1;
buffer_info.align_device_addr =
b->m.planes[i].m.userptr;
- buffer_info.extradata_size = 0;
- buffer_info.extradata_addr = 0;
+ if (!inst->extradata_handle) {
+ inst->extradata_handle =
+ msm_smem_alloc(inst->mem_client,
+ 4096 * 1024, 1, 0,
+ inst->core->resources.io_map[NS_MAP].domain,
+ 0);
+ if (!inst->extradata_handle) {
+ pr_err("Failed to allocate extradta memory\n");
+ rc = -ENOMEM;
+ break;
+ }
+ }
+ buffer_info.extradata_addr =
+ inst->extradata_handle->device_addr;
+ buffer_info.extradata_size = 4096 * 1024;
rc = vidc_hal_session_set_buffers((void *)inst->session,
&buffer_info);
if (rc) {
@@ -344,7 +359,8 @@
buffer_info.num_buffers = 1;
buffer_info.align_device_addr =
b->m.planes[i].m.userptr;
- buffer_info.extradata_addr = 0;
+ buffer_info.extradata_addr =
+ inst->extradata_handle->device_addr;
rc = vidc_hal_session_release_buffers(
(void *)inst->session, &buffer_info);
if (rc)
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 4950097..72c6685 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -23,11 +23,11 @@
#define MIN_NUM_OUTPUT_BUFFERS 2
#define MAX_NUM_OUTPUT_BUFFERS 8
#define MIN_BIT_RATE 64
-#define MAX_BIT_RATE 20000
+#define MAX_BIT_RATE 160000
#define DEFAULT_BIT_RATE 64
#define BIT_RATE_STEP 1
#define MIN_FRAME_RATE 1
-#define MAX_FRAME_RATE 120
+#define MAX_FRAME_RATE 240
#define DEFAULT_FRAME_RATE 30
#define DEFAULT_IR_MBS 30
#define MAX_SLICE_BYTE_SIZE 1024
@@ -63,6 +63,30 @@
"Model 2",
NULL
};
+
+static const char *const h263_level[] = {
+ "1.0",
+ "2.0",
+ "3.0",
+ "4.0",
+ "4.5",
+ "5.0",
+ "6.0",
+ "7.0",
+};
+
+static const char *const h263_profile[] = {
+ "Baseline",
+ "H320 Coding",
+ "Backward Compatible",
+ "ISWV2",
+ "ISWV3",
+ "High Compression",
+ "Internet",
+ "Interlace",
+ "High Latency",
+};
+
static const struct msm_vidc_ctrl msm_venc_ctrls[] = {
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE,
@@ -212,10 +236,48 @@
.minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
.maximum = V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
.default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
- .step = 1,
+ .step = 0,
.menu_skip_mask = 0,
},
{
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE,
+ .name = "H263 Profile",
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE,
+ .maximum = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY,
+ .default_value = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE,
+ .menu_skip_mask = ~(
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY)
+ ),
+ .qmenu = h263_profile,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL,
+ .name = "H263 Level",
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0,
+ .maximum = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0,
+ .default_value = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0,
+ .menu_skip_mask = ~(
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0) |
+ (1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0)
+ ),
+ .qmenu = h263_level,
+ },
+ {
.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION,
.name = "Rotation",
.type = V4L2_CTRL_TYPE_MENU,
@@ -410,8 +472,11 @@
venc_h264_profile_level = {HAL_H264_PROFILE_BASELINE,
HAL_H264_LEVEL_1};
static struct hal_profile_level
- venc_mpeg4_profile_level = {HAL_H264_PROFILE_BASELINE,
- HAL_H264_LEVEL_1};
+ venc_mpeg4_profile_level = {HAL_MPEG4_PROFILE_SIMPLE,
+ HAL_MPEG4_LEVEL_0};
+static struct hal_profile_level
+ venc_h263_profile_level = {HAL_H263_PROFILE_BASELINE,
+ HAL_H263_LEVEL_10};
static struct hal_h264_entropy_control
venc_h264_entropy_control = {HAL_H264_ENTROPY_CAVLC,
HAL_H264_CABAC_MODEL_0};
@@ -456,6 +521,14 @@
.type = CAPTURE_PORT,
},
{
+ .name = "VP8",
+ .description = "VP8 compressed format",
+ .fourcc = V4L2_PIX_FMT_VP8,
+ .num_planes = 1,
+ .get_frame_size = get_frame_size_compressed,
+ .type = CAPTURE_PORT,
+ },
+ {
.name = "YCrCb Semiplanar 4:2:0",
.description = "Y/CrCb 4:2:0",
.fourcc = V4L2_PIX_FMT_NV21,
@@ -896,6 +969,84 @@
pr_debug("\nLevel: %d\n",
profile_level.level);
break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE:
+ property_id =
+ HAL_PARAM_PROFILE_LEVEL_CURRENT;
+
+ switch (control.value) {
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE:
+ control.value = HAL_H263_PROFILE_BASELINE;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING:
+ control.value = HAL_H263_PROFILE_H320CODING;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE:
+ control.value = HAL_H263_PROFILE_BACKWARDCOMPATIBLE;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2:
+ control.value = HAL_H263_PROFILE_ISWV2;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3:
+ control.value = HAL_H263_PROFILE_ISWV3;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION:
+ control.value = HAL_H263_PROFILE_HIGHCOMPRESSION;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET:
+ control.value = HAL_H263_PROFILE_INTERNET;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE:
+ control.value = HAL_H263_PROFILE_INTERLACE;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY:
+ control.value = HAL_H263_PROFILE_HIGHLATENCY;
+ break;
+ default:
+ break;
+ }
+ profile_level.profile = control.value;
+ venc_h263_profile_level.profile = control.value;
+ profile_level.level = venc_h263_profile_level.level;
+ pdata = &profile_level;
+ break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
+ property_id =
+ HAL_PARAM_PROFILE_LEVEL_CURRENT;
+
+ switch (control.value) {
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0:
+ control.value = HAL_H263_LEVEL_10;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0:
+ control.value = HAL_H263_LEVEL_20;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0:
+ control.value = HAL_H263_LEVEL_30;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0:
+ control.value = HAL_H263_LEVEL_40;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5:
+ control.value = HAL_H263_LEVEL_45;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0:
+ control.value = HAL_H263_LEVEL_50;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0:
+ control.value = HAL_H263_LEVEL_60;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0:
+ control.value = HAL_H263_LEVEL_70;
+ break;
+ default:
+ break;
+ }
+
+ profile_level.level = control.value;
+ venc_h263_profile_level.level = control.value;
+ profile_level.profile = venc_h263_profile_level.profile;
+ pdata = &profile_level;
+ break;
case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION:
property_id =
HAL_CONFIG_VPE_OPERATIONS;
diff --git a/drivers/media/video/msm_vidc/msm_vidc.c b/drivers/media/video/msm_vidc/msm_vidc.c
index 28fe2b8..4d4cec5 100644
--- a/drivers/media/video/msm_vidc/msm_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_vidc.c
@@ -316,6 +316,8 @@
kfree(buf);
}
}
+ if (inst->extradata_handle)
+ msm_smem_free(inst->mem_client, inst->extradata_handle);
spin_unlock_irqrestore(&inst->lock, flags);
msm_smem_delete_client(inst->mem_client);
}
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 261879d..cd330316 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -13,6 +13,10 @@
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/iommu.h>
+#include <mach/iommu.h>
+#include <mach/iommu_domains.h>
+#include <mach/peripheral-loader.h>
#include "msm_vidc_common.h"
#include "vidc_hal_api.h"
@@ -52,6 +56,60 @@
return NULL;
}
+static int msm_comm_iommu_attach(struct msm_vidc_core *core)
+{
+ int rc;
+ struct iommu_domain *domain;
+ int i;
+ struct iommu_info *io_map;
+ struct device *dev;
+ for (i = 0; i < MAX_MAP; i++) {
+ io_map = &core->resources.io_map[i];
+ dev = msm_iommu_get_ctx(io_map->ctx);
+ domain = msm_get_iommu_domain(io_map->domain);
+ if (IS_ERR_OR_NULL(domain)) {
+ pr_err("Failed to get domain: %s\n", io_map->name);
+ rc = PTR_ERR(domain);
+ break;
+ }
+ rc = iommu_attach_device(domain, dev);
+ if (rc) {
+ pr_err("IOMMU attach failed: %s\n", io_map->name);
+ break;
+ }
+ }
+ if (i < MAX_MAP) {
+ i--;
+ for (; i >= 0; i--) {
+ io_map = &core->resources.io_map[i];
+ dev = msm_iommu_get_ctx(io_map->ctx);
+ domain = msm_get_iommu_domain(io_map->domain);
+ if (dev && domain)
+ iommu_detach_device(domain, dev);
+ }
+ }
+ return rc;
+}
+
+static void msm_comm_iommu_detach(struct msm_vidc_core *core)
+{
+ struct device *dev;
+ struct iommu_domain *domain;
+ struct iommu_info *io_map;
+ int i;
+ if (!core) {
+ pr_err("Invalid paramter: %p\n", core);
+ return;
+ }
+ for (i = 0; i < MAX_MAP; i++) {
+ io_map = &core->resources.io_map[i];
+ dev = msm_iommu_get_ctx(io_map->ctx);
+ domain = msm_get_iommu_domain(io_map->domain);
+ if (dev && domain)
+ iommu_detach_device(domain, dev);
+ }
+}
+
const struct msm_vidc_format *msm_comm_get_pixel_fmt_index(
const struct msm_vidc_format fmt[], int size, int index, int fmt_type)
{
@@ -454,6 +512,47 @@
break;
}
}
+static int msm_comm_load_fw(struct msm_vidc_core *core)
+{
+ int rc = 0;
+ if (!core) {
+ pr_err("Invalid paramter: %p\n", core);
+ return -EINVAL;
+ }
+
+ if (!core->resources.fw.cookie)
+ core->resources.fw.cookie = pil_get("venus");
+
+ if (IS_ERR_OR_NULL(core->resources.fw.cookie)) {
+ pr_err("Failed to download firmware\n");
+ rc = -ENOMEM;
+ goto fail_pil_get;
+ }
+ rc = msm_comm_iommu_attach(core);
+ if (rc) {
+ pr_err("Failed to attach iommu");
+ goto fail_iommu_attach;
+ }
+ return rc;
+fail_iommu_attach:
+ pil_put(core->resources.fw.cookie);
+ core->resources.fw.cookie = NULL;
+fail_pil_get:
+ return rc;
+}
+
+static void msm_comm_unload_fw(struct msm_vidc_core *core)
+{
+ if (!core) {
+ pr_err("Invalid paramter: %p\n", core);
+ return;
+ }
+ if (core->resources.fw.cookie) {
+ pil_put(core->resources.fw.cookie);
+ core->resources.fw.cookie = NULL;
+ msm_comm_iommu_detach(core);
+ }
+}
static int msm_comm_init_core_done(struct msm_vidc_inst *inst)
{
@@ -499,18 +598,28 @@
core->id, core->state);
goto core_already_inited;
}
+ rc = msm_comm_load_fw(core);
+ if (rc) {
+ pr_err("Failed to load video firmware\n");
+ goto fail_fw_download;
+ }
init_completion(&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)]);
- rc = vidc_hal_core_init(core->device);
+ rc = vidc_hal_core_init(core->device,
+ core->resources.io_map[NS_MAP].domain);
if (rc) {
pr_err("Failed to init core, id = %d\n", core->id);
- goto exit;
+ goto fail_core_init;
}
spin_lock_irqsave(&core->lock, flags);
core->state = VIDC_CORE_INIT;
spin_unlock_irqrestore(&core->lock, flags);
core_already_inited:
change_inst_state(inst, MSM_VIDC_CORE_INIT);
-exit:
+ mutex_unlock(&core->sync_lock);
+ return rc;
+fail_core_init:
+ msm_comm_unload_fw(core);
+fail_fw_download:
mutex_unlock(&core->sync_lock);
return rc;
}
@@ -536,6 +645,7 @@
spin_lock_irqsave(&core->lock, flags);
core->state = VIDC_CORE_UNINIT;
spin_unlock_irqrestore(&core->lock, flags);
+ msm_comm_unload_fw(core);
}
core_already_uninited:
change_inst_state(inst, MSM_VIDC_CORE_UNINIT);
@@ -889,9 +999,16 @@
} else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
frame_data.filled_len = 0;
frame_data.buffer_type = HAL_BUFFER_OUTPUT;
- frame_data.extradata_addr = 0;
- pr_debug("Sending ftb to hal..: Alloc: %d :filled: %d\n",
+ if (inst->extradata_handle) {
+ frame_data.extradata_addr =
+ inst->extradata_handle->device_addr;
+ } else {
+ frame_data.extradata_addr = 0;
+ }
+ pr_debug("Sending ftb to hal..: Alloc: %d :filled: %d",
frame_data.alloc_len, frame_data.filled_len);
+ pr_debug(" extradata_addr: %d\n",
+ frame_data.extradata_addr);
rc = vidc_hal_session_ftb((void *) inst->session,
&frame_data);
} else {
@@ -1020,7 +1137,8 @@
for (i = 0; i < inst->buff_req.buffer[6].buffer_count_actual;
i++) {
handle = msm_smem_alloc(inst->mem_client,
- inst->buff_req.buffer[6].buffer_size, 1, 0);
+ inst->buff_req.buffer[6].buffer_size, 1, 0,
+ inst->core->resources.io_map[NS_MAP].domain, 0);
if (!handle) {
pr_err("Failed to allocate scratch memory\n");
rc = -ENOMEM;
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index fb8fbc4..151fb21 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -106,6 +106,29 @@
struct video_device vdev;
};
+struct msm_vidc_fw {
+ void *cookie;
+};
+
+struct iommu_info {
+ u32 addr_range[2];
+ char name[64];
+ char ctx[64];
+ int domain;
+ int partition;
+};
+
+enum io_maps {
+ CP_MAP,
+ NS_MAP,
+ MAX_MAP
+};
+
+struct msm_vidc_resources {
+ struct msm_vidc_fw fw;
+ struct iommu_info io_map[MAX_MAP];
+};
+
struct msm_vidc_core {
struct list_head list;
struct mutex sync_lock;
@@ -121,6 +144,7 @@
u32 register_size;
u32 irq;
enum vidc_core_state state;
+ struct msm_vidc_resources resources;
struct completion completions[SYS_MSG_END - SYS_MSG_START + 1];
};
@@ -146,6 +170,7 @@
bool in_reconfig;
u32 reconfig_width;
u32 reconfig_height;
+ struct msm_smem *extradata_handle;
};
extern struct msm_vidc_drv *vidc_driver;
diff --git a/drivers/media/video/msm_vidc/vidc_hal.c b/drivers/media/video/msm_vidc/vidc_hal.c
index 11b1ed0..9052a63 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.c
+++ b/drivers/media/video/msm_vidc/vidc_hal.c
@@ -23,7 +23,7 @@
#define REG_ADDR_OFFSET_BITMASK 0x000FFFFF
/*Workaround for virtio */
-#define HFI_VIRTIO_FW_BIAS 0x14f00000
+#define HFI_VIRTIO_FW_BIAS 0x0
struct hal_device_data hal_ctxt;
@@ -300,7 +300,8 @@
return 0;
}
-static int vidc_hal_alloc(void *mem, void *clnt, u32 size, u32 align, u32 flags)
+static int vidc_hal_alloc(void *mem, void *clnt, u32 size, u32 align, u32 flags,
+ int domain)
{
struct vidc_mem_addr *vmem;
struct msm_smem *alloc;
@@ -312,7 +313,7 @@
vmem = (struct vidc_mem_addr *)mem;
HAL_MSG_HIGH("start to alloc: size:%d, Flags: %d", size, flags);
- alloc = msm_smem_alloc(clnt, size, align, flags);
+ alloc = msm_smem_alloc(clnt, size, align, flags, domain, 0);
HAL_MSG_LOW("Alloc done");
if (!alloc) {
HAL_MSG_HIGH("Alloc fail in %s", __func__);
@@ -503,7 +504,7 @@
device->hal_client = NULL;
}
-static int vidc_hal_interface_queues_init(struct hal_device *dev)
+static int vidc_hal_interface_queues_init(struct hal_device *dev, int domain)
{
struct hfi_queue_table_header *q_tbl_hdr;
struct hfi_queue_header *q_hdr;
@@ -513,7 +514,7 @@
rc = vidc_hal_alloc((void *) &dev->iface_q_table,
dev->hal_client,
- VIDC_IFACEQ_TABLE_SIZE, 1, 0);
+ VIDC_IFACEQ_TABLE_SIZE, 1, 0, domain);
if (rc) {
HAL_MSG_ERROR("%s:iface_q_table_alloc_fail", __func__);
return -ENOMEM;
@@ -533,7 +534,7 @@
iface_q = &dev->iface_queues[i];
rc = vidc_hal_alloc((void *) &iface_q->q_array,
dev->hal_client, VIDC_IFACEQ_QUEUE_SIZE,
- 1, 0);
+ 1, 0, domain);
if (rc) {
HAL_MSG_ERROR("%s:iface_q_table_alloc[%d]_fail",
__func__, i);
@@ -592,7 +593,7 @@
return rc;
}
-int vidc_hal_core_init(void *device)
+int vidc_hal_core_init(void *device, int domain)
{
struct hfi_cmd_sys_init_packet pkt;
int rc = 0;
@@ -619,10 +620,10 @@
HAL_MSG_ERROR("Device_Virt_Address : 0x%x,"
"Register_Virt_Addr: 0x%x",
- (u32) dev->hal_data->device_base_addr,
+ dev->hal_data->device_base_addr,
(u32) dev->hal_data->register_base_addr);
- rc = vidc_hal_interface_queues_init(dev);
+ rc = vidc_hal_interface_queues_init(dev, domain);
if (rc) {
HAL_MSG_ERROR("failed to init queues");
rc = -ENOMEM;
@@ -1120,6 +1121,7 @@
case HAL_CONFIG_VENC_REQUEST_IFRAME:
pkt->rg_property_data[0] =
HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME;
+ pkt->size += sizeof(u32);
break;
case HAL_PARAM_VENC_MPEG4_SHORT_HEADER:
break;
@@ -1988,11 +1990,11 @@
list_for_each_safe(curr, next, &core.dev_head) {
device = list_entry(curr, struct hal_device, list);
if (device && device->hal_data->irq == irq &&
- (CONTAINS((u32)device->hal_data->
+ (CONTAINS(device->hal_data->
device_base_addr,
FIRMWARE_SIZE, fw_addr) ||
CONTAINS(fw_addr, FIRMWARE_SIZE,
- (u32)device->hal_data->
+ device->hal_data->
device_base_addr) ||
CONTAINS((u32)device->hal_data->
register_base_addr,
@@ -2006,12 +2008,12 @@
OVERLAPS(reg_addr, reg_size,
(u32)device->hal_data->
register_base_addr, reg_size) ||
- OVERLAPS((u32)device->hal_data->
+ OVERLAPS(device->hal_data->
device_base_addr,
FIRMWARE_SIZE, fw_addr,
FIRMWARE_SIZE) ||
OVERLAPS(fw_addr, FIRMWARE_SIZE,
- (u32)device->hal_data->
+ device->hal_data->
device_base_addr,
FIRMWARE_SIZE))) {
return 0;
@@ -2061,7 +2063,7 @@
struct hal_data *hal = NULL;
int rc = 0;
- if (device_id || !fw_base_addr || !reg_base || !reg_size ||
+ if (device_id || !reg_base || !reg_size ||
!irq || !callback) {
HAL_MSG_ERROR("Invalid Paramters");
return NULL;
@@ -2079,13 +2081,7 @@
return NULL;
}
hal->irq = irq;
- hal->device_base_addr =
- ioremap_nocache(fw_base_addr, FIRMWARE_SIZE);
- if (!hal->device_base_addr) {
- HAL_MSG_ERROR("could not map fw addr %d of size %d",
- fw_base_addr, FIRMWARE_SIZE);
- goto err_map;
- }
+ hal->device_base_addr = fw_base_addr;
hal->register_base_addr =
ioremap_nocache(reg_base, reg_size);
if (!hal->register_base_addr) {
diff --git a/drivers/media/video/msm_vidc/vidc_hal.h b/drivers/media/video/msm_vidc/vidc_hal.h
index 6c7e5df..8e7c3d3 100644
--- a/drivers/media/video/msm_vidc/vidc_hal.h
+++ b/drivers/media/video/msm_vidc/vidc_hal.h
@@ -834,7 +834,7 @@
struct hal_data {
u32 irq;
- u8 *device_base_addr;
+ u32 device_base_addr;
u8 *register_base_addr;
};
diff --git a/drivers/media/video/msm_vidc/vidc_hal_api.h b/drivers/media/video/msm_vidc/vidc_hal_api.h
index 332bbac..c77ae12 100644
--- a/drivers/media/video/msm_vidc/vidc_hal_api.h
+++ b/drivers/media/video/msm_vidc/vidc_hal_api.h
@@ -943,7 +943,7 @@
};
/* VIDC_HAL CORE API's */
-int vidc_hal_core_init(void *device);
+int vidc_hal_core_init(void *device, int domain);
int vidc_hal_core_release(void *device);
int vidc_hal_core_pc_prep(void *device);
int vidc_hal_core_set_resource(void *device,
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 154d523..9339800 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -83,6 +83,8 @@
#define VENDOR_ID 0x18D1
#define PRODUCT_ID 0x0001
+#define ANDROID_DEVICE_NODE_NAME_LENGTH 11
+
struct android_usb_function {
char *name;
void *config;
@@ -94,6 +96,8 @@
/* for android_dev.enabled_functions */
struct list_head enabled_list;
+ struct android_dev *android_dev;
+
/* Optional: initialization during gadget bind */
int (*init)(struct android_usb_function *, struct usb_composite_dev *);
/* Optional: cleanup during gadget unbind */
@@ -132,12 +136,18 @@
char pm_qos[5];
struct pm_qos_request pm_qos_req_dma;
struct work_struct work;
+
+ struct list_head list_item;
+
+ struct usb_configuration config;
};
static struct class *android_class;
-static struct android_dev *_android_dev;
+static struct list_head android_dev_list;
+static int android_dev_count;
static int android_bind_config(struct usb_configuration *c);
static void android_unbind_config(struct usb_configuration *c);
+static struct android_dev *cdev_to_android_dev(struct usb_composite_dev *cdev);
/* string IDs are assigned dynamically */
#define STRING_MANUFACTURER_IDX 0
@@ -189,12 +199,6 @@
NULL,
};
-static struct usb_configuration android_config_driver = {
- .label = "android",
- .unbind = android_unbind_config,
- .bConfigurationValue = 1,
-};
-
enum android_device_state {
USB_DISCONNECTED,
USB_CONNECTED,
@@ -291,7 +295,7 @@
return;
if (--dev->disable_depth == 0) {
- usb_add_config(cdev, &android_config_driver,
+ usb_add_config(cdev, &dev->config,
android_bind_config);
usb_gadget_connect(cdev->gadget);
}
@@ -305,7 +309,7 @@
usb_gadget_disconnect(cdev->gadget);
/* Cancel pending control requests */
usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
- usb_remove_config(cdev, &android_config_driver);
+ usb_remove_config(cdev, &dev->config);
}
}
@@ -343,7 +347,7 @@
static void adb_android_function_enable(struct android_usb_function *f)
{
- struct android_dev *dev = _android_dev;
+ struct android_dev *dev = f->android_dev;
struct adb_data *data = f->config;
data->enabled = true;
@@ -355,7 +359,7 @@
static void adb_android_function_disable(struct android_usb_function *f)
{
- struct android_dev *dev = _android_dev;
+ struct android_dev *dev = f->android_dev;
struct adb_data *data = f->config;
data->enabled = false;
@@ -376,32 +380,30 @@
static void adb_ready_callback(void)
{
- struct android_dev *dev = _android_dev;
+ struct android_dev *dev = adb_function.android_dev;
struct adb_data *data = adb_function.config;
- mutex_lock(&dev->mutex);
-
data->opened = true;
- if (data->enabled)
+ if (data->enabled && dev) {
+ mutex_lock(&dev->mutex);
android_enable(dev);
-
- mutex_unlock(&dev->mutex);
+ mutex_unlock(&dev->mutex);
+ }
}
static void adb_closed_callback(void)
{
- struct android_dev *dev = _android_dev;
+ struct android_dev *dev = adb_function.android_dev;
struct adb_data *data = adb_function.config;
- mutex_lock(&dev->mutex);
-
data->opened = false;
- if (data->enabled)
+ if (data->enabled) {
+ mutex_lock(&dev->mutex);
android_disable(dev);
-
- mutex_unlock(&dev->mutex);
+ mutex_unlock(&dev->mutex);
+ }
}
@@ -609,6 +611,7 @@
char buf[32], *b;
int once = 0, err = -1;
int (*notify)(uint32_t, const char *);
+ struct android_dev *dev = cdev_to_android_dev(c->cdev);
strlcpy(buf, diag_clients, sizeof(buf));
b = strim(buf);
@@ -617,8 +620,8 @@
notify = NULL;
name = strsep(&b, ",");
/* Allow only first diag channel to update pid and serial no */
- if (_android_dev->pdata && !once++)
- notify = _android_dev->pdata->update_pid_and_serial_num;
+ if (dev->pdata && !once++)
+ notify = dev->pdata->update_pid_and_serial_num;
if (name) {
err = diag_function_add(c, name, notify);
@@ -1065,7 +1068,7 @@
static int mass_storage_function_init(struct android_usb_function *f,
struct usb_composite_dev *cdev)
{
- struct android_dev *dev = _android_dev;
+ struct android_dev *dev = cdev_to_android_dev(cdev);
struct mass_storage_function_config *config;
struct fsg_common *common;
int err;
@@ -1247,7 +1250,7 @@
static int android_init_functions(struct android_usb_function **functions,
struct usb_composite_dev *cdev)
{
- struct android_dev *dev = _android_dev;
+ struct android_dev *dev = cdev_to_android_dev(cdev);
struct android_usb_function *f;
struct device_attribute **attrs;
struct device_attribute *attr;
@@ -1256,6 +1259,7 @@
for (; (f = *functions++); index++) {
f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
+ f->android_dev = NULL;
if (!f->dev_name) {
err = -ENOMEM;
goto err_out;
@@ -1342,9 +1346,15 @@
struct android_usb_function *f;
while ((f = *functions++)) {
if (!strcmp(name, f->name)) {
- list_add_tail(&f->enabled_list,
- &dev->enabled_functions);
- return 0;
+ if (f->android_dev)
+ pr_err("%s cannot be enabled on two devices\n",
+ f->name);
+ else {
+ list_add_tail(&f->enabled_list,
+ &dev->enabled_functions);
+ f->android_dev = dev;
+ return 0;
+ }
}
}
return -EINVAL;
@@ -1356,14 +1366,17 @@
static ssize_t remote_wakeup_show(struct device *pdev,
struct device_attribute *attr, char *buf)
{
+ struct android_dev *dev = dev_get_drvdata(pdev);
+
return snprintf(buf, PAGE_SIZE, "%d\n",
- !!(android_config_driver.bmAttributes &
+ !!(dev->config.bmAttributes &
USB_CONFIG_ATT_WAKEUP));
}
static ssize_t remote_wakeup_store(struct device *pdev,
struct device_attribute *attr, const char *buff, size_t size)
{
+ struct android_dev *dev = dev_get_drvdata(pdev);
int enable = 0;
sscanf(buff, "%d", &enable);
@@ -1372,9 +1385,9 @@
enable ? "enabling" : "disabling");
if (enable)
- android_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+ dev->config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
else
- android_config_driver.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP;
+ dev->config.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP;
return size;
}
@@ -1403,6 +1416,7 @@
const char *buff, size_t size)
{
struct android_dev *dev = dev_get_drvdata(pdev);
+ struct android_usb_function *f;
char *name;
char buf[256], *b;
int err;
@@ -1414,6 +1428,10 @@
return -EBUSY;
}
+ /* Clear previous enabled list */
+ list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
+ f->android_dev = NULL;
+ }
INIT_LIST_HEAD(&dev->enabled_functions);
strlcpy(buf, buff, sizeof(buf));
@@ -1612,7 +1630,7 @@
static int android_bind_config(struct usb_configuration *c)
{
- struct android_dev *dev = _android_dev;
+ struct android_dev *dev = cdev_to_android_dev(c->cdev);
int ret = 0;
ret = android_bind_enabled_functions(dev, c);
@@ -1624,26 +1642,34 @@
static void android_unbind_config(struct usb_configuration *c)
{
- struct android_dev *dev = _android_dev;
+ struct android_dev *dev = cdev_to_android_dev(c->cdev);
android_unbind_enabled_functions(dev, c);
}
static int android_bind(struct usb_composite_dev *cdev)
{
- struct android_dev *dev = _android_dev;
+ struct android_dev *dev;
struct usb_gadget *gadget = cdev->gadget;
int gcnum, id, ret;
+ /* Bind to the last android_dev that was probed */
+ dev = list_entry(android_dev_list.prev, struct android_dev, list_item);
+
+ dev->cdev = cdev;
+
/*
* Start disconnected. Userspace will connect the gadget once
* it is done configuring the functions.
*/
usb_gadget_disconnect(gadget);
- ret = android_init_functions(dev->functions, cdev);
- if (ret)
- return ret;
+ /* Init the supported functions only once, on the first android_dev */
+ if (android_dev_count == 1) {
+ ret = android_init_functions(dev->functions, cdev);
+ if (ret)
+ return ret;
+ }
/* Allocate string descriptor numbers ... note that string
* contents can be overridden by the composite_dev glue.
@@ -1673,7 +1699,7 @@
device_desc.iSerialNumber = id;
if (gadget_is_otg(cdev->gadget))
- android_config_driver.descriptors = otg_desc;
+ dev->config.descriptors = otg_desc;
gcnum = usb_gadget_controller_number(gadget);
if (gcnum >= 0)
@@ -1684,14 +1710,12 @@
device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
}
- dev->cdev = cdev;
-
return 0;
}
static int android_usb_unbind(struct usb_composite_dev *cdev)
{
- struct android_dev *dev = _android_dev;
+ struct android_dev *dev = cdev_to_android_dev(cdev);
manufacturer_string[0] = '\0';
product_string[0] = '\0';
@@ -1712,8 +1736,8 @@
static int
android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c)
{
- struct android_dev *dev = _android_dev;
struct usb_composite_dev *cdev = get_gadget_data(gadget);
+ struct android_dev *dev = cdev_to_android_dev(cdev);
struct usb_request *req = cdev->req;
struct android_usb_function *f;
int value = -EOPNOTSUPP;
@@ -1756,8 +1780,8 @@
static void android_disconnect(struct usb_gadget *gadget)
{
- struct android_dev *dev = _android_dev;
struct usb_composite_dev *cdev = get_gadget_data(gadget);
+ struct android_dev *dev = cdev_to_android_dev(cdev);
unsigned long flags;
composite_disconnect(gadget);
@@ -1768,14 +1792,21 @@
spin_unlock_irqrestore(&cdev->lock, flags);
}
-static int android_create_device(struct android_dev *dev)
+static int android_create_device(struct android_dev *dev, u8 usb_core_id)
{
struct device_attribute **attrs = android_usb_attributes;
struct device_attribute *attr;
+ char device_node_name[ANDROID_DEVICE_NODE_NAME_LENGTH];
int err;
+ /*
+ * The primary usb core should always have usb_core_id=0, since
+ * Android user space is currently interested in android0 events.
+ */
+ snprintf(device_node_name, ANDROID_DEVICE_NODE_NAME_LENGTH,
+ "android%d", usb_core_id);
dev->dev = device_create(android_class, NULL,
- MKDEV(0, 0), NULL, "android0");
+ MKDEV(0, 0), NULL, device_node_name);
if (IS_ERR(dev->dev))
return PTR_ERR(dev->dev);
@@ -1801,27 +1832,64 @@
device_destroy(android_class, dev->dev->devt);
}
+static struct android_dev *cdev_to_android_dev(struct usb_composite_dev *cdev)
+{
+ struct android_dev *dev = NULL;
+
+ /* Find the android dev from the list */
+ list_for_each_entry(dev, &android_dev_list, list_item) {
+ if (dev->cdev == cdev)
+ break;
+ }
+
+ return dev;
+}
+
static int __devinit android_probe(struct platform_device *pdev)
{
struct android_usb_platform_data *pdata = pdev->dev.platform_data;
- struct android_dev *dev = _android_dev;
+ struct android_dev *android_dev;
int ret = 0;
- dev->pdata = pdata;
+ if (!android_class) {
+ android_class = class_create(THIS_MODULE, "android_usb");
+ if (IS_ERR(android_class))
+ return PTR_ERR(android_class);
+ }
- android_class = class_create(THIS_MODULE, "android_usb");
- if (IS_ERR(android_class))
- return PTR_ERR(android_class);
+ android_dev = kzalloc(sizeof(*android_dev), GFP_KERNEL);
+ if (!android_dev) {
+ pr_err("%s(): Failed to alloc memory for android_dev\n",
+ __func__);
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
- ret = android_create_device(dev);
+ android_dev->config.label = pdev->name;
+ android_dev->config.unbind = android_unbind_config;
+ android_dev->config.bConfigurationValue = 1;
+ android_dev->disable_depth = 1;
+ android_dev->functions = supported_functions;
+ INIT_LIST_HEAD(&android_dev->enabled_functions);
+ INIT_WORK(&android_dev->work, android_work);
+ mutex_init(&android_dev->mutex);
+
+ android_dev->pdata = pdata;
+
+ list_add_tail(&android_dev->list_item, &android_dev_list);
+ android_dev_count++;
+
+ if (pdata)
+ composite_driver.usb_core_id = pdata->usb_core_id;
+ else
+ composite_driver.usb_core_id = 0; /*To backward compatibility*/
+
+ ret = android_create_device(android_dev, composite_driver.usb_core_id);
if (ret) {
pr_err("%s(): android_create_device failed\n", __func__);
goto err_dev;
}
- if (pdata)
- composite_driver.usb_core_id = pdata->usb_core_id;
-
ret = usb_composite_probe(&android_usb_driver, android_bind);
if (ret) {
pr_err("%s(): Failed to register android "
@@ -1831,67 +1899,91 @@
/* pm qos request to prevent apps idle power collapse */
if (pdata && pdata->swfi_latency)
- pm_qos_add_request(&dev->pm_qos_req_dma,
+ pm_qos_add_request(&android_dev->pm_qos_req_dma,
PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
- strlcpy(dev->pm_qos, "high", sizeof(dev->pm_qos));
+ strlcpy(android_dev->pm_qos, "high", sizeof(android_dev->pm_qos));
return ret;
err_probe:
- android_destroy_device(dev);
+ android_destroy_device(android_dev);
err_dev:
- class_destroy(android_class);
+ list_del(&android_dev->list_item);
+ android_dev_count--;
+ kfree(android_dev);
+err_alloc:
+ if (list_empty(&android_dev_list)) {
+ class_destroy(android_class);
+ android_class = NULL;
+ }
return ret;
}
static int android_remove(struct platform_device *pdev)
{
- struct android_dev *dev = _android_dev;
+ struct android_dev *dev = NULL;
struct android_usb_platform_data *pdata = pdev->dev.platform_data;
+ int usb_core_id = 0;
- android_destroy_device(dev);
- class_destroy(android_class);
- usb_composite_unregister(&android_usb_driver);
- if (pdata && pdata->swfi_latency)
- pm_qos_remove_request(&dev->pm_qos_req_dma);
+ if (pdata)
+ usb_core_id = pdata->usb_core_id;
+
+ /* Find the android dev from the list */
+ list_for_each_entry(dev, &android_dev_list, list_item) {
+ if (!dev->pdata)
+ break; /*To backward compatibility*/
+ if (dev->pdata->usb_core_id == usb_core_id)
+ break;
+ }
+
+ if (dev) {
+ android_destroy_device(dev);
+ if (pdata && pdata->swfi_latency)
+ pm_qos_remove_request(&dev->pm_qos_req_dma);
+ list_del(&dev->list_item);
+ android_dev_count--;
+ kfree(dev);
+ }
+
+ if (list_empty(&android_dev_list)) {
+ class_destroy(android_class);
+ android_class = NULL;
+ usb_composite_unregister(&android_usb_driver);
+ }
return 0;
}
+static const struct platform_device_id android_id_table[] __devinitconst = {
+ {
+ .name = "android_usb",
+ },
+ {
+ .name = "android_usb_hsic",
+ },
+};
+
static struct platform_driver android_platform_driver = {
.driver = { .name = "android_usb"},
.probe = android_probe,
.remove = android_remove,
+ .id_table = android_id_table,
};
static int __init init(void)
{
- struct android_dev *dev;
int ret;
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev) {
- pr_err("%s(): Failed to alloc memory for android_dev\n",
- __func__);
- return -ENOMEM;
- }
-
- dev->disable_depth = 1;
- dev->functions = supported_functions;
- INIT_LIST_HEAD(&dev->enabled_functions);
- INIT_WORK(&dev->work, android_work);
- mutex_init(&dev->mutex);
-
- _android_dev = dev;
-
/* Override composite driver functions */
composite_driver.setup = android_setup;
composite_driver.disconnect = android_disconnect;
+ INIT_LIST_HEAD(&android_dev_list);
+ android_dev_count = 0;
+
ret = platform_driver_register(&android_platform_driver);
if (ret) {
pr_err("%s(): Failed to register android"
"platform driver\n", __func__);
- kfree(dev);
}
return ret;
@@ -1901,7 +1993,5 @@
static void __exit cleanup(void)
{
platform_driver_unregister(&android_platform_driver);
- kfree(_android_dev);
- _android_dev = NULL;
}
module_exit(cleanup);
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index d35d861..86c0e73 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1625,7 +1625,7 @@
{
int retval;
- if (!driver || !driver->dev || !bind || composite)
+ if (!driver || !driver->dev || !bind)
return -EINVAL;
if (!driver->name)
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 278e04e..1ea3982 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2865,15 +2865,6 @@
common->ep0req = cdev->req;
common->cdev = cdev;
- /* Maybe allocate device-global string IDs, and patch descriptors */
- if (fsg_strings[FSG_STRING_INTERFACE].id == 0) {
- rc = usb_string_id(cdev);
- if (unlikely(rc < 0))
- goto error_release;
- fsg_strings[FSG_STRING_INTERFACE].id = rc;
- fsg_intf_desc.iInterface = rc;
- }
-
/*
* Create the LUNs, open their backing files, and register the
* LUN devices in sysfs.
@@ -3194,6 +3185,15 @@
struct fsg_dev *fsg;
int rc;
+ /* Maybe allocate device-global string IDs, and patch descriptors */
+ if (fsg_strings[FSG_STRING_INTERFACE].id == 0) {
+ rc = usb_string_id(cdev);
+ if (unlikely(rc < 0))
+ return rc;
+ fsg_strings[FSG_STRING_INTERFACE].id = rc;
+ fsg_intf_desc.iInterface = rc;
+ }
+
fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
if (unlikely(!fsg))
return -ENOMEM;
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index b6bf47d..36c8749 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -1974,13 +1974,15 @@
bool hdmi_common_get_video_format_from_drv_data(struct msm_fb_data_type *mfd)
{
- uint32 format;
+ uint32 format = HDMI_VFRMT_1920x1080p60_16_9;
struct fb_var_screeninfo *var = &mfd->fbi->var;
bool changed = TRUE;
if (var->reserved[2]) {
format = var->reserved[2]-1;
DEV_DBG("reserved format is %d\n", format);
+ } else if (hdmi_prim_resolution) {
+ format = hdmi_prim_resolution - 1;
} else {
DEV_DBG("detecting resolution from %dx%d use var->reserved[3]"
" to specify mode", mfd->var_xres, mfd->var_yres);
@@ -1995,15 +1997,33 @@
: HDMI_VFRMT_720x576p50_16_9;
break;
case 1280:
- format = HDMI_VFRMT_1280x720p60_16_9;
+ if (mfd->var_frame_rate == 50000)
+ format = HDMI_VFRMT_1280x720p50_16_9;
+ else
+ format = HDMI_VFRMT_1280x720p60_16_9;
break;
case 1440:
- format = (mfd->var_yres == 480)
+ format = (mfd->var_yres == 240) /* interlaced has half
+ of y res.
+ */
? HDMI_VFRMT_1440x480i60_16_9
: HDMI_VFRMT_1440x576i50_16_9;
break;
case 1920:
- format = HDMI_VFRMT_1920x1080p60_16_9;
+ if (mfd->var_yres == 540) {/* interlaced */
+ format = HDMI_VFRMT_1920x1080i60_16_9;
+ } else if (mfd->var_yres == 1080) {
+ if (mfd->var_frame_rate == 50000)
+ format = HDMI_VFRMT_1920x1080p50_16_9;
+ else if (mfd->var_frame_rate == 24000)
+ format = HDMI_VFRMT_1920x1080p24_16_9;
+ else if (mfd->var_frame_rate == 25000)
+ format = HDMI_VFRMT_1920x1080p25_16_9;
+ else if (mfd->var_frame_rate == 30000)
+ format = HDMI_VFRMT_1920x1080p30_16_9;
+ else
+ format = HDMI_VFRMT_1920x1080p60_16_9;
+ }
break;
}
}
diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h
index 57c0804..43a8794 100644
--- a/drivers/video/msm/external_common.h
+++ b/drivers/video/msm/external_common.h
@@ -112,6 +112,8 @@
#define HDMI_VFRMT_MAX 59
#define HDMI_VFRMT_FORCE_32BIT 0x7FFFFFFF
+extern int ext_resolution;
+
struct hdmi_disp_mode_timing_type {
uint32 video_format;
uint32 active_h;
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index f919ad0..4a1427d 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -4742,7 +4742,14 @@
}
external_common_state = &hdmi_msm_state->common;
- external_common_state->video_resolution = HDMI_VFRMT_1920x1080p30_16_9;
+
+ if (hdmi_prim_display && hdmi_prim_resolution)
+ external_common_state->video_resolution =
+ hdmi_prim_resolution - 1;
+ else
+ external_common_state->video_resolution =
+ HDMI_VFRMT_1920x1080p60_16_9;
+
#ifdef CONFIG_FB_MSM_HDMI_3D
external_common_state->switch_3d = hdmi_msm_switch_3d;
#endif
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 3204552..c9be60a 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -2398,6 +2398,8 @@
#ifdef CONFIG_FB_MSM_MIPI_DSI
case MIPI_VIDEO_PANEL:
#ifndef CONFIG_FB_MSM_MDP303
+ mipi = &mfd->panel_info.mipi;
+ configure_mdp_core_clk_table((mipi->dsi_pclk_rate) * 23 / 20);
pdata->on = mdp4_dsi_video_on;
pdata->off = mdp4_dsi_video_off;
mfd->hw_refresh = TRUE;
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index 3fd51ba..184c5ce 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -88,6 +88,7 @@
extern struct mdp_ccs mdp_ccs_yuv2rgb ;
extern struct mdp_ccs mdp_ccs_rgb2yuv ;
extern unsigned char hdmi_prim_display;
+extern unsigned char hdmi_prim_resolution;
/*
* MDP Image Structure
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 5f58af7..36cbbbd 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -193,6 +193,7 @@
static struct msm_fb_platform_data *msm_fb_pdata;
unsigned char hdmi_prim_display;
+unsigned char hdmi_prim_resolution;
int msm_fb_detect_client(const char *name)
{
@@ -213,6 +214,8 @@
if (!strncmp((char *)msm_fb_pdata->prim_panel_name,
"hdmi_msm", len))
hdmi_prim_display = 1;
+ hdmi_prim_resolution =
+ msm_fb_pdata->ext_resolution;
return 0;
} else {
ret = -EPERM;
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 48058e6..ae81dcd 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -204,6 +204,15 @@
#define MSM_CAM_IOCTL_STATS_FLUSH_BUFQ \
_IOR(MSM_CAM_IOCTL_MAGIC, 57, struct msm_stats_flush_bufq *)
+#define MSM_CAM_IOCTL_SET_MCTL_SDEV \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 58, struct msm_mctl_set_sdev_data *)
+
+#define MSM_CAM_IOCTL_UNSET_MCTL_SDEV \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 59, struct msm_mctl_set_sdev_data *)
+
+#define MSM_CAM_IOCTL_GET_INST_HANDLE \
+ _IOR(MSM_CAM_IOCTL_MAGIC, 60, uint32_t *)
+
struct msm_stats_reqbuf {
int num_buf; /* how many buffers requested */
int stats_type; /* stats type */
@@ -334,6 +343,7 @@
struct msm_pp_frame_mp mp[MAX_PLANES];
};
int node_type;
+ uint32_t inst_handle;
};
struct msm_cam_evt_divert_frame {
@@ -767,7 +777,7 @@
#define MSM_V4L2_PID_CTRL_CMD (V4L2_CID_PRIVATE_BASE+13)
#define MSM_V4L2_PID_EVT_SUB_INFO (V4L2_CID_PRIVATE_BASE+14)
#define MSM_V4L2_PID_STROBE_FLASH (V4L2_CID_PRIVATE_BASE+15)
-#define MSM_V4L2_PID_MMAP_ENTRY (V4L2_CID_PRIVATE_BASE+16)
+#define MSM_V4L2_PID_INST_HANDLE (V4L2_CID_PRIVATE_BASE+16)
#define MSM_V4L2_PID_MMAP_INST (V4L2_CID_PRIVATE_BASE+17)
#define MSM_V4L2_PID_PP_PLANE_INFO (V4L2_CID_PRIVATE_BASE+18)
#define MSM_V4L2_PID_MAX MSM_V4L2_PID_PP_PLANE_INFO
@@ -1623,13 +1633,35 @@
uint8_t num_planes;
struct plane_data plane[MAX_PLANES];
uint32_t sp_y_offset;
- uint8_t vpe_can_use;
+ uint32_t inst_handle;
};
#define QCAMERA_NAME "qcamera"
+#define QCAMERA_SERVER_NAME "qcamera_server"
#define QCAMERA_DEVICE_GROUP_ID 1
#define QCAMERA_VNODE_GROUP_ID 2
+enum msm_cam_subdev_type {
+ CSIPHY_DEV,
+ CSID_DEV,
+ CSIC_DEV,
+ ISPIF_DEV,
+ VFE_DEV,
+ AXI_DEV,
+ VPE_DEV,
+ SENSOR_DEV,
+ ACTUATOR_DEV,
+ EEPROM_DEV,
+ GESTURE_DEV,
+ IRQ_ROUTER_DEV,
+ CPP_DEV,
+};
+
+struct msm_mctl_set_sdev_data {
+ uint32_t revision;
+ enum msm_cam_subdev_type sdev_type;
+};
+
#define MSM_CAM_V4L2_IOCTL_GET_CAMERA_INFO \
_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct msm_camera_v4l2_ioctl_t)
@@ -1654,6 +1686,39 @@
#define MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL \
_IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct msm_camera_v4l2_ioctl_t)
+#define MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 9, struct msm_camera_v4l2_ioctl_t)
+
+#define VIDIOC_MSM_VPE_INIT \
+ _IO('V', BASE_VIDIOC_PRIVATE + 15)
+
+#define VIDIOC_MSM_VPE_RELEASE \
+ _IO('V', BASE_VIDIOC_PRIVATE + 16)
+
+#define VIDIOC_MSM_VPE_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 17, struct msm_mctl_pp_params *)
+
+#define VIDIOC_MSM_AXI_INIT \
+ _IO('V', BASE_VIDIOC_PRIVATE + 18)
+
+#define VIDIOC_MSM_AXI_RELEASE \
+ _IO('V', BASE_VIDIOC_PRIVATE + 19)
+
+#define VIDIOC_MSM_AXI_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 20, void *)
+
+#define VIDIOC_MSM_AXI_IRQ \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 21, void *)
+
+#define VIDIOC_MSM_AXI_BUF_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 22, void *)
+
+#define VIDIOC_MSM_VFE_INIT \
+ _IO('V', BASE_VIDIOC_PRIVATE + 22)
+
+#define VIDIOC_MSM_VFE_RELEASE \
+ _IO('V', BASE_VIDIOC_PRIVATE + 23)
+
struct msm_camera_v4l2_ioctl_t {
uint32_t id;
void __user *ioctl_ptr;
@@ -1804,4 +1869,38 @@
#define V4L2_EVENT_CPP_FRAME_DONE (V4L2_EVENT_PRIVATE_START + 0)
+/* Instance Handle - inst_handle
+ * Data bundle containing the information about where
+ * to get a buffer for a particular camera instance.
+ * This is a bitmask containing the following data:
+ * Buffer Handle Bitmask:
+ * ------------------------------------
+ * Bits : Purpose
+ * ------------------------------------
+ * 31 - 24 : Reserved.
+ * 23 : is Image mode valid?
+ * 22 - 16 : Image mode.
+ * 15 : is MCTL PP inst idx valid?
+ * 14 - 8 : MCTL PP inst idx.
+ * 7 : is Video inst idx valid?
+ * 6 - 0 : Video inst idx.
+ */
+#define CLR_IMG_MODE(handle) (handle &= 0xFF00FFFF)
+#define SET_IMG_MODE(handle, data) \
+ (handle |= ((0x1 << 23) | ((data & 0x7F) << 16)))
+#define GET_IMG_MODE(handle) \
+ ((handle & 0x800000) ? ((handle & 0x7F0000) >> 16) : 0xFF)
+
+#define CLR_MCTLPP_INST_IDX(handle) (handle &= 0xFFFF00FF)
+#define SET_MCTLPP_INST_IDX(handle, data) \
+ (handle |= ((0x1 << 15) | ((data & 0x7F) << 8)))
+#define GET_MCTLPP_INST_IDX(handle) \
+ ((handle & 0x8000) ? ((handle & 0x7F00) >> 8) : 0xFF)
+
+#define CLR_VIDEO_INST_IDX(handle) (handle &= 0xFFFFFF00)
+#define GET_VIDEO_INST_IDX(handle) \
+ ((handle & 0x80) ? (handle & 0x7F) : 0xFF)
+#define SET_VIDEO_INST_IDX(handle, data) \
+ (handle |= (0x1 << 7) | (data & 0x7F))
+
#endif /* __LINUX_MSM_CAMERA_H */
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 1f3527b..3df6ded 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -336,7 +336,7 @@
#define VFE_OUTPUTS_RDI1 BIT(12)
struct msm_frame_info {
- uint32_t image_mode;
+ uint32_t inst_handle;
uint32_t path;
};
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index 25a1d84..988de6a 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -599,6 +599,7 @@
V4L2_CID_PRIVATE_SPUR_FREQ_RMSSI,
V4L2_CID_PRIVATE_SPUR_SELECTION,
V4L2_CID_PRIVATE_UPDATE_SPUR_TABLE,
+ V4L2_CID_PRIVATE_VALID_CHANNEL,
/*using private CIDs under userclass*/
V4L2_CID_PRIVATE_IRIS_READ_DEFAULT = 0x00980928,
@@ -786,6 +787,11 @@
#define CALIB_DATA_OFSET 2
#define CALIB_MODE_OFSET 1
#define MAX_CALIB_SIZE 75
+
+/* Channel validity */
+#define INVALID_CHANNEL (0)
+#define VALID_CHANNEL (1)
+
struct hci_fm_set_cal_req_proc {
__u8 mode;
/*Max process calibration data size*/
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index dd8e2aa..fc15fb1 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -253,7 +253,9 @@
sync_supers_tsk = kthread_run(bdi_sync_supers, NULL, "sync_supers");
BUG_ON(IS_ERR(sync_supers_tsk));
- setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0);
+ init_timer_deferrable(&sync_supers_timer);
+ sync_supers_timer.function = sync_supers_timer_fn;
+ sync_supers_timer.data = 0;
bdi_arm_supers_timer();
err = bdi_init(&default_backing_dev_info);