From df747c0a1f26594e9e60dd9619036b8995d4023f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pali=20Roh=C3=A1r?= Date: Sat, 7 Jan 2012 19:16:52 +0100 Subject: [PATCH] Added patches by freemangordon: * efuse calibrations are re-calculated - using linear approximation instead of hard-coded increments * camera driver to use framebuffer memory for video-capture buffer(DMA to framebuffer) --- .../debian/patches/overclock_smartreflex_900.diff | 381 ++++++++++++++------ kernel-power-2.6.28/debian/patches/series | 2 + ...ort-non-page-aligned-buffers-in-iommu_vmap.diff | 113 ++++++ ...buf-dma-sg-support-non-pagable-user-memory.diff | 85 +++++ 4 files changed, 479 insertions(+), 102 deletions(-) create mode 100644 kernel-power-2.6.28/debian/patches/support-non-page-aligned-buffers-in-iommu_vmap.diff create mode 100644 kernel-power-2.6.28/debian/patches/videobuf-dma-sg-support-non-pagable-user-memory.diff diff --git a/kernel-power-2.6.28/debian/patches/overclock_smartreflex_900.diff b/kernel-power-2.6.28/debian/patches/overclock_smartreflex_900.diff index 4421cec..d4d8807 100644 --- a/kernel-power-2.6.28/debian/patches/overclock_smartreflex_900.diff +++ b/kernel-power-2.6.28/debian/patches/overclock_smartreflex_900.diff @@ -1,6 +1,6 @@ -diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/omap3-opp.h kernel-power-2.6.28.SR/arch/arm/mach-omap2/omap3-opp.h ---- kernel-power-2.6.28/arch/arm/mach-omap2/omap3-opp.h 2011-10-11 13:51:21.441301622 +0100 -+++ kernel-power-2.6.28.SR/arch/arm/mach-omap2/omap3-opp.h 2011-10-22 16:31:45.291911000 +0100 +diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/omap3-opp.h kernel-power-2.6.28.new/arch/arm/mach-omap2/omap3-opp.h +--- kernel-power-2.6.28/arch/arm/mach-omap2/omap3-opp.h 2012-01-07 13:49:16.551071653 +0000 ++++ kernel-power-2.6.28.new/arch/arm/mach-omap2/omap3-opp.h 2011-12-31 12:54:23.719318887 +0000 @@ -11,8 +11,7 @@ #define S900M 900000000 #define S850M 850000000 @@ -11,9 +11,9 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/omap3-opp.h kernel-power-2.6.2 #define S600M 600000000 #define S550M 550000000 #define S500M 500000000 -diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/pm34xx.c kernel-power-2.6.28.SR/arch/arm/mach-omap2/pm34xx.c ---- kernel-power-2.6.28/arch/arm/mach-omap2/pm34xx.c 2011-10-11 13:51:19.475662264 +0100 -+++ kernel-power-2.6.28.SR/arch/arm/mach-omap2/pm34xx.c 2011-11-14 17:06:15.733128000 +0000 +diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/pm34xx.c kernel-power-2.6.28.new/arch/arm/mach-omap2/pm34xx.c +--- kernel-power-2.6.28/arch/arm/mach-omap2/pm34xx.c 2012-01-07 13:49:16.515051220 +0000 ++++ kernel-power-2.6.28.new/arch/arm/mach-omap2/pm34xx.c 2011-12-31 12:54:23.735963309 +0000 @@ -629,9 +629,9 @@ * Only needed if we are going to enter retention. */ @@ -26,9 +26,9 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/pm34xx.c kernel-power-2.6.28.S /* CORE */ if (core_next_state < PWRDM_POWER_ON) { -diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/pm.c kernel-power-2.6.28.SR/arch/arm/mach-omap2/pm.c ---- kernel-power-2.6.28/arch/arm/mach-omap2/pm.c 2011-10-11 13:51:21.444897248 +0100 -+++ kernel-power-2.6.28.SR/arch/arm/mach-omap2/pm.c 2011-11-12 13:33:08.600565000 +0000 +diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/pm.c kernel-power-2.6.28.new/arch/arm/mach-omap2/pm.c +--- kernel-power-2.6.28/arch/arm/mach-omap2/pm.c 2012-01-07 13:49:16.567287927 +0000 ++++ kernel-power-2.6.28.new/arch/arm/mach-omap2/pm.c 2011-12-31 12:54:23.772101815 +0000 @@ -44,25 +44,23 @@ struct omap_opp omap3_mpu_rate_table[] = { @@ -125,9 +125,9 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/pm.c kernel-power-2.6.28.SR/ar printk(KERN_ERR "vdd_opp_store: Invalid value\n"); return -EINVAL; } -diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/resource34xx.c kernel-power-2.6.28.SR/arch/arm/mach-omap2/resource34xx.c ---- kernel-power-2.6.28/arch/arm/mach-omap2/resource34xx.c 2011-10-11 13:50:56.787174344 +0100 -+++ kernel-power-2.6.28.SR/arch/arm/mach-omap2/resource34xx.c 2011-11-15 10:50:41.556771000 +0000 +diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/resource34xx.c kernel-power-2.6.28.new/arch/arm/mach-omap2/resource34xx.c +--- kernel-power-2.6.28/arch/arm/mach-omap2/resource34xx.c 2012-01-07 13:49:16.527031015 +0000 ++++ kernel-power-2.6.28.new/arch/arm/mach-omap2/resource34xx.c 2011-12-31 12:54:23.772101815 +0000 @@ -279,7 +279,7 @@ #ifdef CONFIG_OMAP_SMARTREFLEX @@ -137,9 +137,9 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/resource34xx.c kernel-power-2. #endif for (i = 0; i < 2; i++) { if (i == raise) -diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6.28.SR/arch/arm/mach-omap2/smartreflex.c ---- kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c 2011-10-11 13:51:21.441301622 +0100 -+++ kernel-power-2.6.28.SR/arch/arm/mach-omap2/smartreflex.c 2011-11-15 10:54:13.761220000 +0000 +diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6.28.new/arch/arm/mach-omap2/smartreflex.c +--- kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c 2012-01-07 13:49:16.583042210 +0000 ++++ kernel-power-2.6.28.new/arch/arm/mach-omap2/smartreflex.c 2012-01-06 20:56:55.000000000 +0000 @@ -37,6 +37,7 @@ #include "prm.h" #include "smartreflex.h" @@ -148,20 +148,31 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 /* * VP_TRANXDONE_TIMEOUT: maximum microseconds to wait for the VP to -@@ -73,6 +74,12 @@ +@@ -73,6 +74,23 @@ */ #define SR_DISABLE_MAX_ATTEMPTS 4 +#define ACCURACY 100 +#define NDELTA_3430 (3.0 * ACCURACY) +#define PDELTA_3430 (2.6 * ACCURACY) -+#define SR_NVALUE_ADJUST -150000 -+#define SR_NVALUE_DSP_ADJUST 12500 ++ ++/* Since factory calibrated Efuse values lead to very high SR calculated voltages ++ * adjust them with a constant ++ */ ++#define SR_NVALUE_ADJUST_LOWOPP -150000 /* For 125 and 250 MHz */ ++#define SR_NVALUE_ADJUST_HIGHOPP -125000 /* For 500+ MHz */ ++ ++/* Boost voltage with the bellow value(in uV) when DSP frequency is >430 MHz and ++ * twice that value when DSP frequency is > 520 Mhz ++ */ ++#define SR_NVALUE_DSP_MAX_ADJUST 100000 ++ ++static atomic_t sr_vdd1_dsp_boost_coeff; + struct omap_sr { int srid; int is_sr_reset; -@@ -82,6 +89,7 @@ +@@ -82,6 +100,7 @@ u32 req_opp_no; u32 opp1_nvalue, opp2_nvalue, opp3_nvalue, opp4_nvalue; u32 opp5_nvalue; @@ -169,7 +180,7 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 u32 senp_mod, senn_mod; void __iomem *srbase_addr; void __iomem *vpbase_addr; -@@ -101,6 +109,7 @@ +@@ -101,6 +120,7 @@ reg_val = __raw_readl(SR_REGADDR(offset)); reg_val &= ~mask; @@ -177,7 +188,7 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 reg_val |= value; __raw_writel(reg_val, SR_REGADDR(offset)); -@@ -211,6 +220,147 @@ +@@ -211,26 +231,173 @@ } } @@ -221,17 +232,6 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 + return (u32)(n_slope_a*freq+n_slope_b)/1000; +} + -+static u32 calculate_freq_efuse_value(u32 opp0fuse,u32 opp1fuse,u32 freq) -+{ -+ u32 sen_nrn, sen_ngain, sen_prn, sen_pgain; -+ u32 padj,nadj; -+ cal_reciprocal(padj=get_padj_for_freq(opp0fuse,opp1fuse,freq), &sen_pgain, &sen_prn); -+ cal_reciprocal(nadj=get_nadj_for_freq(opp0fuse,opp1fuse,freq), &sen_ngain, &sen_nrn); -+ -+ return (sen_pgain << 0x14) | (sen_ngain << 0x10) -+ | (sen_prn << 0x08) | (sen_nrn); -+} -+ +/** + * recalc_with_margin() - helper to add margin to reciprocal and gain + * @uv: voltage in uVolts to add. @@ -322,10 +322,30 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 + (temp_senp_reciprocal << 8) | temp_senn_reciprocal; + +} ++ ++static u32 calculate_freq_efuse_value(u32 opp0efuse,u32 opp1efuse,u32 freq) ++{ ++ u32 sen_nrn, sen_ngain, sen_prn, sen_pgain; ++ u32 opp0efuse_adj = sr_ntarget_add_margin(opp0efuse,freq>S250M?SR_NVALUE_ADJUST_HIGHOPP:SR_NVALUE_ADJUST_LOWOPP); ++ u32 opp1efuse_adj = sr_ntarget_add_margin(opp1efuse,freq>S250M?SR_NVALUE_ADJUST_HIGHOPP:SR_NVALUE_ADJUST_LOWOPP); ++ ++ freq/=1000000; ++ cal_reciprocal(get_padj_for_freq(opp0efuse_adj,opp1efuse_adj,freq), &sen_pgain, &sen_prn); ++ cal_reciprocal(get_nadj_for_freq(opp0efuse_adj,opp1efuse_adj,freq), &sen_ngain, &sen_nrn); ++ ++ return (sen_pgain << 0x14) | (sen_ngain << 0x10) ++ | (sen_prn << 0x08) | (sen_nrn); ++} ++ static void sr_set_efuse_nvalues(struct omap_sr *sr) { if (sr->srid == SR1) { -@@ -220,17 +370,24 @@ ++ u32 opp0efuse = omap_ctrl_readl(OMAP343X_CONTROL_FUSE_OPP1_VDD1); ++ u32 opp1efuse = omap_ctrl_readl(OMAP343X_CONTROL_FUSE_OPP2_VDD1); ++ + sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) & + OMAP343X_SR1_SENNENABLE_MASK) >> + OMAP343X_SR1_SENNENABLE_SHIFT; sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) & OMAP343X_SR1_SENPENABLE_MASK) >> OMAP343X_SR1_SENPENABLE_SHIFT; @@ -340,28 +360,20 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 - OMAP343X_CONTROL_FUSE_OPP2_VDD1); - sr->opp1_nvalue = omap_ctrl_readl( - OMAP343X_CONTROL_FUSE_OPP1_VDD1); -+ sr->opp1_nvalue = sr_ntarget_add_margin(omap_ctrl_readl( -+ OMAP343X_CONTROL_FUSE_OPP1_VDD1),SR_NVALUE_ADJUST); -+ sr->opp2_nvalue = sr_ntarget_add_margin(omap_ctrl_readl( -+ OMAP343X_CONTROL_FUSE_OPP2_VDD1),SR_NVALUE_ADJUST); -+ /* 500 */ -+ sr->opp3_nvalue = sr_ntarget_add_margin(sr->opp2_nvalue,212500); -+ /* 550 */ -+ sr->opp4_nvalue = sr_ntarget_add_margin(sr->opp3_nvalue,50000); -+ /* 600 */ -+ sr->opp5_nvalue = sr_ntarget_add_margin(sr->opp4_nvalue,50000); -+ /* 720 */ -+ sr->opp6_nvalue = sr_ntarget_add_margin(sr->opp5_nvalue,100000); -+ /* 805 */ -+ sr->opp7_nvalue = sr_ntarget_add_margin(sr->opp6_nvalue,75000); -+ /* 850 */ -+ sr->opp8_nvalue = sr_ntarget_add_margin(sr->opp7_nvalue,50000); -+ /* 900 */ -+ sr->opp9_nvalue = sr_ntarget_add_margin(sr->opp8_nvalue,55000); ++ ++ sr->opp1_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S125M); ++ sr->opp2_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S250M); ++ sr->opp3_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S500M); ++ sr->opp4_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S550M); ++ sr->opp5_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S600M); ++ sr->opp6_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S720M); ++ sr->opp7_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S805M); ++ sr->opp8_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S850M); ++ sr->opp9_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S900M); } else if (sr->srid == SR2) { sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) & OMAP343X_SR2_SENNENABLE_MASK) >> -@@ -262,6 +419,14 @@ +@@ -262,6 +429,14 @@ sr->opp3_nvalue = cal_test_nvalue(0x85b + 0x200, 0x655 + 0x200); sr->opp2_nvalue = cal_test_nvalue(0x506 + 0x1a0, 0x3be + 0x1a0); sr->opp1_nvalue = cal_test_nvalue(0x373 + 0x100, 0x28c + 0x100); @@ -376,7 +388,7 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 } else if (sr->srid == SR2) { sr->senp_mod = 0x03; sr->senn_mod = 0x03; -@@ -426,7 +591,7 @@ +@@ -426,7 +601,7 @@ sr->is_sr_reset = 0; } @@ -385,7 +397,7 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 { u32 target_opp_no, vsel = 0; u32 reg_addr = 0; -@@ -443,6 +608,14 @@ +@@ -443,6 +618,14 @@ reg_addr = R_VDD1_SR_CONTROL; prm_vp1_voltage = prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_VP1_VOLTAGE_OFFSET); @@ -400,7 +412,14 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 t2_smps_steps = abs(vsel - prm_vp1_voltage); errorgain = (target_opp_no > SR_MAX_LOW_OPP) ? PRM_VP1_CONFIG_ERRORGAIN_HIGHOPP : -@@ -513,7 +686,19 @@ +@@ -507,13 +690,24 @@ + { + u32 nvalue_reciprocal, v; + u8 errminlimit; +- + BUG_ON(!(mpu_opps && l3_opps)); +- ++ sr->req_opp_no = target_opp_no; if (sr->srid == SR1) { @@ -421,19 +440,33 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 case 5: nvalue_reciprocal = sr->opp5_nvalue; break; -@@ -534,6 +719,11 @@ - nvalue_reciprocal = sr->opp3_nvalue; +@@ -531,9 +725,24 @@ + nvalue_reciprocal = sr->opp1_nvalue; + break; + default: +- nvalue_reciprocal = sr->opp3_nvalue; ++ nvalue_reciprocal = sr->opp9_nvalue; break; } -+ /* give a little more just when DSP is overclocked */ -+ if(dsp_opps[target_opp_no].rate > S430M) -+ nvalue_reciprocal = sr_ntarget_add_margin(nvalue_reciprocal,SR_NVALUE_DSP_ADJUST); -+ if(dsp_opps[target_opp_no].rate > S520M) -+ nvalue_reciprocal = sr_ntarget_add_margin(nvalue_reciprocal,SR_NVALUE_DSP_ADJUST); ++ /* give more juice when DSP is active and overclocked */ ++ if(omap_pm_dsp_get_min_opp() > VDD1_OPP1 && dsp_opps[target_opp_no].rate > S430M) ++ { ++ /* DSP is active and overclocked, boost voltage based on overclocking percent ++ and target OPP ++ */ ++ u32 dsp_volt_boost = ((dsp_opps[target_opp_no].rate-S430M)/1000000) * ++ atomic_read(&sr_vdd1_dsp_boost_coeff) * ++ (VDD1_OPP9-target_opp_no); ++ dsp_volt_boost = dsp_volt_boost > SR_NVALUE_DSP_MAX_ADJUST?SR_NVALUE_DSP_MAX_ADJUST:dsp_volt_boost; ++ nvalue_reciprocal = sr_ntarget_add_margin( ++ nvalue_reciprocal, ++ dsp_volt_boost ++ ); ++ } } else { switch (target_opp_no) { case 3: -@@ -556,7 +746,6 @@ +@@ -556,7 +765,6 @@ target_opp_no); return SR_FALSE; } @@ -441,7 +474,7 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal); /* Enable the interrupt */ -@@ -772,7 +961,7 @@ +@@ -772,7 +980,7 @@ } EXPORT_SYMBOL(sr_start_vddautocomap); @@ -450,7 +483,7 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 { struct omap_sr *sr = NULL; -@@ -789,7 +978,7 @@ +@@ -789,7 +997,7 @@ sr_clk_disable(sr); sr->is_autocomp_active = 0; /* Reset the volatage for current OPP */ @@ -459,7 +492,7 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 return SR_TRUE; } else return SR_FALSE; -@@ -823,7 +1012,7 @@ +@@ -823,7 +1031,7 @@ } } @@ -468,7 +501,7 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 { struct omap_sr *sr = NULL; -@@ -843,7 +1032,7 @@ +@@ -843,7 +1051,7 @@ /* Disable SR clk */ sr_clk_disable(sr); /* Reset the volatage for current OPP */ @@ -477,7 +510,7 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 } } } -@@ -953,22 +1142,22 @@ +@@ -953,22 +1161,22 @@ const char *buf, size_t n) { unsigned short value; @@ -507,7 +540,7 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 sr_start_vddautocomap(SR1, current_vdd1opp_no); } -@@ -1008,9 +1197,13 @@ +@@ -1008,9 +1216,13 @@ mutex_lock(&dvfs_mutex); current_vdd2opp_no = resource_get_level("vdd2_opp"); @@ -522,7 +555,7 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 else sr_start_vddautocomap(SR2, current_vdd2opp_no); -@@ -1028,23 +1221,87 @@ +@@ -1028,30 +1240,128 @@ .store = omap_sr_vdd2_autocomp_store, }; @@ -544,13 +577,16 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 + sr1.opp8_nvalue, + sr1.opp9_nvalue + ); -+} -+ + } + +-static struct kobj_attribute sr_efuse = { +static struct kobj_attribute sr_efuse_vdd1 = { -+ .attr = { + .attr = { +- .name = "Efuse", + .name = "efuse_vdd1", -+ .mode = 0444, -+ }, + .mode = 0444, + }, +- .show = omap_sr_opp1_efuse_show, + .show = omap_sr_efuse_vdd1_show, +}; + @@ -602,30 +638,68 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 + OMAP3_PRM_VP2_VOLTAGE_OFFSET); + mutex_unlock(&dvfs_mutex); + return sprintf(buf,"%u\n",prm_vp2_voltage); - } - --static struct kobj_attribute sr_efuse = { ++} ++ +static struct kobj_attribute sr_vdd2_voltage = { - .attr = { -- .name = "Efuse", ++ .attr = { + .name = "sr_vdd2_voltage", - .mode = 0444, - }, -- .show = omap_sr_opp1_efuse_show, ++ .mode = 0444, ++ }, + .show = omap_sr_vdd2_voltage_show, ++}; ++ ++static ssize_t omap_sr_vdd1_dsp_boost_show(struct kobject *kobj, ++ struct kobj_attribute *attr, ++ char *buf) ++{ ++ return sprintf(buf,"%u\n",atomic_read(&sr_vdd1_dsp_boost_coeff)); ++} ++ ++static ssize_t omap_sr_vdd1_dsp_boost_store(struct kobject *kobj, ++ struct kobj_attribute *attr, ++ const char *buf, size_t n) ++{ ++ u32 value; ++ ++ if (sscanf(buf, "%u", &value) != 1 || (value > 250)) { ++ printk(KERN_ERR "sr_vdd1_dsp_boost: Invalid value\n"); ++ return -EINVAL; ++ } ++ atomic_set(&sr_vdd1_dsp_boost_coeff,value); ++ ++ return n; ++} ++ ++static struct kobj_attribute sr_vdd1_dsp_boost = { ++ .attr = { ++ .name = __stringify(sr_vdd1_dsp_boost), ++ .mode = 0644, ++ }, ++ .show = omap_sr_vdd1_dsp_boost_show, ++ .store = omap_sr_vdd1_dsp_boost_store, }; static int __init omap3_sr_init(void) -@@ -1084,10 +1341,21 @@ + { + int ret = 0; + u8 RdReg; +- ++ ++ /* Set default dsp boost value */ ++ atomic_set(&sr_vdd1_dsp_boost_coeff,125); ++ + /* Enable SR on T2 */ + ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &RdReg, + R_DCDC_GLOBAL_CFG); +@@ -1084,9 +1394,25 @@ if (ret) printk(KERN_ERR "sysfs_create_file failed: %d\n", ret); - ret = sysfs_create_file(power_kobj, &sr_efuse.attr); + ret = sysfs_create_file(power_kobj, &sr_efuse_vdd1.attr); - if (ret) -- printk(KERN_ERR "sysfs_create_file failed for OPP data: %d\n", ret); ++ if (ret) + printk(KERN_ERR "sysfs_create_file failed for VDD1 efuse data: %d\n", ret); - ++ + ret = sysfs_create_file(power_kobj, &sr_vdd1_voltage.attr); + if (ret) + printk(KERN_ERR "sysfs_create_file failed for VDD1 voltage data: %d\n", ret); @@ -637,12 +711,17 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6 + ret = sysfs_create_file(power_kobj, &sr_vdd2_voltage.attr); + if (ret) + printk(KERN_ERR "sysfs_create_file failed for VDD2 voltage data: %d\n", ret); ++ ++ ret = sysfs_create_file(power_kobj, &sr_vdd1_dsp_boost.attr); + if (ret) +- printk(KERN_ERR "sysfs_create_file failed for OPP data: %d\n", ret); ++ printk(KERN_ERR "sysfs_create_file failed: %d\n", ret); + return 0; } - -diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.h kernel-power-2.6.28.SR/arch/arm/mach-omap2/smartreflex.h ---- kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.h 2011-10-11 13:51:21.441301622 +0100 -+++ kernel-power-2.6.28.SR/arch/arm/mach-omap2/smartreflex.h 2011-11-14 21:08:28.136636000 +0000 +diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.h kernel-power-2.6.28.new/arch/arm/mach-omap2/smartreflex.h +--- kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.h 2012-01-07 13:49:16.543132598 +0000 ++++ kernel-power-2.6.28.new/arch/arm/mach-omap2/smartreflex.h 2011-12-31 12:54:23.820044299 +0000 @@ -63,7 +63,7 @@ /* PRM_VP1_VSTEPMAX */ @@ -691,21 +770,21 @@ diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.h kernel-power-2.6 #else static inline void enable_smartreflex(int srid) {} static inline void disable_smartreflex(int srid) {} -diff -urN kernel-power-2.6.28/arch/arm/plat-omap/include/mach/omap34xx.h kernel-power-2.6.28.SR/arch/arm/plat-omap/include/mach/omap34xx.h ---- kernel-power-2.6.28/arch/arm/plat-omap/include/mach/omap34xx.h 2011-10-11 13:51:21.441301622 +0100 -+++ kernel-power-2.6.28.SR/arch/arm/plat-omap/include/mach/omap34xx.h 2011-10-22 15:52:18.063235000 +0100 +diff -urN kernel-power-2.6.28/arch/arm/plat-omap/include/mach/omap34xx.h kernel-power-2.6.28.new/arch/arm/plat-omap/include/mach/omap34xx.h +--- kernel-power-2.6.28/arch/arm/plat-omap/include/mach/omap34xx.h 2012-01-07 13:49:16.503856035 +0000 ++++ kernel-power-2.6.28.new/arch/arm/plat-omap/include/mach/omap34xx.h 2011-12-31 12:54:23.820044299 +0000 @@ -107,6 +107,14 @@ #define VDD1_OPP3 0x3 #define VDD1_OPP4 0x4 #define VDD1_OPP5 0x5 -+#define VDD1_OPP6 0x6 -+#define VDD1_OPP7 0x7 -+#define VDD1_OPP8 0x8 -+#define VDD1_OPP9 0x9 -+#define VDD1_OPP10 0xA -+#define VDD1_OPP11 0xB -+#define VDD1_OPP12 0xC -+#define VDD1_OPP13 0xD ++#define VDD1_OPP6 0x6 ++#define VDD1_OPP7 0x7 ++#define VDD1_OPP8 0x8 ++#define VDD1_OPP9 0x9 ++#define VDD1_OPP10 0xA ++#define VDD1_OPP11 0xB ++#define VDD1_OPP12 0xC ++#define VDD1_OPP13 0xD /* VDD2 OPPS */ #define VDD2_OPP1 0x1 @@ -719,3 +798,101 @@ diff -urN kernel-power-2.6.28/arch/arm/plat-omap/include/mach/omap34xx.h kernel- #define MIN_VDD2_OPP VDD2_OPP1 #define MAX_VDD2_OPP VDD2_OPP3 +diff -urN kernel-power-2.6.28/arch/arm/plat-omap/include/mach/omap-pm.h kernel-power-2.6.28.new/arch/arm/plat-omap/include/mach/omap-pm.h +--- kernel-power-2.6.28/arch/arm/plat-omap/include/mach/omap-pm.h 2012-01-07 13:49:16.487184834 +0000 ++++ kernel-power-2.6.28.new/arch/arm/plat-omap/include/mach/omap-pm.h 2012-01-06 07:35:45.000000000 +0000 +@@ -280,6 +280,17 @@ + #else + void omap_pm_dsp_set_min_opp(u8 opp_id); + #endif ++ ++/** ++ * omap_pm_dsp_get_min_opp - return desired minimum OPP ID from DSP Bridge ++ * ++ * Get a minimum OPP ID for the DSP. ++ */ ++#ifdef CONFIG_OMAP_PM_NONE ++static inline u8 omap_pm_dsp_get_min_opp(void) { } ++#else ++u8 omap_pm_dsp_get_min_opp(void); ++#endif + + /** + * omap_pm_dsp_get_opp - report the current DSP OPP ID +diff -urN kernel-power-2.6.28/arch/arm/plat-omap/omap-pm-srf.c kernel-power-2.6.28.new/arch/arm/plat-omap/omap-pm-srf.c +--- kernel-power-2.6.28/arch/arm/plat-omap/omap-pm-srf.c 2012-01-07 13:49:16.470963471 +0000 ++++ kernel-power-2.6.28.new/arch/arm/plat-omap/omap-pm-srf.c 2012-01-07 13:45:44.000000000 +0000 +@@ -36,6 +36,20 @@ + #define LAT_RES_POSTAMBLE "_latency" + #define MAX_LATENCY_RES_NAME 30 + ++atomic_t dsp_min_opp; ++/* ++ * Smartreflex module enable/disable interface. ++ * NOTE: if smartreflex is not enabled from sysfs, these functions will not ++ * do anything. ++ */ ++#ifdef CONFIG_OMAP_SMARTREFLEX ++void sr_start_vddautocomap(int srid, u32 target_opp_no); ++int sr_stop_vddautocomap(int srid,u32 cur_opp_no); ++/* SR Modules */ ++#define SR1 1 ++#define SR2 2 ++#endif ++ + /** + * get_lat_res_name - gets the latency resource name given a power domain name + * @pwrdm_name: Name of the power domain. +@@ -205,13 +219,29 @@ + + void omap_pm_dsp_set_min_opp(u8 opp_id) + { ++ u8 curr_dsp_min_opp; ++ pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id); + if (opp_id == 0) { + WARN_ON(1); + return; + } + +- pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id); +- ++ curr_dsp_min_opp = omap_pm_dsp_get_min_opp(); ++ atomic_set(&dsp_min_opp,opp_id); ++#ifdef CONFIG_OMAP_SMARTREFLEX ++ if(curr_dsp_min_opp == VDD1_OPP1 || opp_id == VDD1_OPP1) ++ { ++ /* DSP is about to be enabled/disabled, restart SR, ++ * so DSP voltage boost to be applied or removed. ++ * This is needed in case current OPP has DSP overclocking frequency ++ */ ++ u8 curr_opp = omap_pm_dsp_get_opp(); ++ ++ sr_stop_vddautocomap(SR1 , curr_opp); ++ sr_start_vddautocomap(SR1 , curr_opp); ++ ++ } ++#endif + /* + * For now pass a dummy_dev struct for SRF to identify the caller. + * Maybe its good to have DSP pass this as an argument +@@ -221,6 +251,12 @@ + } + EXPORT_SYMBOL(omap_pm_dsp_set_min_opp); + ++u8 omap_pm_dsp_get_min_opp(void) ++{ ++ return atomic_read(&dsp_min_opp); ++} ++EXPORT_SYMBOL(omap_pm_dsp_get_min_opp); ++ + u8 omap_pm_dsp_get_opp(void) + { + pr_debug("OMAP PM: DSP requests current DSP OPP ID\n"); +@@ -341,6 +377,7 @@ + mpu_opps = mpu_opp_table; + dsp_opps = dsp_opp_table; + l3_opps = l3_opp_table; ++ atomic_set(&dsp_min_opp,VDD1_OPP1); + return 0; + } + diff --git a/kernel-power-2.6.28/debian/patches/series b/kernel-power-2.6.28/debian/patches/series index e04bc44..2badbdf 100644 --- a/kernel-power-2.6.28/debian/patches/series +++ b/kernel-power-2.6.28/debian/patches/series @@ -64,3 +64,5 @@ USB-g_serial-don-t-set-low_latency-flag.diff 0001-mtd-fix-a-huge-latency-problem-in-the-MTD-CFI-flash-.diff 0002-mtd-change-struct-flchip_shared-spinlock-locking-int.diff Support-for-tlv320aic3x-codec-highpass-filter-needed.diff +support-non-page-aligned-buffers-in-iommu_vmap.diff +videobuf-dma-sg-support-non-pagable-user-memory.diff diff --git a/kernel-power-2.6.28/debian/patches/support-non-page-aligned-buffers-in-iommu_vmap.diff b/kernel-power-2.6.28/debian/patches/support-non-page-aligned-buffers-in-iommu_vmap.diff new file mode 100644 index 0000000..6d58c72 --- /dev/null +++ b/kernel-power-2.6.28/debian/patches/support-non-page-aligned-buffers-in-iommu_vmap.diff @@ -0,0 +1,113 @@ +--- a/arch/arm/plat-omap/iovmm.c 2011-11-15 06:09:03.909034496 -0500 ++++ b/arch/arm/plat-omap/iovmm.c 2011-12-21 14:03:23.673780000 -0500 +@@ -59,6 +59,15 @@ + + static struct kmem_cache *iovm_area_cachep; + ++/* return the offset of the first scatterlist entry in a sg table */ ++static unsigned int sgtable_offset(const struct sg_table *sgt) ++{ ++ if (!sgt || !sgt->nents) ++ return 0; ++ ++ return sgt->sgl->offset; ++} ++ + /* return total bytes of sg buffers */ + static size_t sgtable_len(const struct sg_table *sgt) + { +@@ -71,11 +80,17 @@ + for_each_sg(sgt->sgl, sg, sgt->nents, i) { + size_t bytes; + +- bytes = sg_dma_len(sg); ++ bytes = sg_dma_len(sg) + sg->offset; + + if (!iopgsz_ok(bytes)) { +- pr_err("%s: sg[%d] not iommu pagesize(%x)\n", +- __func__, i, bytes); ++ pr_err("%s: sg[%d] not iommu pagesize(%u %u)\n", ++ __func__, i, bytes, sg->offset); ++ return 0; ++ } ++ ++ if (i && sg->offset) { ++ pr_err("%s: sg[%d] offset not allowed in internal " ++ "entries\n", __func__, i); + return 0; + } + +@@ -112,6 +127,16 @@ + + return nr_entries; + } ++static struct scatterlist *sg_alloc(unsigned int nents, gfp_t gfp_mask) ++{ ++ return kmalloc(nents * sizeof(struct scatterlist), gfp_mask); ++} ++ ++static void sg_free(struct scatterlist *sg, unsigned int nents) ++{ ++ kfree(sg); ++} ++ + + /* allocate and initialize sg_table header(a kind of 'superblock') */ + static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) +@@ -138,7 +163,7 @@ + if (!sgt) + return ERR_PTR(-ENOMEM); + +- err = sg_alloc_table(sgt, nr_entries, GFP_KERNEL); ++ err = __sg_alloc_table(sgt, nr_entries, -1, GFP_KERNEL, sg_alloc); + if (err) + return ERR_PTR(err); + +@@ -153,7 +178,7 @@ + if (!sgt) + return; + +- sg_free_table(sgt); ++ __sg_free_table(sgt, -1, sg_free); + kfree(sgt); + + pr_debug("%s: sgt:%p\n", __func__, sgt); +@@ -182,8 +207,8 @@ + u32 pa; + int err; + +- pa = sg_phys(sg); +- bytes = sg_dma_len(sg); ++ pa = sg_phys(sg) - sg->offset; ++ bytes = sg_dma_len(sg) + sg->offset; + + BUG_ON(bytes != PAGE_SIZE); + +@@ -450,8 +475,8 @@ + size_t bytes; + struct iotlb_entry e; + +- pa = sg_phys(sg); +- bytes = sg_dma_len(sg); ++ pa = sg_phys(sg) - sg->offset; ++ bytes = sg_dma_len(sg) + sg->offset; + + flags &= ~IOVMF_PGSZ_MASK; + pgsz = bytes_to_iopgsz(bytes); +@@ -632,7 +657,7 @@ + if (IS_ERR_VALUE(da)) + vunmap_sg(va); + +- return da; ++ return da + sgtable_offset(sgt); + } + EXPORT_SYMBOL_GPL(iommu_vmap); + +@@ -651,6 +676,7 @@ + * 'sgt' is allocated before 'iommu_vmalloc()' is called. + * Just returns 'sgt' to the caller to free + */ ++ da &= PAGE_MASK; + sgt = unmap_vm_area(obj, da, vunmap_sg, IOVMF_DISCONT | IOVMF_MMIO); + if (!sgt) + dev_dbg(obj->dev, "%s: No sgt\n", __func__); diff --git a/kernel-power-2.6.28/debian/patches/videobuf-dma-sg-support-non-pagable-user-memory.diff b/kernel-power-2.6.28/debian/patches/videobuf-dma-sg-support-non-pagable-user-memory.diff new file mode 100644 index 0000000..fba567e --- /dev/null +++ b/kernel-power-2.6.28/debian/patches/videobuf-dma-sg-support-non-pagable-user-memory.diff @@ -0,0 +1,85 @@ +--- a/drivers/media/video/videobuf-dma-sg.c 2011-11-15 06:09:03.031835263 -0500 ++++ b/drivers/media/video/videobuf-dma-sg.c 2011-12-28 07:50:34.514877000 -0500 +@@ -137,6 +137,7 @@ + { + unsigned long first,last; + int err, rw = 0; ++ struct vm_area_struct *vma; + + dma->direction = direction; + switch (dma->direction) { +@@ -154,6 +155,23 @@ + last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT; + dma->offset = data & ~PAGE_MASK; + dma->nr_pages = last-first+1; ++ ++ /* In case the buffer is user-allocated and is actually an IO buffer for ++ some other hardware, we cannot map pages for it. It in fact behaves ++ the same as an overlay. */ ++ vma = find_vma (current->mm, data); ++ if (vma && (vma->vm_flags & VM_IO)) { ++ /* Only a single contiguous buffer is supported. */ ++ if (vma->vm_end < data + size) { ++ dprintk(1, "init user: non-contiguous IO buffer.\n"); ++ return -EFAULT; /* same error that get_user_pages() would give */ ++ } ++ dma->bus_addr = (vma->vm_pgoff << PAGE_SHIFT) + (data - vma->vm_start); ++ dprintk(1,"init user IO [0x%lx+0x%lx => %d pages at 0x%x]\n", ++ data, size, dma->nr_pages, dma->bus_addr); ++ return 0; ++ } ++ + dma->pages = kmalloc(dma->nr_pages * sizeof(struct page*), + GFP_KERNEL); + if (NULL == dma->pages) +@@ -231,12 +249,27 @@ + (dma->vmalloc,dma->nr_pages); + } + if (dma->bus_addr) { +- dma->sglist = vmalloc(sizeof(*dma->sglist)); ++ unsigned long physp=dma->bus_addr; ++ int i,len; ++ ++ len=dma->nr_pages; ++ dma->sglist = vmalloc(len*sizeof(*dma->sglist)); ++ sg_init_table(dma->sglist, len); + if (NULL != dma->sglist) { +- dma->sglen = 1; +- sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK; +- dma->sglist[0].offset = dma->bus_addr & ~PAGE_MASK; +- sg_dma_len(&dma->sglist[0]) = dma->nr_pages * PAGE_SIZE; ++ dma->sglist[0].offset = dma->bus_addr & ~PAGE_MASK; ++ sg_dma_len(&dma->sglist[0]) = PAGE_SIZE - dma->offset; ++ sg_dma_address(&dma->sglist[0]) = (dma_addr_t)physp & PAGE_MASK; ++ physp += sg_dma_len(&dma->sglist[0]); ++ /* ++ * Iterate in a loop for the number of pages ++ */ ++ for (i = 1; i < len; i++) { ++ dma->sglist[i].offset = 0; ++ sg_dma_len(&dma->sglist[i]) = PAGE_SIZE; ++ sg_dma_address(&dma->sglist[i]) = (dma_addr_t)physp; ++ physp += PAGE_SIZE; ++ } ++ dma->sglen = len; + } + } + if (NULL == dma->sglist) { +@@ -263,7 +296,7 @@ + MAGIC_CHECK(dma->magic, MAGIC_DMABUF); + BUG_ON(!dma->sglen); + +- dma_sync_sg_for_cpu(q->dev, dma->sglist, dma->nr_pages, dma->direction); ++ dma_sync_sg_for_cpu(q->dev, dma->sglist, dma->sglen, dma->direction); + return 0; + } + +@@ -273,7 +306,7 @@ + if (!dma->sglen) + return 0; + +- dma_unmap_sg(q->dev, dma->sglist, dma->nr_pages, dma->direction); ++ dma_unmap_sg(q->dev, dma->sglist, dma->sglen, dma->direction); + + vfree(dma->sglist); + dma->sglist = NULL; -- 1.7.9.5