Merge branch 'drm/du/adv7511' of git://linuxtv.org/pinchartl/fbdev into drm-next

The branch is based on a merge of drm-next and Simon's tags/renesas-dt-du-for-
v3.19 available at
git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git, the latter
having been pulled in the ARM SoC tree for v3.19.

Compared to v1, I've rebased my branch on a later drm-next, added Julia's
error return code fix, and documented the "drm: Decouple EDID parsing from I2C
adapter" patch properly.

v1:
Here's a pull request that adds HDMI support to the R-Car DU driver, including
a new slave encoder driver for the adv7511.

* 'drm/du/adv7511' of git://linuxtv.org/pinchartl/fbdev:
  drm: Add adv7511 encoder driver
  video: Add ADV751[13] DT bindings documentation
  drm: Decouple EDID parsing from I2C adapter
  drm: rcar-du: Add HDMI encoder and connector support
  drm: rcar-du: Replace drm_encoder with drm_slave_encoder
  drm: rcar-du: Replace direct DRM encoder access with cast macro
  drm: rcar-du: Pass the encoder DT node to rcar_du_encoder_init()
  drm: rcar-du: Remove platform data support
  drm: rcar-du: fix error return code
  ARM: shmobile: koelsch: Enable DU device in DT
  ARM: shmobile: koelsch-reference: Remove DU platform device
  ARM: shmobile: lager: Enable DU device in DT
  ARM: shmobile: lager-reference: Remove DU platform device
  ARM: shmobile: marzen: Enable DU device in DT
  ARM: shmobile: dts: Add common file for AA104XD12 panel
  ARM: shmobile: r8a7791: Add DU node to device tree
  ARM: shmobile: r8a7790: Add DU node to device tree
  ARM: shmobile: r8a7779: Add DU node to device tree
  ARM: shmobile: Remove FSF address from copyright headers
This commit is contained in:
Dave Airlie 2014-11-27 08:36:19 +10:00
commit 21769c6754
77 changed files with 2232 additions and 524 deletions

View File

@ -0,0 +1,88 @@
Analog Device ADV7511(W)/13 HDMI Encoders
-----------------------------------------
The ADV7511, ADV7511W and ADV7513 are HDMI audio and video transmitters
compatible with HDMI 1.4 and DVI 1.0. They support color space conversion,
S/PDIF, CEC and HDCP.
Required properties:
- compatible: Should be one of "adi,adv7511", "adi,adv7511w" or "adi,adv7513"
- reg: I2C slave address
The ADV7511 supports a large number of input data formats that differ by their
color depth, color format, clock mode, bit justification and random
arrangement of components on the data bus. The combination of the following
properties describe the input and map directly to the video input tables of the
ADV7511 datasheet that document all the supported combinations.
- adi,input-depth: Number of bits per color component at the input (8, 10 or
12).
- adi,input-colorspace: The input color space, one of "rgb", "yuv422" or
"yuv444".
- adi,input-clock: The input clock type, one of "1x" (one clock cycle per
pixel), "2x" (two clock cycles per pixel), "ddr" (one clock cycle per pixel,
data driven on both edges).
The following input format properties are required except in "rgb 1x" and
"yuv444 1x" modes, in which case they must not be specified.
- adi,input-style: The input components arrangement variant (1, 2 or 3), as
listed in the input format tables in the datasheet.
- adi,input-justification: The input bit justification ("left", "evenly",
"right").
Optional properties:
- interrupts: Specifier for the ADV7511 interrupt
- pd-gpios: Specifier for the GPIO connected to the power down signal
- adi,clock-delay: Video data clock delay relative to the pixel clock, in ps
(-1200 ps .. 1600 ps). Defaults to no delay.
- adi,embedded-sync: The input uses synchronization signals embedded in the
data stream (similar to BT.656). Defaults to separate H/V synchronization
signals.
Required nodes:
The ADV7511 has two video ports. Their connections are modelled using the OF
graph bindings specified in Documentation/devicetree/bindings/graph.txt.
- Video port 0 for the RGB or YUV input
- Video port 1 for the HDMI output
Example
-------
adv7511w: hdmi@39 {
compatible = "adi,adv7511w";
reg = <39>;
interrupt-parent = <&gpio3>;
interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
adi,input-depth = <8>;
adi,input-colorspace = "rgb";
adi,input-clock = "1x";
adi,input-style = <1>;
adi,input-justification = "evenly";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
adv7511w_in: endpoint {
remote-endpoint = <&dpi_out>;
};
};
port@1 {
reg = <1>;
adv7511_out: endpoint {
remote-endpoint = <&hdmi_connector_in>;
};
};
};
};

View File

