fbdev changes for 4.2

* ssd1307fb: various fixes and improvements, SSD1305 support
 * Use architecture agnostic functions instead of MTRR functions in various
   fbdev drivers
 * TI DRA7xx SoC display support (arch/arm/ side)
 * OMAPDSS componentization to fix probing order issues
 * OMAPDSS scaling fixes
 * msm_fb: remove obsoleted driver
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJViP8kAAoJEPo9qoy8lh71RqQP/3YnFrHQj1G/EDw4EvaUrcJb
 MiEbc6Q1/OkG+KWls8kNFi0Mm5PeXlOYgjYukr9mFS0C/BxceU/Aqg/+1TqGSMe4
 kZArCTKWa3ZyU2TUwmPPpeUPeUTUBBXrVBdfqtfNzs2wQKunwQX9MlKQnDHnCZJD
 4kUsK12iW5C+EW0fDWDEg9GwEe/cJ6jBLEYWPTg/1ePtrKKGp8O6kEEtOTVwaKT+
 EdStaPOTUKvCgdcfVQhIgKcym2t4/BeFEt2moxDU9vwClatGbXmTDIru2iCrGgIU
 VFGIjOetVwRe0h+8zpYTATxvJPxmjWYL7HhJ0SbFNMDlZephdJxZGJbgszxHZCW/
 ap1fnxWvW2LZ48JsZSmHTnWK0CoX3WGs+Q+TWqMHy1ID8jkOc2SkHeB3IzCyOG/V
 NwUNvDyooyNV0J8ywbBXIMVmlg7YE3AgNROFlApqm2rF5fhtTO3HER71ALBZckEH
 FXRN4tsyLQXbzmuHcQgY3ENxPZgPYM0usSdAVWSU/vIXrhdnWGA7nWE7bRg508Hd
 aHhpw5HrH8L+4nNwDvd4Dai9Ye8DimWvIPdb1wH8mZ2c81sLxCTkePqkAc7AXo54
 UOkXSWjUBu1i8w/BZqXT9U/dU+aCDQ9beNDFLrZQLwrwtHASyyJY75Hi3DtcZyBQ
 HUAWB45Gu2f+k7PCGsRQ
 =Ix8O
 -----END PGP SIGNATURE-----

Merge tag 'fbdev-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux

Pull fbdev updates from Tomi Valkeinen:

 - ssd1307fb: various fixes and improvements, SSD1305 support

 - use architecture agnostic functions instead of MTRR functions in
   various fbdev drivers

 - TI DRA7xx SoC display support (arch/arm/ side)

 - OMAPDSS componentization to fix probing order issues

 - OMAPDSS scaling fixes

 - msm_fb: remove obsoleted driver

* tag 'fbdev-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (77 commits)
  msm: msm_fb: Remove dead code
  OMAPDSS: HDMI: wait for framedone when stopping video
  OMAPDSS: HDMI4: fix error handling
  OMAPDSS: DISPC: scaler debug print
  OMAPDSS: DISPC: do only y decimation on OMAP3
  OMAPDSS: DISPC: check if scaling setup failed
  OMAPDSS: DISPC: fix 64 bit issue in 5-tap
  OMAPDSS: DISPC: fix row_inc for OMAP3
  OMAPDSS: DISPC: add check for scaling limits
  OMAPDSS: DISPC: fix check_horiz_timing_omap3 args
  OMAPDSS: DISPC: fix predecimation for YUV modes
  OMAPDSS: DISPC: work-around for errata i631
  OMAPDSS: simplify submodule reg/unreg code
  OMAPDSS: componentize omapdss
  OMAPDSS: reorder uninit calls
  OMAPDSS: remove uses of __init/__exit
  OMAPDSS: fix dss_init_ports error handling
  OMAPDSS: refactor dss probe function
  OMAPDSS: move 'dss_initialized' to dss driver
  fbdev: propagate result of fb_videomode_from_videomode()
  ...
This commit is contained in:
Linus Torvalds 2015-06-23 16:23:30 -07:00
commit 1a13e36a79
85 changed files with 1325 additions and 6694 deletions

View File

@ -182,6 +182,7 @@ skyworks Skyworks Solutions, Inc.
smsc Standard Microsystems Corporation smsc Standard Microsystems Corporation
snps Synopsys, Inc. snps Synopsys, Inc.
solidrun SolidRun solidrun SolidRun
solomon Solomon Systech Limited
sony Sony Corporation sony Sony Corporation
spansion Spansion Inc. spansion Spansion Inc.
sprd Spreadtrum Communications Inc. sprd Spreadtrum Communications Inc.

View File

@ -2,7 +2,7 @@
Required properties: Required properties:
- compatible: Should be "solomon,<chip>fb-<bus>". The only supported bus for - compatible: Should be "solomon,<chip>fb-<bus>". The only supported bus for
now is i2c, and the supported chips are ssd1306 and ssd1307. now is i2c, and the supported chips are ssd1305, ssd1306 and ssd1307.
- reg: Should contain address of the controller on the I2C bus. Most likely - reg: Should contain address of the controller on the I2C bus. Most likely
0x3c or 0x3d 0x3c or 0x3d
- pwm: Should contain the pwm to use according to the OF device tree PWM - pwm: Should contain the pwm to use according to the OF device tree PWM
@ -15,6 +15,16 @@ Required properties:
Optional properties: Optional properties:
- reset-active-low: Is the reset gpio is active on physical low? - reset-active-low: Is the reset gpio is active on physical low?
- solomon,segment-no-remap: Display needs normal (non-inverted) data column
to segment mapping
- solomon,com-seq: Display uses sequential COM pin configuration
- solomon,com-lrremap: Display uses left-right COM pin remap
- solomon,com-invdir: Display uses inverted COM pin scan direction
- solomon,com-offset: Number of the COM pin wired to the first display line
- solomon,prechargep1: Length of deselect period (phase 1) in clock cycles.
- solomon,prechargep2: Length of precharge period (phase 2) in clock cycles.
This needs to be the higher, the higher the capacitance
of the OLED's pixels is
[0]: Documentation/devicetree/bindings/pwm/pwm.txt [0]: Documentation/devicetree/bindings/pwm/pwm.txt
@ -26,3 +36,14 @@ ssd1307: oled@3c {
reset-gpios = <&gpio2 7>; reset-gpios = <&gpio2 7>;
reset-active-low; reset-active-low;
}; };
ssd1306: oled@3c {
compatible = "solomon,ssd1306fb-i2c";
reg = <0x3c>;
pwms = <&pwm 4 3000>;
reset-gpios = <&gpio2 7>;
reset-active-low;
solomon,com-lrremap;
solomon,com-invdir;
solomon,com-offset = <32>;
};

View File

@ -19,6 +19,7 @@ aliases {
rtc0 = &mcp_rtc; rtc0 = &mcp_rtc;
rtc1 = &tps659038_rtc; rtc1 = &tps659038_rtc;
rtc2 = &rtc; rtc2 = &rtc;
display0 = &hdmi0;
}; };
memory { memory {
@ -103,6 +104,51 @@ extcon_usb2: extcon_usb2 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&extcon_usb2_pins>; pinctrl-0 = <&extcon_usb2_pins>;
}; };
hdmi0: connector {
compatible = "hdmi-connector";
label = "hdmi";
type = "a";
port {
hdmi_connector_in: endpoint {
remote-endpoint = <&tpd12s015_out>;
};
};
};
tpd12s015: encoder {
compatible = "ti,tpd12s015";
pinctrl-names = "default";
pinctrl-0 = <&tpd12s015_pins>;
gpios = <&gpio7 10 GPIO_ACTIVE_HIGH>, /* gpio7_10, CT CP HPD */
<&gpio6 28 GPIO_ACTIVE_HIGH>, /* gpio6_28, LS OE */
<&gpio7 12 GPIO_ACTIVE_HIGH>; /* gpio7_12/sp1_cs2, HPD */
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
tpd12s015_in: endpoint {
remote-endpoint = <&hdmi_out>;
};
};
port@1 {
reg = <1>;
tpd12s015_out: endpoint {
remote-endpoint = <&hdmi_connector_in>;
};
};
};
};
}; };
&dra7_pmx_core { &dra7_pmx_core {
@ -122,6 +168,13 @@ i2c1_pins_default: i2c1_pins_default {
>; >;
}; };
hdmi_pins: pinmux_hdmi_pins {
pinctrl-single,pins = <
0x408 (PIN_INPUT | MUX_MODE1) /* i2c2_sda.hdmi1_ddc_scl */
0x40c (PIN_INPUT | MUX_MODE1) /* i2c2_scl.hdmi1_ddc_sda */
>;
};
i2c3_pins_default: i2c3_pins_default { i2c3_pins_default: i2c3_pins_default {
pinctrl-single,pins = < pinctrl-single,pins = <
0x2a4 (PIN_INPUT| MUX_MODE10) /* mcasp1_aclkx.i2c3_sda */ 0x2a4 (PIN_INPUT| MUX_MODE10) /* mcasp1_aclkx.i2c3_sda */
@ -278,6 +331,14 @@ extcon_usb2_pins: extcon_usb2_pins {
0x3e8 (PIN_INPUT_PULLUP | MUX_MODE14) /* uart1_ctsn.gpio7_24 */ 0x3e8 (PIN_INPUT_PULLUP | MUX_MODE14) /* uart1_ctsn.gpio7_24 */
>; >;
}; };
tpd12s015_pins: pinmux_tpd12s015_pins {
pinctrl-single,pins = <
0x3b0 (PIN_OUTPUT | MUX_MODE14) /* gpio7_10 CT_CP_HPD */
0x3b8 (PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
0x370 (PIN_OUTPUT | MUX_MODE14) /* gpio6_28 LS_OE */
>;
};
}; };
&i2c1 { &i2c1 {
@ -608,3 +669,23 @@ map0 {
}; };
}; };
}; };
&dss {
status = "ok";
vdda_video-supply = <&ldoln_reg>;
};
&hdmi {
status = "ok";
vdda-supply = <&ldo3_reg>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_pins>;
port {
hdmi_out: endpoint {
remote-endpoint = <&tpd12s015_in>;
};
};
};

View File

@ -131,6 +131,11 @@ pbias_mmc_reg: pbias_mmc_omap5 {
regulator-max-microvolt = <3000000>; regulator-max-microvolt = <3000000>;
}; };
}; };
scm_conf_clocks: clocks {
#address-cells = <1>;
#size-cells = <0>;
};
}; };
dra7_pmx_core: pinmux@1400 { dra7_pmx_core: pinmux@1400 {
@ -1469,6 +1474,44 @@ dcan2: can@481d0000 {
clocks = <&sys_clkin1>; clocks = <&sys_clkin1>;
status = "disabled"; status = "disabled";
}; };
dss: dss@58000000 {
compatible = "ti,dra7-dss";
/* 'reg' defined in dra72x.dtsi and dra74x.dtsi */
/* 'clocks' defined in dra72x.dtsi and dra74x.dtsi */
status = "disabled";
ti,hwmods = "dss_core";
/* CTRL_CORE_DSS_PLL_CONTROL */
syscon-pll-ctrl = <&scm_conf 0x538>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
dispc@58001000 {
compatible = "ti,dra7-dispc";
reg = <0x58001000 0x1000>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
ti,hwmods = "dss_dispc";
clocks = <&dss_dss_clk>;
clock-names = "fck";
/* CTRL_CORE_SMA_SW_1 */
syscon-pol = <&scm_conf 0x534>;
};
hdmi: encoder@58060000 {
compatible = "ti,dra7-hdmi";
reg = <0x58040000 0x200>,
<0x58040200 0x80>,
<0x58040300 0x80>,
<0x58060000 0x19000>;
reg-names = "wp", "pll", "phy", "core";
interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
ti,hwmods = "dss_hdmi";
clocks = <&dss_48mhz_clk>, <&dss_hdmi_clk>;
clock-names = "fck", "sys_clk";
};
};
}; };
thermal_zones: thermal-zones { thermal_zones: thermal-zones {

View File

@ -19,6 +19,10 @@ memory {
reg = <0x80000000 0x40000000>; /* 1024 MB */ reg = <0x80000000 0x40000000>; /* 1024 MB */
}; };
aliases {
display0 = &hdmi0;
};
evm_3v3: fixedregulator-evm_3v3 { evm_3v3: fixedregulator-evm_3v3 {
compatible = "regulator-fixed"; compatible = "regulator-fixed";
regulator-name = "evm_3v3"; regulator-name = "evm_3v3";
@ -35,6 +39,51 @@ extcon_usb2: extcon_usb2 {
compatible = "linux,extcon-usb-gpio"; compatible = "linux,extcon-usb-gpio";
id-gpio = <&pcf_gpio_21 2 GPIO_ACTIVE_HIGH>; id-gpio = <&pcf_gpio_21 2 GPIO_ACTIVE_HIGH>;
}; };
hdmi0: connector {
compatible = "hdmi-connector";
label = "hdmi";
type = "a";
port {
hdmi_connector_in: endpoint {
remote-endpoint = <&tpd12s015_out>;
};
};
};
tpd12s015: encoder {
compatible = "ti,tpd12s015";
pinctrl-names = "default";
pinctrl-0 = <&tpd12s015_pins>;
gpios = <&pcf_hdmi 4 GPIO_ACTIVE_HIGH>, /* P4, CT CP HPD */
<&pcf_hdmi 5 GPIO_ACTIVE_HIGH>, /* P5, LS OE */
<&gpio7 12 GPIO_ACTIVE_HIGH>; /* gpio7_12/sp1_cs2, HPD */
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
tpd12s015_in: endpoint {
remote-endpoint = <&hdmi_out>;
};
};
port@1 {
reg = <1>;
tpd12s015_out: endpoint {
remote-endpoint = <&hdmi_connector_in>;
};
};
};
};
}; };
&dra7_pmx_core { &dra7_pmx_core {
@ -45,6 +94,13 @@ i2c1_pins: pinmux_i2c1_pins {
>; >;
}; };
i2c5_pins: pinmux_i2c5_pins {
pinctrl-single,pins = <
0x2b4 (PIN_INPUT | MUX_MODE10) /* mcasp1_axr0.i2c5_sda */
0x2b8 (PIN_INPUT | MUX_MODE10) /* mcasp1_axr1.i2c5_scl */
>;
};
nand_default: nand_default { nand_default: nand_default {
pinctrl-single,pins = < pinctrl-single,pins = <
0x0 (PIN_INPUT | MUX_MODE0) /* gpmc_ad0 */ 0x0 (PIN_INPUT | MUX_MODE0) /* gpmc_ad0 */
@ -142,6 +198,19 @@ qspi1_pins: pinmux_qspi1_pins {
0xb8 (PIN_OUTPUT | MUX_MODE1) /* gpmc_cs2.qspi1_cs0 */ 0xb8 (PIN_OUTPUT | MUX_MODE1) /* gpmc_cs2.qspi1_cs0 */
>; >;
}; };
hdmi_pins: pinmux_hdmi_pins {
pinctrl-single,pins = <
0x408 (PIN_INPUT | MUX_MODE1) /* i2c2_sda.hdmi1_ddc_scl */
0x40c (PIN_INPUT | MUX_MODE1) /* i2c2_scl.hdmi1_ddc_sda */
>;
};
tpd12s015_pins: pinmux_tpd12s015_pins {
pinctrl-single,pins = <
0x3b8 (PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
>;
};
}; };
&i2c1 { &i2c1 {
@ -277,6 +346,27 @@ pcf_gpio_21: gpio@21 {
}; };
}; };
&i2c5 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c5_pins>;
clock-frequency = <400000>;
pcf_hdmi: pcf8575@26 {
compatible = "nxp,pcf8575";
reg = <0x26>;
gpio-controller;
#gpio-cells = <2>;
/*
* initial state is used here to keep the mdio interface
* selected on RU89 through SEL_VIN4_MUX_S0, VIN2_S1 and
* VIN2_S0 driven high otherwise Ethernet stops working
* VIN6_SEL_S0 is low, thus selecting McASP3 over VIN6
*/
lines-initial-states = <0x0f2b>;
};
};
&uart1 { &uart1 {
status = "okay"; status = "okay";
}; };
@ -566,3 +656,23 @@ partition@9 {
}; };
}; };
}; };
&dss {
status = "ok";
vdda_video-supply = <&ldo5_reg>;
};
&hdmi {
status = "ok";
vdda-supply = <&ldo3_reg>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_pins>;
port {
hdmi_out: endpoint {
remote-endpoint = <&tpd12s015_in>;
};
};
};

View File

@ -34,3 +34,14 @@ pmu {
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
}; };
}; };
&dss {
reg = <0x58000000 0x80>,
<0x58004054 0x4>,
<0x58004300 0x20>;
reg-names = "dss", "pll1_clkctrl", "pll1";
clocks = <&dss_dss_clk>,
<&dss_video1_clk>;
clock-names = "fck", "video1_clk";
};

View File

@ -73,3 +73,18 @@ usb4: usb@48950000 {
}; };
}; };
}; };
&dss {
reg = <0x58000000 0x80>,
<0x58004054 0x4>,
<0x58004300 0x20>,
<0x58005054 0x4>,
<0x58005300 0x20>;
reg-names = "dss", "pll1_clkctrl", "pll1",
"pll2_clkctrl", "pll2";
clocks = <&dss_dss_clk>,
<&dss_video1_clk>,
<&dss_video2_clk>;
clock-names = "fck", "video1_clk", "video2_clk";
};

View File

@ -1531,6 +1531,7 @@ dss_dss_clk: dss_dss_clk {
clocks = <&dpll_per_h12x2_ck>; clocks = <&dpll_per_h12x2_ck>;
ti,bit-shift = <8>; ti,bit-shift = <8>;
reg = <0x1120>; reg = <0x1120>;
ti,set-rate-parent;
}; };
dss_hdmi_clk: dss_hdmi_clk { dss_hdmi_clk: dss_hdmi_clk {
@ -2136,3 +2137,13 @@ coreaon_clkdm: coreaon_clkdm {
clocks = <&dpll_usb_ck>; clocks = <&dpll_usb_ck>;
}; };
}; };
&scm_conf_clocks {
dss_deshdcp_clk: dss_deshdcp_clk {
#clock-cells = <0>;
compatible = "ti,gate-clock";
clocks = <&l3_iclk_div>;
ti,bit-shift = <0>;
reg = <0x558>;
};
};

View File

@ -99,6 +99,9 @@ ssd1306: oled@3c {
solomon,height = <32>; solomon,height = <32>;
solomon,width = <128>; solomon,width = <128>;
solomon,page-offset = <0>; solomon,page-offset = <0>;
solomon,com-lrremap;
solomon,com-invdir;
solomon,com-offset = <32>;
}; };
}; };

View File

@ -287,6 +287,8 @@ static enum omapdss_version __init omap_display_get_version(void)
return OMAPDSS_VER_OMAP5; return OMAPDSS_VER_OMAP5;
else if (soc_is_am43xx()) else if (soc_is_am43xx())
return OMAPDSS_VER_AM43xx; return OMAPDSS_VER_AM43xx;
else if (soc_is_dra7xx())
return OMAPDSS_VER_DRA7xx;
else else
return OMAPDSS_VER_UNKNOWN; return OMAPDSS_VER_UNKNOWN;
} }
@ -568,25 +570,25 @@ void __init omapdss_early_init_of(void)
} }
static const char * const omapdss_compat_names[] __initconst = {
"ti,omap2-dss",
"ti,omap3-dss",
"ti,omap4-dss",
"ti,omap5-dss",
"ti,dra7-dss",
};
struct device_node * __init omapdss_find_dss_of_node(void) struct device_node * __init omapdss_find_dss_of_node(void)
{ {
struct device_node *node; struct device_node *node;
int i;
node = of_find_compatible_node(NULL, NULL, "ti,omap2-dss"); for (i = 0; i < ARRAY_SIZE(omapdss_compat_names); ++i) {
if (node) node = of_find_compatible_node(NULL, NULL,
return node; omapdss_compat_names[i]);
if (node)
node = of_find_compatible_node(NULL, NULL, "ti,omap3-dss"); return node;
if (node) }
return node;
node = of_find_compatible_node(NULL, NULL, "ti,omap4-dss");
if (node)
return node;
node = of_find_compatible_node(NULL, NULL, "ti,omap5-dss");
if (node)
return node;
return NULL; return NULL;
} }

View File

@ -48,6 +48,27 @@
* IP blocks * IP blocks
*/ */
/*
* 'dmm' class
* instance(s): dmm
*/
static struct omap_hwmod_class dra7xx_dmm_hwmod_class = {
.name = "dmm",
};
/* dmm */
static struct omap_hwmod dra7xx_dmm_hwmod = {
.name = "dmm",
.class = &dra7xx_dmm_hwmod_class,
.clkdm_name = "emif_clkdm",
.prcm = {
.omap4 = {
.clkctrl_offs = DRA7XX_CM_EMIF_DMM_CLKCTRL_OFFSET,
.context_offs = DRA7XX_RM_EMIF_DMM_CONTEXT_OFFSET,
},
},
};
/* /*
* 'l3' class * 'l3' class
* instance(s): l3_instr, l3_main_1, l3_main_2 * instance(s): l3_instr, l3_main_1, l3_main_2
@ -438,6 +459,7 @@ static struct omap_hwmod_opt_clk dss_opt_clks[] = {
{ .role = "video2_clk", .clk = "dss_video2_clk" }, { .role = "video2_clk", .clk = "dss_video2_clk" },
{ .role = "video1_clk", .clk = "dss_video1_clk" }, { .role = "video1_clk", .clk = "dss_video1_clk" },
{ .role = "hdmi_clk", .clk = "dss_hdmi_clk" }, { .role = "hdmi_clk", .clk = "dss_hdmi_clk" },
{ .role = "hdcp_clk", .clk = "dss_deshdcp_clk" },
}; };
static struct omap_hwmod dra7xx_dss_hwmod = { static struct omap_hwmod dra7xx_dss_hwmod = {
@ -500,6 +522,7 @@ static struct omap_hwmod dra7xx_dss_dispc_hwmod = {
}, },
}, },
.dev_attr = &dss_dispc_dev_attr, .dev_attr = &dss_dispc_dev_attr,
.parent_hwmod = &dra7xx_dss_hwmod,
}; };
/* /*
@ -541,6 +564,7 @@ static struct omap_hwmod dra7xx_dss_hdmi_hwmod = {
}, },
.opt_clks = dss_hdmi_opt_clks, .opt_clks = dss_hdmi_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks),
.parent_hwmod = &dra7xx_dss_hwmod,
}; };
/* /*
@ -2321,6 +2345,14 @@ static struct omap_hwmod dra7xx_wd_timer2_hwmod = {
* Interfaces * Interfaces
*/ */
/* l3_main_1 -> dmm */
static struct omap_hwmod_ocp_if dra7xx_l3_main_1__dmm = {
.master = &dra7xx_l3_main_1_hwmod,
.slave = &dra7xx_dmm_hwmod,
.clk = "l3_iclk_div",
.user = OCP_USER_SDMA,
};
/* l3_main_2 -> l3_instr */ /* l3_main_2 -> l3_instr */
static struct omap_hwmod_ocp_if dra7xx_l3_main_2__l3_instr = { static struct omap_hwmod_ocp_if dra7xx_l3_main_2__l3_instr = {
.master = &dra7xx_l3_main_2_hwmod, .master = &dra7xx_l3_main_2_hwmod,
@ -3289,6 +3321,7 @@ static struct omap_hwmod_ocp_if dra7xx_l4_wkup__wd_timer2 = {
}; };
static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
&dra7xx_l3_main_1__dmm,
&dra7xx_l3_main_2__l3_instr, &dra7xx_l3_main_2__l3_instr,
&dra7xx_l4_cfg__l3_main_1, &dra7xx_l4_cfg__l3_main_1,
&dra7xx_mpu__l3_main_1, &dra7xx_mpu__l3_main_1,

View File

@ -305,13 +305,14 @@ static struct ti_dt_clk dra7xx_clks[] = {
DT_CLK("4882c000.timer", "timer_sys_ck", "timer_sys_clk_div"), DT_CLK("4882c000.timer", "timer_sys_ck", "timer_sys_clk_div"),
DT_CLK("4882e000.timer", "timer_sys_ck", "timer_sys_clk_div"), DT_CLK("4882e000.timer", "timer_sys_ck", "timer_sys_clk_div"),
DT_CLK(NULL, "sys_clkin", "sys_clkin1"), DT_CLK(NULL, "sys_clkin", "sys_clkin1"),
DT_CLK(NULL, "dss_deshdcp_clk", "dss_deshdcp_clk"),
{ .node_name = NULL }, { .node_name = NULL },
}; };
int __init dra7xx_dt_clk_init(void) int __init dra7xx_dt_clk_init(void)
{ {
int rc; int rc;
struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck; struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck, *hdcp_ck;
ti_dt_clocks_register(dra7xx_clks); ti_dt_clocks_register(dra7xx_clks);
@ -347,5 +348,10 @@ int __init dra7xx_dt_clk_init(void)
if (rc) if (rc)
pr_err("%s: failed to set USB_DPLL M2 OUT\n", __func__); pr_err("%s: failed to set USB_DPLL M2 OUT\n", __func__);
hdcp_ck = clk_get_sys(NULL, "dss_deshdcp_clk");
rc = clk_prepare_enable(hdcp_ck);
if (rc)
pr_err("%s: failed to set dss_deshdcp_clk\n", __func__);
return rc; return rc;
} }

View File

@ -687,7 +687,7 @@ static int newport_scroll(struct vc_data *vc, int t, int b, int dir,
static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy, static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy,
int dx, int h, int w) int dx, int h, int w)
{ {
short xs, ys, xe, ye, xoffs, yoffs, tmp; short xs, ys, xe, ye, xoffs, yoffs;
xs = sx << 3; xs = sx << 3;
xe = ((sx + w) << 3) - 1; xe = ((sx + w) << 3) - 1;
@ -701,9 +701,7 @@ static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy,
yoffs = (dy - sy) << 4; yoffs = (dy - sy) << 4;
if (xoffs > 0) { if (xoffs > 0) {
/* move to the right, exchange starting points */ /* move to the right, exchange starting points */
tmp = xe; swap(xe, xs);
xe = xs;
xs = tmp;
} }
newport_wait(npregs); newport_wait(npregs);
npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK | npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |

View File

@ -2326,13 +2326,6 @@ config FB_PRE_INIT_FB
Select this option if display contents should be inherited as set by Select this option if display contents should be inherited as set by
the bootloader. the bootloader.
config FB_MSM
tristate "MSM Framebuffer support"
depends on FB && ARCH_MSM
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
config FB_MX3 config FB_MX3
tristate "MX3 Framebuffer support" tristate "MX3 Framebuffer support"
depends on FB && MX3_IPU depends on FB && MX3_IPU
@ -2478,6 +2471,7 @@ config FB_SSD1307
select FB_SYS_IMAGEBLIT select FB_SYS_IMAGEBLIT
select FB_DEFERRED_IO select FB_DEFERRED_IO
select PWM select PWM
select FB_BACKLIGHT
help help
This driver implements support for the Solomon SSD1307 This driver implements support for the Solomon SSD1307
OLED controller over I2C. OLED controller over I2C.

View File

@ -126,7 +126,6 @@ obj-y += omap2/
obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
obj-$(CONFIG_FB_CARMINE) += carminefb.o obj-$(CONFIG_FB_CARMINE) += carminefb.o
obj-$(CONFIG_FB_MB862XX) += mb862xx/ obj-$(CONFIG_FB_MB862XX) += mb862xx/
obj-$(CONFIG_FB_MSM) += msm/
obj-$(CONFIG_FB_NUC900) += nuc900fb.o obj-$(CONFIG_FB_NUC900) += nuc900fb.o
obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o

View File

@ -2052,7 +2052,7 @@ static void ami_set_sprite(const struct amifb_par *par)
{ {
copins *copl, *cops; copins *copl, *cops;
u_short hs, vs, ve; u_short hs, vs, ve;
u_long pl, ps, pt; u_long pl, ps;
short mx, my; short mx, my;
cops = copdisplay.list[currentcop][0]; cops = copdisplay.list[currentcop][0];
@ -2078,7 +2078,7 @@ static void ami_set_sprite(const struct amifb_par *par)
if (mod2(vs)) { if (mod2(vs)) {
lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve); lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve + 1); shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve + 1);
pt = pl; pl = ps; ps = pt; swap(pl, ps);
} else { } else {
lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve + 1); lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve + 1);
shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve); shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve);

View File

@ -1266,7 +1266,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
goto stop_clk; goto stop_clk;
} }
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); info->screen_base = ioremap_wc(info->fix.smem_start,
info->fix.smem_len);
if (!info->screen_base) { if (!info->screen_base) {
ret = -ENOMEM; ret = -ENOMEM;
goto release_intmem; goto release_intmem;

View File

@ -80,10 +80,6 @@
#include <asm/btext.h> #include <asm/btext.h>
#endif /* CONFIG_BOOTX_TEXT */ #endif /* CONFIG_BOOTX_TEXT */
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include <video/aty128.h> #include <video/aty128.h>
/* Debug flag */ /* Debug flag */
@ -399,10 +395,7 @@ static int default_cmode = CMODE_8;
static int default_crt_on = 0; static int default_crt_on = 0;
static int default_lcd_on = 1; static int default_lcd_on = 1;
#ifdef CONFIG_MTRR
static bool mtrr = true; static bool mtrr = true;
#endif
#ifdef CONFIG_FB_ATY128_BACKLIGHT #ifdef CONFIG_FB_ATY128_BACKLIGHT
#ifdef CONFIG_PMAC_BACKLIGHT #ifdef CONFIG_PMAC_BACKLIGHT
@ -456,9 +449,7 @@ struct aty128fb_par {
u32 vram_size; /* onboard video ram */ u32 vram_size; /* onboard video ram */
int chip_gen; int chip_gen;
const struct aty128_meminfo *mem; /* onboard mem info */ const struct aty128_meminfo *mem; /* onboard mem info */
#ifdef CONFIG_MTRR int wc_cookie;
struct { int vram; int vram_valid; } mtrr;
#endif
int blitter_may_be_busy; int blitter_may_be_busy;
int fifo_slots; /* free slots in FIFO (64 max) */ int fifo_slots; /* free slots in FIFO (64 max) */
@ -1725,12 +1716,10 @@ static int aty128fb_setup(char *options)
#endif #endif
continue; continue;
} }
#ifdef CONFIG_MTRR
if(!strncmp(this_opt, "nomtrr", 6)) { if(!strncmp(this_opt, "nomtrr", 6)) {
mtrr = 0; mtrr = 0;
continue; continue;
} }
#endif
#ifdef CONFIG_PPC_PMAC #ifdef CONFIG_PPC_PMAC
/* vmode and cmode deprecated */ /* vmode and cmode deprecated */
if (!strncmp(this_opt, "vmode:", 6)) { if (!strncmp(this_opt, "vmode:", 6)) {
@ -2133,7 +2122,7 @@ static int aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
par->vram_size = aty_ld_le32(CNFG_MEMSIZE) & 0x03FFFFFF; par->vram_size = aty_ld_le32(CNFG_MEMSIZE) & 0x03FFFFFF;
/* Virtualize the framebuffer */ /* Virtualize the framebuffer */
info->screen_base = ioremap(fb_addr, par->vram_size); info->screen_base = ioremap_wc(fb_addr, par->vram_size);
if (!info->screen_base) if (!info->screen_base)
goto err_unmap_out; goto err_unmap_out;
@ -2170,15 +2159,9 @@ static int aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!aty128_init(pdev, ent)) if (!aty128_init(pdev, ent))
goto err_out; goto err_out;
#ifdef CONFIG_MTRR if (mtrr)
if (mtrr) { par->wc_cookie = arch_phys_wc_add(info->fix.smem_start,
par->mtrr.vram = mtrr_add(info->fix.smem_start, par->vram_size);
par->vram_size, MTRR_TYPE_WRCOMB, 1);
par->mtrr.vram_valid = 1;
/* let there be speed */
printk(KERN_INFO "aty128fb: Rage128 MTRR set to ON\n");
}
#endif /* CONFIG_MTRR */
return 0; return 0;
err_out: err_out:
@ -2212,11 +2195,7 @@ static void aty128_remove(struct pci_dev *pdev)
aty128_bl_exit(info->bl_dev); aty128_bl_exit(info->bl_dev);
#endif #endif
#ifdef CONFIG_MTRR arch_phys_wc_del(par->wc_cookie);
if (par->mtrr.vram_valid)
mtrr_del(par->mtrr.vram, info->fix.smem_start,
par->vram_size);
#endif /* CONFIG_MTRR */
iounmap(par->regbase); iounmap(par->regbase);
iounmap(info->screen_base); iounmap(info->screen_base);
@ -2625,8 +2604,5 @@ MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
module_param(mode_option, charp, 0); module_param(mode_option, charp, 0);
MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
#ifdef CONFIG_MTRR
module_param_named(nomtrr, mtrr, invbool, 0); module_param_named(nomtrr, mtrr, invbool, 0);
MODULE_PARM_DESC(nomtrr, "bool: Disable MTRR support (0 or 1=disabled) (default=0)"); MODULE_PARM_DESC(nomtrr, "bool: Disable MTRR support (0 or 1=disabled) (default=0)");
#endif

View File

@ -85,10 +85,6 @@
#endif /* CONFIG_PPC */ #endif /* CONFIG_PPC */
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include <video/radeon.h> #include <video/radeon.h>
#include <linux/radeonfb.h> #include <linux/radeonfb.h>
@ -271,9 +267,7 @@ static bool mirror = 0;
static int panel_yres = 0; static int panel_yres = 0;
static bool force_dfp = 0; static bool force_dfp = 0;
static bool force_measure_pll = 0; static bool force_measure_pll = 0;
#ifdef CONFIG_MTRR
static bool nomtrr = 0; static bool nomtrr = 0;
#endif
static bool force_sleep; static bool force_sleep;
static bool ignore_devlist; static bool ignore_devlist;
#ifdef CONFIG_PMAC_BACKLIGHT #ifdef CONFIG_PMAC_BACKLIGHT
@ -2260,8 +2254,8 @@ static int radeonfb_pci_register(struct pci_dev *pdev,
rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, rinfo->video_ram); rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, rinfo->video_ram);
do { do {
rinfo->fb_base = ioremap (rinfo->fb_base_phys, rinfo->fb_base = ioremap_wc(rinfo->fb_base_phys,
rinfo->mapped_vram); rinfo->mapped_vram);
} while (rinfo->fb_base == NULL && } while (rinfo->fb_base == NULL &&
((rinfo->mapped_vram /= 2) >= MIN_MAPPED_VRAM)); ((rinfo->mapped_vram /= 2) >= MIN_MAPPED_VRAM));
@ -2359,11 +2353,9 @@ static int radeonfb_pci_register(struct pci_dev *pdev,
goto err_unmap_fb; goto err_unmap_fb;
} }
#ifdef CONFIG_MTRR if (!nomtrr)
rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys, rinfo->wc_cookie = arch_phys_wc_add(rinfo->fb_base_phys,
rinfo->video_ram, rinfo->video_ram);
MTRR_TYPE_WRCOMB, 1);
#endif
if (backlight) if (backlight)
radeonfb_bl_init(rinfo); radeonfb_bl_init(rinfo);
@ -2428,12 +2420,7 @@ static void radeonfb_pci_unregister(struct pci_dev *pdev)
#endif #endif
del_timer_sync(&rinfo->lvds_timer); del_timer_sync(&rinfo->lvds_timer);
arch_phys_wc_del(rinfo->wc_cookie);
#ifdef CONFIG_MTRR
if (rinfo->mtrr_hdl >= 0)
mtrr_del(rinfo->mtrr_hdl, 0, 0);
#endif
unregister_framebuffer(info); unregister_framebuffer(info);
radeonfb_bl_exit(rinfo); radeonfb_bl_exit(rinfo);
@ -2489,10 +2476,8 @@ static int __init radeonfb_setup (char *options)
panel_yres = simple_strtoul((this_opt+11), NULL, 0); panel_yres = simple_strtoul((this_opt+11), NULL, 0);
} else if (!strncmp(this_opt, "backlight:", 10)) { } else if (!strncmp(this_opt, "backlight:", 10)) {
backlight = simple_strtoul(this_opt+10, NULL, 0); backlight = simple_strtoul(this_opt+10, NULL, 0);
#ifdef CONFIG_MTRR
} else if (!strncmp(this_opt, "nomtrr", 6)) { } else if (!strncmp(this_opt, "nomtrr", 6)) {
nomtrr = 1; nomtrr = 1;
#endif
} else if (!strncmp(this_opt, "nomodeset", 9)) { } else if (!strncmp(this_opt, "nomodeset", 9)) {
nomodeset = 1; nomodeset = 1;
} else if (!strncmp(this_opt, "force_measure_pll", 17)) { } else if (!strncmp(this_opt, "force_measure_pll", 17)) {
@ -2552,10 +2537,8 @@ module_param(monitor_layout, charp, 0);
MODULE_PARM_DESC(monitor_layout, "Specify monitor mapping (like XFree86)"); MODULE_PARM_DESC(monitor_layout, "Specify monitor mapping (like XFree86)");
module_param(force_measure_pll, bool, 0); module_param(force_measure_pll, bool, 0);
MODULE_PARM_DESC(force_measure_pll, "Force measurement of PLL (debug)"); MODULE_PARM_DESC(force_measure_pll, "Force measurement of PLL (debug)");
#ifdef CONFIG_MTRR
module_param(nomtrr, bool, 0); module_param(nomtrr, bool, 0);
MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers"); MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers");
#endif
module_param(panel_yres, int, 0); module_param(panel_yres, int, 0);
MODULE_PARM_DESC(panel_yres, "int: set panel yres"); MODULE_PARM_DESC(panel_yres, "int: set panel yres");
module_param(mode_option, charp, 0); module_param(mode_option, charp, 0);

View File

@ -340,7 +340,7 @@ struct radeonfb_info {
struct pll_info pll; struct pll_info pll;
int mtrr_hdl; int wc_cookie;
u32 save_regs[100]; u32 save_regs[100];
int asleep; int asleep;

View File

@ -3,6 +3,7 @@ obj-$(CONFIG_FB_CMDLINE) += fb_cmdline.o
obj-$(CONFIG_FB) += fb.o obj-$(CONFIG_FB) += fb.o
fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
modedb.o fbcvt.o modedb.o fbcvt.o
fb-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
fb-objs := $(fb-y) fb-objs := $(fb-y)
obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
@ -14,4 +15,3 @@ obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o
obj-$(CONFIG_FB_SVGALIB) += svgalib.o obj-$(CONFIG_FB_SVGALIB) += svgalib.o
obj-$(CONFIG_FB_DDC) += fb_ddc.o obj-$(CONFIG_FB_DDC) += fb_ddc.o
obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o

View File

@ -242,5 +242,3 @@ void fb_deferred_io_cleanup(struct fb_info *info)
mutex_destroy(&fbdefio->lock); mutex_destroy(&fbdefio->lock);
} }
EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
MODULE_LICENSE("GPL");

View File

@ -1475,7 +1475,9 @@ int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fb,
if (ret) if (ret)
return ret; return ret;
fb_videomode_from_videomode(&vm, fb); ret = fb_videomode_from_videomode(&vm, fb);
if (ret)
return ret;
pr_debug("%s: got %dx%d display mode from %s\n", pr_debug("%s: got %dx%d display mode from %s\n",
of_node_full_name(np), vm.hactive, vm.vactive, np->name); of_node_full_name(np), vm.hactive, vm.vactive, np->name);

View File

@ -22,9 +22,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/io.h> #include <linux/io.h>
#ifdef CONFIG_X86
#include <asm/mtrr.h>
#endif
#ifdef CONFIG_MIPS #ifdef CONFIG_MIPS
#include <asm/addrspace.h> #include <asm/addrspace.h>
#endif #endif
@ -38,6 +35,7 @@ static struct sgi_gbe *gbe;
struct gbefb_par { struct gbefb_par {
struct fb_var_screeninfo var; struct fb_var_screeninfo var;
struct gbe_timing_info timing; struct gbe_timing_info timing;
int wc_cookie;
int valid; int valid;
}; };
@ -1175,8 +1173,8 @@ static int gbefb_probe(struct platform_device *p_dev)
if (gbe_mem_phys) { if (gbe_mem_phys) {
/* memory was allocated at boot time */ /* memory was allocated at boot time */
gbe_mem = devm_ioremap_nocache(&p_dev->dev, gbe_mem_phys, gbe_mem = devm_ioremap_wc(&p_dev->dev, gbe_mem_phys,
gbe_mem_size); gbe_mem_size);
if (!gbe_mem) { if (!gbe_mem) {
printk(KERN_ERR "gbefb: couldn't map framebuffer\n"); printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
ret = -ENOMEM; ret = -ENOMEM;
@ -1187,8 +1185,8 @@ static int gbefb_probe(struct platform_device *p_dev)
} else { } else {
/* try to allocate memory with the classical allocator /* try to allocate memory with the classical allocator
* this has high chance to fail on low memory machines */ * this has high chance to fail on low memory machines */
gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr, gbe_mem = dma_alloc_writecombine(NULL, gbe_mem_size,
GFP_KERNEL); &gbe_dma_addr, GFP_KERNEL);
if (!gbe_mem) { if (!gbe_mem) {
printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n"); printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
ret = -ENOMEM; ret = -ENOMEM;
@ -1198,9 +1196,8 @@ static int gbefb_probe(struct platform_device *p_dev)
gbe_mem_phys = (unsigned long) gbe_dma_addr; gbe_mem_phys = (unsigned long) gbe_dma_addr;
} }
#ifdef CONFIG_X86 par = info->par;
mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1); par->wc_cookie = arch_phys_wc_add(gbe_mem_phys, gbe_mem_size);
#endif
/* map framebuffer memory into tiles table */ /* map framebuffer memory into tiles table */
for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++) for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
@ -1215,7 +1212,6 @@ static int gbefb_probe(struct platform_device *p_dev)
/* reset GBE */ /* reset GBE */
gbe_reset(); gbe_reset();
par = info->par;
/* turn on default video mode */ /* turn on default video mode */
if (fb_find_mode(&par->var, info, mode_option, NULL, 0, if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
default_mode, 8) == 0) default_mode, 8) == 0)
@ -1240,8 +1236,9 @@ static int gbefb_probe(struct platform_device *p_dev)
return 0; return 0;
out_gbe_unmap: out_gbe_unmap:
arch_phys_wc_del(par->wc_cookie);
if (gbe_dma_addr) if (gbe_dma_addr)
dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys); dma_free_writecombine(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
out_tiles_free: out_tiles_free:
dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t), dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
(void *)gbe_tiles.cpu, gbe_tiles.dma); (void *)gbe_tiles.cpu, gbe_tiles.dma);
@ -1256,11 +1253,13 @@ static int gbefb_probe(struct platform_device *p_dev)
static int gbefb_remove(struct platform_device* p_dev) static int gbefb_remove(struct platform_device* p_dev)
{ {
struct fb_info *info = platform_get_drvdata(p_dev); struct fb_info *info = platform_get_drvdata(p_dev);
struct gbefb_par *par = info->par;
unregister_framebuffer(info); unregister_framebuffer(info);
gbe_turn_off(); gbe_turn_off();
arch_phys_wc_del(par->wc_cookie);
if (gbe_dma_addr) if (gbe_dma_addr)
dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys); dma_free_writecombine(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t), dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
(void *)gbe_tiles.cpu, gbe_tiles.dma); (void *)gbe_tiles.cpu, gbe_tiles.dma);
release_mem_region(GBE_BASE, sizeof(struct sgi_gbe)); release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));

View File

@ -263,7 +263,8 @@ static int gxfb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
info->fix.smem_start = pci_resource_start(dev, 0); info->fix.smem_start = pci_resource_start(dev, 0);
info->fix.smem_len = vram ? vram : gx_frame_buffer_size(); info->fix.smem_len = vram ? vram : gx_frame_buffer_size();
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); info->screen_base = ioremap_wc(info->fix.smem_start,
info->fix.smem_len);
if (!info->screen_base) if (!info->screen_base)
return -ENOMEM; return -ENOMEM;

View File

@ -199,7 +199,6 @@
#define HAS_FONTCACHE 8 #define HAS_FONTCACHE 8
/* driver flags */ /* driver flags */
#define HAS_MTRR 1
#define HAS_ACCELERATION 2 #define HAS_ACCELERATION 2
#define ALWAYS_SYNC 4 #define ALWAYS_SYNC 4
#define LOCKUP 8 #define LOCKUP 8
@ -281,7 +280,7 @@ struct i810fb_par {
u32 ovract; u32 ovract;
u32 cur_state; u32 cur_state;
u32 ddc_num; u32 ddc_num;
int mtrr_reg; int wc_cookie;
u16 bltcntl; u16 bltcntl;
u8 interlace; u8 interlace;
}; };

View File

@ -41,6 +41,7 @@
#include <linux/resource.h> #include <linux/resource.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/console.h> #include <linux/console.h>
#include <linux/io.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/div64.h> #include <asm/div64.h>
@ -1816,7 +1817,9 @@ static void i810_init_device(struct i810fb_par *par)
u8 reg; u8 reg;
u8 __iomem *mmio = par->mmio_start_virtual; u8 __iomem *mmio = par->mmio_start_virtual;
if (mtrr) set_mtrr(par); if (mtrr)
par->wc_cookie= arch_phys_wc_add((u32) par->aperture.physical,
par->aperture.size);
i810_init_cursor(par); i810_init_cursor(par);
@ -1865,8 +1868,8 @@ static int i810_allocate_pci_resource(struct i810fb_par *par,
} }
par->res_flags |= FRAMEBUFFER_REQ; par->res_flags |= FRAMEBUFFER_REQ;
par->aperture.virtual = ioremap_nocache(par->aperture.physical, par->aperture.virtual = ioremap_wc(par->aperture.physical,
par->aperture.size); par->aperture.size);
if (!par->aperture.virtual) { if (!par->aperture.virtual) {
printk("i810fb_init: cannot remap framebuffer region\n"); printk("i810fb_init: cannot remap framebuffer region\n");
return -ENODEV; return -ENODEV;
@ -2096,7 +2099,7 @@ static void i810fb_release_resource(struct fb_info *info,
struct i810fb_par *par) struct i810fb_par *par)
{ {
struct gtt_data *gtt = &par->i810_gtt; struct gtt_data *gtt = &par->i810_gtt;
unset_mtrr(par); arch_phys_wc_del(par->wc_cookie);
i810_delete_i2c_busses(par); i810_delete_i2c_busses(par);

View File

@ -60,32 +60,6 @@ static inline void flush_cache(void)
#define flush_cache() do { } while(0) #define flush_cache() do { } while(0)
#endif #endif
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
static inline void set_mtrr(struct i810fb_par *par)
{
par->mtrr_reg = mtrr_add((u32) par->aperture.physical,
par->aperture.size, MTRR_TYPE_WRCOMB, 1);
if (par->mtrr_reg < 0) {
printk(KERN_ERR "set_mtrr: unable to set MTRR\n");
return;
}
par->dev_flags |= HAS_MTRR;
}
static inline void unset_mtrr(struct i810fb_par *par)
{
if (par->dev_flags & HAS_MTRR)
mtrr_del(par->mtrr_reg, (u32) par->aperture.physical,
par->aperture.size);
}
#else
#define set_mtrr(x) printk("set_mtrr: MTRR is disabled in the kernel\n")
#define unset_mtrr(x) do { } while (0)
#endif /* CONFIG_MTRR */
#ifdef CONFIG_FB_I810_GTF #ifdef CONFIG_FB_I810_GTF
#define IS_DVT (0) #define IS_DVT (0)
#else #else

View File

@ -170,7 +170,7 @@ struct imxfb_info {
struct regulator *lcd_pwr; struct regulator *lcd_pwr;
}; };
static struct platform_device_id imxfb_devtype[] = { static const struct platform_device_id imxfb_devtype[] = {
{ {
.name = "imx1-fb", .name = "imx1-fb",
.driver_data = IMX1_FB, .driver_data = IMX1_FB,

View File

@ -285,9 +285,7 @@ struct intelfb_info {
/* use a gart reserved fb mem */ /* use a gart reserved fb mem */
u8 fbmem_gart; u8 fbmem_gart;
/* mtrr support */ int wc_cookie;
int mtrr_reg;
u32 has_mtrr;
/* heap data */ /* heap data */
struct intelfb_heap_data aperture; struct intelfb_heap_data aperture;

View File

@ -124,10 +124,6 @@
#include <asm/io.h> #include <asm/io.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include "intelfb.h" #include "intelfb.h"
#include "intelfbhw.h" #include "intelfbhw.h"
#include "../edid.h" #include "../edid.h"
@ -410,33 +406,6 @@ static void __exit intelfb_exit(void)
module_init(intelfb_init); module_init(intelfb_init);
module_exit(intelfb_exit); module_exit(intelfb_exit);
/***************************************************************
* mtrr support functions *
***************************************************************/
#ifdef CONFIG_MTRR
static inline void set_mtrr(struct intelfb_info *dinfo)
{
dinfo->mtrr_reg = mtrr_add(dinfo->aperture.physical,
dinfo->aperture.size, MTRR_TYPE_WRCOMB, 1);
if (dinfo->mtrr_reg < 0) {
ERR_MSG("unable to set MTRR\n");
return;
}
dinfo->has_mtrr = 1;
}
static inline void unset_mtrr(struct intelfb_info *dinfo)
{
if (dinfo->has_mtrr)
mtrr_del(dinfo->mtrr_reg, dinfo->aperture.physical,
dinfo->aperture.size);
}
#else
#define set_mtrr(x) WRN_MSG("MTRR is disabled in the kernel\n")
#define unset_mtrr(x) do { } while (0)
#endif /* CONFIG_MTRR */
/*************************************************************** /***************************************************************
* driver init / cleanup * * driver init / cleanup *
***************************************************************/ ***************************************************************/
@ -456,7 +425,7 @@ static void cleanup(struct intelfb_info *dinfo)
if (dinfo->registered) if (dinfo->registered)
unregister_framebuffer(dinfo->info); unregister_framebuffer(dinfo->info);
unset_mtrr(dinfo); arch_phys_wc_del(dinfo->wc_cookie);
if (dinfo->fbmem_gart && dinfo->gtt_fb_mem) { if (dinfo->fbmem_gart && dinfo->gtt_fb_mem) {
agp_unbind_memory(dinfo->gtt_fb_mem); agp_unbind_memory(dinfo->gtt_fb_mem);
@ -675,7 +644,7 @@ static int intelfb_pci_register(struct pci_dev *pdev,
/* Allocate memories (which aren't stolen) */ /* Allocate memories (which aren't stolen) */
/* Map the fb and MMIO regions */ /* Map the fb and MMIO regions */
/* ioremap only up to the end of used aperture */ /* ioremap only up to the end of used aperture */
dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache dinfo->aperture.virtual = (u8 __iomem *)ioremap_wc
(dinfo->aperture.physical, ((offset + dinfo->fb.offset) << 12) (dinfo->aperture.physical, ((offset + dinfo->fb.offset) << 12)
+ dinfo->fb.size); + dinfo->fb.size);
if (!dinfo->aperture.virtual) { if (!dinfo->aperture.virtual) {
@ -772,7 +741,8 @@ static int intelfb_pci_register(struct pci_dev *pdev,
agp_backend_release(bridge); agp_backend_release(bridge);
if (mtrr) if (mtrr)
set_mtrr(dinfo); dinfo->wc_cookie = arch_phys_wc_add(dinfo->aperture.physical,
dinfo->aperture.size);
DBG_MSG("fb: 0x%x(+ 0x%x)/0x%x (0x%p)\n", DBG_MSG("fb: 0x%x(+ 0x%x)/0x%x (0x%p)\n",
dinfo->fb.physical, dinfo->fb.offset, dinfo->fb.size, dinfo->fb.physical, dinfo->fb.offset, dinfo->fb.size,

View File

@ -370,12 +370,9 @@ static void matroxfb_remove(struct matrox_fb_info *minfo, int dummy)
matroxfb_unregister_device(minfo); matroxfb_unregister_device(minfo);
unregister_framebuffer(&minfo->fbcon); unregister_framebuffer(&minfo->fbcon);
matroxfb_g450_shutdown(minfo); matroxfb_g450_shutdown(minfo);
#ifdef CONFIG_MTRR arch_phys_wc_del(minfo->wc_cookie);
if (minfo->mtrr.vram_valid) iounmap(minfo->mmio.vbase.vaddr);
mtrr_del(minfo->mtrr.vram, minfo->video.base, minfo->video.len); iounmap(minfo->video.vbase.vaddr);
#endif
mga_iounmap(minfo->mmio.vbase);
mga_iounmap(minfo->video.vbase);
release_mem_region(minfo->video.base, minfo->video.len_maximum); release_mem_region(minfo->video.base, minfo->video.len_maximum);
release_mem_region(minfo->mmio.base, 16384); release_mem_region(minfo->mmio.base, 16384);
kfree(minfo); kfree(minfo);
@ -591,12 +588,8 @@ static int matroxfb_decode_var(const struct matrox_fb_info *minfo,
unsigned int max_yres; unsigned int max_yres;
while (m1) { while (m1) {
int t;
while (m2 >= m1) m2 -= m1; while (m2 >= m1) m2 -= m1;
t = m1; swap(m1, m2);
m1 = m2;
m2 = t;
} }
m2 = linelen * PAGE_SIZE / m2; m2 = linelen * PAGE_SIZE / m2;
*ydstorg = m2 = 0x400000 % m2; *ydstorg = m2 = 0x400000 % m2;
@ -1256,9 +1249,7 @@ static int nobios; /* "matroxfb:nobios" */
static int noinit = 1; /* "matroxfb:init" */ static int noinit = 1; /* "matroxfb:init" */
static int inverse; /* "matroxfb:inverse" */ static int inverse; /* "matroxfb:inverse" */
static int sgram; /* "matroxfb:sgram" */ static int sgram; /* "matroxfb:sgram" */
#ifdef CONFIG_MTRR
static int mtrr = 1; /* "matroxfb:nomtrr" */ static int mtrr = 1; /* "matroxfb:nomtrr" */
#endif
static int grayscale; /* "matroxfb:grayscale" */ static int grayscale; /* "matroxfb:grayscale" */
static int dev = -1; /* "matroxfb:dev:xxxxx" */ static int dev = -1; /* "matroxfb:dev:xxxxx" */
static unsigned int vesa = ~0; /* "matroxfb:vesa:xxxxx" */ static unsigned int vesa = ~0; /* "matroxfb:vesa:xxxxx" */
@ -1717,14 +1708,17 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)
if (mem && (mem < memsize)) if (mem && (mem < memsize))
memsize = mem; memsize = mem;
err = -ENOMEM; err = -ENOMEM;
if (mga_ioremap(ctrlptr_phys, 16384, MGA_IOREMAP_MMIO, &minfo->mmio.vbase)) {
minfo->mmio.vbase.vaddr = ioremap_nocache(ctrlptr_phys, 16384);
if (!minfo->mmio.vbase.vaddr) {
printk(KERN_ERR "matroxfb: cannot ioremap(%lX, 16384), matroxfb disabled\n", ctrlptr_phys); printk(KERN_ERR "matroxfb: cannot ioremap(%lX, 16384), matroxfb disabled\n", ctrlptr_phys);
goto failVideoMR; goto failVideoMR;
} }
minfo->mmio.base = ctrlptr_phys; minfo->mmio.base = ctrlptr_phys;
minfo->mmio.len = 16384; minfo->mmio.len = 16384;
minfo->video.base = video_base_phys; minfo->video.base = video_base_phys;
if (mga_ioremap(video_base_phys, memsize, MGA_IOREMAP_FB, &minfo->video.vbase)) { minfo->video.vbase.vaddr = ioremap_wc(video_base_phys, memsize);
if (!minfo->video.vbase.vaddr) {
printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n", printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n",
video_base_phys, memsize); video_base_phys, memsize);
goto failCtrlIO; goto failCtrlIO;
@ -1772,13 +1766,9 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)
minfo->video.len_usable = minfo->video.len; minfo->video.len_usable = minfo->video.len;
if (minfo->video.len_usable > b->base->maxdisplayable) if (minfo->video.len_usable > b->base->maxdisplayable)
minfo->video.len_usable = b->base->maxdisplayable; minfo->video.len_usable = b->base->maxdisplayable;
#ifdef CONFIG_MTRR if (mtrr)
if (mtrr) { minfo->wc_cookie = arch_phys_wc_add(video_base_phys,
minfo->mtrr.vram = mtrr_add(video_base_phys, minfo->video.len, MTRR_TYPE_WRCOMB, 1); minfo->video.len);
minfo->mtrr.vram_valid = 1;
printk(KERN_INFO "matroxfb: MTRR's turned on\n");
}
#endif /* CONFIG_MTRR */
if (!minfo->devflags.novga) if (!minfo->devflags.novga)
request_region(0x3C0, 32, "matrox"); request_region(0x3C0, 32, "matrox");
@ -1947,9 +1937,9 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)
return 0; return 0;
failVideoIO:; failVideoIO:;
matroxfb_g450_shutdown(minfo); matroxfb_g450_shutdown(minfo);
mga_iounmap(minfo->video.vbase); iounmap(minfo->video.vbase.vaddr);
failCtrlIO:; failCtrlIO:;
mga_iounmap(minfo->mmio.vbase); iounmap(minfo->mmio.vbase.vaddr);
failVideoMR:; failVideoMR:;
release_mem_region(video_base_phys, minfo->video.len_maximum); release_mem_region(video_base_phys, minfo->video.len_maximum);
failCtrlMR:; failCtrlMR:;
@ -2443,10 +2433,8 @@ static int __init matroxfb_setup(char *options) {
nobios = !value; nobios = !value;
else if (!strcmp(this_opt, "init")) else if (!strcmp(this_opt, "init"))
noinit = !value; noinit = !value;
#ifdef CONFIG_MTRR
else if (!strcmp(this_opt, "mtrr")) else if (!strcmp(this_opt, "mtrr"))
mtrr = value; mtrr = value;
#endif
else if (!strcmp(this_opt, "inv24")) else if (!strcmp(this_opt, "inv24"))
inv24 = value; inv24 = value;
else if (!strcmp(this_opt, "cross4MB")) else if (!strcmp(this_opt, "cross4MB"))
@ -2515,10 +2503,8 @@ module_param(noinit, int, 0);
MODULE_PARM_DESC(noinit, "Disables W/SG/SD-RAM and bus interface initialization (0 or 1=do not initialize) (default=0)"); MODULE_PARM_DESC(noinit, "Disables W/SG/SD-RAM and bus interface initialization (0 or 1=do not initialize) (default=0)");
module_param(memtype, int, 0); module_param(memtype, int, 0);
MODULE_PARM_DESC(memtype, "Memory type for G200/G400 (see Documentation/fb/matroxfb.txt for explanation) (default=3 for G200, 0 for G400)"); MODULE_PARM_DESC(memtype, "Memory type for G200/G400 (see Documentation/fb/matroxfb.txt for explanation) (default=3 for G200, 0 for G400)");
#ifdef CONFIG_MTRR
module_param(mtrr, int, 0); module_param(mtrr, int, 0);
MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)"); MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)");
#endif
module_param(sgram, int, 0); module_param(sgram, int, 0);
MODULE_PARM_DESC(sgram, "Indicates that G100/G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)"); MODULE_PARM_DESC(sgram, "Indicates that G100/G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
module_param(inv24, int, 0); module_param(inv24, int, 0);

View File

@ -44,9 +44,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#if defined(CONFIG_PPC_PMAC) #if defined(CONFIG_PPC_PMAC)
#include <asm/prom.h> #include <asm/prom.h>
@ -187,23 +184,6 @@ static inline void __iomem* vaddr_va(vaddr_t va) {
return va.vaddr; return va.vaddr;
} }
#define MGA_IOREMAP_NORMAL 0
#define MGA_IOREMAP_NOCACHE 1
#define MGA_IOREMAP_FB MGA_IOREMAP_NOCACHE
#define MGA_IOREMAP_MMIO MGA_IOREMAP_NOCACHE
static inline int mga_ioremap(unsigned long phys, unsigned long size, int flags, vaddr_t* virt) {
if (flags & MGA_IOREMAP_NOCACHE)
virt->vaddr = ioremap_nocache(phys, size);
else
virt->vaddr = ioremap(phys, size);
return (virt->vaddr == NULL); /* 0, !0... 0, error_code in future */
}
static inline void mga_iounmap(vaddr_t va) {
iounmap(va.vaddr);
}
struct my_timming { struct my_timming {
unsigned int pixclock; unsigned int pixclock;
int mnp; int mnp;
@ -449,12 +429,7 @@ struct matrox_fb_info {
int plnwt; int plnwt;
int srcorg; int srcorg;
} capable; } capable;
#ifdef CONFIG_MTRR int wc_cookie;
struct {
int vram;
int vram_valid;
} mtrr;
#endif
struct { struct {
int precise_width; int precise_width;
int mga_24bpp_fix; int mga_24bpp_fix;

View File

@ -1,19 +0,0 @@
# core framebuffer
#
obj-y := msm_fb.o
# MDP DMA/PPP engine
#
obj-y += mdp.o mdp_scale_tables.o mdp_ppp.o
# MDDI interface
#
obj-y += mddi.o
# MDDI client/panel drivers
#
obj-y += mddi_client_dummy.o
obj-y += mddi_client_toshiba.o
obj-y += mddi_client_nt35399.o

View File

@ -1,821 +0,0 @@
/*
* MSM MDDI Transport
*
* Copyright (C) 2007 Google Incorporated
* Copyright (C) 2007 QUALCOMM Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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/module.h>
#include <linux/kernel.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/gfp.h>
#include <linux/spinlock.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/sched.h>
#include <linux/platform_data/video-msm_fb.h>
#include "mddi_hw.h"
#define FLAG_DISABLE_HIBERNATION 0x0001
#define FLAG_HAVE_CAPS 0x0002
#define FLAG_HAS_VSYNC_IRQ 0x0004
#define FLAG_HAVE_STATUS 0x0008
#define CMD_GET_CLIENT_CAP 0x0601
#define CMD_GET_CLIENT_STATUS 0x0602
union mddi_rev {
unsigned char raw[MDDI_REV_BUFFER_SIZE];
struct mddi_rev_packet hdr;
struct mddi_client_status status;
struct mddi_client_caps caps;
struct mddi_register_access reg;
};
struct reg_read_info {
struct completion done;
uint32_t reg;
uint32_t status;
uint32_t result;
};
struct mddi_info {
uint16_t flags;
uint16_t version;
char __iomem *base;
int irq;
struct clk *clk;
struct msm_mddi_client_data client_data;
/* buffer for rev encap packets */
void *rev_data;
dma_addr_t rev_addr;
struct mddi_llentry *reg_write_data;
dma_addr_t reg_write_addr;
struct mddi_llentry *reg_read_data;
dma_addr_t reg_read_addr;
size_t rev_data_curr;
spinlock_t int_lock;
uint32_t int_enable;
uint32_t got_int;
wait_queue_head_t int_wait;
struct mutex reg_write_lock;
struct mutex reg_read_lock;
struct reg_read_info *reg_read;
struct mddi_client_caps caps;
struct mddi_client_status status;
void (*power_client)(struct msm_mddi_client_data *, int);
/* client device published to bind us to the
* appropriate mddi_client driver
*/
char client_name[20];
struct platform_device client_pdev;
};
static void mddi_init_rev_encap(struct mddi_info *mddi);
#define mddi_readl(r) readl(mddi->base + (MDDI_##r))
#define mddi_writel(v, r) writel((v), mddi->base + (MDDI_##r))
void mddi_activate_link(struct msm_mddi_client_data *cdata)
{
struct mddi_info *mddi = container_of(cdata, struct mddi_info,
client_data);
mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
}
static void mddi_handle_link_list_done(struct mddi_info *mddi)
{
}
static void mddi_reset_rev_encap_ptr(struct mddi_info *mddi)
{
printk(KERN_INFO "mddi: resetting rev ptr\n");
mddi->rev_data_curr = 0;
mddi_writel(mddi->rev_addr, REV_PTR);
mddi_writel(mddi->rev_addr, REV_PTR);
mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
}
static void mddi_handle_rev_data(struct mddi_info *mddi, union mddi_rev *rev)
{
int i;
struct reg_read_info *ri;
if ((rev->hdr.length <= MDDI_REV_BUFFER_SIZE - 2) &&
(rev->hdr.length >= sizeof(struct mddi_rev_packet) - 2)) {
switch (rev->hdr.type) {
case TYPE_CLIENT_CAPS:
memcpy(&mddi->caps, &rev->caps,
sizeof(struct mddi_client_caps));
mddi->flags |= FLAG_HAVE_CAPS;
wake_up(&mddi->int_wait);
break;
case TYPE_CLIENT_STATUS:
memcpy(&mddi->status, &rev->status,
sizeof(struct mddi_client_status));
mddi->flags |= FLAG_HAVE_STATUS;
wake_up(&mddi->int_wait);
break;
case TYPE_REGISTER_ACCESS:
ri = mddi->reg_read;
if (ri == 0) {
printk(KERN_INFO "rev: got reg %x = %x without "
" pending read\n",
rev->reg.register_address,
rev->reg.register_data_list);
break;
}
if (ri->reg != rev->reg.register_address) {
printk(KERN_INFO "rev: got reg %x = %x for "
"wrong register, expected "
"%x\n",
rev->reg.register_address,
rev->reg.register_data_list, ri->reg);
break;
}
mddi->reg_read = NULL;
ri->status = 0;
ri->result = rev->reg.register_data_list;
complete(&ri->done);
break;
default:
printk(KERN_INFO "rev: unknown reverse packet: "
"len=%04x type=%04x CURR_REV_PTR=%x\n",
rev->hdr.length, rev->hdr.type,
mddi_readl(CURR_REV_PTR));
for (i = 0; i < rev->hdr.length + 2; i++) {
if ((i % 16) == 0)
printk(KERN_INFO "\n");
printk(KERN_INFO " %02x", rev->raw[i]);
}
printk(KERN_INFO "\n");
mddi_reset_rev_encap_ptr(mddi);
}
} else {
printk(KERN_INFO "bad rev length, %d, CURR_REV_PTR %x\n",
rev->hdr.length, mddi_readl(CURR_REV_PTR));
mddi_reset_rev_encap_ptr(mddi);
}
}
static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask);
static void mddi_handle_rev_data_avail(struct mddi_info *mddi)
{
uint32_t rev_data_count;
uint32_t rev_crc_err_count;
struct reg_read_info *ri;
size_t prev_offset;
uint16_t length;
union mddi_rev *crev = mddi->rev_data + mddi->rev_data_curr;
/* clear the interrupt */
mddi_writel(MDDI_INT_REV_DATA_AVAIL, INT);
rev_data_count = mddi_readl(REV_PKT_CNT);
rev_crc_err_count = mddi_readl(REV_CRC_ERR);
if (rev_data_count > 1)
printk(KERN_INFO "rev_data_count %d\n", rev_data_count);
if (rev_crc_err_count) {
printk(KERN_INFO "rev_crc_err_count %d, INT %x\n",
rev_crc_err_count, mddi_readl(INT));
ri = mddi->reg_read;
if (ri == 0) {
printk(KERN_INFO "rev: got crc error without pending "
"read\n");
} else {
mddi->reg_read = NULL;
ri->status = -EIO;
ri->result = -1;
complete(&ri->done);
}
}
if (rev_data_count == 0)
return;
prev_offset = mddi->rev_data_curr;
length = *((uint8_t *)mddi->rev_data + mddi->rev_data_curr);
mddi->rev_data_curr++;
if (mddi->rev_data_curr == MDDI_REV_BUFFER_SIZE)
mddi->rev_data_curr = 0;
length += *((uint8_t *)mddi->rev_data + mddi->rev_data_curr) << 8;
mddi->rev_data_curr += 1 + length;
if (mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE)
mddi->rev_data_curr =
mddi->rev_data_curr % MDDI_REV_BUFFER_SIZE;
if (length > MDDI_REV_BUFFER_SIZE - 2) {
printk(KERN_INFO "mddi: rev data length greater than buffer"
"size\n");
mddi_reset_rev_encap_ptr(mddi);
return;
}
if (prev_offset + 2 + length >= MDDI_REV_BUFFER_SIZE) {
union mddi_rev tmprev;
size_t rem = MDDI_REV_BUFFER_SIZE - prev_offset;
memcpy(&tmprev.raw[0], mddi->rev_data + prev_offset, rem);
memcpy(&tmprev.raw[rem], mddi->rev_data, 2 + length - rem);
mddi_handle_rev_data(mddi, &tmprev);
} else {
mddi_handle_rev_data(mddi, crev);
}
if (prev_offset < MDDI_REV_BUFFER_SIZE / 2 &&
mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE / 2) {
mddi_writel(mddi->rev_addr, REV_PTR);
}
}
static irqreturn_t mddi_isr(int irq, void *data)
{
struct msm_mddi_client_data *cdata = data;
struct mddi_info *mddi = container_of(cdata, struct mddi_info,
client_data);
uint32_t active, status;
spin_lock(&mddi->int_lock);
active = mddi_readl(INT);
status = mddi_readl(STAT);
mddi_writel(active, INT);
/* ignore any interrupts we have disabled */
active &= mddi->int_enable;
mddi->got_int |= active;
wake_up(&mddi->int_wait);
if (active & MDDI_INT_PRI_LINK_LIST_DONE) {
mddi->int_enable &= (~MDDI_INT_PRI_LINK_LIST_DONE);
mddi_handle_link_list_done(mddi);
}
if (active & MDDI_INT_REV_DATA_AVAIL)
mddi_handle_rev_data_avail(mddi);
if (active & ~MDDI_INT_NEED_CLEAR)
mddi->int_enable &= ~(active & ~MDDI_INT_NEED_CLEAR);
if (active & MDDI_INT_LINK_ACTIVE) {
mddi->int_enable &= (~MDDI_INT_LINK_ACTIVE);
mddi->int_enable |= MDDI_INT_IN_HIBERNATION;
}
if (active & MDDI_INT_IN_HIBERNATION) {
mddi->int_enable &= (~MDDI_INT_IN_HIBERNATION);
mddi->int_enable |= MDDI_INT_LINK_ACTIVE;
}
mddi_writel(mddi->int_enable, INTEN);
spin_unlock(&mddi->int_lock);
return IRQ_HANDLED;
}
static long mddi_wait_interrupt_timeout(struct mddi_info *mddi,
uint32_t intmask, int timeout)
{
unsigned long irq_flags;
spin_lock_irqsave(&mddi->int_lock, irq_flags);
mddi->got_int &= ~intmask;
mddi->int_enable |= intmask;
mddi_writel(mddi->int_enable, INTEN);
spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
return wait_event_timeout(mddi->int_wait, mddi->got_int & intmask,
timeout);
}
static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask)
{
if (mddi_wait_interrupt_timeout(mddi, intmask, HZ/10) == 0)
printk(KERN_INFO "mddi_wait_interrupt %d, timeout "
"waiting for %x, INT = %x, STAT = %x gotint = %x\n",
current->pid, intmask, mddi_readl(INT), mddi_readl(STAT),
mddi->got_int);
}
static void mddi_init_rev_encap(struct mddi_info *mddi)
{
memset(mddi->rev_data, 0xee, MDDI_REV_BUFFER_SIZE);
mddi_writel(mddi->rev_addr, REV_PTR);
mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
}
void mddi_set_auto_hibernate(struct msm_mddi_client_data *cdata, int on)
{
struct mddi_info *mddi = container_of(cdata, struct mddi_info,
client_data);
mddi_writel(MDDI_CMD_POWERDOWN, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_IN_HIBERNATION);
mddi_writel(MDDI_CMD_HIBERNATE | !!on, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
}
static uint16_t mddi_init_registers(struct mddi_info *mddi)
{
mddi_writel(0x0001, VERSION);
mddi_writel(MDDI_HOST_BYTES_PER_SUBFRAME, BPS);
mddi_writel(0x0003, SPM); /* subframes per media */
mddi_writel(0x0005, TA1_LEN);
mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN);
mddi_writel(0x0096, DRIVE_HI);
/* 0x32 normal, 0x50 for Toshiba display */
mddi_writel(0x0050, DRIVE_LO);
mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */
mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV);
mddi_writel(MDDI_REV_BUFFER_SIZE, REV_SIZE);
mddi_writel(MDDI_MAX_REV_PKT_SIZE, REV_ENCAP_SZ);
/* disable periodic rev encap */
mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
if (mddi_readl(PAD_CTL) == 0) {
/* If we are turning on band gap, need to wait 5us before
* turning on the rest of the PAD */
mddi_writel(0x08000, PAD_CTL);
udelay(5);
}
/* Recommendation from PAD hw team */
mddi_writel(0xa850f, PAD_CTL);
/* Need an even number for counts */
mddi_writel(0x60006, DRIVER_START_CNT);
mddi_set_auto_hibernate(&mddi->client_data, 0);
mddi_writel(MDDI_CMD_DISP_IGNORE, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
mddi_init_rev_encap(mddi);
return mddi_readl(CORE_VER) & 0xffff;
}
static void mddi_suspend(struct msm_mddi_client_data *cdata)
{
struct mddi_info *mddi = container_of(cdata, struct mddi_info,
client_data);
/* turn off the client */
if (mddi->power_client)
mddi->power_client(&mddi->client_data, 0);
/* turn off the link */
mddi_writel(MDDI_CMD_RESET, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
/* turn off the clock */
clk_disable(mddi->clk);
}
static void mddi_resume(struct msm_mddi_client_data *cdata)
{
struct mddi_info *mddi = container_of(cdata, struct mddi_info,
client_data);
mddi_set_auto_hibernate(&mddi->client_data, 0);
/* turn on the client */
if (mddi->power_client)
mddi->power_client(&mddi->client_data, 1);
/* turn on the clock */
clk_enable(mddi->clk);
/* set up the local registers */
mddi->rev_data_curr = 0;
mddi_init_registers(mddi);
mddi_writel(mddi->int_enable, INTEN);
mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
mddi_writel(MDDI_CMD_SEND_RTD, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
mddi_set_auto_hibernate(&mddi->client_data, 1);
}
static int mddi_get_client_caps(struct mddi_info *mddi)
{
int i, j;
/* clear any stale interrupts */
mddi_writel(0xffffffff, INT);
mddi->int_enable = MDDI_INT_LINK_ACTIVE |
MDDI_INT_IN_HIBERNATION |
MDDI_INT_PRI_LINK_LIST_DONE |
MDDI_INT_REV_DATA_AVAIL |
MDDI_INT_REV_OVERFLOW |
MDDI_INT_REV_OVERWRITE |
MDDI_INT_RTD_FAILURE;
mddi_writel(mddi->int_enable, INTEN);
mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
for (j = 0; j < 3; j++) {
/* the toshiba vga panel does not respond to get
* caps unless you SEND_RTD, but the first SEND_RTD
* will fail...
*/
for (i = 0; i < 4; i++) {
uint32_t stat;
mddi_writel(MDDI_CMD_SEND_RTD, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
stat = mddi_readl(STAT);
printk(KERN_INFO "mddi cmd send rtd: int %x, stat %x, "
"rtd val %x\n", mddi_readl(INT), stat,
mddi_readl(RTD_VAL));
if ((stat & MDDI_STAT_RTD_MEAS_FAIL) == 0)
break;
msleep(1);
}
mddi_writel(CMD_GET_CLIENT_CAP, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
wait_event_timeout(mddi->int_wait, mddi->flags & FLAG_HAVE_CAPS,
HZ / 100);
if (mddi->flags & FLAG_HAVE_CAPS)
break;
printk(KERN_INFO "mddi_init, timeout waiting for caps\n");
}
return mddi->flags & FLAG_HAVE_CAPS;
}
/* link must be active when this is called */
int mddi_check_status(struct mddi_info *mddi)
{
int ret = -1, retry = 3;
mutex_lock(&mddi->reg_read_lock);
mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
do {
mddi->flags &= ~FLAG_HAVE_STATUS;
mddi_writel(CMD_GET_CLIENT_STATUS, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
wait_event_timeout(mddi->int_wait,
mddi->flags & FLAG_HAVE_STATUS,
HZ / 100);
if (mddi->flags & FLAG_HAVE_STATUS) {
if (mddi->status.crc_error_count)
printk(KERN_INFO "mddi status: crc_error "
"count: %d\n",
mddi->status.crc_error_count);
else
ret = 0;
break;
} else
printk(KERN_INFO "mddi status: failed to get client "
"status\n");
mddi_writel(MDDI_CMD_SEND_RTD, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
} while (--retry);
mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
mutex_unlock(&mddi->reg_read_lock);
return ret;
}
void mddi_remote_write(struct msm_mddi_client_data *cdata, uint32_t val,
uint32_t reg)
{
struct mddi_info *mddi = container_of(cdata, struct mddi_info,
client_data);
struct mddi_llentry *ll;
struct mddi_register_access *ra;
mutex_lock(&mddi->reg_write_lock);
ll = mddi->reg_write_data;
ra = &(ll->u.r);
ra->length = 14 + 4;
ra->type = TYPE_REGISTER_ACCESS;
ra->client_id = 0;
ra->read_write_info = MDDI_WRITE | 1;
ra->crc16 = 0;
ra->register_address = reg;
ra->register_data_list = val;
ll->flags = 1;
ll->header_count = 14;
ll->data_count = 4;
ll->data = mddi->reg_write_addr + offsetof(struct mddi_llentry,
u.r.register_data_list);
ll->next = 0;
ll->reserved = 0;
mddi_writel(mddi->reg_write_addr, PRI_PTR);
mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
mutex_unlock(&mddi->reg_write_lock);
}
uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
{
struct mddi_info *mddi = container_of(cdata, struct mddi_info,
client_data);
struct mddi_llentry *ll;
struct mddi_register_access *ra;
struct reg_read_info ri;
unsigned s;
int retry_count = 2;
unsigned long irq_flags;
mutex_lock(&mddi->reg_read_lock);
ll = mddi->reg_read_data;
ra = &(ll->u.r);
ra->length = 14;
ra->type = TYPE_REGISTER_ACCESS;
ra->client_id = 0;
ra->read_write_info = MDDI_READ | 1;
ra->crc16 = 0;
ra->register_address = reg;
ll->flags = 0x11;
ll->header_count = 14;
ll->data_count = 0;
ll->data = 0;
ll->next = 0;
ll->reserved = 0;
s = mddi_readl(STAT);
ri.reg = reg;
ri.status = -1;
do {
init_completion(&ri.done);
mddi->reg_read = &ri;
mddi_writel(mddi->reg_read_addr, PRI_PTR);
mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
/* Enable Periodic Reverse Encapsulation. */
mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
if (wait_for_completion_timeout(&ri.done, HZ/10) == 0 &&
!ri.done.done) {
printk(KERN_INFO "mddi_remote_read(%x) timeout "
"(%d %d %d)\n",
reg, ri.status, ri.result, ri.done.done);
spin_lock_irqsave(&mddi->int_lock, irq_flags);
mddi->reg_read = NULL;
spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
ri.status = -1;
ri.result = -1;
}
if (ri.status == 0)
break;
mddi_writel(MDDI_CMD_SEND_RTD, CMD);
mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
printk(KERN_INFO "mddi_remote_read: failed, sent "
"MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x "
"curr_rev_ptr %x\n", mddi_readl(INT), mddi_readl(STAT),
mddi_readl(RTD_VAL), mddi_readl(CURR_REV_PTR));
} while (retry_count-- > 0);
/* Disable Periodic Reverse Encapsulation. */
mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
mddi->reg_read = NULL;
mutex_unlock(&mddi->reg_read_lock);
return ri.result;
}
static struct mddi_info mddi_info[2];
static int mddi_clk_setup(struct platform_device *pdev, struct mddi_info *mddi,
unsigned long clk_rate)
{
int ret;
/* set up the clocks */
mddi->clk = clk_get(&pdev->dev, "mddi_clk");
if (IS_ERR(mddi->clk)) {
printk(KERN_INFO "mddi: failed to get clock\n");
return PTR_ERR(mddi->clk);
}
ret = clk_enable(mddi->clk);
if (ret)
goto fail;
ret = clk_set_rate(mddi->clk, clk_rate);
if (ret)
goto fail;
return 0;
fail:
clk_put(mddi->clk);
return ret;
}
static int __init mddi_rev_data_setup(struct mddi_info *mddi)
{
void *dma;
dma_addr_t dma_addr;
/* set up dma buffer */
dma = dma_alloc_coherent(NULL, 0x1000, &dma_addr, GFP_KERNEL);
if (dma == 0)
return -ENOMEM;
mddi->rev_data = dma;
mddi->rev_data_curr = 0;
mddi->rev_addr = dma_addr;
mddi->reg_write_data = dma + MDDI_REV_BUFFER_SIZE;
mddi->reg_write_addr = dma_addr + MDDI_REV_BUFFER_SIZE;
mddi->reg_read_data = mddi->reg_write_data + 1;
mddi->reg_read_addr = mddi->reg_write_addr +
sizeof(*mddi->reg_write_data);
return 0;
}
static int mddi_probe(struct platform_device *pdev)
{
struct msm_mddi_platform_data *pdata = pdev->dev.platform_data;
struct mddi_info *mddi = &mddi_info[pdev->id];
struct resource *resource;
int ret, i;
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!resource) {
printk(KERN_ERR "mddi: no associated mem resource!\n");
return -ENOMEM;
}
mddi->base = ioremap(resource->start, resource_size(resource));
if (!mddi->base) {
printk(KERN_ERR "mddi: failed to remap base!\n");
ret = -EINVAL;
goto error_ioremap;
}
resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!resource) {
printk(KERN_ERR "mddi: no associated irq resource!\n");
ret = -EINVAL;
goto error_get_irq_resource;
}
mddi->irq = resource->start;
printk(KERN_INFO "mddi: init() base=0x%p irq=%d\n", mddi->base,
mddi->irq);
mddi->power_client = pdata->power_client;
mutex_init(&mddi->reg_write_lock);
mutex_init(&mddi->reg_read_lock);
spin_lock_init(&mddi->int_lock);
init_waitqueue_head(&mddi->int_wait);
ret = mddi_clk_setup(pdev, mddi, pdata->clk_rate);
if (ret) {
printk(KERN_ERR "mddi: failed to setup clock!\n");
goto error_clk_setup;
}
ret = mddi_rev_data_setup(mddi);
if (ret) {
printk(KERN_ERR "mddi: failed to setup rev data!\n");
goto error_rev_data;
}
mddi->int_enable = 0;
mddi_writel(mddi->int_enable, INTEN);
ret = request_irq(mddi->irq, mddi_isr, 0, "mddi",
&mddi->client_data);
if (ret) {
printk(KERN_ERR "mddi: failed to request enable irq!\n");
goto error_request_irq;
}
/* turn on the mddi client bridge chip */
if (mddi->power_client)
mddi->power_client(&mddi->client_data, 1);
/* initialize the mddi registers */
mddi_set_auto_hibernate(&mddi->client_data, 0);
mddi_writel(MDDI_CMD_RESET, CMD);
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
mddi->version = mddi_init_registers(mddi);
if (mddi->version < 0x20) {
printk(KERN_ERR "mddi: unsupported version 0x%x\n",
mddi->version);
ret = -ENODEV;
goto error_mddi_version;
}
/* read the capabilities off the client */
if (!mddi_get_client_caps(mddi)) {
printk(KERN_INFO "mddi: no client found\n");
/* power down the panel */
mddi_writel(MDDI_CMD_POWERDOWN, CMD);
printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
msleep(100);
printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
return 0;
}
mddi_set_auto_hibernate(&mddi->client_data, 1);
if (mddi->caps.Mfr_Name == 0 && mddi->caps.Product_Code == 0)
pdata->fixup(&mddi->caps.Mfr_Name, &mddi->caps.Product_Code);
mddi->client_pdev.id = 0;
for (i = 0; i < pdata->num_clients; i++) {
if (pdata->client_platform_data[i].product_id ==
(mddi->caps.Mfr_Name << 16 | mddi->caps.Product_Code)) {
mddi->client_data.private_client_data =
pdata->client_platform_data[i].client_data;
mddi->client_pdev.name =
pdata->client_platform_data[i].name;
mddi->client_pdev.id =
pdata->client_platform_data[i].id;
/* XXX: possibly set clock */
break;
}
}
if (i >= pdata->num_clients)
mddi->client_pdev.name = "mddi_c_dummy";
printk(KERN_INFO "mddi: registering panel %s\n",
mddi->client_pdev.name);
mddi->client_data.suspend = mddi_suspend;
mddi->client_data.resume = mddi_resume;
mddi->client_data.activate_link = mddi_activate_link;
mddi->client_data.remote_write = mddi_remote_write;
mddi->client_data.remote_read = mddi_remote_read;
mddi->client_data.auto_hibernate = mddi_set_auto_hibernate;
mddi->client_data.fb_resource = pdata->fb_resource;
if (pdev->id == 0)
mddi->client_data.interface_type = MSM_MDDI_PMDH_INTERFACE;
else if (pdev->id == 1)
mddi->client_data.interface_type = MSM_MDDI_EMDH_INTERFACE;
else {
printk(KERN_ERR "mddi: can not determine interface %d!\n",
pdev->id);
ret = -EINVAL;
goto error_mddi_interface;
}
mddi->client_pdev.dev.platform_data = &mddi->client_data;
printk(KERN_INFO "mddi: publish: %s\n", mddi->client_name);
platform_device_register(&mddi->client_pdev);
return 0;
error_mddi_interface:
error_mddi_version:
free_irq(mddi->irq, 0);
error_request_irq:
dma_free_coherent(NULL, 0x1000, mddi->rev_data, mddi->rev_addr);
error_rev_data:
error_clk_setup:
error_get_irq_resource:
iounmap(mddi->base);
error_ioremap:
printk(KERN_INFO "mddi: mddi_init() failed (%d)\n", ret);
return ret;
}
static struct platform_driver mddi_driver = {
.probe = mddi_probe,
.driver = { .name = "msm_mddi" },
};
static int __init _mddi_init(void)
{
return platform_driver_register(&mddi_driver);
}
module_init(_mddi_init);

View File

@ -1,85 +0,0 @@
/* drivers/video/msm_fb/mddi_client_dummy.c
*
* Support for "dummy" mddi client devices which require no
* special initialization code.
*
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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/device.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/platform_data/video-msm_fb.h>
struct panel_info {
struct platform_device pdev;
struct msm_panel_data panel_data;
};
static int mddi_dummy_suspend(struct msm_panel_data *panel_data)
{
return 0;
}
static int mddi_dummy_resume(struct msm_panel_data *panel_data)
{
return 0;
}
static int mddi_dummy_blank(struct msm_panel_data *panel_data)
{
return 0;
}
static int mddi_dummy_unblank(struct msm_panel_data *panel_data)
{
return 0;
}
static int mddi_dummy_probe(struct platform_device *pdev)
{
struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
struct panel_info *panel =
devm_kzalloc(&pdev->dev, sizeof(struct panel_info), GFP_KERNEL);
if (!panel)
return -ENOMEM;
platform_set_drvdata(pdev, panel);
panel->panel_data.suspend = mddi_dummy_suspend;
panel->panel_data.resume = mddi_dummy_resume;
panel->panel_data.blank = mddi_dummy_blank;
panel->panel_data.unblank = mddi_dummy_unblank;
panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES;
panel->pdev.name = "msm_panel";
panel->pdev.id = pdev->id;
platform_device_add_resources(&panel->pdev,
client_data->fb_resource, 1);
panel->panel_data.fb_data = client_data->private_client_data;
panel->pdev.dev.platform_data = &panel->panel_data;
return platform_device_register(&panel->pdev);
}
static struct platform_driver mddi_client_dummy = {
.probe = mddi_dummy_probe,
.driver = { .name = "mddi_c_dummy" },
};
static int __init mddi_client_dummy_init(void)
{
platform_driver_register(&mddi_client_dummy);
return 0;
}
module_init(mddi_client_dummy_init);

View File

@ -1,252 +0,0 @@
/* drivers/video/msm_fb/mddi_client_nt35399.c
*
* Support for Novatek NT35399 MDDI client of Sapphire
*
* Copyright (C) 2008 HTC Incorporated
* Author: Solomon Chiu (solomon_chiu@htc.com)
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/platform_data/video-msm_fb.h>
static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait);
struct panel_info {
struct msm_mddi_client_data *client_data;
struct platform_device pdev;
struct msm_panel_data panel_data;
struct msmfb_callback *fb_callback;
struct work_struct panel_work;
struct workqueue_struct *fb_wq;
int nt35399_got_int;
};
static void
nt35399_request_vsync(struct msm_panel_data *panel_data,
struct msmfb_callback *callback)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
panel->fb_callback = callback;
if (panel->nt35399_got_int) {
panel->nt35399_got_int = 0;
client_data->activate_link(client_data); /* clears interrupt */
}
}
static void nt35399_wait_vsync(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
if (panel->nt35399_got_int) {
panel->nt35399_got_int = 0;
client_data->activate_link(client_data); /* clears interrupt */
}
if (wait_event_timeout(nt35399_vsync_wait, panel->nt35399_got_int,
HZ/2) == 0)
printk(KERN_ERR "timeout waiting for VSYNC\n");
panel->nt35399_got_int = 0;
/* interrupt clears when screen dma starts */
}
static int nt35399_suspend(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
int ret;
ret = bridge_data->uninit(bridge_data, client_data);
if (ret) {
printk(KERN_INFO "mddi nt35399 client: non zero return from "
"uninit\n");
return ret;
}
client_data->suspend(client_data);
return 0;
}
static int nt35399_resume(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
int ret;
client_data->resume(client_data);
ret = bridge_data->init(bridge_data, client_data);
if (ret)
return ret;
return 0;
}
static int nt35399_blank(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
return bridge_data->blank(bridge_data, client_data);
}
static int nt35399_unblank(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
return bridge_data->unblank(bridge_data, client_data);
}
irqreturn_t nt35399_vsync_interrupt(int irq, void *data)
{
struct panel_info *panel = data;
panel->nt35399_got_int = 1;
if (panel->fb_callback) {
panel->fb_callback->func(panel->fb_callback);
panel->fb_callback = NULL;
}
wake_up(&nt35399_vsync_wait);
return IRQ_HANDLED;
}
static int setup_vsync(struct panel_info *panel, int init)
{
int ret;
int gpio = 97;
unsigned int irq;
if (!init) {
ret = 0;
goto uninit;
}
ret = gpio_request_one(gpio, GPIOF_IN, "vsync");
if (ret)
goto err_request_gpio_failed;
ret = irq = gpio_to_irq(gpio);
if (ret < 0)
goto err_get_irq_num_failed;
ret = request_irq(irq, nt35399_vsync_interrupt, IRQF_TRIGGER_RISING,
"vsync", panel);
if (ret)
goto err_request_irq_failed;
printk(KERN_INFO "vsync on gpio %d now %d\n",
gpio, gpio_get_value(gpio));
return 0;
uninit:
free_irq(gpio_to_irq(gpio), panel->client_data);
err_request_irq_failed:
err_get_irq_num_failed:
gpio_free(gpio);
err_request_gpio_failed:
return ret;
}
static int mddi_nt35399_probe(struct platform_device *pdev)
{
struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
int ret;
struct panel_info *panel = devm_kzalloc(&pdev->dev,
sizeof(struct panel_info),
GFP_KERNEL);
printk(KERN_DEBUG "%s: enter.\n", __func__);
if (!panel)
return -ENOMEM;
platform_set_drvdata(pdev, panel);
ret = setup_vsync(panel, 1);
if (ret) {
dev_err(&pdev->dev, "mddi_nt35399_setup_vsync failed\n");
return ret;
}
panel->client_data = client_data;
panel->panel_data.suspend = nt35399_suspend;
panel->panel_data.resume = nt35399_resume;
panel->panel_data.wait_vsync = nt35399_wait_vsync;
panel->panel_data.request_vsync = nt35399_request_vsync;
panel->panel_data.blank = nt35399_blank;
panel->panel_data.unblank = nt35399_unblank;
panel->panel_data.fb_data = &bridge_data->fb_data;
panel->panel_data.caps = 0;
panel->pdev.name = "msm_panel";
panel->pdev.id = pdev->id;
panel->pdev.resource = client_data->fb_resource;
panel->pdev.num_resources = 1;
panel->pdev.dev.platform_data = &panel->panel_data;
if (bridge_data->init)
bridge_data->init(bridge_data, client_data);
platform_device_register(&panel->pdev);
return 0;
}
static int mddi_nt35399_remove(struct platform_device *pdev)
{
struct panel_info *panel = platform_get_drvdata(pdev);
setup_vsync(panel, 0);
return 0;
}
static struct platform_driver mddi_client_0bda_8a47 = {
.probe = mddi_nt35399_probe,
.remove = mddi_nt35399_remove,
.driver = { .name = "mddi_c_0bda_8a47" },
};
static int __init mddi_client_nt35399_init(void)
{
return platform_driver_register(&mddi_client_0bda_8a47);
}
module_init(mddi_client_nt35399_init);

View File

@ -1,280 +0,0 @@
/* drivers/video/msm_fb/mddi_client_toshiba.c
*
* Support for Toshiba TC358720XBG mddi client devices which require no
* special initialization code.
*
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/platform_data/video-msm_fb.h>
#define LCD_CONTROL_BLOCK_BASE 0x110000
#define CMN (LCD_CONTROL_BLOCK_BASE|0x10)
#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18)
#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34)
#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C)
#define VPOS (LCD_CONTROL_BLOCK_BASE|0xC0)
#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20)
#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54)
#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58)
#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C)
#define BASE5 0x150000
#define BASE6 0x160000
#define BASE7 0x170000
#define GPIOIEV (BASE5 + 0x10)
#define GPIOIE (BASE5 + 0x14)
#define GPIORIS (BASE5 + 0x18)
#define GPIOMIS (BASE5 + 0x1C)
#define GPIOIC (BASE5 + 0x20)
#define INTMASK (BASE6 + 0x0C)
#define INTMASK_VWAKEOUT (1U << 0)
#define INTMASK_VWAKEOUT_ACTIVE_LOW (1U << 8)
#define GPIOSEL (BASE7 + 0x00)
#define GPIOSEL_VWAKEINT (1U << 0)
static DECLARE_WAIT_QUEUE_HEAD(toshiba_vsync_wait);
struct panel_info {
struct msm_mddi_client_data *client_data;
struct platform_device pdev;
struct msm_panel_data panel_data;
struct msmfb_callback *toshiba_callback;
int toshiba_got_int;
};
static void toshiba_request_vsync(struct msm_panel_data *panel_data,
struct msmfb_callback *callback)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
panel->toshiba_callback = callback;
if (panel->toshiba_got_int) {
panel->toshiba_got_int = 0;
client_data->activate_link(client_data);
}
}
static void toshiba_clear_vsync(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
client_data->activate_link(client_data);
}
static void toshiba_wait_vsync(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
if (panel->toshiba_got_int) {
panel->toshiba_got_int = 0;
client_data->activate_link(client_data); /* clears interrupt */
}
if (wait_event_timeout(toshiba_vsync_wait, panel->toshiba_got_int,
HZ/2) == 0)
printk(KERN_ERR "timeout waiting for VSYNC\n");
panel->toshiba_got_int = 0;
/* interrupt clears when screen dma starts */
}
static int toshiba_suspend(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
int ret;
ret = bridge_data->uninit(bridge_data, client_data);
if (ret) {
printk(KERN_INFO "mddi toshiba client: non zero return from "
"uninit\n");
return ret;
}
client_data->suspend(client_data);
return 0;
}
static int toshiba_resume(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
int ret;
client_data->resume(client_data);
ret = bridge_data->init(bridge_data, client_data);
if (ret)
return ret;
return 0;
}
static int toshiba_blank(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
return bridge_data->blank(bridge_data, client_data);
}
static int toshiba_unblank(struct msm_panel_data *panel_data)
{
struct panel_info *panel = container_of(panel_data, struct panel_info,
panel_data);
struct msm_mddi_client_data *client_data = panel->client_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
return bridge_data->unblank(bridge_data, client_data);
}
irqreturn_t toshiba_vsync_interrupt(int irq, void *data)
{
struct panel_info *panel = data;
panel->toshiba_got_int = 1;
if (panel->toshiba_callback) {
panel->toshiba_callback->func(panel->toshiba_callback);
panel->toshiba_callback = 0;
}
wake_up(&toshiba_vsync_wait);
return IRQ_HANDLED;
}
static int setup_vsync(struct panel_info *panel,
int init)
{
int ret;
int gpio = 97;
unsigned int irq;
if (!init) {
ret = 0;
goto uninit;
}
ret = gpio_request_one(gpio, GPIOF_IN, "vsync");
if (ret)
goto err_request_gpio_failed;
ret = irq = gpio_to_irq(gpio);
if (ret < 0)
goto err_get_irq_num_failed;
ret = request_irq(irq, toshiba_vsync_interrupt, IRQF_TRIGGER_RISING,
"vsync", panel);
if (ret)
goto err_request_irq_failed;
printk(KERN_INFO "vsync on gpio %d now %d\n",
gpio, gpio_get_value(gpio));
return 0;
uninit:
free_irq(gpio_to_irq(gpio), panel);
err_request_irq_failed:
err_get_irq_num_failed:
gpio_free(gpio);
err_request_gpio_failed:
return ret;
}
static int mddi_toshiba_probe(struct platform_device *pdev)
{
int ret;
struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
struct msm_mddi_bridge_platform_data *bridge_data =
client_data->private_client_data;
struct panel_info *panel =
kzalloc(sizeof(struct panel_info), GFP_KERNEL);
if (!panel)
return -ENOMEM;
platform_set_drvdata(pdev, panel);
/* mddi_remote_write(mddi, 0, WAKEUP); */
client_data->remote_write(client_data, GPIOSEL_VWAKEINT, GPIOSEL);
client_data->remote_write(client_data, INTMASK_VWAKEOUT, INTMASK);
ret = setup_vsync(panel, 1);
if (ret) {
dev_err(&pdev->dev, "mddi_bridge_setup_vsync failed\n");
return ret;
}
panel->client_data = client_data;
panel->panel_data.suspend = toshiba_suspend;
panel->panel_data.resume = toshiba_resume;
panel->panel_data.wait_vsync = toshiba_wait_vsync;
panel->panel_data.request_vsync = toshiba_request_vsync;
panel->panel_data.clear_vsync = toshiba_clear_vsync;
panel->panel_data.blank = toshiba_blank;
panel->panel_data.unblank = toshiba_unblank;
panel->panel_data.fb_data = &bridge_data->fb_data;
panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES;
panel->pdev.name = "msm_panel";
panel->pdev.id = pdev->id;
panel->pdev.resource = client_data->fb_resource;
panel->pdev.num_resources = 1;
panel->pdev.dev.platform_data = &panel->panel_data;
bridge_data->init(bridge_data, client_data);
platform_device_register(&panel->pdev);
return 0;
}
static int mddi_toshiba_remove(struct platform_device *pdev)
{
struct panel_info *panel = platform_get_drvdata(pdev);
setup_vsync(panel, 0);
kfree(panel);
return 0;
}
static struct platform_driver mddi_client_d263_0000 = {
.probe = mddi_toshiba_probe,
.remove = mddi_toshiba_remove,
.driver = { .name = "mddi_c_d263_0000" },
};
static int __init mddi_client_toshiba_init(void)
{
platform_driver_register(&mddi_client_d263_0000);
return 0;
}
module_init(mddi_client_toshiba_init);

View File

@ -1,305 +0,0 @@
/* drivers/video/msm_fb/mddi_hw.h
*
* MSM MDDI Hardware Registers and Structures
*
* Copyright (C) 2007 QUALCOMM Incorporated
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _MDDI_HW_H_
#define _MDDI_HW_H_
#include <linux/types.h>
#define MDDI_CMD 0x0000
#define MDDI_VERSION 0x0004
#define MDDI_PRI_PTR 0x0008
#define MDDI_SEC_PTR 0x000c
#define MDDI_BPS 0x0010
#define MDDI_SPM 0x0014
#define MDDI_INT 0x0018
#define MDDI_INTEN 0x001c
#define MDDI_REV_PTR 0x0020
#define MDDI_REV_SIZE 0x0024
#define MDDI_STAT 0x0028
#define MDDI_REV_RATE_DIV 0x002c
#define MDDI_REV_CRC_ERR 0x0030
#define MDDI_TA1_LEN 0x0034
#define MDDI_TA2_LEN 0x0038
#define MDDI_TEST_BUS 0x003c
#define MDDI_TEST 0x0040
#define MDDI_REV_PKT_CNT 0x0044
#define MDDI_DRIVE_HI 0x0048
#define MDDI_DRIVE_LO 0x004c
#define MDDI_DISP_WAKE 0x0050
#define MDDI_REV_ENCAP_SZ 0x0054
#define MDDI_RTD_VAL 0x0058
#define MDDI_PAD_CTL 0x0068
#define MDDI_DRIVER_START_CNT 0x006c
#define MDDI_NEXT_PRI_PTR 0x0070
#define MDDI_NEXT_SEC_PTR 0x0074
#define MDDI_MISR_CTL 0x0078
#define MDDI_MISR_DATA 0x007c
#define MDDI_SF_CNT 0x0080
#define MDDI_MF_CNT 0x0084
#define MDDI_CURR_REV_PTR 0x0088
#define MDDI_CORE_VER 0x008c
#define MDDI_INT_PRI_PTR_READ 0x0001
#define MDDI_INT_SEC_PTR_READ 0x0002
#define MDDI_INT_REV_DATA_AVAIL 0x0004
#define MDDI_INT_DISP_REQ 0x0008
#define MDDI_INT_PRI_UNDERFLOW 0x0010
#define MDDI_INT_SEC_UNDERFLOW 0x0020
#define MDDI_INT_REV_OVERFLOW 0x0040
#define MDDI_INT_CRC_ERROR 0x0080
#define MDDI_INT_MDDI_IN 0x0100
#define MDDI_INT_PRI_OVERWRITE 0x0200
#define MDDI_INT_SEC_OVERWRITE 0x0400
#define MDDI_INT_REV_OVERWRITE 0x0800
#define MDDI_INT_DMA_FAILURE 0x1000
#define MDDI_INT_LINK_ACTIVE 0x2000
#define MDDI_INT_IN_HIBERNATION 0x4000
#define MDDI_INT_PRI_LINK_LIST_DONE 0x8000
#define MDDI_INT_SEC_LINK_LIST_DONE 0x10000
#define MDDI_INT_NO_CMD_PKTS_PEND 0x20000
#define MDDI_INT_RTD_FAILURE 0x40000
#define MDDI_INT_REV_PKT_RECEIVED 0x80000
#define MDDI_INT_REV_PKTS_AVAIL 0x100000
#define MDDI_INT_NEED_CLEAR ( \
MDDI_INT_REV_DATA_AVAIL | \
MDDI_INT_PRI_UNDERFLOW | \
MDDI_INT_SEC_UNDERFLOW | \
MDDI_INT_REV_OVERFLOW | \
MDDI_INT_CRC_ERROR | \
MDDI_INT_REV_PKT_RECEIVED)
#define MDDI_STAT_LINK_ACTIVE 0x0001
#define MDDI_STAT_NEW_REV_PTR 0x0002
#define MDDI_STAT_NEW_PRI_PTR 0x0004
#define MDDI_STAT_NEW_SEC_PTR 0x0008
#define MDDI_STAT_IN_HIBERNATION 0x0010
#define MDDI_STAT_PRI_LINK_LIST_DONE 0x0020
#define MDDI_STAT_SEC_LINK_LIST_DONE 0x0040
#define MDDI_STAT_PENDING_TIMING_PKT 0x0080
#define MDDI_STAT_PENDING_REV_ENCAP 0x0100
#define MDDI_STAT_PENDING_POWERDOWN 0x0200
#define MDDI_STAT_RTD_MEAS_FAIL 0x0800
#define MDDI_STAT_CLIENT_WAKEUP_REQ 0x1000
#define MDDI_CMD_POWERDOWN 0x0100
#define MDDI_CMD_POWERUP 0x0200
#define MDDI_CMD_HIBERNATE 0x0300
#define MDDI_CMD_RESET 0x0400
#define MDDI_CMD_DISP_IGNORE 0x0501
#define MDDI_CMD_DISP_LISTEN 0x0500
#define MDDI_CMD_SEND_REV_ENCAP 0x0600
#define MDDI_CMD_GET_CLIENT_CAP 0x0601
#define MDDI_CMD_GET_CLIENT_STATUS 0x0602
#define MDDI_CMD_SEND_RTD 0x0700
#define MDDI_CMD_LINK_ACTIVE 0x0900
#define MDDI_CMD_PERIODIC_REV_ENCAP 0x0A00
#define MDDI_CMD_FORCE_NEW_REV_PTR 0x0C00
#define MDDI_VIDEO_REV_PKT_SIZE 0x40
#define MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE 0x60
#define MDDI_MAX_REV_PKT_SIZE 0x60
/* #define MDDI_REV_BUFFER_SIZE 128 */
#define MDDI_REV_BUFFER_SIZE (MDDI_MAX_REV_PKT_SIZE * 4)
/* MDP sends 256 pixel packets, so lower value hibernates more without
* significantly increasing latency of waiting for next subframe */
#define MDDI_HOST_BYTES_PER_SUBFRAME 0x3C00
#define MDDI_HOST_TA2_LEN 0x000c
#define MDDI_HOST_REV_RATE_DIV 0x0002
struct __attribute__((packed)) mddi_rev_packet {
uint16_t length;
uint16_t type;
uint16_t client_id;
};
struct __attribute__((packed)) mddi_client_status {
uint16_t length;
uint16_t type;
uint16_t client_id;
uint16_t reverse_link_request; /* bytes needed in rev encap message */
uint8_t crc_error_count;
uint8_t capability_change;
uint16_t graphics_busy_flags;
uint16_t crc16;
};
struct __attribute__((packed)) mddi_client_caps {
uint16_t length; /* length, exclusive of this field */
uint16_t type; /* 66 */
uint16_t client_id;
uint16_t Protocol_Version;
uint16_t Minimum_Protocol_Version;
uint16_t Data_Rate_Capability;
uint8_t Interface_Type_Capability;
uint8_t Number_of_Alt_Displays;
uint16_t PostCal_Data_Rate;
uint16_t Bitmap_Width;
uint16_t Bitmap_Height;
uint16_t Display_Window_Width;
uint16_t Display_Window_Height;
uint32_t Color_Map_Size;
uint16_t Color_Map_RGB_Width;
uint16_t RGB_Capability;
uint8_t Monochrome_Capability;
uint8_t Reserved_1;
uint16_t Y_Cb_Cr_Capability;
uint16_t Bayer_Capability;
uint16_t Alpha_Cursor_Image_Planes;
uint32_t Client_Feature_Capability_Indicators;
uint8_t Maximum_Video_Frame_Rate_Capability;
uint8_t Minimum_Video_Frame_Rate_Capability;
uint16_t Minimum_Sub_frame_Rate;
uint16_t Audio_Buffer_Depth;
uint16_t Audio_Channel_Capability;
uint16_t Audio_Sample_Rate_Capability;
uint8_t Audio_Sample_Resolution;
uint8_t Mic_Audio_Sample_Resolution;
uint16_t Mic_Sample_Rate_Capability;
uint8_t Keyboard_Data_Format;
uint8_t pointing_device_data_format;
uint16_t content_protection_type;
uint16_t Mfr_Name;
uint16_t Product_Code;
uint16_t Reserved_3;
uint32_t Serial_Number;
uint8_t Week_of_Manufacture;
uint8_t Year_of_Manufacture;
uint16_t crc16;
} mddi_client_capability_type;
struct __attribute__((packed)) mddi_video_stream {
uint16_t length;
uint16_t type; /* 16 */
uint16_t client_id; /* 0 */
uint16_t video_data_format_descriptor;
/* format of each pixel in the Pixel Data in the present stream in the
* present packet.
* If bits [15:13] = 000 monochrome
* If bits [15:13] = 001 color pixels (palette).
* If bits [15:13] = 010 color pixels in raw RGB
* If bits [15:13] = 011 data in 4:2:2 Y Cb Cr format
* If bits [15:13] = 100 Bayer pixels
*/
uint16_t pixel_data_attributes;
/* interpreted as follows:
* Bits [1:0] = 11 pixel data is displayed to both eyes
* Bits [1:0] = 10 pixel data is routed to the left eye only.
* Bits [1:0] = 01 pixel data is routed to the right eye only.
* Bits [1:0] = 00 pixel data is routed to the alternate display.
* Bit 2 is 0 Pixel Data is in the standard progressive format.
* Bit 2 is 1 Pixel Data is in interlace format.
* Bit 3 is 0 Pixel Data is in the standard progressive format.
* Bit 3 is 1 Pixel Data is in alternate pixel format.
* Bit 4 is 0 Pixel Data is to or from the display frame buffer.
* Bit 4 is 1 Pixel Data is to or from the camera.
* Bit 5 is 0 pixel data contains the next consecutive row of pixels.
* Bit 5 is 1 X Left Edge, Y Top Edge, X Right Edge, Y Bottom Edge,
* X Start, and Y Start parameters are not defined and
* shall be ignored by the client.
* Bits [7:6] = 01 Pixel data is written to the offline image buffer.
* Bits [7:6] = 00 Pixel data is written to the buffer to refresh display.
* Bits [7:6] = 11 Pixel data is written to all image buffers.
* Bits [7:6] = 10 Invalid. Reserved for future use.
* Bits 8 through 11 alternate display number.
* Bits 12 through 14 are reserved for future use and shall be set to zero.
* Bit 15 is 1 the row of pixels is the last row of pixels in a frame.
*/
uint16_t x_left_edge;
uint16_t y_top_edge;
/* X,Y coordinate of the top left edge of the screen window */
uint16_t x_right_edge;
uint16_t y_bottom_edge;
/* X,Y coordinate of the bottom right edge of the window being
* updated. */
uint16_t x_start;
uint16_t y_start;
/* (X Start, Y Start) is the first pixel in the Pixel Data field
* below. */
uint16_t pixel_count;
/* number of pixels in the Pixel Data field below. */
uint16_t parameter_CRC;
/* 16-bit CRC of all bytes from the Packet Length to the Pixel Count. */
uint16_t reserved;
/* 16-bit variable to make structure align on 4 byte boundary */
};
#define TYPE_VIDEO_STREAM 16
#define TYPE_CLIENT_CAPS 66
#define TYPE_REGISTER_ACCESS 146
#define TYPE_CLIENT_STATUS 70
struct __attribute__((packed)) mddi_register_access {
uint16_t length;
uint16_t type; /* 146 */
uint16_t client_id;
uint16_t read_write_info;
/* Bits 13:0 a 14-bit unsigned integer that specifies the number of
* 32-bit Register Data List items to be transferred in the
* Register Data List field.
* Bits[15:14] = 00 Write to register(s);
* Bits[15:14] = 10 Read from register(s);
* Bits[15:14] = 11 Response to a Read.
* Bits[15:14] = 01 this value is reserved for future use. */
#define MDDI_WRITE (0 << 14)
#define MDDI_READ (2 << 14)
#define MDDI_READ_RESP (3 << 14)
uint32_t register_address;
/* the register address that is to be written to or read from. */
uint16_t crc16;
uint32_t register_data_list;
/* list of 4-byte register data values for/from client registers */
};
struct __attribute__((packed)) mddi_llentry {
uint16_t flags;
uint16_t header_count;
uint16_t data_count;
dma_addr_t data; /* 32 bit */
struct mddi_llentry *next;
uint16_t reserved;
union {
struct mddi_video_stream v;
struct mddi_register_access r;
uint32_t _[12];
} u;
};
#endif

View File

@ -1,520 +0,0 @@
/* drivers/video/msm_fb/mdp.c
*
* MSM MDP Interface (used by framebuffer core)
*
* Copyright (C) 2007 QUALCOMM Incorporated
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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/fb.h>
#include <linux/msm_mdp.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/clk.h>
#include <linux/file.h>
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/platform_data/video-msm_fb.h>
#include <linux/platform_device.h>
#include <linux/export.h>
#include "mdp_hw.h"
struct class *mdp_class;
#define MDP_CMD_DEBUG_ACCESS_BASE (0x10000)
static uint16_t mdp_default_ccs[] = {
0x254, 0x000, 0x331, 0x254, 0xF38, 0xE61, 0x254, 0x409, 0x000,
0x010, 0x080, 0x080
};
static DECLARE_WAIT_QUEUE_HEAD(mdp_dma2_waitqueue);
static DECLARE_WAIT_QUEUE_HEAD(mdp_ppp_waitqueue);
static struct msmfb_callback *dma_callback;
static struct clk *clk;
static unsigned int mdp_irq_mask;
static DEFINE_SPINLOCK(mdp_lock);
DEFINE_MUTEX(mdp_mutex);
static int enable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
{
unsigned long irq_flags;
int ret = 0;
BUG_ON(!mask);
spin_lock_irqsave(&mdp_lock, irq_flags);
/* if the mask bits are already set return an error, this interrupt
* is already enabled */
if (mdp_irq_mask & mask) {
printk(KERN_ERR "mdp irq already on already on %x %x\n",
mdp_irq_mask, mask);
ret = -1;
}
/* if the mdp irq is not already enabled enable it */
if (!mdp_irq_mask) {
if (clk)
clk_enable(clk);
enable_irq(mdp->irq);
}
/* update the irq mask to reflect the fact that the interrupt is
* enabled */
mdp_irq_mask |= mask;
spin_unlock_irqrestore(&mdp_lock, irq_flags);
return ret;
}
static int locked_disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
{
/* this interrupt is already disabled! */
if (!(mdp_irq_mask & mask)) {
printk(KERN_ERR "mdp irq already off %x %x\n",
mdp_irq_mask, mask);
return -1;
}
/* update the irq mask to reflect the fact that the interrupt is
* disabled */
mdp_irq_mask &= ~(mask);
/* if no one is waiting on the interrupt, disable it */
if (!mdp_irq_mask) {
disable_irq_nosync(mdp->irq);
if (clk)
clk_disable(clk);
}
return 0;
}
static int disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
{
unsigned long irq_flags;
int ret;
spin_lock_irqsave(&mdp_lock, irq_flags);
ret = locked_disable_mdp_irq(mdp, mask);
spin_unlock_irqrestore(&mdp_lock, irq_flags);
return ret;
}
static irqreturn_t mdp_isr(int irq, void *data)
{
uint32_t status;
unsigned long irq_flags;
struct mdp_info *mdp = data;
spin_lock_irqsave(&mdp_lock, irq_flags);
status = mdp_readl(mdp, MDP_INTR_STATUS);
mdp_writel(mdp, status, MDP_INTR_CLEAR);
status &= mdp_irq_mask;
if (status & DL0_DMA2_TERM_DONE) {
if (dma_callback) {
dma_callback->func(dma_callback);
dma_callback = NULL;
}
wake_up(&mdp_dma2_waitqueue);
}
if (status & DL0_ROI_DONE)
wake_up(&mdp_ppp_waitqueue);
if (status)
locked_disable_mdp_irq(mdp, status);
spin_unlock_irqrestore(&mdp_lock, irq_flags);
return IRQ_HANDLED;
}
static uint32_t mdp_check_mask(uint32_t mask)
{
uint32_t ret;
unsigned long irq_flags;
spin_lock_irqsave(&mdp_lock, irq_flags);
ret = mdp_irq_mask & mask;
spin_unlock_irqrestore(&mdp_lock, irq_flags);
return ret;
}
static int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq)
{
int ret = 0;
unsigned long irq_flags;
wait_event_timeout(*wq, !mdp_check_mask(mask), HZ);
spin_lock_irqsave(&mdp_lock, irq_flags);
if (mdp_irq_mask & mask) {
locked_disable_mdp_irq(mdp, mask);
printk(KERN_WARNING "timeout waiting for mdp to complete %x\n",
mask);
ret = -ETIMEDOUT;
}
spin_unlock_irqrestore(&mdp_lock, irq_flags);
return ret;
}
void mdp_dma_wait(struct mdp_device *mdp_dev)
{
#define MDP_MAX_TIMEOUTS 20
static int timeout_count;
struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
if (mdp_wait(mdp, DL0_DMA2_TERM_DONE, &mdp_dma2_waitqueue) == -ETIMEDOUT)
timeout_count++;
else
timeout_count = 0;
if (timeout_count > MDP_MAX_TIMEOUTS) {
printk(KERN_ERR "mdp: dma failed %d times, somethings wrong!\n",
MDP_MAX_TIMEOUTS);
BUG();
}
}
static int mdp_ppp_wait(struct mdp_info *mdp)
{
return mdp_wait(mdp, DL0_ROI_DONE, &mdp_ppp_waitqueue);
}
void mdp_dma_to_mddi(struct mdp_info *mdp, uint32_t addr, uint32_t stride,
uint32_t width, uint32_t height, uint32_t x, uint32_t y,
struct msmfb_callback *callback)
{
uint32_t dma2_cfg;
uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */
if (enable_mdp_irq(mdp, DL0_DMA2_TERM_DONE)) {
printk(KERN_ERR "mdp_dma_to_mddi: busy\n");
return;
}
dma_callback = callback;
dma2_cfg = DMA_PACK_TIGHT |
DMA_PACK_ALIGN_LSB |
DMA_PACK_PATTERN_RGB |
DMA_OUT_SEL_AHB |
DMA_IBUF_NONCONTIGUOUS;
dma2_cfg |= DMA_IBUF_FORMAT_RGB565;
dma2_cfg |= DMA_OUT_SEL_MDDI;
dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;
dma2_cfg |= DMA_DITHER_EN;
/* setup size, address, and stride */
mdp_writel(mdp, (height << 16) | (width),
MDP_CMD_DEBUG_ACCESS_BASE + 0x0184);
mdp_writel(mdp, addr, MDP_CMD_DEBUG_ACCESS_BASE + 0x0188);
mdp_writel(mdp, stride, MDP_CMD_DEBUG_ACCESS_BASE + 0x018C);
/* 666 18BPP */
dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
/* set y & x offset and MDDI transaction parameters */
mdp_writel(mdp, (y << 16) | (x), MDP_CMD_DEBUG_ACCESS_BASE + 0x0194);
mdp_writel(mdp, ld_param, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0);
mdp_writel(mdp, (MDDI_VDO_PACKET_DESC << 16) | MDDI_VDO_PACKET_PRIM,
MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4);
mdp_writel(mdp, dma2_cfg, MDP_CMD_DEBUG_ACCESS_BASE + 0x0180);
/* start DMA2 */
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0044);
}
void mdp_dma(struct mdp_device *mdp_dev, uint32_t addr, uint32_t stride,
uint32_t width, uint32_t height, uint32_t x, uint32_t y,
struct msmfb_callback *callback, int interface)
{
struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
if (interface == MSM_MDDI_PMDH_INTERFACE) {
mdp_dma_to_mddi(mdp, addr, stride, width, height, x, y,
callback);
}
}
int get_img(struct mdp_img *img, struct fb_info *info,
unsigned long *start, unsigned long *len,
struct file **filep)
{
int ret = 0;
struct fd f = fdget(img->memory_id);
if (f.file == NULL)
return -1;
if (MAJOR(file_inode(f.file)->i_rdev) == FB_MAJOR) {
*start = info->fix.smem_start;
*len = info->fix.smem_len;
} else
ret = -1;
fdput(f);
return ret;
}
void put_img(struct file *src_file, struct file *dst_file)
{
}
int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb,
struct mdp_blit_req *req)
{
int ret;
unsigned long src_start = 0, src_len = 0, dst_start = 0, dst_len = 0;
struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
struct file *src_file = 0, *dst_file = 0;
/* WORKAROUND FOR HARDWARE BUG IN BG TILE FETCH */
if (unlikely(req->src_rect.h == 0 ||
req->src_rect.w == 0)) {
printk(KERN_ERR "mpd_ppp: src img of zero size!\n");
return -EINVAL;
}
if (unlikely(req->dst_rect.h == 0 ||
req->dst_rect.w == 0))
return -EINVAL;
/* do this first so that if this fails, the caller can always
* safely call put_img */
if (unlikely(get_img(&req->src, fb, &src_start, &src_len, &src_file))) {
printk(KERN_ERR "mpd_ppp: could not retrieve src image from "
"memory\n");
return -EINVAL;
}
if (unlikely(get_img(&req->dst, fb, &dst_start, &dst_len, &dst_file))) {
printk(KERN_ERR "mpd_ppp: could not retrieve dst image from "
"memory\n");
return -EINVAL;
}
mutex_lock(&mdp_mutex);
/* transp_masking unimplemented */
req->transp_mask = MDP_TRANSP_NOP;
if (unlikely((req->transp_mask != MDP_TRANSP_NOP ||
req->alpha != MDP_ALPHA_NOP ||
HAS_ALPHA(req->src.format)) &&
(req->flags & MDP_ROT_90 &&
req->dst_rect.w <= 16 && req->dst_rect.h >= 16))) {
int i;
unsigned int tiles = req->dst_rect.h / 16;
unsigned int remainder = req->dst_rect.h % 16;
req->src_rect.w = 16*req->src_rect.w / req->dst_rect.h;
req->dst_rect.h = 16;
for (i = 0; i < tiles; i++) {
enable_mdp_irq(mdp, DL0_ROI_DONE);
ret = mdp_ppp_blit(mdp, req, src_file, src_start,
src_len, dst_file, dst_start,
dst_len);
if (ret)
goto err_bad_blit;
ret = mdp_ppp_wait(mdp);
if (ret)
goto err_wait_failed;
req->dst_rect.y += 16;
req->src_rect.x += req->src_rect.w;
}
if (!remainder)
goto end;
req->src_rect.w = remainder*req->src_rect.w / req->dst_rect.h;
req->dst_rect.h = remainder;
}
enable_mdp_irq(mdp, DL0_ROI_DONE);
ret = mdp_ppp_blit(mdp, req, src_file, src_start, src_len, dst_file,
dst_start,
dst_len);
if (ret)
goto err_bad_blit;
ret = mdp_ppp_wait(mdp);
if (ret)
goto err_wait_failed;
end:
put_img(src_file, dst_file);
mutex_unlock(&mdp_mutex);
return 0;
err_bad_blit:
disable_mdp_irq(mdp, DL0_ROI_DONE);
err_wait_failed:
put_img(src_file, dst_file);
mutex_unlock(&mdp_mutex);
return ret;
}
void mdp_set_grp_disp(struct mdp_device *mdp_dev, unsigned disp_id)
{
struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
disp_id &= 0xf;
mdp_writel(mdp, disp_id, MDP_FULL_BYPASS_WORD43);
}
int register_mdp_client(struct class_interface *cint)
{
if (!mdp_class) {
pr_err("mdp: no mdp_class when registering mdp client\n");
return -ENODEV;
}
cint->class = mdp_class;
return class_interface_register(cint);
}
#include "mdp_csc_table.h"
#include "mdp_scale_tables.h"
int mdp_probe(struct platform_device *pdev)
{
struct resource *resource;
int ret;
int n;
struct mdp_info *mdp;
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!resource) {
pr_err("mdp: can not get mdp mem resource!\n");
return -ENOMEM;
}
mdp = kzalloc(sizeof(struct mdp_info), GFP_KERNEL);
if (!mdp)
return -ENOMEM;
mdp->irq = platform_get_irq(pdev, 0);
if (mdp->irq < 0) {
pr_err("mdp: can not get mdp irq\n");
ret = mdp->irq;
goto error_get_irq;
}
mdp->base = ioremap(resource->start, resource_size(resource));
if (mdp->base == 0) {
printk(KERN_ERR "msmfb: cannot allocate mdp regs!\n");
ret = -ENOMEM;
goto error_ioremap;
}
mdp->mdp_dev.dma = mdp_dma;
mdp->mdp_dev.dma_wait = mdp_dma_wait;
mdp->mdp_dev.blit = mdp_blit;
mdp->mdp_dev.set_grp_disp = mdp_set_grp_disp;
clk = clk_get(&pdev->dev, "mdp_clk");
if (IS_ERR(clk)) {
printk(KERN_INFO "mdp: failed to get mdp clk");
ret = PTR_ERR(clk);
goto error_get_clk;
}
ret = request_irq(mdp->irq, mdp_isr, 0, "msm_mdp", mdp);
if (ret)
goto error_request_irq;
disable_irq(mdp->irq);
mdp_irq_mask = 0;
/* debug interface write access */
mdp_writel(mdp, 1, 0x60);
mdp_writel(mdp, MDP_ANY_INTR_MASK, MDP_INTR_ENABLE);
mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc);
for (n = 0; n < ARRAY_SIZE(csc_table); n++)
mdp_writel(mdp, csc_table[n].val, csc_table[n].reg);
/* clear up unused fg/main registers */
/* comp.plane 2&3 ystride */
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120);
/* unpacked pattern */
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c);
/* comp.plane 2 & 3 */
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118);
/* clear unused bg registers */
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0);
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4);
for (n = 0; n < ARRAY_SIZE(mdp_upscale_table); n++)
mdp_writel(mdp, mdp_upscale_table[n].val,
mdp_upscale_table[n].reg);
for (n = 0; n < 9; n++)
mdp_writel(mdp, mdp_default_ccs[n], 0x40440 + 4 * n);
mdp_writel(mdp, mdp_default_ccs[9], 0x40500 + 4 * 0);
mdp_writel(mdp, mdp_default_ccs[10], 0x40500 + 4 * 0);
mdp_writel(mdp, mdp_default_ccs[11], 0x40500 + 4 * 0);
/* register mdp device */
mdp->mdp_dev.dev.parent = &pdev->dev;
mdp->mdp_dev.dev.class = mdp_class;
dev_set_name(&mdp->mdp_dev.dev, "mdp%d", pdev->id);
/* if you can remove the platform device you'd have to implement
* this:
mdp_dev.release = mdp_class; */
ret = device_register(&mdp->mdp_dev.dev);
if (ret)
goto error_device_register;
return 0;
error_device_register:
free_irq(mdp->irq, mdp);
error_request_irq:
error_get_clk:
iounmap(mdp->base);
error_get_irq:
error_ioremap:
kfree(mdp);
return ret;
}
static struct platform_driver msm_mdp_driver = {
.probe = mdp_probe,
.driver = {.name = "msm_mdp"},
};
static int __init mdp_init(void)
{
mdp_class = class_create(THIS_MODULE, "msm_mdp");
if (IS_ERR(mdp_class)) {
printk(KERN_ERR "Error creating mdp class\n");
return PTR_ERR(mdp_class);
}
return platform_driver_register(&msm_mdp_driver);
}
subsys_initcall(mdp_init);

View File

@ -1,582 +0,0 @@
/* drivers/video/msm_fb/mdp_csc_table.h
*
* Copyright (C) 2007 QUALCOMM Incorporated
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*/
static struct {
uint32_t reg;
uint32_t val;
} csc_table[] = {
{ 0x40400, 0x83 },
{ 0x40404, 0x102 },
{ 0x40408, 0x32 },
{ 0x4040c, 0xffffffb5 },
{ 0x40410, 0xffffff6c },
{ 0x40414, 0xe1 },
{ 0x40418, 0xe1 },
{ 0x4041c, 0xffffff45 },
{ 0x40420, 0xffffffdc },
{ 0x40440, 0x254 },
{ 0x40444, 0x0 },
{ 0x40448, 0x331 },
{ 0x4044c, 0x254 },
{ 0x40450, 0xffffff38 },
{ 0x40454, 0xfffffe61 },
{ 0x40458, 0x254 },
{ 0x4045c, 0x409 },
{ 0x40460, 0x0 },
{ 0x40480, 0x5d },
{ 0x40484, 0x13a },
{ 0x40488, 0x20 },
{ 0x4048c, 0xffffffcd },
{ 0x40490, 0xffffff54 },
{ 0x40494, 0xe1 },
{ 0x40498, 0xe1 },
{ 0x4049c, 0xffffff35 },
{ 0x404a0, 0xffffffec },
{ 0x404c0, 0x254 },
{ 0x404c4, 0x0 },
{ 0x404c8, 0x396 },
{ 0x404cc, 0x254 },
{ 0x404d0, 0xffffff94 },
{ 0x404d4, 0xfffffef0 },
{ 0x404d8, 0x254 },
{ 0x404dc, 0x43a },
{ 0x404e0, 0x0 },
{ 0x40500, 0x10 },
{ 0x40504, 0x80 },
{ 0x40508, 0x80 },
{ 0x40540, 0x10 },
{ 0x40544, 0x80 },
{ 0x40548, 0x80 },
{ 0x40580, 0x10 },
{ 0x40584, 0xeb },
{ 0x40588, 0x10 },
{ 0x4058c, 0xf0 },
{ 0x405c0, 0x10 },
{ 0x405c4, 0xeb },
{ 0x405c8, 0x10 },
{ 0x405cc, 0xf0 },
{ 0x40800, 0x0 },
{ 0x40804, 0x151515 },
{ 0x40808, 0x1d1d1d },
{ 0x4080c, 0x232323 },
{ 0x40810, 0x272727 },
{ 0x40814, 0x2b2b2b },
{ 0x40818, 0x2f2f2f },
{ 0x4081c, 0x333333 },
{ 0x40820, 0x363636 },
{ 0x40824, 0x393939 },
{ 0x40828, 0x3b3b3b },
{ 0x4082c, 0x3e3e3e },
{ 0x40830, 0x404040 },
{ 0x40834, 0x434343 },
{ 0x40838, 0x454545 },
{ 0x4083c, 0x474747 },
{ 0x40840, 0x494949 },
{ 0x40844, 0x4b4b4b },
{ 0x40848, 0x4d4d4d },
{ 0x4084c, 0x4f4f4f },
{ 0x40850, 0x515151 },
{ 0x40854, 0x535353 },
{ 0x40858, 0x555555 },
{ 0x4085c, 0x565656 },
{ 0x40860, 0x585858 },
{ 0x40864, 0x5a5a5a },
{ 0x40868, 0x5b5b5b },
{ 0x4086c, 0x5d5d5d },
{ 0x40870, 0x5e5e5e },
{ 0x40874, 0x606060 },
{ 0x40878, 0x616161 },
{ 0x4087c, 0x636363 },
{ 0x40880, 0x646464 },
{ 0x40884, 0x666666 },
{ 0x40888, 0x676767 },
{ 0x4088c, 0x686868 },
{ 0x40890, 0x6a6a6a },
{ 0x40894, 0x6b6b6b },
{ 0x40898, 0x6c6c6c },
{ 0x4089c, 0x6e6e6e },
{ 0x408a0, 0x6f6f6f },
{ 0x408a4, 0x707070 },
{ 0x408a8, 0x717171 },
{ 0x408ac, 0x727272 },
{ 0x408b0, 0x747474 },
{ 0x408b4, 0x757575 },
{ 0x408b8, 0x767676 },
{ 0x408bc, 0x777777 },
{ 0x408c0, 0x787878 },
{ 0x408c4, 0x797979 },
{ 0x408c8, 0x7a7a7a },
{ 0x408cc, 0x7c7c7c },
{ 0x408d0, 0x7d7d7d },
{ 0x408d4, 0x7e7e7e },
{ 0x408d8, 0x7f7f7f },
{ 0x408dc, 0x808080 },
{ 0x408e0, 0x818181 },
{ 0x408e4, 0x828282 },
{ 0x408e8, 0x838383 },
{ 0x408ec, 0x848484 },
{ 0x408f0, 0x858585 },
{ 0x408f4, 0x868686 },
{ 0x408f8, 0x878787 },
{ 0x408fc, 0x888888 },
{ 0x40900, 0x898989 },
{ 0x40904, 0x8a8a8a },
{ 0x40908, 0x8b8b8b },
{ 0x4090c, 0x8c8c8c },
{ 0x40910, 0x8d8d8d },
{ 0x40914, 0x8e8e8e },
{ 0x40918, 0x8f8f8f },
{ 0x4091c, 0x8f8f8f },
{ 0x40920, 0x909090 },
{ 0x40924, 0x919191 },
{ 0x40928, 0x929292 },
{ 0x4092c, 0x939393 },
{ 0x40930, 0x949494 },
{ 0x40934, 0x959595 },
{ 0x40938, 0x969696 },
{ 0x4093c, 0x969696 },
{ 0x40940, 0x979797 },
{ 0x40944, 0x989898 },
{ 0x40948, 0x999999 },
{ 0x4094c, 0x9a9a9a },
{ 0x40950, 0x9b9b9b },
{ 0x40954, 0x9c9c9c },
{ 0x40958, 0x9c9c9c },
{ 0x4095c, 0x9d9d9d },
{ 0x40960, 0x9e9e9e },
{ 0x40964, 0x9f9f9f },
{ 0x40968, 0xa0a0a0 },
{ 0x4096c, 0xa0a0a0 },
{ 0x40970, 0xa1a1a1 },
{ 0x40974, 0xa2a2a2 },
{ 0x40978, 0xa3a3a3 },
{ 0x4097c, 0xa4a4a4 },
{ 0x40980, 0xa4a4a4 },
{ 0x40984, 0xa5a5a5 },
{ 0x40988, 0xa6a6a6 },
{ 0x4098c, 0xa7a7a7 },
{ 0x40990, 0xa7a7a7 },
{ 0x40994, 0xa8a8a8 },
{ 0x40998, 0xa9a9a9 },
{ 0x4099c, 0xaaaaaa },
{ 0x409a0, 0xaaaaaa },
{ 0x409a4, 0xababab },
{ 0x409a8, 0xacacac },
{ 0x409ac, 0xadadad },
{ 0x409b0, 0xadadad },
{ 0x409b4, 0xaeaeae },
{ 0x409b8, 0xafafaf },
{ 0x409bc, 0xafafaf },
{ 0x409c0, 0xb0b0b0 },
{ 0x409c4, 0xb1b1b1 },
{ 0x409c8, 0xb2b2b2 },
{ 0x409cc, 0xb2b2b2 },
{ 0x409d0, 0xb3b3b3 },
{ 0x409d4, 0xb4b4b4 },
{ 0x409d8, 0xb4b4b4 },
{ 0x409dc, 0xb5b5b5 },
{ 0x409e0, 0xb6b6b6 },
{ 0x409e4, 0xb6b6b6 },
{ 0x409e8, 0xb7b7b7 },
{ 0x409ec, 0xb8b8b8 },
{ 0x409f0, 0xb8b8b8 },
{ 0x409f4, 0xb9b9b9 },
{ 0x409f8, 0xbababa },
{ 0x409fc, 0xbababa },
{ 0x40a00, 0xbbbbbb },
{ 0x40a04, 0xbcbcbc },
{ 0x40a08, 0xbcbcbc },
{ 0x40a0c, 0xbdbdbd },
{ 0x40a10, 0xbebebe },
{ 0x40a14, 0xbebebe },
{ 0x40a18, 0xbfbfbf },
{ 0x40a1c, 0xc0c0c0 },
{ 0x40a20, 0xc0c0c0 },
{ 0x40a24, 0xc1c1c1 },
{ 0x40a28, 0xc1c1c1 },
{ 0x40a2c, 0xc2c2c2 },
{ 0x40a30, 0xc3c3c3 },
{ 0x40a34, 0xc3c3c3 },
{ 0x40a38, 0xc4c4c4 },
{ 0x40a3c, 0xc5c5c5 },
{ 0x40a40, 0xc5c5c5 },
{ 0x40a44, 0xc6c6c6 },
{ 0x40a48, 0xc6c6c6 },
{ 0x40a4c, 0xc7c7c7 },
{ 0x40a50, 0xc8c8c8 },
{ 0x40a54, 0xc8c8c8 },
{ 0x40a58, 0xc9c9c9 },
{ 0x40a5c, 0xc9c9c9 },
{ 0x40a60, 0xcacaca },
{ 0x40a64, 0xcbcbcb },
{ 0x40a68, 0xcbcbcb },
{ 0x40a6c, 0xcccccc },
{ 0x40a70, 0xcccccc },
{ 0x40a74, 0xcdcdcd },
{ 0x40a78, 0xcecece },
{ 0x40a7c, 0xcecece },
{ 0x40a80, 0xcfcfcf },
{ 0x40a84, 0xcfcfcf },
{ 0x40a88, 0xd0d0d0 },
{ 0x40a8c, 0xd0d0d0 },
{ 0x40a90, 0xd1d1d1 },
{ 0x40a94, 0xd2d2d2 },
{ 0x40a98, 0xd2d2d2 },
{ 0x40a9c, 0xd3d3d3 },
{ 0x40aa0, 0xd3d3d3 },
{ 0x40aa4, 0xd4d4d4 },
{ 0x40aa8, 0xd4d4d4 },
{ 0x40aac, 0xd5d5d5 },
{ 0x40ab0, 0xd6d6d6 },
{ 0x40ab4, 0xd6d6d6 },
{ 0x40ab8, 0xd7d7d7 },
{ 0x40abc, 0xd7d7d7 },
{ 0x40ac0, 0xd8d8d8 },
{ 0x40ac4, 0xd8d8d8 },
{ 0x40ac8, 0xd9d9d9 },
{ 0x40acc, 0xd9d9d9 },
{ 0x40ad0, 0xdadada },
{ 0x40ad4, 0xdbdbdb },
{ 0x40ad8, 0xdbdbdb },
{ 0x40adc, 0xdcdcdc },
{ 0x40ae0, 0xdcdcdc },
{ 0x40ae4, 0xdddddd },
{ 0x40ae8, 0xdddddd },
{ 0x40aec, 0xdedede },
{ 0x40af0, 0xdedede },
{ 0x40af4, 0xdfdfdf },
{ 0x40af8, 0xdfdfdf },
{ 0x40afc, 0xe0e0e0 },
{ 0x40b00, 0xe0e0e0 },
{ 0x40b04, 0xe1e1e1 },
{ 0x40b08, 0xe1e1e1 },
{ 0x40b0c, 0xe2e2e2 },
{ 0x40b10, 0xe3e3e3 },
{ 0x40b14, 0xe3e3e3 },
{ 0x40b18, 0xe4e4e4 },
{ 0x40b1c, 0xe4e4e4 },
{ 0x40b20, 0xe5e5e5 },
{ 0x40b24, 0xe5e5e5 },
{ 0x40b28, 0xe6e6e6 },
{ 0x40b2c, 0xe6e6e6 },
{ 0x40b30, 0xe7e7e7 },
{ 0x40b34, 0xe7e7e7 },
{ 0x40b38, 0xe8e8e8 },
{ 0x40b3c, 0xe8e8e8 },
{ 0x40b40, 0xe9e9e9 },
{ 0x40b44, 0xe9e9e9 },
{ 0x40b48, 0xeaeaea },
{ 0x40b4c, 0xeaeaea },
{ 0x40b50, 0xebebeb },
{ 0x40b54, 0xebebeb },
{ 0x40b58, 0xececec },
{ 0x40b5c, 0xececec },
{ 0x40b60, 0xededed },
{ 0x40b64, 0xededed },
{ 0x40b68, 0xeeeeee },
{ 0x40b6c, 0xeeeeee },
{ 0x40b70, 0xefefef },
{ 0x40b74, 0xefefef },
{ 0x40b78, 0xf0f0f0 },
{ 0x40b7c, 0xf0f0f0 },
{ 0x40b80, 0xf1f1f1 },
{ 0x40b84, 0xf1f1f1 },
{ 0x40b88, 0xf2f2f2 },
{ 0x40b8c, 0xf2f2f2 },
{ 0x40b90, 0xf2f2f2 },
{ 0x40b94, 0xf3f3f3 },
{ 0x40b98, 0xf3f3f3 },
{ 0x40b9c, 0xf4f4f4 },
{ 0x40ba0, 0xf4f4f4 },
{ 0x40ba4, 0xf5f5f5 },
{ 0x40ba8, 0xf5f5f5 },
{ 0x40bac, 0xf6f6f6 },
{ 0x40bb0, 0xf6f6f6 },
{ 0x40bb4, 0xf7f7f7 },
{ 0x40bb8, 0xf7f7f7 },
{ 0x40bbc, 0xf8f8f8 },
{ 0x40bc0, 0xf8f8f8 },
{ 0x40bc4, 0xf9f9f9 },
{ 0x40bc8, 0xf9f9f9 },
{ 0x40bcc, 0xfafafa },
{ 0x40bd0, 0xfafafa },
{ 0x40bd4, 0xfafafa },
{ 0x40bd8, 0xfbfbfb },
{ 0x40bdc, 0xfbfbfb },
{ 0x40be0, 0xfcfcfc },
{ 0x40be4, 0xfcfcfc },
{ 0x40be8, 0xfdfdfd },
{ 0x40bec, 0xfdfdfd },
{ 0x40bf0, 0xfefefe },
{ 0x40bf4, 0xfefefe },
{ 0x40bf8, 0xffffff },
{ 0x40bfc, 0xffffff },
{ 0x40c00, 0x0 },
{ 0x40c04, 0x0 },
{ 0x40c08, 0x0 },
{ 0x40c0c, 0x0 },
{ 0x40c10, 0x0 },
{ 0x40c14, 0x0 },
{ 0x40c18, 0x0 },
{ 0x40c1c, 0x0 },
{ 0x40c20, 0x0 },
{ 0x40c24, 0x0 },
{ 0x40c28, 0x0 },
{ 0x40c2c, 0x0 },
{ 0x40c30, 0x0 },
{ 0x40c34, 0x0 },
{ 0x40c38, 0x0 },
{ 0x40c3c, 0x0 },
{ 0x40c40, 0x10101 },
{ 0x40c44, 0x10101 },
{ 0x40c48, 0x10101 },
{ 0x40c4c, 0x10101 },
{ 0x40c50, 0x10101 },
{ 0x40c54, 0x10101 },
{ 0x40c58, 0x10101 },
{ 0x40c5c, 0x10101 },
{ 0x40c60, 0x10101 },
{ 0x40c64, 0x10101 },
{ 0x40c68, 0x20202 },
{ 0x40c6c, 0x20202 },
{ 0x40c70, 0x20202 },
{ 0x40c74, 0x20202 },
{ 0x40c78, 0x20202 },
{ 0x40c7c, 0x20202 },
{ 0x40c80, 0x30303 },
{ 0x40c84, 0x30303 },
{ 0x40c88, 0x30303 },
{ 0x40c8c, 0x30303 },
{ 0x40c90, 0x30303 },
{ 0x40c94, 0x40404 },
{ 0x40c98, 0x40404 },
{ 0x40c9c, 0x40404 },
{ 0x40ca0, 0x40404 },
{ 0x40ca4, 0x40404 },
{ 0x40ca8, 0x50505 },
{ 0x40cac, 0x50505 },
{ 0x40cb0, 0x50505 },
{ 0x40cb4, 0x50505 },
{ 0x40cb8, 0x60606 },
{ 0x40cbc, 0x60606 },
{ 0x40cc0, 0x60606 },
{ 0x40cc4, 0x70707 },
{ 0x40cc8, 0x70707 },
{ 0x40ccc, 0x70707 },
{ 0x40cd0, 0x70707 },
{ 0x40cd4, 0x80808 },
{ 0x40cd8, 0x80808 },
{ 0x40cdc, 0x80808 },
{ 0x40ce0, 0x90909 },
{ 0x40ce4, 0x90909 },
{ 0x40ce8, 0xa0a0a },
{ 0x40cec, 0xa0a0a },
{ 0x40cf0, 0xa0a0a },
{ 0x40cf4, 0xb0b0b },
{ 0x40cf8, 0xb0b0b },
{ 0x40cfc, 0xb0b0b },
{ 0x40d00, 0xc0c0c },
{ 0x40d04, 0xc0c0c },
{ 0x40d08, 0xd0d0d },
{ 0x40d0c, 0xd0d0d },
{ 0x40d10, 0xe0e0e },
{ 0x40d14, 0xe0e0e },
{ 0x40d18, 0xe0e0e },
{ 0x40d1c, 0xf0f0f },
{ 0x40d20, 0xf0f0f },
{ 0x40d24, 0x101010 },
{ 0x40d28, 0x101010 },
{ 0x40d2c, 0x111111 },
{ 0x40d30, 0x111111 },
{ 0x40d34, 0x121212 },
{ 0x40d38, 0x121212 },
{ 0x40d3c, 0x131313 },
{ 0x40d40, 0x131313 },
{ 0x40d44, 0x141414 },
{ 0x40d48, 0x151515 },
{ 0x40d4c, 0x151515 },
{ 0x40d50, 0x161616 },
{ 0x40d54, 0x161616 },
{ 0x40d58, 0x171717 },
{ 0x40d5c, 0x171717 },
{ 0x40d60, 0x181818 },
{ 0x40d64, 0x191919 },
{ 0x40d68, 0x191919 },
{ 0x40d6c, 0x1a1a1a },
{ 0x40d70, 0x1b1b1b },
{ 0x40d74, 0x1b1b1b },
{ 0x40d78, 0x1c1c1c },
{ 0x40d7c, 0x1c1c1c },
{ 0x40d80, 0x1d1d1d },
{ 0x40d84, 0x1e1e1e },
{ 0x40d88, 0x1f1f1f },
{ 0x40d8c, 0x1f1f1f },
{ 0x40d90, 0x202020 },
{ 0x40d94, 0x212121 },
{ 0x40d98, 0x212121 },
{ 0x40d9c, 0x222222 },
{ 0x40da0, 0x232323 },
{ 0x40da4, 0x242424 },
{ 0x40da8, 0x242424 },
{ 0x40dac, 0x252525 },
{ 0x40db0, 0x262626 },
{ 0x40db4, 0x272727 },
{ 0x40db8, 0x272727 },
{ 0x40dbc, 0x282828 },
{ 0x40dc0, 0x292929 },
{ 0x40dc4, 0x2a2a2a },
{ 0x40dc8, 0x2b2b2b },
{ 0x40dcc, 0x2c2c2c },
{ 0x40dd0, 0x2c2c2c },
{ 0x40dd4, 0x2d2d2d },
{ 0x40dd8, 0x2e2e2e },
{ 0x40ddc, 0x2f2f2f },
{ 0x40de0, 0x303030 },
{ 0x40de4, 0x313131 },
{ 0x40de8, 0x323232 },
{ 0x40dec, 0x333333 },
{ 0x40df0, 0x333333 },
{ 0x40df4, 0x343434 },
{ 0x40df8, 0x353535 },
{ 0x40dfc, 0x363636 },
{ 0x40e00, 0x373737 },
{ 0x40e04, 0x383838 },
{ 0x40e08, 0x393939 },
{ 0x40e0c, 0x3a3a3a },
{ 0x40e10, 0x3b3b3b },
{ 0x40e14, 0x3c3c3c },
{ 0x40e18, 0x3d3d3d },
{ 0x40e1c, 0x3e3e3e },
{ 0x40e20, 0x3f3f3f },
{ 0x40e24, 0x404040 },
{ 0x40e28, 0x414141 },
{ 0x40e2c, 0x424242 },
{ 0x40e30, 0x434343 },
{ 0x40e34, 0x444444 },
{ 0x40e38, 0x464646 },
{ 0x40e3c, 0x474747 },
{ 0x40e40, 0x484848 },
{ 0x40e44, 0x494949 },
{ 0x40e48, 0x4a4a4a },
{ 0x40e4c, 0x4b4b4b },
{ 0x40e50, 0x4c4c4c },
{ 0x40e54, 0x4d4d4d },
{ 0x40e58, 0x4f4f4f },
{ 0x40e5c, 0x505050 },
{ 0x40e60, 0x515151 },
{ 0x40e64, 0x525252 },
{ 0x40e68, 0x535353 },
{ 0x40e6c, 0x545454 },
{ 0x40e70, 0x565656 },
{ 0x40e74, 0x575757 },
{ 0x40e78, 0x585858 },
{ 0x40e7c, 0x595959 },
{ 0x40e80, 0x5b5b5b },
{ 0x40e84, 0x5c5c5c },
{ 0x40e88, 0x5d5d5d },
{ 0x40e8c, 0x5e5e5e },
{ 0x40e90, 0x606060 },
{ 0x40e94, 0x616161 },
{ 0x40e98, 0x626262 },
{ 0x40e9c, 0x646464 },
{ 0x40ea0, 0x656565 },
{ 0x40ea4, 0x666666 },
{ 0x40ea8, 0x686868 },
{ 0x40eac, 0x696969 },
{ 0x40eb0, 0x6a6a6a },
{ 0x40eb4, 0x6c6c6c },
{ 0x40eb8, 0x6d6d6d },
{ 0x40ebc, 0x6f6f6f },
{ 0x40ec0, 0x707070 },
{ 0x40ec4, 0x717171 },
{ 0x40ec8, 0x737373 },
{ 0x40ecc, 0x747474 },
{ 0x40ed0, 0x767676 },
{ 0x40ed4, 0x777777 },
{ 0x40ed8, 0x797979 },
{ 0x40edc, 0x7a7a7a },
{ 0x40ee0, 0x7c7c7c },
{ 0x40ee4, 0x7d7d7d },
{ 0x40ee8, 0x7f7f7f },
{ 0x40eec, 0x808080 },
{ 0x40ef0, 0x828282 },
{ 0x40ef4, 0x838383 },
{ 0x40ef8, 0x858585 },
{ 0x40efc, 0x868686 },
{ 0x40f00, 0x888888 },
{ 0x40f04, 0x898989 },
{ 0x40f08, 0x8b8b8b },
{ 0x40f0c, 0x8d8d8d },
{ 0x40f10, 0x8e8e8e },
{ 0x40f14, 0x909090 },
{ 0x40f18, 0x919191 },
{ 0x40f1c, 0x939393 },
{ 0x40f20, 0x959595 },
{ 0x40f24, 0x969696 },
{ 0x40f28, 0x989898 },
{ 0x40f2c, 0x9a9a9a },
{ 0x40f30, 0x9b9b9b },
{ 0x40f34, 0x9d9d9d },
{ 0x40f38, 0x9f9f9f },
{ 0x40f3c, 0xa1a1a1 },
{ 0x40f40, 0xa2a2a2 },
{ 0x40f44, 0xa4a4a4 },
{ 0x40f48, 0xa6a6a6 },
{ 0x40f4c, 0xa7a7a7 },
{ 0x40f50, 0xa9a9a9 },
{ 0x40f54, 0xababab },
{ 0x40f58, 0xadadad },
{ 0x40f5c, 0xafafaf },
{ 0x40f60, 0xb0b0b0 },
{ 0x40f64, 0xb2b2b2 },
{ 0x40f68, 0xb4b4b4 },
{ 0x40f6c, 0xb6b6b6 },
{ 0x40f70, 0xb8b8b8 },
{ 0x40f74, 0xbababa },
{ 0x40f78, 0xbbbbbb },
{ 0x40f7c, 0xbdbdbd },
{ 0x40f80, 0xbfbfbf },
{ 0x40f84, 0xc1c1c1 },
{ 0x40f88, 0xc3c3c3 },
{ 0x40f8c, 0xc5c5c5 },
{ 0x40f90, 0xc7c7c7 },
{ 0x40f94, 0xc9c9c9 },
{ 0x40f98, 0xcbcbcb },
{ 0x40f9c, 0xcdcdcd },
{ 0x40fa0, 0xcfcfcf },
{ 0x40fa4, 0xd1d1d1 },
{ 0x40fa8, 0xd3d3d3 },
{ 0x40fac, 0xd5d5d5 },
{ 0x40fb0, 0xd7d7d7 },
{ 0x40fb4, 0xd9d9d9 },
{ 0x40fb8, 0xdbdbdb },
{ 0x40fbc, 0xdddddd },
{ 0x40fc0, 0xdfdfdf },
{ 0x40fc4, 0xe1e1e1 },
{ 0x40fc8, 0xe3e3e3 },
{ 0x40fcc, 0xe5e5e5 },
{ 0x40fd0, 0xe7e7e7 },
{ 0x40fd4, 0xe9e9e9 },
{ 0x40fd8, 0xebebeb },
{ 0x40fdc, 0xeeeeee },
{ 0x40fe0, 0xf0f0f0 },
{ 0x40fe4, 0xf2f2f2 },
{ 0x40fe8, 0xf4f4f4 },
{ 0x40fec, 0xf6f6f6 },
{ 0x40ff0, 0xf8f8f8 },
{ 0x40ff4, 0xfbfbfb },
{ 0x40ff8, 0xfdfdfd },
{ 0x40ffc, 0xffffff },
};

View File

@ -1,627 +0,0 @@
/* drivers/video/msm_fb/mdp_hw.h
*
* Copyright (C) 2007 QUALCOMM Incorporated
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _MDP_HW_H_
#define _MDP_HW_H_
#include <linux/platform_data/video-msm_fb.h>
struct mdp_info {
struct mdp_device mdp_dev;
char * __iomem base;
int irq;
};
struct mdp_blit_req;
struct mdp_device;
int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
struct file *src_file, unsigned long src_start,
unsigned long src_len, struct file *dst_file,
unsigned long dst_start, unsigned long dst_len);
#define mdp_writel(mdp, value, offset) writel(value, mdp->base + offset)
#define mdp_readl(mdp, offset) readl(mdp->base + offset)
#define MDP_SYNC_CONFIG_0 (0x00000)
#define MDP_SYNC_CONFIG_1 (0x00004)
#define MDP_SYNC_CONFIG_2 (0x00008)
#define MDP_SYNC_STATUS_0 (0x0000c)
#define MDP_SYNC_STATUS_1 (0x00010)
#define MDP_SYNC_STATUS_2 (0x00014)
#define MDP_SYNC_THRESH_0 (0x00018)
#define MDP_SYNC_THRESH_1 (0x0001c)
#define MDP_INTR_ENABLE (0x00020)
#define MDP_INTR_STATUS (0x00024)
#define MDP_INTR_CLEAR (0x00028)
#define MDP_DISPLAY0_START (0x00030)
#define MDP_DISPLAY1_START (0x00034)
#define MDP_DISPLAY_STATUS (0x00038)
#define MDP_EBI2_LCD0 (0x0003c)
#define MDP_EBI2_LCD1 (0x00040)
#define MDP_DISPLAY0_ADDR (0x00054)
#define MDP_DISPLAY1_ADDR (0x00058)
#define MDP_EBI2_PORTMAP_MODE (0x0005c)
#define MDP_MODE (0x00060)
#define MDP_TV_OUT_STATUS (0x00064)
#define MDP_HW_VERSION (0x00070)
#define MDP_SW_RESET (0x00074)
#define MDP_AXI_ERROR_MASTER_STOP (0x00078)
#define MDP_SEL_CLK_OR_HCLK_TEST_BUS (0x0007c)
#define MDP_PRIMARY_VSYNC_OUT_CTRL (0x00080)
#define MDP_SECONDARY_VSYNC_OUT_CTRL (0x00084)
#define MDP_EXTERNAL_VSYNC_OUT_CTRL (0x00088)
#define MDP_VSYNC_CTRL (0x0008c)
#define MDP_CGC_EN (0x00100)
#define MDP_CMD_STATUS (0x10008)
#define MDP_PROFILE_EN (0x10010)
#define MDP_PROFILE_COUNT (0x10014)
#define MDP_DMA_START (0x10044)
#define MDP_FULL_BYPASS_WORD0 (0x10100)
#define MDP_FULL_BYPASS_WORD1 (0x10104)
#define MDP_COMMAND_CONFIG (0x10104)
#define MDP_FULL_BYPASS_WORD2 (0x10108)
#define MDP_FULL_BYPASS_WORD3 (0x1010c)
#define MDP_FULL_BYPASS_WORD4 (0x10110)
#define MDP_FULL_BYPASS_WORD6 (0x10118)
#define MDP_FULL_BYPASS_WORD7 (0x1011c)
#define MDP_FULL_BYPASS_WORD8 (0x10120)
#define MDP_FULL_BYPASS_WORD9 (0x10124)
#define MDP_PPP_SOURCE_CONFIG (0x10124)
#define MDP_FULL_BYPASS_WORD10 (0x10128)
#define MDP_FULL_BYPASS_WORD11 (0x1012c)
#define MDP_FULL_BYPASS_WORD12 (0x10130)
#define MDP_FULL_BYPASS_WORD13 (0x10134)
#define MDP_FULL_BYPASS_WORD14 (0x10138)
#define MDP_PPP_OPERATION_CONFIG (0x10138)
#define MDP_FULL_BYPASS_WORD15 (0x1013c)
#define MDP_FULL_BYPASS_WORD16 (0x10140)
#define MDP_FULL_BYPASS_WORD17 (0x10144)
#define MDP_FULL_BYPASS_WORD18 (0x10148)
#define MDP_FULL_BYPASS_WORD19 (0x1014c)
#define MDP_FULL_BYPASS_WORD20 (0x10150)
#define MDP_PPP_DESTINATION_CONFIG (0x10150)
#define MDP_FULL_BYPASS_WORD21 (0x10154)
#define MDP_FULL_BYPASS_WORD22 (0x10158)
#define MDP_FULL_BYPASS_WORD23 (0x1015c)
#define MDP_FULL_BYPASS_WORD24 (0x10160)
#define MDP_FULL_BYPASS_WORD25 (0x10164)
#define MDP_FULL_BYPASS_WORD26 (0x10168)
#define MDP_FULL_BYPASS_WORD27 (0x1016c)
#define MDP_FULL_BYPASS_WORD29 (0x10174)
#define MDP_FULL_BYPASS_WORD30 (0x10178)
#define MDP_FULL_BYPASS_WORD31 (0x1017c)
#define MDP_FULL_BYPASS_WORD32 (0x10180)
#define MDP_DMA_CONFIG (0x10180)
#define MDP_FULL_BYPASS_WORD33 (0x10184)
#define MDP_FULL_BYPASS_WORD34 (0x10188)
#define MDP_FULL_BYPASS_WORD35 (0x1018c)
#define MDP_FULL_BYPASS_WORD37 (0x10194)
#define MDP_FULL_BYPASS_WORD39 (0x1019c)
#define MDP_FULL_BYPASS_WORD40 (0x101a0)
#define MDP_FULL_BYPASS_WORD41 (0x101a4)
#define MDP_FULL_BYPASS_WORD43 (0x101ac)
#define MDP_FULL_BYPASS_WORD46 (0x101b8)
#define MDP_FULL_BYPASS_WORD47 (0x101bc)
#define MDP_FULL_BYPASS_WORD48 (0x101c0)
#define MDP_FULL_BYPASS_WORD49 (0x101c4)
#define MDP_FULL_BYPASS_WORD50 (0x101c8)
#define MDP_FULL_BYPASS_WORD51 (0x101cc)
#define MDP_FULL_BYPASS_WORD52 (0x101d0)
#define MDP_FULL_BYPASS_WORD53 (0x101d4)
#define MDP_FULL_BYPASS_WORD54 (0x101d8)
#define MDP_FULL_BYPASS_WORD55 (0x101dc)
#define MDP_FULL_BYPASS_WORD56 (0x101e0)
#define MDP_FULL_BYPASS_WORD57 (0x101e4)
#define MDP_FULL_BYPASS_WORD58 (0x101e8)
#define MDP_FULL_BYPASS_WORD59 (0x101ec)
#define MDP_FULL_BYPASS_WORD60 (0x101f0)
#define MDP_VSYNC_THRESHOLD (0x101f0)
#define MDP_FULL_BYPASS_WORD61 (0x101f4)
#define MDP_FULL_BYPASS_WORD62 (0x101f8)
#define MDP_FULL_BYPASS_WORD63 (0x101fc)
#define MDP_TFETCH_TEST_MODE (0x20004)
#define MDP_TFETCH_STATUS (0x20008)
#define MDP_TFETCH_TILE_COUNT (0x20010)
#define MDP_TFETCH_FETCH_COUNT (0x20014)
#define MDP_TFETCH_CONSTANT_COLOR (0x20040)
#define MDP_CSC_BYPASS (0x40004)
#define MDP_SCALE_COEFF_LSB (0x5fffc)
#define MDP_TV_OUT_CTL (0xc0000)
#define MDP_TV_OUT_FIR_COEFF (0xc0004)
#define MDP_TV_OUT_BUF_ADDR (0xc0008)
#define MDP_TV_OUT_CC_DATA (0xc000c)
#define MDP_TV_OUT_SOBEL (0xc0010)
#define MDP_TV_OUT_Y_CLAMP (0xc0018)
#define MDP_TV_OUT_CB_CLAMP (0xc001c)
#define MDP_TV_OUT_CR_CLAMP (0xc0020)
#define MDP_TEST_MODE_CLK (0xd0000)
#define MDP_TEST_MISR_RESET_CLK (0xd0004)
#define MDP_TEST_EXPORT_MISR_CLK (0xd0008)
#define MDP_TEST_MISR_CURR_VAL_CLK (0xd000c)
#define MDP_TEST_MODE_HCLK (0xd0100)
#define MDP_TEST_MISR_RESET_HCLK (0xd0104)
#define MDP_TEST_EXPORT_MISR_HCLK (0xd0108)
#define MDP_TEST_MISR_CURR_VAL_HCLK (0xd010c)
#define MDP_TEST_MODE_DCLK (0xd0200)
#define MDP_TEST_MISR_RESET_DCLK (0xd0204)
#define MDP_TEST_EXPORT_MISR_DCLK (0xd0208)
#define MDP_TEST_MISR_CURR_VAL_DCLK (0xd020c)
#define MDP_TEST_CAPTURED_DCLK (0xd0210)
#define MDP_TEST_MISR_CAPT_VAL_DCLK (0xd0214)
#define MDP_LCDC_CTL (0xe0000)
#define MDP_LCDC_HSYNC_CTL (0xe0004)
#define MDP_LCDC_VSYNC_CTL (0xe0008)
#define MDP_LCDC_ACTIVE_HCTL (0xe000c)
#define MDP_LCDC_ACTIVE_VCTL (0xe0010)
#define MDP_LCDC_BORDER_CLR (0xe0014)
#define MDP_LCDC_H_BLANK (0xe0018)
#define MDP_LCDC_V_BLANK (0xe001c)
#define MDP_LCDC_UNDERFLOW_CLR (0xe0020)
#define MDP_LCDC_HSYNC_SKEW (0xe0024)
#define MDP_LCDC_TEST_CTL (0xe0028)
#define MDP_LCDC_LINE_IRQ (0xe002c)
#define MDP_LCDC_CTL_POLARITY (0xe0030)
#define MDP_LCDC_DMA_CONFIG (0xe1000)
#define MDP_LCDC_DMA_SIZE (0xe1004)
#define MDP_LCDC_DMA_IBUF_ADDR (0xe1008)
#define MDP_LCDC_DMA_IBUF_Y_STRIDE (0xe100c)
#define MDP_DMA2_TERM 0x1
#define MDP_DMA3_TERM 0x2
#define MDP_PPP_TERM 0x3
/* MDP_INTR_ENABLE */
#define DL0_ROI_DONE (1<<0)
#define DL1_ROI_DONE (1<<1)
#define DL0_DMA2_TERM_DONE (1<<2)
#define DL1_DMA2_TERM_DONE (1<<3)
#define DL0_PPP_TERM_DONE (1<<4)
#define DL1_PPP_TERM_DONE (1<<5)
#define TV_OUT_DMA3_DONE (1<<6)
#define TV_ENC_UNDERRUN (1<<7)
#define DL0_FETCH_DONE (1<<11)
#define DL1_FETCH_DONE (1<<12)
#define MDP_PPP_BUSY_STATUS (DL0_ROI_DONE| \
DL1_ROI_DONE| \
DL0_PPP_TERM_DONE| \
DL1_PPP_TERM_DONE)
#define MDP_ANY_INTR_MASK (DL0_ROI_DONE| \
DL1_ROI_DONE| \
DL0_DMA2_TERM_DONE| \
DL1_DMA2_TERM_DONE| \
DL0_PPP_TERM_DONE| \
DL1_PPP_TERM_DONE| \
DL0_FETCH_DONE| \
DL1_FETCH_DONE| \
TV_ENC_UNDERRUN)
#define MDP_TOP_LUMA 16
#define MDP_TOP_CHROMA 0
#define MDP_BOTTOM_LUMA 19
#define MDP_BOTTOM_CHROMA 3
#define MDP_LEFT_LUMA 22
#define MDP_LEFT_CHROMA 6
#define MDP_RIGHT_LUMA 25
#define MDP_RIGHT_CHROMA 9
#define CLR_G 0x0
#define CLR_B 0x1
#define CLR_R 0x2
#define CLR_ALPHA 0x3
#define CLR_Y CLR_G
#define CLR_CB CLR_B
#define CLR_CR CLR_R
/* from lsb to msb */
#define MDP_GET_PACK_PATTERN(a, x, y, z, bit) \
(((a)<<(bit*3))|((x)<<(bit*2))|((y)<<bit)|(z))
/* MDP_SYNC_CONFIG_0/1/2 */
#define MDP_SYNCFG_HGT_LOC 22
#define MDP_SYNCFG_VSYNC_EXT_EN (1<<21)
#define MDP_SYNCFG_VSYNC_INT_EN (1<<20)
/* MDP_SYNC_THRESH_0 */
#define MDP_PRIM_BELOW_LOC 0
#define MDP_PRIM_ABOVE_LOC 8
/* MDP_{PRIMARY,SECONDARY,EXTERNAL}_VSYNC_OUT_CRL */
#define VSYNC_PULSE_EN (1<<31)
#define VSYNC_PULSE_INV (1<<30)
/* MDP_VSYNC_CTRL */
#define DISP0_VSYNC_MAP_VSYNC0 0
#define DISP0_VSYNC_MAP_VSYNC1 (1<<0)
#define DISP0_VSYNC_MAP_VSYNC2 ((1<<0)|(1<<1))
#define DISP1_VSYNC_MAP_VSYNC0 0
#define DISP1_VSYNC_MAP_VSYNC1 (1<<2)
#define DISP1_VSYNC_MAP_VSYNC2 ((1<<2)|(1<<3))
#define PRIMARY_LCD_SYNC_EN (1<<4)
#define PRIMARY_LCD_SYNC_DISABLE 0
#define SECONDARY_LCD_SYNC_EN (1<<5)
#define SECONDARY_LCD_SYNC_DISABLE 0
#define EXTERNAL_LCD_SYNC_EN (1<<6)
#define EXTERNAL_LCD_SYNC_DISABLE 0
/* MDP_VSYNC_THRESHOLD / MDP_FULL_BYPASS_WORD60 */
#define VSYNC_THRESHOLD_ABOVE_LOC 0
#define VSYNC_THRESHOLD_BELOW_LOC 16
#define VSYNC_ANTI_TEAR_EN (1<<31)
/* MDP_COMMAND_CONFIG / MDP_FULL_BYPASS_WORD1 */
#define MDP_CMD_DBGBUS_EN (1<<0)
/* MDP_PPP_SOURCE_CONFIG / MDP_FULL_BYPASS_WORD9&53 */
#define PPP_SRC_C0G_8BIT ((1<<1)|(1<<0))
#define PPP_SRC_C1B_8BIT ((1<<3)|(1<<2))
#define PPP_SRC_C2R_8BIT ((1<<5)|(1<<4))
#define PPP_SRC_C3A_8BIT ((1<<7)|(1<<6))
#define PPP_SRC_C0G_6BIT (1<<1)
#define PPP_SRC_C1B_6BIT (1<<3)
#define PPP_SRC_C2R_6BIT (1<<5)
#define PPP_SRC_C0G_5BIT (1<<0)
#define PPP_SRC_C1B_5BIT (1<<2)
#define PPP_SRC_C2R_5BIT (1<<4)
#define PPP_SRC_C3ALPHA_EN (1<<8)
#define PPP_SRC_BPP_1BYTES 0
#define PPP_SRC_BPP_2BYTES (1<<9)
#define PPP_SRC_BPP_3BYTES (1<<10)
#define PPP_SRC_BPP_4BYTES ((1<<10)|(1<<9))
#define PPP_SRC_BPP_ROI_ODD_X (1<<11)
#define PPP_SRC_BPP_ROI_ODD_Y (1<<12)
#define PPP_SRC_INTERLVD_2COMPONENTS (1<<13)
#define PPP_SRC_INTERLVD_3COMPONENTS (1<<14)
#define PPP_SRC_INTERLVD_4COMPONENTS ((1<<14)|(1<<13))
/* RGB666 unpack format
** TIGHT means R6+G6+B6 together
** LOOSE means R6+2 +G6+2+ B6+2 (with MSB)
** or 2+R6 +2+G6 +2+B6 (with LSB)
*/
#define PPP_SRC_PACK_TIGHT (1<<17)
#define PPP_SRC_PACK_LOOSE 0
#define PPP_SRC_PACK_ALIGN_LSB 0
#define PPP_SRC_PACK_ALIGN_MSB (1<<18)
#define PPP_SRC_PLANE_INTERLVD 0
#define PPP_SRC_PLANE_PSEUDOPLNR (1<<20)
#define PPP_SRC_WMV9_MODE (1<<21)
/* MDP_PPP_OPERATION_CONFIG / MDP_FULL_BYPASS_WORD14 */
#define PPP_OP_SCALE_X_ON (1<<0)
#define PPP_OP_SCALE_Y_ON (1<<1)
#define PPP_OP_CONVERT_RGB2YCBCR 0
#define PPP_OP_CONVERT_YCBCR2RGB (1<<2)
#define PPP_OP_CONVERT_ON (1<<3)
#define PPP_OP_CONVERT_MATRIX_PRIMARY 0
#define PPP_OP_CONVERT_MATRIX_SECONDARY (1<<4)
#define PPP_OP_LUT_C0_ON (1<<5)
#define PPP_OP_LUT_C1_ON (1<<6)
#define PPP_OP_LUT_C2_ON (1<<7)
/* rotate or blend enable */
#define PPP_OP_ROT_ON (1<<8)
#define PPP_OP_ROT_90 (1<<9)
#define PPP_OP_FLIP_LR (1<<10)
#define PPP_OP_FLIP_UD (1<<11)
#define PPP_OP_BLEND_ON (1<<12)
#define PPP_OP_BLEND_SRCPIXEL_ALPHA 0
#define PPP_OP_BLEND_DSTPIXEL_ALPHA (1<<13)
#define PPP_OP_BLEND_CONSTANT_ALPHA (1<<14)
#define PPP_OP_BLEND_SRCPIXEL_TRANSP ((1<<13)|(1<<14))
#define PPP_OP_BLEND_ALPHA_BLEND_NORMAL 0
#define PPP_OP_BLEND_ALPHA_BLEND_REVERSE (1<<15)
#define PPP_OP_DITHER_EN (1<<16)
#define PPP_OP_COLOR_SPACE_RGB 0
#define PPP_OP_COLOR_SPACE_YCBCR (1<<17)
#define PPP_OP_SRC_CHROMA_RGB 0
#define PPP_OP_SRC_CHROMA_H2V1 (1<<18)
#define PPP_OP_SRC_CHROMA_H1V2 (1<<19)
#define PPP_OP_SRC_CHROMA_420 ((1<<18)|(1<<19))
#define PPP_OP_SRC_CHROMA_COSITE 0
#define PPP_OP_SRC_CHROMA_OFFSITE (1<<20)
#define PPP_OP_DST_CHROMA_RGB 0
#define PPP_OP_DST_CHROMA_H2V1 (1<<21)
#define PPP_OP_DST_CHROMA_H1V2 (1<<22)
#define PPP_OP_DST_CHROMA_420 ((1<<21)|(1<<22))
#define PPP_OP_DST_CHROMA_COSITE 0
#define PPP_OP_DST_CHROMA_OFFSITE (1<<23)
#define PPP_BLEND_ALPHA_TRANSP (1<<24)
#define PPP_OP_BG_CHROMA_RGB 0
#define PPP_OP_BG_CHROMA_H2V1 (1<<25)
#define PPP_OP_BG_CHROMA_H1V2 (1<<26)
#define PPP_OP_BG_CHROMA_420 ((1<<25)|(1<<26))
#define PPP_OP_BG_CHROMA_SITE_COSITE 0
#define PPP_OP_BG_CHROMA_SITE_OFFSITE (1<<27)
/* MDP_PPP_DESTINATION_CONFIG / MDP_FULL_BYPASS_WORD20 */
#define PPP_DST_C0G_8BIT ((1<<0)|(1<<1))
#define PPP_DST_C1B_8BIT ((1<<3)|(1<<2))
#define PPP_DST_C2R_8BIT ((1<<5)|(1<<4))
#define PPP_DST_C3A_8BIT ((1<<7)|(1<<6))
#define PPP_DST_C0G_6BIT (1<<1)
#define PPP_DST_C1B_6BIT (1<<3)
#define PPP_DST_C2R_6BIT (1<<5)
#define PPP_DST_C0G_5BIT (1<<0)
#define PPP_DST_C1B_5BIT (1<<2)
#define PPP_DST_C2R_5BIT (1<<4)
#define PPP_DST_C3A_8BIT ((1<<7)|(1<<6))
#define PPP_DST_C3ALPHA_EN (1<<8)
#define PPP_DST_INTERLVD_2COMPONENTS (1<<9)
#define PPP_DST_INTERLVD_3COMPONENTS (1<<10)
#define PPP_DST_INTERLVD_4COMPONENTS ((1<<10)|(1<<9))
#define PPP_DST_INTERLVD_6COMPONENTS ((1<<11)|(1<<9))
#define PPP_DST_PACK_LOOSE 0
#define PPP_DST_PACK_TIGHT (1<<13)
#define PPP_DST_PACK_ALIGN_LSB 0
#define PPP_DST_PACK_ALIGN_MSB (1<<14)
#define PPP_DST_OUT_SEL_AXI 0
#define PPP_DST_OUT_SEL_MDDI (1<<15)
#define PPP_DST_BPP_2BYTES (1<<16)
#define PPP_DST_BPP_3BYTES (1<<17)
#define PPP_DST_BPP_4BYTES ((1<<17)|(1<<16))
#define PPP_DST_PLANE_INTERLVD 0
#define PPP_DST_PLANE_PLANAR (1<<18)
#define PPP_DST_PLANE_PSEUDOPLNR (1<<19)
#define PPP_DST_TO_TV (1<<20)
#define PPP_DST_MDDI_PRIMARY 0
#define PPP_DST_MDDI_SECONDARY (1<<21)
#define PPP_DST_MDDI_EXTERNAL (1<<22)
/* image configurations by image type */
#define PPP_CFG_MDP_RGB_565(dir) (PPP_##dir##_C2R_5BIT | \
PPP_##dir##_C0G_6BIT | \
PPP_##dir##_C1B_5BIT | \
PPP_##dir##_BPP_2BYTES | \
PPP_##dir##_INTERLVD_3COMPONENTS | \
PPP_##dir##_PACK_TIGHT | \
PPP_##dir##_PACK_ALIGN_LSB | \
PPP_##dir##_PLANE_INTERLVD)
#define PPP_CFG_MDP_RGB_888(dir) (PPP_##dir##_C2R_8BIT | \
PPP_##dir##_C0G_8BIT | \
PPP_##dir##_C1B_8BIT | \
PPP_##dir##_BPP_3BYTES | \
PPP_##dir##_INTERLVD_3COMPONENTS | \
PPP_##dir##_PACK_TIGHT | \
PPP_##dir##_PACK_ALIGN_LSB | \
PPP_##dir##_PLANE_INTERLVD)
#define PPP_CFG_MDP_ARGB_8888(dir) (PPP_##dir##_C2R_8BIT | \
PPP_##dir##_C0G_8BIT | \
PPP_##dir##_C1B_8BIT | \
PPP_##dir##_C3A_8BIT | \
PPP_##dir##_C3ALPHA_EN | \
PPP_##dir##_BPP_4BYTES | \
PPP_##dir##_INTERLVD_4COMPONENTS | \
PPP_##dir##_PACK_TIGHT | \
PPP_##dir##_PACK_ALIGN_LSB | \
PPP_##dir##_PLANE_INTERLVD)
#define PPP_CFG_MDP_XRGB_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
#define PPP_CFG_MDP_RGBA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
#define PPP_CFG_MDP_BGRA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
#define PPP_CFG_MDP_RGBX_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
#define PPP_CFG_MDP_Y_CBCR_H2V2(dir) (PPP_##dir##_C2R_8BIT | \
PPP_##dir##_C0G_8BIT | \
PPP_##dir##_C1B_8BIT | \
PPP_##dir##_C3A_8BIT | \
PPP_##dir##_BPP_2BYTES | \
PPP_##dir##_INTERLVD_2COMPONENTS | \
PPP_##dir##_PACK_TIGHT | \
PPP_##dir##_PACK_ALIGN_LSB | \
PPP_##dir##_PLANE_PSEUDOPLNR)
#define PPP_CFG_MDP_Y_CRCB_H2V2(dir) PPP_CFG_MDP_Y_CBCR_H2V2(dir)
#define PPP_CFG_MDP_YCRYCB_H2V1(dir) (PPP_##dir##_C2R_8BIT | \
PPP_##dir##_C0G_8BIT | \
PPP_##dir##_C1B_8BIT | \
PPP_##dir##_C3A_8BIT | \
PPP_##dir##_BPP_2BYTES | \
PPP_##dir##_INTERLVD_4COMPONENTS | \
PPP_##dir##_PACK_TIGHT | \
PPP_##dir##_PACK_ALIGN_LSB |\
PPP_##dir##_PLANE_INTERLVD)
#define PPP_CFG_MDP_Y_CBCR_H2V1(dir) (PPP_##dir##_C2R_8BIT | \
PPP_##dir##_C0G_8BIT | \
PPP_##dir##_C1B_8BIT | \
PPP_##dir##_C3A_8BIT | \
PPP_##dir##_BPP_2BYTES | \
PPP_##dir##_INTERLVD_2COMPONENTS | \
PPP_##dir##_PACK_TIGHT | \
PPP_##dir##_PACK_ALIGN_LSB | \
PPP_##dir##_PLANE_PSEUDOPLNR)
#define PPP_CFG_MDP_Y_CRCB_H2V1(dir) PPP_CFG_MDP_Y_CBCR_H2V1(dir)
#define PPP_PACK_PATTERN_MDP_RGB_565 \
MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8)
#define PPP_PACK_PATTERN_MDP_RGB_888 PPP_PACK_PATTERN_MDP_RGB_565
#define PPP_PACK_PATTERN_MDP_XRGB_8888 \
MDP_GET_PACK_PATTERN(CLR_B, CLR_G, CLR_R, CLR_ALPHA, 8)
#define PPP_PACK_PATTERN_MDP_ARGB_8888 PPP_PACK_PATTERN_MDP_XRGB_8888
#define PPP_PACK_PATTERN_MDP_RGBA_8888 \
MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, 8)
#define PPP_PACK_PATTERN_MDP_BGRA_8888 \
MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, 8)
#define PPP_PACK_PATTERN_MDP_RGBX_8888 \
MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, 8)
#define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1 \
MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8)
#define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V2 PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1
#define PPP_PACK_PATTERN_MDP_Y_CRCB_H2V1 \
MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8)
#define PPP_PACK_PATTERN_MDP_Y_CRCB_H2V2 PPP_PACK_PATTERN_MDP_Y_CRCB_H2V1
#define PPP_PACK_PATTERN_MDP_YCRYCB_H2V1 \
MDP_GET_PACK_PATTERN(CLR_Y, CLR_R, CLR_Y, CLR_B, 8)
#define PPP_CHROMA_SAMP_MDP_RGB_565(dir) PPP_OP_##dir##_CHROMA_RGB
#define PPP_CHROMA_SAMP_MDP_RGB_888(dir) PPP_OP_##dir##_CHROMA_RGB
#define PPP_CHROMA_SAMP_MDP_XRGB_8888(dir) PPP_OP_##dir##_CHROMA_RGB
#define PPP_CHROMA_SAMP_MDP_ARGB_8888(dir) PPP_OP_##dir##_CHROMA_RGB
#define PPP_CHROMA_SAMP_MDP_RGBA_8888(dir) PPP_OP_##dir##_CHROMA_RGB
#define PPP_CHROMA_SAMP_MDP_BGRA_8888(dir) PPP_OP_##dir##_CHROMA_RGB
#define PPP_CHROMA_SAMP_MDP_RGBX_8888(dir) PPP_OP_##dir##_CHROMA_RGB
#define PPP_CHROMA_SAMP_MDP_Y_CBCR_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1
#define PPP_CHROMA_SAMP_MDP_Y_CBCR_H2V2(dir) PPP_OP_##dir##_CHROMA_420
#define PPP_CHROMA_SAMP_MDP_Y_CRCB_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1
#define PPP_CHROMA_SAMP_MDP_Y_CRCB_H2V2(dir) PPP_OP_##dir##_CHROMA_420
#define PPP_CHROMA_SAMP_MDP_YCRYCB_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1
/* Helpful array generation macros */
#define PPP_ARRAY0(name) \
[MDP_RGB_565] = PPP_##name##_MDP_RGB_565,\
[MDP_RGB_888] = PPP_##name##_MDP_RGB_888,\
[MDP_XRGB_8888] = PPP_##name##_MDP_XRGB_8888,\
[MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888,\
[MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888,\
[MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888,\
[MDP_RGBX_8888] = PPP_##name##_MDP_RGBX_8888,\
[MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1,\
[MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2,\
[MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1,\
[MDP_Y_CRCB_H2V2] = PPP_##name##_MDP_Y_CRCB_H2V2,\
[MDP_YCRYCB_H2V1] = PPP_##name##_MDP_YCRYCB_H2V1
#define PPP_ARRAY1(name, dir) \
[MDP_RGB_565] = PPP_##name##_MDP_RGB_565(dir),\
[MDP_RGB_888] = PPP_##name##_MDP_RGB_888(dir),\
[MDP_XRGB_8888] = PPP_##name##_MDP_XRGB_8888(dir),\
[MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888(dir),\
[MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888(dir),\
[MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888(dir),\
[MDP_RGBX_8888] = PPP_##name##_MDP_RGBX_8888(dir),\
[MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1(dir),\
[MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2(dir),\
[MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1(dir),\
[MDP_Y_CRCB_H2V2] = PPP_##name##_MDP_Y_CRCB_H2V2(dir),\
[MDP_YCRYCB_H2V1] = PPP_##name##_MDP_YCRYCB_H2V1(dir)
#define IS_YCRCB(img) ((img == MDP_Y_CRCB_H2V2) | (img == MDP_Y_CBCR_H2V2) | \
(img == MDP_Y_CRCB_H2V1) | (img == MDP_Y_CBCR_H2V1) | \
(img == MDP_YCRYCB_H2V1))
#define IS_RGB(img) ((img == MDP_RGB_565) | (img == MDP_RGB_888) | \
(img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \
(img == MDP_XRGB_8888) | (img == MDP_BGRA_8888) | \
(img == MDP_RGBX_8888))
#define HAS_ALPHA(img) ((img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \
(img == MDP_BGRA_8888))
#define IS_PSEUDOPLNR(img) ((img == MDP_Y_CRCB_H2V2) | \
(img == MDP_Y_CBCR_H2V2) | \
(img == MDP_Y_CRCB_H2V1) | \
(img == MDP_Y_CBCR_H2V1))
/* Mappings from addr to purpose */
#define PPP_ADDR_SRC_ROI MDP_FULL_BYPASS_WORD2
#define PPP_ADDR_SRC0 MDP_FULL_BYPASS_WORD3
#define PPP_ADDR_SRC1 MDP_FULL_BYPASS_WORD4
#define PPP_ADDR_SRC_YSTRIDE MDP_FULL_BYPASS_WORD7
#define PPP_ADDR_SRC_CFG MDP_FULL_BYPASS_WORD9
#define PPP_ADDR_SRC_PACK_PATTERN MDP_FULL_BYPASS_WORD10
#define PPP_ADDR_OPERATION MDP_FULL_BYPASS_WORD14
#define PPP_ADDR_PHASEX_INIT MDP_FULL_BYPASS_WORD15
#define PPP_ADDR_PHASEY_INIT MDP_FULL_BYPASS_WORD16
#define PPP_ADDR_PHASEX_STEP MDP_FULL_BYPASS_WORD17
#define PPP_ADDR_PHASEY_STEP MDP_FULL_BYPASS_WORD18
#define PPP_ADDR_ALPHA_TRANSP MDP_FULL_BYPASS_WORD19
#define PPP_ADDR_DST_CFG MDP_FULL_BYPASS_WORD20
#define PPP_ADDR_DST_PACK_PATTERN MDP_FULL_BYPASS_WORD21
#define PPP_ADDR_DST_ROI MDP_FULL_BYPASS_WORD25
#define PPP_ADDR_DST0 MDP_FULL_BYPASS_WORD26
#define PPP_ADDR_DST1 MDP_FULL_BYPASS_WORD27
#define PPP_ADDR_DST_YSTRIDE MDP_FULL_BYPASS_WORD30
#define PPP_ADDR_EDGE MDP_FULL_BYPASS_WORD46
#define PPP_ADDR_BG0 MDP_FULL_BYPASS_WORD48
#define PPP_ADDR_BG1 MDP_FULL_BYPASS_WORD49
#define PPP_ADDR_BG_YSTRIDE MDP_FULL_BYPASS_WORD51
#define PPP_ADDR_BG_CFG MDP_FULL_BYPASS_WORD53
#define PPP_ADDR_BG_PACK_PATTERN MDP_FULL_BYPASS_WORD54
/* MDP_DMA_CONFIG / MDP_FULL_BYPASS_WORD32 */
#define DMA_DSTC0G_6BITS (1<<1)
#define DMA_DSTC1B_6BITS (1<<3)
#define DMA_DSTC2R_6BITS (1<<5)
#define DMA_DSTC0G_5BITS (1<<0)
#define DMA_DSTC1B_5BITS (1<<2)
#define DMA_DSTC2R_5BITS (1<<4)
#define DMA_PACK_TIGHT (1<<6)
#define DMA_PACK_LOOSE 0
#define DMA_PACK_ALIGN_LSB 0
#define DMA_PACK_ALIGN_MSB (1<<7)
#define DMA_PACK_PATTERN_RGB \
(MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 2)<<8)
#define DMA_OUT_SEL_AHB 0
#define DMA_OUT_SEL_MDDI (1<<14)
#define DMA_AHBM_LCD_SEL_PRIMARY 0
#define DMA_AHBM_LCD_SEL_SECONDARY (1<<15)
#define DMA_IBUF_C3ALPHA_EN (1<<16)
#define DMA_DITHER_EN (1<<17)
#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0
#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY (1<<18)
#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL (1<<19)
#define DMA_IBUF_FORMAT_RGB565 (1<<20)
#define DMA_IBUF_FORMAT_RGB888_OR_ARGB8888 0
#define DMA_IBUF_NONCONTIGUOUS (1<<21)
/* MDDI REGISTER ? */
#define MDDI_VDO_PACKET_DESC 0x5666
#define MDDI_VDO_PACKET_PRIM 0xC3
#define MDDI_VDO_PACKET_SECD 0xC0
#endif

View File

@ -1,731 +0,0 @@
/* drivers/video/msm/mdp_ppp.c
*
* Copyright (C) 2007 QUALCOMM Incorporated
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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/fb.h>
#include <linux/file.h>
#include <linux/delay.h>
#include <linux/msm_mdp.h>
#include <linux/platform_data/video-msm_fb.h>
#include "mdp_hw.h"
#include "mdp_scale_tables.h"
#define DLOG(x...) do {} while (0)
#define MDP_DOWNSCALE_BLUR (MDP_DOWNSCALE_MAX + 1)
static int downscale_y_table = MDP_DOWNSCALE_MAX;
static int downscale_x_table = MDP_DOWNSCALE_MAX;
struct mdp_regs {
uint32_t src0;
uint32_t src1;
uint32_t dst0;
uint32_t dst1;
uint32_t src_cfg;
uint32_t dst_cfg;
uint32_t src_pack;
uint32_t dst_pack;
uint32_t src_rect;
uint32_t dst_rect;
uint32_t src_ystride;
uint32_t dst_ystride;
uint32_t op;
uint32_t src_bpp;
uint32_t dst_bpp;
uint32_t edge;
uint32_t phasex_init;
uint32_t phasey_init;
uint32_t phasex_step;
uint32_t phasey_step;
};
static uint32_t pack_pattern[] = {
PPP_ARRAY0(PACK_PATTERN)
};
static uint32_t src_img_cfg[] = {
PPP_ARRAY1(CFG, SRC)
};
static uint32_t dst_img_cfg[] = {
PPP_ARRAY1(CFG, DST)
};
static uint32_t bytes_per_pixel[] = {
[MDP_RGB_565] = 2,
[MDP_RGB_888] = 3,
[MDP_XRGB_8888] = 4,
[MDP_ARGB_8888] = 4,
[MDP_RGBA_8888] = 4,
[MDP_BGRA_8888] = 4,
[MDP_RGBX_8888] = 4,
[MDP_Y_CBCR_H2V1] = 1,
[MDP_Y_CBCR_H2V2] = 1,
[MDP_Y_CRCB_H2V1] = 1,
[MDP_Y_CRCB_H2V2] = 1,
[MDP_YCRYCB_H2V1] = 2
};
static uint32_t dst_op_chroma[] = {
PPP_ARRAY1(CHROMA_SAMP, DST)
};
static uint32_t src_op_chroma[] = {
PPP_ARRAY1(CHROMA_SAMP, SRC)
};
static uint32_t bg_op_chroma[] = {
PPP_ARRAY1(CHROMA_SAMP, BG)
};
static void rotate_dst_addr_x(struct mdp_blit_req *req, struct mdp_regs *regs)
{
regs->dst0 += (req->dst_rect.w -
min((uint32_t)16, req->dst_rect.w)) * regs->dst_bpp;
regs->dst1 += (req->dst_rect.w -
min((uint32_t)16, req->dst_rect.w)) * regs->dst_bpp;
}
static void rotate_dst_addr_y(struct mdp_blit_req *req, struct mdp_regs *regs)
{
regs->dst0 += (req->dst_rect.h -
min((uint32_t)16, req->dst_rect.h)) *
regs->dst_ystride;
regs->dst1 += (req->dst_rect.h -
min((uint32_t)16, req->dst_rect.h)) *
regs->dst_ystride;
}
static void blit_rotate(struct mdp_blit_req *req,
struct mdp_regs *regs)
{
if (req->flags == MDP_ROT_NOP)
return;
regs->op |= PPP_OP_ROT_ON;
if ((req->flags & MDP_ROT_90 || req->flags & MDP_FLIP_LR) &&
!(req->flags & MDP_ROT_90 && req->flags & MDP_FLIP_LR))
rotate_dst_addr_x(req, regs);
if (req->flags & MDP_ROT_90)
regs->op |= PPP_OP_ROT_90;
if (req->flags & MDP_FLIP_UD) {
regs->op |= PPP_OP_FLIP_UD;
rotate_dst_addr_y(req, regs);
}
if (req->flags & MDP_FLIP_LR)
regs->op |= PPP_OP_FLIP_LR;
}
static void blit_convert(struct mdp_blit_req *req, struct mdp_regs *regs)
{
if (req->src.format == req->dst.format)
return;
if (IS_RGB(req->src.format) && IS_YCRCB(req->dst.format)) {
regs->op |= PPP_OP_CONVERT_RGB2YCBCR | PPP_OP_CONVERT_ON;
} else if (IS_YCRCB(req->src.format) && IS_RGB(req->dst.format)) {
regs->op |= PPP_OP_CONVERT_YCBCR2RGB | PPP_OP_CONVERT_ON;
if (req->dst.format == MDP_RGB_565)
regs->op |= PPP_OP_CONVERT_MATRIX_SECONDARY;
}
}
#define GET_BIT_RANGE(value, high, low) \
(((1 << (high - low + 1)) - 1) & (value >> low))
static uint32_t transp_convert(struct mdp_blit_req *req)
{
uint32_t transp = 0;
if (req->src.format == MDP_RGB_565) {
/* pad each value to 8 bits by copying the high bits into the
* low end, convert RGB to RBG by switching low 2 components */
transp |= ((GET_BIT_RANGE(req->transp_mask, 15, 11) << 3) |
(GET_BIT_RANGE(req->transp_mask, 15, 13))) << 16;
transp |= ((GET_BIT_RANGE(req->transp_mask, 4, 0) << 3) |
(GET_BIT_RANGE(req->transp_mask, 4, 2))) << 8;
transp |= (GET_BIT_RANGE(req->transp_mask, 10, 5) << 2) |
(GET_BIT_RANGE(req->transp_mask, 10, 9));
} else {
/* convert RGB to RBG */
transp |= (GET_BIT_RANGE(req->transp_mask, 15, 8)) |
(GET_BIT_RANGE(req->transp_mask, 23, 16) << 16) |
(GET_BIT_RANGE(req->transp_mask, 7, 0) << 8);
}
return transp;
}
#undef GET_BIT_RANGE
static void blit_blend(struct mdp_blit_req *req, struct mdp_regs *regs)
{
/* TRANSP BLEND */
if (req->transp_mask != MDP_TRANSP_NOP) {
req->transp_mask = transp_convert(req);
if (req->alpha != MDP_ALPHA_NOP) {
/* use blended transparancy mode
* pixel = (src == transp) ? dst : blend
* blend is combo of blend_eq_sel and
* blend_alpha_sel */
regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
PPP_OP_BLEND_CONSTANT_ALPHA |
PPP_BLEND_ALPHA_TRANSP;
} else {
/* simple transparancy mode
* pixel = (src == transp) ? dst : src */
regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
PPP_OP_BLEND_SRCPIXEL_TRANSP;
}
}
req->alpha &= 0xff;
/* ALPHA BLEND */
if (HAS_ALPHA(req->src.format)) {
regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
PPP_OP_BLEND_SRCPIXEL_ALPHA;
} else if (req->alpha < MDP_ALPHA_NOP) {
/* just blend by alpha */
regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
PPP_OP_BLEND_CONSTANT_ALPHA;
}
regs->op |= bg_op_chroma[req->dst.format];
}
#define ONE_HALF (1LL << 32)
#define ONE (1LL << 33)
#define TWO (2LL << 33)
#define THREE (3LL << 33)
#define FRAC_MASK (ONE - 1)
#define INT_MASK (~FRAC_MASK)
static int scale_params(uint32_t dim_in, uint32_t dim_out, uint32_t origin,
uint32_t *phase_init, uint32_t *phase_step)
{
/* to improve precicsion calculations are done in U31.33 and converted
* to U3.29 at the end */
int64_t k1, k2, k3, k4, tmp;
uint64_t n, d, os, os_p, od, od_p, oreq;
unsigned rpa = 0;
int64_t ip64, delta;
if (dim_out % 3 == 0)
rpa = !(dim_in % (dim_out / 3));
n = ((uint64_t)dim_out) << 34;
d = dim_in;
if (!d)
return -1;
do_div(n, d);
k3 = (n + 1) >> 1;
if ((k3 >> 4) < (1LL << 27) || (k3 >> 4) > (1LL << 31)) {
DLOG("crap bad scale\n");
return -1;
}
n = ((uint64_t)dim_in) << 34;
d = (uint64_t)dim_out;
if (!d)
return -1;
do_div(n, d);
k1 = (n + 1) >> 1;
k2 = (k1 - ONE) >> 1;
*phase_init = (int)(k2 >> 4);
k4 = (k3 - ONE) >> 1;
if (rpa) {
os = ((uint64_t)origin << 33) - ONE_HALF;
tmp = (dim_out * os) + ONE_HALF;
if (!dim_in)
return -1;
do_div(tmp, dim_in);
od = tmp - ONE_HALF;
} else {
os = ((uint64_t)origin << 1) - 1;
od = (((k3 * os) >> 1) + k4);
}
od_p = od & INT_MASK;
if (od_p != od)
od_p += ONE;
if (rpa) {
tmp = (dim_in * od_p) + ONE_HALF;
if (!dim_in)
return -1;
do_div(tmp, dim_in);
os_p = tmp - ONE_HALF;
} else {
os_p = ((k1 * (od_p >> 33)) + k2);
}
oreq = (os_p & INT_MASK) - ONE;
ip64 = os_p - oreq;
delta = ((int64_t)(origin) << 33) - oreq;
ip64 -= delta;
/* limit to valid range before the left shift */
delta = (ip64 & (1LL << 63)) ? 4 : -4;
delta <<= 33;
while (abs((int)(ip64 >> 33)) > 4)
ip64 += delta;
*phase_init = (int)(ip64 >> 4);
*phase_step = (uint32_t)(k1 >> 4);
return 0;
}
static void load_scale_table(const struct mdp_info *mdp,
struct mdp_table_entry *table, int len)
{
int i;
for (i = 0; i < len; i++)
mdp_writel(mdp, table[i].val, table[i].reg);
}
enum {
IMG_LEFT,
IMG_RIGHT,
IMG_TOP,
IMG_BOTTOM,
};
static void get_edge_info(uint32_t src, uint32_t src_coord, uint32_t dst,
uint32_t *interp1, uint32_t *interp2,
uint32_t *repeat1, uint32_t *repeat2) {
if (src > 3 * dst) {
*interp1 = 0;
*interp2 = src - 1;
*repeat1 = 0;
*repeat2 = 0;
} else if (src == 3 * dst) {
*interp1 = 0;
*interp2 = src;
*repeat1 = 0;
*repeat2 = 1;
} else if (src > dst && src < 3 * dst) {
*interp1 = -1;
*interp2 = src;
*repeat1 = 1;
*repeat2 = 1;
} else if (src == dst) {
*interp1 = -1;
*interp2 = src + 1;
*repeat1 = 1;
*repeat2 = 2;
} else {
*interp1 = -2;
*interp2 = src + 1;
*repeat1 = 2;
*repeat2 = 2;
}
*interp1 += src_coord;
*interp2 += src_coord;
}
static int get_edge_cond(struct mdp_blit_req *req, struct mdp_regs *regs)
{
int32_t luma_interp[4];
int32_t luma_repeat[4];
int32_t chroma_interp[4];
int32_t chroma_bound[4];
int32_t chroma_repeat[4];
uint32_t dst_w, dst_h;
memset(&luma_interp, 0, sizeof(int32_t) * 4);
memset(&luma_repeat, 0, sizeof(int32_t) * 4);
memset(&chroma_interp, 0, sizeof(int32_t) * 4);
memset(&chroma_bound, 0, sizeof(int32_t) * 4);
memset(&chroma_repeat, 0, sizeof(int32_t) * 4);
regs->edge = 0;
if (req->flags & MDP_ROT_90) {
dst_w = req->dst_rect.h;
dst_h = req->dst_rect.w;
} else {
dst_w = req->dst_rect.w;
dst_h = req->dst_rect.h;
}
if (regs->op & (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON)) {
get_edge_info(req->src_rect.h, req->src_rect.y, dst_h,
&luma_interp[IMG_TOP], &luma_interp[IMG_BOTTOM],
&luma_repeat[IMG_TOP], &luma_repeat[IMG_BOTTOM]);
get_edge_info(req->src_rect.w, req->src_rect.x, dst_w,
&luma_interp[IMG_LEFT], &luma_interp[IMG_RIGHT],
&luma_repeat[IMG_LEFT], &luma_repeat[IMG_RIGHT]);
} else {
luma_interp[IMG_LEFT] = req->src_rect.x;
luma_interp[IMG_RIGHT] = req->src_rect.x + req->src_rect.w - 1;
luma_interp[IMG_TOP] = req->src_rect.y;
luma_interp[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h - 1;
luma_repeat[IMG_LEFT] = 0;
luma_repeat[IMG_TOP] = 0;
luma_repeat[IMG_RIGHT] = 0;
luma_repeat[IMG_BOTTOM] = 0;
}
chroma_interp[IMG_LEFT] = luma_interp[IMG_LEFT];
chroma_interp[IMG_RIGHT] = luma_interp[IMG_RIGHT];
chroma_interp[IMG_TOP] = luma_interp[IMG_TOP];
chroma_interp[IMG_BOTTOM] = luma_interp[IMG_BOTTOM];
chroma_bound[IMG_LEFT] = req->src_rect.x;
chroma_bound[IMG_RIGHT] = req->src_rect.x + req->src_rect.w - 1;
chroma_bound[IMG_TOP] = req->src_rect.y;
chroma_bound[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h - 1;
if (IS_YCRCB(req->src.format)) {
chroma_interp[IMG_LEFT] = chroma_interp[IMG_LEFT] >> 1;
chroma_interp[IMG_RIGHT] = (chroma_interp[IMG_RIGHT] + 1) >> 1;
chroma_bound[IMG_LEFT] = chroma_bound[IMG_LEFT] >> 1;
chroma_bound[IMG_RIGHT] = chroma_bound[IMG_RIGHT] >> 1;
}
if (req->src.format == MDP_Y_CBCR_H2V2 ||
req->src.format == MDP_Y_CRCB_H2V2) {
chroma_interp[IMG_TOP] = (chroma_interp[IMG_TOP] - 1) >> 1;
chroma_interp[IMG_BOTTOM] = (chroma_interp[IMG_BOTTOM] + 1)
>> 1;
chroma_bound[IMG_TOP] = (chroma_bound[IMG_TOP] + 1) >> 1;
chroma_bound[IMG_BOTTOM] = chroma_bound[IMG_BOTTOM] >> 1;
}
chroma_repeat[IMG_LEFT] = chroma_bound[IMG_LEFT] -
chroma_interp[IMG_LEFT];
chroma_repeat[IMG_RIGHT] = chroma_interp[IMG_RIGHT] -
chroma_bound[IMG_RIGHT];
chroma_repeat[IMG_TOP] = chroma_bound[IMG_TOP] -
chroma_interp[IMG_TOP];
chroma_repeat[IMG_BOTTOM] = chroma_interp[IMG_BOTTOM] -
chroma_bound[IMG_BOTTOM];
if (chroma_repeat[IMG_LEFT] < 0 || chroma_repeat[IMG_LEFT] > 3 ||
chroma_repeat[IMG_RIGHT] < 0 || chroma_repeat[IMG_RIGHT] > 3 ||
chroma_repeat[IMG_TOP] < 0 || chroma_repeat[IMG_TOP] > 3 ||
chroma_repeat[IMG_BOTTOM] < 0 || chroma_repeat[IMG_BOTTOM] > 3 ||
luma_repeat[IMG_LEFT] < 0 || luma_repeat[IMG_LEFT] > 3 ||
luma_repeat[IMG_RIGHT] < 0 || luma_repeat[IMG_RIGHT] > 3 ||
luma_repeat[IMG_TOP] < 0 || luma_repeat[IMG_TOP] > 3 ||
luma_repeat[IMG_BOTTOM] < 0 || luma_repeat[IMG_BOTTOM] > 3)
return -1;
regs->edge |= (chroma_repeat[IMG_LEFT] & 3) << MDP_LEFT_CHROMA;
regs->edge |= (chroma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_CHROMA;
regs->edge |= (chroma_repeat[IMG_TOP] & 3) << MDP_TOP_CHROMA;
regs->edge |= (chroma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_CHROMA;
regs->edge |= (luma_repeat[IMG_LEFT] & 3) << MDP_LEFT_LUMA;
regs->edge |= (luma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_LUMA;
regs->edge |= (luma_repeat[IMG_TOP] & 3) << MDP_TOP_LUMA;
regs->edge |= (luma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_LUMA;
return 0;
}
static int blit_scale(const struct mdp_info *mdp, struct mdp_blit_req *req,
struct mdp_regs *regs)
{
uint32_t phase_init_x, phase_init_y, phase_step_x, phase_step_y;
uint32_t scale_factor_x, scale_factor_y;
uint32_t downscale;
uint32_t dst_w, dst_h;
if (req->flags & MDP_ROT_90) {
dst_w = req->dst_rect.h;
dst_h = req->dst_rect.w;
} else {
dst_w = req->dst_rect.w;
dst_h = req->dst_rect.h;
}
if ((req->src_rect.w == dst_w) && (req->src_rect.h == dst_h) &&
!(req->flags & MDP_BLUR)) {
regs->phasex_init = 0;
regs->phasey_init = 0;
regs->phasex_step = 0;
regs->phasey_step = 0;
return 0;
}
if (scale_params(req->src_rect.w, dst_w, 1, &phase_init_x,
&phase_step_x) ||
scale_params(req->src_rect.h, dst_h, 1, &phase_init_y,
&phase_step_y))
return -1;
scale_factor_x = (dst_w * 10) / req->src_rect.w;
scale_factor_y = (dst_h * 10) / req->src_rect.h;
if (scale_factor_x > 8)
downscale = MDP_DOWNSCALE_PT8TO1;
else if (scale_factor_x > 6)
downscale = MDP_DOWNSCALE_PT6TOPT8;
else if (scale_factor_x > 4)
downscale = MDP_DOWNSCALE_PT4TOPT6;
else
downscale = MDP_DOWNSCALE_PT2TOPT4;
if (downscale != downscale_x_table) {
load_scale_table(mdp, mdp_downscale_x_table[downscale], 64);
downscale_x_table = downscale;
}
if (scale_factor_y > 8)
downscale = MDP_DOWNSCALE_PT8TO1;
else if (scale_factor_y > 6)
downscale = MDP_DOWNSCALE_PT6TOPT8;
else if (scale_factor_y > 4)
downscale = MDP_DOWNSCALE_PT4TOPT6;
else
downscale = MDP_DOWNSCALE_PT2TOPT4;
if (downscale != downscale_y_table) {
load_scale_table(mdp, mdp_downscale_y_table[downscale], 64);
downscale_y_table = downscale;
}
regs->phasex_init = phase_init_x;
regs->phasey_init = phase_init_y;
regs->phasex_step = phase_step_x;
regs->phasey_step = phase_step_y;
regs->op |= (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
return 0;
}
static void blit_blur(const struct mdp_info *mdp, struct mdp_blit_req *req,
struct mdp_regs *regs)
{
if (!(req->flags & MDP_BLUR))
return;
if (!(downscale_x_table == MDP_DOWNSCALE_BLUR &&
downscale_y_table == MDP_DOWNSCALE_BLUR)) {
load_scale_table(mdp, mdp_gaussian_blur_table, 128);
downscale_x_table = MDP_DOWNSCALE_BLUR;
downscale_y_table = MDP_DOWNSCALE_BLUR;
}
regs->op |= (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
}
#define IMG_LEN(rect_h, w, rect_w, bpp) (((rect_h) * w) * bpp)
#define Y_TO_CRCB_RATIO(format) \
((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CRCB_H2V2) ? 2 :\
(format == MDP_Y_CBCR_H2V1 || format == MDP_Y_CRCB_H2V1) ? 1 : 1)
static void get_len(struct mdp_img *img, struct mdp_rect *rect, uint32_t bpp,
uint32_t *len0, uint32_t *len1)
{
*len0 = IMG_LEN(rect->h, img->width, rect->w, bpp);
if (IS_PSEUDOPLNR(img->format))
*len1 = *len0/Y_TO_CRCB_RATIO(img->format);
else
*len1 = 0;
}
static int valid_src_dst(unsigned long src_start, unsigned long src_len,
unsigned long dst_start, unsigned long dst_len,
struct mdp_blit_req *req, struct mdp_regs *regs)
{
unsigned long src_min_ok = src_start;
unsigned long src_max_ok = src_start + src_len;
unsigned long dst_min_ok = dst_start;
unsigned long dst_max_ok = dst_start + dst_len;
uint32_t src0_len, src1_len, dst0_len, dst1_len;
get_len(&req->src, &req->src_rect, regs->src_bpp, &src0_len,
&src1_len);
get_len(&req->dst, &req->dst_rect, regs->dst_bpp, &dst0_len,
&dst1_len);
if (regs->src0 < src_min_ok || regs->src0 > src_max_ok ||
regs->src0 + src0_len > src_max_ok) {
DLOG("invalid_src %x %x %lx %lx\n", regs->src0,
src0_len, src_min_ok, src_max_ok);
return 0;
}
if (regs->src_cfg & PPP_SRC_PLANE_PSEUDOPLNR) {
if (regs->src1 < src_min_ok || regs->src1 > src_max_ok ||
regs->src1 + src1_len > src_max_ok) {
DLOG("invalid_src1");
return 0;
}
}
if (regs->dst0 < dst_min_ok || regs->dst0 > dst_max_ok ||
regs->dst0 + dst0_len > dst_max_ok) {
DLOG("invalid_dst");
return 0;
}
if (regs->dst_cfg & PPP_SRC_PLANE_PSEUDOPLNR) {
if (regs->dst1 < dst_min_ok || regs->dst1 > dst_max_ok ||
regs->dst1 + dst1_len > dst_max_ok) {
DLOG("invalid_dst1");
return 0;
}
}
return 1;
}
static void flush_imgs(struct mdp_blit_req *req, struct mdp_regs *regs,
struct file *src_file, struct file *dst_file)
{
}
static void get_chroma_addr(struct mdp_img *img, struct mdp_rect *rect,
uint32_t base, uint32_t bpp, uint32_t cfg,
uint32_t *addr, uint32_t *ystride)
{
uint32_t compress_v = Y_TO_CRCB_RATIO(img->format);
uint32_t compress_h = 2;
uint32_t offset;
if (IS_PSEUDOPLNR(img->format)) {
offset = (rect->x / compress_h) * compress_h;
offset += rect->y == 0 ? 0 :
((rect->y + 1) / compress_v) * img->width;
*addr = base + (img->width * img->height * bpp);
*addr += offset * bpp;
*ystride |= *ystride << 16;
} else {
*addr = 0;
}
}
static int send_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
struct mdp_regs *regs, struct file *src_file,
struct file *dst_file)
{
mdp_writel(mdp, 1, 0x060);
mdp_writel(mdp, regs->src_rect, PPP_ADDR_SRC_ROI);
mdp_writel(mdp, regs->src0, PPP_ADDR_SRC0);
mdp_writel(mdp, regs->src1, PPP_ADDR_SRC1);
mdp_writel(mdp, regs->src_ystride, PPP_ADDR_SRC_YSTRIDE);
mdp_writel(mdp, regs->src_cfg, PPP_ADDR_SRC_CFG);
mdp_writel(mdp, regs->src_pack, PPP_ADDR_SRC_PACK_PATTERN);
mdp_writel(mdp, regs->op, PPP_ADDR_OPERATION);
mdp_writel(mdp, regs->phasex_init, PPP_ADDR_PHASEX_INIT);
mdp_writel(mdp, regs->phasey_init, PPP_ADDR_PHASEY_INIT);
mdp_writel(mdp, regs->phasex_step, PPP_ADDR_PHASEX_STEP);
mdp_writel(mdp, regs->phasey_step, PPP_ADDR_PHASEY_STEP);
mdp_writel(mdp, (req->alpha << 24) | (req->transp_mask & 0xffffff),
PPP_ADDR_ALPHA_TRANSP);
mdp_writel(mdp, regs->dst_cfg, PPP_ADDR_DST_CFG);
mdp_writel(mdp, regs->dst_pack, PPP_ADDR_DST_PACK_PATTERN);
mdp_writel(mdp, regs->dst_rect, PPP_ADDR_DST_ROI);
mdp_writel(mdp, regs->dst0, PPP_ADDR_DST0);
mdp_writel(mdp, regs->dst1, PPP_ADDR_DST1);
mdp_writel(mdp, regs->dst_ystride, PPP_ADDR_DST_YSTRIDE);
mdp_writel(mdp, regs->edge, PPP_ADDR_EDGE);
if (regs->op & PPP_OP_BLEND_ON) {
mdp_writel(mdp, regs->dst0, PPP_ADDR_BG0);
mdp_writel(mdp, regs->dst1, PPP_ADDR_BG1);
mdp_writel(mdp, regs->dst_ystride, PPP_ADDR_BG_YSTRIDE);
mdp_writel(mdp, src_img_cfg[req->dst.format], PPP_ADDR_BG_CFG);
mdp_writel(mdp, pack_pattern[req->dst.format],
PPP_ADDR_BG_PACK_PATTERN);
}
flush_imgs(req, regs, src_file, dst_file);
mdp_writel(mdp, 0x1000, MDP_DISPLAY0_START);
return 0;
}
int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
struct file *src_file, unsigned long src_start, unsigned long src_len,
struct file *dst_file, unsigned long dst_start, unsigned long dst_len)
{
struct mdp_regs regs = {0};
if (unlikely(req->src.format >= MDP_IMGTYPE_LIMIT ||
req->dst.format >= MDP_IMGTYPE_LIMIT)) {
printk(KERN_ERR "mpd_ppp: img is of wrong format\n");
return -EINVAL;
}
if (unlikely(req->src_rect.x > req->src.width ||
req->src_rect.y > req->src.height ||
req->dst_rect.x > req->dst.width ||
req->dst_rect.y > req->dst.height)) {
printk(KERN_ERR "mpd_ppp: img rect is outside of img!\n");
return -EINVAL;
}
/* set the src image configuration */
regs.src_cfg = src_img_cfg[req->src.format];
regs.src_cfg |= (req->src_rect.x & 0x1) ? PPP_SRC_BPP_ROI_ODD_X : 0;
regs.src_cfg |= (req->src_rect.y & 0x1) ? PPP_SRC_BPP_ROI_ODD_Y : 0;
regs.src_rect = (req->src_rect.h << 16) | req->src_rect.w;
regs.src_pack = pack_pattern[req->src.format];
/* set the dest image configuration */
regs.dst_cfg = dst_img_cfg[req->dst.format] | PPP_DST_OUT_SEL_AXI;
regs.dst_rect = (req->dst_rect.h << 16) | req->dst_rect.w;
regs.dst_pack = pack_pattern[req->dst.format];
/* set src, bpp, start pixel and ystride */
regs.src_bpp = bytes_per_pixel[req->src.format];
regs.src0 = src_start + req->src.offset;
regs.src_ystride = req->src.width * regs.src_bpp;
get_chroma_addr(&req->src, &req->src_rect, regs.src0, regs.src_bpp,
regs.src_cfg, &regs.src1, &regs.src_ystride);
regs.src0 += (req->src_rect.x + (req->src_rect.y * req->src.width)) *
regs.src_bpp;
/* set dst, bpp, start pixel and ystride */
regs.dst_bpp = bytes_per_pixel[req->dst.format];
regs.dst0 = dst_start + req->dst.offset;
regs.dst_ystride = req->dst.width * regs.dst_bpp;
get_chroma_addr(&req->dst, &req->dst_rect, regs.dst0, regs.dst_bpp,
regs.dst_cfg, &regs.dst1, &regs.dst_ystride);
regs.dst0 += (req->dst_rect.x + (req->dst_rect.y * req->dst.width)) *
regs.dst_bpp;
if (!valid_src_dst(src_start, src_len, dst_start, dst_len, req,
&regs)) {
printk(KERN_ERR "mpd_ppp: final src or dst location is "
"invalid, are you trying to make an image too large "
"or to place it outside the screen?\n");
return -EINVAL;
}
/* set up operation register */
regs.op = 0;
blit_rotate(req, &regs);
blit_convert(req, &regs);
if (req->flags & MDP_DITHER)
regs.op |= PPP_OP_DITHER_EN;
blit_blend(req, &regs);
if (blit_scale(mdp, req, &regs)) {
printk(KERN_ERR "mpd_ppp: error computing scale for img.\n");
return -EINVAL;
}
blit_blur(mdp, req, &regs);
regs.op |= dst_op_chroma[req->dst.format] |
src_op_chroma[req->src.format];
/* if the image is YCRYCB, the x and w must be even */
if (unlikely(req->src.format == MDP_YCRYCB_H2V1)) {
req->src_rect.x = req->src_rect.x & (~0x1);
req->src_rect.w = req->src_rect.w & (~0x1);
req->dst_rect.x = req->dst_rect.x & (~0x1);
req->dst_rect.w = req->dst_rect.w & (~0x1);
}
if (get_edge_cond(req, &regs))
return -EINVAL;
send_blit(mdp, req, &regs, src_file, dst_file);
return 0;
}

View File

@ -1,766 +0,0 @@
/* drivers/video/msm_fb/mdp_scale_tables.c
*
* Copyright (C) 2007 QUALCOMM Incorporated
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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 "mdp_scale_tables.h"
#include "mdp_hw.h"
struct mdp_table_entry mdp_upscale_table[] = {
{ 0x5fffc, 0x0 },
{ 0x50200, 0x7fc00000 },
{ 0x5fffc, 0xff80000d },
{ 0x50204, 0x7ec003f9 },
{ 0x5fffc, 0xfec0001c },
{ 0x50208, 0x7d4003f3 },
{ 0x5fffc, 0xfe40002b },
{ 0x5020c, 0x7b8003ed },
{ 0x5fffc, 0xfd80003c },
{ 0x50210, 0x794003e8 },
{ 0x5fffc, 0xfcc0004d },
{ 0x50214, 0x76c003e4 },
{ 0x5fffc, 0xfc40005f },
{ 0x50218, 0x73c003e0 },
{ 0x5fffc, 0xfb800071 },
{ 0x5021c, 0x708003de },
{ 0x5fffc, 0xfac00085 },
{ 0x50220, 0x6d0003db },
{ 0x5fffc, 0xfa000098 },
{ 0x50224, 0x698003d9 },
{ 0x5fffc, 0xf98000ac },
{ 0x50228, 0x654003d8 },
{ 0x5fffc, 0xf8c000c1 },
{ 0x5022c, 0x610003d7 },
{ 0x5fffc, 0xf84000d5 },
{ 0x50230, 0x5c8003d7 },
{ 0x5fffc, 0xf7c000e9 },
{ 0x50234, 0x580003d7 },
{ 0x5fffc, 0xf74000fd },
{ 0x50238, 0x534003d8 },
{ 0x5fffc, 0xf6c00112 },
{ 0x5023c, 0x4e8003d8 },
{ 0x5fffc, 0xf6800126 },
{ 0x50240, 0x494003da },
{ 0x5fffc, 0xf600013a },
{ 0x50244, 0x448003db },
{ 0x5fffc, 0xf600014d },
{ 0x50248, 0x3f4003dd },
{ 0x5fffc, 0xf5c00160 },
{ 0x5024c, 0x3a4003df },
{ 0x5fffc, 0xf5c00172 },
{ 0x50250, 0x354003e1 },
{ 0x5fffc, 0xf5c00184 },
{ 0x50254, 0x304003e3 },
{ 0x5fffc, 0xf6000195 },
{ 0x50258, 0x2b0003e6 },
{ 0x5fffc, 0xf64001a6 },
{ 0x5025c, 0x260003e8 },
{ 0x5fffc, 0xf6c001b4 },
{ 0x50260, 0x214003eb },
{ 0x5fffc, 0xf78001c2 },
{ 0x50264, 0x1c4003ee },
{ 0x5fffc, 0xf80001cf },
{ 0x50268, 0x17c003f1 },
{ 0x5fffc, 0xf90001db },
{ 0x5026c, 0x134003f3 },
{ 0x5fffc, 0xfa0001e5 },
{ 0x50270, 0xf0003f6 },
{ 0x5fffc, 0xfb4001ee },
{ 0x50274, 0xac003f9 },
{ 0x5fffc, 0xfcc001f5 },
{ 0x50278, 0x70003fb },
{ 0x5fffc, 0xfe4001fb },
{ 0x5027c, 0x34003fe },
};
static struct mdp_table_entry mdp_downscale_x_table_PT2TOPT4[] = {
{ 0x5fffc, 0x740008c },
{ 0x50280, 0x33800088 },
{ 0x5fffc, 0x800008e },
{ 0x50284, 0x33400084 },
{ 0x5fffc, 0x8400092 },
{ 0x50288, 0x33000080 },
{ 0x5fffc, 0x9000094 },
{ 0x5028c, 0x3300007b },
{ 0x5fffc, 0x9c00098 },
{ 0x50290, 0x32400077 },
{ 0x5fffc, 0xa40009b },
{ 0x50294, 0x32000073 },
{ 0x5fffc, 0xb00009d },
{ 0x50298, 0x31c0006f },
{ 0x5fffc, 0xbc000a0 },
{ 0x5029c, 0x3140006b },
{ 0x5fffc, 0xc8000a2 },
{ 0x502a0, 0x31000067 },
{ 0x5fffc, 0xd8000a5 },
{ 0x502a4, 0x30800062 },
{ 0x5fffc, 0xe4000a8 },
{ 0x502a8, 0x2fc0005f },
{ 0x5fffc, 0xec000aa },
{ 0x502ac, 0x2fc0005b },
{ 0x5fffc, 0xf8000ad },
{ 0x502b0, 0x2f400057 },
{ 0x5fffc, 0x108000b0 },
{ 0x502b4, 0x2e400054 },
{ 0x5fffc, 0x114000b2 },
{ 0x502b8, 0x2e000050 },
{ 0x5fffc, 0x124000b4 },
{ 0x502bc, 0x2d80004c },
{ 0x5fffc, 0x130000b6 },
{ 0x502c0, 0x2d000049 },
{ 0x5fffc, 0x140000b8 },
{ 0x502c4, 0x2c800045 },
{ 0x5fffc, 0x150000b9 },
{ 0x502c8, 0x2c000042 },
{ 0x5fffc, 0x15c000bd },
{ 0x502cc, 0x2b40003e },
{ 0x5fffc, 0x16c000bf },
{ 0x502d0, 0x2a80003b },
{ 0x5fffc, 0x17c000bf },
{ 0x502d4, 0x2a000039 },
{ 0x5fffc, 0x188000c2 },
{ 0x502d8, 0x29400036 },
{ 0x5fffc, 0x19c000c4 },
{ 0x502dc, 0x28800032 },
{ 0x5fffc, 0x1ac000c5 },
{ 0x502e0, 0x2800002f },
{ 0x5fffc, 0x1bc000c7 },
{ 0x502e4, 0x2740002c },
{ 0x5fffc, 0x1cc000c8 },
{ 0x502e8, 0x26c00029 },
{ 0x5fffc, 0x1dc000c9 },
{ 0x502ec, 0x26000027 },
{ 0x5fffc, 0x1ec000cc },
{ 0x502f0, 0x25000024 },
{ 0x5fffc, 0x200000cc },
{ 0x502f4, 0x24800021 },
{ 0x5fffc, 0x210000cd },
{ 0x502f8, 0x23800020 },
{ 0x5fffc, 0x220000ce },
{ 0x502fc, 0x2300001d },
};
static struct mdp_table_entry mdp_downscale_x_table_PT4TOPT6[] = {
{ 0x5fffc, 0x740008c },
{ 0x50280, 0x33800088 },
{ 0x5fffc, 0x800008e },
{ 0x50284, 0x33400084 },
{ 0x5fffc, 0x8400092 },
{ 0x50288, 0x33000080 },
{ 0x5fffc, 0x9000094 },
{ 0x5028c, 0x3300007b },
{ 0x5fffc, 0x9c00098 },
{ 0x50290, 0x32400077 },
{ 0x5fffc, 0xa40009b },
{ 0x50294, 0x32000073 },
{ 0x5fffc, 0xb00009d },
{ 0x50298, 0x31c0006f },
{ 0x5fffc, 0xbc000a0 },
{ 0x5029c, 0x3140006b },
{ 0x5fffc, 0xc8000a2 },
{ 0x502a0, 0x31000067 },
{ 0x5fffc, 0xd8000a5 },
{ 0x502a4, 0x30800062 },
{ 0x5fffc, 0xe4000a8 },
{ 0x502a8, 0x2fc0005f },
{ 0x5fffc, 0xec000aa },
{ 0x502ac, 0x2fc0005b },
{ 0x5fffc, 0xf8000ad },
{ 0x502b0, 0x2f400057 },
{ 0x5fffc, 0x108000b0 },
{ 0x502b4, 0x2e400054 },
{ 0x5fffc, 0x114000b2 },
{ 0x502b8, 0x2e000050 },
{ 0x5fffc, 0x124000b4 },
{ 0x502bc, 0x2d80004c },
{ 0x5fffc, 0x130000b6 },
{ 0x502c0, 0x2d000049 },
{ 0x5fffc, 0x140000b8 },
{ 0x502c4, 0x2c800045 },
{ 0x5fffc, 0x150000b9 },
{ 0x502c8, 0x2c000042 },
{ 0x5fffc, 0x15c000bd },
{ 0x502cc, 0x2b40003e },
{ 0x5fffc, 0x16c000bf },
{ 0x502d0, 0x2a80003b },
{ 0x5fffc, 0x17c000bf },
{ 0x502d4, 0x2a000039 },
{ 0x5fffc, 0x188000c2 },
{ 0x502d8, 0x29400036 },
{ 0x5fffc, 0x19c000c4 },
{ 0x502dc, 0x28800032 },
{ 0x5fffc, 0x1ac000c5 },
{ 0x502e0, 0x2800002f },
{ 0x5fffc, 0x1bc000c7 },
{ 0x502e4, 0x2740002c },
{ 0x5fffc, 0x1cc000c8 },
{ 0x502e8, 0x26c00029 },
{ 0x5fffc, 0x1dc000c9 },
{ 0x502ec, 0x26000027 },
{ 0x5fffc, 0x1ec000cc },
{ 0x502f0, 0x25000024 },
{ 0x5fffc, 0x200000cc },
{ 0x502f4, 0x24800021 },
{ 0x5fffc, 0x210000cd },
{ 0x502f8, 0x23800020 },
{ 0x5fffc, 0x220000ce },
{ 0x502fc, 0x2300001d },
};
static struct mdp_table_entry mdp_downscale_x_table_PT6TOPT8[] = {
{ 0x5fffc, 0xfe000070 },
{ 0x50280, 0x4bc00068 },
{ 0x5fffc, 0xfe000078 },
{ 0x50284, 0x4bc00060 },
{ 0x5fffc, 0xfe000080 },
{ 0x50288, 0x4b800059 },
{ 0x5fffc, 0xfe000089 },
{ 0x5028c, 0x4b000052 },
{ 0x5fffc, 0xfe400091 },
{ 0x50290, 0x4a80004b },
{ 0x5fffc, 0xfe40009a },
{ 0x50294, 0x4a000044 },
{ 0x5fffc, 0xfe8000a3 },
{ 0x50298, 0x4940003d },
{ 0x5fffc, 0xfec000ac },
{ 0x5029c, 0x48400037 },
{ 0x5fffc, 0xff0000b4 },
{ 0x502a0, 0x47800031 },
{ 0x5fffc, 0xff8000bd },
{ 0x502a4, 0x4640002b },
{ 0x5fffc, 0xc5 },
{ 0x502a8, 0x45000026 },
{ 0x5fffc, 0x8000ce },
{ 0x502ac, 0x43800021 },
{ 0x5fffc, 0x10000d6 },
{ 0x502b0, 0x4240001c },
{ 0x5fffc, 0x18000df },
{ 0x502b4, 0x40800018 },
{ 0x5fffc, 0x24000e6 },
{ 0x502b8, 0x3f000014 },
{ 0x5fffc, 0x30000ee },
{ 0x502bc, 0x3d400010 },
{ 0x5fffc, 0x40000f5 },
{ 0x502c0, 0x3b80000c },
{ 0x5fffc, 0x50000fc },
{ 0x502c4, 0x39800009 },
{ 0x5fffc, 0x6000102 },
{ 0x502c8, 0x37c00006 },
{ 0x5fffc, 0x7000109 },
{ 0x502cc, 0x35800004 },
{ 0x5fffc, 0x840010e },
{ 0x502d0, 0x33800002 },
{ 0x5fffc, 0x9800114 },
{ 0x502d4, 0x31400000 },
{ 0x5fffc, 0xac00119 },
{ 0x502d8, 0x2f4003fe },
{ 0x5fffc, 0xc40011e },
{ 0x502dc, 0x2d0003fc },
{ 0x5fffc, 0xdc00121 },
{ 0x502e0, 0x2b0003fb },
{ 0x5fffc, 0xf400125 },
{ 0x502e4, 0x28c003fa },
{ 0x5fffc, 0x11000128 },
{ 0x502e8, 0x268003f9 },
{ 0x5fffc, 0x12c0012a },
{ 0x502ec, 0x244003f9 },
{ 0x5fffc, 0x1480012c },
{ 0x502f0, 0x224003f8 },
{ 0x5fffc, 0x1640012e },
{ 0x502f4, 0x200003f8 },
{ 0x5fffc, 0x1800012f },
{ 0x502f8, 0x1e0003f8 },
{ 0x5fffc, 0x1a00012f },
{ 0x502fc, 0x1c0003f8 },
};
static struct mdp_table_entry mdp_downscale_x_table_PT8TO1[] = {
{ 0x5fffc, 0x0 },
{ 0x50280, 0x7fc00000 },
{ 0x5fffc, 0xff80000d },
{ 0x50284, 0x7ec003f9 },
{ 0x5fffc, 0xfec0001c },
{ 0x50288, 0x7d4003f3 },
{ 0x5fffc, 0xfe40002b },
{ 0x5028c, 0x7b8003ed },
{ 0x5fffc, 0xfd80003c },
{ 0x50290, 0x794003e8 },
{ 0x5fffc, 0xfcc0004d },
{ 0x50294, 0x76c003e4 },
{ 0x5fffc, 0xfc40005f },
{ 0x50298, 0x73c003e0 },
{ 0x5fffc, 0xfb800071 },
{ 0x5029c, 0x708003de },
{ 0x5fffc, 0xfac00085 },
{ 0x502a0, 0x6d0003db },
{ 0x5fffc, 0xfa000098 },
{ 0x502a4, 0x698003d9 },
{ 0x5fffc, 0xf98000ac },
{ 0x502a8, 0x654003d8 },
{ 0x5fffc, 0xf8c000c1 },
{ 0x502ac, 0x610003d7 },
{ 0x5fffc, 0xf84000d5 },
{ 0x502b0, 0x5c8003d7 },
{ 0x5fffc, 0xf7c000e9 },
{ 0x502b4, 0x580003d7 },
{ 0x5fffc, 0xf74000fd },
{ 0x502b8, 0x534003d8 },
{ 0x5fffc, 0xf6c00112 },
{ 0x502bc, 0x4e8003d8 },
{ 0x5fffc, 0xf6800126 },
{ 0x502c0, 0x494003da },
{ 0x5fffc, 0xf600013a },
{ 0x502c4, 0x448003db },
{ 0x5fffc, 0xf600014d },
{ 0x502c8, 0x3f4003dd },
{ 0x5fffc, 0xf5c00160 },
{ 0x502cc, 0x3a4003df },
{ 0x5fffc, 0xf5c00172 },
{ 0x502d0, 0x354003e1 },
{ 0x5fffc, 0xf5c00184 },
{ 0x502d4, 0x304003e3 },
{ 0x5fffc, 0xf6000195 },
{ 0x502d8, 0x2b0003e6 },
{ 0x5fffc, 0xf64001a6 },
{ 0x502dc, 0x260003e8 },
{ 0x5fffc, 0xf6c001b4 },
{ 0x502e0, 0x214003eb },
{ 0x5fffc, 0xf78001c2 },
{ 0x502e4, 0x1c4003ee },
{ 0x5fffc, 0xf80001cf },
{ 0x502e8, 0x17c003f1 },
{ 0x5fffc, 0xf90001db },
{ 0x502ec, 0x134003f3 },
{ 0x5fffc, 0xfa0001e5 },
{ 0x502f0, 0xf0003f6 },
{ 0x5fffc, 0xfb4001ee },
{ 0x502f4, 0xac003f9 },
{ 0x5fffc, 0xfcc001f5 },
{ 0x502f8, 0x70003fb },
{ 0x5fffc, 0xfe4001fb },
{ 0x502fc, 0x34003fe },
};
struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX] = {
[MDP_DOWNSCALE_PT2TOPT4] = mdp_downscale_x_table_PT2TOPT4,
[MDP_DOWNSCALE_PT4TOPT6] = mdp_downscale_x_table_PT4TOPT6,
[MDP_DOWNSCALE_PT6TOPT8] = mdp_downscale_x_table_PT6TOPT8,
[MDP_DOWNSCALE_PT8TO1] = mdp_downscale_x_table_PT8TO1,
};
static struct mdp_table_entry mdp_downscale_y_table_PT2TOPT4[] = {
{ 0x5fffc, 0x740008c },
{ 0x50300, 0x33800088 },
{ 0x5fffc, 0x800008e },
{ 0x50304, 0x33400084 },
{ 0x5fffc, 0x8400092 },
{ 0x50308, 0x33000080 },
{ 0x5fffc, 0x9000094 },
{ 0x5030c, 0x3300007b },
{ 0x5fffc, 0x9c00098 },
{ 0x50310, 0x32400077 },
{ 0x5fffc, 0xa40009b },
{ 0x50314, 0x32000073 },
{ 0x5fffc, 0xb00009d },
{ 0x50318, 0x31c0006f },
{ 0x5fffc, 0xbc000a0 },
{ 0x5031c, 0x3140006b },
{ 0x5fffc, 0xc8000a2 },
{ 0x50320, 0x31000067 },
{ 0x5fffc, 0xd8000a5 },
{ 0x50324, 0x30800062 },
{ 0x5fffc, 0xe4000a8 },
{ 0x50328, 0x2fc0005f },
{ 0x5fffc, 0xec000aa },
{ 0x5032c, 0x2fc0005b },
{ 0x5fffc, 0xf8000ad },
{ 0x50330, 0x2f400057 },
{ 0x5fffc, 0x108000b0 },
{ 0x50334, 0x2e400054 },
{ 0x5fffc, 0x114000b2 },
{ 0x50338, 0x2e000050 },
{ 0x5fffc, 0x124000b4 },
{ 0x5033c, 0x2d80004c },
{ 0x5fffc, 0x130000b6 },
{ 0x50340, 0x2d000049 },
{ 0x5fffc, 0x140000b8 },
{ 0x50344, 0x2c800045 },
{ 0x5fffc, 0x150000b9 },
{ 0x50348, 0x2c000042 },
{ 0x5fffc, 0x15c000bd },
{ 0x5034c, 0x2b40003e },
{ 0x5fffc, 0x16c000bf },
{ 0x50350, 0x2a80003b },
{ 0x5fffc, 0x17c000bf },
{ 0x50354, 0x2a000039 },
{ 0x5fffc, 0x188000c2 },
{ 0x50358, 0x29400036 },
{ 0x5fffc, 0x19c000c4 },
{ 0x5035c, 0x28800032 },
{ 0x5fffc, 0x1ac000c5 },
{ 0x50360, 0x2800002f },
{ 0x5fffc, 0x1bc000c7 },
{ 0x50364, 0x2740002c },
{ 0x5fffc, 0x1cc000c8 },
{ 0x50368, 0x26c00029 },
{ 0x5fffc, 0x1dc000c9 },
{ 0x5036c, 0x26000027 },
{ 0x5fffc, 0x1ec000cc },
{ 0x50370, 0x25000024 },
{ 0x5fffc, 0x200000cc },
{ 0x50374, 0x24800021 },
{ 0x5fffc, 0x210000cd },
{ 0x50378, 0x23800020 },
{ 0x5fffc, 0x220000ce },
{ 0x5037c, 0x2300001d },
};
static struct mdp_table_entry mdp_downscale_y_table_PT4TOPT6[] = {
{ 0x5fffc, 0x740008c },
{ 0x50300, 0x33800088 },
{ 0x5fffc, 0x800008e },
{ 0x50304, 0x33400084 },
{ 0x5fffc, 0x8400092 },
{ 0x50308, 0x33000080 },
{ 0x5fffc, 0x9000094 },
{ 0x5030c, 0x3300007b },
{ 0x5fffc, 0x9c00098 },
{ 0x50310, 0x32400077 },
{ 0x5fffc, 0xa40009b },
{ 0x50314, 0x32000073 },
{ 0x5fffc, 0xb00009d },
{ 0x50318, 0x31c0006f },
{ 0x5fffc, 0xbc000a0 },
{ 0x5031c, 0x3140006b },
{ 0x5fffc, 0xc8000a2 },
{ 0x50320, 0x31000067 },
{ 0x5fffc, 0xd8000a5 },
{ 0x50324, 0x30800062 },
{ 0x5fffc, 0xe4000a8 },
{ 0x50328, 0x2fc0005f },
{ 0x5fffc, 0xec000aa },
{ 0x5032c, 0x2fc0005b },
{ 0x5fffc, 0xf8000ad },
{ 0x50330, 0x2f400057 },
{ 0x5fffc, 0x108000b0 },
{ 0x50334, 0x2e400054 },
{ 0x5fffc, 0x114000b2 },
{ 0x50338, 0x2e000050 },
{ 0x5fffc, 0x124000b4 },
{ 0x5033c, 0x2d80004c },
{ 0x5fffc, 0x130000b6 },
{ 0x50340, 0x2d000049 },
{ 0x5fffc, 0x140000b8 },
{ 0x50344, 0x2c800045 },
{ 0x5fffc, 0x150000b9 },
{ 0x50348, 0x2c000042 },
{ 0x5fffc, 0x15c000bd },
{ 0x5034c, 0x2b40003e },
{ 0x5fffc, 0x16c000bf },
{ 0x50350, 0x2a80003b },
{ 0x5fffc, 0x17c000bf },
{ 0x50354, 0x2a000039 },
{ 0x5fffc, 0x188000c2 },
{ 0x50358, 0x29400036 },
{ 0x5fffc, 0x19c000c4 },
{ 0x5035c, 0x28800032 },
{ 0x5fffc, 0x1ac000c5 },
{ 0x50360, 0x2800002f },
{ 0x5fffc, 0x1bc000c7 },
{ 0x50364, 0x2740002c },
{ 0x5fffc, 0x1cc000c8 },
{ 0x50368, 0x26c00029 },
{ 0x5fffc, 0x1dc000c9 },
{ 0x5036c, 0x26000027 },
{ 0x5fffc, 0x1ec000cc },
{ 0x50370, 0x25000024 },
{ 0x5fffc, 0x200000cc },
{ 0x50374, 0x24800021 },
{ 0x5fffc, 0x210000cd },
{ 0x50378, 0x23800020 },
{ 0x5fffc, 0x220000ce },
{ 0x5037c, 0x2300001d },
};
static struct mdp_table_entry mdp_downscale_y_table_PT6TOPT8[] = {
{ 0x5fffc, 0xfe000070 },
{ 0x50300, 0x4bc00068 },
{ 0x5fffc, 0xfe000078 },
{ 0x50304, 0x4bc00060 },
{ 0x5fffc, 0xfe000080 },
{ 0x50308, 0x4b800059 },
{ 0x5fffc, 0xfe000089 },
{ 0x5030c, 0x4b000052 },
{ 0x5fffc, 0xfe400091 },
{ 0x50310, 0x4a80004b },
{ 0x5fffc, 0xfe40009a },
{ 0x50314, 0x4a000044 },
{ 0x5fffc, 0xfe8000a3 },
{ 0x50318, 0x4940003d },
{ 0x5fffc, 0xfec000ac },
{ 0x5031c, 0x48400037 },
{ 0x5fffc, 0xff0000b4 },
{ 0x50320, 0x47800031 },
{ 0x5fffc, 0xff8000bd },
{ 0x50324, 0x4640002b },
{ 0x5fffc, 0xc5 },
{ 0x50328, 0x45000026 },
{ 0x5fffc, 0x8000ce },
{ 0x5032c, 0x43800021 },
{ 0x5fffc, 0x10000d6 },
{ 0x50330, 0x4240001c },
{ 0x5fffc, 0x18000df },
{ 0x50334, 0x40800018 },
{ 0x5fffc, 0x24000e6 },
{ 0x50338, 0x3f000014 },
{ 0x5fffc, 0x30000ee },
{ 0x5033c, 0x3d400010 },
{ 0x5fffc, 0x40000f5 },
{ 0x50340, 0x3b80000c },
{ 0x5fffc, 0x50000fc },
{ 0x50344, 0x39800009 },
{ 0x5fffc, 0x6000102 },
{ 0x50348, 0x37c00006 },
{ 0x5fffc, 0x7000109 },
{ 0x5034c, 0x35800004 },
{ 0x5fffc, 0x840010e },
{ 0x50350, 0x33800002 },
{ 0x5fffc, 0x9800114 },
{ 0x50354, 0x31400000 },
{ 0x5fffc, 0xac00119 },
{ 0x50358, 0x2f4003fe },
{ 0x5fffc, 0xc40011e },
{ 0x5035c, 0x2d0003fc },
{ 0x5fffc, 0xdc00121 },
{ 0x50360, 0x2b0003fb },
{ 0x5fffc, 0xf400125 },
{ 0x50364, 0x28c003fa },
{ 0x5fffc, 0x11000128 },
{ 0x50368, 0x268003f9 },
{ 0x5fffc, 0x12c0012a },
{ 0x5036c, 0x244003f9 },
{ 0x5fffc, 0x1480012c },
{ 0x50370, 0x224003f8 },
{ 0x5fffc, 0x1640012e },
{ 0x50374, 0x200003f8 },
{ 0x5fffc, 0x1800012f },
{ 0x50378, 0x1e0003f8 },
{ 0x5fffc, 0x1a00012f },
{ 0x5037c, 0x1c0003f8 },
};
static struct mdp_table_entry mdp_downscale_y_table_PT8TO1[] = {
{ 0x5fffc, 0x0 },
{ 0x50300, 0x7fc00000 },
{ 0x5fffc, 0xff80000d },
{ 0x50304, 0x7ec003f9 },
{ 0x5fffc, 0xfec0001c },
{ 0x50308, 0x7d4003f3 },
{ 0x5fffc, 0xfe40002b },
{ 0x5030c, 0x7b8003ed },
{ 0x5fffc, 0xfd80003c },
{ 0x50310, 0x794003e8 },
{ 0x5fffc, 0xfcc0004d },
{ 0x50314, 0x76c003e4 },
{ 0x5fffc, 0xfc40005f },
{ 0x50318, 0x73c003e0 },
{ 0x5fffc, 0xfb800071 },
{ 0x5031c, 0x708003de },
{ 0x5fffc, 0xfac00085 },
{ 0x50320, 0x6d0003db },
{ 0x5fffc, 0xfa000098 },
{ 0x50324, 0x698003d9 },
{ 0x5fffc, 0xf98000ac },
{ 0x50328, 0x654003d8 },
{ 0x5fffc, 0xf8c000c1 },
{ 0x5032c, 0x610003d7 },
{ 0x5fffc, 0xf84000d5 },
{ 0x50330, 0x5c8003d7 },
{ 0x5fffc, 0xf7c000e9 },
{ 0x50334, 0x580003d7 },
{ 0x5fffc, 0xf74000fd },
{ 0x50338, 0x534003d8 },
{ 0x5fffc, 0xf6c00112 },
{ 0x5033c, 0x4e8003d8 },
{ 0x5fffc, 0xf6800126 },
{ 0x50340, 0x494003da },
{ 0x5fffc, 0xf600013a },
{ 0x50344, 0x448003db },
{ 0x5fffc, 0xf600014d },
{ 0x50348, 0x3f4003dd },
{ 0x5fffc, 0xf5c00160 },
{ 0x5034c, 0x3a4003df },
{ 0x5fffc, 0xf5c00172 },
{ 0x50350, 0x354003e1 },
{ 0x5fffc, 0xf5c00184 },
{ 0x50354, 0x304003e3 },
{ 0x5fffc, 0xf6000195 },
{ 0x50358, 0x2b0003e6 },
{ 0x5fffc, 0xf64001a6 },
{ 0x5035c, 0x260003e8 },
{ 0x5fffc, 0xf6c001b4 },
{ 0x50360, 0x214003eb },
{ 0x5fffc, 0xf78001c2 },
{ 0x50364, 0x1c4003ee },
{ 0x5fffc, 0xf80001cf },
{ 0x50368, 0x17c003f1 },
{ 0x5fffc, 0xf90001db },
{ 0x5036c, 0x134003f3 },
{ 0x5fffc, 0xfa0001e5 },
{ 0x50370, 0xf0003f6 },
{ 0x5fffc, 0xfb4001ee },
{ 0x50374, 0xac003f9 },
{ 0x5fffc, 0xfcc001f5 },
{ 0x50378, 0x70003fb },
{ 0x5fffc, 0xfe4001fb },
{ 0x5037c, 0x34003fe },
};
struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX] = {
[MDP_DOWNSCALE_PT2TOPT4] = mdp_downscale_y_table_PT2TOPT4,
[MDP_DOWNSCALE_PT4TOPT6] = mdp_downscale_y_table_PT4TOPT6,
[MDP_DOWNSCALE_PT6TOPT8] = mdp_downscale_y_table_PT6TOPT8,
[MDP_DOWNSCALE_PT8TO1] = mdp_downscale_y_table_PT8TO1,
};
struct mdp_table_entry mdp_gaussian_blur_table[] = {
/* max variance */
{ 0x5fffc, 0x20000080 },
{ 0x50280, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50284, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50288, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x5028c, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50290, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50294, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50298, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x5029c, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502a0, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502a4, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502a8, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502ac, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502b0, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502b4, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502b8, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502bc, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502c0, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502c4, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502c8, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502cc, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502d0, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502d4, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502d8, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502dc, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502e0, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502e4, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502e8, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502ec, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502f0, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502f4, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502f8, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x502fc, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50300, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50304, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50308, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x5030c, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50310, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50314, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50318, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x5031c, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50320, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50324, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50328, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x5032c, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50330, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50334, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50338, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x5033c, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50340, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50344, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50348, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x5034c, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50350, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50354, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50358, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x5035c, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50360, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50364, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50368, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x5036c, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50370, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50374, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x50378, 0x20000080 },
{ 0x5fffc, 0x20000080 },
{ 0x5037c, 0x20000080 },
};

View File

@ -1,38 +0,0 @@
/* drivers/video/msm_fb/mdp_scale_tables.h
*
* Copyright (C) 2007 QUALCOMM Incorporated
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _MDP_SCALE_TABLES_H_
#define _MDP_SCALE_TABLES_H_
#include <linux/types.h>
struct mdp_table_entry {
uint32_t reg;
uint32_t val;
};
extern struct mdp_table_entry mdp_upscale_table[64];
enum {
MDP_DOWNSCALE_PT2TOPT4,
MDP_DOWNSCALE_PT4TOPT6,
MDP_DOWNSCALE_PT6TOPT8,
MDP_DOWNSCALE_PT8TO1,
MDP_DOWNSCALE_MAX,
};
extern struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX];
extern struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX];
extern struct mdp_table_entry mdp_gaussian_blur_table[];
#endif

View File

@ -1,659 +0,0 @@
/* drivers/video/msm/msm_fb.c
*
* Core MSM framebuffer driver.
*
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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/platform_device.h>
#include <linux/module.h>
#include <linux/fb.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/freezer.h>
#include <linux/wait.h>
#include <linux/msm_mdp.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/platform_data/video-msm_fb.h>
#include <linux/workqueue.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/dma-mapping.h>
#define PRINT_FPS 0
#define PRINT_BLIT_TIME 0
#define SLEEPING 0x4
#define UPDATING 0x3
#define FULL_UPDATE_DONE 0x2
#define WAKING 0x1
#define AWAKE 0x0
#define NONE 0
#define SUSPEND_RESUME 0x1
#define FPS 0x2
#define BLIT_TIME 0x4
#define SHOW_UPDATES 0x8
#define DLOG(mask, fmt, args...) \
do { \
if (msmfb_debug_mask & mask) \
printk(KERN_INFO "msmfb: "fmt, ##args); \
} while (0)
static int msmfb_debug_mask;
module_param_named(msmfb_debug_mask, msmfb_debug_mask, int,
S_IRUGO | S_IWUSR | S_IWGRP);
struct mdp_device *mdp;
struct msmfb_info {
struct fb_info *fb;
struct msm_panel_data *panel;
int xres;
int yres;
unsigned output_format;
unsigned yoffset;
unsigned frame_requested;
unsigned frame_done;
int sleeping;
unsigned update_frame;
struct {
int left;
int top;
int eright; /* exclusive */
int ebottom; /* exclusive */
} update_info;
char *black;
spinlock_t update_lock;
struct mutex panel_init_lock;
wait_queue_head_t frame_wq;
struct work_struct resume_work;
struct msmfb_callback dma_callback;
struct msmfb_callback vsync_callback;
struct hrtimer fake_vsync;
ktime_t vsync_request_time;
};
static int msmfb_open(struct fb_info *info, int user)
{
return 0;
}
static int msmfb_release(struct fb_info *info, int user)
{
return 0;
}
/* Called from dma interrupt handler, must not sleep */
static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback)
{
unsigned long irq_flags;
struct msmfb_info *msmfb = container_of(callback, struct msmfb_info,
dma_callback);
spin_lock_irqsave(&msmfb->update_lock, irq_flags);
msmfb->frame_done = msmfb->frame_requested;
if (msmfb->sleeping == UPDATING &&
msmfb->frame_done == msmfb->update_frame) {
DLOG(SUSPEND_RESUME, "full update completed\n");
schedule_work(&msmfb->resume_work);
}
spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
wake_up(&msmfb->frame_wq);
}
static int msmfb_start_dma(struct msmfb_info *msmfb)
{
uint32_t x, y, w, h;
unsigned addr;
unsigned long irq_flags;
uint32_t yoffset;
s64 time_since_request;
struct msm_panel_data *panel = msmfb->panel;
spin_lock_irqsave(&msmfb->update_lock, irq_flags);
time_since_request = ktime_to_ns(ktime_sub(ktime_get(),
msmfb->vsync_request_time));
if (time_since_request > 20 * NSEC_PER_MSEC) {
uint32_t us;
us = do_div(time_since_request, NSEC_PER_MSEC) / NSEC_PER_USEC;
printk(KERN_WARNING "msmfb_start_dma %lld.%03u ms after vsync "
"request\n", time_since_request, us);
}
if (msmfb->frame_done == msmfb->frame_requested) {
spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
return -1;
}
if (msmfb->sleeping == SLEEPING) {
DLOG(SUSPEND_RESUME, "tried to start dma while asleep\n");
spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
return -1;
}
x = msmfb->update_info.left;
y = msmfb->update_info.top;
w = msmfb->update_info.eright - x;
h = msmfb->update_info.ebottom - y;
yoffset = msmfb->yoffset;
msmfb->update_info.left = msmfb->xres + 1;
msmfb->update_info.top = msmfb->yres + 1;
msmfb->update_info.eright = 0;
msmfb->update_info.ebottom = 0;
if (unlikely(w > msmfb->xres || h > msmfb->yres ||
w == 0 || h == 0)) {
printk(KERN_INFO "invalid update: %d %d %d "
"%d\n", x, y, w, h);
msmfb->frame_done = msmfb->frame_requested;
goto error;
}
spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
addr = ((msmfb->xres * (yoffset + y) + x) * 2);
mdp->dma(mdp, addr + msmfb->fb->fix.smem_start,
msmfb->xres * 2, w, h, x, y, &msmfb->dma_callback,
panel->interface_type);
return 0;
error:
spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
/* some clients need to clear their vsync interrupt */
if (panel->clear_vsync)
panel->clear_vsync(panel);
wake_up(&msmfb->frame_wq);
return 0;
}
/* Called from esync interrupt handler, must not sleep */
static void msmfb_handle_vsync_interrupt(struct msmfb_callback *callback)
{
struct msmfb_info *msmfb = container_of(callback, struct msmfb_info,
vsync_callback);
msmfb_start_dma(msmfb);
}
static enum hrtimer_restart msmfb_fake_vsync(struct hrtimer *timer)
{
struct msmfb_info *msmfb = container_of(timer, struct msmfb_info,
fake_vsync);
msmfb_start_dma(msmfb);
return HRTIMER_NORESTART;
}
static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top,
uint32_t eright, uint32_t ebottom,
uint32_t yoffset, int pan_display)
{
struct msmfb_info *msmfb = info->par;
struct msm_panel_data *panel = msmfb->panel;
unsigned long irq_flags;
int sleeping;
int retry = 1;
DLOG(SHOW_UPDATES, "update %d %d %d %d %d %d\n",
left, top, eright, ebottom, yoffset, pan_display);
restart:
spin_lock_irqsave(&msmfb->update_lock, irq_flags);
/* if we are sleeping, on a pan_display wait 10ms (to throttle back
* drawing otherwise return */
if (msmfb->sleeping == SLEEPING) {
DLOG(SUSPEND_RESUME, "drawing while asleep\n");
spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
if (pan_display)
wait_event_interruptible_timeout(msmfb->frame_wq,
msmfb->sleeping != SLEEPING, HZ/10);
return;
}
sleeping = msmfb->sleeping;
/* on a full update, if the last frame has not completed, wait for it */
if ((pan_display && msmfb->frame_requested != msmfb->frame_done) ||
sleeping == UPDATING) {
int ret;
spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
ret = wait_event_interruptible_timeout(msmfb->frame_wq,
msmfb->frame_done == msmfb->frame_requested &&
msmfb->sleeping != UPDATING, 5 * HZ);
if (ret <= 0 && (msmfb->frame_requested != msmfb->frame_done ||
msmfb->sleeping == UPDATING)) {
if (retry && panel->request_vsync &&
(sleeping == AWAKE)) {
panel->request_vsync(panel,
&msmfb->vsync_callback);
retry = 0;
printk(KERN_WARNING "msmfb_pan_display timeout "
"rerequest vsync\n");
} else {
printk(KERN_WARNING "msmfb_pan_display timeout "
"waiting for frame start, %d %d\n",
msmfb->frame_requested,
msmfb->frame_done);
return;
}
}
goto restart;
}
msmfb->frame_requested++;
/* if necessary, update the y offset, if this is the
* first full update on resume, set the sleeping state */
if (pan_display) {
msmfb->yoffset = yoffset;
if (left == 0 && top == 0 && eright == info->var.xres &&
ebottom == info->var.yres) {
if (sleeping == WAKING) {
msmfb->update_frame = msmfb->frame_requested;
DLOG(SUSPEND_RESUME, "full update starting\n");
msmfb->sleeping = UPDATING;
}
}
}
/* set the update request */
if (left < msmfb->update_info.left)
msmfb->update_info.left = left;
if (top < msmfb->update_info.top)
msmfb->update_info.top = top;
if (eright > msmfb->update_info.eright)
msmfb->update_info.eright = eright;
if (ebottom > msmfb->update_info.ebottom)
msmfb->update_info.ebottom = ebottom;
DLOG(SHOW_UPDATES, "update queued %d %d %d %d %d\n",
msmfb->update_info.left, msmfb->update_info.top,
msmfb->update_info.eright, msmfb->update_info.ebottom,
msmfb->yoffset);
spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
/* if the panel is all the way on wait for vsync, otherwise sleep
* for 16 ms (long enough for the dma to panel) and then begin dma */
msmfb->vsync_request_time = ktime_get();
if (panel->request_vsync && (sleeping == AWAKE)) {
panel->request_vsync(panel, &msmfb->vsync_callback);
} else {
if (!hrtimer_active(&msmfb->fake_vsync)) {
hrtimer_start(&msmfb->fake_vsync,
ktime_set(0, NSEC_PER_SEC/60),
HRTIMER_MODE_REL);
}
}
}
static void msmfb_update(struct fb_info *info, uint32_t left, uint32_t top,
uint32_t eright, uint32_t ebottom)
{
msmfb_pan_update(info, left, top, eright, ebottom, 0, 0);
}
static void power_on_panel(struct work_struct *work)
{
struct msmfb_info *msmfb =
container_of(work, struct msmfb_info, resume_work);
struct msm_panel_data *panel = msmfb->panel;
unsigned long irq_flags;
mutex_lock(&msmfb->panel_init_lock);
DLOG(SUSPEND_RESUME, "turning on panel\n");
if (msmfb->sleeping == UPDATING) {
if (panel->unblank(panel)) {
printk(KERN_INFO "msmfb: panel unblank failed,"
"not starting drawing\n");
goto error;
}
spin_lock_irqsave(&msmfb->update_lock, irq_flags);
msmfb->sleeping = AWAKE;
wake_up(&msmfb->frame_wq);
spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
}
error:
mutex_unlock(&msmfb->panel_init_lock);
}
static int msmfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
if ((var->xres != info->var.xres) ||
(var->yres != info->var.yres) ||
(var->xres_virtual != info->var.xres_virtual) ||
(var->yres_virtual != info->var.yres_virtual) ||
(var->xoffset != info->var.xoffset) ||
(var->bits_per_pixel != info->var.bits_per_pixel) ||
(var->grayscale != info->var.grayscale))
return -EINVAL;
return 0;
}
int msmfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct msmfb_info *msmfb = info->par;
struct msm_panel_data *panel = msmfb->panel;
/* "UPDT" */
if ((panel->caps & MSMFB_CAP_PARTIAL_UPDATES) &&
(var->reserved[0] == 0x54445055)) {
msmfb_pan_update(info, var->reserved[1] & 0xffff,
var->reserved[1] >> 16,
var->reserved[2] & 0xffff,
var->reserved[2] >> 16, var->yoffset, 1);
} else {
msmfb_pan_update(info, 0, 0, info->var.xres, info->var.yres,
var->yoffset, 1);
}
return 0;
}
static void msmfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
{
cfb_fillrect(p, rect);
msmfb_update(p, rect->dx, rect->dy, rect->dx + rect->width,
rect->dy + rect->height);
}
static void msmfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
{
cfb_copyarea(p, area);
msmfb_update(p, area->dx, area->dy, area->dx + area->width,
area->dy + area->height);
}
static void msmfb_imageblit(struct fb_info *p, const struct fb_image *image)
{
cfb_imageblit(p, image);
msmfb_update(p, image->dx, image->dy, image->dx + image->width,
image->dy + image->height);
}
static int msmfb_blit(struct fb_info *info,
void __user *p)
{
struct mdp_blit_req req;
struct mdp_blit_req_list req_list;
int i;
int ret;
if (copy_from_user(&req_list, p, sizeof(req_list)))
return -EFAULT;
for (i = 0; i < req_list.count; i++) {
struct mdp_blit_req_list *list =
(struct mdp_blit_req_list *)p;
if (copy_from_user(&req, &list->req[i], sizeof(req)))
return -EFAULT;
ret = mdp->blit(mdp, info, &req);
if (ret)
return ret;
}
return 0;
}
DEFINE_MUTEX(mdp_ppp_lock);
static int msmfb_ioctl(struct fb_info *p, unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
int ret;
switch (cmd) {
case MSMFB_GRP_DISP:
mdp->set_grp_disp(mdp, arg);
break;
case MSMFB_BLIT:
ret = msmfb_blit(p, argp);
if (ret)
return ret;
break;
default:
printk(KERN_INFO "msmfb unknown ioctl: %d\n", cmd);
return -EINVAL;
}
return 0;
}
static struct fb_ops msmfb_ops = {
.owner = THIS_MODULE,
.fb_open = msmfb_open,
.fb_release = msmfb_release,
.fb_check_var = msmfb_check_var,
.fb_pan_display = msmfb_pan_display,
.fb_fillrect = msmfb_fillrect,
.fb_copyarea = msmfb_copyarea,
.fb_imageblit = msmfb_imageblit,
.fb_ioctl = msmfb_ioctl,
};
static unsigned PP[16];
#define BITS_PER_PIXEL 16
static void setup_fb_info(struct msmfb_info *msmfb)
{
struct fb_info *fb_info = msmfb->fb;
int r;
/* finish setting up the fb_info struct */
strncpy(fb_info->fix.id, "msmfb", 16);
fb_info->fix.ypanstep = 1;
fb_info->fbops = &msmfb_ops;
fb_info->flags = FBINFO_DEFAULT;
fb_info->fix.type = FB_TYPE_PACKED_PIXELS;
fb_info->fix.visual = FB_VISUAL_TRUECOLOR;
fb_info->fix.line_length = msmfb->xres * 2;
fb_info->var.xres = msmfb->xres;
fb_info->var.yres = msmfb->yres;
fb_info->var.width = msmfb->panel->fb_data->width;
fb_info->var.height = msmfb->panel->fb_data->height;
fb_info->var.xres_virtual = msmfb->xres;
fb_info->var.yres_virtual = msmfb->yres * 2;
fb_info->var.bits_per_pixel = BITS_PER_PIXEL;
fb_info->var.accel_flags = 0;
fb_info->var.yoffset = 0;
if (msmfb->panel->caps & MSMFB_CAP_PARTIAL_UPDATES) {
/*
* Set the param in the fixed screen, so userspace can't
* change it. This will be used to check for the
* capability.
*/
fb_info->fix.reserved[0] = 0x5444;
fb_info->fix.reserved[1] = 0x5055;
/*
* This preloads the value so that if userspace doesn't
* change it, it will be a full update
*/
fb_info->var.reserved[0] = 0x54445055;
fb_info->var.reserved[1] = 0;
fb_info->var.reserved[2] = (uint16_t)msmfb->xres |
((uint32_t)msmfb->yres << 16);
}
fb_info->var.red.offset = 11;
fb_info->var.red.length = 5;
fb_info->var.red.msb_right = 0;
fb_info->var.green.offset = 5;
fb_info->var.green.length = 6;
fb_info->var.green.msb_right = 0;
fb_info->var.blue.offset = 0;
fb_info->var.blue.length = 5;
fb_info->var.blue.msb_right = 0;
r = fb_alloc_cmap(&fb_info->cmap, 16, 0);
fb_info->pseudo_palette = PP;
PP[0] = 0;
for (r = 1; r < 16; r++)
PP[r] = 0xffffffff;
}
static int setup_fbmem(struct msmfb_info *msmfb, struct platform_device *pdev)
{
struct fb_info *fb = msmfb->fb;
struct resource *resource;
unsigned long size = msmfb->xres * msmfb->yres *
(BITS_PER_PIXEL >> 3) * 2;
unsigned char *fbram;
/* board file might have attached a resource describing an fb */
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!resource)
return -EINVAL;
/* check the resource is large enough to fit the fb */
if (resource->end - resource->start < size) {
printk(KERN_ERR "allocated resource is too small for "
"fb\n");
return -ENOMEM;
}
fb->fix.smem_start = resource->start;
fb->fix.smem_len = resource_size(resource);
fbram = ioremap(resource->start, resource_size(resource));
if (fbram == NULL) {
printk(KERN_ERR "msmfb: cannot allocate fbram!\n");
return -ENOMEM;
}
fb->screen_base = fbram;
return 0;
}
static int msmfb_probe(struct platform_device *pdev)
{
struct fb_info *fb;
struct msmfb_info *msmfb;
struct msm_panel_data *panel = pdev->dev.platform_data;
int ret;
if (!panel) {
pr_err("msmfb_probe: no platform data\n");
return -EINVAL;
}
if (!panel->fb_data) {
pr_err("msmfb_probe: no fb_data\n");
return -EINVAL;
}
fb = framebuffer_alloc(sizeof(struct msmfb_info), &pdev->dev);
if (!fb)
return -ENOMEM;
msmfb = fb->par;
msmfb->fb = fb;
msmfb->panel = panel;
msmfb->xres = panel->fb_data->xres;
msmfb->yres = panel->fb_data->yres;
ret = setup_fbmem(msmfb, pdev);
if (ret)
goto error_setup_fbmem;
setup_fb_info(msmfb);
spin_lock_init(&msmfb->update_lock);
mutex_init(&msmfb->panel_init_lock);
init_waitqueue_head(&msmfb->frame_wq);
INIT_WORK(&msmfb->resume_work, power_on_panel);
msmfb->black = devm_kzalloc(&pdev->dev,
msmfb->fb->var.bits_per_pixel*msmfb->xres,
GFP_KERNEL);
if (!msmfb->black) {
ret = -ENOMEM;
goto error_register_framebuffer;
}
printk(KERN_INFO "msmfb_probe() installing %d x %d panel\n",
msmfb->xres, msmfb->yres);
msmfb->dma_callback.func = msmfb_handle_dma_interrupt;
msmfb->vsync_callback.func = msmfb_handle_vsync_interrupt;
hrtimer_init(&msmfb->fake_vsync, CLOCK_MONOTONIC,
HRTIMER_MODE_REL);
msmfb->fake_vsync.function = msmfb_fake_vsync;
ret = register_framebuffer(fb);
if (ret)
goto error_register_framebuffer;
msmfb->sleeping = WAKING;
platform_set_drvdata(pdev, msmfb);
return 0;
error_register_framebuffer:
iounmap(fb->screen_base);
error_setup_fbmem:
framebuffer_release(msmfb->fb);
return ret;
}
static int msmfb_remove(struct platform_device *pdev)
{
struct msmfb_info *msmfb;
msmfb = platform_get_drvdata(pdev);
unregister_framebuffer(msmfb->fb);
iounmap(msmfb->fb->screen_base);
framebuffer_release(msmfb->fb);
return 0;
}
static struct platform_driver msm_panel_driver = {
/* need to write remove */
.probe = msmfb_probe,
.remove = msmfb_remove,
.driver = {.name = "msm_panel"},
};
static int msmfb_add_mdp_device(struct device *dev,
struct class_interface *class_intf)
{
/* might need locking if mulitple mdp devices */
if (mdp)
return 0;
mdp = container_of(dev, struct mdp_device, dev);
return platform_driver_register(&msm_panel_driver);
}
static void msmfb_remove_mdp_device(struct device *dev,
struct class_interface *class_intf)
{
/* might need locking if mulitple mdp devices */
if (dev != &mdp->dev)
return;
platform_driver_unregister(&msm_panel_driver);
mdp = NULL;
}
static struct class_interface msm_fb_interface = {
.add_dev = &msmfb_add_mdp_device,
.remove_dev = &msmfb_remove_mdp_device,
};
static int __init msmfb_init(void)
{
return register_mdp_client(&msm_fb_interface);
}
module_init(msmfb_init);

View File

@ -316,6 +316,18 @@ static int mxsfb_check_var(struct fb_var_screeninfo *var,
return 0; return 0;
} }
static inline void mxsfb_enable_axi_clk(struct mxsfb_info *host)
{
if (host->clk_axi)
clk_prepare_enable(host->clk_axi);
}
static inline void mxsfb_disable_axi_clk(struct mxsfb_info *host)
{
if (host->clk_axi)
clk_disable_unprepare(host->clk_axi);
}
static void mxsfb_enable_controller(struct fb_info *fb_info) static void mxsfb_enable_controller(struct fb_info *fb_info)
{ {
struct mxsfb_info *host = to_imxfb_host(fb_info); struct mxsfb_info *host = to_imxfb_host(fb_info);
@ -333,14 +345,13 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
} }
} }
if (host->clk_axi)
clk_prepare_enable(host->clk_axi);
if (host->clk_disp_axi) if (host->clk_disp_axi)
clk_prepare_enable(host->clk_disp_axi); clk_prepare_enable(host->clk_disp_axi);
clk_prepare_enable(host->clk); clk_prepare_enable(host->clk);
clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U); clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
mxsfb_enable_axi_clk(host);
/* if it was disabled, re-enable the mode again */ /* if it was disabled, re-enable the mode again */
writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_SET); writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_SET);
@ -380,11 +391,11 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
reg = readl(host->base + LCDC_VDCTRL4); reg = readl(host->base + LCDC_VDCTRL4);
writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4); writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4);
mxsfb_disable_axi_clk(host);
clk_disable_unprepare(host->clk); clk_disable_unprepare(host->clk);
if (host->clk_disp_axi) if (host->clk_disp_axi)
clk_disable_unprepare(host->clk_disp_axi); clk_disable_unprepare(host->clk_disp_axi);
if (host->clk_axi)
clk_disable_unprepare(host->clk_axi);
host->enabled = 0; host->enabled = 0;
@ -421,6 +432,8 @@ static int mxsfb_set_par(struct fb_info *fb_info)
mxsfb_disable_controller(fb_info); mxsfb_disable_controller(fb_info);
} }
mxsfb_enable_axi_clk(host);
/* clear the FIFOs */ /* clear the FIFOs */
writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET); writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET);
@ -438,6 +451,7 @@ static int mxsfb_set_par(struct fb_info *fb_info)
ctrl |= CTRL_SET_WORD_LENGTH(3); ctrl |= CTRL_SET_WORD_LENGTH(3);
switch (host->ld_intf_width) { switch (host->ld_intf_width) {
case STMLCDIF_8BIT: case STMLCDIF_8BIT:
mxsfb_disable_axi_clk(host);
dev_err(&host->pdev->dev, dev_err(&host->pdev->dev,
"Unsupported LCD bus width mapping\n"); "Unsupported LCD bus width mapping\n");
return -EINVAL; return -EINVAL;
@ -451,6 +465,7 @@ static int mxsfb_set_par(struct fb_info *fb_info)
writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1); writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1);
break; break;
default: default:
mxsfb_disable_axi_clk(host);
dev_err(&host->pdev->dev, "Unhandled color depth of %u\n", dev_err(&host->pdev->dev, "Unhandled color depth of %u\n",
fb_info->var.bits_per_pixel); fb_info->var.bits_per_pixel);
return -EINVAL; return -EINVAL;
@ -504,6 +519,8 @@ static int mxsfb_set_par(struct fb_info *fb_info)
fb_info->fix.line_length * fb_info->var.yoffset, fb_info->fix.line_length * fb_info->var.yoffset,
host->base + host->devdata->next_buf); host->base + host->devdata->next_buf);
mxsfb_disable_axi_clk(host);
if (reenable) if (reenable)
mxsfb_enable_controller(fb_info); mxsfb_enable_controller(fb_info);
@ -582,10 +599,14 @@ static int mxsfb_pan_display(struct fb_var_screeninfo *var,
offset = fb_info->fix.line_length * var->yoffset; offset = fb_info->fix.line_length * var->yoffset;
mxsfb_enable_axi_clk(host);
/* update on next VSYNC */ /* update on next VSYNC */
writel(fb_info->fix.smem_start + offset, writel(fb_info->fix.smem_start + offset,
host->base + host->devdata->next_buf); host->base + host->devdata->next_buf);
mxsfb_disable_axi_clk(host);
return 0; return 0;
} }
@ -608,13 +629,17 @@ static int mxsfb_restore_mode(struct mxsfb_info *host,
unsigned line_count; unsigned line_count;
unsigned period; unsigned period;
unsigned long pa, fbsize; unsigned long pa, fbsize;
int bits_per_pixel, ofs; int bits_per_pixel, ofs, ret = 0;
u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl; u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl;
mxsfb_enable_axi_clk(host);
/* Only restore the mode when the controller is running */ /* Only restore the mode when the controller is running */
ctrl = readl(host->base + LCDC_CTRL); ctrl = readl(host->base + LCDC_CTRL);
if (!(ctrl & CTRL_RUN)) if (!(ctrl & CTRL_RUN)) {
return -EINVAL; ret = -EINVAL;
goto err;
}
vdctrl0 = readl(host->base + LCDC_VDCTRL0); vdctrl0 = readl(host->base + LCDC_VDCTRL0);
vdctrl2 = readl(host->base + LCDC_VDCTRL2); vdctrl2 = readl(host->base + LCDC_VDCTRL2);
@ -635,7 +660,8 @@ static int mxsfb_restore_mode(struct mxsfb_info *host,
break; break;
case 1: case 1:
default: default:
return -EINVAL; ret = -EINVAL;
goto err;
} }
fb_info->var.bits_per_pixel = bits_per_pixel; fb_info->var.bits_per_pixel = bits_per_pixel;
@ -673,10 +699,14 @@ static int mxsfb_restore_mode(struct mxsfb_info *host,
pa = readl(host->base + host->devdata->cur_buf); pa = readl(host->base + host->devdata->cur_buf);
fbsize = fb_info->fix.line_length * vmode->yres; fbsize = fb_info->fix.line_length * vmode->yres;
if (pa < fb_info->fix.smem_start) if (pa < fb_info->fix.smem_start) {
return -EINVAL; ret = -EINVAL;
if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len) goto err;
return -EINVAL; }
if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len) {
ret = -EINVAL;
goto err;
}
ofs = pa - fb_info->fix.smem_start; ofs = pa - fb_info->fix.smem_start;
if (ofs) { if (ofs) {
memmove(fb_info->screen_base, fb_info->screen_base + ofs, fbsize); memmove(fb_info->screen_base, fb_info->screen_base + ofs, fbsize);
@ -689,7 +719,11 @@ static int mxsfb_restore_mode(struct mxsfb_info *host,
clk_prepare_enable(host->clk); clk_prepare_enable(host->clk);
host->enabled = 1; host->enabled = 1;
return 0; err:
if (ret)
mxsfb_disable_axi_clk(host);
return ret;
} }
static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host, static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host,
@ -814,7 +848,7 @@ static void mxsfb_free_videomem(struct mxsfb_info *host)
free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len); free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len);
} }
static struct platform_device_id mxsfb_devtype[] = { static const struct platform_device_id mxsfb_devtype[] = {
{ {
.name = "imx23-fb", .name = "imx23-fb",
.driver_data = MXSFB_V3, .driver_data = MXSFB_V3,
@ -915,7 +949,9 @@ static int mxsfb_probe(struct platform_device *pdev)
} }
if (!host->enabled) { if (!host->enabled) {
mxsfb_enable_axi_clk(host);
writel(0, host->base + LCDC_CTRL); writel(0, host->base + LCDC_CTRL);
mxsfb_disable_axi_clk(host);
mxsfb_set_par(fb_info); mxsfb_set_par(fb_info);
mxsfb_enable_controller(fb_info); mxsfb_enable_controller(fb_info);
} }
@ -954,11 +990,15 @@ static void mxsfb_shutdown(struct platform_device *pdev)
struct fb_info *fb_info = platform_get_drvdata(pdev); struct fb_info *fb_info = platform_get_drvdata(pdev);
struct mxsfb_info *host = to_imxfb_host(fb_info); struct mxsfb_info *host = to_imxfb_host(fb_info);
mxsfb_enable_axi_clk(host);
/* /*
* Force stop the LCD controller as keeping it running during reboot * Force stop the LCD controller as keeping it running during reboot
* might interfere with the BootROM's boot mode pads sampling. * might interfere with the BootROM's boot mode pads sampling.
*/ */
writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR); writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR);
mxsfb_disable_axi_clk(host);
} }
static struct platform_driver mxsfb_driver = { static struct platform_driver mxsfb_driver = {

View File

@ -71,11 +71,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include <video/vga.h> #include <video/vga.h>
#include <video/neomagic.h> #include <video/neomagic.h>
@ -1710,6 +1705,7 @@ static int neo_map_video(struct fb_info *info, struct pci_dev *dev,
int video_len) int video_len)
{ {
//unsigned long addr; //unsigned long addr;
struct neofb_par *par = info->par;
DBG("neo_map_video"); DBG("neo_map_video");
@ -1723,7 +1719,7 @@ static int neo_map_video(struct fb_info *info, struct pci_dev *dev,
} }
info->screen_base = info->screen_base =
ioremap(info->fix.smem_start, info->fix.smem_len); ioremap_wc(info->fix.smem_start, info->fix.smem_len);
if (!info->screen_base) { if (!info->screen_base) {
printk("neofb: unable to map screen memory\n"); printk("neofb: unable to map screen memory\n");
release_mem_region(info->fix.smem_start, release_mem_region(info->fix.smem_start,
@ -1733,11 +1729,8 @@ static int neo_map_video(struct fb_info *info, struct pci_dev *dev,
printk(KERN_INFO "neofb: mapped framebuffer at %p\n", printk(KERN_INFO "neofb: mapped framebuffer at %p\n",
info->screen_base); info->screen_base);
#ifdef CONFIG_MTRR par->wc_cookie = arch_phys_wc_add(info->fix.smem_start,
((struct neofb_par *)(info->par))->mtrr = pci_resource_len(dev, 0));
mtrr_add(info->fix.smem_start, pci_resource_len(dev, 0),
MTRR_TYPE_WRCOMB, 1);
#endif
/* Clear framebuffer, it's all white in memory after boot */ /* Clear framebuffer, it's all white in memory after boot */
memset_io(info->screen_base, 0, info->fix.smem_len); memset_io(info->screen_base, 0, info->fix.smem_len);
@ -1754,16 +1747,11 @@ static int neo_map_video(struct fb_info *info, struct pci_dev *dev,
static void neo_unmap_video(struct fb_info *info) static void neo_unmap_video(struct fb_info *info)
{ {
struct neofb_par *par = info->par;
DBG("neo_unmap_video"); DBG("neo_unmap_video");
#ifdef CONFIG_MTRR arch_phys_wc_del(par->wc_cookie);
{
struct neofb_par *par = info->par;
mtrr_del(par->mtrr, info->fix.smem_start,
info->fix.smem_len);
}
#endif
iounmap(info->screen_base); iounmap(info->screen_base);
info->screen_base = NULL; info->screen_base = NULL;

View File

@ -148,12 +148,7 @@ struct nvidia_par {
u32 forceCRTC; u32 forceCRTC;
u32 open_count; u32 open_count;
u8 DDCBase; u8 DDCBase;
#ifdef CONFIG_MTRR int wc_cookie;
struct {
int vram;
int vram_valid;
} mtrr;
#endif
struct nvidia_i2c_chan chan[3]; struct nvidia_i2c_chan chan[3];
volatile u32 __iomem *REGS; volatile u32 __iomem *REGS;

View File

@ -21,9 +21,6 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/console.h> #include <linux/console.h>
#include <linux/backlight.h> #include <linux/backlight.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#ifdef CONFIG_BOOTX_TEXT #ifdef CONFIG_BOOTX_TEXT
#include <asm/btext.h> #include <asm/btext.h>
#endif #endif
@ -76,9 +73,7 @@ static int paneltweak = 0;
static int vram = 0; static int vram = 0;
static int bpp = 8; static int bpp = 8;
static int reverse_i2c; static int reverse_i2c;
#ifdef CONFIG_MTRR
static bool nomtrr = false; static bool nomtrr = false;
#endif
#ifdef CONFIG_PMAC_BACKLIGHT #ifdef CONFIG_PMAC_BACKLIGHT
static int backlight = 1; static int backlight = 1;
#else #else
@ -1361,7 +1356,8 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize; par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
par->CursorStart = par->FbUsableSize + (32 * 1024); par->CursorStart = par->FbUsableSize + (32 * 1024);
info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize); info->screen_base = ioremap_wc(nvidiafb_fix.smem_start,
par->FbMapSize);
info->screen_size = par->FbUsableSize; info->screen_size = par->FbUsableSize;
nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024; nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
@ -1372,20 +1368,9 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
par->FbStart = info->screen_base; par->FbStart = info->screen_base;
#ifdef CONFIG_MTRR if (!nomtrr)
if (!nomtrr) { par->wc_cookie = arch_phys_wc_add(nvidiafb_fix.smem_start,
par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start, par->RamAmountKBytes * 1024);
par->RamAmountKBytes * 1024,
MTRR_TYPE_WRCOMB, 1);
if (par->mtrr.vram < 0) {
printk(KERN_ERR PFX "unable to setup MTRR\n");
} else {
par->mtrr.vram_valid = 1;
/* let there be speed */
printk(KERN_INFO PFX "MTRR set to ON\n");
}
}
#endif /* CONFIG_MTRR */
info->fbops = &nvidia_fb_ops; info->fbops = &nvidia_fb_ops;
info->fix = nvidiafb_fix; info->fix = nvidiafb_fix;
@ -1443,13 +1428,7 @@ static void nvidiafb_remove(struct pci_dev *pd)
unregister_framebuffer(info); unregister_framebuffer(info);
nvidia_bl_exit(par); nvidia_bl_exit(par);
arch_phys_wc_del(par->wc_cookie);
#ifdef CONFIG_MTRR
if (par->mtrr.vram_valid)
mtrr_del(par->mtrr.vram, info->fix.smem_start,
info->fix.smem_len);
#endif /* CONFIG_MTRR */
iounmap(info->screen_base); iounmap(info->screen_base);
fb_destroy_modedb(info->monspecs.modedb); fb_destroy_modedb(info->monspecs.modedb);
nvidia_delete_i2c_busses(par); nvidia_delete_i2c_busses(par);
@ -1501,10 +1480,8 @@ static int nvidiafb_setup(char *options)
vram = simple_strtoul(this_opt+5, NULL, 0); vram = simple_strtoul(this_opt+5, NULL, 0);
} else if (!strncmp(this_opt, "backlight:", 10)) { } else if (!strncmp(this_opt, "backlight:", 10)) {
backlight = simple_strtoul(this_opt+10, NULL, 0); backlight = simple_strtoul(this_opt+10, NULL, 0);
#ifdef CONFIG_MTRR
} else if (!strncmp(this_opt, "nomtrr", 6)) { } else if (!strncmp(this_opt, "nomtrr", 6)) {
nomtrr = true; nomtrr = true;
#endif
} else if (!strncmp(this_opt, "fpdither:", 9)) { } else if (!strncmp(this_opt, "fpdither:", 9)) {
fpdither = simple_strtol(this_opt+9, NULL, 0); fpdither = simple_strtol(this_opt+9, NULL, 0);
} else if (!strncmp(this_opt, "bpp:", 4)) { } else if (!strncmp(this_opt, "bpp:", 4)) {
@ -1592,11 +1569,9 @@ MODULE_PARM_DESC(bpp, "pixel width in bits"
"(default=8)"); "(default=8)");
module_param(reverse_i2c, int, 0); module_param(reverse_i2c, int, 0);
MODULE_PARM_DESC(reverse_i2c, "reverse port assignment of the i2c bus"); MODULE_PARM_DESC(reverse_i2c, "reverse port assignment of the i2c bus");
#ifdef CONFIG_MTRR
module_param(nomtrr, bool, false); module_param(nomtrr, bool, false);
MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
"(default=0)"); "(default=0)");
#endif
MODULE_AUTHOR("Antonino Daplas"); MODULE_AUTHOR("Antonino Daplas");
MODULE_DESCRIPTION("Framebuffer driver for nVidia graphics chipset"); MODULE_DESCRIPTION("Framebuffer driver for nVidia graphics chipset");

View File

@ -42,7 +42,7 @@ config FB_OMAP_LCD_MIPID
config FB_OMAP_LCD_H3 config FB_OMAP_LCD_H3
bool "TPS65010 LCD controller on OMAP-H3" bool "TPS65010 LCD controller on OMAP-H3"
depends on MACH_OMAP_H3 depends on MACH_OMAP_H3
depends on TPS65010 depends on TPS65010=y
default y default y
help help
Say Y here if you want to have support for the LCD on the Say Y here if you want to have support for the LCD on the

View File

@ -201,15 +201,9 @@ static int opa362_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata); platform_set_drvdata(pdev, ddata);
gpio = devm_gpiod_get(&pdev->dev, "enable"); gpio = devm_gpiod_get_optional(&pdev->dev, "enable", GPIOD_OUT_LOW);
if (IS_ERR(gpio)) { if (IS_ERR(gpio))
if (PTR_ERR(gpio) != -ENOENT) return PTR_ERR(gpio);
return PTR_ERR(gpio);
gpio = NULL;
} else {
gpiod_direction_output(gpio, 0);
}
ddata->enable_gpio = gpio; ddata->enable_gpio = gpio;

View File

@ -209,16 +209,9 @@ static int panel_dpi_probe_of(struct platform_device *pdev)
struct videomode vm; struct videomode vm;
struct gpio_desc *gpio; struct gpio_desc *gpio;
gpio = devm_gpiod_get(&pdev->dev, "enable"); gpio = devm_gpiod_get_optional(&pdev->dev, "enable", GPIOD_OUT_LOW);
if (IS_ERR(gpio))
if (IS_ERR(gpio)) { return PTR_ERR(gpio);
if (PTR_ERR(gpio) != -ENOENT)
return PTR_ERR(gpio);
else
gpio = NULL;
} else {
gpiod_direction_output(gpio, 0);
}
ddata->enable_gpio = gpio; ddata->enable_gpio = gpio;

View File

@ -285,15 +285,14 @@ static int lb035q02_probe_of(struct spi_device *spi)
struct omap_dss_device *in; struct omap_dss_device *in;
struct gpio_desc *gpio; struct gpio_desc *gpio;
gpio = devm_gpiod_get(&spi->dev, "enable"); gpio = devm_gpiod_get(&spi->dev, "enable", GPIOD_OUT_LOW);
if (IS_ERR(gpio)) { if (IS_ERR(gpio)) {
dev_err(&spi->dev, "failed to parse enable gpio\n"); dev_err(&spi->dev, "failed to parse enable gpio\n");
return PTR_ERR(gpio); return PTR_ERR(gpio);
} else {
gpiod_direction_output(gpio, 0);
ddata->enable_gpio = gpio;
} }
ddata->enable_gpio = gpio;
ddata->backlight_gpio = -ENOENT; ddata->backlight_gpio = -ENOENT;
in = omapdss_of_find_source_for_first_ep(node); in = omapdss_of_find_source_for_first_ep(node);

View File

@ -268,17 +268,12 @@ static int sharp_ls_get_gpio_of(struct device *dev, int index, int val,
const char *desc, struct gpio_desc **gpiod) const char *desc, struct gpio_desc **gpiod)
{ {
struct gpio_desc *gd; struct gpio_desc *gd;
int r;
*gpiod = NULL; *gpiod = NULL;
gd = devm_gpiod_get_index(dev, desc, index); gd = devm_gpiod_get_index(dev, desc, index, GPIOD_OUT_LOW);
if (IS_ERR(gd)) if (IS_ERR(gd))
return PTR_ERR(gd) == -ENOENT ? 0 : PTR_ERR(gd); return PTR_ERR(gd);
r = gpiod_direction_output(gd, val);
if (r)
return r;
*gpiod = gd; *gpiod = gd;
return 0; return 0;

View File

@ -50,8 +50,6 @@ static char *def_disp_name;
module_param_named(def_disp, def_disp_name, charp, 0); module_param_named(def_disp, def_disp_name, charp, 0);
MODULE_PARM_DESC(def_disp, "default display name"); MODULE_PARM_DESC(def_disp, "default display name");
static bool dss_initialized;
const char *omapdss_get_default_display_name(void) const char *omapdss_get_default_display_name(void)
{ {
return core.default_display_name; return core.default_display_name;
@ -65,12 +63,6 @@ enum omapdss_version omapdss_get_version(void)
} }
EXPORT_SYMBOL(omapdss_get_version); EXPORT_SYMBOL(omapdss_get_version);
bool omapdss_is_initialized(void)
{
return dss_initialized;
}
EXPORT_SYMBOL(omapdss_is_initialized);
struct platform_device *dss_get_core_pdev(void) struct platform_device *dss_get_core_pdev(void)
{ {
return core.pdev; return core.pdev;
@ -253,6 +245,8 @@ static struct platform_driver omap_dss_driver = {
/* INIT */ /* INIT */
static int (*dss_output_drv_reg_funcs[])(void) __initdata = { static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
dss_init_platform_driver,
dispc_init_platform_driver,
#ifdef CONFIG_OMAP2_DSS_DSI #ifdef CONFIG_OMAP2_DSS_DSI
dsi_init_platform_driver, dsi_init_platform_driver,
#endif #endif
@ -276,32 +270,32 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
#endif #endif
}; };
static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { static void (*dss_output_drv_unreg_funcs[])(void) = {
#ifdef CONFIG_OMAP2_DSS_DSI #ifdef CONFIG_OMAP5_DSS_HDMI
dsi_uninit_platform_driver, hdmi5_uninit_platform_driver,
#endif
#ifdef CONFIG_OMAP2_DSS_DPI
dpi_uninit_platform_driver,
#endif
#ifdef CONFIG_OMAP2_DSS_SDI
sdi_uninit_platform_driver,
#endif
#ifdef CONFIG_OMAP2_DSS_RFBI
rfbi_uninit_platform_driver,
#endif
#ifdef CONFIG_OMAP2_DSS_VENC
venc_uninit_platform_driver,
#endif #endif
#ifdef CONFIG_OMAP4_DSS_HDMI #ifdef CONFIG_OMAP4_DSS_HDMI
hdmi4_uninit_platform_driver, hdmi4_uninit_platform_driver,
#endif #endif
#ifdef CONFIG_OMAP5_DSS_HDMI #ifdef CONFIG_OMAP2_DSS_VENC
hdmi5_uninit_platform_driver, venc_uninit_platform_driver,
#endif #endif
#ifdef CONFIG_OMAP2_DSS_RFBI
rfbi_uninit_platform_driver,
#endif
#ifdef CONFIG_OMAP2_DSS_SDI
sdi_uninit_platform_driver,
#endif
#ifdef CONFIG_OMAP2_DSS_DPI
dpi_uninit_platform_driver,
#endif
#ifdef CONFIG_OMAP2_DSS_DSI
dsi_uninit_platform_driver,
#endif
dispc_uninit_platform_driver,
dss_uninit_platform_driver,
}; };
static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)];
static int __init omap_dss_init(void) static int __init omap_dss_init(void)
{ {
int r; int r;
@ -311,35 +305,20 @@ static int __init omap_dss_init(void)
if (r) if (r)
return r; return r;
r = dss_init_platform_driver();
if (r) {
DSSERR("Failed to initialize DSS platform driver\n");
goto err_dss;
}
r = dispc_init_platform_driver();
if (r) {
DSSERR("Failed to initialize dispc platform driver\n");
goto err_dispc;
}
/*
* It's ok if the output-driver register fails. It happens, for example,
* when there is no output-device (e.g. SDI for OMAP4).
*/
for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) { for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) {
r = dss_output_drv_reg_funcs[i](); r = dss_output_drv_reg_funcs[i]();
if (r == 0) if (r)
dss_output_drv_loaded[i] = true; goto err_reg;
} }
dss_initialized = true;
return 0; return 0;
err_dispc: err_reg:
dss_uninit_platform_driver(); for (i = ARRAY_SIZE(dss_output_drv_reg_funcs) - i;
err_dss: i < ARRAY_SIZE(dss_output_drv_reg_funcs);
++i)
dss_output_drv_unreg_funcs[i]();
platform_driver_unregister(&omap_dss_driver); platform_driver_unregister(&omap_dss_driver);
return r; return r;
@ -349,13 +328,8 @@ static void __exit omap_dss_exit(void)
{ {
int i; int i;
for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i) { for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i)
if (dss_output_drv_loaded[i]) dss_output_drv_unreg_funcs[i]();
dss_output_drv_unreg_funcs[i]();
}
dispc_uninit_platform_driver();
dss_uninit_platform_driver();
platform_driver_unregister(&omap_dss_driver); platform_driver_unregister(&omap_dss_driver);
} }

View File

@ -39,6 +39,7 @@
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/component.h>
#include <video/omapdss.h> #include <video/omapdss.h>
@ -95,6 +96,9 @@ struct dispc_features {
bool mstandby_workaround:1; bool mstandby_workaround:1;
bool set_max_preload:1; bool set_max_preload:1;
/* PIXEL_INC is not added to the last pixel of a line */
bool last_pixel_inc_missing:1;
}; };
#define DISPC_MAX_NR_FIFOS 5 #define DISPC_MAX_NR_FIFOS 5
@ -1741,6 +1745,15 @@ static void dispc_ovl_set_rotation_attrs(enum omap_plane plane, u8 rotation,
row_repeat = false; row_repeat = false;
} }
/*
* OMAP4/5 Errata i631:
* NV12 in 1D mode must use ROTATION=1. Otherwise DSS will fetch extra
* rows beyond the framebuffer, which may cause OCP error.
*/
if (color_mode == OMAP_DSS_COLOR_NV12 &&
rotation_type != OMAP_DSS_ROT_TILER)
vidrot = 1;
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), vidrot, 13, 12); REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), vidrot, 13, 12);
if (dss_has_feature(FEAT_ROWREPEATENABLE)) if (dss_has_feature(FEAT_ROWREPEATENABLE))
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane),
@ -2154,7 +2167,7 @@ static unsigned long calc_core_clk_five_taps(unsigned long pclk,
if (height > out_height) { if (height > out_height) {
unsigned int ppl = mgr_timings->x_res; unsigned int ppl = mgr_timings->x_res;
tmp = pclk * height * out_width; tmp = (u64)pclk * height * out_width;
do_div(tmp, 2 * out_height * ppl); do_div(tmp, 2 * out_height * ppl);
core_clk = tmp; core_clk = tmp;
@ -2162,14 +2175,14 @@ static unsigned long calc_core_clk_five_taps(unsigned long pclk,
if (ppl == out_width) if (ppl == out_width)
return 0; return 0;
tmp = pclk * (height - 2 * out_height) * out_width; tmp = (u64)pclk * (height - 2 * out_height) * out_width;
do_div(tmp, 2 * out_height * (ppl - out_width)); do_div(tmp, 2 * out_height * (ppl - out_width));
core_clk = max_t(u32, core_clk, tmp); core_clk = max_t(u32, core_clk, tmp);
} }
} }
if (width > out_width) { if (width > out_width) {
tmp = pclk * width; tmp = (u64)pclk * width;
do_div(tmp, out_width); do_div(tmp, out_width);
core_clk = max_t(u32, core_clk, tmp); core_clk = max_t(u32, core_clk, tmp);
@ -2267,6 +2280,11 @@ static int dispc_ovl_calc_scaling_24xx(unsigned long pclk, unsigned long lclk,
} }
} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error); } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
if (error) {
DSSERR("failed to find scaling settings\n");
return -EINVAL;
}
if (in_width > maxsinglelinewidth) { if (in_width > maxsinglelinewidth) {
DSSERR("Cannot scale max input width exceeded"); DSSERR("Cannot scale max input width exceeded");
return -EINVAL; return -EINVAL;
@ -2283,7 +2301,6 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
{ {
int error; int error;
u16 in_width, in_height; u16 in_width, in_height;
int min_factor = min(*decim_x, *decim_y);
const int maxsinglelinewidth = const int maxsinglelinewidth =
dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
@ -2317,20 +2334,32 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
error = (error || in_width > maxsinglelinewidth * 2 || error = (error || in_width > maxsinglelinewidth * 2 ||
(in_width > maxsinglelinewidth && *five_taps) || (in_width > maxsinglelinewidth && *five_taps) ||
!*core_clk || *core_clk > dispc_core_clk_rate()); !*core_clk || *core_clk > dispc_core_clk_rate());
if (error) {
if (*decim_x == *decim_y) { if (!error) {
*decim_x = min_factor; /* verify that we're inside the limits of scaler */
++*decim_y; if (in_width / 4 > out_width)
error = 1;
if (*five_taps) {
if (in_height / 4 > out_height)
error = 1;
} else { } else {
swap(*decim_x, *decim_y); if (in_height / 2 > out_height)
if (*decim_x < *decim_y) error = 1;
++*decim_x;
} }
} }
if (error)
++*decim_y;
} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error); } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, width, if (error) {
height, out_width, out_height, *five_taps)) { DSSERR("failed to find scaling settings\n");
return -EINVAL;
}
if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, in_width,
in_height, out_width, out_height, *five_taps)) {
DSSERR("horizontal timing too tight\n"); DSSERR("horizontal timing too tight\n");
return -EINVAL; return -EINVAL;
} }
@ -2390,6 +2419,9 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk,
return 0; return 0;
} }
#define DIV_FRAC(dividend, divisor) \
((dividend) * 100 / (divisor) - ((dividend) / (divisor) * 100))
static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk, static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
enum omap_overlay_caps caps, enum omap_overlay_caps caps,
const struct omap_video_timings *mgr_timings, const struct omap_video_timings *mgr_timings,
@ -2449,8 +2481,19 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
if (ret) if (ret)
return ret; return ret;
DSSDBG("required core clk rate = %lu Hz\n", core_clk); DSSDBG("%dx%d -> %dx%d (%d.%02d x %d.%02d), decim %dx%d %dx%d (%d.%02d x %d.%02d), taps %d, req clk %lu, cur clk %lu\n",
DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate()); width, height,
out_width, out_height,
out_width / width, DIV_FRAC(out_width, width),
out_height / height, DIV_FRAC(out_height, height),
decim_x, decim_y,
width / decim_x, height / decim_y,
out_width / (width / decim_x), DIV_FRAC(out_width, width / decim_x),
out_height / (height / decim_y), DIV_FRAC(out_height, height / decim_y),
*five_taps ? 5 : 3,
core_clk, dispc_core_clk_rate());
if (!core_clk || core_clk > dispc_core_clk_rate()) { if (!core_clk || core_clk > dispc_core_clk_rate()) {
DSSERR("failed to set up scaling, " DSSERR("failed to set up scaling, "
@ -2533,6 +2576,21 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
if (paddr == 0 && rotation_type != OMAP_DSS_ROT_TILER) if (paddr == 0 && rotation_type != OMAP_DSS_ROT_TILER)
return -EINVAL; return -EINVAL;
switch (color_mode) {
case OMAP_DSS_COLOR_YUV2:
case OMAP_DSS_COLOR_UYVY:
case OMAP_DSS_COLOR_NV12:
if (in_width & 1) {
DSSERR("input width %d is not even for YUV format\n",
in_width);
return -EINVAL;
}
break;
default:
break;
}
out_width = out_width == 0 ? width : out_width; out_width = out_width == 0 ? width : out_width;
out_height = out_height == 0 ? height : out_height; out_height = out_height == 0 ? height : out_height;
@ -2563,6 +2621,27 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
in_width = in_width / x_predecim; in_width = in_width / x_predecim;
in_height = in_height / y_predecim; in_height = in_height / y_predecim;
if (x_predecim > 1 || y_predecim > 1)
DSSDBG("predecimation %d x %x, new input size %d x %d\n",
x_predecim, y_predecim, in_width, in_height);
switch (color_mode) {
case OMAP_DSS_COLOR_YUV2:
case OMAP_DSS_COLOR_UYVY:
case OMAP_DSS_COLOR_NV12:
if (in_width & 1) {
DSSDBG("predecimated input width is not even for YUV format\n");
DSSDBG("adjusting input width %d -> %d\n",
in_width, in_width & ~1);
in_width &= ~1;
}
break;
default:
break;
}
if (color_mode == OMAP_DSS_COLOR_YUV2 || if (color_mode == OMAP_DSS_COLOR_YUV2 ||
color_mode == OMAP_DSS_COLOR_UYVY || color_mode == OMAP_DSS_COLOR_UYVY ||
color_mode == OMAP_DSS_COLOR_NV12) color_mode == OMAP_DSS_COLOR_NV12)
@ -2632,6 +2711,9 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
dispc_ovl_set_ba1_uv(plane, p_uv_addr + offset1); dispc_ovl_set_ba1_uv(plane, p_uv_addr + offset1);
} }
if (dispc.feat->last_pixel_inc_missing)
row_inc += pix_inc - 1;
dispc_ovl_set_row_inc(plane, row_inc); dispc_ovl_set_row_inc(plane, row_inc);
dispc_ovl_set_pix_inc(plane, pix_inc); dispc_ovl_set_pix_inc(plane, pix_inc);
@ -3692,7 +3774,7 @@ static void _omap_dispc_initial_config(void)
dispc_init_mflag(); dispc_init_mflag();
} }
static const struct dispc_features omap24xx_dispc_feats __initconst = { static const struct dispc_features omap24xx_dispc_feats = {
.sw_start = 5, .sw_start = 5,
.fp_start = 15, .fp_start = 15,
.bp_start = 27, .bp_start = 27,
@ -3709,9 +3791,10 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
.num_fifos = 3, .num_fifos = 3,
.no_framedone_tv = true, .no_framedone_tv = true,
.set_max_preload = false, .set_max_preload = false,
.last_pixel_inc_missing = true,
}; };
static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = { static const struct dispc_features omap34xx_rev1_0_dispc_feats = {
.sw_start = 5, .sw_start = 5,
.fp_start = 15, .fp_start = 15,
.bp_start = 27, .bp_start = 27,
@ -3729,9 +3812,10 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
.num_fifos = 3, .num_fifos = 3,
.no_framedone_tv = true, .no_framedone_tv = true,
.set_max_preload = false, .set_max_preload = false,
.last_pixel_inc_missing = true,
}; };
static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = { static const struct dispc_features omap34xx_rev3_0_dispc_feats = {
.sw_start = 7, .sw_start = 7,
.fp_start = 19, .fp_start = 19,
.bp_start = 31, .bp_start = 31,
@ -3749,9 +3833,10 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
.num_fifos = 3, .num_fifos = 3,
.no_framedone_tv = true, .no_framedone_tv = true,
.set_max_preload = false, .set_max_preload = false,
.last_pixel_inc_missing = true,
}; };
static const struct dispc_features omap44xx_dispc_feats __initconst = { static const struct dispc_features omap44xx_dispc_feats = {
.sw_start = 7, .sw_start = 7,
.fp_start = 19, .fp_start = 19,
.bp_start = 31, .bp_start = 31,
@ -3771,7 +3856,7 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
.set_max_preload = true, .set_max_preload = true,
}; };
static const struct dispc_features omap54xx_dispc_feats __initconst = { static const struct dispc_features omap54xx_dispc_feats = {
.sw_start = 7, .sw_start = 7,
.fp_start = 19, .fp_start = 19,
.bp_start = 31, .bp_start = 31,
@ -3792,7 +3877,7 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = {
.set_max_preload = true, .set_max_preload = true,
}; };
static int __init dispc_init_features(struct platform_device *pdev) static int dispc_init_features(struct platform_device *pdev)
{ {
const struct dispc_features *src; const struct dispc_features *src;
struct dispc_features *dst; struct dispc_features *dst;
@ -3882,8 +3967,9 @@ void dispc_free_irq(void *dev_id)
EXPORT_SYMBOL(dispc_free_irq); EXPORT_SYMBOL(dispc_free_irq);
/* DISPC HW IP initialisation */ /* DISPC HW IP initialisation */
static int __init omap_dispchw_probe(struct platform_device *pdev) static int dispc_bind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev);
u32 rev; u32 rev;
int r = 0; int r = 0;
struct resource *dispc_mem; struct resource *dispc_mem;
@ -3955,12 +4041,27 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
return r; return r;
} }
static int __exit omap_dispchw_remove(struct platform_device *pdev) static void dispc_unbind(struct device *dev, struct device *master,
void *data)
{ {
pm_runtime_disable(&pdev->dev); pm_runtime_disable(dev);
dss_uninit_overlay_managers(); dss_uninit_overlay_managers();
}
static const struct component_ops dispc_component_ops = {
.bind = dispc_bind,
.unbind = dispc_unbind,
};
static int dispc_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &dispc_component_ops);
}
static int dispc_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &dispc_component_ops);
return 0; return 0;
} }
@ -4013,7 +4114,8 @@ static const struct of_device_id dispc_of_match[] = {
}; };
static struct platform_driver omap_dispchw_driver = { static struct platform_driver omap_dispchw_driver = {
.remove = __exit_p(omap_dispchw_remove), .probe = dispc_probe,
.remove = dispc_remove,
.driver = { .driver = {
.name = "omapdss_dispc", .name = "omapdss_dispc",
.pm = &dispc_pm_ops, .pm = &dispc_pm_ops,
@ -4024,10 +4126,10 @@ static struct platform_driver omap_dispchw_driver = {
int __init dispc_init_platform_driver(void) int __init dispc_init_platform_driver(void)
{ {
return platform_driver_probe(&omap_dispchw_driver, omap_dispchw_probe); return platform_driver_register(&omap_dispchw_driver);
} }
void __exit dispc_uninit_platform_driver(void) void dispc_uninit_platform_driver(void)
{ {
platform_driver_unregister(&omap_dispchw_driver); platform_driver_unregister(&omap_dispchw_driver);
} }

View File

@ -324,7 +324,7 @@ int display_init_sysfs(struct platform_device *pdev)
for_each_dss_dev(dssdev) { for_each_dss_dev(dssdev) {
r = kobject_init_and_add(&dssdev->kobj, &display_ktype, r = kobject_init_and_add(&dssdev->kobj, &display_ktype,
&pdev->dev.kobj, dssdev->alias); &pdev->dev.kobj, "%s", dssdev->alias);
if (r) { if (r) {
DSSERR("failed to create sysfs files\n"); DSSERR("failed to create sysfs files\n");
omap_dss_put_device(dssdev); omap_dss_put_device(dssdev);

View File

@ -32,6 +32,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/component.h>
#include <video/omapdss.h> #include <video/omapdss.h>
@ -731,7 +732,7 @@ static void dpi_init_output(struct platform_device *pdev)
omapdss_register_output(out); omapdss_register_output(out);
} }
static void __exit dpi_uninit_output(struct platform_device *pdev) static void dpi_uninit_output(struct platform_device *pdev)
{ {
struct dpi_data *dpi = dpi_get_data_from_pdev(pdev); struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
struct omap_dss_device *out = &dpi->output; struct omap_dss_device *out = &dpi->output;
@ -775,7 +776,7 @@ static void dpi_init_output_port(struct platform_device *pdev,
omapdss_register_output(out); omapdss_register_output(out);
} }
static void __exit dpi_uninit_output_port(struct device_node *port) static void dpi_uninit_output_port(struct device_node *port)
{ {
struct dpi_data *dpi = port->data; struct dpi_data *dpi = port->data;
struct omap_dss_device *out = &dpi->output; struct omap_dss_device *out = &dpi->output;
@ -783,8 +784,9 @@ static void __exit dpi_uninit_output_port(struct device_node *port)
omapdss_unregister_output(out); omapdss_unregister_output(out);
} }
static int omap_dpi_probe(struct platform_device *pdev) static int dpi_bind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev);
struct dpi_data *dpi; struct dpi_data *dpi;
dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL); dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
@ -802,16 +804,32 @@ static int omap_dpi_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int __exit omap_dpi_remove(struct platform_device *pdev) static void dpi_unbind(struct device *dev, struct device *master, void *data)
{ {
dpi_uninit_output(pdev); struct platform_device *pdev = to_platform_device(dev);
dpi_uninit_output(pdev);
}
static const struct component_ops dpi_component_ops = {
.bind = dpi_bind,
.unbind = dpi_unbind,
};
static int dpi_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &dpi_component_ops);
}
static int dpi_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &dpi_component_ops);
return 0; return 0;
} }
static struct platform_driver omap_dpi_driver = { static struct platform_driver omap_dpi_driver = {
.probe = omap_dpi_probe, .probe = dpi_probe,
.remove = __exit_p(omap_dpi_remove), .remove = dpi_remove,
.driver = { .driver = {
.name = "omapdss_dpi", .name = "omapdss_dpi",
.suppress_bind_attrs = true, .suppress_bind_attrs = true,
@ -823,12 +841,12 @@ int __init dpi_init_platform_driver(void)
return platform_driver_register(&omap_dpi_driver); return platform_driver_register(&omap_dpi_driver);
} }
void __exit dpi_uninit_platform_driver(void) void dpi_uninit_platform_driver(void)
{ {
platform_driver_unregister(&omap_dpi_driver); platform_driver_unregister(&omap_dpi_driver);
} }
int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) int dpi_init_port(struct platform_device *pdev, struct device_node *port)
{ {
struct dpi_data *dpi; struct dpi_data *dpi;
struct device_node *ep; struct device_node *ep;
@ -870,7 +888,7 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
return r; return r;
} }
void __exit dpi_uninit_port(struct device_node *port) void dpi_uninit_port(struct device_node *port)
{ {
struct dpi_data *dpi = port->data; struct dpi_data *dpi = port->data;

View File

@ -40,6 +40,7 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/component.h>
#include <video/omapdss.h> #include <video/omapdss.h>
#include <video/mipi_display.h> #include <video/mipi_display.h>
@ -5274,8 +5275,9 @@ static int dsi_init_pll_data(struct platform_device *dsidev)
} }
/* DSI1 HW IP initialisation */ /* DSI1 HW IP initialisation */
static int omap_dsihw_probe(struct platform_device *dsidev) static int dsi_bind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *dsidev = to_platform_device(dev);
u32 rev; u32 rev;
int r, i; int r, i;
struct dsi_data *dsi; struct dsi_data *dsi;
@ -5484,8 +5486,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
return r; return r;
} }
static int __exit omap_dsihw_remove(struct platform_device *dsidev) static void dsi_unbind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *dsidev = to_platform_device(dev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
of_platform_depopulate(&dsidev->dev); of_platform_depopulate(&dsidev->dev);
@ -5502,7 +5505,21 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
regulator_disable(dsi->vdds_dsi_reg); regulator_disable(dsi->vdds_dsi_reg);
dsi->vdds_dsi_enabled = false; dsi->vdds_dsi_enabled = false;
} }
}
static const struct component_ops dsi_component_ops = {
.bind = dsi_bind,
.unbind = dsi_unbind,
};
static int dsi_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &dsi_component_ops);
}
static int dsi_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &dsi_component_ops);
return 0; return 0;
} }
@ -5569,8 +5586,8 @@ static const struct of_device_id dsi_of_match[] = {
}; };
static struct platform_driver omap_dsihw_driver = { static struct platform_driver omap_dsihw_driver = {
.probe = omap_dsihw_probe, .probe = dsi_probe,
.remove = __exit_p(omap_dsihw_remove), .remove = dsi_remove,
.driver = { .driver = {
.name = "omapdss_dsi", .name = "omapdss_dsi",
.pm = &dsi_pm_ops, .pm = &dsi_pm_ops,
@ -5584,7 +5601,7 @@ int __init dsi_init_platform_driver(void)
return platform_driver_register(&omap_dsihw_driver); return platform_driver_register(&omap_dsihw_driver);
} }
void __exit dsi_uninit_platform_driver(void) void dsi_uninit_platform_driver(void)
{ {
platform_driver_unregister(&omap_dsihw_driver); platform_driver_unregister(&omap_dsihw_driver);
} }

View File

@ -39,6 +39,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/component.h>
#include <video/omapdss.h> #include <video/omapdss.h>
@ -111,6 +112,14 @@ static const char * const dss_generic_clk_source_names[] = {
[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DSI_PLL2_HSDIV_DSI", [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DSI_PLL2_HSDIV_DSI",
}; };
static bool dss_initialized;
bool omapdss_is_initialized(void)
{
return dss_initialized;
}
EXPORT_SYMBOL(omapdss_is_initialized);
static inline void dss_write_reg(const struct dss_reg idx, u32 val) static inline void dss_write_reg(const struct dss_reg idx, u32 val)
{ {
__raw_writel(val, dss.base + idx.idx); __raw_writel(val, dss.base + idx.idx);
@ -811,7 +820,7 @@ static const enum omap_display_type dra7xx_ports[] = {
OMAP_DISPLAY_TYPE_DPI, OMAP_DISPLAY_TYPE_DPI,
}; };
static const struct dss_features omap24xx_dss_feats __initconst = { static const struct dss_features omap24xx_dss_feats = {
/* /*
* fck div max is really 16, but the divider range has gaps. The range * fck div max is really 16, but the divider range has gaps. The range
* from 1 to 6 has no gaps, so let's use that as a max. * from 1 to 6 has no gaps, so let's use that as a max.
@ -824,7 +833,7 @@ static const struct dss_features omap24xx_dss_feats __initconst = {
.num_ports = ARRAY_SIZE(omap2plus_ports), .num_ports = ARRAY_SIZE(omap2plus_ports),
}; };
static const struct dss_features omap34xx_dss_feats __initconst = { static const struct dss_features omap34xx_dss_feats = {
.fck_div_max = 16, .fck_div_max = 16,
.dss_fck_multiplier = 2, .dss_fck_multiplier = 2,
.parent_clk_name = "dpll4_ck", .parent_clk_name = "dpll4_ck",
@ -833,7 +842,7 @@ static const struct dss_features omap34xx_dss_feats __initconst = {
.num_ports = ARRAY_SIZE(omap34xx_ports), .num_ports = ARRAY_SIZE(omap34xx_ports),
}; };
static const struct dss_features omap3630_dss_feats __initconst = { static const struct dss_features omap3630_dss_feats = {
.fck_div_max = 32, .fck_div_max = 32,
.dss_fck_multiplier = 1, .dss_fck_multiplier = 1,
.parent_clk_name = "dpll4_ck", .parent_clk_name = "dpll4_ck",
@ -842,7 +851,7 @@ static const struct dss_features omap3630_dss_feats __initconst = {
.num_ports = ARRAY_SIZE(omap2plus_ports), .num_ports = ARRAY_SIZE(omap2plus_ports),
}; };
static const struct dss_features omap44xx_dss_feats __initconst = { static const struct dss_features omap44xx_dss_feats = {
.fck_div_max = 32, .fck_div_max = 32,
.dss_fck_multiplier = 1, .dss_fck_multiplier = 1,
.parent_clk_name = "dpll_per_x2_ck", .parent_clk_name = "dpll_per_x2_ck",
@ -851,7 +860,7 @@ static const struct dss_features omap44xx_dss_feats __initconst = {
.num_ports = ARRAY_SIZE(omap2plus_ports), .num_ports = ARRAY_SIZE(omap2plus_ports),
}; };
static const struct dss_features omap54xx_dss_feats __initconst = { static const struct dss_features omap54xx_dss_feats = {
.fck_div_max = 64, .fck_div_max = 64,
.dss_fck_multiplier = 1, .dss_fck_multiplier = 1,
.parent_clk_name = "dpll_per_x2_ck", .parent_clk_name = "dpll_per_x2_ck",
@ -860,7 +869,7 @@ static const struct dss_features omap54xx_dss_feats __initconst = {
.num_ports = ARRAY_SIZE(omap2plus_ports), .num_ports = ARRAY_SIZE(omap2plus_ports),
}; };
static const struct dss_features am43xx_dss_feats __initconst = { static const struct dss_features am43xx_dss_feats = {
.fck_div_max = 0, .fck_div_max = 0,
.dss_fck_multiplier = 0, .dss_fck_multiplier = 0,
.parent_clk_name = NULL, .parent_clk_name = NULL,
@ -869,7 +878,7 @@ static const struct dss_features am43xx_dss_feats __initconst = {
.num_ports = ARRAY_SIZE(omap2plus_ports), .num_ports = ARRAY_SIZE(omap2plus_ports),
}; };
static const struct dss_features dra7xx_dss_feats __initconst = { static const struct dss_features dra7xx_dss_feats = {
.fck_div_max = 64, .fck_div_max = 64,
.dss_fck_multiplier = 1, .dss_fck_multiplier = 1,
.parent_clk_name = "dpll_per_x2_ck", .parent_clk_name = "dpll_per_x2_ck",
@ -878,7 +887,7 @@ static const struct dss_features dra7xx_dss_feats __initconst = {
.num_ports = ARRAY_SIZE(dra7xx_ports), .num_ports = ARRAY_SIZE(dra7xx_ports),
}; };
static int __init dss_init_features(struct platform_device *pdev) static int dss_init_features(struct platform_device *pdev)
{ {
const struct dss_features *src; const struct dss_features *src;
struct dss_features *dst; struct dss_features *dst;
@ -932,7 +941,7 @@ static int __init dss_init_features(struct platform_device *pdev)
return 0; return 0;
} }
static int __init dss_init_ports(struct platform_device *pdev) static int dss_init_ports(struct platform_device *pdev)
{ {
struct device_node *parent = pdev->dev.of_node; struct device_node *parent = pdev->dev.of_node;
struct device_node *port; struct device_node *port;
@ -976,7 +985,7 @@ static int __init dss_init_ports(struct platform_device *pdev)
return 0; return 0;
} }
static void __exit dss_uninit_ports(struct platform_device *pdev) static void dss_uninit_ports(struct platform_device *pdev)
{ {
struct device_node *parent = pdev->dev.of_node; struct device_node *parent = pdev->dev.of_node;
struct device_node *port; struct device_node *port;
@ -1018,69 +1027,16 @@ static void __exit dss_uninit_ports(struct platform_device *pdev)
} while ((port = omapdss_of_get_next_port(parent, port)) != NULL); } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
} }
/* DSS HW IP initialisation */ static int dss_video_pll_probe(struct platform_device *pdev)
static int __init omap_dsshw_probe(struct platform_device *pdev)
{ {
struct resource *dss_mem;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
u32 rev;
int r;
struct regulator *pll_regulator; struct regulator *pll_regulator;
int r;
dss.pdev = pdev; if (!np)
return 0;
r = dss_init_features(dss.pdev); if (of_property_read_bool(np, "syscon-pll-ctrl")) {
if (r)
return r;
dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
if (!dss_mem) {
DSSERR("can't get IORESOURCE_MEM DSS\n");
return -EINVAL;
}
dss.base = devm_ioremap(&pdev->dev, dss_mem->start,
resource_size(dss_mem));
if (!dss.base) {
DSSERR("can't ioremap DSS\n");
return -ENOMEM;
}
r = dss_get_clocks();
if (r)
return r;
r = dss_setup_default_clock();
if (r)
goto err_setup_clocks;
pm_runtime_enable(&pdev->dev);
r = dss_runtime_get();
if (r)
goto err_runtime_get;
dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
/* Select DPLL */
REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
#ifdef CONFIG_OMAP2_DSS_VENC
REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */
REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
#endif
dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
dss_init_ports(pdev);
if (np && of_property_read_bool(np, "syscon-pll-ctrl")) {
dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np, dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np,
"syscon-pll-ctrl"); "syscon-pll-ctrl");
if (IS_ERR(dss.syscon_pll_ctrl)) { if (IS_ERR(dss.syscon_pll_ctrl)) {
@ -1117,47 +1073,130 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
if (of_property_match_string(np, "reg-names", "pll1") >= 0) { if (of_property_match_string(np, "reg-names", "pll1") >= 0) {
dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator); dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator);
if (IS_ERR(dss.video1_pll)) { if (IS_ERR(dss.video1_pll))
r = PTR_ERR(dss.video1_pll); return PTR_ERR(dss.video1_pll);
goto err_pll_init;
}
} }
if (of_property_match_string(np, "reg-names", "pll2") >= 0) { if (of_property_match_string(np, "reg-names", "pll2") >= 0) {
dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator); dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator);
if (IS_ERR(dss.video2_pll)) { if (IS_ERR(dss.video2_pll)) {
r = PTR_ERR(dss.video2_pll); dss_video_pll_uninit(dss.video1_pll);
goto err_pll_init; return PTR_ERR(dss.video2_pll);
} }
} }
return 0;
}
/* DSS HW IP initialisation */
static int dss_bind(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct resource *dss_mem;
u32 rev;
int r;
dss.pdev = pdev;
r = dss_init_features(dss.pdev);
if (r)
return r;
dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
if (!dss_mem) {
DSSERR("can't get IORESOURCE_MEM DSS\n");
return -EINVAL;
}
dss.base = devm_ioremap(&pdev->dev, dss_mem->start,
resource_size(dss_mem));
if (!dss.base) {
DSSERR("can't ioremap DSS\n");
return -ENOMEM;
}
r = dss_get_clocks();
if (r)
return r;
r = dss_setup_default_clock();
if (r)
goto err_setup_clocks;
r = dss_video_pll_probe(pdev);
if (r)
goto err_pll_init;
r = dss_init_ports(pdev);
if (r)
goto err_init_ports;
pm_runtime_enable(&pdev->dev);
r = dss_runtime_get();
if (r)
goto err_runtime_get;
dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
/* Select DPLL */
REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
#ifdef CONFIG_OMAP2_DSS_VENC
REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */
REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
#endif
dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
rev = dss_read_reg(DSS_REVISION); rev = dss_read_reg(DSS_REVISION);
printk(KERN_INFO "OMAP DSS rev %d.%d\n", printk(KERN_INFO "OMAP DSS rev %d.%d\n",
FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
dss_runtime_put(); dss_runtime_put();
r = component_bind_all(&pdev->dev, NULL);
if (r)
goto err_component;
dss_debugfs_create_file("dss", dss_dump_regs); dss_debugfs_create_file("dss", dss_dump_regs);
pm_set_vt_switch(0); pm_set_vt_switch(0);
dss_initialized = true;
return 0; return 0;
err_pll_init: err_component:
err_runtime_get:
pm_runtime_disable(&pdev->dev);
dss_uninit_ports(pdev);
err_init_ports:
if (dss.video1_pll) if (dss.video1_pll)
dss_video_pll_uninit(dss.video1_pll); dss_video_pll_uninit(dss.video1_pll);
if (dss.video2_pll) if (dss.video2_pll)
dss_video_pll_uninit(dss.video2_pll); dss_video_pll_uninit(dss.video2_pll);
err_runtime_get: err_pll_init:
pm_runtime_disable(&pdev->dev);
err_setup_clocks: err_setup_clocks:
dss_put_clocks(); dss_put_clocks();
return r; return r;
} }
static int __exit omap_dsshw_remove(struct platform_device *pdev) static void dss_unbind(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev);
dss_initialized = false;
component_unbind_all(&pdev->dev, NULL);
if (dss.video1_pll) if (dss.video1_pll)
dss_video_pll_uninit(dss.video1_pll); dss_video_pll_uninit(dss.video1_pll);
@ -1169,7 +1208,46 @@ static int __exit omap_dsshw_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
dss_put_clocks(); dss_put_clocks();
}
static const struct component_master_ops dss_component_ops = {
.bind = dss_bind,
.unbind = dss_unbind,
};
static int dss_component_compare(struct device *dev, void *data)
{
struct device *child = data;
return dev == child;
}
static int dss_add_child_component(struct device *dev, void *data)
{
struct component_match **match = data;
component_match_add(dev->parent, match, dss_component_compare, dev);
return 0;
}
static int dss_probe(struct platform_device *pdev)
{
struct component_match *match = NULL;
int r;
/* add all the child devices as components */
device_for_each_child(&pdev->dev, &match, dss_add_child_component);
r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
if (r)
return r;
return 0;
}
static int dss_remove(struct platform_device *pdev)
{
component_master_del(&pdev->dev, &dss_component_ops);
return 0; return 0;
} }
@ -1215,7 +1293,8 @@ static const struct of_device_id dss_of_match[] = {
MODULE_DEVICE_TABLE(of, dss_of_match); MODULE_DEVICE_TABLE(of, dss_of_match);
static struct platform_driver omap_dsshw_driver = { static struct platform_driver omap_dsshw_driver = {
.remove = __exit_p(omap_dsshw_remove), .probe = dss_probe,
.remove = dss_remove,
.driver = { .driver = {
.name = "omapdss_dss", .name = "omapdss_dss",
.pm = &dss_pm_ops, .pm = &dss_pm_ops,
@ -1226,7 +1305,7 @@ static struct platform_driver omap_dsshw_driver = {
int __init dss_init_platform_driver(void) int __init dss_init_platform_driver(void)
{ {
return platform_driver_probe(&omap_dsshw_driver, omap_dsshw_probe); return platform_driver_register(&omap_dsshw_driver);
} }
void dss_uninit_platform_driver(void) void dss_uninit_platform_driver(void)

View File

@ -309,18 +309,18 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
/* SDI */ /* SDI */
int sdi_init_platform_driver(void) __init; int sdi_init_platform_driver(void) __init;
void sdi_uninit_platform_driver(void) __exit; void sdi_uninit_platform_driver(void);
#ifdef CONFIG_OMAP2_DSS_SDI #ifdef CONFIG_OMAP2_DSS_SDI
int sdi_init_port(struct platform_device *pdev, struct device_node *port) __init; int sdi_init_port(struct platform_device *pdev, struct device_node *port);
void sdi_uninit_port(struct device_node *port) __exit; void sdi_uninit_port(struct device_node *port);
#else #else
static inline int __init sdi_init_port(struct platform_device *pdev, static inline int sdi_init_port(struct platform_device *pdev,
struct device_node *port) struct device_node *port)
{ {
return 0; return 0;
} }
static inline void __exit sdi_uninit_port(struct device_node *port) static inline void sdi_uninit_port(struct device_node *port)
{ {
} }
#endif #endif
@ -333,7 +333,7 @@ struct dentry;
struct file_operations; struct file_operations;
int dsi_init_platform_driver(void) __init; int dsi_init_platform_driver(void) __init;
void dsi_uninit_platform_driver(void) __exit; void dsi_uninit_platform_driver(void);
void dsi_dump_clocks(struct seq_file *s); void dsi_dump_clocks(struct seq_file *s);
@ -350,25 +350,25 @@ static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
/* DPI */ /* DPI */
int dpi_init_platform_driver(void) __init; int dpi_init_platform_driver(void) __init;
void dpi_uninit_platform_driver(void) __exit; void dpi_uninit_platform_driver(void);
#ifdef CONFIG_OMAP2_DSS_DPI #ifdef CONFIG_OMAP2_DSS_DPI
int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init; int dpi_init_port(struct platform_device *pdev, struct device_node *port);
void dpi_uninit_port(struct device_node *port) __exit; void dpi_uninit_port(struct device_node *port);
#else #else
static inline int __init dpi_init_port(struct platform_device *pdev, static inline int dpi_init_port(struct platform_device *pdev,
struct device_node *port) struct device_node *port)
{ {
return 0; return 0;
} }
static inline void __exit dpi_uninit_port(struct device_node *port) static inline void dpi_uninit_port(struct device_node *port)
{ {
} }
#endif #endif
/* DISPC */ /* DISPC */
int dispc_init_platform_driver(void) __init; int dispc_init_platform_driver(void) __init;
void dispc_uninit_platform_driver(void) __exit; void dispc_uninit_platform_driver(void);
void dispc_dump_clocks(struct seq_file *s); void dispc_dump_clocks(struct seq_file *s);
void dispc_enable_sidle(void); void dispc_enable_sidle(void);
@ -418,18 +418,18 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
/* VENC */ /* VENC */
int venc_init_platform_driver(void) __init; int venc_init_platform_driver(void) __init;
void venc_uninit_platform_driver(void) __exit; void venc_uninit_platform_driver(void);
/* HDMI */ /* HDMI */
int hdmi4_init_platform_driver(void) __init; int hdmi4_init_platform_driver(void) __init;
void hdmi4_uninit_platform_driver(void) __exit; void hdmi4_uninit_platform_driver(void);
int hdmi5_init_platform_driver(void) __init; int hdmi5_init_platform_driver(void) __init;
void hdmi5_uninit_platform_driver(void) __exit; void hdmi5_uninit_platform_driver(void);
/* RFBI */ /* RFBI */
int rfbi_init_platform_driver(void) __init; int rfbi_init_platform_driver(void) __init;
void rfbi_uninit_platform_driver(void) __exit; void rfbi_uninit_platform_driver(void);
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS

View File

@ -32,6 +32,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/component.h>
#include <video/omapdss.h> #include <video/omapdss.h>
#include <sound/omap-hdmi-audio.h> #include <sound/omap-hdmi-audio.h>
@ -229,9 +230,9 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
err_mgr_enable: err_mgr_enable:
hdmi_wp_video_stop(&hdmi.wp); hdmi_wp_video_stop(&hdmi.wp);
err_vid_enable: err_vid_enable:
err_phy_cfg:
hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
err_phy_pwr: err_phy_pwr:
err_phy_cfg:
err_pll_cfg: err_pll_cfg:
dss_pll_disable(&hdmi.pll.pll); dss_pll_disable(&hdmi.pll.pll);
err_pll_enable: err_pll_enable:
@ -646,8 +647,9 @@ static int hdmi_audio_register(struct device *dev)
} }
/* HDMI HW IP initialisation */ /* HDMI HW IP initialisation */
static int omapdss_hdmihw_probe(struct platform_device *pdev) static int hdmi4_bind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev);
int r; int r;
int irq; int irq;
@ -713,8 +715,10 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
return r; return r;
} }
static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) static void hdmi4_unbind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev);
if (hdmi.audio_pdev) if (hdmi.audio_pdev)
platform_device_unregister(hdmi.audio_pdev); platform_device_unregister(hdmi.audio_pdev);
@ -723,7 +727,21 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
hdmi_pll_uninit(&hdmi.pll); hdmi_pll_uninit(&hdmi.pll);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
}
static const struct component_ops hdmi4_component_ops = {
.bind = hdmi4_bind,
.unbind = hdmi4_unbind,
};
static int hdmi4_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &hdmi4_component_ops);
}
static int hdmi4_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &hdmi4_component_ops);
return 0; return 0;
} }
@ -756,8 +774,8 @@ static const struct of_device_id hdmi_of_match[] = {
}; };
static struct platform_driver omapdss_hdmihw_driver = { static struct platform_driver omapdss_hdmihw_driver = {
.probe = omapdss_hdmihw_probe, .probe = hdmi4_probe,
.remove = __exit_p(omapdss_hdmihw_remove), .remove = hdmi4_remove,
.driver = { .driver = {
.name = "omapdss_hdmi", .name = "omapdss_hdmi",
.pm = &hdmi_pm_ops, .pm = &hdmi_pm_ops,
@ -771,7 +789,7 @@ int __init hdmi4_init_platform_driver(void)
return platform_driver_register(&omapdss_hdmihw_driver); return platform_driver_register(&omapdss_hdmihw_driver);
} }
void __exit hdmi4_uninit_platform_driver(void) void hdmi4_uninit_platform_driver(void)
{ {
platform_driver_unregister(&omapdss_hdmihw_driver); platform_driver_unregister(&omapdss_hdmihw_driver);
} }

View File

@ -654,6 +654,13 @@ static void hdmi_core_audio_infoframe_cfg(struct hdmi_core_data *core,
hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), info_aud->db3); hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), info_aud->db3);
sum += info_aud->db3; sum += info_aud->db3;
/*
* The OMAP HDMI IP requires to use the 8-channel channel code when
* transmitting more than two channels.
*/
if (info_aud->db4_ca != 0x00)
info_aud->db4_ca = 0x13;
hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), info_aud->db4_ca); hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), info_aud->db4_ca);
sum += info_aud->db4_ca; sum += info_aud->db4_ca;
@ -795,7 +802,9 @@ int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
/* /*
* the HDMI IP needs to enable four stereo channels when transmitting * the HDMI IP needs to enable four stereo channels when transmitting
* more than 2 audio channels * more than 2 audio channels. Similarly, the channel count in the
* Audio InfoFrame has to match the sample_present bits (some channels
* are padded with zeroes)
*/ */
if (channel_count == 2) { if (channel_count == 2) {
audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL; audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL;
@ -807,6 +816,7 @@ int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN | HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN |
HDMI_AUDIO_I2S_SD3_EN; HDMI_AUDIO_I2S_SD3_EN;
acore.layout = HDMI_AUDIO_LAYOUT_8CH; acore.layout = HDMI_AUDIO_LAYOUT_8CH;
audio->cea->db1_ct_cc = 7;
} }
acore.en_spdif = false; acore.en_spdif = false;

View File

@ -37,6 +37,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/component.h>
#include <video/omapdss.h> #include <video/omapdss.h>
#include <sound/omap-hdmi-audio.h> #include <sound/omap-hdmi-audio.h>
@ -681,8 +682,9 @@ static int hdmi_audio_register(struct device *dev)
} }
/* HDMI HW IP initialisation */ /* HDMI HW IP initialisation */
static int omapdss_hdmihw_probe(struct platform_device *pdev) static int hdmi5_bind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev);
int r; int r;
int irq; int irq;
@ -748,8 +750,10 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
return r; return r;
} }
static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) static void hdmi5_unbind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev);
if (hdmi.audio_pdev) if (hdmi.audio_pdev)
platform_device_unregister(hdmi.audio_pdev); platform_device_unregister(hdmi.audio_pdev);
@ -758,7 +762,21 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
hdmi_pll_uninit(&hdmi.pll); hdmi_pll_uninit(&hdmi.pll);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
}
static const struct component_ops hdmi5_component_ops = {
.bind = hdmi5_bind,
.unbind = hdmi5_unbind,
};
static int hdmi5_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &hdmi5_component_ops);
}
static int hdmi5_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &hdmi5_component_ops);
return 0; return 0;
} }
@ -792,8 +810,8 @@ static const struct of_device_id hdmi_of_match[] = {
}; };
static struct platform_driver omapdss_hdmihw_driver = { static struct platform_driver omapdss_hdmihw_driver = {
.probe = omapdss_hdmihw_probe, .probe = hdmi5_probe,
.remove = __exit_p(omapdss_hdmihw_remove), .remove = hdmi5_remove,
.driver = { .driver = {
.name = "omapdss_hdmi5", .name = "omapdss_hdmi5",
.pm = &hdmi_pm_ops, .pm = &hdmi_pm_ops,
@ -807,7 +825,7 @@ int __init hdmi5_init_platform_driver(void)
return platform_driver_register(&omapdss_hdmihw_driver); return platform_driver_register(&omapdss_hdmihw_driver);
} }
void __exit hdmi5_uninit_platform_driver(void) void hdmi5_uninit_platform_driver(void)
{ {
platform_driver_unregister(&omapdss_hdmihw_driver); platform_driver_unregister(&omapdss_hdmihw_driver);
} }

View File

@ -790,7 +790,9 @@ static void hdmi5_core_audio_infoframe_cfg(struct hdmi_core_data *core,
hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF1, info_aud->db2_sf_ss); hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF1, info_aud->db2_sf_ss);
hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF2, info_aud->db4_ca); hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF2, info_aud->db4_ca);
hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF3, info_aud->db5_dminh_lsv); hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF3,
(info_aud->db5_dminh_lsv & CEA861_AUDIO_INFOFRAME_DB5_DM_INH) >> 3 |
(info_aud->db5_dminh_lsv & CEA861_AUDIO_INFOFRAME_DB5_LSV));
} }
int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
@ -870,6 +872,7 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES;
audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS;
audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT;
audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
/* only LPCM atm */ /* only LPCM atm */
audio_format.type = HDMI_AUDIO_TYPE_LPCM; audio_format.type = HDMI_AUDIO_TYPE_LPCM;

View File

@ -110,7 +110,23 @@ int hdmi_wp_video_start(struct hdmi_wp_data *wp)
void hdmi_wp_video_stop(struct hdmi_wp_data *wp) void hdmi_wp_video_stop(struct hdmi_wp_data *wp)
{ {
int i;
hdmi_write_reg(wp->base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_FRAME_DONE);
REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, false, 31, 31); REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, false, 31, 31);
for (i = 0; i < 50; ++i) {
u32 v;
msleep(20);
v = hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS_RAW);
if (v & HDMI_IRQ_VIDEO_FRAME_DONE)
return;
}
DSSERR("no HDMI FRAMEDONE when disabling output\n");
} }
void hdmi_wp_video_config_format(struct hdmi_wp_data *wp, void hdmi_wp_video_config_format(struct hdmi_wp_data *wp,

View File

@ -36,6 +36,7 @@
#include <linux/semaphore.h> #include <linux/semaphore.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/component.h>
#include <video/omapdss.h> #include <video/omapdss.h>
#include "dss.h" #include "dss.h"
@ -938,7 +939,7 @@ static void rfbi_init_output(struct platform_device *pdev)
omapdss_register_output(out); omapdss_register_output(out);
} }
static void __exit rfbi_uninit_output(struct platform_device *pdev) static void rfbi_uninit_output(struct platform_device *pdev)
{ {
struct omap_dss_device *out = &rfbi.output; struct omap_dss_device *out = &rfbi.output;
@ -946,8 +947,9 @@ static void __exit rfbi_uninit_output(struct platform_device *pdev)
} }
/* RFBI HW IP initialisation */ /* RFBI HW IP initialisation */
static int omap_rfbihw_probe(struct platform_device *pdev) static int rfbi_bind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev);
u32 rev; u32 rev;
struct resource *rfbi_mem; struct resource *rfbi_mem;
struct clk *clk; struct clk *clk;
@ -1005,8 +1007,10 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
return r; return r;
} }
static int __exit omap_rfbihw_remove(struct platform_device *pdev) static void rfbi_unbind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev);
rfbi_uninit_output(pdev); rfbi_uninit_output(pdev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
@ -1014,6 +1018,22 @@ static int __exit omap_rfbihw_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct component_ops rfbi_component_ops = {
.bind = rfbi_bind,
.unbind = rfbi_unbind,
};
static int rfbi_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &rfbi_component_ops);
}
static int rfbi_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &rfbi_component_ops);
return 0;
}
static int rfbi_runtime_suspend(struct device *dev) static int rfbi_runtime_suspend(struct device *dev)
{ {
dispc_runtime_put(); dispc_runtime_put();
@ -1038,8 +1058,8 @@ static const struct dev_pm_ops rfbi_pm_ops = {
}; };
static struct platform_driver omap_rfbihw_driver = { static struct platform_driver omap_rfbihw_driver = {
.probe = omap_rfbihw_probe, .probe = rfbi_probe,
.remove = __exit_p(omap_rfbihw_remove), .remove = rfbi_remove,
.driver = { .driver = {
.name = "omapdss_rfbi", .name = "omapdss_rfbi",
.pm = &rfbi_pm_ops, .pm = &rfbi_pm_ops,
@ -1052,7 +1072,7 @@ int __init rfbi_init_platform_driver(void)
return platform_driver_register(&omap_rfbihw_driver); return platform_driver_register(&omap_rfbihw_driver);
} }
void __exit rfbi_uninit_platform_driver(void) void rfbi_uninit_platform_driver(void)
{ {
platform_driver_unregister(&omap_rfbihw_driver); platform_driver_unregister(&omap_rfbihw_driver);
} }

View File

@ -27,6 +27,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/component.h>
#include <video/omapdss.h> #include <video/omapdss.h>
#include "dss.h" #include "dss.h"
@ -350,15 +351,17 @@ static void sdi_init_output(struct platform_device *pdev)
omapdss_register_output(out); omapdss_register_output(out);
} }
static void __exit sdi_uninit_output(struct platform_device *pdev) static void sdi_uninit_output(struct platform_device *pdev)
{ {
struct omap_dss_device *out = &sdi.output; struct omap_dss_device *out = &sdi.output;
omapdss_unregister_output(out); omapdss_unregister_output(out);
} }
static int omap_sdi_probe(struct platform_device *pdev) static int sdi_bind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev);
sdi.pdev = pdev; sdi.pdev = pdev;
sdi_init_output(pdev); sdi_init_output(pdev);
@ -366,16 +369,32 @@ static int omap_sdi_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int __exit omap_sdi_remove(struct platform_device *pdev) static void sdi_unbind(struct device *dev, struct device *master, void *data)
{ {
sdi_uninit_output(pdev); struct platform_device *pdev = to_platform_device(dev);
sdi_uninit_output(pdev);
}
static const struct component_ops sdi_component_ops = {
.bind = sdi_bind,
.unbind = sdi_unbind,
};
static int sdi_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &sdi_component_ops);
}
static int sdi_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &sdi_component_ops);
return 0; return 0;
} }
static struct platform_driver omap_sdi_driver = { static struct platform_driver omap_sdi_driver = {
.probe = omap_sdi_probe, .probe = sdi_probe,
.remove = __exit_p(omap_sdi_remove), .remove = sdi_remove,
.driver = { .driver = {
.name = "omapdss_sdi", .name = "omapdss_sdi",
.suppress_bind_attrs = true, .suppress_bind_attrs = true,
@ -387,12 +406,12 @@ int __init sdi_init_platform_driver(void)
return platform_driver_register(&omap_sdi_driver); return platform_driver_register(&omap_sdi_driver);
} }
void __exit sdi_uninit_platform_driver(void) void sdi_uninit_platform_driver(void)
{ {
platform_driver_unregister(&omap_sdi_driver); platform_driver_unregister(&omap_sdi_driver);
} }
int __init sdi_init_port(struct platform_device *pdev, struct device_node *port) int sdi_init_port(struct platform_device *pdev, struct device_node *port)
{ {
struct device_node *ep; struct device_node *ep;
u32 datapairs; u32 datapairs;
@ -426,7 +445,7 @@ int __init sdi_init_port(struct platform_device *pdev, struct device_node *port)
return r; return r;
} }
void __exit sdi_uninit_port(struct device_node *port) void sdi_uninit_port(struct device_node *port)
{ {
if (!sdi.port_initialized) if (!sdi.port_initialized)
return; return;

View File

@ -35,6 +35,7 @@
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/component.h>
#include <video/omapdss.h> #include <video/omapdss.h>
@ -802,7 +803,7 @@ static void venc_init_output(struct platform_device *pdev)
omapdss_register_output(out); omapdss_register_output(out);
} }
static void __exit venc_uninit_output(struct platform_device *pdev) static void venc_uninit_output(struct platform_device *pdev)
{ {
struct omap_dss_device *out = &venc.output; struct omap_dss_device *out = &venc.output;
@ -852,8 +853,9 @@ static int venc_probe_of(struct platform_device *pdev)
} }
/* VENC HW IP initialisation */ /* VENC HW IP initialisation */
static int omap_venchw_probe(struct platform_device *pdev) static int venc_bind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev);
u8 rev_id; u8 rev_id;
struct resource *venc_mem; struct resource *venc_mem;
int r; int r;
@ -912,12 +914,28 @@ static int omap_venchw_probe(struct platform_device *pdev)
return r; return r;
} }
static int __exit omap_venchw_remove(struct platform_device *pdev) static void venc_unbind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev);
venc_uninit_output(pdev); venc_uninit_output(pdev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
}
static const struct component_ops venc_component_ops = {
.bind = venc_bind,
.unbind = venc_unbind,
};
static int venc_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &venc_component_ops);
}
static int venc_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &venc_component_ops);
return 0; return 0;
} }
@ -950,7 +968,6 @@ static const struct dev_pm_ops venc_pm_ops = {
.runtime_resume = venc_runtime_resume, .runtime_resume = venc_runtime_resume,
}; };
static const struct of_device_id venc_of_match[] = { static const struct of_device_id venc_of_match[] = {
{ .compatible = "ti,omap2-venc", }, { .compatible = "ti,omap2-venc", },
{ .compatible = "ti,omap3-venc", }, { .compatible = "ti,omap3-venc", },
@ -959,8 +976,8 @@ static const struct of_device_id venc_of_match[] = {
}; };
static struct platform_driver omap_venchw_driver = { static struct platform_driver omap_venchw_driver = {
.probe = omap_venchw_probe, .probe = venc_probe,
.remove = __exit_p(omap_venchw_remove), .remove = venc_remove,
.driver = { .driver = {
.name = "omapdss_venc", .name = "omapdss_venc",
.pm = &venc_pm_ops, .pm = &venc_pm_ops,
@ -974,7 +991,7 @@ int __init venc_init_platform_driver(void)
return platform_driver_register(&omap_venchw_driver); return platform_driver_register(&omap_venchw_driver);
} }
void __exit venc_uninit_platform_driver(void) void venc_uninit_platform_driver(void)
{ {
platform_driver_unregister(&omap_venchw_driver); platform_driver_unregister(&omap_venchw_driver);
} }

View File

@ -38,10 +38,6 @@
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include <video/permedia2.h> #include <video/permedia2.h>
#include <video/cvisionppc.h> #include <video/cvisionppc.h>
@ -81,10 +77,7 @@ static char *mode_option;
static bool lowhsync; static bool lowhsync;
static bool lowvsync; static bool lowvsync;
static bool noaccel; static bool noaccel;
/* mtrr option */
#ifdef CONFIG_MTRR
static bool nomtrr; static bool nomtrr;
#endif
/* /*
* The hardware state of the graphics card that isn't part of the * The hardware state of the graphics card that isn't part of the
@ -100,7 +93,7 @@ struct pm2fb_par
u32 mem_control; /* MemControl reg at probe */ u32 mem_control; /* MemControl reg at probe */
u32 boot_address; /* BootAddress reg at probe */ u32 boot_address; /* BootAddress reg at probe */
u32 palette[16]; u32 palette[16];
int mtrr_handle; int wc_cookie;
}; };
/* /*
@ -1637,21 +1630,16 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_exit_mmio; goto err_exit_mmio;
} }
info->screen_base = info->screen_base =
ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len); ioremap_wc(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
if (!info->screen_base) { if (!info->screen_base) {
printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n"); printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n");
release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len); release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
goto err_exit_mmio; goto err_exit_mmio;
} }
#ifdef CONFIG_MTRR
default_par->mtrr_handle = -1;
if (!nomtrr) if (!nomtrr)
default_par->mtrr_handle = default_par->wc_cookie = arch_phys_wc_add(pm2fb_fix.smem_start,
mtrr_add(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
pm2fb_fix.smem_len,
MTRR_TYPE_WRCOMB, 1);
#endif
info->fbops = &pm2fb_ops; info->fbops = &pm2fb_ops;
info->fix = pm2fb_fix; info->fix = pm2fb_fix;
@ -1733,12 +1721,7 @@ static void pm2fb_remove(struct pci_dev *pdev)
struct pm2fb_par *par = info->par; struct pm2fb_par *par = info->par;
unregister_framebuffer(info); unregister_framebuffer(info);
arch_phys_wc_del(par->wc_cookie);
#ifdef CONFIG_MTRR
if (par->mtrr_handle >= 0)
mtrr_del(par->mtrr_handle, info->fix.smem_start,
info->fix.smem_len);
#endif /* CONFIG_MTRR */
iounmap(info->screen_base); iounmap(info->screen_base);
release_mem_region(fix->smem_start, fix->smem_len); release_mem_region(fix->smem_start, fix->smem_len);
iounmap(par->v_regs); iounmap(par->v_regs);
@ -1791,10 +1774,8 @@ static int __init pm2fb_setup(char *options)
lowvsync = 1; lowvsync = 1;
else if (!strncmp(this_opt, "hwcursor=", 9)) else if (!strncmp(this_opt, "hwcursor=", 9))
hwcursor = simple_strtoul(this_opt + 9, NULL, 0); hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
#ifdef CONFIG_MTRR
else if (!strncmp(this_opt, "nomtrr", 6)) else if (!strncmp(this_opt, "nomtrr", 6))
nomtrr = 1; nomtrr = 1;
#endif
else if (!strncmp(this_opt, "noaccel", 7)) else if (!strncmp(this_opt, "noaccel", 7))
noaccel = 1; noaccel = 1;
else else
@ -1847,10 +1828,8 @@ MODULE_PARM_DESC(noaccel, "Disable acceleration");
module_param(hwcursor, int, 0644); module_param(hwcursor, int, 0644);
MODULE_PARM_DESC(hwcursor, "Enable hardware cursor " MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
"(1=enable, 0=disable, default=1)"); "(1=enable, 0=disable, default=1)");
#ifdef CONFIG_MTRR
module_param(nomtrr, bool, 0); module_param(nomtrr, bool, 0);
MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)"); MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
#endif
MODULE_AUTHOR("Jim Hague <jim.hague@acm.org>"); MODULE_AUTHOR("Jim Hague <jim.hague@acm.org>");
MODULE_DESCRIPTION("Permedia2 framebuffer device driver"); MODULE_DESCRIPTION("Permedia2 framebuffer device driver");

View File

@ -32,9 +32,6 @@
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include <video/pm3fb.h> #include <video/pm3fb.h>
@ -58,11 +55,7 @@
static int hwcursor = 1; static int hwcursor = 1;
static char *mode_option; static char *mode_option;
static bool noaccel; static bool noaccel;
/* mtrr option */
#ifdef CONFIG_MTRR
static bool nomtrr; static bool nomtrr;
#endif
/* /*
* This structure defines the hardware state of the graphics card. Normally * This structure defines the hardware state of the graphics card. Normally
@ -76,7 +69,7 @@ struct pm3_par {
u32 video; /* video flags before blanking */ u32 video; /* video flags before blanking */
u32 base; /* screen base in 128 bits unit */ u32 base; /* screen base in 128 bits unit */
u32 palette[16]; u32 palette[16];
int mtrr_handle; int wc_cookie;
}; };
/* /*
@ -1374,8 +1367,8 @@ static int pm3fb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
printk(KERN_WARNING "pm3fb: Can't reserve smem.\n"); printk(KERN_WARNING "pm3fb: Can't reserve smem.\n");
goto err_exit_mmio; goto err_exit_mmio;
} }
info->screen_base = info->screen_base = ioremap_wc(pm3fb_fix.smem_start,
ioremap_nocache(pm3fb_fix.smem_start, pm3fb_fix.smem_len); pm3fb_fix.smem_len);
if (!info->screen_base) { if (!info->screen_base) {
printk(KERN_WARNING "pm3fb: Can't ioremap smem area.\n"); printk(KERN_WARNING "pm3fb: Can't ioremap smem area.\n");
release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len); release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
@ -1383,12 +1376,9 @@ static int pm3fb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
} }
info->screen_size = pm3fb_fix.smem_len; info->screen_size = pm3fb_fix.smem_len;
#ifdef CONFIG_MTRR
if (!nomtrr) if (!nomtrr)
par->mtrr_handle = mtrr_add(pm3fb_fix.smem_start, par->wc_cookie = arch_phys_wc_add(pm3fb_fix.smem_start,
pm3fb_fix.smem_len, pm3fb_fix.smem_len);
MTRR_TYPE_WRCOMB, 1);
#endif
info->fbops = &pm3fb_ops; info->fbops = &pm3fb_ops;
par->video = PM3_READ_REG(par, PM3VideoControl); par->video = PM3_READ_REG(par, PM3VideoControl);
@ -1478,11 +1468,7 @@ static void pm3fb_remove(struct pci_dev *dev)
unregister_framebuffer(info); unregister_framebuffer(info);
fb_dealloc_cmap(&info->cmap); fb_dealloc_cmap(&info->cmap);
#ifdef CONFIG_MTRR arch_phys_wc_del(par->wc_cookie);
if (par->mtrr_handle >= 0)
mtrr_del(par->mtrr_handle, info->fix.smem_start,
info->fix.smem_len);
#endif /* CONFIG_MTRR */
iounmap(info->screen_base); iounmap(info->screen_base);
release_mem_region(fix->smem_start, fix->smem_len); release_mem_region(fix->smem_start, fix->smem_len);
iounmap(par->v_regs); iounmap(par->v_regs);
@ -1533,10 +1519,8 @@ static int __init pm3fb_setup(char *options)
noaccel = 1; noaccel = 1;
else if (!strncmp(this_opt, "hwcursor=", 9)) else if (!strncmp(this_opt, "hwcursor=", 9))
hwcursor = simple_strtoul(this_opt + 9, NULL, 0); hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
#ifdef CONFIG_MTRR
else if (!strncmp(this_opt, "nomtrr", 6)) else if (!strncmp(this_opt, "nomtrr", 6))
nomtrr = 1; nomtrr = 1;
#endif
else else
mode_option = this_opt; mode_option = this_opt;
} }
@ -1577,10 +1561,8 @@ MODULE_PARM_DESC(noaccel, "Disable acceleration");
module_param(hwcursor, int, 0644); module_param(hwcursor, int, 0644);
MODULE_PARM_DESC(hwcursor, "Enable hardware cursor " MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
"(1=enable, 0=disable, default=1)"); "(1=enable, 0=disable, default=1)");
#ifdef CONFIG_MTRR
module_param(nomtrr, bool, 0); module_param(nomtrr, bool, 0);
MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)"); MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
#endif
MODULE_DESCRIPTION("Permedia3 framebuffer device driver"); MODULE_DESCRIPTION("Permedia3 framebuffer device driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@ -41,9 +41,6 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/bitrev.h> #include <linux/bitrev.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#ifdef CONFIG_PMAC_BACKLIGHT #ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/backlight.h> #include <asm/backlight.h>
@ -204,9 +201,7 @@ MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
static int flatpanel = -1; /* Autodetect later */ static int flatpanel = -1; /* Autodetect later */
static int forceCRTC = -1; static int forceCRTC = -1;
static bool noaccel = 0; static bool noaccel = 0;
#ifdef CONFIG_MTRR
static bool nomtrr = 0; static bool nomtrr = 0;
#endif
#ifdef CONFIG_PMAC_BACKLIGHT #ifdef CONFIG_PMAC_BACKLIGHT
static int backlight = 1; static int backlight = 1;
#else #else
@ -2010,28 +2005,18 @@ static int rivafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
rivafb_fix.smem_len = riva_get_memlen(default_par) * 1024; rivafb_fix.smem_len = riva_get_memlen(default_par) * 1024;
default_par->dclk_max = riva_get_maxdclk(default_par) * 1000; default_par->dclk_max = riva_get_maxdclk(default_par) * 1000;
info->screen_base = ioremap(rivafb_fix.smem_start, info->screen_base = ioremap_wc(rivafb_fix.smem_start,
rivafb_fix.smem_len); rivafb_fix.smem_len);
if (!info->screen_base) { if (!info->screen_base) {
printk(KERN_ERR PFX "cannot ioremap FB base\n"); printk(KERN_ERR PFX "cannot ioremap FB base\n");
ret = -EIO; ret = -EIO;
goto err_iounmap_pramin; goto err_iounmap_pramin;
} }
#ifdef CONFIG_MTRR if (!nomtrr)
if (!nomtrr) { default_par->wc_cookie =
default_par->mtrr.vram = mtrr_add(rivafb_fix.smem_start, arch_phys_wc_add(rivafb_fix.smem_start,
rivafb_fix.smem_len, rivafb_fix.smem_len);
MTRR_TYPE_WRCOMB, 1);
if (default_par->mtrr.vram < 0) {
printk(KERN_ERR PFX "unable to setup MTRR\n");
} else {
default_par->mtrr.vram_valid = 1;
/* let there be speed */
printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
}
}
#endif /* CONFIG_MTRR */
info->fbops = &riva_fb_ops; info->fbops = &riva_fb_ops;
info->fix = rivafb_fix; info->fix = rivafb_fix;
@ -2105,13 +2090,7 @@ static void rivafb_remove(struct pci_dev *pd)
unregister_framebuffer(info); unregister_framebuffer(info);
riva_bl_exit(info); riva_bl_exit(info);
arch_phys_wc_del(par->wc_cookie);
#ifdef CONFIG_MTRR
if (par->mtrr.vram_valid)
mtrr_del(par->mtrr.vram, info->fix.smem_start,
info->fix.smem_len);
#endif /* CONFIG_MTRR */
iounmap(par->ctrl_base); iounmap(par->ctrl_base);
iounmap(info->screen_base); iounmap(info->screen_base);
if (par->riva.Architecture == NV_ARCH_03) if (par->riva.Architecture == NV_ARCH_03)
@ -2150,10 +2129,8 @@ static int rivafb_setup(char *options)
flatpanel = 1; flatpanel = 1;
} else if (!strncmp(this_opt, "backlight:", 10)) { } else if (!strncmp(this_opt, "backlight:", 10)) {
backlight = simple_strtoul(this_opt+10, NULL, 0); backlight = simple_strtoul(this_opt+10, NULL, 0);
#ifdef CONFIG_MTRR
} else if (!strncmp(this_opt, "nomtrr", 6)) { } else if (!strncmp(this_opt, "nomtrr", 6)) {
nomtrr = 1; nomtrr = 1;
#endif
} else if (!strncmp(this_opt, "strictmode", 10)) { } else if (!strncmp(this_opt, "strictmode", 10)) {
strictmode = 1; strictmode = 1;
} else if (!strncmp(this_opt, "noaccel", 7)) { } else if (!strncmp(this_opt, "noaccel", 7)) {
@ -2209,10 +2186,8 @@ module_param(flatpanel, int, 0);
MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)"); MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)");
module_param(forceCRTC, int, 0); module_param(forceCRTC, int, 0);
MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetection fails. (0 or 1) (default=autodetect)"); MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetection fails. (0 or 1) (default=autodetect)");
#ifdef CONFIG_MTRR
module_param(nomtrr, bool, 0); module_param(nomtrr, bool, 0);
MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)"); MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
#endif
module_param(strictmode, bool, 0); module_param(strictmode, bool, 0);
MODULE_PARM_DESC(strictmode, "Only use video modes from EDID"); MODULE_PARM_DESC(strictmode, "Only use video modes from EDID");

View File

@ -61,9 +61,7 @@ struct riva_par {
int FlatPanel; int FlatPanel;
struct pci_dev *pdev; struct pci_dev *pdev;
int cursor_reset; int cursor_reset;
#ifdef CONFIG_MTRR int wc_cookie;
struct { int vram; int vram_valid; } mtrr;
#endif
struct riva_i2c_chan chan[3]; struct riva_i2c_chan chan[3];
}; };

View File

@ -213,9 +213,7 @@ struct savagefb_par {
void __iomem *vbase; void __iomem *vbase;
u32 pbase; u32 pbase;
u32 len; u32 len;
#ifdef CONFIG_MTRR int wc_cookie;
int mtrr;
#endif
} video; } video;
struct { struct {

View File

@ -57,10 +57,6 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include "savagefb.h" #include "savagefb.h"
@ -1775,7 +1771,7 @@ static int savage_map_video(struct fb_info *info, int video_len)
par->video.pbase = pci_resource_start(par->pcidev, resource); par->video.pbase = pci_resource_start(par->pcidev, resource);
par->video.len = video_len; par->video.len = video_len;
par->video.vbase = ioremap(par->video.pbase, par->video.len); par->video.vbase = ioremap_wc(par->video.pbase, par->video.len);
if (!par->video.vbase) { if (!par->video.vbase) {
printk("savagefb: unable to map screen memory\n"); printk("savagefb: unable to map screen memory\n");
@ -1787,11 +1783,7 @@ static int savage_map_video(struct fb_info *info, int video_len)
info->fix.smem_start = par->video.pbase; info->fix.smem_start = par->video.pbase;
info->fix.smem_len = par->video.len - par->cob_size; info->fix.smem_len = par->video.len - par->cob_size;
info->screen_base = par->video.vbase; info->screen_base = par->video.vbase;
par->video.wc_cookie = arch_phys_wc_add(par->video.pbase, video_len);
#ifdef CONFIG_MTRR
par->video.mtrr = mtrr_add(par->video.pbase, video_len,
MTRR_TYPE_WRCOMB, 1);
#endif
/* Clear framebuffer, it's all white in memory after boot */ /* Clear framebuffer, it's all white in memory after boot */
memset_io(par->video.vbase, 0, par->video.len); memset_io(par->video.vbase, 0, par->video.len);
@ -1806,10 +1798,7 @@ static void savage_unmap_video(struct fb_info *info)
DBG("savage_unmap_video"); DBG("savage_unmap_video");
if (par->video.vbase) { if (par->video.vbase) {
#ifdef CONFIG_MTRR arch_phys_wc_del(par->video.wc_cookie);
mtrr_del(par->video.mtrr, par->video.pbase, par->video.len);
#endif
iounmap(par->video.vbase); iounmap(par->video.vbase);
par->video.vbase = NULL; par->video.vbase = NULL;
info->screen_base = NULL; info->screen_base = NULL;

View File

@ -458,7 +458,7 @@ struct sis_video_info {
unsigned char *bios_abase; unsigned char *bios_abase;
int mtrr; int wc_cookie;
u32 sisfb_mem; u32 sisfb_mem;

View File

@ -53,9 +53,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include "sis.h" #include "sis.h"
#include "sis_main.h" #include "sis_main.h"
@ -4130,13 +4127,13 @@ static void sisfb_post_map_vram(struct sis_video_info *ivideo,
if (*mapsize < (min << 20)) if (*mapsize < (min << 20))
return; return;
ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize)); ivideo->video_vbase = ioremap_wc(ivideo->video_base, (*mapsize));
if(!ivideo->video_vbase) { if(!ivideo->video_vbase) {
printk(KERN_ERR printk(KERN_ERR
"sisfb: Unable to map maximum video RAM for size detection\n"); "sisfb: Unable to map maximum video RAM for size detection\n");
(*mapsize) >>= 1; (*mapsize) >>= 1;
while((!(ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize))))) { while((!(ivideo->video_vbase = ioremap_wc(ivideo->video_base, (*mapsize))))) {
(*mapsize) >>= 1; (*mapsize) >>= 1;
if((*mapsize) < (min << 20)) if((*mapsize) < (min << 20))
break; break;
@ -6186,7 +6183,7 @@ static int sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto error_2; goto error_2;
} }
ivideo->video_vbase = ioremap(ivideo->video_base, ivideo->video_size); ivideo->video_vbase = ioremap_wc(ivideo->video_base, ivideo->video_size);
ivideo->SiS_Pr.VideoMemoryAddress = ivideo->video_vbase; ivideo->SiS_Pr.VideoMemoryAddress = ivideo->video_vbase;
if(!ivideo->video_vbase) { if(!ivideo->video_vbase) {
printk(KERN_ERR "sisfb: Fatal error: Unable to map framebuffer memory\n"); printk(KERN_ERR "sisfb: Fatal error: Unable to map framebuffer memory\n");
@ -6254,8 +6251,6 @@ error_3: vfree(ivideo->bios_abase);
ivideo->SiS_Pr.VideoMemoryAddress += ivideo->video_offset; ivideo->SiS_Pr.VideoMemoryAddress += ivideo->video_offset;
ivideo->SiS_Pr.VideoMemorySize = ivideo->sisfb_mem; ivideo->SiS_Pr.VideoMemorySize = ivideo->sisfb_mem;
ivideo->mtrr = -1;
ivideo->vbflags = 0; ivideo->vbflags = 0;
ivideo->lcddefmodeidx = DEFAULT_LCDMODE; ivideo->lcddefmodeidx = DEFAULT_LCDMODE;
ivideo->tvdefmodeidx = DEFAULT_TVMODE; ivideo->tvdefmodeidx = DEFAULT_TVMODE;
@ -6443,14 +6438,8 @@ error_3: vfree(ivideo->bios_abase);
printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags); printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags);
#ifdef CONFIG_MTRR ivideo->wc_cookie = arch_phys_wc_add(ivideo->video_base,
ivideo->mtrr = mtrr_add(ivideo->video_base, ivideo->video_size, ivideo->video_size);
MTRR_TYPE_WRCOMB, 1);
if(ivideo->mtrr < 0) {
printk(KERN_DEBUG "sisfb: Failed to add MTRRs\n");
}
#endif
if(register_framebuffer(sis_fb_info) < 0) { if(register_framebuffer(sis_fb_info) < 0) {
printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n"); printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
ret = -EINVAL; ret = -EINVAL;
@ -6507,11 +6496,7 @@ static void sisfb_remove(struct pci_dev *pdev)
pci_dev_put(ivideo->nbridge); pci_dev_put(ivideo->nbridge);
#ifdef CONFIG_MTRR arch_phys_wc_del(ivideo->wc_cookie);
/* Release MTRR region */
if(ivideo->mtrr >= 0)
mtrr_del(ivideo->mtrr, ivideo->video_base, ivideo->video_size);
#endif
/* If device was disabled when starting, disable /* If device was disabled when starting, disable
* it when quitting. * it when quitting.

View File

@ -7,6 +7,7 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/backlight.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/fb.h> #include <linux/fb.h>
@ -38,22 +39,43 @@
#define SSD1307FB_SET_COM_PINS_CONFIG 0xda #define SSD1307FB_SET_COM_PINS_CONFIG 0xda
#define SSD1307FB_SET_VCOMH 0xdb #define SSD1307FB_SET_VCOMH 0xdb
#define MAX_CONTRAST 255
#define REFRESHRATE 1
static u_int refreshrate = REFRESHRATE;
module_param(refreshrate, uint, 0);
struct ssd1307fb_par; struct ssd1307fb_par;
struct ssd1307fb_ops { struct ssd1307fb_deviceinfo {
int (*init)(struct ssd1307fb_par *); u32 default_vcomh;
int (*remove)(struct ssd1307fb_par *); u32 default_dclk_div;
u32 default_dclk_frq;
int need_pwm;
int need_chargepump;
}; };
struct ssd1307fb_par { struct ssd1307fb_par {
u32 com_invdir;
u32 com_lrremap;
u32 com_offset;
u32 com_seq;
u32 contrast;
u32 dclk_div;
u32 dclk_frq;
struct ssd1307fb_deviceinfo *device_info;
struct i2c_client *client; struct i2c_client *client;
u32 height; u32 height;
struct fb_info *info; struct fb_info *info;
struct ssd1307fb_ops *ops;
u32 page_offset; u32 page_offset;
u32 prechargep1;
u32 prechargep2;
struct pwm_device *pwm; struct pwm_device *pwm;
u32 pwm_period; u32 pwm_period;
int reset; int reset;
u32 seg_remap;
u32 vcomh;
u32 width; u32 width;
}; };
@ -213,6 +235,16 @@ static ssize_t ssd1307fb_write(struct fb_info *info, const char __user *buf,
return count; return count;
} }
static int ssd1307fb_blank(int blank_mode, struct fb_info *info)
{
struct ssd1307fb_par *par = info->par;
if (blank_mode != FB_BLANK_UNBLANK)
return ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_OFF);
else
return ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_ON);
}
static void ssd1307fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) static void ssd1307fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{ {
struct ssd1307fb_par *par = info->par; struct ssd1307fb_par *par = info->par;
@ -238,6 +270,7 @@ static struct fb_ops ssd1307fb_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.fb_read = fb_sys_read, .fb_read = fb_sys_read,
.fb_write = ssd1307fb_write, .fb_write = ssd1307fb_write,
.fb_blank = ssd1307fb_blank,
.fb_fillrect = ssd1307fb_fillrect, .fb_fillrect = ssd1307fb_fillrect,
.fb_copyarea = ssd1307fb_copyarea, .fb_copyarea = ssd1307fb_copyarea,
.fb_imageblit = ssd1307fb_imageblit, .fb_imageblit = ssd1307fb_imageblit,
@ -249,74 +282,46 @@ static void ssd1307fb_deferred_io(struct fb_info *info,
ssd1307fb_update_display(info->par); ssd1307fb_update_display(info->par);
} }
static struct fb_deferred_io ssd1307fb_defio = { static int ssd1307fb_init(struct ssd1307fb_par *par)
.delay = HZ,
.deferred_io = ssd1307fb_deferred_io,
};
static int ssd1307fb_ssd1307_init(struct ssd1307fb_par *par)
{ {
int ret; int ret;
u32 precharge, dclk, com_invdir, compins;
par->pwm = pwm_get(&par->client->dev, NULL); if (par->device_info->need_pwm) {
if (IS_ERR(par->pwm)) { par->pwm = pwm_get(&par->client->dev, NULL);
dev_err(&par->client->dev, "Could not get PWM from device tree!\n"); if (IS_ERR(par->pwm)) {
return PTR_ERR(par->pwm); dev_err(&par->client->dev, "Could not get PWM from device tree!\n");
} return PTR_ERR(par->pwm);
}
par->pwm_period = pwm_get_period(par->pwm); par->pwm_period = pwm_get_period(par->pwm);
/* Enable the PWM */ /* Enable the PWM */
pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period); pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period);
pwm_enable(par->pwm); pwm_enable(par->pwm);
dev_dbg(&par->client->dev, "Using PWM%d with a %dns period.\n", dev_dbg(&par->client->dev, "Using PWM%d with a %dns period.\n",
par->pwm->pwm, par->pwm_period); par->pwm->pwm, par->pwm_period);
};
/* Map column 127 of the OLED to segment 0 */
ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SEG_REMAP_ON);
if (ret < 0)
return ret;
/* Turn on the display */
ret = ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_ON);
if (ret < 0)
return ret;
return 0;
}
static int ssd1307fb_ssd1307_remove(struct ssd1307fb_par *par)
{
pwm_disable(par->pwm);
pwm_put(par->pwm);
return 0;
}
static struct ssd1307fb_ops ssd1307fb_ssd1307_ops = {
.init = ssd1307fb_ssd1307_init,
.remove = ssd1307fb_ssd1307_remove,
};
static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
{
int ret;
/* Set initial contrast */ /* Set initial contrast */
ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CONTRAST); ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CONTRAST);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = ssd1307fb_write_cmd(par->client, 0x7f); ret = ssd1307fb_write_cmd(par->client, par->contrast);
if (ret < 0)
return ret;
/* Set COM direction */
ret = ssd1307fb_write_cmd(par->client, 0xc8);
if (ret < 0) if (ret < 0)
return ret; return ret;
/* Set segment re-map */ /* Set segment re-map */
ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SEG_REMAP_ON); if (par->seg_remap) {
ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SEG_REMAP_ON);
if (ret < 0)
return ret;
};
/* Set COM direction */
com_invdir = 0xc0 | (par->com_invdir & 0x1) << 3;
ret = ssd1307fb_write_cmd(par->client, com_invdir);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -334,7 +339,7 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = ssd1307fb_write_cmd(par->client, 0x20); ret = ssd1307fb_write_cmd(par->client, par->com_offset);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -343,7 +348,8 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = ssd1307fb_write_cmd(par->client, 0xf0); dclk = ((par->dclk_div - 1) & 0xf) | (par->dclk_frq & 0xf) << 4;
ret = ssd1307fb_write_cmd(par->client, dclk);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -352,7 +358,8 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = ssd1307fb_write_cmd(par->client, 0x22); precharge = (par->prechargep1 & 0xf) | (par->prechargep2 & 0xf) << 4;
ret = ssd1307fb_write_cmd(par->client, precharge);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -361,7 +368,9 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = ssd1307fb_write_cmd(par->client, 0x22); compins = 0x02 | !(par->com_seq & 0x1) << 4
| (par->com_lrremap & 0x1) << 5;
ret = ssd1307fb_write_cmd(par->client, compins);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -370,7 +379,7 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = ssd1307fb_write_cmd(par->client, 0x49); ret = ssd1307fb_write_cmd(par->client, par->vcomh);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -379,7 +388,8 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = ssd1307fb_write_cmd(par->client, 0x14); ret = ssd1307fb_write_cmd(par->client,
(par->device_info->need_chargepump & 0x1 << 2) & 0x14);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -393,6 +403,7 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
if (ret < 0) if (ret < 0)
return ret; return ret;
/* Set column range */
ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COL_RANGE); ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COL_RANGE);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -405,6 +416,7 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
if (ret < 0) if (ret < 0)
return ret; return ret;
/* Set page range */
ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PAGE_RANGE); ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PAGE_RANGE);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -426,18 +438,75 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par)
return 0; return 0;
} }
static struct ssd1307fb_ops ssd1307fb_ssd1306_ops = { static int ssd1307fb_update_bl(struct backlight_device *bdev)
.init = ssd1307fb_ssd1306_init, {
struct ssd1307fb_par *par = bl_get_data(bdev);
int ret;
int brightness = bdev->props.brightness;
par->contrast = brightness;
ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CONTRAST);
if (ret < 0)
return ret;
ret = ssd1307fb_write_cmd(par->client, par->contrast);
if (ret < 0)
return ret;
return 0;
}
static int ssd1307fb_get_brightness(struct backlight_device *bdev)
{
struct ssd1307fb_par *par = bl_get_data(bdev);
return par->contrast;
}
static int ssd1307fb_check_fb(struct backlight_device *bdev,
struct fb_info *info)
{
return (info->bl_dev == bdev);
}
static const struct backlight_ops ssd1307fb_bl_ops = {
.options = BL_CORE_SUSPENDRESUME,
.update_status = ssd1307fb_update_bl,
.get_brightness = ssd1307fb_get_brightness,
.check_fb = ssd1307fb_check_fb,
};
static struct ssd1307fb_deviceinfo ssd1307fb_ssd1305_deviceinfo = {
.default_vcomh = 0x34,
.default_dclk_div = 1,
.default_dclk_frq = 7,
};
static struct ssd1307fb_deviceinfo ssd1307fb_ssd1306_deviceinfo = {
.default_vcomh = 0x20,
.default_dclk_div = 1,
.default_dclk_frq = 8,
.need_chargepump = 1,
};
static struct ssd1307fb_deviceinfo ssd1307fb_ssd1307_deviceinfo = {
.default_vcomh = 0x20,
.default_dclk_div = 2,
.default_dclk_frq = 12,
.need_pwm = 1,
}; };
static const struct of_device_id ssd1307fb_of_match[] = { static const struct of_device_id ssd1307fb_of_match[] = {
{
.compatible = "solomon,ssd1305fb-i2c",
.data = (void *)&ssd1307fb_ssd1305_deviceinfo,
},
{ {
.compatible = "solomon,ssd1306fb-i2c", .compatible = "solomon,ssd1306fb-i2c",
.data = (void *)&ssd1307fb_ssd1306_ops, .data = (void *)&ssd1307fb_ssd1306_deviceinfo,
}, },
{ {
.compatible = "solomon,ssd1307fb-i2c", .compatible = "solomon,ssd1307fb-i2c",
.data = (void *)&ssd1307fb_ssd1307_ops, .data = (void *)&ssd1307fb_ssd1307_deviceinfo,
}, },
{}, {},
}; };
@ -446,8 +515,11 @@ MODULE_DEVICE_TABLE(of, ssd1307fb_of_match);
static int ssd1307fb_probe(struct i2c_client *client, static int ssd1307fb_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct backlight_device *bl;
char bl_name[12];
struct fb_info *info; struct fb_info *info;
struct device_node *node = client->dev.of_node; struct device_node *node = client->dev.of_node;
struct fb_deferred_io *ssd1307fb_defio;
u32 vmem_size; u32 vmem_size;
struct ssd1307fb_par *par; struct ssd1307fb_par *par;
u8 *vmem; u8 *vmem;
@ -468,8 +540,8 @@ static int ssd1307fb_probe(struct i2c_client *client,
par->info = info; par->info = info;
par->client = client; par->client = client;
par->ops = (struct ssd1307fb_ops *)of_match_device(ssd1307fb_of_match, par->device_info = (struct ssd1307fb_deviceinfo *)of_match_device(
&client->dev)->data; ssd1307fb_of_match, &client->dev)->data;
par->reset = of_get_named_gpio(client->dev.of_node, par->reset = of_get_named_gpio(client->dev.of_node,
"reset-gpios", 0); "reset-gpios", 0);
@ -487,19 +559,51 @@ static int ssd1307fb_probe(struct i2c_client *client,
if (of_property_read_u32(node, "solomon,page-offset", &par->page_offset)) if (of_property_read_u32(node, "solomon,page-offset", &par->page_offset))
par->page_offset = 1; par->page_offset = 1;
if (of_property_read_u32(node, "solomon,com-offset", &par->com_offset))
par->com_offset = 0;
if (of_property_read_u32(node, "solomon,prechargep1", &par->prechargep1))
par->prechargep1 = 2;
if (of_property_read_u32(node, "solomon,prechargep2", &par->prechargep2))
par->prechargep2 = 2;
par->seg_remap = !of_property_read_bool(node, "solomon,segment-no-remap");
par->com_seq = of_property_read_bool(node, "solomon,com-seq");
par->com_lrremap = of_property_read_bool(node, "solomon,com-lrremap");
par->com_invdir = of_property_read_bool(node, "solomon,com-invdir");
par->contrast = 127;
par->vcomh = par->device_info->default_vcomh;
/* Setup display timing */
par->dclk_div = par->device_info->default_dclk_div;
par->dclk_frq = par->device_info->default_dclk_frq;
vmem_size = par->width * par->height / 8; vmem_size = par->width * par->height / 8;
vmem = devm_kzalloc(&client->dev, vmem_size, GFP_KERNEL); vmem = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
get_order(vmem_size));
if (!vmem) { if (!vmem) {
dev_err(&client->dev, "Couldn't allocate graphical memory.\n"); dev_err(&client->dev, "Couldn't allocate graphical memory.\n");
ret = -ENOMEM; ret = -ENOMEM;
goto fb_alloc_error; goto fb_alloc_error;
} }
ssd1307fb_defio = devm_kzalloc(&client->dev, sizeof(struct fb_deferred_io), GFP_KERNEL);
if (!ssd1307fb_defio) {
dev_err(&client->dev, "Couldn't allocate deferred io.\n");
ret = -ENOMEM;
goto fb_alloc_error;
}
ssd1307fb_defio->delay = HZ / refreshrate;
ssd1307fb_defio->deferred_io = ssd1307fb_deferred_io;
info->fbops = &ssd1307fb_ops; info->fbops = &ssd1307fb_ops;
info->fix = ssd1307fb_fix; info->fix = ssd1307fb_fix;
info->fix.line_length = par->width / 8; info->fix.line_length = par->width / 8;
info->fbdefio = &ssd1307fb_defio; info->fbdefio = ssd1307fb_defio;
info->var = ssd1307fb_var; info->var = ssd1307fb_var;
info->var.xres = par->width; info->var.xres = par->width;
@ -515,7 +619,7 @@ static int ssd1307fb_probe(struct i2c_client *client,
info->var.blue.offset = 0; info->var.blue.offset = 0;
info->screen_base = (u8 __force __iomem *)vmem; info->screen_base = (u8 __force __iomem *)vmem;
info->fix.smem_start = (unsigned long)vmem; info->fix.smem_start = __pa(vmem);
info->fix.smem_len = vmem_size; info->fix.smem_len = vmem_size;
fb_deferred_io_init(info); fb_deferred_io_init(info);
@ -538,11 +642,9 @@ static int ssd1307fb_probe(struct i2c_client *client,
gpio_set_value(par->reset, 1); gpio_set_value(par->reset, 1);
udelay(4); udelay(4);
if (par->ops->init) { ret = ssd1307fb_init(par);
ret = par->ops->init(par); if (ret)
if (ret) goto reset_oled_error;
goto reset_oled_error;
}
ret = register_framebuffer(info); ret = register_framebuffer(info);
if (ret) { if (ret) {
@ -550,13 +652,30 @@ static int ssd1307fb_probe(struct i2c_client *client,
goto panel_init_error; goto panel_init_error;
} }
snprintf(bl_name, sizeof(bl_name), "ssd1307fb%d", info->node);
bl = backlight_device_register(bl_name, &client->dev, par,
&ssd1307fb_bl_ops, NULL);
if (IS_ERR(bl)) {
dev_err(&client->dev, "unable to register backlight device: %ld\n",
PTR_ERR(bl));
goto bl_init_error;
}
bl->props.brightness = par->contrast;
bl->props.max_brightness = MAX_CONTRAST;
info->bl_dev = bl;
dev_info(&client->dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size); dev_info(&client->dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size);
return 0; return 0;
bl_init_error:
unregister_framebuffer(info);
panel_init_error: panel_init_error:
if (par->ops->remove) if (par->device_info->need_pwm) {
par->ops->remove(par); pwm_disable(par->pwm);
pwm_put(par->pwm);
};
reset_oled_error: reset_oled_error:
fb_deferred_io_cleanup(info); fb_deferred_io_cleanup(info);
fb_alloc_error: fb_alloc_error:
@ -569,16 +688,24 @@ static int ssd1307fb_remove(struct i2c_client *client)
struct fb_info *info = i2c_get_clientdata(client); struct fb_info *info = i2c_get_clientdata(client);
struct ssd1307fb_par *par = info->par; struct ssd1307fb_par *par = info->par;
ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_OFF);
backlight_device_unregister(info->bl_dev);
unregister_framebuffer(info); unregister_framebuffer(info);
if (par->ops->remove) if (par->device_info->need_pwm) {
par->ops->remove(par); pwm_disable(par->pwm);
pwm_put(par->pwm);
};
fb_deferred_io_cleanup(info); fb_deferred_io_cleanup(info);
__free_pages(__va(info->fix.smem_start), get_order(info->fix.smem_len));
framebuffer_release(info); framebuffer_release(info);
return 0; return 0;
} }
static const struct i2c_device_id ssd1307fb_i2c_id[] = { static const struct i2c_device_id ssd1307fb_i2c_id[] = {
{ "ssd1305fb", 0 },
{ "ssd1306fb", 0 }, { "ssd1306fb", 0 },
{ "ssd1307fb", 0 }, { "ssd1307fb", 0 },
{ } { }

View File

@ -78,24 +78,6 @@
#define DPRINTK(a, b...) pr_debug("fb: %s: " a, __func__ , ## b) #define DPRINTK(a, b...) pr_debug("fb: %s: " a, __func__ , ## b)
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#else
/* duplicate asm/mtrr.h defines to work on archs without mtrr */
#define MTRR_TYPE_WRCOMB 1
static inline int mtrr_add(unsigned long base, unsigned long size,
unsigned int type, char increment)
{
return -ENODEV;
}
static inline int mtrr_del(int reg, unsigned long base,
unsigned long size)
{
return -ENODEV;
}
#endif
#define BANSHEE_MAX_PIXCLOCK 270000 #define BANSHEE_MAX_PIXCLOCK 270000
#define VOODOO3_MAX_PIXCLOCK 300000 #define VOODOO3_MAX_PIXCLOCK 300000
#define VOODOO5_MAX_PIXCLOCK 350000 #define VOODOO5_MAX_PIXCLOCK 350000
@ -167,7 +149,6 @@ static int nopan;
static int nowrap = 1; /* not implemented (yet) */ static int nowrap = 1; /* not implemented (yet) */
static int hwcursor = 1; static int hwcursor = 1;
static char *mode_option; static char *mode_option;
/* mtrr option */
static bool nomtrr; static bool nomtrr;
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
@ -1454,8 +1435,8 @@ static int tdfxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_err_regbase; goto out_err_regbase;
} }
info->screen_base = ioremap_nocache(info->fix.smem_start, info->screen_base = ioremap_wc(info->fix.smem_start,
info->fix.smem_len); info->fix.smem_len);
if (!info->screen_base) { if (!info->screen_base) {
printk(KERN_ERR "fb: Can't remap %s framebuffer.\n", printk(KERN_ERR "fb: Can't remap %s framebuffer.\n",
info->fix.id); info->fix.id);
@ -1473,11 +1454,9 @@ static int tdfxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(KERN_INFO "fb: %s memory = %dK\n", info->fix.id, printk(KERN_INFO "fb: %s memory = %dK\n", info->fix.id,
info->fix.smem_len >> 10); info->fix.smem_len >> 10);
default_par->mtrr_handle = -1;
if (!nomtrr) if (!nomtrr)
default_par->mtrr_handle = default_par->wc_cookie= arch_phys_wc_add(info->fix.smem_start,
mtrr_add(info->fix.smem_start, info->fix.smem_len, info->fix.smem_len);
MTRR_TYPE_WRCOMB, 1);
info->fix.ypanstep = nopan ? 0 : 1; info->fix.ypanstep = nopan ? 0 : 1;
info->fix.ywrapstep = nowrap ? 0 : 1; info->fix.ywrapstep = nowrap ? 0 : 1;
@ -1566,9 +1545,7 @@ static int tdfxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
#ifdef CONFIG_FB_3DFX_I2C #ifdef CONFIG_FB_3DFX_I2C
tdfxfb_delete_i2c_busses(default_par); tdfxfb_delete_i2c_busses(default_par);
#endif #endif
if (default_par->mtrr_handle >= 0) arch_phys_wc_del(default_par->wc_cookie);
mtrr_del(default_par->mtrr_handle, info->fix.smem_start,
info->fix.smem_len);
release_region(pci_resource_start(pdev, 2), release_region(pci_resource_start(pdev, 2),
pci_resource_len(pdev, 2)); pci_resource_len(pdev, 2));
out_err_screenbase: out_err_screenbase:
@ -1604,10 +1581,8 @@ static void __init tdfxfb_setup(char *options)
nowrap = 1; nowrap = 1;
} else if (!strncmp(this_opt, "hwcursor=", 9)) { } else if (!strncmp(this_opt, "hwcursor=", 9)) {
hwcursor = simple_strtoul(this_opt + 9, NULL, 0); hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
#ifdef CONFIG_MTRR
} else if (!strncmp(this_opt, "nomtrr", 6)) { } else if (!strncmp(this_opt, "nomtrr", 6)) {
nomtrr = 1; nomtrr = 1;
#endif
} else { } else {
mode_option = this_opt; mode_option = this_opt;
} }
@ -1633,9 +1608,7 @@ static void tdfxfb_remove(struct pci_dev *pdev)
#ifdef CONFIG_FB_3DFX_I2C #ifdef CONFIG_FB_3DFX_I2C
tdfxfb_delete_i2c_busses(par); tdfxfb_delete_i2c_busses(par);
#endif #endif
if (par->mtrr_handle >= 0) arch_phys_wc_del(par->wc_cookie);
mtrr_del(par->mtrr_handle, info->fix.smem_start,
info->fix.smem_len);
iounmap(par->regbase_virt); iounmap(par->regbase_virt);
iounmap(info->screen_base); iounmap(info->screen_base);
@ -1677,10 +1650,8 @@ MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
"(1=enable, 0=disable, default=1)"); "(1=enable, 0=disable, default=1)");
module_param(mode_option, charp, 0); module_param(mode_option, charp, 0);
MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'"); MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
#ifdef CONFIG_MTRR
module_param(nomtrr, bool, 0); module_param(nomtrr, bool, 0);
MODULE_PARM_DESC(nomtrr, "Disable MTRR support (default: enabled)"); MODULE_PARM_DESC(nomtrr, "Disable MTRR support (default: enabled)");
#endif
module_init(tdfxfb_init); module_init(tdfxfb_init);
module_exit(tdfxfb_exit); module_exit(tdfxfb_exit);

View File

@ -19,16 +19,20 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/screen_info.h> #include <linux/screen_info.h>
#include <linux/io.h>
#include <video/vga.h> #include <video/vga.h>
#include <asm/io.h>
#include <asm/mtrr.h>
#define dac_reg (0x3c8) #define dac_reg (0x3c8)
#define dac_val (0x3c9) #define dac_val (0x3c9)
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
struct vesafb_par {
u32 pseudo_palette[256];
int wc_cookie;
};
static struct fb_var_screeninfo vesafb_defined = { static struct fb_var_screeninfo vesafb_defined = {
.activate = FB_ACTIVATE_NOW, .activate = FB_ACTIVATE_NOW,
.height = -1, .height = -1,
@ -175,7 +179,10 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
static void vesafb_destroy(struct fb_info *info) static void vesafb_destroy(struct fb_info *info)
{ {
struct vesafb_par *par = info->par;
fb_dealloc_cmap(&info->cmap); fb_dealloc_cmap(&info->cmap);
arch_phys_wc_del(par->wc_cookie);
if (info->screen_base) if (info->screen_base)
iounmap(info->screen_base); iounmap(info->screen_base);
release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size);
@ -228,6 +235,7 @@ static int vesafb_setup(char *options)
static int vesafb_probe(struct platform_device *dev) static int vesafb_probe(struct platform_device *dev)
{ {
struct fb_info *info; struct fb_info *info;
struct vesafb_par *par;
int i, err; int i, err;
unsigned int size_vmode; unsigned int size_vmode;
unsigned int size_remap; unsigned int size_remap;
@ -291,14 +299,14 @@ static int vesafb_probe(struct platform_device *dev)
spaces our resource handlers simply don't know about */ spaces our resource handlers simply don't know about */
} }
info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev); info = framebuffer_alloc(sizeof(struct vesafb_par), &dev->dev);
if (!info) { if (!info) {
release_mem_region(vesafb_fix.smem_start, size_total); release_mem_region(vesafb_fix.smem_start, size_total);
return -ENOMEM; return -ENOMEM;
} }
platform_set_drvdata(dev, info); platform_set_drvdata(dev, info);
info->pseudo_palette = info->par; par = info->par;
info->par = NULL; info->pseudo_palette = par->pseudo_palette;
/* set vesafb aperture size for generic probing */ /* set vesafb aperture size for generic probing */
info->apertures = alloc_apertures(1); info->apertures = alloc_apertures(1);
@ -404,60 +412,27 @@ static int vesafb_probe(struct platform_device *dev)
* region already (FIXME) */ * region already (FIXME) */
request_region(0x3c0, 32, "vesafb"); request_region(0x3c0, 32, "vesafb");
#ifdef CONFIG_MTRR if (mtrr == 3) {
if (mtrr) {
unsigned int temp_size = size_total; unsigned int temp_size = size_total;
unsigned int type = 0;
switch (mtrr) { /* Find the largest power-of-two */
case 1: temp_size = roundup_pow_of_two(temp_size);
type = MTRR_TYPE_UNCACHABLE;
break;
case 2:
type = MTRR_TYPE_WRBACK;
break;
case 3:
type = MTRR_TYPE_WRCOMB;
break;
case 4:
type = MTRR_TYPE_WRTHROUGH;
break;
default:
type = 0;
break;
}
if (type) { /* Try and find a power of two to add */
int rc; do {
par->wc_cookie =
arch_phys_wc_add(vesafb_fix.smem_start,
temp_size);
temp_size >>= 1;
} while (temp_size >= PAGE_SIZE && par->wc_cookie < 0);
/* Find the largest power-of-two */
temp_size = roundup_pow_of_two(temp_size);
/* Try and find a power of two to add */
do {
rc = mtrr_add(vesafb_fix.smem_start, temp_size,
type, 1);
temp_size >>= 1;
} while (temp_size >= PAGE_SIZE && rc == -EINVAL);
}
}
#endif
switch (mtrr) {
case 1: /* uncachable */
info->screen_base = ioremap_nocache(vesafb_fix.smem_start, vesafb_fix.smem_len);
break;
case 2: /* write-back */
info->screen_base = ioremap_cache(vesafb_fix.smem_start, vesafb_fix.smem_len);
break;
case 3: /* write-combining */
info->screen_base = ioremap_wc(vesafb_fix.smem_start, vesafb_fix.smem_len); info->screen_base = ioremap_wc(vesafb_fix.smem_start, vesafb_fix.smem_len);
break; } else {
case 4: /* write-through */ if (mtrr && mtrr != 3)
default: WARN_ONCE(1, "Only MTRR_TYPE_WRCOMB (3) make sense\n");
info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len); info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
break;
} }
if (!info->screen_base) { if (!info->screen_base) {
printk(KERN_ERR printk(KERN_ERR
"vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n", "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
@ -492,6 +467,7 @@ static int vesafb_probe(struct platform_device *dev)
fb_info(info, "%s frame buffer device\n", info->fix.id); fb_info(info, "%s frame buffer device\n", info->fix.id);
return 0; return 0;
err: err:
arch_phys_wc_del(par->wc_cookie);
if (info->screen_base) if (info->screen_base)
iounmap(info->screen_base); iounmap(info->screen_base);
framebuffer_release(info); framebuffer_release(info);

View File

@ -1,146 +0,0 @@
/*
* Internal shared definitions for various MSM framebuffer parts.
*
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _MSM_FB_H_
#define _MSM_FB_H_
#include <linux/device.h>
struct mddi_info;
struct msm_fb_data {
int xres; /* x resolution in pixels */
int yres; /* y resolution in pixels */
int width; /* disply width in mm */
int height; /* display height in mm */
unsigned output_format;
};
struct msmfb_callback {
void (*func)(struct msmfb_callback *);
};
enum {
MSM_MDDI_PMDH_INTERFACE,
MSM_MDDI_EMDH_INTERFACE,
MSM_EBI2_INTERFACE,
};
#define MSMFB_CAP_PARTIAL_UPDATES (1 << 0)
struct msm_panel_data {
/* turns off the fb memory */
int (*suspend)(struct msm_panel_data *);
/* turns on the fb memory */
int (*resume)(struct msm_panel_data *);
/* turns off the panel */
int (*blank)(struct msm_panel_data *);
/* turns on the panel */
int (*unblank)(struct msm_panel_data *);
void (*wait_vsync)(struct msm_panel_data *);
void (*request_vsync)(struct msm_panel_data *, struct msmfb_callback *);
void (*clear_vsync)(struct msm_panel_data *);
/* from the enum above */
unsigned interface_type;
/* data to be passed to the fb driver */
struct msm_fb_data *fb_data;
/* capabilities supported by the panel */
uint32_t caps;
};
struct msm_mddi_client_data {
void (*suspend)(struct msm_mddi_client_data *);
void (*resume)(struct msm_mddi_client_data *);
void (*activate_link)(struct msm_mddi_client_data *);
void (*remote_write)(struct msm_mddi_client_data *, uint32_t val,
uint32_t reg);
uint32_t (*remote_read)(struct msm_mddi_client_data *, uint32_t reg);
void (*auto_hibernate)(struct msm_mddi_client_data *, int);
/* custom data that needs to be passed from the board file to a
* particular client */
void *private_client_data;
struct resource *fb_resource;
/* from the list above */
unsigned interface_type;
};
struct msm_mddi_platform_data {
unsigned int clk_rate;
void (*power_client)(struct msm_mddi_client_data *, int on);
/* fixup the mfr name, product id */
void (*fixup)(uint16_t *mfr_name, uint16_t *product_id);
struct resource *fb_resource; /*optional*/
/* number of clients in the list that follows */
int num_clients;
/* array of client information of clients */
struct {
unsigned product_id; /* mfr id in top 16 bits, product id
* in lower 16 bits
*/
char *name; /* the device name will be the platform
* device name registered for the client,
* it should match the name of the associated
* driver
*/
unsigned id; /* id for mddi client device node, will also
* be used as device id of panel devices, if
* the client device will have multiple panels
* space must be left here for them
*/
void *client_data; /* required private client data */
unsigned int clk_rate; /* optional: if the client requires a
* different mddi clk rate
*/
} client_platform_data[];
};
struct mdp_blit_req;
struct fb_info;
struct mdp_device {
struct device dev;
void (*dma)(struct mdp_device *mpd, uint32_t addr,
uint32_t stride, uint32_t w, uint32_t h, uint32_t x,
uint32_t y, struct msmfb_callback *callback, int interface);
void (*dma_wait)(struct mdp_device *mdp);
int (*blit)(struct mdp_device *mdp, struct fb_info *fb,
struct mdp_blit_req *req);
void (*set_grp_disp)(struct mdp_device *mdp, uint32_t disp_id);
};
struct class_interface;
int register_mdp_client(struct class_interface *class_intf);
/**** private client data structs go below this line ***/
struct msm_mddi_bridge_platform_data {
/* from board file */
int (*init)(struct msm_mddi_bridge_platform_data *,
struct msm_mddi_client_data *);
int (*uninit)(struct msm_mddi_bridge_platform_data *,
struct msm_mddi_client_data *);
/* passed to panel for use by the fb driver */
int (*blank)(struct msm_mddi_bridge_platform_data *,
struct msm_mddi_client_data *);
int (*unblank)(struct msm_mddi_bridge_platform_data *,
struct msm_mddi_client_data *);
struct msm_fb_data fb_data;
};
#endif

View File

@ -159,10 +159,7 @@ struct neofb_par {
unsigned char VCLK3NumeratorHigh; unsigned char VCLK3NumeratorHigh;
unsigned char VCLK3Denominator; unsigned char VCLK3Denominator;
unsigned char VerticalExt; unsigned char VerticalExt;
int wc_cookie;
#ifdef CONFIG_MTRR
int mtrr;
#endif
u8 __iomem *mmio_vbase; u8 __iomem *mmio_vbase;
u8 cursorOff; u8 cursorOff;
u8 *cursorPad; /* Must die !! */ u8 *cursorPad; /* Must die !! */

View File

@ -196,7 +196,7 @@ struct tdfx_par {
u32 palette[16]; u32 palette[16];
void __iomem *regbase_virt; void __iomem *regbase_virt;
unsigned long iobase; unsigned long iobase;
int mtrr_handle; int wc_cookie;
#ifdef CONFIG_FB_3DFX_I2C #ifdef CONFIG_FB_3DFX_I2C
struct tdfxfb_i2c_chan chan[2]; struct tdfxfb_i2c_chan chan[2];
#endif #endif

View File

@ -210,16 +210,18 @@ static int hdmi_dai_hw_params(struct snd_pcm_substream *substream,
cea->db3 = 0; /* not used, all zeros */ cea->db3 = 0; /* not used, all zeros */
/*
* The OMAP HDMI IP requires to use the 8-channel channel code when
* transmitting more than two channels.
*/
if (params_channels(params) == 2) if (params_channels(params) == 2)
cea->db4_ca = 0x0; cea->db4_ca = 0x0;
else if (params_channels(params) == 6)
cea->db4_ca = 0xb;
else else
cea->db4_ca = 0x13; cea->db4_ca = 0x13;
cea->db5_dminh_lsv = CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PROHIBITED; if (cea->db4_ca == 0x00)
cea->db5_dminh_lsv = CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PERMITTED;
else
cea->db5_dminh_lsv = CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PROHIBITED;
/* the expression is trivial but makes clear what we are doing */ /* the expression is trivial but makes clear what we are doing */
cea->db5_dminh_lsv |= (0 & CEA861_AUDIO_INFOFRAME_DB5_LSV); cea->db5_dminh_lsv |= (0 & CEA861_AUDIO_INFOFRAME_DB5_LSV);