Merge "msm: pil-8660: Break off modem code into platform driver" into msm-3.0
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 101658c..95c93ad 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5298,13 +5298,16 @@
CLK_LOOKUP("mdp_clk", mdp_clk.c, NULL),
CLK_LOOKUP("core_clk", mdp_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("mdp_vsync_clk", mdp_vsync_clk.c, NULL),
+ CLK_LOOKUP("vsync_clk", mdp_vsync_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("lut_mdp", lut_mdp_clk.c, NULL),
+ CLK_LOOKUP("lut_clk", lut_mdp_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("core_clk", rot_clk.c, "msm_rotator.0"),
CLK_LOOKUP("core_clk", rot_clk.c, "footswitch-8x60.6"),
CLK_DUMMY("tv_src_clk", TV_SRC_CLK, NULL, OFF),
CLK_LOOKUP("core_clk", vcodec_clk.c, "msm_vidc.0"),
CLK_LOOKUP("core_clk", vcodec_clk.c, "footswitch-8x60.7"),
CLK_DUMMY("mdp_tv_clk", MDP_TV_CLK, NULL, OFF),
+ CLK_DUMMY("tv_clk", MDP_TV_CLK, "footswitch-8x60.4", OFF),
CLK_DUMMY("hdmi_clk", HDMI_TV_CLK, NULL, OFF),
CLK_LOOKUP("core_clk", hdmi_app_clk.c, NULL),
CLK_LOOKUP("vpe_clk", vpe_clk.c, NULL),
@@ -5531,7 +5534,9 @@
CLK_LOOKUP("mdp_clk", mdp_clk.c, NULL),
CLK_LOOKUP("core_clk", mdp_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("mdp_vsync_clk", mdp_vsync_clk.c, NULL),
+ CLK_LOOKUP("vsync_clk", mdp_vsync_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("lut_mdp", lut_mdp_clk.c, NULL),
+ CLK_LOOKUP("lut_clk", lut_mdp_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("qdss_pclk", qdss_p_clk.c, NULL),
CLK_LOOKUP("qdss_at_clk", qdss_at_clk.c, NULL),
CLK_LOOKUP("qdss_pclkdbg_clk", qdss_pclkdbg_clk.c, NULL),
@@ -5541,11 +5546,13 @@
CLK_LOOKUP("core_clk", rot_clk.c, "msm_rotator.0"),
CLK_LOOKUP("core_clk", rot_clk.c, "footswitch-8x60.6"),
CLK_LOOKUP("tv_src_clk", tv_src_clk.c, NULL),
+ CLK_LOOKUP("tv_src_clk", tv_src_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("tv_enc_clk", tv_enc_clk.c, NULL),
CLK_LOOKUP("tv_dac_clk", tv_dac_clk.c, NULL),
CLK_LOOKUP("core_clk", vcodec_clk.c, "msm_vidc.0"),
CLK_LOOKUP("core_clk", vcodec_clk.c, "footswitch-8x60.7"),
CLK_LOOKUP("mdp_tv_clk", mdp_tv_clk.c, NULL),
+ CLK_LOOKUP("tv_clk", mdp_tv_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("hdmi_clk", hdmi_tv_clk.c, NULL),
CLK_LOOKUP("core_clk", hdmi_app_clk.c, "hdmi_msm.1"),
CLK_LOOKUP("vpe_clk", vpe_clk.c, "msm_vpe.0"),
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 9af21d3..9da8bb4 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3704,8 +3704,11 @@
CLK_LOOKUP("mdp_clk", mdp_clk.c, NULL),
CLK_LOOKUP("core_clk", mdp_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("mdp_vsync_clk", mdp_vsync_clk.c, NULL),
+ CLK_LOOKUP("vsync_clk", mdp_vsync_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("pixel_lcdc_clk", pixel_lcdc_clk.c, NULL),
+ CLK_LOOKUP("pixel_lcdc_clk", pixel_lcdc_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("pixel_mdp_clk", pixel_mdp_clk.c, NULL),
+ CLK_LOOKUP("pixel_mdp_clk", pixel_mdp_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("core_clk", rot_clk.c, "msm_rotator.0"),
CLK_LOOKUP("core_clk", rot_clk.c, "footswitch-8x60.6"),
CLK_LOOKUP("tv_enc_clk", tv_enc_clk.c, NULL),
@@ -3713,8 +3716,10 @@
CLK_LOOKUP("core_clk", vcodec_clk.c, "msm_vidc.0"),
CLK_LOOKUP("core_clk", vcodec_clk.c, "footswitch-8x60.7"),
CLK_LOOKUP("mdp_tv_clk", mdp_tv_clk.c, NULL),
+ CLK_LOOKUP("tv_clk", mdp_tv_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("hdmi_clk", hdmi_tv_clk.c, NULL),
CLK_LOOKUP("tv_src_clk", tv_src_clk.c, NULL),
+ CLK_LOOKUP("tv_src_clk", tv_src_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("core_clk", hdmi_app_clk.c, "hdmi_msm.1"),
CLK_LOOKUP("vpe_clk", vpe_clk.c, NULL),
CLK_LOOKUP("core_clk", vpe_clk.c, "footswitch-8x60.9"),
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index 5006419..51f0336 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -10,6 +10,8 @@
* GNU General Public License for more details.
*/
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/delay.h>
@@ -22,6 +24,7 @@
#include <mach/msm_bus_board.h>
#include <mach/msm_bus.h>
#include <mach/scm-io.h>
+#include <mach/socinfo.h>
#include "clock.h"
#include "footswitch.h"
@@ -49,8 +52,9 @@
#define RETENTION_BIT BIT(9)
#define RESET_DELAY_US 1
-/* Core clock rate to use if one has not previously been set. */
-#define DEFAULT_CLK_RATE 27000000
+/* Clock rate to use if one has not previously been set. */
+#define DEFAULT_RATE 27000000
+#define MAX_CLKS 10
/*
* Lock is only needed to protect against the first footswitch_enable()
@@ -58,72 +62,76 @@
*/
static DEFINE_MUTEX(claim_lock);
-struct clock_state {
- int ahb_clk_en;
- int axi_clk_en;
- int core_clk_rate;
+struct clk_data {
+ const char *name;
+ struct clk *clk;
+ unsigned long rate;
+ unsigned long reset_rate;
+ bool enabled;
};
struct footswitch {
struct regulator_dev *rdev;
struct regulator_desc desc;
void *gfs_ctl_reg;
- int bus_port1, bus_port2;
+ int bus_port0, bus_port1;
bool is_enabled;
bool is_claimed;
- const bool has_axi_clk;
+ struct clk_data *clk_data;
struct clk *core_clk;
- struct clk *ahb_clk;
- struct clk *axi_clk;
- unsigned int reset_rate;
- struct clock_state clk_state;
unsigned int gfs_delay_cnt:5;
};
static int setup_clocks(struct footswitch *fs)
{
int rc = 0;
+ struct clk_data *clock;
+ long rate;
/*
- * Enable all clocks in the power domain. If a core requires a
- * specific clock rate when being reset, apply it.
+ * Enable all clocks in the power domain. If a specific clock rate is
+ * required for reset timing, set that rate before enabling the clocks.
*/
- fs->clk_state.core_clk_rate = clk_get_rate(fs->core_clk);
- if (!fs->clk_state.core_clk_rate || fs->reset_rate) {
- int rate = fs->reset_rate ? fs->reset_rate : DEFAULT_CLK_RATE;
- rc = clk_set_rate(fs->core_clk, rate);
- if (rc) {
- pr_err("%s: Failed to set core_clk rate to %d Hz.\n",
- __func__, fs->reset_rate);
- return rc;
+ for (clock = fs->clk_data; clock->clk; clock++) {
+ clock->rate = clk_get_rate(clock->clk);
+ if (!clock->rate || clock->reset_rate) {
+ rate = clock->reset_rate ?
+ clock->reset_rate : DEFAULT_RATE;
+ rc = clk_set_rate(clock->clk, rate);
+ if (rc && rc != -ENOSYS) {
+ pr_err("Failed to set %s rate to %lu Hz.\n",
+ clock->name, clock->rate);
+ for (clock--; clock >= fs->clk_data; clock--) {
+ if (clock->enabled)
+ clk_disable(clock->clk);
+ clk_set_rate(clock->clk, clock->rate);
+ }
+ return rc;
+ }
}
+ /*
+ * Some clocks are for reset purposes only. These clocks will
+ * fail to enable. Ignore the failures but keep track of them so
+ * we don't try to disable them later and crash due to
+ * unbalanced calls.
+ */
+ clock->enabled = !clk_enable(clock->clk);
}
- clk_enable(fs->core_clk);
- /*
- * Some AHB and AXI clocks are for reset purposes only. These clocks
- * will fail to enable. Keep track of them so we don't try to disable
- * them later and crash.
- */
- fs->clk_state.ahb_clk_en = !clk_enable(fs->ahb_clk);
- if (fs->axi_clk)
- fs->clk_state.axi_clk_en = !clk_enable(fs->axi_clk);
-
- return rc;
+ return 0;
}
static void restore_clocks(struct footswitch *fs)
{
+ struct clk_data *clock;
+
/* Restore clocks to their orignal states before setup_clocks(). */
- if (fs->axi_clk && fs->clk_state.axi_clk_en)
- clk_disable(fs->axi_clk);
- if (fs->clk_state.ahb_clk_en)
- clk_disable(fs->ahb_clk);
- clk_disable(fs->core_clk);
- if (fs->clk_state.core_clk_rate) {
- if (clk_set_rate(fs->core_clk, fs->clk_state.core_clk_rate))
- pr_err("%s: Failed to restore core_clk rate.\n",
- __func__);
+ for (clock = fs->clk_data; clock->clk; clock++) {
+ if (clock->enabled)
+ clk_disable(clock->clk);
+ if (clock->rate && clk_set_rate(clock->clk, clock->rate))
+ pr_err("Failed to restore %s rate to %lu Hz.\n",
+ clock->name, clock->rate);
}
}
@@ -137,6 +145,7 @@
static int footswitch_enable(struct regulator_dev *rdev)
{
struct footswitch *fs = rdev_get_drvdata(rdev);
+ struct clk_data *clock;
uint32_t regval, rc = 0;
mutex_lock(&claim_lock);
@@ -154,17 +163,17 @@
return rc;
/* Un-halt all bus ports in the power domain. */
- if (fs->bus_port1) {
- rc = msm_bus_axi_portunhalt(fs->bus_port1);
+ if (fs->bus_port0) {
+ rc = msm_bus_axi_portunhalt(fs->bus_port0);
if (rc) {
- pr_err("%s: Port 1 unhalt failed.\n", __func__);
+ pr_err("Port 0 unhalt failed.\n");
goto err;
}
}
- if (fs->bus_port2) {
- rc = msm_bus_axi_portunhalt(fs->bus_port2);
+ if (fs->bus_port1) {
+ rc = msm_bus_axi_portunhalt(fs->bus_port1);
if (rc) {
- pr_err("%s: Port 2 unhalt failed.\n", __func__);
+ pr_err("Port 1 unhalt failed.\n");
goto err_port2_halt;
}
}
@@ -174,10 +183,8 @@
* footswitch_enable() is first called before footswitch_disable()
* and resets should be asserted before power is restored.
*/
- if (fs->axi_clk)
- clk_reset(fs->axi_clk, CLK_RESET_ASSERT);
- clk_reset(fs->ahb_clk, CLK_RESET_ASSERT);
- clk_reset(fs->core_clk, CLK_RESET_ASSERT);
+ for (clock = fs->clk_data; clock->clk; clock++)
+ clk_reset(clock->clk, CLK_RESET_ASSERT);
/* Wait for synchronous resets to propagate. */
udelay(RESET_DELAY_US);
@@ -193,10 +200,8 @@
writel_relaxed(regval, fs->gfs_ctl_reg);
/* Deassert resets for all clocks in the power domain. */
- clk_reset(fs->core_clk, CLK_RESET_DEASSERT);
- clk_reset(fs->ahb_clk, CLK_RESET_DEASSERT);
- if (fs->axi_clk)
- clk_reset(fs->axi_clk, CLK_RESET_DEASSERT);
+ for (clock = fs->clk_data; clock->clk; clock++)
+ clk_reset(clock->clk, CLK_RESET_DEASSERT);
/* Toggle core reset again after first power-on (required for GFX3D). */
if (fs->desc.id == FS_GFX3D) {
clk_reset(fs->core_clk, CLK_RESET_ASSERT);
@@ -212,7 +217,7 @@
return 0;
err_port2_halt:
- msm_bus_axi_porthalt(fs->bus_port1);
+ msm_bus_axi_porthalt(fs->bus_port0);
err:
restore_clocks(fs);
return rc;
@@ -221,6 +226,7 @@
static int footswitch_disable(struct regulator_dev *rdev)
{
struct footswitch *fs = rdev_get_drvdata(rdev);
+ struct clk_data *clock;
uint32_t regval, rc = 0;
/* Return early if already disabled. */
@@ -234,17 +240,17 @@
return rc;
/* Halt all bus ports in the power domain. */
- if (fs->bus_port1) {
- rc = msm_bus_axi_porthalt(fs->bus_port1);
+ if (fs->bus_port0) {
+ rc = msm_bus_axi_porthalt(fs->bus_port0);
if (rc) {
- pr_err("%s: Port 1 halt failed.\n", __func__);
+ pr_err("Port 0 halt failed.\n");
goto err;
}
}
- if (fs->bus_port2) {
- rc = msm_bus_axi_porthalt(fs->bus_port2);
+ if (fs->bus_port1) {
+ rc = msm_bus_axi_porthalt(fs->bus_port1);
if (rc) {
- pr_err("%s: Port 1 halt failed.\n", __func__);
+ pr_err("Port 1 halt failed.\n");
goto err_port2_halt;
}
}
@@ -253,10 +259,8 @@
* Assert resets for all clocks in the clock domain so that
* outputs settle prior to clamping.
*/
- if (fs->axi_clk)
- clk_reset(fs->axi_clk, CLK_RESET_ASSERT);
- clk_reset(fs->ahb_clk, CLK_RESET_ASSERT);
- clk_reset(fs->core_clk, CLK_RESET_ASSERT);
+ for (clock = fs->clk_data; clock->clk; clock++)
+ clk_reset(clock->clk, CLK_RESET_ASSERT);
/* Wait for synchronous resets to propagate. */
udelay(RESET_DELAY_US);
@@ -283,7 +287,7 @@
return 0;
err_port2_halt:
- msm_bus_axi_portunhalt(fs->bus_port1);
+ msm_bus_axi_portunhalt(fs->bus_port0);
err:
restore_clocks(fs);
return rc;
@@ -292,6 +296,7 @@
static int gfx2d_footswitch_enable(struct regulator_dev *rdev)
{
struct footswitch *fs = rdev_get_drvdata(rdev);
+ struct clk_data *clock;
uint32_t regval, rc = 0;
mutex_lock(&claim_lock);
@@ -309,10 +314,10 @@
return rc;
/* Un-halt all bus ports in the power domain. */
- if (fs->bus_port1) {
- rc = msm_bus_axi_portunhalt(fs->bus_port1);
+ if (fs->bus_port0) {
+ rc = msm_bus_axi_portunhalt(fs->bus_port0);
if (rc) {
- pr_err("%s: Port 1 unhalt failed.\n", __func__);
+ pr_err("Port 0 unhalt failed.\n");
goto err;
}
}
@@ -325,12 +330,10 @@
* footswitch_enable() is first called before footswitch_disable()
* and resets should be asserted before power is restored.
*/
- if (fs->axi_clk)
- clk_reset(fs->axi_clk, CLK_RESET_ASSERT);
- clk_reset(fs->ahb_clk, CLK_RESET_ASSERT);
- clk_reset(fs->core_clk, CLK_RESET_ASSERT);
+ for (clock = fs->clk_data; clock->clk; clock++)
+ clk_reset(clock->clk, CLK_RESET_ASSERT);
/* Wait for synchronous resets to propagate. */
- udelay(20);
+ udelay(RESET_DELAY_US);
/* Enable the power rail at the footswitch. */
regval |= ENABLE_BIT;
@@ -343,11 +346,9 @@
writel_relaxed(regval, fs->gfs_ctl_reg);
/* Deassert resets for all clocks in the power domain. */
- if (fs->axi_clk)
- clk_reset(fs->axi_clk, CLK_RESET_DEASSERT);
- clk_reset(fs->ahb_clk, CLK_RESET_DEASSERT);
- clk_reset(fs->core_clk, CLK_RESET_DEASSERT);
- udelay(20);
+ for (clock = fs->clk_data; clock->clk; clock++)
+ clk_reset(clock->clk, CLK_RESET_DEASSERT);
+ udelay(RESET_DELAY_US);
/* Re-enable core clock. */
clk_enable(fs->core_clk);
@@ -366,6 +367,7 @@
static int gfx2d_footswitch_disable(struct regulator_dev *rdev)
{
struct footswitch *fs = rdev_get_drvdata(rdev);
+ struct clk_data *clock;
uint32_t regval, rc = 0;
/* Return early if already disabled. */
@@ -379,10 +381,10 @@
return rc;
/* Halt all bus ports in the power domain. */
- if (fs->bus_port1) {
- rc = msm_bus_axi_porthalt(fs->bus_port1);
+ if (fs->bus_port0) {
+ rc = msm_bus_axi_porthalt(fs->bus_port0);
if (rc) {
- pr_err("%s: Port 1 halt failed.\n", __func__);
+ pr_err("Port 0 halt failed.\n");
goto err;
}
}
@@ -394,12 +396,10 @@
* Assert resets for all clocks in the clock domain so that
* outputs settle prior to clamping.
*/
- if (fs->axi_clk)
- clk_reset(fs->axi_clk, CLK_RESET_ASSERT);
- clk_reset(fs->ahb_clk, CLK_RESET_ASSERT);
- clk_reset(fs->core_clk, CLK_RESET_ASSERT);
+ for (clock = fs->clk_data; clock->clk; clock++)
+ clk_reset(clock->clk, CLK_RESET_ASSERT);
/* Wait for synchronous resets to propagate. */
- udelay(20);
+ udelay(5);
/*
* Clamp the I/O ports of the core to ensure the values
@@ -438,8 +438,102 @@
.disable = gfx2d_footswitch_disable,
};
-#define FOOTSWITCH(_id, _name, _ops, _gfs_ctl_reg, _dc, _axi_clk, \
- _reset_rate, _bp1, _bp2) \
+/*
+ * Lists of required clocks for the collapse and restore sequences.
+ *
+ * Order matters here. Clocks are listed in the same order as their
+ * resets will be de-asserted when the core is restored. Also, rate-
+ * settable clocks must be listed before any of the branches that
+ * are derived from them. Otherwise, the branches may fail to enable
+ * if their parent's rate is not yet set.
+ */
+
+static struct clk_data gfx2d0_clks[] = {
+ { .name = "core_clk" },
+ { .name = "iface_clk" },
+ { 0 }
+};
+
+static struct clk_data gfx2d1_clks[] = {
+ { .name = "core_clk" },
+ { .name = "iface_clk" },
+ { 0 }
+};
+
+static struct clk_data gfx3d_clks[] = {
+ { .name = "core_clk", .reset_rate = 27000000 },
+ { .name = "iface_clk" },
+ { 0 }
+};
+
+
+static struct clk_data ijpeg_clks[] = {
+ { .name = "core_clk" },
+ { .name = "iface_clk" },
+ { .name = "bus_clk" },
+ { 0 }
+};
+
+static struct clk_data mdp_8960_clks[] = {
+ { .name = "core_clk" },
+ { .name = "iface_clk" },
+ { .name = "bus_clk" },
+ { .name = "vsync_clk" },
+ { .name = "lut_clk" },
+ { .name = "tv_src_clk" },
+ { .name = "tv_clk" },
+ { 0 }
+};
+
+static struct clk_data mdp_8660_clks[] = {
+ { .name = "core_clk" },
+ { .name = "iface_clk" },
+ { .name = "bus_clk" },
+ { .name = "vsync_clk" },
+ { .name = "tv_src_clk" },
+ { .name = "tv_clk" },
+ { .name = "pixel_mdp_clk" },
+ { .name = "pixel_lcdc_clk" },
+ { 0 }
+};
+
+static struct clk_data rot_clks[] = {
+ { .name = "core_clk" },
+ { .name = "iface_clk" },
+ { .name = "bus_clk" },
+ { 0 }
+};
+
+static struct clk_data ved_clks[] = {
+ { .name = "core_clk" },
+ { .name = "iface_clk" },
+ { .name = "bus_clk" },
+ { 0 }
+};
+
+static struct clk_data vfe_clks[] = {
+ { .name = "core_clk" },
+ { .name = "iface_clk" },
+ { .name = "bus_clk" },
+ { 0 }
+};
+
+static struct clk_data vpe_clks[] = {
+ { .name = "core_clk" },
+ { .name = "iface_clk" },
+ { .name = "bus_clk" },
+ { 0 }
+};
+
+static struct clk_data vcap_clks[] = {
+ { .name = "core_clk" },
+ { .name = "iface_clk" },
+ { .name = "bus_clk" },
+ { 0 }
+};
+
+#define FOOTSWITCH(_id, _name, _ops, _gfs_ctl_reg, _dc, _clk_data, \
+ _bp1, _bp2) \
[(_id)] = { \
.desc = { \
.id = (_id), \
@@ -450,43 +544,42 @@
}, \
.gfs_ctl_reg = (_gfs_ctl_reg), \
.gfs_delay_cnt = (_dc), \
- .bus_port1 = (_bp1), \
- .bus_port2 = (_bp2), \
- .has_axi_clk = (_axi_clk), \
- .reset_rate = (_reset_rate), \
+ .clk_data = (_clk_data), \
+ .bus_port0 = (_bp1), \
+ .bus_port1 = (_bp2), \
}
static struct footswitch footswitches[] = {
FOOTSWITCH(FS_GFX2D0, "fs_gfx2d0", &gfx2d_fs_ops,
- GFX2D0_GFS_CTL_REG, 31, false, 0,
+ GFX2D0_GFS_CTL_REG, 31, gfx2d0_clks,
MSM_BUS_MASTER_GRAPHICS_2D_CORE0, 0),
FOOTSWITCH(FS_GFX2D1, "fs_gfx2d1", &gfx2d_fs_ops,
- GFX2D1_GFS_CTL_REG, 31, false, 0,
+ GFX2D1_GFS_CTL_REG, 31, gfx2d1_clks,
MSM_BUS_MASTER_GRAPHICS_2D_CORE1, 0),
FOOTSWITCH(FS_GFX3D, "fs_gfx3d", &standard_fs_ops,
- GFX3D_GFS_CTL_REG, 31, false, 27000000,
+ GFX3D_GFS_CTL_REG, 31, gfx3d_clks,
MSM_BUS_MASTER_GRAPHICS_3D, 0),
FOOTSWITCH(FS_IJPEG, "fs_ijpeg", &standard_fs_ops,
- GEMINI_GFS_CTL_REG, 31, true, 0,
+ GEMINI_GFS_CTL_REG, 31, ijpeg_clks,
MSM_BUS_MASTER_JPEG_ENC, 0),
FOOTSWITCH(FS_MDP, "fs_mdp", &standard_fs_ops,
- MDP_GFS_CTL_REG, 31, true, 0,
+ MDP_GFS_CTL_REG, 31, NULL,
MSM_BUS_MASTER_MDP_PORT0,
MSM_BUS_MASTER_MDP_PORT1),
FOOTSWITCH(FS_ROT, "fs_rot", &standard_fs_ops,
- ROT_GFS_CTL_REG, 31, true, 0,
+ ROT_GFS_CTL_REG, 31, rot_clks,
MSM_BUS_MASTER_ROTATOR, 0),
FOOTSWITCH(FS_VED, "fs_ved", &standard_fs_ops,
- VED_GFS_CTL_REG, 31, true, 0,
+ VED_GFS_CTL_REG, 31, ved_clks,
MSM_BUS_MASTER_HD_CODEC_PORT0,
MSM_BUS_MASTER_HD_CODEC_PORT1),
FOOTSWITCH(FS_VFE, "fs_vfe", &standard_fs_ops,
- VFE_GFS_CTL_REG, 31, true, 0,
+ VFE_GFS_CTL_REG, 31, vfe_clks,
MSM_BUS_MASTER_VFE, 0),
FOOTSWITCH(FS_VPE, "fs_vpe", &standard_fs_ops,
- VPE_GFS_CTL_REG, 31, true, 0,
+ VPE_GFS_CTL_REG, 31, vpe_clks,
MSM_BUS_MASTER_VPE, 0),
FOOTSWITCH(FS_VCAP, "fs_vcap", &standard_fs_ops,
- VCAP_GFS_CTL_REG, 31, true, 0,
+ VCAP_GFS_CTL_REG, 31, vcap_clks,
MSM_BUS_MASTER_VIDEO_CAP, 0),
};
@@ -494,6 +587,7 @@
{
struct footswitch *fs;
struct regulator_init_data *init_data;
+ struct clk_data *clock;
uint32_t regval, rc = 0;
if (pdev == NULL)
@@ -505,30 +599,24 @@
fs = &footswitches[pdev->id];
init_data = pdev->dev.platform_data;
- /* Setup core clock. */
- fs->core_clk = clk_get(&pdev->dev, "core_clk");
- if (IS_ERR(fs->core_clk)) {
- pr_err("%s: clk_get(core_clk) failed\n", __func__);
- rc = PTR_ERR(fs->core_clk);
- goto err_core_clk;
+ if (pdev->id == FS_MDP) {
+ if (cpu_is_msm8960() || cpu_is_msm8930())
+ fs->clk_data = mdp_8960_clks;
+ else if (cpu_is_msm8x60())
+ fs->clk_data = mdp_8660_clks;
+ else
+ BUG();
}
- /* Setup AHB clock. */
- fs->ahb_clk = clk_get(&pdev->dev, "iface_clk");
- if (IS_ERR(fs->ahb_clk)) {
- pr_err("%s: clk_get(iface_clk) failed\n", __func__);
- rc = PTR_ERR(fs->ahb_clk);
- goto err_ahb_clk;
- }
-
- /* Setup AXI clock. */
- if (fs->has_axi_clk) {
- fs->axi_clk = clk_get(&pdev->dev, "bus_clk");
- if (IS_ERR(fs->axi_clk)) {
- pr_err("%s: clk_get(bus_clk) failed\n", __func__);
- rc = PTR_ERR(fs->axi_clk);
- goto err_axi_clk;
+ for (clock = fs->clk_data; clock->name; clock++) {
+ clock->clk = clk_get(&pdev->dev, clock->name);
+ if (IS_ERR(clock->clk)) {
+ rc = PTR_ERR(clock->clk);
+ pr_err("clk_get(%s) failed\n", clock->name);
+ goto err;
}
+ if (!strncmp(clock->name, "core_clk", 8))
+ fs->core_clk = clock->clk;
}
/*
@@ -543,34 +631,28 @@
fs->rdev = regulator_register(&fs->desc, &pdev->dev, init_data, fs);
if (IS_ERR(footswitches[pdev->id].rdev)) {
- pr_err("%s: regulator_register(\"%s\") failed\n",
- __func__, fs->desc.name);
+ pr_err("regulator_register(\"%s\") failed\n",
+ fs->desc.name);
rc = PTR_ERR(footswitches[pdev->id].rdev);
- goto err_register;
+ goto err;
}
return 0;
-err_register:
- if (fs->has_axi_clk)
- clk_put(fs->axi_clk);
-err_axi_clk:
- clk_put(fs->ahb_clk);
-err_ahb_clk:
- clk_put(fs->core_clk);
-err_core_clk:
+err:
+ for (clock = fs->clk_data; clock->clk; clock++)
+ clk_put(clock->clk);
+
return rc;
}
static int __devexit footswitch_remove(struct platform_device *pdev)
{
struct footswitch *fs = &footswitches[pdev->id];
+ struct clk_data *clock;
- clk_put(fs->core_clk);
- clk_put(fs->ahb_clk);
- if (fs->axi_clk)
- clk_put(fs->axi_clk);
-
+ for (clock = fs->clk_data; clock->clk; clock++)
+ clk_put(clock->clk);
regulator_unregister(fs->rdev);
return 0;
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index a971594..aef3f4e 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -83,6 +83,8 @@
return AO8960_TOOLS_ID;
case APQ8064_MACHINE_ID:
return APQ8064_TOOLS_ID;
+ case MSM8930_MACHINE_ID:
+ return MSM8930_TOOLS_ID;
default:
return 0;
}
@@ -97,6 +99,12 @@
switch (socinfo_get_id()) {
case AO8960_MACHINE_ID:
case APQ8064_MACHINE_ID:
+ case MSM8930_MACHINE_ID:
+ case MSM8630_MACHINE_ID:
+ case MSM8230_MACHINE_ID:
+ case APQ8030_MACHINE_ID:
+ case MSM8627_MACHINE_ID:
+ case MSM8227_MACHINE_ID:
return 1;
default:
return 0;
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index edf5c27..d6fb937 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -82,6 +82,7 @@
#define MAX_SESSIONS 16
#define INVALID_SESSION -1
#define VERSION_KEY_MASK 0xFFFFFF00
+#define MAX_DOWNSCALE_RATIO 3
struct tile_parm {
unsigned int width; /* tile's width */
@@ -428,7 +429,9 @@
}
iowrite32((1 << 18) | /* chroma sampling 1=H2V1 */
(ROTATIONS_TO_BITMASK(info->rotations) << 9) |
- 1 << 8, /* ROT_EN */
+ 1 << 8 | /* ROT_EN */
+ info->downscale_ratio << 2 | /* downscale v ratio */
+ info->downscale_ratio, /* downscale h ratio */
MSM_ROTATOR_SUB_BLOCK_CFG);
iowrite32(0 << 29 | /* frame format 0 = linear */
(use_imem ? 0 : 1) << 22 | /* tile size */
@@ -528,7 +531,9 @@
}
iowrite32((3 << 18) | /* chroma sampling 3=4:2:0 */
(ROTATIONS_TO_BITMASK(info->rotations) << 9) |
- 1 << 8, /* ROT_EN */
+ 1 << 8 | /* ROT_EN */
+ info->downscale_ratio << 2 | /* downscale v ratio */
+ info->downscale_ratio, /* downscale h ratio */
MSM_ROTATOR_SUB_BLOCK_CFG);
iowrite32((is_tile ? 2 : 0) << 29 | /* frame format */
@@ -579,7 +584,9 @@
MSM_ROTATOR_OUT_PACK_PATTERN1);
iowrite32((1 << 18) | /* chroma sampling 1=H2V1 */
(ROTATIONS_TO_BITMASK(info->rotations) << 9) |
- 1 << 8, /* ROT_EN */
+ 1 << 8 | /* ROT_EN */
+ info->downscale_ratio << 2 | /* downscale v ratio */
+ info->downscale_ratio, /* downscale h ratio */
MSM_ROTATOR_SUB_BLOCK_CFG);
iowrite32(0 << 29 | /* frame format 0 = linear */
(use_imem ? 0 : 1) << 22 | /* tile size */
@@ -624,7 +631,9 @@
iowrite32(info->dst.width * bpp, MSM_ROTATOR_OUT_YSTRIDE1);
iowrite32((0 << 18) | /* chroma sampling 0=rgb */
(ROTATIONS_TO_BITMASK(info->rotations) << 9) |
- 1 << 8, /* ROT_EN */
+ 1 << 8 | /* ROT_EN */
+ info->downscale_ratio << 2 | /* downscale v ratio */
+ info->downscale_ratio, /* downscale h ratio */
MSM_ROTATOR_SUB_BLOCK_CFG);
switch (info->src.format) {
case MDP_RGB_565:
@@ -1068,24 +1077,31 @@
if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
return -EFAULT;
- if (info.rotations & MDP_ROT_90) {
- dst_w = info.src_rect.h;
- dst_h = info.src_rect.w;
- } else {
- dst_w = info.src_rect.w;
- dst_h = info.src_rect.h;
- }
-
if ((info.rotations > MSM_ROTATOR_MAX_ROT) ||
(info.src.height > MSM_ROTATOR_MAX_H) ||
(info.src.width > MSM_ROTATOR_MAX_W) ||
(info.dst.height > MSM_ROTATOR_MAX_H) ||
(info.dst.width > MSM_ROTATOR_MAX_W) ||
- checkoffset(info.src_rect.x, info.src_rect.w, info.src.width) ||
+ (info.downscale_ratio > MAX_DOWNSCALE_RATIO)) {
+ pr_err("%s: Invalid parameters\n", __func__);
+ return -EINVAL;
+ }
+
+ if (info.rotations & MDP_ROT_90) {
+ dst_w = info.src_rect.h >> info.downscale_ratio;
+ dst_h = info.src_rect.w >> info.downscale_ratio;
+ } else {
+ dst_w = info.src_rect.w >> info.downscale_ratio;
+ dst_h = info.src_rect.h >> info.downscale_ratio;
+ }
+
+ if (checkoffset(info.src_rect.x, info.src_rect.w, info.src.width) ||
checkoffset(info.src_rect.y, info.src_rect.h, info.src.height) ||
checkoffset(info.dst_x, dst_w, info.dst.width) ||
- checkoffset(info.dst_y, dst_h, info.dst.height))
- return -EINVAL;
+ checkoffset(info.dst_y, dst_h, info.dst.height)) {
+ pr_err("%s: Invalid src or dst rect\n", __func__);
+ return -ERANGE;
+ }
switch (info.src.format) {
case MDP_RGB_565:
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 5c94a3c..bdbaffd 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -41,9 +41,16 @@
#define AO8960_MACHINE_ID 87
#define MSM8660_MACHINE_ID 71
#define APQ8064_MACHINE_ID 109
+#define MSM8930_MACHINE_ID 116
+#define MSM8630_MACHINE_ID 117
+#define MSM8230_MACHINE_ID 118
+#define APQ8030_MACHINE_ID 119
+#define MSM8627_MACHINE_ID 120
+#define MSM8227_MACHINE_ID 121
#define APQ8060_TOOLS_ID 4062
#define AO8960_TOOLS_ID 4064
#define APQ8064_TOOLS_ID 4072
+#define MSM8930_TOOLS_ID 4072
#define MSG_MASK_0 (0x00000001)
#define MSG_MASK_1 (0x00000002)
diff --git a/include/linux/msm_rotator.h b/include/linux/msm_rotator.h
index 611d7b4..72809cf 100644
--- a/include/linux/msm_rotator.h
+++ b/include/linux/msm_rotator.h
@@ -30,6 +30,7 @@
unsigned int dst_y;
unsigned char rotations;
int enable;
+ unsigned int downscale_ratio;
};
struct msm_rotator_data_info {