@ -68,6 +68,78 @@ led4 {
gpios = <&gpio4 31 GPIO_ACTIVE_HIGH>;
};
};
vga-encoder {
compatible = "adi,adv7123";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
vga_enc_in: endpoint {
remote-endpoint = <&du_out_rgb0>;
};
};
port@1 {
reg = <1>;
vga_enc_out: endpoint {
remote-endpoint = <&vga_in>;
};
};
};
};
vga {
compatible = "vga-connector";
port {
vga_in: endpoint {
remote-endpoint = <&vga_enc_out>;
};
};
};
lvds-encoder {
compatible = "thine,thc63lvdm83d";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
lvds_enc_in: endpoint {
remote-endpoint = <&du_out_rgb1>;
};
};
port@1 {
reg = <1>;
lvds_connector: endpoint {
};
};
};
};
};
&du {
pinctrl-0 = <&du_pins>;
pinctrl-names = "default";
status = "okay";
ports {
port@0 {
endpoint {
remote-endpoint = <&vga_enc_in>;
};
};
port@1 {
endpoint {
remote-endpoint = <&lvds_enc_in>;
};
};
};
};
&irqpin0 {
@ -83,6 +155,17 @@ &tmu0 {
};
&pfc {
du_pins: du {
du0 {
renesas,groups = "du0_rgb888", "du0_sync_1", "du0_clk_out_0";
renesas,function = "du0";
};
du1 {
renesas,groups = "du1_rgb666", "du1_sync_1", "du1_clk_out";
renesas,function = "du1";
};
};
lan0_pins: lan0 {
intc {
renesas,groups = "intc_irq1_b";

View File

@ -379,6 +379,30 @@ hspi2: spi@fffc6000 {
status = "disabled";
};
du: display@fff80000 {
compatible = "renesas,du-r8a7779";
reg = <0 0xfff80000 0 0x40000>;
interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7779_CLK_DU>;
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
du_out_rgb0: endpoint {
};
};
port@1 {
reg = <1>;
du_out_rgb1: endpoint {
};
};
};
};
clocks {
#address-cells = <1>;
#size-cells = <1>;

View File

@ -144,6 +144,56 @@ vccq_sdhi2: regulator@4 {
states = <3300000 1
1800000 0>;
};
vga-encoder {
compatible = "adi,adv7123";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
adv7123_in: endpoint {
remote-endpoint = <&du_out_rgb>;
};
};
port@1 {
reg = <1>;
adv7123_out: endpoint {
remote-endpoint = <&vga_in>;
};
};
};
};
vga {
compatible = "vga-connector";
port {
vga_in: endpoint {
remote-endpoint = <&adv7123_out>;
};
};
};
};
&du {
pinctrl-0 = <&du_pins>;
pinctrl-names = "default";
status = "okay";
ports {
port@0 {
endpoint {
remote-endpoint = <&adv7123_in>;
};
};
port@2 {
lvds_connector: endpoint {
};
};
};
};
&extal_clk {
@ -151,9 +201,6 @@ &extal_clk {
};
&pfc {
pinctrl-0 = <&du_pins>;
pinctrl-names = "default";
du_pins: du {
renesas,groups = "du_rgb666", "du_sync_1", "du_clk_out_0";
renesas,function = "du";

View File

@ -600,6 +600,96 @@ vin3: video@e6ef3000 {
status = "disabled";
};
vsp1@fe920000 {
compatible = "renesas,vsp1";
reg = <0 0xfe920000 0 0x8000>;
interrupts = <0 266 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7790_CLK_VSP1_R>;
renesas,has-sru;
renesas,#rpf = <5>;
renesas,#uds = <1>;
renesas,#wpf = <4>;
};
vsp1@fe928000 {
compatible = "renesas,vsp1";
reg = <0 0xfe928000 0 0x8000>;
interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7790_CLK_VSP1_S>;
renesas,has-lut;
renesas,has-sru;
renesas,#rpf = <5>;
renesas,#uds = <3>;
renesas,#wpf = <4>;
};
vsp1@fe930000 {
compatible = "renesas,vsp1";
reg = <0 0xfe930000 0 0x8000>;
interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU0>;
renesas,has-lif;
renesas,has-lut;
renesas,#rpf = <4>;
renesas,#uds = <1>;
renesas,#wpf = <4>;
};
vsp1@fe938000 {
compatible = "renesas,vsp1";
reg = <0 0xfe938000 0 0x8000>;
interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU1>;
renesas,has-lif;
renesas,has-lut;
renesas,#rpf = <4>;
renesas,#uds = <1>;
renesas,#wpf = <4>;
};
du: display@feb00000 {
compatible = "renesas,du-r8a7790";
reg = <0 0xfeb00000 0 0x70000>,
<0 0xfeb90000 0 0x1c>,
<0 0xfeb94000 0 0x1c>;
reg-names = "du", "lvds.0", "lvds.1";
interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>,
<0 268 IRQ_TYPE_LEVEL_HIGH>,
<0 269 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp7_clks R8A7790_CLK_DU0>,
<&mstp7_clks R8A7790_CLK_DU1>,
<&mstp7_clks R8A7790_CLK_DU2>,
<&mstp7_clks R8A7790_CLK_LVDS0>,
<&mstp7_clks R8A7790_CLK_LVDS1>;
clock-names = "du.0", "du.1", "du.2", "lvds.0", "lvds.1";
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
du_out_rgb: endpoint {
};
};
port@1 {
reg = <1>;
du_out_lvds0: endpoint {
};
};
port@2 {
reg = <2>;
du_out_lvds1: endpoint {
};
};
};
};
clocks {
#address-cells = <2>;
#size-cells = <2>;

View File

@ -211,14 +211,24 @@ vccq_sdhi2: regulator@5 {
};
};
&du {
pinctrl-0 = <&du_pins>;
pinctrl-names = "default";
status = "okay";
ports {
port@1 {
lvds_connector: endpoint {
};
};
};
};
&extal_clk {
clock-frequency = <20000000>;
};
&pfc {
pinctrl-0 = <&du_pins>;
pinctrl-names = "default";
i2c2_pins: i2c2 {
renesas,groups = "i2c2";
renesas,function = "i2c2";

View File

@ -637,6 +637,75 @@ vin2: video@e6ef2000 {
status = "disabled";
};
vsp1@fe928000 {
compatible = "renesas,vsp1";
reg = <0 0xfe928000 0 0x8000>;
interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7791_CLK_VSP1_S>;
renesas,has-lut;
renesas,has-sru;
renesas,#rpf = <5>;
renesas,#uds = <3>;
renesas,#wpf = <4>;
};
vsp1@fe930000 {
compatible = "renesas,vsp1";
reg = <0 0xfe930000 0 0x8000>;
interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU0>;
renesas,has-lif;
renesas,has-lut;
renesas,#rpf = <4>;
renesas,#uds = <1>;
renesas,#wpf = <4>;
};
vsp1@fe938000 {
compatible = "renesas,vsp1";
reg = <0 0xfe938000 0 0x8000>;
interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU1>;
renesas,has-lif;
renesas,has-lut;
renesas,#rpf = <4>;
renesas,#uds = <1>;
renesas,#wpf = <4>;
};
du: display@feb00000 {
compatible = "renesas,du-r8a7791";
reg = <0 0xfeb00000 0 0x40000>,
<0 0xfeb90000 0 0x1c>;
reg-names = "du", "lvds.0";
interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>,
<0 268 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp7_clks R8A7791_CLK_DU0>,
<&mstp7_clks R8A7791_CLK_DU1>,
<&mstp7_clks R8A7791_CLK_LVDS0>;
clock-names = "du.0", "du.1", "lvds.0";
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
du_out_rgb: endpoint {
};
};
port@1 {
reg = <1>;
du_out_lvds0: endpoint {
};
};
};
};
clocks {
#address-cells = <2>;
#size-cells = <2>;

View File

@ -0,0 +1,41 @@
/*
* Common file for the AA104XD12 panel connected to Renesas R-Car boards
*
* Copyright (C) 2014 Renesas Electronics Corp.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
/ {
panel {
compatible = "mitsubishi,aa104xd12", "panel-dpi";
width-mm = <210>;
height-mm = <158>;
panel-timing {
/* 1024x768 @65Hz */
clock-frequency = <65000000>;
hactive = <1024>;
vactive = <768>;
hsync-len = <136>;
hfront-porch = <20>;
hback-porch = <160>;
vfront-porch = <3>;
vback-porch = <29>;
vsync-len = <6>;
};
port {
panel_in: endpoint {
remote-endpoint = <&lvds_connector>;
};
};
};
};
&lvds_connector {
remote-endpoint = <&panel_in>;
};

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/gpio.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/gpio.h>

View File

@ -12,11 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <linux/clk.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/of_platform.h>

View File

@ -13,10 +13,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/mfd/tmio.h>

View File

@ -13,93 +13,17 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/of_platform.h>
#include <linux/platform_data/rcar-du.h>
#include <asm/mach/arch.h>
#include "clock.h"
#include "common.h"
#include "irqs.h"
#include "r8a7791.h"
#include "rcar-gen2.h"
/* DU */
static struct rcar_du_encoder_data koelsch_du_encoders[] = {
{
.type = RCAR_DU_ENCODER_NONE,
.output = RCAR_DU_OUTPUT_LVDS0,
.connector.lvds.panel = {
.width_mm = 210,
.height_mm = 158,
.mode = {
.pixelclock = 65000000,
.hactive = 1024,
.hfront_porch = 20,
.hback_porch = 160,
.hsync_len = 136,
.vactive = 768,
.vfront_porch = 3,
.vback_porch = 29,
.vsync_len = 6,
},
},
},
};
static struct rcar_du_platform_data koelsch_du_pdata = {
.encoders = koelsch_du_encoders,
.num_encoders = ARRAY_SIZE(koelsch_du_encoders),
};
static const struct resource du_resources[] __initconst = {
DEFINE_RES_MEM(0xfeb00000, 0x40000),
DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"),
DEFINE_RES_IRQ(gic_spi(256)),
DEFINE_RES_IRQ(gic_spi(268)),
};
static void __init koelsch_add_du_device(void)
{
struct platform_device_info info = {
.name = "rcar-du-r8a7791",
.id = -1,
.res = du_resources,
.num_res = ARRAY_SIZE(du_resources),
.data = &koelsch_du_pdata,
.size_data = sizeof(koelsch_du_pdata),
.dma_mask = DMA_BIT_MASK(32),
};
platform_device_register_full(&info);
}
/*
* This is a really crude hack to provide clkdev support to platform
* devices until they get moved to DT.
*/
static const struct clk_name clk_names[] __initconst = {
{ "du0", "du.0", "rcar-du-r8a7791" },
{ "du1", "du.1", "rcar-du-r8a7791" },
{ "lvds0", "lvds.0", "rcar-du-r8a7791" },
};
static void __init koelsch_add_standard_devices(void)
{
shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false);
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
koelsch_add_du_device();
}
static const char * const koelsch_boards_compat_dt[] __initconst = {
"renesas,koelsch",
"renesas,koelsch-reference",
@ -110,7 +34,6 @@ DT_MACHINE_START(KOELSCH_DT, "koelsch")
.smp = smp_ops(r8a7791_smp_ops),
.init_early = shmobile_init_delay,
.init_time = rcar_gen2_timer_init,
.init_machine = koelsch_add_standard_devices,
.init_late = shmobile_init_late,
.reserve = rcar_gen2_reserve,
.dt_compat = koelsch_boards_compat_dt,

View File

@ -14,10 +14,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/dma-mapping.h>

View File

@ -14,10 +14,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/delay.h>

View File

@ -11,10 +11,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/delay.h>

View File

@ -12,100 +12,17 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/platform_data/rcar-du.h>
#include <asm/mach/arch.h>
#include "clock.h"
#include "common.h"
#include "irqs.h"
#include "r8a7790.h"
#include "rcar-gen2.h"
/* DU */
static struct rcar_du_encoder_data lager_du_encoders[] = {
{
.type = RCAR_DU_ENCODER_VGA,
.output = RCAR_DU_OUTPUT_DPAD0,
}, {
.type = RCAR_DU_ENCODER_NONE,
.output = RCAR_DU_OUTPUT_LVDS1,
.connector.lvds.panel = {
.width_mm = 210,
.height_mm = 158,
.mode = {
.pixelclock = 65000000,
.hactive = 1024,
.hfront_porch = 20,
.hback_porch = 160,
.hsync_len = 136,
.vactive = 768,
.vfront_porch = 3,
.vback_porch = 29,
.vsync_len = 6,
},
},
},
};
static struct rcar_du_platform_data lager_du_pdata = {
.encoders = lager_du_encoders,
.num_encoders = ARRAY_SIZE(lager_du_encoders),
};
static const struct resource du_resources[] __initconst = {
DEFINE_RES_MEM(0xfeb00000, 0x70000),
DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"),
DEFINE_RES_MEM_NAMED(0xfeb94000, 0x1c, "lvds.1"),
DEFINE_RES_IRQ(gic_spi(256)),
DEFINE_RES_IRQ(gic_spi(268)),
DEFINE_RES_IRQ(gic_spi(269)),
};
static void __init lager_add_du_device(void)
{
struct platform_device_info info = {
.name = "rcar-du-r8a7790",
.id = -1,
.res = du_resources,
.num_res = ARRAY_SIZE(du_resources),
.data = &lager_du_pdata,
.size_data = sizeof(lager_du_pdata),
.dma_mask = DMA_BIT_MASK(32),
};
platform_device_register_full(&info);
}
/*
* This is a really crude hack to provide clkdev support to platform
* devices until they get moved to DT.
*/
static const struct clk_name clk_names[] __initconst = {
{ "du0", "du.0", "rcar-du-r8a7790" },
{ "du1", "du.1", "rcar-du-r8a7790" },
{ "du2", "du.2", "rcar-du-r8a7790" },
{ "lvds0", "lvds.0", "rcar-du-r8a7790" },
{ "lvds1", "lvds.1", "rcar-du-r8a7790" },
};
static void __init lager_add_standard_devices(void)
{
shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false);
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
lager_add_du_device();
}
static const char *lager_boards_compat_dt[] __initdata = {
"renesas,lager",
"renesas,lager-reference",
@ -116,7 +33,6 @@ DT_MACHINE_START(LAGER_DT, "lager")
.smp = smp_ops(r8a7790_smp_ops),
.init_early = shmobile_init_delay,
.init_time = rcar_gen2_timer_init,
.init_machine = lager_add_standard_devices,
.init_late = shmobile_init_late,
.reserve = rcar_gen2_reserve,
.dt_compat = lager_boards_compat_dt,

View File

@ -13,10 +13,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/gpio.h>

View File

@ -16,10 +16,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/delay.h>
#include <linux/kernel.h>

View File

@ -13,10 +13,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/clk/shmobile.h>

View File

@ -13,10 +13,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/init.h>
#include <linux/io.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>

View File

@ -17,10 +17,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/bitops.h>
#include <linux/init.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/init.h>
#include <linux/io.h>

View File

@ -13,10 +13,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/init.h>
#include <linux/io.h>

View File

@ -11,10 +11,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>

View File

@ -11,10 +11,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>

View File

@ -14,10 +14,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <linux/kernel.h>
#include <linux/init.h>

View File

@ -11,10 +11,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>

View File

@ -12,11 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <linux/linkage.h>

View File

@ -11,10 +11,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>

View File

@ -11,10 +11,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>

View File

@ -10,10 +10,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __ASM_R8A7740_H__

View File

@ -11,10 +11,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __ASM_R8A7778_H__
#define __ASM_R8A7778_H__

View File

@ -11,10 +11,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/irq.h>
#include <linux/kernel.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/delay.h>
#include <linux/dma-mapping.h>

View File

@ -13,10 +13,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>

View File

@ -13,10 +13,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/irq.h>

View File

@ -13,10 +13,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/irq.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/clk/shmobile.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>

View File

@ -13,10 +13,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>

View File

@ -22,11 +22,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <linux/linkage.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>

View File

@ -12,10 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>

View File

@ -12,11 +12,6 @@
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <linux/platform_device.h>
#include <linux/clocksource.h>

View File

@ -1125,9 +1125,9 @@ EXPORT_SYMBOL(drm_edid_is_valid);
* Return: 0 on success or -1 on failure.
*/
static int
drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
int block, int len)
drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len)
{
struct i2c_adapter *adapter = data;
unsigned char start = block * EDID_LENGTH;
unsigned char segment = block >> 1;
unsigned char xfers = segment ? 3 : 2;
@ -1184,8 +1184,26 @@ static bool drm_edid_is_zero(u8 *in_edid, int length)
return true;
}
static u8 *
drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
/**
* drm_do_get_edid - get EDID data using a custom EDID block read function
* @connector: connector we're probing
* @get_edid_block: EDID block read function
* @data: private data passed to the block read function
*
* When the I2C adapter connected to the DDC bus is hidden behind a device that
* exposes a different interface to read EDID blocks this function can be used
* to get EDID data using a custom block read function.
*
* As in the general case the DDC bus is accessible by the kernel at the I2C
* level, drivers must make all reasonable efforts to expose it as an I2C
* adapter and use drm_get_edid() instead of abusing this function.
*
* Return: Pointer to valid EDID or NULL if we couldn't find any.
*/
struct edid *drm_do_get_edid(struct drm_connector *connector,
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
size_t len),
void *data)
{
int i, j = 0, valid_extensions = 0;
u8 *block, *new;
@ -1196,7 +1214,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
/* base block fetch */
for (i = 0; i < 4; i++) {
if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH))
if (get_edid_block(data, block, 0, EDID_LENGTH))
goto out;
if (drm_edid_block_valid(block, 0, print_bad_edid))
break;
@ -1210,7 +1228,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
/* if there's no extensions, we're done */
if (block[0x7e] == 0)
return block;
return (struct edid *)block;
new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL);
if (!new)
@ -1219,7 +1237,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
for (j = 1; j <= block[0x7e]; j++) {
for (i = 0; i < 4; i++) {
if (drm_do_probe_ddc_edid(adapter,
if (get_edid_block(data,
block + (valid_extensions + 1) * EDID_LENGTH,
j, EDID_LENGTH))
goto out;
@ -1247,7 +1265,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
block = new;
}
return block;
return (struct edid *)block;
carp:
if (print_bad_edid) {
@ -1260,6 +1278,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
kfree(block);
return NULL;
}
EXPORT_SYMBOL_GPL(drm_do_get_edid);
/**
* drm_probe_ddc() - probe DDC presence
@ -1289,12 +1308,10 @@ EXPORT_SYMBOL(drm_probe_ddc);
struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter)
{
struct edid *edid = NULL;
if (!drm_probe_ddc(adapter))
return NULL;
if (drm_probe_ddc(adapter))
edid = (struct edid *)drm_do_get_edid(connector, adapter);
return edid;
return drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
}
EXPORT_SYMBOL(drm_get_edid);

View File

@ -1,6 +1,12 @@
menu "I2C encoder or helper chips"
depends on DRM && DRM_KMS_HELPER && I2C
config DRM_I2C_ADV7511
tristate "AV7511 encoder"
select REGMAP_I2C
help
Support for the Analog Device ADV7511(W) and ADV7513 HDMI encoders.
config DRM_I2C_CH7006
tristate "Chrontel ch7006 TV encoder"
default m if DRM_NOUVEAU

View File

@ -1,5 +1,7 @@
ccflags-y := -Iinclude/drm
obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511.o
ch7006-y := ch7006_drv.o ch7006_mode.o
obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,289 @@
/*
* Analog Devices ADV7511 HDMI transmitter driver
*
* Copyright 2012 Analog Devices Inc.
*
* Licensed under the GPL-2.
*/
#ifndef __DRM_I2C_ADV7511_H__
#define __DRM_I2C_ADV7511_H__
#include <linux/hdmi.h>
#define ADV7511_REG_CHIP_REVISION 0x00
#define ADV7511_REG_N0 0x01
#define ADV7511_REG_N1 0x02
#define ADV7511_REG_N2 0x03
#define ADV7511_REG_SPDIF_FREQ 0x04
#define ADV7511_REG_CTS_AUTOMATIC1 0x05
#define ADV7511_REG_CTS_AUTOMATIC2 0x06
#define ADV7511_REG_CTS_MANUAL0 0x07
#define ADV7511_REG_CTS_MANUAL1 0x08
#define ADV7511_REG_CTS_MANUAL2 0x09
#define ADV7511_REG_AUDIO_SOURCE 0x0a
#define ADV7511_REG_AUDIO_CONFIG 0x0b
#define ADV7511_REG_I2S_CONFIG 0x0c
#define ADV7511_REG_I2S_WIDTH 0x0d
#define ADV7511_REG_AUDIO_SUB_SRC0 0x0e
#define ADV7511_REG_AUDIO_SUB_SRC1 0x0f
#define ADV7511_REG_AUDIO_SUB_SRC2 0x10
#define ADV7511_REG_AUDIO_SUB_SRC3 0x11
#define ADV7511_REG_AUDIO_CFG1 0x12
#define ADV7511_REG_AUDIO_CFG2 0x13
#define ADV7511_REG_AUDIO_CFG3 0x14
#define ADV7511_REG_I2C_FREQ_ID_CFG 0x15
#define ADV7511_REG_VIDEO_INPUT_CFG1 0x16
#define ADV7511_REG_CSC_UPPER(x) (0x18 + (x) * 2)
#define ADV7511_REG_CSC_LOWER(x) (0x19 + (x) * 2)
#define ADV7511_REG_SYNC_DECODER(x) (0x30 + (x))
#define ADV7511_REG_DE_GENERATOR (0x35 + (x))
#define ADV7511_REG_PIXEL_REPETITION 0x3b
#define ADV7511_REG_VIC_MANUAL 0x3c
#define ADV7511_REG_VIC_SEND 0x3d
#define ADV7511_REG_VIC_DETECTED 0x3e
#define ADV7511_REG_AUX_VIC_DETECTED 0x3f
#define ADV7511_REG_PACKET_ENABLE0 0x40
#define ADV7511_REG_POWER 0x41
#define ADV7511_REG_STATUS 0x42
#define ADV7511_REG_EDID_I2C_ADDR 0x43
#define ADV7511_REG_PACKET_ENABLE1 0x44
#define ADV7511_REG_PACKET_I2C_ADDR 0x45
#define ADV7511_REG_DSD_ENABLE 0x46
#define ADV7511_REG_VIDEO_INPUT_CFG2 0x48
#define ADV7511_REG_INFOFRAME_UPDATE 0x4a
#define ADV7511_REG_GC(x) (0x4b + (x)) /* 0x4b - 0x51 */
#define ADV7511_REG_AVI_INFOFRAME_VERSION 0x52
#define ADV7511_REG_AVI_INFOFRAME_LENGTH 0x53
#define ADV7511_REG_AVI_INFOFRAME_CHECKSUM 0x54
#define ADV7511_REG_AVI_INFOFRAME(x) (0x55 + (x)) /* 0x55 - 0x6f */
#define ADV7511_REG_AUDIO_INFOFRAME_VERSION 0x70
#define ADV7511_REG_AUDIO_INFOFRAME_LENGTH 0x71
#define ADV7511_REG_AUDIO_INFOFRAME_CHECKSUM 0x72
#define ADV7511_REG_AUDIO_INFOFRAME(x) (0x73 + (x)) /* 0x73 - 0x7c */
#define ADV7511_REG_INT_ENABLE(x) (0x94 + (x))
#define ADV7511_REG_INT(x) (0x96 + (x))
#define ADV7511_REG_INPUT_CLK_DIV 0x9d
#define ADV7511_REG_PLL_STATUS 0x9e
#define ADV7511_REG_HDMI_POWER 0xa1
#define ADV7511_REG_HDCP_HDMI_CFG 0xaf
#define ADV7511_REG_AN(x) (0xb0 + (x)) /* 0xb0 - 0xb7 */
#define ADV7511_REG_HDCP_STATUS 0xb8
#define ADV7511_REG_BCAPS 0xbe
#define ADV7511_REG_BKSV(x) (0xc0 + (x)) /* 0xc0 - 0xc3 */
#define ADV7511_REG_EDID_SEGMENT 0xc4
#define ADV7511_REG_DDC_STATUS 0xc8
#define ADV7511_REG_EDID_READ_CTRL 0xc9
#define ADV7511_REG_BSTATUS(x) (0xca + (x)) /* 0xca - 0xcb */
#define ADV7511_REG_TIMING_GEN_SEQ 0xd0
#define ADV7511_REG_POWER2 0xd6
#define ADV7511_REG_HSYNC_PLACEMENT_MSB 0xfa
#define ADV7511_REG_SYNC_ADJUSTMENT(x) (0xd7 + (x)) /* 0xd7 - 0xdc */
#define ADV7511_REG_TMDS_CLOCK_INV 0xde
#define ADV7511_REG_ARC_CTRL 0xdf
#define ADV7511_REG_CEC_I2C_ADDR 0xe1
#define ADV7511_REG_CEC_CTRL 0xe2
#define ADV7511_REG_CHIP_ID_HIGH 0xf5
#define ADV7511_REG_CHIP_ID_LOW 0xf6
#define ADV7511_CSC_ENABLE BIT(7)
#define ADV7511_CSC_UPDATE_MODE BIT(5)
#define ADV7511_INT0_HDP BIT(7)
#define ADV7511_INT0_VSYNC BIT(5)
#define ADV7511_INT0_AUDIO_FIFO_FULL BIT(4)
#define ADV7511_INT0_EDID_READY BIT(2)
#define ADV7511_INT0_HDCP_AUTHENTICATED BIT(1)
#define ADV7511_INT1_DDC_ERROR BIT(7)
#define ADV7511_INT1_BKSV BIT(6)
#define ADV7511_INT1_CEC_TX_READY BIT(5)
#define ADV7511_INT1_CEC_TX_ARBIT_LOST BIT(4)
#define ADV7511_INT1_CEC_TX_RETRY_TIMEOUT BIT(3)
#define ADV7511_INT1_CEC_RX_READY3 BIT(2)
#define ADV7511_INT1_CEC_RX_READY2 BIT(1)
#define ADV7511_INT1_CEC_RX_READY1 BIT(0)
#define ADV7511_ARC_CTRL_POWER_DOWN BIT(0)
#define ADV7511_CEC_CTRL_POWER_DOWN BIT(0)
#define ADV7511_POWER_POWER_DOWN BIT(6)
#define ADV7511_HDMI_CFG_MODE_MASK 0x2
#define ADV7511_HDMI_CFG_MODE_DVI 0x0
#define ADV7511_HDMI_CFG_MODE_HDMI 0x2
#define ADV7511_AUDIO_SELECT_I2C 0x0
#define ADV7511_AUDIO_SELECT_SPDIF 0x1
#define ADV7511_AUDIO_SELECT_DSD 0x2
#define ADV7511_AUDIO_SELECT_HBR 0x3
#define ADV7511_AUDIO_SELECT_DST 0x4
#define ADV7511_I2S_SAMPLE_LEN_16 0x2
#define ADV7511_I2S_SAMPLE_LEN_20 0x3
#define ADV7511_I2S_SAMPLE_LEN_18 0x4
#define ADV7511_I2S_SAMPLE_LEN_22 0x5
#define ADV7511_I2S_SAMPLE_LEN_19 0x8
#define ADV7511_I2S_SAMPLE_LEN_23 0x9
#define ADV7511_I2S_SAMPLE_LEN_24 0xb
#define ADV7511_I2S_SAMPLE_LEN_17 0xc
#define ADV7511_I2S_SAMPLE_LEN_21 0xd
#define ADV7511_SAMPLE_FREQ_44100 0x0
#define ADV7511_SAMPLE_FREQ_48000 0x2
#define ADV7511_SAMPLE_FREQ_32000 0x3
#define ADV7511_SAMPLE_FREQ_88200 0x8
#define ADV7511_SAMPLE_FREQ_96000 0xa
#define ADV7511_SAMPLE_FREQ_176400 0xc
#define ADV7511_SAMPLE_FREQ_192000 0xe
#define ADV7511_STATUS_POWER_DOWN_POLARITY BIT(7)
#define ADV7511_STATUS_HPD BIT(6)
#define ADV7511_STATUS_MONITOR_SENSE BIT(5)
#define ADV7511_STATUS_I2S_32BIT_MODE BIT(3)
#define ADV7511_PACKET_ENABLE_N_CTS BIT(8+6)
#define ADV7511_PACKET_ENABLE_AUDIO_SAMPLE BIT(8+5)
#define ADV7511_PACKET_ENABLE_AVI_INFOFRAME BIT(8+4)
#define ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME BIT(8+3)
#define ADV7511_PACKET_ENABLE_GC BIT(7)
#define ADV7511_PACKET_ENABLE_SPD BIT(6)
#define ADV7511_PACKET_ENABLE_MPEG BIT(5)
#define ADV7511_PACKET_ENABLE_ACP BIT(4)
#define ADV7511_PACKET_ENABLE_ISRC BIT(3)
#define ADV7511_PACKET_ENABLE_GM BIT(2)
#define ADV7511_PACKET_ENABLE_SPARE2 BIT(1)
#define ADV7511_PACKET_ENABLE_SPARE1 BIT(0)
#define ADV7511_REG_POWER2_HDP_SRC_MASK 0xc0
#define ADV7511_REG_POWER2_HDP_SRC_BOTH 0x00
#define ADV7511_REG_POWER2_HDP_SRC_HDP 0x40
#define ADV7511_REG_POWER2_HDP_SRC_CEC 0x80
#define ADV7511_REG_POWER2_HDP_SRC_NONE 0xc0
#define ADV7511_REG_POWER2_TDMS_ENABLE BIT(4)
#define ADV7511_REG_POWER2_GATE_INPUT_CLK BIT(0)
#define ADV7511_LOW_REFRESH_RATE_NONE 0x0
#define ADV7511_LOW_REFRESH_RATE_24HZ 0x1
#define ADV7511_LOW_REFRESH_RATE_25HZ 0x2
#define ADV7511_LOW_REFRESH_RATE_30HZ 0x3
#define ADV7511_AUDIO_CFG3_LEN_MASK 0x0f
#define ADV7511_I2C_FREQ_ID_CFG_RATE_MASK 0xf0
#define ADV7511_AUDIO_SOURCE_I2S 0
#define ADV7511_AUDIO_SOURCE_SPDIF 1
#define ADV7511_I2S_FORMAT_I2S 0
#define ADV7511_I2S_FORMAT_RIGHT_J 1
#define ADV7511_I2S_FORMAT_LEFT_J 2
#define ADV7511_PACKET(p, x) ((p) * 0x20 + (x))
#define ADV7511_PACKET_SDP(x) ADV7511_PACKET(0, x)
#define ADV7511_PACKET_MPEG(x) ADV7511_PACKET(1, x)
#define ADV7511_PACKET_ACP(x) ADV7511_PACKET(2, x)
#define ADV7511_PACKET_ISRC1(x) ADV7511_PACKET(3, x)
#define ADV7511_PACKET_ISRC2(x) ADV7511_PACKET(4, x)
#define ADV7511_PACKET_GM(x) ADV7511_PACKET(5, x)
#define ADV7511_PACKET_SPARE(x) ADV7511_PACKET(6, x)
enum adv7511_input_clock {
ADV7511_INPUT_CLOCK_1X,
ADV7511_INPUT_CLOCK_2X,
ADV7511_INPUT_CLOCK_DDR,
};
enum adv7511_input_justification {
ADV7511_INPUT_JUSTIFICATION_EVENLY = 0,
ADV7511_INPUT_JUSTIFICATION_RIGHT = 1,
ADV7511_INPUT_JUSTIFICATION_LEFT = 2,
};
enum adv7511_input_sync_pulse {
ADV7511_INPUT_SYNC_PULSE_DE = 0,
ADV7511_INPUT_SYNC_PULSE_HSYNC = 1,
ADV7511_INPUT_SYNC_PULSE_VSYNC = 2,
ADV7511_INPUT_SYNC_PULSE_NONE = 3,
};
/**
* enum adv7511_sync_polarity - Polarity for the input sync signals
* @ADV7511_SYNC_POLARITY_PASSTHROUGH: Sync polarity matches that of
* the currently configured mode.
* @ADV7511_SYNC_POLARITY_LOW: Sync polarity is low
* @ADV7511_SYNC_POLARITY_HIGH: Sync polarity is high
*
* If the polarity is set to either LOW or HIGH the driver will configure the
* ADV7511 to internally invert the sync signal if required to match the sync
* polarity setting for the currently selected output mode.
*
* If the polarity is set to PASSTHROUGH, the ADV7511 will route the signal
* unchanged. This is used when the upstream graphics core already generates
* the sync signals with the correct polarity.
*/
enum adv7511_sync_polarity {
ADV7511_SYNC_POLARITY_PASSTHROUGH,
ADV7511_SYNC_POLARITY_LOW,
ADV7511_SYNC_POLARITY_HIGH,
};
/**
* struct adv7511_link_config - Describes adv7511 hardware configuration
* @input_color_depth: Number of bits per color component (8, 10 or 12)
* @input_colorspace: The input colorspace (RGB, YUV444, YUV422)
* @input_clock: The input video clock style (1x, 2x, DDR)
* @input_style: The input component arrangement variant
* @input_justification: Video input format bit justification
* @clock_delay: Clock delay for the input clock (in ps)
* @embedded_sync: Video input uses BT.656-style embedded sync
* @sync_pulse: Select the sync pulse
* @vsync_polarity: vsync input signal configuration
* @hsync_polarity: hsync input signal configuration
*/
struct adv7511_link_config {
unsigned int input_color_depth;
enum hdmi_colorspace input_colorspace;
enum adv7511_input_clock input_clock;
unsigned int input_style;
enum adv7511_input_justification input_justification;
int clock_delay;
bool embedded_sync;
enum adv7511_input_sync_pulse sync_pulse;
enum adv7511_sync_polarity vsync_polarity;
enum adv7511_sync_polarity hsync_polarity;
};
/**
* enum adv7511_csc_scaling - Scaling factor for the ADV7511 CSC
* @ADV7511_CSC_SCALING_1: CSC results are not scaled
* @ADV7511_CSC_SCALING_2: CSC results are scaled by a factor of two
* @ADV7511_CSC_SCALING_4: CSC results are scalled by a factor of four
*/
enum adv7511_csc_scaling {
ADV7511_CSC_SCALING_1 = 0,
ADV7511_CSC_SCALING_2 = 1,
ADV7511_CSC_SCALING_4 = 2,
};
/**
* struct adv7511_video_config - Describes adv7511 hardware configuration
* @csc_enable: Whether to enable color space conversion
* @csc_scaling_factor: Color space conversion scaling factor
* @csc_coefficents: Color space conversion coefficents
* @hdmi_mode: Whether to use HDMI or DVI output mode
* @avi_infoframe: HDMI infoframe
*/
struct adv7511_video_config {
bool csc_enable;
enum adv7511_csc_scaling csc_scaling_factor;
const uint16_t *csc_coefficents;
bool hdmi_mode;
struct hdmi_avi_infoframe avi_infoframe;
};
#endif /* __DRM_I2C_ADV7511_H__ */

View File

@ -11,10 +11,17 @@ config DRM_RCAR_DU
Choose this option if you have an R-Car chipset.
If M is selected the module will be called rcar-du-drm.
config DRM_RCAR_HDMI
bool "R-Car DU HDMI Encoder Support"
depends on DRM_RCAR_DU
depends on OF
help
Enable support for external HDMI encoders.
config DRM_RCAR_LVDS
bool "R-Car DU LVDS Encoder Support"
depends on DRM_RCAR_DU
depends on ARCH_R8A7790 || ARCH_R8A7791 || COMPILE_TEST
help
Enable support the R-Car Display Unit embedded LVDS encoders
(currently only on R8A7790).
Enable support for the R-Car Display Unit embedded LVDS encoders
(currently only on R8A7790 and R8A7791).

View File

@ -7,6 +7,8 @@ rcar-du-drm-y := rcar_du_crtc.o \
rcar_du_plane.o \
rcar_du_vgacon.o
rcar-du-drm-$(CONFIG_DRM_RCAR_HDMI) += rcar_du_hdmicon.o \
rcar_du_hdmienc.o
rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS) += rcar_du_lvdsenc.o
obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o

View File

@ -586,7 +586,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
if (irq < 0) {
dev_err(rcdu->dev, "no IRQ for CRTC %u\n", index);
return ret;
return irq;
}
ret = devm_request_irq(rcdu->dev, irq, rcar_du_crtc_irq, irqflags,

View File

@ -15,7 +15,6 @@
#define __RCAR_DU_CRTC_H__
#include <linux/mutex.h>
#include <linux/platform_data/rcar-du.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
@ -41,6 +40,15 @@ struct rcar_du_crtc {
#define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc)
enum rcar_du_output {
RCAR_DU_OUTPUT_DPAD0,
RCAR_DU_OUTPUT_DPAD1,
RCAR_DU_OUTPUT_LVDS0,
RCAR_DU_OUTPUT_LVDS1,
RCAR_DU_OUTPUT_TCON,
RCAR_DU_OUTPUT_MAX,
};
int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index);
void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable);
void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc,

View File

@ -146,12 +146,11 @@ static int rcar_du_load(struct drm_device *dev, unsigned long flags)
{
struct platform_device *pdev = dev->platformdev;
struct device_node *np = pdev->dev.of_node;
struct rcar_du_platform_data *pdata = pdev->dev.platform_data;
struct rcar_du_device *rcdu;
struct resource *mem;
int ret;
if (pdata == NULL && np == NULL) {
if (np == NULL) {
dev_err(dev->dev, "no platform data\n");
return -ENODEV;
}
@ -163,7 +162,6 @@ static int rcar_du_load(struct drm_device *dev, unsigned long flags)
}
rcdu->dev = &pdev->dev;
rcdu->pdata = pdata;
rcdu->info = np ? of_match_device(rcar_du_of_table, rcdu->dev)->data
: (void *)platform_get_device_id(pdev)->driver_data;
rcdu->ddev = dev;

View File

@ -15,7 +15,6 @@
#define __RCAR_DU_DRV_H__
#include <linux/kernel.h>
#include <linux/platform_data/rcar-du.h>
#include "rcar_du_crtc.h"
#include "rcar_du_group.h"
@ -67,7 +66,6 @@ struct rcar_du_device_info {
struct rcar_du_device {
struct device *dev;
const struct rcar_du_platform_data *pdata;
const struct rcar_du_device_info *info;
void __iomem *mmio;

View File

@ -19,6 +19,8 @@
#include "rcar_du_drv.h"
#include "rcar_du_encoder.h"
#include "rcar_du_hdmicon.h"
#include "rcar_du_hdmienc.h"
#include "rcar_du_kms.h"
#include "rcar_du_lvdscon.h"
#include "rcar_du_lvdsenc.h"
@ -33,7 +35,7 @@ rcar_du_connector_best_encoder(struct drm_connector *connector)
{
struct rcar_du_connector *rcon = to_rcar_connector(connector);
return &rcon->encoder->encoder;
return rcar_encoder_to_drm_encoder(rcon->encoder);
}
/* -----------------------------------------------------------------------------
@ -142,10 +144,11 @@ static const struct drm_encoder_funcs encoder_funcs = {
int rcar_du_encoder_init(struct rcar_du_device *rcdu,
enum rcar_du_encoder_type type,
enum rcar_du_output output,
const struct rcar_du_encoder_data *data,
struct device_node *np)
struct device_node *enc_node,
struct device_node *con_node)
{
struct rcar_du_encoder *renc;
struct drm_encoder *encoder;
unsigned int encoder_type;
int ret;
@ -154,6 +157,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
return -ENOMEM;
renc->output = output;
encoder = rcar_encoder_to_drm_encoder(renc);
switch (output) {
case RCAR_DU_OUTPUT_LVDS0:
@ -175,6 +179,9 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
case RCAR_DU_ENCODER_LVDS:
encoder_type = DRM_MODE_ENCODER_LVDS;
break;
case RCAR_DU_ENCODER_HDMI:
encoder_type = DRM_MODE_ENCODER_TMDS;
break;
case RCAR_DU_ENCODER_NONE:
default:
/* No external encoder, use the internal encoder type. */
@ -182,23 +189,35 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
break;
}
ret = drm_encoder_init(rcdu->ddev, &renc->encoder, &encoder_funcs,
if (type == RCAR_DU_ENCODER_HDMI) {
if (renc->lvds) {
dev_err(rcdu->dev,
"Chaining LVDS and HDMI encoders not supported\n");
return -EINVAL;
}
ret = rcar_du_hdmienc_init(rcdu, renc, enc_node);
if (ret < 0)
return ret;
} else {
ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
encoder_type);
if (ret < 0)
return ret;
drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs);
drm_encoder_helper_add(encoder, &encoder_helper_funcs);
}
switch (encoder_type) {
case DRM_MODE_ENCODER_LVDS: {
const struct rcar_du_panel_data *pdata =
data ? &data->connector.lvds.panel : NULL;
return rcar_du_lvds_connector_init(rcdu, renc, pdata, np);
}
case DRM_MODE_ENCODER_LVDS:
return rcar_du_lvds_connector_init(rcdu, renc, con_node);
case DRM_MODE_ENCODER_DAC:
return rcar_du_vga_connector_init(rcdu, renc);
case DRM_MODE_ENCODER_TMDS:
return rcar_du_hdmi_connector_init(rcdu, renc);
default:
return -EINVAL;
}

View File

@ -14,21 +14,32 @@
#ifndef __RCAR_DU_ENCODER_H__
#define __RCAR_DU_ENCODER_H__
#include <linux/platform_data/rcar-du.h>
#include <drm/drm_crtc.h>
#include <drm/drm_encoder_slave.h>
struct rcar_du_device;
struct rcar_du_hdmienc;
struct rcar_du_lvdsenc;
enum rcar_du_encoder_type {
RCAR_DU_ENCODER_UNUSED = 0,
RCAR_DU_ENCODER_NONE,
RCAR_DU_ENCODER_VGA,
RCAR_DU_ENCODER_LVDS,
RCAR_DU_ENCODER_HDMI,
};
struct rcar_du_encoder {
struct drm_encoder encoder;
struct drm_encoder_slave slave;
enum rcar_du_output output;
struct rcar_du_hdmienc *hdmi;
struct rcar_du_lvdsenc *lvds;
};
#define to_rcar_encoder(e) \
container_of(e, struct rcar_du_encoder, encoder)
container_of(e, struct rcar_du_encoder, slave.base)
#define rcar_encoder_to_drm_encoder(e) (&(e)->slave.base)
struct rcar_du_connector {
struct drm_connector connector;
@ -44,7 +55,7 @@ rcar_du_connector_best_encoder(struct drm_connector *connector);
int rcar_du_encoder_init(struct rcar_du_device *rcdu,
enum rcar_du_encoder_type type,
enum rcar_du_output output,
const struct rcar_du_encoder_data *data,
struct device_node *np);
struct device_node *enc_node,
struct device_node *con_node);
#endif /* __RCAR_DU_ENCODER_H__ */

View File

@ -0,0 +1,118 @@
/*
* R-Car Display Unit HDMI Connector
*
* Copyright (C) 2014 Renesas Electronics Corporation
*
* Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_encoder_slave.h>
#include "rcar_du_drv.h"
#include "rcar_du_encoder.h"
#include "rcar_du_hdmicon.h"
#include "rcar_du_kms.h"
#define to_slave_funcs(e) (to_rcar_encoder(e)->slave.slave_funcs)
static int rcar_du_hdmi_connector_get_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = connector->encoder;
struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
if (sfuncs->get_modes == NULL)
return 0;
return sfuncs->get_modes(encoder, connector);
}
static int rcar_du_hdmi_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_encoder *encoder = connector->encoder;
struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
if (sfuncs->mode_valid == NULL)
return MODE_OK;
return sfuncs->mode_valid(encoder, mode);
}
static const struct drm_connector_helper_funcs connector_helper_funcs = {
.get_modes = rcar_du_hdmi_connector_get_modes,
.mode_valid = rcar_du_hdmi_connector_mode_valid,
.best_encoder = rcar_du_connector_best_encoder,
};
static void rcar_du_hdmi_connector_destroy(struct drm_connector *connector)
{
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
}
static enum drm_connector_status
rcar_du_hdmi_connector_detect(struct drm_connector *connector, bool force)
{
struct drm_encoder *encoder = connector->encoder;
struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
if (sfuncs->detect == NULL)
return connector_status_unknown;
return sfuncs->detect(encoder, connector);
}
static const struct drm_connector_funcs connector_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = rcar_du_hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = rcar_du_hdmi_connector_destroy,
};
int rcar_du_hdmi_connector_init(struct rcar_du_device *rcdu,
struct rcar_du_encoder *renc)
{
struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc);
struct rcar_du_connector *rcon;
struct drm_connector *connector;
int ret;
rcon = devm_kzalloc(rcdu->dev, sizeof(*rcon), GFP_KERNEL);
if (rcon == NULL)
return -ENOMEM;
connector = &rcon->connector;
connector->display_info.width_mm = 0;
connector->display_info.height_mm = 0;
ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
DRM_MODE_CONNECTOR_HDMIA);
if (ret < 0)
return ret;
drm_connector_helper_add(connector, &connector_helper_funcs);
ret = drm_connector_register(connector);
if (ret < 0)
return ret;
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
drm_object_property_set_value(&connector->base,
rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
ret = drm_mode_connector_attach_encoder(connector, encoder);
if (ret < 0)
return ret;
connector->encoder = encoder;
rcon->encoder = renc;
return 0;
}

View File

@ -0,0 +1,31 @@
/*
* R-Car Display Unit HDMI Connector
*
* Copyright (C) 2014 Renesas Electronics Corporation
*
* Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __RCAR_DU_HDMICON_H__
#define __RCAR_DU_HDMICON_H__
struct rcar_du_device;
struct rcar_du_encoder;
#if IS_ENABLED(CONFIG_DRM_RCAR_HDMI)
int rcar_du_hdmi_connector_init(struct rcar_du_device *rcdu,
struct rcar_du_encoder *renc);
#else
static inline int rcar_du_hdmi_connector_init(struct rcar_du_device *rcdu,
struct rcar_du_encoder *renc)
{
return -ENOSYS;
}
#endif
#endif /* __RCAR_DU_HDMICON_H__ */

View File

@ -0,0 +1,151 @@
/*
* R-Car Display Unit HDMI Encoder
*
* Copyright (C) 2014 Renesas Electronics Corporation
*
* Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/slab.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_encoder_slave.h>
#include "rcar_du_drv.h"
#include "rcar_du_encoder.h"
#include "rcar_du_hdmienc.h"
struct rcar_du_hdmienc {
struct rcar_du_encoder *renc;
struct device *dev;
int dpms;
};
#define to_rcar_hdmienc(e) (to_rcar_encoder(e)->hdmi)
#define to_slave_funcs(e) (to_rcar_encoder(e)->slave.slave_funcs)
static void rcar_du_hdmienc_dpms(struct drm_encoder *encoder, int mode)
{
struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
if (hdmienc->dpms == mode)
return;
if (sfuncs->dpms)
sfuncs->dpms(encoder, mode);
hdmienc->dpms = mode;
}
static bool rcar_du_hdmienc_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
if (sfuncs->mode_fixup == NULL)
return true;
return sfuncs->mode_fixup(encoder, mode, adjusted_mode);
}
static void rcar_du_hdmienc_mode_prepare(struct drm_encoder *encoder)
{
rcar_du_hdmienc_dpms(encoder, DRM_MODE_DPMS_OFF);
}
static void rcar_du_hdmienc_mode_commit(struct drm_encoder *encoder)
{
rcar_du_hdmienc_dpms(encoder, DRM_MODE_DPMS_ON);
}
static void rcar_du_hdmienc_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
if (sfuncs->mode_set)
sfuncs->mode_set(encoder, mode, adjusted_mode);
rcar_du_crtc_route_output(encoder->crtc, hdmienc->renc->output);
}
static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
.dpms = rcar_du_hdmienc_dpms,
.mode_fixup = rcar_du_hdmienc_mode_fixup,
.prepare = rcar_du_hdmienc_mode_prepare,
.commit = rcar_du_hdmienc_mode_commit,
.mode_set = rcar_du_hdmienc_mode_set,
};
static void rcar_du_hdmienc_cleanup(struct drm_encoder *encoder)
{
struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
rcar_du_hdmienc_dpms(encoder, DRM_MODE_DPMS_OFF);
drm_encoder_cleanup(encoder);
put_device(hdmienc->dev);
}
static const struct drm_encoder_funcs encoder_funcs = {
.destroy = rcar_du_hdmienc_cleanup,
};
int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
struct rcar_du_encoder *renc, struct device_node *np)
{
struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc);
struct drm_i2c_encoder_driver *driver;
struct i2c_client *i2c_slave;
struct rcar_du_hdmienc *hdmienc;
int ret;
hdmienc = devm_kzalloc(rcdu->dev, sizeof(*hdmienc), GFP_KERNEL);
if (hdmienc == NULL)
return -ENOMEM;
/* Locate the slave I2C device and driver. */
i2c_slave = of_find_i2c_device_by_node(np);
if (!i2c_slave || !i2c_get_clientdata(i2c_slave))
return -EPROBE_DEFER;
hdmienc->dev = &i2c_slave->dev;
if (hdmienc->dev->driver == NULL) {
ret = -EPROBE_DEFER;
goto error;
}
/* Initialize the slave encoder. */
driver = to_drm_i2c_encoder_driver(to_i2c_driver(hdmienc->dev->driver));
ret = driver->encoder_init(i2c_slave, rcdu->ddev, &renc->slave);
if (ret < 0)
goto error;
ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
DRM_MODE_ENCODER_TMDS);
if (ret < 0)
goto error;
drm_encoder_helper_add(encoder, &encoder_helper_funcs);
renc->hdmi = hdmienc;
hdmienc->renc = renc;
return 0;
error:
put_device(hdmienc->dev);
return ret;
}

View File

@ -0,0 +1,35 @@
/*
* R-Car Display Unit HDMI Encoder
*
* Copyright (C) 2014 Renesas Electronics Corporation
*
* Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __RCAR_DU_HDMIENC_H__
#define __RCAR_DU_HDMIENC_H__
#include <linux/module.h>
struct device_node;
struct rcar_du_device;
struct rcar_du_encoder;
#if IS_ENABLED(CONFIG_DRM_RCAR_HDMI)
int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
struct rcar_du_encoder *renc, struct device_node *np);
#else
static inline int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
struct rcar_du_encoder *renc,
struct device_node *np)
{
return -ENOSYS;
}
#endif
#endif /* __RCAR_DU_HDMIENC_H__ */

View File

@ -190,41 +190,7 @@ static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = {
.output_poll_changed = rcar_du_output_poll_changed,
};
static int rcar_du_encoders_init_pdata(struct rcar_du_device *rcdu)
{
unsigned int num_encoders = 0;
unsigned int i;
int ret;
for (i = 0; i < rcdu->pdata->num_encoders; ++i) {
const struct rcar_du_encoder_data *pdata =
&rcdu->pdata->encoders[i];
const struct rcar_du_output_routing *route =
&rcdu->info->routes[pdata->output];
if (pdata->type == RCAR_DU_ENCODER_UNUSED)
continue;
if (pdata->output >= RCAR_DU_OUTPUT_MAX ||
route->possible_crtcs == 0) {
dev_warn(rcdu->dev,
"encoder %u references unexisting output %u, skipping\n",
i, pdata->output);
continue;
}
ret = rcar_du_encoder_init(rcdu, pdata->type, pdata->output,
pdata, NULL);
if (ret < 0)
return ret;
num_encoders++;
}
return num_encoders;
}
static int rcar_du_encoders_init_dt_one(struct rcar_du_device *rcdu,
static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
enum rcar_du_output output,
struct of_endpoint *ep)
{
@ -233,6 +199,7 @@ static int rcar_du_encoders_init_dt_one(struct rcar_du_device *rcdu,
enum rcar_du_encoder_type type;
} encoders[] = {
{ "adi,adv7123", RCAR_DU_ENCODER_VGA },
{ "adi,adv7511w", RCAR_DU_ENCODER_HDMI },
{ "thine,thc63lvdm83d", RCAR_DU_ENCODER_LVDS },
};
@ -323,14 +290,14 @@ static int rcar_du_encoders_init_dt_one(struct rcar_du_device *rcdu,
connector = entity;
}
ret = rcar_du_encoder_init(rcdu, enc_type, output, NULL, connector);
ret = rcar_du_encoder_init(rcdu, enc_type, output, encoder, connector);
of_node_put(encoder);
of_node_put(connector);
return ret < 0 ? ret : 1;
}
static int rcar_du_encoders_init_dt(struct rcar_du_device *rcdu)
static int rcar_du_encoders_init(struct rcar_du_device *rcdu)
{
struct device_node *np = rcdu->dev->of_node;
struct device_node *prev = NULL;
@ -377,7 +344,7 @@ static int rcar_du_encoders_init_dt(struct rcar_du_device *rcdu)
}
/* Process the output pipeline. */
ret = rcar_du_encoders_init_dt_one(rcdu, output, &ep);
ret = rcar_du_encoders_init_one(rcdu, output, &ep);
if (ret < 0) {
of_node_put(ep_node);
return ret;
@ -442,11 +409,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
if (ret < 0)
return ret;
if (rcdu->pdata)
ret = rcar_du_encoders_init_pdata(rcdu);
else
ret = rcar_du_encoders_init_dt(rcdu);
ret = rcar_du_encoders_init(rcdu);
if (ret < 0)
return ret;

View File

@ -27,7 +27,11 @@
struct rcar_du_lvds_connector {
struct rcar_du_connector connector;
struct rcar_du_panel_data panel;
struct {
unsigned int width_mm; /* Panel width in mm */
unsigned int height_mm; /* Panel height in mm */
struct videomode mode;
} panel;
};
#define to_rcar_lvds_connector(c) \
@ -78,22 +82,18 @@ static const struct drm_connector_funcs connector_funcs = {
int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu,
struct rcar_du_encoder *renc,
const struct rcar_du_panel_data *panel,
/* TODO const */ struct device_node *np)
{
struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc);
struct rcar_du_lvds_connector *lvdscon;
struct drm_connector *connector;
struct display_timing timing;
int ret;
lvdscon = devm_kzalloc(rcdu->dev, sizeof(*lvdscon), GFP_KERNEL);
if (lvdscon == NULL)
return -ENOMEM;
if (panel) {
lvdscon->panel = *panel;
} else {
struct display_timing timing;
ret = of_get_display_timing(np, "panel-timing", &timing);
if (ret < 0)
return ret;
@ -102,7 +102,6 @@ int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu,
of_property_read_u32(np, "width-mm", &lvdscon->panel.width_mm);
of_property_read_u32(np, "height-mm", &lvdscon->panel.height_mm);
}
connector = &lvdscon->connector.connector;
connector->display_info.width_mm = lvdscon->panel.width_mm;
@ -122,11 +121,11 @@ int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu,
drm_object_property_set_value(&connector->base,
rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
ret = drm_mode_connector_attach_encoder(connector, &renc->encoder);
ret = drm_mode_connector_attach_encoder(connector, encoder);
if (ret < 0)
return ret;
connector->encoder = &renc->encoder;
connector->encoder = encoder;
lvdscon->connector.encoder = renc;
return 0;

View File

@ -16,11 +16,9 @@
struct rcar_du_device;
struct rcar_du_encoder;
struct rcar_du_panel_data;
int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu,
struct rcar_du_encoder *renc,
const struct rcar_du_panel_data *panel,
struct device_node *np);
#endif /* __RCAR_DU_LVDSCON_H__ */

View File

@ -16,7 +16,6 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_data/rcar-du.h>
struct rcar_drm_crtc;
struct rcar_du_lvdsenc;

View File

@ -52,6 +52,7 @@ static const struct drm_connector_funcs connector_funcs = {
int rcar_du_vga_connector_init(struct rcar_du_device *rcdu,
struct rcar_du_encoder *renc)
{
struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc);
struct rcar_du_connector *rcon;
struct drm_connector *connector;
int ret;
@ -78,11 +79,11 @@ int rcar_du_vga_connector_init(struct rcar_du_device *rcdu,
drm_object_property_set_value(&connector->base,
rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
ret = drm_mode_connector_attach_encoder(connector, &renc->encoder);
ret = drm_mode_connector_attach_encoder(connector, encoder);
if (ret < 0)
return ret;
connector->encoder = &renc->encoder;
connector->encoder = encoder;
rcon->encoder = renc;
return 0;

View File

@ -381,4 +381,9 @@ static inline int drm_eld_size(const uint8_t *eld)
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
}
struct edid *drm_do_get_edid(struct drm_connector *connector,
int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
size_t len),
void *data);
#endif /* __DRM_EDID_H__ */

View File

@ -1,74 +0,0 @@
/*
* rcar_du.h -- R-Car Display Unit DRM driver
*
* Copyright (C) 2013 Renesas Corporation
*
* Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __RCAR_DU_H__
#define __RCAR_DU_H__
#include <video/videomode.h>
enum rcar_du_output {
RCAR_DU_OUTPUT_DPAD0,
RCAR_DU_OUTPUT_DPAD1,
RCAR_DU_OUTPUT_LVDS0,
RCAR_DU_OUTPUT_LVDS1,
RCAR_DU_OUTPUT_TCON,
RCAR_DU_OUTPUT_MAX,
};
enum rcar_du_encoder_type {
RCAR_DU_ENCODER_UNUSED = 0,
RCAR_DU_ENCODER_NONE,
RCAR_DU_ENCODER_VGA,
RCAR_DU_ENCODER_LVDS,
};
struct rcar_du_panel_data {
unsigned int width_mm; /* Panel width in mm */
unsigned int height_mm; /* Panel height in mm */
struct videomode mode;
};
struct rcar_du_connector_lvds_data {
struct rcar_du_panel_data panel;
};
struct rcar_du_connector_vga_data {
/* TODO: Add DDC information for EDID retrieval */
};
/*
* struct rcar_du_encoder_data - Encoder platform data
* @type: the encoder type (RCAR_DU_ENCODER_*)
* @output: the DU output the connector is connected to (RCAR_DU_OUTPUT_*)
* @connector.lvds: platform data for LVDS connectors
* @connector.vga: platform data for VGA connectors
*
* Encoder platform data describes an on-board encoder, its associated DU SoC
* output, and the connector.
*/
struct rcar_du_encoder_data {
enum rcar_du_encoder_type type;
enum rcar_du_output output;
union {
struct rcar_du_connector_lvds_data lvds;
struct rcar_du_connector_vga_data vga;
} connector;
};
struct rcar_du_platform_data {
struct rcar_du_encoder_data *encoders;
unsigned int num_encoders;
};
#endif /* __RCAR_DU_H__ */